From 503dd069c86468c0a3b039f59acc8925f41f562b Mon Sep 17 00:00:00 2001 From: lynxize Date: Fri, 20 Jun 2025 15:16:26 -0600 Subject: [PATCH] finish updating to python 3 --- rebuild_db.py | 86 ++++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/rebuild_db.py b/rebuild_db.py index 929692b..1ef9580 100755 --- a/rebuild_db.py +++ b/rebuild_db.py @@ -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()