Fix redundant tick field
This commit is contained in:
@ -98,15 +98,13 @@ def process_koreader_sqlite_file(sqlite_file_path, user_id):
|
||||
if created:
|
||||
pages = book_row[KoReaderBookColumn.PAGES.value]
|
||||
run_time = pages * book.AVG_PAGE_READING_SECONDS
|
||||
run_time_ticks = run_time * 1000
|
||||
book_dict = {
|
||||
"title": book_row[KoReaderBookColumn.TITLE.value],
|
||||
"pages": book_row[KoReaderBookColumn.PAGES.value],
|
||||
"koreader_md5": book_row[KoReaderBookColumn.MD5.value],
|
||||
"koreader_id": int(book_row[KoReaderBookColumn.ID.value]),
|
||||
"koreader_authors": book_row[KoReaderBookColumn.AUTHORS.value],
|
||||
"run_time": run_time,
|
||||
"run_time_ticks": run_time_ticks,
|
||||
"run_time_seconds": run_time,
|
||||
}
|
||||
Book.objects.filter(pk=book.id).update(**book_dict)
|
||||
book.fix_metadata()
|
||||
@ -114,10 +112,9 @@ def process_koreader_sqlite_file(sqlite_file_path, user_id):
|
||||
if author_list:
|
||||
book.authors.add(*[a.id for a in author_list])
|
||||
|
||||
playback_position = int(
|
||||
playback_position_seconds = int(
|
||||
book_row[KoReaderBookColumn.TOTAL_READ_TIME.value]
|
||||
)
|
||||
playback_position_ticks = playback_position * 1000
|
||||
pages_read = int(book_row[KoReaderBookColumn.TOTAL_READ_PAGES.value])
|
||||
timestamp = datetime.utcfromtimestamp(
|
||||
book_row[KoReaderBookColumn.LAST_OPEN.value]
|
||||
@ -129,8 +126,7 @@ def process_koreader_sqlite_file(sqlite_file_path, user_id):
|
||||
user_id=user_id,
|
||||
source="KOReader",
|
||||
timestamp=timestamp,
|
||||
playback_position_ticks=playback_position_ticks,
|
||||
playback_position=playback_position,
|
||||
playback_position_seconds=playback_position_seconds,
|
||||
played_to_completion=True,
|
||||
in_progress=False,
|
||||
book_pages_read=pages_read,
|
||||
|
||||
18
vrobbler/apps/books/migrations/0009_alter_book_run_time.py
Normal file
18
vrobbler/apps/books/migrations/0009_alter_book_run_time.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("books", "0008_book_first_sentence"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="book",
|
||||
name="run_time",
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:21
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("books", "0009_alter_book_run_time"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="book",
|
||||
old_name="run_time",
|
||||
new_name="run_time_seconds",
|
||||
),
|
||||
]
|
||||
@ -131,8 +131,9 @@ class Book(LongPlayScrobblableMixin):
|
||||
self.cover.save(fname, ContentFile(r.content), save=True)
|
||||
|
||||
if self.pages:
|
||||
self.run_time = self.pages * int(self.AVG_PAGE_READING_SECONDS)
|
||||
self.run_time_ticks = int(self.run_time) * 1000
|
||||
self.run_time_seconds = self.pages * int(
|
||||
self.AVG_PAGE_READING_SECONDS
|
||||
)
|
||||
|
||||
self.save()
|
||||
|
||||
|
||||
@ -51,7 +51,6 @@ class TrackAdmin(admin.ModelAdmin):
|
||||
"title",
|
||||
"album",
|
||||
"artist",
|
||||
"run_time",
|
||||
"musicbrainz_id",
|
||||
)
|
||||
list_filter = ("album", "artist")
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
JELLYFIN_POST_KEYS = {
|
||||
"ITEM_TYPE": "ItemType",
|
||||
"RUN_TIME_TICKS": "RunTimeTicks",
|
||||
"RUN_TIME": "RunTime",
|
||||
"TITLE": "Name",
|
||||
"TIMESTAMP": "UtcTimestamp",
|
||||
|
||||
@ -107,13 +107,11 @@ class LastFM:
|
||||
|
||||
for scrobble in found_scrobbles:
|
||||
run_time = None
|
||||
run_time_ticks = None
|
||||
mbid = None
|
||||
artist = None
|
||||
|
||||
try:
|
||||
run_time_ticks = scrobble.track.get_duration()
|
||||
run_time = int(run_time_ticks / 1000)
|
||||
run_time = int(scrobble.track.get_duration() / 1000)
|
||||
mbid = scrobble.track.get_mbid()
|
||||
artist = scrobble.track.get_artist().name
|
||||
except pylast.MalformedResponseError as e:
|
||||
|
||||
18
vrobbler/apps/music/migrations/0015_alter_track_run_time.py
Normal file
18
vrobbler/apps/music/migrations/0015_alter_track_run_time.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("music", "0014_album_theaudiodb_year_released"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="track",
|
||||
name="run_time",
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:21
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("music", "0015_alter_track_run_time"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="track",
|
||||
old_name="run_time",
|
||||
new_name="run_time_seconds",
|
||||
),
|
||||
]
|
||||
@ -42,7 +42,7 @@ def lookup_album_from_mb(musicbrainz_id: str) -> dict:
|
||||
{
|
||||
"title": recording["title"],
|
||||
"musicbrainz_id": recording["id"],
|
||||
"run_time_ticks": track["length"],
|
||||
"run_time": track["length"] / 1000,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -72,8 +72,7 @@ def get_or_create_track(
|
||||
artist: Artist,
|
||||
album: Album,
|
||||
mbid: str = None,
|
||||
run_time=None,
|
||||
run_time_ticks=None,
|
||||
run_time_seconds=None,
|
||||
) -> Track:
|
||||
track = None
|
||||
if not mbid:
|
||||
@ -91,8 +90,7 @@ def get_or_create_track(
|
||||
artist=artist,
|
||||
album=album,
|
||||
musicbrainz_id=mbid,
|
||||
run_time=run_time,
|
||||
run_time_ticks=run_time_ticks,
|
||||
run_time_seconds=run_time_seconds,
|
||||
)
|
||||
|
||||
return track
|
||||
|
||||
@ -27,7 +27,6 @@ class EpisodeAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
"title",
|
||||
"podcast",
|
||||
"run_time",
|
||||
)
|
||||
list_filter = ("podcast",)
|
||||
ordering = ("-created",)
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("podcasts", "0005_alter_episode_options_alter_episode_title"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="episode",
|
||||
name="run_time",
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:21
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("podcasts", "0006_alter_episode_run_time"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="episode",
|
||||
old_name="run_time",
|
||||
new_name="run_time_seconds",
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:00
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("scrobbles", "0030_scrobble_notes"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="scrobble",
|
||||
name="playback_position",
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:21
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("scrobbles", "0031_alter_scrobble_playback_position"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="scrobble",
|
||||
old_name="playback_position",
|
||||
new_name="playback_position_seconds",
|
||||
),
|
||||
]
|
||||
@ -17,7 +17,7 @@ class ScrobblableMixin(TimeStampedModel):
|
||||
|
||||
uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
|
||||
title = models.CharField(max_length=255, **BNULL)
|
||||
run_time = models.CharField(max_length=8, **BNULL)
|
||||
run_time_seconds = models.IntegerField(**BNULL)
|
||||
run_time_ticks = models.PositiveBigIntegerField(**BNULL)
|
||||
|
||||
class Meta:
|
||||
|
||||
@ -406,7 +406,7 @@ class Scrobble(TimeStampedModel):
|
||||
# Time keeping
|
||||
timestamp = models.DateTimeField(**BNULL)
|
||||
playback_position_ticks = models.PositiveBigIntegerField(**BNULL)
|
||||
playback_position = models.CharField(max_length=10, **BNULL)
|
||||
playback_position_seconds = models.IntegerField(**BNULL)
|
||||
|
||||
# Status indicators
|
||||
is_paused = models.BooleanField(default=False)
|
||||
@ -476,26 +476,25 @@ class Scrobble(TimeStampedModel):
|
||||
if not self.media_obj:
|
||||
return 0
|
||||
|
||||
if self.media_obj and not self.media_obj.run_time_ticks:
|
||||
if self.media_obj and not self.media_obj.run_time_seconds:
|
||||
return 100
|
||||
|
||||
if not self.playback_position_ticks and self.played_to_completion:
|
||||
if not self.playback_position_seconds and self.played_to_completion:
|
||||
return 100
|
||||
|
||||
playback_ticks = self.playback_position_ticks
|
||||
if not playback_ticks:
|
||||
playback_ticks = (timezone.now() - self.timestamp).seconds * 1000
|
||||
playback_seconds = self.playback_position_seconds
|
||||
if not playback_seconds:
|
||||
playback_seconds = (timezone.now() - self.timestamp).seconds
|
||||
|
||||
percent = int((playback_ticks / self.media_obj.run_time_ticks) * 100)
|
||||
run_time_secs = self.media_obj.run_time_seconds
|
||||
percent = int((playback_seconds / run_time_secs) * 100)
|
||||
|
||||
if self.is_long_play:
|
||||
run_time_secs = int(self.media_obj.run_time)
|
||||
playback_secs = (timezone.now() - self.timestamp).seconds
|
||||
long_play_secs = 0
|
||||
if self.previous and not self.previous.long_play_complete:
|
||||
long_play_secs = self.previous.long_play_seconds or 0
|
||||
percent = int(
|
||||
((playback_secs + long_play_secs) / run_time_secs) * 100
|
||||
((playback_seconds + long_play_secs) / run_time_secs) * 100
|
||||
)
|
||||
|
||||
# if percent > 100:
|
||||
@ -635,9 +634,7 @@ class Scrobble(TimeStampedModel):
|
||||
if class_name in LONG_PLAY_MEDIA.values():
|
||||
now = timezone.now()
|
||||
self.played_to_completion = True
|
||||
self.playback_position = (now - self.timestamp).seconds
|
||||
# TODO Refactor ticks outta here, this is silly
|
||||
self.playback_position_ticks = int(self.playback_position) * 1000
|
||||
self.playback_position_seconds = (now - self.timestamp).seconds
|
||||
|
||||
media_filter = models.Q(video_game=self.video_game)
|
||||
if class_name == "Book":
|
||||
@ -650,16 +647,15 @@ class Scrobble(TimeStampedModel):
|
||||
played_to_completion=True,
|
||||
long_play_complete=False,
|
||||
).last()
|
||||
self.long_play_seconds = self.playback_position
|
||||
self.long_play_seconds = self.playback_position_seconds
|
||||
if last_scrobble:
|
||||
self.long_play_seconds = int(
|
||||
last_scrobble.playback_position
|
||||
) + int(self.playback_position)
|
||||
last_scrobble.playback_position_seconds
|
||||
) + int(self.playback_position_seconds)
|
||||
|
||||
self.save(
|
||||
update_fields=[
|
||||
"playback_position",
|
||||
"playback_position_ticks",
|
||||
"playback_position_seconds",
|
||||
"played_to_completion",
|
||||
"long_play_seconds",
|
||||
]
|
||||
@ -688,11 +684,8 @@ class Scrobble(TimeStampedModel):
|
||||
self.delete()
|
||||
|
||||
def update_ticks(self, data) -> None:
|
||||
self.playback_position_ticks = data.get("playback_position_ticks")
|
||||
self.playback_position = data.get("playback_position")
|
||||
self.playback_position_seconds = data.get("playback_position_seconds")
|
||||
logger.info(
|
||||
f"{self.id} - {self.playback_position_ticks} - {self.source}"
|
||||
)
|
||||
self.save(
|
||||
update_fields=["playback_position_ticks", "playback_position"]
|
||||
f"{self.id} - {self.playback_position_seconds} - {self.source}"
|
||||
)
|
||||
self.save(update_fields=["playback_position_seconds"])
|
||||
|
||||
@ -37,8 +37,7 @@ def mopidy_scrobble_podcast(
|
||||
episode_name = parsed_data.get("episode_filename")
|
||||
episode_dict = {
|
||||
"title": episode_name,
|
||||
"run_time_ticks": data_dict.get("run_time_ticks"),
|
||||
"run_time": data_dict.get("run_time"),
|
||||
"run_time_seconds": data_dict.get("run_time"),
|
||||
"number": parsed_data.get("episode_num"),
|
||||
"pub_date": parsed_data.get("pub_date"),
|
||||
"mopidy_uri": mopidy_uri,
|
||||
@ -50,7 +49,7 @@ def mopidy_scrobble_podcast(
|
||||
mopidy_data = {
|
||||
"user_id": user_id,
|
||||
"timestamp": timezone.now(),
|
||||
"playback_position_ticks": data_dict.get("playback_time_ticks"),
|
||||
"playback_position_seconds": data_dict.get("playback_time_ticks"),
|
||||
"source": "Mopidy",
|
||||
"mopidy_status": data_dict.get("status"),
|
||||
}
|
||||
@ -78,15 +77,15 @@ def mopidy_scrobble_track(
|
||||
mbid=data_dict.get("musicbrainz_track_id"),
|
||||
artist=artist,
|
||||
album=album,
|
||||
run_time_ticks=data_dict.get("run_time_ticks"),
|
||||
run_time=data_dict.get("run_time"),
|
||||
run_time_seconds=data_dict.get("run_time"),
|
||||
)
|
||||
|
||||
# Now we run off a scrobble
|
||||
playback_seconds = data_dict.get("playback_time_ticks") / 1000
|
||||
mopidy_data = {
|
||||
"user_id": user_id,
|
||||
"timestamp": timezone.now(),
|
||||
"playback_position_ticks": data_dict.get("playback_time_ticks"),
|
||||
"playback_position_seconds": playback_seconds,
|
||||
"source": "Mopidy",
|
||||
"mopidy_status": data_dict.get("status"),
|
||||
}
|
||||
@ -103,15 +102,10 @@ def build_scrobble_dict(data_dict: dict, user_id: int) -> dict:
|
||||
elif data_dict.get("NotificationType") == "PlaybackStop":
|
||||
jellyfin_status = "stopped"
|
||||
|
||||
playback_ticks = data_dict.get("PlaybackPositionTicks", "")
|
||||
if playback_ticks:
|
||||
playback_ticks = playback_ticks // 10000
|
||||
|
||||
return {
|
||||
"user_id": user_id,
|
||||
"timestamp": parse(data_dict.get("UtcTimestamp")),
|
||||
"playback_position_ticks": playback_ticks,
|
||||
"playback_position": data_dict.get("PlaybackPosition", ""),
|
||||
"playback_position_seconds": data_dict.get("PlaybackPosition", ""),
|
||||
"source": data_dict.get("ClientName", "Vrobbler"),
|
||||
"source_id": data_dict.get("MediaSourceId"),
|
||||
"jellyfin_status": jellyfin_status,
|
||||
@ -142,9 +136,6 @@ def jellyfin_scrobble_track(
|
||||
mbid=data_dict.get(JELLYFIN_POST_KEYS["ALBUM_MB_ID"]),
|
||||
)
|
||||
|
||||
run_time_ticks = (
|
||||
data_dict.get(JELLYFIN_POST_KEYS["RUN_TIME_TICKS"]) // 10000
|
||||
)
|
||||
run_time = convert_to_seconds(
|
||||
data_dict.get(JELLYFIN_POST_KEYS["RUN_TIME"])
|
||||
)
|
||||
@ -152,15 +143,13 @@ def jellyfin_scrobble_track(
|
||||
title=data_dict.get("Name"),
|
||||
artist=artist,
|
||||
album=album,
|
||||
run_time_ticks=run_time_ticks,
|
||||
run_time=run_time,
|
||||
run_time_seconds=run_time,
|
||||
)
|
||||
|
||||
scrobble_dict = build_scrobble_dict(data_dict, user_id)
|
||||
|
||||
# A hack to make Jellyfin work more like Mopidy for music tracks
|
||||
scrobble_dict["playback_position_ticks"] = 0
|
||||
scrobble_dict["playback_position"] = ""
|
||||
scrobble_dict["playback_position_seconds"] = 0
|
||||
|
||||
return Scrobble.create_or_update(track, user_id, scrobble_dict)
|
||||
|
||||
@ -210,8 +199,7 @@ def manual_scrobble_video_game(data_dict: dict, user_id: Optional[int]):
|
||||
scrobble_dict = {
|
||||
"user_id": user_id,
|
||||
"timestamp": timezone.now(),
|
||||
"playback_position_ticks": None, # int(start_playback_position) * 1000,
|
||||
"playback_position": 0,
|
||||
"playback_position_seconds": 0,
|
||||
"source": "Vrobbler",
|
||||
"long_play_complete": False,
|
||||
}
|
||||
@ -225,8 +213,7 @@ def manual_scrobble_book(data_dict: dict, user_id: Optional[int]):
|
||||
scrobble_dict = {
|
||||
"user_id": user_id,
|
||||
"timestamp": timezone.now(),
|
||||
"playback_position_ticks": None,
|
||||
"playback_position": 0,
|
||||
"playback_position_seconds": 0,
|
||||
"source": "Vrobbler",
|
||||
"long_play_complete": False,
|
||||
}
|
||||
|
||||
@ -78,18 +78,16 @@ def check_scrobble_for_finish(
|
||||
completion_percent = scrobble.media_obj.COMPLETION_PERCENT
|
||||
|
||||
if scrobble.percent_played >= completion_percent or force_finish:
|
||||
logger.info(f"{scrobble.id} {completion_percent} met, finishing")
|
||||
|
||||
if (
|
||||
scrobble.playback_position_ticks
|
||||
and scrobble.media_obj.run_time_ticks
|
||||
and force_to_100
|
||||
scrobble.playback_position_seconds
|
||||
and scrobble.media_obj.run_time_seconds
|
||||
):
|
||||
scrobble.playback_position_ticks = (
|
||||
scrobble.media_obj.run_time_ticks
|
||||
logger.info(f"{scrobble.id} {completion_percent} met, finishing")
|
||||
scrobble.playback_position_seconds = (
|
||||
scrobble.media_obj.run_time_seconds
|
||||
)
|
||||
logger.info(
|
||||
f"{scrobble.playback_position_ticks} set to {scrobble.media_obj.run_time_ticks}"
|
||||
f"{scrobble.playback_position_seconds} set to {scrobble.media_obj.run_time_seconds}"
|
||||
)
|
||||
|
||||
scrobble.in_progress = False
|
||||
@ -101,7 +99,7 @@ def check_scrobble_for_finish(
|
||||
"in_progress",
|
||||
"is_paused",
|
||||
"played_to_completion",
|
||||
"playback_position_ticks",
|
||||
"playback_position_seconds",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("sports", "0008_sportevent_thesportsdb_id"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="sport",
|
||||
name="default_event_type",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("UK", "Event"),
|
||||
("GA", "Game"),
|
||||
("RA", "Race"),
|
||||
("MA", "Match"),
|
||||
],
|
||||
default="UK",
|
||||
max_length=2,
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="sportevent",
|
||||
name="event_type",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("UK", "Event"),
|
||||
("GA", "Game"),
|
||||
("RA", "Race"),
|
||||
("MA", "Match"),
|
||||
],
|
||||
default="UK",
|
||||
max_length=2,
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="sportevent",
|
||||
name="run_time",
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:21
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("sports", "0009_alter_sport_default_event_type_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="sportevent",
|
||||
old_name="run_time",
|
||||
new_name="run_time_seconds",
|
||||
),
|
||||
]
|
||||
@ -41,9 +41,6 @@ class Sport(TheSportsDbMixin):
|
||||
default=SportEventType.UNKNOWN,
|
||||
)
|
||||
|
||||
# TODO Add these to the default run_time for Football
|
||||
# run_time_seconds = 11700
|
||||
# run_time_ticks = run_time_seconds * 1000
|
||||
@property
|
||||
def default_event_run_time_ticks(self):
|
||||
default_run_time = getattr(
|
||||
@ -51,7 +48,7 @@ class Sport(TheSportsDbMixin):
|
||||
)
|
||||
if self.default_event_run_time:
|
||||
default_run_time = self.default_event_run_time
|
||||
return default_run_time * 1000
|
||||
return default_run_time
|
||||
|
||||
|
||||
class League(TheSportsDbMixin):
|
||||
@ -231,8 +228,7 @@ class SportEvent(ScrobblableMixin):
|
||||
"player_two": player_two,
|
||||
"start": data_dict["Start"],
|
||||
"round": round,
|
||||
"run_time_ticks": data_dict.get("RunTimeTicks"),
|
||||
"run_time": data_dict.get("RunTime", ""),
|
||||
"run_time_seconds": data_dict.get("RunTime", 0),
|
||||
}
|
||||
event, _created = cls.objects.get_or_create(**event_dict)
|
||||
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("videogames", "0006_videogame_summary_alter_videogame_platforms"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="videogame",
|
||||
name="run_time",
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:21
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("videogames", "0007_alter_videogame_run_time"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="videogame",
|
||||
old_name="run_time",
|
||||
new_name="run_time_seconds",
|
||||
),
|
||||
]
|
||||
@ -145,9 +145,8 @@ class VideoGame(LongPlayScrobblableMixin):
|
||||
load_game_data_from_igdb(self.id)
|
||||
|
||||
if (not self.run_time_ticks or force_update) and self.main_story_time:
|
||||
self.run_time_ticks = self.main_story_time * 1000 # miliseconds
|
||||
self.run_time = self.main_story_time
|
||||
self.save(update_fields=["run_time_ticks", "run_time"])
|
||||
self.run_time_seconds = self.main_story_time
|
||||
self.save(update_fields=["run_time_seconds"])
|
||||
|
||||
@classmethod
|
||||
def find_or_create(cls, data_dict: dict) -> "Game":
|
||||
|
||||
@ -22,9 +22,6 @@ def lookup_video_from_imdb(imdb_id: str) -> dict:
|
||||
if runtimes:
|
||||
run_time_seconds = int(runtimes[0]) * 60
|
||||
|
||||
# Ticks otherwise known as miliseconds
|
||||
run_time_ticks = run_time_seconds * 1000 * 1000
|
||||
|
||||
item_type = "Movie"
|
||||
if media.get("series title"):
|
||||
item_type = "Episode"
|
||||
@ -45,7 +42,6 @@ def lookup_video_from_imdb(imdb_id: str) -> dict:
|
||||
"Year": media.get("year"),
|
||||
"Provider_imdb": imdb_id,
|
||||
"RunTime": run_time_seconds,
|
||||
"RunTimeTicks": run_time_ticks,
|
||||
"SeriesName": media.get("series title"),
|
||||
"EpisodeNumber": media.get("episode"),
|
||||
"SeasonNumber": media.get("season"),
|
||||
|
||||
18
vrobbler/apps/videos/migrations/0007_alter_video_run_time.py
Normal file
18
vrobbler/apps/videos/migrations/0007_alter_video_run_time.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("videos", "0006_alter_video_year"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="video",
|
||||
name="run_time",
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-12 01:21
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("videos", "0007_alter_video_run_time"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="video",
|
||||
old_name="run_time",
|
||||
new_name="run_time_seconds",
|
||||
),
|
||||
]
|
||||
@ -4,9 +4,9 @@
|
||||
|
||||
{% block head_extra %}
|
||||
<style>
|
||||
dl { width: 260px; float:left; margin-right: 10px; }
|
||||
dl { width: 210px; float:left; margin-right: 10px; }
|
||||
dt a { color:white; text-decoration: none; font-size:smaller; }
|
||||
img { height:200px; width: 250px; object-fit: cover; }
|
||||
img { height:200px; width: 200px; object-fit: cover; }
|
||||
dd .right { float:right; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
@ -18,25 +18,18 @@
|
||||
{% if view == 'grid' %}
|
||||
<div>
|
||||
{% for media in in_progress %}
|
||||
{% if media.hltb_cover %}
|
||||
<dl>
|
||||
<dt><a href="{{media.get_absolute_url}}">{{media.title}}</a></dt>
|
||||
{% if media.hltb_cover %}
|
||||
<dd><a href="{{media.get_absolute_url}}"><img src="{{media.hltb_cover.url}}" width=200 height=200 /></a></dd>
|
||||
<dd>
|
||||
<a type="button" class="btn btn-sm btn-primary" href="{{media.get_start_url}}">Resume</a>
|
||||
<a type="button" class="right btn btn-sm " href="{{media.get_longplay_finish_url}}">Finish</a>
|
||||
</dd>
|
||||
</dl>
|
||||
{% elif media.cover %}
|
||||
<dl>
|
||||
<dt><a href="{{media.get_absolute_url}}">{{media.title}}</a></dt>
|
||||
{% else %}
|
||||
<dd><a href="{{media.get_absolute_url}}"><img src="{{media.cover.url}}" style="width: 200px; height: 200px; object-fit:cover; " /></a></dd>
|
||||
{% endif %}
|
||||
<dd>
|
||||
<a type="button" class="btn btn-sm btn-primary" href="{{media.get_start_url}}">Resume</a>
|
||||
{% if media.is_long_play_in_progress %}Playing{% else %}<a type="button" class="btn btn-sm btn-primary" href="{{media.get_start_url}}">Resume</a>{% endif %}
|
||||
<a type="button" class="right btn btn-sm " href="{{media.get_longplay_finish_url}}">Finish</a>
|
||||
</dd>
|
||||
</dl>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
<tr>
|
||||
<td>{{scrobble.timestamp}}</td>
|
||||
<td>{% if scrobble.long_play_complete == True %}Yes{% endif %}</td>
|
||||
<td>{% if scrobble.in_progress %}Now playing{% else %}{{scrobble.playback_position|natural_duration}}{% endif %}</td>
|
||||
<td>{% if scrobble.in_progress %}Now playing{% else %}{{scrobble.playback_position_seconds|natural_duration}}{% endif %}</td>
|
||||
<td>{% for platform in scrobble.video_game.platforms.all %}<a href="{{platform.get_absolute_url}}">{{platform}}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
Reference in New Issue
Block a user