среда, 27 апреля 2011 г.

iMacros

iMacros

About

iMacros - это плагин для браузера. Есть версии для FF, IE, Chrome.
Имитирует действия пользователя в браузере с помощью команд-макросов. Макросы записываются в *.iim фалы. Файлы хранятся на диске.
Программа выглядит, как набор команд.

Пример кода:

VERSION BUILD=6650406 RECORDER=FX
TAB T=1
TAB CLOSEALLOTHERS
URL GOTO=http://ya.ru
URL GOTO=javascript:alert('test');

iMacros может работать под управлением JavaScript. Создаются js-файлы, которые могут вызывать iim. Например, в js-файле можно определить переменные, которые будут использоваться в нескольких вызываемых iim-файлах.

Макрокоманды

TAB

закрыть все вкладки браузера, кроме текущей:
TAB CLOSEALLOTHERS
открыть новую вкладку:
TAB OPEN NEW

TAG

обратиться к полю Input и задать ему значение:
TAG POS=1 TYPE=INPUT ATTR=ID:k_name CONTENT={{FIRM}}
получить содержимое страницы внутрь массива iimGetLastExtract (доступен внутри javascript):
TAG POS=1 TYPE=* ATTR=* EXTRACT=TXT

JavaScript

функции

iimPlay('test')
выполнить файл test.iim
iimSet('-var_SERVER', 'http://google.ru')
установить переменную, тогда в iim-файле к ней можно обратиться так:
URL GOTO={{SERVER}}
iimGetLastExtract(1)
обратиться к результату, выдернутому со страницы

объекты

браузер

var br = getBrowser();
var tabs = br.mTabContainer.childNodes; // массив открытых табов браузера
alert(tabs.length); // отобразить количество табов

Решения

Обход по списку ссылок

javascript-файл:
var br = getBrowser();
var tabs = br.mTabContainer.childNodes;
var a = [
    "http://google.ru",
    "http://ya.ru",
    "http://rambler.ru",
    "http://mail.ru",
    "http://yahoo.com"
];
function tt(){
    while ( tabs.length < 3 ){
        iimSet('-var_SERVER', a.pop())
        iimSet('-var_TAB', tabs.length )
        iimPlay( 'test' );
    }
    if (a.length>0){
        setTimeout( tt, 1000 );
    }
}
tt();
iim-файл:
VERSION BUILD=6650406 RECORDER=FX
TAB OPEN NEW
TAB T={{TAB}}
URL GOTO={{SERVER}}

Получение json-строки по URL

js-файл:
iimPlay( "test.iim" );
var myObj = JSON.parse( iimGetLastExtract(1) );
alert(myObj[1]);
iim-файл
URL GOTO={{SERVER}}
TAG POS=1 TYPE=* ATTR=* EXTRACT=TXT





воскресенье, 24 апреля 2011 г.

php. Типы данных

Типы данных

print gettype( $var ); // определить тип данных

print get_class($var); // определить имя класса

Числа

бесконечность:
echo INF > 10000000 , "\n";
echo -INF > 100 ? "true" : "false", "\n";
echo -INF < -10000000 , "\n";
выведет:
1
false
1

Строки

плэйсхолдеры:
$text = sprintf( "text %s digit %d", "text", 11 );
кодировка:
string iconv( string $in_charset , string $out_charset , string $str );
ещё советуют посмотреть convert_cyr_string
экранировать html:
htmlspecialchars( $string ); // преобразует спец-символы в соответствующие html-последовательности ( '<' → &lt;).
strip_tags( $string ); // вырезает html символы
склейка:
$str = implode( "; ", $myArray );
заменить один массив строк другим:
$res = " 1, 2, 3";
echo str_replace( array("1","2"), array("4","5"), $res );

Массивы (Array)

Если массив используется как list, то добавление (append) элемента в массив:
$a = new Array();
$a[] = "first";

проверить вхождение в массив
in_array( $value, $array )
$module = array_shift( $args ); // получает первый элемент и удаляет его из массива

Сортировка

Перемешать массив произвольным ("рандомным") образом:
shuffle($arr_sauna);
Чтобы при обновлении страницы "рандомная" сортировка массива не изменялась:
srand(crc32(session_id())); // устанавливаем функцию рандомайза зависимой от session_id()
if(@$_SESSION['a']!=1)     shuffle($arr_sauna);


Дата и время

