import logging from django.db.models.signals import post_delete, post_save from django.dispatch import receiver from django.utils import timezone from scrobbles.models import FavoriteMedia, Scrobble from scrobbles.tasks import ( add_favorite_to_mopidy_playlist, CHARTABLE_MEDIA_TYPES, remove_favorite_from_mopidy_playlist, SCROBBLES_WITHOUT_CHARTS, update_charts_for_timestamp, ) from scrobbles.utils import tokenize_title_to_tags logger = logging.getLogger(__name__) @receiver(post_save, sender=Scrobble) def update_charts_on_scrobble_complete(sender, instance, **kwargs): if not instance.played_to_completion: return if instance.timestamp is None: return if instance.media_type.lower() in SCROBBLES_WITHOUT_CHARTS: return if instance.media_type.lower() not in CHARTABLE_MEDIA_TYPES: return _update_charts_for_timestamp(instance.user, instance.timestamp) @receiver(post_delete, sender=Scrobble) def update_charts_on_scrobble_delete(sender, instance, **kwargs): if instance.timestamp is None: return if instance.media_type.lower() in SCROBBLES_WITHOUT_CHARTS: return if instance.media_type.lower() not in CHARTABLE_MEDIA_TYPES: return _update_charts_for_timestamp(instance.user, instance.timestamp) def _update_charts_for_timestamp(user, ts): if ts is None: return if timezone.is_naive(ts): ts = timezone.make_aware(ts) year = ts.year month = ts.month week = ts.isocalendar()[1] day = ts.day update_charts_for_timestamp.delay(user.id, year, month, day, week) @receiver(post_save, sender=Scrobble) def add_tags_from_task_title(sender, instance, **kwargs): if instance.media_type != Scrobble.MediaType.TASK: return title = instance.logdata.title if not title: return new_tags = tokenize_title_to_tags(title) existing_tags = {t.name for t in instance.tags.all()} for tag in new_tags: if tag not in existing_tags: instance.tags.add(tag) @receiver(post_save, sender=FavoriteMedia) def add_to_mopidy_playlist_on_favorite(sender, instance, created, **kwargs): if not created: return if instance.media_type != Scrobble.MediaType.TRACK: return if not instance.track: return add_favorite_to_mopidy_playlist.delay(instance.id) @receiver(post_delete, sender=FavoriteMedia) def remove_from_mopidy_playlist_on_unfavorite(sender, instance, **kwargs): if instance.media_type != Scrobble.MediaType.TRACK: return if not instance.track_id: return remove_favorite_from_mopidy_playlist.delay( user_id=instance.user_id, track_id=instance.track_id, )