automated futurize pass

This commit is contained in:
lynxize 2025-06-20 08:55:00 -06:00
parent db2a7650d4
commit 66fe9bc514
Signed by: lynxize
GPG key ID: 8615849B8532CD77

View file

@ -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"):