Показаны сообщения с ярлыком python. Показать все сообщения
Показаны сообщения с ярлыком python. Показать все сообщения

вторник, 3 июня 2014 г.

Плеер mopidy

Плеер Mopidy оказался для меня открытием. Плеер может работать как сервер MPD. Управляться с клиентов MPD. Проигрывать как локальный контент, так и с SoundCloud, GooglePlay Music, TuneIn ... etc.
Если запускаем плеер как сервис, то конфиг лежит в /etc/mopidy/mopidy.conf


Я активировал tunein, mpd и soundcloud. tunein  и soundcloud доставляются отдельными плагинами. Mpd встроен изначально.
Текущая конфигурация смотрится командой
mopidy config

Оконный менеджер Qtile

QTile это tiling оконный менеджер написанный полностью на Python. Основные его плюсы состоят в том что написан на Python и вроде как сейчас активно развивается. Конфиг тоже пишется на Python, поэтому для человека знакомого с данным языком проблем с конфигурацией не должно быть.
Установить Qtile можно из git репозитория, репозиториев дистрибутивов, с помощью питоновский утилит pip и easy_install, а так же и из исходных кодов.
Если вы ставили Qtile из репозитория дистрибутива, то на экране login должен быть доступен сеанс Qtile, в него и загружаемся.
Пока у вас нету своего конфига, будет работать DefaulConfig. Можно сохранить его в ~/.config/qtile/config.py и начать править.
 Переключение между рабочими столами происходит по кнопке WinKey+буква(a, s, d, f, u, i, o, p)
Запуск терминала Winkey+Enter
Что бы запустить любой приложение, можно нажать WinKey+r, появится строка ввода, куда надо вводить имя программы для запуска.
Завершение Qtile по нажатию WinKey+Ctrl+q.
Перезагрузка Qtile по нажатию WinKey+Ctrl+r. (удобно пока экспериментируешь с конфигом)

По сути, это все что вам необходимо для того что бы начать создавать свой конфиг. На сайте разработчика есть небольшая документация, в которой освещены основные моменты настройки. Я описывать тоже самое не будет, просто приведу свой конфиг.
Разберем не которые детали:

выставляем клавиши
mod = "mod4"
alt = "mod1"

Управление музыкой через mpc
    Key([mod], "Home", lazy.spawn("mpc toggle")),
    Key([mod], "End", lazy.spawn("mpc stop")),
    Key([mod], "Page_Down", lazy.spawn("mpc next")),
    Key([mod], "Delete", lazy.spawn("mpc prev")),
    Key(
        [mod], "m",
        lazy.spawn(
            """
            mpc playlist | dmenu -l 10  |\
            xargs -I '{}' sh -c "mpc playlist \
            | grep -rne '{}' | awk -F: '{print \$1}'" \
            | xargs -I '{}' sh -c "test -n '{}' && mpc play '{}'"
            """)
    ),

закрыть текущее окно
    Key(
        [mod], "w",
        lazy.window.kill()
    ),
поднимаем спрятавшееся окно наружу(grave -  это клавиша ~)
    Key(
        [alt], "grave",
        lazy.window.bring_to_front()
    ),

переключение на следующее окно в группе(полезно когда какой-нибудь всплывающее окно ушло за задний фон)
    Key(
        [alt], "Tab",
        lazy.group.next_window()),

Переключение между группами
    Key(
        [mod], "Left",
        lazy.group.prevgroup()
    ),
    Key(
        [mod], "Right",
        lazy.group.nextgroup()
    ),
переключение между слоями
    Key(
        [mod], "h",
        lazy.layout.previous()
    ),
    Key(
        [mod], "l",
        lazy.layout.next()
    ),
    Key(
        [mod], "j",
        lazy.layout.up()
    ),
    Key(
        [mod], "k",
        lazy.layout.down()
    ),

переключить окно в плавающее(не обходимо для окон работающий не навесь экран, например диалоги)
    Key(
        [mod], "f",
        lazy.window.toggle_floating()
    ),
