Archive for the ‘Code’ Category

Проверка количества проиндексированных страниц в Google

Tuesday, September 7th, 2010 |

Как определить кол-во проиндексированных страниц в гугле? реализация на Python. Недавно нужно было срочно, написал :

import urllib
import re

from urllib2 import urlopen
from urlparse import urlparse
from urllib import FancyURLopener

class GOpener(FancyURLopener):
    version = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6'

def web_getpage(url):
    g_opener = GOpener()
    page = g_opener.open(url)
    return page.read()

def get_index(url):
    request = 'http://www.google.com/search?q=site:' + url
    # About 105,000,000 results
    index = 0
    try:
        gs = web_getpage(request)
        p = re.compile('About (.*) results')
        index = int(p.findall(gs)[0].replace(",", ""))
    except SearchError, e:
        index = -1
        #print "Search Failed : %s" % e
    finally:
        #print "Index: %d\tURL: %s" % (int(index), url)
        return index

Проверка подключения к интернету

Thursday, September 2nd, 2010 |
from urllib2 import urlopen
""" Returns True if we appear to have an internet connection or False.
    It defaults to using google as a test server, but you can supply an alternative if you want."""
def isonline(reliableserver='http://www.google.com'):
    try:
        urlopen(reliableserver)
        return True
    except IOError:
        return False

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

Проверка Google PR на Python

Tuesday, August 31st, 2010 |

Собственно рабочая функция проверки Google Page Rank :

import urllib, sys

def get_pagerank(url):
    hsh = check_hash(hash_url(url))
    gurl = 'http://www.google.com/search?client=navclient-auto&features=Rank:&q=info:%s&ch=%s' % (urllib.quote(url), hsh)
    try:
        f = urllib.urlopen(gurl)
        rank = f.read().strip()[9:]
    except Exception:
        rank = 'N/A'
    if rank == '':
        rank = '0'
    return rank

def  int_str(string, integer, factor):
    for i in range(len(string)) :
        integer *= factor
        integer &= 0xFFFFFFFF
        integer += ord(string[i])
    return integer

def hash_url(string):
    c1 = int_str(string, 0x1505, 0x21)
    c2 = int_str(string, 0, 0x1003F)

    c1 >>= 2
    c1 = ((c1 >> 4) & 0x3FFFFC0) | (c1 & 0x3F)
    c1 = ((c1 >> 4) & 0x3FFC00) | (c1 & 0x3FF)
    c1 = ((c1 >> 4) & 0x3C000) | (c1 & 0x3FFF)

    t1 = (c1 & 0x3C0) << 4
    t1 |= c1 & 0x3C
    t1 = (t1 << 2) | (c2 & 0xF0F)

    t2 = (c1 & 0xFFFFC000) << 4
    t2 |= c1 & 0x3C00
    t2 = (t2 << 0xA) | (c2 & 0xF0F0000)

    return (t1 | t2)

def check_hash(hash_int):
    hash_str = '%u' % (hash_int)
    flag = 0
    check_byte = 0

    i = len(hash_str) - 1
    while i >= 0:
        byte = int(hash_str[i])
        if 1 == (flag % 2):
            byte *= 2;
            byte = byte / 10 + byte % 10
        check_byte += byte
        flag += 1
        i -= 1

    check_byte %= 10
    if 0 != check_byte:
        check_byte = 10 - check_byte
        if 1 == flag % 2:
            if 1 == check_byte % 2:
                check_byte += 9
            check_byte >>= 1

    return '7' + str(check_byte) + hash_str

print get_pagerank("http://twitter.com")

Легкая IDE для Pyhton

Tuesday, August 24th, 2010 |

Не так давно услышал про такую IDE как Pyscripter. Скачал отсюда, утсановил. Вообщем пара слов : легче чем NetBeans определенно. Рекомендую.

pyscripter IDE

Время выполнения функции python

Monday, June 21st, 2010 |

Бывает необходимо замерить время выполнения скрипта или функции. Сделать это можно следующим образом :

