finish updating to python 3
This commit is contained in:
parent
d0d8588e5f
commit
503dd069c8
1 changed files with 44 additions and 42 deletions
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import functools
|
||||
# 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
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
|
@ -14,18 +14,11 @@
|
|||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from builtins import chr
|
||||
from builtins import input
|
||||
from builtins import map
|
||||
from builtins import range
|
||||
from functools import reduce
|
||||
|
||||
from past.builtins import cmp
|
||||
from past.utils import old_div
|
||||
|
||||
__title__ = "KeyJ's iPod shuffle Database Builder"
|
||||
__version__ = "1.0"
|
||||
__author__ = "Martin Fiedler"
|
||||
|
@ -112,7 +105,7 @@ def open_log():
|
|||
global logfile
|
||||
if Options['logging']:
|
||||
try:
|
||||
logfile = file(Options['logfile'], "w")
|
||||
logfile = open(Options['logfile'], "w")
|
||||
except IOError:
|
||||
logfile = None
|
||||
else:
|
||||
|
@ -166,11 +159,11 @@ def MatchRule(props, rule):
|
|||
if rule[1] == '~':
|
||||
return fnmatch.fnmatchcase(prop.lower(), ref.lower())
|
||||
elif rule[1] == '=':
|
||||
return cmp(prop, ref) == 0
|
||||
return prop == ref
|
||||
elif rule[1] == '>':
|
||||
return cmp(prop, ref) > 0
|
||||
return prop > ref
|
||||
elif rule[1] == '<':
|
||||
return cmp(prop, ref) < 0
|
||||
return prop < ref
|
||||
else:
|
||||
return False
|
||||
|
||||
|
@ -193,7 +186,7 @@ def ParseRule(rule):
|
|||
|
||||
|
||||
def ParseAction(action):
|
||||
prop, value = list(map(string.strip, action.split('=', 1)))
|
||||
prop, value = list(map(str.strip, action.split('=', 1)))
|
||||
if not prop in KnownProps:
|
||||
log("WARNING: unknown property `%s'" % prop)
|
||||
return (prop, ParseValue(value))
|
||||
|
@ -201,12 +194,12 @@ def ParseAction(action):
|
|||
|
||||
def ParseRuleLine(line):
|
||||
line = line.strip()
|
||||
if not (line) or line[0] == "#":
|
||||
if not line or line[0] == "#":
|
||||
return None
|
||||
try:
|
||||
# split line into "ruleset: action"
|
||||
tmp = line.split(":")
|
||||
ruleset = list(map(string.strip, ":".join(tmp[:-1]).split(",")))
|
||||
ruleset = list(map(str.strip, ":".join(tmp[:-1]).split(",")))
|
||||
actions = dict(list(map(ParseAction, tmp[-1].split(","))))
|
||||
if len(ruleset) == 1 and not (ruleset[0]):
|
||||
return ([], actions)
|
||||
|
@ -215,7 +208,6 @@ def ParseRuleLine(line):
|
|||
except OSError: # (ValueError,IndexError,KeyError):
|
||||
log("WARNING: rule `%s' is malformed, ignoring" % line)
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
################################################################################
|
||||
|
@ -269,12 +261,12 @@ def write_to_db(filename):
|
|||
entry = props['reuse'] and (filename in KnownEntries) and KnownEntries[filename]
|
||||
if not entry:
|
||||
header[29] = props['type']
|
||||
entry = header.tostring() + \
|
||||
"".join([c + "\0" for c in filename[:261]]) + \
|
||||
"\0" * (525 - 2 * len(filename))
|
||||
entry = header.tobytes() + \
|
||||
("".join([c + "\0" for c in filename[:261]]) + \
|
||||
"\0" * (525 - 2 * len(filename))).encode()
|
||||
|
||||
# write entry, modifying shuffleflag and bookmarkflag at least
|
||||
iTunesSD.write(entry[:555] + chr(props['shuffle']) + chr(props['bookmark']) + entry[557])
|
||||
iTunesSD.write(entry[:555] + bytes([props['shuffle']]) + bytes([props['bookmark']]) + bytes([entry[557]]))
|
||||
if props['shuffle']: domains[-1].append(total_count)
|
||||
total_count += 1
|
||||
return 1
|
||||
|
@ -294,7 +286,7 @@ def make_key(s):
|
|||
|
||||
def key_repr(x):
|
||||
if type(x) == tuple:
|
||||
return "%s%d%s" % (x[0], x[1], key_repr(x[2]))
|
||||
return b"%s%d%s" % (x[0], x[1], key_repr(x[2]))
|
||||
else:
|
||||
return x
|
||||
|
||||
|
@ -305,9 +297,14 @@ def cmp_key(a, b):
|
|||
else:
|
||||
return cmp(key_repr(a), key_repr(b))
|
||||
|
||||
def cmp(a, b):
|
||||
if a < b: return -1
|
||||
elif a > b: return 1
|
||||
else: return 0
|
||||
|
||||
|
||||
def file_entry(path, name, prefix=""):
|
||||
if not (name) or name[0] == ".": return None
|
||||
if not name or name[0] == ".": return None
|
||||
fullname = "%s/%s" % (path, name)
|
||||
may_rename = not (fullname.startswith("./iPod_Control")) and Options['rename']
|
||||
try:
|
||||
|
@ -315,10 +312,10 @@ def file_entry(path, name, prefix=""):
|
|||
return None
|
||||
if os.path.isdir(fullname):
|
||||
if may_rename: name = rename_safely(path, name)
|
||||
return (0, make_key(name), prefix + name)
|
||||
return 0, make_key(name), prefix + name
|
||||
if os.path.splitext(name)[1].lower() in (".mp3", ".m4a", ".m4b", ".m4p", ".aa", ".wav"):
|
||||
if may_rename: name = rename_safely(path, name)
|
||||
return (1, make_key(name), prefix + name)
|
||||
return 1, make_key(name), prefix + name
|
||||
except OSError:
|
||||
pass
|
||||
return None
|
||||
|
@ -362,7 +359,7 @@ def browse(path, interactive):
|
|||
except OSError:
|
||||
pass
|
||||
|
||||
files.sort(cmp_key)
|
||||
files.sort(key = functools.cmp_to_key(cmp_key))
|
||||
count = len([None for x in files if x[0]])
|
||||
if count: domains.append([])
|
||||
|
||||
|
@ -385,7 +382,7 @@ def browse(path, interactive):
|
|||
|
||||
def stringval(i):
|
||||
if i < 0: i += 0x1000000
|
||||
return "%c%c%c" % (i & 0xFF, (i >> 8) & 0xFF, (i >> 16) & 0xFF)
|
||||
return b"%c%c%c" % (i & 0xFF, (i >> 8) & 0xFF, (i >> 16) & 0xFF)
|
||||
|
||||
|
||||
def listval(i):
|
||||
|
@ -399,20 +396,21 @@ def make_playback_state(volume=None):
|
|||
log("Setting playback state ...", False)
|
||||
PState = []
|
||||
try:
|
||||
f = file("iPod_Control/iTunes/iTunesPState", "rb")
|
||||
f = open("iPod_Control/iTunes/iTunesPState", "rb")
|
||||
a = array.array('B')
|
||||
a.fromstring(f.read())
|
||||
a.frombytes(f.read())
|
||||
PState = a.tolist()
|
||||
f.close()
|
||||
except IOError as EOFError:
|
||||
except IOError:
|
||||
del PState[:]
|
||||
if len(PState) != 21:
|
||||
PState = listval(29) + [0] * 15 + listval(1) # volume 29, FW ver 1.0
|
||||
#if len(PState) != 21:
|
||||
# print("catstare")
|
||||
# PState = listval(29) + [0] * 15 + listval(1) # volume 29, FW ver 1.0
|
||||
PState[3:15] = [0] * 6 + [1] + [0] * 5 # track 0, shuffle mode, start of track
|
||||
if volume is not None:
|
||||
PState[:3] = listval(volume)
|
||||
try:
|
||||
f = file("iPod_Control/iTunes/iTunesPState", "wb")
|
||||
f = open("iPod_Control/iTunes/iTunesPState", "wb")
|
||||
array.array('B', PState).tofile(f)
|
||||
f.close()
|
||||
except IOError:
|
||||
|
@ -425,8 +423,9 @@ def make_playback_state(volume=None):
|
|||
def make_stats(count):
|
||||
log("Creating statistics file ...", False)
|
||||
try:
|
||||
file("iPod_Control/iTunes/iTunesStats", "wb").write( \
|
||||
stringval(count) + "\0" * 3 + (stringval(18) + "\xff" * 3 + "\0" * 12) * count)
|
||||
file = open("iPod_Control/iTunes/iTunesStats", "wb")
|
||||
file.write(stringval(count) + b"\0" * 3 + (stringval(18) + b"\xff" * 3 + b"\0" * 12) * count)
|
||||
file.close()
|
||||
except IOError:
|
||||
log("FAILED.")
|
||||
return 0
|
||||
|
@ -453,11 +452,11 @@ def smart_shuffle():
|
|||
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 = old_div((max(metric) + 1), 2)
|
||||
thresh = (max(metric) + 1) // 2
|
||||
farthest = [s for s in range(slice_count) if metric[s] >= thresh]
|
||||
|
||||
# find emptiest slices
|
||||
thresh = old_div((min(slice_fill) + max(slice_fill) + 1), 2)
|
||||
thresh = (min(slice_fill) + max(slice_fill) + 1) // 2
|
||||
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
|
||||
|
@ -488,7 +487,8 @@ def make_shuffle(count):
|
|||
seq = list(range(count))
|
||||
random.shuffle(seq)
|
||||
try:
|
||||
file("iPod_Control/iTunes/iTunesShuffle", "wb").write("".join(map(stringval, seq)))
|
||||
with open("iPod_Control/iTunes/iTunesShuffle", "wb") as file:
|
||||
file.write(b"".join(map(stringval, seq)))
|
||||
except IOError:
|
||||
log("FAILED.")
|
||||
return 0
|
||||
|
@ -505,7 +505,7 @@ def main(dirs):
|
|||
log()
|
||||
|
||||
try:
|
||||
f = file("rebuild_db.rules", "r")
|
||||
f = open("rebuild_db.rules", "r")
|
||||
Rules += [_f for _f in map(ParseRuleLine, f.read().split("\n")) if _f]
|
||||
f.close()
|
||||
except IOError:
|
||||
|
@ -521,13 +521,13 @@ Please make sure that:
|
|||
header = array.array('B')
|
||||
iTunesSD = None
|
||||
try:
|
||||
iTunesSD = file("iPod_Control/iTunes/iTunesSD", "rb")
|
||||
iTunesSD = open("iPod_Control/iTunes/iTunesSD", "rb")
|
||||
header.fromfile(iTunesSD, 51)
|
||||
if Options['reuse']:
|
||||
iTunesSD.seek(18)
|
||||
entry = iTunesSD.read(558)
|
||||
while len(entry) == 558:
|
||||
filename = entry[33::2].split("\0", 1)[0]
|
||||
filename = entry[33::2].split(b"\0", 1)[0]
|
||||
KnownEntries[filename] = entry
|
||||
entry = iTunesSD.read(558)
|
||||
except (IOError, EOFError):
|
||||
|
@ -551,7 +551,7 @@ Please make sure that:
|
|||
|
||||
log()
|
||||
try:
|
||||
iTunesSD = file("iPod_Control/iTunes/iTunesSD", "wb")
|
||||
iTunesSD = open("iPod_Control/iTunes/iTunesSD", "wb")
|
||||
header[:18].tofile(iTunesSD)
|
||||
except IOError:
|
||||
log("""ERROR: Cannot write to the iPod database file (iTunesSD)!
|
||||
|
@ -572,7 +572,7 @@ Please make sure that:
|
|||
log()
|
||||
log("Fixing iTunesSD header.")
|
||||
iTunesSD.seek(0)
|
||||
iTunesSD.write("\0%c%c" % (total_count >> 8, total_count & 0xFF))
|
||||
iTunesSD.write(b"\0%c%c" % (total_count >> 8, total_count & 0xFF))
|
||||
iTunesSD.close()
|
||||
except IOError:
|
||||
log("ERROR: Some strange errors occured while writing iTunesSD.")
|
||||
|
@ -625,6 +625,8 @@ def parse_options():
|
|||
"logfile=", "rename"])
|
||||
except getopt.GetoptError as message:
|
||||
opterr(message)
|
||||
sys.exit(1)
|
||||
|
||||
for opt, arg in opts:
|
||||
if opt in ("-h", "--help"):
|
||||
help()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue