Explorar o código

Implemented like system

Denis Merigoux %!s(int64=9) %!d(string=hai) anos
pai
achega
c4e0a876af

+ 5 - 1
counter/models.py

@@ -42,7 +42,7 @@ class Reset(models.Model):
42 42
                                          locale='fr'), self.reason)
43 43
         else:
44 44
             return '%s à %s : %s (%s)' % (self.who, self.counter,
45
-                                           format_timedelta(
45
+                                          format_timedelta(
46 46
                                               datetime.now() -
47 47
                                               self.timestamp.replace(
48 48
                                                   tzinfo=None),
@@ -61,3 +61,7 @@ class Like(models.Model):
61 61
     class Meta:
62 62
         verbose_name = 'like'
63 63
         verbose_name_plural = 'likes'
64
+        unique_together = ('liker', 'reset')
65
+
66
+    def __str__(self):
67
+        return '%s aime %s' % (self.liker, self.reset)

+ 27 - 1
counter/templates/counterTemplate.html

@@ -9,7 +9,31 @@
9 9
     <div class="col-md-3">
10 10
       <div class="panel panel-primary">
11 11
         <div class="panel-heading">
12
-          <h2 class="panel-title">Dernier seum {% if not counter.lastReset.noSeum %}<span class="badge pull-right">{{ counter.seumCount }}</span>{% endif %}</h2>
12
+            <form action="{% url 'like' %}" method="POST" name="like{{counter.id}}">
13
+                {% csrf_token %}
14
+                <input type="hidden" name="liker" value="{{myCounter.id}}" />
15
+                <input type="hidden" name="reset" value="{{counter.lastReset.id}}" <h2 class="panel-title" />
16
+                <input type="hidden" name="redirect" value="{% url 'counter' id_counter=counter.id %}" />
17
+                <a class="counter-link" href="{% url 'counter' id_counter=counter.id %}">
18
+                    <b>{{ counter.trigramme }}</b> <small>{{ counter.name }}</small>
19
+                </a>
20
+                {% if not counter.lastReset.noSeum %}
21
+                {% if counter.alreadyLiked %}
22
+                <span class="pull-right badge">
23
+                    <span class="glyphicon glyphicon-ok" />&nbsp;{{ counter.likeCount }}
24
+                </span>
25
+                {% elif counter.id == myCounter.id %}
26
+                <span class="pull-right badge">
27
+                    <span class="glyphicon glyphicon-fire" />&nbsp;{{ counter.likeCount }}
28
+                </span>
29
+                {% else %}
30
+                <a class="pull-right badge" onclick="document.forms['like{{counter.id}}'].submit();">
31
+                    <span class="glyphicon glyphicon-fire" />&nbsp;{{ counter.likeCount }}
32
+                </a>
33
+                {% endif %}
34
+                {% endif %}
35
+                </h2>
36
+            </form>
13 37
         </div>
14 38
         <div class="seum-counter panel-body" style="height:125px" id="container{{counter.id}}">
15 39
           {% if counter.lastReset.noSeum %}
@@ -74,6 +98,7 @@
74 98
                 <th>Date</th>
75 99
                 <th>Motif</th>
76 100
                 <th>Fouteur de seum</th>
101
+                <th>Nombre de likes</th>
77 102
               </tr>
78 103
             </thead>
79 104
             <tbody>
@@ -86,6 +111,7 @@
86 111
                     {{ reset.who.trigramme }}
87 112
                 {% endif %}
88 113
                 </td>
114
+                <td>{{ reset.likeCount }}</td>
89 115
               </tr>
90 116
               {% endfor %}
91 117
             </tbody>

+ 30 - 8
counter/templates/homeTemplate.html

@@ -7,11 +7,16 @@
7 7
 		<div class="col-sm-6">
8 8
 			<div class="panel panel-primary">
9 9
 				<div class="panel-heading">
10
-					<a class="counter-link" href="{% url 'counter' id_counter=myCounter.id %}">
11
-						<h2 class="panel-title"><b>{{ myCounter.trigramme }}</b> <small>{{ myCounter.name }}</small>
12
-							{% if not myCounter.lastReset.noSeum %}<span class="pull-right badge">{{ myCounter.seumCount }}</span>{% endif %}
10
+					<h2 class="panel-title">
11
+						<a class="counter-link panel-title" href="{% url 'counter' id_counter=myCounter.id %}">
12
+							<b>{{ myCounter.trigramme }}</b> <small>{{ myCounter.name }}</small>
13
+						</a>
14
+						{% if not myCounter.lastReset.noSeum %}
15
+							<span class="pull-right badge">
16
+								<span class="glyphicon glyphicon-fire" />&nbsp;{{ myCounter.likeCount }}
17
+							</span>
18
+						{% endif %}
13 19
 						</h2>
14
-					</a>
15 20
 				</div>
16 21
 				<div class="primary-counter panel-body" id="container{{myCounter.id}}">
17 22
 					<div style="width:100%;">
@@ -85,11 +90,28 @@
85 90
 		<div class="col-md-3 col-sm-4 col-lg-2">
86 91
 			<div class="panel panel-{{counter.CSSclass}}" style="opacity:{{counter.opacity}}">
87 92
 				<div class="panel-heading">
88
-					<a class="counter-link" href="{% url 'counter' id_counter=counter.id %}">
89
-						<h2 class="panel-title"><b>{{ counter.trigramme }}</b> <small>{{ counter.name }}</small>
90
-							{% if not counter.lastReset.noSeum %}<span class="pull-right badge">{{ counter.seumCount }}</span>{% endif %}
93
+					<form action="{% url 'like' %}" method="POST" name="like{{counter.id}}">
94
+						{% csrf_token %}
95
+						<input type="hidden" name="liker" value="{{myCounter.id}}" />
96
+						<input type="hidden" name="redirect" value="{% url 'counter' id_counter=counter.id %}" />
97
+						<input type="hidden" name="reset" value="{{counter.lastReset.id}}" />
98
+						<h2 class="panel-title">
99
+							<a class="counter-link" href="{% url 'counter' id_counter=counter.id %}">
100
+								<b>{{ counter.trigramme }}</b> <small>{{ counter.name }}</small>
101
+							</a>
102
+							{% if not counter.lastReset.noSeum %}
103
+							{% if counter.alreadyLiked %}
104
+							<span class="pull-right badge">
105
+								<span class="glyphicon glyphicon-ok" />&nbsp;{{ counter.likeCount }}
106
+							</span>
107
+							{% else %}
108
+							<a class="pull-right badge" onclick="document.forms['like{{counter.id}}'].submit();">
109
+								<span class="glyphicon glyphicon-fire" />&nbsp;{{ counter.likeCount }}
110
+							</a>
111
+							{% endif %}
112
+							{% endif %}
91 113
 						</h2>
92
-					</a>
114
+					</form>
93 115
 				</div>
94 116
 				<div class="seum-counter panel-body">
95 117
 					{% if counter.lastReset.noSeum %}

+ 13 - 12
counter/urls.py

@@ -6,40 +6,41 @@ from django.views.generic.base import RedirectView
6 6
 from . import views
7 7
 
8 8
 urlpatterns = [
9
-    url(r'^$', views.home, name="home"),
10
-    url(r'^reset-counter/$', views.resetCounter, name="reset-counter"),
11
-    url(r'^counter/(?P<id_counter>\d+)/$', views.counter, name="counter"),
9
+    url(r'^$', views.home, name='home'),
10
+    url(r'^reset-counter/$', views.resetCounter, name='reset-counter'),
11
+    url(r'^counter/(?P<id_counter>\d+)/$', views.counter, name='counter'),
12 12
     url(r'^rss/$', SeumFeed()),
13
-    url(r'^create_user/$', views.createUser, name="create_user"),
13
+    url(r'^create_user/$', views.createUser, name='create_user'),
14
+    url(r'^like/$', views.like, name='like'),
14 15
     url(r'^toggle-notif/$', views.toggleEmailNotifications,
15
-        name="toggle_email_notifications"),
16
+        name='toggle_email_notifications'),
16 17
     url(r'^login/$', auth_views.login,
17 18
         {'template_name': 'login.html'},
18
-        name="login"),
19
+        name='login'),
19 20
     url(r'^logout/$', auth_views.logout_then_login,
20 21
         name='logout'),
21 22
     url(r'^password/change/$', auth_views.password_change,
22 23
         {'template_name': 'passwordChange.html'},
23
-        name="password_change"),
24
+        name='password_change'),
24 25
     url(r'^password/change/done∕$', auth_views.password_change_done,
25 26
         {'template_name': 'passwordChangeDone.html'},
26
-        name="password_change_done"),
27
+        name='password_change_done'),
27 28
     url(r'^password/reset/$', auth_views.password_reset,
28 29
         {'template_name': 'passwordReset.html',
29 30
          'email_template_name': 'resetEmail.txt',
30 31
          'subject_template_name': 'subjectEmail.txt'},
31
-        name="password_reset"),
32
+        name='password_reset'),
32 33
     url(r'^password/reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
33 34
         auth_views.password_reset_confirm,
34 35
         {'template_name': 'passwordResetConfirm.html'},
35
-        name="password_reset_confirm"),
36
+        name='password_reset_confirm'),
36 37
     url(r'^password/reset/complete/$',
37 38
         auth_views.password_reset_complete,
38 39
         {'template_name': 'passwordResetComplete.html'},
39
-        name="password_reset_complete"),
40
+        name='password_reset_complete'),
40 41
     url(r'^password/reset/done/$',
41 42
         auth_views.password_reset_done,
42 43
         {'template_name': 'passwordResetDone.html'},
43
-        name="password_reset_done"),
44
+        name='password_reset_done'),
44 45
     url(r'^', RedirectView.as_view(pattern_name='home')),
