bug 592591, addonlogs->activity_log importer
This commit is contained in:
Родитель
96ee20f045
Коммит
d6f53ca38f
|
@ -26,6 +26,8 @@ def add_redis(f):
|
|||
|
||||
try:
|
||||
import redisutils
|
||||
# TODO(davedash): This should be our persistence layer when that's
|
||||
# set in production.
|
||||
redis = redisutils.connections['master']
|
||||
pipe = redis.pipeline(transaction=True)
|
||||
ret = f(cls, redis, pipe, *args, **kw)
|
||||
|
@ -77,3 +79,19 @@ class ReverseNameLookup(object):
|
|||
for hash in hashes:
|
||||
pipe.delete('%s:%s' % (cls.prefix, hash))
|
||||
pipe.delete('%s:%d' % (cls.prefix, addon_id))
|
||||
|
||||
|
||||
#TODO(davedash): remove after remora
|
||||
class ActivityLogMigrationTracker(object):
|
||||
"""This tracks what id of the addonlog we're on."""
|
||||
key = 'amo:activitylog:migration'
|
||||
|
||||
@add_redis
|
||||
def __init__(self, redis, pipe):
|
||||
self.redis = redis
|
||||
|
||||
def get(self):
|
||||
return self.redis.get(self.key)
|
||||
|
||||
def set(self, value):
|
||||
return self.redis.set(self.key, value)
|
||||
|
|
|
@ -4,16 +4,21 @@ from subprocess import Popen, PIPE
|
|||
|
||||
from django.conf import settings
|
||||
|
||||
from celeryutils import task
|
||||
import cronjobs
|
||||
import commonware.log
|
||||
|
||||
import amo
|
||||
from amo.utils import chunked
|
||||
from addons.utils import ActivityLogMigrationTracker
|
||||
from bandwagon.models import Collection
|
||||
from cake.models import Session
|
||||
from devhub.models import ActivityLog
|
||||
from files.models import TestResult, TestResultCache
|
||||
from devhub.models import ActivityLog, LegacyAddonLog
|
||||
from files.models import TestResultCache
|
||||
from sharing import SERVICES_LIST
|
||||
from stats.models import AddonShareCount, Contribution
|
||||
from users.models import UserProfile
|
||||
from versions.models import Version
|
||||
|
||||
log = commonware.log.getLogger('z.cron')
|
||||
|
||||
|
@ -36,14 +41,6 @@ def gc(test_result=True):
|
|||
AddonShareCount.objects.exclude(
|
||||
service__in=[s.shortname for s in SERVICES_LIST]).delete()
|
||||
|
||||
# XXX(davedash): I can't seem to run this during testing without triggering
|
||||
# an error: "test_remora.nose_c doesn't exist"
|
||||
# for some reason a ForeignKey attaches itself to TestResult during testing
|
||||
# I suspect it's the name, but I don't have time to really figure this out.
|
||||
if test_result:
|
||||
log.debug('Cleaning up test results.')
|
||||
TestResult.objects.filter(created__lt=one_hour_ago).delete()
|
||||
|
||||
log.debug('Cleaning up test results cache.')
|
||||
TestResultCache.objects.filter(date__lt=one_hour_ago).delete()
|
||||
|
||||
|
@ -98,3 +95,55 @@ def gc(test_result=True):
|
|||
log.debug('Cleaning up anonymous collections.')
|
||||
Collection.objects.filter(created__lt=two_days_ago,
|
||||
type=amo.COLLECTION_ANONYMOUS).delete()
|
||||
|
||||
|
||||
@cronjobs.register
|
||||
def migrate_logs():
|
||||
# Get the highest id we've looked at.
|
||||
a = ActivityLogMigrationTracker()
|
||||
id = a.get() or 0
|
||||
|
||||
items = LegacyAddonLog.objects.filter(pk__gt=id).values_list(
|
||||
'id', flat=True)
|
||||
for chunk in chunked(items, 100):
|
||||
_migrate_logs.delay(chunk)
|
||||
a.set(chunk[-1])
|
||||
|
||||
|
||||
@task
|
||||
def _migrate_logs(items, **kw):
|
||||
print 'Processing: %d..%d' % (items[0], items[-1])
|
||||
for item in LegacyAddonLog.objects.filter(pk__in=items):
|
||||
kw = dict(user=item.user, created=item.created)
|
||||
if item.type not in amo.LOG_KEEP:
|
||||
continue
|
||||
elif item.type in [amo.LOG.CREATE_ADDON.id, amo.LOG.SET_INACTIVE.id,
|
||||
amo.LOG.UNSET_INACTIVE.id,
|
||||
amo.LOG.SET_PUBLIC_STATS.id,
|
||||
amo.LOG.UNSET_PUBLIC_STATS.id,
|
||||
amo.LOG.ADD_RECOMMENDED.id,
|
||||
amo.LOG.REMOVE_RECOMMENDED.id]:
|
||||
amo.log(amo.LOG_BY_ID[item.type], item.addon, **kw)
|
||||
|
||||
elif item.type in [amo.LOG.ADD_USER_WITH_ROLE.id,
|
||||
amo.LOG.REMOVE_USER_WITH_ROLE.id]:
|
||||
amo.log(amo.LOG_BY_ID[item.type], item.addon,
|
||||
(UserProfile, item.object1_id),
|
||||
unicode(dict(amo.AUTHOR_CHOICES)[item.object2_id]), **kw)
|
||||
elif item.type == amo.LOG.CHANGE_STATUS.id:
|
||||
amo.log(amo.LOG_BY_ID[item.type], item.addon,
|
||||
unicode(amo.STATUS_CHOICES[item.object1_id]), **kw)
|
||||
# Items that require only a version
|
||||
elif item.type in [amo.LOG.ADD_VERSION.id,
|
||||
amo.LOG.APPROVE_VERSION.id,
|
||||
amo.LOG.RETAIN_VERSION.id,
|
||||
amo.LOG.ESCALATE_VERSION.id,
|
||||
amo.LOG.REQUEST_VERSION.id]:
|
||||
try:
|
||||
v = Version.objects.get(pk=item.object1_id)
|
||||
amo.log(amo.LOG_BY_ID[item.type], item.addon, v, **kw)
|
||||
except Version.DoesNotExist:
|
||||
print ('Version %d does not exist. No worries, it happens.'
|
||||
% item.object1_id)
|
||||
elif item.type == amo.LOG.DELETE_VERSION.id:
|
||||
amo.log(amo.LOG_BY_ID[item.type], item.addon, item.name1, **kw)
|
||||
|
|
|
@ -51,20 +51,20 @@ class EDIT_CONTRIBUTIONS:
|
|||
|
||||
class USER_DISABLE:
|
||||
id = 8
|
||||
format = _(u'{user.name} disabled addon {addon}')
|
||||
format = _(u'{addon} set inactive.')
|
||||
keep = True
|
||||
|
||||
|
||||
class USER_ENABLE:
|
||||
id = 9
|
||||
format = _(u'{user.name} enabled addon {addon}')
|
||||
format = _(u'{addon} activated.')
|
||||
keep = True
|
||||
|
||||
|
||||
# TODO(davedash): Log these types when pages are present
|
||||
class SET_PUBLIC_STATS:
|
||||
id = 10
|
||||
format = _(u'{user.name} set stats public for {addon}')
|
||||
format = _(u'Stats set public for {addon}.')
|
||||
keep = True
|
||||
|
||||
|
||||
|
@ -79,7 +79,7 @@ class UNSET_PUBLIC_STATS:
|
|||
class CHANGE_STATUS:
|
||||
id = 12
|
||||
# L10n: {0} is the status
|
||||
format = _(u'{user.name} changed {addon} status to {0}')
|
||||
format = _(u'{addon} status changed to {0}')
|
||||
keep = True
|
||||
|
||||
|
||||
|
@ -114,7 +114,9 @@ class EDIT_VERSION:
|
|||
|
||||
class DELETE_VERSION:
|
||||
id = 18
|
||||
format = _(u'{user.name} deleted version {0} from {addon}')
|
||||
# Note, {0} is a string not a version since the version is deleted.
|
||||
# L10n: {0} is the version number
|
||||
format = _(u'Version {0} deleted from {addon}.')
|
||||
keep = True
|
||||
|
||||
|
||||
|
@ -137,14 +139,14 @@ class DELETE_FILE_FROM_VERSION:
|
|||
# TODO(davedash): When editor tools exist
|
||||
class APPROVE_VERSION:
|
||||
id = 21
|
||||
format = _(u'Version {0.version} of {addon} approved')
|
||||
format = _(u'{addon} {version} approved.')
|
||||
keep = True
|
||||
|
||||
|
||||
# TODO(davedash): When editor tools exist
|
||||
class RETAIN_VERSION:
|
||||
id = 22
|
||||
format = _(u'{user.name} retained version {0.version} of {addon}')
|
||||
format = _(u'{addon} {version} retained.')
|
||||
keep = True
|
||||
|
||||
|
||||
|
@ -152,7 +154,7 @@ class RETAIN_VERSION:
|
|||
class ESCALATE_VERSION:
|
||||
id = 23
|
||||
# L10n: {0.version} is the version of an addon.
|
||||
format = _(u'{user.name} escalated review of {addon} {0.version}')
|
||||
format = _(u'Review escalated for {addon} {version}.')
|
||||
keep = True
|
||||
|
||||
|
||||
|
@ -160,8 +162,7 @@ class ESCALATE_VERSION:
|
|||
class REQUEST_VERSION:
|
||||
id = 24
|
||||
# L10n: {0.version} is the version of an addon.
|
||||
format = _(u'{user.name} requested more information regarding '
|
||||
'{addon} {0.version}')
|
||||
format = _(u'More information regarding {addon} {version} was requested.')
|
||||
keep = True
|
||||
|
||||
|
||||
|
@ -205,13 +206,13 @@ class REMOVE_RECOMMENDED_CATEGORY:
|
|||
|
||||
class ADD_RECOMMENDED:
|
||||
id = 33
|
||||
format = _(u'{addon} is now featured')
|
||||
format = _(u'{addon} is now featured.')
|
||||
keep = True
|
||||
|
||||
|
||||
class REMOVE_RECOMMENDED:
|
||||
id = 34
|
||||
format = _(u'{addon} is no longer featured')
|
||||
format = _(u'{addon} is no longer featured.')
|
||||
keep = True
|
||||
|
||||
|
||||
|
@ -265,10 +266,10 @@ LOGS = (CREATE_ADDON, EDIT_PROPERTIES, EDIT_DESCRIPTIONS, EDIT_CATEGORIES,
|
|||
)
|
||||
LOG_BY_ID = dict((l.id, l) for l in LOGS)
|
||||
LOG = AttributeDict((l.__name__, l) for l in LOGS)
|
||||
LOG_KEEP = (l.id for l in LOGS if hasattr(l, 'keep'))
|
||||
LOG_KEEP = [l.id for l in LOGS if hasattr(l, 'keep')]
|
||||
|
||||
|
||||
def log(action, *args):
|
||||
def log(action, *args, **kw):
|
||||
"""
|
||||
e.g. amo.log(amo.LOG.CREATE_ADDON, []),
|
||||
amo.log(amo.LOG.ADD_FILE_TO_VERSION, file, version)
|
||||
|
@ -278,7 +279,7 @@ def log(action, *args):
|
|||
from users.models import UserProfile
|
||||
from amo import get_user, logger_log
|
||||
|
||||
user = get_user()
|
||||
user = kw.get('user', get_user())
|
||||
|
||||
if not user:
|
||||
logger_log.warning('Activity log called with no user: %s' % action.id)
|
||||
|
@ -287,6 +288,10 @@ def log(action, *args):
|
|||
al = ActivityLog(user=user, action=action.id)
|
||||
al.arguments = args
|
||||
al.save()
|
||||
if 'created' in kw:
|
||||
al.created = kw['created']
|
||||
# Double save necessary since django resets the created date on save.
|
||||
al.save()
|
||||
|
||||
for arg in args:
|
||||
if isinstance(arg, Addon):
|
||||
|
|
|
@ -234,6 +234,7 @@ class LegacyAddonLog(models.Model):
|
|||
|
||||
class Meta:
|
||||
db_table = 'addonlogs'
|
||||
ordering = ('id',)
|
||||
|
||||
|
||||
class SubmitStep(models.Model):
|
||||
|
|
Загрузка…
Ссылка в новой задаче