Archive for 'devel'

Django+FastCGI+nginx

Если django (да пожалуй и другие фреймфворки и не только на питоне) работает через fastcgi и проксируется nginx’ом по https, то последнему нужно добавить параметр:
fastcgi_param HTTPS on;

Posted on 19 March '09 by spoof, under comp, devel, django, unix. No Comments.

Дружим django и экспорт в Excel

И так, мы хотим, чтобы пользовал клацнув на кнопочку “Экспорт в Excel” получил это документ и был доволен. Что может проще скажете вы – взять положить файл в каталог и тупо его HTTP сервером отдавать. Но не все так просто в случае если вам необходимо, чтобы этот файл генерировался динамически (из-за меняющихся в нем данных), например django, на котором крутиться сайт.

Насколько мне удалось узнать, в мире существует один адеватный генератор Excel файлов – xlwt, который можно юзать на Unix системах. Это клон pyExcelator’a, но лучше подходит для django и сохранения не в файл. С документацией у него беда, но парочку линков все же нашел: обзор и пример.
Кроме того, примеры есть и в тарболе с pyexcelator’ом или в самом xlwt.

И так создаем во views.py приложения django функцию, которая будет возрвращать xls файл:

def export_xls(request):
wb = Workbook() # создаем основной документ
sheet = wb.add_sheet(’sheet1′) # добавляем лист (должен быть как минимум 1 лист)
# далее идут действия по добавлению данный на лист
# это нам не интересно в данном контексте

Но это еще не все. Далее нам нужно этот документ каким-то образом передать пользователю. Отсюда вытекают 2 проблемы или вопроса:

  1. Как же собственно преобразовать объект типа Workbook в строку (читай stream). По идее же должен быть какой-то метод save или что-то подобное. Да, есть, но в случае использования pyExcelator’a метод save предполагает сохранение в файл, но не в переменную как нам надо. В xlwt метод save() более гибкий. Ниже расскажу
  2. И как дать этому “файлу” человеческое имя, если у нас данные для генерации xls файла передаются через GET/POST параметры. При таком раскладе у нас файл будет называться последним “нодом” url’a, на который ведет ссылка. Например, если ссылка: http://bla.com/bla/export_xls?bla&bla=2, то файл будет называться export_xls, что не есть гуд

Начну пожалуй со второй проблемы, ибо она решается довольно просто. Если залезть в RFC 2183, то можно узнать про интересное поле в HTTP заголовке – Content-Disposition, которое то и позволит присвоить имя файлу через присвоение ему типа attachment с параметром filename. Для Django это будет выглядеть так:

response = HttpResponse(xls, mimetype=”application/vnd.ms-excel”)
response['Content-Disposition'] = ‘attachment; filename= %s’ % (filename)
return response
# здесь xls – фактически представляет собой переменную с содержимым Excel файла,
# filename – название файла, которое мы должны задать ранее

И так, для решения первой проблемы (в случае если используется pyExcelator) я порылся в коде pyExcelator’a и выкопал следующее. Оказывается метод save() класса Workbook делает следующее:

def save(self, filename):
import CompoundDoc
doc = CompoundDoc.XlsDoc()
doc.save(filename, self.get_biff_data())

CompoundDoc.XlsDoc() собственно и представляет собой обертку над бинарными данными, который сгенерировал Workbook (их получаем с помощью self.get_biff_data()). Как раз после save() класса CompoundDoc.XlsDoc() и получаем конечный Excel документ. Но смотрим далее в метод save() этого XlsDoc‘a:

def save(self, filename, stream):
# 1. Align stream on 0×1000 boundary (and therefore on sector boundary)
padding = ‘\x00′ * (0×1000 – (len(stream) % 0×1000))
self.book_stream_len = len(stream) + len(padding)
self.__build_directory()
self.__build_sat()
self.__build_header()
f = file(filename, ‘wb’)
f.write(self.header)
f.write(self.packed_MSAT_1st)
f.write(stream)
f.write(padding)
f.write(self.packed_MSAT_2nd)
f.write(self.packed_SAT)
f.write(self.dir_stream)
f.close()

Как видно, опять, тут идет работа с файлов. Слава богу это конечный пункт сохранения файла, поэтому смело овверайдим эти два класса для работы с Django:

class XlsDoc(CompoundDoc.XlsDoc):
def get(self, stream):
padding = ‘\x00′ * (0×1000 – (len(stream) % 0×1000))
self.book_stream_len = len(stream) + len(padding)
self.__build_directory()
self.__build_sat()
self.__build_header()
return ‘%s%s%s%s%s%s%s’ % (
self.header,
self.packed_MSAT_1st,
stream,
padding,
self.packed_MSAT_2nd,
self.packed_SAT,
self.dir_stream)
class Workbook(Workbook):
def get(self):
doc = XlsDoc()
return doc.get(self.get_biff_data())

Вставляем этот код в views.py нашего приложения и в коде нашей функции export_xls() после создания и генерации данных пишем:

xsl = wb.get()

Здесь wb – это WoorBook из первого листинга (но это не тот Workbook, что из pyExcelator’a, а наш, который мы переопределили).
Вот собственно и все. Небольшая компиляция собранных с краев интернета кусочков. Может и есть какой-то более прямой способ.
UPD В случае использования xlwt все проще. Юзаем:

import cStringIO
xls = cStringIO.StringIO()
..
wb.save(xls)
response = HttpResponse(xls.getvalue(), mimetype=”application/vnd.ms-excel”)

Posted on 23 October '08 by spoof, under comp, devel, django, python. 1 Comment.

Mercurial tips

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

  • hg init new_repo

    В этой же директории где лежит и старый репозитарий old_repo, который требуется разделить.

  • Создаем файл filemap.txt, в котором задаем те директории, которые надо включить в новый репозитарий:
    exclude “*”
    rename “subdir” “.”
    include “subdir”

    Т.е. игнорируем все файлы из old_repo, переименовываем subdir в “.”, чтобы эта директория стала корнем new_repo и включаем ее в копирование

  • Выполняем команду:
    hg convert –filemap filemap.txt old_repo/ new_repo/
  • cd new_repo && hg update

Собственна все, далее можно из old_repo удалять subdir:

cd old_repo && hg remove subdir

Posted on 11 July '08 by spoof, under devel. No Comments.

Some tips

  1. Переезжаем с automake 0.9x на 1.10:
    for file in $(find . -name “Makefile.am” -type f); do sed -e ’s/INCLUDES/AM_CPPFLAGS/g’ $file > $file-tmp; mv $file-tmp $file; done;
  2. Удаляем все каталоги .svn из сырцов:
    find . -name “.svn” -type d -exec rm -rf {} \;

 

Posted on 18 June '08 by spoof, under devel. No Comments.

Mysql tricks

Два дня минус почти просто так. Были потрачены они на поиск баги в моем питоньем скрипте, который р аботает с MySQL. Работа эта заключается в получении данных и распихивании их по словарикам (питоний). Так вот, было замечено, что для двух одинаковых значений ключа создается 2 записи в словаре (какого ху…дожника?!). При более внимательном рассмотрении было выяснено, что эти два якобы одинаковых ключа на самом деле разные, а разные они в регистре одной буквы. При запросе из MySQL возвращалось 2 значения вместо одного – отсюда возникали глюки. А все потому, что MySQL по-дефолту при сравнении строк не учитывает регистр, если не указаны collations для поля/таблицы в *_bin или *_cs. Век живи – век учись. Это конечно должно было известно быть – оно мне и было известно, но я об этом успешно давно забыл, ибо уже не помню когда последний раз с этим сталкивался. Взято отсюда 

Posted on 21 April '08 by spoof, under devel. No Comments.

Блоговое

Похакал немного текущую тему для блога. Прикрутил к ней сайдбар с виджетами и подогнал к общей стилистике. Вроде ничотак, а вы как думаете? Но немного жаль потраченного часа – слишком уж много заморочек с CSS. Благо Inspector в Safari сильно помогает в разборе.

Posted on 10 April '08 by spoof, under blog, devel. No Comments.

Некоторые замечания на память

Про MySQL и SQL.
  1. COUNT(*) быстрее чем COUNT(`field`) 
  2. INSERT … VALUES (), () … () быстрее кучи INSERT’ов
  3. Глядя на второй пункт не стоит забывать про параметр MySQL - max_allowed_packet, который ограничивает размер одного SQL запроса.

Posted on 8 April '08 by spoof, under comp, devel, заметки. No Comments.

Про индусов

Если вы программист, или какое-то отношение к ним имеете, то вы наверно встречали индусов, а точнее “индусов”. А именно тех еб^Wнехороших людей, которые пишут совершенно отвратный код. Так о чем это я. Короче, устал я от ковыряния кривоработающих компонентов своих проектов – будь это что-то рабочее или “быдлокодерское” (фрилансерское). А устал именно от того, что эти компоненты написаны тяп ляп и постоянно убиваешь кучу времени на то, что фиксишь баги в этих компонентах или адаптируешь их под себя. Я бы сказал немеряно времени, бывает, что сильно больше, чем реализация чего-то непосредственно касамеого самого проекта.
(more…)

Posted on 11 October '07 by spoof, under comp, devel, modx, wordpress. No Comments.

Лень в топку. Даешь прогресс!

Finally, поборол свою лень и занялся сайтами, в том числе и своим блогом. К своему блогу прикрутил categories cloud widget (уж очень нравицца) и плагин del.isio.us, который стягивает последние ссылки с моего аккаунта на одноименном сайте. Widget…слово то какое. Короче это новая фича, которая идет в 2.2 и была доступна в качестве плагина для wordress’a версий ниже. Если у Modx это называется snippet, у Joomla – модуль/компонент, то тут это те же яйца, только вид сбоку. Хотя это грамотное решение проблемы постоянной правки шаблонов/templates дизайна – тупо перетащил нужный widget в понравившееся место на sidebar’e (жаль, что только на sidebar’e) и юзаешь на здоровье и никакой правки шаблона.

Вот бы таким же образом сделали openid “авторизацию”, чтобы возможно было комментировать. Сейчас же опять надо менять это в шаблоне. Шаблон, кстати тоже поменял, но это временно, ибо он мне не нравится, но лучше ничего не нашел.

Продолжил работу над сайтом Ragga-Jungle.Ru. Первоначально задумывалось сделать это всё на движке Joomla, но оказалось, что это настолько запутанная CMS, что возникает вопрос : что курили разработчики этой cms, когда ее создавали? Я знаю, что корни идут от Mambo, но тем не менее.

Короче, вернулся на Modx, который показался мне наиболее удобным и понятным для создания того, что требуется. Переход правда связан с потерей интеграции всех модулей друг с другом. Надо пилить руками – но хотя бы понятно, что куда и зачем. Modx однозначно рулит! За 2 дня я сделал больше, чем за неделю (если быть точным за два вечера против пяти вечеров).

И еще.. Cи++ постепенно съедает мой моск и время :)

upd: Таки пришлось мне править шаблон руками. Ссылка home была битая и вела на текущую страницу всё время. В коде надо было заменить $url  = get_option(’wpurl’) на $url = get_bloginfo(’url’); Видимо это wordpress 2.x specific “фича”.

Posted on 2 August '07 by spoof, under comp, devel, life, spylog, wordpress. 1 Comment.

Summary of the last week

Закончились 2 достаточно сложных недели, в течение которых было очень очень мало свободного времени. Подведу небольшой итог:

  1. Почти всё время убил типовой расчет (хотя это скорее больше курсовой или даже 2 курсовых проекта). Куча бессоных ночей, куча невыпитого пива и куча времени, которое я должен был потратить на работу. Типовой расчет по предмету “Модели и методы анализа проектных решений”. Задача – написать планировщик задач, используя алгоритмы и приемы. которые нам начитал завкаф. В общем, получилось порядка 1300 строк питоньего кода. Если б не питон, то это число раза в 2-2.5 возросло бы. Короче, слава богу, что это сдали. Остается теперь готовится к экзамену по всему этому. Еще надо сделать курсач по базам данных, курсовой по МДС, штук 5 типовых по Искусственному интеллекту – короче сессия скоро.
  2. На работе закончил писать скриптик на питоне, который лопатит кучу больших файлов. Кроме того только сейчас осилил true way использования тредов и соотвественно приделал его к этому скрипту. Некоторые полезные ссылки по этой и другим темам есть у меня в del.icio.us
  3. Обновил wordpress с 2.1.3 до 2.2 версии. Приделал к нему кучу плагинов. Например, akismet, который за несколько дней словил порядка 100 спамных камментов и не пропустил ни одного спамного. Пока спама нет, тьфу тьфу тьфу. Еще поставил плагин codesnippet, с помощью которого удобно выводить куски кода (долго искал, кстати). Понравилось в этой версии wordpress’a, что есть такая штука Widgets (раньше ставился как плагин, а теперь это в ядре), которая позволяет управлять всякими “элементами” блога для вывода на страницу. Можно например Tags и Categories менять местами, отключать… Теперь для этого не надо в теме копаться. Еще хочу вместо тупого списка тэгов tag cloud :) модняво. И надо всё же тему поменять, а то эта надоела.
  4. На днях таки ощутил всю прелесть весны и тепла, валяясь с пивом тихим теплым вечером на травке на Котельниках. Шикарно, хочу еще :)
  5. После месячного перерыва снова начал играть в кваку. Ибо наконец-то появилось немного свободного времени и удачно в дебиановский репозиторий попали nvidia legacy дрова для моей видеокарты – nvidia-glx-legacy-96xx. Правда и тут не обошлось без бубна. Модуль к ядру 2.6.20 от этих дров не хочет собираться. При сборке сваливается с ошибкой:
    More info, building fails because:
    FATAL: modpost: GPL-incompatible module nvidia.ko uses GPL-only symbol ‘para
    virt_ops’ .

    Решение отсюда помогло.

Posted on 18 May '07 by spoof, under blog, debian, devel, life, spylog. No Comments.