Merge lp:~widelands-dev/widelands-website/more_latest_posts into lp:widelands-website

Proposed by kaputtnik on 2019-03-18
Status: Merged
Merged at revision: 528
Proposed branch: lp:~widelands-dev/widelands-website/more_latest_posts
Merge into: lp:widelands-website
Diff against target: 337 lines (+221/-10)
9 files modified
mainpage/templates/mainpage/header.html (+1/-1)
pybb/forms.py (+12/-0)
pybb/settings.py (+1/-0)
pybb/templates/pybb/all_last_posts.html (+73/-0)
pybb/templates/pybb/inlines/latest_posts_table.html (+21/-0)
pybb/templates/pybb/last_posts.html (+3/-0)
pybb/templatetags/pybb_extras.py (+11/-8)
pybb/urls.py (+1/-0)
pybb/views.py (+98/-1)
To merge this branch: bzr merge lp:~widelands-dev/widelands-website/more_latest_posts
Reviewer Review Type Date Requested Status
GunChleoc Approve on 2019-03-21
kaputtnik Resubmit on 2019-03-20
Review via email: mp+364706@code.launchpad.net

Commit message

Add a 'more latest posts view'

Description of the change

Add a view to show more 'latest posts'

- Add a link to the bottom of the 'Latest Posts' box
- Add a view showing the latest posts
- Add a form to adjust the days and the sort option: by topic/forum
- Increased number for the 'Last Post' box to have more last posts in it if too many posts are created in one topic.
- fixed url parsing after login: A url with a query string like '.../?page=3#post-27347' does not work after login. Now it works.

I have merged it on alpha for testing: http://alpha.widelands.org/forum/latest_posts/?days=365&sort_by=topic

To post a comment you must log in.
GunChleoc (gunchleoc) wrote :

Added some nits for strings and comments.

The grouping doesn't work properly. In

http://alpha.widelands.org/forum/latest_posts/?days=400&sort_by=forum

I see the "Germany" forum twice and the topic "Na dann gucken wir mal wie das hier ist" 3 times.

In http://alpha.widelands.org/forum/latest_posts/?days=400&sort_by=topic, I see the same topic listed multiple times as well.

kaputtnik (franku) wrote :

Thanks. I have replied to one of your inline comments below.

About grouping: I agree that this can be confusing. Currently the list is always sorted by the posts dates, so grouping lead into this situation were some topics appear double. Say we have:

post1 created 12.3.2019 in topic foo
post2 created 11.3.2019 in topic bar
post3 created 10.3.2019 in topic baz
post4 created 1.1.2019 in topic foo

Will lead to:

topic foo:
 post1 (12.3.2019)

topic bar:
 post2 (11.3.1019)

topic baz:
 post3 (10.3.2019)

topic foo:
 post4 (1.1.2019)

If we change this to something like:

topic foo:
 post1 (12.3.2019)
 post4 (1.1.2019)

topic bar:
 post2 (11.3.1019)

topic baz:
 post3 (10.3.2019)

The posts are not sorted by date anymore: A post created yesterday may appear at the bottom of the page then, after several other old posts.

I am unsure about a good grouping. Maybe this should be tested in production to have real time data? Or adding a third option 'no grouping' which shows the posts by date descending and change the grouping by topic/forum to have no double entries?

GunChleoc (gunchleoc) wrote :

The change you mention is exactly what I would expect. Sorted by topics' last post date rather than each individual post's date.

The only reason we need this long list really is that we can't link to the first unread post.

539. By kaputtnik on 2019-03-19

stringfixes

kaputtnik (franku) wrote :

Done with stringfixes, also applied the change to the label of days as you suggested.

Will apply the needed changes to have the ordering/grouping you mentioned. This may take some time so i shut down alpha again.

540. By kaputtnik on 2019-03-20

rework of grouping algorithm

541. By kaputtnik on 2019-03-20

cleanups

kaputtnik (franku) wrote :
review: Resubmit
GunChleoc (gunchleoc) wrote :

Perfect, let's have it :)

review: Approve
kaputtnik (franku) wrote :

Thanks :-)

