Решение "проблемы" ненужных картинок или "пылесос" для LiveStreet


Вот тут была поднята тема о неиспользуемых картинках:
http://livestreet.ru/blog/questions/110.html

Эта «проблема» легко решаема. Всё просто:
Берём этот скриптик, сохраняем в файлик с именем допустим cleaner.php и кладём этот файлик в корневую директорию сайта.

Архив со скриптом: Перенесён в раздел «Модули»

Для того что бы никто кроме вашего демона крон не мог запустить этот достаточно ресурсоёмкий скрипт на исполнение, в .htaccess добавляем следующие строчки:

<Files "cleaner.php">
  Order Deny,Allow
  Deny from all
  Allow from *IP на котором находится Ваш cron* 
</Files>


P.S. Я не несу ответственности за возможные негативные последствия использования этого скрипта. Если вдруг этот скрип доставил Вам проблем, я Вас очень прошу не смотрите сериал «ALF» — он Вас будет бесить, поверьте.

P.P.S. Забыл добавить, что этот скрипт работает только для LiveStreet 0.2

33 комментария

avatar
Спасибо за пылесос! Но LS 0.2 уже не актуально, похоже…
avatar
Спасибо, я бы сказал LS 0.3 не актуально пока. Если речь идет про рабочий проект (продакшн) то использовать current версию это экстрим.
avatar
Можно и в 0.3 прибраться.

Тут возможны два варианта — один простой, второй тоже не сложный.

1. Простой:

Отучаем саму LiveStreet «мусорить» — убираем в самой системы раскладывание по кучам папок (там насколько я помню просто рандомная функция натыкана), и делаем имена сохраняемых файлов подлиннее (навряд ли пользователь зальёт столько изображений, что имена файлов будут временами совпадать). В этом случае система просто будет складировать файлы в одну директорию закреплённую за пользователем. Так же необходимо ещё добавить в этот скрипт проверку поля фотографий пользователей в таблице с пользователями.

(Этот вариант подойдёт для тех, кто ставит систему с нуля)

2. Посложнее, так как в этом случае нужно «чесать репу», а это всегда «лениво».

Добавить в этот скрипт ещё парочку циклов, и тем самым научить его ковыряться в подпапках. Соответственно так же нужно добавить проверку фотографий.

(Этот вариант подойдёт для тех, у кого сайт уже с контентом)

***

В случае с VDS и полноценным дедиком проблемы с файловым мусором не стоит — там места водоём, а вот для небольших сообществ у которых система крутится на обычном виртуальном хосте эта проблема теоретически может возникнуть.
avatar
О каких «подпапках», «рандомности» и «кучах» идёт речь? Все картинки пользователя хранятся в директории, имя которой совпадает с порядковым номером юзера
avatar
Мы уже плавно перешли к обсуждению версии 0.3
В версии 0.2 да, там всё именно так как Вы описали, а вот в 0.3 такая ситуация:

livestreet.ru/uploads/images/2/2/8/3/1306/f21ab38509.jpg

В ранних ревизиях 0.3 фотки пользователей разбрасывались произвольно по директории images в рандомных подпапках, а как в свежих ревизиях обстоит дело с этим я затруднюсь ответить.
avatar
Спасибо за информацию, я грядущую версию протестировать ещё не успел. Интересно, чем руководствовался разработчик, вводя акое новшество?
avatar
тем чтоб в одном каталоге не скапливалось слишком много контента, а при большой активности это не избежно
avatar
Прблема замедления выборки из директории с большим количеством файлов мне известна. Непонятно, для чего столько уровней вложенности и почему каталоги создаются рандомно. Или они создаются внутри пользовательской директории?
avatar
по уровням вложенности я исходил из теории вероятности, формулу уже не помню, но суть в том, чтоб скажем при 1000000 юзеров каталог не переполнялся.
На счет второго момента(внутри пользовательской директории) — а где хранить эти пользовательские каталоги? в одном общем каталоге?
тут возможен вариант с «запоминанием» для каждого юзера своего случайного каталога, но я сделал без этого
avatar
Мне нравилась идея в предыдущей версии — когда есть каталог с именем, соответствующим ийди пользователя. В нём вполне уместно хранить все загруженные юзером картинки.

Дополнительным аргументом в пользу такого варианта служит тот факт, что при использовании лишь одной файловой системы можно получать информацию о картинках конкретного пользователя. Например, у меня была идея выбирать случайную картинку пользователя из его каталога либо даже сделать подобие галереи вроде той, что на сайте русской службы би-би-си показывает «лицо дня» или что-вроде этого.
avatar
те же случайно создаваемые каталоги можно размещать внутри персональной пользовательской директории в стиле ЛС 0.2
avatar
это понятно, здесь вопрос в том, где размещать эти самые пользовательские каталоги
avatar
site.ru/uploads/images/%user_id%/%random%/%random%/

такой вариант разве не пройдёт?
avatar
нет, т.к. в каталоге images будет куча каталогов вида %user_id% при большом числе юзеров, т.е. от чего избавлялись к тому и пришли
avatar
а если применять разделени по каталогам, используя десятичные разряды?

например, для пользователя #2379
site.ru/uploads/images/0/0/2/3/7/9/%random%/%random%/
для пользователя #14
site.ru/uploads/images/0/0/0/0/1/4/%random%/%random%/
avatar
тоже вариант, только для себя не нашел практической необходимости иметь один каталог в котором файлы только одного юзера. Хотя, да, польза в этом есть =)
avatar
Был бы вам благодарен, если бы в будущем появилась такая возможность :-)
avatar
реализация из прошлой версии не выжила бы при большом числе пользователей
avatar
Можете пояснить, почему именно при большой нагрузке? Я полагал, что сложности возникнут из-за накопления большого количества файлов в одной директории.
avatar
я не имел ввиду нагрузку, ответ здесь
avatar
На самом деле на эту тему можно очень долго рассуждать. «Проблема замедления выборки из директории с большим количеством файлов» это довольно неоднозначная, спорная и по большей части теоретическая. Файловые системы разные, все они имеют свои преимущества и свои недостатки. К тому же стоит добавить, что всё течёт, всё меняется. Но перестраховаться да, не помешает. К тому же на любом этапе жизни портала всё можно, при желании, переиграть.
avatar
только недавно поставил систему и сразу же столкнулся с неудобством такого именования картинок. тем более что при заливке картинки часто теряются и приходится заливать их заново

как я понял, такой сложный формат /uploads/images/5/b/1/2/1/8c60e25c50.jpg имеет смысл только как защита от автоматического скачивания изображений 01.jpg — 99.jpg. что только мешает людям.

во всех прочих смыслах это крайне неудобная логика именования файлов

не найдя, как ее отключить — зашел сюда и, как понял, это лишь способ раскидать картинки по разным директориям, чтобы в каждой было не больше 40-100. я верно понял?

если да — предлагаю простой и удобный способ сделать это, который позволит в любой момент найти любые изображения:

пользователь/дата/01-99.jpg

/uploads/images/gamberro/2010-01-11/01.jpg…

после этого чистить картинки станет возможно руками
avatar
/uploads/images/gamberro/2010-01-11/01.jpg
при таком подходе в каталоге images будет много директорий, т.к. число пользователей бывает большим
В ЛС 0.4 пути такие: /images/00/00/01/2010/01/11/asdad.gif, где 000001 — id пользователя
avatar
тогда бьём пользователей по алфавиту
/uploads/images/ga/gamberro/2010-01-11/01.jpg
/uploads/images/ga/gatherer/2010-01-11/01.jpg
/uploads/images/gu/gunny/2010-01-11/01.jpg

можно еще точнее — присваивать каждому посту уникальный id и
/uploads/images/gu/gunny-00023825/01.jpg
avatar
реализую у себя

