TonieToolbox 0.6.0rc3__py3-none-any.whl → 0.6.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -195,6 +195,101 @@ def get_file_tags(file_path: str) -> Dict[str, Any]:
195
195
  logger.error("Error reading tags from file %s: %s", file_path, str(e))
196
196
  return tags
197
197
 
198
+ def get_all_file_tags(file_path: str) -> Dict[str, Any]:
199
+ """
200
+ Extract ALL metadata tags from an audio file, excluding artwork/picture data.
201
+
202
+ This function returns all tags present in the file, not just the ones
203
+ defined in TAG_MAPPINGS. Tag names are returned as-is from the file format.
204
+ APIC (Attached Picture) tags and other artwork-related tags are excluded.
205
+
206
+ Args:
207
+ file_path: Path to the audio file
208
+
209
+ Returns:
210
+ Dictionary containing all tag names and values found in the file
211
+ (excluding artwork/picture tags)
212
+ """
213
+ global MUTAGEN_AVAILABLE
214
+
215
+ if not MUTAGEN_AVAILABLE:
216
+ if ensure_mutagen(auto_install=True):
217
+ if not _import_mutagen():
218
+ logger.warning("Mutagen library not available. Cannot read media tags.")
219
+ return {}
220
+ else:
221
+ logger.warning("Mutagen library not available. Cannot read media tags.")
222
+ return {}
223
+
224
+ logger.debug("Reading all tags from file: %s", file_path)
225
+ tags = {}
226
+
227
+ try:
228
+ audio = mutagen.File(file_path)
229
+ if audio is None:
230
+ logger.warning("Could not identify file format: %s", file_path)
231
+ return tags
232
+ if isinstance(audio, ID3) or hasattr(audio, 'ID3'):
233
+ try:
234
+ id3 = audio if isinstance(audio, ID3) else audio.ID3
235
+ for tag_key, tag_value in id3.items():
236
+ # Skip APIC (Attached Picture) tags
237
+ if hasattr(tag_value, 'FrameID') and tag_value.FrameID == 'APIC':
238
+ continue
239
+ tag_value_str = str(tag_value)
240
+ tags[tag_key] = normalize_tag_value(tag_value_str)
241
+ except (AttributeError, TypeError) as e:
242
+ logger.debug("Error accessing ID3 tags: %s", e)
243
+ try:
244
+ if hasattr(audio, 'tags') and audio.tags:
245
+ for tag_key in audio.tags.keys():
246
+ if tag_key.startswith('APIC'):
247
+ continue
248
+ tag_value = audio.tags[tag_key]
249
+ if hasattr(tag_value, 'text'):
250
+ tag_value_str = str(tag_value.text[0]) if tag_value.text else ''
251
+ else:
252
+ tag_value_str = str(tag_value)
253
+ tags[tag_key] = normalize_tag_value(tag_value_str)
254
+ except Exception as e:
255
+ logger.debug("Alternative ID3 tag reading failed: %s", e)
256
+ elif isinstance(audio, (FLAC, OggOpus, OggVorbis)):
257
+ for tag_key, tag_values in audio.items():
258
+ if tag_key.lower() in ('metadata_block_picture', 'coverart', 'cover'):
259
+ continue
260
+ tag_value = tag_values[0] if tag_values else ''
261
+ tags[tag_key] = normalize_tag_value(tag_value)
262
+ elif isinstance(audio, MP4):
263
+ for tag_key, tag_value in audio.items():
264
+ # Skip cover art (covr atom)
265
+ if tag_key == 'covr':
266
+ continue
267
+ if isinstance(tag_value, list):
268
+ if tag_key in ('trkn', 'disk'):
269
+ if tag_value and isinstance(tag_value[0], tuple) and len(tag_value[0]) >= 1:
270
+ tags[tag_key] = str(tag_value[0][0])
271
+ else:
272
+ tag_value_str = str(tag_value[0]) if tag_value else ''
273
+ tags[tag_key] = normalize_tag_value(tag_value_str)
274
+ else:
275
+ tag_value_str = str(tag_value)
276
+ tags[tag_key] = normalize_tag_value(tag_value_str)
277
+ else:
278
+ for tag_key, tag_value in audio.items():
279
+ if isinstance(tag_value, list):
280
+ tag_value_str = str(tag_value[0]) if tag_value else ''
281
+ tags[tag_key] = normalize_tag_value(tag_value_str)
282
+ else:
283
+ tag_value_str = str(tag_value)
284
+ tags[tag_key] = normalize_tag_value(tag_value_str)
285
+
286
+ logger.debug("Successfully read %d total tags from file", len(tags))
287
+ logger.debug("All tags: %s", str(tags))
288
+ return tags
289
+ except Exception as e:
290
+ logger.error("Error reading all tags from file %s: %s", file_path, str(e))
291
+ return tags
292
+
198
293
  def extract_first_audio_file_tags(folder_path: str) -> Dict[str, str]:
199
294
  """
200
295
  Extract tags from the first audio file in a folder.