##// END OF EJS Templates
gists: fixed translation for age component which uses pyramid translate component.
marcink -
r1346:b11e64ec default
parent child Browse files
Show More
@@ -1,365 +1,369 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2013-2017 RhodeCode GmbH
3 # Copyright (C) 2013-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 gist controller for RhodeCode
23 gist controller for RhodeCode
24 """
24 """
25
25
26 import time
26 import time
27 import logging
27 import logging
28
28
29 import formencode
29 import formencode
30 import peppercorn
30 import peppercorn
31
31
32 from pylons import request, response, tmpl_context as c, url
32 from pylons import request, response, tmpl_context as c, url
33 from pylons.controllers.util import redirect
33 from pylons.controllers.util import redirect
34 from pylons.i18n.translation import _
34 from pylons.i18n.translation import _
35 from webob.exc import HTTPNotFound, HTTPForbidden
35 from webob.exc import HTTPNotFound, HTTPForbidden
36 from sqlalchemy.sql.expression import or_
36 from sqlalchemy.sql.expression import or_
37
37
38
38
39 from rhodecode.model.gist import GistModel
39 from rhodecode.model.gist import GistModel
40 from rhodecode.model.meta import Session
40 from rhodecode.model.meta import Session
41 from rhodecode.model.db import Gist, User
41 from rhodecode.model.db import Gist, User
42 from rhodecode.lib import auth
42 from rhodecode.lib import auth
43 from rhodecode.lib import helpers as h
43 from rhodecode.lib import helpers as h
44 from rhodecode.lib.base import BaseController, render
44 from rhodecode.lib.base import BaseController, render
45 from rhodecode.lib.auth import LoginRequired, NotAnonymous
45 from rhodecode.lib.auth import LoginRequired, NotAnonymous
46 from rhodecode.lib.utils import jsonify
46 from rhodecode.lib.utils import jsonify
47 from rhodecode.lib.utils2 import time_to_datetime
47 from rhodecode.lib.utils2 import time_to_datetime
48 from rhodecode.lib.ext_json import json
48 from rhodecode.lib.ext_json import json
49 from rhodecode.lib.vcs.exceptions import VCSError, NodeNotChangedError
49 from rhodecode.lib.vcs.exceptions import VCSError, NodeNotChangedError
50 from rhodecode.model import validation_schema
50 from rhodecode.model import validation_schema
51 from rhodecode.model.validation_schema.schemas import gist_schema
51 from rhodecode.model.validation_schema.schemas import gist_schema
52
52
53
53
54 log = logging.getLogger(__name__)
54 log = logging.getLogger(__name__)
55
55
56
56
57 class GistsController(BaseController):
57 class GistsController(BaseController):
58 """REST Controller styled on the Atom Publishing Protocol"""
58 """REST Controller styled on the Atom Publishing Protocol"""
59
59
60 def __load_defaults(self, extra_values=None):
60 def __load_defaults(self, extra_values=None):
61 c.lifetime_values = [
61 c.lifetime_values = [
62 (-1, _('forever')),
62 (-1, _('forever')),
63 (5, _('5 minutes')),
63 (5, _('5 minutes')),
64 (60, _('1 hour')),
64 (60, _('1 hour')),
65 (60 * 24, _('1 day')),
65 (60 * 24, _('1 day')),
66 (60 * 24 * 30, _('1 month')),
66 (60 * 24 * 30, _('1 month')),
67 ]
67 ]
68 if extra_values:
68 if extra_values:
69 c.lifetime_values.append(extra_values)
69 c.lifetime_values.append(extra_values)
70 c.lifetime_options = [(c.lifetime_values, _("Lifetime"))]
70 c.lifetime_options = [(c.lifetime_values, _("Lifetime"))]
71 c.acl_options = [
71 c.acl_options = [
72 (Gist.ACL_LEVEL_PRIVATE, _("Requires registered account")),
72 (Gist.ACL_LEVEL_PRIVATE, _("Requires registered account")),
73 (Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users"))
73 (Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users"))
74 ]
74 ]
75
75
76 @LoginRequired()
76 @LoginRequired()
77 def index(self):
77 def index(self):
78 """GET /admin/gists: All items in the collection"""
78 """GET /admin/gists: All items in the collection"""
79 # url('gists')
79 # url('gists')
80 not_default_user = c.rhodecode_user.username != User.DEFAULT_USER
80 not_default_user = c.rhodecode_user.username != User.DEFAULT_USER
81 c.show_private = request.GET.get('private') and not_default_user
81 c.show_private = request.GET.get('private') and not_default_user
82 c.show_public = request.GET.get('public') and not_default_user
82 c.show_public = request.GET.get('public') and not_default_user
83 c.show_all = request.GET.get('all') and c.rhodecode_user.admin
83 c.show_all = request.GET.get('all') and c.rhodecode_user.admin
84
84
85 gists = _gists = Gist().query()\
85 gists = _gists = Gist().query()\
86 .filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time()))\
86 .filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time()))\
87 .order_by(Gist.created_on.desc())
87 .order_by(Gist.created_on.desc())
88
88
89 c.active = 'public'
89 c.active = 'public'
90 # MY private
90 # MY private
91 if c.show_private and not c.show_public:
91 if c.show_private and not c.show_public:
92 gists = _gists.filter(Gist.gist_type == Gist.GIST_PRIVATE)\
92 gists = _gists.filter(Gist.gist_type == Gist.GIST_PRIVATE)\
93 .filter(Gist.gist_owner == c.rhodecode_user.user_id)
93 .filter(Gist.gist_owner == c.rhodecode_user.user_id)
94 c.active = 'my_private'
94 c.active = 'my_private'
95 # MY public
95 # MY public
96 elif c.show_public and not c.show_private:
96 elif c.show_public and not c.show_private:
97 gists = _gists.filter(Gist.gist_type == Gist.GIST_PUBLIC)\
97 gists = _gists.filter(Gist.gist_type == Gist.GIST_PUBLIC)\
98 .filter(Gist.gist_owner == c.rhodecode_user.user_id)
98 .filter(Gist.gist_owner == c.rhodecode_user.user_id)
99 c.active = 'my_public'
99 c.active = 'my_public'
100 # MY public+private
100 # MY public+private
101 elif c.show_private and c.show_public:
101 elif c.show_private and c.show_public:
102 gists = _gists.filter(or_(Gist.gist_type == Gist.GIST_PUBLIC,
102 gists = _gists.filter(or_(Gist.gist_type == Gist.GIST_PUBLIC,
103 Gist.gist_type == Gist.GIST_PRIVATE))\
103 Gist.gist_type == Gist.GIST_PRIVATE))\
104 .filter(Gist.gist_owner == c.rhodecode_user.user_id)
104 .filter(Gist.gist_owner == c.rhodecode_user.user_id)
105 c.active = 'my_all'
105 c.active = 'my_all'
106 # Show all by super-admin
106 # Show all by super-admin
107 elif c.show_all:
107 elif c.show_all:
108 c.active = 'all'
108 c.active = 'all'
109 gists = _gists
109 gists = _gists
110
110
111 # default show ALL public gists
111 # default show ALL public gists
112 if not c.show_public and not c.show_private and not c.show_all:
112 if not c.show_public and not c.show_private and not c.show_all:
113 gists = _gists.filter(Gist.gist_type == Gist.GIST_PUBLIC)
113 gists = _gists.filter(Gist.gist_type == Gist.GIST_PUBLIC)
114 c.active = 'public'
114 c.active = 'public'
115
115
116 from rhodecode.lib.utils import PartialRenderer
116 from rhodecode.lib.utils import PartialRenderer
117 _render = PartialRenderer('data_table/_dt_elements.mako')
117 _render = PartialRenderer('data_table/_dt_elements.mako')
118
118
119 data = []
119 data = []
120
120
121 for gist in gists:
121 for gist in gists:
122 data.append({
122 data.append({
123 'created_on': _render('gist_created', gist.created_on),
123 'created_on': _render('gist_created', gist.created_on),
124 'created_on_raw': gist.created_on,
124 'created_on_raw': gist.created_on,
125 'type': _render('gist_type', gist.gist_type),
125 'type': _render('gist_type', gist.gist_type),
126 'access_id': _render('gist_access_id', gist.gist_access_id, gist.owner.full_contact),
126 'access_id': _render('gist_access_id', gist.gist_access_id, gist.owner.full_contact),
127 'author': _render('gist_author', gist.owner.full_contact, gist.created_on, gist.gist_expires),
127 'author': _render('gist_author', gist.owner.full_contact, gist.created_on, gist.gist_expires),
128 'author_raw': h.escape(gist.owner.full_contact),
128 'author_raw': h.escape(gist.owner.full_contact),
129 'expires': _render('gist_expires', gist.gist_expires),
129 'expires': _render('gist_expires', gist.gist_expires),
130 'description': _render('gist_description', gist.gist_description)
130 'description': _render('gist_description', gist.gist_description)
131 })
131 })
132 c.data = json.dumps(data)
132 c.data = json.dumps(data)
133 return render('admin/gists/index.mako')
133 return render('admin/gists/index.mako')
134
134
135 @LoginRequired()
135 @LoginRequired()
136 @NotAnonymous()
136 @NotAnonymous()
137 @auth.CSRFRequired()
137 @auth.CSRFRequired()
138 def create(self):
138 def create(self):
139 """POST /admin/gists: Create a new item"""
139 """POST /admin/gists: Create a new item"""
140 # url('gists')
140 # url('gists')
141 self.__load_defaults()
141 self.__load_defaults()
142
142
143 data = dict(request.POST)
143 data = dict(request.POST)
144 data['filename'] = data.get('filename') or Gist.DEFAULT_FILENAME
144 data['filename'] = data.get('filename') or Gist.DEFAULT_FILENAME
145 data['nodes'] = [{
145 data['nodes'] = [{
146 'filename': data['filename'],
146 'filename': data['filename'],
147 'content': data.get('content'),
147 'content': data.get('content'),
148 'mimetype': data.get('mimetype') # None is autodetect
148 'mimetype': data.get('mimetype') # None is autodetect
149 }]
149 }]
150
150
151 data['gist_type'] = (
151 data['gist_type'] = (
152 Gist.GIST_PUBLIC if data.get('public') else Gist.GIST_PRIVATE)
152 Gist.GIST_PUBLIC if data.get('public') else Gist.GIST_PRIVATE)
153 data['gist_acl_level'] = (
153 data['gist_acl_level'] = (
154 data.get('gist_acl_level') or Gist.ACL_LEVEL_PRIVATE)
154 data.get('gist_acl_level') or Gist.ACL_LEVEL_PRIVATE)
155
155
156 schema = gist_schema.GistSchema().bind(
156 schema = gist_schema.GistSchema().bind(
157 lifetime_options=[x[0] for x in c.lifetime_values])
157 lifetime_options=[x[0] for x in c.lifetime_values])
158
158
159 try:
159 try:
160
160
161 schema_data = schema.deserialize(data)
161 schema_data = schema.deserialize(data)
162 # convert to safer format with just KEYs so we sure no duplicates
162 # convert to safer format with just KEYs so we sure no duplicates
163 schema_data['nodes'] = gist_schema.sequence_to_nodes(
163 schema_data['nodes'] = gist_schema.sequence_to_nodes(
164 schema_data['nodes'])
164 schema_data['nodes'])
165
165
166 gist = GistModel().create(
166 gist = GistModel().create(
167 gist_id=schema_data['gistid'], # custom access id not real ID
167 gist_id=schema_data['gistid'], # custom access id not real ID
168 description=schema_data['description'],
168 description=schema_data['description'],
169 owner=c.rhodecode_user.user_id,
169 owner=c.rhodecode_user.user_id,
170 gist_mapping=schema_data['nodes'],
170 gist_mapping=schema_data['nodes'],
171 gist_type=schema_data['gist_type'],
171 gist_type=schema_data['gist_type'],
172 lifetime=schema_data['lifetime'],
172 lifetime=schema_data['lifetime'],
173 gist_acl_level=schema_data['gist_acl_level']
173 gist_acl_level=schema_data['gist_acl_level']
174 )
174 )
175 Session().commit()
175 Session().commit()
176 new_gist_id = gist.gist_access_id
176 new_gist_id = gist.gist_access_id
177 except validation_schema.Invalid as errors:
177 except validation_schema.Invalid as errors:
178 defaults = data
178 defaults = data
179 errors = errors.asdict()
179 errors = errors.asdict()
180
180
181 if 'nodes.0.content' in errors:
181 if 'nodes.0.content' in errors:
182 errors['content'] = errors['nodes.0.content']
182 errors['content'] = errors['nodes.0.content']
183 del errors['nodes.0.content']
183 del errors['nodes.0.content']
184 if 'nodes.0.filename' in errors:
184 if 'nodes.0.filename' in errors:
185 errors['filename'] = errors['nodes.0.filename']
185 errors['filename'] = errors['nodes.0.filename']
186 del errors['nodes.0.filename']
186 del errors['nodes.0.filename']
187
187
188 return formencode.htmlfill.render(
188 return formencode.htmlfill.render(
189 render('admin/gists/new.mako'),
189 render('admin/gists/new.mako'),
190 defaults=defaults,
190 defaults=defaults,
191 errors=errors,
191 errors=errors,
192 prefix_error=False,
192 prefix_error=False,
193 encoding="UTF-8",
193 encoding="UTF-8",
194 force_defaults=False
194 force_defaults=False
195 )
195 )
196
196
197 except Exception:
197 except Exception:
198 log.exception("Exception while trying to create a gist")
198 log.exception("Exception while trying to create a gist")
199 h.flash(_('Error occurred during gist creation'), category='error')
199 h.flash(_('Error occurred during gist creation'), category='error')
200 return redirect(url('new_gist'))
200 return redirect(url('new_gist'))
201 return redirect(url('gist', gist_id=new_gist_id))
201 return redirect(url('gist', gist_id=new_gist_id))
202
202
203 @LoginRequired()
203 @LoginRequired()
204 @NotAnonymous()
204 @NotAnonymous()
205 def new(self, format='html'):
205 def new(self):
206 """GET /admin/gists/new: Form to create a new item"""
206 """GET /admin/gists/new: Form to create a new item"""
207 # url('new_gist')
207 # url('new_gist')
208 self.__load_defaults()
208 self.__load_defaults()
209 return render('admin/gists/new.mako')
209 return render('admin/gists/new.mako')
210
210
211 @LoginRequired()
211 @LoginRequired()
212 @NotAnonymous()
212 @NotAnonymous()
213 @auth.CSRFRequired()
213 @auth.CSRFRequired()
214 def delete(self, gist_id):
214 def delete(self, gist_id):
215 """DELETE /admin/gists/gist_id: Delete an existing item"""
215 """DELETE /admin/gists/gist_id: Delete an existing item"""
216 # Forms posted to this method should contain a hidden field:
216 # Forms posted to this method should contain a hidden field:
217 # <input type="hidden" name="_method" value="DELETE" />
217 # <input type="hidden" name="_method" value="DELETE" />
218 # Or using helpers:
218 # Or using helpers:
219 # h.form(url('gist', gist_id=ID),
219 # h.form(url('gist', gist_id=ID),
220 # method='delete')
220 # method='delete')
221 # url('gist', gist_id=ID)
221 # url('gist', gist_id=ID)
222 c.gist = Gist.get_or_404(gist_id)
222 c.gist = Gist.get_or_404(gist_id)
223
223
224 owner = c.gist.gist_owner == c.rhodecode_user.user_id
224 owner = c.gist.gist_owner == c.rhodecode_user.user_id
225 if not (h.HasPermissionAny('hg.admin')() or owner):
225 if not (h.HasPermissionAny('hg.admin')() or owner):
226 raise HTTPForbidden()
226 raise HTTPForbidden()
227
227
228 GistModel().delete(c.gist)
228 GistModel().delete(c.gist)
229 Session().commit()
229 Session().commit()
230 h.flash(_('Deleted gist %s') % c.gist.gist_access_id, category='success')
230 h.flash(_('Deleted gist %s') % c.gist.gist_access_id, category='success')
231
231
232 return redirect(url('gists'))
232 return redirect(url('gists'))
233
233
234 def _add_gist_to_context(self, gist_id):
234 def _add_gist_to_context(self, gist_id):
235 c.gist = Gist.get_or_404(gist_id)
235 c.gist = Gist.get_or_404(gist_id)
236
236
237 # Check if this gist is expired
237 # Check if this gist is expired
238 if c.gist.gist_expires != -1:
238 if c.gist.gist_expires != -1:
239 if time.time() > c.gist.gist_expires:
239 if time.time() > c.gist.gist_expires:
240 log.error(
240 log.error(
241 'Gist expired at %s', time_to_datetime(c.gist.gist_expires))
241 'Gist expired at %s', time_to_datetime(c.gist.gist_expires))
242 raise HTTPNotFound()
242 raise HTTPNotFound()
243
243
244 # check if this gist requires a login
244 # check if this gist requires a login
245 is_default_user = c.rhodecode_user.username == User.DEFAULT_USER
245 is_default_user = c.rhodecode_user.username == User.DEFAULT_USER
246 if c.gist.acl_level == Gist.ACL_LEVEL_PRIVATE and is_default_user:
246 if c.gist.acl_level == Gist.ACL_LEVEL_PRIVATE and is_default_user:
247 log.error("Anonymous user %s tried to access protected gist `%s`",
247 log.error("Anonymous user %s tried to access protected gist `%s`",
248 c.rhodecode_user, gist_id)
248 c.rhodecode_user, gist_id)
249 raise HTTPNotFound()
249 raise HTTPNotFound()
250
250
251 @LoginRequired()
251 @LoginRequired()
252 def show(self, gist_id, revision='tip', format='html', f_path=None):
252 def show(self, gist_id, revision='tip', format='html', f_path=None):
253 """GET /admin/gists/gist_id: Show a specific item"""
253 """GET /admin/gists/gist_id: Show a specific item"""
254 # url('gist', gist_id=ID)
254 # url('gist', gist_id=ID)
255 self._add_gist_to_context(gist_id)
255 self._add_gist_to_context(gist_id)
256 c.render = not request.GET.get('no-render', False)
256 c.render = not request.GET.get('no-render', False)
257
257
258 try:
258 try:
259 c.file_last_commit, c.files = GistModel().get_gist_files(
259 c.file_last_commit, c.files = GistModel().get_gist_files(
260 gist_id, revision=revision)
260 gist_id, revision=revision)
261 except VCSError:
261 except VCSError:
262 log.exception("Exception in gist show")
262 log.exception("Exception in gist show")
263 raise HTTPNotFound()
263 raise HTTPNotFound()
264 if format == 'raw':
264 if format == 'raw':
265 content = '\n\n'.join([f.content for f in c.files
265 content = '\n\n'.join([f.content for f in c.files
266 if (f_path is None or f.path == f_path)])
266 if (f_path is None or f.path == f_path)])
267 response.content_type = 'text/plain'
267 response.content_type = 'text/plain'
268 return content
268 return content
269 return render('admin/gists/show.mako')
269 return render('admin/gists/show.mako')
270
270
271 @LoginRequired()
271 @LoginRequired()
272 @NotAnonymous()
272 @NotAnonymous()
273 @auth.CSRFRequired()
273 @auth.CSRFRequired()
274 def edit(self, gist_id):
274 def edit(self, gist_id):
275 self.__load_defaults()
275 self.__load_defaults()
276 self._add_gist_to_context(gist_id)
276 self._add_gist_to_context(gist_id)
277
277
278 owner = c.gist.gist_owner == c.rhodecode_user.user_id
278 owner = c.gist.gist_owner == c.rhodecode_user.user_id
279 if not (h.HasPermissionAny('hg.admin')() or owner):
279 if not (h.HasPermissionAny('hg.admin')() or owner):
280 raise HTTPForbidden()
280 raise HTTPForbidden()
281
281
282 data = peppercorn.parse(request.POST.items())
282 data = peppercorn.parse(request.POST.items())
283
283
284 schema = gist_schema.GistSchema()
284 schema = gist_schema.GistSchema()
285 schema = schema.bind(
285 schema = schema.bind(
286 # '0' is special value to leave lifetime untouched
286 # '0' is special value to leave lifetime untouched
287 lifetime_options=[x[0] for x in c.lifetime_values] + [0],
287 lifetime_options=[x[0] for x in c.lifetime_values] + [0],
288 )
288 )
289
289
290 try:
290 try:
291 schema_data = schema.deserialize(data)
291 schema_data = schema.deserialize(data)
292 # convert to safer format with just KEYs so we sure no duplicates
292 # convert to safer format with just KEYs so we sure no duplicates
293 schema_data['nodes'] = gist_schema.sequence_to_nodes(
293 schema_data['nodes'] = gist_schema.sequence_to_nodes(
294 schema_data['nodes'])
294 schema_data['nodes'])
295
295
296 GistModel().update(
296 GistModel().update(
297 gist=c.gist,
297 gist=c.gist,
298 description=schema_data['description'],
298 description=schema_data['description'],
299 owner=c.gist.owner,
299 owner=c.gist.owner,
300 gist_mapping=schema_data['nodes'],
300 gist_mapping=schema_data['nodes'],
301 lifetime=schema_data['lifetime'],
301 lifetime=schema_data['lifetime'],
302 gist_acl_level=schema_data['gist_acl_level']
302 gist_acl_level=schema_data['gist_acl_level']
303 )
303 )
304
304
305 Session().commit()
305 Session().commit()
306 h.flash(_('Successfully updated gist content'), category='success')
306 h.flash(_('Successfully updated gist content'), category='success')
307 except NodeNotChangedError:
307 except NodeNotChangedError:
308 # raised if nothing was changed in repo itself. We anyway then
308 # raised if nothing was changed in repo itself. We anyway then
309 # store only DB stuff for gist
309 # store only DB stuff for gist
310 Session().commit()
310 Session().commit()
311 h.flash(_('Successfully updated gist data'), category='success')
311 h.flash(_('Successfully updated gist data'), category='success')
312 except validation_schema.Invalid as errors:
312 except validation_schema.Invalid as errors:
313 errors = errors.asdict()
313 errors = errors.asdict()
314 h.flash(_('Error occurred during update of gist {}: {}').format(
314 h.flash(_('Error occurred during update of gist {}: {}').format(
315 gist_id, errors), category='error')
315 gist_id, errors), category='error')
316 except Exception:
316 except Exception:
317 log.exception("Exception in gist edit")
317 log.exception("Exception in gist edit")
318 h.flash(_('Error occurred during update of gist %s') % gist_id,
318 h.flash(_('Error occurred during update of gist %s') % gist_id,
319 category='error')
319 category='error')
320
320
321 return redirect(url('gist', gist_id=gist_id))
321 return redirect(url('gist', gist_id=gist_id))
322
322
323 @LoginRequired()
323 @LoginRequired()
324 @NotAnonymous()
324 @NotAnonymous()
325 def edit_form(self, gist_id, format='html'):
325 def edit_form(self, gist_id):
326 translate = _ = c.pyramid_request.translate
327
326 """GET /admin/gists/gist_id/edit: Form to edit an existing item"""
328 """GET /admin/gists/gist_id/edit: Form to edit an existing item"""
327 # url('edit_gist', gist_id=ID)
329 # url('edit_gist', gist_id=ID)
328 self._add_gist_to_context(gist_id)
330 self._add_gist_to_context(gist_id)
329
331
330 owner = c.gist.gist_owner == c.rhodecode_user.user_id
332 owner = c.gist.gist_owner == c.rhodecode_user.user_id
331 if not (h.HasPermissionAny('hg.admin')() or owner):
333 if not (h.HasPermissionAny('hg.admin')() or owner):
332 raise HTTPForbidden()
334 raise HTTPForbidden()
333
335
334 try:
336 try:
335 c.file_last_commit, c.files = GistModel().get_gist_files(gist_id)
337 c.file_last_commit, c.files = GistModel().get_gist_files(gist_id)
336 except VCSError:
338 except VCSError:
337 log.exception("Exception in gist edit")
339 log.exception("Exception in gist edit")
338 raise HTTPNotFound()
340 raise HTTPNotFound()
339
341
340 if c.gist.gist_expires == -1:
342 if c.gist.gist_expires == -1:
341 expiry = _('never')
343 expiry = _('never')
342 else:
344 else:
343 # this cannot use timeago, since it's used in select2 as a value
345 # this cannot use timeago, since it's used in select2 as a value
344 expiry = h.age(h.time_to_datetime(c.gist.gist_expires))
346 expiry = h.age(h.time_to_datetime(c.gist.gist_expires))
347
348 expiry = translate(expiry)
345 self.__load_defaults(
349 self.__load_defaults(
346 extra_values=(0, _('%(expiry)s - current value') % {'expiry': expiry}))
350 extra_values=(0, _('%(expiry)s - current value') % {'expiry': expiry}))
347 return render('admin/gists/edit.mako')
351 return render('admin/gists/edit.mako')
348
352
349 @LoginRequired()
353 @LoginRequired()
350 @NotAnonymous()
354 @NotAnonymous()
351 @jsonify
355 @jsonify
352 def check_revision(self, gist_id):
356 def check_revision(self, gist_id):
353 c.gist = Gist.get_or_404(gist_id)
357 c.gist = Gist.get_or_404(gist_id)
354 last_rev = c.gist.scm_instance().get_commit()
358 last_rev = c.gist.scm_instance().get_commit()
355 success = True
359 success = True
356 revision = request.GET.get('revision')
360 revision = request.GET.get('revision')
357
361
358 ##TODO: maybe move this to model ?
362 ##TODO: maybe move this to model ?
359 if revision != last_rev.raw_id:
363 if revision != last_rev.raw_id:
360 log.error('Last revision %s is different then submitted %s'
364 log.error('Last revision %s is different then submitted %s'
361 % (revision, last_rev))
365 % (revision, last_rev))
362 # our gist has newer version than we
366 # our gist has newer version than we
363 success = False
367 success = False
364
368
365 return {'success': success}
369 return {'success': success}
General Comments 0
You need to be logged in to leave comments. Login now