def retrieve_review_list(request, movie_id): if request.method == 'GET': movie = get_object_or_404(Movie, pk=movie_id) queryset = MovieReview.get_available(movie, request.user, request.session['oauth_token']) paginator = Paginator(queryset, REVIEW_PER_PAGE) page_number = request.GET.get('page', default=1) reviews = paginator.get_page(page_number) reviews.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages) return render(request, 'movies/review_list.html', { 'reviews': reviews, 'movie': movie, }) else: return HttpResponseBadRequest()
def retrieve_mark_list(request, movie_id): if request.method == 'GET': movie = get_object_or_404(Movie, pk=movie_id) queryset = MovieMark.get_available(movie, request.user, request.session['oauth_token']) paginator = Paginator(queryset, MARK_PER_PAGE) page_number = request.GET.get('page', default=1) marks = paginator.get_page(page_number) marks.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages) for m in marks: m.get_status_display = MovieMarkStatusTranslator(m.status) return render(request, 'movies/mark_list.html', { 'marks': marks, 'movie': movie, }) else: return HttpResponseBadRequest()
def movie_list(request, id, status): if request.method == 'GET': if not status.upper() in MarkStatusEnum.names: return HttpResponseBadRequest() if isinstance(id, str): try: username = id.split('@')[0] site = id.split('@')[1] except IndexError as e: return HttpResponseBadRequest("Invalid user id") query_kwargs = {'username': username, 'mastodon_site': site} elif isinstance(id, int): query_kwargs = {'pk': id} try: user = User.objects.get(**query_kwargs) except ObjectDoesNotExist: msg = _("😖哎呀这位老师还没有注册书影音呢,快去长毛象喊TA来吧!") sec_msg = _("目前只开放本站用户注册") return render(request, 'common/error.html', { 'msg': msg, 'secondary_msg': sec_msg, }) if not user == request.user: # mastodon request relation = get_relationship(request.user, user, request.session['oauth_token'])[0] if relation['blocked_by']: msg = _("你没有访问TA主页的权限😥") return render(request, 'common/error.html', { 'msg': msg, }) queryset = MovieMark.get_available_user_data( user, relation['following']).filter(status=MarkStatusEnum[ status.upper()]).order_by("-edited_time") user.target_site_id = get_cross_site_id( user, request.user.mastodon_site, request.session['oauth_token']) else: queryset = MovieMark.objects.filter( owner=user, status=MarkStatusEnum[status.upper()]).order_by("-edited_time") paginator = Paginator(queryset, ITEMS_PER_PAGE) page_number = request.GET.get('page', default=1) marks = paginator.get_page(page_number) for mark in marks: mark.movie.tag_list = mark.movie.get_tags_manager().values( 'content').annotate(tag_frequency=Count('content')).order_by( '-tag_frequency')[:TAG_NUMBER_ON_LIST] marks.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages) list_title = str( MovieMarkStatusTranslator(MarkStatusEnum[status.upper()])) + str( _("的电影和剧集")) return render(request, 'users/movie_list.html', { 'marks': marks, 'user': user, 'list_title': list_title, }) else: return HttpResponseBadRequest()
def search(request): if request.method == 'GET': empty_querystring_criteria = {k: v for k, v in request.GET.items() if k != 'c'} if not len(empty_querystring_criteria): return HttpResponseBadRequest() # category, book/movie/record etc category = request.GET.get("c", default='').strip().lower() def book_param_handler(): q = Q() query_args = [] # keywords keywords = request.GET.get("q", default='').strip() for keyword in [keywords]: q = q | Q(title__icontains=keyword) q = q | Q(subtitle__icontains=keyword) q = q | Q(orig_title__icontains=keyword) # tag tag = request.GET.get("tag", default='') if tag: q = q & Q(book_tags__content__iexact=tag) query_args.append(q) queryset = Book.objects.filter(*query_args).distinct() def calculate_similarity(book): if keywords: # search by keywords similarity, n = 0, 0 for keyword in keywords: similarity += 1/2 * SequenceMatcher(None, keyword, book.title).quick_ratio() + 1/3 * SequenceMatcher(None, keyword, book.orig_title).quick_ratio() + 1/6 * SequenceMatcher(None, keyword, book.subtitle).quick_ratio() n += 1 book.similarity = similarity / n elif tag: # search by single tag book.similarity = 0 if book.rating_number is None else book.rating_number return book.similarity if len(queryset) > 0: ordered_queryset = sorted(queryset, key=calculate_similarity, reverse=True) else: ordered_queryset = list(queryset) return ordered_queryset def movie_param_handler(): q = Q() query_args = [] # keywords keywords = request.GET.get("q", default='').strip() for keyword in [keywords]: q = q | Q(title__icontains=keyword) q = q | Q(other_title__icontains=keyword) q = q | Q(orig_title__icontains=keyword) # tag tag = request.GET.get("tag", default='') if tag: q = q & Q(movie_tags__content__iexact=tag) query_args.append(q) queryset = Movie.objects.filter(*query_args).distinct() def calculate_similarity(movie): if keywords: # search by name similarity, n = 0, 0 for keyword in keywords: similarity += 1/2 * SequenceMatcher(None, keyword, movie.title).quick_ratio() + 1/4 * SequenceMatcher(None, keyword, movie.orig_title).quick_ratio() + 1/4 * SequenceMatcher(None, keyword, movie.other_title).quick_ratio() n += 1 movie.similarity = similarity / n elif tag: # search by single tag movie.similarity = 0 if movie.rating_number is None else movie.rating_number return movie.similarity if len(queryset) > 0: ordered_queryset = sorted(queryset, key=calculate_similarity, reverse=True) else: ordered_queryset = list(queryset) return ordered_queryset def all_param_handler(): book_queryset = book_param_handler() movie_queryset = movie_param_handler() ordered_queryset = sorted( book_queryset + movie_queryset, key=operator.attrgetter('similarity'), reverse=True ) return ordered_queryset param_handler = { 'book': book_param_handler, 'movie': movie_param_handler, 'all': all_param_handler, '': all_param_handler } try: queryset = param_handler[category]() except KeyError as e: queryset = param_handler['all']() paginator = Paginator(queryset, ITEMS_PER_PAGE) page_number = request.GET.get('page', default=1) items = paginator.get_page(page_number) items.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages) for item in items: item.tag_list = item.get_tags_manager().values('content').annotate( tag_frequency=Count('content')).order_by('-tag_frequency')[:TAG_NUMBER_ON_LIST] return render( request, "common/search_result.html", { "items": items, } ) else: return HttpResponseBadRequest()
def search(request): if request.method == 'GET': # test if input serach string is empty or not excluding param ?c= empty_querystring_criteria = {k: v for k, v in request.GET.items() if k != 'c'} if not len(empty_querystring_criteria): return HttpResponseBadRequest() # test if user input an URL, if so jump to URL handling function url_validator = URLValidator() input_string = request.GET.get('q', default='').strip() try: url_validator(input_string) # validation success return jump_or_scrape(request, input_string) except ValidationError as e: pass # category, book/movie/music etc category = request.GET.get("c", default='').strip().lower() # keywords, seperated by blank space # it is better not to split the keywords keywords = request.GET.get("q", default='').strip() keywords = [keywords] if keywords else '' # tag, when tag is provided there should be no keywords , for now tag = request.GET.get("tag", default='') # white space string, empty query if not (keywords or tag): return render( request, "common/search_result.html", { "items": None, } ) def book_param_handler(**kwargs): # keywords keywords = kwargs.get('keywords') # tag tag = kwargs.get('tag') query_args = [] q = Q() for keyword in keywords: q = q | Q(title__icontains=keyword) q = q | Q(subtitle__icontains=keyword) q = q | Q(orig_title__icontains=keyword) if tag: q = q & Q(book_tags__content__iexact=tag) query_args.append(q) queryset = Book.objects.filter(*query_args).distinct() def calculate_similarity(book): if keywords: # search by keywords similarity, n = 0, 0 for keyword in keywords: similarity += 1/2 * SequenceMatcher(None, keyword, book.title).quick_ratio() + 1/3 * SequenceMatcher(None, keyword, book.orig_title).quick_ratio() + 1/6 * SequenceMatcher(None, keyword, book.subtitle).quick_ratio() n += 1 book.similarity = similarity / n elif tag: # search by single tag book.similarity = 0 if book.rating_number is None else book.rating_number else: book.similarity = 0 return book.similarity if len(queryset) > 0: ordered_queryset = sorted(queryset, key=calculate_similarity, reverse=True) else: ordered_queryset = list(queryset) return ordered_queryset def movie_param_handler(**kwargs): # keywords keywords = kwargs.get('keywords') # tag tag = kwargs.get('tag') query_args = [] q = Q() for keyword in keywords: q = q | Q(title__icontains=keyword) q = q | Q(other_title__icontains=keyword) q = q | Q(orig_title__icontains=keyword) if tag: q = q & Q(movie_tags__content__iexact=tag) query_args.append(q) queryset = Movie.objects.filter(*query_args).distinct() def calculate_similarity(movie): if keywords: # search by name similarity, n = 0, 0 for keyword in keywords: similarity += 1/2 * SequenceMatcher(None, keyword, movie.title).quick_ratio() + 1/4 * SequenceMatcher(None, keyword, movie.orig_title).quick_ratio() + 1/4 * SequenceMatcher(None, keyword, movie.other_title).quick_ratio() n += 1 movie.similarity = similarity / n elif tag: # search by single tag movie.similarity = 0 if movie.rating_number is None else movie.rating_number else: movie.similarity = 0 return movie.similarity if len(queryset) > 0: ordered_queryset = sorted(queryset, key=calculate_similarity, reverse=True) else: ordered_queryset = list(queryset) return ordered_queryset def game_param_handler(**kwargs): # keywords keywords = kwargs.get('keywords') # tag tag = kwargs.get('tag') query_args = [] q = Q() for keyword in keywords: q = q | Q(title__icontains=keyword) q = q | Q(other_title__icontains=keyword) q = q | Q(developer__icontains=keyword) q = q | Q(publisher__icontains=keyword) if tag: q = q & Q(game_tags__content__iexact=tag) query_args.append(q) queryset = Game.objects.filter(*query_args).distinct() def calculate_similarity(game): if keywords: # search by name developer_dump = ' '.join(game.developer) publisher_dump = ' '.join(game.publisher) similarity, n = 0, 0 for keyword in keywords: similarity += 1/2 * SequenceMatcher(None, keyword, game.title).quick_ratio() + 1/4 * SequenceMatcher(None, keyword, game.other_title).quick_ratio() + 1/16 * SequenceMatcher(None, keyword, developer_dump).quick_ratio() + 1/16 * SequenceMatcher(None, keyword, publisher_dump).quick_ratio() n += 1 game.similarity = similarity / n elif tag: # search by single tag game.similarity = 0 if game.rating_number is None else game.rating_number else: game.similarity = 0 return game.similarity if len(queryset) > 0: ordered_queryset = sorted(queryset, key=calculate_similarity, reverse=True) else: ordered_queryset = list(queryset) return ordered_queryset def music_param_handler(**kwargs): # keywords keywords = kwargs.get('keywords') # tag tag = kwargs.get('tag') query_args = [] q = Q() # search albums for keyword in keywords: q = q | Q(title__icontains=keyword) q = q | Q(artist__icontains=keyword) if tag: q = q & Q(album_tags__content__iexact=tag) query_args.append(q) album_queryset = Album.objects.filter(*query_args).distinct() # extra query args for songs q = Q() for keyword in keywords: q = q | Q(album__title__icontains=keyword) q = q | Q(title__icontains=keyword) q = q | Q(artist__icontains=keyword) if tag: q = q & Q(song_tags__content__iexact=tag) query_args.clear() query_args.append(q) song_queryset = Song.objects.filter(*query_args).distinct() queryset = list(album_queryset) + list(song_queryset) def calculate_similarity(music): if keywords: # search by name similarity, n = 0, 0 artist_dump = ' '.join(music.artist) for keyword in keywords: if music.__class__ == Album: similarity += 1/2 * SequenceMatcher(None, keyword, music.title).quick_ratio() \ + 1/2 * SequenceMatcher(None, keyword, artist_dump).quick_ratio() elif music.__class__ == Song: similarity += 1/2 * SequenceMatcher(None, keyword, music.title).quick_ratio() \ + 1/6 * SequenceMatcher(None, keyword, artist_dump).quick_ratio() \ + 1/6 * SequenceMatcher(None, keyword, music.album.title).quick_ratio() n += 1 music.similarity = similarity / n elif tag: # search by single tag music.similarity = 0 if music.rating_number is None else music.rating_number else: music.similarity = 0 return music.similarity if len(queryset) > 0: ordered_queryset = sorted(queryset, key=calculate_similarity, reverse=True) else: ordered_queryset = list(queryset) return ordered_queryset def all_param_handler(**kwargs): book_queryset = book_param_handler(**kwargs) movie_queryset = movie_param_handler(**kwargs) music_queryset = music_param_handler(**kwargs) game_queryset = game_param_handler(**kwargs) ordered_queryset = sorted( book_queryset + movie_queryset + music_queryset + game_queryset, key=operator.attrgetter('similarity'), reverse=True ) return ordered_queryset param_handler = { 'book': book_param_handler, 'movie': movie_param_handler, 'music': music_param_handler, 'game': game_param_handler, 'all': all_param_handler, '': all_param_handler } categories = [k for k in param_handler.keys() if not k in ['all', '']] try: queryset = param_handler[category]( keywords=keywords, tag=tag ) except KeyError as e: queryset = param_handler['all']( keywords=keywords, tag=tag ) paginator = Paginator(queryset, ITEMS_PER_PAGE) page_number = request.GET.get('page', default=1) items = paginator.get_page(page_number) items.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages) for item in items: item.tag_list = item.get_tags_manager().values('content').annotate( tag_frequency=Count('content')).order_by('-tag_frequency')[:TAG_NUMBER_ON_LIST] return render( request, "common/search_result.html", { "items": items, "categories": categories, } ) else: return HttpResponseBadRequest()