home » zplus/freepost.git
Author zPlus <zplus@peers.community> 2018-07-22 07:43:39
Committer zPlus <zplus@peers.community> 2018-07-22 07:43:39
Commit 022590a (patch)
Tree ff60fdb
Parent(s)

Add "topic" filter in user interface.


commits diff: c822d3e..022590a
8 files changed, 123 insertions, 108 deletionsdownload


Diffstat
-rwxr-xr-x freepost/__init__.py 81
-rw-r--r-- freepost/database.py 45
-rwxr-xr-x freepost/static/stylus/freepost.styl 17
-rwxr-xr-x freepost/static/stylus/reset.styl 8
-rwxr-xr-x freepost/templates/homepage.html 4
-rw-r--r-- freepost/templates/layout.html 74
-rwxr-xr-x freepost/templates/submit.html 2
-rwxr-xr-x freepost/templates/user_settings.html 0

Diff options
View
Side
Whitespace
Context lines
Inter-hunk lines
+39/-42 M   freepost/__init__.py
index e76844a..060df8c
old size: 25K - new size: 25K
@@ -49,13 +49,14 @@ template = functools.partial (
49 49 'globals': {
50 50 'new_messages': lambda user_id: database.count_unread_messages (user_id),
51 51 'now': lambda: datetime.now (timezone.utc),
52 - 'url': application.get_url,
52 + 'request': request,
53 53 # Return a setting from 'settings.yaml'
54 54 'settings': lambda section, key: settings[section][key],
55 55 # Get the current user of the session
56 56 'session_user': lambda: session.user (),
57 57 # Split a string of topics into a list
58 - 'split_topics': lambda topics: [ topic for topic in topics.split (' ') ] if topics else []
58 + 'split_topics': lambda topics: [ topic for topic in topics.split (' ') ] if topics else [],
59 + 'url': application.get_url,
59 60 },
60 61 'autoescape': True
61 62 })
@@ -94,7 +95,7 @@ def requires_logout (controller):
94 95 secret = settings['cookies']['secret'])
95 96
96 97 if database.is_valid_session (session_token):
97 - redirect (application.get_url ('user'))
98 + redirect (application.get_url ('user_settings'))
98 99 else:
99 100 return controller ()
100 101
@@ -108,26 +109,8 @@ def homepage ():
108 109 Display homepage with posts sorted by 'hot'.
109 110 """
110 111
111 - # Page number
112 - page = int (request.query.page or 0)
113 -
114 - if page < 0:
115 - redirect (application.get_url ('homepage'))
116 -
117 - user = session.user ()
118 - posts = database.get_hot_posts (page, user['id'] if user else None)
119 -
120 - return template (
121 - 'homepage.html',
122 - page_number=page,
123 - posts=posts,
124 - sorting='hot')
125 -
126 - @get ('/new', name='new')
127 - def new ():
128 - """
129 - Display homepage with posts sorted by 'new'.
130 - """
112 + # Sort order
113 + sort = request.query.sort or 'hot'
131 114
132 115 # Page number
133 116 page = int (request.query.page or 0)
@@ -136,13 +119,19 @@ def new ():
136 119 redirect (application.get_url ('homepage'))
137 120
138 121 user = session.user ()
139 - posts = database.get_new_posts (page, user['id'] if user else None)
122 +
123 + if sort in [ 'hot', 'new' ]:
124 + posts = database.get_posts (
125 + page, user['id'] if user else None,
126 + sort)
127 + else:
128 + posts = []
140 129
141 130 return template (
142 131 'homepage.html',
143 132 page_number=page,
144 133 posts=posts,
145 - sorting='new')
134 + sorting=sort)
146 135
147 136 # TODO implement this
148 137 @get ('/topic/<name>', name='topic')
@@ -151,22 +140,30 @@ def topic (name):
151 140 Display posts by topic.
152 141 """
153 142
154 - return ""
143 + # Sort order
144 + sort = request.query.sort or 'hot'
155 145
156 146 # Page number
157 147 page = int (request.query.page or 0)
158 148
159 149 if page < 0:
160 - redirect (application.get_url ('topic', name=name))
150 + redirect (application.get_url ('homepage'))
161 151
162 152 user = session.user ()
163 - posts = database.get_topic_posts (page, user['id'] if user else None)
153 +
154 + if sort in [ 'hot', 'new' ]:
155 + posts = database.get_posts (
156 + page, user['id'] if user else None,
157 + sort, name)
158 + else:
159 + posts = []
164 160
165 161 return template (
166 162 'homepage.html',
163 + topic=name,
167 164 page_number=page,
168 165 posts=posts,
169 - sorting='hot')
166 + sorting=sort)
170 167
171 168 @get ('/about', name='about')
172 169 def about ():
@@ -393,20 +390,20 @@ def validate_new_password ():
393 390
394 391 # Start new session and redirect user
395 392 session.start (user['id'])
396 - redirect (application.get_url ('user'))
393 + redirect (application.get_url ('user_settings'))
397 394
398 - @get ('/user', name='user')
395 + @get ('/user/settings', name='user_settings')
399 396 @requires_login
400 - def user_private_homepage ():
397 + def user_settings ():
401 398 """
402 399 A user's personal page.
403 400 """
404 401
405 - return template ('user_private_homepage.html')
402 + return template ('user_settings.html')
406 403
407 - @post ('/user')
404 + @post ('/user/settings')
408 405 @requires_login
409 - def update_user ():
406 + def update_user_settings ():
410 407 """
411 408 Update user info (about, email, ...).
412 409 """
@@ -417,12 +414,12 @@ def update_user ():
417 414 email = request.forms.get ('email')
418 415
419 416 if about is None or email is None:
420 - redirect (application.get_url ('user'))
417 + redirect (application.get_url ('user_settings'))
421 418
422 419 # Update user info in the database
423 420 database.update_user (user['id'], about, email, False)
424 421
425 - redirect (application.get_url ('user'))
422 + redirect (application.get_url ('user_settings'))
426 423
427 424 @get ('/user_activity/posts')
428 425 @requires_login
@@ -440,7 +437,7 @@ def user_comments ():
440 437
441 438 return template ('user_comments.html', comments=comments)
442 439
443 - @get ('/user_activity/replies')
440 + @get ('/user_activity/replies', name='user_replies')
444 441 @requires_login
445 442 def user_replies ():
446 443 user = session.user ()
@@ -450,7 +447,7 @@ def user_replies ():
450 447
451 448 return template ('user_replies.html', replies=replies)
452 449
453 - @get ('/user/<username>', name='user_public')
450 + @get ('/user/public/<username>', name='user_public')
454 451 def user_public_homepage (username):
455 452 """
456 453 Display a publicly accessible page with public info about the user.
@@ -459,7 +456,7 @@ def user_public_homepage (username):
459 456 account = database.get_user_by_username (username)
460 457
461 458 if account is None:
462 - redirect (application.get_url ('user'))
459 + redirect (application.get_url ('user_settings'))
463 460
464 461 return template ('user_public_homepage.html', account=account)
465 462
@@ -610,7 +607,7 @@ def submit ():
610 607
611 608 return template ('submit.html')
612 609
613 - @post ('/submit')
610 + @post ('/submit', name='submit')
614 611 @requires_login
615 612 def submit_check ():
616 613 """
@@ -783,7 +780,7 @@ def vote ():
783 780 # Add -1
784 781 database.vote_comment (comment['id'], user['id'], -1)
785 782
786 - @get ('/search')
783 + @get ('/search', name='search')
787 784 def search ():
788 785 """
789 786 Search content on this instance, and display the results.

+14/-31 M   freepost/database.py
index bedc247..f81d8ea
old size: 18K - new size: 18K
@@ -157,36 +157,17 @@ def get_user_by_session_token (session_token):
157 157 return cursor.fetchone ()
158 158
159 159 # Get posts by date (for homepage)
160 - def get_new_posts (page = 0, session_user_id = None):
161 - cursor = db.cursor (MySQLdb.cursors.DictCursor)
160 + def get_posts (page = 0, session_user_id = None, sort = 'hot', topic = None):
161 + if sort == 'new':
162 + sort = 'ORDER BY P.created DESC'
163 + else:
164 + sort = 'ORDER BY P.dateCreated DESC, P.vote DESC, P.commentsCount DESC'
162 165
163 - cursor.execute (
164 - """
165 - SELECT
166 - P.*,
167 - U.username,
168 - V.vote AS user_vote,
169 - GROUP_CONCAT(DISTINCT T.name ORDER BY T.name SEPARATOR " ") AS topics
170 - FROM post AS P
171 - JOIN user AS U ON P.userId = U.id
172 - LEFT JOIN vote_post as V ON V.postId = P.id AND V.userId = %(user)s
173 - LEFT JOIN topic as T ON T.post_id = P.id
174 - GROUP BY P.id
175 - ORDER BY P.created DESC
176 - LIMIT %(limit)s
177 - OFFSET %(offset)s
178 - """,
179 - {
180 - 'user': session_user_id,
181 - 'limit': settings['defaults']['items_per_page'],
182 - 'offset': page * settings['defaults']['items_per_page']
183 - }
184 - )
166 + if topic:
167 + topic_name = 'WHERE T.name = %(topic)s'
168 + else:
169 + topic_name = ''
185 170
186 - return cursor.fetchall ()
187 -
188 - # Get posts by rating (for homepage)
189 - def get_hot_posts (page = 0, session_user_id = None):
190 171 cursor = db.cursor (MySQLdb.cursors.DictCursor)
191 172
192 173 cursor.execute (
@@ -200,15 +181,17 @@ def get_hot_posts (page = 0, session_user_id = None):
200 181 JOIN user AS U ON P.userId = U.id
201 182 LEFT JOIN vote_post as V ON V.postId = P.id AND V.userId = %(user)s
202 183 LEFT JOIN topic as T ON T.post_id = P.id
184 + {topic}
203 185 GROUP BY P.id
204 - ORDER BY P.dateCreated DESC, P.vote DESC, P.commentsCount DESC
186 + {order}
205 187 LIMIT %(limit)s
206 188 OFFSET %(offset)s
207 - """,
189 + """.format (topic=topic_name, order=sort),
208 190 {
209 191 'user': session_user_id,
210 192 'limit': settings['defaults']['items_per_page'],
211 - 'offset': page * settings['defaults']['items_per_page']
193 + 'offset': page * settings['defaults']['items_per_page'],
194 + 'topic': topic
212 195 }
213 196 )
214 197

+10/-7 M   freepost/static/stylus/freepost.styl
index c80a570..b60b12e
old size: 11K - new size: 11K
@@ -40,11 +40,13 @@ body
40 40
41 41 /* Page header */
42 42 > .header
43 + display grid
44 + grid-template-columns max-content auto
43 45 padding 1rem 0
44 46 text-align center
45 47
46 48 /* Menu under the logo */
47 - > .menu
49 + .menu
48 50 border-bottom 1px solid transparent
49 51 display flex
50 52 flex-direction row
@@ -53,8 +55,6 @@ body
53 55 align-content flex-start
54 56 align-items flex-start
55 57
56 - margin 1em auto
57 -
58 58 > .flex-item
59 59 flex 0 1 auto
60 60 align-self auto
@@ -65,10 +65,6 @@ body
65 65 color #000
66 66 margin 0 0
67 67 padding 0 .5rem .5rem .5rem
68 -
69 - &:first-child
70 - border-bottom 2px solid transparent
71 - margin-left 0
72 68
73 69 /* Highlight menu item of the current active page (Hot/New/Submit/...) */
74 70 > .active_page
@@ -84,6 +80,13 @@ body
84 80 padding .5em .5em
85 81 text-decoration none
86 82
83 + .submenu
84 + display flex
85 + flex-direction row
86 + flex-wrap wrap
87 + justify-content flex-start
88 + align-content flex-start
89 + align-items flex-start
87 90
88 91 > .content
89 92 padding 1em 0

+8/-0 M   freepost/static/stylus/reset.styl
index 273c774..83a48d4
old size: 5K - new size: 5K
@@ -191,5 +191,13 @@ p > code
191 191 white-space -moz-pre-wrap
192 192 white-space -o-pre-wrap
193 193
194 + select
195 + -webkit-appearance none
196 + -moz-appearance none
197 + appearance none
198 + background transparent
199 + border 0
200 + cursor pointer
201 +
194 202 ul, ol
195 203 margin 1.2em 2em

+2/-2 M   freepost/templates/homepage.html
index 521cc57..527a76d
old size: 4K - new size: 4K
@@ -79,12 +79,12 @@
79 79
80 80 <div class="more">
81 81 {% if page_number > 0 %}
82 - <a href="{{ url ('homepage') if page_number == 1 else '?page=' ~ (page_number - 1) }}" class="button button_default1">
82 + <a href="{{ request.urlparts.path if page_number == 1 else '?page=' ~ (page_number - 1) }}" class="button button_default1">
83 83 Previous
84 84 </a>
85 85 {% endif %}
86 86
87 - <a href="?page={{ page_number + 1 }}" class="button button_default1">
87 + <a href="?page={{ page_number + 1 }}{{ '&sort=' ~ request.query.sort }}" class="button button_default1">
88 88 Next
89 89 </a>
90 90 </div>

+49/-25 M   freepost/templates/layout.html
index a583fab..4aae247
old size: 4K - new size: 5K
@@ -15,38 +15,62 @@
15 15 <div class="container">
16 16
17 17 <div class="header">
18 - <div class="menu">
19 - <a href="/" class="flex-item logo">
20 - freepost
18 + <div>
19 + {% if topic %}
20 + <a href="{{ url ('topic', name=topic) }}" class="flex-item logo">
21 + topic / {{ topic }}
22 + </a>
23 + {% else %}
24 + <a href="{{ url ('homepage') }}" class="flex-item logo">
25 + freepost
26 + </a>
27 + {% endif %}
28 +
29 + <a href="{{ url ('homepage') }}" class="flex-item logo">
21 30 <img alt="🐵&nbsp;" title="freepost" src="/images/freepost.png" class="monkey" />
22 31 </a>
23 - <a href="/" class="flex-item {{ "active_page" if active_page == "hot" else "" }}">Hot</a>
24 - <a href="/new" class="flex-item {{ "active_page" if active_page == "new" else "" }}">New</a>
25 - <a href="/search" class="flex-item {{ "active_page" if active_page == "search" else "" }}">Search</a>
26 -
27 - {% if user %}
28 - {% set unread_messages = new_messages (user.id) %}
29 -
30 - <a href="/submit" class="flex-item {{ "active_page" if active_page == "submit" else "" }}">Submit</a>
32 + </div>
33 +
34 + <div>
35 + <div class="menu">
36 + <a href="{{ url ('topic', name=topic) if topic else url ('homepage') }}" class="flex-item {{ 'active_page' if active_page == 'hot' }}">
37 + Hot
38 + </a>
39 + <a href="{{ url ('topic', name=topic) if topic else url ('homepage') }}?sort=new" class="flex-item {{ 'active_page' if active_page == 'new' }}">
40 + New
41 + </a>
31 42
32 - {% if unread_messages %}
33 - <a href="/user_activity/replies" class="new_messages flex-item">
34 - {{ user.username }} ({{ unread_messages }})
43 + {% if user %}
44 + <a href="{{ url ('submit') }}{{ '?topic=' ~ topic if topic }}" class="flex-item {{ 'active_page' if active_page == 'submit' }}">
45 + Submit
35 46 </a>
47 + {% endif %}
48 +
49 + <a href="{{ url ('search') }}" class="flex-item {{ 'active_page' if active_page == 'search' }}">Search</a>
50 +
51 + <a href="{{ url ('about') }}" class="flex-item {{ 'active_page' if active_page == 'about' }}">About</a>
52 +
53 + {% if user %}
54 + {% set unread_messages = new_messages (user.id) %}
55 +
56 + {% if unread_messages %}
57 + <a href="{{ url ('user_replies') }}" class="new_messages flex-item">
58 + {{ user.username }} ({{ unread_messages }})
59 + </a>
60 + {% else %}
61 + <a href="{{ url ('user_settings') }}" class="flex-item {{ 'active_page' if active_page == 'user' }}">
62 + {{ user.username }}
63 + </a>
64 + {% endif %}
65 +
66 + <a href="{{ url ('logout') }}" class="flex-item">Log out</a>
36 67 {% else %}
37 - <a href="/user" class="flex-item {{ "active_page" if active_page == "user" else "" }}">
38 - {{ user.username }}
39 - </a>
68 + <a href="{{ url ('login') }}" class="flex-item {{ 'active_page' if active_page == 'login' }}">Log in</a>
40 69 {% endif %}
41 - {% endif %}
42 -
43 - <a href="/about" class="flex-item {{ "active_page" if active_page == "about" else "" }}">About</a>
70 + </div>
44 71
45 - {% if user %}
46 - <a href="/logout" class="flex-item">Log out</a>
47 - {% else %}
48 - <a href="/login" class="flex-item {{ "active_page" if active_page == "login" else "" }}">Log in</a>
49 - {% endif %}
72 + <div class="submenu">
73 + </div>
50 74 </div>
51 75 </div>
52 76

+1/-1 M   freepost/templates/submit.html
index f8883c3..0fd7c83
old size: 1K - new size: 1K
@@ -29,7 +29,7 @@
29 29 {% if settings ('defaults', 'topics_per_post') > 0 %}
30 30 <h3>Topics</h3>
31 31 <div>
32 - <input type="text" name="topics" class="form-control" />
32 + <input type="text" name="topics" value="{{ request.query.topic }}" class="form-control" />
33 33 </div>
34 34 <div>
35 35 Max {{ settings ('defaults', 'topics_per_post') }}

+0/-0 R   freepost/templates/user_private_homepage.html -> freepost/templates/user_settings.html
index 73a6b7e..73a6b7e
old size: 2K - new size: 2K