<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en" xmlns="http://www.w3.org/2005/Atom"><title>Internet-developer workshop</title><link href="https://adw0rd.com/en/" rel="alternate"></link><link href="https://adw0rd.com/feed/en/" rel="self"></link><id>https://adw0rd.com/en/</id><updated>2021-05-19T08:33:58+03:00</updated><author><name>adw0rd</name></author><subtitle>Blog of Mikhail Andreev, aka adw0rd</subtitle><logo></logo><entry><title>Debugging in docker-compose
</title><link href="https://adw0rd.com/2021/05/19/debugging-in-docker-compose/en/" rel="alternate"></link><published>2021-05-19T08:33:58+03:00</published><id>https://adw0rd.com/2021/05/19/debugging-in-docker-compose/en/</id><summary type="html">It is often necessary to use the debugging tools inside the container, but for this you need to get a full-fledged tty with to interact with the debugger interface via stdin/stdout. In the note below I will show you how to do this, using this method I run pudb ,…
</summary><content type="html" xml:base="https://adw0rd.com/2021/05/19/debugging-in-docker-compose/en/">&lt;p&gt;It is often necessary to use the debugging tools inside the container, but for this you need to get a full-fledged tty with to interact with the debugger interface via stdin/stdout.&lt;/p&gt;

&lt;p&gt;In the note below I will show you how to do this, using this method I run &lt;a rel="nofollow" href="https://adw0rd.com/2012/3/24/python-django-pudb/"&gt;pudb&lt;/a&gt; , &lt;a rel="nofollow" href="https://adw0rd.com/2012/10/7/python-pdb/"&gt;pdb&lt;/a&gt;, &lt;a rel="nofollow" href="https://github.com/gotcha/ipdb"&gt;ipdb&lt;/a&gt;, etc.&lt;/p&gt;

&lt;p&gt;&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You need to add &lt;tt&gt;stdin_open: true&lt;/tt&gt; and &lt;tt&gt;tty: true&lt;/tt&gt; to your service:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;version: "3.9"
services:
  api:
    build: .
    stdin_open: true
    tty: true
    ports:
      - "8000:8000"
    volumes:
      - .:/app
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then run it as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;docker-compose run --service-ports api
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If for some reason you cannot do this, then you can use the &lt;a rel="nofollow" href="https://github.com/Kozea/wdb"&gt;wdb&lt;/a&gt;&lt;/p&gt;
</content></entry><entry><title>Sniffing HTTPS Traffic in Chromium with Wireshark
</title><link href="https://adw0rd.com/2020/12/02/chromium-https-ssl-tls-sniffing-with-wireshark/en/" rel="alternate"></link><published>2020-12-02T22:33:04+03:00</published><id>https://adw0rd.com/2020/12/02/chromium-https-ssl-tls-sniffing-with-wireshark/en/</id><summary type="html">For decrypt traffic from Chromium (or Chrome), you need to configure writing SSL-logs to a file, and then configure Wireshark so that it reads this file. Chromium setup /usr/local/bin/chromium --ssl-version-max=tls1.3 --ssl-key-log-file=/tmp/sslkeylog.log (it will be more convenient to specify alias for your shell) Wireshark setup Go to Preferences &amp;gt; Protocols &amp;gt;…
</summary><content type="html" xml:base="https://adw0rd.com/2020/12/02/chromium-https-ssl-tls-sniffing-with-wireshark/en/">&lt;p&gt;&lt;img src="/media/uploads/wireshark.png" class="alignright whitespace"&gt;&lt;/p&gt;

&lt;p&gt;For decrypt traffic from &lt;strong&gt;Chromium&lt;/strong&gt; (or Chrome), you need to configure writing SSL-logs to a file, and then configure &lt;strong&gt;Wireshark&lt;/strong&gt; so that it reads this file.&lt;/p&gt;

&lt;p&gt;&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Chromium setup&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;/usr/local/bin/chromium --ssl-version-max=tls1.3 --ssl-key-log-file=/tmp/sslkeylog.log
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(it will be more convenient to specify alias for your shell)&lt;/p&gt;

&lt;h3&gt;Wireshark setup&lt;/h3&gt;

&lt;p&gt;Go to &lt;tt&gt;Preferences &amp;gt; Protocols &amp;gt; TLS&lt;/tt&gt;, specify the path to the file:&lt;/p&gt;

&lt;p&gt;&lt;img src="/media/uploads/wireshark-tls.png" alt="wireshark-tls-settings.png" /&gt;&lt;/p&gt;

&lt;p&gt;As a result, you will be able to see the decrypted data:&lt;/p&gt;

&lt;p&gt;&lt;img src="/media/uploads/wireshark-ssl.png" alt="wireshark-ssl.png" /&gt;&lt;/p&gt;
</content></entry><entry><title>Simple healthcheck to Kafka for docker-compose
</title><link href="https://adw0rd.com/2020/11/25/kafka-healthcheck-by-topic/en/" rel="alternate"></link><published>2020-11-25T12:36:26+03:00</published><id>https://adw0rd.com/2020/11/25/kafka-healthcheck-by-topic/en/</id><summary type="html">version: "2.1" services: kafka: image: 'bitnami/kafka:latest' ports: - '9092:9092' - '9093:9093' environment: - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 - ALLOW_PLAINTEXT_LISTENER=yes - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CLIENT:PLAINTEXT,EXTERNAL:PLAINTEXT - KAFKA_CFG_LISTENERS=CLIENT://:9093,EXTERNAL://:9092 - KAFKA_CFG_ADVERTISED_LISTENERS=CLIENT://kafka:9093,EXTERNAL://localhost:9092 - KAFKA_INTER_BROKER_LISTENER_NAME=CLIENT depends_on: - zookeeper healthcheck: test: ["CMD-SHELL", "kafka-topics.sh --bootstrap-server 127.0.0.1:9092 --topic &amp;lt;TOPIC_NAME&amp;gt; --describe"] interval: 2s timeout: 2s retries: 15 someservice: image: ... depends_on: kafka: condition: service_healthy links:…
</summary><content type="html" xml:base="https://adw0rd.com/2020/11/25/kafka-healthcheck-by-topic/en/">&lt;pre&gt;&lt;code&gt;version: "2.1"

services:
  kafka:
    image: 'bitnami/kafka:latest'
    ports:
      - '9092:9092'
      - '9093:9093'
    environment:
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - ALLOW_PLAINTEXT_LISTENER=yes
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CLIENT:PLAINTEXT,EXTERNAL:PLAINTEXT
      - KAFKA_CFG_LISTENERS=CLIENT://:9093,EXTERNAL://:9092
      - KAFKA_CFG_ADVERTISED_LISTENERS=CLIENT://kafka:9093,EXTERNAL://localhost:9092
      - KAFKA_INTER_BROKER_LISTENER_NAME=CLIENT
    depends_on:
      - zookeeper
    healthcheck:
      test: ["CMD-SHELL", "kafka-topics.sh --bootstrap-server 127.0.0.1:9092 --topic &amp;lt;TOPIC_NAME&amp;gt; --describe"]
      interval: 2s
      timeout: 2s
      retries: 15

  someservice:
    image: ...
    depends_on:
      kafka:
        condition: service_healthy
    links:
      - kafka
    command: ['...']
&lt;/code&gt;&lt;/pre&gt;
</content></entry><entry><title>Denial of cybercrime
</title><link href="https://adw0rd.com/2018/12/13/refute/en/" rel="alternate"></link><published>2018-12-13T11:42:11+03:00</published><id>https://adw0rd.com/2018/12/13/refute/en/</id><summary type="html">Photo from the wikipedia Some time ago, my name began to be mentioned in the media, pointing to my involvement in illegal actions, to which I have no relation. I am always aware of what I'm doing. I have never done, not doing now and do not plan to do…
</summary><content type="html" xml:base="https://adw0rd.com/2018/12/13/refute/en/">&lt;div style="float:right;text-align:right""&gt;
&lt;img src="/media/uploads/fbi.svg" width="150"&gt;&lt;br&gt;
&lt;small&gt;Photo from &lt;a rel="nofollow" href="https://en.wikipedia.org/wiki/Federal_Bureau_of_Investigation"&gt;the wikipedia&lt;/a&gt;&lt;/small&gt;
&lt;/div&gt;

&lt;p&gt;Some time ago, my name began to be mentioned in the media, pointing to my involvement in illegal actions, to which I have no relation. I am always aware of what I'm doing. I have never done, not doing now and do not plan to do in the future anything illegal. This can be confirmed by everyone whom I have ever worked or communicated.&lt;/p&gt;

&lt;blockquote class="info"&gt;
&lt;b&gt;Disclaimer:&lt;/b&gt; The article that you see is an inaccurate translation of the &lt;a rel="nofollow" href="https://adw0rd.com/2018/12/13/refute/"&gt;original article&lt;/a&gt; and is for reference only. The translation was not performed by a professional and may not coincide in meaning with the original article.
&lt;/blockquote&gt;

&lt;p&gt;&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please &lt;strong&gt;refute&lt;/strong&gt; in the media (such as  &lt;a rel="nofollow" href="https://www.buzzfeednews.com/article/craigsilverman/who-ran-methbot-3ve-ad-fraud"&gt;BuzzFeed&lt;/a&gt;, &lt;a rel="nofollow" href="https://krebsonsecurity.com/2016/12/report-3-5m-in-ad-fraud-daily-from-methbot/#more-37299"&gt;Krebs on Security&lt;/a&gt;, &lt;a rel="nofollow" href="https://www.forbes.com/sites/daveywinder/2018/11/28/how-russian-pornhub-hackers-pulled-off-30m-advertising-scam/"&gt;Forbes&lt;/a&gt;) due to &lt;strong&gt;erroneous or unreasonable&lt;/strong&gt; including me on the list of those accused of violating the law.&lt;/p&gt;

&lt;p&gt;I ask the FBI to remove my name from the list of suspects, since I have never taken any illegal actions (described &lt;a rel="nofollow" href="https://www.justice.gov/usao-edny/pr/two-international-cybercriminal-rings-dismantled-and-eight-defendants-indicted-causing"&gt;in the document&lt;/a&gt; or any others) &lt;strong&gt;did not commit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In 2016, I already responded to such accusations by the &lt;a rel="nofollow" href="https://krebsonsecurity.com/2016/12/report-3-5m-in-ad-fraud-daily-from-methbot/#more-37299"&gt;Krebs on Security&lt;/a&gt;, gave an interview to &lt;a rel="nofollow" href="https://republic.ru/posts/77732"&gt;The Republic&lt;/a&gt; magazine with a refutation of any illegal activity on my part. I attach to this article screenshots of correspondence with the journalist of the &lt;strong&gt;The Republic&lt;/strong&gt; edition:&lt;/p&gt;

&lt;div style="float:left;margin-right:20px"&gt;&lt;img src="/media/uploads/1_NDiH2gU.PNG" width="300"&gt;&lt;/div&gt;

&lt;div&gt;&lt;img src="/media/uploads/2_e8WSbpJ.PNG" width="300"&gt;&lt;/div&gt;

&lt;div style="float:left;margin-right:20px"&gt;&lt;img src="/media/uploads/3_rLYsx3B.PNG" width="300"&gt;&lt;/div&gt;

&lt;div&gt;&lt;img src="/media/uploads/4_fdYElQD.PNG" width="300"&gt;&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;In addition to the above, I want to write a few more words about myself: I lead an open public lifestyle, play sports and skateboarding, work as an outsourcer programmer, my direction is developing web applications on Python, Erlang and JavaScript, data analysis and consulting services. In my free time &lt;a rel="nofollow" href="https://adw0rd.com/"&gt;I keep a technical blog&lt;/a&gt;. I am outgoing, positive and law-abiding person. Any illegal activity for me is rejected by nature of me.&lt;/p&gt;

&lt;p&gt;I am sure that people and organizations that have access to all my personal, confidential information and are engaged in this investigation - can easily make sure that I am &lt;strong&gt;innocent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.:&lt;/strong&gt; I have great respect for the profession of a reporter, but please do not disturb me on the above issue, because I can not add anything else to this.&lt;/p&gt;

&lt;p&gt;Regards, Mikhail Andreev.&lt;/p&gt;
</content></entry><entry><title>Mount Google Drive drive through gdfs on Ubuntu 17.04
</title><link href="https://adw0rd.com/2017/12/29/google-drive-ubuntu-gdfs/en/" rel="alternate"></link><published>2017-12-29T10:28:12+03:00</published><id>https://adw0rd.com/2017/12/29/google-drive-ubuntu-gdfs/en/</id><summary type="html">I use Google Drive to store backups on some of my servers, but I can invent many scenarios for using this cloud storage. To do this, we will need to install the client library to work with the Google API, the gdfs driver, get the authorization code and configure the…
</summary><content type="html" xml:base="https://adw0rd.com/2017/12/29/google-drive-ubuntu-gdfs/en/">&lt;p&gt;I use Google Drive to store backups on some of my servers, but I can invent many scenarios for using this cloud storage.&lt;/p&gt;

&lt;p&gt;To do this, we will need to install the client library to work with the Google API, the gdfs driver, get the authorization code and configure the automatic mount when the server boots.&lt;/p&gt;

&lt;p&gt;&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Install the Google Client API&lt;/h3&gt;

&lt;p&gt;The client is needed to authorize gdfs&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt install -y python-pip
git clone https://github.com/google/google-api-python-client
cd google-api-python-client
sudo python setup.py install install_egg_info
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Install Google Drive FS&lt;/h3&gt;

&lt;p&gt;Install gdrivefs and make a symlink for convenience&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo pip install gdrivefs
cd /sbin
sudo ln -s `which gdfs` mount.gdfs
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Customization&lt;/h3&gt;

&lt;p&gt;You need to authenticate to the Google API Client and create a directory to mount the drive&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gdfstool auth -u
# Open the link in your browser, please log in
# and copy the received key as &amp;lt;code&amp;gt;
gdfstool auth -a /var/.gdfs.creds "&amp;lt;code&amp;gt;"
mkdir /mnt/gdrivefs
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Mounting through /etc/fstab&lt;/h3&gt;

&lt;p&gt;You can add the following entry to &lt;tt&gt;/etc/fstab&lt;/tt&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo "/var/.gdfs.creds/mnt/gdrivefs gdfs allow_other, big_writes 0 0" &amp;gt;&amp;gt; /etc/fstab
mount /mnt/gdrivefs
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But the mount takes place before the network connection of the server, and without the network you can not connect Google Drive, so after rebooting the server you will have problems with the mount. You can add the option _netdev:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo "/var/.gdfs.creds/mnt/gdrivefs gdfs allow_other,big_writes,_netdev 0 0" &amp;gt;&amp;gt; /etc/fstab
mount /mnt/gdrivefs
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But I could not use this option:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fuse: unknown option "_netdev"
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Mounting through /etc/network/interfaces&lt;/h3&gt;

&lt;p&gt;I mount the disk in the following way&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo "post-up /bin/mount/var/.gdfs.creds/mnt/gdrivefs -t gdfs -o allow_other,big_writes" &amp;gt;&amp;gt; /etc/network/interfaces
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After rebooting the server, you will start post-up and mount the disk.&lt;/p&gt;

&lt;h3&gt;Checking&lt;/h3&gt;

&lt;p&gt;We will mount it manually and look at the files:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mount /var/.gdfs.creds /mnt/gdrivefs -t gdfs -o allow_other,big_writes
ls -la /mnt/gdrivefs
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I recommend that you reboot and check that everything works.&lt;/p&gt;
</content></entry><entry><title>Erlang. Fix run multiple copies of epmd
</title><link href="https://adw0rd.com/2013/02/11/erlang-epmd-pang/en/" rel="alternate"></link><published>2013-02-11T11:50:50+04:00</published><id>https://adw0rd.com/2013/02/11/erlang-epmd-pang/en/</id><summary type="html">Faced with the problem when you do not ping the erlang-node on some server that is running two epmd. And running two of them, because one runs the project (at the start erl), and the second starts ejabberd. Symptoms resemble a problem with firewall: (test2@127.0.0.1)1&amp;gt; net_adm:ping('test1@127.0.0.1'). pang See ps ax:…
</summary><content type="html" xml:base="https://adw0rd.com/2013/02/11/erlang-epmd-pang/en/">&lt;p&gt;&lt;img src="http://adw0rd.com/media/uploads/erlang_30.png" class="alignright whitespace" /&gt;&lt;/p&gt;

&lt;p&gt;Faced with the problem when you do not ping the erlang-node on some server that is running two &lt;strong&gt;epmd&lt;/strong&gt;. And running two of them, because one runs the project (at the start &lt;tt&gt;erl&lt;/tt&gt;), and the second starts &lt;strong&gt;ejabberd&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Symptoms resemble a problem with &lt;strong&gt;firewall&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(test2@127.0.0.1)1&amp;gt; net_adm:ping('test1@127.0.0.1').
pang
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See &lt;tt&gt;ps ax&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ps ax | grep epmd
root     1212   ... /usr/local/lib/erlang/erts-5.9.3.1/bin/epmd -daemon
root     1515   ... /usr/local/bin/epmd -daemon
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And if you execute &lt;tt&gt;kill 1212 1515&lt;/tt&gt; and run again &lt;strong&gt;erl&lt;/strong&gt;, it will be pinged:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(test2@127.0.0.1)1&amp;gt; net_adm:ping('test1@127.0.0.1').
pong
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Additional symptoms I described on &lt;a rel="nofollow" href="http://stackoverflow.com/questions/14389573/erlang-one-of-two-nodes-is-not-ping-in-first-time-after-ping-from-second-node"&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Solution&lt;/h3&gt;

