Add whitespace, no two imports in one line
[ordnung.git] / ordnung.py
blob2db0e650bca520390c0111b3446a9d0d7e51487a
1 from path import path
2 import fnmatch
3 import os
4 import shutil
5 import sys
7 from optparse import OptionParser, OptionGroup
8 from tag_wrapper import tag
10 ACCEPTEXTS = [".ogg", ".mp3"] # Keep it simple for now
12 def issupportedfile(name):
13 for ext in ACCEPTEXTS:
14 if os.path.splitext(name)[1] == ext:
15 return True
16 return False
19 def mkdir(newdir):
20 if not os.path.isdir(newdir):
21 os.makedirs(newdir)
24 def newpath(file, pattern):
25 # Create the tokens dictionary
26 tokens = {}
27 tags = tag(file)
28 # TODO: add tracknumber, disknumber and possibily compilation
29 for t in ["title", "artist", "album artist", "album", "composer", "genre", "date"]:
30 try:
31 tokens[t] = tags[t]
32 except KeyError:
33 tokens[t] = None
34 # %album artist% is %artist% if nothing can be found in the tags
35 if tokens["album artist"] == None:
36 tokens["album artist"] = tokens["artist"]
38 # Now replace all tokens by their values
39 for i in tokens:
40 repl = "%" + i + "%"
41 if tokens[i] != None:
42 pattern = pattern.replace(repl, tokens[i][0])
44 # Add the extension and return the new path
45 return pattern + os.path.splitext(file)[1]
48 def safeprint(string):
49 """
50 Print string first trying to normally encode it, sending it to the
51 console in "raw" UTF-8 if it fails.
53 This is a workaround for Windows's broken console
54 """
55 try:
56 print string
57 except UnicodeEncodeError:
58 print string.encode("utf-8")
61 def files_to_move(base_dir, pattern, recursive=False):
62 """
63 Figure out which files to move where
64 """
65 basepath = path(base_dir)
66 if recursive:
67 files = basepath.walkfiles()
68 else:
69 files = basepath.files()
71 # This list will later contain all the (origin, destination) tuples
72 files_return = []
74 for file in files:
75 if issupportedfile(file):
76 t = [ file, newpath(file, pattern) ]
77 files_return.append(t)
79 return files_return
81 def main():
82 # Pseudo-enum for actions
83 COPY = 0
84 MOVE = 1
85 PREVIEW = 2
87 # Handle arguments
88 usage = "Usage: %prog [options] directory pattern"
89 parser = OptionParser(usage=usage)
90 parser.add_option("-r", "--recursive", action="store_true",
91 dest="recursive", help="also move/copy files from sub-directories", default=False)
93 actions = OptionGroup(parser, "Possible actions")
94 actions.add_option("--preview", "-p", action="store_const",
95 const=PREVIEW, dest="action", help="preview, don't make any changes (default)")
96 actions.add_option("--copy", "-c", action="store_const",
97 const=COPY, dest="action", help="copy files")
98 actions.add_option("--move", "-m", action="store_const",
99 const=MOVE, dest="action", help="move files")
100 parser.add_option_group(actions)
101 (options, args) = parser.parse_args()
103 try:
104 base = args[0]
105 except IndexError:
106 print "You must specify a directory"
107 sys.exit()
109 try:
110 pattern = args[1]
111 except IndexError:
112 print "You must specify a pattern"
113 sys.exit()
115 for i in files_to_move(base_dir=base,
116 pattern=pattern, recursive=options.recursive):
117 if options.action == MOVE:
118 mkdir(os.path.split(i[1])[0])
119 shutil.move(i[0], i[1])
120 elif options.action == COPY:
121 mkdir(os.path.split(i[1])[0])
122 shutil.copy2(i[0], i[1])
123 else:
124 safeprint (i[0] + " --> " + i[1])
127 if __name__ == "__main__":
128 main()