start = time.time()
function_name()
print "Elapsed Time: %s" % (time.time() - start)

function_name() <<—- функция время выполнения которой нужно замерить

HumanEmulator. Пишем framework для регистраций.

Monday, May 3rd, 2010 |

Продолжая монологи про HumanEmulator дам совет о том, как сделать более-менее универсальный шаблон для создания регистраций. Ведь по сути выполняются одни и те же дейсвия : “Зайти сюда, заполнить поля, щелкнуть эту кнопку”. Это естественно касается именно процесса регистрации, далее все равно придется писать код “как положенно”.

	$fields = array(
		"input:name" => $name,
		"input:mail" => $gmail,
		"input:conf_mail" => $gmail,
		"input:profile_url" => "http://google.com",
		"cptch:4" => "recaptcha_response_field", // cptch - image number, value = field name
		"checkbox:og_register[1750]"	=> True,
		"textarea:profile_description"	=> $bio,
		"confirm:button" => "op"
	);

Это что-то вроде правила для заполнения полей. Далее пишем функцию _register() которая заполняет поля форм согласно правилу. Функция естественно “демо”, её задача дать базовое представление о том, как это всё будет работать.

function _register($fields) {
	include("include_all.php");
	foreach ($fields as $key=>$value) {
		$split				= explode(':', $key);
		$param_field		=	$split[0];
		$param_name	= $split[1];
		switch ($param_field)	{
			case "input" :
				$input->set_focus_by_name($param_name);
				$input->set_value_by_name($param_name, $value);
			break;
			case "cptch" :
				$captcha = $app->dlg_captcha_from_image_number($param_name);
				$input->set_focus_by_name($value);
				$input->set_value_by_name($value, $captcha);
			break;
			case "listbox" :
				$list_size		=	$listbox->get_length_by_name($param_name);
				$rnd_elem	= rand(1, $list_size - 1);
				if ($list_size > 50) {
					$rnd_elem = 80;
				}
				$listbox->select_num_value_by_name($param_name, $rnd_elem);
				echo "

\n\n\n";
				echo "List name : $param_name List size : $list_size Elem : $rnd_elem \n\n";
			break;
			case "confirm" :
					switch ($param_name) {
						case "button" :
							$browser->wait(1);
							sleep(rand(1,3));
							$button->click_by_name($value);
						break;
						case "btn" :
							$browser->wait(1);
							sleep(rand(1,3));
							$btn->click_by_number($value);
						break;
					}
			break;
			case "checkbox" :
				$checkbox->click_by_name($param_name);
			break;
			case "textarea" :
				$textarea->set_value_by_name($param_name, $value);
			break;
		}
	}
}

В итоге сам процесс регистрации :

	$browser->navigate($url);
	$browser->wait(1);
	sleep(rand(1,3));

	$anchor->click_by_inner_text("Register", true);

	$browser->wait(rand(2,6));

	_register($fields);

	gmail_confirmer($gmail, $pass, 'http://www.site.com/validate/', "site registration");

Используется функция gmail_confirmer о которой можно прочитать в предыдущей статье посвещянной использованию  HumanEmulator’а.  Весь код как говориться “very basic”, но идею уловить можно и переписать код под свои задачи.

Human Emulator. Автоконфирм e-mail.

Tuesday, April 20th, 2010 |

Речь пойдет о такой замечательно программе, как Human Emulator. Мне кажется это оптимальное сочетание простоты и скорости написания небольших скриптов с довольно мощьным функционалом. На нем даже можно написать полоноценную спамилку. Вообщем продукт безусловно хороший и полезный, свою стоимость он оправдывает на 100%.

Программировать на Human Emulator – легко, но как всегда есть типовые задачи для которых неплохо было бы иметь сниппеты. Итак сниппет первый – автоконфирмер регистрацый которые приходят на ящик gmail. Суть проста – любой кодер без проблем уловит идею и перепишет как ему нужно.

Вызывается примерно так

gmail_confirmer($gmail, $pass, 'http://............./validate/', "Welcome to site ....");

Как видно 3ий параметр это с чего начинается строчка на которую нужно кликнуть, чтобы подтвердить регистрацию, а 4ый – это заголовок приходящего e-mail.

function gmail_confirmer($usr_mail, $usr_pass, $site_url, $search_str) {
	include("include_all.php");
	init_browser();
	$browser->wait(3);
	sleep(rand(1,3));

	$browser->navigate("gmail.com");

	$browser->wait(2);

	$input->set_focus_by_name("Email");
	$input->set_value_by_name("Email", $usr_mail);
	$browser->wait(2);
	$input->set_focus_by_name("Passwd");
	$input->set_value_by_name("Passwd", $usr_pass);
	$browser->wait(2);

	$button->click_by_name("signIn");
	$browser->wait(rand(2,6));
	$anchor->click_by_inner_text("basic HTML", false);
	$browser->wait(rand(2,6));

	$anchor->click_by_inner_text($search_str, false);

	$browser->wait(rand(2,6));

	$urls	= $anchor->get_all_urls();
	$urls	=	explode("", $urls);

	$url	=	array_find($site_url, $urls);
	//$debug->message_box($url);

	$browser->wait(3);
	$browser->navigate($url);
	$browser->wait(3);
	return true;
}

Несколько пояснений include(“include_all.php”); – для того чотбы без проблем использовать объекты Human Emulator внутри функций. Выглядит файл примерно так :

	// Yo
	global	$browser;
	global	$anchor;
	global	$input;
	global	$listbox;
	global	$button;
	global	$radiobox;
	global	$checkbox;
	global	$debug;
	global	$textarea;
	global	$inputimage;
	global	$captcha;
	global	$webpage;
	global	$app;
	global	$init_browser;
	global	$textfile;
	global	$btn;
	global	$inputfile;
	global	$debug;
	global	$frame;
	global	$form;

init_browser(); – инициализирует браузер. тут можно делать что угодно, очищать куки, делать рефреш.

Добавить категории через WordPress API

Wednesday, March 10th, 2010 |

Класс описанный в статье “Постинг в WordPress” позволяет прикрепить к посту уже созданные категории, что как бы несколько неудобно если их нужно создавать динамически. Это можно сделать через WordPress API (по XML-RPC), но в библиотеке эта функция не реализованна, впрочем как и многие другие. Пришлось написать самому :

import xmlrpclib

def uniq(input):
  output = []
  for x in input:
    if x not in output:
      output.append(x)
  return output

def getCategories(blog_url, blog_user, blog_pwd):
    _server = xmlrpclib.ServerProxy(blog_url)
    cat = _server.wp.getCategories(1, blog_user, blog_pwd)
    categories = []
    for item in cat:
        categories.append(item['categoryName'].replace("&", "&"))
    return categories

def addCategories(blog_url, blog_user, blog_pwd, categories):
    _server = xmlrpclib.ServerProxy(blog_url)
    categories = uniq(categories)
    created_cat = getCategories(blog_url, blog_user, blog_pwd)
    for item in categories:
        itm = item.replace("&", "&")
        if (itm not in created_cat):
            post_name = itm
            post_slug = itm.replace(" ", "-")
            post_slug = post_slug.replace("&", "")
            post_parent_id = 0
            post_description = itm
            catStructure = {'name' : post_name,
                            'slug' : post_slug,
                            'parent_id' : post_parent_id,
                            'description' : post_description}
            category_id = _server.wp.newCategory(1, blog_user, blog_pwd, catStructure)

Подобный образом можно реализовать вызов практически любого документированного метода. btw разработчики вордпресса сильно отстают с документацией, поэтому проще посмореть исходный код файла xml-rpc.php в последней сборке вордпресса, чтобы быть в курсе. Я так понимаю, используя вордпрессовскую реализацию metaWeblog API (metaWeblog.newPost) можно добавлять еще и тэги к посту, но саму функцию вроде addTags я не нашел, к сожалению.

