Saturday, December 27, 2014

Notification when command finished running on linux terminal

Often we run some command in terminal which takes a hell of a lot of time to finish. Then, we wish we could do something else while the command runs but get a notification when it's done.

Getting this notification is quite easy.

Just run your command in the following manner to achieve this:
your-main-command; notification-command &


where,
    your-main-command ==> the command that you are running
    notification-command ==> command used for notifying

Various Notification Commands

You can use any of these commands for notification: 

notify-send "Command finished running." #use on Ubuntu/Mint
xmessage "Command finished running." #can be used on all Linux distros


So, your final command should look something like this:
your-command; notify-send "Command finished running." &


Automating for every command


Now, what if you wanted the notification to show up after every command you type, without having to type the notification as well. To do this, install autokey first.
sudo apt-get install autokey-gtk

Autokey is a software for mapping different actions to different keystrokes. It's very powerful. Now, open Autokey and follow these steps:

  1. Here, define a new "phrase". Give it some name. In the big text-box on the right side, enter the following text:
    ; notify-send "Job finished!" &
    
    
    
    IMP: Note that in the above phrase text, there is a newline after the first line. Be sure to include that.
  2. Set the "hotkey" as alt+center.
  3. Assign the "Window Filter" as
    .*(guake)|(Terminal).*
    NOTE: If you're some other terminal than Terminal or guake, then add its name in the window filter.
You're done now. Everytime you enter a command and wish to get a notification for it, just run it using Alt+Enter and it will notify you.



Tuesday, December 23, 2014

Zim Wiki Custom Shortcuts/Keystrokes

NOTE: This solution is not limited to Zim wiki itself. It can be used for any purpose, for any software on your Linux desktop to increase productivity.

I needed to define a custom shortcut for adding Latex equations in Zim wiki. There was no shortcut defined by default and it was cumbersome to every time go to the menu and click on the item using mouse to add an equation.

NOTE: Equation plugin is not enabled by default and you'll have to enable it.

So what I did was install this cool piece of software : Autokey. This is an opensource clone of the ever-popular Windows software Autohotkey.

sudo apt-get install autokey-gtk

Now, we know that to reach the menu item for adding equation can be reached through a few keystrokes in Zim. First we press Alt+i. This opens up the "Insert" menu. Then we press that "q" is highlighted in the "Equation" item in the dropdown menu. This means that pressing "q" will now open the equations dialog. We want this process to be done in a single keystroke.

So, open autokey. Click on New->Script. Add the following code and set a hotkey for the script. I set the hotkey to Alt+e.


keyboard.send_keys("<alt>+i")
keyboard.send_key("q")


Another Example: setting hotkey for adding codeblock

NOTE: You need to have syntax-highlighting plugin enabled.

Just use the following script and set a preferred hotkey.
keyboard.send_keys("<alt>+i")
keyboard.send_key("<up>", repeat=5)
keyboard.send_key("<enter>")
time.sleep(0.25)
keyboard.send_key("<tab>", repeat=2)
keyboard.send_key("<enter>")
In this example we had to implement a "hacky" way. In this case, if we press Alt+i, then we see that no key in the Codeblock item is highlighted. Hence, can not directly reach there using some alphabet. To reach there, we press UP five times (might be different in your case). Then we press ENTER. After that we press TAB two times to reach OK in the popup dialog, and then we press ENTER.

Wednesday, March 26, 2014

Error splicing file: Input/output error : The Final Solution

This error appears to be a very common one on many Linux boxes. I, especially, faced it many times.

Now, this problem can have many sources, not just one. So, I will try to register all the sources of error and the proposed solutions. This will be a work in progress, and I will keep updating it as I find new problems/solutions.

What is this error?

This error shows up when trying to copy a file from some place to the other, especially involving ext4 filesystems.

Possible sources of error:

  • Corrupt file
  • Bad sector in HDD

Proposed solutions

  1. For corrupt files, this seems to be a sure-shot solution:
sudo apt-get install gddrescue
ddrescue /media/dcrom/VoyagerS01E01.avi foo.avi foo.log

Sunday, March 16, 2014

Nautilus Browser for PDF Management : Show and Edit PDF Metadata in Nautilus

I had an ever-growing stock of pdf files (academic journals) which I had to read for my research. I worked mostly on my Linux box and used GNOME to explore files.

In such a case, I wanted my Nautilus to have the capability to

  1. Show the PDF metadata
  2. And be able to edit it

