def leave_a_message(request): """ 添加留言 """ uid = request.POST.get('uid', '').strip()[:100] content = request.POST.get('content', '').strip()[:500] nickname = request.POST.get('nickname', '').strip()[:20] contact = request.POST.get('contact', '').strip()[:50] user = get_login_user(request) if content: try: msg = Message(uid=uid, content=content, nickname=nickname, contact=contact, user=user) msg.save() logger.warning(f"有新的留言:`{content}") return get_all_issues(request) except: logger.error(f"留言增加失败:`{uid}`{content}`{nickname}`{contact}") return HttpResponseServerError('Internal Error') logger.warning(f"参数错误:`{content}") return HttpResponseNotFound("Param Error")
def index(request): """ index home page :param request: :return: """ # PC 版、手机版适配 user_agent = parse(request.META.get('HTTP_USER_AGENT', '')) pc = user_agent.is_pc # 判断是否登录用户 user = get_login_user(request) # 默认的渲染列表,区分是否登录用户 if user is None: sub_feeds = get_visitor_subscribe_feeds('', '') else: sub_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) pre_load_count = 2 if pc else 10 articles = Article.objects.filter(status='active', site_id__in=sub_feeds).order_by('-id')[:pre_load_count] context = dict() context['articles'] = articles context['user'] = user context['github_oauth_key'] = settings.GITHUB_OAUTH_KEY # 记录访问来源 add_referer_stats(request.META.get('HTTP_REFERER', '')) if pc: return render(request, 'index.html', context) else: return render(request, 'mobile/index.html', context)
def user_star_article(request): """ 登陆用户收藏文章 """ uindex = request.POST.get('id') user = get_login_user(request) if user and uindex: if not is_user_stared(user.oauth_id, uindex): article = Article.objects.get(uindex=uindex, status='active') try: record = UserArticle(user=user, site=article.site, uindex=uindex, title=article.title, author=article.author, src_url=article.src_url) record.save() except django.db.utils.IntegrityError: logger.warning(f"已经收藏过了:`{user.oauth_id}`{uindex}") return JsonResponse({}) # 缓存标记 set_user_stared(user.oauth_id, uindex) # 统计次数 incr_view_star('STAR', uindex) return JsonResponse({}) else: return JsonResponse({}) return HttpResponseNotFound("Param Error")
def submit_a_feed(request): """ 用户添加一个自定义的订阅源 """ feed_url = request.POST.get('url', '').strip()[:1024] user = get_login_user(request) if feed_url: host = get_host_name(feed_url) if 'ershicimi.com' in host: rsp = parse_wemp_ershicimi(feed_url) elif host in settings.ALLOWED_HOSTS: rsp = parse_self_atom(feed_url) else: rsp = parse_atom(feed_url) if rsp: logger.warning(f"有新订阅源被提交:`{feed_url}") # 已登录用户,自动订阅 if user: add_user_sub_feeds(user.oauth_id, [ rsp['name'], ]) return JsonResponse(rsp) else: logger.warning(f"RSS 解析失败:`{feed_url}") return HttpResponseNotFound("Param error")
def get_article_update_view(request): """ 获取更新的文章列表视图;登录用户展示其订阅内容 """ # 请求参数获取 sub_feeds = json.loads(request.POST.get('sub_feeds') or '[]') unsub_feeds = json.loads(request.POST.get('unsub_feeds') or '[]') page_size = int(request.POST.get('page_size', 10)) page = int(request.POST.get('page', 1)) mobile = request.POST.get('mobile', False) onlyunread = request.POST.get('onlyunread', 'no') == 'yes' user = get_login_user(request) # 我的订阅源 if user is None: my_sub_feeds = get_visitor_subscribe_feeds(tuple(sub_feeds), tuple(unsub_feeds)) else: my_sub_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) # 获取文章索引列表 my_articles = set() for site_id in my_sub_feeds: my_articles.update(get_recent_site_articles(site_id)) # 过滤 if user and onlyunread: my_articles = get_user_unread_articles(user.oauth_id, my_articles) my_articles = sorted(my_articles, reverse=True) if my_articles: # 分页处理 try: paginator_obj = Paginator(my_articles, page_size) except: logger.warning( f"分页参数错误:`{page}`{page_size}`{sub_feeds}`{unsub_feeds}") return HttpResponseForbidden("Page Number Error") pg = paginator_obj.page(page) num_pages = paginator_obj.num_pages articles = Article.objects.filter( uindex__in=pg.object_list).order_by('-id')[:50] context = dict() context['articles'] = articles context['num_pages'] = num_pages context['user'] = user context['pg'] = pg if mobile: return render(request, 'mobile/list.html', context=context) else: return render(request, 'left/list_view.html', context=context) return HttpResponseForbidden("No Feeds Subscribed")
def get_article_detail(request): """ 获取文章详情;已登录用户记录已读 TODO 服务器记录阅读数 """ uindex = request.POST.get('id') user = get_login_user(request) mobile = request.POST.get('mobile', False) try: article = Article.objects.get(uindex=uindex, status='active') except: logger.info(f"获取文章详情请求处理异常:`{uindex}") return HttpResponseNotFound("Param Error") if user: set_user_read_article(user.oauth_id, uindex) context = dict() context['article'] = article context['user'] = user if mobile: return render(request, 'mobile/article.html', context=context) else: return render(request, 'article/index.html', context=context)
def article(request, pid): """ 详情页,主要向移动端、搜索引擎提供,这个页面需要做风控 """ # 外链统计 add_referer_stats(request.META.get('HTTP_REFERER', '')) try: article = Article.objects.get(uindex=pid, status='active') except: return HttpResponseRedirect('https://dinorss.org/') user = get_login_user(request) if user: set_user_read_article(user.oauth_id, pid) # 判断是否命中敏感词 # if is_sensitive_content(pid, article.site_id): # user_agent = parse(request.META.get('HTTP_USER_AGENT', '')) # # if user_agent.is_mobile or user_agent.is_bot: # logger.warning(f'文章命中了敏感词,转到原文:`{article.title}`{pid}') # return redirect(article.src_url) # else: # logger.warning(f'文章命中了敏感词,禁止访问:`{article.title}`{pid}') # return redirect('index') context = dict() context['article'] = article context['user'] = user return render(request, 'mobile/article.html', context=context)
def get_lastweek_articles(request): """ 游客用户返回过去一周的文章 id 列表;登录用户返回过去一周的未读文章 id 列表 """ uid = request.POST.get('uid', '') user = get_login_user(request) sub_feeds = request.POST.get('sub_feeds', '').split(',') unsub_feeds = request.POST.get('unsub_feeds', '').split(',') ext = request.POST.get('ext', '') logger.info(f"过去一周文章查询:`{uid}`{unsub_feeds}`{ext}") if user is None: my_sub_feeds = get_subscribe_sites(tuple(sub_feeds), tuple(unsub_feeds)) else: my_sub_feeds = get_user_sub_feeds(user.oauth_id) my_lastweek_articles = list( Article.objects.all().prefetch_related('site').filter( status='active', site__name__in=my_sub_feeds, is_recent=True).values_list('uindex', flat=True)) if user: my_lastweek_articles = get_user_unread_articles( user.oauth_id, my_lastweek_articles) return JsonResponse({"result": my_lastweek_articles})
def get_recommend_sites(request): """ 获取文章推荐的订阅源,只开放登录用户;考虑性能,这里进行随机生成 :param request: :return: """ user = get_login_user(request) if user: user_sub_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) sites = Site.objects.filter( status='active', star__gte=10).exclude(pk__in=user_sub_feeds) try: sites = random.sample(list(sites), 3) except: logger.warning(f"生成随机订阅失败:`{sites}") return JsonResponse({}) context = dict() context['sites'] = sites context['user'] = user return render(request, 'recommend/random_sites.html', context=context) return HttpResponseForbidden("No Recommend Data")
def get_lastweek_articles(request): """ 游客用户返回过去一周的文章 id 列表;登录用户返回过去一周的未读数 """ uid = request.POST.get('uid', '') user = get_login_user(request) sub_feeds = json.loads(request.POST.get('sub_feeds') or '[]') unsub_feeds = json.loads(request.POST.get('unsub_feeds') or '[]') ext = request.POST.get('ext', '') reach_sub_limit = False logger.info(f"查询未读数:`{uid}`{ext}") if user is None: my_sub_feeds = get_visitor_subscribe_feeds(tuple(sub_feeds), tuple(unsub_feeds)) reach_sub_limit = len(my_sub_feeds) == settings.VISITOR_SUBS_LIMIT else: my_sub_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) if user.level < 10: reach_sub_limit = len(my_sub_feeds) == settings.USER_SUBS_LIMIT # 异步更新任务 django_rq.enqueue(update_sites_async, list(my_sub_feeds)) # 获取文章索引列表 my_toread_articles = set() for site_id in my_sub_feeds: my_toread_articles.update(get_recent_site_articles(site_id)) my_toread_articles = list(my_toread_articles) if user: my_unread_count = get_user_unread_count(user.oauth_id, my_toread_articles) # 标记用户登陆 set_user_visit_day(user.oauth_id) response = JsonResponse({"result": my_unread_count}) if reach_sub_limit: response.set_signed_cookie('toast', 'SUBS_LIMIT_ERROR_MSG', max_age=20) return response else: response = JsonResponse({"result": my_toread_articles}) if reach_sub_limit: response.set_signed_cookie('toast', 'SUBS_LIMIT_ERROR_MSG', max_age=20) return response
def submit_a_feed(request): """ 用户添加一个自定义的订阅源 """ feed_url = request.POST.get('url', '').strip()[:1024] user = get_login_user(request) if feed_url: host = get_host_name(feed_url) if settings.ERSHICIMI_HOST in host: feed_url = feed_url.replace('/user/analysis?bid=', '/a/') rsp = add_ershicimi_feed(feed_url) elif host in settings.ALLOWED_HOSTS: rsp = add_self_feed(feed_url) elif settings.QNMLGB_HOST in host: rsp = add_qnmlgb_feed(feed_url) elif settings.WEMP_HOST in host: rsp = add_wemp_feed(feed_url) elif settings.CHUANSONGME_HOST in host: rsp = add_chuansongme_feed(feed_url) elif settings.ANYV_HOST in host: rsp = add_anyv_feed(feed_url) else: # 区分播客还是普通 RSS feed_obj = feedparser.parse(feed_url) if is_podcast_feed(feed_obj): rsp = add_postcast_feed(feed_obj) else: rsp = add_atom_feed(feed_obj) if rsp: logger.warning(f"有新订阅源被提交:`{feed_url}") set_active_site(rsp['site']) # 已登录用户,自动订阅 if user: add_user_sub_feeds(user.oauth_id, [ rsp['site'], ]) if rsp.get('creator') == 'user': # 新增的普通 RSS 才触发异步更新任务 django_rq.enqueue(update_sites_async, [ rsp['site'], ], result_ttl=1, ttl=3600, failure_ttl=3600) return JsonResponse(rsp) else: logger.warning(f"RSS 解析失败:`{feed_url}") return HttpResponseNotFound("Param Error")
def get_all_issues(request): user = get_login_user(request) msgs = Message.objects.filter(status='active').order_by('-id')[:20] context = dict() context['msgs'] = msgs context['user'] = user return render(request, 'issues.html', context=context)
def user_unsubscribe_feed(request): """ 已登录用户取消订阅源 """ feed = request.POST.get('feed', '').strip()[:32] user = get_login_user(request) if user and feed: del_user_sub_feed(user.oauth_id, feed) return JsonResponse({"name": feed}) return HttpResponseNotFound("Param error")
def get_faq(request): """ 获取FAQ """ mobile = request.POST.get('mobile', False) user = get_login_user(request) context = dict() context['mobile'] = mobile context['user'] = user return render(request, 'faq.html', context=context)
def user_mark_read_all(request): """ 设置全部已读 """ ids = request.POST.get('ids', '').split(',') user = get_login_user(request) if user: for uindex in ids: set_user_read_article(user.oauth_id, uindex) return JsonResponse({}) return HttpResponseNotFound("Param error")
def user_unsubscribe_feed(request): """ 已登录用户取消订阅源 """ site_id = request.POST.get('site_id', '').strip()[:32] user = get_login_user(request) if user and site_id: del_user_sub_feed(user.oauth_id, site_id) logger.warning(f"登陆用户取消订阅动作:`{user.oauth_name}`{site_id}") return JsonResponse({"site": site_id}) return HttpResponseForbidden("Param Error")
def user_subscribe_feed(request): """ 已登录用户订阅源 """ feed = request.POST.get('feed', '').strip()[:32] user = get_login_user(request) if user and feed: try: Site.objects.get(name=feed) add_user_sub_feeds(user.oauth_id, [feed, ]) return JsonResponse({"name": feed}) except: logger.warning(f'用户订阅出现异常:`{feed}`{user.oauth_id}') return HttpResponseNotFound("Param error")
def get_site_article_update_view(request): """ 获取某个站点的更新文章列表视图 """ # 请求参数获取 site_id = request.POST.get('site_id', 0) page_size = int(request.POST.get('page_size', 10)) page = int(request.POST.get('page', 1)) user = get_login_user(request) site = Site.objects.get(pk=site_id, status='active') recent_articles = list(get_recent_site_articles(site.pk)) # 查看文章数限制 site_articles_limit = 9999 if user: if user.level < 10: site_articles_limit = settings.USER_SITE_ARTICLES_LIMIT else: site_articles_limit = settings.VISITOR_SITE_ARTICLES_LIMIT site_articles = Article.objects.filter( site=site, status='active').order_by('-id')[:site_articles_limit] if site_articles: # 分页处理 paginator_obj = Paginator(site_articles, page_size) try: # 页面及数据 pg = paginator_obj.page(page) num_pages = paginator_obj.num_pages context = dict() context['pg'] = pg context['num_pages'] = num_pages context['site'] = site context['user'] = user context['articles'] = json.dumps(recent_articles) return render(request, 'left/list2_view.html', context=context) except: logger.warning(f"分页参数错误:`{page}`{page_size}`{site_id}") return HttpResponseForbidden("Page Number Error") return HttpResponseForbidden("No Sites Data")
def get_recent_sites(request): """ 获取最近提交源 """ user = get_login_user(request) user_sub_feeds = [] if user: user_sub_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) sites = Site.objects.filter(status='active').order_by('-id')[:50] context = dict() context['user'] = user context['sites'] = sites context['user_sub_feeds'] = user_sub_feeds return render(request, 'explore/recent_sites.html', context=context)
def user_custom_site(request): """ 用户自定义源名称 """ site_id = request.POST.get('site_id', '').strip()[:32] site_name = request.POST.get('site_name', '').strip()[:20] site_author = request.POST.get('site_author', '').strip()[:20] user = get_login_user(request) if user and site_id: logger.warning(f"用户自定义订阅源:`{site_id}`{site_name}`{site_author}") set_user_site_cname(user.oauth_id, site_id, site_name) set_user_site_author(user.oauth_id, site_id, site_author) return JsonResponse({}) return HttpResponseForbidden("Param Error")
def get_feed_ranking(request): """ 获取订阅源排行榜 """ user = get_login_user(request) user_sub_feeds = [] if user: user_sub_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) feed_ranking = get_feed_ranking_dict() context = dict() context['user'] = user context['feed_ranking'] = feed_ranking context['user_sub_feeds'] = user_sub_feeds return render(request, 'ranking/feed_ranking.html', context=context)
def get_recent_articles(request): """ 获取最近更新内容 TODO 优化查询性能 """ user = get_login_user(request) ids = get_sites_lastids() articles = Article.objects.filter(uindex__in=ids) user_sub_feeds = [] if user: user_sub_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) context = dict() context['articles'] = articles context['user'] = user context['user_sub_feeds'] = user_sub_feeds return render(request, 'explore/recent_articles.html', context=context)
def get_my_feeds(request): """ 获取我的订阅列表;游客已订阅、推荐订阅;登陆用户已订阅、推荐订阅 """ sub_feeds = json.loads(request.POST.get('sub_feeds') or '[]') unsub_feeds = json.loads(request.POST.get('unsub_feeds') or '[]') user, reach_sub_limit = get_login_user(request), [False, 0] if user is None: visitor_sub_feeds = get_visitor_subscribe_feeds( tuple(sub_feeds), tuple(unsub_feeds)) sub_sites = Site.objects.filter( status='active', pk__in=visitor_sub_feeds).order_by('-star') recom_sites = Site.objects.filter(status='active', star__gte=20).exclude(pk__in=visitor_sub_feeds).\ order_by('-star') if len(visitor_sub_feeds) == settings.VISITOR_SUBS_LIMIT: reach_sub_limit = [True, settings.VISITOR_SUBS_LIMIT] else: user_sub_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) sub_sites = Site.objects.filter( status='active', pk__in=user_sub_feeds).order_by('-star') recom_sites = Site.objects.filter(status='active', star__gte=20).exclude(pk__in=user_sub_feeds)\ .order_by('-star') if user.level < 10: if len(user_sub_feeds) == settings.USER_SUBS_LIMIT: reach_sub_limit = [True, settings.USER_SUBS_LIMIT] context = dict() context['sub_sites'] = sub_sites context['recom_sites'] = recom_sites context['user'] = user context['reach_sub_limit'] = reach_sub_limit return render(request, 'myfeeds.html', context=context)
def get_recommend_articles(request): """ 获取文章推荐的订阅源,只开放登录用户 TODO 优化性能 :param request: :return: """ uindex = int(request.POST['id']) user = get_login_user(request) if uindex and user: recommend_articles = [] relative_articles = list(get_similar_article(uindex).keys()) user_sub_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) for relative_uindex in relative_articles: try: article = Article.objects.get(uindex=relative_uindex, status='active') except: continue if article.site_id not in user_sub_feeds: recommend_articles.append(article) if len(recommend_articles) >= 3: break if recommend_articles: logger.info(f'推荐数据条数:`{len(recommend_articles)}`{user.oauth_name}') context = dict() context['recommend_articles'] = recommend_articles return render(request, 'recommend/relative_article.html', context=context) else: return JsonResponse({}) return HttpResponseForbidden("No Recommend Data")
def user_subscribe_feed(request): """ 已登录用户订阅源 """ site_id = request.POST.get('site_id', '').strip()[:32] user = get_login_user(request) site = Site.objects.get(pk=site_id, status='active') if user and site: # 先判断是否达到限制 if user.level < 10: if len(get_user_subscribe_feeds(user.oauth_id, from_user=False, user_level=user.level)) \ == settings.USER_SUBS_LIMIT: logger.warning(f"已达到订阅上限:`{user.oauth_name}") return JsonResponse({ "code": 1, "msg": f"已达到 {settings.USER_SUBS_LIMIT} 个订阅数,请先取消一部分!" }) add_user_sub_feeds(user.oauth_id, [ site_id, ]) # 异步更新 django_rq.enqueue(update_sites_async, [ site.pk, ], result_ttl=1, ttl=3600, failure_ttl=3600) logger.warning(f"登陆用户订阅动作:`{user.oauth_name}`{site_id}") return JsonResponse({"code": 0, "msg": '订阅成功 ^o^'}) return HttpResponseForbidden("Param Error")
def submit_a_feed(request): """ 用户添加一个自定义的订阅源 """ feed_url = request.POST.get('url', '').strip()[:1024] user = get_login_user(request) if feed_url: host = get_host_name(feed_url) if 'ershicimi.com' in host: feed_url = feed_url.replace('/user/analysis?bid=', '/a/') rsp = parse_wemp_ershicimi(feed_url) elif host in settings.ALLOWED_HOSTS: rsp = parse_self_atom(feed_url) elif 'qnmlgb.tech' in host: rsp = parse_qnmlgb_atom(feed_url) else: rsp = parse_atom(feed_url) if rsp: logger.warning(f"有新订阅源被提交:`{feed_url}") # 已登录用户,自动订阅 if user: add_user_sub_feeds(user.oauth_id, [ rsp['site'], ]) # 异步更新任务 django_rq.enqueue(update_sites_async, [ rsp['site'], ]) return JsonResponse(rsp) else: logger.warning(f"RSS 解析失败:`{feed_url}") return HttpResponseNotFound("Param Error")
def user_mark_read_all(request): """ 设置批量已读,如不传 ids 则设置全部已读 """ ids = json.loads(request.POST.get('ids') or '[]') user = get_login_user(request) if user: if not ids: my_sub_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) ids = set() for site_id in my_sub_feeds: ids.update(get_recent_site_articles(site_id)) set_user_read_articles(user.oauth_id, ids) if ids: return get_lastweek_articles(request) else: return JsonResponse({}) return HttpResponseNotFound("Param Error")
def get_site_update_view(request): """ 获取更新的全局站点视图,游客 100 个,登陆用户 200 个站点 """ sub_feeds = json.loads(request.POST.get('sub_feeds') or '[]') unsub_feeds = json.loads(request.POST.get('unsub_feeds') or '[]') page_size = int(request.POST.get('page_size', 10)) page = int(request.POST.get('page', 1)) onlyunread = request.POST.get('onlyunread', 'no') == 'yes' user = get_login_user(request) if user is None: my_feeds = get_visitor_subscribe_feeds(tuple(sub_feeds), tuple(unsub_feeds)) else: my_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) # 过滤有内容更新的 if user and onlyunread: my_feeds = get_user_unread_sites(user.oauth_id, my_feeds) my_feeds = sorted(my_feeds, key=lambda t: get_site_last_id(t), reverse=True) if my_feeds: # 分页处理 try: paginator_obj = Paginator(my_feeds, page_size) except: logger.warning( f"分页参数错误:`{page}`{page_size}`{sub_feeds}`{unsub_feeds}") return HttpResponseNotFound("Page Number Error") pg = paginator_obj.page(page) num_pages = paginator_obj.num_pages sites = Site.objects.filter(pk__in=pg.object_list, status='active').order_by('-star')[:50] for site in sites: recent_articles = get_recent_site_articles(site.pk) site.update_count = len(recent_articles) site.update_ids = json.dumps(list(recent_articles)) site.update_time = get_site_last_id(site.pk) if user: site.unread_count = get_user_unread_count( user.oauth_id, recent_articles) context = dict() context['pg'] = pg context['sites'] = sites context['num_pages'] = num_pages context['user'] = user return render(request, 'left/site_view.html', context=context) return HttpResponseNotFound("No Feeds Subscribed")
def in_site_search(request): """ 站内搜索 """ user = get_login_user(request) keyword = request.POST.get('keyword', '').strip() scope = request.POST.get('scope', 'all') logger.warning(f"搜索关键字:`{keyword}") keyword = split_cn_words(keyword, join=True) logger.info(f"转换后的关键字:`{keyword}") if scope not in ('all', 'feed', 'article'): return HttpResponseForbidden('Param Error') if not keyword: return HttpResponseNotFound("Empty Keyword") storage = FileStorage(settings.WHOOSH_IDX_DIR) rel_sites, rel_articles = None, None # 查找相关源 if scope in ('feed', 'all'): idx = storage.open_index(indexname="site", schema=whoosh_site_schema) qp = MultifieldParser(['cname', 'author', 'brief'], schema=whoosh_site_schema) query = qp.parse(keyword) sites = [] with idx.searcher() as s: results = s.search(query, limit=50) for ret in results: sites.append(ret['id']) rel_sites = Site.objects.filter(status='active', pk__in=sites).order_by('-star') elif scope == 'article': # 查找相关文章 idx = storage.open_index(indexname="article", schema=whoosh_article_schema) qp = MultifieldParser(['title', 'author', 'content'], schema=whoosh_article_schema) query = qp.parse(keyword) articles = [] with idx.searcher() as s: old_mask = TermRange("uindex", None, str(current_ts() - 7 * 86400 * 1000)) results = s.search(query, mask=old_mask, limit=50) for ret in results: articles.append(ret['uindex']) rel_articles = Article.objects.filter(is_recent=True, status='active', uindex__in=articles).iterator() # 用户订阅 user_sub_feeds = [] if user: user_sub_feeds = get_user_subscribe_feeds(user.oauth_id, user_level=user.level) context = dict() context['user'] = user context['user_sub_feeds'] = user_sub_feeds context['rel_sites'] = rel_sites context['rel_articles'] = rel_articles context['keyword'] = keyword if scope == 'all': return render(request, 'search/search.html', context=context) elif scope == 'feed': return render(request, 'search/search_feeds.html', context=context) elif scope == 'article': return render(request, 'search/search_articles.html', context=context)