|
@@ -2,75 +2,32 @@
|
|
# -*- coding: utf-8 -*-
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
import datetime as dt
|
|
import datetime as dt
|
|
-import mutagen
|
|
|
|
-import mutagen.id3
|
|
|
|
-import mutagen.mp4
|
|
|
|
import os
|
|
import os
|
|
import re
|
|
import re
|
|
|
|
+import symuid
|
|
import symuid.library.itunes
|
|
import symuid.library.itunes
|
|
import sys
|
|
import sys
|
|
|
|
|
|
|
|
|
|
-def generate_play_count_tag_label(player, library_id, reg_dt):
|
|
|
|
- return 'symuid:pcnt:{}:{}:{}'.format(player, library_id, int(reg_dt.timestamp()))
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-def set_play_count_tag(track_path, player, library_id, reg_dt, play_count):
|
|
|
|
- assert isinstance(reg_dt, dt.datetime), reg_dt
|
|
|
|
- tag_label = generate_play_count_tag_label(
|
|
|
|
- player=player,
|
|
|
|
- library_id=library_id,
|
|
|
|
- reg_dt=reg_dt,
|
|
|
|
- )
|
|
|
|
- track = mutagen.File(filename=track_path)
|
|
|
|
- if isinstance(track.tags, mutagen.id3.ID3):
|
|
|
|
- tag_label_id3 = 'TXXX:' + tag_label
|
|
|
|
- if not tag_label_id3 in track.tags:
|
|
|
|
- # mutagen.id3._specs.EncodedTextSpec.write encodes
|
|
|
|
- # 'desc' and 'text'
|
|
|
|
- tag = mutagen.id3.TXXX(
|
|
|
|
- encoding=mutagen.id3.Encoding.LATIN1,
|
|
|
|
- desc=tag_label,
|
|
|
|
- text=[str(play_count)],
|
|
|
|
- )
|
|
|
|
- track.tags.add(tag)
|
|
|
|
- track.save()
|
|
|
|
- print('{!r}: set ID3 tag {!r}'.format(track_path, tag))
|
|
|
|
- elif isinstance(track.tags, mutagen.mp4.MP4Tags):
|
|
|
|
- tag_label_mp4 = '----:' + tag_label
|
|
|
|
- if not tag_label_mp4 in track.tags:
|
|
|
|
- track.tags[tag_label_mp4] = tag = mutagen.mp4.MP4FreeForm(
|
|
|
|
- # "a signed big-endian integer with length one of { 1,2,3,4,8 } bytes"
|
|
|
|
- # TODO set byte length properly
|
|
|
|
- # setting signed=True just to be explicit here
|
|
|
|
- # (irrelevant for positive integers)
|
|
|
|
- data=play_count.to_bytes(1, byteorder='big', signed=True),
|
|
|
|
- dataformat=mutagen.mp4.AtomDataType.INTEGER,
|
|
|
|
- )
|
|
|
|
- track.save()
|
|
|
|
- print('{!r}: set MP4 tag {!r}'.format(track_path, tag))
|
|
|
|
- else:
|
|
|
|
- raise Exception(track_path)
|
|
|
|
-
|
|
|
|
-
|
|
|
|
def symuid_import_itunes(xml_library_path, path_regex_sub):
|
|
def symuid_import_itunes(xml_library_path, path_regex_sub):
|
|
lib = symuid.library.itunes.XmlLibrary(xml_library_path)
|
|
lib = symuid.library.itunes.XmlLibrary(xml_library_path)
|
|
- for track in lib.tracks:
|
|
+ for itunes_track in lib.tracks:
|
|
# TODO create tag if last_play_dt is None
|
|
# TODO create tag if last_play_dt is None
|
|
- if track.last_play_dt and track.local:
|
|
+ if itunes_track.last_play_dt and itunes_track.local:
|
|
- track_path = track.local_path
|
|
+ track_path = itunes_track.local_path
|
|
for pattern, repl in path_regex_sub:
|
|
for pattern, repl in path_regex_sub:
|
|
track_path = re.sub(pattern, repl, track_path)
|
|
track_path = re.sub(pattern, repl, track_path)
|
|
if not os.path.exists(track_path):
|
|
if not os.path.exists(track_path):
|
|
sys.stderr.write('{!r}: not found\n'.format(track_path))
|
|
sys.stderr.write('{!r}: not found\n'.format(track_path))
|
|
else:
|
|
else:
|
|
|
|
+ symuid_track = symuid.Track(path=track_path)
|
|
# TODO dt=dt.datetime.now()
|
|
# TODO dt=dt.datetime.now()
|
|
- set_play_count_tag(
|
|
+ symuid_track.register_play_count(
|
|
- track_path=track_path,
|
|
|
|
player='itunes',
|
|
player='itunes',
|
|
library_id=lib.id,
|
|
library_id=lib.id,
|
|
- reg_dt=track.last_play_dt,
|
|
+ register_dt=itunes_track.last_play_dt,
|
|
- play_count=track.play_count,
|
|
+ play_count=itunes_track.play_count,
|
|
|
|
+ tag_set_cb=lambda tr, tag: print('{!r}: set tag {!r}'.format(tr.path, tag)),
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|