вторник, 4 июня 2013 г.

Встроенный web-сервер в PHP

В PHP начиная с версии 5.4 встроен Web сервер. Запустить его очень легко:
  1. Открываем терминал.
  2. Переходим в директорию в которой находятся скрипты, доступ к которым должен предоставить web сервер.
  3. Выполняем команду:
    php -S хост:порт
Если в качестве хоста прописать localhost, то доступ к серверу будут иметь только локальные клиенты.

суббота, 1 июня 2013 г.

Настрока прокси для Git

Чтобы Git начал работать через прокси, нужно:
Создать, если не существует, файл .gitconfig в корневой папке пользователя.
В файл добавить следующие строки:
[http]
proxy = http://логин:пароль@хост:порт
sslverify = false
где
   логин, пароль - параметры учетной записи на прокси сервере;
   хост, порт - адрес для подключения к прокси серверу.

Ошибка 0x80004005 при попытке получения Developer License в Visual Studio 2012 for Windows 8

На работе установил Visual Studio 2012 for Windows 8. А она при открытии требует получения Лицензии Разработчика (Developer License). Нажимаю "Получить"  и вместо лицензии получаю ошибку 0x80004005. Решения предлагаемые в инете не подошли, но зато я понял что ошибка из-за подключения к интернету. Интернет на работе задается через прокси сервер. Как оказалось, в этом и была проблема. Несмотря на то что в IE я настроил работу через прокси, VS небо все равно.

Решение проблемы

Решил проблему настройкой глобального прокси через утилиту netsh.
Под учетной записью администратора нужно выполнить следующую команду:
netsh winhttp set proxy прокси-хост:прокси-порт 

суббота, 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.
  • Всё.