28 сентября 2015 г.

${0%${0##*/}}

Есть небольшой трюк в bash, который мне давно нравился — получение текущей директории запущенного скрипта, используя только $0 и операции над строками bash-а. Это то, что в заголовке. Как вариант, его можно использовать в виде:
cd ${0%${0##*/}}
Исходные данные: $0 - полный путь запущенного скрипта. Понятно, что скрипт надо выполнять по полному пути, иначе использование метода лишено смысла.

Используются последовательно две операции над строками:
${string##substring} - удаление самой длинной, из найденных, подстроки $substring в строке $string. Поиск ведется с начала строки.
${string%substring} - удаление самой короткой, из найденных, подстроки $substring в строке $string. Поиск ведется с конца строки.


${0%${0##*/}} - самая длинная из найденных строк */ — это весь путь до последнего слеша включительно. Если удалить это из полного пути, то получится просто имя файла самого скрипта (без пути).

${0%${0##*/}} - далее, если из $0 («полный путь») удалить «имя файла» (получено выше), то получится как раз «путь без имени файла».

5 марта 2014 г.

django: самодельный if-else тег

Здесь пример самодельного тега шаблонизатора django, выполняющего роль if-else-endif. Мой код подразумевает переменную 'current_statuskey' в контексте (кладётся напрямую или с помощью middleware). Писал для очень сложной страницы с кучей частей, имеющих разный вид в зависимости от статуса. Вообще там ещё у меня дополнительная логика, но это минимальный пример здесь. Использование в шаблоне:
{% ifstatus one,five,blabla %}
...
{% else %}
...
{% endifstatus %}
Можно было описать в десяток строк, но здесь больше и код очень сильно похож на стандартные теги ifequals и сопутствующие, откуда я его и адаптировал, чтобы получить более правильную и канонiчную реализацию.

4 февраля 2014 г.

ant: компиляция и сборка jar прямиком с git

Пояснять особо нечего тут. Используются только стандартные таски. Для git clone используется exec, далее компилируется и собирается как обычно. Ниже пример моего ant-скрипта для сборки с git либы json.jar.

15 декабря 2013 г.

проект django project на shared hosting хостинге mod_wsgi

Историческая заметка по большей части. Черновик схемы настройки проекта на django 1.4 на хостинге с mod_wsgi.

13 ноября 2013 г.

django: contrib.comments работаем через ajax

Тут рассказ о том, как заставить стандартный django.contrib.comments работать через ajax. Цель была такова: минимальные изменения в клиентских view, чтобы работали стандартные templates перегружаемые, полноценная админка (обычная от приложения comments), да и вообще максимальное использование оригинального кода. Короче, в итоге после нескольких самопроизвольных переписываний (вместе с использованием подобного решения в проектах) получилась минимальная обёртка, которую по идее тоже можно вынести в отдельный app.

Да, скоро это уже не совсем актуально станет (django.contrib.comments устаревший и с версии 1.6 вынесен в отдельный проект), но решение отточилось на третьей версии и мне жалко его терять просто :) Пример тут для версии 1.5.

2 ноября 2013 г.

django: текущий пользователь в логах

Удобно в логах иметь текущего залогиненого юзера, чтобы видно было на ком падает, удобнее разбираться. Для логгера "django.request" передаётся экстра-параметр request. Его можно вытащить и залоггировать. Например, с помощью кастомного фильтра. Фильтр добавляет в вывод форматтера поле "user" с именем (строковое представление#id) юзера если оно есть. Фильтр вешается на нужные handlers. А в соответствующие formatters на этих handlers добавляется поле "user". В фильтре проверка на существование атрибутов request и request.user обязательна, если текущий formatter повешен на что-либо, кроме логгера "django.request", иначе будет падать в попытке найти поле с ид "user".

class RequestPushUserFilter(logging.Filter):
    def filter(self, record):
        if hasattr(record, 'request'):
            if hasattr(record.request, 'user'):
                record.user = u'%s#%s' % (record.request.user, record.request.user.pk)
            else:
                record.user = '?'
        else:
            record.user = '-'
        return True


LOGGING = {
    ...
    'filters': {
        ...
        'request_pushuser_filter': {
            '()': 'project.settings.RequestPushUserFilter',
        },
    },
    ...
    'formatters': {
        'standard': {
            'format': "[%(asctime)s] %(levelname)s [%(name)s:%(module)s:%(lineno)s] [%(user)s] %(message)s",
            'datefmt': '%d.%m.%Y %H:%M:%S',
        },
    },
    ...
    'handlers': {
        'logfile': {
            ...
            'filters': ['request_pushuser_filter'],
            ...
            'formatter': 'standard',
        },
    ...
В итоге в логах будет примерно так:
[31.10.2013 00:43:20] ERROR [django.request:base:212] [Driver John#1] Internal Server Error: блабла

См. также про логгирование в файл django.

31 октября 2013 г.

django: csrf при ajax-запросах

Несколько раз встречал вопросы на счёт csrf при самодельных ajax-запросах (например, через jquery как в примере ниже), и несколько вариантов странных даже видел. Я делаю проще - в основную страницу (например, в шаблон base.html или как он там у вас назван) выношу стандартный csrf_token в качестве javascript-переменной и во всех последующих скриптах удобно его использую.
Секюрность не страдает, конечно, т.к. сам токен не представляет интереса. Потом при запросах, например, через jquery.ajax можно просто передавать как параметр с именем "csrfmiddlewaretoken" (аналогично тому как он передаётся через скрытый input в обычных формах)

$.ajax({
  type: 'POST',
  url: '...',
  data : { ..., 'csrfmiddlewaretoken' : csrf_token, },
  ...
});