[videos] Update youtubes stuff
This commit is contained in:
@ -12,8 +12,9 @@ from music.utils import (
|
|||||||
)
|
)
|
||||||
from scrobbles.constants import AsTsvColumn
|
from scrobbles.constants import AsTsvColumn
|
||||||
from scrobbles.models import Scrobble
|
from scrobbles.models import Scrobble
|
||||||
|
from music.constants import MOPIDY_POST_KEYS
|
||||||
|
|
||||||
from vrobbler.apps.scrobbles.utils import timestamp_user_tz_to_utc
|
from scrobbles.utils import timestamp_user_tz_to_utc
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -43,8 +44,8 @@ def process_audioscrobbler_tsv_file(file_path, user_id, user_tz=None):
|
|||||||
rockbox_info += row[0] + "\n"
|
rockbox_info += row[0] + "\n"
|
||||||
continue
|
continue
|
||||||
if len(row) > 8:
|
if len(row) > 8:
|
||||||
logger.warning(
|
logger.info(
|
||||||
"Improper row length during Audioscrobbler import",
|
"[skip] too many columns in row",
|
||||||
extra={"row": row},
|
extra={"row": row},
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
@ -73,7 +74,13 @@ def process_audioscrobbler_tsv_file(file_path, user_id, user_tz=None):
|
|||||||
|
|
||||||
# TODO Set all this up as constants
|
# TODO Set all this up as constants
|
||||||
if row[AsTsvColumn["COMPLETE"].value] == "S":
|
if row[AsTsvColumn["COMPLETE"].value] == "S":
|
||||||
logger.info(f"Skipping track {track} because not finished")
|
logger.info(
|
||||||
|
"[skip] track not finished",
|
||||||
|
extra={
|
||||||
|
"album_name": row[AsTsvColumn["ALBUM_NAME"].value],
|
||||||
|
"artist_name": row[AsTsvColumn["ARTIST_NAME"].value],
|
||||||
|
}
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
timestamp = timestamp_user_tz_to_utc(
|
timestamp = timestamp_user_tz_to_utc(
|
||||||
|
|||||||
@ -0,0 +1,88 @@
|
|||||||
|
# Generated by Django 4.2.16 on 2024-11-06 15:49
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django_extensions.db.fields
|
||||||
|
import taggit.managers
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("scrobbles", "0066_scrobble_beer_alter_scrobble_media_type"),
|
||||||
|
("videos", "0018_video_youtube_url_alter_video_video_type"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name="video",
|
||||||
|
old_name="youtube_url",
|
||||||
|
new_name="youtube_id",
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="Channel",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.BigAutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"created",
|
||||||
|
django_extensions.db.fields.CreationDateTimeField(
|
||||||
|
auto_now_add=True, verbose_name="created"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"modified",
|
||||||
|
django_extensions.db.fields.ModificationDateTimeField(
|
||||||
|
auto_now=True, verbose_name="modified"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"uuid",
|
||||||
|
models.UUIDField(
|
||||||
|
blank=True,
|
||||||
|
default=uuid.uuid4,
|
||||||
|
editable=False,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("name", models.CharField(max_length=255)),
|
||||||
|
(
|
||||||
|
"cover_image",
|
||||||
|
models.ImageField(
|
||||||
|
blank=True, null=True, upload_to="videos/channels/"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"genre",
|
||||||
|
taggit.managers.TaggableManager(
|
||||||
|
help_text="A comma-separated list of tags.",
|
||||||
|
through="scrobbles.ObjectWithGenres",
|
||||||
|
to="scrobbles.Genre",
|
||||||
|
verbose_name="Tags",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"get_latest_by": "modified",
|
||||||
|
"abstract": False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="video",
|
||||||
|
name="channel",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
||||||
|
to="videos.channel",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -23,6 +23,56 @@ from videos.imdb import lookup_video_from_imdb
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
BNULL = {"blank": True, "null": True}
|
BNULL = {"blank": True, "null": True}
|
||||||
|
|
||||||
|
class Channel(TimeStampedModel):
|
||||||
|
uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
|
||||||
|
name = models.CharField(max_length=255)
|
||||||
|
cover_image = models.ImageField(upload_to="videos/channels/", **BNULL)
|
||||||
|
cover_small = ImageSpecField(
|
||||||
|
source="cover_image",
|
||||||
|
processors=[ResizeToFit(100, 100)],
|
||||||
|
format="JPEG",
|
||||||
|
options={"quality": 60},
|
||||||
|
)
|
||||||
|
cover_medium = ImageSpecField(
|
||||||
|
source="cover_image",
|
||||||
|
processors=[ResizeToFit(300, 300)],
|
||||||
|
format="JPEG",
|
||||||
|
options={"quality": 75},
|
||||||
|
)
|
||||||
|
genre = TaggableManager(through=ObjectWithGenres)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse("videos:channel_detail", kwargs={"slug": self.uuid})
|
||||||
|
|
||||||
|
def youtube_link(self):
|
||||||
|
return f"https://www.youtube.com/user/t{self.yt_username}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def primary_image_url(self) -> str:
|
||||||
|
url = ""
|
||||||
|
if self.cover_image:
|
||||||
|
url = self.cover_image_medium.url
|
||||||
|
return url
|
||||||
|
|
||||||
|
def scrobbles_for_user(self, user_id: int, include_playing=False):
|
||||||
|
from scrobbles.models import Scrobble
|
||||||
|
|
||||||
|
played_query = models.Q(played_to_completion=True)
|
||||||
|
if include_playing:
|
||||||
|
played_query = models.Q()
|
||||||
|
return Scrobble.objects.filter(
|
||||||
|
played_query,
|
||||||
|
video__channel=self,
|
||||||
|
user=user_id,
|
||||||
|
).order_by("-timestamp")
|
||||||
|
|
||||||
|
def fix_metadata(self, force: bool = False):
|
||||||
|
# TODO Scrape channel info from Youtube
|
||||||
|
logger.warning("Not implemented yet")
|
||||||
|
return
|
||||||
|
|
||||||
class Series(TimeStampedModel):
|
class Series(TimeStampedModel):
|
||||||
uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
|
uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
|
||||||
@ -141,6 +191,7 @@ class Video(ScrobblableMixin):
|
|||||||
|
|
||||||
# TV show specific fields
|
# TV show specific fields
|
||||||
tv_series = models.ForeignKey(Series, on_delete=models.DO_NOTHING, **BNULL)
|
tv_series = models.ForeignKey(Series, on_delete=models.DO_NOTHING, **BNULL)
|
||||||
|
channel = models.ForeignKey(Channel, on_delete=models.DO_NOTHING, **BNULL)
|
||||||
season_number = models.IntegerField(**BNULL)
|
season_number = models.IntegerField(**BNULL)
|
||||||
episode_number = models.IntegerField(**BNULL)
|
episode_number = models.IntegerField(**BNULL)
|
||||||
next_imdb_id = models.CharField(max_length=20, **BNULL)
|
next_imdb_id = models.CharField(max_length=20, **BNULL)
|
||||||
@ -162,7 +213,7 @@ class Video(ScrobblableMixin):
|
|||||||
tvrage_id = models.CharField(max_length=20, **BNULL)
|
tvrage_id = models.CharField(max_length=20, **BNULL)
|
||||||
tvdb_id = models.CharField(max_length=20, **BNULL)
|
tvdb_id = models.CharField(max_length=20, **BNULL)
|
||||||
tmdb_id = models.CharField(max_length=20, **BNULL)
|
tmdb_id = models.CharField(max_length=20, **BNULL)
|
||||||
youtube_url = models.CharField(max_length=255, **BNULL)
|
youtube_id = models.CharField(max_length=255, **BNULL)
|
||||||
plot = models.TextField(**BNULL)
|
plot = models.TextField(**BNULL)
|
||||||
year = models.IntegerField(**BNULL)
|
year = models.IntegerField(**BNULL)
|
||||||
|
|
||||||
@ -171,7 +222,9 @@ class Video(ScrobblableMixin):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.video_type == self.VideoType.TV_EPISODE:
|
if self.video_type == self.VideoType.TV_EPISODE:
|
||||||
return f"{self.tv_series} - Season {self.season_number}, Episode {self.episode_number}"
|
return f"{self.title} - {self.tv_series} - Season {self.season_number}, Episode {self.episode_number}"
|
||||||
|
if self.video_type == self.VideoType.YOUTUBE:
|
||||||
|
return f"{self.title} - {self.channel}"
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
@ -195,6 +248,10 @@ class Video(ScrobblableMixin):
|
|||||||
def link(self):
|
def link(self):
|
||||||
return self.imdb_link
|
return self.imdb_link
|
||||||
|
|
||||||
|
@property
|
||||||
|
def youtube_link(self):
|
||||||
|
return f"https://www.youtube.com/watch?v={self.youtube_id}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def primary_image_url(self) -> str:
|
def primary_image_url(self) -> str:
|
||||||
url = ""
|
url = ""
|
||||||
|
|||||||
Reference in New Issue
Block a user