Compare commits

...

3 Commits
0.7.4 ... 0.7.5

Author SHA1 Message Date
4b4fbf4777 Bump version to 0.7.5 2023-01-31 10:41:40 -05:00
ca57eabf87 Another attempt to fix the Jellyfin issue
This time, we simplify the progress updates, aggressively mark tracks as
100 played if they are marked played_to_completion, and implement a hack
for Jellyfin spamming us with progress updates less than a second apart.
2023-01-31 10:28:54 -05:00
6fc51d9296 Fix resurrecting past tracks
This may also be hack, but I think that if the playback position ticks
are automatically jumped to the run time ticks of the media object, it
should stop the resurrection of past scrobbles, because they will be
appropriately marked as being 100 played when the scrobble is finished.

The only weirdness here is that "in progress" scrobbles will suddenly
complete once the media type's threshold is met (90, 95 percent,
whatever). But it should be better than overwriting old scrobbles.
2023-01-30 23:18:42 -05:00
3 changed files with 20 additions and 19 deletions

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "vrobbler"
version = "0.7.4"
version = "0.7.5"
description = ""
authors = ["Colin Powell <colin@unbl.ink>"]

View File

@ -12,6 +12,7 @@ from podcasts.models import Episode
from scrobbles.utils import check_scrobble_for_finish
from sports.models import SportEvent
from videos.models import Series, Video
from vrobbler.apps.profiles.utils import now_user_timezone
logger = logging.getLogger(__name__)
User = get_user_model()
@ -146,7 +147,7 @@ class Scrobble(TimeStampedModel):
playback_ticks = (timezone.now() - self.timestamp).seconds * 1000
if self.played_to_completion:
playback_ticks = self.media_obj.run_time_ticks
return 100
percent = int((playback_ticks / self.media_obj.run_time_ticks) * 100)
return percent
@ -210,17 +211,26 @@ class Scrobble(TimeStampedModel):
cls.objects.filter(
track=track,
user_id=user_id,
played_to_completion=False,
)
.order_by('-modified')
.first()
)
if scrobble and scrobble.percent_played <= 100:
if scrobble:
logger.debug(
f"Found existing scrobble for track {track}, updating",
{"scrobble_data": scrobble_data},
)
return cls.update(scrobble, scrobble_data)
if 'jellyfin_status' in scrobble_data.keys():
last_scrobble = Scrobble.objects.last()
if (
scrobble_data['timestamp'] - last_scrobble.timestamp
).seconds <= 1:
logger.warning('Jellyfin spammed us with duplicate updates')
return last_scrobble
logger.debug(
f"No existing scrobble for track {track}, creating",
{"scrobble_data": scrobble_data},
@ -311,7 +321,6 @@ class Scrobble(TimeStampedModel):
for key, value in scrobble_data.items():
setattr(scrobble, key, value)
scrobble.save()
check_scrobble_for_finish(scrobble)
return scrobble
@classmethod
@ -334,6 +343,7 @@ class Scrobble(TimeStampedModel):
check_scrobble_for_finish(self, force_finish)
def pause(self) -> None:
print('Trying to pause it')
if self.is_paused:
logger.warning("Scrobble already paused")
return
@ -346,6 +356,7 @@ class Scrobble(TimeStampedModel):
self.is_paused = False
self.in_progress = True
return self.save(update_fields=["is_paused", "in_progress"])
logger.warning("Resume called but in progress or not paused")
def cancel(self) -> None:
check_scrobble_for_finish(self, force_finish=True)

View File

@ -99,26 +99,15 @@ def create_jellyfin_scrobble_dict(data_dict: dict, user_id: int) -> dict:
jellyfin_status = "resumed"
if data_dict.get("IsPaused"):
jellyfin_status = "paused"
if data_dict.get("PlayedToCompletion"):
if data_dict.get("NotificationType") == 'PlaybackStop':
jellyfin_status = "stopped"
playback_position_ticks = None
if data_dict.get("PlaybackPositionTicks"):
playback_position_ticks = (
data_dict.get("PlaybackPositionTicks") // 10000
)
if playback_position_ticks <= 0:
playback_position_ticks = None
playback_position = data_dict.get("PlaybackPosition")
if playback_position:
playback_position = convert_to_seconds(playback_position)
return {
"user_id": user_id,
"timestamp": parse(data_dict.get("UtcTimestamp")),
"playback_position_ticks": playback_position_ticks,
"playback_position": playback_position,
"playback_position_ticks": data_dict.get("PlaybackPositionTicks", "")
// 10000,
"playback_position": data_dict.get("PlaybackPosition", ""),
"source": data_dict.get("ClientName", "Vrobbler"),
"source_id": data_dict.get('MediaSourceId'),
"jellyfin_status": jellyfin_status,
@ -128,6 +117,7 @@ def create_jellyfin_scrobble_dict(data_dict: dict, user_id: int) -> dict:
def jellyfin_scrobble_track(
data_dict: dict, user_id: Optional[int]
) -> Optional[Scrobble]:
if not data_dict.get("Provider_musicbrainztrack", None):
logger.error(
"No MBrainz Track ID received. This is likely because all metadata is bad, not scrobbling"