emblem-mode for Emacs

Emblem.js is an ember friendly templating engine used as an alternative for handlebars.js.
Emblem.js doesn't have any official plugins for emacs. However, they recommend using slim-mode plugins as they are similar.
You get slim-mode from melpa. Install with
M-x install-package slim-mode
Now we have to activate slim-mode for emblem files which will be ending with .em or .emblem. We can use auto-mode-alist to set major modes that need to activate for files with specific extension.
(add-to-list 'auto-mode-alist '("\\.\\(em\\|emblem\\)\\'" . slim-mode))
We can add this to emacs configuration which automatically activates slim mode for emblem.js files.
Read more ...

Auto Completion For Custom Search Engines In Chrome

If we have to search for a video on YouTube or a product on Amazon, we will open up that site first and then we will search for it.
Chrome-custom-search-autocompletion1
To avoid this, Chrome allows us to search using custom search engines without visiting the site first. In chrome search settings, we can assign a single letter to a custom search engine.
Chrome-custom-search-autocompletion1
Now if we go to browser, type y and hit Tab, it prompts for YouTube search instead of default search.
Chrome-custom-search-autocompletion1
This is handy. But the major problem with this approach is there won't be autocompletion in chrome address bar.
This is where vimium comes into picture. Vimium provides auto completion for custom search engines.
You can install it from chrome webstore. Once it is installed, go to Vimium options and add youtube search to custom search engines.
y: http://www.youtube.com/results?search_query=%s Youtube
Also add a custom key map for this search.
map y Vomnibar.activateInNewTab keyword=y
If we just press y, it open youtube custom search with autocompletion.
Chrome-custom-search-autocompletion1
Now in every page, we have autocompletion for custom search engines.

More articles about Chrome.
Read more ...

Concurrent Downloads - Bash (xargs, parallel) Vs Python (ThreadPoolExecutor)

I just found one more free telugu book Graded readings in modern literary Telugu by Golla Narayanaswami Reddy and Dan M Matson in Digital South Asia Library.
Unfortunately they didn't provide it as an ebook but as a set of 221 tif images.
I wrote a simple for loop in shell which downloaded all images one by one using wget.
$ base_url="http://dsal.uchicago.edu"
$ url="$base_url/digbooks/images/PL4775.R4_1967/PL4775.R4_1967_%03g.gif"
$ time -p sh -c 'for i in $(seq -f $url 1 221); do; wget $i; done;'
I took 375 seconds for that. This was too slow. So I tried to download them parallelly using xargs.
$ time echo $(seq -f $url 1 221) | xargs -n 1 -P 36 wget
My laptop has a quad core processor. So I tried with 20, 24, 28, 32 process at a time.
With wget+xargs, the best timing is 13 seconds (CPU: 15%, Process: 28).
Again I tried downloading them parallelly but with GNU parallel.
$ time seq -f $url 1 221 | parallel -j36 wget {}
With wget+parallel, the best timing is 12 seconds (CPU: 48%, Process: 24).
Here is cpu consumption and time taken at each step.
paralle_python_bash2
Once I have done with bash, I decided to try the same things with Python and see how it goes.
I wrote a simple script using requests to download images.
import shutil
import sys
from concurrent import futures

import requests


def download_image(url):
    r = requests.get(url)
    file_name = url.split('/')[-1]
    with open(file_name, 'wb') as fh:
        fh.write(r.content)


base_url = 'http://dsal.uchicago.edu'
book_url = base_url + '/digbooks/images/PL4775.R4_1967/PL4775.R4_1967_{}.gif'
urls = [book_url.format(str(i).zfill(3)) for i in range(1, 221)]

def download_serially():
    for url in urls:
        download_image(url)

download_serially()
This took 244 seconds.
To download images parallelly, I have used Threadpoolexecutor from concurrent module.
def download_parallely():
    workers = int(sys.argv[1])

    with futures.ThreadPoolExecutor(max_workers=workers) as executor:
        result = executor.map(download_image, urls)

download_parallely()
I used previous script but just added one more function which queues tasks. Then I have executed the script with several options.
$ time python down.py 28
Threadpoolexecutor documentation uses 5 times number of processors as max_workers by default. I tried same options which I have used for bash. Here is the overall comparision.
With requests+ThreadPoolExecutor, the best timing is 12 seconds (CPU: 36%, Process: 28).
Here is the overall comparision.
paralle_python_bash
For a simple concurrent download, xargs+wget seems to be the best option.

Read more ...

Emacs - Browsing Projects With Etags

A tag is a reference to a sub unit in a program. A tag references syntactic elements like functions, classes e.t.c. A tags table consists of list of tag names and their positions in corresponding files.

Creating Tags Table

A tags table can be generated by etags program. If you are using Ubuntu machine, you can install it with
sudo apt-get install exuberant-ctags
Now, you can generate tags for a file with
etags input_file
Depending on the project, we can also generate tags for a particular type. For example, we can generate tags for all python files using
find . -name '*.py' -exec etags -a {} \;

Browsing Tags

This tag tables enables you to jump to definition of any tag. You can place cursor on a tag and pressM-.(find-tag) which takes you to definition of that tag. If you want to go back to previous location, you can use M-*(pop-tag -mark). There are several functions which help to navigate tags.

Tips

ctags-update is a third party package which automatically updates TAGS file when new files are created.
In addition to them, helm provides a function called helm-semantic which shows all available tags in the current file. This works without TAGS file. Helm also has helm-etags-select which provides helm interface to select tags.
If you are working with a python projects, you can use elpy which navigates tags (using Jedi in the backend) without any TAGS file.

Read more ...

[Django Tips] Make Deleting Easy In Admin!

Lets say we have a model as shown in some project.
from django.db import models

class Resource(models.Model):
    """
    Model to hold resources for books.
    """
    book = models.ForeignKey('Book')
    book_type = models.IntegerField()
    url = models.URLField()
This model can be registered in admin as follows.
from django.contrib import admin

from . import models

class ResourceAdmin(admin.ModelAdmin):
    list_display = ('book', 'book_type', 'url')


admin.site.register(models.Resource, ResourceAdmin)
This will generate a nice admin interface to modify the data.
django-admin-delete
Now if we want to delete a record, we need to follow these steps.
  • First, we have to select that record
  • Next, we have to click on the action dropdown
  • Next, we have to select delete action
  • Next, we have to click Go button.
  • In the next page we have to confirm that we have to delete.
Just to delete a single record, we have to click 5 times. That's too many clicks for a single action.
To simplify the process, we can have simple delete button for the objects as shown. This can be achieved by writing a function which will insert delete button for every record.
from django.contrib import admin

from . import models


class ResourceAdmin(admin.ModelAdmin):
    def delete(self, obj):
        return '<input type="button" value="Delete" onclick="location.href=\'%s/delete/\'" />'.format(obj.pk)

    delete.allow_tags = True
    delete.short_description = 'Delete object'

    list_display = ('book',  'book_type', 'url', 'delete')


admin.site.register(models.Book)
Now we have an admin with delete button for the records.
django-admin-delete
To delete an object, just click on delete button and then confirm to delete it. Now, we are deleting objects with just 2 clicks.

Read more django tips.
Read more posts about django.

Read more ...

Auto Convert & Upload Books To Kindle

I have ebooks in various formats like pdf, epub, mobi e.t.c. If I want to read books in laptop, I could use ebook reader like Calibre which can open supports most of the formats.
If I have to read them on Kindle paperwhite, it becomes a problem as it supports only few formats. So whenever I get an ebook, I have to convert it to mobi format and send it to kindle.
I can connect kindle to laptop via USB cable and I can copy books. I can also send books to kindle via email.
I found an IFTTT recipe, to automate all this process. I just need to create a folder to store all the books in dropbox. Then use IFTTT recipe to link dropbox folder which has books and gmail to send books to kindle email.
Now when I move required books into dropbox folder in my laptop, they will automatically appear in my kinde.
Read more ...

Automate Boring Stuff - Accepting Waitlist RSVPs

Meetup.com makes it easier to organize events. Before meetup you can specify how many people you can accomodate. Then you send mail to all people so that interested people can RSVP.
If RSVP is full, people can join waitlist. So if somebody changes RSVP to No, we can accomodate people in waitlist.
On the otherhand, if you find a place where you can accomodate more number than you have planned, you can accept all people in waitlist.
Unfortunately, there is no option in meetup for that. You have to accept people one by one which is a boring job if there are ~50 people in waitlist.
This where Python comes to rescue. Python has an excellent package called pyautogui which helps you to automate all boring tasks.
Here is the simple script I have used for this task.
import time

import pyautogui


print('Goto meetup event page and place cursor...')
time.sleep(5)

x, y = pyautogui.position()

for i in range(100):
    pyautogui.click(x, y)
    time.sleep(5)