различные переключения и изменения размеров для разных layout. проще попробовать самому.
    Key(
        [mod, "shift"], "space",
        lazy.layout.rotate(),
        lazy.layout.flip(),              # xmonad-tall
        ),
    Key(
        [mod, "shift"], "k",
        lazy.layout.shuffle_up(),         # Stack, xmonad-tall
        ),
    Key(
        [mod, "shift"], "j",
        lazy.layout.shuffle_down(),       # Stack, xmonad-tall
        ),
    Key(
        [mod, "control"], "l",
        lazy.layout.add(),                # Stack
        lazy.layout.increase_ratio(),     # Tile
        lazy.layout.maximize(),           # xmonad-tall
        ),
    Key(
        [mod, "control"], "h",
        lazy.layout.delete(),             # Stack
        lazy.layout.decrease_ratio(),     # Tile
        lazy.layout.normalize(),          # xmonad-tall
        ),
    Key(
        [mod, "control"], "k",
        lazy.layout.shrink(),             # xmonad-tall
        lazy.layout.decrease_nmaster(),   # Tile
        ),
    Key(
        [mod, "control"], "j",
        lazy.layout.grow(),               # xmonad-tall
        lazy.layout.increase_nmaster(),   # Tile
        ), 
запуск различных программ
    Key(
        [mod], "n",
        lazy.spawn("firefox")
        ),
    Key(
        [mod], "d",
        lazy.spawn("subl")
        ),

    Key(
        [mod], "u",
        lazy.spawn("uzbl-tabbed")
        ),
    Key([mod], "Return", lazy.spawn("urxvt")), 
переключение на следующий layout
Key([mod], "Tab",    lazy.nextlayout()),
запуск приложение через dmenu
    Key(
        [mod], "space",
        lazy.spawn(
            "dmenu_run -fn 'Terminus:size=8' -nb '#000000' -nf '#fefefe'")
    ),
настройка громкости
    Key(
        [mod], "equal",
        lazy.spawn("amixer -c 0 -q set Master 2dB+")
    ),
    Key(
        [mod], "minus",
        lazy.spawn("amixer -c 0 -q set Master 2dB-")
    ),
управление мышкой
 mouse = [
    Drag(
        [mod], "Button1",
        lazy.window.set_position_floating(),
        start=lazy.window.get_position()
    ),
    Drag(
        [mod], "Button3",
        lazy.window.set_size_floating(),
        start=lazy.window.get_size()
    ),
    Click(
        [mod], "Button2",
        lazy.window.bring_to_front()
    ),
]
задаем рабочие столы. У меня это клавиши от 1 до 0. Для переключение нажимаем клавишу mod + номер. Для переноса окна на другой стол, mod+shift+номер
groups = [Group(str(i)) for i in (1, 2, 3, 4, 5, 6, 7, 8, 9, 0)]
for i in groups:
    keys.append(Key([mod], i.name, lazy.group[i.name].toscreen()))
    keys.append(
        Key(
            [mod, "shift"], i.name, lazy.window.togroup(i.name),
            lazy.group[i.name].toscreen()))
настраиваем border для окон
border = dict(
    border_normal='#808080',
    border_width=1,
)
задаем какие будем использоваться layouts. Здесь можно почитать про встроенные layouts, но документация как всегда не успевает за разработчиками, так что лучше все посмотреть в git
layouts = [
    layout.Max(),
    layout.MonadTall(**border),
    layout.Matrix(**border)
]
теперь задаем наш экран. у меня один монитор, поэтому screen один. Можно настраивать поведение при нескольких мониторах. В нашем мониторе создаем Bar и задаем что на необходимо там видеть. Опять же, вот тут про встроенные виджеты или тут в исходных кодах.
В вкратце, у меня используется GroupBox - отображает рабочие столы, WindowName - отображает заголовок текущего окна, Notify - типа статусной строки, Systray - системный трай, KeyboardLayout - раскладка клавиатуры, Volume - громкость, BitcoinTicker - все ясно, и часы. У  каждого виджета есть свои настройки, более подробно в исходнике виджета.
screens = [
    Screen(
        top=bar.Bar(
            [
                widget.GroupBox(margin_y=1,
                                margin_x=1,
                                borderwidth=1,
                                padding=1,),
                widget.WindowName(foreground="a0a0a0",),
                widget.Notify(),
                widget.Systray(),
                widget.KeyboardLayout(configured_keyboards=["us", "ru"]),
                widget.Volume(foreground="70ff70",),
                widget.BitcoinTicker(currency="rub", format="{buy}"),
                widget.Clock(foreground="a0a0a0",
                             fmt="%H:%M %d.%m.%Y",),
            ],
            18,
        ),
    ),
]
эти хуки необходимы для того что бы некоторые всплывающие окна и диалоги автоматом переключались в режим floating и не открывались во весь экран
@hook.subscribe.client_new
def dialogs(window):
    if (window.window.get_wm_type() == 'dialog'
            or window.window.get_wm_transient_for()):
        window.floating = True


@hook.subscribe.client_new
def vue_tools(window):
    if((window.window.get_wm_class() == (
        'sun-awt-X11-XWindowPeer', 'tufts-vue-VUE')
            and window.window.get_wm_hints()['window_group'] != 0)
            or (window.window.get_wm_class() == (
                'sun-awt-X11-XDialogPeer', 'tufts-vue-VUE'))):
        window.floating = True


@hook.subscribe.client_new
def idle_dialogues(window):
    if((window.window.get_name() == 'Search Dialog') or
      (window.window.get_name() == 'Module') or
      (window.window.get_name() == 'Goto') or
      (window.window.get_name() == 'IDLE Preferences')):
        window.floating = True


@hook.subscribe.client_new
def libreoffice_dialogues(window):
    if ((window.window.get_wm_class() == (
        'VCLSalFrame', 'libreoffice-calc')) or
            (window.window.get_wm_class() == (
                'VCLSalFrame', 'LibreOffice 3.4'))):
        window.floating = True
а здесь мы создаем метод для запуск программ и описываем программы которые необходимо запускать при старте qtile
def is_running(process):
    s = subprocess.Popen(["ps", "axw"], stdout=subprocess.PIPE)
    for x in s.stdout:
        if re.search(process, x):
            return True
    return False


def execute_once(process):
    if not is_running(process):
        return subprocess.Popen(process.split())


@hook.subscribe.startup
def startup():
    execute_once("nm-applet")
    execute_once("synergy")
    execute_once("feh --bg-fill /home/pavel/Pictures/arch.png")
    execute_once(
        'setxkbmap -layout us,ru -option grp:caps_toggle,grp_led:scroll')

четверг, 8 ноября 2012 г.

Не показывать preview для больших архивов в ranger

    После того как я начал использовать ranger, мне понравилось что он быстро показывает превью для файлов, картинок, архивов. Но вот с архивами была проблема, когда просто перемещаешься по директории и натыкаешься на большой архив, ranger начинает его разархивировать, что бы получить список файлов и пока он не закончит, нельзя перемещаться дальше. Поэтому первое что пришло в голову, заставить ranger не показывать превью для архивов больше определенного размера. Как сделать это штатными средствами я не нашел. Да скорее всего это и не возможно. Потому что отображение preview занимается не сам ranger, а скрипт scope.sh, который мы можем свободно править. Находиться он в директории
 ~/.config/ranger/scope.sh  
на необходим вот этот кусок кода:
case "$extension" in
    # Archive extensions:
    7z|a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\
    rar|rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip)
        als "$path" | head -n $maxln
        success && exit 0 || acat "$path" | head -n $maxln && exit 3

в строке

als "$path" | head -n $maxln
мы и получаем список файлов из архива
Нам неоходимо это делать только вслучее если размер архива меньше опреденного. Для этого вводи переменную
maxSize=20000000
что равно 20Мб и добавляем получение условие с размером архива, в итоге получаем:
maxSize=20000000
case "$extension" in
    # Archive extensions:
    7z|a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\
    rar|rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip)
        [ `stat -c%s $path` -lt $maxSize ] && als "$path" | head -n $maxln
        success && exit 0 || acat "$path" | head -n $maxln && exit 3
сохраняем и все готов. Ни чего не надо перезапускать, все сразу работает.

среда, 26 сентября 2012 г.

Виджет раскладки клавиатуры в QTile

    В Qtile мне очень не хватало аплета отображающего текущую раскладку клавиатуры и поэтому я решил озадачиться этим вопросам. В прошлой статье я описал как получить текущую раскладку клавиатуры в Python, теперь осталось прикрутить это к qtile.
Что оказалось совсем не сложно сделать. За основу я взял виджет часов, который является TextBox'ом. Весь Qtile у меня находить в директории
 /usr/local/lib/python2.7/dist-packages/libqtile/  
виджеты во вложеной директории widget
Класс виджета часов выглядит следующим образом:
import datetime
from .. import hook, bar, manager
import base

