backend for watching collections (bug 589952)
This commit is contained in:
Родитель
819a52b383
Коммит
4686b8374d
|
@ -70,7 +70,7 @@
|
|||
"lastname": "Clouser",
|
||||
"emailhidden": 0,
|
||||
"user": 10482,
|
||||
"password": "sha1$a04e0$0512298efb3e6e7dbace3976474151d396078fdd",
|
||||
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600",
|
||||
"nickname": "clouserw",
|
||||
"username": "clouserw",
|
||||
"display_name": "clouserw",
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
import datetime
|
||||
import itertools
|
||||
|
||||
from django.db import connection, connections, transaction
|
||||
from django.db import connection, transaction
|
||||
from django.db.models import Count
|
||||
|
||||
import commonware.log
|
||||
import multidb
|
||||
from celery.messaging import establish_connection
|
||||
from celeryutils import task
|
||||
|
||||
import amo
|
||||
from amo.utils import chunked, slugify
|
||||
from bandwagon.models import (CollectionSubscription,
|
||||
from bandwagon.models import (CollectionWatcher,
|
||||
CollectionVote, Collection, CollectionUser)
|
||||
import cronjobs
|
||||
|
||||
|
@ -55,7 +54,7 @@ def migrate_collection_users():
|
|||
def update_collections_subscribers():
|
||||
"""Update collections subscribers totals."""
|
||||
|
||||
d = (CollectionSubscription.objects.values('collection_id')
|
||||
d = (CollectionWatcher.objects.values('collection_id')
|
||||
.annotate(count=Count('collection'))
|
||||
.extra(where=['DATE(created)=%s'], params=[datetime.date.today()]))
|
||||
|
||||
|
|
|
@ -353,7 +353,7 @@ class CollectionPromo(amo.models.ModelBase):
|
|||
promo_dict[promo_id].collection = collection.next()
|
||||
|
||||
|
||||
class CollectionSubscription(amo.models.ModelBase):
|
||||
class CollectionWatcher(amo.models.ModelBase):
|
||||
collection = models.ForeignKey(Collection, related_name='subscriptions')
|
||||
user = models.ForeignKey(UserProfile)
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import json
|
||||
|
||||
import django.test
|
||||
from django.utils.datastructures import MultiValueDict
|
||||
from django.utils import encoding
|
||||
|
@ -14,7 +16,8 @@ from addons.models import Addon
|
|||
from amo.urlresolvers import reverse
|
||||
from amo.utils import urlparams
|
||||
from bandwagon import forms
|
||||
from bandwagon.models import Collection, CollectionVote, CollectionUser
|
||||
from bandwagon.models import (Collection, CollectionVote, CollectionUser,
|
||||
CollectionWatcher)
|
||||
from users.models import UserProfile
|
||||
|
||||
|
||||
|
@ -564,7 +567,7 @@ class AjaxTest(test_utils.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
assert self.client.login(username='clouserw@gmail.com',
|
||||
password='yermom')
|
||||
password='password')
|
||||
self.user = UserProfile.objects.get(email='clouserw@gmail.com')
|
||||
self.other = UserProfile.objects.exclude(id=self.user.id)[0]
|
||||
|
||||
|
@ -628,3 +631,42 @@ class AjaxTest(test_utils.TestCase):
|
|||
def test_ajax_list_bad_addon_id(self):
|
||||
url = reverse('collections.ajax_list') + '?addon_id=fff'
|
||||
eq_(self.client.get(url).status_code, 400)
|
||||
|
||||
|
||||
class TestWatching(test_utils.TestCase):
|
||||
fixtures = ['base/users', 'base/collection_57181']
|
||||
|
||||
def setUp(self):
|
||||
self.collection = c = Collection.objects.get(id=57181)
|
||||
self.url = reverse('collections.watch',
|
||||
args=[c.author.username, c.slug])
|
||||
assert self.client.login(username='clouserw@gmail.com',
|
||||
password='password')
|
||||
|
||||
self.qs = CollectionWatcher.objects.filter(user__username='clouserw',
|
||||
collection=57181)
|
||||
eq_(self.qs.count(), 0)
|
||||
|
||||
def test_watch(self):
|
||||
r = self.client.post(self.url, follow=True)
|
||||
eq_(r.status_code, 200)
|
||||
eq_(self.qs.count(), 1)
|
||||
|
||||
def test_unwatch(self):
|
||||
r = self.client.post(self.url, follow=True)
|
||||
eq_(r.status_code, 200)
|
||||
r = self.client.post(self.url, follow=True)
|
||||
eq_(r.status_code, 200)
|
||||
eq_(self.qs.count(), 0)
|
||||
|
||||
def test_amouser_watching(self):
|
||||
r = self.client.post(self.url, follow=True)
|
||||
eq_(r.status_code, 200)
|
||||
r = self.client.get('/en-US/firefox/')
|
||||
eq_(r.context['amo_user'].watching, [57181])
|
||||
|
||||
def test_ajax_response(self):
|
||||
r = self.client.post(self.url, follow=True,
|
||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
eq_(r.status_code, 200)
|
||||
eq_(json.loads(r.content), {'watching': True})
|
||||
|
|
|
@ -18,6 +18,7 @@ detail_urls = patterns('',
|
|||
url('^delete$', views.delete, name='collections.delete'),
|
||||
url('^(?P<action>add|remove)$', views.collection_alter,
|
||||
name='collections.alter'),
|
||||
url('^watch$', views.watch, name='collections.watch'),
|
||||
)
|
||||
|
||||
ajax_urls = patterns('',
|
||||
|
|
|
@ -11,14 +11,14 @@ import caching.base as caching
|
|||
from tower import ugettext_lazy as _lazy, ugettext as _
|
||||
|
||||
import amo.utils
|
||||
from amo.decorators import login_required, post_required
|
||||
from amo.decorators import login_required, post_required, json_view
|
||||
from amo.urlresolvers import reverse
|
||||
from access import acl
|
||||
from addons.models import Addon
|
||||
from addons.views import BaseFilter
|
||||
from tags.models import Tag
|
||||
from translations.query import order_by_translation
|
||||
from .models import (Collection, CollectionAddon,
|
||||
from .models import (Collection, CollectionAddon, CollectionWatcher,
|
||||
CollectionVote, SPECIAL_SLUGS)
|
||||
from . import forms
|
||||
|
||||
|
@ -432,3 +432,28 @@ def delete(request, username, slug):
|
|||
return http.HttpResponseRedirect(collection.get_url_path())
|
||||
|
||||
return jingo.render(request, 'bandwagon/delete.html', data)
|
||||
|
||||
|
||||
@login_required
|
||||
@post_required
|
||||
@json_view
|
||||
def watch(request, username, slug):
|
||||
"""
|
||||
POST /collections/:user/:slug/watch to toggle the user's watching status.
|
||||
|
||||
For ajax, return {watching: true|false}. (reflects the new value)
|
||||
Otherwise, redirect to the collection page.
|
||||
"""
|
||||
collection = get_collection(request, username, slug)
|
||||
d = dict(user=request.amo_user, collection=collection)
|
||||
qs = CollectionWatcher.uncached.using('default').filter(**d)
|
||||
watching = not qs # Flip the bool since we're about to change it.
|
||||
if qs:
|
||||
qs.delete()
|
||||
else:
|
||||
CollectionWatcher.objects.create(**d)
|
||||
|
||||
if request.is_ajax():
|
||||
return {'watching': watching}
|
||||
else:
|
||||
return redirect(collection.get_url_path())
|
||||
|
|
|
@ -231,7 +231,7 @@ class UserProfile(amo.models.ModelBase):
|
|||
"""Adds extra goodies to a UserProfile (meant for request.amo_user)."""
|
||||
# We don't want to cache these things on every UserProfile; they're
|
||||
# only used by a user attached to a request.
|
||||
from bandwagon.models import CollectionAddon
|
||||
from bandwagon.models import CollectionAddon, CollectionWatcher
|
||||
SPECIAL = amo.COLLECTION_SPECIAL_SLUGS.keys()
|
||||
user = users[0]
|
||||
qs = CollectionAddon.objects.filter(
|
||||
|
@ -241,6 +241,8 @@ class UserProfile(amo.models.ModelBase):
|
|||
addons[ctype].append(addon)
|
||||
user.mobile_addons = addons[amo.COLLECTION_MOBILE]
|
||||
user.favorite_addons = addons[amo.COLLECTION_FAVORITES]
|
||||
user.watching = list((CollectionWatcher.objects.filter(user=user)
|
||||
.values_list('collection', flat=True)))
|
||||
|
||||
|
||||
class BlacklistedUsername(amo.models.ModelBase):
|
||||
|
|
Загрузка…
Ссылка в новой задаче