Browse Source

symuid-import-cmus: print play count & path if play count > 0

Fabian Peter Hammerle 6 years ago
parent
commit
0a4dd5021a
1 changed files with 37 additions and 14 deletions
  1. 37 14
      symuid-import-cmus

+ 37 - 14
symuid-import-cmus

@@ -11,30 +11,53 @@ import sys
 FILE_PREFIX = b'CTC'
 VERSION_LENGTH = 1
 SUPPORTED_VERSION = b'\x0c'
-LINE_SEPARATOR = b'\xff' * 56
-COLUMN_SEPARATOR = b'\x00'
 # always big endian, see cache_init()
 FLAGS_BYTEORDER = 'big'
 FLAGS_LENGTH = 4
 FLAG_64_BIT = 0x01
 
+
+class Track:
+
+    def __init__(self, cache_size, cache_bytes):
+        """
+        struct cache_entry {
+            // size of this struct including size itself
+            uint32_t size;
+            int32_t play_count;
+            int64_t mtime;
+            int32_t duration;
+            int32_t bitrate;
+            int32_t bpm;
+            uint8_t _reserved[CACHE_ENTRY_RESERVED_SIZE];
+            // filename, codec, codec_profile and N * (key, val)
+            char strings[];
+        };
+        """
+        assert len(cache_bytes) + 4 == cache_size
+        self._play_count = int.from_bytes(cache_bytes[0:4], byteorder=sys.byteorder)
+        self._path = cache_bytes.split(b'\xff' * 56)[1].split(b'\x00')[0]
+        if self._play_count > 0:
+            print(self._play_count, self._path.decode())
+
+
 def symuid_import_cmus(cache_path):
-    with open(os.path.expanduser(cache_path), 'rb') as c:
+    with open(os.path.expanduser(cache_path), 'rb') as cache:
         # see cache.c cache_init()
-        assert c.read(len(FILE_PREFIX)) == FILE_PREFIX
-        cache_version = c.read(VERSION_LENGTH)
+        assert cache.read(len(FILE_PREFIX)) == FILE_PREFIX
+        cache_version = cache.read(VERSION_LENGTH)
         assert cache_version == SUPPORTED_VERSION, cache_version
-        flags = int.from_bytes(c.read(FLAGS_LENGTH), byteorder=FLAGS_BYTEORDER)
+        flags = int.from_bytes(cache.read(FLAGS_LENGTH), byteorder=FLAGS_BYTEORDER)
         # only support 64-bit flag
         assert flags & ~FLAG_64_BIT == 0, flags
-        cache_data = [l.split(COLUMN_SEPARATOR)
-                      for l in c.read().split(LINE_SEPARATOR)]
-    for track_data in cache_data[1:]:
-        track_path, codec, codec_profile = track_data[0:3]
-        if not os.path.exists(track_path):
-            sys.stderr.write('{!r}: not found\n'.format(track_path))
-        else:
-            print(track_path)
+        # size includes size itself
+        while True:
+            size = int.from_bytes(cache.read(4), byteorder=sys.byteorder)
+            if size == 0:
+                break
+            Track(size, cache.read(size - 4))
+            # see cache.c write_ti ALIGN
+            cache.read((-size) % 8)
 
 
 def _init_argparser():