Example #1
0
def add(request, addon, template=None):
    if addon.has_author(request.user):
        raise PermissionDenied
    form = forms.ReviewForm(request.POST or None)
    if (request.method == 'POST' and form.is_valid() and
            not request.POST.get('detailed')):
        details = _review_details(request, addon, form)
        review = Review.objects.create(**details)
        if 'flag' in form.cleaned_data and form.cleaned_data['flag']:
            rf = ReviewFlag(review=review,
                            user_id=request.user.id,
                            flag=ReviewFlag.OTHER,
                            note='URLs')
            rf.save()

        amo.log(amo.LOG.ADD_REVIEW, addon, review)
        log.debug('New review: %s' % review.id)

        reply_url = helpers.url('addons.reviews.reply', addon.slug, review.id,
                                add_prefix=False)
        data = {'name': addon.name,
                'rating': '%s out of 5 stars' % details['rating'],
                'review': details['body'],
                'reply_url': helpers.absolutify(reply_url)}

        emails = [a.email for a in addon.authors.all()]
        send_mail('reviews/emails/add_review.ltxt',
                  u'Mozilla Add-on User Review: %s' % addon.name,
                  emails, Context(data), 'new_review')

        return redirect(helpers.url('addons.reviews.list', addon.slug))
    return render(request, template, dict(addon=addon, form=form))
Example #2
0
def groupuser_post_save(sender, instance, **kw):
    if kw.get('raw'):
        return

    amo.log(amo.LOG.GROUP_USER_ADDED, instance.group, instance.user)
    log.info('Added %s to %s' % (instance.user, instance.group))
    del instance.user.groups_list
Example #3
0
def addon_manage(request, addon):
    form = AddonStatusForm(request.POST or None, instance=addon)
    pager = amo.utils.paginate(
        request, Version.unfiltered.filter(addon=addon), 30)
    # A list coercion so this doesn't result in a subquery with a LIMIT which
    # MySQL doesn't support (at this time).
    versions = list(pager.object_list)
    files = File.objects.filter(version__in=versions).select_related('version')
    formset = FileFormSet(request.POST or None, queryset=files)

    if form.is_valid() and formset.is_valid():
        if 'status' in form.changed_data:
            amo.log(amo.LOG.CHANGE_STATUS, addon, form.cleaned_data['status'])
            log.info('Addon "%s" status changed to: %s' % (
                addon.slug, form.cleaned_data['status']))
            form.save()

        for form in formset:
            if 'status' in form.changed_data:
                log.info('Addon "%s" file (ID:%d) status changed to: %s' % (
                    addon.slug, form.instance.id, form.cleaned_data['status']))
                form.save()
        return redirect('zadmin.addon_manage', addon.slug)

    # Build a map from file.id to form in formset for precise form display
    form_map = dict((form.instance.id, form) for form in formset.forms)
    # A version to file map to avoid an extra query in the template
    file_map = {}
    for file in files:
        file_map.setdefault(file.version_id, []).append(file)

    return render(request, 'zadmin/addon_manage.html', {
        'addon': addon, 'pager': pager, 'versions': versions, 'form': form,
        'formset': formset, 'form_map': form_map, 'file_map': file_map})
 def test_json_failboat(self):
     a = Addon.objects.get()
     amo.log(amo.LOG['CREATE_ADDON'], a)
     entry = ActivityLog.objects.get()
     entry._arguments = 'failboat?'
     entry.save()
     eq_(entry.arguments, None)
Example #5
0
    def save(self, *args, **kw):
        """Save all form data.

        This will only create a new license if it's not one of the builtin
        ones.

        Keyword arguments

        **log=True**
            Set to False if you do not want to log this action for display
            on the developer dashboard.
        """
        log = kw.pop('log', True)
        changed = self.changed_data

        builtin = self.cleaned_data['builtin']
        if builtin == '':  # No license chosen, it must be an unlisted add-on.
            return
        if builtin != License.OTHER:
            license = License.objects.get(builtin=builtin)
        else:
            # Save the custom license:
            license = super(LicenseForm, self).save(*args, **kw)

        if self.version:
            if changed or license != self.version.license:
                self.version.update(license=license)
                if log:
                    amo.log(amo.LOG.CHANGE_LICENSE, license,
                            self.version.addon)
        return license
 def test_addon_logging_pseudo(self):
     """
     If we are given (Addon, 3615) it should log in the AddonLog as well.
     """
     a = Addon.objects.get()
     amo.log(amo.LOG.CREATE_ADDON, (Addon, a.id))
     eq_(AddonLog.objects.count(), 1)
 def test_version_log(self):
     version = Version.objects.all()[0]
     amo.log(amo.LOG.REJECT_VERSION, version.addon, version,
             user=self.request.user)
     entries = ActivityLog.objects.for_version(version)
     assert len(entries) == 1
     assert version.get_url_path() in unicode(entries[0])
Example #8
0
def groupuser_post_delete(sender, instance, **kw):
    if kw.get('raw'):
        return

    amo.log(amo.LOG.GROUP_USER_REMOVED, instance.group, instance.user)
    log.info('Removed %s from %s' % (instance.user, instance.group))
    del instance.user.groups_list
    def test_user_review_history(self):
        self.theme_factory()

        reviewer = self.create_and_become_reviewer()

        res = self.client.get(reverse('editors.themes.history'))
        assert res.status_code == 200
        doc = pq(res.content)
        assert doc('tbody tr').length == 0

        theme = Persona.objects.all()[0]
        for x in range(3):
            amo.log(amo.LOG.THEME_REVIEW, theme.addon, user=reviewer,
                    details={'action': rvw.ACTION_APPROVE,
                             'comment': '', 'reject_reason': ''})

        res = self.client.get(reverse('editors.themes.history'))
        assert res.status_code == 200
        doc = pq(res.content)
        assert doc('tbody tr').length == 3

        res = self.client.get(reverse('editors.themes.logs'))
        assert res.status_code == 200
        doc = pq(res.content)
        assert doc('tbody tr').length == 3 * 2  # Double for comment rows.
Example #10
0
    def save(self, log_for_developer=True):
        u = super(UserEditForm, self).save(commit=False)
        data = self.cleaned_data
        photo = data['photo']
        if photo:
            u.picture_type = 'image/png'
            tmp_destination = u.picture_path + '__unconverted'

            with storage.open(tmp_destination, 'wb') as fh:
                for chunk in photo.chunks():
                    fh.write(chunk)

            tasks.resize_photo.delay(tmp_destination, u.picture_path,
                                     set_modified_on=[u])

        if data['password']:
            u.set_password(data['password'])
            log.info(u'User (%s) changed their password' % u.username)
            if log_for_developer:
                amo.log(amo.LOG.CHANGE_PASSWORD)

        for (i, n) in email.NOTIFICATIONS_BY_ID.items():
            enabled = n.mandatory or (str(i) in data['notifications'])
            UserNotification.update_or_create(
                user=u, notification_id=i, update={'enabled': enabled})

        log.debug(u'User (%s) updated their profile' % u)

        u.save()
        return u
Example #11
0
 def test_json_failboat(self):
     addon = Addon.objects.get()
     amo.log(amo.LOG['CREATE_ADDON'], addon)
     entry = ActivityLog.objects.get()
     entry._arguments = 'failboat?'
     entry.save()
     assert entry.arguments is None
Example #12
0
 def flag(cls, addon, event, message=None):
     cls.objects.get_or_create(addon=addon)
     if message:
         amo.log(event, addon, addon.current_version,
                 details={'comments': message})
     else:
         amo.log(event, addon, addon.current_version)
 def test_hidden(self):
     version = Version.objects.create(addon=self.addon)
     amo.log(amo.LOG.COMMENT_VERSION, self.addon, version)
     res = self.get_response(addon=self.addon.id)
     key = RssKey.objects.get()
     res = self.get_response(privaterss=key.key)
     assert "<title>Comment on" not in res.content
Example #14
0
    def post_save(sender, instance, created, **kwargs):
        if kwargs.get("raw"):
            return

        if hasattr(instance, "user_responsible"):
            # user_responsible is not a field on the model, so it's not
            # persistent: it's just something the views will set temporarily
            # when manipulating a Review that indicates a real user made that
            # change.
            action = "New" if created else "Edited"
            if instance.reply_to:
                log.debug("%s reply to %s: %s" % (action, instance.reply_to_id, instance.pk))
            else:
                log.debug("%s review: %s" % (action, instance.pk))

            # For new reviews - not replies - and all edits (including replies
            # this time) by users we want to insert a new ActivityLog.
            new_review_or_edit = not instance.reply_to or not created
            if new_review_or_edit:
                action = amo.LOG.ADD_REVIEW if created else amo.LOG.EDIT_REVIEW
                amo.log(action, instance.addon, instance, user=instance.user_responsible)

            # For new reviews and new replies we want to send an email.
            if created:
                instance.send_notification_email()

        instance.refresh(update_denorm=created)
        if created:
            # Avoid slave lag with the delay.
            check_spam.apply_async(args=[instance.id], countdown=600)
Example #15
0
 def test_tag_no_match(self):
     addon = Addon.objects.get()
     tag = Tag.objects.create(tag_text='http://foo.com')
     amo.log(amo.LOG.ADD_TAG, addon, tag)
     log = ActivityLog.objects.get()
     text = jingo.env.from_string('<p>{{ log }}</p>').render({'log': log})
     # There should only be one a, the link to the addon, but no tag link.
     eq_(len(pq(text)('a')), 1)
Example #16
0
 def test_basic(self):
     a = Addon.objects.get()
     amo.log(amo.LOG['CREATE_ADDON'], a)
     entries = ActivityLog.objects.for_addons(a)
     eq_(len(entries), 1)
     eq_(entries[0].arguments[0], a)
     for x in ('Delicious Bookmarks', 'was created.'):
         assert x in unicode(entries[0])
Example #17
0
 def save(self, **kw):
     # Three different loggers? :(
     amo.log(amo.LOG.CHANGE_PASSWORD, user=self.user)
     log.info(u'User (%s) changed password with reset form' % self.user)
     log_cef('Password Changed', 5, self.request,
             username=self.user.username, signature='PASSWORDCHANGED',
             msg='User changed password')
     super(SetPasswordForm, self).save(**kw)
Example #18
0
    def save(self):
        desc = self.data.get('description')
        if desc and desc != unicode(self.instance.description):
            amo.log(amo.LOG.EDIT_DESCRIPTIONS, self.instance)
        if self.changed_data:
            amo.log(amo.LOG.EDIT_PROPERTIES, self.instance)

        super(AddonForm, self).save()
Example #19
0
    def save(self):
        addon = self.instance
        persona = addon.persona
        data = self.cleaned_data

        # Update Persona-specific data.
        persona_data = {
            'license': int(data['license']),
            'accentcolor': data['accentcolor'].lstrip('#'),
            'textcolor': data['textcolor'].lstrip('#'),
            'author': self.request.user.username,
            'display_username': self.request.user.name
        }
        changed = False
        for k, v in persona_data.iteritems():
            if v != getattr(persona, k):
                changed = True
                setattr(persona, k, v)
        if changed:
            persona.save()

        if self.changed_data:
            amo.log(amo.LOG.EDIT_PROPERTIES, addon)
        self.instance.modified = datetime.now()

        # Update Addon-specific data.
        changed = (
            set(self.old_tags) != data['tags'] or  # Check if tags changed.
            self.initial['slug'] != data['slug'] or  # Check if slug changed.
            transfield_changed('description', self.initial, data) or
            transfield_changed('name', self.initial, data))
        if changed:
            # Only save if addon data changed.
            super(EditThemeForm, self).save()

        # Update tags.
        tags_new = data['tags']
        tags_old = [slugify(t, spaces=True) for t in self.old_tags]
        # Add new tags.
        for t in set(tags_new) - set(tags_old):
            Tag(tag_text=t).save_tag(addon)
        # Remove old tags.
        for t in set(tags_old) - set(tags_new):
            Tag(tag_text=t).remove_tag(addon)

        # Update category.
        if data['category'].id != self.initial['category']:
            addon_cat = addon.addoncategory_set.all()[0]
            addon_cat.category = data['category']
            addon_cat.save()

        # Theme reupload.
        if not addon.is_pending():
            if data['header_hash'] or data['footer_hash']:
                save_theme_reupload.delay(
                    data['header_hash'], data['footer_hash'], addon)

        return data
Example #20
0
    def save(self):
        action = self.cleaned_data['action']
        comment = self.cleaned_data.get('comment')
        reject_reason = self.cleaned_data.get('reject_reason')
        theme = self.cleaned_data['theme']

        is_rereview = (
            theme.rereviewqueuetheme_set.exists() and
            theme.addon.status not in (amo.STATUS_PENDING,
                                       amo.STATUS_REVIEW_PENDING))

        theme_lock = ThemeLock.objects.get(theme=self.cleaned_data['theme'])

        mail_and_log = True
        if action == rvw.ACTION_APPROVE:
            if is_rereview:
                approve_rereview(theme)
            theme.addon.update(status=amo.STATUS_PUBLIC)
            theme.approve = datetime.datetime.now()
            theme.save()

        elif action in (rvw.ACTION_REJECT, rvw.ACTION_DUPLICATE):
            if is_rereview:
                reject_rereview(theme)
            else:
                theme.addon.update(status=amo.STATUS_REJECTED)

        elif action == rvw.ACTION_FLAG:
            if is_rereview:
                mail_and_log = False
            else:
                theme.addon.update(status=amo.STATUS_REVIEW_PENDING)

        elif action == rvw.ACTION_MOREINFO:
            if not is_rereview:
                theme.addon.update(status=amo.STATUS_REVIEW_PENDING)

        if mail_and_log:
            send_mail(self.cleaned_data, theme_lock)

            # Log.
            amo.log(amo.LOG.THEME_REVIEW, theme.addon, details={
                    'theme': theme.addon.name.localized_string,
                    'action': action,
                    'reject_reason': reject_reason,
                    'comment': comment}, user=theme_lock.reviewer)
            log.info('%sTheme %s (%s) - %s' % (
                '[Rereview] ' if is_rereview else '', theme.addon.name,
                theme.id, action))

        score = 0
        if action in (rvw.ACTION_REJECT, rvw.ACTION_DUPLICATE,
                      rvw.ACTION_APPROVE):
            score = ReviewerScore.award_points(
                theme_lock.reviewer, theme.addon, theme.addon.status)
        theme_lock.delete()

        return score
Example #21
0
 def test_addon_log_unlisted_addon(self):
     addon = Addon.objects.get()
     # Get the url before the addon is changed to unlisted.
     url_path = addon.get_url_path()
     addon.update(is_listed=False)
     amo.log(amo.LOG.CREATE_ADDON, (Addon, addon.id))
     entries = ActivityLog.objects.for_addons(addon)
     assert len(entries) == 1
     assert url_path not in unicode(entries[0])
Example #22
0
 def test_last_reviewed_version(self):
     today = datetime.today().date()
     self.new_file(name='addon123', version='1.0')
     v2 = self.new_file(name='addon123', version='2.0')['version']
     amo.log(amo.LOG.PRELIMINARY_VERSION, v2, v2.addon,
             user=UserProfile.objects.get(pk=999))
     self.new_file(name='addon123', version='3.0')
     row = self.Queue.objects.all()[0]
     assert row.review_date == today
     assert row.review_version_num == '2.0'
Example #23
0
 def create_version(self, license=None):
     data = self.cleaned_data
     v = Version(addon=self.addon, license=license,
                 version=data['version'],
                 releasenotes=data['release_notes'])
     v.save()
     amo.log(amo.LOG.ADD_VERSION, v.addon, v)
     self._save_apps(v)
     self._save_file(v)
     return v
Example #24
0
 def test_version_log_unlisted_addon(self):
     version = Version.objects.all()[0]
     # Get the url before the addon is changed to unlisted.
     url_path = version.get_url_path()
     self.make_addon_unlisted(version.addon)
     amo.log(amo.LOG.REJECT_VERSION, version.addon, version,
             user=self.request.user)
     entries = ActivityLog.objects.for_version(version)
     assert len(entries) == 1
     assert url_path not in unicode(entries[0])
Example #25
0
    def log_action(self, action):
        details = {'comments': self.data['comments'],
                   'reviewtype': self.review_type}
        if self.files:
            details['files'] = [f.id for f in self.files]
        if self.version:
            details['version'] = self.version.version

        amo.log(action, self.addon, self.version, user=self.user,
                created=datetime.datetime.now(), details=details)
Example #26
0
    def _save_apps(self, version):
        # clear old app versions
        version.apps.all().delete()
        apps = self.cleaned_data['apps']

        for app in apps:
            av = ApplicationsVersions.objects.create(
                version=version, min=app.min, max=app.max, application=app.id)
            amo.log(amo.LOG.ADD_APPVERSION,
                    version, version.addon, app.appdata.short, av)
Example #27
0
def migrate_preliminary_to_full(ids, **kwargs):
    log.info(
        '[%s@%s] Removing preliminary status from all addons starting w/ id: '
        '%s...' % (len(ids), migrate_preliminary_to_full.rate_limit, ids[0]))
    addons = Addon.unfiltered.filter(pk__in=ids)
    ids_to_email = []

    for addon in addons:
        # Add-on is preliminary reviewed, so make it full and experimental.
        files = File.objects.filter(version__addon=addon)
        if addon.status == amo.STATUS_LITE:
            files.filter(status=amo.STATUS_LITE).update(
                status=amo.STATUS_PUBLIC)
            files.filter(original_status=amo.STATUS_LITE).update(
                original_status=amo.STATUS_PUBLIC)
            addon.update(status=amo.STATUS_PUBLIC, is_experimental=True)
            add_note = True
        # Add-on is waiting for preliminary approval, so make it nominated and
        # experimental.
        elif addon.status == amo.STATUS_UNREVIEWED:
            addon.update(status=amo.STATUS_NOMINATED, is_experimental=True)
            add_note = True
        # Add-on is preliminary approved and nominated for full, so make it
        # full and not experimental.
        elif addon.status == amo.STATUS_LITE_AND_NOMINATED:
            files.filter(status=amo.STATUS_LITE).update(
                status=amo.STATUS_PUBLIC)
            files.filter(original_status=amo.STATUS_LITE).update(
                original_status=amo.STATUS_PUBLIC)
            addon.update(status=amo.STATUS_PUBLIC)
            add_note = True
        else:
            add_note = False
        # Clear up any stray preliminary reviewed versions.
        files.filter(status=amo.STATUS_LITE).update(
            status=amo.STATUS_DISABLED)
        files.filter(original_status=amo.STATUS_LITE).update(
            original_status=amo.STATUS_DISABLED)

        if add_note:
            should_email = not addon.is_disabled and addon.is_listed
            log_args = (addon, addon.latest_or_rejected_version) if (
                addon.latest_or_rejected_version) else (addon,)
            log_kwargs = {
                'user': UserProfile.objects.get(pk=settings.TASK_USER_ID),
                'details': {
                    'email': should_email,
                    'comments': 'Add-on migrated from preliminary reviewed,'
                                'take care when reviewing.'}}
            amo.log(
                amo.LOG.PRELIMINARY_ADDON_MIGRATED, *log_args, **log_kwargs)
            if should_email:
                ids_to_email.append('%s' % addon.id)
    log.info('Add-ons that need to be email notified: [%s]' % (
        ','.join(ids_to_email),))
Example #28
0
 def update_version(self, license=None):
     data = self.cleaned_data
     v = self.version
     v.license = license
     v.version = data['version']
     v.releasenotes = data['release_notes']
     v.save()
     amo.log(amo.LOG.EDIT_VERSION, v.addon, v)
     self._save_apps(v)
     self._save_file(v)
     return v