45 46
 ]

+ 30 - 7
counter/views.py

@@ -1,5 +1,5 @@
1 1
 from django.shortcuts import render
2
-from counter.models import Counter, Reset
2
+from counter.models import Counter, Reset, Like
3 3
 from django.contrib.auth.models import User
4 4
 from babel.dates import format_timedelta, format_datetime
5 5
 from datetime import datetime, timedelta
@@ -51,8 +51,8 @@ def home(request):
51 51
                 myCounter.lastReset.selfSeum = False
52 52
             myCounter.lastReset.delta = datetime.now(
53 53
             ) - myCounter.lastReset.timestamp.replace(tzinfo=None)
54
-            myCounter.seumCount = Reset.objects.filter(
55
-                counter=myCounter).count()
54
+            myCounter.likeCount = Like.objects.filter(
55
+                reset=myCounter.lastReset).count()
56 56
         myCounter.lastReset.formatted_delta = format_timedelta(
57 57
             myCounter.lastReset.delta, locale='fr', threshold=1)
58 58
     except Counter.DoesNotExist:
@@ -61,7 +61,7 @@ def home(request):
61 61
     # Building data for counters display
62 62
     counters = Counter.objects.all()
63 63
     for counter in counters:
64
-        #Only the last reset is displayed
64
+        # Only the last reset is displayed
65 65
         lastReset = Reset.objects.filter(
66 66
             counter=counter).order_by('-timestamp')
67 67
         if (lastReset.count() == 0):  # This person never had the seum
@@ -101,9 +101,12 @@ def home(request):
101 101
             counter.opacity = 0.4 + 0.6 * \
102 102
                 math.exp(-(counter.lastReset.delta.total_seconds()) /
103 103
                          (7 * 24 * 3600))
104
-            # Computing the total number of resets for this counter
105
-            counter.seumCount = Reset.objects.filter(
106
-                counter=counter).count()
104
+            # Computing the total number of likes for this counter
105
+            counter.likeCount = Like.objects.filter(
106
+                reset=counter.lastReset).count()
107
+            counter.alreadyLiked = (Like.objects.filter(
108
+                reset=counter.lastReset, liker=myCounter).exists())
109
+
107 110
         counter.lastReset.formatted_delta = format_timedelta(
108 111
             counter.lastReset.delta, locale='fr', threshold=1)
109 112
         counter.isHidden = "hidden"
@@ -327,6 +330,10 @@ def counter(request, id_counter):
327 330
         seumFrequency = format_timedelta((
328 331
             datetime.now() - firstReset.timestamp.replace(tzinfo=None)) /
329 332
             counter.seumCount, locale='fr', threshold=1)
333
+        counter.alreadyLiked = (Like.objects.filter(
334
+            reset=counter.lastReset, liker=myCounter).exists())
335
+        counter.likeCount = Like.objects.filter(
336
+            reset=counter.lastReset).count()
330 337
 
331 338
     for reset in resets:
332 339
         if (reset.who is None or
@@ -337,6 +344,8 @@ def counter(request, id_counter):
337 344
         reset.date = format_datetime(
338 345
             reset.timestamp, locale='fr',
339 346
             format="dd/MM/Y HH:mm")
347
+        reset.likeCount = Like.objects.filter(reset=reset).count()
348
+
340 349
     # Timeline graph
341 350
     # Data pre-processing
342 351
     if not counter.lastReset.noSeum:
@@ -429,3 +438,17 @@ def toggleEmailNotifications(request):
429 438
     counter.email_notifications = not counter.email_notifications
430 439
     counter.save()
431 440
     return HttpResponseRedirect(reverse('home'))
441
+
442
+
443
+@login_required
444
+def like(request):
445
+    if (request.method == 'POST'):
446
+        # create a form instance and populate it with data from the request:
447
+        data = dict(request.POST)
448
+        liker = Counter.objects.get(pk=data['liker'][0])
449
+        reset = Reset.objects.get(pk=data['reset'][0])
450
+        like = Like()
451
+        like.liker = liker
452
+        like.reset = reset
453
+        like.save()
454
+    return HttpResponseRedirect(data['redirect'][0])