7 декабря 2012 г.

archlinux перевод на systemd

Как известно, archlinux к данному моменту почти полностью перешёл на systemd. Старый механизм sysvinit/initscripts тоже почти полноценно пока поддерживается через костыли. Чтобы вату не катать, я тоже стал переходить. В данный момент переход довольно подробно описан на арчвики, но на момент накидывания черновика этой заметки всё только начиналось, к тому же у меня чуть более сложный случай, т.к. стояло несколько специфических сервисов итд. Чтобы сразу всё не сломалось (а оно может даже если ничего не трогать), переходить решил постепенно, в принципе, на арчвики так же рекомендовано сейчас.

17 ноября 2012 г.

django: пролучить комментарии для объекта

Комментарии в django.contrib.comments, как известно, привязаны к моделям приложений через джанговский contenttypes. В документации рассказано как отрендерить и получить список в шаблонах, но механизм работы более подробно не рассмотрен для того, чтобы работать с комментариями в своих вьюшках. Ничего тут сложного нету, можно получить ContentType и вытащить все комментарии, но есть более удобный метод:
from django.contrib.comments.models import Comment

project_comments = Comment.objects.for_model(Project).filter(object_pk=project.id)
Его тоже можно разглядеть и изучить в исходниках django. Короче, с помощью for_model у CommentManager можно покороче и поудобнее сделать это всё. Содержимое метода вполне очевидно:
def for_model(self, model):
    """
    QuerySet for all comments for a particular model (either an instance or a class).
    """
    ct = ContentType.objects.get_for_model(model)
    qs = self.get_query_set().filter(content_type=ct)
    if isinstance(model, models.Model):
        qs = qs.filter(object_pk=force_unicode(model._get_pk_val()))
    return qs
Также можно обратить внимание, что если есть возможность, то можно передать не модельку, а конкретный экземпляр, тогда фильтровать по object_pk не придётся.

9 октября 2012 г.

django формы ChoiceField пустой выбор

Как ни странно, на данный момент у ChoiceField нет возможности из формы запросто задать пустой вариант выбора, как, например, у ModelChoiceField. Мелкая обёртка на скорую руку делает это аналогично тому, как это работает в ModelChoiceField.
from django import forms

class EmptyChoiceField(forms.ChoiceField):
    def __init__(self, choices=(), empty_label=u"---------", required=True, *args, **kwargs):
        # если не required и указана empty_label
        if not required and empty_label is not None:
            choices = tuple([(u'', empty_label)] + list(choices))
        super(EmptyChoiceField, self).__init__(choices=choices, required=required, *args, **kwargs)

14 сентября 2012 г.

eclipse pydev ImportError: Could not import settings

Ещё один косяк после рефакторинга проекта и перевода его на django 1.4. Ни в какую не стартует сервер из manage.py из самого eclipse. Бился-бился, всё равно пишет:
ImportError: Could not import settings 'project-django.settings' (Is it on sys.path?): No module named project-django.settings
И пути прописывал и всё остальное. Что характерно, извне эклипса, из консоли, всё отлично поднимается. Создал новый проект, запускаю — запускается. Начал разбираться — всё одинаковое в настройках проектов. Ничего не пойму.

django: ImproperlyConfigured Error importing authentication backend

Столкнулся с дурацкой непонятной ошибкой после большого рефакторинга проекта.

ImproperlyConfigured at /
Error importing authentication backend app.auth_backends.CustomUserModelBackend: "No module named app.auth_backends"

Всё дело оказалось в сессиях. В БД в таблице django_session хранятся в том числе и все AUTHENTICATION_BACKENDS сеансов. Чистка таблицы решила проблему.

30 мая 2012 г.

openbox и lxde на arch linux (черновикъ и всякие фишки)

Однажды я ударился головой в сильный минимализм и решил делать очень тонкую систему (на WM openbox, панельке tint2, и всякой другой босоте), потом постепенно пришёл к компромиссу — LXDE, которая тоже использует по умолчанию openbox, плюс свою довольно приличную панельку lxpanel и прочие lx-плюшки, обладающие для меня на данный момент идеальным балансом минимализм-юзабельность. Тут последовательно в виде мелких исторических заметок.

25 мая 2012 г.

Делаем скриншоты в LXDE/openbox кнопкой

В openbox/lxde нет родного способа снять скриншот, а мне этого так не хватало. Имеется способ снятия через утилиту import, входящую в состав imagemagick. Сначала вешаем на обычные кнопкосочетания PrtScr (снять весь экран) и Alt+PrtScr (снять текущее окно) вызовы скриптов. Для этого прописываем в ~/.config/openbox/lxde-rc.xml (для openbox в составе lxde) в секцию <keyboard>:

22 мая 2012 г.

linux: почему же ELF interpreter в Arch Linux 64 линкуется в /lib

Как-то однажды я собрал программу в своём 64-битном Arch Linux и отдал бинарник, а оно берёт и не работает. Пишет:
/lib/ld-linux-x86-64.so.2: bad ELF interpreter: Нет такого файла или каталога
Ну, долго тут думать не пришлось — оказался странным путь для ld-linux-x86-64. Я не понял как оно должно быть по LSB, но во всех тестируемых системах ld-linux-x86-64.so.2 ищется в /lib64.
Fedora 17:
$ whereis ld-linux-x86-64.so.2
ld-linux-x86-64.so: /lib64/ld-linux-x86-64.so.2 /usr/lib64/ld-linux-x86-64.so.2
Arch Linux:
$  whereis ld-linux-x86-64.so.2
ld-linux-x86-64.so: /lib/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
В генту lib это ссылка на lib64.
Причём, в арче в lib64 кроме двух ссылок на соответствующие файлы в lib больше ничего нет:
$ ls /lib64
ld-2.15.so  ld-linux-x86-64.so.2

27 апреля 2012 г.

linux: утилита pv (pipeviewer)

Прикрутил к небольшому скрипту дампа полезную маленькую утилитку pv (pipeviewer), теперь при архивации показыается бегущая шкала и остаток времени, полезно очень.

Как это выглядит:
$ dumparch ./.thunderbird
202MB 0:01:29 [9,67MB/s] [===>        ] 20% ETA 0:05:47

24 апреля 2012 г.

linux: webdav монтирование (на примере yandex.диск)

Сначала монтировал через gvfs, но не вполне удобно. Можно прописать намертво в fstab и всегда монтировать при старте в /mnt куда-нибудь, но мне этот вариант не очень нравится, всё же целевой ресурс персональный и монтироваться-авторизоваться должен на уровне юзера, имхо. Т.е. хочется от юзера монтировать в свою папку и логины-пароли держать где-то там же. Так-то вообще самый простой путь:

15 апреля 2012 г.

Блокировка экрана (LXDE, openbox) с клавиатуры

Самый простой способ: ставим xscreensaver (для арча можно из AUR поставить xscreensaver-arch-logo). Редактируем ~/.config/openbox/lxde-rc.xml (или ~/.config/openbox/rc.xml для чистого openbox), в секцию <keyboard> :
<keybind key="W-l">
      <action name="Execute">
        <command>xscreensaver-command -lock</command>
      </action>
</keybind>
Т.е. я повесил блокировку на Win+L почему-то.

29 марта 2012 г.

java, linux: установка oracle jdk и JAVA_HOME (на примере archlinux)

С тех пор, как SUN/Oracle Java выпилили из дистрибутивов, приходится руками качать и ставить. Вкратце.
Качаем дистрибутив JDK под нашу архитектуру, например, в виде bin-файла. Даём ему права +x, запускаем в /opt (здесь и далее всё от рута), распаковывается в каталог /opt/jdk1.6.0_31.
Для удобства делаем ссылки прямиком на jdk и jre, чтобы потом легко заменять версии:
ln -s jdk1.6.0_31 jdk
ln -s jdk/jre jre
Далее надо настроить переменные окружения. Прописываем в /etc/profile:
export JDK_HOME="/opt/jdk"
export JAVA_HOME="/opt/jdk"
export PATH=$PATH:$JDK_HOME/bin
Если ставим только JRE отдельно, то JDK_HOME не нужна, а JAVA_HOME указывается на корень JRE. В случае JDK лучше JAVA_HOME настраивать на корень JDK, и в PATH добавлять лучше именно bin от JDK.

21 марта 2012 г.

Битовые сдвиги и приведения в Java: подводные камни

1. Операции сдвига

Сначала вкратце самые основы. Как известно, в Java все примитивные типы знаковые, и есть несколько вариантов побитовых операций сдвига:
  • >> сдвиг вправо
  • << сдвиг влево
  • >>> сдвиг вправо («беззнаковый»)
Как видно, в дополнение к классическим сдвигам есть также «беззнаковый» сдвиг, который игнорирует знаковый левый бит и сдвигает его как обычный. Также эти сдвиги называются, соответственно, логический (когда первый бит теряется а последний заполняется нулём) и арифметический (аналогично, но значение считается значением в дополнительном коде и последний бит (знаковый) сохраняет своё значение).

24 февраля 2012 г.

java: Почему Thread.stop, Thread.suspend, Thread.resume и Runtime.runFinalizersOnExit объявлены deprecated?

Это я на скорую руку по надобности переводил доку оракловскую. Часть этих док я ещё на тысячах в аспирантуре переводил…
Оригинал (английский): Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?
http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

Почему не рекомендуется использовать Thread.stop?


Потому что это по своей сути небезопасно. Это приводит к разблокировке всех залоченных мониторов (исключение ThreadDeath пробрасывается вверх по стеку). Если любой из объектов, ранее защищенный мониторами, был в неустойчивом состоянии, таким его теперь могут увидеть другие потоки. Это может привести к неопределённому поведению, как скрытому труднообнаружимому, так и ярковыраженному. В отличие от других unchecked-исключений, ThreadDeath убивает потоки молча, так что пользователь может и не узнать, что его программа, вероятно, повреждена. Повреждение может проявиться в любое время после реальной аварии, через несколько часов или даже дней.

10 января 2012 г.

java и чтение unicode BOM

Ошибка древняя, как гавно мамонта, запишу здесь для истории. Проблема в том, что стандартными методами ридеров и стримов (с указанием, разумеется, соответствующих кодировок) в Java осуществлена неполная поддержка юникодовских кодировок, а именно полное игнорирование любых BOM-ов (в начале файлов). То есть если вы сохраните файл в любую юникодную кодировку «плохим» редактором (например, в виндовом блокноте), приложив BOM, то в Java без костылей прочитать не получится никак.

Баг на сане был открыт ещё в 2001 году, на данный момент помечен как «исправляться не будет», с объяснением «иначе некоторый софт может сломаться», т.е. баги тоже должны быть обратно совместимы ;) В каментах к багу много негодований, но обсуждение правильности этого решения пусть останется за рамками этой заметки.

На данный момент (конец jdk6 - начало jdk7) ошибка не исправлена и исправляться не собирается.

В качестве решения предлагается обрабатывать BOM-ы самостоятельно в коде. Готовые классы-обёртки находятся здесь: http://koti.mbnet.fi/akini/java/unicodereader/.

Например, UnicodeReader оттуда работает как замена InputStreamReader в такой конструкции:
new InputStreamReader( new FileInputStream( new File( "config.txt" ) ), "UTF-8" )
и является просто обёрткой над ним, создавая InputStreamReader внутри себя с кодировкой согласно прочитанным BOM из файла, либо указанной в конструкторе (как и в конструкторе InputStreamReader) конкретной дефолтной кодировке.