Блог Рагимова Романа

 

Aspen Player и Kinobaza.tv

Я думаю, пришло время подумать об отказе от Kinobaza.tv в качестве источника информации о фильмах, т.к. со своей ролью она совершенно не справляется. Вот, что на данный момент отображается в списке эпизодов Теории Большого взрыва:

Отсутствие информации о сериале на Kinobaza.tv

А между тем, на TVRage, для уже вышедших(!) серий, доступны не только названия, но даже screencaps.

Проблема же заключается в полном отсутствии у Kinobaza конкурентов. Kinopoisk не подходит по причине отсутствия API, IMDB по той же причине + проблемы с русским языком. Да, для сериалов можно использовать API MyShows.ru, благо оно тоже бесплатное и даже, в некотором смысле, проще представленного в прошлом году официального API Kinobaza.tv. Но у MyShows есть одна проблема, которая не позволяет полностью отказаться от Kinobaza в Aspen Player — отсутствие поиска по полнометражным фильмам.

Вот и сижу я, размышляю, как бы решить данную проблему? Ну не свою же базу организовывать, в самом деле.

Производительность библиотек для парсинга JSON в Python

В одном из проектов потребовалось парсить достаточно объемные JSON файлы, отдаваемые API. Примерный размер файла 6 Мб и около 50000 записей. Стандартная библиотека работала достаточно неспешно и я решил сравнить производительность предлагаемых альтернатив.

Тестирование проводилось на виртуальной машине Ubuntu 10.10 32bit. Возможно, на 64 bit результаты будут отличаться. Время выполнения измерялось с помощью timeit.repeat(repeat=10, number=10) с последующим усреднением.

Библиотека parsing parsing + serialization
simplejson 2.162 5.182
cjson 2.395 7.851
ujson 2.416 5.524
py-yajl 3.830 Killed
jsonlib 4.081 10.155
json 5.209 9.764

Как видите, самой быстрой реализацией на данный момент является simplejson. Следом за ним идут cjson и ujson. cjson немного быстрее при парсинге, но значительно проигрывает при сериализации обратно в строку. Все три библиотеки примерно в два раза быстрее стандартного модуля json.

py-yajl, несмотря на заверения авторов обертки, во-первых, оказалась значительно медленнее нативных библиотек, во-вторых, была достаточно сложна в сборке и установке, ну и в-третьих, выдала «killed» в качестве результата теста на парсинг-сериализацию.

Решение проблемы «Ошибка 403» в Pingdjack

Во время работы с библиотекой pingdjack от Ивана Сагалаева, обнаружилась досадная особенность, не отраженная в документации, но доставившая мне немало хлопот.

Ввиду того, что в последних версиях django по умолчанию включена защита от CSRF, система со включенным CSRFMiddleware выдает ошибку 403. Решить это можно двумя путями:

Во втором варианте в файл server.py требуется добавить следующее:

# в начале файла
from django.views.decorators.csrf import csrf_exempt

# Добавить @csrf_exempt между @require_POST и def server_view
@require_POST
@csrf_exempt 
def server_view(request, root='/'):

Второй метод выглядит предпочтительнее, т.к. маловероятно, что пингующий сайт вдруг, внезапно, возьмет откуда-то требуемый CSRF-токен, а следовательно CSRF защита для данного участка кода бессмысленна.

Google Analytics + gdata + Django = ранжируем посты по популярности

Когда я переписывал движок блога на django, мне захотелось получить список популярных постов за последний месяц. Причем список должен был строиться не по каким-то там эфемерным «плюсикам» к посту, а по количеству просмотров. На помощь пришел Google Analytics с его мощным API и обертка gdata для Python.

Итоговый код выглядит примерно так:

from django.core.urlresolvers import resolve, Resolver404
from datetime import date, timedelta
from blog.models import Entry # модель отвечающая за записи в блоге. Содержит поле popularity для хранения количества просмотров.
import gdata.analytics.service
import blog.views

client = gdata.analytics.service.AnalyticsDataService()
client.ClientLogin("user@gmail.com", "password")
# далее мы строим таблицу просмотров страниц по пути до данной страницы
data = client.GetData("ga:profileId", dimensions="ga:pagePath", metrics="ga:pageviews", start_date=(date.today() - timedelta(30)), end_date = date.today(), sort="-ga:pageviews")

for de in data.entry:
    try:
        view, args, kwargs = resolve(str(de.pagePath))
        if view == blog.views.entry:
            try:
                e = Entry.objects.get(slug = kwargs["slug"])
                e.popularity = int(str(de.pageviews))
                e.save()
            except Entry.DoesNotExist:
                pass
    except Resolver404:
        pass

Если в не знаете своего ga:profileId, то можете получить его, выполнив следующий код:

import gdata.analytics.service
client = gdata.analytics.service.AccountsService()
client.ClientLogin('user@gmail.com', 'mypassword')
accounts = client.GetAccountList()
for account in accounts.entry:
    print '%s profileId: %s' % (account.title.text, account.profileId)

ActionScript3 Selector Library для Adobe AIR

Набросал некое подобие библиотеки селекторов на AS3 для использования в Adobe AIR. Фактически это означает возможность разбирать HTML документы с помощью запросов к DOM, а не длинными непонятными RegExp.

К примеру, получение всех заголовков Habrahabr выглядит так:

import com.unrarme.utils.Aquery;
private var aq:Aquery;

private function getHeaders(); {
    aq = new Aquery(new URLRequest("http://habrahabr.ru/"));  
    aq.addEventListener(Event.COMPLETE, onHTMLLoadComplete);   
}

private function onHTMLLoadComplete(e:Event):void {
    var headers:Array = aq.select("h2 a.topic");  
    for each (var header:Object in headers) { trace(header.innerText); }  
}

Достаточно просто, как мне кажется.

Библиотека дописывается «по ходу», так что не стесняйтесь писать в Issues Tracker.

Исходники на GitHub (я в курсе качества кода, но предпочитаю не париться до момента, когда низкая производительность станет критичной)

← Старое