$date = strptime( '2009-10-20', '%Y-%m-%d' ); // Получить время (в массив) из строки в заданном формате
// далее преобразуем в unix-time c помощью mktime:
$time = mktime( $date["tm_hour"], $date["tm_min"], $date["tm_sec"], $date["tm_mon"], $date["tm_mday"], $date["tm_year"] + 1900 );
$str = strftime( '%Y.%m.%d %H:%M:%S', $time ); // и, наконец, получаем строку в нормальном человеческом виде

получить в виде строки:
date( "d.m.Y" ); // 31.10.2009
для базы данных:
date( 'Y-m-d H:i:s' );

получить в виде массива:
$date_time_array = getdate( time() );
echo $date_time_array['weekday']; // "seconds", "minutes", "hours", "mday" - день месяца, "wday" - день недели в числовом формате
                // "mon" - месяц в числовом формате, "year" - год, "dyear" - день года в числовом формате, "month" - полное имя месяца







пятница, 22 апреля 2011 г.

php



Настройки php.ini

# Максимальный размер загружаемого файла.
upload_max_filesize = 2M

сменить кодировку сайта

header( "Content-Type:	text/html; charset=utf-8" );

Конструкции языка

foreach

конструкция: foreach ($params as $name => &$value) проход по ассоциативному массиву
в $name записываются ключи
в $value значения.
при изменении value будет изменяться массив $params

function &name() # результат возвращается по ссылке (не происходит копирования)

однострочные функции (аналог lambda в python)

$lambda = create_function('', 'return "g_item_id=%d";');
$sql = "delete from {imce_gallery_items} where " . (implode( " or ", array_map( $lambda, $key_array ) ) );

Классы

Объявление

class MyClass{
    var $attr;
    function __construct(){  // конструктор в php5.
        $this->attr = "1"; // ключевое слово $this - указатель на текущий объект
                                 // ключевое слово self - указатель на текущий класс
    }
}

В php4 название конструктора совпадает с название класса. Если в php5 для класса не найдена функция __construct, то в качестве конструктора берётся функция с именем совпадающим с именем класса.

Переменная класса (статическая переменная)

задать значения статических переменных

По-умолчанию статической переменной можно задать только статическое занчение:
class Module extends Common{
    public static $tt = "какое-то там дефолтное значение. нельзя даже написать \$tt=md5();";
}
Но можно определить значение более-менее динамически:
class Module extends Common{
    public static $tt;
    public static function init(){
        self::$tt = md5("param1");
    }
}
Module::init(); // сразу после объявления класса вызываем статическую функцию, которая определяет значения статических переменных.
На самом деле Module::init(); можно вызывать и перед кодом класса, т.к. php-файл сначала загружается и разбирается, а уже потом выполняется.

реестр объектов внутри класса

$a = new MyClass();
$b = new MyClass();
$c = new MyClass();
print_r( MyClass::$byId );

class MyClass{
    static public $byId = Array();
    function __construct(){
        self::$byId[] = $this;
    }
}

Работа с файлами

$a = fopen( "1.txt", "w"); // открыть файл на запись. если файл не существует, создать
fwrite( $a, "aaa" ); // записать строку в файл
fclose( $a );

Загрузка файла на сервер

<form method="post" enctype="multipart/form-data">

if(copy($_FILES["filename"]["tmp_name"], "c:/temp/".$_FILES["filename"]["name"]))
{
echo(
"Файл успешно загружен <br>");
}

Получить список директорий

function dirList($path){
    $componentList = array();
    foreach (scandir($path) as $dir){
        if (is_dir($path . $dir) && $dir !== '.' && $dir !== '..'){
            $componentList[] = $dir;
        }
    }
    return $componentList;
}


Работа с сетью

Curl

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://web20/ws/");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); // чтобы полученный ответ от удалённого сервера был доступен как результат curl_exec();
$res = curl_exec($ch);
curl_close($ch);

post

curl_setopt($chCURLOPT_POST1);
curl_setopt($chCURLOPT_POSTFIELDS$data);

get и urlencode

в php нет функции, которая по массиву создаёт url-строку (типа питоновской urllib.urlencode), поэтому:
$authParam = array('msgType'=>'loginRequest','session'=>$dsS,'login'=>$_POST["login"],'passwd'=>$_POST["pswd"]);
function dictToUrl($authParam){
    array_walk($authParam, create_function('&$v,$k', '$v = $k."=".urlencode($v) ;'));
    return implode("&",$authParam);
}

Буфер


интересная php-конструкция:

function obHandler($text) // $text, видимо, это содержимое буфера
{

    header('Content-Type: application/json; charset=UTF-8');

    return json_encode($GLOBALS['_RESULT']);
}
ob_start("obHandler"); // назначает callback

при завершении работы php-скрипта выведет содержимое массива

XML

DOM

Пусть есть некий xml-файл:
<?xml version="1.0" encoding="utf-8" ?>
<commands>
<command name="Get" table="User"/>
<command name="Get" table="User">
    <item>
        <guid>ce987888-c6ba-4527-bbff-85b356f9ad9b</guid>
    </item>
</command>
</commands>
Парсим его:
$xml = DOMDocument::load( "1.xml" );
$nodeList = $xml->documentElement->getElementsByTagName("command");
for ( $i=0; $i < $nodeList->length; $i++ ){
    $command = $nodeList->item($i); // тип DOMNode
    print $command->nodeName . "<br>"; // название "command" ноды из строки
                                       // <command name="Get" ....
    $domAttr = $command->attributes->getNamedItem("name"); // из DOMNamedNodeMaps вытаскиваем DOMAttr
    print sprintf( '%s="%s"', $domAttr->name ,$domAttr->value );
    print "<br>";
}

Именованные параметры <command name="Get" table="User"/> вытаскиваются из DOMNode через параметр attributes (тип DOMNamedNodeMaps).
Вложенные узлы <command name="Get" table="User"><item>... вытаскиваются из DOMNode через параметр childNodes (тип DOMNodeList).
Чтобы получить текст внутри узла: $guidNode->childNodes->item(0)->wholeText (но что-то подсказывает, что должен быть метод проще)

SOAP

SOAP - это протокол обмена сообщениями в формате XML, передаваемых по какому-то сетевому протоколу (чаще всего через HTTP).
С помощью SOAP реализуются различные web-сервисы. Все возможные запросы к web-сервису могут быть описаны в WSDL-документе (см. http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL). Для тестирования запросов есть хорошая программа soapUI.
Классы для работы с SOAP в PHP доступны после установки соответствующего расширения (extension). Под windows - это файл php_soap.dll, он есть в дистрибутиве PHP. В Denwer-е по-умолчанию SOAP не установлен.


Xdebug

1. скачать dll c http://xdebug.org/. Пред скачиванием сайт попросит отправить phpinfo(), зато потом расскажет подробно что и как надо устанавливать.
2. в php.ini надо прописать настройки:
[Xdebug]
zend_extension_ts = \usr\local\php5\ext\php_xdebug-2.1.0-5.2-vc6.dll
xdebug.profiler_enable=On
xdebug.profiler_output_dir=\traces
xdebug.profiler_output_name = "cachegrind.out.%t.%s"
я их добавил сразу после "секции" Dynamic Extensions
3. установил php-программу webgrind

Все запускаемые фалы будут оставлять после себя логи в указанной для трейсов директории.
После запуска webgrind надо нажать кнопку update, после этого он начнёт анализировать самый последний лог-файл.
Анализ может идти несколько минут, если файл большой.








вторник, 19 апреля 2011 г.

MySQL DML

Работа с данными (DML - data manipulation language)



Select

select column1 as field1 from table1
можно исключить as из запроса:
select column1 as field1 from table1

тернарный оператор

select if(0, "true", "false")

dual

dual - это виртуальная несуществующая таблица, которую можно использовать для заглушки:
select null colum1 from dual where false
Такой запрос может быть нужен чтобы сгенерировать названия колонок в запросе, который объединяет несколько таблиц через union.

regexp, rlike

Функция RLIKE является синонимом для REGEXP, она предусмотрена для совместимости с mSQL.

экранирование спец-символов требует двойного обратного слеша:
select * from comment where comment_hi rlike '^1\\.[^\\.]*$'
примеры:
^[0-9]+$последовательность цифр


Вложенный select

можно проверить, существуют ли строки, удовлетворяющие условию:
select t.codec_group_name, t.description, t.codec_group_id from rtu.mvts_codec_group t
where (not exists (select * from rtu.test_codec_group_comments t1 where t1.codec_group_id=t.codec_group_id))
exists ищет до первой строки, удовлетворяющей условию (т.е. работает быстрее, чем count)

Сортировка средствами базы

Рандомная сортировка
select * from my_table order by rand();

Кастомная сортировка
select * from mw_attr where attr_id in (301,302,305,306)
order by case attr_id
    when 301 then 1
    when 305 then 2
    when 306 then 3
    when 302 then 100
