Пользователь
0,0
рейтинг
6 августа 2013 в 09:32

Разработка → 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 и дополнительной копией на случай апокалипсиса :)…
sergeyfast @sergeyfast
карма
35,5
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (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
        5.3+ как выяснилось…
  • 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 идентифицирует фотографию, по пути или по хэшу файла?
    Если фотку взять и переместить в другую папку например, в веб форме она останиться и на том же месте/альбоме?

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