Subversion Repositories programming

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
116 ira 1
#!/usr/bin/python
2
 
3
import sys, os, glob, re, shutil
4
 
5
DICT_FILE = os.path.expanduser('~/bin/animesorter.dict')
6
WORK_DIR = os.path.expanduser('~/downloads/usenet')
7
SORT_DIR = '/data/Anime'
8
 
9
def parsedict(dict=DICT_FILE):
10
    """Parses a dictionary file containing the sort definitions in the form:
11
    DIRECTORY = PATTERN
12
 
13
    Returns a list of tuples, each containing the contents of one line."""
14
    try:
15
        f = open(dict, 'r', 0)
16
        try:
17
            data = f.read()
18
        finally:
19
            f.close()
20
    except IOError:
21
        print 'Error opening %s ... exiting!' % dict
22
        sys.exit()
23
 
24
    ### Get a LIST containing each line in the file
25
    lines = [l for l in data.split('\n') if len(l) > 0]
26
 
27
    ### Split each line into a tuple, and strip each element of spaces
28
    tuples = [(k, v) for k, v in [l.split('=') for l in lines]]
29
    tuples = [(k.strip() ,v.strip()) for k, v in tuples]
30
 
31
    return tuple(tuples)
32
 
33
def getfiles(dir=WORK_DIR):
34
    """getfiles(dir):
35
 
36
    dir is type STRING
37
 
38
    Return a LIST of the files of type *.{avi,ogm,mkv} that are in the
39
    directory given as a parameter."""
40
    files = []
41
    types = ('avi', 'ogm', 'mkv')
42
 
43
    # Match every type in the type array
44
    for t in types:
45
        files.extend( glob.glob('%s/%s' % (dir, '*.%s' % t)) )
46
 
47
    files = [f for d,f in [os.path.split(f) for f in files]]
48
    return files
49
 
50
def getdirs(dir=WORK_DIR):
51
    """getdirs(dir):
52
 
53
    dir is type STRING
54
 
55
    Return a LIST of the subdirectories of the directory given as a parameter."""
56
    dirs = [os.path.join(dir, d) for d in os.listdir(dir) if os.path.isdir(os.path.join(dir, d))]
57
    return dirs
58
 
59
def createpattern(string):
60
    """createpattern(string):
61
 
62
    Returns a sre.SRE_Pattern created from the string given as a parameter."""
63
    pattern = re.compile(string)
64
    return pattern
65
 
66
def getmatches(files, pattern):
67
    """getmatches(files, pattern):
68
 
69
    files is type LIST
70
    pattern is type sre.SRE_Pattern
71
 
72
    Returns a list of the files matching the pattern as type sre.SRE_Match."""
73
    matches = [m for m in files if pattern.search(m)]
74
    return matches
75
 
76
def fname_from_match(match):
77
    """fname_from_match(match):
78
 
79
    match is a LIST containing type sre.SRE_Match
80
 
81
    Returns a string (the filename) of the LIST match given as a parameter."""
82
    fname = ''.join(match.string)
83
    return fname
84
 
85
def getmatchnames(matches):
86
    """getmatchnames(matches):
87
 
88
    matches is a String containing (many) objects of type sre.SRE_Match
89
 
90
    Returns a LIST of STRINGS representing the filenames of the matches."""
91
    matchnames = [fname_from_match(n) for n in matches]
92
    return matchnames
93
 
94
def move_file(file, fromdir=WORK_DIR, todir=SORT_DIR):
95
    """move_file(file, dir):
96
 
97
    file is a STRING representing a complete filename (with full path)
98
    fromdir is a STRING representing where the file exists currently
99
    destdir is a STRING representing the directory to move the file to
100
 
101
    Returns either True if the move was successful, False otherwise."""
102
    fromfile = os.path.join(fromdir, file)
103
    destfile = os.path.join(todir, file)
104
 
105
    try:
106
        shutil.move(fromfile, destfile)
107
    except:
108
        return False
109
 
110
    return True
111
 
112
def get_dstdir(dir):
113
    """get_dstdir(dir):
114
 
115
    Get an appropriate destination directory depending on whether dir
116
    has a slash on the beginning"""
117
    if( dir[0] == '/' ):
118
        return dir
119
 
120
    return os.path.join(SORT_DIR, dir)
121
 
118 ira 122
def printfailed(moved, failed, cwd):
123
    """printfailed(moved, failed, cwd):
116 ira 124
 
125
    moved is an INTEGER number representing the number of files successfully moved
118 ira 126
    failed is a LIST of the filenames which could not be moved
127
    cwd is a STRING containing the current working directory"""
116 ira 128
    if( len(failed) > 0 and moved > 0 ):
129
        print '================================================================================'
130
 
131
    if( len(failed) > 0 and moved == 0 ):
118 ira 132
        printwdheader(cwd)
116 ira 133
 
134
    for f in failed:
135
        print "Failed to move %s" % f
136
 
137
    if( len(failed) == 0 and moved == 0 ):
138
        pass
139
    else:
140
        print
141
 
142
def printwdheader(dir):
143
    """Prints out a header telling the user we're working in the directory
144
    passed as an argument"""
145
    print 'Working in directory: %s' % dir
146
    print '================================================================================'
147
 
118 ira 148
def printmove(num, file, dstdir, cwd):
116 ira 149
    if( num == 1 ):
118 ira 150
        printwdheader(cwd)
116 ira 151
 
152
    print "Moved %s to %s!" % (file, dstdir)
153
 
154
def mainloop(dir, dict):
155
    """mainloop(dir, dict):
156
 
157
    dir is of type STRING
158
    dict is of type LIST of TUPLES
159
 
160
    Runs the main sort algorithm on the given directory using the pre-parsed
161
    dictionary passed as a parameter."""
162
    files = getfiles(dir)
163
    subdirs = getdirs(dir)
164
    cwd=dir
165
    moved = 0
166
    failed = []
167
 
168
    for regex, todir in dict:
169
        pattern = createpattern(regex)
170
        matches = getmatches(files, pattern)
171
        dstdir = get_dstdir(todir)
172
 
173
        for f in matches:
174
            ret = move_file(f, cwd, dstdir)
175
 
176
            if( ret == False ):
177
                failed.append(f)
178
            else:
179
                moved = moved + 1
118 ira 180
                printmove(moved, f, dstdir, cwd)
116 ira 181
 
118 ira 182
    printfailed(moved, failed, cwd)
116 ira 183
 
184
    # Call ourself recursively on the subdirectories
185
    for s in subdirs:
186
        mainloop(s, dict)
187
 
188
##### THE MAIN PROGRAM STARTS HERE #####
189
if( __name__ == '__main__' ):
190
    print 'Regular Expression File Sorter (aka animesorter)'
191
    print '================================================================================'
192
    print 'Copyright (c) 2005, Ira W. Snyder (devel@irasnyder.com)'
193
    print 'All rights reserved.'
194
    print 'This program is licensed under the GNU GPL v2'
195
    print
196
 
197
    dict = parsedict()
198
    mainloop(WORK_DIR, dict)
199
 
200
    print 'Goodbye!'