Поиск и перенос неиспользуемых картинок в Upload 2.X

1890
В продолжение темы про удаление пустых папок, сделал утилиту для глобальной очистки папки upload.
Запускается из админки.
1. Сканирует в полях всех таблиц базы (имена нужных полей можно добавлять через запятую в опциях) все ссылки на файлы изображений и записывает результат в файл /upload/links.json.
2. Сканирует файлы в папке upload и записывает результаты в файл /upload/files.json
3. Преобразует оба файла в массивы, сравнивает второй с первым и заносит результат в файл /upload/compare.json
4. Снова сканирует папку upload и файлы, совпадающие именами с содержимым /upload/compare.json, переносит с сохранением подпапок и путей в папку /deleted/upload/
5. Бонусом (если поставить галку) удаляет пустые папки и в upload и в deleted.
6. Пакует папку deleted в zip и вывешивает ссылку на скачивание.

Выглядит все это так:
Поиск и перенос неиспользуемых картинок в Upload

Поиск и перенос неиспользуемых картинок в Upload

По идее начинать нужно сначала и на следующий пункт перейдет автоматически, но если что-то пошло не так (не хватило времени, памяти и т.д.), всегда можно продолжить, перейдя на следующий пункт принудительно.

Если Вы не знаете, как на сервере перемещать файлы и в каких полях у Вас есть ссылки на изображения - лучше ничего не трогайте и не устанавливайте это!

Компонент предоставляется "как есть" и претензии по пропавшим фотографиям любимой собачки не принимаются.
Все файлы при должном умении можно вернуть назад. Просто перенести или скопировать /deleted/upload/ в /upload/
Работает долго и нудно. Чем больше сайт, тем больше риск, что не хватит памяти.

Установка обычным способом.

Скачать компонент unfinder
Удаление пустых папок в Upload | Бэкап базы данных по расписанию.
Комментарии (79)
Rainbow 28 февраля 2018 в 08:41 0
small user social cms
Работает замечательно.
На тестовом, убрал треть мусора из upload было 150 Мб стало 97 Мб. Выберу время буду пробовать на реальном.

По улучшению
Андрей 28 февраля 2018 в 10:13 -1
small user social cms
Ris, скажите пожалуйста - Удаление пустых папок в Upload - можно удалить если этот компонент поставить? Или он дополняет его?
Ris 28 февраля 2018 в 10:19 +2
small user social cms
Можно удалить.
Тот по хрону срабатывает каждую ночь, а этот вручную, когда захочется..
Андрей 28 февраля 2018 в 10:36 -1
small user social cms
Спасибо, я понял.
Zau4man 28 февраля 2018 в 10:21 0
small user social cms
Спасибо за труды.
Обязательно воспользуюсь после тестов на локалке.
MegaRostov 28 февраля 2018 в 12:55 0
small user social cms
Огромное спасибо! ОГРОМНЫЙ +
Kreator 28 февраля 2018 в 13:35 0
small user social cms
1) Ищет с БД только в полях для картинок? или любые? поле для content где путь может быть среди текста, а так же путь к картинке там может быть относительным и абсолютным
2) Вопрос по нагрузкам планируете решать? как быть если картинок и записей в таблицах по нескольку миллионов?
Ris 28 февраля 2018 в 14:31 +2
small user social cms
1. В любых полях, какие укажете, в любом месте. Оно ищет сочетание букв.
yury 28 февраля 2018 в 16:56 0
no avatar
не совсем понял какие именно неиспользуемые картинки удаляет? как определяется неиспользуемая картинка и как она попала на сайт?
vikont 28 февраля 2018 в 18:40 0
small user social cms
1. Был раньше отмечен пресет, потом от него отказались, но ранее загруженные картинки уже растирожировались по пресетам и теперь картинки стали ник чему не привязаны.
2. Загружали картинку, что то пошло не так, в тексте не появилась и грузите заново, а предыдущая осталась, да еще расрирожированная по пресетам
3. Была одна картинка, потом решили заменить, а старая не удаляется!
4. Разные хвосты от дополнений и от удаленного контента.
У меня за 2,5 года накопилось 20000 мусорных картинок! Ориентировочный вес около 1 гб...
И это при условии, что большая часть картинок были оптимизированы!
@WS38 28 февраля 2018 в 19:09 +2
no avatar
Спасибо за Ваш труд! Подчистили сегодня сайт. Почти гиг хлама.
ermakover 28 февраля 2018 в 22:03 0
small user social cms
Супер! Спасибо за такой классный компонент. В сжатой папке 1,5 Гб картинок хлама очистил.
Kreator 1 марта 2018 в 01:41 0
small user social cms
А, я кажется понял. чтобы НЛО блоги не удаляли, надо не соблюдать правила сообщества (п.3.6) и выкладывать дополнения в каталог а наоборот.
А я то думаю чо ни так ... почему удаляют ... а тут вон оно чо
Ris 1 марта 2018 в 07:46 +3
small user social cms
Вы уфолог? smile
Протестируют люди дополнение, выскажут свое мнение, выявят все нюансы - устраню недостатки и выложу дополнение в каталог.
Андрей 1 марта 2018 в 10:07 -1
small user social cms
Протестировал на поддомене, отличная работа, отличный компонент. Папка upload уменьшилась существенно. Единственное не понял, почему компонент удалил папку /upload/icons у меня в ней хранятся иконки-фавиконы для различных устройств (не критично, можно вернуть) и еще компонент удалил картинки из компонента lottery - хотя эти пресеты используются lotto_poster, bg_lott. А так всё отлично, компонент отрабатывает норм.
Ris 1 марта 2018 в 11:26 +1
small user social cms
не понял, почему компонент удалил папку /upload/icons
Значит эти иконки нигде в базе данных не упомянуты.
компонент удалил картинки из компонента lottery - хотя эти пресеты используются lotto_poster, bg_lott
Посмотрите в базе, как называется поле этого компонента, где упоминаются картинки и добавьте в список полей в опциях.
@IamB 1 марта 2018 в 12:57 +2
small user social cms
Значит эти иконки нигде в базе данных не упомянуты.
Напрашивается ещё одно поле в Опциях - Исключить из работы папки
ermakover 1 марта 2018 в 10:09 0
small user social cms
Ну раз можно писать и о том, что не сработало - напишу.
При переносе файлов сайт ушёл в ошибку 503 и висел долго-долго, и с главной страницы было не зайти - тоже 503, пока я через SSH доступ не снял задачу переноса файлов.
Но в защиту программы скажу, что и удалённых файлов получилось в уже упакованном архиве 1,5 Гб, понятно, что сложно на виртуальном хостинге такую громаду ворочать.
Но после того как снял ошибку, увидел, что задача выполнена.
При архивации у меня тоже уходит в 503, но при этом задача архивации выполняется.
Автор очень мне помог, потому что я смог уменьшить размер пространства у хостера и платить меньше на 4 рубля в день! v
Ris 1 марта 2018 в 11:28 0
small user social cms
При переносе файлов сайт ушёл в ошибку 503 и висел долго-долго, и с главной страницы было не зайти - тоже 503
Так оно всю базу перебирало. Если база большая - времени требуется много. При архивации тоже.
Можно было не убивать задачу, а просто подождать.
ermakover 1 марта 2018 в 10:33 0
small user social cms
Из папки Инстайлера в upload удаляет все пресеты фонов. Я ими не пользуюсь, но остались пустые ячейки. Пришлось вернуть.
ermakover 1 марта 2018 в 10:34 0
small user social cms
Да, и все файлы, которые загружались в Инстайлере тоже пропали. Но это дело восстановимое.
Андрей 1 марта 2018 в 10:46 -1
small user social cms
Да background-image или cover почему-то удаляет, хотя они используются
ermakover 1 марта 2018 в 10:55 0
small user social cms
Да, пипец я попал - стал смотреть - у меня большей частью изображений нет, в папке Delited в архиве половины изображений нет, а из upload они удалились. Делаю срочный откат сайтов.
Rainbow 1 марта 2018 в 11:28 0
small user social cms
Делаю срочный откат сайтов

Бекапы при таких операциях просто необходимая вещь.
Ris 1 марта 2018 в 11:45 0
small user social cms
Все правильно.
Вы операцию сканирования базы прервали. Соответственно оно не проверило все поля и не занесло картинки в список используемых.
Соответственно сочло неиспользуемыми и перенесло.
Delited в архиве половины изображений нет, а из upload они удалились
Там еще осталась неархиврированная папка делетед. В ней все есть.
Как вернуть - написано в теме поста.
Все файлы при должном умении можно вернуть назад. Просто перенести или скопировать /deleted/upload/ в /upload/
ermakover 1 марта 2018 в 20:33 0
small user social cms
Нет, я Вас ни в коем случае не обвиняю, всё вернул назад, просто мне, как пользователю, надо к процессу подходить более вдумчиво. А то я не разобравшись - ну всё чистить laugh
Ris 1 марта 2018 в 20:36 0
small user social cms
Я ничего не говорю.
Просто прежде чем паниковать, сначала можно было почитать, прикинуть...
Это, кстати, всех аварийных случаев в жизни касается.
Ris 1 марта 2018 в 11:41 0
small user social cms
Ищите поля в которых упоминаются эти картинки и добавляйте в опции.
Чудес в этом компоненте нет никаких. Собственным интеллектом он не обладает. Ищет текст типа "abc123dfg.jpg" в полях, которые ему указали.
Андрей 1 марта 2018 в 14:54 -1
small user social cms
а после проверки с оставшимися файлами json (4 штуки) в папке upload, что делать?
Ris 1 марта 2018 в 15:07 +1
small user social cms
Удалить.
Rainbow 1 марта 2018 в 17:40 0
small user social cms
У кого на изображениях стоял ватермарк, тоже обновляйте - сносит.
Ris 1 марта 2018 в 18:12 0
small user social cms
Просто вернуть ватермарк.
Pocus 1 марта 2018 в 18:15 0
small user social cms
Точно? По идее не должен. Ватермарк же накладывается при создании картинки, т.е. в итоге это просто картинка.
Pocus 1 марта 2018 в 18:18 0
small user social cms
А, дошло. Удаляется сам ватермак, а не картинки с ним. Ступил.
@WS38 1 марта 2018 в 18:25 0
no avatar
У нас удалились все обложки с групп. А так всё на месте. Может в дальнейшем и выявим. Обложки загрузили, всё ОК. Завтра попробуем ещё один сайт очистить.
Андрей 1 марта 2018 в 18:39 -1
small user social cms
Я сейчас проверял по таблицам, чтобы картинку обложки не сносило в компоненте Группы cms_groups - поле cover нужно добавить, а у компонента Лотерея cms_lottery_lottos - поля bg_lott и poster.
И в типы файлов я добавил расширение для картинок svg.
Pocus 1 марта 2018 в 18:59 +1
small user social cms
Владельцам ivideo добавить background_img, tumb_path, cover
Для комментариев добавить content_html
Для обложек групп - cover
Для вложений нью-мессенжера - info
.......
Ris 1 марта 2018 в 19:39 0
small user social cms
Для комментариев добавить content_html
Не стоит. Мускул гарантированно захлебывается.
Для обложек групп - cover
Там уже отмечено cover_image.
Андрей 1 марта 2018 в 21:25 -1
small user social cms
у альбомов cover_image, а у групп cover
Андрей 3 марта 2018 в 00:32 -1
small user social cms
У кого форум от Kreator стоит добавьте от таблицы cms_forum поле icon
Pocus 1 марта 2018 в 18:33 0
small user social cms
Ris, а что, если сканировать всю базу, все поля без разбора?
А чтобы при этом сайт не завис наглухо, после каждой таблицы делать перерывчик на перекур?
А то сейчас пытаюсь найти и составить список полей с картинками, утомительное это дело. И наверняка что-нибудь все-равно упущу.
И потом этот список надо будет постоянно обновлять при установке или удалении компонентов и полей в типах контента.

Или хотя бы в форме, поле с полями (простите за тавтологию) сделать текстовым а не строковым. Список будет удобнее делать.
Pocus 1 марта 2018 в 18:40 0
small user social cms
Или, как вариант, в список включать анти-поля, которые точно не надо обрабатывать. Типа id, title, slug, seo_keys, tags, date_pub и т.д.
А остальные сканировать на предмет картинок?
Rainbow 1 марта 2018 в 19:40 +2
small user social cms
Здесь главное не переборщить с настройками. Если усложнить сильно будет еще хуже.
Может быть просто надо приноровится, смотреть вначале на тестовом, что именно снесет на конкретном сайте,

все это куда то записывать, что бы не забыть.
Не каждый же день чистить...
Ris 1 марта 2018 в 19:43 0
small user social cms
А чтобы при этом сайт не завис наглухо, после каждой таблицы делать перерывчик на перекур?
Вот как бы его делать?
Я пробовал. Ели количество строк в таблице > 10000 - выплевывать в аякс лимит, а промежуточный результат сохранять в джейсон, а потом мержить с остальными. Что-то такая навороченная катавасия получилась, что отказался от этой затеи...
Rainbow 1 марта 2018 в 19:59 0
small user social cms
И все таки может быть рассмотреть мой вариант в первом комменте?
Каждый тип контента создает свою папку, а в ней уже подпапки.

Если задавать сканировать только определенные подпапки, это позволит выбирать тип контента,
За один проход - один, за второй - другой и т.д.

Уже будет как то разделено. Не знаю как там в коде усложнит, но в настройках не сильно.
А у кого сайты не большие, можно и все сразу...
Ris 1 марта 2018 в 20:05 0
small user social cms
Каждый тип контента создает свою папку, а в ней уже подпапки.
На самой большой таблице захлебнется.
Тут единственный вариант, если в сканируемой таблице много строк - делать цикл на яваскрипте.
Но так как в яваскрипте я некопенгаген, то требуется помощь компетентных людей, а её нету.
@IamB 2 марта 2018 в 12:42 0
small user social cms
Можно попробовать реализовать останов и перезапуск утилиты, перед остановом - сохранение состояния .
Для этого можно создать класс-контейнер в котором будут только данные, это те переменные, массивы, что вы используете
при работе утилиты.
Выполнили определённый объём, объект класса-контейнера(дамп состояния) сохранили в файл. Далее header('Location: утилита');
В утилите первым делом восстанавливаете из файла объект класса-контейнера и продолжаете с нужной точки.
Код ваш не смотрел, так что это только теория.
@IamB 2 марта 2018 в 17:16 0
small user social cms
Код PHP:
  1. <?php
  2. class Box
  3. {
  4. public $a = true;
  5. public $b = 1;
  6. public $c = ['z','x','c'];
  7. }
  8.  
  9. $b0 = new Box();
  10. $b0->a = false;
  11. $b0->b = -20;
  12. $b0->c = ['q','w','e','xx'];
  13.  
  14. $box = serialize($b0);
  15.  
  16. $b1 = new Box();
  17. $b1 = unserialize($box);
  18. var_dump($b1);
Ris 2 марта 2018 в 19:24 +1
small user social cms
Практика показала, что остановить скрипт php и запустить заново, чтобы очистилась память, не получается. Пока все до конца не отработает - все переменные и массивы висят в оперативке.
Единственный выход - цикл на яваскрипте.
А уж как сохранять результаты итераций этого цикла - дело десятое.
@IamB 2 марта 2018 в 19:54 0
small user social cms
Отлично, что попытались!
@IamB 10 марта 2018 в 09:19 0
small user social cms
Увидел в документации такую конструкцию
Код PHP:
  1. header("Location: http://www.example.com/"); /* Перенаправление браузера */
  2. /* Убедиться, что код ниже не выполнится после перенаправления .*/
Вы exit() в своём опыте импользовали?
Ris 10 марта 2018 в 11:54 0
small user social cms
@IamB
На самом деле я не очень понял, как этот код применить.
Вот в этом дополнении есть в файле \system\controllers\unfinder\backend.php есть функция getLinks()
Там есть такой код:
Код PHP:
  1. $this->model->db->getRows($co['TABLE_NAME'], "{$co['COLUMN_NAME']} REGEXP '".$ex."'" , $co['COLUMN_NAME']);
