Создаем Web-приложение, умеющее работать с Twitter
Похоже, что в наши дни Twiiter можно обнаружить где угодно. Политики,
актеры, наши родители – все пользуются ресурсами социальных сетей.
Клиенты требуют приложений, которые не только позволяют пользоваться
Twitter, но и имеют глянцевый вид в стиле Web 2.0, которого можно
добиться только с помощью Ajax. Нам в этом помогут Django и
jQuery.
FAQ: Часто задаваемые вопросы (Frequently asked questions)
HTML: Язык разметки гипертекста (Hypertext Markup Language)
HTTP: Протокол передачи гипертекста (Hypertext Transfer Protocol)
REST: Передача состояния представления (Representational State Transfer)
UI: Пользовательский интерфейс (User interface)
Прежде чем приступать к работе с этой статьей, я
настоятельно рекомендую вам проработать учебное руководство по Django.
Также вы должны иметь уверенные знания JavaScript. Разумеется, у вас
должна быть учетная запись Twitter, и вы должны знать его жаргон,
например, что такое твит. В арсенале ваших инструментов должны быть Python, Django, jQuery и библиотека pyhon-twitter. В разделе Ресурсы приведены ссылки, по которым их можно загрузить.
Также нам понадобится включенная в Python база данных sqlite3 для
хранения данных о сеансах, а о сохранении остальных данных позаботится
инфраструктура Twitter. Конечно же, в дальнейшем для улучшения
приложения можно будет интегрировать более сложную структуру базы данных
для хранения на вашем сервере статистики, копий твитов и любой другой
информации, связанной с вашей учетной записью Twitter. Также в этой
статье предполагается, что вы работаете на Linux®.
Я проверял данное приложение с Python 2.5.2. По умолчанию Python
установлен на большинстве Linux-машин, однако если Python у вас все же
отсутствует, то в разделе Ресурсы можно найти информацию по его загрузке и установке.
Twitter позволяет получать данные с помощью двух API-интерфейсов: API
поиска и REST API. (На сайте Twitter в разделе FAQ упоминается о планах
по созданию единого API). REST Web-сервисом называется Web-сервис,
реализованный на протоколе http и следующий принципам архитектуры REST
(см. информацию в разделе Ресурсы). Устанавливаем библиотеку python-twitter
Последний компонент, который нам нужен - это библиотека python-twitter.
Согласно сайту проекта, она представляет собой "оберточную библиотеку
python, основанную на API Twitter и модели данных twitter". Существует
несколько библиотек, позволяющих взаимодействовать с сервисами Twitter
во множестве языков - от Ruby до Eiffel. В настоящий момент в Python
имеется 5 библиотек для взаимодействия с Twitter: Python-twitter Де
Витта Клинтона (DeWitt Clinton), python-twyt Эндрю Прайса (Andrew
Price), twitty-twister Дастина Сэллингса (Dustin Sallings), twython
Райана Макграта (Ryan McGrath) и Tweepy Джоша Росслейна (Josh
Roesslein).
Библиотеке python-twitter для работы нужен пакет simplejson (см. Ресурсы). Загрузите этот пакет и установите его, выполнив команды, показанные в листинге 1.
tar -zxvf simplejson-2.0.9.tar.gz
cd simplejson-2.0.9
sudo python setup.py build
sudo python setup.py install
Если вы предпочитаете работать с egg-пакетами, используйте команду sudo easy_install simplejson-2.0.9-py2.5-win32.egg.
Теперь можно установить и python-twitter. Загрузите пакет и выполните команды, показанные в листинге 2.
tar -zxvf python-twitter-0.6.tar.gz
cd python-twitter-0.6
sudo python setup.py build
sudo python setup.py install
Устанавливаем Django
Теперь пришло время установить Django - мощную инфраструктуру разработки
Web-приложений на Python. В описываемом в данной статье приложении я
работал с Django версии 1.1.1. Установка Django так же проста, как
установка simplejson и python-twitter. Загрузите пакет и выполните в
терминале команды, показанные в листинге 3.
tar -zxvf Django-1.1.1.tar.gz
cd Django-1.1.1
sudo python setup.py build
sudo python setup.py install
Проверьте, что путь к Django есть в вашей переменной path, для чего выполните команду $ django-admin --version. Если все прошло как ожидалось, то можно взяться за написание кода.
Библиотека python-twitter
Установив библиотеку python-twitter, можно приступить к изучению ее
возможностей. Чтобы получить доступ к библиотеке, выполните команду import twitter. Модуль twitter предоставляет обертки для модели данных Twitter и его API. В нем имеется три класса моделей данных: twitter.Status, twitter.User и twitter.DirectMessage. Все вызовы API возвращают объект одного из этих классов. Для работы с API следует создать экземпляр класса twitter.Api()
(обратите внимание, что первая буква - заглавная). Если создать
экземпляр этого класса, не передавая в конструктор никаких параметров,
то можно будет вызывать только методы, которые не требуют входа в
систему. Чтобы войти в систему и получить полный доступ к API,
используйте следующий синтаксис:
import twitter
api = twitter.Api(username='yourUserName', password='yourPassword')
Имея экземпляр класса Api, можно запрашивать ваших
фолловеров (пользователей, которые читают ваши твиты), пользователей,
твиты которых читаете вы, получать статусы (твиты), можно посылать
твиты и т.д. Например, чтобы получить список твитов пользователя,
сделайте вызов statuses = api.GetUserTimeline(), который вернет список объектов twitter.Status. Чтобы создать список с текстом (строками) ваших твитов, можно использовать следующее выражение: >>>print [s.text for s in statuses].
В таблице 1 перечислены классы и методы, которые мы будем использовать в
нашем Web-приложении. С полной документацией можно ознакомиться через
pydoc, например — $ pydoc twitter.Api, или на web-странице документации python-twitter (см. Ресурсы).
Добавляем в коктейль jQuery
Следует уточнить, что мы будем использовать не только ядро jQuery, но и
библиотеку jQuery UI, предоставляющую виджеты, темы и анимацию.
Посетите страницу ThemeRoller и на панели слева нажмите на вкладку Gallery (Галерея). Выберите тему, которая вам нравится (я в этом приложении использовал тему Cupertino) и перейдите по ссылке Download,
находящейся под именем темы. Вы попадете на страницу загрузки. Выберите
на ней текущую (стабильную) версию. На момент написания статьи это
была версия 1.7.2 для jQuery 1.3+.
Процесса установки как такового нет, просто извлеките файл ThemeRoller и
поместите нужные директории/файлы в нужное место. Также при желании
можно создать новую тему, но я в этом примере ограничился использованием
одной из готовых тем.
Создаем проект Django
Теперь нужно создать новый проект Django. Это делается с помощью команды django-admin startproject pytweetproj, где pytweetproj
– это имя проекта, используемое в этой статье. Вы можете указать любое
другое имя, однако в таком случае следите за тем, чтобы везде дальше
по ходу статьи использовать именно его. Перейдите в директорию
pytweetproj. Чтобы запустить web-сервер Django, выполните в терминале
команду python manage.py runserver, запустите
Web-браузер и перейдите по адресу http://127.0.0.1:8000. Вы увидите
страницу с надписью «It worked!». Если вы в какой-либо момент захотите
остановить или перезапустить сервер, нажмите Ctrl+C,
чтобы завершить его процесс. Не используйте сервер разработки в рабочей
среде. Завершив разработку проекта, перенесите его на надежный и
безопасный сервер, например, Apache.
Создайте в корневой директории проекта поддиректорию с именем resources,
в которой мы будем хранить CSS-файлы, сценарии JavaScript и прочие
медиа-файлы. Скопируйте сюда директории css и js, извлеченные из
ZIP-архива ThemeRoller, а также ядро jQuery.
Откройте в своем любимом текстовом редакторе файл settings.py и поменяйте его согласно листингу 4.
# Настройки Django для проекта pytweetproj.
import os
APPLICATION_DIR = os.path.dirname( globals()[ '__file__' ] )
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
)
MANAGERS = ADMINS
# для кэширования мы будем использовать базу данных sqlite3
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'session.db'
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''
TIME_ZONE = 'America/Chicago'
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
# если вы не будете пользоваться возможностями интернационализации, то для скорости
# работы лучше оставить этому параметру значение false
USE_I18N = False
MEDIA_ROOT = os.path.join( APPLICATION_DIR, 'resources' )
MEDIA_URL = 'http://localhost:8000/resources/'
ADMIN_MEDIA_PREFIX = '/media/'
# Сделайте этот ключ уникальным и никому его не показывайте.
SECRET_KEY = '=y^moj$+yfgwy2kc7^oexnl-f6(b#rkvvhq6c-ckks9_c#$35'
# Список загрузчиков шаблонов, которые могут импортировать шаблоны из различных
# источников.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.load_template_source',
'django.template.loaders.app_directories.load_template_source',
# 'django.template.loaders.eggs.load_template_source',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
)
ROOT_URLCONF = 'pytweetproj.urls'
TEMPLATE_DIRS = (
os.path.join( APPLICATION_DIR, 'templates' ),
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'twitterPanel',
)
# добавим это для сессий
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
При задании директории приложения используйте вызов os.path.dirname( globals()[ '__file__' ] ),
который возвращает путь к текущей рабочей директории и работает на всех
операционных системах. С помощью этого вызова задайте путь к
директории ресурсов, а также TEMPLATE_DIR. Также необходимо задать
переменной MEDIA_URL значение http://localhost:8000/resources/.
Мы будем использовать базу данных sqlite3, по умолчанию включенную в
Python. Также необходимо задать переменные DATABASE_ENGINE,
DATABASE_NAME и ROOT_URLCONF. Обратите внимание, что в переменной
INSTALLED_APPS, в которой перечисляются установленные приложения,
указано еще не созданное приложение twitterPanel. Мы создадим это приложение чуть позже. А пока выполним команду python manage.py syncdb чтобы создать базу данных для session.db.
Выполните команду django-admin startapp twitterPanel чтобы создать приложение twitterPanel,
после чего перейдите в только что созданную директорию twitterPanel. В
директории twitterPanel создайте директорию с именем templates, в
которой мы будем хранить шаблоны Django.
Создаем адреса URL
Откройте в своем любимом текстовом редакторе файл url.py, находящийся в
корневой директории проекта и поменяйте код в соответствии с листингом
5. В этом файле шаблонам адресов URL ставятся в соответствие функции
обратного вызова.
Согласно Википедии, регулярные выражения "предоставляют лаконичные и
гибкие средства для идентификации текста, представляющего интерес,
например, содержащего определенные символы, слова или шаблоны
символов". Если у вас нет опыта работы с регулярными выражениями, я
рекомендую вам книгу Mastering Regular Expressions, написанную Джеффри Фридлом (Jeffrey Friedl) или Text Processing in Python,
написанную Дэвидом Мерцем (David Mertz). Также можно начать с
HOWTO-руководства по регулярным выражениям, размещенного на странице
документации Python.
Первый элемент urlpatterns определяет, как
будут обрабатываться статические ресурсы или медиа-файлы – например
изображения. Поскольку мы используем сервер разработки Django, для
обслуживания статических данных мы будем использовать представление django.views.static.serve(). Второй элемент urlpatterns подключает шаблоны URL, найденные в приложении twitterPanel.
Откройте файл url.py, находящийся в директории twitterPanel (не
путайте его с файлом url.py, находящимся в корне проекта) и добавьте в
него код, показанный в листинге 6.
Представления
Мы создадим только три представления: index, panel и update. Обратите
внимание, что мы будем добавлять представления не в корень проекта, а в
приложение twitterPanel. Откройте файл views.py, находящийся в
директории twitterPanel, и добавьте в начало файла инструкции импорта,
указанные в листинге 7:
from django.shortcuts import render_to_response
from django.template.context import RequestContext
import twitter
Метод Django render_to_response() отображает шаблон с определенным контекстом и возвращает объект класса HttpResponse. RequestContext - это контекст Django, немного отличающийся от обычного контекста django.template.Context, а именно, он принимает объект класса HttpRequest и автоматически заполняет контекст переменными, найденными в параметре TEMPLATE_CONTEXT_PROCESSORS.
Первый метод представления – index() - должен выглядеть так, как показано в листинге 8.
def index(request):
template = 'index.html'
userName = request.POST.get( 'userTxt' )
password = request.POST.get( 'passwordTxt' )
if userName is not None and password is not None:
try:
api = twitter.Api( username = userName, password = password)
# запрашиваем 5 первых твитов
statuses = api.GetUserTimeline()[0:5]
# получаем 120 первых друзей
following = api.GetFriends()[0:120]
except NameError, e:
print "unable to login"
else:
statuses = {}
following = False
# помещаем данные в сессию
request.session['statuses'] = statuses
request.session['following'] = following
request.session['userName'] = userName
request.session['password'] = password
data = {
'statuses' : statuses,
'following' : following,
}
return render_to_response(template, data,
context_instance = RequestContext(request))
Шаблон index.html еще не написан. Сейчас мы пока просто запомним, что у
нас есть два HTML-элемента: поля для ввода имени пользователя и
пароля. Данные посылаются в представление с помощью метода POST. Если имя пользователя и пароль введены, мы создаем объект класса twitter.Api
и извлекаем для этого пользователя первые 5 твитов и первых 120
пользователей, за твитами которых он следит. Статусы, друзья, имя
пользователя и пароль сохраняются в сеансе, чтобы к ним можно было
обратиться в других частях нашей программы.
Второй метод представления - panel() - намного короче. Он показан в листинге 9.
Здесь мы используем шаблон panel.html, которого также еще нет. После
входа пользователя все действия происходят именно в этом представлении.
Именно здесь отображаются твиты, друзья и выполняются обновления. Чуть
позже мы расскажем об этом подробнее. В настоящий момент все, что мы
здесь делаем - это получаем из сеанса некоторые данные и вызываем метод
render_and_response. Третий метод представления - update - напротив, немного сложнее. Взгляните на листинг 10:
Имя пользователя и пароль извлекаются из сеанса и используются для создания еще одного объекта twitter.Api, который используется для отправки обновления. После этого производится перезагрузка статусов.
Давайте изучим код, показанный в листинге 11. Сначала мы с помощью переменной {{MEDIA_URL}} сообщаем браузеру о том, где находятся файлы CSS, JavaScript и jQuery. При отображении шаблона Django подставляет вместо {{MEDIA_URL}} фактический путь к файлам.
Внутри заголовка добавим свой код JavaScript. Знак доллара ($) – это сокращение, с помощью которого можно обратиться к экземпляру jQuery. В jQuery краткая форма записи для document.getElementById('name') выглядит так: $('#name'). Например, мы определяем элемент dialog из jQuery UI с помощью тега <div>, а затем вызываем метод .dialog() для создания окна jQuery. Внутри этого окна мы помещаем кнопки OK и Cancel. Кнопка Cancel закрывает окно, а OK
не просто закрывает окно, но и посылает данные на сервер. Если
данные, полученные представлением index, являются корректными именем
пользователя и паролем, приложение вернет данные о твитах и о
читателях твитов данного пользователя. После этого окно с кнопками
исчезает и вместо него появляется панель Twitter.
Вся магия здесь заключена в строке $( '#panel' ).html( ' ' ).load( '{% url twitterPanel_panel %}' ),
в которой загружается внешний шаблон Django с именем panel.html.
Панель Twitter представляет собой виджет accordion, входящий в
библиотеку jQuery UI. В листинге 12 показан код шаблона panel.
Сохраните его в файле panel.html в директории twitterPanel/templates.
Дадим виджету accordion имя «main». Вся работа приложения после входа
пользователя в систему происходит именно здесь. В этом виджете имеется
3 вкладки: My Recent Tweets, Update Status и Following, которые
показаны на рисунке 5.
На первой вкладке просто отображается 5 последних твитов. Если объект status не пустой, Django проходит по всем объектам status и отображает соответствующий текст. В противном случае на этой вкладке выводится сообщение "No tweets found".
На второй вкладке - Update Status - находится HTML-форма с текстовым полем и кнопкой. Под формой находятся 2 элемента <div>: один с именем charCount, другой с именем updateStatus. Вкладке Update Status назначается событие onclick,
при котором проверяется, что длина введенного сообщения не превышает
140 символов, и, если это так, введенный текст отправляется с помощью
имеющегося в jQuery метода post в представление update, которое выполняет остальную работу. После этого на данной странице отображаются последние твиты.
Ради интереса я также добавил JavaScript-код, подсчитывающий количество
символов, которые еще можно ввести в твите. Как вы помните, Twitter
ограничивает длину сообщения 140 символами. Этот код при каждом
отпускании клавиши вычитает из 140 количество символов, введенных в
поле update text, после чего обновляет счетчик символов на странице.
На третьей вкладке панели Twitter – Following в первую очередь проверяется, что объект following не пустой, и, если это так, то как и на вкладке My Recent Tweets,
приложение в цикле обходит всех пользователей. У каждого пользователя
можно получить URL изображения, показываемого в профиле. Мы привяжем это
значение к атрибуту src тега <image>. В результате на третьей вкладке будут показаны все пользователи, за твитами которых вы следите.
Теперь, когда мы разложили все по своим местам, давайте запустим сервер
Django и откроем URL http://127.0.0.1:8000/twitterPanel. Вы должны
увидеть кнопку jQuery UI для входа в приложение. После того как вы
нажмете эту кнопку и введете имя пользователя и пароль для twitter,
должна появиться панель Twitter.
Заключение
Теперь, когда вы познакомились с демо-приложением, вы наверняка оценили
динамику и эффектность, придаваемую приложению библиотекой jQuery UI. В
свою очередь Django облегчает работу с серверным кодом Python и
шаблонами.
Данное приложение можно улучшить, добавив проверки в процесс
регистрации, окна с сообщениями об ошибках, список пользователей,
следящих за вашими твитами, посылку личных твитов, а также поиск
твитов. Разумеется, возможности расширения приложения ограничены
только вашим воображением.