def document_listing(request, template, product_slug, topic_slug): """The document listing page for a product + topic.""" product = get_object_or_404(Product, slug=product_slug) topic = get_object_or_404(Topic, slug=topic_slug) refine_slug = request.GET.get('refine') if refine_slug: refine = get_object_or_404(Topic, slug=refine_slug) topics = [topic, refine] else: refine = None topics = [topic] documents, fallback_documents = documents_for(locale=request.LANGUAGE_CODE, products=[product], topics=topics) return render( request, template, { 'product': product, 'topic': topic, 'topics': topics_for(products=[product]), 'refine': refine, 'refine_topics': topics_for(products=[product], topics=[topic]), 'documents': documents, 'fallback_documents': fallback_documents, 'search_params': { 'product': product_slug } })
def document_listing(request, template, product_slug, topic_slug): """The document listing page for a product + topic.""" product = get_object_or_404(Product, slug=product_slug) topic = get_object_or_404(Topic, slug=topic_slug) refine_slug = request.GET.get("refine") if refine_slug: refine = get_object_or_404(Topic, slug=refine_slug) topics = [topic, refine] else: refine = None topics = [topic] documents, fallback_documents = documents_for(locale=request.LANGUAGE_CODE, products=[product], topics=topics) return jingo.render( request, template, { "product": product, "topic": topic, "topics": topics_for(products=[product]), "refine": refine, "refine_topics": topics_for(products=[product], topics=[topic]), "documents": documents, "fallback_documents": fallback_documents, "search_params": {"product": product_slug}, }, )
def test_documents_for_topics(self): general_documents = documents_for( locale='en-US', topics=[self.general]) eq_(len(general_documents), 1) bookmarks_documents = documents_for( locale='en-US', topics=[self.bookmarks]) eq_(len(bookmarks_documents), 2) sync_documents = documents_for(locale='en-US', topics=[self.sync]) eq_(len(sync_documents), 1) general_bookmarks_documents = documents_for( locale='en-US', topics=[self.general, self.bookmarks]) eq_(len(general_bookmarks_documents), 1) general_sync_documents = documents_for( locale='en-US', topics=[self.general, self.sync]) eq_(len(general_sync_documents), 0)
def document_listing(request, product_slug, topic_slug): """The document listing page for a product + topic.""" if not show_ia(request): return HttpResponseRedirect(reverse('products')) product = get_object_or_404(Product, slug=product_slug) topic = get_object_or_404(Topic, slug=topic_slug) documents = documents_for( locale=request.locale, products=[product], topics=[topic]) return jingo.render(request, 'products/documents.html', { 'product': product, 'topic': topic, 'documents': documents})
def document_listing(request, product_slug, topic_slug): """The document listing page for a product + topic.""" product = get_object_or_404(Product, slug=product_slug) topic = get_object_or_404(Topic, slug=topic_slug) documents, fallback_documents = documents_for( locale=request.locale, products=[product], topics=[topic]) return jingo.render(request, 'products/documents.html', { 'product': product, 'topic': topic, 'topics': topics_for(products=[product]), 'documents': documents, 'fallback_documents': fallback_documents})
def _fallback_results(locale, product_slugs): """Return the top 20 articles by votes for the given product(s).""" products = [] for slug in product_slugs: try: p = Product.objects.get(slug=slug) products.append(p) except Product.DoesNotExist: pass docs, fallback = documents_for(locale, products=products) docs = docs + (fallback or []) return docs[:20]
def document_listing(request, product_slug, topic_slug): """The document listing page for a product + topic.""" if not show_new_sumo(request): return HttpResponseRedirect(reverse('products')) product = get_object_or_404(Product, slug=product_slug) topic = get_object_or_404(Topic, slug=topic_slug) documents = documents_for( locale=request.locale, products=[product], topics=[topic]) return jingo.render(request, 'products/documents.html', { 'product': product, 'topic': topic, 'topics': topics_for(products=[product]), 'documents': documents})
def product_landing(request, slug): """The product landing page.""" if not show_new_sumo(request): return HttpResponseRedirect(reverse('products')) product = get_object_or_404(Product, slug=slug) hot_docs = documents_for( locale=request.locale, topics=[Topic.objects.get(slug=HOT_TOPIC_SLUG)], products=[product]) return jingo.render(request, 'products/product.html', { 'product': product, 'products': Product.objects.filter(visible=True), 'topics': topics_for(products=[product]), 'hot_docs': hot_docs})
def topic_landing(request, slug): """The topic landing page. If `selectproduct=1` query param is passed, shows the product picker. Else, shows the list of articles. """ topic = get_object_or_404(Topic, slug=slug) topics = Topic.objects.filter(visible=True) data = dict(topic=topic, topics=topics) if request.GET.get("selectproduct") == "1": data.update(products=products_for(topics=[topic])) else: docs, fallback = documents = documents_for(locale=request.locale, topics=[topic]) data.update(documents=docs, fallback_documents=fallback) return jingo.render(request, "topics/topic.html", data)
def document_listing(request, template, product_slug, topic_slug): """The document listing page for a product + topic.""" product = get_object_or_404(Product, slug=product_slug) topic = get_object_or_404(Topic, slug=topic_slug) documents, fallback_documents = documents_for( locale=request.LANGUAGE_CODE, products=[product], topics=[topic]) subtopics = Topic.objects.filter(parent=topic) return render(request, template, { 'product': product, 'topic': topic, 'topics': topics_for(products=[product]), 'subtopics': subtopics, 'documents': documents, 'fallback_documents': fallback_documents, 'search_params': {'product': product_slug}})
def topic_landing(request, slug): """The topic landing page. If `selectproduct=1` query param is passed, shows the product picker. Else, shows the list of articles. """ topic = get_object_or_404(Topic, slug=slug) topics = Topic.objects.filter(visible=True) data = dict(topic=topic, topics=topics) if request.GET.get('selectproduct') == '1': data.update(products=products_for(topics=[topic])) else: docs, fallback = documents_for( locale=request.LANGUAGE_CODE, topics=[topic]) data.update(documents=docs, fallback_documents=fallback) return render(request, 'topics/topic.html', data)
def product_landing(request, template, slug): """The product landing page.""" product = get_object_or_404(Product, slug=slug) try: hot_docs, fallback_hot_docs = documents_for( locale=request.locale, topics=[Topic.objects.get(slug=HOT_TOPIC_SLUG)], products=[product]) except Topic.DoesNotExist: # "hot" topic doesn't exist, move on. hot_docs = fallback_hot_docs = None return jingo.render(request, template, { 'product': product, 'products': Product.objects.filter(visible=True), 'topics': topics_for(products=[product]), 'hot_docs': hot_docs, 'fallback_hot_docs': fallback_hot_docs})
def topic_landing(request, slug): """The topic landing page. If `selectproduct=1` query param is passed, shows the product picker. Else, shows the list of articles. """ if not show_new_sumo(request): # User should only be able to get here in new IA. # Redirect to home page return HttpResponseRedirect(reverse("home")) topic = get_object_or_404(Topic, slug=slug) data = dict(topic=topic) if request.GET.get("selectproduct") == "1": data.update(products=products_for(topics=[topic])) else: data.update(documents=documents_for(locale=request.locale, topics=[topic])) return jingo.render(request, "topics/topic.html", data)
def topic_landing(request, slug): """The topic landing page. If `selectproduct=1` query param is passed, shows the product picker. Else, shows the list of articles. """ if not show_new_sumo(request): # User should only be able to get here in new IA. # Redirect to home page return HttpResponseRedirect(reverse('home')) topic = get_object_or_404(Topic, slug=slug) data = dict(topic=topic) if request.GET.get('selectproduct') == '1': data.update(products=products_for(topics=[topic])) else: data.update(documents=documents_for( locale=request.locale, topics=[topic])) return jingo.render(request, 'topics/topic.html', data)
def document_listing(request, template, product_slug, topic_slug): """The document listing page for a product + topic.""" product = get_object_or_404(Product, slug=product_slug) topic = get_object_or_404(Topic, slug=topic_slug) documents, fallback_documents = documents_for(locale=request.LANGUAGE_CODE, products=[product], topics=[topic]) subtopics = Topic.objects.filter(parent=topic) return render( request, template, { 'product': product, 'topic': topic, 'topics': topics_for(products=[product]), 'subtopics': subtopics, 'documents': documents, 'fallback_documents': fallback_documents, 'search_params': { 'product': product_slug } })
def document_listing(request, product_slug, topic_slug): """The document listing page for a product + topic.""" product = get_object_or_404(Product, slug=product_slug) topic = get_object_or_404(Topic, slug=topic_slug) refine_slug = request.GET.get('refine') if refine_slug: refine = get_object_or_404(Topic, slug=refine_slug) topics = [topic, refine] else: refine = None topics = [topic] documents, fallback_documents = documents_for( locale=request.locale, products=[product], topics=topics) return jingo.render(request, 'products/documents.html', { 'product': product, 'topic': topic, 'topics': topics_for(products=[product]), 'refine': refine, 'refine_topics': topics_for(products=[product], topics=[topic]), 'documents': documents, 'fallback_documents': fallback_documents})
def home(request): """The home page.""" if not show_new_sumo(request): return old_home(request) products = Product.objects.filter(visible=True) topics = Topic.objects.filter(visible=True) moz_news = get_object_fallback( Document, MOZILLA_NEWS_DOC, request.locale) try: hot_docs = documents_for( locale=request.locale, topics=[Topic.objects.get(slug=HOT_TOPIC_SLUG)]) except Topic.DoesNotExist: # "hot" topic doesn't exist, move on. hot_docs = None return jingo.render(request, 'landings/home.html', { 'products': products, 'topics': topics, 'hot_docs': hot_docs, 'moz_news': moz_news})
def document_listing(request, template, product_slug, topic_slug): """The document listing page for a product + topic.""" product = get_object_or_404(Product, slug=product_slug) topic = get_object_or_404(Topic, slug=topic_slug) refine_slug = request.GET.get('refine') if refine_slug: refine = get_object_or_404(Topic, slug=refine_slug) topics = [topic, refine] else: refine = None topics = [topic] documents, fallback_documents = documents_for( locale=request.LANGUAGE_CODE, products=[product], topics=topics) return render(request, template, { 'product': product, 'topic': topic, 'topics': topics_for(products=[product]), 'refine': refine, 'refine_topics': topics_for(products=[product], topics=[topic]), 'documents': documents, 'fallback_documents': fallback_documents, 'search_params': {'product': product_slug}})
def product_landing(request, template, slug): """The product landing page.""" product = get_object_or_404(Product, slug=slug) try: hot_docs, fallback_hot_docs = documents_for( locale=request.LANGUAGE_CODE, topics=[Topic.objects.get(slug=HOT_TOPIC_SLUG)], products=[product]) except Topic.DoesNotExist: # "hot" topic doesn't exist, move on. hot_docs = fallback_hot_docs = None return render( request, template, { 'product': product, 'products': Product.objects.filter(visible=True), 'topics': topics_for(products=[product]), 'hot_docs': hot_docs, 'fallback_hot_docs': fallback_hot_docs, 'search_params': { 'product': slug } })
def product_landing(request, template, slug): """The product landing page.""" product = get_object_or_404(Product, slug=slug) try: hot_docs, fallback_hot_docs = documents_for( locale=request.LANGUAGE_CODE, topics=[Topic.objects.get(slug=HOT_TOPIC_SLUG)], products=[product] ) except Topic.DoesNotExist: # "hot" topic doesn't exist, move on. hot_docs = fallback_hot_docs = None return jingo.render( request, template, { "product": product, "products": Product.objects.filter(visible=True), "topics": topics_for(products=[product]), "hot_docs": hot_docs, "fallback_hot_docs": fallback_hot_docs, "search_params": {"product": slug}, }, )
def home(request): """The home page.""" if request.MOBILE: return redirect_to(request, 'products', permanent=False) products = Product.objects.filter(visible=True) topics = Topic.objects.filter(visible=True) moz_news = get_object_fallback( Document, MOZILLA_NEWS_DOC, request.LANGUAGE_CODE) try: hot_docs, fallback_hot_docs = documents_for( locale=request.LANGUAGE_CODE, topics=[Topic.objects.get(slug=HOT_TOPIC_SLUG)]) except Topic.DoesNotExist: # "hot" topic doesn't exist, move on. hot_docs = fallback_hot_docs = None return jingo.render(request, 'landings/home.html', { 'products': products, 'topics': topics, 'hot_docs': hot_docs, 'fallback_hot_docs': fallback_hot_docs, 'moz_news': moz_news})
def home(request): """The home page.""" if not show_new_sumo(request): return old_home(request) products = Product.objects.filter(visible=True) topics = Topic.objects.filter(visible=True) moz_news = get_object_fallback(Document, MOZILLA_NEWS_DOC, request.locale) try: hot_docs = documents_for( locale=request.locale, topics=[Topic.objects.get(slug=HOT_TOPIC_SLUG)]) except Topic.DoesNotExist: # "hot" topic doesn't exist, move on. hot_docs = None return jingo.render( request, 'landings/home.html', { 'products': products, 'topics': topics, 'hot_docs': hot_docs, 'moz_news': moz_news })
def aaq(request, product_key=None, category_key=None, showform=False, template=None, step=0): """Ask a new question.""" if product_key is None: product_key = request.GET.get('product') if request.MOBILE and product_key is None: product_key = 'desktop' product = products.get(product_key) if product_key and not product: raise Http404 if category_key is None: category_key = request.GET.get('category') if product and category_key: category = product['categories'].get(category_key) if not category: # If we get an invalid category, redirect to previous step. return HttpResponseRedirect( reverse('questions.aaq_step2', args=[product_key])) deadend = category.get('deadend', False) topic = category.get('topic') if topic: html = None articles, fallback = documents_for( locale=settings.WIKI_DEFAULT_LANGUAGE, # en-US only for now. products=Product.objects.filter( slug__in=product.get('products')), topics=[Topic.objects.get(slug=topic)]) else: html = category.get('html') articles = category.get('articles') else: category = None deadend = product.get('deadend', False) if product else False html = product.get('html') if product else None articles = None if product: # User is on the select category step statsd.incr('questions.aaq.select-category') else: # User is on the select product step statsd.incr('questions.aaq.select-product') login_t = ('questions/mobile/new_question_login.html' if request.MOBILE else 'questions/new_question_login.html') if request.method == 'GET': search = request.GET.get('search', '') if search: results = _search_suggestions( request, search, locale_or_default(request.locale), product.get('tags'), product.get('products')) tried_search = True else: results = [] tried_search = False if category: # User is on the "Ask This" step statsd.incr('questions.aaq.search-form') if showform or request.GET.get('showform'): # Before we show the form, make sure the user is auth'd: if not request.user.is_authenticated(): # User is on the login or register Step statsd.incr('questions.aaq.login-or-register') login_form = AuthenticationForm() register_form = RegisterForm() return jingo.render(request, login_t, {'product': product, 'category': category, 'title': search, 'register_form': register_form, 'login_form': login_form}) form = NewQuestionForm(product=product, category=category, initial={'title': search}) # User is on the question details step statsd.incr('questions.aaq.details-form') else: form = None if search: # User is on the article and questions suggestions step statsd.incr('questions.aaq.suggestions') return jingo.render(request, template, {'form': form, 'results': results, 'tried_search': tried_search, 'products': products, 'current_product': product, 'current_category': category, 'current_html': html, 'current_articles': articles, 'current_step': step, 'deadend': deadend, 'host': Site.objects.get_current().domain}) # Handle the form post. if not request.user.is_authenticated(): if request.POST.get('login'): login_form = handle_login(request, only_active=False) statsd.incr('questions.user.login') register_form = RegisterForm() elif request.POST.get('register'): login_form = AuthenticationForm() email_template = 'questions/email/confirm_question.ltxt' email_subject = _('Please confirm your Firefox Help question') email_data = request.GET.get('search') register_form = handle_register(request, email_template, email_subject, email_data) if register_form.is_valid(): # Now try to log in. user = auth.authenticate(username=request.POST.get('username'), password=request.POST.get('password')) auth.login(request, user) statsd.incr('questions.user.register') else: # L10n: This shouldn't happen unless people tamper with POST data. message = _lazy('Request type not recognized.') return jingo.render(request, 'handlers/400.html', {'message': message}, status=400) if request.user.is_authenticated(): # Redirect to GET the current URL replacing the step parameter. # This is also required for the csrf middleware to set the auth'd # tokens appropriately. url = urlparams(request.get_full_path(), step='aaq-question') return HttpResponseRedirect(url) else: return jingo.render(request, login_t, {'product': product, 'category': category, 'title': request.POST.get('title'), 'register_form': register_form, 'login_form': login_form}) form = NewQuestionForm(product=product, category=category, data=request.POST) if form.is_valid(): question = Question(creator=request.user, title=form.cleaned_data['title'], content=form.cleaned_data['content']) question.save() # User successfully submitted a new question statsd.incr('questions.new') question.add_metadata(**form.cleaned_metadata) if product: # TODO: This add_metadata call should be removed once we are # fully IA-driven (sync isn't special case anymore). question.add_metadata(product=product['key']) for p in Product.objects.filter(slug__in=product.get('products')): question.products.add(p) if category: # TODO: This add_metadata call should be removed once we are # fully IA-driven (sync isn't special case anymore). question.add_metadata(category=category['key']) t = category.get('topic') if t: question.topics.add(Topic.objects.get(slug=t)) # The first time a question is saved, automatically apply some tags: question.auto_tag() # Submitting the question counts as a vote question_vote(request, question.id) if request.user.is_active: messages.add_message(request, messages.SUCCESS, _('Done! Your question is now posted on the Mozilla community ' 'support forum.')) url = reverse('questions.answers', kwargs={'question_id': question.id}) return HttpResponseRedirect(url) return HttpResponseRedirect(reverse('questions.aaq_confirm')) statsd.incr('questions.aaq.details-form-error') return jingo.render(request, template, {'form': form, 'products': products, 'current_product': product, 'current_category': category, 'current_articles': articles})
def aaq(request, product_key=None, category_key=None, showform=False, template=None, step=0): """Ask a new question.""" if product_key is None: product_key = request.GET.get("product") if request.MOBILE and product_key is None: product_key = "mobile" product = products.get(product_key) if product_key and not product: raise Http404 if category_key is None: category_key = request.GET.get("category") if product and category_key: category = product["categories"].get(category_key) if not category: # If we get an invalid category, redirect to previous step. return HttpResponseRedirect(reverse("questions.aaq_step2", args=[product_key])) deadend = category.get("deadend", False) topic = category.get("topic") if topic: html = None articles, fallback = documents_for( locale=request.LANGUAGE_CODE, products=Product.objects.filter(slug__in=product.get("products")), topics=[Topic.objects.get(slug=topic)], ) else: html = category.get("html") articles = category.get("articles") else: category = None deadend = product.get("deadend", False) if product else False html = product.get("html") if product else None articles = None if product: # User is on the select category step statsd.incr("questions.aaq.select-category") else: # User is on the select product step statsd.incr("questions.aaq.select-product") login_t = "questions/mobile/new_question_login.html" if request.MOBILE else "questions/new_question_login.html" if request.method == "GET": search = request.GET.get("search", "") if search: results = _search_suggestions( request, search, locale_or_default(request.LANGUAGE_CODE), product.get("products") ) tried_search = True else: results = [] tried_search = False if category: # User is on the "Ask This" step statsd.incr("questions.aaq.search-form") if showform or request.GET.get("showform"): # Before we show the form, make sure the user is auth'd: if not request.user.is_authenticated(): # User is on the login or register Step statsd.incr("questions.aaq.login-or-register") login_form = AuthenticationForm() register_form = RegisterForm() return jingo.render( request, login_t, { "product": product, "category": category, "title": search, "register_form": register_form, "login_form": login_form, }, ) form = NewQuestionForm(product=product, category=category, initial={"title": search}) # User is on the question details step statsd.incr("questions.aaq.details-form") else: form = None if search: # User is on the article and questions suggestions step statsd.incr("questions.aaq.suggestions") return jingo.render( request, template, { "form": form, "results": results, "tried_search": tried_search, "products": products, "current_product": product, "current_category": category, "current_html": html, "current_articles": articles, "current_step": step, "deadend": deadend, "host": Site.objects.get_current().domain, }, ) # Handle the form post. if not request.user.is_authenticated(): if request.POST.get("login"): login_form = handle_login(request, only_active=False) statsd.incr("questions.user.login") register_form = RegisterForm() elif request.POST.get("register"): login_form = AuthenticationForm() email_template = "questions/email/confirm_question.ltxt" email_subject = _("Please confirm your Firefox Help question") email_data = request.GET.get("search") register_form = handle_register(request, email_template, email_subject, email_data) if register_form.is_valid(): # Now try to log in. user = auth.authenticate(username=request.POST.get("username"), password=request.POST.get("password")) auth.login(request, user) statsd.incr("questions.user.register") else: # L10n: This shouldn't happen unless people tamper with POST data. message = _lazy("Request type not recognized.") return jingo.render(request, "handlers/400.html", {"message": message}, status=400) if request.user.is_authenticated(): # Redirect to GET the current URL replacing the step parameter. # This is also required for the csrf middleware to set the auth'd # tokens appropriately. url = urlparams(request.get_full_path(), step="aaq-question") return HttpResponseRedirect(url) else: return jingo.render( request, login_t, { "product": product, "category": category, "title": request.POST.get("title"), "register_form": register_form, "login_form": login_form, }, ) form = NewQuestionForm(product=product, category=category, data=request.POST) if form.is_valid(): question = Question( creator=request.user, title=form.cleaned_data["title"], content=form.cleaned_data["content"], locale=request.LANGUAGE_CODE, ) question.save() # User successfully submitted a new question statsd.incr("questions.new") question.add_metadata(**form.cleaned_metadata) if product: # TODO: This add_metadata call should be removed once we are # fully IA-driven (sync isn't special case anymore). question.add_metadata(product=product["key"]) if product.get("products"): for p in Product.objects.filter(slug__in=product["products"]): question.products.add(p) if category: # TODO: This add_metadata call should be removed once we are # fully IA-driven (sync isn't special case anymore). question.add_metadata(category=category["key"]) t = category.get("topic") if t: question.topics.add(Topic.objects.get(slug=t)) # The first time a question is saved, automatically apply some tags: question.auto_tag() # Submitting the question counts as a vote question_vote(request, question.id) if request.user.is_active: messages.add_message( request, messages.SUCCESS, _("Done! Your question is now posted on the Mozilla community " "support forum."), ) url = reverse("questions.answers", kwargs={"question_id": question.id}) return HttpResponseRedirect(url) return HttpResponseRedirect(reverse("questions.aaq_confirm")) statsd.incr("questions.aaq.details-form-error") return jingo.render( request, template, { "form": form, "products": products, "current_product": product, "current_category": category, "current_articles": articles, }, )
def test_documents_for_fallback(self): """Verify the fallback in documents_for.""" general_bookmarks_documents, fallback = documents_for( locale='es', topics=[self.general, self.bookmarks]) eq_(len(general_bookmarks_documents), 0) eq_(len(fallback), 1)