<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><title>Светлячный Dev Лог</title><link href="http://dev.svetlyak.ru" rel="alternate" /><id>http://dev.svetlyak.ru</id><updated>2012-04-11T15:19:00Z</updated><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/dev-svetlyak/all-en" /><feedburner:info uri="dev-svetlyak/all-en" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry><title>Periodical Tasks For Things</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/pOazi5mw-KQ/" rel="alternate" /><updated>2012-04-11T15:19:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/things-en/</id><summary type="html">&lt;p&gt;Few days ago, I read a funny document "&lt;a href="http://gtdfh.branchable.com/"&gt;GTD for hackers&lt;/a&gt;" and found an interesting ideas there.
One of them is to create the checklists for routines.&lt;/p&gt;
&lt;p&gt;I already use &lt;a href="http://culturedcode.com/things/"&gt;Things&lt;/a&gt; by Cultured Code, to track my todos. However there is no such feature as periodical tasks. They should behave like periodical events in the calendar — you add it once, specifying a time interval, and task should appear in the list automatically. Things is lack this feature.&lt;/p&gt;
&lt;p&gt;But we have this wonderful Apple Script, and it allow to do almost anything!&lt;/p&gt;
&lt;p&gt;I spent about hour to generate a 10 lines script. It adds a task to the Things right from the command line. The last part was pretty easy — to run a crontab and to add a one line for each periodical task I want to appear in my checklist.&lt;/p&gt;
&lt;p&gt;Finally, I've got a very flexible system, which solves my problem and does not require any additional software.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/svetlyak40wt/things-periodical-tasks"&gt;Sources are available&lt;/a&gt; at the GitHub. Fork and edit.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/pOazi5mw-KQ" height="1" width="1"/&gt;</summary><category term="python" /><feedburner:origLink>http://dev.svetlyak.ru/things-en/</feedburner:origLink></entry><entry><title>GitHub in Numbers</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/RgeBkQSlqBk/" rel="alternate" /><updated>2011-10-15T09:20:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/github-stats-en/</id><summary type="html">&lt;p&gt;Some times ago, I had got an idea — to create a new service around the GitHub. In the first place it will be useful to those users who have many repositories or following/watching many users and repositories.&lt;/p&gt;
&lt;p&gt;My basic GitHub usage pattern is: to follow other coders to see in the News Feed which other coders they are following and which projects they are watching. This way I'm able to discover interesting people and projects on the GitHub. But this approach works only to a paritcular moment, while amount of data is not very big. When I had got a lot of items in my News Feed, I stoped to read it.&lt;/p&gt;
&lt;p&gt;The idea is to aggregate items from the news feed and pop out interesting projects. For example, people who you are following instest can be used or people from the 2nd circle.&lt;/p&gt;
&lt;p&gt;Moreover, this service should be useful for watching on the changes in your repositories forks. This feature will be useful for those guys who have tens public repositories. I already implemented this functionality for myself as a simple script. This script generates a RSS feed with new commits from the forks.&lt;/p&gt;
&lt;p&gt;Also, there will be a funny medals and ratings. Push a dozen commits at the midnight and you'll become a "Midnight code warrior" :)&lt;/p&gt;
&lt;p&gt;But before actual implementation of the idea, I decided to calculate some stats about GitHub's usage. I have to estimate how many people will be interested in such project, because I hate to create useless things.&lt;/p&gt;
&lt;h2&gt;Progress&lt;/h2&gt;
&lt;p&gt;At first, I wrote a GitHub's profiles and reps fetcher. It takes one login and downloads a his profile and add all users who he follows to the queue. Then it repeats the process for every login in the queue.&lt;/p&gt;
&lt;p&gt;Because the rate limit in 5000 reqeusts a hour, my script worked about 2 days.&lt;/p&gt;
&lt;p&gt;Totally about &lt;strong&gt;57 thousand&lt;/strong&gt; profiles were downloaded and &lt;strong&gt;500 thousand&lt;/strong&gt; repositories were fetched. I expected that there are much more users, but probably these numbers are correct. After all, if my script didn't download somebody then nowbody follows hib and his account probably abandoned.&lt;/p&gt;
&lt;p&gt;This graph depicts a fetching progress. At this graph is well seen the moment when queue stopped to grow and started to fall down.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;
&lt;img alt="" src="http://chart.apis.google.com/chart?cht=lxy&amp;amp;chs=800x300&amp;amp;chd=e:AAApBSB7CkDND2EfFIFxGaHDHrIUI9JmKPK4LhMKMzNcOFOuPXQAQpRSR7SkTNT1UeVHVwWZXCXrYUY9ZmaPa4bhcKczdceFeufXgAgohRh6ijjMj1kelHlwmZnCnroUo9pmqPq4rhsKsztbuEutvWv.woxRx6yjzMz10e1H1w2Z3C3r4U495m6O637g8J8y9b-E-t.W..,FtSbbKjQmuqvthvwxU0D043Z5o5d7N-I8X8K9B9X-V...e.8-z-z.Y.o.A-K-J9w736D7Q6C425S3P23000dzuyMy-y2ySy1xyw6wcuyuFtFrQrAqGpPphomnNmpnsmQmSkhjVh9hTfselfjecczeVcPbfavZMcRbUaIYgXnWwV4UyUTSCRLPIN4MaKrJJHpGIEzDSCJAH&amp;amp;chtt=Fetching%20progress&amp;amp;chxt=y,x,y,x&amp;amp;chxl=2:%7cqueue%7c3:%7cnumber%20of%20fetched%20profiles&amp;amp;chxr=0,0,3707%7c1,0,57001&amp;amp;chxp=2,50%7c3,50&amp;amp;chg=25,25,1,0" /&gt;
&lt;/center&gt;&lt;/p&gt;
&lt;h2&gt;Watch &amp;amp; Follow&lt;/h2&gt;
&lt;p&gt;One of the most impotent stats for my project is portion of users who are watching a large amount of repositories or following many other coders:&lt;/p&gt;
&lt;center&gt;

&lt;p&gt;&lt;img alt="" src="http://chart.apis.google.com/chart?cht=p3&amp;amp;chs=500x150&amp;amp;chd=s:EbZFAA&amp;amp;chtt=Num%20watched%20repositories&amp;amp;chco=208020&amp;amp;chl=%3C1000%20%287.0%25%29%7c%3C100%20%2843.7%25%29%7c%3C10%20%2841.7%25%29%7cnot%20watching%20%287.4%25%29%7c%3C10000%20%2852%29%7c%3E10000%20%281%29" /&gt; | &lt;img alt="" src="http://chart.apis.google.com/chart?cht=p3&amp;amp;chs=500x150&amp;amp;chd=s:NdTA&amp;amp;chtt=Number%20of%20followed%20users&amp;amp;chco=208020&amp;amp;chl=%3C100%20%2820.5%25%29%7c%3C10%20%2847.3%25%29%7cnot%20following%20%2831.4%25%29%7c%3E100%20%28410%29" /&gt;&lt;/p&gt;
&lt;/center&gt;

&lt;p&gt;Here we see that about 50% of users are watching more than 10 repositories and 7% (~ 4000) — are watching more than 100. Also I'm interested in those 20% (~11000), who are following more than 10 people, definitely they are unable to read through all their news feeds. And certanly those 410 users who follow more then hungred other coders will fall in love with aggregation feature. Myself is in the latter category as I'm following about 331 users.&lt;/p&gt;
&lt;h2&gt;A number of repositories&lt;/h2&gt;
&lt;p&gt;Average amount of public repositories is &lt;strong&gt;8&lt;/strong&gt;, &lt;strong&gt;3&lt;/strong&gt; of them are forks of someone's else repository.&lt;/p&gt;
&lt;center&gt;

&lt;p&gt;&lt;img alt="" src="http://chart.apis.google.com/chart?cht=p3&amp;amp;chs=500x150&amp;amp;chd=s:PlJA&amp;amp;chtt=Number%20of%20public%20repositories&amp;amp;chco=208020&amp;amp;chl=%3C100%20%2824.4%25%29%7c%3C10%20%2860.1%25%29%7cno%20reps%20%2815.2%25%29%7c%3E100%20%28158%29" /&gt; | &lt;img alt="" src="http://chart.apis.google.com/chart?cht=p3&amp;amp;chs=500x150&amp;amp;chd=s:mIPA&amp;amp;chtt=Number%20of%20public%20repositories%20%28except%20forks%29&amp;amp;chco=208020&amp;amp;chl=%3C10%20%2862.1%25%29%7c%3C100%20%2813.4%25%29%7cno%20reps%20%2824.4%25%29%7c%3E100%20%2854%29" /&gt;&lt;/p&gt;
&lt;/center&gt;

&lt;p&gt;This graph shows that 60% of users have less than 10 public repositories and 15% does not have repositories at all. But about a quarter of users have from 10 to 100 public repositories. They will appreciate a fork watching feature of my project.&lt;/p&gt;
&lt;p&gt;Also, I calculated a part of active repositories. Only 10% of repositories had been pushed at last month.&lt;/p&gt;
&lt;h2&gt;And more…&lt;/h2&gt;
&lt;p&gt;As I said before, totally about &lt;strong&gt;500 thousand&lt;/strong&gt; repositories were downloaded and &lt;strong&gt;40%&lt;/strong&gt; of them are forks. It is amazing! I thought this number should be much much bigger.&lt;/p&gt;
&lt;p&gt;In addition, I estimated how much a 2nd cirle is. Average GitHub user follows 9 people and watches at 33 repositories. But his 2nd circle contains 230 people and 800 repositories. This is average number, but for geeks like me they are much bigger. I have in 2nd cirle 11548 people and 42882 repositories. It is about 1/5 of all GitHub!&lt;/p&gt;
&lt;p&gt;And here is how many &lt;strong&gt;organisations&lt;/strong&gt; relative to &lt;strong&gt;users&lt;/strong&gt;:&lt;/p&gt;
&lt;center&gt;

&lt;p&gt;&lt;img alt="" src="http://chart.apis.google.com/chart?cht=p3&amp;amp;chs=500x150&amp;amp;chd=s:7C&amp;amp;chtt=User%20types&amp;amp;chco=208020&amp;amp;chl=User%20%2896.41%25%29%7cOrganization%20%283.59%25%29" /&gt;&lt;/p&gt;
&lt;/center&gt;

&lt;h2&gt;And some tops, I know, you like them!&lt;/h2&gt;
&lt;style&gt;
  div.top {width: 40%; float: left; margin-right: 10%;}
  br.clear {border: 0px; clear: both;}
&lt;/style&gt;

&lt;div class="top"&gt;

&lt;h3 id="top_20_companies"&gt;Top 20 Companies&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Company&lt;/th&gt;
&lt;th&gt;Users&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td /&gt;
&lt;td&gt;37965&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ThoughtWorks&lt;/td&gt;
&lt;td&gt;75&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mozilla&lt;/td&gt;
&lt;td&gt;61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Red Hat&lt;/td&gt;
&lt;td&gt;58&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Freelance&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Twitter&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Japan&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Yandex&lt;/td&gt;
&lt;td&gt;39&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Freelancer&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Globo.com&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Yahoo!&lt;/td&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intridea&lt;/td&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Facebook&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Student&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Emergya&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pivotal Labs&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Engine Yard&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;div class="top"&gt;

&lt;h3 id="top_20_cities"&gt;Top 20 Cities&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;City&lt;/th&gt;
&lt;th&gt;Users&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td /&gt;
&lt;td&gt;23657&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;San Francisco&lt;/td&gt;
&lt;td&gt;1441&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;London&lt;/td&gt;
&lt;td&gt;962&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New York&lt;/td&gt;
&lt;td&gt;578&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Paris&lt;/td&gt;
&lt;td&gt;474&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chicago&lt;/td&gt;
&lt;td&gt;458&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Seattle&lt;/td&gt;
&lt;td&gt;457&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tokyo&lt;/td&gt;
&lt;td&gt;430&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Berlin&lt;/td&gt;
&lt;td&gt;423&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Germany&lt;/td&gt;
&lt;td&gt;417&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Portland&lt;/td&gt;
&lt;td&gt;346&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Toronto&lt;/td&gt;
&lt;td&gt;317&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boston&lt;/td&gt;
&lt;td&gt;288&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Austin&lt;/td&gt;
&lt;td&gt;280&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sydney&lt;/td&gt;
&lt;td&gt;272&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stockholm&lt;/td&gt;
&lt;td&gt;261&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Japan&lt;/td&gt;
&lt;td&gt;244&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Los Angeles&lt;/td&gt;
&lt;td&gt;230&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brooklyn&lt;/td&gt;
&lt;td&gt;226&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Melbourne&lt;/td&gt;
&lt;td&gt;221&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;div class="top"&gt;

&lt;h3 id="top_20_followers"&gt;Top 20 "followers"&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Login&lt;/th&gt;
&lt;th&gt;Follows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;snytkine&lt;/td&gt;
&lt;td&gt;3242&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mtsoerin&lt;/td&gt;
&lt;td&gt;1983&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;webiest&lt;/td&gt;
&lt;td&gt;1903&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;superfeedr&lt;/td&gt;
&lt;td&gt;1710&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;charlenopires&lt;/td&gt;
&lt;td&gt;1236&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stonegao&lt;/td&gt;
&lt;td&gt;1205&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Marak&lt;/td&gt;
&lt;td&gt;1068&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;speedygonzalez&lt;/td&gt;
&lt;td&gt;1059&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tyru&lt;/td&gt;
&lt;td&gt;1022&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;esneko&lt;/td&gt;
&lt;td&gt;867&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;josegonzalez&lt;/td&gt;
&lt;td&gt;640&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;c9s&lt;/td&gt;
&lt;td&gt;556&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kanzure&lt;/td&gt;
&lt;td&gt;555&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;take-cheeze&lt;/td&gt;
&lt;td&gt;517&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;elliottcable&lt;/td&gt;
&lt;td&gt;495&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sannis&lt;/td&gt;
&lt;td&gt;475&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mattn&lt;/td&gt;
&lt;td&gt;462&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;j2labs&lt;/td&gt;
&lt;td&gt;453&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dpree&lt;/td&gt;
&lt;td&gt;446&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rkh&lt;/td&gt;
&lt;td&gt;444&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;div class="top"&gt;

