diff --git a/vrobbler/apps/beers/migrations/0007_beer_tags.py b/vrobbler/apps/beers/migrations/0007_beer_tags.py new file mode 100644 index 0000000..26d255e --- /dev/null +++ b/vrobbler/apps/beers/migrations/0007_beer_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("beers", "0006_remove_beer_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="beer", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/boardgames/migrations/0014_boardgame_tags.py b/vrobbler/apps/boardgames/migrations/0014_boardgame_tags.py new file mode 100644 index 0000000..c562292 --- /dev/null +++ b/vrobbler/apps/boardgames/migrations/0014_boardgame_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("boardgames", "0013_boardgame_publishers"), + ] + + operations = [ + migrations.AddField( + model_name="boardgame", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/books/constants.py b/vrobbler/apps/books/constants.py index 2de0721..e39f92d 100644 --- a/vrobbler/apps/books/constants.py +++ b/vrobbler/apps/books/constants.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +from enum import Enum BOOKS_TITLES_TO_IGNORE = [ "KOReader Quickstart Guide", @@ -7,3 +8,16 @@ BOOKS_TITLES_TO_IGNORE = [ ] READCOMICSONLINE_URL = "https://readcomicsonline.ru" + + +class MediaSourceTag(str, Enum): + OPENLIBRARY = "source_openlibrary" + GOOGLE_BOOKS = "source_google_books" + COMICVINE = "source_comicvine" + LOCG = "source_locg" + KOREADER = "source_koreader" + SEMANTIC_SCHOLAR = "source_semantic_scholar" + + @classmethod + def choices(cls): + return [(tag.value, tag.name.replace("_", " ").title()) for tag in cls] diff --git a/vrobbler/apps/books/migrations/0034_book_tags.py b/vrobbler/apps/books/migrations/0034_book_tags.py new file mode 100644 index 0000000..43c06a8 --- /dev/null +++ b/vrobbler/apps/books/migrations/0034_book_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:23 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("books", "0033_alter_book_issue_number_alter_book_volume_number"), + ] + + operations = [ + migrations.AddField( + model_name="book", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/books/migrations/0035_paper_tags.py b/vrobbler/apps/books/migrations/0035_paper_tags.py new file mode 100644 index 0000000..fa413eb --- /dev/null +++ b/vrobbler/apps/books/migrations/0035_paper_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("books", "0034_book_tags"), + ] + + operations = [ + migrations.AddField( + model_name="paper", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/books/models.py b/vrobbler/apps/books/models.py index 1330df4..6e85c3d 100644 --- a/vrobbler/apps/books/models.py +++ b/vrobbler/apps/books/models.py @@ -6,7 +6,7 @@ from typing import Optional from uuid import uuid4 import requests -from books.constants import READCOMICSONLINE_URL +from books.constants import MediaSourceTag, READCOMICSONLINE_URL from books.locg import ( lookup_comic_by_locg_slug, lookup_comic_from_locg, @@ -269,8 +269,11 @@ class Book(LongPlayScrobblableMixin): return book book_dict = None + source_tag = None if READCOMICSONLINE_URL in url: book_dict = lookup_comic_from_comicvine(title) + if book_dict: + source_tag = MediaSourceTag.COMICVINE book_dict["readcomics_url"] = get_comic_issue_url(url) book_dict["next_readcomics_url"] = next_url_if_exists( book_dict["readcomics_url"] @@ -278,9 +281,13 @@ class Book(LongPlayScrobblableMixin): if not book_dict: book_dict = lookup_book_from_ol(title, author=author) + if book_dict: + source_tag = MediaSourceTag.OPENLIBRARY if not book_dict: book_dict = lookup_book_from_google(title) + if book_dict: + source_tag = MediaSourceTag.GOOGLE_BOOKS if not book_dict: logger.warning( @@ -312,6 +319,8 @@ class Book(LongPlayScrobblableMixin): if genres: book.genre.add(*genres) book.authors.add(*author_list) + if source_tag: + book.tags.add(source_tag.value) return book diff --git a/vrobbler/apps/bricksets/migrations/0004_brickset_tags.py b/vrobbler/apps/bricksets/migrations/0004_brickset_tags.py new file mode 100644 index 0000000..a8ba5c2 --- /dev/null +++ b/vrobbler/apps/bricksets/migrations/0004_brickset_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("bricksets", "0003_remove_brickset_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="brickset", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/foods/migrations/0006_food_tags.py b/vrobbler/apps/foods/migrations/0006_food_tags.py new file mode 100644 index 0000000..8bde79f --- /dev/null +++ b/vrobbler/apps/foods/migrations/0006_food_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("foods", "0005_food_nutrition_and_sources"), + ] + + operations = [ + migrations.AddField( + model_name="food", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/lifeevents/migrations/0004_lifeevent_tags.py b/vrobbler/apps/lifeevents/migrations/0004_lifeevent_tags.py new file mode 100644 index 0000000..fd21562 --- /dev/null +++ b/vrobbler/apps/lifeevents/migrations/0004_lifeevent_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("lifeevents", "0003_remove_lifeevent_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="lifeevent", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/locations/migrations/0009_geolocation_tags.py b/vrobbler/apps/locations/migrations/0009_geolocation_tags.py new file mode 100644 index 0000000..bb87518 --- /dev/null +++ b/vrobbler/apps/locations/migrations/0009_geolocation_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("locations", "0008_remove_geolocation_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="geolocation", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/moods/migrations/0005_mood_tags.py b/vrobbler/apps/moods/migrations/0005_mood_tags.py new file mode 100644 index 0000000..edd151b --- /dev/null +++ b/vrobbler/apps/moods/migrations/0005_mood_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("moods", "0004_remove_mood_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="mood", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/music/migrations/0030_track_tags.py b/vrobbler/apps/music/migrations/0030_track_tags.py new file mode 100644 index 0000000..df19cef --- /dev/null +++ b/vrobbler/apps/music/migrations/0030_track_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("music", "0029_remove_track_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="track", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/podcasts/migrations/0019_podcastepisode_tags.py b/vrobbler/apps/podcasts/migrations/0019_podcastepisode_tags.py new file mode 100644 index 0000000..1763217 --- /dev/null +++ b/vrobbler/apps/podcasts/migrations/0019_podcastepisode_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("podcasts", "0018_remove_podcastepisode_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="podcastepisode", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/puzzles/migrations/0005_puzzle_tags.py b/vrobbler/apps/puzzles/migrations/0005_puzzle_tags.py new file mode 100644 index 0000000..6b3827a --- /dev/null +++ b/vrobbler/apps/puzzles/migrations/0005_puzzle_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("puzzles", "0004_remove_puzzle_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="puzzle", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/scrobbles/mixins.py b/vrobbler/apps/scrobbles/mixins.py index 8c5e933..c4b413f 100644 --- a/vrobbler/apps/scrobbles/mixins.py +++ b/vrobbler/apps/scrobbles/mixins.py @@ -60,6 +60,7 @@ class ScrobblableMixin(TimeStampedModel): base_run_time_seconds = models.IntegerField(**BNULL) genre = TaggableManager(through=ObjectWithGenres, blank=True) + tags = TaggableManager(blank=True) class Meta: abstract = True diff --git a/vrobbler/apps/sports/migrations/0017_sportevent_tags.py b/vrobbler/apps/sports/migrations/0017_sportevent_tags.py new file mode 100644 index 0000000..3e12356 --- /dev/null +++ b/vrobbler/apps/sports/migrations/0017_sportevent_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("sports", "0016_remove_sportevent_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="sportevent", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/tasks/migrations/0006_task_tags.py b/vrobbler/apps/tasks/migrations/0006_task_tags.py new file mode 100644 index 0000000..3e2394e --- /dev/null +++ b/vrobbler/apps/tasks/migrations/0006_task_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("tasks", "0005_remove_task_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="task", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/trails/migrations/0007_trail_tags.py b/vrobbler/apps/trails/migrations/0007_trail_tags.py new file mode 100644 index 0000000..63794a7 --- /dev/null +++ b/vrobbler/apps/trails/migrations/0007_trail_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("trails", "0006_remove_trail_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="trail", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/videogames/migrations/0014_videogame_tags.py b/vrobbler/apps/videogames/migrations/0014_videogame_tags.py new file mode 100644 index 0000000..29e8ceb --- /dev/null +++ b/vrobbler/apps/videogames/migrations/0014_videogame_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("videogames", "0013_remove_videogame_run_time_seconds_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="videogame", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/videos/migrations/0027_video_tags.py b/vrobbler/apps/videos/migrations/0027_video_tags.py new file mode 100644 index 0000000..2586280 --- /dev/null +++ b/vrobbler/apps/videos/migrations/0027_video_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("videos", "0026_unique_imdb_youtube_together"), + ] + + operations = [ + migrations.AddField( + model_name="video", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/vrobbler/apps/webpages/migrations/0008_webpage_tags.py b/vrobbler/apps/webpages/migrations/0008_webpage_tags.py new file mode 100644 index 0000000..e061848 --- /dev/null +++ b/vrobbler/apps/webpages/migrations/0008_webpage_tags.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.29 on 2026-03-26 21:25 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), + ("webpages", "0007_webpage_image"), + ] + + operations = [ + migrations.AddField( + model_name="webpage", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ]