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))
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
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)
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])
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.
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
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
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
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)
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)
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])
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)
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()
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
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
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])
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'
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
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])
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)
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)
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),))
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
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
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()
def test_not_review_count(self): amo.log(amo.LOG['EDIT_VERSION'], Addon.objects.get()) assert len(ActivityLog.objects.monthly_reviews()) == 0
def add_approve_logs(self, count): for x in range(0, count): amo.log(amo.LOG['APPROVE_VERSION'], Addon.objects.get())
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
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
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)
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.
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()
def test_no_arguments(self): amo.log(amo.LOG['CUSTOM_HTML']) entry = ActivityLog.objects.get() assert entry.arguments == []
def log_status(self, num): for i in xrange(num): amo.log(amo.LOG.USER_DISABLE, self.addon)
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])
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)
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)
def log_review(self, num): r = Review(addon=self.addon) for i in xrange(num): amo.log(amo.LOG.ADD_REVIEW, self.addon, r)
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
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
def test_output(self): amo.log(amo.LOG['CUSTOM_TEXT'], 'hi there') entry = ActivityLog.objects.get() assert unicode(entry) == 'hi there'
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
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()))))
def test_not_total(self): amo.log(amo.LOG['EDIT_VERSION'], Addon.objects.get()) assert len(ActivityLog.objects.total_reviews()) == 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.
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
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)
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)
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)
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