&lt;h3 id="top_20_who_followed"&gt;Top 20 "who followed"&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Login&lt;/th&gt;
&lt;th&gt;Followers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;defunkt&lt;/td&gt;
&lt;td&gt;4005&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;torvalds&lt;/td&gt;
&lt;td&gt;3803&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;jeresig&lt;/td&gt;
&lt;td&gt;3466&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mojombo&lt;/td&gt;
&lt;td&gt;3248&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ryanb&lt;/td&gt;
&lt;td&gt;2737&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;schacon&lt;/td&gt;
&lt;td&gt;2429&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;paulirish&lt;/td&gt;
&lt;td&gt;2316&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dhh&lt;/td&gt;
&lt;td&gt;2170&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wycats&lt;/td&gt;
&lt;td&gt;2044&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ry&lt;/td&gt;
&lt;td&gt;2032&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rails&lt;/td&gt;
&lt;td&gt;1946&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;facebook&lt;/td&gt;
&lt;td&gt;1802&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;jquery&lt;/td&gt;
&lt;td&gt;1767&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;technoweenie&lt;/td&gt;
&lt;td&gt;1572&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pjhyett&lt;/td&gt;
&lt;td&gt;1563&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;visionmedia&lt;/td&gt;
&lt;td&gt;1554&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cyanogen&lt;/td&gt;
&lt;td&gt;1410&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;douglascrockford&lt;/td&gt;
&lt;td&gt;1380&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tpope&lt;/td&gt;
&lt;td&gt;1369&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;android&lt;/td&gt;
&lt;td&gt;1317&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;div class="top"&gt;

&lt;h3 id="top_20_repository_owners"&gt;Top 20 repository owners&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Login&lt;/th&gt;
&lt;th&gt;Repositories&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gitpan&lt;/td&gt;
&lt;td&gt;21976&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vim-scripts&lt;/td&gt;
&lt;td&gt;3735&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;emacsmirror&lt;/td&gt;
&lt;td&gt;3101&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Epictetus&lt;/td&gt;
&lt;td&gt;911&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;panega&lt;/td&gt;
&lt;td&gt;612&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;jenkinsci&lt;/td&gt;
&lt;td&gt;602&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dev2dev&lt;/td&gt;
&lt;td&gt;504&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wave2future&lt;/td&gt;
&lt;td&gt;411&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CyanogenMod&lt;/td&gt;
&lt;td&gt;342&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MechanisM&lt;/td&gt;
&lt;td&gt;329&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rjbs&lt;/td&gt;
&lt;td&gt;325&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tokuhirom&lt;/td&gt;
&lt;td&gt;297&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rwldrn&lt;/td&gt;
&lt;td&gt;297&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;aculich&lt;/td&gt;
&lt;td&gt;287&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rainly&lt;/td&gt;
&lt;td&gt;282&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;albertobraschi&lt;/td&gt;
&lt;td&gt;278&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;idega&lt;/td&gt;
&lt;td&gt;272&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rafl&lt;/td&gt;
&lt;td&gt;266&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;apache&lt;/td&gt;
&lt;td&gt;258&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kristianmandrup&lt;/td&gt;
&lt;td&gt;244&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;div class="top"&gt;

&lt;h3 id="top_20_watchers"&gt;Top 20 "watchers"&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Login&lt;/th&gt;
&lt;th&gt;Watches&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gitpan&lt;/td&gt;
&lt;td&gt;21976&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vim-scripts&lt;/td&gt;
&lt;td&gt;3736&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;emacsmirror&lt;/td&gt;
&lt;td&gt;3588&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stonegao&lt;/td&gt;
&lt;td&gt;2789&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;abecciu&lt;/td&gt;
&lt;td&gt;2474&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;igrigorik&lt;/td&gt;
&lt;td&gt;2415&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;charlenopires&lt;/td&gt;
&lt;td&gt;2339&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stan&lt;/td&gt;
&lt;td&gt;2318&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;matagus&lt;/td&gt;
&lt;td&gt;2160&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;smtlaissezfaire&lt;/td&gt;
&lt;td&gt;1955&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rmetzler&lt;/td&gt;
&lt;td&gt;1916&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;shanlalit&lt;/td&gt;
&lt;td&gt;1897&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;willi&lt;/td&gt;
&lt;td&gt;1896&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Epictetus&lt;/td&gt;
&lt;td&gt;1821&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;filipeamoreira&lt;/td&gt;
&lt;td&gt;1812&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;arden&lt;/td&gt;
&lt;td&gt;1783&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;andrew&lt;/td&gt;
&lt;td&gt;1746&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;methodmissing&lt;/td&gt;
&lt;td&gt;1665&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rkh&lt;/td&gt;
&lt;td&gt;1571&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;lgs&lt;/td&gt;
&lt;td&gt;1511&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;h2&gt;The end&lt;/h2&gt;
&lt;p&gt;Certanly, some other interesting metrics could be calculated, using my database. If you have any ideas feel comment this post or send me an email.&lt;/p&gt;
&lt;p&gt;P.S. — I think that my project have a chance to take off and will be useful for few thousand of people around the world. One more thing to think about is how to monetize it to pay rent for servers.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/RgeBkQSlqBk" height="1" width="1"/&gt;</summary><category term="git" /><category term="github" /><feedburner:origLink>http://dev.svetlyak.ru/github-stats-en/</feedburner:origLink></entry><entry><title>Git helper for GitHub Users</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/zGqGCdPAoUA/" rel="alternate" /><updated>2011-04-14T12:26:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/hub-en/</id><summary type="html">&lt;p&gt;Found a &lt;a href="http://defunkt.io/hub/"&gt;helper&lt;/a&gt;, to work with GitHub from command line. All your need is Ruby (it is already included into the Mac OS X). This script should be downloaded into the &lt;code&gt;PATH&lt;/code&gt;, and aliased as &lt;code&gt;alias git=hub&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To use all features, you also have to add you username and GitHub's API token into the &lt;code&gt;~/.gitconfig&lt;/code&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="k"&gt;[github]&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;svetlyak40wt&lt;/span&gt;
    &lt;span class="na"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;a-secret-token&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Afterwards, you'll be able to make a quick fork of any GitHub project, for example, mine &lt;a href="http://github.com/svetlyak40wt/forkfeed"&gt;ForkFeed&lt;/a&gt; is a good candidate as it is useful for GitHub users too:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;clone&lt;/span&gt; &lt;span class="n"&gt;svetlyak40wt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;forkfeed&lt;/span&gt;
