вторник, 12 мая 2015 г.

Как установить io.js на Ubuntu

Всем привет! Для того чтобы установить io.js на лучшую в мире ОС :) надо обладать особым складом ума, иметь навыки и ловкость ниндзя. Итак по-порядку:
  • Создадим или перейдем в папку с вашими любимыми бинарниками, например /home/tobi/soft
  • Скачаем архив с оф. сайта, в моем случае это x64 (все доступные для текущей версии 2.0.1)
  • Распакуем и удалим архив
  • Создадим ссылки на бинарники что бы можно было вызвать iojs в любом месте
Ну а теперь понятным языком :)
$: mkdir /home/tobi/soft
$: cd /home/tobi/soft
$: curl -O https://iojs.org/dist/v2.0.1/iojs-v2.0.1-linux-x64.tar.gz
$: tar -xvf iojs-v2.0.1-linux-x64.tar.gz
$: unlink iojs-v2.0.1-linux-x64.tar.gz
$: ln -s /home/tobi/soft/iojs-v2.0.1-linux-x64/bin/iojs /usr/bin/iojs
проверяем установку для пущей правды перейдем в домашний каталог
$: cd ~
$: iojs -v
v2.0.1
Это пожалуй все

понедельник, 24 ноября 2014 г.

Magento. Подчищаем атрибуты, без шума и пыли.

Вот вы создали какой-то "кривой" атрибут и решили быстренько его убрать от глумящихся над вашей некомпетентностью коллег, или же поставили очередной вело-криво-собранный модуль написанный индусами, не беда пару строк в красивом файле восстановят вашу репутацию:

<?php
include 'app/Mage.php';
Mage::app();
$setup = Mage::getResourceModel('catalog/setup','catalog_setup');
$setup->removeAttribute('catalog_product','your_attribute_name');

Вместо your_attribute_name вписываете имя удаляемого атрибута. Все! честь спасена.

вторник, 11 февраля 2014 г.

CORS. Как посылать запросы GET, POST, DELETE etc.

В наши дни не знать что такое CORS (wiki), сродни прогулки тёмной ночью по последнему этажу, недостроенной высотки где-нибудь за городом, в неблагополучном районе... Т.е. смертеподнобно, а особенно если вы фронт-енд разработчик.

Более подробно вы можете ознакомиться перейдя по ссылкам в конце текста, я же скажу вкратце, CORS это набор HTTP заголовков, которые позволяют объяснить браузеру и серверу, что они хоть и из разных доменов, но одной крови работать могут вместе. Т.е. кросс-доменные зпросы поддерживаються. Кто не знает, то запрос из браузера посредством старого, доброго JavaSctipt недавно, так на чистоту, без костылей сделать было невозможно. Ура, эти мрачные времена канули в лету. Пришёл на момощь CORS.

Речь пойдет именно о процессе использования и базовой настройки заголовков сервера, и отсыла запросов клиента с использованием jQuery.

Сервер, который мнит себя крутым сервисом, настолько куртым что хочет предоставить поддержку кросс-доменных запросов. Должен клинету сообщить об этом. Отправив следующие заголовки:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers

Это тот минимум, который необходим для успешной работы наших кросс-доменных запросов. немного рапишем что, к чему:

Access-Control-Allow-Origin — (обязательный) собственно список разделенный пробелами допустимых доменнов (источников), которые будут ломиться делать запросы к нам на сервер. Из особенностей: регистрозависим, поддерживает маски, например, http://api.superservice.com/, http://*.superservice.com/ или, как вы могли догадаться просто "звездочка" *. Этот заголовок будет сравниваться с заголовком Origin клиентского запроса.
Access-Control-Allow-Method — (обязательный) это список доступных HTTP методов, разделенных запятыми. Особое внимание стоит уделить тому, что "звездочка" аля * работать не будет!
Access-Control-Allow-Headers — (обязательный вместе с Access-Control-Request-Headers) список через запятую заголовков разрешенных в запросе.

Пример настройки для Apache:

# CORS заголовки (добавте это, например, в .htaccess)
<ifmodule mod_headers.c>
  Header always set Access-Control-Allow-Origin: "*"
  Header always set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
  Header always set Access-Control-Allow-Headers "X-Requested-With, content-type"
</ifModule>

Давайте разберемся, что тут происходит? А происходит следующее, запросы будут обработанны с любого источника, если они будут одного из перечисленных в Header always set Access-Control-Allow-Methods типов, так же будут подерживаться заголовки X-Requested-With и content-type

Тот же пример для PHP

<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: X-Requested-With, content-type');
?>

Теперь, предположим, что сервис у нас крутится по адресу http://api.superservice.com/ , а GET запрос нам надо сделать со странички http://pure.client.net/. Это не сложно сделать, к примеру с jQuery:

