|
1 from cm.models import Activity, Text |
|
2 from django.contrib.auth.models import User |
|
3 from django.db.models import signals |
|
4 from datetime import datetime, timedelta |
|
5 from time import mktime |
|
6 import django.dispatch |
|
7 import logging |
|
8 |
|
9 def register_activity(request, type, text=None, comment=None, user=None, text_version=None): |
|
10 signal_activity.send(sender=text, request=request, type=type, comment=comment, user=user, text_version=text_version) |
|
11 |
|
12 # activity signal |
|
13 |
|
14 signal_activity = django.dispatch.Signal(providing_args=["request", "type", "comment"]) |
|
15 |
|
16 def _save_activity(sender, **kwargs): |
|
17 request = kwargs['request'] |
|
18 type = kwargs['type'] |
|
19 comment = kwargs['comment'] |
|
20 user = kwargs['user'] |
|
21 |
|
22 text = sender |
|
23 text_version = kwargs.get('text_version', None) |
|
24 if not text_version and text: |
|
25 text_version = text.last_text_version |
|
26 |
|
27 if request.user.is_anonymous(): |
|
28 originator_user = None |
|
29 else: |
|
30 originator_user = request.user |
|
31 ip = request.META['REMOTE_ADDR'] |
|
32 Activity.objects.create(text=text, user=user, text_version=text_version, comment=comment, type=type, ip=ip, originator_user=originator_user) |
|
33 |
|
34 def connect_all(): |
|
35 signal_activity.connect(_save_activity) |
|
36 |
|
37 connect_all() |
|
38 |
|
39 # activity processing |
|
40 |
|
41 def seconds(t_delta): |
|
42 return abs(t_delta.seconds + t_delta.days * 86400) |
|
43 |
|
44 VISIT_DURATION = timedelta(seconds=30 * 60) # 30 minutes |
|
45 |
|
46 def get_activity(text='all', user='all', reference_date=None, nb_slots=31, slot_timedelta=timedelta(days=1), action="all", kind=''): |
|
47 """ |
|
48 text : text: specific text |
|
49 'all': all texts |
|
50 user : user: specific user |
|
51 None: anonymous users |
|
52 'all': all users |
|
53 """ |
|
54 # calc activities used |
|
55 if not reference_date: |
|
56 reference_date = datetime.now() |
|
57 from_date = reference_date - slot_timedelta * nb_slots |
|
58 activities = Activity.objects.filter(created__gt=from_date) |
|
59 if action != 'all': |
|
60 activities = activities.filter(type=action) |
|
61 if text != 'all': |
|
62 activities = activities.filter(text=text) |
|
63 if user != 'all': |
|
64 activities = activities.filter(originator_user=user) |
|
65 activities = activities.order_by('created').only('created', 'originator_user', 'text') |
|
66 #print 'got %d activities' % len(activities), [a.created for a in activities] |
|
67 |
|
68 if kind == 'raw': |
|
69 visits = activities |
|
70 else: |
|
71 # calc visits |
|
72 visits = [] |
|
73 if activities: |
|
74 for i in range(len(activities)): |
|
75 activity = activities[i] |
|
76 found = False |
|
77 for j in range(i - 1, -1, -1): |
|
78 prev_act = activities[j] |
|
79 if activity.created > prev_act.created + VISIT_DURATION: # out of session bounds: add act |
|
80 visits.append(activity) |
|
81 found = True |
|
82 break |
|
83 else: |
|
84 if not activity.is_same_user(prev_act): # another user: just ignore prev_act |
|
85 continue |
|
86 else: # in session: do not count act |
|
87 found = True |
|
88 break |
|
89 if not found: |
|
90 visits.append(activity) |
|
91 #print 'got %d visits' % len(visits), [(v.created, v.user) for v in visits] |
|
92 |
|
93 # hist by slot_timedelta |
|
94 slots = [seconds(from_date - v.created) // seconds(slot_timedelta) for v in visits] |
|
95 |
|
96 # TODO: could be more efficient... |
|
97 res = [slots.count(index) for index in range(nb_slots)] |
|
98 return res |
|
99 |
|
100 |