&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;forkfeed&lt;/span&gt;
&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="nb"&gt;fork&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Have a fun!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/zGqGCdPAoUA" height="1" width="1"/&gt;</summary><category term="git" /><feedburner:origLink>http://dev.svetlyak.ru/hub-en/</feedburner:origLink></entry><entry><title>Asynchronous testing with Twisted</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/yWCOGR0c95U/" rel="alternate" /><updated>2011-03-01T10:53:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/async-testing-en/</id><summary type="html">&lt;p&gt;Some time ago, &lt;a href="http://twitter.com/svetlyak40wt/status/38659219838337024"&gt;I tweeted&lt;/a&gt; that I like to write unittests for programs, using a &lt;a href="http://twistedmatrix.com"&gt;Twisted&lt;/a&gt; framework. Tweets are short and there are not enough space for more comprehensive description, that is why I decided to write a separate post on this theme.&lt;/p&gt;
&lt;p&gt;I am developing a distribute, fault-tolerant lock service. It is asynchronous and uses Twisted. Nodes talk to each other using TCP and custom text protocol, but provide a REST HTTP API for clients. It is very important to be consistent and durable, that is the reason I wrote tests before any actual lock implementation. They are functional, rather than unit-tests.&lt;/p&gt;
&lt;p&gt;Well, my tests check an interaction among different nodes. Nodes exchange messages via network. How to run such tests? Should I start few separate processes? And if I should, then how to debug them?&lt;/p&gt;
&lt;p&gt;Debugging threaded networking code is a complex task. But (drum roll), not with Twisted!&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://img-fotki.yandex.ru/get/5005/alexander-artemenko.e/0_755a1_e15d9963_L" /&gt;&lt;br /&gt;
by &lt;a href="http://www.flickr.com/photos/dirkscircusimages/2785357852/"&gt;dirkjanranzijn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;First, twisted allowed to run all five nodes in one process on one reactor, and now I am able to set &lt;code&gt;pdb.set_trace()&lt;/code&gt; where I want.&lt;/p&gt;
&lt;p&gt;Second, I replaced a networking layer with a mock objects, which deliver messages with some random delay. But I can drive the python's random generator which gives me ability to reproduce stochastic errors and debug them. It works as following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;before the test &lt;code&gt;TestCase&lt;/code&gt; class calls &lt;code&gt;random.seed(some_value)&lt;/code&gt; and remembers the &lt;code&gt;some_value&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;it test raises &lt;code&gt;AssertionError&lt;/code&gt; besides a normal error message, &lt;code&gt;TestCase&lt;/code&gt; prints &lt;code&gt;RANDOM SEED: some_value&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;to run test, with random generator initialized explicitly, it should be decorated:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="nd"&gt;@seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;some_value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_my_broken_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are the class &lt;code&gt;TestCase&lt;/code&gt; and the decorator &lt;code&gt;seed&lt;/code&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;random&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;twisted.trial&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unittest&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_random_seed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;decorator&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;seed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;_random_seed&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
        &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;seed_info_adder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;failure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;failure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#39; (random seed: &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;)&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;failure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;failure&lt;/span&gt;

        &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addErrback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seed_info_adder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Feel free to write your thoughts about this testing method, or send any suggestions.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/yWCOGR0c95U" height="1" width="1"/&gt;</summary><category term="python" /><category term="twisted" /><feedburner:origLink>http://dev.svetlyak.ru/async-testing-en/</feedburner:origLink></entry><entry><title>Yet Another HTTP Lib</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/GXE76Ns-X2M/" rel="alternate" /><updated>2011-02-16T11:11:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/yet-another-http-en/</id><summary type="html">&lt;p&gt;Sometimes I see interesting links in the Twitter. For example, Yury Yurevich retwitted few PyPi updates yesterday. One of them is a new &lt;a href="http://pypi.python.org/pypi/requests/"&gt;HTTP library&lt;/a&gt;. This is just a wrapper around urllib and urllib2, to make the life easier. But this bicycle design could be improved.&lt;/p&gt;
