Журнал LinuxFormat - перейти на главную

LXF122:Python

Материал из Linuxformat
Перейти к: навигация, поиск
Python Заставим Web доставлять нужное содержимое вам на блюдечке

Содержание

Python: Прочту вам твиты

Часть 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? Он, э-э, вылитый 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, и приступим к созданию микроблога:


>>> 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 существует несколько утилит преобразования текста в речь и даже распознавания голоса (LXF116117). В вашем дистрибутиве, возможно, уже установлены 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

Персональные инструменты
купить
подписаться
Яндекс.Метрика