|
@@ -2,6 +2,7 @@ import logging
|
|
|
import re
|
|
|
from datetime import datetime, timedelta
|
|
|
from typing import Any, Optional
|
|
|
+from zoneinfo import ZoneInfo
|
|
|
|
|
|
import pendulum
|
|
|
import pytz
|
|
@@ -18,6 +19,7 @@ from music.models import Track
|
|
|
from people.models import Person
|
|
|
from podcasts.models import PodcastEpisode
|
|
|
from podcasts.utils import parse_mopidy_uri
|
|
|
+from profiles.models import UserProfile
|
|
|
from puzzles.models import Puzzle
|
|
|
from scrobbles.constants import (
|
|
|
JELLYFIN_AUDIO_ITEM_TYPES,
|
|
@@ -390,10 +392,25 @@ def email_scrobble_board_game(
|
|
|
locations[location_dict.get("id")] = location
|
|
|
|
|
|
scrobbles_created = []
|
|
|
+ second = 0
|
|
|
for play_dict in bgstat_data.get("plays", []):
|
|
|
+ hour = None
|
|
|
+ minute = None
|
|
|
+ second = None
|
|
|
if "comments" in play_dict.keys():
|
|
|
- if "Learning to play" in play_dict.get("comments"):
|
|
|
- log_data["learning"] = True
|
|
|
+ for line in play_dict.get("comments", "").split("\n"):
|
|
|
+ if "Learning to play" in line:
|
|
|
+ log_data["learning"] = True
|
|
|
+ if "Start time:" in line:
|
|
|
+ start_time = line.split(": ")[1]
|
|
|
+ pieces = start_time.split(":")
|
|
|
+ hour = int(pieces[0])
|
|
|
+ minute = int(pieces[1])
|
|
|
+ try:
|
|
|
+ second = int(pieces[2])
|
|
|
+ except IndexError:
|
|
|
+ second = 0
|
|
|
+
|
|
|
log_data["details"] = play_dict.get("comments")
|
|
|
log_data["expansion_ids"] = []
|
|
|
try:
|
|
@@ -402,7 +419,6 @@ def email_scrobble_board_game(
|
|
|
try:
|
|
|
base_game = expansions[play_dict.get("gameRefId")]
|
|
|
except KeyError:
|
|
|
- print(play_dict)
|
|
|
logger.info(
|
|
|
"Skipping scrobble of play, can't find game",
|
|
|
extra={"play_dict": play_dict},
|
|
@@ -440,31 +456,51 @@ def email_scrobble_board_game(
|
|
|
}
|
|
|
)
|
|
|
|
|
|
- start = parse(play_dict.get("playDate"))
|
|
|
+ timestamp = parse(play_dict.get("playDate"))
|
|
|
+ if hour and minute:
|
|
|
+ logger.info(f"Scrobble playDate has manual start time {timestamp}")
|
|
|
+ timestamp = timestamp.replace(
|
|
|
+ hour=hour, minute=minute, second=second or 0
|
|
|
+ )
|
|
|
+ logger.info(f"Update to {timestamp}")
|
|
|
+
|
|
|
+ profile = UserProfile.objects.filter(user_id=user_id).first()
|
|
|
+ timestamp = profile.get_timestamp_with_tz(timestamp)
|
|
|
+
|
|
|
if play_dict.get("durationMin") > 0:
|
|
|
duration_seconds = play_dict.get("durationMin") * 60
|
|
|
else:
|
|
|
duration_seconds = base_game.run_time_seconds
|
|
|
- stop = start + timedelta(seconds=duration_seconds)
|
|
|
+ stop_timestamp = timestamp + timedelta(seconds=duration_seconds)
|
|
|
+
|
|
|
+ logger.info(f"Creating scrobble for {base_game} at {timestamp}")
|
|
|
scrobble_dict = {
|
|
|
"user_id": user_id,
|
|
|
- "timestamp": start,
|
|
|
+ "timestamp": timestamp,
|
|
|
"playback_position_seconds": duration_seconds,
|
|
|
"source": "BG Stats",
|
|
|
"log": log_data,
|
|
|
}
|
|
|
|
|
|
- scrobble = Scrobble.objects.filter(
|
|
|
- board_game=base_game, user_id=user_id, timestamp=start
|
|
|
- ).first()
|
|
|
+ scrobble = None
|
|
|
+ if timestamp.year > 2023:
|
|
|
+ logger.info(
|
|
|
+ "Scrobbles older than 2024 likely have no time associated just create it"
|
|
|
+ )
|
|
|
+ scrobble = Scrobble.objects.filter(
|
|
|
+ board_game=base_game, user_id=user_id, timestamp=timestamp
|
|
|
+ ).first()
|
|
|
if scrobble:
|
|
|
logger.info(
|
|
|
"Scrobble already exists, skipping",
|
|
|
extra={"scrobble_dict": scrobble_dict, "user_id": user_id},
|
|
|
)
|
|
|
continue
|
|
|
- scrobble = Scrobble.create_or_update(base_game, user_id, scrobble_dict)
|
|
|
- scrobble.stop_timestamp = stop
|
|
|
+ scrobble = Scrobble.create_or_update(
|
|
|
+ base_game, user_id, scrobble_dict, skip_in_progress_check=True
|
|
|
+ )
|
|
|
+ scrobble.timezone = timestamp.tzinfo.name
|
|
|
+ scrobble.stop_timestamp = stop_timestamp
|
|
|
scrobble.in_progress = False
|
|
|
scrobble.played_to_completion = True
|
|
|
scrobble.save()
|