src/cm/activity.py
author Production Moz <dev@sopinspace.com>
Tue, 31 May 2011 17:52:28 +0200
changeset 344 9787360440db
parent 282 b5deb8e32219
child 590 e103299bccc0
permissions -rw-r--r--
memoize get_activity
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     1
from cm.models import Activity, Text
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     2
from django.contrib.auth.models import User
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     3
from django.db.models import signals
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     4
from datetime import datetime, timedelta
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     5
from time import mktime
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     6
import django.dispatch
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     7
import logging
282
b5deb8e32219 add STORE_ACTIVITY_IP parameter to avoid storing ips for activities.
raph
parents: 0
diff changeset
     8
from cm.cm_settings import STORE_ACTIVITY_IP
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     9
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    10
def register_activity(request, type, text=None, comment=None, user=None, text_version=None):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    11
    signal_activity.send(sender=text, request=request, type=type, comment=comment, user=user, text_version=text_version)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    12
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    13
# activity signal
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    14
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    15
signal_activity = django.dispatch.Signal(providing_args=["request", "type", "comment"])
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    16
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    17
def _save_activity(sender, **kwargs):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    18
    request = kwargs['request']
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    19
    type = kwargs['type']
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    20
    comment = kwargs['comment']
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    21
    user = kwargs['user']
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    22
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    23
    text = sender
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    24
    text_version = kwargs.get('text_version', None)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    25
    if not text_version and text:
282
b5deb8e32219 add STORE_ACTIVITY_IP parameter to avoid storing ips for activities.
raph
parents: 0
diff changeset
    26
        text_version = text.last_text_version
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    27
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    28
    if request.user.is_anonymous():
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    29
        originator_user = None
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    30
    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    31
        originator_user = request.user
282
b5deb8e32219 add STORE_ACTIVITY_IP parameter to avoid storing ips for activities.
raph
parents: 0
diff changeset
    32
    
b5deb8e32219 add STORE_ACTIVITY_IP parameter to avoid storing ips for activities.
raph
parents: 0
diff changeset
    33
    if STORE_ACTIVITY_IP:
b5deb8e32219 add STORE_ACTIVITY_IP parameter to avoid storing ips for activities.
raph
parents: 0
diff changeset
    34
        ip = request.META['REMOTE_ADDR']
b5deb8e32219 add STORE_ACTIVITY_IP parameter to avoid storing ips for activities.
raph
parents: 0
diff changeset
    35
    else:
b5deb8e32219 add STORE_ACTIVITY_IP parameter to avoid storing ips for activities.
raph
parents: 0
diff changeset
    36
        ip = None
b5deb8e32219 add STORE_ACTIVITY_IP parameter to avoid storing ips for activities.
raph
parents: 0
diff changeset
    37
    
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    38
    Activity.objects.create(text=text, user=user, text_version=text_version, comment=comment, type=type, ip=ip, originator_user=originator_user)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    39
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    40
def connect_all():
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    41
    signal_activity.connect(_save_activity)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    42
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    43
connect_all()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    44
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    45
# activity processing
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    46
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    47
def seconds(t_delta):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    48
    return abs(t_delta.seconds + t_delta.days * 86400)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    49
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    50
VISIT_DURATION = timedelta(seconds=30 * 60) # 30 minutes
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    51
344
9787360440db memoize get_activity
Production Moz <dev@sopinspace.com>
parents: 282
diff changeset
    52
from cm.utils.cache import memoize, dj_memoize
9787360440db memoize get_activity
Production Moz <dev@sopinspace.com>
parents: 282
diff changeset
    53
9787360440db memoize get_activity
Production Moz <dev@sopinspace.com>
parents: 282
diff changeset
    54
@dj_memoize
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    55
def get_activity(text='all', user='all', reference_date=None, nb_slots=31, slot_timedelta=timedelta(days=1), action="all", kind=''):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    56
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    57
    text : text: specific text
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    58
           'all': all texts
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    59
    user : user: specific user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    60
           None: anonymous users
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    61
           'all': all users
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    62
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    63
    # calc activities used    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    64
    if not reference_date:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    65
        reference_date = datetime.now()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    66
    from_date = reference_date - slot_timedelta * nb_slots
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    67
    activities = Activity.objects.filter(created__gt=from_date)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    68
    if action != 'all':
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    69
        activities = activities.filter(type=action)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    70
    if text != 'all':
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    71
        activities = activities.filter(text=text)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    72
    if user != 'all':
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    73
        activities = activities.filter(originator_user=user)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    74
    activities = activities.order_by('created').only('created', 'originator_user', 'text')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    75
    #print 'got %d activities' % len(activities), [a.created for a in activities]
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    76
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    77
    if kind == 'raw':
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    78
        visits = activities
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    79
    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    80
        # calc visits
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    81
        visits = []
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    82
        if activities:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    83
            for i in range(len(activities)):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    84
                activity = activities[i]
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    85
                found = False
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    86
                for j in range(i - 1, -1, -1):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    87
                    prev_act = activities[j]                
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    88
                    if activity.created > prev_act.created + VISIT_DURATION: # out of session bounds: add act
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    89
                        visits.append(activity)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    90
                        found = True
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    91
                        break
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    92
                    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    93
                        if not activity.is_same_user(prev_act): # another user: just ignore prev_act
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    94
                            continue
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    95
                        else: # in session: do not count act
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    96
                            found = True
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    97
                            break
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    98
                if not found:                    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    99
                    visits.append(activity)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   100
        #print 'got %d visits' % len(visits), [(v.created, v.user) for v in visits]
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   101
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   102
    # hist by slot_timedelta
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   103
    slots = [seconds(from_date - v.created) // seconds(slot_timedelta) for v in visits]
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   104
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   105
    # TODO: could be more efficient...
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   106
    res = [slots.count(index) for index in range(nb_slots)]
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   107
    return res
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   108
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   109