Merged and deployed.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'mainpage/templates/mainpage/header.html'
2--- mainpage/templates/mainpage/header.html 2019-03-03 15:17:58 +0000
3+++ mainpage/templates/mainpage/header.html 2019-03-20 21:32:45 +0000
4@@ -42,7 +42,7 @@
5 <br />
6 <a href="{% url 'logout' %}?next=/">Logout</a>
7 {% else %}
8- <a href="{% url 'login' %}?next={{ request.path|iriencode }}">Login/Register</a>
9+ <a href="{% url 'login' %}?next={{ request.get_full_path|urlencode }}">Login/Register</a>
10 {% endif %}
11 </li>
12 </ul>
13
14=== modified file 'pybb/forms.py'
15--- pybb/forms.py 2018-12-21 11:26:08 +0000
16+++ pybb/forms.py 2019-03-20 21:32:45 +0000
17@@ -87,3 +87,15 @@
18 post.updated = datetime.now()
19 post.save(*args, **kwargs)
20 return post
21+
22+
23+class LastPostsDayForm(forms.Form):
24+ days = forms.IntegerField(
25+ max_value = 1000,
26+ min_value = 5,
27+ )
28+
29+ sort_by = forms.ChoiceField(
30+ choices = [('forum','Forum'),('topic', 'Topic'),],
31+ label = 'Group by:',
32+ )
33
34=== modified file 'pybb/settings.py'
35--- pybb/settings.py 2018-12-21 12:50:32 +0000
36+++ pybb/settings.py 2019-03-20 21:32:45 +0000
37@@ -18,6 +18,7 @@
38 ATTACHMENT_SIZE_LIMIT = get('PYBB_ATTACHMENT_SIZE_LIMIT', 1024 * 1024)
39 ATTACHMENT_ENABLE = get('PYBB_ATTACHMENT_ENABLE', True)
40 INTERNAL_PERM = get('INTERNAL_PERM', 'pybb.can_access_internal')
41+LAST_POSTS_DAYS = get('LAST_POSTS_DAYS', 30)
42
43 # That is used internally
44 DISABLE_NOTIFICATION = False
45
46=== added file 'pybb/templates/pybb/all_last_posts.html'
47--- pybb/templates/pybb/all_last_posts.html 1970-01-01 00:00:00 +0000
48+++ pybb/templates/pybb/all_last_posts.html 2019-03-20 21:32:45 +0000
49@@ -0,0 +1,73 @@
50+{% extends 'pybb/base.html' %}
51+
52+{% block title %}
53+ Latest posts - {{ block.super }}
54+{% endblock title %}
55+
56+{% block content_header %}
57+ <h1>Latest Posts</h1>
58+{% endblock %}
59+
60+{% block content_main %}
61+<div class="blogEntry">
62+ <form action="." method="post" novalidate>
63+ {% csrf_token %}
64+ <span class="errormessage">{{ form.days.errors }}</span>
65+ <label for="id_days">Show posts created up to
66+ {{ form.days }} days ago. </label>
67+ <span class="errormessage">{{ form.sort_by.errors }}</span>
68+ {{ form.sort_by.label_tag }} {{ form.sort_by }}
69+ <input type="submit" value="Submit" />
70+ {% if form.errors %}
71+ <p class="errormessage">
72+ An error occured, some default values are used.
73+ Please correct the errors above to get valuable results.
74+ </p>
75+ {% else %}
76+ <p>
77+ Found {{ posts_count }} posts. The list is always sorted by the most recent post first.
78+ </p>
79+ {% endif %}
80+ </form>
81+
82+ <hr>
83+
84+{% if sort_by == 'topic' %}
85+ {% for topic, posts in object_list.items %}
86+ <h2>Topic: {{ topic }}</h2>
87+ <p>
88+ At Forum:
89+ <a href="{% url 'pybb_forum' topic.forum.id %}">{{ topic.forum }}</a>
90+ </p>
91+ {% include 'pybb/inlines/latest_posts_table.html'%}
92+ {% endfor %}
93+
94+{% else %} {# sort by forum #}
95+ {% for forum, topics in object_list.items %}
96+ <h2>Forum: {{ forum }}</h2>
97+ <table class='forum'>
98+ <thead>
99+ <tr>
100+ <th style="text-align: left; width: 30%;">Topic{{ topic_list|length|pluralize }}</th>
101+ <th style="text-align: left;">Post{{ posts|length|pluralize }}</th>
102+ </tr>
103+ </thead>
104+ <tbody>
105+ {% for topic, posts in topics.items %}
106+ <tr class={% cycle 'odd' 'even' %}>
107+ <td class='post'>
108+ <a href="{% url 'pybb_topic' topic.id %}">{{ topic }}</a>
109+ </td>
110+ <td>
111+ {% include 'pybb/inlines/latest_posts_table.html'%}
112+ </td>
113+ </tr>
114+ {% endfor %}
115+ </tbody>
116+ </table>
117+ {% empty %}
118+ <p>Sorry, no posts found...</p>
119+ {% endfor %}
120+{% endif %}
121+</div>
122+{% endblock %}
123
124=== added file 'pybb/templates/pybb/inlines/latest_posts_table.html'
125--- pybb/templates/pybb/inlines/latest_posts_table.html 1970-01-01 00:00:00 +0000
126+++ pybb/templates/pybb/inlines/latest_posts_table.html 2019-03-20 21:32:45 +0000
127@@ -0,0 +1,21 @@
128+{% load custom_date %}
129+{% load wlprofile_extras %}
130+
131+<table class='forum'>
132+ <thead>
133+ <tr>
134+ <th style="text-align: left; width: 20%;">Date</th>
135+ <th style="text-align: left; width: 20%;">User</th>
136+ <th style="text-align: left;">Post{{posts|length|pluralize}}</th>
137+ </tr>
138+ </thead>
139+ <tbody>
140+ {% for post in posts %}
141+ <tr class="{% cycle 'odd' 'even' %}">
142+ <td class='post'>{{ post.created|custom_date:user }}</td>
143+ <td class='post'>{{ post.user|user_link }}</td>
144+ <td class='post'><a href="{{post.get_absolute_url}}">"{{ post.body_text|truncatechars:80}}"</a></td>
145+ </tr>
146+ {% endfor %}
147+ </tbody>
148+</table>
149
150=== modified file 'pybb/templates/pybb/last_posts.html'
151--- pybb/templates/pybb/last_posts.html 2018-12-10 16:37:12 +0000
152+++ pybb/templates/pybb/last_posts.html 2019-03-20 21:32:45 +0000
153@@ -15,6 +15,9 @@
154 by {{ post.user|user_link }} {{ post.created|minutes }} ago
155 </li>
156 {% endfor %}
157+ <li class="small">
158+ <a href="{% url 'all_latest_posts' %}">More latest posts</a>
159+ </li>
160 </ul>
161 </div>
162 </div>
163
164=== modified file 'pybb/templatetags/pybb_extras.py'
165--- pybb/templatetags/pybb_extras.py 2019-02-27 17:20:01 +0000
166+++ pybb/templatetags/pybb_extras.py 2019-03-20 21:32:45 +0000
167@@ -20,15 +20,18 @@
168
169 @register.inclusion_tag('pybb/last_posts.html', takes_context=True)
170 def pybb_last_posts(context, number=8):
171+
172+ # Create a Queryset
173+ last_posts = Post.objects.all().order_by(
174+ '-created')
175+
176+ # Permission dependent Queryset filtering
177 if pybb.views.allowed_for(context.request.user):
178- last_posts = Post.objects.filter(
179- hidden=False).order_by(
180- '-created')[:45]
181+ last_posts = last_posts.filter(
182+ hidden=False)[:100]
183 else:
184- last_posts = Post.objects.filter(
185- hidden=False, topic__forum__category__internal=False).order_by(
186- '-created')[:45]
187-
188+ last_posts = last_posts.filter(
189+ hidden=False, topic__forum__category__internal=False)[:100]
190
191 check = []
192 answer = []
193@@ -39,7 +42,7 @@
194 answer = answer + [post]
195 return {
196 'posts': answer,
197- }
198+ }
199
200
201 @register.simple_tag
202
203=== modified file 'pybb/urls.py'
204--- pybb/urls.py 2018-12-21 09:50:32 +0000
205+++ pybb/urls.py 2019-03-20 21:32:45 +0000
206@@ -40,6 +40,7 @@
207 url('^post/(?P<post_id>\d+)/edit/$', views.edit_post, name='pybb_edit_post'),
208 url('^post/(?P<post_id>\d+)/delete/$',
209 views.delete_post, name='pybb_delete_post'),
210+ url(r'^latest_posts/$', views.all_latest, name='all_latest_posts'),
211
212 # Attachment
213 url('^attachment/(?P<hash>\w+)/$',
214
215=== modified file 'pybb/views.py'
216--- pybb/views.py 2019-03-04 17:47:12 +0000
217+++ pybb/views.py 2019-03-20 21:32:45 +0000
218@@ -1,4 +1,5 @@
219 import math
220+from collections import OrderedDict
221 from mainpage.templatetags.wl_markdown import do_wl_markdown
222 from pybb.markups import mypostmarkup
223
224@@ -14,12 +15,14 @@
225 from pybb.util import render_to, build_form, quote_text, ajax, urlize
226 from pybb.models import Category, Forum, Topic, Post, Attachment,\
227 MARKUP_CHOICES
228-from pybb.forms import AddPostForm, EditPostForm
229+from pybb.forms import AddPostForm, EditPostForm, LastPostsDayForm
230 from pybb import settings as pybb_settings
231 from pybb.orm import load_related
232 from pybb.templatetags.pybb_extras import pybb_moderated_by
233
234 from check_input.models import SuspiciousInput
235+from datetime import date, timedelta
236+
237
238 try:
239 from notification import models as notification
240@@ -387,3 +390,97 @@
241 first_post.save()
242
243 return redirect(topic)
244+
245+
246+def all_latest_posts(request):
247+ """Provide a view to show more latest posts."""
248+
249+ # default values
250+ sort_by_default = 'topic'
251+ days_default = pybb_settings.LAST_POSTS_DAYS
252+
253+ if request.method == 'POST':
254+ # Executed when the form is submitted
255+ form = LastPostsDayForm(request.POST)
256+ if form.is_valid():
257+ days = form.cleaned_data['days']
258+ sort_by = form.cleaned_data['sort_by']
259+ url = '{}?days={days}&sort_by={sort_by}'.format(
260+ reverse('all_latest_posts'),
261+ days=days, sort_by=sort_by
262+ )
263+
264+ return HttpResponseRedirect(url)
265+
266+ else: # request GET
267+ # Initialize if no values are given or if the
268+ # values are given in the url
269+ days = request.GET.get('days', days_default)
270+ sort_by = request.GET.get('sort_by', sort_by_default)
271+
272+ # Create a bound form, so error messages are shown if
273+ # the given values don't validate against the form
274+ form = LastPostsDayForm(
275+ {
276+ 'days': days,
277+ 'sort_by': sort_by,
278+ }
279+ )
280+
281+ if not form.is_valid():
282+ # If we are here, the user has likely modified the query in the url
283+ # with invalid values and we apply defaults for the database query
284+ days = days_default
285+ sort_by = sort_by_default
286+
287+ # Executed on every request (POST and GET)
288+ search_date = date.today() - timedelta(int(days))
289+
290+ # Create a QuerySet ordered by date
291+ last_posts = Post.objects.filter(
292+ created__gte=search_date,
293+ hidden=False,
294+ topic__forum__category__internal=False
295+ ).order_by('-created')
296+
297+ # Exclude hidden topics. After this operation last_posts isn't a
298+ # type of QuerySet anymore and django queries will not work
299+ last_posts = [p for p in last_posts if not p.topic.is_hidden]
300+
301+ posts_count = len(last_posts)
302+
303+ if sort_by == 'topic':
304+ # The use of an OrderedDict makes sure the ordering of
305+ # last_posts get not arbitrary
306+ topics = OrderedDict()
307+ for post in last_posts:
308+ if post.topic not in topics:
309+ # Create a new key with a list as value
310+ topics[post.topic] = [post]
311+ else:
312+ # key exists, just add the post
313+ topics[post.topic].append(post)
314+
315+ object_list = topics
316+
317+ elif sort_by == 'forum':
318+ forums = OrderedDict()
319+ for post in last_posts:
320+ if post.topic.forum.name not in forums:
321+ forums[post.topic.forum.name] = OrderedDict({post.topic: [post]})
322+ elif post.topic not in forums[post.topic.forum.name]:
323+ forums[post.topic.forum.name].update({post.topic: [post]})
324+ else:
325+ forums[post.topic.forum.name][post.topic].append(post)
326+
327+ object_list = forums
328+
329+ return {
330+ 'object_list': object_list,
331+ 'posts_count': posts_count,
332+ 'form': form,
333+ 'sort_by': sort_by
334+ }
335+
336+
337+all_latest = render_to('pybb/all_last_posts.html')(all_latest_posts)

Subscribers

People subscribed via source and target branches

to status/vote changes: