воскресенье, 16 декабря 2012 г.

Ubuntu server 320+ mb of ram free

В убунту сервере, например 12.04 есть такой непонятный процесс, под названием whoopsie. Это крэш репортер... Так вот памяти жрет он немеряно, у меня на облачном rackspace была загрузка 385Мб памяти, хотя вращался nginx и все. После анализа процессов по htop увидел что жрет память как раз вышеназванная какашка. Пишем:
service whoopsie stop
И вуаля - 65Мб занято...
Вот так резко повышаем кол-во занятой памяти :)

суббота, 30 июня 2012 г.

Show git/hg/svn info in bash/zsh promt.

Очень удобно когда заходишь в папку с репозитарием и в промте отображается текущая ветка и еще дополнительная информация.
Выглядит это так:




либо







скачать .zhsrc или .bashrc

пятница, 11 мая 2012 г.

django youtube video template filter

Немного переделал http://djangosnippets.org/snippets/858/ под свои нужды. Теперь фильтр выковыривает ссылки из текста (раньше фильтр обрабатывал только одну ссылку) и вставляет как oembed объект. Можно задать длину-ширину опционально: {{ content|youtube:"320x240" }} по дефолту 320x240.

# -*- coding: utf-8 -*-

from django.template.defaultfilters import stringfilter
from django import template
import re

register = template.Library()

@register.filter
@stringfilter
def youtube(url, size=None):
    regex = re.compile(r".*(http://)?(www\.)?(youtube\.com/watch\?)?v=(?P[A-Za-z0-9\-=_]{11})(\&)?.*", re.UNICODE)
    match = regex.match(url)
    if not match: return url
    video_id = match.group('id')
    
    video_w = "320"
    video_h = "240"
    if size and "x" in size:
        (video_w, video_h) = size.split('x')
    
    youtube_iframe = """
    <iframe src="http://www.youtube.com/embed/%s?fs=1&feature=oembed" frameborder="0" allowfullscreen width="%spx" height="%spx"></iframe>
    """ % (video_id, video_w, video_h)
    
    repl = re.compile(r"(http://)?(www\.)?(youtube\.com/watch\?v=)?(?P[A-Za-z0-9\-=_]{11}[^\b]*)", re.UNICODE)
    text = re.sub(repl, youtube_iframe, url)
    return text
youtube.is_safe = True # Don't escape HTML

вторник, 20 марта 2012 г.

jqcanvas positioning bug

http://code.google.com/p/jqcanvas/
Когда попытался встроить в проект канвас отрисовался не понятно где, но вообще не там где надо. Position:relative, absolute и т.д. ничего не давало. Пришлось залезть немного в код плагина и заменить:
            var top = $this.offset().top;
            var left = $this.offset().left;
в строках 36 и 37 на
            var top = $this.position().top;
            var left = $this.position().left;
После чего все встало на свои места. :)

вторник, 28 февраля 2012 г.

Django fulltext search aka fieldName__search + relevance

Вот такая коротенькая заметка: если надо сортировать результаты поиска по релевантности (когда пытаемся сделать полнотекстовый поиск) делаем следующее:
pages = Page.objects.filter(content__search=q).extra(select={
        'relevance': ur"MATCH (content) AGAINST('%s' IN BOOLEAN MODE)" % q
    },where=[
        u"MATCH(content) AGAINST('%s' IN BOOLEAN MODE)" % q
    ]).order_by('-relevance') 
 

Ну и само собой мы можем использовать релевантность как то так pages[0].relevance
Также не забываем сначала создать fulltext index на поле(я) по которым будем искать.

воскресенье, 26 февраля 2012 г.

Сниппеты в django как в MODx или пишем свою middleware

Я думаю многие используют flatpages или что то похожее в своих django-проектах и многим из вас не хватало динамически генерируемых кусочков внутри страниц. Кто знаком с MODx наверное уже понял в чем дело :) Там есть очень удобные штуки внутри страницы можно вставить "метку" типа [[*snippet_name]] и она заменяется на результат выполнения кода, который лежит в т.н. сниппете.
Мною это реализовано через middleware которую я вам и представляю :

file: your_project_folder/middlewares/template_injector.py
# -*- coding: utf-8 -*-
from django.conf import settings
import re

class TemplateInjector(object):
    
    def process_response(self, request, response):
        #return if admin
        if request.get_full_path().startswith('/admin'):
            return response
                
        functions = re.findall(r'{{{(.*?)}}}', response.content)
        
        #if no template vars return response
        if len(functions) == 0:
            return response
        
        #apply funciton to every match found
        for fn in functions:
            try:
                imported = __import__(settings.TEMPLATE_INJECTOR_INCLUDES + '.' + fn)                
                result = eval('imported.' + fn + '.' + fn + '()')
                response.content = re.sub(r'{{{%s}}}' % fn, result, response.content)
                result = imported = None
            except ImportError:
                response.content = re.sub(r'{{{%s}}}' % fn, '', response.content)
            
        return response

Проверяет чтоб находились не в админке, чтоб не изменить контент при редактировании :)
Находит все кусочки текста находящиеся между {{{ и }}}
Проходит в цикле по всем найденным названиям, импортирует соответствующий им файл, выполняет ф-ю и заменяет кусочек результатом выполнения функции.
Если файл не был найден - вырезает {{{snippet_name}}} части из контента.

Пару слов о настройках: как видно в настройках мы должны прописать папку где будут храниться файлы с кодом для замены. У меня в settings.py это выглядит так:
TEMPLATE_INJECTOR_INCLUDES = 'ti_includes'

и подключаем нашу middleware там же:
MIDDLEWARE_CLASSES = (
    ...,
    'project_name.middlewares.template_injector.TemplateInjector',
)
 Теперь, в своей реализации flatpages(у меня чуть больше полей и т.д. но это не важно) при редактировании страницы добавляем для примера {{{test}}} и сохраняем страницу. Ложим в папку ti_includes (или как вы обзовете ее в настройках) файлик test.py c функцией test внутри возвращающей какой либо текстовый результат и вуаля - мы видим что при выводе на странице {{{test}}} заменено результатом работы функции. Удачи = )

пятница, 24 февраля 2012 г.

Firefox "Open containing folder" with dolphin on gentoo linux

Если у вас firefox открывает папки другим файловым менеджером, а вам хочется чтоб это был, например dolphin то все очень просто:

sudo vim /usr/share/applications/mimeinfo.cache

ищем строчку:

inode/directory=kde4-gwenview.desktop;kde4-kfmclient_dir.desktop;kde4-dolphin.desktop;

меняем gwenview на dophin

inode/directory=kde4-dophin.desktop;kde4-kfmclient_dir.desktop;kde4-dolphin.desktop;

PROFIT.

четверг, 16 февраля 2012 г.

вторник, 7 февраля 2012 г.

Regexp в vim-е

Допустим нам надо быстро убрать все тэги <font bla bla bla>текст</font> из HTML кода.
Если попробовать написать что нибудь типа /<\/?font.*?> ничего не получится - т.к. вим не понимает вопросик. Делаем так:
найти (/) и вводим команду: <\/\{0,1\}font.\{-\}> и вуаля видим что нашлись все тэги font открывающие и закрывающие ( :set hlsearch для наглядности). После того как убедились что подсветилось то что нужно - смело пишем :%s///g - и тэги магическим образом исчезают. :)


вторник, 17 января 2012 г.

Fabric в помощь при деплое django проекта

Т.к. все (по возможности) проекты я храню в Git то при деплое мне нужно делать pull на удаленном сервере. Также, если кто либо из команды добавил, например картинку или еще чего на сервере то это все нужно добавлять автоматом в коммит и push-ить  в репозиторий.
Для этого я создал такой вот fabfile.py который:

Сохраняет все локальные изменения (если есть в коммит) и пушит в репозиторий
  • Делает дамп удаленной базы и заменяет локальную (на случай добавления/изменения материалов на сайте)
  • Убивает кэш django и *.pyc файлы
  • Сохраняет и пушит удаленные изменения
  • Pullит изменения в локальный репозиторий
 
from fabric.api import *
from fabric.colors import yellow, red, green, blue

HOST = 'root@212.150.40.30:2280'
REMOTE_PATH = '/var/www/sample-python/'
REMOTE_DB_NAME = 'remote_dbname'
REMOTE_DB_USER = 'root'
REMOTE_DB_PASS = '1'

LOCAL_DB_NAME = 'dbname'
LOCAL_DB_USER = 'root'
LOCAL_DB_PASS = '1'

env.hosts = [HOST]
#env.hosts = ['localhost']

def deploy():
    local('git pull')
    #local('python manage.py synccompress --force')
    try:
        local('git commit -am "local autocommit"')
    except:
        print(red('nothing to commit'))
    local('git push')
    with cd(REMOTE_PATH):
        print(blue('dir: ' + REMOTE_PATH))
        run('mysqldump -u%s -p%s %s > db.sql' % (REMOTE_DB_USER, REMOTE_DB_PASS, REMOTE_DB_NAME))
        run('tar zcvf db.tar.gz db.sql')
        print(yellow('bd dumped'))
        get('db.tar.gz', './')
        print(yellow('bd downloaded'))
        run('rm db.tar.gz')
        run('rm db.sql')
        local('tar zxfv db.tar.gz')
        local('rm db.tar.gz')
        local('mysql -u%s -p%s %s < db.sql' % (REMOTE_DB_USER, REMOTE_DB_PASS, REMOTE_DB_NAME))
        print(red('DB imported to a local computer'))
        local('rm db.sql')
        local('git pull')
        run('./killcache')
        print(green('OK'))
    download_media()

def download_media():
    with cd(REMOTE_PATH):
        print(blue('dir: ' + REMOTE_PATH))
        run('git pull')
        run('git add .')
        #run('git checkout js/all_compressed.js')
        try:
            run('git commit -am "deploy media added"')
            run('git push')
            local('git pull')
            print(green('OK'))
        except:
            print(red('already up-to-date')) 
Вот так выглядит мой fabfile.py Записываю его в корневую папку на локальном компьютере где лежит .git, меняю данные в начале файла, выполняю fab deploy и все отлично ;)