&lt;p&gt;For example, to use HTTP basic auth, author suggest to create an Auth object and then use it in every call:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;conv_auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;requeststest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;requeststest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;https://convore.com/api/account/verify.json&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conv_auth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Why? This object just stores a username and a password, why not to use a tuple instead? If you strive for simplicity, why not to go to the end?&lt;/p&gt;
&lt;p&gt;And there are some comments, related to the code. It is incompatible with python2.5 because author forgot about &lt;code&gt;from __future__ import absolute_import&lt;/code&gt; and uses new style try except blocks. The main method, sending request, is overcomplicated and contains few huge ifelse blocks. Also, he is trying to do some monkeypatching if there are 'eventlet' or 'gevent' modules. But which side-effects I should be aware of if one of these libraries is installed in the system, but I don't mind to use it?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/GXE76Ns-X2M" height="1" width="1"/&gt;</summary><category term="python" /><feedburner:origLink>http://dev.svetlyak.ru/yet-another-http-en/</feedburner:origLink></entry><entry><title>Zen for Everyone</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/rYsKdo6tqvI/" rel="alternate" /><updated>2011-02-15T10:03:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/zen-for-everyone-en/</id><summary type="html">&lt;p&gt;There is a &lt;a href="http://www.python.org/dev/peps/pep-0020/"&gt;PEP-0020&lt;/a&gt;, recommended for every beginners learning the Python right after they learned a &lt;a href="http://www.python.org/dev/peps/pep-0008/"&gt;PEP-0008&lt;/a&gt;. This is a set of rules to follow programming in Python (and not only in Python). These rules were written by Tim Peters and they are available right in the python interpreter. Just do the &lt;code&gt;import this&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Today I want to give you a link to &lt;a href="http://artifex.org/~hblanks/talks/2011/pep20_by_example.html"&gt;extension of the PEP-0020&lt;/a&gt;, written by Hunter Blanks. It is a concise illustration of every item of "The Zen of Python".&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/rYsKdo6tqvI" height="1" width="1"/&gt;</summary><category term="python" /><feedburner:origLink>http://dev.svetlyak.ru/zen-for-everyone-en/</feedburner:origLink></entry><entry><title>Projects evolution at GitHub</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/Nicb3liCFrA/" rel="alternate" /><updated>2011-02-09T12:11:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/forkfeed-en/</id><summary type="html">&lt;p&gt;Today I released a small tool, useful for all GitHub users. This project's name is &lt;a href="https://github.com/svetlyak40wt/forkfeed"&gt;Forkfeed&lt;/a&gt;. It's target is to watch how your projects' forks are evolved on GitHub.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://img-fotki.yandex.ru/get/5602/alexander-artemenko.e/0_73de3_97d804f1_L" /&gt;&lt;br /&gt;
by &lt;a href="http://www.flickr.com/photos/graeme_pow/4534266872/in/photostream/"&gt;GraemePow@flickr&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sometimes somebody forks your project and begins to improve it. But not many people send pull requests. It is hard to track all new forks. That is because I wrote a script which inspects each of your projects at Github and creates an Atom feed for all new commits. My own &lt;a href="http://forkfeed.svetlyak.ru/svetlyak40wt.xml"&gt;feed&lt;/a&gt; updated daily at a VPS. Now I will be well-informed about all new forks and all new commits in them.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/Nicb3liCFrA" height="1" width="1"/&gt;</summary><category term="python" /><feedburner:origLink>http://dev.svetlyak.ru/forkfeed-en/</feedburner:origLink></entry><entry><title>Cony in the Bottle</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/5xkRienh_EM/" rel="alternate" /><updated>2011-02-01T00:35:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/cony-in-the-bottle-en/</id><summary type="html">&lt;p&gt;Two weeks ago, in the "&lt;a href="http://dev.svetlyak.ru/facebook-bunny1/"&gt;Command Line for the Internet&lt;/a&gt;" post, I wrote about useful smart bookmarks service.&lt;/p&gt;
&lt;p&gt;Digging into a code of the project, I figured out that it is too complex for such trivial idea. And of course I've decided to rewrite it :-)&lt;/p&gt;
&lt;p&gt;My own &lt;a href="http://github.com/svetlyak40wt/cony/"&gt;fork&lt;/a&gt; is called Cony that is a synonym for Bunny.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://img-fotki.yandex.ru/get/5800/alexander-artemenko.e/0_735d1_b947df73_L" /&gt;&lt;br /&gt;
by &lt;a href="http://flic.kr/p/6bLmMR"&gt;animalvegetable@flickr&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And if Bunny1 has a dependency from heavy CherryPy, then Cony is much more modest. It uses a micro-framework &lt;a href="http://github.com/defnull/bottle"&gt;Bottle&lt;/a&gt;. Bottle, is only a python file committed right into the repository.&lt;/p&gt;
&lt;h2&gt;Extend&lt;/h2&gt;
&lt;p&gt;Because there are not dependencies, installation is quite simple — just clone a repository and run &lt;code&gt;./cony.py&lt;/code&gt;. Adding your own shortcuts is trivial as well — it is enough to create a &lt;code&gt;local_commands.py&lt;/code&gt; file in the current directory. Some examples already in &lt;code&gt;examples&lt;/code&gt; directory, ready to import into the &lt;code&gt;local_commands.py&lt;/code&gt; file. Just do &lt;code&gt;from examples import *&lt;/code&gt; to plug them all or import each function separately.&lt;/p&gt;
&lt;h2&gt;Clone &amp;amp; Share&lt;/h2&gt;
&lt;p&gt;If you wrote an interesting shortcut don't be lazy, fork the project on GitHub, put your command into &lt;code&gt;examples&lt;/code&gt; and send me a Pull Request.&lt;/p&gt;
&lt;h2&gt;A little about the Bottle&lt;/h2&gt;
&lt;p&gt;I liked the Bottle. It is minimalistic. There are url router and templates built-in. Of course you are able to use any other template engine and ORM. For small projects, like Cony it suits very well.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/5xkRienh_EM" height="1" width="1"/&gt;</summary><category term="python" /><feedburner:origLink>http://dev.svetlyak.ru/cony-in-the-bottle-en/</feedburner:origLink></entry><entry><title>OpenSource Translations</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/2U5SA4HlRBk/" rel="alternate" /><updated>2011-01-27T14:55:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/transifex-en/</id><summary type="html">&lt;p&gt;About a week ago, I saw an announce at the &lt;a href="http://groups.google.com/group/django-developers"&gt;django-developers&lt;/a&gt; mail list. It was about the Django translation process, which is moved to online translation service &lt;a href="http://www.transifex.net"&gt;Transifex&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Transifex provides an interface to work on translations. Here is the process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You have to sign in.&lt;/li&gt;
&lt;li&gt;Then to add a project.&lt;/li&gt;
&lt;li&gt;Upload existing translations. Usually it is a gettext "po" files.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then you need to gather some translators around the project. They must be organized into the language teams.&lt;/p&gt;
&lt;p&gt;When translation is ready, you are able to download the "po" files.&lt;/p&gt;
&lt;p&gt;For experiment, I added one of my tiny projects &lt;a href="http://www.transifex.net/projects/p/django-faces/"&gt;django-faces&lt;/a&gt; to the service. If you know language other than Russian or English, try to translate it. There is a little amount of text.&lt;/p&gt;
&lt;p&gt;By the way, I found the there are about 600 projects at the Transifex, but only half have some translation resources. It means that these developers start to play with the interface, but something prevents them from finishing the process. And interface is really obscure. For example, I do not understand how to search some project to translate it into Russian.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/2U5SA4HlRBk" height="1" width="1"/&gt;</summary><category term="web" /><category term="tools" /><feedburner:origLink>http://dev.svetlyak.ru/transifex-en/</feedburner:origLink></entry><entry><title>Command Line for the Internet</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/q0QHMFw2aJU/" rel="alternate" /><updated>2011-01-20T11:11:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/facebook-bunny1-en/</id><summary type="html">&lt;p&gt;Do you use search shortcuts, allowing to enter a query directly into the browser's address bar? If yes, then you will certainly be interested to know that you can not only to connect existing search engines to your browser, but also to write a more sophisticated query processor directly in Python.&lt;/p&gt;
&lt;p&gt;Yesterday, I found an interesting project on the GitHub. It was developed in the Facebook. The project's name is &lt;a href="https://github.com/facebook/bunny1/"&gt;Bunny1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://resizer.co/?image=http%3A%2F%2Ffarm1.static.flickr.com%2F120%2F256250194_ac05247901_o.jpg&amp;amp;w=600" /&gt;&lt;br /&gt;
by &lt;a href="http://www.flickr.com/photos/opid/256250194/"&gt;serenionion@flickr&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bunny1, is a web server, which receives a command and a query, and then either redirects somewhere else, or shows a HTML page with the result. If you'll plug the URL of the server as the default search engine, you'll get the powerful command line directly in the browser. And the most useful here is that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it will work in all modern browsers;&lt;/li&gt;
&lt;li&gt;commands can be added by yourself and written in the Python.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, you can write a handler that by the request &lt;code&gt;tw Good morning, Moscow!&lt;/code&gt; will tweet from your name and redirect to the tweet's page.&lt;/p&gt;
&lt;p&gt;Sake of justice, it should be noted that the idea is not new. There is, a service &lt;a href="http://yubnub.org/"&gt;YubNub&lt;/a&gt;, which implements similar functionality and a Firefox plug-in &lt;a href="https://mozillalabs.com/ubiquity/"&gt;Ubiquity&lt;/a&gt;. But the former contains a lot of unnecessary commands and can't be extended, and the latter is suitable only for Firefox users.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/q0QHMFw2aJU" height="1" width="1"/&gt;</summary><category term="python" /><feedburner:origLink>http://dev.svetlyak.ru/facebook-bunny1-en/</feedburner:origLink></entry><entry><title>Debugger With Blackjack</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/o4i6DQnXmRE/" rel="alternate" /><updated>2011-01-18T14:13:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/debugger-with-blackjack-en/</id><summary type="html">&lt;p&gt;I decided to adhere to a certain post publication schedule. I'll try to publish something interesting every Tuesday and Thursday.&lt;/p&gt;
&lt;p&gt;Today I want to tell you about a pretty useful tool — namely, on the debugger. If you're not a fan of full-fledged IDE, you probably used the standard Python debugger pdb. It covers 90% of the necessary functionality to me, but still somewhat inconvenient. For example, there is no auto-complete and it is annoying to run &lt;code&gt;list&lt;/code&gt; command after an every few steps just to see the current line's context.&lt;/p&gt;
&lt;p&gt;The project pdbpp was created to solve these, as well as some other issues. Here are a few features, which proved to me the most useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a sticky mode — in this mode, the debugger redraws current function after each step of the interpreter;&lt;/li&gt;
&lt;li&gt;tag auto-complete — you no longer have to call &lt;code&gt;dir(obj)&lt;/code&gt; just to view an object's interface;&lt;/li&gt;
&lt;li&gt;syntax highlighting — pdbpp uses Pygments, to make the code even more beautiful than it is (your code is amazing, right?).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, there are such things as calling the editor to correct the file is being traced, an intelligent parsing of the command, the command &lt;code&gt;longlist (ll)&lt;/code&gt; to display the current function or method.&lt;/p&gt;
&lt;p&gt;Here is a typical pdbpp session:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://bitbucket.org/antocuni/pdb/raw/0c86c93cee41/screenshot.png" /&gt;&lt;/p&gt;
&lt;p&gt;In order to use this wonderful tool, it is enough to set it into the system by any of the methods available to you, then, as usual, you can use it as usual: &lt;code&gt;import pdb; pdb.set_trace()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; recorded a short demo of how it works (comments are in russian).&lt;/p&gt;
&lt;p&gt;&lt;object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'&gt;&lt;param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' &gt;&lt;/param&gt;&lt;param name='flashvars' value='i=158211' &gt;&lt;/param&gt;&lt;param name='allowFullScreen' value='true' &gt;&lt;/param&gt;&lt;embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=158211' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer' &gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/o4i6DQnXmRE" height="1" width="1"/&gt;</summary><category term="python" /><feedburner:origLink>http://dev.svetlyak.ru/debugger-with-blackjack-en/</feedburner:origLink></entry><entry><title>Social bookmarks at the GitHub</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/6zwkq1dwLxc/" rel="alternate" /><updated>2011-01-13T11:17:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/gitmarks-en/</id><summary type="html">&lt;p&gt;Today I want to tell you about an interesting project from the GitHub. It
is developed by Hilary Mason and called &lt;a href="https://github.com/hmason/gitmarks/"&gt;gitmarks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This project allows to save URLs and share them with other GitHub users. For
each bookmark, script downloads page's content. Also, you could specify the
tags and description of the link. All data are saved to the git repository and
committed, and of course you could use &lt;code&gt;git grep&lt;/code&gt; to search over all saved
bookmarks. URLs could be added from the command line or using a bookmarklet,
but in the latter case you have to start a local web server.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://farm3.static.flickr.com/2262/2201268993_a560441f47.jpg" /&gt;&lt;br /&gt;
Image by &lt;a href="http://www.flickr.com/photos/eikumpel/2201268993/"&gt;Ei! Kumpel&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, this project has a few shortcomings.&lt;/p&gt;
&lt;p&gt;First, the code looks ugly because Hilary ignores &lt;a href="http://www.python.org/dev/peps/pep-0008/"&gt;naming conventions&lt;/a&gt;, accepted
by the Python community.&lt;/p&gt;
&lt;p&gt;Secondly, existing documentation says nothing where to store bookmarks. Because of that,
many people start to fork the repository and to save bookmarks in it. Look at
the &lt;a href="https://github.com/hmason/gitmarks/network"&gt;network graph&lt;/a&gt;, it is quite cluttered with bookmark commits and it
is very hard to find code changes in this heap.&lt;/p&gt;
&lt;p&gt;It's worse to enforce the code and content separation, to make script development
easier.&lt;/p&gt;
&lt;p&gt;And finally, there is a batch of small things which are inconvenient. For
example, people could comment bookmarks of one another, using the GitHub's
commit comments. However, the commit page looks very scary because
it includes a full HTML downloaded from the bookmarked URL. To avoid this
HTML have to be converted into the readable text.&lt;/p&gt;
&lt;p&gt;I hope, this project will evolve to the usable distributed bookmark service.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/6zwkq1dwLxc" height="1" width="1"/&gt;</summary><category term="python" /><category term="git" /><feedburner:origLink>http://dev.svetlyak.ru/gitmarks-en/</feedburner:origLink></entry><entry><title>Diff Git Cached in Vim</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/gz29EUftK3M/" rel="alternate" /><updated>2011-01-09T14:14:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/diff-git-cached-en/</id><summary type="html">&lt;p&gt;Surprisingly, there is a useful command in Vim for editing git commit messages. It was shipped with Vim starting from version 7.2. It's name is :DiffGitCahced.&lt;/p&gt;
&lt;p&gt;Diff could be showed manually, but also, you could write this line in the config:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;autocmd&lt;/span&gt; &lt;span class="n"&gt;FileType&lt;/span&gt; &lt;span class="n"&gt;gitcommit&lt;/span&gt; &lt;span class="n"&gt;DiffGitCached&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;wincmd&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And then diff will be opened automatically after the &lt;code&gt;git commit&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This tip was found in the &lt;a href="http://vim.runpaint.org/extending/integrating-vim-with-git/"&gt;Vim Recipes&lt;/a&gt; ebook.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/gz29EUftK3M" height="1" width="1"/&gt;</summary><category term="vim" /><category term="git" /><feedburner:origLink>http://dev.svetlyak.ru/diff-git-cached-en/</feedburner:origLink></entry><entry><title>Image Shortener Wanted!</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/pZh47Om_ebU/" rel="alternate" /><updated>2010-12-28T01:05:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/image-shortener-wanted-en/</id><summary type="html">&lt;p&gt;I have an idea of a new service. I call it "The Image Shortener".&lt;/p&gt;
&lt;p&gt;Sometimes, I found an image on the internet, licensed under the Creative Commons and just insert
it into the blog post. But to get nice result, image have to be resized according to a blog
column width.&lt;/p&gt;
&lt;p&gt;I'm wondering if there is already such service exists which is acts like a resizing proxy server and
url shortener simultaneously?&lt;/p&gt;
&lt;p&gt;For example, if I found this image &lt;a href="http://farm5.static.flickr.com/4005/4203341399_c1c99027e5_o.jpg"&gt;http://farm5.static.flickr.com/4005/4203341399_c1c99027e5_o.jpg&lt;/a&gt; and
want to insert in into my blog post, but it should be resized to have no more 600 pixels width:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I go to the shortener and enter the URL (ideally, I even don't have to enter the image's URL
   (it is should work with flickr's pages too).&lt;/li&gt;
&lt;li&gt;Shortener remember the URL and give me the shortened &lt;code&gt;http://blah.img/3bfg&lt;/code&gt;, which, by default,
   redirects to the original image.&lt;/li&gt;
&lt;li&gt;Then I insert this URL into the blog post but supply additional parameter: &lt;code&gt;http://blah.img/3bfg?width=600&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When this image will be requested, shortener will have to fetch the original, resize it, save somewhere
   in the cloud and redirect to this new image.&lt;/li&gt;
&lt;li&gt;And finally, I get the profit from this automatization.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What do you think about this idea? Is it a bicycle and already implemented somewhere?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/pZh47Om_ebU" height="1" width="1"/&gt;</summary><category term="ideas" /><feedburner:origLink>http://dev.svetlyak.ru/image-shortener-wanted-en/</feedburner:origLink></entry><entry><title>Powered by Pelican</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/Ile7dK3TpJc/" rel="alternate" /><updated>2010-12-25T23:06:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/powered-by-pelican-en/</id><summary type="html">&lt;p&gt;After a few days of work, I rewrote my blog to static blog generator &lt;a href="https://github.com/svetlyak40wt/pelican"&gt;Pelican&lt;/a&gt;. Moreover, I transfered not only one blog but two: my english blog &lt;a href="http://aartemenko.com"&gt;http://aartemenko.com&lt;/a&gt; and my Google Buzz where I tried to write about software development in russian.&lt;/p&gt;
&lt;p&gt;I decided to drop &lt;a href="http://aartemenko.com"&gt;http://aartemenko.com&lt;/a&gt; and move this blog to static to reduce a memory usage on my VPS. Google Buzz turned out useless for short programmer's notes, because it even not support a simple HTML tags nor syntax highlight for code snippets.&lt;/p&gt;
&lt;p&gt;As the result, I took a new static blog generator &lt;a href="https://github.com/svetlyak40wt/pelican"&gt;Pelican&lt;/a&gt;, forked it on the GitHub and patched. Some bugs were fixed and some functionality was added. For example, now it could handle article translation into different languages and separate Atom feeds are available for all translations. About two days I spent, developing my own scheme for the Pelican.&lt;/p&gt;
&lt;p&gt;Now I able to edit blog posts in my favorite editor Vim, grep them and do other things, you want usually do with texts. For now, Pelican supports only Markdown and ReST markups, but that is enough for most cases. The other features which I need to implement, are Vim helper to deploy articles to the server and ping the FeedBurner.&lt;/p&gt;
&lt;p&gt;By the way, I published &lt;a href="https://github.com/svetlyak40wt/dev.svetlyak"&gt;the sources, of this blog&lt;/a&gt; at the GitHub as an example of the modified Pelican usage.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/Ile7dK3TpJc" height="1" width="1"/&gt;</summary><category term="life" /><category term="python" /><feedburner:origLink>http://dev.svetlyak.ru/powered-by-pelican-en/</feedburner:origLink></entry><entry><title>Python Logging in Twisted</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/yyAg8wNak30/" rel="alternate" /><updated>2010-11-28T03:27:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/python-logging-twisted-en/</id><summary type="html">&lt;p&gt;This is a way to turn on a standart pyton's logging support in the Twisted. But it is broken. Really. For example, this is my default log format: &lt;code&gt;"%(asctime)s %(process)s/%(thread)s %(levelname)s %(name)s %(filename)s:%(lineno)s %(message)s"&lt;/code&gt;, and this is piece of log which I get using &lt;code&gt;twisted.python.log.PythonLoggingObserver&lt;/code&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mo"&gt;027&lt;/span&gt; &lt;span class="mi"&gt;7571&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220024640&lt;/span&gt; &lt;span class="n"&gt;INFO&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt; &lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:508&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt; &lt;span class="n"&gt;opened&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mo"&gt;02&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="mi"&gt;7571&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220024640&lt;/span&gt; &lt;span class="n"&gt;ERROR&lt;/span&gt; &lt;span class="n"&gt;blah&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:37&lt;/span&gt; &lt;span class="n"&gt;blah&lt;/span&gt; &lt;span class="n"&gt;minor&lt;/span&gt;
&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mo"&gt;031&lt;/span&gt; &lt;span class="mi"&gt;7571&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220024640&lt;/span&gt; &lt;span class="n"&gt;INFO&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt; &lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:508&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LockFactory&lt;/span&gt; &lt;span class="n"&gt;starting&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="mi"&gt;4001&lt;/span&gt;
&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mo"&gt;032&lt;/span&gt; &lt;span class="mi"&gt;7571&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220024640&lt;/span&gt; &lt;span class="n"&gt;INFO&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt; &lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:508&lt;/span&gt; &lt;span class="n"&gt;Starting&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LockFactory&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x8755d2c&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mo"&gt;033&lt;/span&gt; &lt;span class="mi"&gt;7571&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220024640&lt;/span&gt; &lt;span class="n"&gt;INFO&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt; &lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:508&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Site&lt;/span&gt; &lt;span class="n"&gt;starting&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt;
&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mo"&gt;034&lt;/span&gt; &lt;span class="mi"&gt;7571&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220024640&lt;/span&gt; &lt;span class="n"&gt;INFO&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt; &lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:508&lt;/span&gt; &lt;span class="n"&gt;Starting&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;twisted&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Site&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x875a18c&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Did you see these &lt;code&gt;log.py:508&lt;/code&gt; everywhere? This is wrong! Wrong! But there is the simple way to fix it:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;twisted&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;span class="n"&gt;_srcfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_srcfile&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;.pyc&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;.pyo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;_srcfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_srcfile&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;.py&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;_srcfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;normcase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_srcfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_srcfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_srcfile&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;After this fix, the log will have the right file and line numbers in it:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;763&lt;/span&gt; &lt;span class="mi"&gt;7710&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220380992&lt;/span&gt; &lt;span class="n"&gt;INFO&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:35&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt; &lt;span class="n"&gt;opened&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;764&lt;/span&gt; &lt;span class="mi"&gt;7710&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220380992&lt;/span&gt; &lt;span class="n"&gt;ERROR&lt;/span&gt; &lt;span class="n"&gt;blah&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:37&lt;/span&gt; &lt;span class="n"&gt;blah&lt;/span&gt; &lt;span class="n"&gt;minor&lt;/span&gt;
&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;766&lt;/span&gt; &lt;span class="mi"&gt;7710&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220380992&lt;/span&gt; &lt;span class="n"&gt;INFO&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt; &lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:861&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LockFactory&lt;/span&gt; &lt;span class="n"&gt;starting&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="mi"&gt;4001&lt;/span&gt;
&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;767&lt;/span&gt; &lt;span class="mi"&gt;7710&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220380992&lt;/span&gt; &lt;span class="n"&gt;INFO&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt; &lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:44&lt;/span&gt; &lt;span class="n"&gt;Starting&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LockFactory&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x8755d2c&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;769&lt;/span&gt; &lt;span class="mi"&gt;7710&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220380992&lt;/span&gt; &lt;span class="n"&gt;INFO&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt; &lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:861&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Site&lt;/span&gt; &lt;span class="n"&gt;starting&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt;
&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;770&lt;/span&gt; &lt;span class="mi"&gt;7710&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;1220380992&lt;/span&gt; &lt;span class="n"&gt;INFO&lt;/span&gt; &lt;span class="n"&gt;twisted&lt;/span&gt; &lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py:44&lt;/span&gt; &lt;span class="n"&gt;Starting&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;twisted&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Site&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x875a18c&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Have a fun, read sources!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: I created &lt;a href="http://twistedmatrix.com/trac/ticket/4749"&gt;a ticket&lt;/a&gt; in Twisted's trac.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/yyAg8wNak30" height="1" width="1"/&gt;</summary><category term="python" /><category term="twisted" /><feedburner:origLink>http://dev.svetlyak.ru/python-logging-twisted-en/</feedburner:origLink></entry><entry><title>Helper to use SELECT FOR UPDATE in Django</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/J-4zwq8KDcE/" rel="alternate" /><updated>2010-11-16T13:18:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/select-update-django-en/</id><summary type="html">&lt;p&gt;Just wrote a simple helper to use SELECT FOR UPDATE construction in django:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DEFAULT_DB_ALIAS&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_for_update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryset&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; Returns query, rewrited to use SELECT ... FOR UPDATE.&lt;/span&gt;
&lt;span class="sd"&gt;        Can be used in transaction to get lock on selected rows.&lt;/span&gt;
&lt;span class="sd"&gt;        Database must support this SQL statements.&lt;/span&gt;

&lt;span class="sd"&gt;        Example:&lt;/span&gt;
&lt;span class="sd"&gt;        &amp;gt;&amp;gt;&amp;gt; query = select_for_update(MyModel.objects.filter(blah = &amp;#39;minor&amp;#39;))&lt;/span&gt;
&lt;span class="sd"&gt;        &amp;gt;&amp;gt;&amp;gt; unicode(query.query)&lt;/span&gt;
&lt;span class="sd"&gt;        &amp;quot;SELECT * FROM myapp_mymodel WHERE blah = &amp;#39;minor&amp;#39; FOR UPDATE&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;queryset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_compiler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DEFAULT_DB_ALIAS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_sql&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;queryset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_default_manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#39; FOR UPDATE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/J-4zwq8KDcE" height="1" width="1"/&gt;</summary><category term="django" /><category term="sql" /><feedburner:origLink>http://dev.svetlyak.ru/select-update-django-en/</feedburner:origLink></entry><entry><title>Filtering choices in Django's ModelForm</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/JdNYqf8biC8/" rel="alternate" /><updated>2010-06-04T13:12:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/filtering-choices-en/</id><summary type="html">&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="c"&gt;# ...&lt;/span&gt;
&lt;span class="c"&gt;# There are models Subscription and MailList defined above.&lt;/span&gt;
&lt;span class="c"&gt;# MailList has a many to many field &amp;#39;managers&amp;#39;. This field&lt;/span&gt;
&lt;span class="c"&gt;# defines which manager is able to edit/add subscriptions to&lt;/span&gt;
&lt;span class="c"&gt;# a maillist.&lt;/span&gt;
&lt;span class="c"&gt;# &lt;/span&gt;
&lt;span class="c"&gt;# To filter choices in the Django&amp;#39;s admin, I use following code:&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SubscriptionAdmin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelAdmin&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;list_display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;mail_list&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;form_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SubscriptionAdmin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ModelFormWithPermissions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form_class&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ModelFormWithPermissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;mail_list&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;queryset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; \ 
                    &lt;span class="n"&gt;MailList&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;managers__id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ModelFormWithPermissions&lt;/span&gt;

&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Subscription&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SubscriptionAdmin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# This code creates a special ModelForm class which know&lt;/span&gt;
&lt;span class="c"&gt;# about the current user, his &amp;#39;id&amp;#39; and permissions.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Here is a &lt;a href="http://gist.github.com/425182"&gt;gist file&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/JdNYqf8biC8" height="1" width="1"/&gt;</summary><category term="python" /><category term="django" /><category term="snippet" /><feedburner:origLink>http://dev.svetlyak.ru/filtering-choices-en/</feedburner:origLink></entry><entry><title>10 Minute Mail refresher</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/Cja5dl44Shw/" rel="alternate" /><updated>2010-03-23T12:13:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/10-minute-mail-refresher-en/</id><summary type="html">&lt;p&gt;&lt;a href="http://userscripts.org/scripts/show/72196"&gt;"10 Minute Mail" is&lt;/a&gt; a service of temporary emails. This script is used to keep mailbox alive while it is opened in the browser.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/Cja5dl44Shw" height="1" width="1"/&gt;</summary><category term="javascript" /><category term="user-scripts" /><feedburner:origLink>http://dev.svetlyak.ru/10-minute-mail-refresher-en/</feedburner:origLink></entry><entry><title>How to parse CSS colors?</title><link href="http://feedproxy.google.com/~r/dev-svetlyak/all-en/~3/DmUfQuTh-SE/" rel="alternate" /><updated>2009-11-30T21:03:00Z</updated><author><name>Александр Артеменко</name></author><id>http://dev.svetlyak.ru/parse-css-colors-en/</id><summary type="html">&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; Parses color string in format #ABC or #AABBCC to RGB tuple. &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:])&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ch2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ch1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ch2&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; \
                     &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch1&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ch1&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
                        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch2&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ch2&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                        &lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Here is a &lt;a href="http://gist.github.com/245648"&gt;gist file&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/dev-svetlyak/all-en/~4/DmUfQuTh-SE" height="1" width="1"/&gt;</summary><category term="python" /><category term="snippet" /><feedburner:origLink>http://dev.svetlyak.ru/parse-css-colors-en/</feedburner:origLink></entry></feed>