jQuery.ajax({
  url: 'http://api.superservice.com/credit-card-ids',
  type: 'GET',
  contentType: 'application/json', // тот тип контента, который вы будете получать от своего сервиса
  headers: { }, // Разные заголовки, нестандартные заголовки, не забудте их указать в Access-Control-Allow-Headers
  success: function (res) { 
  console.log(res);
},
error: function () { ... }
});

Думаю самое время упомянуть о неприятном моменте с AngularJs если вам понадобиться сделать кросс-доменый запрос с помощью $http или $resource, то надо будет удалить один заголовок, делается это так:

myApp.config(['$httpProvider', function($httpProvider) {
 $httpProvider.defaults.useXDomain = true;
 delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);

Такое поведение странно, для меня, по крайней мере, несмотря на то что заголовок X-Requested-With вы укажите Access-Control-Allow-Headers не исключены проблемы с запросами. Ходят слухи что это бага AngularJs, кому интересно, если найдете что, отпишитесь в коментах.

Переходим к интересным запросам типа POST/PUT/DELETE, всех их объединяет то что они пытаются что-то изменить на сервере. Но как сделать такой запрос кросс-доменным? Сначала надо получить список заголовков типа Access-Control-*, делается это предварительным OPTIONS запросом. Который может вернуть тот же набор Access-Control-*, что и обычный метод GET.

На сервере если вы больше нигде и не для чего более не будете использовать OPTIONS запросы, то можете смело на все запросы типа OPTIONS отвечать необходимыми заголовками в том числе и такими заветными для нас как CORS заголовки. Если кто не понял то имееться ввиду добавить правило для всех запросов типа OPTIONS в роутах вашего любимого фреймворка. Или же сделать обработку руками.

Этот предварительный запрос (prefligth-запрос), делается автоматически jQuery или тем же Angular, по-тому же URL что и ваш основной запрос POST/PUT/DELETE поэтому будте внимательны если вы не сделаете правильной обработку запросов типа OPTIONS то и запрос POST/PUT/DELETE у вас сделать не получиться, из-за политики безопасности, который следуют браузеры.

Пример запроса POST с использованием jQuery.

jQuery.ajax({
  ulr: 'http://api.superservice.com/credit-card-ids',
  type: 'POST',
  data: '{"content": "' + content + '"}', // внимание! если вы передатите параметр как объект то это будет Query String, в данном случае это Request Body, т.к. тут передана строка.
  contentType: 'application/json', // тот тип контента, который вы будете получать от своего сервиса
  headers: { }, // Разные заголовки, нестандартные заголовки, не забудте их указать в Access-Control-Allow-Headers
  success: function (res) { 
  console.log(res);
},
error: function () { ... }
});

Я старался изложить кратко, в справочном виде, не очень получилось :), но думаю многим кто прочитал это сэкономит время. Ниже список источников, который позволят вам более глумого изучить вопрос CORS

пятница, 20 декабря 2013 г.

Node.js. Легкий стресс-тест через Phanos.

На волне набирающей популярности ноды. Решил взяться за написание маленького паучка, который бы имитировал реального пользователя. И гулял по сайту не аки бот, а как нормальный человек. Благо в инфраструктуре ноды добра для написания такого чудного существа достаточно. Основа паука стал phantom.js, это "обезгалвленный" движек Webkit, другими словами - это браузер лишенный UI.

Итак, Phanos, в первую очередь мне он был нужен для одной важной задачи, - сымитировать набег пользователей на сайт в течении 2х недель! Самое интересное что для сайт этот был single page application. Т.е. это полноценное web-приложение с кучей асинхроных запросов и всякой джэесины :). Которую как мы понимаем не в состоянии отработать jMeter ни тем более Apache Banchmark. А так как интерес к node.js у меня сейчас в обостренной форме, хотя как мы можем заметить, в рунете заметен спад заинтересованности. То собственно и был рожден сей паучек. Еще одна особенность сайта - это то что он также реализован на node.js и эта штука вся крутится на heroku, то вся статитка также отдается через аппликуху, то так же важно грузить и все остальное, т.е. картинки, стили и собственно Js.

Phanos, его особенности это:

  • имитация посещения пользователями длительное время, т.е. вы можете оставить тулзу работать в течении дня, недели, месяца, да хоть года, указать количество пользователей и вперед.
  • полностью отрабатывает страницы с ajax js
  • легко устанавливается и работает под Linux и Windows, теоретически должен работать и на Mac.

Для начала работы с Phanos необходимо установить node.js. А затем выполнить команду, Ubuntu:

$ sudo npm install -g phanos

для Windows:

$ npm install -g phanos

В процесе установки будет загружен phantomjs под вашу платформу. Ниже приведу пару примеров как пользоваться phanos.

$ phanos -u = http://www.google.com -w 10 -t 3600

Команда выше запустить 10 волкеров (пользователей) "гулять" по гугл в течении 1 часа (3600 сек.). Как лего догадаться то -u это адрес страницы, -w это количество пользователей, -t время работы скрипта, здесь час.

$ phanos -u = http://www.google.com -w 10

Тут просто 10 волкеров в течении 30 сек. будут шнурять по сайту.

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

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


P.S.: Phanos - это симбиоз от слов Phantom и stress, а не то что могут подумать некоторые изощреные умы =)

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

Magento. Операторы сравнения.

Magento выделяется особой самобытностью, в этом движке любят делать все не так как все, хорошо это или плохо... не мне судить, но вот чтобы добавить какой-дибо атрибут для фильтрации колекции, необходимо знать операторы сравнения. Ниже они преведены собственной персоной.
Операторы сравнения Magento:

array("eq"=>'n2610')
WHERE (e.sku = 'n2610')

array("neq"=>'n2610')
WHERE (e.sku != 'n2610')

array("like"=>'n2610')
WHERE (e.sku like 'n2610')

array("nlike"=>'n2610')
WHERE (e.sku not like 'n2610')

array("is"=>'n2610')
WHERE (e.sku is 'n2610')

array("in"=>array('n2610'))
WHERE (e.sku in ('n2610'))

array("nin"=>array('n2610'))
WHERE (e.sku not in ('n2610'))

array("notnull"=>true)
WHERE (e.sku is NOT NULL)

array("null"=>true)
WHERE (e.sku is NULL)

array("gt"=>'n2610')
WHERE (e.sku > 'n2610')

array("lt"=>'n2610')
WHERE (e.sku < 'n2610')

array("gteq"=>'n2610')
WHERE (e.sku >= 'n2610')

array("moreq"=>'n2610') //a weird, second way to do greater than equal
WHERE (e.sku >= 'n2610')

array("lteq"=>'n2610')
WHERE (e.sku <= 'n2610')

array("finset"=>array('n2610'))
WHERE (find_in_set('n2610',e.sku))

array('from'=>'10','to'=>'20')
WHERE e.sku >= '10' and e.sku <= '20'

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

Git, nodejs-проект и SSH. Установка, разворачивание, запуск в фоне

Итак, поступил заказ на "допиливание" проекта, или же вы купили новый девайс, на котором планируете вести разработку любимого Web-приложения параллельно с основным или надо быстро поднять окружение для разработки на Node.js с уже имеющимся кодом или... Или 1000 и одна причина по которой может резко понадобиться разворачивание проекта на машине. Речь, как можно догадаться из заголовка, пойдет о таких вещах: Nodejs, Git, Ssh. Начнем-с.
В первую очередь оговорюсь, все проделывалось в Debian/Ubuntu системе, хотя немного изменив курс туториала, это применимо и к другим дистрибутивам и даже к Windows :)

  • Ставим Git если его еще нет в системе (для Винды это  вообще очен мажно с ним в придачу можно поставить чудо-юдо MingGW)
    $ sudo apt-get install git
    
  • На всякий случай обновляем репы
    $ sudo apt-get update
    
  • Вот эта штука очень полезная, я про python-software-properties. Она содержит в себе утилиту add-apt-repository и что самое грустое что если у вас сервер Ubuntu то скорее всего у вас ее нет, если десктоп, то можно и не ставить.
    $ sudo apt-get install python-software-properties python g++ make # Ставим зависимости
    $ sudo add-apt-repository ppa:chris-lea/node.js # Добавляем репозиторий node.js
    $ sudo apt-get update # Обновляем репы
    $ sudo apt-get install nodejs # Ставим node.js последней версии
    
  • Далее переходим в директорию в которой будем разворачивать проект
    $ cd /var/www # Эта директория указана для примера и может быть любой другой.
    
  • Далее надо сгенерировать SSH ключ
    $ ssh-keygen -t rsa
    
    Если вы не указывали никакого другого пути для сохранения ключа то вы его можете найти в
    $ ~/.ssh/id_rsa.pub
    
  • Копируем его содержимое и добавляем в сервис (или в ~/.ssh/authorized_key на сервере от куда мы будем тянуть код проекта) например это может быть Github, Bitbaсket, Heroku и др. У меня это Heroku
  • Переходим в папку для проекта у меня это /var/www и клонируем проект
    $ cd /var/www
    $ git clone git@heroku.com:yourproject.git ./
    
  • После чего не забываем установить сопутствующие модули, не думаю что у вас их не будет
    $ npm install
    
  • И если вы хотите "повешать" процесс на "прослушку" 80-го порта, то не забудте это сделать от рута, т.к. мы же все помним что порты ниже 1024 требуют прав рута.
    $ sudo NODE_ENV=staging PORT=80 node app.js
    

А еще нам может понадобиться запустить ноду в фоне, аля процесс-демон. Сразу скажу тут не будет ничего про демоны, а будет про интересный модуль supervisor и "финт" ушами.

Итак для того чтобы запустить ноду в фоне надо выполнить следующую команду. Предварительно создайте директорию для логирования вывода процесса, ну, например, /home/macho/logs/ или /var/logs/yourproject

$ sudo npm install supervisor -g # Устанавливаем глобально модуль supervisor
$ sudo NODE_ENV=staging PORT=80 supervisor app.js > /var/logs/yourproject &
Собственно команда выше запустит ноду в фоне и вы можете насладится результатами работы вашего приложения на 80-м порту.
Удачи, надеюсь пост окажет непосильную помощь, в освоении node.js

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

Nodejs. Как же все таки работать с модулем Async

Node.js ворвалось на сервера с невероятной скоростью, ровно с такой же скоростью повергло в шок многих сервер-сайд разработчиков... Многим даже пришлось действительно изучить JavaScript и выйти за уровень jQuery подключателей :), но думаю одной из самых интересных и необычных сторон Node.js в частности и JavaScript в целом это его система колбеков, асинхронных вызовов. Потеряться во вложенности начинающему разработчику раз плюнуть.

Как полностью устроен принцип работы callback в node.js рассказывать не стану. Просто скажу, что первым параметром колбека всегда должен быть err объект или строка ошибки. Если внутри вашей пачки колбеков (в независимом скоупе есть еще череда колбеков), то у внутренних колбеков можно опустить параметр ошибки, т.к. эта пачка будет "видеть" общий для них объект ошибки, который можно смело передать в "выходной" колбек. Чего-то я какой-то замудренной фигни понаписал :), итак перейдем к инструменту который позволяет немного упростить и привести ваш код к более красивому и читаемому виду - это модуль Async, он позволяет навести порядки в ваших стеках колбэков. Итак приступаем. Первым делом добавляем в ваш package.json новую зависимость: "async": "*", после запускаем
npm install
Или же можно просто сделать так
npm install --global async
Эта команда установит Async глобально в вашу систему и будет доступен во всех проектах. Итак что нам может предложить Async для Node.js? А предложить он может многое стоит заглянуть для полного списка на его страничку github.org,я же приведу примеры для некоторых из них, и только из раздела control flow а именно:

Series — этот метод позволяет выполнять коллекцию задач по-порядку, и на выходе выполнить какой-нибудь полезный колбек. Этот метод полезен когда важен порядок выполнения, если можно так сказать то этот метод позволит вам "победить" асинхронность ноды:
var async = require('async')
  , tasksIndex = [
        function (callback) {
            // Вымышленный метод который вернет 231
            var viewsNumber = models.stat.viewsNumber();
            callback(null, viewsNumber);         
        }
      , function (callback) {
            // Вымышленный метод который вернет 24
            var growFactor = models.stat.growFactor();
            callback(null, growFactor);
        }
    ]
  , taskNamed = {
        viewsNumber: function (callback) {
            callback(null, models.stat.viewsNumber());
        }
      , growFactor: function (callback) {
            callback(null, models.stat.growFactor());
        }
    };

async.series(tasksIndex, function (err, results) {
    // Результат будет массивом
    console.log(results); // [231, 24]
});
async.series(taskNamed, function (err, results) {
    // Результат будет объектом 
    console.log(results); // {viewsNumber: 231, growFactor: 24}
});

Parallel — а этот метод работает в лучших традициях ноды, не нарушая ее асинхронности, но позволяет отследить конец работы всей пачки задач, т.е. все задачи выполняются параллельно и в конце результаты пробрасываются в финальный колбек. Листинг для этого метода практически ничем не будет отличаться от предыдущего, только надо вызвать не series а parallel

Waterfall — этот метод работает словно цепочка, результаты одной задачи передаются в колбеке следующей задачи, таким образом можно:
async.waterfall([
    function(callback){
        callback(null, 'один', 'два');
  , }
    function(arg1, arg2, callback){
        // Тут arg1 равен "один"
        // , а arg2 равен "два"
        // что соответствует второму и третьему параметру текщего колбека
        // , а первый конечно же мы не забыли - это err но в этом случае
        // ошибок нет поэтому null
        callback(null, 'три');
  , }
    function(arg1, callback){
        // Здесь же arg1 будет равен уже "три"
        callback(null, 'Готово');
    }
], function (err, result) {
   // Сейчас результат будет равен 'Готово'    
});

Собственно это основные методы по контролю за выполнением колбеков, который упростят работу с ними, для получения более подробной информации советую посетить страничку модуля на Github.