Example #29
0
    def save(self, commit=True):
        ob = super(PolicyForm, self).save(commit)
        for k, field in (('has_eula', 'eula'),
                         ('has_priv', 'privacy_policy')):
            if not self.cleaned_data[k]:
                delete_translation(self.instance, field)

        if 'privacy_policy' in self.changed_data:
            amo.log(amo.LOG.CHANGE_POLICY, self.addon, self.instance)

        return ob
Example #30
0
 def delete(self, hard=False):
     log.info(u'Version deleted: %r (%s)' % (self, self.id))
     amo.log(amo.LOG.DELETE_VERSION, self.addon, str(self.version))
     if hard:
         super(Version, self).delete()
     else:
         # By default we soft delete so we can keep the files for comparison
         # and a record of the version number.
         self.files.update(status=amo.STATUS_DISABLED)
         self.deleted = True
         self.save()
Example #31
0
 def test_not_review_count(self):
     amo.log(amo.LOG['EDIT_VERSION'], Addon.objects.get())
     assert len(ActivityLog.objects.monthly_reviews()) == 0
Example #32
0
 def add_approve_logs(self, count):
     for x in range(0, count):
         amo.log(amo.LOG['APPROVE_VERSION'], Addon.objects.get())
Example #33
0
    def from_upload(cls,
                    upload,
                    addon,
                    platforms,
                    channel,
                    send_signal=True,
                    source=None,
                    is_beta=False):
        from olympia.addons.models import AddonFeatureCompatibility

        data = utils.parse_addon(upload, addon)
        try:
            license = addon.versions.latest().license_id
        except Version.DoesNotExist:
            license = None
        version = cls.objects.create(
            addon=addon,
            version=data['version'],
            license_id=license,
            source=source,
            channel=channel,
        )
        log.info('New version: %r (%s) from %r' %
                 (version, version.id, upload))
        amo.log(amo.LOG.ADD_VERSION, version, addon)
        # Update the add-on e10s compatibility since we're creating a new
        # version that may change that.
        e10s_compatibility = data.get('e10s_compatibility')
        if e10s_compatibility is not None:
            feature_compatibility = (
                AddonFeatureCompatibility.objects.get_or_create(
                    addon=addon)[0])
            feature_compatibility.update(e10s=e10s_compatibility)

        compatible_apps = {}
        for app in data.get('apps', []):
            compatible_apps[app.appdata] = ApplicationsVersions(
                version=version, min=app.min, max=app.max, application=app.id)
            compatible_apps[app.appdata].save()

        # See #2828: sometimes when we generate the filename(s) below, in
        # File.from_upload(), cache-machine is confused and has trouble
        # fetching the ApplicationsVersions that were just created. To work
        # around this we pre-generate version.compatible_apps and avoid the
        # queries completely.
        version.compatible_apps = compatible_apps

        if addon.type == amo.ADDON_SEARCH:
            # Search extensions are always for all platforms.
            platforms = [amo.PLATFORM_ALL.id]
        else:
            platforms = cls._make_safe_platform_files(platforms)

        for platform in platforms:
            File.from_upload(upload,
                             version,
                             platform,
                             parse_data=data,
                             is_beta=is_beta)

        version.disable_old_files()
        # After the upload has been copied to all platforms, remove the upload.
        storage.delete(upload.path)
        if send_signal:
            version_uploaded.send(sender=version)

        # Track the time it took from first upload through validation
        # (and whatever else) until a version was created.
        upload_start = utc_millesecs_from_epoch(upload.created)
        now = datetime.datetime.now()
        now_ts = utc_millesecs_from_epoch(now)
        upload_time = now_ts - upload_start

        log.info('Time for version {version} creation from upload: {delta}; '
                 'created={created}; now={now}'.format(delta=upload_time,
                                                       version=version,
                                                       created=upload.created,
                                                       now=now))
        statsd.timing('devhub.version_created_from_upload', upload_time)

        return version
Example #34
0
 def test_review_count(self):
     amo.log(amo.LOG['APPROVE_VERSION'], Addon.objects.get())
     result = ActivityLog.objects.monthly_reviews()
     assert len(result) == 1
     assert result[0]['approval_count'] == 1
     assert result[0]['user'] == self.user.pk
Example #35
0
 def log(self, comments, action, created):
     details = {'comments': comments}
     details['version'] = self.addon.current_version.version
     kwargs = {'user': self.user, 'created': created, 'details': details}
     return amo.log(action, self.addon, self.addon.current_version,
                    **kwargs)
Example #36
0
 def add_addon(self, addon):
     "Adds an addon to the collection."
     CollectionAddon.objects.get_or_create(addon=addon, collection=self)
     if self.listed:
         amo.log(amo.LOG.ADD_TO_COLLECTION, addon, self)
     self.save()  # To invalidate Collection.
Example #37
0
 def test_no_user(self):
     amo.set_user(None)
     count = ActivityLog.objects.count()
     amo.log(amo.LOG.CUSTOM_TEXT, 'hi')
     assert count == ActivityLog.objects.count()
Example #38
0
 def test_no_arguments(self):
     amo.log(amo.LOG['CUSTOM_HTML'])
     entry = ActivityLog.objects.get()
     assert entry.arguments == []
Example #39
0
 def log_status(self, num):
     for i in xrange(num):
         amo.log(amo.LOG.USER_DISABLE, self.addon)
Example #40
0
 def test_addon_log(self):
     addon = Addon.objects.get()
     amo.log(amo.LOG.CREATE_ADDON, (Addon, addon.id))
     entries = ActivityLog.objects.for_addons(addon)
     assert len(entries) == 1
     assert addon.get_url_path() in unicode(entries[0])
Example #41
0
 def log_collection(self, num, prefix='foo'):
     for i in xrange(num):
         c = Collection.objects.create(name='%s %d' % (prefix, i))
         amo.log(amo.LOG.ADD_TO_COLLECTION, self.addon, c)
Example #42
0
 def log_tag(self, num, prefix='foo'):
     for i in xrange(num):
         t = Tag.objects.create(tag_text='%s %d' % (prefix, i))
         amo.log(amo.LOG.ADD_TAG, self.addon, t)
Example #43
0
 def log_review(self, num):
     r = Review(addon=self.addon)
     for i in xrange(num):
         amo.log(amo.LOG.ADD_REVIEW, self.addon, r)
Example #44
0
 def test_user_log(self):
     request = self.request
     amo.log(amo.LOG['CUSTOM_TEXT'], 'hi there')
     entries = ActivityLog.objects.for_user(request.user)
     assert len(entries) == 1
Example #45
0
 def test_log_not_admin(self):
     amo.log(amo.LOG['EDIT_VERSION'], Addon.objects.get())
     assert len(ActivityLog.objects.admin_events()) == 0
     assert len(ActivityLog.objects.for_developer()) == 1
Example #46
0
 def test_output(self):
     amo.log(amo.LOG['CUSTOM_TEXT'], 'hi there')
     entry = ActivityLog.objects.get()
     assert unicode(entry) == 'hi there'
Example #47
0
 def test_log_admin(self):
     amo.log(amo.LOG['OBJECT_EDITED'], Addon.objects.get())
     assert len(ActivityLog.objects.admin_events()) == 1
     assert len(ActivityLog.objects.for_developer()) == 0