Вот так это выглядит на практике :

        wp_cat.addCategories(category)
        cats_id = []
        for item in category:
            if (wp.getCategoryIdFromName(item) <> None):
                cats_id.append(wp.getCategoryIdFromName(item))
        post.categories = tuple(uniq(cats_id))
        idPost = wp.newPost(post, True)

Где wp – это экземпляр класса wordpresslib, а category – это список категрий в виде списка – ['look', 'here']. Типа того, вообщем разобраться несложно.

База данных WordNet. Словарь синонимов.

Thursday, December 3rd, 2009 |

Более подробно сабж можно оценить сходив по ссылке.

WordNet – большая лексическая база данных Английского языка разработанная под руководством George A. Miller.
В наличии имеются существительные, глаголы, прилагательные и наречия, которые сгруппированы в наборы когнитивных синонимов (synsets), каждый из которых выражает различные понятия. Synsets взаимосвязаны посредством концептуально-семантических и лексических отношений (жесть!!!).
Итоговую сеть связей между значениями слов и понятий, можно просматривать с помощью WordNet, который свободно распространяется и доступен для скачивания. Структура WordNet делает его полезным инструментом для компьютерной лингвистике и обработки естественного языка.

Я думаю, намек довольно прозрачен.

Скачать и посмотреть.

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

Библиотеки для работы с WordNet.

Там есть на что посмотреть. Например онлайн словари http://www.a2zdefined.com/ и http://www.memidex.com/

Рекомендую взглянуть на Natural Language Toolkit – это библиотека для Python. Примеры использования по ссылке.

Как сделать крутой Login Page используя PHP, MySQL & jQuery

Thursday, December 3rd, 2009 |

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

Создание Login Page : PHP, MySQL & jQuery

Код пригодится для создание member zone на сайтах (партнерки, дейтенги, или еще какая-нибудь ерунда). Демо можно скачать тут.

Step 1 – MySQL

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

