automated futurize pass
This commit is contained in:
parent
db2a7650d4
commit
66fe9bc514
1 changed files with 41 additions and 33 deletions
|
@ -1,5 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: iso-8859-1
|
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -15,8 +14,17 @@
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import division
|
||||||
|
from past.builtins import cmp
|
||||||
|
from builtins import chr
|
||||||
|
from builtins import input
|
||||||
|
from builtins import map
|
||||||
|
from builtins import range
|
||||||
|
from past.utils import old_div
|
||||||
|
from functools import reduce
|
||||||
__title__="KeyJ's iPod shuffle Database Builder"
|
__title__="KeyJ's iPod shuffle Database Builder"
|
||||||
__version__="1.0-rc1"
|
__version__="1.0"
|
||||||
__author__="Martin Fiedler"
|
__author__="Martin Fiedler"
|
||||||
__email__="martin.fiedler@gmx.net"
|
__email__="martin.fiedler@gmx.net"
|
||||||
|
|
||||||
|
@ -110,10 +118,10 @@ def open_log():
|
||||||
def log(line="",newline=True):
|
def log(line="",newline=True):
|
||||||
global logfile
|
global logfile
|
||||||
if newline:
|
if newline:
|
||||||
print line
|
print(line)
|
||||||
line+="\n"
|
line+="\n"
|
||||||
else:
|
else:
|
||||||
print line,
|
print(line, end=' ')
|
||||||
line+=" "
|
line+=" "
|
||||||
if logfile:
|
if logfile:
|
||||||
try:
|
try:
|
||||||
|
@ -179,7 +187,7 @@ def ParseRule(rule):
|
||||||
return (prop,rule[sep_pos],ParseValue(rule[sep_pos+1:].strip()))
|
return (prop,rule[sep_pos],ParseValue(rule[sep_pos+1:].strip()))
|
||||||
|
|
||||||
def ParseAction(action):
|
def ParseAction(action):
|
||||||
prop,value=map(string.strip,action.split('=',1))
|
prop,value=list(map(string.strip,action.split('=',1)))
|
||||||
if not prop in KnownProps:
|
if not prop in KnownProps:
|
||||||
log("WARNING: unknown property `%s'"%prop)
|
log("WARNING: unknown property `%s'"%prop)
|
||||||
return (prop,ParseValue(value))
|
return (prop,ParseValue(value))
|
||||||
|
@ -191,12 +199,12 @@ def ParseRuleLine(line):
|
||||||
try:
|
try:
|
||||||
# split line into "ruleset: action"
|
# split line into "ruleset: action"
|
||||||
tmp=line.split(":")
|
tmp=line.split(":")
|
||||||
ruleset=map(string.strip,":".join(tmp[:-1]).split(","))
|
ruleset=list(map(string.strip,":".join(tmp[:-1]).split(",")))
|
||||||
actions=dict(map(ParseAction,tmp[-1].split(",")))
|
actions=dict(list(map(ParseAction,tmp[-1].split(","))))
|
||||||
if len(ruleset)==1 and not(ruleset[0]):
|
if len(ruleset)==1 and not(ruleset[0]):
|
||||||
return ([],actions)
|
return ([],actions)
|
||||||
else:
|
else:
|
||||||
return (map(ParseRule,ruleset),actions)
|
return (list(map(ParseRule,ruleset)),actions)
|
||||||
except OSError: #(ValueError,IndexError,KeyError):
|
except OSError: #(ValueError,IndexError,KeyError):
|
||||||
log("WARNING: rule `%s' is malformed, ignoring"%line)
|
log("WARNING: rule `%s' is malformed, ignoring"%line)
|
||||||
return None
|
return None
|
||||||
|
@ -267,22 +275,22 @@ def write_to_db(filename):
|
||||||
def make_key(s):
|
def make_key(s):
|
||||||
if not s: return s
|
if not s: return s
|
||||||
s=s.lower()
|
s=s.lower()
|
||||||
for i in xrange(len(s)):
|
for i in range(len(s)):
|
||||||
if s[i].isdigit(): break
|
if s[i].isdigit(): break
|
||||||
if not s[i].isdigit(): return s
|
if not s[i].isdigit(): return s
|
||||||
for j in xrange(i,len(s)):
|
for j in range(i,len(s)):
|
||||||
if not s[j].isdigit(): break
|
if not s[j].isdigit(): break
|
||||||
if s[j].isdigit(): j+=1
|
if s[j].isdigit(): j+=1
|
||||||
return (s[:i],int(s[i:j]),make_key(s[j:]))
|
return (s[:i],int(s[i:j]),make_key(s[j:]))
|
||||||
|
|
||||||
def key_repr(x):
|
def key_repr(x):
|
||||||
if type(x)==types.TupleType:
|
if type(x)==tuple:
|
||||||
return "%s%d%s"%(x[0],x[1],key_repr(x[2]))
|
return "%s%d%s"%(x[0],x[1],key_repr(x[2]))
|
||||||
else:
|
else:
|
||||||
return x
|
return x
|
||||||
|
|
||||||
def cmp_key(a,b):
|
def cmp_key(a,b):
|
||||||
if type(a)==types.TupleType and type(b)==types.TupleType:
|
if type(a)==tuple and type(b)==tuple:
|
||||||
return cmp(a[0],b[0]) or cmp(a[1],b[1]) or cmp_key(a[2],b[2])
|
return cmp(a[0],b[0]) or cmp(a[1],b[1]) or cmp_key(a[2],b[2])
|
||||||
else:
|
else:
|
||||||
return cmp(key_repr(a),key_repr(b))
|
return cmp(key_repr(a),key_repr(b))
|
||||||
|
@ -316,7 +324,7 @@ def browse(path, interactive):
|
||||||
if interactive:
|
if interactive:
|
||||||
while 1:
|
while 1:
|
||||||
try:
|
try:
|
||||||
choice=raw_input("include `%s'? [(Y)es, (N)o, (A)ll] "%displaypath)[:1].lower()
|
choice=input("include `%s'? [(Y)es, (N)o, (A)ll] "%displaypath)[:1].lower()
|
||||||
except EOFError:
|
except EOFError:
|
||||||
raise KeyboardInterrupt
|
raise KeyboardInterrupt
|
||||||
if not choice: continue
|
if not choice: continue
|
||||||
|
@ -329,17 +337,17 @@ def browse(path, interactive):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
files=filter(None,[file_entry(path,name) for name in os.listdir(path)])
|
files=[_f for _f in [file_entry(path,name) for name in os.listdir(path)] if _f]
|
||||||
except OSError:
|
except OSError:
|
||||||
return
|
return
|
||||||
|
|
||||||
if path=="./iPod_Control/Music":
|
if path=="./iPod_Control/Music":
|
||||||
subdirs=[x[2] for x in files if not x[0]]
|
subdirs=[x[2] for x in files if not x[0]]
|
||||||
files=filter(lambda x: x[0], files)
|
files=[x for x in files if x[0]]
|
||||||
for dir in subdirs:
|
for dir in subdirs:
|
||||||
subpath="%s/%s"%(path,dir)
|
subpath="%s/%s"%(path,dir)
|
||||||
try:
|
try:
|
||||||
files.extend(filter(lambda x: x and x[0],[file_entry(subpath,name,dir+"/") for name in os.listdir(subpath)]))
|
files.extend([x for x in [file_entry(subpath,name,dir+"/") for name in os.listdir(subpath)] if x and x[0]])
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -384,7 +392,7 @@ def make_playback_state(volume=None):
|
||||||
a.fromstring(f.read())
|
a.fromstring(f.read())
|
||||||
PState=a.tolist()
|
PState=a.tolist()
|
||||||
f.close()
|
f.close()
|
||||||
except IOError,EOFError:
|
except IOError as EOFError:
|
||||||
del PState[:]
|
del PState[:]
|
||||||
if len(PState)!=21:
|
if len(PState)!=21:
|
||||||
PState=listval(29)+[0]*15+listval(1) # volume 29, FW ver 1.0
|
PState=listval(29)+[0]*15+listval(1) # volume 29, FW ver 1.0
|
||||||
|
@ -419,24 +427,24 @@ def make_stats(count):
|
||||||
|
|
||||||
def smart_shuffle():
|
def smart_shuffle():
|
||||||
try:
|
try:
|
||||||
slice_count=max(map(len,domains))
|
slice_count=max(list(map(len,domains)))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return []
|
return []
|
||||||
slices=[[] for x in xrange(slice_count)]
|
slices=[[] for x in range(slice_count)]
|
||||||
slice_fill=[0]*slice_count
|
slice_fill=[0]*slice_count
|
||||||
|
|
||||||
for d in xrange(len(domains)):
|
for d in range(len(domains)):
|
||||||
used=[]
|
used=[]
|
||||||
if not domains[d]: continue
|
if not domains[d]: continue
|
||||||
for n in domains[d]:
|
for n in domains[d]:
|
||||||
# find slices where the nearest track of the same domain is far away
|
# find slices where the nearest track of the same domain is far away
|
||||||
metric=[min([slice_count]+[min(abs(s-u),abs(s-u+slice_count),abs(s-u-slice_count)) for u in used]) for s in xrange(slice_count)]
|
metric=[min([slice_count]+[min(abs(s-u),abs(s-u+slice_count),abs(s-u-slice_count)) for u in used]) for s in range(slice_count)]
|
||||||
thresh=(max(metric)+1)/2
|
thresh=old_div((max(metric)+1),2)
|
||||||
farthest=[s for s in xrange(slice_count) if metric[s]>=thresh]
|
farthest=[s for s in range(slice_count) if metric[s]>=thresh]
|
||||||
|
|
||||||
# find emptiest slices
|
# find emptiest slices
|
||||||
thresh=(min(slice_fill)+max(slice_fill)+1)/2
|
thresh=old_div((min(slice_fill)+max(slice_fill)+1),2)
|
||||||
emptiest=[s for s in xrange(slice_count) if slice_fill[s]<=thresh if (s in farthest)]
|
emptiest=[s for s in range(slice_count) if slice_fill[s]<=thresh if (s in farthest)]
|
||||||
|
|
||||||
# choose one of the remaining candidates and add the track to the chosen slice
|
# choose one of the remaining candidates and add the track to the chosen slice
|
||||||
s=random.choice(emptiest or farthest)
|
s=random.choice(emptiest or farthest)
|
||||||
|
@ -463,7 +471,7 @@ def make_shuffle(count):
|
||||||
seq=smart_shuffle()
|
seq=smart_shuffle()
|
||||||
else:
|
else:
|
||||||
log("Generating shuffle sequence ...",False)
|
log("Generating shuffle sequence ...",False)
|
||||||
seq=range(count)
|
seq=list(range(count))
|
||||||
random.shuffle(seq)
|
random.shuffle(seq)
|
||||||
try:
|
try:
|
||||||
file("iPod_Control/iTunes/iTunesShuffle","wb").write("".join(map(stringval,seq)))
|
file("iPod_Control/iTunes/iTunesShuffle","wb").write("".join(map(stringval,seq)))
|
||||||
|
@ -484,7 +492,7 @@ def main(dirs):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
f=file("rebuild_db.rules","r")
|
f=file("rebuild_db.rules","r")
|
||||||
Rules+=filter(None,map(ParseRuleLine,f.read().split("\n")))
|
Rules+=[_f for _f in map(ParseRuleLine,f.read().split("\n")) if _f]
|
||||||
f.close()
|
f.close()
|
||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
|
@ -573,8 +581,8 @@ Please make sure that:
|
||||||
|
|
||||||
|
|
||||||
def help():
|
def help():
|
||||||
print "Usage: %s [OPTION]... [DIRECTORY]..."%sys.argv[0]
|
print("Usage: %s [OPTION]... [DIRECTORY]..."%sys.argv[0])
|
||||||
print """Rebuild iPod shuffle database.
|
print("""Rebuild iPod shuffle database.
|
||||||
|
|
||||||
Mandatory arguments to long options are mandatory for short options too.
|
Mandatory arguments to long options are mandatory for short options too.
|
||||||
-h, --help display this help text
|
-h, --help display this help text
|
||||||
|
@ -587,19 +595,19 @@ Mandatory arguments to long options are mandatory for short options too.
|
||||||
-L, --logfile set log file name
|
-L, --logfile set log file name
|
||||||
|
|
||||||
Must be called from the iPod's root directory. By default, the whole iPod is
|
Must be called from the iPod's root directory. By default, the whole iPod is
|
||||||
searched for playable files, unless at least one DIRECTORY is specified."""
|
searched for playable files, unless at least one DIRECTORY is specified.""")
|
||||||
|
|
||||||
|
|
||||||
def opterr(msg):
|
def opterr(msg):
|
||||||
print "parse error:",msg
|
print("parse error:",msg)
|
||||||
print "use `%s -h' to get help"%sys.argv[0]
|
print("use `%s -h' to get help"%sys.argv[0])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def parse_options():
|
def parse_options():
|
||||||
try:
|
try:
|
||||||
opts,args=getopt.getopt(sys.argv[1:],"hiv:snlfL:r",\
|
opts,args=getopt.getopt(sys.argv[1:],"hiv:snlfL:r",\
|
||||||
["help","interactive","volume=","nosmart","nochdir","nolog","force","logfile=","rename"])
|
["help","interactive","volume=","nosmart","nochdir","nolog","force","logfile=","rename"])
|
||||||
except getopt.GetoptError, message:
|
except getopt.GetoptError as message:
|
||||||
opterr(message)
|
opterr(message)
|
||||||
for opt,arg in opts:
|
for opt,arg in opts:
|
||||||
if opt in ("-h","--help"):
|
if opt in ("-h","--help"):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue