Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/apps/bandwagon/tasks.py
blob: 69a2376abd911bb2de46cb53cfb18ddee98d69e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import logging
import math
import os

from django.conf import settings
from django.db.models import Count

from celeryutils import task
from easy_thumbnails import processors
from PIL import Image

import amo
from tags.models import Tag
from . import cron  # Pull in tasks run through cron.
from .models import Collection, CollectionAddon, CollectionVote

log = logging.getLogger('z.task')


@task
def collection_votes(*ids, **kw):
    log.info('[%s@%s] Updating collection votes.' %
             (len(ids), collection_votes.rate_limit))
    using = kw.get('using')
    for collection in ids:
        v = CollectionVote.objects.filter(collection=collection).using(using)
        votes = dict(v.values_list('vote').annotate(Count('vote')))
        c = Collection.objects.get(id=collection)
        c.upvotes = up = votes.get(1, 0)
        c.downvotes = down = votes.get(-1, 0)
        try:
            # Use log to limit the effect of the multiplier.
            c.rating = (up - down) * math.log(up + down)
        except ValueError:
            c.rating = 0
        c.save()


@task
def resize_icon(src, dst):
    """Resizes collection icons to 32x32"""
    log.info('[1@None] Resizing icon: %s' % dst)

    try:
        im = Image.open(src)
        im = processors.scale_and_crop(im, (32, 32))
        im.save(dst)
        os.remove(src)
    except Exception, e:
        log.error("Error saving collection icon: %s" % e)

@task
def delete_icon(dst):
    log.info('[1@None] Deleting icon: %s.' % dst)

    if not dst.startswith(settings.COLLECTIONS_ICON_PATH):
        log.error("Someone tried deleting something they shouldn't: %s" % dst)
        return

    try:
        os.remove(dst)
    except Exception, e:
        log.error("Error deleting icon: %s" % e)


@task
def collection_meta(*ids, **kw):
    log.info('[%s@%s] Updating collection metadata.' %
             (len(ids), collection_meta.rate_limit))
    using = kw.get('using')
    qs = (CollectionAddon.objects.filter(collection__in=ids)
          .using(using).values_list('collection'))
    counts = dict(qs.annotate(Count('id')))
    persona_counts = dict(qs.filter(addon__type=amo.ADDON_PERSONA)
                          .annotate(Count('id')))
    tags = (Tag.objects.not_blacklisted().values_list('id')
            .annotate(cnt=Count('id')).filter(cnt__gt=1).order_by('-cnt'))
    for c in Collection.objects.no_cache().filter(id__in=ids):
        addon_count = counts.get(c.id, 0)
        all_personas = addon_count == persona_counts.get(c.id, None)
        addons = list(c.addons.values_list('id', flat=True))
        c.top_tags = [t for t, _ in tags.filter(addons__in=addons)[:5]]
        Collection.objects.filter(id=c.id).update(addon_count=addon_count,
                                                  all_personas=all_personas)


@task(rate_limit='10/m')
def cron_collection_meta(*addons):
    collection_meta(*addons)