def save(self, commit=False): from .tasks import create_persona_preview_image, save_persona_image # We ignore `commit`, since we need it to be `False` so we can save # the ManyToMany fields on our own. addon = super(NewPersonaForm, self).save(commit=False) addon.status = amo.STATUS_UNREVIEWED addon.type = amo.ADDON_PERSONA addon.save() addon._current_version = Version.objects.create(addon=addon, version='0') addon.save() amo.log(amo.LOG.CREATE_ADDON, addon) log.debug('New persona %r uploaded' % addon) data = self.cleaned_data header = data['header_hash'] footer = data['footer_hash'] header = os.path.join(settings.TMP_PATH, 'persona_header', header) footer = os.path.join(settings.TMP_PATH, 'persona_footer', footer) dst = os.path.join(settings.PERSONAS_PATH, str(addon.id)) # Save header, footer, and preview images. save_persona_image(src=header, dst=dst, img_basename='header.jpg') save_persona_image(src=footer, dst=dst, img_basename='footer.jpg') create_persona_preview_image(src=header, dst=dst, img_basename='preview.jpg', set_modified_on=[addon]) # Save user info. user = self.request.amo_user AddonUser(addon=addon, user=user).save() p = Persona() p.persona_id = 0 p.addon = addon p.header = 'header' p.footer = 'footer' if data['accentcolor']: p.accentcolor = data['accentcolor'].lstrip('#') if data['textcolor']: p.textcolor = data['textcolor'].lstrip('#') p.license_id = data['license'] p.submit = datetime.now() p.author = user.name p.display_username = user.username p.save() # Save tags. for t in data['tags']: Tag(tag_text=t).save_tag(addon) # Save categories. tb_c = Category.objects.get(application=amo.THUNDERBIRD.id, name__id=data['category'].name_id) AddonCategory(addon=addon, category=data['category']).save() AddonCategory(addon=addon, category=tb_c).save() return addon
def save(self, commit=False): from addons.tasks import (create_persona_preview_image, save_persona_image) data = self.cleaned_data addon = Addon.objects.create(id=None, name=data['name'], slug=data['slug'], description=data['summary'], status=amo.STATUS_PENDING, type=amo.ADDON_PERSONA) addon._current_version = Version.objects.create(addon=addon, version='0') addon.save() # Save header, footer, and preview images. try: header = data['header_hash'] footer = data['footer_hash'] header = os.path.join(settings.TMP_PATH, 'persona_header', header) footer = os.path.join(settings.TMP_PATH, 'persona_footer', footer) dst = os.path.join(settings.PERSONAS_PATH, str(addon.id)) save_persona_image(src=header, dst=dst, img_basename='header.jpg') save_persona_image(src=footer, dst=dst, img_basename='footer.jpg') create_persona_preview_image(src=header, dst=dst, img_basename='preview.jpg', set_modified_on=[addon]) except IOError: addon.delete() raise IOError # Save user info. user = self.request.amo_user AddonUser(addon=addon, user=user).save() # Create Persona instance. p = Persona() p.persona_id = 0 p.addon = addon p.header = 'header' p.footer = 'footer' if data['accentcolor']: p.accentcolor = data['accentcolor'].lstrip('#') if data['textcolor']: p.textcolor = data['textcolor'].lstrip('#') p.license_id = data['license'] p.submit = datetime.now() p.author = user.name p.display_username = user.username p.save() # Save categories. tb_c, created = Category.objects.get_or_create( application_id=amo.THUNDERBIRD.id, name__id=data['category'].name.id, type=amo.ADDON_PERSONA) AddonCategory(addon=addon, category=data['category']).save() AddonCategory(addon=addon, category=tb_c).save() return addon
def setup_featured_tools_and_extensions(self): # Pretend all Add-ons are search-related: Addon.objects.update(type=amo.ADDON_SEARCH) # One will be an extension in the search category: limon = Addon.objects.get( name__localized_string='Limon free English-Hebrew dictionary') limon.type = amo.ADDON_EXTENSION limon.status = amo.STATUS_PUBLIC limon.save() AppSupport(addon=limon, app_id=amo.FIREFOX.id).save() # Another will be a search add-on in the search category: readit = Addon.objects.get(name__localized_string='Read It Later') readit.type = amo.ADDON_SEARCH readit.status = amo.STATUS_PUBLIC readit.save() AppSupport(addon=readit, app_id=amo.FIREFOX.id).save() # Un-feature all others: Feature.objects.all().delete() # Feature foxy : foxy = Addon.objects.get(name__localized_string='FoxyProxy Standard') Feature(addon=foxy, application_id=amo.FIREFOX.id, start=datetime.datetime.now(), end=datetime.datetime.now() + timedelta(days=30)).save() # Feature Limon Dictionary and Read It Later as a category feature: s = Category.objects.get(slug='search-tools') s.addoncategory_set.add(AddonCategory(addon=limon, feature=True)) s.addoncategory_set.add(AddonCategory(addon=readit, feature=True)) s.save()
def creatured(request, category): TYPE = amo.ADDON_EXTENSION q = Category.objects.filter(application=request.APP.id, type=TYPE) category = get_object_or_404(q, slug=category) ids = AddonCategory.creatured_random(category, request.LANG) addons = manual_order(Addon.objects.public(), ids, pk_name="addons.id") return render(request, "browse/creatured.html", {"addons": addons, "category": category, "sorting": "featured"})
def _landing(request, category=None): if category: featured = '' category = get_list_or_404( Category.objects.filter(type=amo.ADDON_PERSONA, slug=category))[0] popular = (Addon.objects.public() .filter(type=amo.ADDON_PERSONA, addoncategory__category__id=category.id) .order_by('-persona__popularity')[:12]) categories, filter, base, category = personas_listing(request, category.slug) ids = AddonCategory.creatured_random(category, request.LANG) featured = manual_order(base, ids, pk_name="addons.id")[:12] else: popular = (Addon.objects.public().filter(type=amo.ADDON_PERSONA) .order_by('-persona__popularity')[:12]) featured = get_featured_personas(request, num_personas=12) return jingo.render(request, 'themes/landing.html', { 'category': category, 'popular': popular, 'featured': featured, })
def test_no_featured_addons_by_category(self): Feature.objects.all().delete() # Pretend Foxy is a bookmarks related search add-on foxy = Addon.objects.get(name__localized_string='FoxyProxy Standard') foxy.type = amo.ADDON_SEARCH foxy.save() bookmarks = Category.objects.get(slug='bookmarks') bookmarks.addoncategory_set.add( AddonCategory(addon=foxy, feature=False)) bookmarks.save() response = self.client.get( reverse('browse.search-tools', args=('bookmarks', ))) eq_(response.status_code, 200) doc = pq(response.content) eq_([ a.name.localized_string for a in response.context['addons'].object_list ], [u'FoxyProxy Standard']) eq_(response.context['filter'].field, 'popular') eq_( doc('title').text(), 'Bookmarks :: Search Tools :: Add-ons for Firefox') # Ensure that all heading links have the proper base URL # between the category / no category cases. sort_links = [ urlparse(a.attrib['href']).path for a in doc('.listing-header ul li a') ] eq_(set(sort_links), set([reverse('browse.search-tools', args=('bookmarks', ))]))
def personas(request, category=None, template=None): categories, filter, base, category = personas_listing(request, category) # Pass the count from base instead of letting it come from # filter.qs.count() since that would join against personas. count = category.count if category else base.count() if "sort" not in request.GET and ((request.MOBILE and not category) or (not request.MOBILE and count > 4)): template += "category_landing.html" else: template += "grid.html" addons = amo.utils.paginate(request, filter.qs, 30, count=count) if category: ids = AddonCategory.creatured_random(category, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") else: ids = Addon.featured_random(request.APP, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") ctx = { "categories": categories, "category": category, "addons": addons, "filter": filter, "sorting": filter.field, "sort_opts": filter.opts, "featured": featured, "search_cat": "personas", "is_homepage": category is None and "sort" not in request.GET, } return jingo.render(request, template, ctx)
def test_search_tools_within_a_category(self): # Pretend Foxy is the only bookmarks related search add-on AddonCategory.objects.all().delete() foxy = Addon.objects.get(name__localized_string='FoxyProxy Standard') foxy.type = amo.ADDON_SEARCH foxy.save() bookmarks = Category.objects.get(slug='bookmarks') bookmarks.addoncategory_set.add( AddonCategory(addon=foxy, feature=False)) bookmarks.save() url = reverse('browse.search-tools.rss', args=('bookmarks', )) + '?sort=popular' r = self.client.get(url) eq_(r.status_code, 200) doc = pq(r.content) eq_( doc('rss channel title')[0].text, 'Bookmarks :: Search Tools :: Add-ons for Firefox') link = doc('rss channel link')[0].text rel_link = reverse('browse.search-tools.rss', args=('bookmarks', )) + '?sort=popular' assert link.endswith(rel_link), ('Unexpected link: %r' % link) eq_( doc('rss channel description')[0].text, "Search tools relating to Bookmarks") eq_([e.text for e in doc('rss channel item title')], ['FoxyProxy Standard 2.17'])
def personas(request, category=None, template=None): categories, filter, base, category = personas_listing(request, category) # Pass the count from base instead of letting it come from # filter.qs.count() since that would join against personas. count = category.count if category else base.count() if ('sort' not in request.GET and ((request.MOBILE and not category) or (not request.MOBILE and count > 4))): template += 'category_landing.html' else: template += 'grid.html' addons = amo.utils.paginate(request, filter.qs, 30, count=count) if category: ids = AddonCategory.creatured_random(category, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") else: ids = Addon.featured_random(request.APP, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") ctx = { 'categories': categories, 'category': category, 'addons': addons, 'filter': filter, 'sorting': filter.field, 'sort_opts': filter.opts, 'featured': featured, 'search_cat': 'personas', 'is_homepage': category is None and 'sort' not in request.GET } return jingo.render(request, template, ctx)
def personas(request, category=None): categories, filter, base, category = personas_listing(request, category) # Pass the count from base instead of letting it come from # filter.qs.count() since that would join against personas. count = category.count if category else base.count() if 'sort' in request.GET or count < 5: template = 'grid.html' else: template = 'category_landing.html' addons = amo.utils.paginate(request, filter.qs, 30, count=count) if category: ids = AddonCategory.creatured_random(category, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") else: ids = Addon.featured_random(request.APP, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") is_homepage = category is None and 'sort' not in request.GET return jingo.render(request, 'browse/personas/' + template, {'categories': categories, 'category': category, 'filter': filter, 'addons': addons, 'featured': featured, 'is_homepage': is_homepage, 'search_cat': 'personas'})
def personas(request, category=None, template=None): categories, filter, base, category = personas_listing(request, category) # Pass the count from base instead of letting it come from # filter.qs.count() since that would join against personas. count = category.count if category else base.count() if ('sort' not in request.GET and ((request.MOBILE and not category) or (not request.MOBILE and count > 4))): template += 'category_landing.html' else: template += 'grid.html' addons = amo.utils.paginate(request, filter.qs, 30, count=count) if category: ids = AddonCategory.creatured_random(category, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") else: ids = Addon.featured_random(request.APP, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") ctx = {'categories': categories, 'category': category, 'addons': addons, 'filter': filter, 'sorting': filter.field, 'sort_opts': filter.opts, 'featured': featured, 'search_cat': 'personas', 'is_homepage': category is None and 'sort' not in request.GET} return jingo.render(request, template, ctx)
def test_edit_categories_addandremove(self): AddonCategory(addon=self.addon, category_id=23).save() eq_([c.id for c in self.get_addon().all_categories], [22, 23]) self.cat_initial['categories'] = [22, 24] self.client.post(self.basic_edit_url, self.get_dict()) addon_cats = self.get_addon().categories.values_list('id', flat=True) eq_(sorted(addon_cats), [22, 24])
def creatured(request, category): TYPE = amo.ADDON_EXTENSION q = Category.objects.filter(application=request.APP.id, type=TYPE) category = get_object_or_404(q, slug=category) ids = AddonCategory.creatured_random(category, request.LANG) addons = manual_order(Addon.objects.public(), ids, pk_name='addons.id') return render(request, 'browse/creatured.html', {'addons': addons, 'category': category, 'sorting': 'featured'})
def test_edit_categories_remove(self): c = Category.objects.get(id=23) AddonCategory(addon=self.addon, category=c).save() eq_([cat.id for cat in self.get_addon().all_categories], [22, 23]) self.cat_initial['categories'] = [22] self.client.post(self.basic_edit_url, self.get_dict()) addon_cats = self.get_addon().categories.values_list('id', flat=True) eq_(sorted(addon_cats), [22])
def personas(request, category=None, template=None): listing = personas_listing(request, category) # I guess this was a Complete Theme after all. if isinstance(listing, (HttpResponsePermanentRedirect, HttpResponseRedirect)): return listing categories, filter_, base, cat = listing if filter_.field == 'up-and-coming': # Almost hardcoding the number of element because performing # `filter_.qs.count()` is a performance killer. We're still # verifying the `base.count()` for the template switch below. base_count = base.count() count = (base_count if base_count < MIN_COUNT_FOR_LANDING else PAGINATE_PERSONAS_BY * settings.PERSONA_DEFAULT_PAGES) else: # Pass the count from base instead of letting it come from # filter_.qs.count() since that would join against personas. count = cat.count if cat else base.count() addons = amo.utils.paginate(request, filter_.qs, PAGINATE_PERSONAS_BY, count=count) if ('sort' not in request.GET and ((request.MOBILE and not cat) or (not request.MOBILE and count > MIN_COUNT_FOR_LANDING))): template += 'category_landing.html' else: template += 'grid.html' if cat: ids = AddonCategory.creatured_random(cat, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") else: ids = Addon.featured_random(request.APP, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") ctx = { 'categories': categories, 'category': cat, 'addons': addons, 'filter': filter_, 'sorting': filter_.field, 'sort_opts': filter_.opts, 'featured': featured, 'search_cat': 'themes', 'is_homepage': cat is None and 'sort' not in request.GET } return render(request, template, ctx)
def personas(request, category=None, template=None): listing = personas_listing(request, category) # I guess this was a Complete Theme after all. if isinstance(listing, (HttpResponsePermanentRedirect, HttpResponseRedirect)): return listing categories, filter_, base, cat = listing if filter_.field == "up-and-coming": # Almost hardcoding the number of element because performing # `filter_.qs.count()` is a performance killer. We're still # verifying the `base.count()` for the template switch below. base_count = base.count() count = ( base_count if base_count < MIN_COUNT_FOR_LANDING else PAGINATE_PERSONAS_BY * settings.PERSONA_DEFAULT_PAGES ) else: # Pass the count from base instead of letting it come from # filter_.qs.count() since that would join against personas. count = cat.count if cat else base.count() addons = amo.utils.paginate(request, filter_.qs, PAGINATE_PERSONAS_BY, count=count) if "sort" not in request.GET and ( (request.MOBILE and not cat) or (not request.MOBILE and count > MIN_COUNT_FOR_LANDING) ): template += "category_landing.html" else: template += "grid.html" if cat: ids = AddonCategory.creatured_random(cat, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") else: ids = Addon.featured_random(request.APP, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") ctx = { "categories": categories, "category": cat, "addons": addons, "filter": filter_, "sorting": filter_.field, "sort_opts": filter_.opts, "featured": featured, "search_cat": "themes", "is_homepage": cat is None and "sort" not in request.GET, } return render(request, template, ctx)
def save(self, addon): categories_new = self.cleaned_data['categories'] categories_old = [cats for app, cats in addon.app_categories if app.id == self.cleaned_data['application'].id] if categories_old: categories_old = categories_old[0] # Add new categories. for c in set(categories_new) - set(categories_old): AddonCategory(addon=addon, category=c).save() # Remove old categories. for c in set(categories_old) - set(categories_new): AddonCategory.objects.filter(addon=addon, category=c).delete()
def save(self, commit=False): data = self.cleaned_data addon = Addon.objects.create(slug=data.get('slug'), status=amo.STATUS_PENDING, type=amo.ADDON_PERSONA) addon.name = {'en-US': data['name']} if data.get('description'): addon.description = data['description'] addon._current_version = Version.objects.create(addon=addon, version='0') addon.save() # Create Persona instance. p = Persona() p.persona_id = 0 p.addon = addon p.header = 'header.png' if data['footer_hash']: p.footer = 'footer.png' if data['accentcolor']: p.accentcolor = data['accentcolor'].lstrip('#') if data['textcolor']: p.textcolor = data['textcolor'].lstrip('#') p.license = data['license'] p.submit = datetime.now() user = self.request.user p.author = user.username p.display_username = user.name p.save() # Save header, footer, and preview images. save_theme.delay(data['header_hash'], data['footer_hash'], addon) # Save user info. addon.addonuser_set.create(user=user, role=amo.AUTHOR_ROLE_OWNER) # Save tags. for t in data['tags']: Tag(tag_text=t).save_tag(addon) # Save categories. AddonCategory(addon=addon, category=data['category']).save() return addon
def save(self, commit=False): from addons.tasks import (create_persona_preview_images, save_persona_image) data = self.cleaned_data addon = Addon.objects.create(slug=data.get('slug'), status=amo.STATUS_PENDING, type=amo.ADDON_PERSONA) addon.name = {'en-US': data['name']} if data.get('summary'): addon.description = {'en-US': data['summary']} addon._current_version = Version.objects.create(addon=addon, version='0') addon.save() # Save header, footer, and preview images. try: header = data['header_hash'] footer = data['footer_hash'] header = os.path.join(settings.TMP_PATH, 'persona_header', header) footer = os.path.join(settings.TMP_PATH, 'persona_footer', footer) dst_root = os.path.join(settings.ADDONS_PATH, str(addon.id)) save_persona_image.delay(src=header, full_dst=os.path.join( dst_root, 'header.png')) save_persona_image.delay(src=footer, full_dst=os.path.join( dst_root, 'footer.png')) create_persona_preview_images.delay( src=header, full_dst=[ os.path.join(dst_root, 'preview.png'), os.path.join(dst_root, 'icon.png') ], set_modified_on=[addon]) except IOError: addon.delete() raise # Save user info. user = self.request.amo_user AddonUser(addon=addon, user=user).save() # Create Persona instance. p = Persona() p.persona_id = 0 p.addon = addon p.header = 'header.png' p.footer = 'footer.png' if data['accentcolor']: p.accentcolor = data['accentcolor'].lstrip('#') if data['textcolor']: p.textcolor = data['textcolor'].lstrip('#') p.license = data['license'] p.submit = datetime.now() p.author = user.name p.display_username = user.username p.save() # Save tags. for t in data['tags']: Tag(tag_text=t).save_tag(addon) # Save categories. AddonCategory(addon=addon, category=data['category']).save() return addon
def __init__(self, request, base, category, key, default): self.category = category self.ids = AddonCategory.creatured_random(category, request.LANG) super(CategoryLandingFilter, self).__init__(request, base, key, default)