Showing PDF Metadata in Nautilus in List View

There is a famous plugin for that: nautilus-columns. It's not in the official repository. It's a plugin by webupd8. So, just do:

sudo add-apt-repository ppa:nilarimogard/webupd8
sudo apt-get update
sudo apt-get install nautilus-columns
nautilus -q
After this, just open your nautilus and go to Preferences  > List Columns. Here, you can now check the metadata you would like to see in the "List Columns View".


A probable problem and its solution

Now, some people might the face problem that it is not work in their Nautilus, especially in MATE desktops. So, for this, you just need to rewire your python a bit: 

For 32-bit users:


sudo ln -sf /usr/lib/libpython2.7.so.1 /usr/lib/libpython2.7.so.1.0
sudo ln -sf /usr/lib/i386-linux-gnu/libpython2.7.so.1 /usr/lib/libpython2.7.so.1
For 64-bit users:
sudo ln -s /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 /usr/lib/libpython2.7.so.1.0
sudo ln -s /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 /usr/lib/x86_64-linux-gnu/libpython2.7.so

Adding more fields for PDF Metadata

By default the nautilus-columns has very less fields related to PDF. Only two, actually: "Title" and "Artist"(author). But you definitely need more. In my case, I needed "Subject", "Year of Publication" and "Keywords". So, I modified the script file a bit.

Now, this script is located at "/usr/share/nautilus-python/extensions/". Go here, and open "bsc-v2.py" as root. Now, if you know a bit about python scripting, it'd be straightforward to you to add more relevant fields. For a demonstration, here's a link to the modified script file that I used for my purpose: https://dl.dropboxusercontent.com/u/14472678/bsc-v2.py

Edits I made: 
  • Added "import re" in line 36
  • Added some fields in lines 88-90
  • Modified the pdf handling starting from line 222
Just browse through the code, and if you have any problem, just drop in a comment.


Editing Metadata in Nautilus

Now, coming to this. Install these requirements:
  • nautilus-actions
  • exiftool
 Now, follow the steps:
1) Open Nautilus-Actions. Click on "New Action" (Ctrl+N)
2) On the right side, in "Action" tab, add something to "Context Label" field. Let's say, we add: "Add Title to PDF"

3) In the "Command" tab, in the "Path" field, we have to enter our command. We enter this:

echo "Enter the title and press enter"; read title; exiftool -Title=$title -overwrite_original %F 

4) In the "Execution" tab, check "In a terminal" as the execution mode. 

5) Now, this is the crucial part. Go to Preferences > Runtime Execution. Here, in the command pattern, add this: 
gnome-terminal -x sh -c COMMAND

6) Now, Save this (Ctrl+S). Close the application. And restart nautilus (nautilus -q). Now, open Nautilus, select any pdf file, and right click on it. You'd see a Nautilus-Actions > "Add Title to PDF" menu item. Click on it. A terminal will open up. Enter the desired title. And it'd be instantly changed. 

And we're done!!


What's happening here?

Nothing much. We are basically using exiftool  to edit the metadata. Also, we used the "read" command to take input from the user. Rest is self-explanatory.




Sunday, December 2, 2012

Zim with Truecrypt and Dropbox : The Final solution for Secure Personal Notes

Skip the first two paras if you need to go read about the technical part of setting up Zim with Truecrypt and Dropbox.

I realized one day that there is so much we are consuming these days due to overflow of information that our mind fails to filter out what has to be saved in our brains. I'd been learning many things, many ideas used to pop up in my mind but all of it used to vanish into nothingness. I realized that perhaps it was time I started keeping a journal.

I started off with a physical journal: the pen and paper diary. Over time, they got too many in number and not as portable. I then realized that perhaps it was time to use an e-journal. Thus, started a search for the perfect one. I started with usual LibreOffice doc files. For private diary notes, I'd encrypt them (they use Blowfish and now AES, so pretty safe). All this would remain synchronized with Dropbox. Later, I came to know about Evernote. It was good but not for secret notes, b'coz if anybody hacked into Evernote server or my evernote account, it'd be all out. So, my secret notes would still stay in doc files. And then I found Zim. It appeared initially as a very weak solution to my needs. But then, slowly I started loving it. And now I love it so much that I am even ditching Evernote for this pretty thing.

