Работа

У меня есть два сообщения про работу.

1)Ищу удалённую работу. Умею делать сайты на django и писать скрипты на python. Вот здесь можно прочитать что-то типа резюме: lorien.name/resume.html

2) Сегодня с утра набросал сайтик pyjob.ru. Почти что русский клон djangogis.com, за исключением того, что я не стал делать каталог разработчиков т.е. pyjob.ru — это просто список вакансий. На данный момент список пустой. Буду прилагать усилия в направлении его наполняемости.

Если у вас есть какие-то предложения по первому или второму пункту, то мой email/jabber: lorien@lorien.name

UPD: Объявление о поиске работы уже неактуально.

djangodash.com в разгаре

Прошли первые сутки :-) Нам с севеновым удалось изобразить такое: http://djapp.org — завтра будем допричёсывать. А что это ваще такое? Ну это такой каталог django-приложений — типа djangopluggables.com но с претензией на удобство использования. Для начального наполнения я написал скрипт для парсинга pypi и вытащил оттуда всё, что искалось по запросу django и худо-бедно рассовал по категориям. Кстати, подобрать категории -очень сложная задача :(

Распараллеливание заданий

В питоне есть модуль threading, позволяющий одновременно выполнять несколько заданий. Часто бывает так, что количество допустимых потоков меньше, чем количество заданий. Например, при работе с сетью мы упрёмся в ширину канала, при вычислениях мы упрёмся в скорость процессора или в GIL.

Для такой задачи я написал удобный код, суть которого это выполнение X заданий в Y потоков. До изобретения велосипеда я пробовал threadpool библиотеку, но она выдавала странные эксепшны время от времени и я углядел в этом знак свыше — боги одобряют очередной велосипед.

Так появился этот код: http://dumpz.org/8724/. Модуль содержит единственную функцию

def make_work(callback, tasks, limit, results=None):

Для каждого задания запускается callback, одновременно запускается не более, чем limit потоков. Если нужно сохранять выхлоп callback’ов, то создаём объект Queue и передаём в аргументе results. Аргумент tasks может быть или объектом Queue или tuple или list. В последних двух случаях он автоматически преобразовывается в Queue.

UPD: Порефакторенная с учётом заменчаний версия make_work: http://dumpz.org/10066/

Анонсы двух мероприятий в python мире.

Хочу рассказать о двух событиях, которые произойдут в ближайшее время.

На 6 июня запланирована RuPyRu 2009. Это конференция по python и ruby, ежегодно проходящая в начале лета в г.Омске. Подробности о мероприятии можно узнать из сообщения её основателя и главного организатора Юры Юревича RuPyRu 2009: ищутся участники.

Напоминаю, что для конференции создана google группа: rupyru-discuss, где можно задавать, интересующие вас вопросы.

Второе событие — это djangodash.com. Дата начала — 30 мая. Djangodash — это соревнование, суть которого сделать с нуля за 48 часов сайт на джанго. Мы там будем с sevenov одну штуку мутить. Вот наша команда Code monkeys :-)

Предлагаю всем питонерам проявить активность и по мере сил и возможностей принять участие в том или ином мероприятии :-)

wgetpaste & dumpz.org

Сегодня в качестве разминки мозга сделал поддержку dumpz.org в программе wgetpaste. Это такая консольная утилитка, написанная на bash, которой для работы нужны только стандартные утилиты.

# A Script that automates pasting to a number of pastebin services
# relying only on bash, sed, coreutils (mktemp/sort/tr/wc/whoami/tee) and wget

Что умеет программа можно понять из —help вывода http://dumpz.org/8213/

Пока разбирался в сорцах проги узнал много нового про bash scripting language. Например, мне теперь понятна галиматья типа этой:

