def setUp(self): user = get_user_model().objects.create_user(username='******', password='******') otaku = get_user_model().objects.create_user(username='******', password='******') otaku2 = get_user_model().objects.create_user(username='******', password='******') self.anime_category = Category.objects.get(slug='anime') manga = Category.objects.get(slug='manga') works = [ Work(title='Anime B', nb_episodes=0, category=self.anime_category), Work(title='Anime A', nb_episodes=1, category=self.anime_category), Work(title='Manga B', category=manga), Work(title='Manga A', category=manga), ] works = Work.objects.bulk_create(works) # This will work as long as mangaki.algo.dataset.RATED_BY_AT_LEAST <= 2 ratings = ( [Rating(user=otaku, work=work, choice='like') for work in works] + [ Rating(user=otaku2, work=work, choice='dislike') for work in works ] + [Rating(user=user, work=works[0], choice='dislike')]) Rating.objects.bulk_create(ratings) if not os.path.exists(SNAPSHOT_DIR_TEST): os.makedirs(SNAPSHOT_DIR_TEST)
def setUp(self): self.user = get_user_model().objects.create_user(username='******', password='******') otaku = get_user_model().objects.create_user(username='******', password='******') otaku2 = get_user_model().objects.create_user(username='******', password='******') self.anime_category = Category.objects.get(slug='anime') manga = Category.objects.get(slug='manga') works = [ Work(title='Anime B', nb_episodes=0, category=self.anime_category), Work(title='Anime A', nb_episodes=1, category=self.anime_category), Work(title='Manga B', category=manga), Work(title='Manga A', category=manga), ] works = Work.objects.bulk_create(works) self.work = works[0] # This will work as long as zero.dataset.RATED_BY_AT_LEAST <= 2 ratings = ( [Rating(user=otaku, work=work, choice='like') for work in works] + [ Rating(user=otaku2, work=work, choice='dislike') for work in works ] + [Rating(user=self.user, work=works[0], choice='dislike')]) Rating.objects.bulk_create(ratings) if not os.path.exists(ML_SNAPSHOT_ROOT_TEST): os.makedirs(ML_SNAPSHOT_ROOT_TEST) for key in {'svd', 'als', 'knn', 'knn-anonymous'}: path = get_path(key) if not os.path.exists(path): os.makedirs(path)
def test_work_group_by_category_order(self): anime = Category.objects.get(slug='anime') manga = Category.objects.get(slug='manga') works = [ Work(title='Anime B', nb_episodes=0, category=anime), Work(title='Anime A', nb_episodes=1, category=anime), Work(title='Manga B', category=manga), Work(title='Manga A', category=manga), ] works = Work.objects.bulk_create(works) works = [work.pk for work in works] grouped = Work.objects.filter(pk__in=works).order_by('pk').group_by_category() self.assertEqual(len(grouped), 2) self.assertEqual(len(grouped[anime.id]), 2) self.assertEqual(len(grouped[manga.id]), 2) self.assertEqual([work.title for work in grouped[anime.id]], ['Anime B', 'Anime A']) self.assertEqual([work.title for work in grouped[manga.id]], ['Manga B', 'Manga A']) grouped = Work.objects.filter(pk__in=works).order_by('title').group_by_category() self.assertEqual(len(grouped), 2) self.assertEqual(len(grouped[anime.id]), 2) self.assertEqual(len(grouped[manga.id]), 2) self.assertEqual([work.title for work in grouped[anime.id]], ['Anime A', 'Anime B']) self.assertEqual([work.title for work in grouped[manga.id]], ['Manga A', 'Manga B'])
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) slot_sort_types = ['popularity', 'controversy', 'top', 'random'] search_text = self.search_query sort_mode = self.sort_mode() flat = self.flat() context['search'] = search_text context['flat'] = flat context['sort_mode'] = sort_mode context['letter'] = self.request.GET.get('letter', '') context['category'] = self.category.slug context['is_dpp'] = self.is_dpp context['config'] = VANILLA_UI_CONFIG_FOR_RATINGS if not self.is_dpp else DPP_UI_CONFIG_FOR_RATINGS context['enable_kb_shortcuts'] = (False if self.request.user.is_anonymous else self.request.user.profile.keyboard_shortcuts_enabled) context['objects_count'] = self.category.work_set.count() if sort_mode == 'mosaic' and not self.is_dpp: context['object_list'] = [ { 'slot_type': slot_sort_type, 'work': Work(title='Chargement…', ext_poster='/static/img/chiro.gif') } for slot_sort_type in slot_sort_types ] return context
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) sort_mode = self.request.GET.get('sort', 'mosaic') flat_mode = self.request.GET.get('flat', '0') letter = self.request.GET.get('letter', '') context['params'] = {'sort': sort_mode, 'letter': letter, 'flat': flat_mode} context['url'] = urlencode({'sort': sort_mode, 'letter': letter}) context['manga_count'] = Manga.objects.count() context['template_mode'] = 'work_no_poster.html' if flat_mode == '1' else 'work_poster.html' if self.request.user.is_authenticated(): ratings = dict( Rating.objects.filter( user=self.request.user, work__in=list(context['object_list'])) \ .values_list('work_id', 'choice')) else: ratings = {} for obj in context['object_list']: obj.rating = ratings.get(obj.id, None) obj.poster = obj.safe_poster(self.request.user) if sort_mode == 'mosaic': context['object_list'] = [Work(title='Chargement…', poster='/static/img/chiro.gif') for _ in range(4)] return context
def setUp(self): self.user = get_user_model().objects.create_superuser(username='******', password='******', email='*****@*****.**') anime = Category.objects.get(slug='anime') Work.objects.bulk_create([ Work(title='Sangatsu no Lion', category=anime), Work(title='Hibike! Euphonium', category=anime), Work(title='Kiznaiver', category=anime) ]) self.work_ids = Work.objects.values_list('pk', flat=True) WorkTitle.objects.bulk_create([ WorkTitle(work=Work.objects.get(id=self.work_ids[0]), title='3-gatsu no Lion', type='synonym'), WorkTitle(work=Work.objects.get(id=self.work_ids[1]), title='Sound! Euphonium', type='synonym') ]) self.worktitle_ids = WorkTitle.objects.values_list('pk', flat=True)
def get_reco(request): category = request.GET.get('category', 'all') editor = request.GET.get('editor', 'unspecified') reco_list = [] dummy = Work(title='Chargement…', poster='/static/img/chiro.gif') for _ in range(4): reco_list.append((dummy, 'dummy')) return render(request, 'mangaki/reco_list.html', {'reco_list': reco_list, 'category': category, 'editor': editor})
def get_reco(request): category = request.GET.get('category', 'all') editor = request.GET.get('editor', 'unspecified') if request.user.rating_set.exists(): reco_list = [Work(title='Chargement…', poster='/static/img/chiro.gif') for _ in range(4)] else: reco_list = [] return render(request, 'mangaki/reco_list.html', {'reco_list': reco_list, 'category': category, 'editor': editor})
def get_reco(request): category = request.GET.get('category', 'all') algo = request.GET.get('algo', 'knn') if request.user.rating_set.exists(): reco_list = [Work(title='Chargement…', ext_poster='/static/img/chiro.gif') for _ in range(4)] else: reco_list = [] return render(request, 'mangaki/reco_list.html', {'reco_list': reco_list, 'category': category, 'algo': algo})
def get_reco_dpp(request): category = request.GET.get('category', 'all') reco_list = [Work(title='Chargement…', ext_poster='/static/img/chiro.gif') for _ in range(4)] return render(request, 'mangaki/reco_list_dpp.html', { 'reco_list': reco_list, 'category': category, 'config': DPP_UI_CONFIG_FOR_RATINGS })
def setUp(self): self.user = get_user_model().objects.create_superuser( username='******', password='******', email='*****@*****.**') client.client_id = 'fake' client.client_ver = 1 client.is_available = True self.anime = Category.objects.get(slug='anime') Work.objects.bulk_create([ Work(title='Hibike! Euphonium', anidb_aid=10889, category=self.anime), Work(title='Punchline', category=self.anime), Work(title='Kiznaiver', anidb_aid=11692, category=self.anime), Work(title='Kiznaiver Duplicate', anidb_aid=11692, category=self.anime) ]) self.work_ids = Work.objects.values_list('pk', flat=True)
def get_reco(request): category = request.GET.get('category', 'all') algo_name = request.GET.get('algo', 'svd' if user_exists_in_backup(request.user, 'svd') else 'knn') if current_user_ratings(request): reco_list = [{ 'work': Work(title='Chargement…', ext_poster='/static/img/chiro.gif') } for _ in range(4)] else: reco_list = [] return render(request, 'mangaki/reco_list.html', { 'reco_list': reco_list, 'category': category, 'algo': algo_name, 'config': VANILLA_UI_CONFIG_FOR_RATINGS })
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) search_text = self.search() sort_mode = self.sort_mode() context['search'] = search_text context['sort_mode'] = sort_mode context['letter'] = self.request.GET.get('letter', '') context['category'] = self.category.slug context['objects_count'] = self.category.work_set.count() if sort_mode == 'mosaic': context['object_list'] = [ Work(title='Chargement…', poster='/static/img/chiro.gif') for _ in range(4) ] return context
def _build_related_animes(self, work: Work, related_animes: Dict[int, Dict[str, str]]) -> List[RelatedWork]: anidb_aids = related_animes.keys() # Fill the Work database with missing work items and retrieve existing ones # Note : these works won't be filled with data, they'll have to be updated afterwards existing_works = Work.objects.filter(anidb_aid__in=anidb_aids) existing_anidb_aids = set(existing_works.values_list('anidb_aid', flat=True)) new_works = [] for anidb_aid in anidb_aids: if anidb_aid not in existing_anidb_aids: new_works.append( Work( title=related_animes[anidb_aid]['title'], category=self.anime_category, anidb_aid=anidb_aid ) ) works = [work for work in existing_works] works.extend(Work.objects.bulk_create(new_works)) # Add relations between works if they don't yet exist existing_relations = RelatedWork.objects.filter(child_work__in=works, parent_work=work) existing_child_works = set(existing_relations.values_list('child_work__pk', flat=True)) existing_parent_works = set(existing_relations.values_list('parent_work__pk', flat=True)) new_relations = [] for child_work in works: if child_work.pk not in existing_child_works and work.pk not in existing_parent_works: new_relations.append( RelatedWork( parent_work=work, child_work=child_work, type=related_animes[child_work.anidb_aid]['type'] ) ) RelatedWork.objects.bulk_create(new_relations) return new_relations
def get_context_data(self, **kwargs): my_rated_works = get_rated_works( self.request.user) if self.request.user.is_authenticated() else {} sort_mode = self.request.GET.get('sort', 'mosaic') flat_mode = self.request.GET.get('flat', '0') letter = self.request.GET.get('letter', '') page = int(self.request.GET.get('page', '1')) context = super(MangaList, self).get_context_data(**kwargs) # context['object_list'] = list(context['object_list']) if sort_mode == 'mosaic': manga_ids = [] context['object_list'] = [ Work(title='Chargement…', poster='/static/img/chiro.gif') for _ in range(4) ] elif sort_mode in ['popularity', 'controversy', 'top', 'random']: manga_ids = Deck.objects.get( category='manga', sort_mode=sort_mode).content.split(',') if sort_mode == 'random': shuffle(manga_ids) else: manga_ids = list(map(lambda obj: obj.id, context['object_list']) ) # Double conversion (and repetition), to fix paginator = Paginator( manga_ids, TITLES_PER_PAGE if flat_mode == '1' else POSTERS_PER_PAGE) try: page_manga_ids = paginator.page(page) except PageNotAnInteger: # If page is not an integer, deliver first page. page_manga_ids = paginator.page(1) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. page_manga_ids = paginator.page(paginator.num_pages) context['params'] = { 'sort': sort_mode, 'letter': letter, 'page': page, 'flat': flat_mode } context['url'] = urlencode({'sort': sort_mode, 'letter': letter}) context['manga_count'] = Manga.objects.count() context['pages'] = filter( lambda x: 1 <= x <= paginator.num_pages, range(page_manga_ids.number - 2, page_manga_ids.number + 2 + 1)) context[ 'template_mode'] = 'work_no_poster.html' if flat_mode == '1' else 'work_poster.html' works = Work.objects.in_bulk(page_manga_ids) manga_list = list( map(lambda work_id: works[int(work_id)], page_manga_ids)) for obj in manga_list: update_poster_if_nsfw(obj, self.request.user) if self.request.user.is_authenticated(): obj.rating = my_rated_works.get(obj.id, None) if sort_mode != 'mosaic': context['object_list'] = manga_list return context
def setUp(self): self.user = get_user_model().objects.create_superuser( username='******', password='******', email='*****@*****.**') self.users = [] for username in 'ABCD': self.users.append(get_user_model().objects.create_user( username=username, password='******')) today = datetime.now() yesterday = datetime.now() - timedelta(1) tomorrow = datetime.now() + timedelta(1) anime = Category.objects.get(slug='anime') Work.objects.bulk_create([ Work(title='Sangatsu no Lion', category=anime) for _ in range(10) ]) Work.objects.create(title='Sangatsu no Lion', category=anime, nb_episodes=22) self.work_ids = Work.objects.values_list('id', flat=True) # Admin rated every movie Rating.objects.bulk_create([ Rating(work_id=work_id, user=self.user, choice='like') for work_id in self.work_ids ]) the_artist = Artist.objects.create(name='Yoko Kanno') references = [] for work_id in self.work_ids: references.extend( Reference.objects.bulk_create([ Reference(work_id=work_id, source='MAL', identifier=31646, url='https://myanimelist.net/anime/31646'), Reference( work_id=work_id, source='AniDB', identifier=11606, url= 'https://anidb.net/perl-bin/animedb.pl?show=anime&aid=11606' ) ])) roles = Role.objects.bulk_create([ Role(name='Director', slug='xxx'), Role(name='Composer', slug='yyy') ]) Staff.objects.bulk_create([ Staff(work_id=self.work_ids[0], artist=the_artist, role=roles[0]), Staff(work_id=self.work_ids[1], artist=the_artist, role=roles[0]), Staff(work_id=self.work_ids[1], artist=the_artist, role=roles[1]) ]) genres = Genre.objects.bulk_create( [Genre(title='SF'), Genre(title='Slice of life')]) Work.objects.get(id=self.work_ids[0]).genre.add(genres[0]) Work.objects.get(id=self.work_ids[1]).genre.add(genres[0]) Work.objects.get(id=self.work_ids[1]).genre.add(genres[1]) # Rating are built so that after merge, only the favorites should be kept Rating.objects.bulk_create([ Rating(work_id=self.work_ids[0], user=self.users[0], choice='like', date=today), Rating(work_id=self.work_ids[1], user=self.users[0], choice='favorite', date=tomorrow), Rating(work_id=self.work_ids[2], user=self.users[0], choice='dislike', date=yesterday), Rating(work_id=self.work_ids[1], user=self.users[1], choice='favorite', date=today), Rating(work_id=self.work_ids[0], user=self.users[2], choice='favorite', date=today), Rating(work_id=self.work_ids[2], user=self.users[2], choice='like', date=yesterday), Rating(work_id=self.work_ids[0], user=self.users[3], choice='favorite', date=yesterday) ]) Rating.objects.filter(work_id=self.work_ids[1], user=self.users[0]).update(date=tomorrow) Rating.objects.filter(work_id=self.work_ids[2], user=self.users[0]).update(date=yesterday) Rating.objects.filter(work_id=self.work_ids[2], user=self.users[2]).update(date=yesterday), Rating.objects.filter(work_id=self.work_ids[0], user=self.users[3]).update(date=yesterday)
def get_poster(self, work: Work): return work.safe_poster(self.context['request'].user)