From bde7ce47a3b39e2da8b5414d11be89d59565b0a1 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 29 Dec 2022 23:49:28 -0500 Subject: [PATCH] song->album; refactor shelf --- journal/models.py | 104 +++--- journal/tests.py | 10 +- journal/views.py | 8 +- legacy/management/commands/migrate_catalog.py | 309 +++++++++++------- legacy/management/commands/migrate_journal.py | 22 +- legacy/models.py | 5 + social/tests.py | 6 +- 7 files changed, 261 insertions(+), 203 deletions(-) diff --git a/journal/models.py b/journal/models.py index bc15ba65..6a7fdf41 100644 --- a/journal/models.py +++ b/journal/models.py @@ -65,7 +65,7 @@ def query_item_category(item_category): # return q ct = all_content_types() contenttype_ids = [ct[cls] for cls in classes] - return Q(item__polymorphic_ctype__in=sorted(contenttype_ids)) + return Q(item__polymorphic_ctype__in=contenttype_ids) class Piece(PolymorphicModel, UserOwnedObjectMixin): @@ -325,6 +325,9 @@ class List(Piece): def recent_members(self): return self.members.all().order_by("-created_time") + def get_members_in_category(self, item_category): + return self.members.all().filter(query_item_category(item_category)) + def get_member_for_item(self, item): return self.members.filter(item=item).first() @@ -459,44 +462,16 @@ class ShelfMember(ListMember): class Shelf(List): class Meta: - unique_together = [["owner", "item_category", "shelf_type"]] + unique_together = [["owner", "shelf_type"]] MEMBER_CLASS = ShelfMember items = models.ManyToManyField(Item, through="ShelfMember", related_name="+") - item_category = models.CharField( - choices=ItemCategory.choices, max_length=100, null=False, blank=False - ) shelf_type = models.CharField( choices=ShelfType.choices, max_length=100, null=False, blank=False ) def __str__(self): - return f"{self.id} {self.title}" - - @cached_property - def item_category_label(self): - return ItemCategory(self.item_category).label - - @cached_property - def shelf_label(self): - return next( - iter( - [ - n[2] - for n in iter(ShelfTypeNames) - if n[0] == self.item_category and n[1] == self.shelf_type - ] - ), - self.shelf_type, - ) - - @cached_property - def title(self): - q = _("{shelf_label}的{item_category}").format( - shelf_label=self.shelf_label, item_category=self.item_category_label - ) - return q - # return _("{user}'s {shelf_name}").format(user=self.owner.mastodon_username, shelf_name=q) + return f"{self.id} [{self.owner} {self.shelf_type} list]" class ShelfLogEntry(models.Model): @@ -526,39 +501,31 @@ class ShelfManager: def __init__(self, user): self.owner = user + qs = Shelf.objects.filter(owner=self.owner) + self.shelf_list = {v.shelf_type: v for v in qs} + if len(self.shelf_list) == 0: + self.initialize() def initialize(self): - for ic in ItemCategory: - for qt in ShelfType: - Shelf.objects.create(owner=self.owner, item_category=ic, shelf_type=qt) + for qt in ShelfType: + self.shelf_list[qt] = Shelf.objects.create(owner=self.owner, shelf_type=qt) - def _shelf_member_for_item(self, item): + def locate_item(self, item) -> ShelfMember: return ShelfMember.objects.filter( - item=item, parent__in=self.owner.shelf_set.all() + item=item, parent__in=list(self.shelf_list.values()) ).first() - def _shelf_for_item_and_type(self, item, shelf_type): - if not item or not shelf_type: - return None - return self.owner.shelf_set.all().filter( - item_category=item.category, shelf_type=shelf_type - ) - - def locate_item(self, item): - member = ShelfMember.objects.filter(owner=self.owner, item=item).first() - return member # .parent if member else None - def move_item(self, item, shelf_type, visibility=0, metadata=None): # shelf_type=None means remove from current shelf # metadata=None means no change if not item: raise ValueError("empty item") new_shelfmember = None - last_shelfmember = self._shelf_member_for_item(item) + last_shelfmember = self.locate_item(item) last_shelf = last_shelfmember.parent if last_shelfmember else None last_metadata = last_shelfmember.metadata if last_shelfmember else None last_visibility = last_shelfmember.visibility if last_shelfmember else None - shelf = self.get_shelf(item.category, shelf_type) if shelf_type else None + shelf = self.shelf_list[shelf_type] if shelf_type else None changed = False if last_shelf != shelf: # change shelf changed = True @@ -596,20 +563,29 @@ class ShelfManager: "timestamp" ) - def get_shelf(self, item_category, shelf_type): - return ( - self.owner.shelf_set.all() - .filter(item_category=item_category, shelf_type=shelf_type) - .first() - ) + def get_shelf(self, shelf_type): + return self.shelf_list[shelf_type] - def get_items_on_shelf(self, item_category, shelf_type): - shelf = ( - self.owner.shelf_set.all() - .filter(item_category=item_category, shelf_type=shelf_type) - .first() + def get_members(self, shelf_type, item_category): + return self.shelf_list[shelf_type].get_members_in_category(item_category) + + # def get_items_on_shelf(self, item_category, shelf_type): + # shelf = ( + # self.owner.shelf_set.all() + # .filter(item_category=item_category, shelf_type=shelf_type) + # .first() + # ) + # return shelf.members.all().order_by + + def get_title(self, shelf_type, item_category): + ic = ItemCategory(item_category).label + sts = [ + n[2] for n in ShelfTypeNames if n[0] == item_category and n[1] == shelf_type + ] + st = sts[0] if sts else shelf_type + return _("{shelf_label}的{item_category}").format( + shelf_label=st, item_category=ic ) - return shelf.members.all().order_by @staticmethod def get_manager_for_user(user): @@ -820,7 +796,11 @@ class Mark: @property def shelf_label(self): - return self.shelfmember.parent.shelf_label if self.shelfmember else None + return ( + self.owner.shelf_manager.get_title(self.shelf_type, self.item.category) + if self.shelfmember + else None + ) @property def created_time(self): diff --git a/journal/tests.py b/journal/tests.py index 0d3107da..31e55c2f 100644 --- a/journal/tests.py +++ b/journal/tests.py @@ -35,12 +35,11 @@ class ShelfTest(TestCase): def test_shelf(self): user = User.objects.create(mastodon_site="site", username="name") shelf_manager = ShelfManager(user=user) - shelf_manager.initialize() - self.assertEqual(user.shelf_set.all().count(), 33) + self.assertEqual(user.shelf_set.all().count(), 3) book1 = Edition.objects.create(title="Hyperion") book2 = Edition.objects.create(title="Andymion") - q1 = shelf_manager.get_shelf(ItemCategory.Book, ShelfType.WISHLIST) - q2 = shelf_manager.get_shelf(ItemCategory.Book, ShelfType.PROGRESS) + q1 = shelf_manager.get_shelf(ShelfType.WISHLIST) + q2 = shelf_manager.get_shelf(ShelfType.PROGRESS) self.assertIsNotNone(q1) self.assertIsNotNone(q2) self.assertEqual(q1.members.all().count(), 0) @@ -123,7 +122,6 @@ class MarkTest(TestCase): def setUp(self): self.book1 = Edition.objects.create(title="Hyperion") self.user1 = User.objects.create(mastodon_site="site", username="name") - self.user1.shelf_manager.initialize() pass def test_mark(self): @@ -139,7 +137,7 @@ class MarkTest(TestCase): mark = Mark(self.user1, self.book1) self.assertEqual(mark.shelf_type, ShelfType.WISHLIST) - self.assertEqual(mark.shelf_label, "想读") + self.assertEqual(mark.shelf_label, "想读的书") self.assertEqual(mark.text, "a gentle comment") self.assertEqual(mark.rating, 9) self.assertEqual(mark.visibility, 1) diff --git a/journal/views.py b/journal/views.py index b9d635ae..f902ae09 100644 --- a/journal/views.py +++ b/journal/views.py @@ -380,8 +380,7 @@ def _render_list( ): return render_user_blocked(request) if type == "mark": - shelf = user.shelf_manager.get_shelf(item_category, shelf_type) - queryset = ShelfMember.objects.filter(owner=user, parent=shelf) + queryset = user.shelf_manager.get_members(shelf_type, item_category) elif type == "tagmember": tag = Tag.objects.filter(owner=user, title=tag_title).first() if not tag: @@ -555,10 +554,9 @@ def home(request, user_name): for category in visbile_categories: shelf_list[category] = {} for shelf_type in ShelfType: - shelf = user.shelf_manager.get_shelf(category, shelf_type) - members = shelf.recent_members.filter(qv) + members = user.shelf_manager.get_members(shelf_type, category).filter(qv) shelf_list[category][shelf_type] = { - "title": shelf.title, + "title": user.shelf_manager.get_title(shelf_type, category), "count": members.count(), "members": members[:5].prefetch_related("item"), } diff --git a/legacy/management/commands/migrate_catalog.py b/legacy/management/commands/migrate_catalog.py index fb89c1a8..eb01e8c6 100644 --- a/legacy/management/commands/migrate_catalog.py +++ b/legacy/management/commands/migrate_catalog.py @@ -16,115 +16,133 @@ from django.db.models import Q, Count, Sum from django.utils import dateparse, timezone import re from legacy.models import * - +from django.db import DatabaseError, transaction +from music.models import SongMark +from collection.models import CollectionItem BATCH_SIZE = 1000 def _book_convert(entity): - content = ResourceContent(metadata={ - 'title': entity.title, - 'brief': entity.brief, - 'cover_image_path': str(entity.cover), - - 'subtitle': entity.subtitle, - 'orig_title': entity.orig_title, - 'author': entity.author, - 'translator': entity.translator, - 'language': entity.language, - 'pub_house': entity.pub_house, - 'pub_year': entity.pub_year, - 'pub_month': entity.pub_month, - 'binding': entity.binding, - 'price': entity.price, - 'pages': entity.pages, - 'contents': entity.contents, - 'series': entity.other_info.get('丛书') if entity.other_info else None, - 'imprint': entity.other_info.get('出品方') if entity.other_info else None, - }) + content = ResourceContent( + metadata={ + "title": entity.title, + "brief": entity.brief, + "cover_image_path": str(entity.cover), + "subtitle": entity.subtitle, + "orig_title": entity.orig_title, + "author": entity.author, + "translator": entity.translator, + "language": entity.language, + "pub_house": entity.pub_house, + "pub_year": entity.pub_year, + "pub_month": entity.pub_month, + "binding": entity.binding, + "price": entity.price, + "pages": entity.pages, + "contents": entity.contents, + "series": entity.other_info.get("丛书") if entity.other_info else None, + "imprint": entity.other_info.get("出品方") if entity.other_info else None, + } + ) if entity.isbn: t, v = detect_isbn_asin(entity.isbn) if t: content.lookup_ids[t] = v - if entity.other_info and entity.other_info.get('统一书号'): - content.lookup_ids[IdType.CUBN] = entity.other_info.get('统一书号') + if entity.other_info and entity.other_info.get("统一书号"): + content.lookup_ids[IdType.CUBN] = entity.other_info.get("统一书号") return content def _album_convert(entity): - content = ResourceContent(metadata={ - 'title': entity.title, - 'brief': entity.brief, - 'cover_image_path': str(entity.cover), - - 'other_title': entity.other_info.get('又名') if entity.other_info else None, - 'album_type': entity.other_info.get('专辑类型') if entity.other_info else None, - 'media': entity.other_info.get('介质') if entity.other_info else None, - 'disc_count': entity.other_info.get('碟片数') if entity.other_info else None, - 'artist': entity.artist, - 'genre': entity.genre, - 'release_date': entity.release_date.strftime('%Y-%m-%d') if entity.release_date else None, - 'duration': entity.duration, - 'company': entity.company, - 'track_list': entity.track_list, - 'bandcamp_album_id': entity.other_info.get('bandcamp_album_id') if entity.other_info else None, - }) - if entity.other_info and entity.other_info.get('ISRC'): - content.lookup_ids[IdType.ISRC] = entity.other_info.get('ISRC') - if entity.other_info and entity.other_info.get('条形码'): - content.lookup_ids[IdType.GTIN] = entity.other_info.get('条形码') - if entity.other_info and entity.other_info.get('UPC'): - content.lookup_ids[IdType.GTIN] = entity.other_info.get('UPC') + content = ResourceContent( + metadata={ + "title": entity.title, + "brief": entity.brief, + "cover_image_path": str(entity.cover), + "other_title": entity.other_info.get("又名") if entity.other_info else None, + "album_type": entity.other_info.get("专辑类型") if entity.other_info else None, + "media": entity.other_info.get("介质") if entity.other_info else None, + "disc_count": entity.other_info.get("碟片数") if entity.other_info else None, + "artist": entity.artist, + "genre": entity.genre, + "release_date": entity.release_date.strftime("%Y-%m-%d") + if entity.release_date + else None, + "duration": entity.duration, + "company": entity.company, + "track_list": entity.track_list, + "bandcamp_album_id": entity.other_info.get("bandcamp_album_id") + if entity.other_info + else None, + } + ) + if entity.other_info and entity.other_info.get("ISRC"): + content.lookup_ids[IdType.ISRC] = entity.other_info.get("ISRC") + if entity.other_info and entity.other_info.get("条形码"): + content.lookup_ids[IdType.GTIN] = entity.other_info.get("条形码") + if entity.other_info and entity.other_info.get("UPC"): + content.lookup_ids[IdType.GTIN] = entity.other_info.get("UPC") return content def _game_convert(entity): - content = ResourceContent(metadata={ - 'title': entity.title, - 'brief': entity.brief, - 'cover_image_path': str(entity.cover), - - 'other_title': entity.other_title, - 'developer': entity.developer, - 'publisher': entity.publisher, - 'release_date': entity.release_date.strftime('%Y-%m-%d') if entity.release_date else None, - 'genre': entity.genre, - 'platform': entity.platform, - 'official_site': entity.other_info.get('official_site') if entity.other_info else None, - }) - if entity.other_info and entity.other_info.get('steam_url'): - content.lookup_ids[IdType.Steam] = re.search(r'store\.steampowered\.com/app/(\d+)', entity.other_info.get('steam_url'))[1] + content = ResourceContent( + metadata={ + "title": entity.title, + "brief": entity.brief, + "cover_image_path": str(entity.cover), + "other_title": entity.other_title, + "developer": entity.developer, + "publisher": entity.publisher, + "release_date": entity.release_date.strftime("%Y-%m-%d") + if entity.release_date + else None, + "genre": entity.genre, + "platform": entity.platform, + "official_site": entity.other_info.get("official_site") + if entity.other_info + else None, + } + ) + if entity.other_info and entity.other_info.get("steam_url"): + content.lookup_ids[IdType.Steam] = re.search( + r"store\.steampowered\.com/app/(\d+)", entity.other_info.get("steam_url") + )[1] return content def _movie_tv_convert(entity): - content = ResourceContent(metadata={ - 'title': entity.title, - 'brief': entity.brief, - 'cover_image_path': str(entity.cover), - - 'orig_title': entity.orig_title, - 'other_title': entity.other_title, - 'director': entity.director, - 'playwright': entity.playwright, - 'actor': entity.actor, - 'genre': entity.genre, - 'showtime': entity.showtime, - 'site': entity.site, - 'area': entity.area, - 'language': entity.language, - 'year': entity.year, - 'duration': entity.duration, - 'season_count': entity.other_info.get('Seasons') if entity.other_info else None, - 'season_number': entity.season, - 'episode_count': entity.episodes, - 'single_episode_length': entity.single_episode_length, - 'is_series': entity.is_series, - }) + content = ResourceContent( + metadata={ + "title": entity.title, + "brief": entity.brief, + "cover_image_path": str(entity.cover), + "orig_title": entity.orig_title, + "other_title": entity.other_title, + "director": entity.director, + "playwright": entity.playwright, + "actor": entity.actor, + "genre": entity.genre, + "showtime": entity.showtime, + "site": entity.site, + "area": entity.area, + "language": entity.language, + "year": entity.year, + "duration": entity.duration, + "season_count": entity.other_info.get("Seasons") + if entity.other_info + else None, + "season_number": entity.season, + "episode_count": entity.episodes, + "single_episode_length": entity.single_episode_length, + "is_series": entity.is_series, + } + ) if entity.imdb_code: content.lookup_ids[IdType.IMDB] = entity.imdb_code - if entity.other_info and entity.other_info.get('TMDB_ID'): - content.lookup_ids[IdType.TMDB_TV] = entity.other_info.get('TMDB_ID') + if entity.other_info and entity.other_info.get("TMDB_ID"): + content.lookup_ids[IdType.TMDB_TV] = entity.other_info.get("TMDB_ID") return content @@ -147,33 +165,77 @@ model_link = { class Command(BaseCommand): - help = 'Migrate legacy catalog' + help = "Migrate legacy catalog" def add_arguments(self, parser): - parser.add_argument('--book', dest='types', action='append_const', const=Legacy_Book) - parser.add_argument('--movie', dest='types', action='append_const', const=Legacy_Movie) - parser.add_argument('--album', dest='types', action='append_const', const=Legacy_Album) - parser.add_argument('--game', dest='types', action='append_const', const=Legacy_Game) - parser.add_argument('--id', help='id to convert; or, if using with --max-id, the min id') - parser.add_argument('--maxid', help='max id to convert') - parser.add_argument('--failstop', help='stop on fail', action='store_true') - parser.add_argument('--clearlink', help='clear legacy link table', action='store_true') - parser.add_argument('--reload', help='reload and ignore existing ExternalResource', action='store_true') + parser.add_argument( + "--book", dest="types", action="append_const", const=Legacy_Book + ) + parser.add_argument( + "--movie", dest="types", action="append_const", const=Legacy_Movie + ) + parser.add_argument( + "--album", dest="types", action="append_const", const=Legacy_Album + ) + parser.add_argument( + "--game", dest="types", action="append_const", const=Legacy_Game + ) + parser.add_argument("--song", help="process songs", action="store_true") + parser.add_argument( + "--id", help="id to convert; or, if using with --max-id, the min id" + ) + parser.add_argument("--maxid", help="max id to convert") + parser.add_argument("--failstop", help="stop on fail", action="store_true") + parser.add_argument( + "--clearlink", help="clear legacy link table", action="store_true" + ) + parser.add_argument( + "--reload", + help="reload and ignore existing ExternalResource", + action="store_true", + ) + + def process_song(self, entity): + if entity.album: + new_uid = AlbumLink.objects.get(old_id=entity.album.id).new_uid + else: + new_uid = Album.objects.create( + title=entity.title, + brief=entity.brief, + cover=entity.cover, + artist=entity.artist, + ).uid + if SongLink.objects.filter(old_id=entity.id).count() == 0: + SongLink.objects.create(old_id=entity.id, new_uid=new_uid) def handle(self, *args, **options): - types = options['types'] or [Legacy_Game, Legacy_Album, Legacy_Movie, Legacy_Book] - reload = options['reload'] + if options["song"]: + for sm in SongMark.objects.all(): + self.process_song(sm.song) + for ci in CollectionItem.objects.filter(song__isnull=False): + self.process_song(ci.song) + return + + types = options["types"] or [ + Legacy_Game, + Legacy_Album, + Legacy_Movie, + Legacy_Book, + ] + reload = options["reload"] for typ in types: print(typ) LinkModel = model_link[typ] - if options['clearlink']: + if options["clearlink"]: LinkModel.objects.all().delete() - qs = typ.objects.all().order_by('id') - if options['id']: - if options['maxid']: - qs = qs.filter(id__gte=int(options['id']), id__lte=int(options['maxid'])) + qs = typ.objects.all().order_by("id") + if options["id"]: + if options["maxid"]: + qs = qs.filter( + id__gte=int(options["id"]), id__lte=int(options["maxid"]) + ) else: - qs = qs.filter(id=int(options['id'])) + qs = qs.filter(id=int(options["id"])) pg = Paginator(qs, BATCH_SIZE) for p in tqdm(pg.page_range): @@ -185,34 +247,47 @@ class Command(BaseCommand): site = SiteManager.get_site_by_url(entity.source_url) item = None if site: - if not site.DEFAULT_MODEL and not content.metadata.get('preferred_model'): + if not site.DEFAULT_MODEL and not content.metadata.get( + "preferred_model" + ): if model_map[typ] == Movie and entity.is_series: - content.metadata['preferred_model'] = 'TVSeason' if entity.season else 'TVShow' + content.metadata["preferred_model"] = ( + "TVSeason" if entity.season else "TVShow" + ) else: - content.metadata['preferred_model'] = model_map[typ].__name__ - item = site.get_resource_ready(preloaded_content=content, ignore_existing_content=reload).item + content.metadata["preferred_model"] = model_map[ + typ + ].__name__ + item = site.get_resource_ready( + preloaded_content=content, + ignore_existing_content=reload, + ).item else: # not known site, try save item without external resource item = None - model = Edition + model = model_map[typ] t, v = None, None if content.lookup_ids: t, v = Item.get_best_lookup_id(content.lookup_ids) - item = model.objects.filter(primary_lookup_id_type=t, primary_lookup_id_value=v).first() + item = model.objects.filter( + primary_lookup_id_type=t, + primary_lookup_id_value=v, + ).first() if not item: obj = model.copy_metadata(content.metadata) - obj['primary_lookup_id_type'] = t - obj['primary_lookup_id_value'] = v + obj["primary_lookup_id_type"] = t + obj["primary_lookup_id_value"] = v item = model.objects.create(**obj) - item.cover = content.metadata['cover_image_path'] + item.cover = content.metadata["cover_image_path"] item.last_editor = entity.last_editor item.save() links.append(LinkModel(old_id=entity.id, new_uid=item.uid)) # pprint.pp(site.get_item()) except Exception as e: - print(f'Convert failed for {typ} {entity.id}: {e}') - if options['failstop']: - raise(e) + print(f"Convert failed for {typ} {entity.id}: {e}") + if options["failstop"]: + raise (e) # return LinkModel.objects.bulk_create(links) - self.stdout.write(self.style.SUCCESS(f'Done.')) + + self.stdout.write(self.style.SUCCESS(f"Done.")) diff --git a/legacy/management/commands/migrate_journal.py b/legacy/management/commands/migrate_journal.py index 36001e61..a434c3a7 100644 --- a/legacy/management/commands/migrate_journal.py +++ b/legacy/management/commands/migrate_journal.py @@ -6,7 +6,7 @@ from games.models import Game as Legacy_Game from common.models import MarkStatusEnum from books.models import BookMark, BookReview from movies.models import MovieMark, MovieReview -from music.models import AlbumMark, AlbumReview +from music.models import AlbumMark, AlbumReview, SongMark, SongReview from games.models import GameMark, GameReview from collection.models import Collection as Legacy_Collection from collection.models import CollectionMark as Legacy_CollectionMark @@ -35,14 +35,17 @@ model_link = { MovieMark: MovieLink, AlbumMark: AlbumLink, GameMark: GameLink, + SongMark: SongLink, BookReview: BookLink, MovieReview: MovieLink, AlbumReview: AlbumLink, GameReview: GameLink, + SongReview: SongLink, Legacy_Book: BookLink, Legacy_Movie: MovieLink, Legacy_Album: AlbumLink, Legacy_Game: GameLink, + Legacy_Song: SongLink, } shelf_map = { @@ -55,6 +58,7 @@ tag_map = { BookMark: "bookmark_tags", MovieMark: "moviemark_tags", AlbumMark: "albummark_tags", + SongMark: "songmark_tags", GameMark: "gamemark_tags", } @@ -75,6 +79,9 @@ class Command(BaseCommand): parser.add_argument( "--game", dest="types", action="append_const", const=GameMark ) + parser.add_argument( + "--song", dest="types", action="append_const", const=SongMark + ) parser.add_argument( "--mark", help="migrate shelves/tags/ratings, then exit", @@ -104,7 +111,7 @@ class Command(BaseCommand): print("Initialize shelves") with transaction.atomic(): for user in tqdm(User.objects.filter(is_active=True)): - user.shelf_manager.initialize() + temp = user.shelf_manager def clear(self, classes): print("Deleting migrated user pieces") @@ -196,12 +203,11 @@ class Command(BaseCommand): raise (e) def mark(self, options): - types = options["types"] or [GameMark, AlbumMark, MovieMark, BookMark] + types = options["types"] or [GameMark, SongMark, AlbumMark, MovieMark, BookMark] print("Preparing cache") tag_cache = {f"{t.owner_id}_{t.title}": t.id for t in Tag.objects.all()} shelf_cache = { - f"{s.owner_id}_{s.item_category}_{shelf_map[s.shelf_type]}": s.id - for s in Shelf.objects.all() + f"{s.owner_id}_{shelf_map[s.shelf_type]}": s.id for s in Shelf.objects.all() } for typ in types: @@ -255,9 +261,7 @@ class Command(BaseCommand): text=entity.text, visibility=visibility, ) - shelf = shelf_cache[ - f"{user_id}_{item.category}_{entity.status}" - ] + shelf = shelf_cache[f"{user_id}_{entity.status}"] ShelfMember.objects.create( parent_id=shelf, owner_id=user_id, @@ -309,7 +313,7 @@ class Command(BaseCommand): elif options["mark"]: if options["clear"]: self.clear( - [Comment, Rating, TagMember, Tag, ShelfLogEntry, ShelfMember] + [Comment, Rating, TagMember, Tag, ShelfLogEntry, ShelfMember, Shelf] ) else: self.mark(options) diff --git a/legacy/models.py b/legacy/models.py index f9e4fe51..d1e3d1eb 100644 --- a/legacy/models.py +++ b/legacy/models.py @@ -16,6 +16,11 @@ class AlbumLink(models.Model): new_uid = models.UUIDField() +class SongLink(models.Model): + old_id = models.IntegerField(db_index=True) + new_uid = models.UUIDField() + + class GameLink(models.Model): old_id = models.IntegerField(db_index=True) new_uid = models.UUIDField() diff --git a/social/tests.py b/social/tests.py index 9640b636..e7cf87cb 100644 --- a/social/tests.py +++ b/social/tests.py @@ -11,9 +11,7 @@ class SocialTest(TestCase): self.book2 = Edition.objects.create(title="Andymion") self.movie = Edition.objects.create(title="Fight Club") self.alice = User.objects.create(mastodon_site="MySpace", username="Alice") - self.alice.shelf_manager.initialize() self.bob = User.objects.create(mastodon_site="KKCity", username="Bob") - self.bob.shelf_manager.initialize() def test_timeline(self): # alice see 0 activity in timeline in the beginning @@ -40,8 +38,8 @@ class SocialTest(TestCase): self.assertEqual(len(timeline2), 0) # bob follows alice, see 2 activities - self.bob.mastodon_following = ['Alice@MySpace'] - self.alice.mastodon_follower = ['Bob@KKCity'] + self.bob.mastodon_following = ["Alice@MySpace"] + self.alice.mastodon_follower = ["Bob@KKCity"] self.bob.following = self.bob.get_following_ids() timeline2 = self.bob.activity_manager.get_timeline() self.assertEqual(len(timeline2), 2)