end;
Выведет колонки отсортированными по весу.


Сортировка по логическому выражению

select * from action order by version='all' desc;
В этом запросе сначала будут выведены те строки, для которых условие выполняется.

Связь многие ко многим

Допустим, что есть таблица районов. Таблица предприятий. И таблица связей между районами и предприятиями.
Предприятие может иметь филиалы в нескольких районах. Очевидно, что связь многие ко многим через третью таблицу.
Теперь, положим, надо выбрать все районы, но каждый раз определять, есть ли филиал заданного предприятия в каждом районе.
Запрос будет выглядеть примерно так:
select district_id, district_nm,
    (select firm_id from distict_firm t1 where firm_id=78 and t.district_id=t1.district_id) firm_id
from district t
ключевым моментом здесь является использование подзапроса, который должен вернуть ровно одну ячейку.

Группировка

Склеить значения varchar поля:
select group_concat(version separator '') from update_special group by object_type

Update

update первым параметром получает table_reference, что означает, что вместо имени таблицы можно использовать конструкции left/right/inner join.

update update_special t inner join update_path p on t.version=p.target_version and p.path_id<25
set t.path_id=p.path_id;

Update из второй (виртуальной) таблицы

update

            table1 t1,

            (

                        select * from (

                        select '01.01' gui_hi_old, '_01.02' gui_hi_new

                        union all

                        select '01.01.01' gui_hi_old, '_01.02.01' gui_hi_new

                        union all

                        select '01.02' gui_hi_old, '_01.01.01' gui_hi_new

                        union all

                        select '01.02.01' gui_hi_old, '_01.01' gui_hi_new

                        ) t3 order by gui_hi_old desc

            ) t2

set

            t1.gui_hi = t2.gui_hi_new

where

            t1.gui_hi = t2.gui_hi_old


Изменение сортировки строк по полю pos

UPDATE my_table
SET pos = ELT(FIELD(pos, 1,2,3), 3,2,1)
WHERE pos IN (1,2,3);
Сортировка не прокатит, если поле pos является уникальным ключом

Insert

Копировать данные из одной таблицы в другую

1. insert into mw_role_set ( select 3, object_id, rights from mw_role_set where role_id=1);

2. insert into mw_string_prop ( str_id, prop_nm, lang_id, str_text )
select 930, 'MERATableColumn', t.lang_id, t.str_text from mw_string_prop
where str_id=928 and prop_nm='name'

При вставке даннных может возникнуть проблема пересечения ключей. Можно сделать обрабочик:
insert into my_table select * from my_table2
on duplicate key update
    field = concat( values(field), my_table.field );
через values будет доступно значение из выборки по my_table2

Вставка из виртуальной таблицы

insert into test2 (t1_id, t2_item)
select  1,  "description"
union
select  2 ,  "scription"
union
select  2,  "unscription"

Replace

replace mw_user_default_aa set gui_hi='119.01', aa_id=3

Встроенные функции

Работа со строками

http://www.intuit.ru/department/database/mysql/10/

concat
cклеить строки
select concat("str1", "str2");
group_concatсклеить результаты подселекта в строку. имеет ограничение в количестве склеиваемых символов (где-то 1000). чтобы отменить ограничение:
set group_concat_max_len = 1000000;
select column0, (select group_concat(column1 separator "," ) from t2) from t1;
replace()
заменить подстроку

SELECT REPLACE('www.mysql.com', 'w', 'Ww');

'WwWwWw.mysql.com'

Дата и время

date_format
получить время в заданном формате (как строку)
icom-studio.com.ua/blog/use_of_mysql_date_format.html
select date_format(date_column, '%Y.%m.%d %H:%i:%S') from my_table;
now()
текущее дата-время

curdate()
текущая дата


выбрать данные за указанный период
select * from my_table where DATE_SUB(NOW(), INTERVAL 1 DAY) < column_nm
select * from my_table where DATE_SUB(NOW(), INTERVAL 24 HOUR) < column_nm
период может быть указан в виде дроби 1.3 DAY

Типы данных

Бинарные данные (blob и longblob)

blob и longblob - текстовые поля для хранения бинарных данных.
blob ограничен 64кб, longblob - 4.2Gb

Запрос получения данных (select) не может вернуть больше 16Mb (определяется конфигурацией MySQL). Нельзя записать (insert, update) данных больше, чем позволяет оперативная память компьютера. Поэтому, есть ограничения при работе с большими файлами (будем считать, что в blob хранятся файлы).

