##// END OF EJS Templates
notifications: fixed problem with 500 errors on non-numeric...
marcink -
r1812:7d0f908d default
parent child Browse files
Show More
@@ -1,178 +1,157 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 """
22 """
23 notifications controller for RhodeCode
23 notifications controller for RhodeCode
24 """
24 """
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28
28
29 from pylons import request
29 from pylons import request
30 from pylons import tmpl_context as c, url
30 from pylons import tmpl_context as c, url
31 from pylons.controllers.util import redirect, abort
31 from pylons.controllers.util import redirect, abort
32 import webhelpers.paginate
32 import webhelpers.paginate
33 from webob.exc import HTTPBadRequest
33 from webob.exc import HTTPBadRequest
34
34
35 from rhodecode.lib import auth
35 from rhodecode.lib import auth
36 from rhodecode.lib.auth import LoginRequired, NotAnonymous
36 from rhodecode.lib.auth import LoginRequired, NotAnonymous
37 from rhodecode.lib.base import BaseController, render
37 from rhodecode.lib.base import BaseController, render
38 from rhodecode.lib import helpers as h
38 from rhodecode.lib import helpers as h
39 from rhodecode.lib.helpers import Page
39 from rhodecode.lib.helpers import Page
40 from rhodecode.lib.utils2 import safe_int
40 from rhodecode.lib.utils2 import safe_int
41 from rhodecode.model.db import Notification
41 from rhodecode.model.db import Notification
42 from rhodecode.model.notification import NotificationModel
42 from rhodecode.model.notification import NotificationModel
43 from rhodecode.model.meta import Session
43 from rhodecode.model.meta import Session
44
44
45
45
46 log = logging.getLogger(__name__)
46 log = logging.getLogger(__name__)
47
47
48
48
49 class NotificationsController(BaseController):
49 class NotificationsController(BaseController):
50 """REST Controller styled on the Atom Publishing Protocol"""
50 """REST Controller styled on the Atom Publishing Protocol"""
51 # To properly map this controller, ensure your config/routing.py
52 # file has a resource setup:
53 # map.resource('notification', 'notifications', controller='_admin/notifications',
54 # path_prefix='/_admin', name_prefix='_admin_')
55
51
56 @LoginRequired()
52 @LoginRequired()
57 @NotAnonymous()
53 @NotAnonymous()
58 def __before__(self):
54 def __before__(self):
59 super(NotificationsController, self).__before__()
55 super(NotificationsController, self).__before__()
60
56
61 def index(self):
57 def index(self):
62 """GET /_admin/notifications: All items in the collection"""
58 """GET /_admin/notifications: All items in the collection"""
63 # url('notifications')
59 # url('notifications')
64 c.user = c.rhodecode_user
60 c.user = c.rhodecode_user
65 notif = NotificationModel().get_for_user(c.rhodecode_user.user_id,
61 notif = NotificationModel().get_for_user(
66 filter_=request.GET.getall('type'))
62 c.rhodecode_user.user_id, filter_=request.GET.getall('type'))
67
63
68 p = safe_int(request.GET.get('page', 1), 1)
64 p = safe_int(request.GET.get('page', 1), 1)
69 notifications_url = webhelpers.paginate.PageURL(
65 notifications_url = webhelpers.paginate.PageURL(
70 url('notifications'), request.GET)
66 url('notifications'), request.GET)
71 c.notifications = Page(notif, page=p, items_per_page=10,
67 c.notifications = Page(notif, page=p, items_per_page=10,
72 url=notifications_url)
68 url=notifications_url)
73 c.pull_request_type = Notification.TYPE_PULL_REQUEST
69 c.pull_request_type = Notification.TYPE_PULL_REQUEST
74 c.comment_type = [Notification.TYPE_CHANGESET_COMMENT,
70 c.comment_type = [Notification.TYPE_CHANGESET_COMMENT,
75 Notification.TYPE_PULL_REQUEST_COMMENT]
71 Notification.TYPE_PULL_REQUEST_COMMENT]
76
72
77 _current_filter = request.GET.getall('type')
73 _current_filter = request.GET.getall('type')
78 c.current_filter = 'all'
74 c.current_filter = 'all'
79 if _current_filter == [c.pull_request_type]:
75 if _current_filter == [c.pull_request_type]:
80 c.current_filter = 'pull_request'
76 c.current_filter = 'pull_request'
81 elif _current_filter == c.comment_type:
77 elif _current_filter == c.comment_type:
82 c.current_filter = 'comment'
78 c.current_filter = 'comment'
83
79
84 if request.is_xhr:
80 if request.is_xhr:
85 return render('admin/notifications/notifications_data.mako')
81 return render('admin/notifications/notifications_data.mako')
86
82
87 return render('admin/notifications/notifications.mako')
83 return render('admin/notifications/notifications.mako')
88
84
89
90 @auth.CSRFRequired()
85 @auth.CSRFRequired()
91 def mark_all_read(self):
86 def mark_all_read(self):
92 if request.is_xhr:
87 if request.is_xhr:
93 nm = NotificationModel()
88 nm = NotificationModel()
94 # mark all read
89 # mark all read
95 nm.mark_all_read_for_user(c.rhodecode_user.user_id,
90 nm.mark_all_read_for_user(c.rhodecode_user.user_id,
96 filter_=request.GET.getall('type'))
91 filter_=request.GET.getall('type'))
97 Session().commit()
92 Session().commit()
98 c.user = c.rhodecode_user
93 c.user = c.rhodecode_user
99 notif = nm.get_for_user(c.rhodecode_user.user_id,
94 notif = nm.get_for_user(c.rhodecode_user.user_id,
100 filter_=request.GET.getall('type'))
95 filter_=request.GET.getall('type'))
101 notifications_url = webhelpers.paginate.PageURL(
96 notifications_url = webhelpers.paginate.PageURL(
102 url('notifications'), request.GET)
97 url('notifications'), request.GET)
103 c.notifications = Page(notif, page=1, items_per_page=10,
98 c.notifications = Page(notif, page=1, items_per_page=10,
104 url=notifications_url)
99 url=notifications_url)
105 return render('admin/notifications/notifications_data.mako')
100 return render('admin/notifications/notifications_data.mako')
106
101
107 def _has_permissions(self, notification):
102 def _has_permissions(self, notification):
108 def is_owner():
103 def is_owner():
109 user_id = c.rhodecode_user.user_id
104 user_id = c.rhodecode_user.user_id
110 for user_notification in notification.notifications_to_users:
105 for user_notification in notification.notifications_to_users:
111 if user_notification.user.user_id == user_id:
106 if user_notification.user.user_id == user_id:
112 return True
107 return True
113 return False
108 return False
114 return h.HasPermissionAny('hg.admin')() or is_owner()
109 return h.HasPermissionAny('hg.admin')() or is_owner()
115
110
116 @auth.CSRFRequired()
111 @auth.CSRFRequired()
117 def update(self, notification_id):
112 def update(self, notification_id):
118 """PUT /_admin/notifications/id: Update an existing item"""
113 no = Notification.get_or_404(notification_id)
119 # Forms posted to this method should contain a hidden field:
120 # <input type="hidden" name="_method" value="PUT" />
121 # Or using helpers:
122 # h.form(url('notification', notification_id=ID),
123 # method='put')
124 # url('notification', notification_id=ID)
125 try:
114 try:
126 no = Notification.get(notification_id)
127 if self._has_permissions(no):
115 if self._has_permissions(no):
128 # deletes only notification2user
116 # deletes only notification2user
129 NotificationModel().mark_read(c.rhodecode_user.user_id, no)
117 NotificationModel().mark_read(c.rhodecode_user.user_id, no)
130 Session().commit()
118 Session().commit()
131 return 'ok'
119 return 'ok'
132 except Exception:
120 except Exception:
133 Session().rollback()
121 Session().rollback()
134 log.exception("Exception updating a notification item")
122 log.exception("Exception updating a notification item")
135 raise HTTPBadRequest()
123 raise HTTPBadRequest()
136
124
137 @auth.CSRFRequired()
125 @auth.CSRFRequired()
138 def delete(self, notification_id):
126 def delete(self, notification_id):
139 """DELETE /_admin/notifications/id: Delete an existing item"""
127 no = Notification.get_or_404(notification_id)
140 # Forms posted to this method should contain a hidden field:
141 # <input type="hidden" name="_method" value="DELETE" />
142 # Or using helpers:
143 # h.form(url('notification', notification_id=ID),
144 # method='delete')
145 # url('notification', notification_id=ID)
146 try:
128 try:
147 no = Notification.get(notification_id)
148 if self._has_permissions(no):
129 if self._has_permissions(no):
149 # deletes only notification2user
130 # deletes only notification2user
150 NotificationModel().delete(c.rhodecode_user.user_id, no)
131 NotificationModel().delete(c.rhodecode_user.user_id, no)
151 Session().commit()
132 Session().commit()
152 return 'ok'
133 return 'ok'
153 except Exception:
134 except Exception:
154 Session().rollback()
135 Session().rollback()
155 log.exception("Exception deleting a notification item")
136 log.exception("Exception deleting a notification item")
156 raise HTTPBadRequest()
137 raise HTTPBadRequest()
157
138
158 def show(self, notification_id):
139 def show(self, notification_id):
159 """GET /_admin/notifications/id: Show a specific item"""
160 # url('notification', notification_id=ID)
161 c.user = c.rhodecode_user
140 c.user = c.rhodecode_user
162 no = Notification.get(notification_id)
141 no = Notification.get_or_404(notification_id)
163
142
164 if no and self._has_permissions(no):
143 if no and self._has_permissions(no):
165 unotification = NotificationModel()\
144 unotification = NotificationModel()\
166 .get_user_notification(c.user.user_id, no)
145 .get_user_notification(c.user.user_id, no)
167
146
168 # if this association to user is not valid, we don't want to show
147 # if this association to user is not valid, we don't want to show
169 # this message
148 # this message
170 if unotification:
149 if unotification:
171 if not unotification.read:
150 if not unotification.read:
172 unotification.mark_as_read()
151 unotification.mark_as_read()
173 Session().commit()
152 Session().commit()
174 c.notification = no
153 c.notification = no
175
154
176 return render('admin/notifications/show_notification.mako')
155 return render('admin/notifications/show_notification.mako')
177
156
178 return abort(403)
157 return abort(403)
General Comments 0
You need to be logged in to leave comments. Login now