I suspect your 'tags' is not a dict object, but some extension of it. Lookup its type, or the documentation of the library you are using for how to retrieve values from an ID3 object.
Python
Welcome to the Python community on the programming.dev Lemmy instance!
π Events
Past
November 2023
- PyCon Ireland 2023, 11-12th
- PyData Tel Aviv 2023 14th
October 2023
- PyConES Canarias 2023, 6-8th
- DjangoCon US 2023, 16-20th (!django π¬)
July 2023
- PyDelhi Meetup, 2nd
- PyCon Israel, 4-5th
- DFW Pythoneers, 6th
- Django Girls Abraka, 6-7th
- SciPy 2023 10-16th, Austin
- IndyPy, 11th
- Leipzig Python User Group, 11th
- Austin Python, 12th
- EuroPython 2023, 17-23rd
- Austin Python: Evening of Coding, 18th
- PyHEP.dev 2023 - "Python in HEP" Developer's Workshop, 25th
August 2023
- PyLadies Dublin, 15th
- EuroSciPy 2023, 14-18th
September 2023
- PyData Amsterdam, 14-16th
- PyCon UK, 22nd - 25th
π Python project:
- Python
- Documentation
- News & Blog
- Python Planet blog aggregator
π Python Community:
- #python IRC for general questions
- #python-dev IRC for CPython developers
- PySlackers Slack channel
- Python Discord server
- Python Weekly newsletters
- Mailing lists
- Forum
β¨ Python Ecosystem:
π Fediverse
Communities
- #python on Mastodon
- c/django on programming.dev
- c/pythorhead on lemmy.dbzer0.com
Projects
- PythΓΆrhead: a Python library for interacting with Lemmy
- Plemmy: a Python package for accessing the Lemmy API
- pylemmy pylemmy enables simple access to Lemmy's API with Python
- mastodon.py, a Python wrapper for the Mastodon API
Feeds
Looking at the docs, it looks like it's an instance of ID3Tags
, which appears to be based on couple of helper classes mutagen._util.DictProxy
and mutagen._tags.Tags
, where DictProxy
(and its base DictMixin
) provides the dict-like interface. Underneath that, it looks like it's storing the actual values in a simple dict
(DictProxy.__dict
) and proxying to that.
I'm not seeing anything obvious that would muck with the incoming lookup key anywhere in ID3Tags
or DictProxy.__getitem__
or any of the other base classes.
I have to jump off to pack for a trip, but might try this out later in a live shell session to see if there's something odd going on with the API.
In the meantime, OP, are you positive you were looking at the same file each time? Was this in a script or in a live Python shell session?
So I tried all the different methods you mentioned but everyone fails and so when I took a deep breath, I figured that I'm probably not understanding properly how it works.
I can say this without a doubt though, the needless complexity regarding these rating tags is stupid. I don't understand why people thought this made sense. It's illogical!
For testing purposes, same file every time, this one: https://file.coffee/u/IxKmfKfUwgPybq_vv8YJc.mp3
This is strange. I tried your snippet with your file and it works for me:
(env) β testing cat x.py
from mutagen.id3 import ID3
tags = ID3("myfile.mp3")
print(tags["TXXX:FMPS_Rating_Amarok_Score"])
(env) β testing python x.py
0.78
I'm getting 0.66 when I do get a rating. But I'm definitely not getting that to print. Here's the full file
import os
import mutagen
import requests
import urllib.parse
from mutagen.easyid3 import EasyID3
from mutagen.id3 import ID3
from pprint import pprint
# Navidrome credentials
navidrome_url = "http://navidrome.local:4533"
navidrome_username = "your-username"
navidrome_password = "your-password"
hex_encoded_pass = navidrome_password.encode().hex()
headers = None
# Directory containing MP3 files
mp3_directory = "/nfs"
def extract_rating(mp3_file):
global rating
audio = mutagen.File(mp3_file)
tags = ID3(mp3_file)
print(tags["TXXX:FMPS_Rating_AMarok_Score"]) #Gives KeyError
for frame in tags.getall("TXXX"):
rating = frame #This is terrible. The last key is the rating and since I can't call it by the key, I'm just refilling the variable
print(rating)
# It was moaning about strings and floats, so commented out
# if rating >= 1.0:
# return 5
# elif rating >= 0.8:
# return 4
# elif rating >= 0.6:
# return 3
# elif rating >= 0.4:
# return 2
# elif rating >= 0.2:
# return 1
# else:
# return 0
# return rating
def update_rating_on_navidrome(track_id, rating):
url = f"{navidrome_url}/rest/setRating?id={track_id}&u={navidrome_username}&p=enc: {hex_encoded_pass}&v=1.12.0&rating={rating}"
data = {"rating": rating}
response = requests.get(url, headers=headers, json=data)
def find_track_id_on_navidrome(mp3_file):
url = urllib.parse(url)
url = f"{navidrome_url}/rest/getSong?path={mp3_file.encode()}&u={navidrome_username}&p=enc: {hex_encoded_pass}&v=1.12.0"
response = requests.get(url, headers=headers, json=data)
return url[track_id]
if response.status_code == 204:
print(f"Rating updated successfully for track {track_id}")
else:
print(f"Failed to update rating for track {track_id}: {response.text}")
print("hello")
#test =
print(os.listdir(mp3_directory))
for foldername in os.listdir(mp3_directory):
folderpath = "/".join([mp3_directory, foldername])
for filename in os.listdir(folderpath):
if filename.endswith(".mp3"):
mp3_file = "/".join([folderpath, filename])
rating = extract_rating(mp3_file)
print(mp3_file, rating, sep= "_____")
print(rating)
#
# # Implement logic to find the track ID on Navidrome based on filename or other metadata
# track_id = find_track_id_on_navidrome(filename) # Replace with your implementation#
#
# if track_id:
# update_rating_on_navidrome(track_id, rating)
# else:
# print(f"Track ID not found on Navidrome for {filename}")
Have I called something erroneously that would mess it up?
Sorry if it's terrible to read, up until I started trying to do this, I had never touched Python before and haven't attempted to code for years.
Dict keys are case sensitive in python. In your code I can see the key you've used has a capital M in Amarok. Maybe that's the issue here
Thanks that was really helpful