Ignore hashlib deprecation warning
[ordnung.git] / ordnung.py
blob5715c5694791084e4cb2cbc86754f504115a8eb1
1 # Copyright 2009, Erik Hahn
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 import warnings
17 warnings.filterwarnings("ignore", message="the md5 module is deprecated; " + \
18 "use hashlib instead")
20 from path import path
21 import fnmatch
22 import os
23 import shutil
24 import sys
26 from optparse import OptionParser, OptionGroup
27 from tag_wrapper import tag
29 ACCEPTEXTS = [".ogg", ".mp3"] # Keep it simple for now
31 def issupportedfile(name):
32 for ext in ACCEPTEXTS:
33 if os.path.splitext(name)[1] == ext:
34 return True
35 return False
38 def mkdir(newdir):
39 if not os.path.isdir(newdir):
40 os.makedirs(newdir)
43 def newpath(file, pattern):
44 # Create the tokens dictionary
45 tokens = {}
46 tags = tag(file)
47 # TODO: add tracknumber, disknumber and possibily compilation
48 for t in ["title", "artist", "album artist", "album", "composer", "genre", "date"]:
49 try:
50 tokens[t] = tags[t]
51 except KeyError:
52 tokens[t] = None
53 # %album artist% is %artist% if nothing can be found in the tags
54 if tokens["album artist"] is None:
55 tokens["album artist"] = tokens["artist"]
57 # Now replace all tokens by their values
58 for i in tokens:
59 repl = "%" + i + "%"
60 if tokens[i] is not None:
61 pattern = pattern.replace(repl, tokens[i][0])
63 # Add the extension and return the new path
64 return pattern + os.path.splitext(file)[1]
67 def safeprint(string):
68 """
69 Print string first trying to normally encode it, sending it to the
70 console in "raw" UTF-8 if it fails.
72 This is a workaround for Windows's broken console
73 """
74 try:
75 print string
76 except UnicodeEncodeError:
77 print string.encode("utf-8")
80 def files_to_move(base_dir, pattern, recursive=False):
81 # Figure out which files to move where
82 basepath = path(base_dir)
83 if recursive:
84 files = basepath.walkfiles()
85 else:
86 files = basepath.files()
88 files_return = []
90 for file in files:
91 if issupportedfile(file):
92 t = [ file, newpath(file, pattern) ]
93 files_return.append(t)
95 return files_return
97 def main():
98 # Pseudo-enum for actions
99 COPY = 0
100 MOVE = 1
101 PREVIEW = 2
103 # Handle arguments
104 usage = "Usage: %prog [options] directory pattern"
105 version = "Ordnung 0.1 alpha 1"
106 parser = OptionParser(usage=usage, version=version)
107 parser.add_option("-r", "--recursive", action="store_true",
108 dest="recursive", help="also move/copy files from sub-directories", default=False)
110 actions = OptionGroup(parser, "Possible actions")
111 actions.add_option("--preview", "-p", action="store_const",
112 const=PREVIEW, dest="action", help="preview, don't make any changes (default)")
113 actions.add_option("--copy", "-c", action="store_const",
114 const=COPY, dest="action", help="copy files")
115 actions.add_option("--move", "-m", action="store_const",
116 const=MOVE, dest="action", help="move files")
117 parser.add_option_group(actions)
118 (options, args) = parser.parse_args()
120 try:
121 base = args[0]
122 except IndexError:
123 print "You must specify a directory"
124 sys.exit()
126 try:
127 pattern = args[1]
128 except IndexError:
129 print "You must specify a pattern"
130 sys.exit()
132 # Do stuff
133 for i in files_to_move(base_dir=base,
134 pattern=pattern, recursive=options.recursive):
135 if options.action == MOVE:
136 mkdir(os.path.split(i[1])[0])
137 shutil.move(i[0], i[1])
138 elif options.action == COPY:
139 mkdir(os.path.split(i[1])[0])
140 shutil.copy2(i[0], i[1])
141 else:
142 safeprint (i[0] + " --> " + i[1])
145 if __name__ == "__main__":
146 main()