Analitycs

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

четверг, 20 октября 2011 г.

Как демонизировать(daemon) проект на Twisted?

Есть три способа демонизировать проект на Twisted.

1) использование родного демона twistd. По идее - это более "методически грамотный" способ, но в свое время что-то не завелся у меня "в лоб", по этому до сих пор применяю второй.

2) скрестить старый работающий демон с реактором Twisted

#!/usr/bin/python                                                                                               
import sys
import src.daemon
import procname

class YourServer(twisted.web.server.Site):
    pass

class YourDaemon(Daemon):
    name   = 'yourserverd'
    site   = None
    server = None

    #--------------------------------------------------------------------------
    def __init__(self):
        self.server = YourServer()
        Daemon.__init__(self, pidfile='/var/run/%s.pid' % (self.name.lower()) )
        procname.setprocname(self.name)

    #--------------------------------------------------------------------------
    def run(self):
        self.server = YourServer()
        reactor.listenTCP(self.server.port, self.server)
        reactor.run()

if __name__ == '__main__':
      daemon = YourDaemon()
      daemon.processAction(sys.argv)

Да, procname служит для переименования процесса, о чем писал тут.


3) есть еще правда и python-daemon (PEP-3143), надо бы повнимательней изучить, но думаю что родной twistd оптимальней.

среда, 19 октября 2011 г.

Как настроить Nginx + php-fastcgi для Wordpress?

По просьбе Олега "TheAppleGeek" выкладываю рабочий конфиг Ngnix с php-fastcgi для Wordpress c включенным плагином W3 Total Cache
server {
    listen 80;
    server_name host.ru;
    index index.php;
    root /var/www/vhosts/host.ru/httpdocs;

    location ~ \.php$ {
                limit_conn three 20; 
                include         /etc/nginx/include.d/default_fastcgi_params.conf;
                fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass    php;
    }

    location ~ /\.ht {
        deny all;
    }

    if (!-e $request_filename) {
        rewrite ^(.+)$  /index.php   last;
    }
}

и общий для всех хостов на машине /etc/nginx/include.d/default_fastcgi_params.conf
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

fastcgi_connect_timeout 60;
fastcgi_send_timeout 60;
fastcgi_read_timeout 60;

Aperture 3.2 падает после обновления случайным образом

Нет, определенно -  после моего отъезда Apple распоясалась - сегодня очередное подтверждение.

После обновления Aperture 3.2 случайным образом падает в самопроизвольных местах - да так, что работа напоминает хождение по минному полю - рванёт в любую секунду.

На форуме Apple уже 6 страниц гневных посланий и баг идентифицировали - если у вас старая машина с CoreDuo (не Core2Duo - это первые серии машин с Intel, 2006 год) и RAW файлы - вы почти обречены.

Пока единственный вариант - НЕ ОБНОВЛЯТЬСЯ на 3.2, оставаясь на Aperture 3.1.3

 - либо уже если поторопились и обновились - то спасет только восстановление из бекапа TimeMachine. Но при мысле о восстановлении 25 Гб лично мне как-то становится грустно.

Ну или ждать обновления - хз когда. Правда, стоит отметить, что по тем небольшим промежуткам работы, которые удалось увидеть между падениями - программа стала значительно быстрее работать.

Нет, Apple определенно уже не торт...  "Грусть-печаль" (с) ;-( 

понедельник, 17 октября 2011 г.

py2app собирает .app с Qt4 без MySQL (libqsqlmysql.dylib)

Все чудесатей и чудесатей - сказала Алиса.
Все чудестраньше и чудестраньше

Мало того что, в Qt4 по умолчанию отсутствует поддержка MySQL - приходится докомпилировать  плагин из исходников, так еще и выяснилось, что при сборке .app пакета приложения py2app честно включает туда библиотеки Qt,  но забывает положить ее же plugins.

Лечение

$ macdeployqt ./dist/YourSuperPuperApplication.app


После непродолжительной ругани в консоли в .app появляется папка PlugIns - обратите внимание на большую I в центре названия.

Но разумеется - папка sqldrivers там не появилась (это было бы слишком просто ;-) ), приходится докопировать "ручками".


$ cp -R /Developer/Applications/Qt/plugins/sqldrivers ./distYourSuperPuperApplication.app/Content/PlugIns/

После чего приложение вроде бы подхватило MySQL и попыталось взлететь... но, к сожалению -  грохнулось на взлёте по другой причине.

Но это, уже как говорится - другая история... ;-)

Одно не понимаю - толи лыжи не едут, то ли я... чего то не понимаю - почему такие сложности на каждом шагу? ЧЯДН?

locate/updatedb в MacOS

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

Например, всегда раздражает не работающий locate/updatedb в MacOS по умолчанию "из коробки.

Но если locate дает явную подсказку - чего и как запускать, чтобы заработало, до updatedb - просто отсутствует как класс.

# updatedn
sh: updatedb: command not found

Лечение

# sudo ln -s /usr/libexec/locate.updatedb /usr/bin/updatedb

# sudo updatedb
И теперь наслаждаемся нормально работающим locate. ;-)

Найдено тут

воскресенье, 16 октября 2011 г.

Как обновить MacPorts на MacOS X?

Вкратце - для тех кто не знаком, представляю MacPorts - система полноценных портов для красноглазиков любителей true-unix-way в MacOs.

Собственно - после их установки работаем как с обычным FreeBSD

# /opt/local/bin/port install py2app

Время от времени нужно делать обновление самих портов

# /opt/local/bin/port selfupdate

Но самый страшный вопрос - это как обновить MacPorts?

Отвечаю... примерно так



# port upgrade outdated

И можно идти курить, есть, спать... и все такое прочее ;-)

суббота, 15 октября 2011 г.

Python py2app: AttributeError: 'module' object has no attribute 'TickCount'

Симптомы

После запуска собранного с помощью py2app пакета для MacOS на другой машине получаем падение с ошибкой

AttributeError: 'module' object has no attribute 'TickCount'

Лечение

В файле setup.py отключить argv_emulation, то есть - поставить в False

APP = ['MyApp.py']
OPTIONS = { 
   'argv_emulation': False,
   ...
}

setup(
    app=APP,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)


Подробности тут

вторник, 11 октября 2011 г.

Как узнать из какого каталога Python использует библиотеку? (import xxx)


$ python

Python 2.6.7 (r267:88850, Oct  8 2011, 08:42:47)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> import PyQt4
>>> PyQt4

<module 'PyQt4' from '/Users/michael_xiii/Envs/py26/lib/python2.6/site-packages/PyQt4/__init__.py'>

понедельник, 10 октября 2011 г.

Python - RuntimeError: maximum recursion depth exceeded while getting the str of an object

При активном использовании рекурсивных функций в Питоне начинает вываливаться ошибка RuntimeError: maximum recursion depth exceeded while getting the str of an object

Лечение быстрое, но не оптимальное

import sys
sys.setrecursionlimit(XXX)

Где XXX число, подбираемое экспериментально, основываясь на вашей программе. Но лучше, конечно, обходится без рекурсии. ;-)

суббота, 8 октября 2011 г.

Ошибка - Невозможно подключиться к базе данных QMYSQL (Mac, Python, Qt)

Симптомы

При запуске Qt приложения с MySQL ошибка "Невозможно подключиться к базе данных QMYSQL".

Причина

Отсутствие драйвера MySQL "из коробки" в каких-то вариантах Qt. Почему-то по умолчанию включают только SQLite.

Как лечить?

Скомпилировать драйвер самостоятельно, для чего умные люди написали вот такой скриптик.

Разумеется, не забываем поправить необходимую версию Qt и проверить, чтобы в путях не было пробелов. (У меня в username есть пробел, из-за чего время от времени ловлю различные проблемы с компиляторами)

PyQT на MacOS - Error: Unable to create the C++ code.

При сборке PyQt на MacOS вот по этому мануалу на команде

python configure.py

упорно вылезает ошибка

Error: Unable to create the C++ code.

Решение оказалось простым, как грабли - в пути до исходников не должно быть пробелов.

Теперь сижу, курю - жду пока соберется. ;-)

понедельник, 3 октября 2011 г.

Как бекапить проекты с помощью rsync, sshpass, scp?

Как известно, "админы делятся на две категории - те кто не делает backup, и те, кто его УЖЕ делает". (с)

Ежедневный бэкап

Как кому удобно - я делаю mysqldump базы на продакшене и потом rsync синхронизирую httpdocs и дамп на удаленную машину. Для авторизации - используются ключи.

#!/bin/bash                                                                                                      
DESTINATION=/var/www/vhosts/xxx/httpdocs                                                              
KEY="ssh -i /home/user/.ssh/scm_dsa -l xxx"                                                          
ORIG_HOST=user@xxxx                                                                                              
rsync -a -e "$KEY" --delete --exclude="${DESTINATION}/cache/*" $ORIG_HOST:${DESTINATION}/* ${DESTINATION}/

Недельный бэкап

Уже на удаленной машине архивирую засинхронизированную папку несколько раз и через несколько дней заливаю архив на backup-space. К сожалению, доступ в backup-машинам - только по ftp, поэтому приходится немного извращаться, используя для авторизации sshpass.

#!/bin/bash

VHOSTS_DIR=/var/www/vhosts
TMP_DIR=/mnt/backup
BACKUP_DIR=FTP_USER@XXXXX.XXX.XX:/

/usr/local/bin/sshpass -pFTP_PASSWORD scp ${TMP_DIR}/* ${BACKUP_DIR}scp -Cp ${TMP_DIR}/* ${BACKUP_DIR}

/etc/crontab

Да, разумеется - лучше всего делать эти процедуры тогда, когда народу на сайтах поменьше.

0 3 * * * root /home/user/bin/backup.sh >> /home/user/logs/backup.log
7 1 * * 0 root /home/user/bin/backup_weekly.sh >> /home/user/logs/backup_weekly.log

Как просмотреть битовые поля(bit fields) в MySQL?

Когда вы используете в таблицах MySQL битовые поля,  то стандартный консольный клиент их не показывает в результатах запросов.

mysql> select deleted from shopping_cart where id > 1000 and deleted = 0 limit 3;
+---------+
| deleted |
+---------+
|         | 
|         | 
|         | 
+---------+
3 rows in set (0.00 sec)

mysql> select deleted from shopping_cart where id > 1000 and deleted = 1 limit 3;
+---------+
| deleted |
+---------+
|        | 
|        | 
|        | 
+---------+
3 rows in set (0.00 sec)

Внимательный человек заметит, что у результатов команды отличается отступ.

Для того чтоб значение поля было показано явно, нужно в запросе либо добавить +0 к имени поля, либо вызвать функцию bin, как показано ниже.

mysql> select deleted+0 from shopping_cart where id > 1000 and deleted = 0 limit 3;
+-----------+
| deleted+0 |
+-----------+
|         0 | 
|         0 | 
|         0 | 
+-----------+
3 rows in set (0.36 sec)

mysql> select deleted+0 from shopping_cart where id > 1000 and deleted = 1 limit 3;
+-----------+
| deleted+0 |
+-----------+
|         1 | 
|         1 | 
|         1 | 
+-----------+
3 rows in set (0.01 sec)

mysql> select bin(deleted) from shopping_cart where id > 1000 and deleted = 1 limit 3;
+--------------+
| bin(deleted) |
+--------------+
|            1 | 
|            1 | 
|            1 | 
+--------------+
3 rows in set (0.01 sec)

mysql> select id,bin(deleted) from shopping_cart where id > 2000 and deleted = 0 limit 3;
+------+--------------+
| id   | bin(deleted) |
+------+--------------+
| 2001 | 0            | 
| 2002 | 0            | 
| 2003 | 0            | 
+------+--------------+
3 rows in set (0.00 sec)

Ну очень вольный перевод вот этого мана

суббота, 1 октября 2011 г.

Несколько аккаунтов Google - Не можете войти в Docs, Reager, Calendar?

У меня сейчас было такое.

Предыстория  - имеется несколько связанных аккаутнов Google - личный и рабочий на Google Apps.

После удаления аккаунта из Google Apps - не мог войти в личные Google Reader, Docs, Plus, причем Gmail работал отлично.

Лечится полной чисткой cookies и кеша браузера. 

пятница, 23 сентября 2011 г.

Python mktime/strptime - TypeError: expected string or buffer

Иногда апдейты повергают меня в транс - недавно ловил баг с PHP+cURL, теперь отличился Python ;-/

Traceback (most recent call last):
  File "test.py", line 22, in 
    s = strptime(row['change_time'], TIME_FORMAT)  File "/usr/lib/python2.6/_strptime.py", line 454, in _strptime_time
    return _strptime(data_string, format)[0]
  File "/usr/lib/python2.6/_strptime.py", line 322, in _strptime
    found = format_regex.match(data_string)
TypeError: expected string or buffer

Описание

Лезем в код - получаем какой-то набор данных из MySQL через питоновский fetchall, затем преобразуем поле со временем и начинаем с ним танцевать.

Перестала работать конструкция
 
    s = strptime(row['change_time'], TIME_FORMAT)
    last_change_time = mktime(s)

После курения манов по времени в Python выясняется, что нужно в mktime отдавать 9 численный tuple


    s = row['change_time'].timetuple()
    last_change_time = mktime(s)

Вот и верь после этого людям... обновляй после этого пакеты...

понедельник, 19 сентября 2011 г.

PHP: echo var_export($xx) ничего не выводит

Иногда с логики построения функций PHP хочется биться головой об стену.

Конструкция

logActivity(var_export($vars));

Не выводит в лог НИЧЕГО. Ломаю голову, пытаясь понять, куда делись переменные.
Подсказка проста - второй аргумент.

logActivity(var_export($vars, TRUE));

пятница, 16 сентября 2011 г.

Как исправить Fatal error: Cannot use object of type stdClass as array (PHP+JSON)

Всем хороша в пятом php функция json_decode, только по умолчанию декодирует JSON строку в объект класса stdClass, с которым нельзя работать как с массивом.

Ибо конструкция

$json = json_decode($string);
echo $json['result'];

приведет к ошибке
Fatal error: Cannot use object of type stdClass as array

Правится это добавлением второго параметра
$json = json_decode($string, true);
echo $json['result'];

четверг, 15 сентября 2011 г.

Как исправить ошибку Python datetime.datetime() is not JSON serializable?

Немного о сериализации через simplejson даты/времени, полученной из MySQL

При попытке сдампить результат из fetchall - чтобы отдать данные наружу во фронтендовский в Javascript в стиле

            sql  ='SELECT * FROM xxx WHERE id=%d'                                                          
            self._query(sql % id)
            data = self._cursor.fetchall()

получаем Exception

datetime.datetime(2011, 9, 14, 10, 18, 57) is not JSON serializable

Исправляется дополнительным форматом через лямбда-функцию

            dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime) else None
            response = json.dumps(data, ensure_ascii=False, default=dthandler)
Найдено, как водится - на StackOverflow

понедельник, 12 сентября 2011 г.

Как определить какая версия PHP/eAccelerator используется?

$ php -v


PHP 5.1.6 (cli) (built: Mar 31 2010 02:39:17)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies
    with eAccelerator v0.9.5.3, Copyright (c) 2004-2006 eAccelerator, by eAccelerator

пятница, 9 сентября 2011 г.

Проблема в PHP+cURL+CURLOPT_POSTFIELDS - после обновления

Обновив PHP и cURL поймал забавность - старая конструкция, нормально работавшая несколько месяцев

 $data = array(
  'id' => $id,
 );
 
 $ch = curl_init();

 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
 curl_setopt($ch, CURLOPT_POST, 1);
 curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&', $data));

 $result = curl_exec($ch);

 curl_close($ch);
  
 return json_decode($result);

перестала отправлять в POST данные.

Покурив маны, нашел ошибку в коде - не нужно implode на массив

 $data = array(
  'id' => $id,
 );
 
 $ch = curl_init();

 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
 curl_setopt($ch, CURLOPT_POST, 1);
 curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

 $result = curl_exec($ch);

 curl_close($ch);
  
 return json_decode($result);

Нет, ну понятно - как бы косяк, но тогда вопрос - ПОЧЕМУ ЭТО РАБОТАЛО?

P.S. "Чем дальше в лес - тем толще партизаны" (с) Ненавижу...