-
1С и JSON: работа над ошибками
UPD: новая версия
Пилотная версия функции преобразования данных 1С в JSON оказалась вполне удачной. Делюсь новой версией: http://pastebin.com/y2K5V3Xt
Исправления:
- типы
Неопределено
иNull
преобразуются вnull
; - добавлен тип
СписокЗначений
; - исправлен ISO-формат даты;
- строки преобразовываются в последовательности вида
\uxxxx
.
Напомню, что код состоит из одной функции и не зависит от сторонних модулей и компонент.
Пример:
с = новый СписокЗначений; с.Добавить("Привет!"); с.Добавить(42); с.Добавить(ТекущаяДата()); с.Добавить(Неопределено); с.Добавить(Null); с.Добавить("!№2№%Ё~{}"); с.Добавить(новый Структура("поле1, поле2", ВидДвиженияБухгалтерии.Дебет, новый Массив(3))); Сообщить(json(с));
Результат:
[ "\u041f\u0440\u0438\u0432\u0435\u0442!", 42, "2012-11-13T10:17:55", null, null, "!\u21162\u2116%\u0401~{}", { "\u043f\u043e\u043b\u04352": [ null, null, null ], "\u043f\u043e\u043b\u04351": "\u0414\u0435\u0431\u0435\u0442" } ]
Комментарии из старого блога
11/21/12 Артемий Зайцев: А зачем все символы заменять на подстановки
\u0414
? Вместо “N” (1 байт) получим замену в 6 байт при передаче по интернету. Вся прелесть JSON теряется. XML становится выгоднее.11/21/12 Иван Гришаев: Заменяются не все символы, а только те, что не входят в диапазон
0x20-0x7f (A-z, 0-9)
. Если у вас английский текст, то разницы не будет.\uxxxx
- это код символа Unicode. Согласно стандарту JSON строки должны быть представлены Unicode-последовательностями. Это правило можно нарушать, но тогда никто не гарантирует корректный разбор JSON-документа со строками, скажем, на украинском.Преимущество JSON перед XML не в меньшем объеме данных, а в удобстве сериализации и парсинга. Одной функцией структура сворачивается в JSON, другой – обратно. Генерация и парсинг XML занимают больше времени и сил.
11/21/12 Артемий Зайцев: Проверил с разными языками. В UTF всё работает. Еще у вас подстановок спецсимволов в строке. Если в тексте есть знаки / \ “, то JSON ломается.
Сделал как-то так:
Если Тип = Тип("Строка") Тогда Возврат """" + MyJSONМаскировать(Объект) + """"; .... Функция MyJSONМаскировать(Знач Стр) Стр=СтрЗаменить(Стр,"\","\\"); Стр=СтрЗаменить(Стр,Символы.ПС,"\n"); Стр=СтрЗаменить(Стр,Символы.ВК,"\r"); Стр=СтрЗаменить(Стр,Символы.Таб,"\t"); Стр=СтрЗаменить(Стр,"/","\/"); Стр=СтрЗаменить(Стр,"""","\"""); Возврат Стр КонецФункции
11/21/12 Иван Гришаев: Да, спасибо, только что сам обнаружил, что с кавычками косяк, нужно их экранировать заменой, как у вас. Завтра выложу новую версию функции.
05/31/13 Кирилл: Спасибо автору!
05/31/13 Зайцев Артемий Анатольевич: Кирилл, рано автора хвалить. Он только начинает учить 1С. Есть еще ошибки:
(Формат(Объект, "ДФ=yyyy-MM-ddThh:mm:ss")
- после буквы T ничего не пишет.05/31/13 Иван Гришаев: Вы комментируете старую версию функции. Вот новая. Там много чего исправлено. Эта крутится в продакшене уже больше года.
05/31/13 Зайцев Артемий Анатольевич: Иван. В новой тот же косяк с датой:
Возврат json(Формат(Объект, "ДФ=yyyy-MM-ddThh:mm:ss"));
надо как-то:
Возврат json(Формат(Объект, "ДФ=yyyy-MM-dd") + "T" + Формат(Объект, "ДФ=hh:mm:ss") );
05/31/13 Иван Гришаев: Похоже, вы правы, спасибо. В моем проекте часы и минуты не нужны, не обратил внимания.
- типы
-
Личный кабинет Читаэнергосбыта для Андроида
Выложил в Маркет свое первое приложение — личный кабинет абонента Читаэнергосбыта.
Веб-версия кабинета работает уже второй год, на момент написания заметки зарегистрировано 3500 абонентов, передано 4000 показаний приборов, зарегистрировано 250 заявок.
Теперь все это удобство доступно в смартфоне.
На создание, тестирование и отладку ушло 3 месяца. Приложение взаимодействует с нашим сервером HTTP запросами, трафик копеечный.
Так что если вы наш абонент, милости прошу установить и пользоваться.
Комментарии из старого блога
01/12/13 obmorrock: А где кроме маркета можно скачать apk? А то у меня на смарте маркет выпилен, а установить хочется….
01/12/13 Иван Гришаев: Выслал почтой.
04/23/13 Иванов Сергей: Уважаемый Иван! Установил и пользовался вашим приложением несколько месяцев всё работало прекрасно, но более недели уже не могу им воспользоваться. При нажатии “Войти” выдаёт сообщение “Ошибка сервера” при этом приходит сообщение, что “выполнен вход в личный кабинет дата время”. Что случилось?
04/23/13 Иван Гришаев: Здравствуйте! С самим приложением все в порядке, неполадки возникают на стороне сервера, который возвращает данные. Я уже не работаю в Читаэнергосбыте, поэтому исправить ошибку не смогу, но дам знать коллегам.
04/23/13 Иванов Сергей: Спасибо.
-
JSON-сериализация в 1С
UPD: новая версия функции.
Быдлоплатформа 1С не умеет работать с JSON, MD5, SHA, чем огорчает веб-разработчика. Ничего, научим: http://pastebin.com/4tF96gQH
Пример:
Запрос = новый Запрос( "ВЫБРАТЬ ПЕРВЫЕ 5 | Договоры.Код, | Договоры.Ссылка, | Договоры.ДатаЗаключения, | Договоры.Комментарий, | Договоры.Предопределенный |ИЗ | Справочник.Договоры КАК Договоры" ); с = новый Структура("foo, bar, baz, tab", 1, "Привет!", ТекущаяДата(), Запрос.Выполнить().Выгрузить()); Сообщить(json(с));
Результат:
{ "foo": 1, "bar": "Привет!", "baz": "2012-11-09T10.50.29", "tab": [ { "Код": "ВСООЦ0050133", "Ссылка": "ВСООЦ0050133", "ДатаЗаключения": "2012-09-14T12.00.00", "Комментарий": "", "Предопределенный": false }, { ... } ] }
TODO: добавить некоторые типы данных (выборка из результата запроса, наборы записей).
-
Степень схожести строк (коэффициент Танимото)
Иногда нужно определить степень схожести двух строк, т.е., насколько одна строка похожа на другую. Например, у вас есть список названий фильмов. Источники разные, нет никаких уникальных идентификаторов, только заголовки. При этом стоит учесть, что даже самые простые названия могут быть написаны по-разному: «ЗАЛОЖНИЦА 2» и Заложница 2. Очевидно, что сравнение этих строк в лоб ничего не даст: лишние символы, разный регистр.
Строки можно рассматривать как множество символов. Две строки — два множества. Коэффициент Танимото позволяет определить степень схожести двух множеств:
, где:
- k — сам коэффициент от 0 до 1;
- a — количество элементов в первом множестве;
- b — количество элементов во втором множестве;
- c — количество общих элементов в двух множествах.
Изящная функция на Питоне:
def tanimoto(s1, s2): a, b, c = len(s1), len(s2), 0.0 for sym in s1: if sym in s2: c += 1 return c / (a + b - c)
Пара примеров:
print tanimoto('Иван Гришаев', 'Гришаев И.В.') 0.846153846154 print tanimoto('tanimoto test 1', 'testing Tanimoto #2') 0.7
В Питоне работает т.н. утиная типизация, когда важен не тип объекта, а его поля и методы. Нетрудно заметить, что код функции требует от объектов методов длины, вхождения элемента и итерации. Это значит, что вместо строк можно передавать списки, кортежи, словари и другие структуры:
print tanimoto( (1, 2, 3, 4, 5, 4), (4, 2, 5, 4, 9, 3), ) 0.714285714286
Конечно, расчет коэффициента нужно производить с умом. Например, вычистить регулярными выражениями лишние символы или передавать строки в одинаковом регистре. И конечно, лучше оперировать строками в юникоде.
Возвращаясь к нашему примеру:
print tanimoto( u'«ЗАЛОЖНИЦА 2»'.lower(), u'Заложница 2'.lower(), ) 0.846153846154
Величина 0.85 говорит о том, что оба названия указывают на один и тот же фильм. Однако, не лишним будет на всякий случай сверить год выпуска.
-
Работа с DBF в Питоне
Формат DBF, хоть и признан устаревшим, до сих пор широко используется в финансовых учреждениях. Он подходит для обмена табличными данными, такими, например, как отчеты и реестры платежей. Формат имеет простую логическую структуру, поэтому библиотеку для работы с ним можно написать самостоятельно. Классический DBF поддерживает основные типы данных — числа, строки, даты и булево. Благодаря этому дата, записанная в DBF, будет считата как дата, а не текстовая строка, которую будет необходимо парсить.
Для работы с файлами DBF в Питоне потребуется библиотека dbfpy. Это, кстати, не единственное решение, есть еще библиотеки pyDBF и dbf. Сам я работал только с первой из трех, функционал полность устраивает.
Приведу пару примеров: чтение и запись файла.
from dbfpy import dbf # Открываем имеющийся файл. db = dbf.Dbf("dbfile.dbf") # Обход всех записей. for rec in db: print rec # Извлечение записи по номеру. rec = db[42] # Значения полей извлекаются по их именам. value = rec["VALUE"] account = rec["ACCOUNT"] date = rec["DATE"] # Всегда закрывайте файл. db.close()
Запись нового файла немного сложнее, так как потребуется указать схему данных. Фрагмент кода из реального проекта:
from dbfpy import dbf # Определяем набор полей файла. C — строка, N — число, D — дата, L — булево. # Для строк нужно указать длину, для чисел — количество разрядов целой и дробной частей. SCHEMA = ( ("PSU", "C", 64 ), ("TSO", "C", 64 ), ("PAYMENT", "N", 16, 0), ("SERVICE", "N", 8, 0), ("DATE", "D" ), ("MRO", "C", 64 ), ("TERMINAL", "N", 8, 0), ("ACCOUNT", "C", 16 ), ("SUMMARY", "N", 16, 2), ("OPERATOR", "N", 8, 0), ("SUPPLIER", "N", 8, 0), ("TIME", "C", 8 ), ("LAST_NAME", "C", 64 ), ("FIRST_NAME", "C", 64 ), ("MIDDLE_NAM", "C", 64 ), ) db = dbf.Dbf("dbfile.dbf", new=True) db.addField(*SCHEMA) # Обходим в цикле данные, которые необходимо записать в DBF. # В данном случае payments — объект QuerySet из Джанго. # На каждом шаге цикла создается новая запись и заполняются ее поля. for payment in payments: rec = db.newRecord() rec["ACCOUNT"] = payment.account rec["FIRST_NAME"] = payment.first_name.encode("cp866") rec["date"] = payment.date # Заполняем остальные поля... # Сохранение записи. rec.store() db.close()
Готово, файл создан.
Наверняка вы обратили внимание на кодирование поля
payment.first_name
. Это unocode-строка, и для того, чтобы записать ее в файл, необходимо сперва преобразовать в обычную строку в какой-то кодировке. Исторически сложилось так, что основной кодировкой для этого формата является OEM, она же DOS, она жеcp866
. Многие программы, например, офисные Эксель и Акцесс работают с DBF-файлами именно в этой кодировке. Чтобы созданные вами файлы читались в сторонних программах, преобразовывайте перед записью строки с кириллицей вcp866
.Работать с DBF можно как с SQL-базой через драйвер ODBC. При этом именем таблицы является имя файла. Доступны все CRUD-операции на записями. Склеить два DBF-файла оператором JOIN, к сожалению, нельзя. Для работы с ODBC-источниками скачайте библиотеку pyodbc.
import pyodbc # Строка, определяющая источник ODBC. DefaultDir — директория с DBF-файлом. s = "Driver={Microsoft dBASE Driver (*.dbf)};DefaultDir=d:\\temp" db = pyodbc.connect(s, autocommit=True) cursor = db.cursor() # Пример выборки. cursor.execute(''' SELECT value, account, date FROM dbfile WHERE processed = 'false' ''') # Извлечение записи. row = cursor.fetchone() if row: print row # Закрываем курсор и ресурс. cursor.close() db.close()
Вставка, удаление и обновление записей реализуются аналогично согласно SQL-синтаксису:
cursor.execute(''' DELETE FROM dbfile WHERE processed = 'false' ''') cursor.execute(''' UPDATE dbfile SET account = 'test', value = 42 WHERE id = 1 ''')
Какой способ работы с DBF задействовать в проекте — решать вам. dbfpy не требует сторонних зависимостей, написана на чистом Питоне, может работать в сервисах типа App Engine, однако, не столь быстра, как pyodbc. Последняя, напротив, быстрее, но зависит от платформы и иногда глючит на Винде (у меня были проблемы с ошибками в DLL-библиотеках). Для небольших проектов рекомендую использовать dbfpy, в промышленных масштабах — pyodbc.
Комментарии из старого блога
04/08/14 Городецкий: привет! получаю
invalid syntax
приfrom dbfpy import dbf
. Подскажи пожалуйста, что не так?04/09/14 Иван Гришаев: Точка в конце не нужна. Или какая-то из букв кириллическая. Трейс должен показывать стрелочкой, где косяк.
01/09/15 Ole: Отличный пост
09/02/15 Дамир Аманов: в pyodbc как работать с кириллицой? в windows
09/03/15 Иван Гришаев: Насколько помню, кодировать строки в cp2151, если не получается с юникодом.
-
Замечательный движок Эгея
Этот блог работает на движке Эгея. Я узнал о нем из блога Ильи Бирмана (автора проекта). Поначалу мое отношение было скептическим — мало ли сейчас различных движков? Решив вести собственный блог, я перебрал несколько движков и КМС, и вышло так, что только Эгея не только удовлетворила все мои требования, но и приятно удивила в дальнейшем.
Почему я не использовал Друпал? Его долго собирать. Это не готовая КМС, а конструктор. Установив Друпал, приходится еще полдня ставить модули и лазить в настройках. Эгея же просто работает. В ней нет хлама вроде опросов, древовидных тегов, визуального редактора, архива за прошлые года. Она минималистична и быстра.
Эгея позволяет сконцентрироваться на содержимом блога, а не его техническом устройстве.
Пока что я вижу в движке два недостатка: вики-разметка и кодировка cp1251.
Использование разметки вместо обычного ХТМЛ является правильным решением: набирать теги руками замучаешься, а визуальные редакторы выдают отвратительный код. Вот только Илья не угадал с разметкой, лучше было бы взять не вики, а маркдаун, он проще и удобнее. Впрочем, к вики быстро привыкаешь.
Кодировка cp1251 устарела и отовсюду вытесняется УТФ, так как не позволяет использовать символы юникода и не дружит со многими языками. Эгею нужно перевести на УТФ обязательно, cp1251 — преграда на пути проекта к широкой аудитории.
И тем не менее, Эгея — лучший движок для блога из всех, что мне приходилось видеть. Помимо очевидных плюсов, вроде быстрой установки и высокой скорости работы, в ней есть сюрпризы. Например, картинки вставляются перетаскиванием файла в браузер. Это этого получаешь дикий, нестовый восторг! Не нужно больше искать изображения в дурацком диалоге выбора файла!
Эгея легко поддается темизации, написать свою тему для нее нетрудно. Движок поддерживает пользовательские блоки — это ПХП-файлики, содержимое которых выводится в определенное место, например, перед статьей, после статьи, в сайдбаре, в подвале и т.д. Мне понадобилось всего три таких файла — сайдбар с меню, область после статьи для социальных кнопок и подвал для джаваскрипта (метрика, подствека кода).
Словом, нисколько не ошибся с выбором Эгеи. Отличный движок, желаю Илье не забрасывать и развивать прект.
-
Мысли о Друпале
Друпал (анг. Drupal) — система управления содержимым, написанная на ПХП Дрисом Бёйтартом. Вместе с Вордпрессом и Джумлой входит в большую тройку КМС.
Историю Друпала вы можете прочесть в Википедии. Ознакомиться с текущим состоянием дел можно на официальном сайте. Начинающим будет полезно зарегистрироваться на форуме Дупал.ру, сообщество активно, есть подборка обучающих статей.
В этом посте я хочу выразить некоторые мысли, которые сформировались за долгое время работы с Друпалом. Это отдельные тезисы с краткими пояснениями.
Гибкость системы. Главным достоинством Дупала является его гибкость. Не секрет, что любая КМС в той или иной степени ограничивает разработчика. Дрис и команда разработали систему модулей и хуков. Она позволяет менять поведение Друпала без правок ядра.
Хуки — именованные функции. За хакерским словечком «хук» скрывается банальная вещь — функция, имя которой удовлетворяет шаблону
<имя модуля>_<имя хука>
. Эти функции должны располагаться в теле модуля. Друпал опрашивает модули на предмет наличия этих функций и вызывает их. При этом функция-хук должна либо вернуть какие-то данные, либо изменить те, что были переданы ей по ссылке. Хуков много, вызываются они в разное время. Некоторые модули могут определять собственные хуки.Множество модулей. Система модулей и хуков понравилась разработчикам. В настоящее время число всех модулей оценивается в несколько тысяч. В актуальном состоянии поддерживается около тысячи модулей. Написать свой модуль легко — это ПХП-файл с расширением
*.module
с функциями-хуками внутри. Описание каждого хука с примерами смотрите в документации.Не все в Друпале так идеально, как кажется. Друпал имеет солидный возраст, это зрелый программный продукт. Однако, некоторые его компоненты устарели и нуждаются в переработке. Например, работа с формами. В любом современном фреймворке форма, поля и валидаторы — это классы. Нужно расширить форму — наследуете от нее свой класс. Работа с классами проще, чем с хэш-массивами двойной вложенности. Друпал хранит переводы и кэш в базе, что отрицательно сказывается на производительности. Система нод (или сущностей) Друпала раскидывает поля по отдельным таблицам, вместо того, чтобы добавлять поля к имеющимся.
Не делайте из Друпала культ. Начинающим веб-разработчикам кажется, что Друпал способен на все. Это правда, но лишь в теории. Легкость создания больших сайтов без написания кода компенсируется многими уровнями абстракций и чрезмерно сложной логикой. Приступая к новому проекту, спросите себя, так ли нужен здесь Друпал, нельзя ли обойтись чем-либо попроще? Например, вы решили вести блог. Стоит ли качать Друпал, ставить на него и настраивать кучу модулей, если проще взять специализированный движок?
Любите Друпал не больше других средств разработки. Не зацикливайтесь на Друпале. Постарайтесь освоить несколько технологий, языков, фреймворков, КМС. С разнообразием приходит опыт. Заимствуйте удачные решения из одного проекта в другой. Старайтесь не привязывать удачные решения только к Друпалу. Например, если в модуле есть код рассылки смс, оформите его в отдельном файле и выложите на Гитхаб.
Комментарии из старого блога
08/19/12 jedi: Согласен со всем, жалко мало написали. Сам перехожу на yii
-
Победителя определяет скорость
Скорость разработки — это:
- один из основных критериев, определяющих профессионализм разработчка;
- главный аргумент в выборе тех или иных средств;
- решающий фактор в бизнесе как для стартапа, так и для транснационального гиганта.
Все три тезиса могут быть оспорены в непринужденной дискуссии, но утверждают себя на производстве — всё всем нужно вчера. В таких условиях программисту следует внимательнее отнестить к методологии и средствам разработки.
Для рутинных действий и автоматизации процессов хорошо подходит Питон — скриптовый язык с динамической типизацией. Он поддерживает множество парадигм, позволяет писать код так, как нужно именно вам. Например, если скрипт простой, вы сразу описываете рабочую логику, а не мусор вроде
public class Foo
иpublic static void main()
.С Питоном вы становитесь эффективнее. Работа с почтой, разбор и формирование XML, смс-рассылки, перегон данных из одного формата в другой, обработка офисных документов, чтение и запись DBF, COM-автоматизация, взаимодействие с сервисам Гугла, быстрые сайты на Джанго, работа с устройствами по серийному порту и уйма всего другого — это Питон. Плюс кросплатформенность, малый размер дистрибутива, пакетный менеджер (даже два — pip и pypm), масса библиотек на все случаи жизни. Плюс скорость.
Не бойтесь делегировать больше задач сторонним утилитам. Например, вы программируете сайт, и в какой-то момент требуется ужать и обрезать загруженное пользователем изображение. Или сгенерировать капчу. Или штрихкод. Или QR-код. Или Excel-книгу. Или отправить письмо. Стандартный подход — подключить модуль, просмотреть примеры, написать код. Вы потратили время, код увеличился.
Быстрый подход — задействовать консольную утилиту. Работа с изображениями — ImageMagick, генерация капчи — он же, отправка письма — sendmail или blat для Винды, работа с Excel — скрипт на VB Script, штрихкод — GNU Barcode, QR-код — Google Charts. И так далее.
Да, есть в этом подходе и минусы — проект становится зависим от стороннего ПО, использование утилит порождает внешние процессы, что значительно медленнее, чем вызов функций.
Однако, вы выигрываете в скорости разработки. Вы представите публике рабочую версию продукта быстрее, чем ваш конкурент — коллега или стартап. И у вас будет время на то, чтобы подключить нужные классы и заменить утилиты нативными API, в отличии от тех, чей прект вообще не вышел из тестирования.
Не бойтесь внедрять новые технологии. Роман Ворушин внедрил Джанго-систему в банке, где все было написано на Джаве. Иван Сагалаев принес Джанго в Яндекс. Я, не являясь специалистом такого уровня, внедрил Питон и Джанго в организации, где был только PHP и сервера на Винде.
Скорость очень убедительна.
-
Умирает ли РСС?
В последнее время в Сети то и дело пишут о том, что формат РСС умирает. Дескать, все продвинутые читают Твиттер и Гугл+, все актуальное и интересное там, а РСС для неудачников.
Поговорим об этом.
Чтобы развеять миф, озвученный в первом предложении, необходимо и достаточно ответить на два вопроса:
- Какие преимущества есть у РСС-лент?
- Что произойдет, если формат действительно умрет, и все сайты мира отключат РСС?
Преимущества
Во-первых, РСС — очень простой формат, обычная XML-ка.
Взгляните на официальный документ — структура совершенно прозрачна. Причем не обязательно соблюдать условности вроде тега
<title>
— современные приложения в состоянии разобрать даже самые невалидные ленты. Например, сайт slon.ru отдает ленту только с тегами<description>
,<link>
и<pubDate>
, что никак не мешает ее чтению.Во-вторых — открытость и минималистичность формата делает работу с ним очень удобной. Построение и парсинг XML — обычная рутинная задача веб-разработчика. Собрал XML и сохранил на диск — приложение пользователя само его заберет и распарсит. Никаких OAuth-танцев, токенов и авторизаций.
Третий пункт — практически каждый сайтовый движок, CMS, форум может генерировать РСС. Во многих движках есть ленты по отдельным авторам, тегам, комментариям к статьям, разделам форумов и даже поисковым запросам! Это же очень удобно — подписались на двух интересных авторов и читаете только их. Или отслеживаете комментации в интересной статье.
Четвертый — существет немыслимое количество приложений для чтения лент, для всех операционных систем и платформ. Читать можно в браузере, в десктоп-приложениях, в телефонах, планшетах. Немало сервисов основано на передачи данных из одного источника в другой именно в РСС-формате. Кросспост в Твиттер, Фейсбук и другие социальные сети основан на РСС-лентах. Сервис twitterfeed — абсолютный монополист в этой области — обслуживает на текущий момент свыше шести миллионов лент!
Пятый — в некоторые сайты помещают в ленту статьи целиком, а не только анонс. Если при этом в статье сохранены все теги, картинки и форматирование, то РСС-читалка становится полноценным браузером. Не нужно открывать сайт, загружать рекламу и баннеры.
Шестой — продвинутую читалку вроде Google Reader можно использовать как каталог избранных ссылок. На многих сайтах есть возможность помечать статью как избранную или добавлять в закладки (что по сути одно и то же). При этом они хранятся разрозненно: на Хабре — избранное только Хабра и т.д. Однако, если отмечать статьи в едином пространстве (в РСС-читалке), то поиск и просмотр избранных статей станет намного проще.
Представим, что РСС умер
Как теперь распростронять информацию с сайта, блога? Через Твиттер. Для того, чтобы организовать кросспост, владельцу сайта необходимо выполнить следующие шаги:
- зарегистрировать в Твиттере новое приложение;
- найти модуль для своей CMS или библиотеку для языка/платформы;
- все настроить, запустить, протестировать.
Хорошо, если сайт работает на какой-нибудь CMS вроде Дупала, Вордпресса или Джумлы. Для них модули уже есть. А как быть владельцам малораспространенных CMS или тем, чьи сайты работают на фреймворках или самописных движках? Уверены, что сможете все организовать сами? Действительно ли это проще, чем добавить ленту в twitterfeed?
Далее, при кросспосте нужно сокращать ссылки. Кто будет этим заниматься? Теперь ответственность лежит на вас. Регистрируемся в [Bit.ly]((http://Bit.ly), получаем открытый и закрытый ключи, качаем библиотеку для нужного языка, проходим OAuth-авторизацию и //только теперь// можем приступить к сокращению ссылок! Аналогично с Goo.gl: сперва включаем сервис в консоли API, получаем ключи, качаем библиотеки, читаем доки, авторизуемся и сокращаем. Уверяю, не все так просто. Тонкости работы с goo.gl я подробно описывал на Хабре.
Исходя из вышесказанного, можно с уверенностью предсказать возникновение сервисов, которые возьмут волокиту на себя. От нас только потребуется передавать информацию в удобном виде — вот заголовок, вот тело статьи, вот ссылка на оригинал. Формат, вероятно, XML — он лучше подходит для структурированных данных. И к чему мы пришли? Не к тому ли, что имеем — РСС и twitterfeed?
Не забываем, что размер твита ограничен 140 символами. Из них половина может уйти на заголовк статьи, плюс ссылка, плюс хэштеги и всё — упираемся в лимит. В итоге, полезность статьи можно оценить исключительно по заголовку, что, согласитесь, очень неудобно в сравнении с РСС.
И последний довод. Всю информацию, поступающую в Твиттер, можно разделить на два типа. Первый тип — то, что написано живыми людьми, неважно, при помощи какого приложения. Написал ли человек твит прямо на сайте, или отправил с телефона, или с Инстаграма — это первый тип. Такая информация отражает актуальные действия и мысли человека, т.е. прямо отвечает на вопрос-слоган «Что ты делаешь сейчас»?
Информация второго типа — та, что публикуется ботами и сервисами. В основном, это кросспост из блогов, новостных сайтов и сообществ вроде Хабра. Такая информация слабо привязана ко времени и имеет большую актуальность. Например, так ли важно, когда вы прочитаете новую техническую статью — спустя 10 минут, час или день после ее публикации?
Твиттер очень хорош для распространения актуальной информации первого типа. А со вторым типом он обращается плохо — информация тонет в сплошном потоке. Если ваш твит с ссылкой на статью не прочли в постоянно обновляемой ленте сейчас, то уже не прочтут никогда.
Твиттер не убил РСС-ленты, просто вытеснил их оттуда, где требуется скорость и актуальность. В остальном, РСС отлично справляются с задачей, заменить их нечем и не требуется.
Комментарии из старого блога
05/21/13 sheber: Отличный пост, спасибо. Кстати, Google Reader закрывается http://googlereader.blogspot.com/2013/03/powering-down-google-reader.html
-
Работаем с Твиттером
Как по-быстому связать приложение на Питоне с Твиттером?
Ответ — подключить библиотеку oauthtwitter.
Почему не python-twitter? Потому что первая гораздо меньше по объему кода и числу зависимостей от дополнительных модулей: 300 строк кода против 4000!
Установим необходимые библиотеки:
pip install ouath2 pip install httplib2 pip install simplejson
Для работы с Твиттером нужно зарегистрировать приложение. Твиттер позволяет указывать ссылки вида
localhost
или127.0.0.1
в поле «Callback URL», что очень полезно при разработке на локальной машине.Consumer key — это открытый ключ приложения, что-то вроде логина. Consumer secret — закрытый ключ, которым подписываются запросы к Твиттеру. Если вы где-то опубликовали его, немедленно смените в настройках приложения.
Авторизация в Твиттере проходит в несколько шагов.
Шаг 1: запрос на авторизацию
import oauthtwitter CONSUMER_KEY = "key" SECRET_KEY = "secret" # Инициализация клиента по ключам def sign_init(request): client = oauthtwitter.OAuthApi(CONSUMER_KEY, SECRET_KEY) # Уникальный токен, действительный только для одной авторизации request_token = client.getRequestToken() # Сохраняем токен в сессию пользователя. Можно сохранить на диск или в БД request.session["request_token"] = request_token # Получаем уникальный адрес авторизации на основе токена url = client.getAuthorizationURL(request_token) # Перенаправляем пользователя на страницу ввода пароля return redirect(url)
Шаг 2: ввод логина и пароля на стороне Твиттера
Шаг 3: возврат пользователя на ваш сайт
После авторизации пользователь будет направлен обратно на ваш сайт. Напомню, что в приложении на стадии тестирования у нас указано что-то вроде
http://localhost:8080/twitter/callback
По этому адресу должен быть обработчик, который завершит процесс авторизации.def sign_callback(request): # Извлекаем сохраненный ранее в сессии токен. # Если токена нет, то пусть начинает всё с начала. request_token = request.session.get("request_token") if not request_token: add_message(request, ERROR, u"Request token not found.") return redirect(frontpage) # Ключ валидации запроса из командной строки. oauth_verifier = request.GET.get("oauth_verifier") if not oauth_verifier: add_message(request, ERROR, u"OAuth verifier not found.") return redirect(frontpage) # Снова инициализируем клиента client = oauthtwitter.OAuthApi(CONSUMER_KEY, SECRET_KEY) # Извлечени параметров доступа access_token = client.getAccessToken(request_token, oauth_verifier) print access_token >>> { 'oauth_token_secret': 'xTbNbG0IcUGgng9pyNdy******************', 'user_id': '123123123', 'oauth_token': '78741204-cLgfThwKXuqudeXGTQP***********************', 'screen_name': 'username' }
Отлично! Как видно, access_token представляет из себя словарь со всеми нужными данными: идентификатором и именем пользователя, открытым и закрытым ключами доступа.
Дальнейший сценарий зависит от архитектуры вашего приложения. Например, на основании screen_name заводится новый пользователь (или извлекается имеющийся). Оба ключа записываются в профиль пользователя. Теперь можно работать с Твиттером:
# Инициализация клиента с ключами приложения и пользователя client = oauthtwitter.OAuthApi(CONSUMER_KEY, SECRET_KEY, user_oauth_token, user_oauth_token_secret) # Извлечение твитов пользователя timeline = client.GetUserTimeline() # Твитнуть сообщение client.UpdateStatus("Python testing") # Получить фолловеров timeline = client.GetFollowers()
И так далее, список всех методов ищите в коде класса. Очень доволен этой библиотекой, использую ее в двух проектах.
Комментарии из старого блога
02/11/13 Майя Любимая: я ничего не понимаю
02/20/13 Иван Гришаев: То же самое могу сказать о вашем комментарии.