# generate POST data
postdata() {
    local post nr extra f
    post=POST_$ENGINE
    nr=${!post//[^ ]}
    [[ 6 = ${#nr} ]] || die "\"${SERVICE}\" is not supported by ${FUNCNAME}()."
    extra=${!post%% *}
    [[ '%' = $extra ]] || echo -n "$extra&"
    e() {
        post="$1"
        shift
        while [[ -n $1 ]]; do
            f=${post%% *}
            [[ '%' != $f ]] && echo -n "$f=${!1}" && [[ $# -gt 1 ]] && echo -n "&"
            shift
            post=${post#$f }
        done
    }
    e "${!post#$extra }" NICK DESCRIPTION LANGUAGE EXPIRATION CVT_TABS INPUT
}

Сейчас сижу и прусь от этого :-)

Сайт программы (если это можно назвать сайтом) тут: http://wgetpaste.zlin.dk/ Патченную версию (для dumpz.org) можно скачать тут: http://dumpz.org/8211/

Chromium в Debian

Сегодня решил почитать, чего там на хабре пишут, вычитал интересную новость, что уже доступны deb-пакеты chromium для ubuntu. Как показал эксперимент, в Debian их тоже можно поставить.

Алгоритм:

1) Добавить в /etc/apt/sources.list

deb http://ppa.launchpad.net/chromium-daily/ppa/ubuntu intrepid main

2) Настроить какой-то ключ, я толком не знаю, что это :-)

sudo su —
gpg --keyserver subkeys.pgp.net --recv-keys 5A9BF3BB4E5E17B5
gpg --armor --export 5A9BF3BB4E5E17B5 | apt-key add —

3) Сделать sudo apt-get update

4) Сделать sudo apt-get install chromium-browser

Скриншот: http://it-omsk.com/pub/ca2150967df20021ca6e6f8d1718dda9.png

Особо не лазил по инету. Открыл пару страничек — работает весьма шустро.

Ускоряем работу debug-сервера

Django debug сервер, который запускается через ./manage.py runserver, работает достаточно неторопливо. Это особо ощущается, когда он обслуживает запросы к статике. Конечно, такой подход удобен тем, что при разработке не нужно поднимать каких-то дополнительных серверов, но иногда эта канитель начинает раздражать. Дабы не тратить попусту нервы и время, можно возложуть груз ответственности за статику на плечи _____ (вписать имя вашего любимого веб-сервера).

Для начала создадим в /etc/hosts строку: 127.0.0.1 foobar.local

Далее, в settings_local.py пропишем:

MEDIA_URL = 'http://foobar.local/media/'
STATIC_URL = 'http://foobar.local/static/'

Потом идём в конфиг nginx и создаём новый сервер:

server {
    server_name .foobar.local;
    root /web/foobar; # это корень проекте, вернее каталога где лежит static каталог

    location /static {}
    location /favicon.ico {}

    location / {
        proxy_pass http://localhost:8000;
    }
}

Теперь запускаем debug сервер и радуемся — все запросы на статику обрабатываются боевым сервером :-)

Ещё один велосипед — блогодвижок djaba

Неделю назад меня торкнуло вести блог переводов англоязычных публикаций на SEO тему. В лучших традициях велосипедостроения я решил написать для блога новый движок. На Django, конечно. И написал же :-) Скорее всего, я даже на него веб-мозги переведу в будущем, когда фунционал до концидии догоню. Сейчас блог работает на byteflow, но я его немного побаиваюсь. Какой-то он большой — это меня угнетает :-)

Сайт проекта: http://bitbucket.org/lorien/djaba/

Блог умеет на данный момент:

  • markdown разметка постов и комментариев
  • авторазметка plain text ссылок
  • запоминание персональных данных комментаторов в форме комментирования. Комментирование доступно пока только в anonymous-режиме с указанием имени, емайла, сайта.
  • автопинг блог-директорий и поисковиков при написании нового поста.
  • тэги
  • <—more—> фича
  • генерация sitemap
  • фиды постов и комментариев

Основная идея движка: простой и удобный способ делиться информацией с другими людьми. Будет сделан уклон на средства продвижения блога. Например, уже сейчас работает пинг директорий и сайтмап.

Вот так всё простенько :-) Подивиться на велосипед можно на сайте работающего блога переводов статей о поисковой оптимизации сайтов

Yandex & django sitemap

Сегодня столкнулся с тем, что yandex выдавал ошибку, когда я пытался скормить ему sitemap.xml через http://webmaster.yandex.ru/. Причина отказа, как было установлено, долгая генерация файла с картой сайта. Проблема решается просто: нужно кэшировать генерируемый sitemap: предварительно записать его в кэш и затем уже скармливать яндексу.

Если на сайте кэширования ранее не было вообще, то самый простой способ настроить кэш — это использовать файловый backend.

Пишем в settings.py:

CACHE_BACKEND = 'file:///tmp/domain.com'

В файле urls.py заворачиваем генерацию sitemap в cache_page декоратор

from django.views.decorators.cache import cache_page
from django.contrib.sitemaps.views import sitemap

from project.sitemaps import ProjectSitemap

sitemaps = {
    'site': ProjectSitemap,
}

urlpatterns = patterns('',
    (r'^sitemap.xml$', cache_page(sitemap, 60 * 30), {'sitemaps': sitemaps}),

linkfeed.ru & python

Захотелось мне пощупать linkfeed.ru биржу ссылок. Поэтому пришлось писать python-адаптер. Как оказалось биржа вполне себе прогрессивная — возможно забирать базу данных в виде XML. Даже какой-то SOAP API есть для оптимизаторских контор.

Если кому нужно, адаптер можно взять тут: hg.pydev.ru/linkfeed. Код пока очень сырой — я его минут 10 назад написал :-) Как пользоваться написано в README