Привет Читатели.
В этом посте хочу поделиться опытом организации фотогалереи на своем сайте с использованием Google Picasa как хранилища фотографий. Подобное решение для php уже было на Хабре, здесь же приводится реализация на Django. Кому интересна эта тема, добро пожаловать.
Некоторое время назад я озаботился выбором движка для организации фотогалереи на своем сайте. Требования были довольно простыми: организация фот в альбомы, показ всей галереи как миниатюр альбомов, а также фотографий в альбомах.
Для тех, кто дальше читать не хочет, сразу готовый результат.
Введение
Готовых решений галерей для Django великое множество, стоит к примеру заглянуть сюда. При этом фотографии, миниатюры, созданные кэши хранятся на нашем сервере, предлагаемый же способ использует сервера Гугла для всей черной работы, тем самым снижая нагрузки и экономя место на нашем. Сразу оговорюсь что никаких нагрузочных и других тестов не проводил, что позволяет заминусовать меня в хлам за голословные слова о повышении производительности и т.д.
Google Picasa как и многие продукты Гугла имеет свой API, подробно с которым можно ознакомиться в документации.
Что нам понадобится:
- Google Data Python Client Library python-клиент API данных Google
- prettyPhoto jQuery-движок для отображения наших фот
Описание приложения
Перейдем к описанию нашего приложения picasagallery. Основой приложения будут два представления(view), и шаблоны к ним.
Для начала определим две функции, возвращающие список альбомов и фотографий в альбоме соответственно:
from gdata.photos.service import PhotosService
def get_albums():
pws = PhotosService()
uf = pws.GetUserFeed(user=settings.PICASAGALLERY_USER)
return pws.GetFeed(uf.GetAlbumsUri() + '&thumbsize=%s' % ALBUM_THUMBSIZE).entry
def get_photos(album):
return PhotosService().GetFeed(album.GetPhotosUri() +
'&imgmax=%s&thumbsize=%s' % (PHOTO_IMGMAXSIZE, PHOTO_THUMBSIZE)).entry
Тут все очень просто(как впрочем и в дальнейшем). Наверное разве что стоит прокомментировать передаваемые в запрос параметры:
- user — имя пользователя в Picasa;
- thumbsize — размер миниатюр запрашиваемых объектов, т.е. альбомов и фотографий в данном случае. Доступные размеры миниатюр можно узнать в документации. Миниатюры могут быть обрезанными(cropped), т.е. квадратными, и необрезанными(uncropped), например '160c' или '128u'. Также можно указать несколько значений через запятую;
- imgmax — максимальный размер фотографии (спасибо кэпу), т.е. это размер изображений, возвращаемых нашей функцией get_photos().
Для удобства поместим эти параметры в settings.py:
# Picasagallery settings
PICASAGALLERY_USER = 'your_email'
PICASAGALLERY_PHOTO_THUMBSIZE = '128'
PICASAGALLERY_PHOTO_IMGMAXSIZE = '1024'
PICASAGALLERY_ALBUM_THUMBSIZE = '160c'
При помощи django shell можно поэкспериментировать с этим хозяйством:
>>> from picasagallery.utils import get_albums, get_photos
>>> my_first_album = get_albums()[0]
>>> print my_first_album.title.text # имя альбома
>>> print my_first_album.media.thumbnail[0].url # url первой миниатюры альбома
https://lh3.googleusercontent.com/-aWPQC60j9zQ/TwCXlTD6CtE/AAAAAAAAAJk/E90Hu9OPiyg/s160-c/FotoLife.jpg
>>> my_first_photo = get_photos(my_first_album)[0]
>>> print my_first_photo.media.thumbnail[0].url # url первой фоты в альбоме
https://lh3.googleusercontent.com/-3Hb7VwUTBNg/TwCXlXqdAQI/AAAAAAAAAH8/v8ecBJtjV6k/s128/261799.jpg
>>> print my_first_photo.content.src # url изображения первой фоты, размер изображения определяется переданным параметром imgmax
Список my_first_album.media.thumbnail содержит миниатюры фотографий, его размер равен количеству переданных через запятую значений в параметре thumbsize.
Миниатюра альбома — это миниатюра его главной фотографии, по умолчанию это первая загруженная в альбом фотография, но это можно изменить в настройках альбома на сайте Google Picasa. Возможность изменения главной фотографии через API не нашел, если кто знает, подскажите в комментариях.
Представления
Определим два представления для страниц галереи и альбома соответственно.
from django.shortcuts import render_to_response
from django.http import Http404
from django.template import RequestContext
from picasagallery.utils import get_albums, get_photos
def gallery(request):
albums = get_albums()
return render_to_response('picasagallery/gallery.html', locals(),
context_instance = RequestContext(request))
def album_list(request, album_id):
for album in get_albums():
if(album.gphoto_id.text == album_id):
photos = get_photos(album)
return render_to_response('picasagallery/album.html', locals(),
context_instance = RequestContext(request))
raise Http404()
Шаблоны
Шаблон для галереи:
{% extends 'base.html' %}
{% load extras %}
{% load i18n %}
{% block head %}
<link rel="stylesheet" href="{{ STATIC_URL }}picasagallery/css/base.css"
type="text/css" media="screen" charset="utf-8" />
{% endblock %}
{% block content %}
{% for album in albums %}
<div class='album'>
<div class='album-head'>
<a href="{% url picasagallery.views.album_list album.GetAlbumId %}" >
<img class="album-preview" src="{% thumbnail_url album %}">
</a>
</div>
<div class="album-name">
<a href="{% url picasagallery.views.album_list album.GetAlbumId %}">{{ album.title.text }}</a>
</div>
</div>
{% endfor %}
<p>
<a href="/media/picasa_gdata.zip">{% trans 'Download source' %}</a>
</p>
{% endblock %}
Шаблон для альбома:
{% extends 'base.html' %}
{% load extras %}
{% load i18n %}
{% block head %}
{% include 'picasagallery/pphoto.html' %}
<link rel="stylesheet" href="{{ STATIC_URL }}picasagallery/css/base.css"
type="text/css" media="screen" charset="utf-8" />
{% endblock %}
{% block content %}
<a href='{% url picasagallery.views.gallery %}' >{% trans "Back to gallery" %}</a>
<p>{% trans "Album:" %} {{ album.title.text }}</p>
<div class='gallery'>
{% for photo in photos %}
<div class='image-preview-div'>
<a class='image-preview-link' style='{% thumbnail_style photo %}'
rel='gallery-image[pp_gal]' href='{{ photo.content.src }}'>
<img class='image-preview-img' style='{% thumbnail_style photo %}'
src='{% thumbnail_url photo %}'>
</a>
</div>
{% endfor %}
<p>
<a href='{{ album.GetHtmlLink.href }}' target='_blank'>{% trans "Show in Google Picasa" %}</a>
</p>
</div>
{% endblock %}
Для получения url миниатюр альбомов и фотографий эти шаблоны используют тег thumbnail_url, возвращающий url первой миниатюры из списка. Также используется тег thumbnail_style, возвращающий строку вида 'width: 48; height: 48;' для использования в качестве аргумента для
<img ... />
Эти теги определим в файле extras.py папки templatetags:
from django.template import Library
register = Library()
def get_thumbnail(obj):
return obj.media.thumbnail[0]
@register.simple_tag
def thumbnail_url(obj):
return get_thumbnail(obj).url
@register.simple_tag
def thumbnail_style(obj):
style = 'width: %s; height: %s;'
thumbnail = get_thumbnail(obj)
return style % ('%spx' % thumbnail.width, '%spx' % thumbnail.height)
Шаблон для альбома содержит код для подключеня prettyPhoto:
{% include 'picasagallery/pphoto.html' %}
На этом моменте подробно останавливаться не буду, кому интересно, можно заглянуть в исходники.
Ну и в заключение, что из этого получилось, и тоже самое тут.
Спасибо за внимание.
Автор: pollydrag