- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF122:Python
Материал из Linuxformat.
- Python Заставим Web доставлять нужное содержимое вам на блюдечке
Содержание |
Python: Прочту вам твиты
Python |
---|
Python для профессионалов |
---|
Python + PyGame |
---|
Python + Web |
---|
Python + Clutter |
---|
- Часть 3: Ник Вейч продолжает web-эксперименты а-ля доктор Моро, на сей раз создавая гибрид, умеющий говорить – полу-Python, полу-Twitter.
Однажды некто решил, что людям нужно больше отвлекаться от работы – и придумал Twitter. Возможно, в штаб-квартире Twitter эту историю изложили бы не совсем так – скорее всего потому, что она создает не слишком гламурный имидж (ну да, да, это еще и дико неточно). Так или иначе, Twitter оседлал волну популярности. Если вы хотите узнать, в какой точке планеты сейчас находится Стивен Фрай, что каждый житель США ел на ланч или как самодовольно бахвалится о своем величии Джонатан Росс сегодня, проще всего обратиться туда.
Вы удивитесь, но Twitter способен и на полезные штуки. По нашим предыдущим урокам мы поняли, что секрет победы над технологией – узнать, как работает сервис, а затем выяснить детали его интерфейса прикладного программирования (API, Application Programming Interface). Оказывается, API Twitter закручен довольно лихо: всякие вещи в нем работают самыми разными способами. Но не будем расстраиваться, ведь в Python для него существует масса оберток. Больше всего нам подойдет стандартный Python-Twitter, доступный во множестве репозиториев, а также по адресу http://code.google.com/p/python-twitter.
Перерыв
Identi.ca – это свободная платформа микроблоггинга с открытым кодом. Ее содержимое доступно по лицензии Creative Commons, и, наверное, это мило по отношению к прародительнице. Увы, она далеко не так популярна, как Twitter. Но, может, оно и к лучшему – все же меньше шума. Основы этого урока можно применить к Identi.ca таким же образом, как и к Twitter, потому что API Identi.ca подобен API Twitter (довольно странному) на низком уровне.
Так, теперь приостановим урок, чтобы дать вам выбор. Вы когда-нибудь слышали об Identi.ca? Он, э-э, вылитый Twitter, более или менее, но работает на свободном ПО под лицензией GPl. Его содержание доступно на условиях Creative Commons, а значит, в целом он убедительнее и красивее, чем Twitter. Честно.
Все еще тут? Тогда заодно расскажем, как все работает в Identi.ca. Специального модуля Python для этого сервиса нет, но поскольку API схож с Twitter, мы просто сменим настройки подключения к серверу в файле twitter.py. Вообще-то это уже сделано за нас – посмотрите файл по адресу http://www.dilella.org/foo/twitter.py_new. И это на самом деле позволяет передавать данные на сервер – поэтому теперь, увидев
client = twitter.Api(username=”foo”,password=”bar”)
можете сделать следующую замену:
client = twitter.Api(username=”foo”, password=”bar”, twitterserver=”identi.ca”)
Если хотите использовать эту расширенную библиотеку, просто скачайте файл по ссылке. Понадобится заменить установленную библиотеку, связанную с Twitter (для более гладкой работы системы, лучше сперва установить исходный пакет Python-Twitter). В зависимости от ваших версий Linux и Python, он находится в /usr/lib/python2.5/site-packages или где-то еще. Просто замените файл twitter.py на новый.
Соединение
Чтобы от системы Twitter был прок, создадим учетную запись. Как и в предыдущих проектах, для этих целей можно написать скрипт, но гораздо легче просто перейти на web-страницу, зарегистрироваться и запомнить детали, которые вы будете использовать. Вы, наверное, также захотите добавить друзей (в противном случае будет скучновато), а можно и использовать имеющуюся учетную запись. Для целей нашего урока, мы создали профиль для evilbotx и решили следовать по Twitter за очаровательной Бритни Спирс. Теперь запустите Python в окне терминала (набрав python, и приступим к созданию микроблога:
О функциях любого модуля Python можно разузнать в подробностях, импортировав его в оболочке Python и набрав ‘help (имямодуля)’.
>>> import twitter >>> client = twitter. Api(username=”evilbotx”, password=”mypassword”) >>> client.PostUpdate(“Hello World!”) <twitter.Status object at 0xb7c2f44c>
Эти строки завершают ритуал самопровозглашения нашего приложения. Сначала мы создали объект под названием client, который соединился с сервером Twitter и идентифицировался, а в следующей строке применили его метод для публикации сообщения (в терминологии Twitter это называется «обновить статус»).
Если вы создаете чисто автономную систему, больше вам знать и не надо – вы можете вставить данный кусок кода в свой скрипт и отправлять твиты куда захотите. Но мы хотим большего. Следующим шагом будет список людей, за обновлениями которых вы желаете следить и узнавать их статусы. Процесс не сложен, потому что для большинства задач существуют готовые методы:
>>> userlist = client.GetFriends() >>> for username in userlist: ... print username.screen_name, username.status.text ...evilnick @tweeny4 it’s hard to beat a poached egg serenajwilliams @celebsdontreply. Of course, I reply. britneyspears The Circus is coming back to the states -Britney
Из этого кода видно, что метод GetFriends() возвращает список объектов user. User – это класс в модуле Twitter с различными атрибутами: описание пользователя, псевдоним и т. д. Модуль получает эти данные от Twitter при создании объектов, и их можно извлечь. Рассмотрим некоторые полезные свойства.
- User.id Уникальный идентификационный номер, присваиваемый пользователю сервиса Twitter.
- User.name Реальное имя пользователя. *
- User.screen_name Его псевдоним в Twitter.
- User.description Небольшое описание, введенное пользователем. *
- User. Profile_image_url Ссылка на картинку профиля пользователя.
- User.url URL, введенный пользователем, часто – домашняя страница. *
- User.status Последний объект status этого пользователя.
* Эти поля могут оставаться пустыми, если пользователь не указал информацию.
При желании можно использовать все это программно – например, подгружая изображения для графического клиента Twitter или объединяя пользователей в группы по интересам.
Как было бы здорово иметь клиент Twitter с поддержкой аудио! Вместо того, чтобы пялиться в дурацкий экран, отрываясь от написания ценного кода, можно просто включить свои уши и прослушивать обновления статусов. Для Linux существует несколько утилит преобразования текста в речь и даже распознавания голоса (LXF116–117). В вашем дистрибутиве, возможно, уже установлены Festival или Espeak, а если нет, пакеты легко найти в обычных репозиториях. Мы возьмем Espeak, но вы можете использовать и другие, потому что код почти одинаковый. Для выполнения такого легкого задания не будем гнаться за сложными решениями – применим наш старый любимый модуль subprocess. Он, если вы помните, вызывает оболочку из Python. Воспользуемся методом call, который просто берет список аргументов, которые вы хотите использовать. Простой пример:
>>> import subprocess >>> subprocess.call([‘espeak’,’”Hello World!”])
Получите ваши настройки
Вы будете дружелюбно (если вам по вкусу синтетические голоса) поприветствованы голосом. В случае синтаксической ошибки тщательно проверьте правильность расстановки кавычек. Последний элемент в списке – текстовая строка, заключенная в двойные кавычки, а затем в простые кавычки. Она передает Полное объяснение модуля Pyton-Twitter имеется на сайте http://static.unto.net/python-twitter/0.6/doc/twitter.html.espeak «Hello World!” в командную строку. Итак, наш клиент будет выглядеть наподобие
import twitter, subprocess, time client = twitter.Api(“evilbotx”, “evilbot”) while True : list = client.GetFriends() for name in list: print name.screen_name, name.status.text, name.status.id texty = name.screen_name + name.status.text time.sleep(2) subprocess.call([“espeak”, texty]) time.sleep(60)
Здесь мы устанавливаем соединение, входим в бесконечный цикл и получаем список друзей. Внутренний цикл обрабатывает статусы и выдает их, конвертирует информацию в строку и затем использует subprocess.call для ее перевода в речь. Time.sleep(60) инициализирует задержку, чтобы не досаждать серверу слишком часто.
Вы можете удивиться, почему мы обращаемся к списку друзей внутри главного цикла. Но так будет проще, по двум причинам. Во-первых, все объекты User из списка автоматически снабжаются последними статусами. Загрузив список друзей единожды, мы все равно в каждом цикле справлялись бы со статусами, что загромоздило бы код и (только не надо меня здесь цитировать: доказательств у меня никаких, одни смутные подозрения), возможно, увеличило бы затраты на взаимодействие клиента с сервером. Вторая причина заключается в том, что мы можем спокойно запускать и его, и другой клиент Twitter, или заходить на сайты. Любые изменения в списке друзей сразу отразятся в скрипте.
На этом этапе все работает, но есть проблема: статусы оглашаются независимо от того, были ли они обновлены за данный период. Не мешает проверить время, когда было создано статусное сообщение, и сравнить с настоящим. Если сообщение создано более чем 60 секунд назад (или, допустим, 61 – дадим доработать остатку кода), то его нужно сказать вслух. На беду, время относительно. Временной модуль Python выдает время как смещение от начала эпохи (секунды с момента создания вселенной – согласно Unix, это была полночь 1 января 1970 г.), а Twitter выдает время создания статусного сообщения в текстовом формате.
Чтобы сравнить эти времена, надо привести их к одному виду. Похоже, модуль Twitter-Python в процессе трансляции делает ошибочное допущение, потому что его методы определения времени получения статусного сообщения и времени, когда оно было опубликовано, дают различные результаты. Это усложняет ситуацию, но не делает невозможным ее исправление. API Twitter возвращает даты и время в виде текстовых строк в формате Mon Jun 8 11:46:34 +0000 2009. Тут все в порядке, потому что Python умеет конвертировать их в нормальный числовой формат и затем в число секунд от начала эпохи. Единственный небольшой прокол – Twitter не включает в формат даты часовой пояс. Однако эксперименты покажут вам, что время, как и следовало ожидать, в UTC (или GMT, если вы помните, что время изобрели в Британии). Теперь можно просто добавить UTC в конец строки, и пусть Python преобразует это в более удобный числовой формат. Объект status сохраняет время прямо из Twitter в виде свойства created-at, и мы можем использовать его безо всяких проблем. Функция time.strptime преобразует имеющуюся строку в набор числовых величин стандартной формы. Для получения результата, нужно передать саму строку и строку-описание ее формата, которая содержит указания или описания в соответствии со списком значений, поддерживаемых модулем. Для нас они таковы: %а – аббревиатура для названия дня, %b – для названия месяца, %d – для обозначения числа, %H – часы, %m – минуты, %S – секунды, %Y – год, и %Z – трехбуквенное обозначение часового пояса.
Один статус за все
Кто читал предыдущий выпуск, про чат-ботов, возможно, помнит, что статусное сообщение легко установить программно. А как насчет автоматической установки вашего статуса в чате по вашему последнему обновлению в Twitter? По-простому, можно поступить так:
import xmpp, twitter twituser=”foo1” twitpass=”foo2” jabberuser=”bar1@something” jabberpass=”bar2” twit=twitter.Api(username=twituser,password=twitpass) text=twit.GetUser(twituser).status.text jid=xmpp.protocol.JID(jabberuser) jab=xmpp.Client(jid.getDomain(),debug=[]) jab.connect() jab.auth(jid.getNode(),jabberpass) jab.sendInitPresence() jab.send(xmpp.Presence(status = text , show = “chat”, priority = ‘1’)
Вставьте все это в цикл с подходящей задержкой, и получите два в одном – только не забудьте подставить в начале свой настоящий ID и пароль.
Когда был твит?
Как вы можете заметить, мы добавили последнюю величину сами, чтобы она участвовала в обработке времени в Python. Внутренний числовой формат, используемый в Python, просто указывает все даты в числах, что легко увидеть, преобразовав время вручную:
>>> time.strptime(‘Mon Jun 8 10:51:32 +0000 2009 UTC’, ‘%a %b %d %H:%M:%S +0000 %Y %Z’) (2009, 6, 8, 10, 51, 32, 0, 159, 0)
Эти числа, соответственно, год, месяц, число, часы, минуты, секунды, день недели (понедельнику соответствует 0), день в году и отметка о летнем времени. Поэтому-то и важно указать часовой пояс, ведь при отсутствии данной отметки Python попытается ввести свою, что может привести к непонятным результатам.
Время можно затем перевести в привычные для Unix секунды от начала эпохи, используя time.mktime(). Вы можете найти более подробную информацию о модуле time и различных методах, открыв в своем браузере http://docs.python.org/library/time.html.
Наш преобразованный код принял следующий вид:
import twitter, subprocess, time client = twitter.Api(“evilbotx”, “password”) while True : list = client.GetFriends() for name in list: texty= name.screen_name + name.status.text now = time.mktime(time.gmtime()) stringmsgtime =name.status.created_at + ‘ UTC’ msgtime=time.mktime(time.strptime(stringmsgtime,‘%a %b %d %H:%M:%S +0000 %Y %Z’)) if ((msgtime+61)>now): subprocess.call([“espeak”, texty]) time.sleep(60)
Теперь у вас есть функционирующий аудио-клиент Twitter всего из 13 строк кода. Неплохо; единственная проблема возникнет, если в вашем списке активных друзей более дюжины человек – тогда скрипт вам будет не заткнуть. В этом случае, ограничьтесь теми пользователями, за обновлениями которых вы хотите следить, а затем получайте статус каждого из вашего списка, и для этого нужно поменять всего лишь несколько строк кода:
import twitter, subprocess, time client = twitter.Api(“evilbotx”, “password”) list = [‘evilnick’, ‘evilbottester’, ‘tweeny4’] while True : for item in list: name=client.GetUser(item) texty= name.screen_name + name.status.text now = time.mktime(time.gmtime()) stringmsgtime =name.status.created_at + ‘ UTC’ msgtime=time.mktime(time.strptime(stringmsgtime,‘%a %b %d %H:%M:%S +0000 %Y %Z’)) if ((msgtime+61)>now): subprocess.call([“espeak”, texty]) time.sleep(60)
В новой версии нашего скрипта внутренний цикл проходит через список и задействует метод GetUser() для каждого псевдонима пользователя. Он возвращается как объект User со свойствами, включающими последнее обновление. Теперь вы получите голосовое уведомление, только если статус обновит кто-то из избранных контактов.
Идем дальше
Полезным дополнением к скрипту может быть GUI для быстрого обновления вашего собственного статуса. Для этого достаточно создать поле ввода (не более 140 знаков), используя PyQt, wxWidgets или другой любезный вам GUI, и подсоединить метод для публикации обновлений статусов по нажатию Enter. А можно употребить ваши знания методов Twitter для добавления его функций к другим сервисам. Пусть ваши серверы сообщают о степени своей загрузки и остатке свободного пространства; или добавьте скрипт в Amarok для создания уведомлений о проигрываемых треках; или запрограммируйте произвольные выкрики про Майка. Все в ваших руках. LXF