feat: add quality_score field to Track model and update related functionality

Fixes #51
This commit is contained in:
Kamil
2024-12-11 20:33:13 +00:00
parent b877ee04e3
commit 4d9e6162fc
4 changed files with 50 additions and 4 deletions

View File

@@ -59,8 +59,11 @@ class Track(db.Model):
download_status = db.Column(db.String(2048), nullable=True) download_status = db.Column(db.String(2048), nullable=True)
provider_id = db.Column(db.String(20)) provider_id = db.Column(db.String(20))
# Many-to-Many relationship with Playlists # Many-to-Many relationship with Playlists
playlists = db.relationship('Playlist', secondary=playlist_tracks, back_populates='tracks') playlists = db.relationship('Playlist', secondary=playlist_tracks, back_populates='tracks')
lidarr_processed = db.Column(db.Boolean(), default=False) lidarr_processed = db.Column(db.Boolean(), default=False)
quality_score = db.Column(db.Float(), default=0)
def __repr__(self): def __repr__(self):
return f'<Track {self.name}:{self.provider_track_id}>' return f'<Track {self.name}:{self.provider_track_id}>'

View File

@@ -418,11 +418,18 @@ def update_jellyfin_id_for_downloaded_tracks(self):
app.logger.info("Starting Jellyfin ID update for tracks...") app.logger.info("Starting Jellyfin ID update for tracks...")
with app.app_context(): with app.app_context():
downloaded_tracks = Track.query.filter_by(downloaded=True, jellyfin_id=None).all()
downloaded_tracks = Track.query.filter(
Track.downloaded == True,
Track.jellyfin_id == None,
(Track.quality_score < app.config['QUALITY_SCORE_THRESHOLD']) | (Track.quality_score == None)
).all()
if task_manager.acquire_lock(full_update_key, expiration=60*60*24): if task_manager.acquire_lock(full_update_key, expiration=60*60*24):
app.logger.info(f"performing full update on jellyfin track ids. (Update tracks and playlists if better quality will be found)") app.logger.info(f"performing full update on jellyfin track ids. (Update tracks and playlists if better quality will be found)")
downloaded_tracks = Track.query.all() app.logger.info(f"\tQUALITY_SCORE_THRESHOLD = {app.config['QUALITY_SCORE_THRESHOLD']}")
downloaded_tracks = Track.query.filter(
(Track.quality_score < app.config['QUALITY_SCORE_THRESHOLD']) | (Track.quality_score == None)
).all()
else: else:
app.logger.debug(f"doing update on tracks with downloaded = True and jellyfin_id = None") app.logger.debug(f"doing update on tracks with downloaded = True and jellyfin_id = None")
total_tracks = len(downloaded_tracks) total_tracks = len(downloaded_tracks)
@@ -436,6 +443,7 @@ def update_jellyfin_id_for_downloaded_tracks(self):
for track in downloaded_tracks: for track in downloaded_tracks:
try: try:
best_match = find_best_match_from_jellyfin(track) best_match = find_best_match_from_jellyfin(track)
if best_match: if best_match:
track.downloaded = True track.downloaded = True
if track.jellyfin_id != best_match['Id']: if track.jellyfin_id != best_match['Id']:
@@ -445,7 +453,7 @@ def update_jellyfin_id_for_downloaded_tracks(self):
track.filesystem_path = best_match['Path'] track.filesystem_path = best_match['Path']
app.logger.info(f"Updated filesystem_path for track: {track.name} ({track.provider_track_id})") app.logger.info(f"Updated filesystem_path for track: {track.name} ({track.provider_track_id})")
track.quality_score = best_match['quality_score']
db.session.commit() db.session.commit()
else: else:
@@ -611,7 +619,9 @@ def find_best_match_from_jellyfin(track: Track):
if quality_score > best_quality_score: if quality_score > best_quality_score:
best_match = result best_match = result
best_quality_score = quality_score best_quality_score = quality_score
# attach the quality_score to the best_match
if best_match:
best_match['quality_score'] = best_quality_score
return best_match return best_match
except Exception as e: except Exception as e:
app.logger.error(f"Error searching Jellyfin for track {track.name}: {str(e)}") app.logger.error(f"Error searching Jellyfin for track {track.name}: {str(e)}")

View File

@@ -34,6 +34,7 @@ class Config:
CHECK_FOR_UPDATES = os.getenv('CHECK_FOR_UPDATES','true').lower() == 'true' CHECK_FOR_UPDATES = os.getenv('CHECK_FOR_UPDATES','true').lower() == 'true'
SPOTDL_PROXY = os.getenv('SPOTDL_PROXY',None) SPOTDL_PROXY = os.getenv('SPOTDL_PROXY',None)
SPOTDL_OUTPUT_FORMAT = os.getenv('SPOTDL_OUTPUT_FORMAT','__jellyplist/{artist}-{title}.mp3') SPOTDL_OUTPUT_FORMAT = os.getenv('SPOTDL_OUTPUT_FORMAT','__jellyplist/{artist}-{title}.mp3')
QUALITY_SCORE_THRESHOLD = float(os.getenv('QUALITY_SCORE_THRESHOLD',1000.0))
# SpotDL specific configuration # SpotDL specific configuration
SPOTDL_CONFIG = { SPOTDL_CONFIG = {
'cookie_file': '/jellyplist/cookies.txt', 'cookie_file': '/jellyplist/cookies.txt',

View File

@@ -0,0 +1,32 @@
"""Add quality score to Track
Revision ID: 2777a1885a6b
Revises: 46a65ecc9904
Create Date: 2024-12-11 20:02:00.303765
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '2777a1885a6b'
down_revision = '46a65ecc9904'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('track', schema=None) as batch_op:
batch_op.add_column(sa.Column('quality_score', sa.Float(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('track', schema=None) as batch_op:
batch_op.drop_column('quality_score')
# ### end Alembic commands ###