Так вот если в таблице много строк - на выборку из нее не хватает памяти.
Я уже сделал цикл на яваскрипте для выборки из больших таблиц. И поиск ссылок на картинки во всех таблицах и полях базы сделал.
Сейчас допиливаю...
@IamB 10 марта 2018 в 12:23 0
small user social cms
Собственно, я и предлагал с помощью header('Locaition: ...') сделать некое подобие того цикла (перезапуск скрипта с новыми данными), что вы сейчас реализуете на JS. Вы попробовали и написали, что перезапустить можно, но не срабатывает "сборщик мусора" - всё висит в памяти.
Я смотрел документацию и подумал, что, exit() как раз и может запустить процесс очистки памяти перед очередной итерацией.
Если у вас получается с JS, то, извините, зря отвлёк.
vikont 2 марта 2018 в 11:30 0
small user social cms
Уже будет как то разделено
более 90% всех картинок в таблице news никакое разделение не поможет!
Ris 2 марта 2018 в 11:34 0
small user social cms
Это у Вас.
А у меня в постах и комментариях.
Олег Васильевич я 2 марта 2018 в 11:44 0
small user social cms
Ris, я не тестировал, поэтому заранее извините, если в этом плане всё нормально.
Суть в следующем: некоторые картинки, находящиеся в папке upload прописаны только в конфиге шаблона. Судя по вопросу, который получил недавно в личке, они тоже удаляются.
Ris 2 марта 2018 в 11:45 0
small user social cms
Я тоже хотел у Вас спросить? А где например в шаблоне tseso хранится путь к логотипу?
Олег Васильевич я 2 марта 2018 в 12:22 0
small user social cms
Картинка прописана в стилях (как фон).
Если не грузилась из админки (в настройках темы), - то в стилевом файле назначанного скина, а если грузилась, то - в options.css.php (последний подхватывает из system\config\theme_tseso.yml)
Олег Васильевич я 2 марта 2018 в 11:47 0
small user social cms
А за дополнение, спасибо! Для тех, кто запустил сайты на ранних версиях двойки очень полезное.
Ris 2 марта 2018 в 11:53 0
small user social cms
Или для тех, кто мигрировал с первой ветки.
vikont 7 марта 2018 в 21:17 0
small user social cms
Компонент замечательный, НО, я опять буду настаивать на том, что надо не вписывать поля, а сканировать таблицы на предмет поиска полей содержащих картинки!!!
Всегда что то забудешь, а порой и не знаешь что такое поле есть!
У меня в компоненте Ротатор баннеров, нашлись картинки в поле file - не знал!
А так же сам наплодил поля photos2 - photos4
Что еще не учел трудно сказать, все как бы нормально, но вдруг натыкаешься на отсутствие фотографий....
Учитывая большую массу файлов, все это время...
Ris 7 марта 2018 в 23:03 0
small user social cms
У меня в базе 148 таблиц в которых 1455 полей.
При попытке сканирования память заполняется мгновенно.
Kreator 8 марта 2018 в 00:11 0
small user social cms
Значит надо по-немногу, не быстро, пусть подольше но качественно)
Ris 8 марта 2018 в 00:24 0
small user social cms
Цикл на яваскрипте и аякс-запрос.
Сможете сделать пример, как выплюнуть данные в браузер, сменить лимит офсет и с новым лимитом запустить скрипт в бэкэнде?
Kreator 8 марта 2018 в 01:45 0
small user social cms
Это важный момент, так как данная вещь очень важна на более больших проектах и не очень актуальна на малельких.
Есть база данных с несколькими миллионами записей.
Даже пробовать не буду там запускать)
А по сути вещь очень нужная.
@IamB 8 марта 2018 в 13:16 0
small user social cms
Сначала для @Ris цикл на JavaScript напишите, а уж потом настаивайте.
Ris 8 марта 2018 в 13:25 0
small user social cms
Цикл я знаю как выглядит. Я не знаю, как из шаблона (или из яваскрипта ) вызвать функцию в бэкенде.
Если никто не подскажет - придется делать фронтенд и экшенз. Там я знаю как функцию вызвать.
eoleg 8 марта 2018 в 21:18 0
small user social cms
Мнение электронщика:
1. триггер в мускуле сканирует в полях всех таблиц базы (имена нужных полей можно добавлять через запятую в опциях) все ссылки на файлы изображений и записывает результат в таблицу links
2. Сканирует файлы в папке upload и записывает результаты в таблицу upload в базе
3. триггер в мускуле сравнивает таблицу links и таблицу upload и заносит результат в таблицу compare
4. дальше переносит, пакует, удаляет или что там ещё делает.
Ну конечно при условии того что триггеры в мускуле нормально реализованы.
eoleg 8 марта 2018 в 21:22 0
small user social cms
Ну это я к тому - как снизить системные требования у этого скрипта.
Ris 8 марта 2018 в 21:53 0
small user social cms
Олег, я тоже электронщик.
Все равно, где хранить результаты сканирования, в базе, в переменной, в файле. Затык происходит на стадии выборки из таблицы с большим количеством строк.
$this->model->db->getRows($co['TABLE_NAME'], "{$co['COLUMN_NAME']} REGEXP 'jpg|gif|png'));
Тут нужно, если в таблице больше, к примеру, 10000 строк - отправлять выборку в цикл с limit $x * 10000, 10000. Соответственно $x при каждой итерации меняется.
Старый балбес 9 марта 2018 в 07:02 0
small user social cms
Код PHP:
  1.  
  2. $x = 100;
  3. cmsUser::sessionSet('limit',$x);
  4. while ($x<1000){
  5. $limit = cmsUser::sessionGet('limit', true);
  6. $x = $x + 100;
  7. echo $x;
  8. cmsUser::sessionSet('limit', $x);
  9. }
  10.  
Ris 9 марта 2018 в 11:53 0
small user social cms
Тут задача стоит такая:
Все поля таблиц базы, сканируются на предмет строк с наличием текста типа .jpg, .gif, .png и т.д. и подсчитывается количество строк с наличием такого текста.
Все таблицы и поля, в которых меньше 15000 строк с картинками заносятся в файл columns.json, а те, в которых больше - в файл big_columns.json.
Это уже реализовано.
Теперь нужно после сканирования таблиц, которые в columns.json, запустить цикл именно на яваскрипте (чтобы память между итерациями очищалась) и просканировать таблицы и поля, которые в big_columns.json, причем по частям с переключением лимита на выборку, чтобы память не переполнялась.
И вот ни как запустить яваскрипт из php, ни как обратиться к функции php из яваскрипта, я не очень представляю...
Alex 30 марта 2018 в 01:29 0
small user social cms
Надо добавить возможность указывать папки исключения, в которых удалять ничего не нужно.
Pocus 3 апреля 2018 в 12:05 0
small user social cms
Ris, скажите, а вы продолжаете работы над компонентом?
Ris 3 апреля 2018 в 12:19 +2
small user social cms
Да. Есть почти готовый новый поискиватель. Сам находит поля с картинками, сканирует большие таблицы с циклом на яваскрипте и аяксе.
Но просто трындец, как долго... laugh
Alex 3 апреля 2018 в 16:43 0
small user social cms
Уж поскорей бы показали поискиватель, картинки сироты плачут
Alex 11 мая 2018 в 21:18 +1
small user social cms
Почти всё хорошо, единственное что он не очень хорошо определяет папки из которых нужно чистить картинки, и удаляет нужные, потому что заодно чистит папки от сторонних компонентов.
Я позволил себе немного изменить файл,
.\system\controllers\unfinder\backend.php
теперь корректно определяет директории для чистки

стр.127 было :
Код PHP:
  1.  
  2. if ( !strpos($name, 'default') && !strpos($name, 'installer') && !strpos($name, 'files')) {
  3. if (preg_match_all('/[a-z0-9-_]+\.('.$ex.')/', $name, $matches)){
  4. $filelist[] = $matches[0][0];
  5. }
  6. }
после изменения стало так :
Код PHP:
  1.  
  2. //if ( !strpos($name, 'default') && !strpos($name, 'installer') && !strpos($name, 'files')) {
  3. if (preg_match_all('/[0-9-_]+\/()/', $name)) // маска папки с именем цифрами: /012/
  4. if (preg_match_all('/[a-z0-9-_]+\.('.$ex.')/', $name, $matches)){
  5. $filelist[] = $matches[0][0];
  6. }
  7. //}
теперь папки: default, installer, files и т.д. отдельно прописывать не нужно
Xamle 26 мая 2018 в 15:54 0
small user social cms
Где скачать можно?! по ссылки выходит "Файл не найден"
Ris 26 мая 2018 в 16:28 +1
small user social cms
Четыре раза выкладывал - удаляют.
Попробуйте здесь скачать:
https://yadi.sk/d/w4TP5a5a3WZNKE