Example #48
0
def notify_compatibility_chunk(users, job, data, **kw):
    log.info('[%s@%s] Sending notification mail for job %s.' %
             (len(users), notify_compatibility.rate_limit, job.pk))
    set_user(get_task_user())
    dry_run = data['preview_only']
    app_id = job.target_version.application
    stats = collections.defaultdict(int)
    stats['processed'] = 0
    stats['is_dry_run'] = int(dry_run)

    for user in users:
        stats['processed'] += 1

        try:
            for a in chain(user.passing_addons, user.failing_addons):
                try:
                    results = job.result_set.filter(file__version__addon=a)

                    a.links = [
                        absolutify(
                            reverse('devhub.bulk_compat_result',
                                    args=[a.slug, r.pk])) for r in results
                    ]

                    v = a.current_version or a.latest_version
                    a.compat_link = absolutify(
                        reverse('devhub.versions.edit', args=[a.pk, v.pk]))
                except:
                    task_error = sys.exc_info()
                    log.error(
                        u'Bulk validation email error for user %s, '
                        u'addon %s: %s: %s' %
                        (user.email, a.slug, task_error[0], task_error[1]),
                        exc_info=False)

            context = Context({
                'APPLICATION':
                unicode(amo.APP_IDS[job.application].pretty),
                'VERSION':
                job.target_version.version,
                'PASSING_ADDONS':
                user.passing_addons,
                'FAILING_ADDONS':
                user.failing_addons,
            })

            log.info(
                u'Emailing %s%s for %d addons about '
                'bulk validation job %s' %
                (user.email, ' [PREVIEW]' if dry_run else '',
                 len(user.passing_addons) + len(user.failing_addons), job.pk))
            args = (Template(data['subject']).render(context),
                    Template(data['text']).render(context))
            kwargs = dict(from_email=settings.DEFAULT_FROM_EMAIL,
                          recipient_list=[user.email])
            if dry_run:
                job.preview_notify_mail(*args, **kwargs)
            else:
                stats['author_emailed'] += 1
                send_mail(*args, **kwargs)
                amo.log(amo.LOG.BULK_VALIDATION_USER_EMAILED,
                        user,
                        details={
                            'passing': [a.id for a in user.passing_addons],
                            'failing': [a.id for a in user.failing_addons],
                            'target': job.target_version.version,
                            'application': app_id
                        })
        except:
            task_error = sys.exc_info()
            log.error(u'Bulk validation email error for user %s: %s: %s' %
                      (user.email, task_error[0], task_error[1]),
                      exc_info=False)

    log.info('[%s@%s] bulk email stats for job %s: {%s}' %
             (len(users), notify_compatibility.rate_limit, job.pk, ', '.join(
                 '%s: %s' % (k, stats[k]) for k in sorted(stats.keys()))))
Example #49
0
 def test_not_total(self):
     amo.log(amo.LOG['EDIT_VERSION'], Addon.objects.get())
     assert len(ActivityLog.objects.total_reviews()) == 0
Example #50
0
 def remove_addon(self, addon):
     CollectionAddon.objects.filter(addon=addon, collection=self).delete()
     if self.listed:
         amo.log(amo.LOG.REMOVE_FROM_COLLECTION, addon, self)
     self.save()  # To invalidate Collection.
Example #51
0
 def test_review_last_month(self):
     log = amo.log(amo.LOG['APPROVE_VERSION'], Addon.objects.get())
     log.update(created=self.lm)
     assert len(ActivityLog.objects.monthly_reviews()) == 0
Example #52
0
 def log_creates(self, num, addon=None):
     if not addon:
         addon = self.addon
     for i in xrange(num):
         amo.log(amo.LOG.CREATE_ADDON, addon)
Example #53
0
 def remove_tag(self, addon):
     tag, created = Tag.objects.get_or_create(tag_text=self.tag_text)
     for addon_tag in AddonTag.objects.filter(addon=addon, tag=tag):
         addon_tag.delete()
     amo.log(amo.LOG.REMOVE_TAG, tag, addon)
Example #54
0
    def log_updates(self, num, version_string='1'):
        version = Version.objects.create(version=version_string,
                                         addon=self.addon)

        for i in xrange(num):
            amo.log(amo.LOG.ADD_VERSION, self.addon, version)
Example #55
0
 def save_tag(self, addon):
     tag, created = Tag.objects.get_or_create(tag_text=self.tag_text)
     AddonTag.objects.get_or_create(addon=addon, tag=tag)
     amo.log(amo.LOG.ADD_TAG, tag, addon)
     return tag