<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>graywolf&#039;s lair &#187; Мережі та ІТ</title>
	<atom:link href="http://graywolf.org.ua/category/blog/it/feed/" rel="self" type="application/rss+xml" />
	<link>http://graywolf.org.ua</link>
	<description>Inhuman being&#039;s diary...</description>
	<lastBuildDate>Thu, 02 Sep 2010 14:11:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Mercurial саторі. Частина 1</title>
		<link>http://graywolf.org.ua/2010/09/02/mercurial-satori-1/</link>
		<comments>http://graywolf.org.ua/2010/09/02/mercurial-satori-1/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 12:17:45 +0000</pubDate>
		<dc:creator>graywolf</dc:creator>
				<category><![CDATA[Мережі та ІТ]]></category>
		<category><![CDATA[dvcs]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[itblog-ua]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[svc]]></category>
		<category><![CDATA[версіїї]]></category>
		<category><![CDATA[меркуріал]]></category>
		<category><![CDATA[рскв]]></category>
		<category><![CDATA[скв]]></category>

		<guid isPermaLink="false">http://graywolf.org.ua/?p=1520</guid>
		<description><![CDATA[Скоро мені знадобиться знайомити одного майбутнього молодого розробника з таїнством користування системами контролю версій (надалі VCS, version control system) і тому щоб трохи систематизувати те, що я збирався розповісти, вирішив написати цей допис. Він розрахований на зовсім базовий рівень роботи і тому тут багато розжовувань, які більш досвідченим особам наврядчи будуть цікаві. Знайомство одразу буду [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://graywolf.org.ua/wp-content/uploads/2010/09/mercurial_logo.png"><img src="http://graywolf.org.ua/wp-content/uploads/2010/09/mercurial_logo.png" alt="" title="Mercurial (Меркуріал)" width="200" height="240" class="alignleft size-full wp-image-1523" align="left" /></a> Скоро мені знадобиться знайомити одного майбутнього молодого розробника з таїнством користування системами контролю версій (надалі VCS, <em>version control system</em>) і тому щоб трохи систематизувати те, що я збирався розповісти, вирішив написати цей допис. Він розрахований на зовсім базовий рівень роботи і тому тут багато розжовувань, які більш досвідченим особам наврядчи будуть цікаві. Знайомство одразу буду проводити на прикладі сучасних розподілених систем, в нашому випадку <a href="http://mercurial.selenic.com/">Mercurial</a>.</p>
<h3>Навіщо воно треба?</h3>
<p>Для людей які хоч трохи займались програмуванням відповідь має бути очевидною, але на всяк випадок нагадаю: під час роботи над чимось ви сто відсотків будете проходити якісь віхи розробки і контроль версій дозволить отримувати стан проекту на певний момент. Плюс можна створювати гілки розробки. Уявіть, що при побудові будинку ви вирішите добудувати якийсь незапланований поверх, але не впевнені чи все триматиметься як слід. Ви віртуально дублюєте поточний будинок, будуєте свій поверх, поки інші будівельники тим часом працюють по запланованому графіку. Потім ви вирішуєте, що результат вашої роботи вас влаштовує ви плеском в долоні вставляєте його у існуючий будинок. А може будівельники десь помилились при розрахунках і набудували якусь фігню, то вони можуть так само швидко відкотитись до місця коли щось пішло не так.<br />
До речі, місце де зберігаютсья всі стани проекту в термінах VCS називаєтсья репозитарій, а місце в якому ви вносите правки &#8211; відповідно робоча копія. Процес відправки набору змін з робочої копії до репозиторію &#8211; це операція <em>commit</em>. Репозитарії часто зберігають десь подалі, не на робочих машинах, щоб у випаку коли у вас, наприклад, здохне комп, весь код можна буде повіністю відновити. У мене був гіркий досвід збереження єдиного екземпляру коду одного сайту на ноуті, який згодом сперли&#8230; З тих пір я не розлучний -з VCS та бекап-системами типу <a href="http://graywolf.org.ua/2009/02/10/dropbox-sync-and-backup/">Dropbox</a> і зберігаю всі важливі дані в інтернеті. Плюс зручно, що можна з легкістю отримувати точні копії на будь-яку машину.<br />
І нарешті ще одна зручна штука в користуванні VCS, хоч і похідна від нього &#8211; це можливість робити code review &#8211; огляд змін які зробив розробник між версійми коду. Принципироботи code review-систем чудово накладаються на принципи роботи VCS і тому вони часто бувають нерозлучні, коли якість коду має велике значення.<br />
<span id="more-1520"></span></p>
<h3>Розподілені VCS</h3>
<p>Як писалося вище, існують поняття репозитарію та робочої копії. У VCS, які були популярні донедавна було чітке розподілення обов&#8217;язків: репозитарій був один і центральний, часто на виділеному сервері. Кожний <em>commit</em> відправляв дані з робочої копії до репозиторію. В певному сенсі це було не завжди зручно у випадку, коли ви хочете закинути кілька змін різними commit&#8217;ами на сервер, що знаходиться в інтернеті. По перше, процес зазвичай досить повільний, по-друге, за відсутності зв&#8217;язку з інтернетом ви взагалі не зможете зробити <em>commit</em>.</p>
<p>Тому щоб побороти подібні недоліки прийшли <em>розподілені системи контролю версій</em>: <a href="http://mercurial.selenic.com/">Mercurial</a>, <a href="http://git-scm.com/">Git</a>, <a href="http://bazaar.canonical.com/en/">Bazaar</a>, тощо&#8230; Суть їх проста: кожна копія проекту є одночасно і репозитарієм і робочою копією. Тобто вся робота по суті виконуєтсья локально, але існує механізм синхронізації між самотніми репозитаріями. За такої організації вищезгадані проблеми з відсутністю зв&#8217;язку з інтернетом нівелюються &#8211; ви можете робити весь спектр операцій з VCS локально. Але як я вже казав зберігати дані локально &#8211; небезпечно, тому зазвичай в інтернеті відкривають віддалені репозитарії, які слугують таким собі хабом між людьми які працюють з даними. Тобто синхроніхація репозитаріїв іде не кожен-з-кожним (хоча і такий принцип організації можливий), а всі синхронізуютсья лише з віддаленим (але навіть за його недоступності робота може продовжуватись).</p>
<p>Розподілених VCS є кілька. Найбільш популярні наразі <a href="http://git-scm.com/">Git</a> та <a href="http://mercurial.selenic.com/">Mercurial</a>. Вибір між ними справа релігійна, але якщо цікаво порівняти, то ось гарний <a href="http://code.google.com/p/support/wiki/DVCSAnalysis">аналіз від Google (англ)</a>.</p>
<h3>Працюємо з Mercurial</h3>
<p>Як я вже говорив, робоча копія Mercurial фактично є заодно і репозиторієм, але всі зрізи версій зберігаються в каталозі <strong>.hg</strong> з мета-інформацією репозиторія. Поза цією папкою власне робоча копія. Не видаляйте папку, бо втратите репозиторій!</p>
<p>Варіантів для отримання локального репозитарію проекту два:</p>
<ul>
<li>якщо він існує на іншому комп&#8217;ютері чи сервері і тоді вам треба виконати команду <em>clone</em>:
<pre class="brush: plain;">$ hg clone http://path/to/your/repository</pre>
<p>вона створить копію репозитарію з вказоного URL в поточному каталозі
</li>
<li>якщо ви створюєте новий проект, то потрібно виконати команду <em>init</em> в папці з проектом:
<pre class="brush: plain;">$ hg init</pre>
<p> потім додати всі потрібні файли командою <em>add</em>:</p>
<pre class="brush: plain;">$ hg add</pre>
<p> <strong>Увага!</strong> У вас в каталозі можуть бути файли, які не варто зберігати: наприклад, &#8220;.obj&#8221;-файли C++ чи Пітонівські &#8220;.pyc&#8221;.<br />
  для цього в кореневій папці (на одному рівні з папкою &#8220;.hg&#8221;) треба створити файл <em>.hgignore</em> з вмістом типу:</p>
<pre class="brush: plain;">glob:*.bak
glob:*.obj
glob:Debug
glob:Release</pre>
<p>  і так далі&#8230; Можна також прописувати не лише файли, а і цілі каталоги (Debug та Release в прикладі вище).
</li>
</ul>
<p>Далі можна працювати з кодом. Якщо додавались нові файли &#8211; не забувати виконувати команду <em>add</em>. Коли потрібно залити зміни в репозитарій виконуємо команду <em>commit</em>:</p>
<pre class="brush: plain;">$ hg commit</pre>
<p>Тепер варто трохи поговорити про синхронізацію репозитаріїв, але для цього треба зробити невеликий ліричний відступ. Із-за розподіленої архітектури дерево ревізій в Mercurial утворює досить цікаві завитки. В же централізованих системах дерево ревізій представляє собою ланцюжок. Тобто робота виглядає наступним чином:</p>
<ol>
<li>була деяка початкова ревізія №1, яку для подальшої роботи стягнули два розробники</li>
<li>обидва щось поправили і один був першим, хто закомітив зміни на сервер, і з&#8217;явилась ревізія №2</li>
<li>другий спробував закомітитись, але сервер відмовив, вказавши що не може залити зміни поверх версії №1. Тому другий розробник має забрати собі версію №2 з репозиторія та об&#8217;єднати (або як часто кажуть <em>&#8220;змерджити&#8221;</em> від англомовного терміну <em>merge</em>) докупи зміни з ревізії №2 та свої власні правки. Часто це проходить автоматично, але буває, що треба ручна правка, коли зміни торкаються однакових фрагментів коду. Потім об&#8217;єднаний код можна комітити в репозиторій і так з&#8217;явиться ревізія №3</li>
</ol>
<p>Таким чином у централізованих системах є лише одна &#8220;головна&#8221; ревізія, а самі ревізії йдуть одна за одною. Ось так це виглядає схематично:</p>
<p><img src="http://graywolf.org.ua/wp-content/uploads/2010/09/svn-rev.gif" alt="" title="SVN revision history" width="413" height="68" class="aligncenter size-full wp-image-1530" /></p>
<p>У розподілених систем нема центрального сервера, а всі коміти йдуть локально, тому типовий приклад роботи з ними наступний:</p>
<ol>
<li>є центральний хаб з якого два розробники забирають єдину ревізію №1</li>
<li>обидва роблять правки та локальні коміти, таким чином і у першого, і у другого на комп&#8217;ютері з&#8217;являється по дві ревізії: загальна №1 і у кожного власна №2</li>
<li>вони обидва синхронізують свої копії зі спільним репозитарієм і в результаті на спільному репозиторії з&#8217;являється три ревізії: №1, №2 та №3. Таким чином утворилося дві &#8220;головні&#8221; ревізії №2 та №3.</li>
<li>один з розробників знову синхронізує репозиторій і у нього з&#8217;являєтясь копія спільного. Він може оновити локальну копію до однієї з головних ревізій і продовжити роботу в цій &#8220;підгілці&#8221;, а може об&#8217;єднати (змержити) зміни з №2 та №3 і закомітити їх як ревізію №4: таким чином граф ревізій утворить ромб.</li>
</ol>
<p><img src="http://graywolf.org.ua/wp-content/uploads/2010/09/hg-rev.gif" alt="" title="Mercurial revision history" width="600" height="435" class="aligncenter size-full wp-image-1531" /></p>
<p>Синхронізація в <em>Mercurial</em> однонаправлена: тобто за одну операцію можна або залити свої ревізії у віддалений репозиторій (операція <em>push</em>), або отримати звідти ревізії у свій локальний (операція pull).</p>
<pre class="brush: plain;">$ hg pull http://path/to/your/repository
$ hg push http://path/to/your/repository</pre>
<p>Поки що це вся теоретична частина. Якщо ви працюєте під ОС Windows, то життя собі можна значно полегшити, якщо поставити собі <a href="http://tortoisehg.bitbucket.org/">TortoiseHg</a> &#8211; графічний фронт-енд для роботи з Меркуріал. Плюс роботу можна зробити зручнішою та розширити потужність системи поправивши конфігураційний файл <em>Mercurial</em>. Але це я залишу на наступний раз.</p>
]]></content:encoded>
			<wfw:commentRss>http://graywolf.org.ua/2010/09/02/mercurial-satori-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2010/09/mercurial_logo-150x150.png" />
		<media:content url="http://graywolf.org.ua/wp-content/uploads/2010/09/mercurial_logo.png" medium="image">
			<media:title type="html">Mercurial (Меркуріал)</media:title>
			<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2010/09/mercurial_logo-150x150.png" />
		</media:content>
		<media:content url="http://graywolf.org.ua/wp-content/uploads/2010/09/svn-rev.gif" medium="image">
			<media:title type="html">SVN revision history</media:title>
			<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2010/09/svn-rev-150x68.gif" />
		</media:content>
		<media:content url="http://graywolf.org.ua/wp-content/uploads/2010/09/hg-rev.gif" medium="image">
			<media:title type="html">Mercurial revision history</media:title>
			<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2010/09/hg-rev-150x150.gif" />
		</media:content>
	</item>
		<item>
		<title>Google App Engine + Django</title>
		<link>http://graywolf.org.ua/2010/04/08/google-app-engine-django/</link>
		<comments>http://graywolf.org.ua/2010/04/08/google-app-engine-django/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 21:14:46 +0000</pubDate>
		<dc:creator>graywolf</dc:creator>
				<category><![CDATA[Code snippets]]></category>
		<category><![CDATA[appengine]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[GAE]]></category>
		<category><![CDATA[gaeutilities]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[itblog-ua]]></category>
		<category><![CDATA[zipimport]]></category>

		<guid isPermaLink="false">http://graywolf.org.ua/?p=1385</guid>
		<description><![CDATA[Яким би поганим не здався мені на перший погляд Datastore у Google App Engine, але тим не менш для багатьох проектів і його буде цілком достатньо (тим паче, що у roadmap його розвитку майорить довгоочікуваний повнотекстовий пошук). Тому для платформи одного з нових міні-проектів, які нещодавно спали мені на думку мну вибрав саме Google App [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://graywolf.org.ua/wp-content/uploads/2010/04/django-logo-negative-300x136.png" alt="django-logo-negative" title="django-logo-negative" width="120" class="alignright size-medium wp-image-1397" /> <img src="http://code.google.com/appengine/images/appengine-silver-120x30.gif" alt="Powered by Google App Engine" align="right" />Яким би <a href="http://graywolf.org.ua/2009/05/24/google-datastore-sucks/">поганим не здався мені на перший погляд Datastore</a> у <a href="http://code.google.com/appengine/">Google App Engine</a>, але тим не менш для багатьох проектів і його буде цілком достатньо (тим паче, що у roadmap його розвитку майорить довгоочікуваний повнотекстовий пошук). Тому для платформи одного з нових міні-проектів, які нещодавно спали мені на думку мну вибрав саме <em>Google App Engine</em>. Водночас мну дуже вже звик до фреймворку <a href="http://www.djangoproject.com/">Django</a> і мається на увазі не лише його <em>ORM</em>, тому вирішив підключити його останню версію (в комплекті з GAE йде 0.96, яка вже ну дууууже застаріла). Але не за допомогою костилів (<a href="http://code.google.com/p/google-app-engine-django/">цього</a> чи <a href="http://code.google.com/p/app-engine-patch/">ось цього</a>) як минулого разу, а просто напряму і викинувши все зайве (тобто фактично все, що було зав&#8217;язано на <em>ORM</em>). І не дивлячись на те, що в Інеті було повно мануалів по підключенню <em>Django</em> помучитись в неочікуваних місцях трохи довелося.<br />
<span id="more-1385"></span><br />
По-перше, сама збірка <em>Django</em>. Я підбирав модулі частково експериментальним шляхом і щоб не прописувати все вручну постійно зробив собі простенький <strong>.bat</strong>-файл, який пакує в архів необхідну частину джанги:</p>
<pre class="brush: plain;">
&quot;C:\Program Files\7-Zip\7z.exe&quot; a django.zip ^
django\__init__.py ^
django\bin ^
django\core ^
django\conf ^
django\db ^
django\dispatch ^
django\forms ^
django\http ^
django\middleware ^
django\shortcuts ^
django\template ^
django\templatetags ^
django\test ^
django\utils ^
django\views ^
django\contrib\__init__.py ^
django\contrib\contenttypes ^
django\contrib\localflavor ^
django\contrib\markup ^
django\contrib\sitemaps ^
django\contrib\humanize ^
django\contrib\formtools
</pre>
<p>Зібраний цим скриптом архівний файлик я підклав у корінь новоствореного gae-проекту. Причому пакування в архів тут робиться не задля економії дискового простору. Просто у <em>App Engine</em> є обмеження на кількість файлів, а в проекті <em>Django</em> їх дуже багато. Тепер залишилась справа за малим: підмінити <em>Django</em> що йде у комплекті з <em>GAE</em> на нашу версію, яку ми завантажимо з архіву за допомогою фічі <a href="http://docs.python.org/release/2.6/library/zipimport.html">zipimport</a>. Тут все досить просто (це мій поточний варіант скрипта, але думаю без якихось проблем має запрацювати і той, що виклдаений на <a href="http://code.google.com/intl/uk/appengine/articles/django10_zipimport.html">офіційній сторінці інтеграції GAE та Django</a>):</p>
<p><strong>main.py</strong></p>
<pre class="brush: python;">#!/usr/bin/env python
# main.py

import os, sys, logging
os.environ[&quot;DJANGO_SETTINGS_MODULE&quot;] = &quot;projectname.settings&quot;

# Google App Engine imports.
from google.appengine.ext.webapp import util

# Uninstall Django 0.96.
for k in [k for k in sys.modules if k.startswith('django')]:
    del sys.modules[k]

# Add Django 1.0 archive to the path.
django_path = 'django.zip'
sys.path.insert(0, django_path)

# Force Django to reload its settings.
from django.conf import settings
settings._target = None

import django.core.handlers.wsgi
import django.core.signals
import django.db

def log_exception(*args, **kwds):
    logging.exception('Exception in request:')

# Log errors.
django.core.signals.got_request_exception.connect(log_exception)

# Unregister the rollback event handler.
django.core.signals.got_request_exception.disconnect(django.db._rollback_on_exception)

def main():
    # Create a Django application for WSGI.
    application = django.core.handlers.wsgi.WSGIHandler()

    # Run the WSGI CGI handler with that application.
    util.run_wsgi_app(application)

if __name__ == &quot;__main__&quot;:
    main()
</pre>
<p>Але найцікавіша частина над якою я намучився найбільше &#8211; це налаштування файлу <strong>settings.py</strong> в самому <em>Django</em>. По-перше, треба повідключати модулі зав&#8217;язані на Django ORM, тобто видалити або закоментити Middleware-класи:</p>
<p><code>django.contrib.sessions.middleware.SessionMiddleware<br />
django.middleware.csrf.CsrfViewMiddleware<br />
django.contrib.auth.middleware.AuthenticationMiddleware<br />
django.contrib.messages.middleware.MessageMiddleware</code></p>
<p><strong>NOTE:</strong> <em>SessionMiddleware</em> варто замінити на той, що йде у комплекті з <a href="http://gaeutilities.appspot.com/">gaeutilities</a> &#8211; тоді ви принаймні зможете скористатись портованим аналогом сессій.</p>
<p>Контекст-процесори:</p>
<p><code>django.contrib.auth.context_processors.auth<br />
django.contrib.messages.context_processors.messages</code></p>
<p>Та додатки:</p>
<p><code>django.contrib.auth<br />
django.contrib.sessions<br />
django.contrib.sites<br />
django.contrib.messages</code></p>
<p>Також, наскільки я зрозумів, портована версія Django має певні проблеми з підтримкою i18n, тому в конфігураційному файлі її варто відключити (але питання інтернаціоналізації для мене вельми актуальне, тому найближчим часом постараюсь цю проблему вирішити):</p>
<p><code>USE_I18N = False</code></p>
<p>Ну от в принципі і все. Мну черпав джерело натхнення з:</p>
<ul>
<li><a href="http://thomas.broxrost.com/2008/04/08/django-on-google-app-engine/">Django on Google App Engine in 13 simple steps by Thomas Brox Røst</a></li>
<li><a href="http://habrahabr.ru/blogs/django/25696/">Django приложение на Google App Engine by diadya_vova</a></li>
<li><a href="http://code.google.com/intl/uk/appengine/articles/django10_zipimport.html">Using Django 1.0 on App Engine with Zipimport by Dan Sanderson</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://graywolf.org.ua/2010/04/08/google-app-engine-django/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2010/04/django-logo-negative-150x150.png" />
		<media:content url="http://graywolf.org.ua/wp-content/uploads/2010/04/django-logo-negative.png" medium="image">
			<media:title type="html">django-logo-negative</media:title>
			<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2010/04/django-logo-negative-150x150.png" />
		</media:content>
		<media:content url="http://code.google.com/appengine/images/appengine-silver-120x30.gif" medium="image">
			<media:title type="html">Powered by Google App Engine</media:title>
			<media:thumbnail url="http://code.google.com/appengine/images/appengine-silver-120x30.gif" />
		</media:content>
	</item>
		<item>
		<title>Скрінсейвер з гарними фотками для ледачих</title>
		<link>http://graywolf.org.ua/2010/01/26/screensaver-with-cool-rss-photos/</link>
		<comments>http://graywolf.org.ua/2010/01/26/screensaver-with-cool-rss-photos/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 22:44:42 +0000</pubDate>
		<dc:creator>graywolf</dc:creator>
				<category><![CDATA[Мережі та ІТ]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[itblog-ua]]></category>
		<category><![CDATA[picasa]]></category>
		<category><![CDATA[screensaver]]></category>
		<category><![CDATA[yahoo pipes]]></category>

		<guid isPermaLink="false">http://graywolf.org.ua/?p=1325</guid>
		<description><![CDATA[Багатьом людям рано чи пізно стандартний майкрософтівський прапорець набридає і вони шукають якоїсь гарненької заміни. Одним хочеться оживити &#8220;відпочиваючий&#8221; комп&#8217;ютер усякими там анімованими пейзажами чи акваріумними рибками (ненав&#8217;язлива реклама ), а іншим типу мене обожнює дивитись на всякі там гарні фотки. Скрінсейверів, що просто показують фотографії з певних каталогів на диску нині дофіга, але всам [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://graywolf.org.ua/wp-content/uploads/2010/01/ss_collage-300x212.jpg" alt="Google Photos Screensaver" title="Google Photos Screensaver" width="300" height="212" class="alignleft size-medium wp-image-1326" align="left" /> Багатьом людям рано чи пізно стандартний майкрософтівський прапорець набридає і вони шукають якоїсь гарненької заміни. Одним хочеться оживити &#8220;відпочиваючий&#8221; комп&#8217;ютер усякими там <a href="http://screensaver.in.ua/">анімованими пейзажами чи акваріумними рибками</a> (ненав&#8217;язлива реклама <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ), а іншим типу мене обожнює дивитись на всякі там гарні фотки. Скрінсейверів, що просто показують фотографії з певних каталогів на диску нині дофіга, але всам факт завантажування фоток такого ледащо і гіка як я вельми дратує &#8211; ну не сучасно це, і кому ті зайві рухи потрібні? От як би то його зробити, щоб воно саме&#8230; Та сучасні технології не стоять на місці і вже мабуть навіть останній найледачіший користувач інтернету знає про інсування <a href="http://uk.wikipedia.org/wiki/RSS">стрічок RSS</a> &#8211; найзручнішого засобу отримувати свіжу інформацію без нагальної необхідності лазити по сайтах (найбільш адекватні з них ще й користуються єдино вірною RSS-читалкою &#8211; <a href="http://reader.google.com/">Google Reader</a>, але зрештою донесення цієї істини до варварів не є темою цього допису і залишаєтсья на самоопрацювання). Так от, одне з чудес <strong>RSS</strong> полягає в тому, що воно дозволяє додавати в стрічку не лише звичайні статті (з текстом, відео та картинками), а і долучати до нього медіа-дані (як аттачменти у електронній пошті). Ті самі відео та картинки, але не як елемент статті, а як окрему сутність (в термінах RSS воно називається <em>enclosure</em>). Це важливо, бо комп&#8217;ютери все-таки тупі і виділити потрібну картинку з-поміж тексту їм не так легко як людині. Думаю ви розумієте до чого я веду: картининки можна автоматично отримувати з відповідних RSS і не треба нічого самотужки качати &#8211; розумні програми зроблять все за вас. Єдина умова &#8211; щоб ці картинки були оформлені у стрічці як <em>enclosue</em> (на жаль, не всі фото-сайти настільки просунуті, щоб видавати стрічки картинок з картинками не у вигляді вмісту новини, а саме як додаток).<br />
<span id="more-1325"></span><br />
Вибір самих RSS з фотографіями чи картинками та скрінсейвера з підтримкою їх завантаження з чих стрічок &#8211; справа смаку, але особисто мну для цих цілей рекомендує дві речі: фотки краще всього діставати з найкращого сайту по фотографії &#8211; <a href="http://flickr.com/">Flickr</a>, а в якості самого скрінсейвера <strong>Google Photos Screensaver</strong>. З останнім, щоправда, Гугль зробив невелику підлість &#8211; раніше це був окремий продукт, а зараз він іде виключно як складова <a href="http://picasa.google.com/">Google Picasa</a>, яка мені в повному обсязі нафіг не треба, бо я замість <em>Пікаси</em> все одно більш полюбляю <a href="http://www.adobe.com/products/photoshoplightroom/">Adobe Lightroom</a> (бета версія якого ще нещодавно була безкоштовною, але як зараз &#8211; не знаю). Але повертаючись до нашого барану&#8230; Нижче показано як виглядає його налаштування за замовчуванням (дефолтна стрічка вже декілька місяців, на жаль, не працює, а там були непогані фото). При додаванні нової RSS-стрічки він перевіряє її на наявність додатків-фотографій і якщо таких не буде, то скаже, що вона не підходить.</p>
<p><a href="http://www.scrnshots.com/users/graywolf/screenshots/225780"><img src="http://s3.amazonaws.com/scrnshots.com/screenshots/225780/gphotoscreensaver-settingspng" /></a></p>
<p>Чим крутий <a href="http://flickr.com/">Флікр</a>? По-перше, тим, що це зараз мабуть найбільший і найкращий сайт де можна знайти справді гарні фотки практично всього що завгодно. Плюс саме завдяки ньому я частково відучився від поганої практики завантаження фоток на локальну машину. Навіщо? Щоб вона потім згубилась в нетрях диску? Краще вподобану вами на <em>Флікрі</em> фотографію додати собі у &#8220;favorites&#8221; &#8211; вона буде там присутня поки власнк не надумає її видалити (що буває вкрай рідко), плюс автор фото дізнається, що вона вам сподобалась і йому буде приємно. По-друге, цей сайт багато в чому передовий і там підтримується згадана вище RSS з фото-додатками майже для всього що тільки можна! Хочете отримати фотки, у яких в тегах прописано &#8220;кіт&#8221; &#8211; будь-ласка, з певної групи &#8211; ніяких проблем, власні вподобання &#8211; та залюбки&#8230;</p>
<p><a href="http://www.scrnshots.com/users/graywolf/screenshots/225788"><img src="http://s3.amazonaws.com/scrnshots.com/screenshots/225788/flickr-feedpng" /></a></p>
<p>Єдиний мінус Флікра &#8211; це жлобство деяких професійних (і не дуже) фотографів <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  В тому сенсі, що вони викладають лише зменшені копії своїх фотографій і тому при показі скрінсейвера воно виглядє убого. Я довго мучився з цим, поки одного осіннього ранку, чи то вечора на мене не зійшло осяяння під назвою <a href="http://pipes.yahoo.com/pipes/">Yahoo Pipes</a>. Це така кльова штука, яка дозволяє збирати та модифікувати дані з різних джерел та видавати у потрібному вигляді, але при цьому не вимагає від вас ніяких навичок програмування <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  В нашому випадку задача проста як двері: взяти RSS-потік з додатками-картинками та відфільтрувати його по розмірам зображень, але про це я напишу вже іншим разом, ок? <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
]]></content:encoded>
			<wfw:commentRss>http://graywolf.org.ua/2010/01/26/screensaver-with-cool-rss-photos/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2010/01/ss_collage-150x150.jpg" />
		<media:content url="http://graywolf.org.ua/wp-content/uploads/2010/01/ss_collage.jpg" medium="image">
			<media:title type="html">Google Photos Screensaver</media:title>
			<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2010/01/ss_collage-150x150.jpg" />
		</media:content>
		<media:content url="http://s3.amazonaws.com/scrnshots.com/screenshots/225780/gphotoscreensaver-settingspng" medium="image">
			<media:thumbnail url="http://s3.amazonaws.com/scrnshots.com/screenshots/225780/gphotoscreensaver-settingspng" />
		</media:content>
		<media:content url="http://s3.amazonaws.com/scrnshots.com/screenshots/225788/flickr-feedpng" medium="image">
			<media:thumbnail url="http://s3.amazonaws.com/scrnshots.com/screenshots/225788/flickr-feedpng" />
		</media:content>
	</item>
		<item>
		<title>Google JS API</title>
		<link>http://graywolf.org.ua/2009/10/22/google-js-api/</link>
		<comments>http://graywolf.org.ua/2009/10/22/google-js-api/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 15:48:51 +0000</pubDate>
		<dc:creator>graywolf</dc:creator>
				<category><![CDATA[Code snippets]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[js]]></category>

		<guid isPermaLink="false">http://graywolf.org.ua/?p=1201</guid>
		<description><![CDATA[Ті, хто займаються Вебом, звісно, давно знають про цю фічу, тому я публікую це не стільки в розрахунку на когось, скільки на згадку собі, бо задовбався при створоенні кожного нового сайту шукати в шаблонах старих сайтів ці заповітні декілька рядків: &#60;script type=&#34;text/javascript&#34; src=&#34;http://www.google.com/jsapi&#34;&#62;&#60;/script&#62; &#60;script type=&#34;text/javascript&#34;&#62; google.load(&#34;jquery&#34;, &#34;1.3.2&#34;); &#60;/script&#62; Фрагмент вище дозволяє завантажувати потрібну версію jQuery [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://graywolf.org.ua/wp-content/uploads/2009/10/code_logo.png" alt="Google Code" title="Google Code" width="161" height="40" class="alignleft size-full wp-image-1204" style="border: 0;" />Ті, хто займаються Вебом, звісно, давно знають про цю фічу, тому я публікую це не стільки в розрахунку на когось, скільки на згадку собі, бо задовбався при створоенні кожного нового сайту шукати в шаблонах старих сайтів ці заповітні декілька рядків:</p>
<pre class="brush: xml;">
&lt;script type=&quot;text/javascript&quot; src=&quot;http://www.google.com/jsapi&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
  google.load(&quot;jquery&quot;, &quot;1.3.2&quot;);
&lt;/script&gt;
</pre>
<p>Фрагмент вище дозволяє завантажувати потрібну версію <em>jQuery</em> прямо з Гугла і при виході нової версії не потрібно щось перезаливати на свій сайт &#8211; лише змінити в шаблоні заголовку сторінки номер версії і все готово.</p>
<p>Звісно ж таким чином можна завантажувати не лише <em>jQuer</em>y, а й декілька інших Javascript-фреймворків. На сторінці <a href="http://code.google.com/apis/ajaxlibs/documentation/">Google AJAX Libraries API</a> можна знайти всі бібліотеки та їх версії, що наразі підтримуються.</p>
<p>Більше того, таким чином можна також завантажувати Javascript&#8217;ові сервіси Гугла, наприклад такі як <a href="http://maps.google.com/">Google Maps</a>, але для того доведеться звісно ж при завантаженні <em>JSAPI</em> вказати <em>API Key</em>, який отримується <a href="http://code.google.com/apis/ajaxsearch/signup.html">тут</a> під конкретний домен. Тобто загальний вигляд підключення <em>Google Maps API</em> виглядатиме так:</p>
<pre class="brush: xml;">
&lt;script type=&quot;text/javascript&quot; src=&quot;http://www.google.com/jsapi?key=ABCDEFG&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
  google.load(&quot;maps&quot;, &quot;2&quot;);
&lt;/script&gt;
</pre>
<p>Детальніше про роботу з <em>JSAPI</em> можна знайти на сторінці <a href="http://code.google.com/intl/uk-UA/apis/ajax/documentation/">Google AJAX API</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://graywolf.org.ua/2009/10/22/google-js-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2009/10/code_logo-150x40.png" />
		<media:content url="http://graywolf.org.ua/wp-content/uploads/2009/10/code_logo.png" medium="image">
			<media:title type="html">Google Code</media:title>
			<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2009/10/code_logo-150x40.png" />
		</media:content>
	</item>
		<item>
		<title>Пишем GUI з wxWidgets. Підготовка</title>
		<link>http://graywolf.org.ua/2009/08/27/writing-with-wxwidgets-preparations/</link>
		<comments>http://graywolf.org.ua/2009/08/27/writing-with-wxwidgets-preparations/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 00:21:10 +0000</pubDate>
		<dc:creator>graywolf</dc:creator>
				<category><![CDATA[Мережі та ІТ]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[visual studio]]></category>
		<category><![CDATA[wxwidgets]]></category>

		<guid isPermaLink="false">http://graywolf.org.ua/?p=1164</guid>
		<description><![CDATA[Отож, як і обіцяв, вирішив почати потроху описувати свій досвід освоєння цього GUI-фреймворку. По-перше пара слів про сам wxWidgets. Це вже досить старий і тому стабільний і потужний фреймворк для розробки графічних інтерфейсів. Він кросплатформенний (є версії для Windows, Linux, MacOS та кількох інших, навіть для OS/2) і доступний у варіантах для декількох мов програмування [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://graywolf.org.ua/wp-content/uploads/2009/08/logo9.jpg" alt="wxWidgets logo" title="wxWidgets logo" width="300" height="64" class="alignleft size-full wp-image-1165" /> Отож, як і обіцяв, вирішив почати потроху описувати свій досвід освоєння цього GUI-фреймворку. По-перше пара слів про сам <a href="http://www.wxwidgets.org/">wxWidgets</a>. Це вже досить старий і тому стабільний і потужний фреймворк для розробки графічних інтерфейсів. Він кросплатформенний (є версії для Windows, Linux, MacOS та кількох інших, навіть для OS/2) і доступний у варіантах для декількох мов програмування (наприклад, C++, Python, Perl, C#, тощо). Як заявляють розробники прямо на головній сторінці сайту, основною особливістю їх фреймворку є те, що він повністю базується на &#8220;рідних&#8221; для того чи іншого середовища контролах, а не емулює їх, як робить більшість інших кросплатформенних GUI-бібліотек. За рахунок цього бінарний код виходить дуже компактним, а графіка виглядає природно для відповідної системи. Отака цікава штука. Трохи забігаючи наперед скажу, що, <em>wxWidgets</em>, звісно, не такі приємні в розробці як <a href="http://qt.nokia.com/">Qt</a> (там взагалі просто сідаєш і пишеш &#8211; настільки логічно все побудовано, а кращої документації я ще не бачив ні до чого), але водночас після декількох днів роботи з ним він мені починає подобатись все більше і більше.</p>
<p>Ось така цікава штука цей <em>wxWidgets</em>. А тепер перейдемо власне до підготовчих кроків, які доведеться зробити перед тим як розпочати перший проект. Наразі я опишу процес для <em>Win32</em>, але згодом хочу спробувати і відповідно занотувати цю саму процедуру для <em>Linux</em>.<br />
<span id="more-1164"></span><br />
Перше, що нам знадобиться &#8211; це <a href="http://www.wxwidgets.org/downloads/">скачати вихідні коди</a> фреймворку, щоб потім зібрати на вашій машині версію оптимізовану для вашого компілятора. До речі, цікава штука: воно також має працювати з Visual Studio 2008 Express, так що таким чином можна створювати ПЗ абсолютно легально. Далі одразу рекомендую обзавестись дизайнером форм, щоб економити час на рутині. Офіційного редактора від розробників немає, а є лише купа редакторів від сторонніх виробників. Я спробував декілька і для себе зупинився на <a href="http://wxformbuilder.org/?page_id=7">wxFormBuilder</a>. Якщо хтось знайде щось зручніше і потужніше &#8211; з радістю вислухаю. </p>
<p>Тож завантажуємо і встановлюємо відповідну версію wxWidgets. Там знаходимо в підкаталозі <em>&#8220;builds/msw&#8221;</em> того місця, куди ви встановили <em>wxWidgets</em> проект <em>&#8220;wx.dsw&#8221;</em>, відкриваємо його і при необхідності погоджуємося на пропозицію студії сконвертувати його в її рідну версію. Далі обираємо тип білда. Я поки що пробував лише звичайні Release та Debug &#8211; це звичайні версії для статичної лінковки. Робимо білд. До речі, порівняно з тим-таки <em>Qt</em> збирається <em>wxWidgets</em> просто миттєво. Тепер перевіримо чи все у нас гаразд. В каталозі <em>&#8220;samples&#8221;</em> відкриваємо проект <em>&#8220;samples.dsw&#8221;</em>. В ньому знаходимо підпроект <strong>minimal</strong> і збираємо лише його (причому в одній з конфігурацій, в яких збирали саму бібліотеку). Можна було б, звісно, і всі sample-проекти при бажанні скомпілити, але то марна трата часу. Якщо <em>minimal</em> нормально скомпілювався, злінкувався та запустився, значить все чудово. Тепер не забудьте прописати шляхи до хедерів та скомпільованиз бібліотек у <em>Visual Studio</em>: в Tools&rarr;Options&rarr;Projects and Solutions&rarr;VC++ Directories відповідно для &#8220;Include files&#8221; прописуємо шлях до хедерів, а в &#8220;Library files&#8221; &#8211; шлях до щойно зібраних бібліотек.</p>
<p>Якщо хто хоче подивитись як описане вище виглядають вживу, можу запропонувати оцей англомовний скрінкаст (єдина відмінність &#8211; там шляхи до хедерів та бібліотек прописуються через vsprops-файл):</p>
<p><center><embed src="http://blip.tv/play/AcHOKIaNZw" type="application/x-shockwave-flash" width="640" height="510" allowscriptaccess="always" allowfullscreen="true"></embed></center></p>
<p>Ну і на всяк випадок лінки на рекомендації по встановленню під різні версії студії:</p>
<ul>
<li><a href="http://wiki.wxwidgets.org/MSVC_.NET_Setup_Guide">wxWidgets на MS Visual Studio.NET (8.0)</a></li>
<li><a href="http://wiki.wxwidgets.org/Visual_Studio_2008_(9.0)">wxWidgets на MS Visual Studio 2008 (9.0)</a></li>
</ul>
<p>Ну і поки що все. Наступного разу створимо свою в міру простеньку форму і запустимо її <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
]]></content:encoded>
			<wfw:commentRss>http://graywolf.org.ua/2009/08/27/writing-with-wxwidgets-preparations/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2009/08/logo9-150x64.jpg" />
		<media:content url="http://graywolf.org.ua/wp-content/uploads/2009/08/logo9.jpg" medium="image">
			<media:title type="html">wxWidgets logo</media:title>
			<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2009/08/logo9-150x64.jpg" />
		</media:content>
	</item>
		<item>
		<title>latitude2brightkite</title>
		<link>http://graywolf.org.ua/2009/08/19/latitude2brightkite/</link>
		<comments>http://graywolf.org.ua/2009/08/19/latitude2brightkite/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 19:06:17 +0000</pubDate>
		<dc:creator>graywolf</dc:creator>
				<category><![CDATA[Мережі та ІТ]]></category>
		<category><![CDATA[brightkite]]></category>
		<category><![CDATA[GAE]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[gps]]></category>
		<category><![CDATA[itblog-ua]]></category>
		<category><![CDATA[latitude]]></category>
		<category><![CDATA[latitude2btightkite]]></category>
		<category><![CDATA[lifestreaming]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[social web]]></category>

		<guid isPermaLink="false">http://graywolf.org.ua/?p=1131</guid>
		<description><![CDATA[Останнім писком моди в сучасному інтернеті є всякі фішечки пов&#8217;язані з GeoLocation, тобто вашим місцерозташуванням на Земній кулі. Щоправда оскільки більшість сервісів пов&#8217;язаних з цією фічею базувались на Google Maps ми стояли дещо осторонь технологічного прогресу, бо не мали нормальної мапи українських міст. Але так не могло тривати вічно і ось декілька тижнів тому в [...]]]></description>
			<content:encoded><![CDATA[<p>Останнім писком моди в сучасному інтернеті є всякі фішечки пов&#8217;язані з GeoLocation, тобто вашим місцерозташуванням на Земній кулі. Щоправда оскільки більшість сервісів пов&#8217;язаних з цією фічею базувались на <a href="http://maps.google.com">Google Maps</a> ми стояли дещо осторонь технологічного прогресу, бо не мали нормальної мапи українських міст. Але так не могло тривати вічно і ось декілька тижнів тому в Гугл Мапс з&#8217;явилась нормальна мапа України з деталями обласних центрів (не ідеальна, звісно, але яка є). Але повернемося до гео-сервісів. Одним з найцікавіших, на мій погляд, був <a href="http://brightkite.com/">Brightkite</a>. Брайткайт &#8211; це такий собі Твіттер, але по-першу, з можливістю постити картинки, а по-друге &#8211; з прив&#8217;язкою до вашого розташування. Особливість його в тому, що ви можете фільтрувати повідомлення по радіусу відносно вашого положення, що в країнах де це розвинуто вельми прикольно. Але мені в Брайткайті не подобалась одна річ: треба було постійно оновлювати своє розташування вручну набираючи свою адресу, або (коли підтрики адрес в мапах не було) копіпастячи з Google Maps широту та довготу, що взагалі нівелювало задоволення від користування сервісом. Для сучасних телефонів з GPS типу <em>iPhone</em> та <em>Andriod&#8217;ів</em> вже є нативні додатки, які дозволяють постити місцерозташування в Брайткайт автоматично. Але у мене є лише старенький телефон з <em>Windows Mobile 5 for Smartphones</em> на борту. Щоправда одразу після релізу я на нього поставив <a href="http://www.google.com/intl/en_us/latitude/intro.html">Google Latitude</a> &#8211; це такий собі виключно мобільний (принаймні для України) і значно примітивніший аналог <em>Brightkite</em>, але прикол його в тому, що навіть за відсутності GPS він визначав місце по сотам GSM-мережі, що хоч і дає похибку десь в 1-3 км залежно від соти, але все ж вельми непогано. Коротше кажучи, навідала мене думка склеїти їх якось і ось результат:</p>
<p><center><a href="http://latitude2brightkite.appspot.com/"><img alt="" src="http://latitude2brightkite.appspot.com/static/img/gl2b.png" title="latitude2brightkite" class="alignnone" width="400" height="70" /></a></center></p>
<p><a href="http://latitude2brightkite.appspot.com/">latitude2brightkite</a> &#8211; це сервіс, на якому можна підконектитись до ваших аккаунтів на <em>Brightkite</em> (через <a href="http://oauth.net/">OAuth</a>, що цілком безпечно, бо не вимагає від вас зберігати паролі на сайті) та <em>Google Latitude</em> (тут треба буде вручну скопіпастити ваш Латітьюдівський ідентифікатор, бо, на жаль, поки що в мене не вийшло автоматизувати його отримання). Ну і далі сервіс використовуючи ці дані періодично отримує гео-інформацію з Латітьюд і постить її у Брайткайт. От і все. Там є ще пара дрібних багів, але я їх на цьому тижні пофікшу.</p>
<p>До речі, з <em>OAuth</em> я промучився добряче. Мануали які я знайшов &#8211; всі з купою води і ніфіга не зрозуміло, тому довелося дізнаватись подробиці того як працює ця кухня просто взявши робочий приклад для <em>Google App Engine</em> і дивлячись що і як там зроблено. Так що я може навіть переборю лінощі і трохи згодом напишу свій стислий мануал.</p>
]]></content:encoded>
			<wfw:commentRss>http://graywolf.org.ua/2009/08/19/latitude2brightkite/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:thumbnail url="http://latitude2brightkite.appspot.com/static/img/gl2b.png" />
		<media:content url="http://latitude2brightkite.appspot.com/static/img/gl2b.png" medium="image">
			<media:title type="html">latitude2brightkite</media:title>
			<media:thumbnail url="http://latitude2brightkite.appspot.com/static/img/gl2b.png" />
		</media:content>
	</item>
		<item>
		<title>Гарні новини від Brainbench продовжуютсья</title>
		<link>http://graywolf.org.ua/2009/08/13/brainbench-discount-continued/</link>
		<comments>http://graywolf.org.ua/2009/08/13/brainbench-discount-continued/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 10:55:58 +0000</pubDate>
		<dc:creator>graywolf</dc:creator>
				<category><![CDATA[Мережі та ІТ]]></category>
		<category><![CDATA[Щоденник]]></category>
		<category><![CDATA[brainbench]]></category>
		<category><![CDATA[discount]]></category>
		<category><![CDATA[itblog-ua]]></category>
		<category><![CDATA[знижка]]></category>
		<category><![CDATA[сертифікація]]></category>
		<category><![CDATA[тести]]></category>

		<guid isPermaLink="false">http://graywolf.org.ua/?p=1126</guid>
		<description><![CDATA[На днях Brainbench прислали мені листа повідомляючи, що через місяць в мене закінчується підписка на їх тести. Минулого року я вже писав, що вони пропонували річну підписку для деяких країн з 85% знижкою, тобто всього за 30$ на рік (річна підписка коштує майже 200$). І от я думав, що це типу була на рік замануха, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://brainbench.com/"><img alt="" src="http://www.brainbench.com/avmedia/images/default/bblogosmall.gif" title="Brainbench logo" class="alignleft" align="left" width="170" height="46" /></a>На днях <a href="http://brainbench.com/">Brainbench</a> прислали мені листа повідомляючи, що через місяць в мене закінчується підписка на їх тести. Минулого року я вже писав, що вони <a href="http://graywolf.org.ua/2008/08/28/цікава-новина-від-brainbench/">пропонували річну підписку для деяких країн з 85% знижкою</a>, тобто всього за 30$ на рік (річна підписка коштує майже 200$). І от я думав, що це типу була на рік замануха, а на наступний вже доведеться платити повну ціну, що, звісно, мене геть не влаштовувало, але заради цікавості подивився на інвойс і був приємно вражений, що на наступний рік ціна залишилась незмінною. Отаке. Так що в через місяць треба буде не забути сплатити, бо штука все ж прикольна для оцінки власних знань.</p>
]]></content:encoded>
			<wfw:commentRss>http://graywolf.org.ua/2009/08/13/brainbench-discount-continued/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="http://www.brainbench.com/avmedia/images/default/bblogosmall.gif" />
		<media:content url="http://www.brainbench.com/avmedia/images/default/bblogosmall.gif" medium="image">
			<media:title type="html">Brainbench logo</media:title>
			<media:thumbnail url="http://www.brainbench.com/avmedia/images/default/bblogosmall.gif" />
		</media:content>
	</item>
		<item>
		<title>Вовча мобілізація або Dell, Huawei E800 та Utel</title>
		<link>http://graywolf.org.ua/2009/07/22/dell-inspiron-e6500-huawei-e800-utel/</link>
		<comments>http://graywolf.org.ua/2009/07/22/dell-inspiron-e6500-huawei-e800-utel/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 21:15:26 +0000</pubDate>
		<dc:creator>graywolf</dc:creator>
				<category><![CDATA[Мережі та ІТ]]></category>
		<category><![CDATA[Щоденник]]></category>
		<category><![CDATA[3g]]></category>
		<category><![CDATA[dell]]></category>
		<category><![CDATA[dell latitude]]></category>
		<category><![CDATA[e800]]></category>
		<category><![CDATA[e800a]]></category>
		<category><![CDATA[ebay]]></category>
		<category><![CDATA[hsdpa]]></category>
		<category><![CDATA[huawei e800]]></category>
		<category><![CDATA[led]]></category>
		<category><![CDATA[modem]]></category>
		<category><![CDATA[problem]]></category>
		<category><![CDATA[utel]]></category>
		<category><![CDATA[модем]]></category>
		<category><![CDATA[Утел]]></category>

		<guid isPermaLink="false">http://graywolf.org.ua/?p=1095</guid>
		<description><![CDATA[Отож від сьогодні мій ноут повністю обмобілізовано: тобто при необхідності в будь-якому місці з покриттям HSDPA або хоча б GSM у нього буде інет. Поки що це ніби-то і лише забавка, але так як вона обійшлася у вельми скромну суму, то чому б і ні? Тим паче, що можливості все ж гарні відкриваються: по-перше, тепер [...]]]></description>
			<content:encoded><![CDATA[<p>Отож від сьогодні мій ноут повністю обмобілізовано: тобто при необхідності в будь-якому місці з покриттям HSDPA або хоча б GSM у нього буде інет. Поки що це ніби-то і лише забавка, але так як вона обійшлася у вельми скромну суму, то чому б і ні? Тим паче, що можливості все ж гарні відкриваються: по-перше, тепер зможу повноцінно працювати принаймні по дорозі додому в Білу Церкву, по-друге, тепер у гарну погоду не обов&#8217;язково це робити вдома &#8211; можна піти в місто та посидіти десь в парку на лавці, чи на травичці спершись спиною об якесь деревце, що просто прекрасно.</p>
<p><center><a href="http://graywolf.org.ua/wp-content/uploads/2009/07/3_4.jpg"><img src="http://graywolf.org.ua/wp-content/uploads/2009/07/3_4.jpg" alt="Huawei E800 (HSDPA modem)" title="Huawei E800 (HSDPA modem)" width="350" height="292" class="aligncenter size-full wp-image-1096" /></a></center></p>
<p>Епопея з моїм омобілюванням почалася досить таки давно, здається наприкінці минулого року, коли завдяки Феру мну став власником чудового 3G-пакету  <strong>U&#8217;Family 5</strong> від <a href="http://utel.ua/">Utel</a> з інетом по 5 коп./МБ (навіть в GSM-роумінгу) всього за ~26 з копійками гривень в місяць абонплати. Але телефон у мене був звичайний і тому я весь час сидів виключно у білайнівському роумінгу. Після вимушеної покупки нового ноутбуку мну помітив, що у нього потенційно є вбудована можливість роботи з HSDPA модемами (навіть слот для сім-карти під акумулятором був), але такими фічами комплектуються лише збірки ноутів для США та Нової Зеландії. Я зацікавився можливістю встановлення такого обладнання у нас, та в сервісному центрі <a href="http://www.ulyssys.com/">&#8220;Улісс&#8221;</a> мені сказали, що зробити вони теоретично таке можуть, але модеми, що приходять від <em>Dell</em> залочені під <em>AT&#038;T</em> і у них був випадок, коли модем  не запрацював з нашими картками і тому вони мені порадили просто взяти модем у форматі <em>Express-Card</em> і забути про які б то не було проблеми. На тому мій запал тимчасово пропав, адже ціна, яку <a href="http://utel.ua/private/equipments.php?show=%CC%EE%E4%E5%EC%E8">просив за модеми Utel</a> кусаєтьcя вельми боляче: від найпростішого USB-модему 749 до Wi-Fi роутеру за 1699 грн. Але ж є така чудова річ як <a href="http://ebay.com/">eBay</a>! Час від часу я заходив туди цікавлячись поточними цінами на модем <a href="http://www.huawei.com/mobileweb/en/products/view.do?id=400">Huawei E800</a>. Аналогічний девайс можна було придбати у <em>Utel</em> за 899 грн., що, погодьтесь, дещо забагато як для модему. І ось трапилося диво: десь на третій чи то четвертий захід я знайшов лот, де продавався новенький розлочений <strong>E800</strong>. Ціна на той час становила трохи більше 20$ і торги закінчувалась за 10 хвилин. І біддер був лише один. Накинувши в останні секунди розіграшу пару баксів я на диво з легкістю виграв лот. Загальна вартість разом з доставкою була в районі 45$, але в перерахунку на гривні навіть по курсу 8 (в той час як на момент покупки він був у районі 7.6-7.7), це було у 2.5 рази дешевше, аніж брати у того таки Utel. І от сьогодні, через кілька тижнів очікування, нарешті девайсик опинився у мене. Але це все приказка. Казка буде далі <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  </p>
<p><span id="more-1095"></span></p>
<p>На моє велике здивування бандерольку з модемом пошта кинула прямо в поштову скриньку <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  А що: упаковка радше нагадувала коробку з-під DVD (ну може на 2-3 мм товща) аніж якийсь електронний товар. Посміявшись з сусідом трохи з дещо дивного нашій людині імені відправника Hu LongHui, мну відкрив коробку і поставив девайс у відповідний слот свого ноутбука <strong>Dell Latitude E6500</strong> (модель ноута важлива для цієї оповіді). Windows радо помітила новий пристрій попросила дрова. Я поглянув на коробку, але помітив, що ними там і не пахло. &#8220;Ну і грець з ними&#8221;, &#8211; подумав я, &#8211; &#8220;інет же поруч!&#8221; Але це виявилось не так-то просто. Перші дрова, які я знайшов були на новозеландському сайті Vodafone <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_confused.gif' alt=':???:' class='wp-smiley' />  І хоч я їх теж на всяк випадок скачав, але ставити не став. Потім я таки ледь <a href="http://www.huaweidevice.com/worldwide/downLoadDetail.do?method=view&#038;centerFlag=software&#038;productId=400&#038;oneSelected=4&#038;twoSelected=582&#038;thirdSelected=400&#038;softwareName=">знайшов їх на офіційному сайті Huawei</a> (руки повідривав би за таке юзабіліті). Скачав. Перший архів виявився лише прошивкою, але наступний вже мав ISO-образ диску з дровами та необхідним софтом. Після встановлення модем розпізнався системою, але софт, що йшов у комплекті ніяк не хотів його бачити. Перезавантаження системи не допомогли. В бій знову пішов Гугл. Тут я довідався, що виявляється диску з дровами немає в комплекті, бо дрова і софт є на самій картці(!!!), яка має розпізнаватись також як CD-диск. Подумки вже почав прикидати ціну чи варто буде відсилати модем назад і просити обмін. Витягнув картку зі свого ноута і пішов смикати Растіка, що трохи прихворів і так доречно був вдома, щоб спробувати на його ноуті <em>Lenovo</em>. На моє полегшення все запрацювало: картка розпізналась як диск, софт і дрова встановилися, <strong>Mobile Partner</strong> розпізнав пристрій і мну успішно з&#8217;єднався з мережею. Ура! Отже картка робоча, але були якісь приколи саме з <em>Dell</em>&#8216;ом. Гугл вивів на форум Vodafone, де подібна проблема визнавалась (правда з моделлю <strong>Huawei E870</strong>) і рекомендувалось оновити її прошивку. Я знову взяв картку і на Растіковій машині спробував оновити до прошивки, що я скачав з оф. сайту виробника раніше, але тут виявилося, що це і є моя версія firmware, а нічого новішого на сайті Huawei нема. Новіша прошивка знайшлась лише на сайті Vodafone, але були підозри, що після неї мій розлочений модем знову стане досить таки залоченим, що мене не влаштовувало. І ось нарешті на ще <a href="http://www.geekzone.co.nz/forums.asp?forumid=11&#038;topicid=32040">одному новозеландському форумі</a> я побачив посилання на сайт <a href="http://www.wind.com.gr/pages.fds?langID=2&#038;pageid=1516">грецього оператора &#8220;Wind&#8221;</a> (з музикою &#8220;Каті Перової&#8221; (с) у фоні <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ), де таки була новіша версія firmware для <strong>E800</strong>. Я подумав, що навряд там версія з якимось локом, адже інакше вона б не запрацювала у новозеландців. На свій страх таки перепрошив і, о диво(!), мій ноут побачив картку як диск, зміг нормально поставити софт і дрова, а <strong>Mobile Partner</strong> успішно законектився до мережі <em>Utel</em>. Отакі от у мене сьогодні були пригоди&#8230;</p>
<p>Щойно вирішив також заміряти швидкість роботи мережі. Статистика ось:<br />
<img src="http://speed.io/pics/2244/4838/speed.io.png" alt="Speed of Utel operator via Huawei E800 card" /></p>
<p>Суто суб&#8217;єктивні враження: кількасекундна затримка на DNS-ресолвінгу та конекті до сайту, але потім вантажить усе миттєво (звісно, якщо посилань на інші сайти небагато <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ). Коротше кажучи, цілком юзабельно.</p>
<p>For my english-speaking visitors: <strong>the ultimate guide to make your Huawei E800 card working on Dell, Fujitsu-Siemens and some other notebooks</strong> <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Download the new firmware for <strong>Huawei E800/E800A</strong> from <a href="http://www.wind.com.gr/pages.fds?langID=2&#038;pageid=1516">this site</a> and follow the installation instructions there to upload it onto your card. The notebook used to upload should be the one correctly working with this card (e.g. not Dell notebook or so). After that everything should work just fine.</p>
]]></content:encoded>
			<wfw:commentRss>http://graywolf.org.ua/2009/07/22/dell-inspiron-e6500-huawei-e800-utel/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2009/07/3_4-150x150.jpg" />
		<media:content url="http://graywolf.org.ua/wp-content/uploads/2009/07/3_4.jpg" medium="image">
			<media:title type="html">Huawei E800 (HSDPA modem)</media:title>
			<media:thumbnail url="http://graywolf.org.ua/wp-content/uploads/2009/07/3_4-150x150.jpg" />
		</media:content>
		<media:content url="http://speed.io/pics/2244/4838/speed.io.png" medium="image">
			<media:title type="html">Speed of Utel operator via Huawei E800 card</media:title>
			<media:thumbnail url="http://speed.io/pics/2244/4838/speed.io.png" />
		</media:content>
	</item>
		<item>
		<title>Google datastore sucks&#8230;</title>
		<link>http://graywolf.org.ua/2009/05/24/google-datastore-sucks/</link>
		<comments>http://graywolf.org.ua/2009/05/24/google-datastore-sucks/#comments</comments>
		<pubDate>Sun, 24 May 2009 16:16:02 +0000</pubDate>
		<dc:creator>graywolf</dc:creator>
				<category><![CDATA[Мережі та ІТ]]></category>
		<category><![CDATA[Щоденник]]></category>
		<category><![CDATA[Datastore]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[GAE]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://graywolf.org.ua/?p=1022</guid>
		<description><![CDATA[Ну, не так щоб взагалі, але сьогодні сівши після півторатижневої перерви (співбесіди і все таке) за згаданий нещодавно новий веб-проект остаточно зрозумів, що для моєї задачі воно абсолютно не підходить. Google App Engine &#8211; непогана штука, але для простих проектів типу того ж Jaiku. У мене ж структура даних досить насичена відношеннями many-to-many та ще [...]]]></description>
			<content:encoded><![CDATA[<p>Ну, не так щоб взагалі, але сьогодні сівши після півторатижневої перерви (співбесіди і все таке) за згаданий нещодавно новий веб-проект остаточно зрозумів, що для моєї задачі воно абсолютно не підходить. <a href="http://appengine.google.com/">Google App Engine</a> &#8211; непогана штука, але для простих проектів типу того ж <a href="http://jaiku.com/">Jaiku</a>. У мене ж структура даних досить насичена відношеннями <em>many-to-many</em> та ще й має велику ієрархічну структуру, яку легко можна описати засобами <em>Datastore</em>, але працювати практично нереально із-за відсутності хоча б якоїсь подоби join&#8217;ів. Плюс до того, я під час написання минулого проекту на <a href="http://www.djangoproject.com/">Django</a> став вельми балуваним і те, що тут інтеграція з цим фреймворком через дупу і з купою обмежень мене кумарить. Сама робота полягає більше в тому як так ви**нутись, щоб хоч якось отримати отримати в <em>Datastore</em> те, що за допомогою <em>Django Models</em> робиться в один рядок. Коротше кажучи, мну вирішив вибиратись з цього болота, поки не пізно. Буду портувати те, що понаписував на нормальну Джангу. Сподіваюсь, на наступному тижні буде достатньо вільного часу і я встигну до кінця місяця швиденьку портувати код. Потім проект розгорну на тому ж хостингу, де і цей блог. Щойно перевірив: воно чудово працює і через <em>mod_python</em>, так що поки буду розробляти можна навіть не доплачувати за FastCGI (правда треба буде не забути сам хостинг проплатити, а то це, здається, останній місяць). Отаке&#8230; :-/ </p>
]]></content:encoded>
			<wfw:commentRss>http://graywolf.org.ua/2009/05/24/google-datastore-sucks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
	</item>
		<item>
		<title>Приклад використання Twitter REST API</title>
		<link>http://graywolf.org.ua/2009/05/13/twitter-rest-api/</link>
		<comments>http://graywolf.org.ua/2009/05/13/twitter-rest-api/#comments</comments>
		<pubDate>Wed, 13 May 2009 10:39:11 +0000</pubDate>
		<dc:creator>graywolf</dc:creator>
				<category><![CDATA[Code snippets]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[bit.ly]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[tricks]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://graywolf.org.ua/?p=1018</guid>
		<description><![CDATA[Вчора вночі щось мене пробило і я до 2-ї ночі сидів писав одну штуку собі в допомогу, а сьогодні вранці, коли хотів вже залити виявилось, що це вже зробили до мене, причому найцікавіше, що виглядає все один в один як те, що зробив мну. Не розумію, правда, як я не знайшов його вчора &#8211; мабуть [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.python.org/"><img alt="" src="http://www.python.org/images/python-logo.gif" title="Python logo" class="alignleft" width="211" height="71" /></a>
<p>Вчора вночі щось мене пробило і я до 2-ї ночі сидів писав одну штуку собі в допомогу, а сьогодні вранці, коли хотів вже залити виявилось, що це <a href="http://twitter.com/lostfilmnews/">вже зробили до мене</a>, причому найцікавіше, що виглядає все один в один як те, що зробив мну. Не розумію, правда, як я не знайшов його вчора &#8211; мабуть вже заспаний був, але суть не втому. Щоб робота марно не пропадала поділюся парою коротких сніпетів на пітоні.</p>
<p><span id="more-1018"></span><br />
Перший &#8211; для скорочення URL за допомогою сервісу <a href="http://bit.ly/">bit.ly</a> (перед використанням там треба зареєструватись, щоб отримати API key):</p>
<pre class="brush: python;">import urllib, urllib2
import json # є лише Python 2.6 і старше

bitly_login = &quot;your bitly login&quot;
bitly_apikey = &quot;your API key&quot;

def ShortenURL(url):
  try:
    request = urllib2.urlopen(&quot;http://api.bit.ly/shorten?version=2.0.1&amp;longUrl=%s&amp;login=%s&amp;apiKey=%s&quot; % (url, bitly_login, bitly_apikey))
    result = json.loads(request.read())
    return result[&quot;results&quot;][url][&quot;shortUrl&quot;]
  except:
    return None
</pre>
<p>Другий &#8211; для публікації повідомлення в <a href="http://twitter.com">Twitter</a> (тут використовується несек&#8217;юрна Basic HTTP Authorization, бо з <a href="http://oauth.net/">oAuth</a> це було б набагато складніше, а мені вночі було ліньки возитись).</p>
<pre class="brush: python;">import urllib, urllib2
import base64

login = &quot;your twitter login&quot;
passwd = &quot;your twitter password&quot;

secret = base64.encodestring(&quot;%s:%s&quot; % (login, passwd))[:-1]

def Post(message):
  request = urllib2.Request(&quot;http://twitter.com/statuses/update.xml&quot;, urllib.urlencode({&quot;status&quot;: message}), {&quot;Authorization&quot;: &quot;Basic &quot; + secret})

  try:
    urllib2.urlopen(request)
    return message # returning message if it was successfully sent
  except:
    return None
</pre>
<p>Обожнюю python <img src='http://graywolf.org.ua/wp-includes/images/smilies/icon_rolleyes.gif' alt=':roll:' class='wp-smiley' />  </p>
]]></content:encoded>
			<wfw:commentRss>http://graywolf.org.ua/2009/05/13/twitter-rest-api/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:thumbnail url="http://www.python.org/images/python-logo.gif" />
		<media:content url="http://www.python.org/images/python-logo.gif" medium="image">
			<media:title type="html">Python logo</media:title>
			<media:thumbnail url="http://www.python.org/images/python-logo.gif" />
		</media:content>
	</item>
	</channel>
</rss>
