Wednesday, August 15, 2012

A Python tool to find file and work on the file

This is a simple python example to do a very simple work. This is generally to address one of the
most boring part of our work. Generally we locate a file and do something with the file while doing
development. For example, we may have two/three locations in our machine where we maintain         
development directories. Generally, we do the following:                                           
    1. Locate the file                                                                             
    2. There may multiple copies of the file, but we want to do something with one copy of the file
    3. We select one copy of the file
    4. Then we may
        - Edit the file
        - Go to directory of the file and do something
        - Delete the file

This simple thing needs a lot of typing. This typing can be avoided by using this tool. I can write
a one line shell script to do the same. But I want to practice Python and Python is much more
powerful than simple shell scripts.

The tool uses 'locate' command to locate the file. 'locate' is part of mlocate package. On a CentOS
or Redhat Linux system, you may issue "yum search mlocate"  command to search mlocate package and
then "yum install" to install the package. If you have mlocate installed, run "updatedb" to have the
latest filenames in your system to mlocate database. mlocate stores the filenames in a Berkeley DB
database and "locate" searches for the file name in this database. The DB may not be updated with
the latest file names and so it is better to have a cron job runing every 4/5 hours to keep the DB
updated.

The script locates file(s) by its name and ask you to choose one of the matched file. Then it ask
you what you would like to do with the file. It allows 3 actions as given below:
    Choice <1> open the file with vim
    Choice <2> change directory to file location
    Choice <3> delete the file
Thats all.

Usage is given below:
findfileaction.py filename <regex> <filter-file-regex>

filename may be a regular expression and that is assumed if the 2nd command line argument is
"regex". 2nd argument and 3rd argument are optional. 3rd argument is used to filter some file out.
E.g. if you don't want to see .cpp files, then pass '.*cpp$' as the 3rd argument. 3rd argument can
be a regular expression.

Hope the tool will be helpful for you :)
Copy the below code to a file findfileaction.py. 
Here is the  github link. 

#!/usr/bin/python

import sys
import string
import subprocess
import re
import os

def delete_file(filename):
    if (not os.path.isfile(filename)):
        print filename + " seems not there or not a rgular file"
        return False
    os.remove(filename)
    return True


def open_file_with_vim(filename):
    if (not os.path.isfile(filename)):
        print filename + " seems not there "
        return False
    subprocess.call(['vim' , filename])
    return True

def cd_to_dir(filename):
    cdloc = ''
    if (os.path.isdir(filename)):
        cdloc = filename
    elif (os.path.isfile(filename)):
        cdloc = os.path.dirname(filename)
    else:
        print filename + ' might not exist'
        return False
    os.chdir(cdloc)
    subprocess.call([os.getenv('SHELL') ])
    return True
    
def read_choie(prompt, max_val, min_val, bad_choice):
    try:
        x = raw_input(prompt);
        if (int(x) > max_val):
            return bad_choice
        return x
    except ValueError:
        return bad_choice

def find_file(filename, regexex=False):
    output = ""
    if (regexex == False):
        output = subprocess.Popen(['locate' , filename ] , stdout=subprocess.PIPE ).communicate()[0]
    else:
        output = subprocess.Popen(['locate' , '-r', filename ] , stdout=subprocess.PIPE ).communicate()[0]
    files = string.split(output, '\n')
    return files
try:
    regexex = False
    filterexp = None
    if ((len(sys.argv) > 2) and (sys.argv[2].lower() == 'regex' )):
        regexex = True
    if (len(sys.argv) > 3):
        filterexp = re.compile(sys.argv[3])
    files = find_file(sys.argv[1], regexex )
    required_files = []
    printname=False
    for file in files:
        printname = True
        if ((filterexp is not None)and (filterexp.search(file) is not None)):
            printname = False
        if ( printname and file != "") :
            required_files.append(file)
    i = 0
    for file in required_files:
        print str(i) + " " + file
        i = i + 1
    if (len(required_files) == 0):
        sys.exit(0)
    bad_choice = 4294967295
    choice_index = read_choie('Please index of your file of interest ', len(required_files) -1,\
            0, bad_choice)
    if (choice_index == bad_choice):
        print "You chose bad index"
        sys.exit(1)
    print "What you want to do with this file "
    print "Choice <1> open the file with vim "
    print "Choice <2> change directory to file location "
    print "Choice <3> delete the file "
    
    work_index = read_choie('Please enter your choice ', 3, 1, bad_choice)
    if (work_index == bad_choice):
        print "Bad choice"
        sys.exit(1)
    if (work_index == '1'):
        open_file_with_vim(required_files[int(choice_index)])
    elif (work_index == '2'):
            cd_to_dir(required_files[int(choice_index)])
    elif (work_index == '3'):
            delete_file(required_files[int(choice_index)])
    sys.exit(0)

except IndexError:
    print 'Usage: ' + sys.argv[0] + " filename <regex> <filter-file-regex> "



No comments:

Post a Comment