finish updating to python 3

This commit is contained in:
lynxize 2025-06-20 15:16:26 -06:00
parent d0d8588e5f
commit 503dd069c8
Signed by: lynxize
GPG key ID: 8615849B8532CD77

View file

@ -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()