The code is self explanatory. First we are importing pyautogui and then wait for 5 seconds so that we can go to meetup page and point mouse correctly. Get the cursor position and start clicking on that position with a gap of 5 seconds. This gap is needed as meetup shows a notification once you accept  RSVP.
Pyautogui is an interesting package which makes your boring job easier.
Update:
Just found that increasing Attendee limit auto changes RSVP of waitlist people to Yes.

Read more articles about Python!
Read more ...

Let It Be - A Zen Story By Buddha!

Once Buddha was walking from one town to another town with a few of his followers. While they were travelling, they happened to pass a lake. They stopped there and Buddha told one of his disciples, “I am thirsty. Do get me some water from that lake there.”

The disciple walked up to the lake. When he reached it, he noticed a bullock cart started crossing through the lake. As a result, the water became very muddy. The disciple thought, “How can I give this muddy water to Buddha to drink!” So he came back and told Buddha, “The water in there is very muddy. I don’t think it is fit to drink.”

After about half an hour, again Buddha asked the same disciple to go back to the lake and get him some water to drink. The disciple obediently went back to the lake. This time he found that the lake had absolutely clear water in it. The mud had settled down and the water above it looked fit to be had. So he collected some water in a pot and brought it to Buddha.

Buddha looked at the water, and then he looked up at the disciple and said, “See what you did to make the water clean. You let it be ... and the mud settled down on its own – and you got clear water... Your mind is also like that. When it is disturbed, just let it be. Give it a little time. It will settle down on its own. You don’t have to put in any effort to calm it down. It will happen. It is effortless.”



Read more ...

Dropbox As Wormhole Between Ubuntu & Google Drive!

I use Ubuntu on multiple computers everyday. It is important to keep various files synced across them. I keep most of the public data in github repositories and it is very easy to sync across multiple machines.
Google Drive gives 15GB of space with free account. I have multiple accounts and that space is enough to backup my data. I have been storing lots of files in Google Drive from past few years. The main problem is that Google Drive doesn't have a Linux client. To add files, I need to open a web page and then select files to upload and wait until its done. There are few 3rd party clients and none of them work well. So, it is very difficult to sync them across multiple computers.
Dropbox gives 5GB of space with free account. It has Linux client and it works very well. But 5GB of space is not sufficient to store my data.
It is quite difficult to pick one among them as I need benefits of both for free.
Even though I have lot of data, I dont want all of it to sync to all computers everyday. Nearly 90% of data is just backup. Only 10% of data needs to be synced between multiple computers. So I decided to use dropbox as a frontend to google drive.
I have created 2 folders, say Daily & Backup in Dropbox.
Whatever I add to Daily folder will be in Dropbox and it will sync across multiple machines.
There is an amazing service called IFTTT which will help you to connect two products/apps. I found a IFTTT recipe which will add dropbox files in one folder to Google drive.
I have connected Backup folder in Dropbox to Google Drive. Whenever I add a file to Backup folder in Dropbox, it gets added to Google Drive. Once in a week, I will delete files in Backup directory so that Dropbox won't run out of space. So Backup folder will serve as a wormhole to transfer files into Google Drive from my system.

Since I have multiple Google accounts, I have created multiple folders in Dropbox and all folders will be synced to corresponding Google Drive folders.
This setup works well for me as I have Dropbox's Linux client and sufficient storage to backup data to Google Drive.

Read more ...

Book Review - A Psycho Path By Haris Ibrahim K. V.

I stumbled on haris blog and I am thrilled to find that he wrote a book called A Psycho Path. Since ebook was free, I downloaded it and started reading.
I skipped ForewardPreface and skimmed through the first story Etsuko’s picnic.
The second story in the book is A surprising blood test. The story is quite impressive and it hooked me in. Before that story I was lying on the bed and reading. After reading it I got up, sat properly and started reading. Among all the stories, I liked it the most.
Sound relations is another article which I found very fascinating. I read the article many times... 10 times? 20 times? may be more. Long before reading the book, me & my friends had a similar discussion while discussing about impact of music. This article gave an interesting conclusion to our discussion.
Narration of Quito San is interesting.
The book has ~20 stories/articles. Most stories are short stories(2-4 pages). The Prophecy of Amelyah and Quito San are medium sized stories(~20 pages).
Overall the book is very good.
I got a print book after reading ebook. I would recommend getting a get print book from Pothi or Amazon. You can also download free ebook here.
Read more ...