задачи:
1. максимально сократить вложенность директорий,
2. класть файл в понятный человеку урл: директорию пользователя/блога/топика
3. оставлять прежнее имя файла для удобства отслеживания, какие файлы были залиты в сообщение, а какие еще нет

было
/uploads/images/5/b/1/2/1/8c60e25c50.jpg
должно стать
/up-img/ga/gamberro/%название_блога%/%номер_топика%/01.jpg

нужна ваша помощь в нахождении нужных переменных движка
как узнать не номер пользователя, а его имя?
как узнать название блога?
как узнать номер топика?
как в 38 строке v0.3 > /include/ajax/uploadImg.php заменить func_generator(), выдающий 8c60e25c50 на оригинальное имя файла типа 06.jpg?
avatar
Спасибо за труд, пригодилось.
avatar
Вот чистилка для 0.3:
(только умоляю — поосторожнее с ней)

<code><?PHP

$bConfig=include("./config/config.php");
$cConfig=include("./config/config.table.php");

   $dConfig=include("./config/config.db.php");
   $sDSN=$dConfig['type'].'://'.$dConfig['user'].':'.$dConfig['pass'].'@'.$dConfig['host'].':'.$dConfig['port'].'/'.$dConfig['dbname'];		

  //Цепляем класс
   require_once "./classes/lib/external/DbSimple/Generic.php";
  //Создаём объект
   $oDbSimple=DbSimple_Generic::connect($sDSN);

function cleaning_filesystem($dirname)  {

global $oDbSimple;

    if  (is_dir($dirname))
        $dir_handle  =  opendir($dirname);
    if  (!$dir_handle)
        return  false;
     
		//Перебираем
		while(($file  =  readdir($dir_handle))!==false)  {
            if  ($file  !=  "."  &&  $file  !=  ".." && ereg("avatar", $file)!=TRUE)  {
                if  (!is_dir($dirname."/".$file)) {
                   
                    //Проверяем 
                    $sql = $oDbSimple->select("SELECT topic_id FROM ".DB_TABLE_TOPIC_CONTENT." WHERE topic_text_source LIKE '%$file%'");
                    $a=count($sql);
                       $sql = $oDbSimple->select("SELECT page_id FROM ".DB_TABLE_PAGE." WHERE page_text LIKE '%$file%'");
                       $a=$a+count($sql);
                          $sql = $oDbSimple->select("SELECT comment_id FROM ".DB_TABLE_TOPIC_COMMENT." WHERE comment_text LIKE '%$file%'");
                          $a=$a+count($sql);
							 $sql = $oDbSimple->select("SELECT user_id FROM ".DB_TABLE_USER." WHERE user_profile_foto LIKE '%$file%'");
                             $a=$a+count($sql);
                   
                   //Удаляем
                    if ($a==0) {
                        if (unlink($dirname."/".$file))
                       //Если файл удалился, то выводим на экран сообщение об успехе
                        { echo "<font color='green'>DELETED</font>".' '.$dirname."/".$file."
\n"; }
                            else
                       //Если файл не удалился, то выводим на экран сообщение об ошибке
                        { echo "<font color='red'>DELETED</font>".' '.$dirname."/".$file."
\n"; }
                    }	
					
				}					
					
                else 
			   //Рекурсия
                cleaning_filesystem($dirname.'/'.$file);                       
            }
        }
       //Закрываем
        closedir($dir_handle);
       //Удаляем
        @rmdir($dirname);
       //Возвращаем
        return  true;
} 

$dirname=".".DIR_UPLOADS_IMAGES;
cleaning_filesystem($dirname);

?></code>


Заранее извиняюсь за «портянку».
  • ALF
  • +1
avatar
Поставил на денвере LS02
Пароль на цифру, выкидывает ошибку, но регестрирует
Не режет длинные слова, проверю здесь
ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп
  • aaa
  • -2
avatar
Тоже не обрезает, ладно хоть блок не резиновый.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.