src/cm/activity.py
author Simon Descarpentries <sid@sopinspace.com>
Mon, 21 Oct 2013 16:37:07 +0200
changeset 553 bf26fb47a14c
parent 344 9787360440db
child 590 e103299bccc0
permissions -rw-r--r--
To allow scrolling in Safari mobile, we set the content of text_view_comments frame in a jQuery UI layout. So the automated scrolling operations in c_sync.js must be adjustable to the right part to scroll. Also, if a comment have to be shown outside of the current viewport, we scroll the correct part to that viewport and then set the comment top Y offset to juste what it needs to avoid the "Add comment" button after scrolling operation. If not in Safari mobile, we add an offset here to avoid comment to display under the "Add comment" button.
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