как строки
С полями blob можно работать точно так же, как со строками. Можно получить часть строки, узнать количество байт, добавить к строке.
select substring(f, 1, 10), length(f) from myTable where id=1;
update myTable set f=f+%s where id=1;


работа через файлы

select f from myTable where id=2 into dumpfile '/tmp/sss.avi';
update myTable set f=load_file('/tmp/xxx.avi') where id=1

Lock-и

Залочить таблицу:

lock tables debug_call write; # есть ещё read, но не знаю, зачем он нужен

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

Разлочить таблицы, залоченные текущим курсором:
unlock tables;

Получить информацию о залоченных таблицах:
show open tables;













понедельник, 18 апреля 2011 г.

shell


Shell


Начало

shell - это интерпретируемый язык. shell-файл - это программа.
Первая строка шелл-файла, которая говорит, что интерпретировать файл надо через shell:
#!/bin/sh 

строка, которая выполнится в консоли:
script -c "mvts3g-server -f $*"

Команды

sleep 1s 1mждать 1 секунду и 1 минуту



Переменные

Специальные


#!/bin/bash
# Its a test script : test.sh
echo "First Parameter : \$1 = $1"
echo "Second parameter : \$2 = $2"
echo "Total passed parameters : \$# = $#"
echo "All parameters : \$* = $*"
echo "All parameters : \$@ = $@"
echo "Process Id : \$$ = $$"

exit 0

отличия $@ и $i

в кавычках $* превращается в строку, разделенную первым символом IFS, а $@ — в набор строк
поэтому желательно использовать $@
#!/bin/bash
export IFS="___"
echo "\$*: $*"
for i in "$*";
do
    echo "$i" ## в цикле будет одна(!) итерация
done

echo "\$@: $@"
for i in "$@";
do
    echo "$i" ## сколько параметров запуска скрипта, столько же итераций
done

Экспорт переменных

Пусть есть два скрипта
s1
#!/bin/sh
VAR=12345
export VAR ## пробрасывает переменные в вызываемые скрипты
echo $VAR
./s2
и s2
#!/bin/sh
echo $VAR

Конструкции

обратные кавычки ``

код, написанный в обратных кавычках выполнится первым, и результат выполнения вернётся в качестве аргумента.
$ echo `echo 'off'`
выведет на экран
off




воскресенье, 17 апреля 2011 г.

PyScripter

PyScripter



отображать номера строк:
Tools -> Options -> Editor options -> вкладка Display -> Show line numbers

PyLint

pylint - тулзина для проверки кода по code standard (запускается из под
pyscripter)

http://www.logilab.org/Project - скачать архивы pylint, logilab-common, logilab-astng


файл pylint-0.15.2.tar.gz распаковать в
C:\Python25\Lib\site-packages\pylint





оставшиеся два в

C:\Python25\Lib\site-packages\logilab\common

и C:\Python25\Lib\site-packages\logilab\astng



в папке C:\Python25\Lib\site-packages\logilab должен присутствовать
файл __init__.py, чтобы эта
папка воспринималась как package питона





в настройках PyScripter-a прописать:

Tools -> Configure Tools -> PyLint -> Parameters ->

$[PythonDir-Short]Lib\site-packages\pylint\lint.py $[ActiveDoc-Short]
-fparseable -rn --disable-msg-cat=R --disable-msg=C0103

далее pylint будет доступен по Tools -> Tools -> PyLint

(либо по ctrl+L )

Ошибки

Missing docstring Отсутствует описание модуля (в начале документа)














Команды

ctrl+ shift+ L - режим выделения строк (строки будут выделяться по shift+ arrow)
перейти в нормальный режим выделения: ctrl+ shift+ N

форматы данных

форматы данных

Сериализация

json


yaml

библиотека для Python
http://pyyaml.org/download/pyyaml/

xml


Устройство файлов

png

import struct
a = open('1.png', 'rb' )
content = a.read() ## считываем начало файла
start = content.index("IHDR")+4
w, = struct.unpack( ">i", content[start:start+4] )  ## внимание: big-endian!!!
h, = struct.unpack( ">i", content[start+4:start+8] )
print w, h  ## ширина / высота

gif

import struct
a = open('2.gif', 'rb' )
content = a.read()
start = 6 ## пропускаем заголовок
w, = struct.unpack( "h", content[start:start+2] )
h, = struct.unpack( "h", content[start+2:start+4] )
print w,h