28.12.12

os.path.split

Хорошо, что никто никогда не спрашивал меня на собеседованиях, как работает os.path.split, потому что оно работает логично, но коварно. Если вы ожидаете, что получите из /foo/bar/__init__.py ['foo', 'bar', '__init__.py'], то вы неправы. Оно вернет ['/foo/bar', '__init__.py'].
Поэтому делить путь на директории или что у вас там вместо них можно:
  • небезопасно совсем (разбивая строку по слэшам),
  • слегка небезопасно (разбивая по os.path.sep) и
  • совсем безопасно (раз за разом разбивая голову результата os.path.split).

19.12.12

Если на CentOS мы хотим добавить, например, 8.8.8.8 в начало /ets/resolv.conf, то надо проинструктировать dhclient, который запускает dhclient-script, который перезаписывает /etc/resolv.conf. Для этого в /etc/dhcp/dhclient.conf добавляем одну строчку
prepend domain-name-servers 8.8.8.8;
Перезапускаем сеть
service network restart
.

18.12.12

Сеть в CentOS

Если на свежем CentOS не получается пинговать Гугл, то надо начать с проверки /etc/sysconfig/network-scripts/ifcfg-eth0 (или какой там у вас интерфейс). Должна быть строка ONBOOT="yes"

Отключаем Selinux на Centos

Если надо выключить Selinux (чтобы getenforce выводила Disabled), мало просто отредактировать /ets/sysconfig/selinux и написать там SELINUX=Disabled. Надо отредактировать /etc/grub.conf и там добавить в хвост строки, начинающейся с kernel, текст selinux=0. После перезагрузки Selinux будет отключен.

VirtualBox, Ubutnu и vboxdrv

Вы устанавливаете VirtualBox на свежей Ubuntu 12.10 и получаете от него просьбу запустить /etc/init.d/vboxdrv setup, при этом в /etc/init.d нет vboxdrv. Что делать? Надо установить заголовки ядра и переустановить dkms и virtualbox-dkms, после чего загрузить модуль vboxdrv. sudo apt-get install linux-headers-`uname -r` sudo apt-get install --reinstall dkms virtualbox-dkms sudo modprobe vboxdrv Перезагрузка не требуется, виртуалки начинают стартовать.

03.03.12

logger

Correctly logs to stdout under runserver. Under mod_wsgi logs into apache error log and file named after python import path + function name. Call logger = get_logger() or logger = get_logger(request)
import inspect
import logging
import os
import os.path
import sys

from django.conf import settings
from django.http import HttpRequest

def obtain_request():
    ancestors = inspect.getouterframes(inspect.currentframe())
    for frame_record in ancestors:
        frame = frame_record[0]
        if 'request' in frame.f_locals:
            req = frame.f_locals['request']
            if isinstance(req, HttpRequest):
                return req

def get_logger(request=None):
    if request is None:
        request = obtain_request()
    stack = inspect.stack()
    logger_name = '%s.%s' % (stack[1][0].f_globals['__name__'], stack[1][3])
    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.DEBUG)
    def addLogger(x):
        x.setLevel(logging.DEBUG)
        logger.addHandler(x)
    server = request.META.get('wsgi.file_wrapper', None) if request else None
    if server is None or server.__module__ == 'django.core.servers.basehttp':
        addLogger(logging.StreamHandler(sys.stdout))
    else:
        addLogger(logging.StreamHandler(request.META['wsgi.errors']))
        log_file = os.path.join(
            os.path.abspath(settings.PROJECT_ROOT),
            'logs', '%s.log' % logger_name)
        log_dir = os.path.dirname(log_file)
        if not os.path.exists(log_dir):
            os.mkdirs(log_dir)
        addLogger(logging.FileHandler(log_file))
    return logger

25.10.11

Uploadify на Mac OS X

Говорят, что у Mac OS X есть какие-то проблемы с Flash. Или наоборот, что у Flash есть какие-то проблемы с Mac OS X. В общем, есть между ними какие-то трения. Я лично столкнулся с чем-то таким, используя Uploadify. Этот плагин jQuery вносит метод uploadify, который принимает объект опций, среди которых есть scriptData. scriptData - объект, свойства которого будут добавлены к POSTу, когда flash-часть uploadify начнет загружать файл на сервер. В теории и документации вы увидите все, что передали в scriptData, в request.POST (если, конечно, используете Django).

На самом деле все не так. На Mac OS X вы увидите только первое свойство объекта scriptData. Так, если scriptData: {'size': '160x160', 'crop': true}, то вы request.POST будет только size. Обойти это можно так. Вместо {'scriptData': {'foo': 'bar', 'bar': 'foo'} }надо передать {'auto': false, 'onSelect': function(){ $x.uploadifySettings({'foo': 'bar', 'bar': 'foo'}); $x.uploadifyUpload();}}. Здесь $x - тот же объекта, метод котрого uploadify() вы вызываете. Так работает.

Но это не вся правда. в request.POST будет элемент 'foo' и элемент 'amp;bar'. Ну это просто:


if 'amp;crop' in request.POST:
        request.POST['crop'] = request.POST['amp;crop']

Почему так - не знаю. Но надеюсь, что моя небольшая находка сэкономит кому-то (мне) немного времени.