##// END OF EJS Templates
my-account: fixed pagination of unread messages
super-admin -
r5115:e7219b77 default
parent child Browse files
Show More
@@ -1,183 +1,185 b''
1 # Copyright (C) 2010-2023 RhodeCode GmbH
1 # Copyright (C) 2010-2023 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
5 # (only), as published by the Free Software Foundation.
5 # (only), as published by the Free Software Foundation.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU Affero General Public License
12 # You should have received a copy of the GNU Affero General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #
14 #
15 # This program is dual-licensed. If you wish to learn more about the
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19 import logging
19 import logging
20
20
21 from pyramid.httpexceptions import (
21 from pyramid.httpexceptions import (
22 HTTPFound, HTTPNotFound, HTTPInternalServerError)
22 HTTPFound, HTTPNotFound, HTTPInternalServerError)
23
23
24 from rhodecode.apps._base import BaseAppView
24 from rhodecode.apps._base import BaseAppView
25 from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired
25 from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired
26
26
27 from rhodecode.lib import helpers as h
27 from rhodecode.lib import helpers as h
28 from rhodecode.lib.helpers import SqlPage
28 from rhodecode.lib.helpers import SqlPage
29 from rhodecode.lib.utils2 import safe_int
29 from rhodecode.lib.utils2 import safe_int
30 from rhodecode.model.db import Notification
30 from rhodecode.model.db import Notification
31 from rhodecode.model.notification import NotificationModel
31 from rhodecode.model.notification import NotificationModel
32 from rhodecode.model.meta import Session
32 from rhodecode.model.meta import Session
33
33
34
34
35 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
36
36
37
37
38 class MyAccountNotificationsView(BaseAppView):
38 class MyAccountNotificationsView(BaseAppView):
39
39
40 def load_default_context(self):
40 def load_default_context(self):
41 c = self._get_local_tmpl_context()
41 c = self._get_local_tmpl_context()
42 c.user = c.auth_user.get_instance()
42 c.user = c.auth_user.get_instance()
43
43
44 return c
44 return c
45
45
46 def _has_permissions(self, notification):
46 def _has_permissions(self, notification):
47 def is_owner():
47 def is_owner():
48 user_id = self._rhodecode_db_user.user_id
48 user_id = self._rhodecode_db_user.user_id
49 for user_notification in notification.notifications_to_users:
49 for user_notification in notification.notifications_to_users:
50 if user_notification.user.user_id == user_id:
50 if user_notification.user.user_id == user_id:
51 return True
51 return True
52 return False
52 return False
53 return h.HasPermissionAny('hg.admin')() or is_owner()
53 return h.HasPermissionAny('hg.admin')() or is_owner()
54
54
55 @LoginRequired()
55 @LoginRequired()
56 @NotAnonymous()
56 @NotAnonymous()
57 def notifications_show_all(self):
57 def notifications_show_all(self):
58 c = self.load_default_context()
58 c = self.load_default_context()
59
59
60 c.unread_count = NotificationModel().get_unread_cnt_for_user(
60 c.unread_count = NotificationModel().get_unread_cnt_for_user(
61 self._rhodecode_db_user.user_id)
61 self._rhodecode_db_user.user_id)
62
62
63 _current_filter = self.request.GET.getall('type') or ['unread']
63 _current_filter = self.request.GET.getall('type') or ['unread']
64
64
65 notifications = NotificationModel().get_for_user(
65 notifications = NotificationModel().get_for_user(
66 self._rhodecode_db_user.user_id,
66 self._rhodecode_db_user.user_id,
67 filter_=_current_filter)
67 filter_=_current_filter)
68
68
69 p = safe_int(self.request.GET.get('page', 1), 1)
69 p = safe_int(self.request.GET.get('page', 1), 1)
70
70
71 def url_generator(page_num):
71 def url_generator(page_num):
72 query_params = {
72 query_params = {
73 'page': page_num
73 'page': page_num
74 }
74 }
75 _query = self.request.GET.mixed()
75 _query = self.request.GET.mixed()
76 query_params.update(_query)
76 _query.update(query_params)
77 query_params = _query
78
77 return self.request.current_route_path(_query=query_params)
79 return self.request.current_route_path(_query=query_params)
78
80
79 c.notifications = SqlPage(notifications, page=p, items_per_page=10,
81 c.notifications = SqlPage(notifications, page=p, items_per_page=10,
80 url_maker=url_generator)
82 url_maker=url_generator)
81
83
82 c.unread_type = 'unread'
84 c.unread_type = 'unread'
83 c.all_type = 'all'
85 c.all_type = 'all'
84 c.pull_request_type = Notification.TYPE_PULL_REQUEST
86 c.pull_request_type = Notification.TYPE_PULL_REQUEST
85 c.comment_type = [Notification.TYPE_CHANGESET_COMMENT,
87 c.comment_type = [Notification.TYPE_CHANGESET_COMMENT,
86 Notification.TYPE_PULL_REQUEST_COMMENT]
88 Notification.TYPE_PULL_REQUEST_COMMENT]
87
89
88 c.current_filter = 'unread' # default filter
90 c.current_filter = 'unread' # default filter
89
91
90 if _current_filter == [c.pull_request_type]:
92 if _current_filter == [c.pull_request_type]:
91 c.current_filter = 'pull_request'
93 c.current_filter = 'pull_request'
92 elif _current_filter == c.comment_type:
94 elif _current_filter == c.comment_type:
93 c.current_filter = 'comment'
95 c.current_filter = 'comment'
94 elif _current_filter == [c.unread_type]:
96 elif _current_filter == [c.unread_type]:
95 c.current_filter = 'unread'
97 c.current_filter = 'unread'
96 elif _current_filter == [c.all_type]:
98 elif _current_filter == [c.all_type]:
97 c.current_filter = 'all'
99 c.current_filter = 'all'
98 return self._get_template_context(c)
100 return self._get_template_context(c)
99
101
100 @LoginRequired()
102 @LoginRequired()
101 @NotAnonymous()
103 @NotAnonymous()
102 def notifications_show(self):
104 def notifications_show(self):
103 c = self.load_default_context()
105 c = self.load_default_context()
104 notification_id = self.request.matchdict['notification_id']
106 notification_id = self.request.matchdict['notification_id']
105 notification = Notification.get_or_404(notification_id)
107 notification = Notification.get_or_404(notification_id)
106
108
107 if not self._has_permissions(notification):
109 if not self._has_permissions(notification):
108 log.debug('User %s does not have permission to access notification',
110 log.debug('User %s does not have permission to access notification',
109 self._rhodecode_user)
111 self._rhodecode_user)
110 raise HTTPNotFound()
112 raise HTTPNotFound()
111
113
112 u_notification = NotificationModel().get_user_notification(
114 u_notification = NotificationModel().get_user_notification(
113 self._rhodecode_db_user.user_id, notification)
115 self._rhodecode_db_user.user_id, notification)
114 if not u_notification:
116 if not u_notification:
115 log.debug('User %s notification does not exist',
117 log.debug('User %s notification does not exist',
116 self._rhodecode_user)
118 self._rhodecode_user)
117 raise HTTPNotFound()
119 raise HTTPNotFound()
118
120
119 # when opening this notification, mark it as read for this use
121 # when opening this notification, mark it as read for this use
120 if not u_notification.read:
122 if not u_notification.read:
121 u_notification.mark_as_read()
123 u_notification.mark_as_read()
122 Session().commit()
124 Session().commit()
123
125
124 c.notification = notification
126 c.notification = notification
125
127
126 return self._get_template_context(c)
128 return self._get_template_context(c)
127
129
128 @LoginRequired()
130 @LoginRequired()
129 @NotAnonymous()
131 @NotAnonymous()
130 @CSRFRequired()
132 @CSRFRequired()
131 def notifications_mark_all_read(self):
133 def notifications_mark_all_read(self):
132 NotificationModel().mark_all_read_for_user(
134 NotificationModel().mark_all_read_for_user(
133 self._rhodecode_db_user.user_id,
135 self._rhodecode_db_user.user_id,
134 filter_=self.request.GET.getall('type'))
136 filter_=self.request.GET.getall('type'))
135 Session().commit()
137 Session().commit()
136 raise HTTPFound(h.route_path('notifications_show_all'))
138 raise HTTPFound(h.route_path('notifications_show_all'))
137
139
138 @LoginRequired()
140 @LoginRequired()
139 @NotAnonymous()
141 @NotAnonymous()
140 @CSRFRequired()
142 @CSRFRequired()
141 def notification_update(self):
143 def notification_update(self):
142 notification_id = self.request.matchdict['notification_id']
144 notification_id = self.request.matchdict['notification_id']
143 notification = Notification.get_or_404(notification_id)
145 notification = Notification.get_or_404(notification_id)
144
146
145 if not self._has_permissions(notification):
147 if not self._has_permissions(notification):
146 log.debug('User %s does not have permission to access notification',
148 log.debug('User %s does not have permission to access notification',
147 self._rhodecode_user)
149 self._rhodecode_user)
148 raise HTTPNotFound()
150 raise HTTPNotFound()
149
151
150 try:
152 try:
151 # updates notification read flag
153 # updates notification read flag
152 NotificationModel().mark_read(
154 NotificationModel().mark_read(
153 self._rhodecode_user.user_id, notification)
155 self._rhodecode_user.user_id, notification)
154 Session().commit()
156 Session().commit()
155 return 'ok'
157 return 'ok'
156 except Exception:
158 except Exception:
157 Session().rollback()
159 Session().rollback()
158 log.exception("Exception updating a notification item")
160 log.exception("Exception updating a notification item")
159
161
160 raise HTTPInternalServerError()
162 raise HTTPInternalServerError()
161
163
162 @LoginRequired()
164 @LoginRequired()
163 @NotAnonymous()
165 @NotAnonymous()
164 @CSRFRequired()
166 @CSRFRequired()
165 def notification_delete(self):
167 def notification_delete(self):
166 notification_id = self.request.matchdict['notification_id']
168 notification_id = self.request.matchdict['notification_id']
167 notification = Notification.get_or_404(notification_id)
169 notification = Notification.get_or_404(notification_id)
168 if not self._has_permissions(notification):
170 if not self._has_permissions(notification):
169 log.debug('User %s does not have permission to access notification',
171 log.debug('User %s does not have permission to access notification',
170 self._rhodecode_user)
172 self._rhodecode_user)
171 raise HTTPNotFound()
173 raise HTTPNotFound()
172
174
173 try:
175 try:
174 # deletes only notification2user
176 # deletes only notification2user
175 NotificationModel().delete(
177 NotificationModel().delete(
176 self._rhodecode_user.user_id, notification)
178 self._rhodecode_user.user_id, notification)
177 Session().commit()
179 Session().commit()
178 return 'ok'
180 return 'ok'
179 except Exception:
181 except Exception:
180 Session().rollback()
182 Session().rollback()
181 log.exception("Exception deleting a notification item")
183 log.exception("Exception deleting a notification item")
182
184
183 raise HTTPInternalServerError()
185 raise HTTPInternalServerError()
General Comments 0
You need to be logged in to leave comments. Login now