From a22afb4f46bafed178dea9b3b8c2dfb6830bf64c Mon Sep 17 00:00:00 2001 From: Allen Short Date: Thu, 23 Aug 2012 17:26:07 -0700 Subject: [PATCH] Add time ranges to featured apps tool (bug 779898) --- media/js/mkt/admin_featuredapp.js | 62 +++++++++++++++++-- migrations/460-featured-app-start-end.sql | 2 + mkt/browse/tests/test_views.py | 2 + mkt/home/tests/test_views.py | 22 +++++++ mkt/webapps/models.py | 10 ++- mkt/zadmin/models.py | 2 + .../templates/zadmin/featured_apps_ajax.html | 24 +++++-- mkt/zadmin/tests/test_views.py | 20 +++++- mkt/zadmin/urls.py | 4 +- mkt/zadmin/views.py | 14 ++++- 10 files changed, 147 insertions(+), 15 deletions(-) create mode 100644 migrations/460-featured-app-start-end.sql diff --git a/media/js/mkt/admin_featuredapp.js b/media/js/mkt/admin_featuredapp.js index 16f0bc836a..295b7310bd 100644 --- a/media/js/mkt/admin_featuredapp.js +++ b/media/js/mkt/admin_featuredapp.js @@ -24,11 +24,54 @@ function registerAddonAutocomplete(node) { }; } +function registerDatepicker(node) { + var $startPicker = node.find('.start-date-picker'); + var $tabl = $startPicker.closest('table'); + var url = $tabl.data('url'); + var appid = $tabl.data('app-id'); + debugger; + $startPicker.datepicker({ + dateFormat: 'yy-mm-dd', + onSelect: function(dateText) { + node.find('.date-range-start').val(dateText); + saveFeaturedDate('startdate', url, appid, dateText); + } + }); + var $endPicker = node.find('.end-date-picker'); + $endPicker.datepicker({ + dateFormat: 'yy-mm-dd', + onSelect: function(dateText) { + node.find('.date-range-end').val(dateText); + saveFeaturedDate('enddate', url, appid, dateText); + } + }); + + var $start = node.find('.date-range-start'); + $start.change( + function (e) { + saveFeaturedDate('startdate', $tabl.data('url'), $tabl.data('app-id'), $start.val()); + }); + var $end = node.find('.date-range-end'); + $end.change( + function (e) { + saveFeaturedDate('enddate', $tabl.data('url'), $tabl.data('app-id'), $end.val()); + }); + +} + +function saveFeaturedDate(which, url, appid, val) { + var data = {}; + data[which] = val; + data.app = appid; + $.ajax({type: 'POST', url: url, data: data }); +}; + function newAddonSlot(id) { var $tbody = $("#featured-webapps"); var $form = $tbody.next().children("tr").clone(); var $input = $form.find('input.placeholder'); registerAddonAutocomplete($input); + registerDatepicker($form); $tbody.append($form); } @@ -73,16 +116,17 @@ $(document).ready(function(){ 'select.localepicker', 'change', _pd(function (e) { - var region = $(e.target); + var $region = $(e.target); + var $tabl = $region.closest('table'); $.ajax({ type: 'POST', - url: region.data('url'), + url: $tabl.data('url'), data: { 'region': - _(region.children('option')) + _($region.children('option')) .filter(function(opt) {return opt.selected}) .map(function(sopt) {return sopt.value}), - 'app': region.data('id') + 'app': $tabl.data('app-id') } }); }) @@ -93,10 +137,16 @@ $(document).ready(function(){ url: categories.data("src")}); p.then(function(data) { categories.html(data); - showAppsList(categories); + showAppsList(categories).then( + function () { + registerDatepicker(appslist); + }); }); categories.change(function (e) { - showAppsList(categories); + showAppsList(categories).then( + function () { + registerDatepicker(appslist); + }); }); $('#featured-add').click(_pd(function() { newAddonSlot(); })); }); diff --git a/migrations/460-featured-app-start-end.sql b/migrations/460-featured-app-start-end.sql new file mode 100644 index 0000000000..a6a8c16879 --- /dev/null +++ b/migrations/460-featured-app-start-end.sql @@ -0,0 +1,2 @@ +ALTER TABLE `zadmin_featuredapp` ADD COLUMN `startdate` DATE, + ADD COLUMN `enddate` DATE; diff --git a/mkt/browse/tests/test_views.py b/mkt/browse/tests/test_views.py index 9e4ce4fabb..8d7d9be042 100644 --- a/mkt/browse/tests/test_views.py +++ b/mkt/browse/tests/test_views.py @@ -1,3 +1,4 @@ +import datetime from django.conf import settings from nose import SkipTest @@ -38,6 +39,7 @@ class BrowseBase(amo.tests.ESTestCase): # Feature in the US region. FeaturedAppRegion.objects.create(featured_app=f, region=mkt.regions.US.id) + return f def setup_featured(self): self.skip_if_disabled(settings.REGION_STORES) diff --git a/mkt/home/tests/test_views.py b/mkt/home/tests/test_views.py index 9ccd7ad673..177eb2e35c 100644 --- a/mkt/home/tests/test_views.py +++ b/mkt/home/tests/test_views.py @@ -5,6 +5,7 @@ from amo.urlresolvers import reverse import mkt from mkt.browse.tests.test_views import BrowseBase +from mkt.webapps.models import Webapp from mkt.zadmin.models import FeaturedApp, FeaturedAppRegion @@ -56,3 +57,24 @@ class TestHome(BrowseBase): def test_popular_region_exclusions(self): self._test_popular_region_exclusions() + + + @mock_es + def test_featured_time_limitation(self): + # Home featured. + a = app_factory() + fa = self.make_featured(app=a, category=None) + fa.startdate = datetime.date(2012, 1, 1) + fa.enddate = datetime.date(2012, 2, 1) + fa.save() + for d in [datetime.date(2012, 1, 1), + datetime.date(2012, 1, 15), + datetime.date(2012, 2, 1)]: + Webapp.now = staticmethod(lambda: d) + eq_(self.get_pks('featured', self.url, {'region': 'us'}), + [a.id]) + + for d in [datetime.date(2011, 12, 15), + datetime.date(2012, 2, 2)]: + Webapp.now = staticmethod(lambda: d) + eq_(self.get_pks('featured', self.url, {'region': 'us'}), []) diff --git a/mkt/webapps/models.py b/mkt/webapps/models.py index d7bd5d7201..982878fe3d 100644 --- a/mkt/webapps/models.py +++ b/mkt/webapps/models.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import datetime import json import os import urlparse @@ -399,12 +400,19 @@ class Webapp(Addon): return list(self.content_ratings.filter(ratings_body__in=rb) .order_by('rating')) + @classmethod + def now(cls): + return datetime.date.today() + @classmethod def featured(cls, cat=None, region=None, limit=6): FeaturedApp = models.get_model('zadmin', 'FeaturedApp') qs = (FeaturedApp.objects .filter(app__status=amo.STATUS_PUBLIC, - app__disabled_by_user=False) + app__disabled_by_user=False, + startdate__lte=cls.now(), + enddate__gte=cls.now() + ) .order_by('-app__weekly_downloads')) if isinstance(cat, list): diff --git a/mkt/zadmin/models.py b/mkt/zadmin/models.py index aac4294c66..385f27e2a6 100644 --- a/mkt/zadmin/models.py +++ b/mkt/zadmin/models.py @@ -10,6 +10,8 @@ class FeaturedApp(models.Model): app = models.ForeignKey(Webapp, null=False) category = models.ForeignKey(Category, null=True) is_sponsor = models.BooleanField(default=False) + startdate = models.DateField(null=True) + enddate = models.DateField(null=True) class Meta: db_table = 'zadmin_featuredapp' diff --git a/mkt/zadmin/templates/zadmin/featured_apps_ajax.html b/mkt/zadmin/templates/zadmin/featured_apps_ajax.html index 1e61f7b77e..195ba40eb9 100644 --- a/mkt/zadmin/templates/zadmin/featured_apps_ajax.html +++ b/mkt/zadmin/templates/zadmin/featured_apps_ajax.html @@ -2,7 +2,7 @@ {% for row, selected_regions in apps_regions -%} - +
@@ -19,9 +19,7 @@ + + + + + + + +
{{ row.app.name }} {% if row.is_sponsor %}Sponsored{% else %}Not sponsored{% endif %} - {%- for locName, loc in regions -%}
+ {{ _('Start date') }} + + +
+
+ {{ _('End date') }} + + +
+
× diff --git a/mkt/zadmin/tests/test_views.py b/mkt/zadmin/tests/test_views.py index 38363549fa..8d8d9ddfaa 100644 --- a/mkt/zadmin/tests/test_views.py +++ b/mkt/zadmin/tests/test_views.py @@ -1,3 +1,4 @@ +from datetime import date from nose.tools import eq_ from pyquery import PyQuery as pq @@ -114,7 +115,7 @@ class TestFeaturedApps(amo.tests.TestCase): def test_set_region(self): f = FeaturedApp.objects.create(app=self.a1, category=None) FeaturedAppRegion.objects.create(featured_app=f, region=1) - r = self.client.post(reverse('zadmin.set_region_ajax'), + r = self.client.post(reverse('zadmin.set_attrs_ajax'), data={'app': f.pk, 'region[]': (3, 2)}) eq_(r.status_code, 200) eq_(list(FeaturedApp.objects.get(pk=f.pk).regions.values_list( @@ -122,6 +123,23 @@ class TestFeaturedApps(amo.tests.TestCase): [2, 3]) + def test_set_startdate(self): + f = FeaturedApp.objects.create(app=self.a1, category=None) + FeaturedAppRegion.objects.create(featured_app=f, region=1) + r = self.client.post(reverse('zadmin.set_attrs_ajax'), + data={'app': f.pk, 'startdate': '2012-08-01'}) + eq_(r.status_code, 200) + eq_(FeaturedApp.objects.get(pk=f.pk).startdate, date(2012, 8, 1)) + + def test_set_enddate(self): + f = FeaturedApp.objects.create(app=self.a1, category=None) + FeaturedAppRegion.objects.create(featured_app=f, region=1) + r = self.client.post(reverse('zadmin.set_attrs_ajax'), + data={'app': f.pk, 'enddate': '2012-08-31'}) + eq_(r.status_code, 200) + eq_(FeaturedApp.objects.get(pk=f.pk).enddate, date(2012, 8, 31)) + + class TestAddonSearch(amo.tests.ESTestCase): fixtures = ['base/users', 'webapps/337141-steamcube', 'base/addon_3615'] diff --git a/mkt/zadmin/urls.py b/mkt/zadmin/urls.py index 0583e2a5d4..0e40a2451a 100644 --- a/mkt/zadmin/urls.py +++ b/mkt/zadmin/urls.py @@ -12,6 +12,6 @@ urlpatterns = patterns( name='zadmin.featured_apps_ajax'), url('^apps/featured_categories_ajax$', views.featured_categories_ajax, name='zadmin.featured_categories_ajax'), - url('^apps/set_region_ajax$', views.set_region_ajax, - name='zadmin.set_region_ajax'), + url('^apps/set_attrs_ajax$', views.set_attrs_ajax, + name='zadmin.set_attrs_ajax'), ) diff --git a/mkt/zadmin/views.py b/mkt/zadmin/views.py index b556331fb0..8742cd04e2 100644 --- a/mkt/zadmin/views.py +++ b/mkt/zadmin/views.py @@ -1,3 +1,4 @@ +import datetime import jingo from django.contrib import admin @@ -71,8 +72,11 @@ def featured_apps_ajax(request): @admin_required -def set_region_ajax(request): +def set_attrs_ajax(request): regions = request.POST.getlist('region[]') + startdate = request.POST.get('startdate', None) + enddate = request.POST.get('enddate', None) + app = request.POST.get('app', None) if regions and app: fa = FeaturedApp.objects.get(pk=app) @@ -83,6 +87,14 @@ def set_region_ajax(request): for i in to_create: FeaturedAppRegion.objects.create(featured_app=fa, region=i) + if startdate and app: + FeaturedApp.objects.update( + startdate=datetime.datetime.strptime(startdate, + '%Y-%m-%d')) + if enddate and app: + FeaturedApp.objects.update( + enddate=datetime.datetime.strptime(enddate, + '%Y-%m-%d')) return HttpResponse()