--
-- Table structure for table `tz_members`
--
CREATE TABLE `tz_members` (
  `id` int(11) NOT NULL auto_increment,
  `usr` varchar(32) collate utf8_unicode_ci NOT NULL default '',
  `pass` varchar(32) collate utf8_unicode_ci NOT NULL default '',
  `email` varchar(255) collate utf8_unicode_ci NOT NULL default '',
  `regIP` varchar(15) collate utf8_unicode_ci NOT NULL default '',
  `dt` datetime NOT NULL default '0000-00-00 00:00:00',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `usr` (`usr`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Мы определили id как auto_increment, это уникальный идентификатор, который будет присвоен каждому пользователю. Так же urs определен как UNIQUE KEY, для того, чтобы гарантировать уникальность юзернейма.

После того как таблица создана, нужно прописать данные в файл connect.php, это несложно. После этого можно будет запустить пример на своем сервере. Допилить напильником, и вставить куда надо.

Step 2 – XHTML

demo.php
Пора включить феб форму логина в нашу страницу.


The Sliding jQuery Panel

A register/login solution

You are free to use this login and registration system in you sites!

A Big Thanks

This tutorial was built on top of Web-Kreation's amazing sliding panel.

Member Login

'.$_SESSION['msg']['login-err'].'
'; unset($_SESSION['msg']['login-err']); // This will output login errors, if any } ?>

Not a member yet? Sign Up!

'.$_SESSION['msg']['reg-err'].'
'; unset($_SESSION['msg']['reg-err']); // This will output the registration errors, if any } if($_SESSION['msg']['reg-success']) { echo '
'.$_SESSION['msg']['reg-success'].'
'; unset($_SESSION['msg']['reg-success']); // This will output the registration success message } ?>

Members panel

You can put member-only data here View a special member page - or - Log off

В нескольких местах кода идет проверка определены ли переменные : $_SESSION['usr'] и $_SESSION['id'], это позволяет определить залогинен ли юзер на сайте или нет. Если они определены то это значит, что юзер уже залонился на сайте и ему нужно показывать совсем другой контент. Позже обсудим этот момент более детально.
После формы login – расположена основная часть страницы. Как это принято у нас, вебмастеров.

A Cool Login System

Easy registration management with PHP & jQuery

This is a ...

Как видите ничего особенного.

i21

Step 3 – PHP

demo.php
Далее собственно логика обработки этой формы. Сделано на PHP, ну хоть на что-то этот язык годен.
В статье дают дельный совет : если вы планируете на века и проект серьезный, будет хорошей идеей разбить в на несколько файлов, и включать их по мере надобности (require). Это важно для больших проектов т.к. позволить использовать код повторно в других местах.

Вот что получается :

define('INCLUDE_CHECK',true);

require 'connect.php';
require 'functions.php';

// Those two files can be included only if INCLUDE_CHECK is defined

session_name('tzLogin');
// Starting the session

session_set_cookie_params(2*7*24*60*60);
// Making the cookie live for 2 weeks

session_start();

if($_SESSION['id'] && !isset($_COOKIE['tzRemember']) && !$_SESSION['rememberMe'])
{
	// If you are logged in, but you don't have the tzRemember cookie (browser restart)
	// and you have not checked the rememberMe checkbox:

	$_SESSION = array();
	session_destroy();

	// Destroy the session
}

if(isset($_GET['logoff']))
{
	$_SESSION = array();
	session_destroy();
	header("Location: demo.php");
	exit;
}

if($_POST['submit']=='Login')
{
	// Checking whether the Login form has been submitted

	$err = array();
	// Will hold our errors

	if(!$_POST['username'] || !$_POST['password'])
		$err[] = 'All the fields must be filled in!';

	if(!count($err))
	{
		$_POST['username'] = mysql_real_escape_string($_POST['username']);
		$_POST['password'] = mysql_real_escape_string($_POST['password']);
		$_POST['rememberMe'] = (int)$_POST['rememberMe'];

		// Escaping all input data

		$row = mysql_fetch_assoc(mysql_query("SELECT id,usr FROM tz_members WHERE usr='{$_POST['username']}' AND pass='".md5($_POST['password'])."'"));

		if($row['usr'])
		{
			// If everything is OK login

			$_SESSION['usr']=$row['usr'];
			$_SESSION['id'] = $row['id'];
			$_SESSION['rememberMe'] = $_POST['rememberMe'];

			// Store some data in the session

			setcookie('tzRemember',$_POST['rememberMe']);
			// We create the tzRemember cookie
		}
		else $err[]='Wrong username and/or password!';
	}

	if($err)
		$_SESSION['msg']['login-err'] = implode('
',$err);
		// Save the error messages in the session

	header("Location: demo.php");
	exit;
}

Мы ставим cookie tzRemember чтобы всегда знать следует ли логофать пользователя, который не поставил галочку “remember me”. Если кука не стоит (например после рестарта браузера) и посетитель не выбрал “remember me”, ему придеться вбивать логин/пасс заново.
Сама сессия ставится на 2е недели (session_set_cookie_params).

Следующая часть файла demo.php

else if($_POST['submit']=='Register')
{
	// If the Register form has been submitted
	$err = array();

	if(strlen($_POST['username'])<4 || strlen($_POST['username'])>32)
	{
		$err[]='Your username must be between 3 and 32 characters!';
	}

	if(preg_match('/[^a-z0-9\-\_\.]+/i',$_POST['username']))
	{
		$err[]='Your username contains invalid characters!';
	}

	if(!checkEmail($_POST['email']))
	{
		$err[]='Your email is not valid!';
	}

	if(!count($err))
	{
		// If there are no errors
		$pass = substr(md5($_SERVER['REMOTE_ADDR'].microtime().rand(1,100000)),0,6);
		// Generate a random password

		$_POST['email'] = mysql_real_escape_string($_POST['email']);
		$_POST['username'] = mysql_real_escape_string($_POST['username']);
		// Escape the input data

		mysql_query("	INSERT INTO tz_members(usr,pass,email,regIP,dt)
					VALUES(
					'".$_POST['username']."',
					'".md5($pass)."',
					'".$_POST['email']."',
					'".$_SERVER['REMOTE_ADDR']."',
					NOW()
		)");

		if(mysql_affected_rows($link)==1)
		{
			send_mail(	'demo-test@tutorialzine.com',
					$_POST['email'],
					'Registration System Demo - Your New Password',
					'Your password is: '.$pass);
					$_SESSION['msg']['reg-success']='We sent you an email with your new password!';
		}
		else $err[]='This username is already taken!';
	}

	if(count($err))
	{
		$_SESSION['msg']['reg-err'] = implode('
',$err);
	}

	header("Location: demo.php");
	exit;
}

$script = '';
if($_SESSION['msg'])
{
	// The script below shows the sliding panel on page load
	$script = '
	';
}

Сохраняем все встречающиеся ошибки в массив $err, который далее присваевается переменной $_SESSION, для того, чтобы сохранить эти данные после редиректа.

Вы могли замететь на некоторых сайтах, что когда заполняете и отправляете форму, а затем обновляете страницу – данные передаются опять. Это может стать проблемой, привести к 2ой регистрации и ненужной нагрузке на сервер, чтобы избежать этого в примере использована функция header, которая просто редиректит браузер на ту же страницу. Страница обновляется, данные не посылаются.

Не забываем о том, что используется $_SESSION для хранения встречающихся ошибок, и важно сделать unset для этой переменной, после того как покажем ошибку юзеру, иначе они будут показываться при каждом просмотре страницы. Обратите внимание, что мы создали дополнительный скрипт (строчки 60-70 2ой части PHP кода), который показывает панель при загрузке страницы.

Теперь CSS

i12

Step 4 – CSS

Выдвигающаясяя панель имеет собственный шаблон CSS.
demo.css

body,h1,h2,h3,p,quote,small,form,input,ul,li,ol,label{
	/* The reset rules */
	margin:0px;
	padding:0px;
}

body{
	color:#555555;
	font-size:13px;
	background: #eeeeee;
	font-family:Arial, Helvetica, sans-serif;
	width: 100%;
}

h1{
	font-size:28px;
	font-weight:bold;
	font-family:"Trebuchet MS",Arial, Helvetica, sans-serif;
	letter-spacing:1px;
}

h2{
	font-family:"Arial Narrow",Arial,Helvetica,sans-serif;
	font-size:10px;
	font-weight:normal;
	letter-spacing:1px;
	padding-left:2px;
	text-transform:uppercase;
	white-space:nowrap;
	margin-top:4px;
	color:#888888;
}

#main p{
	padding-bottom:8px;
}

.clear{
	clear:both;
}

#main{
	width:800px;
	/* Centering it in the middle of the page */
	margin:60px auto;
}

.container{
	margin-top:20px;

	background:#FFFFFF;
	border:1px solid #E0E0E0;
	padding:15px;

	/* Rounded corners */
	-moz-border-radius:20px;
	-khtml-border-radius: 20px;
	-webkit-border-radius: 20px;
	border-radius:20px;
}

.err{
	color:red;
}

.success{
	color:#00CC00;
}

a, a:visited {
	color:#00BBFF;
	text-decoration:none;
	outline:none;
}

a:hover{
	text-decoration:underline;
}

.tutorial-info{
	text-align:center;
	padding:10px;
}

Step 5 – jQuery

demo.php







В этом кусочке кода, для начала мы используем библиотеку Google CDN. Затем хак, чтобы долбанный IE отображал все правильно.
В конце страницы вызывается скрипт который показывает нашу панель логина.

About Me

Few shit about and url More

Want to subscribe?

 Subscribe in a reader Or, subscribe via email:
Enter your email address:  
Find entries :