&lt;p&gt;Open for editing &lt;tt&gt;/etc/rc.conf&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ejabberd_enable="YES"
epmd_enable="YES"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And in &lt;tt&gt;/usr/local/etc/rc.d/epmd&lt;/tt&gt; adding:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;start_precmd=epmd_prestart
epmd_prestart() {
    `ps ax | grep epmd | awk '{ print $1}' | xargs kill`
    return 0
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We have to use a hack, because I could not find how to get &lt;strong&gt;ejabberd&lt;/strong&gt; not to launch &lt;strong&gt;epmd&lt;/strong&gt;.&lt;/p&gt;
</content></entry><entry><title>Fast resize and caching of images with "django-nginx-image"
</title><link href="https://adw0rd.com/2012/11/10/django-nginx-image/en/" rel="alternate"></link><published>2012-11-10T09:26:01+04:00</published><id>https://adw0rd.com/2012/11/10/django-nginx-image/en/</id><summary type="html">For a project KinsburgTV I had to do resize images. At first I copied from one of my projects a template tag for resizing (taking roots from this snippet), but for production it is very slow solution. So I wrote another template tag, which built correct URL for Nginx, and…
</summary><content type="html" xml:base="https://adw0rd.com/2012/11/10/django-nginx-image/en/">&lt;p&gt;&lt;img src="http://adw0rd.com/media/uploads/django_nginx_image.jpg" class="alignright whitespace" /&gt;&lt;/p&gt;

&lt;p&gt;For a project &lt;a rel="nofollow" href="http://adw0rd.com/2012/kinsburgtv/en/"&gt;KinsburgTV&lt;/a&gt; I had to do resize images. At first I copied from one of my projects a template tag for resizing (taking roots from &lt;a rel="nofollow" href="http://djangosnippets.org/snippets/1944/"&gt;this snippet&lt;/a&gt;), but for production it is very slow solution. So I wrote another template tag, which built correct URL for Nginx, and this URL handled in &lt;a rel="nofollow" href="http://nginx.org/en/docs/http/ngx_http_image_filter_module.html"&gt;ngx_http_image_filter_module&lt;/a&gt; and &lt;a rel="nofollow" href="http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache"&gt;proxy_cache&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I have a chart for comparison, which I did through &lt;strong&gt;JMeter&lt;/strong&gt;, but it was not informative for me. If anyone interested, &lt;a rel="nofollow" href="http://adw0rd.com/media/uploads/JMeterAggregateGraph.png"&gt;here's the chart&lt;/a&gt;. At the left side is &lt;strong&gt;PIL&lt;/strong&gt;, at the right side &lt;strong&gt;Nginx&lt;/strong&gt;. Select for 1000 requests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Obtained a faster, transparent for applications a resizer and cropper, with caching results. And command for convert images to supported format. So, meet &lt;a rel="nofollow" href="https://github.com/adw0rd/django-nginx-image"&gt;django-nginx-image&lt;/a&gt;!&lt;br /&gt;
&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Installation and settings&lt;/h3&gt;

&lt;p&gt;Install from &lt;a rel="nofollow" href="http://pypi.python.org/pypi/django-nginx-image/"&gt;PyPI&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pip install django-nginx-image
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, you should setup &lt;strong&gt;Nginx&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;&amp;lt;STORAGE_ROOT&amp;gt;&lt;/tt&gt; - a path to "media/statiс" directories (example "/storage/kinsburg_tv");&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;&amp;lt;CACHE_NAME&amp;gt;&lt;/tt&gt; - arbitrarily name for cache (example "kinsburg_tv_thumbnails_cache").&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;&lt;code&gt;
http {

    # Specify a desired path to cache directory, name of cache and maximum size of cache
    proxy_cache_path &amp;lt;STORAGE_ROOT&amp;gt;/nginx/cache levels=1:2 keys_zone=&amp;lt;CACHE_NAME&amp;gt;:10m max_size=1G;

    # Now, you must setup a "server", which will cache results
    server {
        listen 80;
        server_name www.example.org;

        location ~* ^/(resize|crop)/ {
            proxy_pass http://image.example.org$request_uri;
            proxy_cache &amp;lt;CACHE_NAME&amp;gt;;
            proxy_cache_key "$host$document_uri";
            proxy_cache_valid 200 1d;
            proxy_cache_valid any 1m;
            proxy_cache_use_stale error timeout invalid_header updating;
        }
    }

    # And a second "server", which will be resize and crop
    server {
        listen 80;
        server_name image.example.org;

        location ~* ^/resize/([\d\-]+)/([\d\-]+)/(.+)$ {
            alias &amp;lt;STORAGE_ROOT&amp;gt;/$3;
            image_filter resize $1 $2;
            image_filter_buffer 2M;
            error_page 415 = /empty;
        }

        location ~* ^/crop/([\d\-]+)/([\d\-]+)/(.+)$ {
            alias &amp;lt;STORAGE_ROOT&amp;gt;/$3;
            image_filter crop $1 $2;
            image_filter_buffer 2M;
            error_page 415 = /empty;
        }

        location = /empty {
            empty_gif;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you have no need for caching, then simply remove a location from the first "server" and move locations from the second section "server" in the the first. Caching is increased performance to 10-20%.&lt;/p&gt;

&lt;p&gt;Then add to &lt;tt&gt;settings.py&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
INSTALLED_APPS = (
    'nginx_image',
)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Scheme to illustrate the work&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://adw0rd.com/media/uploads/django-nginx-image.jpg" alt="scheme to illustrate the work" /&gt;&lt;/p&gt;

&lt;h3&gt;Usage&lt;/h3&gt;

&lt;p&gt;In any of your templates, plug in the module &lt;tt&gt;nginx_image&lt;/tt&gt; with the template tag &lt;tt&gt;thumbnail&lt;/tt&gt;, give to tag a &lt;strong&gt;path to image&lt;/strong&gt; , &lt;strong&gt;width&lt;/strong&gt;, &lt;strong&gt;height&lt;/strong&gt; and optional flag &lt;strong&gt;crop&lt;/strong&gt; to crop the image, not resize:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
{% load nginx_image %}

Proportionally resize a image, based on the width and the height:
    &amp;lt;img src="{% thumbnail user.profile.avatar 130 130 %}" /&amp;gt;

Proportionally resize a image, based on the width:
    &amp;lt;img src="{% thumbnail user.profile.avatar 130 '-' %}" /&amp;gt;
    &amp;lt;img src="{% thumbnail user.profile.avatar 130 0 %}" /&amp;gt;
    &amp;lt;img src="{% thumbnail user.profile.avatar 130 %}" /&amp;gt;

Proportionally resize a image, based on the height:
    &amp;lt;img src="{% thumbnail user.profile.avatar '-' 130 %}" /&amp;gt;
    &amp;lt;img src="{% thumbnail user.profile.avatar 0 130 %}" /&amp;gt;

Crop a image:
    &amp;lt;img src="{% thumbnail user.profile.avatar 130 130 crop=1 %}" /&amp;gt;
    &amp;lt;img src="{% thumbnail user.profile.avatar 130 0 crop=1 %}" /&amp;gt;
    &amp;lt;img src="{% thumbnail user.profile.avatar 0 130 crop=1 %}" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In general, this tag only generates &lt;strong&gt;URL&lt;/strong&gt; like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/resize/130/-/media/users/avatars/12345.jpg&lt;/li&gt;
&lt;li&gt;/resize/-/130/media/users/avatars/12345.jpg&lt;/li&gt;
&lt;li&gt;/crop/130/-/media/users/avatars/12345.jpg&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tag can be used outside a template, for example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
class Film(models.Model):
    thumbnail = models.ImageField(upload_to='films/thumbnails', null=True)

    def thumbnail_preview_url(self):
        from nginx_image.templatetags.nginx_image import thumbnail
        return thumbnail(self.thumbnail, 160, 140, crop=True)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;The command nginx_image_converter&lt;/h3&gt;

&lt;p&gt;Unfortunately (or fortunately), &lt;a rel="nofollow" href="http://nginx.org/en/docs/http/ngx_http_image_filter_module.html"&gt;ngx_http_image_filter_module&lt;/a&gt; only supports JPEG, GIF and PNG, so I had to write a converter that converts the formats other than the above to &lt;strong&gt;JPEG&lt;/strong&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;./manage.py nginx_image_converter -i /storage/project/media -o /storage/project/newmedia
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Additional options for this command you can see &lt;a rel="nofollow" href="https://github.com/adw0rd/django-nginx-image#convert"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;The problem with Nginx resolver&lt;/h4&gt;

&lt;p&gt;If you found a bug in &lt;tt&gt;nginx/error.log&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;... no resolver defined to resolve image.example.org ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;then setup &lt;a rel="nofollow" href="http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver"&gt;resolver&lt;/a&gt; in &lt;tt&gt;nginx/nginx.conf&lt;/tt&gt;, example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;resolver 127.0.0.1 8.8.8.8;
&lt;/code&gt;&lt;/pre&gt;
</content></entry><entry><title>Nice to meet, KinsburgTV!
</title><link href="https://adw0rd.com/2012/09/29/kinsburgtv/en/" rel="alternate"></link><published>2012-09-29T18:00:43+04:00</published><id>https://adw0rd.com/2012/09/29/kinsburgtv/en/</id><summary type="html">Passed three years since the launch of the first version, and two years with the second. The new major release is available on the new domain kinsburg.tv, so I decided not to disconnect the old site, and develop a new site as parallel. The new project is written in Python…
</summary><content type="html" xml:base="https://adw0rd.com/2012/09/29/kinsburgtv/en/">&lt;p&gt;&lt;a rel="nofollow" href="http://kinsburg.tv"&gt;&lt;img src="http://adw0rd.com/media/uploads/logo_black_.png" alt="KinsburgTV logotype" class="alignright whitespace" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Passed three years since the launch of the &lt;a rel="nofollow" href="http://adw0rd.com/2009/kinsburg/"&gt;first version&lt;/a&gt;, and two years with the &lt;a rel="nofollow" href="http://adw0rd.com/2010/kinsburg-year-later/"&gt;second&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The new major release is available on the new domain &lt;a rel="nofollow" href="http://kinsburg.tv/"&gt;kinsburg.tv&lt;/a&gt;, so I decided not to disconnect the old site, and develop a new site as parallel.&lt;/p&gt;

&lt;p&gt;The new project is written in &lt;strong&gt;Python&lt;/strong&gt; and &lt;strong&gt;Django&lt;/strong&gt;, also under the hood are &lt;strong&gt;Nginx+uwsgi&lt;/strong&gt;, &lt;strong&gt;Scrapy&lt;/strong&gt;, &lt;strong&gt;MySQL&lt;/strong&gt;, &lt;strong&gt;SphinxSearch&lt;/strong&gt;, &lt;strong&gt;Redis&lt;/strong&gt;, &lt;strong&gt;Celery&lt;/strong&gt;, and to deploy and support the project using &lt;a rel="nofollow" href="http://adw0rd.com/2012/python-virtualenv/"&gt;virtualenv&lt;/a&gt;, &lt;a rel="nofollow" href="http://adw0rd.com/2012/python-supervisor/"&gt;supervisor&lt;/a&gt;, &lt;strong&gt;South&lt;/strong&gt; and &lt;a rel="nofollow" href="http://adw0rd.com/2012/python-fabric/"&gt;Fabric&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The project is rewritten, because I'm in the last 3 years have been programming using Python and Django. Maintain and develop features for PHP was too expensive, so I decided to rewrite everything in Python.&lt;br /&gt;
&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;New features&lt;/h2&gt;

&lt;p&gt;&lt;a rel="nofollow" href="http://adw0rd.com/media/uploads/one_of_the_many_pages.png"&gt;&lt;img class="alignright whitespace" width="250" src="http://adw0rd.com/media/uploads/one_of_the_many_pages_.jpg" alt="ScreenShot" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Appeared English interface!&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The new filter&lt;/strong&gt; (with sorting and searching) without reloading the page. Looking well, in addition to text, there is a search for the mask.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;New bookmarking service&lt;/strong&gt; with the ability to create your own types of bookmarks:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;Also has the ability to move, delete and copy bookmarks;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Architecture provides an opportunity to put in a bookmark any objects (thanks to "django.contrib.contenttypes"), and not only films (but now the bookmarks are only for films).&lt;/li&gt;&lt;br /&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Film companies and countries&lt;/strong&gt; are now clickable:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;Now, there are few published film companies, but they will be added gradually through Scrapy;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Countries were not represented in the menu, but you can get it from the film page.&lt;/li&gt;&lt;br /&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blogs&lt;/strong&gt; about movies, movie stars and film companies:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;Blogs yet taken only from the site &lt;a rel="nofollow" href="http://www.spletnik.ru/"&gt;www.spletnik.ru&lt;/a&gt; and only themes about movies, of course.&lt;/li&gt;&lt;br /&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Film reviews&lt;/strong&gt;:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;While reviews are taken from &lt;a rel="nofollow" href="http://kinopoisk.ru/"&gt;Kinopoisk&lt;/a&gt;, but also has a manual entry of reviews completed yet and will soon be published and user-friendly interface to writing reviews.&lt;/li&gt;&lt;br /&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Appeared the &lt;strong&gt;authorization through social networks&lt;/strong&gt;! I decided that now is relevant only &lt;strong&gt;Facebook&lt;/strong&gt;, &lt;strong&gt;Vkontake&lt;/strong&gt; and &lt;strong&gt;Twitter&lt;/strong&gt;. I'm thinking about adding Google, Yandex and OpenID, but am not sure that this is true. Authorization is implemented using nice library &lt;a rel="nofollow" href="https://github.com/adw0rd/django-social-auth"&gt;django-social-auth&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the project also helped me &lt;a rel="nofollow" href="http://kilgoretrout.ru/"&gt;mouellke&lt;/a&gt;. She did a good design for the entire site! Thank her so much!&lt;/p&gt;

&lt;p&gt;Visit &lt;a rel="nofollow" href="http://kinsburg.tv/"&gt;KinsburgTV&lt;/a&gt; right now!&lt;/p&gt;
</content></entry><entry><title>Released a pluggable application "django-sql-stacktrace"
</title><link href="https://adw0rd.com/2012/08/23/django-sql-stacktrace/en/" rel="alternate"></link><published>2012-08-23T17:16:18+04:00</published><id>https://adw0rd.com/2012/08/23/django-sql-stacktrace/en/</id><summary type="html">This application is puts python stack trace to a SQL-query as comment. It's useful when you is debugging your project, when you see many SQL-queries and do not understand where these queries were launched. PyPI: django-sql-stacktrace For example, you have come to a new project and you have been asked…
</summary><content type="html" xml:base="https://adw0rd.com/2012/08/23/django-sql-stacktrace/en/">&lt;p&gt;&lt;img src="http://adw0rd.com/media/2009/11/Djangologo.gif" alt="" title="Released a pluggable application django-sql-stacktrace" width="125" height="50" class="alignright size-full wp-image-4834" /&gt;&lt;/p&gt;

&lt;p&gt;This application is puts python stack trace to a SQL-query as comment. It's useful when you is debugging your project, when you see many SQL-queries and do not understand where these queries were launched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PyPI:&lt;/strong&gt; &lt;a rel="nofollow" href="http://pypi.python.org/pypi/django-sql-stacktrace/"&gt;django-sql-stacktrace&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, you have come to a new project and you have been asked to deal with a lot of SQL-queries that hang at run time. You look at the "processlist" and see a lot of different SQL-queries:&lt;/p&gt;

&lt;p&gt;&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
...

SELECT COUNT(*) FROM `films_film` INNER JOIN `films_year` ON (`films_film`.`year_id` = 
`films_year`.`id`) WHERE (`films_film`.`status` = 'published' AND `films_year`.`id` IS NOT NULL);

SELECT `blogs_post`.`id`, `blogs_post`.`blog_id`, `blogs_post`.`title`, `blogs_post`.`slug`, 
`blogs_post`.`status`, `blogs_post`.`created`, `blogs_post`.`updated`, 
`blogs_post`.`published`, `blogs_post`.`description`, `blogs_post`.`thumbnail`, 
`blogs_post`.`content`, `blogs_post`.`count_of_views`, `blogs_post`.`source_content`, 
`blogs_post`.`source_published`, `blogs_post`.`source_count_views`, 
`blogs_post`.`source_author_of_content`, `blogs_post`.`source_author_of_photo`, 
`blogs_post`.`source_keywords`, `blogs_post`.`source_url` FROM `blogs_post` WHERE 
`blogs_post`.`status` = 'published' ORDER BY `blogs_post`.`published` DESC LIMIT 4;

SELECT `social_auth_usersocialauth`.`id`, `social_auth_usersocialauth`.`user_id`, 
`social_auth_usersocialauth`.`provider`, `social_auth_usersocialauth`.`uid`, 
`social_auth_usersocialauth`.`extra_data` FROM `social_auth_usersocialauth` WHERE 
`social_auth_usersocialauth`.`user_id` = 42;

SELECT `films_film`.`id`, `films_film`.`status`, `films_film`.`created`, `films_film`.`updated`, 
`films_film`.`published`, `films_film`.`title_original`, `films_film`.`title_ru`, `films_film`.`slug`, 
`films_film`.`thumbnail`, `films_film`.`slogan`, `films_film`.`description`, 
`films_film`.`date_premiere`, `films_film`.`year_id`, `films_film`.`rating_votes`, 
`films_film`.`rating_score`, `films_film`.`rating_score_with_vote_weight`, `films_year`.`id`, 
`films_year`.`name`, `films_year`.`count`, `films_year`.`size` FROM `films_film` LEFT OUTER 
JOIN `films_year` ON (`films_film`.`year_id` = `films_year`.`id`) WHERE (`films_film`.`status` 
= 'published'  AND `films_year`.`id` IS NOT NULL) ORDER BY `films_film`.`published` DESC 
LIMIT 30;

...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Where did they run you do not know, moreover, it is not only the queries from views, it may also be sql-queries from the django commands, something daemons, etc.&lt;/p&gt;

&lt;p&gt;No problem! You take &lt;tt&gt;django-sql-stacktrace&lt;/tt&gt;, run on a local copy of the project and see the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
...

SELECT COUNT(*) FROM `films_film` INNER JOIN `films_year` ON (`films_film`.`year_id` = `films_year`.`id`)
WHERE (`films_film`.`status` = 'published' AND `films_year`.`id` IS NOT NULL)
/* STACKTRACE: 
&gt; File "/home/adw0rd/work/kinsburg_tv/kinsburg_tv/common/views.py", line 27, in get_context_data
&gt; context = super(MainPage, self).get_context_data(**kwargs)

STACKTRACE: 
&gt; File "/home/adw0rd/work/kinsburg_tv/kinsburg_tv/films/mixins.py", line 14, in get_context_data
&gt; context = super(FilmsMixin, self).get_context_data(**kwargs)

STACKTRACE: 
&gt; File "/home/adw0rd/work/kinsburg_tv/venv/local/lib/python2.7/site-packages/django/db/models/query.py", line 351, in count
&gt; return self.query.get_count(using=self.db)

STACKTRACE: 
&gt; File "/home/adw0rd/work/kinsburg_tv/venv/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 418, in get_count
&gt; number = obj.get_aggregation(using=using)[None]

STACKTRACE: 
&gt; File "/home/adw0rd/work/kinsburg_tv/venv/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 384, in get_aggregation
&gt; result = query.get_compiler(using).execute_sql(SINGLE)

STACKTRACE: 
&gt; File "/home/adw0rd/work/kinsburg_tv/venv/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 818, in execute_sql
&gt; cursor.execute(sql, params)

STACKTRACE: 
&gt; File "/home/adw0rd/work/kinsburg_tv/venv/local/lib/python2.7/site-packages/sqlstacktrace/stacktracecursor.py", line 16, in execute
&gt; stacks = get_stacktrace()

STACKTRACE: 
&gt; File "/home/adw0rd/work/kinsburg_tv/venv/local/lib/python2.7/site-packages/sqlstacktrace/stacktrace.py", line 93, in get_stacktrace
&gt; stack = get_stack()
*/;

...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Good job! Now you know where these queries were launched and has something to do with this problem.&lt;/p&gt;

&lt;h3&gt;Installation and configuration&lt;/h3&gt;

&lt;p&gt;Install from &lt;a rel="nofollow" href="http://pypi.python.org/pypi/django-sql-stacktrace/"&gt;PyPI&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pip install django-sql-stacktrace
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or install the dev-version from &lt;strong&gt;GitHub&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pip install -e git://github.com/adw0rd/django-sql-stacktrace.git#egg=sqlstacktrace
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, add to "INSTALLED_APPS":&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;INSTALLED_APPS = (
    ...
    'sqlstacktrace',
    ...
)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And turn on the &lt;tt&gt;SQL_STACKTRACE&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;SQL_STACKTRACE = True
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Getting code&lt;/h3&gt;

&lt;p&gt;You can get &lt;tt&gt;django-sql-stacktrace&lt;/tt&gt; from &lt;a rel="nofollow" href="https://github.com/adw0rd/django-sql-stacktrace"&gt;https://github.com/adw0rd/django-sql-stacktrace&lt;/a&gt;. The application is distributed by BSD license.&lt;/p&gt;
</content></entry><entry><title>The "django-lictor" for Django Dash 2012
</title><link href="https://adw0rd.com/2012/08/21/django-lictor/en/" rel="alternate"></link><published>2012-08-21T17:16:58+04:00</published><id>https://adw0rd.com/2012/08/21/django-lictor/en/</id><summary type="html">Hello everybody, at weekend we participated in the Django Dash 2012, and we made an application to visualize your projects via stack trace. What is "lictor"? The lictor (possibly from Latin: ligare, "to bind") was a member of a special class of Roman civil servant, with special tasks of attending…
</summary><content type="html" xml:base="https://adw0rd.com/2012/08/21/django-lictor/en/">&lt;p&gt;&lt;img src="http://adw0rd.com/media/uploads/lictor_.jpg" class="alignright" /&gt;&lt;/p&gt;

&lt;p&gt;Hello everybody, at weekend we participated in the &lt;a rel="nofollow" href="http://www.djangodash.com/"&gt;Django Dash 2012&lt;/a&gt;, and we made an application to visualize your projects via stack trace.&lt;/p&gt;

&lt;h3&gt;What is "lictor"?&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;The &lt;strong&gt;lictor&lt;/strong&gt; (possibly from Latin: ligare, "to bind") was a member of a special class of Roman civil servant, with special tasks of attending and guarding magistrates of the Roman Republic and Empire who held imperium, the right and power to command; essentially, a bodyguard. The origin of the tradition of lictors goes back to the time when Rome was a kingdom, perhaps acquired from their Etruscan neighbours.&lt;br/&gt;&lt;br /&gt;
  &lt;a rel="nofollow" href="http://en.wikipedia.org/wiki/Lictors"&gt;http://en.wikipedia.org/wiki/Lictors&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Team&lt;/h3&gt;

&lt;p&gt;Our &lt;a rel="nofollow" href="http://www.djangodash.com/teams/c3/tetronix/"&gt;team&lt;/a&gt; was called &lt;strong&gt;Tetronix&lt;/strong&gt; and included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Oleg Grigoriev (&lt;a rel="nofollow" href="http://blgo.ru/blog/"&gt;vasa-c&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Mikhail Andreev (adw0rd)&lt;/li&gt;
&lt;li&gt;Boris Timokhin (&lt;a rel="nofollow" href="http://mathete.com/"&gt;mathete&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We did in amount 132 commits, but was not enough time to finish the project.&lt;/p&gt;

&lt;h3&gt;Demostration&lt;/h3&gt;

&lt;p&gt;You can see the demo on page &lt;a rel="nofollow" href="http://lictor.tetronix.org/"&gt;http://lictor.tetronix.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="color:gray"&gt;Unfortunately, I can't create screencast in Linux (xUbuntu), please suggest a program for it!&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a rel="nofollow" href="http://adw0rd.com/media/uploads/lictor.png"&gt;&lt;img src="http://adw0rd.com/media/uploads/lictor_thumbnail.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's open source and you can get a code from &lt;a rel="nofollow" href="https://github.com/ussi/django-lictor"&gt;https://github.com/ussi/django-lictor&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;What's next?&lt;/h3&gt;

&lt;p&gt;Since "django-lictor" is part of the idea of ​​visualization Django-projects, then my next step will be the appearance of the application [django-visualization](https://github.com/adw0rd/django-visualization, which will render the whole project, not just the call stack.&lt;/p&gt;

&lt;p&gt;While planning to use AST, source code of "django-lictor" will be used to visualize the stack trace built tree project.&lt;/p&gt;

&lt;p&gt;Also the opportunity to create a task, review, etc.&lt;/p&gt;
</content></entry><entry><title>jQuery. Wrote a plugin "jquery-cleverfocus"
</title><link href="https://adw0rd.com/2012/03/01/jquery-cleverfocus/en/" rel="alternate"></link><published>2012-03-01T15:01:15+04:00</published><id>https://adw0rd.com/2012/03/01/jquery-cleverfocus/en/</id><summary type="html">Today, I released a plugin for jQuery, which, when you enter a some text in "nowhere" intercepts it, and at the expiration of the limit entered symbols - write collected symbols to you specified "input" and puts a "focus". A plugin is compability with the jQuery 1.7.1, because it has…
</summary><content type="html" xml:base="https://adw0rd.com/2012/03/01/jquery-cleverfocus/en/">&lt;p&gt;&lt;img src="/media/2012/03/jquery-cleverfocus-min.png" class="alignright" /&gt;&lt;/p&gt;

&lt;p&gt;Today, I released a plugin for &lt;strong&gt;jQuery&lt;/strong&gt;, which, when you enter a some text in "nowhere" intercepts it, and at the expiration of the limit entered symbols - write collected symbols to you specified "input" and puts a "focus".&lt;/p&gt;

&lt;p&gt;A plugin is compability with the &lt;strong&gt;jQuery 1.7.1&lt;/strong&gt;, because it has only been tested.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a rel="nofollow" href="https://github.com/adw0rd/jquery-cleverfocus"&gt;Source code on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" href="http://adw0rd.github.com/jquery-cleverfocus/"&gt;Demo on adw0rd.github.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Use cases&lt;/h3&gt;

&lt;h5&gt;Case #1&lt;/h5&gt;

&lt;p&gt;User comes to the site, seen the search form and typing a search words (herewith he looks at the keyboard). Looking up, he understand that the text wrote "to nowhere", he is irritated. Puts focus to search input, typing several characters, check what he does to type "where necessary" and calmer continues typing in search terms.&lt;/p&gt;

&lt;p&gt;Then you say: "Hey! Need to set the focus after loading the DOM!".&lt;br /&gt;
But no, this is also a bad decision, I explain it in the Case #2.&lt;/p&gt;

&lt;h5&gt;Case #2&lt;/h5&gt;

&lt;p&gt;User comes to the site, he was not interested in the search form, he wants scrolling (Left/Right, Up/Down, PgUp/PgDown, Home/End, etc.) page using the keyboard (users who use laptops without mouse quite a lot), and since we have is the focus on the search form, then we cant scroll the page.&lt;/p&gt;

&lt;p&gt;For decision this two cases has been created this plugin: &lt;a rel="nofollow" href="http://github.com/adw0rd/jquery-cleverfocus"&gt;jquery-cleverfocus&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Example&lt;/h3&gt;

&lt;p&gt;Suppose, you have a form with id="search_input":&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;input id="search_input" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, just use the plugin:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$("#search_input").cleverfocus({
    keypress_limit: 3
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The plugin includes &lt;a rel="nofollow" href="https://github.com/adw0rd/jquery-cleverfocus/blob/master/functional_test.html"&gt;functional_test.html&lt;/a&gt;, which serves to testing form, as well as you can see onlone demo on &lt;a rel="nofollow" href="http://adw0rd.github.com/jquery-cleverfocus/"&gt;adw0rd.github.com/jquery-cleverfocus&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Why do I named it that?&lt;/h3&gt;

&lt;p&gt;First, I named it as "jquery-autofocus", but then searched in Google and found this name &lt;a rel="nofollow" href="https://github.com/miketaylr/autofocus"&gt;plugin with the same name&lt;/a&gt;, which is designed to emulate the autofocus attribute of HTML5 in HTML earlier versions.&lt;/p&gt;

&lt;p&gt;Later, I named it "jquery-smartfocus", but here waiting for me disappointed, because there is such a &lt;a rel="nofollow" href="http://archive.plugins.jquery.com/project/smartFocus"&gt;plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the end, I named it by "humanly" - &lt;strong&gt;cleverfocus&lt;/strong&gt;.&lt;/p&gt;
</content></entry><entry><title>Released a pluggable application "django-multi-sessions"
</title><link href="https://adw0rd.com/2012/02/27/django-multi-sessions/en/" rel="alternate"></link><published>2012-02-27T16:11:44+04:00</published><id>https://adw0rd.com/2012/02/27/django-multi-sessions/en/</id><summary type="html">This application provides interfaces for multi-session backend. Basically designed to transfer sessions from one machine to another, without stopping your sessions. Current version is 0.0.3 Installation from PyPI: pip install django-multi-sessions Or manual installation: Download tarball, extract and run: python setup.py install Settings You need specify in settings.py a "multi_sessions.session"…
</summary><content type="html" xml:base="https://adw0rd.com/2012/02/27/django-multi-sessions/en/">&lt;p&gt;&lt;img src="/media/2009/11/Djangologo.gif" alt="" title="Multi-sessions backend for Django" width="125" height="50" class="alignright size-full wp-image-4834" /&gt;&lt;/p&gt;

&lt;p&gt;This application provides interfaces for multi-session backend. Basically designed to transfer sessions from one machine to another, without stopping your sessions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current version is 0.0.3&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;Installation from PyPI:&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;pip install django-multi-sessions
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Or manual installation:&lt;/h3&gt;

&lt;p&gt;Download &lt;a rel="nofollow" href="http://pypi.python.org/pypi/django-multi-sessions"&gt;tarball&lt;/a&gt;, extract and run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;python setup.py install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Settings&lt;/h3&gt;

&lt;p&gt;You need specify in settings.py a "multi_sessions.session" as SESSION_ENGINE and fill the SESSION_MULTISESSIONS_POOL, as in example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;SESSION_ENGINE = "multi_sessions.session"
SESSION_MULTISESSIONS_POOL = (
    {
        "backend": "redis_sessions.session",
        "modes": ["read", "write", "delete"]
    },
    {
        "backend": "django.contrib.sessions.backends.db",
        "modes": ["read", "delete"]
    },
)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this example the "redis-session" is using as a priority storage (read, write/create, delete), and "database-backend" is using only for reads and delete a sessions, because we migrate to "redis", and is no meaning in store data in "database-backend".&lt;/p&gt;

&lt;h3&gt;Sources&lt;/h3&gt;

&lt;p&gt;This application is open source, and you can getting source code from &lt;a rel="nofollow" href="https://github.com/adw0rd/django-multi-sessions"&gt;https://github.com/adw0rd/django-multi-sessions&lt;/a&gt;&lt;/p&gt;
</content></entry></feed>