суббота, 25 мая 2013 г.

MonoDevelop 4 под Ubuntu 12.10

На официальном сайте MonoDevelop для Ubuntu доступны бинарники только версии 2.6. Для получения версии 4 нужно собрать её самому. Делается это следующим образом:
sudo apt-get install build-essential automake checkinstall intltool git
sudo apt-get install mono-complete mono-addins-utils gtk-sharp2 gnome-sharp2
git clone git://github.com/mono/monodevelop
cd monodevelop
git checkout monodevelop-4.0
git submodule update --init --recursive
./configure
make
sudo checkinstall
После сборки exe-шник доступен по пути: monodevelop/main/build/bin/MonoDevelop.exe. Запускается командой:
mono MonoDevelop.exe
Если вы используете оболочку Unity (по умолчанию в Ubuntu 12.10), то заметите что главное меню отсутствует. Эта проблема возникает только в Unity. Для того чтобы вернуть меню, перед запуском MonoDevelop нужно присвоить переменной окружения UBUNTU_MENUPROXY значение 0. Для того чтобы каждый раз не мучиться, можно создать скрипт, который всё это делает:
UBUNTU_MENUPROXY=0
mono ~/monodevelop/main/build/bin/MonoDevelop.exe
Спасибо за внимание.

среда, 3 апреля 2013 г.

Дамп базы PostgreSQL

Для создания дампа базы PostgreSQL существует утилита pg_dump.
Самый простой вызов этой утилиты выглядит так:
pg_dump база > файл_дампа

Если нужно задампить только одну таблицу:
pg_dump -t таблица база > файл_дампа

Если нужно указать имя пользователя, хост и порт, то нужно применить соответсвующие опции:

pg_dump -U пользователь -h хост -p порт базы > файл_дампа
или
pg_dump -U пользователь --host=хост --port=порт базы > файл_дампа

Во всех приведенных вариантах вызовов, pg_dump запросит пароль пользователя. Если вы пишите скрипт для автоматического бекапирования, то такое поведение не подходит -- пароль должен передаваться из скрипта. Для этого существует переменная окружения PGPASSWORD.  Следующий вызов не запросит пароль пользователя:
set PGPASSWORD = пароль_пользователя
pg_dump -U пользователь база > файл_дампа

Помимо переменной с паролем поддерживаются следующие переменные окружения:
  • PGDATABASE - база данных;
  • PGHOST - хост;
  • PGPORT - порт;
  • PGUSER - имя пользователя.


Очень полезно при бекапе ставить ключ --inserts, который для вставки данных в таблицы использует INSERT выражения (а не COPY как по умолчанию, которые понимает только pg_dump).

Ключ -c или --clean вставляет DROP выражения перед выражениями CREATE. Удобно если вы разворачиваете дамп в базу в которой уже есть таблицы и вам их нужно заменить.

четверг, 28 марта 2013 г.

Yahoo Web Mail Service

На работе интернет только через прокси + закрыты все порты, кроме 80 и 433. А нужно было протестировать механизм регистрации на разрабатываемом сайте (с отправкой сообщения пользователю на мыло). Единственное что пришло в голову, это найти сервис электронной почты с открытым API и использовать его для отправки сообщений. Погуглив, нашел только на yahoo.com такой API. Вот тут его описание.
Для работы с Yahoo Web Mail Service, нужно:
  • Завести аккаунт на Yahoo.com.
  • Зайти на страницу управления вашими проектами и создаем новый. Проект - это сущность, которая является "учетной записью" вашего проекта на сервере Yahoo. Каждый проект имеет Consumer Key и Consumer Secret, по которым и осуществляется доступ к API.
  • Скачать здесь PHP-библиотеку для работы с Yahoo Web Mail Service и поместить её в директорию сайта.
  • Ниже приведен исходный код скрипта для работы с API:
    require_once 'ymclient.php';
    
    define('OA_CONSUMER_KEY', '****************************************************************************************************');
    define('OA_CONSUMER_SECRET', '****************************************');
    define('OA_CALLBACK_URL', 'http://localhost/');
    define('REQUEST_TOKEN_COOKIE_NAME', 'rt');
    define('ACCESS_TOKEN_COOKIE_NAME', 'at');
    
    $ymc = new YMClientRequest(OA_CONSUMER_KEY, OA_CONSUMER_SECRET,
     OA_CALLBACK_URL, '192.168.60.3:3128');
    
    header("Content-type: text/plain\r\n\r\n");
    message = new stdclass();
    $msg->message->subject = 'Test from Yahoo!';
    $msg->message->from = new stdclass();
    $msg->message->from->email = '*******@yahoo.com';
    $msg->message->to = new stdclass();
    $msg->message->to->email = '******@gmail.com';
    $msg->message->simplebody = new stdclass();
    $msg->message->simplebody->text = 'Hello, World!';
    if ($ymc->SendMessage($msg)===false)
     echo 'error';
    else
     echo 'ok';
    
    class YMClientRequest {
        function __construct($oaConsumerKey, $oaConsumerSecret, $callbackURL,
          $proxy=null) {
            $this->oaConsumerKey = $oaConsumerKey;
            $this->oaConsumerSecret = $oaConsumerSecret;
            $this->callbackURL = $callbackURL;
            $this->ymc = new YMClient($oaConsumerKey, $oaConsumerSecret, $proxy);
        }
        function __call($method, $arguments) {
            $tok = $this->__get_access_token();            
            $result = $this->ymc->$method($arguments, $tok);
            $newtok = $this->ymc->oauth_get_refreshed_token();
            if($newtok) {
                setcookie(ACCESS_TOKEN_COOKIE_NAME, 
                    YMClient::oauth_token_to_query_string($newtok));
            }
            return $result;
        }
        private function __get_access_token() {
            // Access token exists in a cookie
            if(isset($_COOKIE[ACCESS_TOKEN_COOKIE_NAME])
                && $_COOKIE[ACCESS_TOKEN_COOKIE_NAME]) {
                parse_str($_COOKIE[ACCESS_TOKEN_COOKIE_NAME], $tok);                
                return $tok;
            }
            // Handling a redirect back from login
            else if(isset($_COOKIE[REQUEST_TOKEN_COOKIE_NAME])
                && $_COOKIE[REQUEST_TOKEN_COOKIE_NAME]
                && isset($_REQUEST['oauth_verifier'])
                && $_REQUEST['oauth_verifier'] 
                && isset($_REQUEST['oauth_token'])
                && $_REQUEST['oauth_token']) {
    
                $tok = YMClient::oauth_token_from_query_string(
                    $_COOKIE[REQUEST_TOKEN_COOKIE_NAME]);
    
                if($tok['oauth_token'] != $_REQUEST['oauth_token'])
                    throw new Exception("Cookie and URL disagree "
                        ."about request token value");
    
                $tok['oauth_verifier'] = $_REQUEST['oauth_verifier'];                            
                $newtok = $this->ymc->oauth_get_access_token($tok);
    
                setcookie(REQUEST_TOKEN_COOKIE_NAME, "", time()-3600);
                setcookie(ACCESS_TOKEN_COOKIE_NAME,
                    YMClient::oauth_token_to_query_string($newtok));
                return $newtok;
            }
            else {
                list ($tok, $url) = $this->ymc->oauth_get_request_token(
                    $this->callbackURL);
                setcookie(REQUEST_TOKEN_COOKIE_NAME,
                    YMClient::oauth_token_to_query_string($tok));
                header("Location: $url");
            }
        }
    }
    
    В приведенном выше фрагменте используется прокси для подключению с API. Изначально библиотека этого не предусматривала, поэтому её пришлось несколько модифицировать. Исходный код модифицированной версии можно скачать здесь. Этот фрагмент отправляет электронное сообщение, что и требовалось.
Интересные факты(:
  • Аутентификация осуществляется через OAuth.

среда, 27 марта 2013 г.

Настройка NTP-сервера на Windows

Для того чтобы настроить NTP-сервер, необходимо в редакторе реестра зайти в каталог:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time.

В нем:
  • В подкаталоге Config, установить:
    • AnnounceFlags = 0x05
    • MaxNegPhaseCorrection = 0x2a300
    • MaxPosPhaseCorrection = 0x2a300
  • В подкаталоге Parameters, установить:
    • NtpServer = <адрес_сервера_для_синхронизации>,0x1
    • Type = NTP
  • В подкаталоге TimeProviders/NtpClient, установить:
    • Enabled = 1
  • В подкаталоге TimeProviders/NtpServer, установить:
    • Enabled = 1
    • AllowNonstandardModeCombinations = 1
    • InputProvider = 0
  • Перезапустить службу времени Windows или вызвать команду
    w32tm /update /config.
  • Всё.

суббота, 16 марта 2013 г.

Yii + PHPUnit + PhpStorm

В иерархии папок web-приложения Yii есть папка webroot/protected/tests/unit для создания unit-тестов.
Для того чтобы тесты работали по мимо PHPUnit должен быть установлен PHPUnit_Selenium и быть запущен Selenium Server.
Как установить PHPUnit и PHPUnit_Selenium написано в предыдущем посте.
Для настройки проекта для тестирования в PhpStorm, нужно создать PHPUnit конфигурацию, в которой:
  • DirectoryC:\www\casade\casade2\protected\tests\unit.
  • Поставить галочку Use alternative configuration file и выбрать в качестве конфигурационного файла  webroot/protected/tests/phpunit.xml.

пятница, 15 марта 2013 г.

Установка и настройка PHPUnit. Настройка PhpStorm

Установка PHPUnit

Установить PHPUnit можно через PEAR командой:
pear channel-discover pear.phpunit.de
pear install --alldeps phpunit/PHPUnit
Так же может потребоваться установка PHPUnit_Selenium. Но перед этим нужно добавить канал pear.symfony.com, т. к. PHPUnit_Selenium использует Symfony2 Yaml Component. Добавляется канал командой:
pear channel-discover pear.symfony.com
После этого можно устанавливать PHPUnit_Selenium:
pear install --alldeps phpunit/PHPUnit_Selenium

Настройка PhpStorm

PHPUnit в PhpStorm не требует каких-либо дополнительных настроек, главное чтобы в настройках Settings->PHP->Include path был путь к директории PEAR.

Установка и настройка PEAR

  1. Скачать PEAR http://pear.php.net/go-pear.phar.
  2. Скопировать его в отдельную папку, например c:\utils\pear.
  3. Выполнить команду php go-pear.phar.
  4. Во время установки PEAR спросит где Вы хотите сохранить конфигурационные файлы: system - в C:\Windows, local - в папке PEAR'а.
  5. Так же он спросит место расположения PHP, т. к. дописывает свой путь в include_path. Пусть к PEAR можно дописать в php.ini и после установки:
    ;***** Added by go-pear
    include_path=".;C:\utils\pear\pear"
    ;*****
  6. Послу установки можно добавить нужные каналы:
    pear channel-discover pear.phpunit.de
    pear channel-discover pear.symfony.com
    
  7. После этого можно устанавливать пакеты командой:
    pear install --alldeps phpunit/PHPUnit
    

О том как настраивать PEAR с помощью переменных окружения написано тут.