Add scrobble log option and CLI tool

This commit is contained in:
2023-01-05 13:39:56 -05:00
parent 68c1b3c6f0
commit 41a74f46c8
6 changed files with 100 additions and 10 deletions

View File

@ -62,9 +62,7 @@ combine_as_imports = true
exclude_dirs = ["*/tests/*", "*/migrations/*"]
[tool.poetry.scripts]
server = 'scripts:server'
migrate = 'scripts:migrate'
shell = 'scripts:shell'
vrobbler = "vrobbler.cli:main"
[build-system]
requires = ["poetry-core>=1.0.0"]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.1.5 on 2023-01-05 17:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('scrobbles', '0003_remove_scrobble_counted_scrobble_in_progress'),
]
operations = [
migrations.AddField(
model_name='scrobble',
name='scrobble_log',
field=models.TextField(blank=True, null=True),
),
]

View File

@ -21,6 +21,7 @@ class Scrobble(TimeStampedModel):
source = models.CharField(max_length=255, **BNULL)
source_id = models.TextField(**BNULL)
in_progress = models.BooleanField(default=True)
scrobble_log = models.TextField(**BNULL)
@property
def percent_played(self) -> int:

View File

@ -34,7 +34,9 @@ class RecentScrobbleList(ListView):
model = Scrobble
def get_queryset(self):
return Scrobble.objects.filter(in_progress=False)
return Scrobble.objects.filter(in_progress=False).order_by(
'-timestamp'
)
@csrf_exempt
@ -93,8 +95,16 @@ def jellyfin_websocket(request):
.order_by('-modified')
.first()
)
existing_in_progress_scrobble = (
Scrobble.objects.filter(
video=video, user_id=request.user.id, in_progress=True
)
.order_by('-modified')
.first()
)
minutes_from_now = timezone.now() + timedelta(minutes=15)
a_day_from_now = timezone.now() + timedelta(days=1)
if (
existing_finished_scrobble
@ -105,14 +115,28 @@ def jellyfin_websocket(request):
)
return Response(video_dict, status=status.HTTP_204_NO_CONTENT)
scrobble, scrobble_created = Scrobble.objects.get_or_create(
**scrobble_dict
)
# Check if found in progress scrobble is more than a day old
if not (
existing_in_progress_scrobble
and existing_in_progress_scrobble.modified < a_day_from_now
):
logger.info(
'Found a scrobble for this video more than a day old, creating a new scrobble'
)
scrobble = existing_in_progress_scrobble
scrobble_created = False
else:
if getattr(settings, "DELETE_STALE_SCROBBLES", True):
existing_in_progress_scrobble.delete()
scrobble, scrobble_created = Scrobble.objects.get_or_create(
**scrobble_dict
)
if scrobble_created:
# If we newly created this, capture the client we're watching from
scrobble.source = data_dict['ClientName']
scrobble.source_id = data_dict['MediaSourceId']
scrobble.scrobble_log = ""
else:
last_tick = scrobble.playback_position_ticks
@ -121,7 +145,14 @@ def jellyfin_websocket(request):
scrobble.playback_position = data_dict["PlaybackPosition"]
scrobble.timestamp = parse(data_dict["UtcTimestamp"])
scrobble.is_paused = data_dict["IsPaused"] in TRUTHY_VALUES
scrobble.save()
scrobble.save(
update_fields=[
'playback_position_ticks',
'playback_position',
'timestamp',
'is_paused',
]
)
# If we hit our completion threshold, save it and get ready
# to scrobble again if we re-watch this.
@ -133,6 +164,9 @@ def jellyfin_websocket(request):
scrobble.save()
if scrobble.percent_played % 5 == 0:
logger.info(f"You are {scrobble.percent_played}% through {video}")
if getattr(settings, "KEEP_DETAILED_SCROBBLE_LOGS", False):
scrobble.scrobble_log += f"\n{str(scrobble.timestamp)} - {scrobble.playback_position} - {str(scrobble.playback_position_ticks)} - {str(scrobble.percent_played)}%"
scrobble.save(update_fields=['scrobble_log'])
logger.debug(f"You are {scrobble.percent_played}% through {video}")
return Response(video_dict, status=status.HTTP_201_CREATED)

34
vrobbler/cli.py Normal file
View File

@ -0,0 +1,34 @@
# cli.py
import logging
import sys
from os import environ as env
if not 'DJANGO_SETTINGS_MODULE' in env:
from vrobbler import settings
env.setdefault('DJANGO_SETTINGS_MODULE', settings.__name__)
import django
django.setup()
# this line must be after django.setup() for logging configure
logger = logging.getLogger('vrobbler')
def main():
# to get configured settings
from django.conf import settings
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

View File

@ -32,6 +32,12 @@ DEBUG = os.getenv("VROBBLER_DEBUG", False)
TESTING = len(sys.argv) > 1 and sys.argv[1] == "test"
KEEP_DETAILED_SCROBBLE_LOGS = os.getenv(
"VROBBLER_KEEP_DETAILED_SCROBBLE_LOGS", False
)
DELETE_STALE_SCROBBLES = os.getenv("VROBBLER_DELETE_STALE_SCROBBLES", True)
TMDB_API_KEY = os.getenv("VROBBLER_TMDB_API_KEY", "")
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
@ -61,7 +67,6 @@ INSTALLED_APPS = [
"django_filters",
"django_extensions",
'rest_framework.authtoken',
"vrobbler",
"scrobbles",
"videos",
"rest_framework",