class Clock(base._TextBox):
    """
        A simple but flexible text-based clock.
    """
    defaults = manager.Defaults(
        ("font", "Arial", "Clock font"),
        ("fontsize", None, "Clock pixel size. Calculated if None."),
        ("padding", None, "Clock padding. Calculated if None."),
        ("background", "000000", "Background colour"),
        ("foreground", "ffffff", "Foreground colour")
    )
    def __init__(self, fmt="%H:%M", width=bar.CALCULATED, **config):
        """
            - fmt: A Python datetime format string.

            - width: A fixed width, or bar.CALCULATED to calculate the width
            automatically (which is recommended).
        """
        self.fmt = fmt
        base._TextBox.__init__(self, " ", width, **config)

    def _configure(self, qtile, bar):
        base._TextBox._configure(self, qtile, bar)
        self.timeout_add(1, self.update)

    def update(self):
        now = datetime.datetime.now().strftime(self.fmt)
        if self.text != now:
            self.text = now
            self.bar.draw()
        return True

Как видно в методе update производиться присвоение значения текстового поля, в _configure прописывается обновлять виджет каждую секунду, что для нас является очень полезным. Скопируем данный класс под именем kblayout.py. Это и будет наш новый виджет. Так же в директорию с виджетами необходимо скопировать класс который занимется получением текущей раскладки клавиатуры из прошлой статьи под именем kb.py.
После изменения kblayout.py получаем:
from .. import hook, bar, manager
import base
import subprocess
from kb import kb


class kblayout(base._TextBox):
    """
        A simple but flexible text-based kblayout.
    """
    defaults = manager.Defaults(
        ("font", "Arial", "kblayout font"),
        ("fontsize", None, "kblayout pixel size. Calculated if None."),
        ("padding", None, "kblayout padding. Calculated if None."),
        ("background", "000000", "Background colour"),
        ("foreground", "ffffff", "Foreground colour")
    )

    def __init__(self, width=bar.CALCULATED, **config):
        base._TextBox.__init__(self, "ru", width, **config)

    def _configure(self, qtile, bar):
        base._TextBox._configure(self, qtile, bar)
        self.timeout_add(1, self.update)

    def update(self):
        k = kb()
        l = k.curkb()
        if self.text != l:
            self.text = l
            self.bar.draw()
        return True

    Тут у меня вылезлал какая то проблема с gobject, который используется в qtile, которую я так и не смог решить, но смог ее обойти. Для этого в kb.py добавляем строку
del sys.modules['gobject']
получается
import sys
import os
import subprocess
os.environ['GI_TYPELIB_PATH'] =\
    'libxklavier:' + os.environ.get('GI_TYPELIB_PATH', '')

del sys.modules['gobject']
from gi.repository import Xkl, Gdk, GdkX11


class kb():

    def __init__(self):
        display = GdkX11.x11_get_default_xdisplay()
        self.engine = Xkl.Engine.get_instance(display)

    def curkb(self):
        t = subprocess.check_output(["xset", "-q"])
        num = int(t.splitlines()[1].split()[9][4])
        groups = self.engine.get_groups_names()
        if (len(groups) > num):
            return str(groups[int(num)])[:2]
        else:
            return "Err"

k = kb()
print k.curkb()


 И в классе виджета mpriswidget.py за меняем строку
import gobject

на
from gi.repository import Xkl, Gdk, GdkX11

Теперь проблем не должно возникнуть. Осталось прописать наш виджет в файл __init__.py директории widget
from kblayout import kblayout
и прописать наш виджет в своем конфиге qtile - ~/.config/qtile/config.py
У меня это выглядит вот так:
screens = [
    Screen(
        top=bar.Bar([widget.GroupBox(
            borderwidth=2, font='Consolas', fontsize=13,
            padding=1, margin_x=1, margin_y=1),
            widget.Sep(),
            widget.WindowName(
                font='Consolas', fontsize=13, margin_x=6),
            widget.Sep(),
            widget.Battery(
                font='Consolas', fontsize=13, margin_x=6,
                energy_now_file="charge_now",
                energy_full_file="charge_full",
                power_now_file="current_now"),
            widget.Sep(),
            widget.Systray(),
            widget.kblayout(font='Consolas', fontsize=13, padding=6),
            widget.Sep(),
            widget.Clock(
                '%H:%M:%S %d.%m.%Y',
                font='Consolas', fontsize=13, padding=6), ], 24,),
    ),
]






Получение текущей раскладки клавиатуры в python

     Я так и не смог найти нормального способа получить текущую раскладку клавиатуры из командрой строки. В интернете много разный примеров, но ни один у меня не выдал нужного результата(система Ubuntu 12.04). Единственное что дает хоть какой-то результат:

xset -q

 на выходе получаем
 Keyboard Control:  
  auto repeat: on  key click percent: 0  LED mask: 00000002  
  XKB indicators:  
   00: Caps Lock:  off  01: Num Lock:  on   02: Scroll Lock: off  
   03: Compose:   off  04: Kana:    off  05: Sleep:    off  
   06: Suspend:   off  07: Mute:    off  08: Misc:    off  
   09: Mail:    off  10: Charging:  off  11: Shift Lock: off  
   12: Group 2:   off  13: Mouse Keys: off  
  auto repeat delay: 500  repeat rate: 33  
  auto repeating keys: 00ffffffdffffbbf  
             fadfffefffedffff  
             9fffffffffffffff  
             fff7ffffffffffff  
  bell percent: 50  bell pitch: 400  bell duration: 100  
 Pointer Control:  
  acceleration: 2/1  threshold: 4  
 Screen Saver:  
  prefer blanking: yes  allow exposures: yes  
  timeout: 600  cycle: 600  
 Colors:  
  default colormap: 0x20  BlackPixel: 0  WhitePixel: 16777215  
 Font Path:  
  /usr/share/fonts/X11/misc,/usr/share/fonts/X11/100dpi/:unscaled,/usr/share/fonts/X11/75dpi/:unscaled,/usr/share/fonts/X11/Type1,/usr/share/fonts/X11/100dpi,/usr/share/fonts/X11/75dpi,/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType,built-ins  
 DPMS (Energy Star):  
  Standby: 0  Suspend: 0  Off: 0  
  DPMS is Enabled  
  Monitor is On  

Для нас важна вторая строка, а конкретно
 LED mask: 00000002  

если мы переключим раскладку с default на другую то получим
 LED mask: 00001002

вот у все что у нас есть. Если у вас больше двух раскладок, то вы не узнаете какая у вас сейчас. Данным способом мы можем узнать только дефолтная раскладка сейчас или нет. Что на самом деле достаточно для большенства.

В bash можно использовать в таком виде
 xset -q | grep LED | awk '{print $10}' | cut -c 5  

возвращает 0 при дефолтной раскладке и 1 при альтернативной.

Но мне раскладка клавиатуры нужна в python.
Для получения группы раскладок в Python мы можем использовать следующий код:

import sys

import os

os.environ['GI_TYPELIB_PATH'] = 'libxklavier:' + os.environ.get('GI_TYPELIB_PATH', '')

from gi.repository import Xkl, Gdk, GdkX11

display = GdkX11.x11_get_default_xdisplay()

engine = Xkl.Engine.get_instance(display)

print('group names:', engine.get_groups_names())


Теперь имея список раскладок, мы можем поставить в соответствие значение получаемое из
  xset -q  
с раскладкой из группы engine.get_groups_names()

в итоге получился такой не большой класс:

import sys
import sys
import os
import subprocess
os.environ['GI_TYPELIB_PATH'] =\
    'libxklavier:' + os.environ.get('GI_TYPELIB_PATH', '')

from gi.repository import Xkl, Gdk, GdkX11


class kb():

    def __init__(self):
        display = GdkX11.x11_get_default_xdisplay()
        self.engine = Xkl.Engine.get_instance(display)

    def curkb(self):
        t = subprocess.check_output(["xset", "-q"])
        num = int(t.splitlines()[1].split()[9][4])
        groups = self.engine.get_groups_names()
        if (len(groups) > num):
            return str(groups[int(num)])[:2]
        else:
            return "Err"


вторник, 14 августа 2012 г.

Tiling windows managers

    Tiling windows manager - это фреймовый оконный менеджер, который разбивает рабочее пространство на взаимно не пересекающиеся прямоугольные области. Таким образом у вас ни когда не будет пересекающихся окон, все окна всегда будут на виду. При такой оконному менеджере более активно приходиться пользоваться рабочими столами. Фреймовый оконный менеджер позволяет полность избавить от мышки!
Выглядит примерно так
    Была когда то в прошлом у меня попытка перейти на данный вид оконного менеджера, но она не увенчалась успехом, толи я был не готово, толи менеджеры тогда были еще сыроваты.
    В очередной раз устав от Unity, от ее тормозов, да и вообще непригодному для работы окружению. Я ни чего не имею против Unity на домашнем компьютере, она вполне сносно справляеться с просмотром фильмов и серфингом в интернете. Да и жене попроще. Но на рабочем месте должна быть максимально фунциональная и быстра стреда. Unity  в качестве такой не годиться.
    Сперва были попытки перейти на Gnome 3. Которые не увенчались успехом, так как Gnome 3, это тот же Unity, только вид сбоку.
    Дальше я попробовал XUbuntu, затем чистый XFCE, на котором я просидел достаточно долго и в общем он меня устаивал, но чего то все равно не хватало.
    И как то наткнулся в статье на информацию что в Google некоторые сотрудники используют Ubuntu, но предпочитают использовать Xmonad, вместо Unity. Оказалось что Xmonad, это Tiling WM. И я решил попробовать что же это такой Tiling WM.
    На Ubuntu Xmonad ставиться с ходу из репозитория, в списке сессий появляется два новых пункта, Xmonad и Xmoad with Gnome. Xmonad with Gnome помоему у меня сразу не заработал, а Xmonad запустился и показал мне чистый рабочий стол. Оказывается это все! Можно было начинать работать. Только надо знать кучу хоткеев и написать не мало конфигов. Ну так просто я не был готов сдаться... Нашел как прикрутить к нему gnome-panel. Даже можно unity-2d-panel прикрутить, но оно того не стоит. На самом деле, после первых часов работы в Xmonad я был в восторге от идеи Tiling WM и от Xmonad. Благодаря легковесности Xmonad на моем не очень сильном ноуте, все начала просто летать. Оперативка свободна, проц отдыхает. Вот только это gnome-panel нагружает систему. Но есть Xmobar, которые я так и не попробовал. И вот после полудня работы, понял что кое что мне хотелось бы донастроить. А так как Xmonad написан на Haskell, то и конфиг у него представляет из себя Haskell программу. А изучать синтаксис Haskell мне совсем не хотелось. Возможно там все просто, но я ленивый. Мой друг параллельно со мной начал изучать тему Tiling WM, по моей рекомендации поставил Xmonad, но на отрез отказался ставить дополнительно к нему gnome-panel. Попытался привзять это все к Unity, что оказалось не так посто. Это получилось только у одного чувака, который для этого правил код Unity. Затем, друган пробовал поставить Xmobar, что вроде как у него даже получилось, но он все равно остался не  удовлетворен.
    И следующим шагом была установка Awesome, второго из двух самых популярных Tiling WM. Awesome сразу оказался более дружелюбным, так как после устаноки сразу все себе нес бар, к которому легко прикручивались апплеты погоды, сети, почты и т.п. Awesome в свою очередь требовал редактирования конфигов на языке Lua. Что опять же меня совсем не обрадовало. Хотя по Awesome полно русскоязычной документации. Но глядя на эти WM написанные на Haskell и на Lua, я подумал, было бы превосходно поставить WM написанный на моем любимом Python. И к моему счастью оказалось что такой Tiling WM  есть - QTile. О котором и будет следующая заметка.

среда, 28 декабря 2011 г.

Компиляция python кода в exe под Linux

Если на linux машинах python установлен повсеместно, то windows все наоборот. Решил скомпилировать свое приложения в exe, причем желельно что бы это был одинокий exe файл и не тянул с собой дополнительные dll библиотеки.
Для компиляции python кода в бинарные файлы есть очень удобная программа pyinstaller - http://www.pyinstaller.org/. Поддержку cross компиляции они уже начали добавлять, но пока она работает не полноценно, поэтому я решил установить python под wine.
Устанавливаем wine c http://www.winehq.org/
Качаем python c http://www.python.org/download/releases/
У меня, кстати, python 2.7.2 отказался устанавливать под wine, а вот 2.7.1 встал без проблем
для работы pyinstaller под windows нужен пакет pywin32, качаем и устанавливаем(http://sourceforge.net/projects/pywin32/)
Качаем pyinstaller(http://www.pyinstaller.org/).
После того как у нас установлен python и pywin32 под wine, мы готовы.
Распаковываем pyinstaller куда-нибудь поближе к установленном python, у меня это было
/home/pavel/.wine/drive_c/Python27/progs/pyinstaller-1.5.1
Туда же, в progs, копируем наше python приложение.
Для начала надо что pyintaller создал файл конфигурации для нашей системы
wine python.exe progs/pyinstaller-1.5.1/Configure.py
Далее создаем spec файл для нашего python приложения
wine python.exe progs/pyinstaller-1.5.1/Makespec.py -F progs/foobar.py
ключик -F как раз нужен для того чтобы на выходе у нас получился stand-alone executables.
Makespec.py сгенерирует файл foobar.spec, который нам необходим для компиляции.
И последнее что осталось сделать, это сбилдить наш бинарник.
wine python.exe progs/pyinstaller-1.5.1/Build.py foobar.spec
И в директории dist получаем наш foobar.exe.