Zim basically is a wiki like notebook software which stores your data in files in a given folder. So, what I did was create a truecrypt container in a Dropbox folder, and mount it somewhere and then create a Zim notebook in that mounted location. So, before starting Zim, I'd everytime mount that Trucrypt container and then start Zim and write my notes. After closing Zim, I'd unmount that container and Dropbox would synchronize it. What was cool was that Dropbox wouldn't synchronize the whole Truecrypt container everytime. Rather only those bits which were changed (Note that you need to have the option "Preserve Modification Timestamp of the Containers" checked yes in the "Truecrypt Preferences"). 

But what sucked was that this process of mounting container everytime and then unmounting it was too cumbersome. So, I wrote a quick bash script for this.

#!/bin/bash
truecrypt ~/Dropbox/zim/container /media/truecrypt5  # mount the container using truecrypt
zim  #start zim after mounting container

PID=($(pidof -x zim))   #extract the PIDs of all Zim processes and save them in an array
while ps -p ${PID[*]}; do sleep 1; done ; truecrypt -d /media/truecrypt5     #keep a watch on whether Zim is runnning or not; as soon as it gets closed, unmount the container

Note that I had configured Zim to use the default Notebook folder as /media/truecrypt5 during the first launch. Change it to whatever you did.

Now, eveytime, I'd just run this script. After running this script, it'd first ask me a password for my container. After entering in the password, it 'd mount the container and open Zim. After editing in Zim and closing it, the script would automatically unmount the container and it'd get synchronize with Dropbox.


How secure is it?
This probably isn't fool-proof but still the best option. The thing is that Dropbox will keep revisions for your container for past 30 days. So, if someone gains access to your Dropbox, they can get the keyfile using these different versions. And they can then crack the password of the container. However, if your password is too long then it'd be tough for them. So, still it's pretty secure if you're having a long password for your container.

Please comment on the security vulnerabilities if you can think of any. I'm only a noob concerning security and encryption. 


UPDATED SCRIPT
 I am writing an updated script. The above mentioned script might fail some time.

#!/bin/bash
#filename: "zimdiary"
#this script using "pgrep" is more robust than the previous one using "pidof"

truecrypt ~/Dropbox/zim/container /media/truecrypt5

zim Diary #given that the notebook's name is "Diary"

PIDzim=($(pgrep -f zim))
PIDzimdiary=($(pgrep -f zimdiary))    

#this gets the PIDs for this script itself (which is named as zimdiary), this is done because PIDzim contains PIDs for both "zim" and "zimdiary"

while ps -p ${PIDzim[*]} && [ ${#PIDzim[*]} != ${#PIDzimdiary[*]} ];
    do
        sleep 1
        PIDzim=($(pgrep -f zim))
        PIDzimdiary=($(pgrep -f zimdiary))
done

truecrypt -d /media/truecrypt5

Monday, April 30, 2012

Deploying Apache with Django on Ubuntu Linux

So, the other day I was trying to start of my Django on a production server on Ubuntu 12.04 LTS.

Prelims: What is Django and the difference between production and development server?

You know what is Django. Otherwise you shouldn't be here. Now, Django comes packed with a development server. This means you can start off with Django without any server installed (e.g. Apache). Django has its own mini-server. However, if you're deploying the site online, you need a production server e.g. Apache. So, our problem statement is to allow Django to use Apache.

Let's Roll

You should have your Django already installed. Now, you need to install mod_wsgi. This will be used as a connector for Django to Apache. Also, install python-mysqldb if you will be using mysql database. 

Open your terminal:
    $ cd  /var/www/
    $ django-admin.py startproject mysite

(Note that if you don't have the permission, then do it as root i.e. using sudo)

Now, you have created your Django project.

Now, open /etc/apache2/apache2.conf. Add the following lines at the end:

WSGIScriptAlias /django /var/www/mysite/mysite/wsgi.py
WSGIPythonPath /var/www/mysite

<Directory /var/www/mysite/mysite>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory> 

Now, restart apache.

Now, open up firefox and fire: http://localhost/django. That's it.

 Now, let me explain a bit. 

/django : this is the alias for your site i.e. how you access it through the client (your browser). If you left it as "/", then you could have accessed your site simply as localhost.
/var/www/mysite/mysite/wsgi.py : this is where your wsgi file resides
/var/www/mysite : this is where you started your project
/var/www/mysite/mysite : this is the directory of the project

You could have started your project elsewhere. Correspondingly, above destinations will change.