EazyPhoto: уютный фотохостинг для своего сервера

    В недалекие времена, когда flickr ещё не предлагал терабайт под хранение фотографий, а BitTorrent Sync только вышел на экраны интернета в своей небезопасной альфа-версии, была у меня потребность: делиться фотографиями с друзьями и не только. Но как обычно у программистов это бывает, под словом «делиться» стоит гораздо больше, чем выложить фоточки во ВКонтактик. А именно:
    • Выложить куда-нибудь фотографии на свой сервер с красивым и простым web-интерфейсом.
    • Просто и массово заливать и скачивать оригиналы изображений.
    • Иметь возможность разграничить доступ к определенным альбомам.
    • Попытаться связать это с локальным сетевым хранилищем, чтобы не дублировать фотографии.
    • По возможности удалять оригиналы фотографий с сервера через какое-то время и оставлять только фотографии с измененным размером.
    • По-максимуму бесплатно! :)

    После таких мыслей в голове начинает зарождаться идея: «Надо накреативить...» — и ты уже не можешь остановиться.

    Что сейчас предлагают фотохостинги?


    Гугл нашел очень много облачных сервисов для выкладывания фотографий, предназначенных в основном для фотографов (и не только). Суть всех сервисов сводится к тому, что начиная с определенного объема надо платить фиксированную сумму в месяц. Если за полгода сумма не выглядит большой, то спустя два года она будет неприятным напоминанием. Аналогию можно провести с оплатой ru-доменов по 600 рублей в год в nic.ru и с постоянным напоминанием себе, что надо бы перевести уже эти домены к другим регистраторам :).

    С другой стороны, если у вас уже есть какой-нибудь сервер, то надо использовать его по максимуму. Я нашел два проекта, которые в принципе бы смогли подойти под мои задачи. Это Piwigo (бывший phpWebGallery) и Koken. Последний проект вообще очень сильно порадовал. Но познакомившись с ними поближе, понял, что это мне тоже не подходит.

    Dropbox, Skydrive, Google+ (Picasa), Яндекс.Фотки — вот эти ребята отлично выполняли свои функции до тех пор, пока места хватало.

    Поделиться с друзьями


    Хочу подробнее рассказать о том, что значит для меня термин «поделиться». После какого-то события (будь то поездка на природу или прогулки по городу), в котором принимают участие несколько человек, появляется много фоток. После обработки фотки (300-700 МБ) отправляются на местный NAS (Synology DS210j). И вот эту папку с NAS надо бы выложить в Интернет, чтобы её скачали те самые друзья, которые есть на фотках.
    Загружать/скачивать через браузер такой объем — не для меня.

    Но в конечном итоге хочется иметь ссылку на альбом, которую можно скинуть ещё кому-нибудь. Ну и список альбомов тоже неплохо было бы получить. Простой обычный процесс.

    Самое главное, должны быть оригиналы фотографий и нормальный ресайз без фильтров (не то, что сейчас предлагают VK и остальные). Потом, когда у каждого будет 4К телевизор (как сейчас FullHD), будет очень здорово полистать свой фотоархив и ещё раз порадоваться.

    BitTorrent Sync


    После того, как я прочитал новости о выходе первой версии BTSyncа под все платформы — я все осознал. В моей голове четко выстроился алгоритм работы:
    1. Первоначальная заливка фотографий происходит через BitTorrent Sync.
    2. Пользователь неважно где расшаривает папку и получает readonly secret key, при этом он может сделать это на NAS или у себя локально.
    3. Далее пользователь идет в веб-интерфейс управления и добавляет альбом через readonly secret key.
    4. Веб-интерфейс посылает команду BTSync скачать вот эту папку на сервере. Постепенно начинается скачивание на сервер.
    5. В это время в кроне или ещё где идет проверка, скачалось ли все или нет (а-ля индексация файлов). Все файлы, например, добавляются в БД, и к ним создается уменьшенная копия (т.е. вся мета-информация попадает из оригинальных файлов в базу данных).
    6. Через какое-то время мы удаляем оригиналы с сервера (но! они сохраняются у пользователей, которые успели скачать).


    У BTSync под Linux консольного API до сих пор нет. Но есть веб-интерфейс, который может выступать в качестве API-сервера. Вооружившись Go, я написал консольную утилиту для работы с BTSync. Ну а потом сделал класс для PHP. А дальше дело за малым: написать все остальное ;)

    EazyPhoto


    По основной своей специальности я php-программист. Верстка — это самое страшное для меня, что может быть:). Поэтому, взяв Foundation, я попытался что-нибудь на нем изобразить.

    На главной странице мы видим список альбомов с названиями и датами. А на странице альбома — квадратные фотки с предпросмотром, как в дропбоксе. Если добавить к каждой фотке описание и задать её порядковый номер, то получится что-то типа блога. Размер больших фотографий для web-интерфейса я выбрал прямо как маркетолог — FullHD :)

    Управление альбомами и фотографиями происходит внутри административной панели. Вот таким вражеским образом выглядит добавление нового альбома: достаточно заполнить название, дату начала и ReadOnly Secret.

    На чем это все написано?
    Проект написан на внутреннем движке Eaze. Он далек от совершенства, но позволяет быстро решать определенные задачи в известный короткий промежуток времени. У него нет нормальной документации, но он же написан на PHP, поэтому чтобы что-то понять, достаточно заглянуть внутрь (прямо как в идеологии go-lang :).

    База данных: выбрал mysql, потому что оно у всех есть. В основном тут интересны эти две таблички: albums и photos



    Индексация файлов


    Сначала я написал индексатор на PHP: он пробегал по новым альбомам, добавлял их в очередь на загрузку в BTSync, и потом пробегал по существующим и добавлял новые найденные файлы. Достаточно повесить скрипт в cron раз в 5 минут: и этого бы хватило. Но не мне.
    Было бы круто, если бы фотки добавлялись в базу по мере их скачивания. И тут на помощь приходит Go.

    eazyphotod


    Небольшой демон, который висит и проверяет директории на наличие новых файлов. Создает превью для фотографий и сохраняет в базу. Общается с BTSync'ом. Вот его основные задачи.
    Для реализации данных задач я воспользовался следующими пакетами:
    Проверив в демо-проекте все необходимые функции, я начал собирать это все в рабочую версию. Потребовалось примерно два дня, чтобы получить готовый результат.
    Как это работает?
    eazyphotod запускается через upstart (в дальнейшем планирую переделать под supervisord). После запуска он загружает все альбомы в память и начинает сканирование директорий на наличие новых фотографий. Параллельно с этим запускается гоурутина на остлеживание изменений в файловой системе и на обработку HTTP запросов (обновить мета-информацию альбома и добавить новый альбом в очередь на скачку).
    Все запросы (resize, обновление мета-информации, событие о новом файле) ставятся в одну очередь:
    var  SyncQueue  = make(chan *SyncItem) 
    type SyncItem struct {
    	Album    *model.Album
    	FsPhotos model.PhotoList
    	FullSync bool
    	Filename string
    }
    

    Поэтому нет необходимости отслеживать одновременный доступ к map'ам и другим важным переменным. Все идет в одной общей очереди.
    Работа с базой данных тоже получилась довольно простой.
    Вообще, если вы думали писать на go, но все не решались — мой вам совет: возьмите и напишите уже что-нибудь на нем :)

    И ещё одно: мои go-проекты на github по идеологии размещены неправильно, т.к. в репозитории должна быть корневой только одна папка src. А у меня — целиком проект. Мне как-то не комфортно, когда рядом с исходным кодом в одной папке лежат примеры конфигов, README.md и прочие вспомогательные материалы.


    Итог


    Со своими задачами сервис вполне справляется: хранилище все время в сети, на нем установлен BTSync. После того, как фотографии отправлены на хранилище, папка добавлена в BTSync и веб-интерфейсе создан альбом — можно лечь спать. Сервер с eazyphoto сам скачает фотографии и добавит их в текущий альбом. Утром можно зайти, проверить, и отправить ссылку друзьям. А друзья уже при необходимости скачают оригиналы к себе через BitTorrent Sync.

    Попробуй собери


    Для тех, кто решил попробовать поднять это все у себя — вот ссылки:
    1. github.com/sergeyfast/eazyphoto-web — php-часть
    2. github.com/sergeyfast/eazyphotod — сам демон

    Для тех, кто хочет потыкать и посмотреть пример
    Ссылку на демо сознательно не публикую. Но Яндекс поможет найти по словам на черной плашке.

    Все инструкции (или их подобие) находятся внутри проектов (open source такой open source :).

    Установка вспомогательного софта на примере Ubuntu
    1. Установим btsync:
    sudo add-apt-repository ppa:tuxpoldo/btsync
    sudo apt-get update
    sudo apt-get install btsync
    

    Порт с данными = 0. Порт для веб-интерфейса: 8888. IP: 127.0.0.1

    2. Установим go
    Рекомендую через godeb blog.labix.org/2013/06/15/in-flight-deb-packages-of-go
    Минимальная версия go: 1.1

    3. Установим eazyphotod
    git clone git://github.com/sergeyfast/eazyphotod.git
    cd eazyphotod
    export GOPATH=`pwd`
    go get code.google.com/p/gcfg github.com/disintegration/imaging github.com/go-sql-driver/mysql github.com/howeyc/fsnotify github.com/rwcarlsen/goexif/exif github.com/sergeyfast/btsync-cli/src/btsync
    go build -o eazyphotod src/*.go
    

    После этого у нас появился бинарник.
    Рекомендую создать /usr/local/eazyphotod/ (user www-data), туда скопировать eazyphotod + config.gcfg
    Закинуть eazyphotod.conf в /etc/init/ и запустить (предварительно настроив config.gcfg):
    service eazyphotod start

    (deb-way: засунть конфиг в /etc/eazyphotod.conf, бинарник в /usr/bin/eazyphotod, и указать ссылку на конфиг через -config параметр).


    Дальнейшее развитие


    Хотелось бы не пугать потенциальных пользователей админкой, а сделать им нормальный веб-интерфейс для управления и простой скрипт/пакет для установки. Но все это актуально только с eazyphotod, потому что cron и php-процесс для гиков — явно не выход ;)

    Если у кого-нибудь есть мысли по функциональности или тому, как должно это все выглядеть (или вдруг кто-нибудь хочет помочь ;) — велком.

    Напоследок: лирическое отступление. Фотографируйте, делитесь с друзьями и родителями. Жизнь быстро проходит, а фотоархив остаётся (желательно в RAID1 и дополнительной копией на случай апокалипсиса :)…
    Поделиться публикацией
    Похожие публикации
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 43
    • 0
      Круть, а пример того что получилось в настоящем интернете, а не на скриншотах.
      • +2
        tl; dr. Ссылку на демо сознательно не публикую. Но Яндекс поможет найти по словам на черной плашке.
        • 0
          Расшифрую минусующих (я не один из них): Нет смысла так шифроваться, если это НЕ коммерческий проект и вы не капитализируете переходы.
          • +3
            Шифроваться смысл есть если ТС не уверен что его NAS или то, на чем крутится проект, выдержит хабраэффект же.
            • 0
              Согласен, об этом я как-то не подумал ))
      • +1
        Всё круто.

        Чего не хватает — возможности скачивать целые фотоальбомы домохозяйкам :) Чтобы не устанавливать им BTSync.
        Hint: можно сделать упаковку альбома в zip и отдачу его домохозяйке.
        • 0
          Круто, попробую поставить себе как только гитхаб оживет. Не увидел system requirements, минимальную версию php. На NAS все же часто далеко не акутальные Debian с php 5.2.
          • 0
            На php 5.2, насколько я помню, должно работать. Стабильно работает на 5.3. Из экзотического — php_exif и gd (нужны только для php-индексатора). А гитхаб опечалил, да ;(
        • 0
          С юзабилити нужно что то делать. Создание альбома 14 полей, о значении половины полей можно только догадываться, например, дата начала (начала чего? может проще сразу брать время создания), еще более шокирующие поля — путь до папки и readonly secret. Я так понимаю это что то от программиста для программистов )
          • 0
            Радует то, что нужно вбить только название, дату начала и RO Secret (путь до папки и системное имя генерируются автоматически). Ко всем полям можно добавить слово «альбома» и получить ответ, для чего они. Дата начала альбома (т.е. дата начала первой фотки). Дата начала завязана на физический путь до папки с фотками.
            И да, это от программистов для друзей программистов :))
          • 0
            А ссылку для тех, кто хочет потыкать и посмотреть пример? Или ссылку на черную плашку?
            • 0
              В Я без проблем находится: Aurinka's EazyPhoto
            • 0
              Не понял зачем столько гемороя когда есть synology и родной софт фотогалереи который на 100% подходит для описанных задач
              • 0
                Причин несколько:
                — он очень дооолго индексирует фотки.
                — открывать его в интернет — не самый лучший выбор для «домашней безопасности».
                — не у всех безлимитный интернет ;) У меня, например, есть только мегафон 4г, в котором 40 гигабайт в месяц (с 8 до 0). Думаю это комментировать не нужно)
                — для тех, у кого нет synology, но тоже хотят себе такие же фотогалереи — постоят в сторонке.
                • 0
                  1) ну а есть какая-то спешка? вроде новая версия шустрая.
                  2) открыть надо только нужный порт. у меня вообще в DMZ стоит уже не один год и все отлично. штатная система защиты работает на ура
                  3) так это тоже плюс к синолоджи. не надо ничего заливать в интернет
              • 0
                Koken какой-то слишком уж мудрёный, а вот EazyPhoto — для дома самое то.
                • 0
                  Как там нам говорили на лекциях по маркетингу — «нужно создать потребность, а потом удовлетворить её».
                  Вот вы потребность создали, однозначно)) Вечером полезу в код разбираться. На сам ваш сайт решил пока не лазать, 40 гиг в месяц это очень мало.
                  • 0
                    Сайт на хостинге, так что там все ок) Это было к вопросу о том, почему NAS не надо выкладывать в интернет)
                  • 0
                    Если кому-то интересна тема самостоятельного хостинга фотографий, то можете также обратить внимание на проект Trovebox (aka Openphoto). Из плюсов есть мобильные приложения (iOS & Android) которые работают в том числе и для инсталляций на собственном хостинге.
                    Пример галереи: current.trovebox.com/photos/list
                    Исходники и инструкции по установке: github.com/photo/frontend
                    • 0
                      Достойная альтернатива, да. Но насколько я понял, она работает только с облачными хранилищами?
                      И опять такие же вопросы к загрузке фотографий и их массовом скачивании.
                      • 0
                        Можно использовать как облачное так и локальное хранилище. Загрузка оригиналов возможна (только по одному, на сколько я знаю). Также можно расшарить приватный альбом (ссылка с ключом). Массовое скачивание, к сожалению, вроде как, не доступно. Думаю, при должном уровне мастерства добавить последнее вполне реально.
                      • 0
                        Не очень понятно с приватностью. Там есть возможности поделиться только с определенными людьми, только по скрытой ссылке?
                        • 0
                          Да, есть такая возможность. Генерируется токен доступа для фотографии или альбома, который в последствии можно аннулировать. Таким образом можно делиться даже приватными фотографиями.
                      • 0
                        В целом очень интересно, попробую у себя его поднять на NAS-e. Как на счет что-то по стилю 500px? Модальные окна при выборе фотографии, информация про фотографию, локация.
                        • 0
                          Сделал бы кто-нибудь такой дизайн и верстку — было бы здорово (натянуть верстку на проект не проблема :)
                          А смысл поднимать на NAS? Скорее всего фотографии уже на NAS — тогда получатся дубликаты.
                          А вот если фотографии на компьютере — то тогда это имеет смысл.
                          • +1
                            А разве нельзя его натравить на папку в которой уже есть фото, отключит btsync и кроном запускать индексацию?
                            • 0
                              Так можно, но для этого нужно положить все в правильные пути. Пример: допустим, в базе создаем альбом с датой начала 2013-05-01, путем до папки не рандомным, а скажем 20130501-test и Статус — опубликован. Тогда фотки надо положить в web/shared/files/albums/2013/20130501-test/source/. Или второй вариант — вместо «положить» — сделать линк с хранилища на папку source.
                              • +1
                                Имхо скрипт индксатор сам должен сканировать папку и при наличии в ней подпапок воспринимать их как альбомы и заносить их в бд с какими-то дефолтными параметрами.
                                • 0
                                  Вообще не факт, потому что структура хранения фоток у все разная. Кто-то вообще делает год-месяц-день — т.е. три уровня. Так что это все пишется вручную.
                                  • 0
                                    Можно же по маске %Y%-%M%-%D% ;)
                            • 0
                              Согласен)

                              У меня фотки на компе. И если еще в семье на разных компах то можно будет всем лить на NAS в background-e.
                              • 0
                                Вёрстку я могу, дизайн я не могу )
                            • 0
                              sergeyfast, а у вас в общем сколько фотографий? Хочу очень домашний сайт с фотогалереей, но боюсь индексация фотобазы в количество 750 000 штук займет очень долгое время.
                              • 0
                                Выложенных всего 1324. Тут самое сложное — добавить альбомы в базу ;) 750к фоток для такого проекта — это не много. А для индексации можно использовать как раз eazyphotod, только надо удалить оттуда часть, отвечающую за btsync, fsnotify и вебсервер. Самая долгая операция — ресайз (тут все зависит от процессора).
                              • 0
                                Точь-в-точь такая же идея посещала, только хотелось сделать веб-галерею, крутящуюся на Zyxel Keenetic Giga с подключенного usb-hdd, которая сканировала бы новые папки и создавала превьюшки прям с подключенного hdd.
                                Для Кинетика есть nginx, php 5.3, mysql.
                                • –1
                                  Эх, это бы под WIndows, хотя бы и на php…
                                  • 0
                                    Если бы BTSync под Windows был точно таким же сервисом с веб-интерфейсом, как под Linux, то проблем бы вообще не было (ну или у него было хоть какое-нибудь API под Windows). А так, все остальное работает, даже eazyphotod :)
                                  • 0
                                    Скорость открытия первой страницы радует!
                                    • 0
                                      Почему бы кстати, вместо BTSync не использовать Dropbox, высасывая фотки оттуда?
                                      • 0
                                        Потому что в дропбоксе ограниченное место.
                                      • 0
                                        sergeyfast расскажите поподробней что не понравилось в Koken.

                                        Интересный проект, но делиться только через BTsync это через чур. Я тут 6 человекам пытался раздать так фотки, только у одного получилось.
                                        Я правильно понял что все фотографии добавляются автоматически, и убрать их из раздачи/показа нельзя?

                                        Я вот тоже пишу свою галерею. Вот обзор, если интересно bviewer.readthedocs.org/en/latest/intro/overview.html
                                        • 0
                                          Подскажите как EazyPhoto идентифицирует фотографию, по пути или по хэшу файла?
                                          Если фотку взять и переместить в другую папку например, в веб форме она останиться и на том же месте/альбоме?

                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.