Mercurial > kallithea
comparison rhodecode/controllers/admin/gists.py @ 3840:dc4644865e8b beta
Implemented simple gist functionality ref #530.
- creation of public/private gists with given lifetime
- rhodecode-gist CLI for quick gist creation
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sat, 11 May 2013 20:24:02 +0200 |
parents | |
children | ad4a680113b7 |
comparison
equal
deleted
inserted
replaced
3839:9dec870411e0 | 3840:dc4644865e8b |
---|---|
1 # -*- coding: utf-8 -*- | |
2 """ | |
3 rhodecode.controllers.admin.gist | |
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
5 | |
6 gist controller for RhodeCode | |
7 | |
8 :created_on: May 9, 2013 | |
9 :author: marcink | |
10 :copyright: (C) 2010-2013 Marcin Kuzminski <marcin@python-works.com> | |
11 :license: GPLv3, see COPYING for more details. | |
12 """ | |
13 # This program is free software: you can redistribute it and/or modify | |
14 # it under the terms of the GNU General Public License as published by | |
15 # the Free Software Foundation, either version 3 of the License, or | |
16 # (at your option) any later version. | |
17 # | |
18 # This program is distributed in the hope that it will be useful, | |
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 # GNU General Public License for more details. | |
22 # | |
23 # You should have received a copy of the GNU General Public License | |
24 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25 import time | |
26 import logging | |
27 import traceback | |
28 import formencode | |
29 from formencode import htmlfill | |
30 | |
31 from pylons import request, tmpl_context as c, url | |
32 from pylons.controllers.util import abort, redirect | |
33 from pylons.i18n.translation import _ | |
34 | |
35 from rhodecode.model.forms import GistForm | |
36 from rhodecode.model.gist import GistModel | |
37 from rhodecode.model.meta import Session | |
38 from rhodecode.model.db import Gist | |
39 from rhodecode.lib import helpers as h | |
40 from rhodecode.lib.base import BaseController, render | |
41 from rhodecode.lib.auth import LoginRequired, NotAnonymous | |
42 from rhodecode.lib.utils2 import safe_str, safe_int, time_to_datetime | |
43 from rhodecode.lib.helpers import Page | |
44 from webob.exc import HTTPNotFound | |
45 from sqlalchemy.sql.expression import or_ | |
46 from rhodecode.lib.vcs.exceptions import VCSError | |
47 | |
48 log = logging.getLogger(__name__) | |
49 | |
50 | |
51 class GistsController(BaseController): | |
52 """REST Controller styled on the Atom Publishing Protocol""" | |
53 | |
54 def __load_defaults(self): | |
55 c.lifetime_values = [ | |
56 (str(-1), _('forever')), | |
57 (str(5), _('5 minutes')), | |
58 (str(60), _('1 hour')), | |
59 (str(60 * 24), _('1 day')), | |
60 (str(60 * 24 * 30), _('1 month')), | |
61 ] | |
62 c.lifetime_options = [(c.lifetime_values, _("Lifetime"))] | |
63 | |
64 @LoginRequired() | |
65 def index(self, format='html'): | |
66 """GET /admin/gists: All items in the collection""" | |
67 # url('gists') | |
68 c.show_private = request.GET.get('private') and c.rhodecode_user.username != 'default' | |
69 gists = Gist().query()\ | |
70 .filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time()))\ | |
71 .order_by(Gist.created_on.desc()) | |
72 if c.show_private: | |
73 c.gists = gists.filter(Gist.gist_type == Gist.GIST_PRIVATE)\ | |
74 .filter(Gist.gist_owner == c.rhodecode_user.user_id) | |
75 else: | |
76 c.gists = gists.filter(Gist.gist_type == Gist.GIST_PUBLIC) | |
77 p = safe_int(request.GET.get('page', 1), 1) | |
78 c.gists_pager = Page(c.gists, page=p, items_per_page=10) | |
79 return render('admin/gists/index.html') | |
80 | |
81 @LoginRequired() | |
82 @NotAnonymous() | |
83 def create(self): | |
84 """POST /admin/gists: Create a new item""" | |
85 # url('gists') | |
86 self.__load_defaults() | |
87 gist_form = GistForm([x[0] for x in c.lifetime_values])() | |
88 try: | |
89 form_result = gist_form.to_python(dict(request.POST)) | |
90 #TODO: multiple files support, from the form | |
91 nodes = { | |
92 form_result['filename'] or 'gistfile1.txt': { | |
93 'content': form_result['content'], | |
94 'lexer': None # autodetect | |
95 } | |
96 } | |
97 _public = form_result['public'] | |
98 gist_type = Gist.GIST_PUBLIC if _public else Gist.GIST_PRIVATE | |
99 gist = GistModel().create( | |
100 description=form_result['description'], | |
101 owner=c.rhodecode_user, | |
102 gist_mapping=nodes, | |
103 gist_type=gist_type, | |
104 lifetime=form_result['lifetime'] | |
105 ) | |
106 Session().commit() | |
107 new_gist_id = gist.gist_access_id | |
108 except formencode.Invalid, errors: | |
109 defaults = errors.value | |
110 | |
111 return formencode.htmlfill.render( | |
112 render('admin/gists/new.html'), | |
113 defaults=defaults, | |
114 errors=errors.error_dict or {}, | |
115 prefix_error=False, | |
116 encoding="UTF-8" | |
117 ) | |
118 | |
119 except Exception, e: | |
120 log.error(traceback.format_exc()) | |
121 h.flash(_('Error occurred during gist creation'), category='error') | |
122 return redirect(url('new_gist')) | |
123 return redirect(url('gist', id=new_gist_id)) | |
124 | |
125 @LoginRequired() | |
126 @NotAnonymous() | |
127 def new(self, format='html'): | |
128 """GET /admin/gists/new: Form to create a new item""" | |
129 # url('new_gist') | |
130 self.__load_defaults() | |
131 return render('admin/gists/new.html') | |
132 | |
133 @LoginRequired() | |
134 @NotAnonymous() | |
135 def update(self, id): | |
136 """PUT /admin/gists/id: Update an existing item""" | |
137 # Forms posted to this method should contain a hidden field: | |
138 # <input type="hidden" name="_method" value="PUT" /> | |
139 # Or using helpers: | |
140 # h.form(url('gist', id=ID), | |
141 # method='put') | |
142 # url('gist', id=ID) | |
143 | |
144 @LoginRequired() | |
145 @NotAnonymous() | |
146 def delete(self, id): | |
147 """DELETE /admin/gists/id: Delete an existing item""" | |
148 # Forms posted to this method should contain a hidden field: | |
149 # <input type="hidden" name="_method" value="DELETE" /> | |
150 # Or using helpers: | |
151 # h.form(url('gist', id=ID), | |
152 # method='delete') | |
153 # url('gist', id=ID) | |
154 | |
155 @LoginRequired() | |
156 def show(self, id, format='html'): | |
157 """GET /admin/gists/id: Show a specific item""" | |
158 # url('gist', id=ID) | |
159 gist_id = id | |
160 c.gist = Gist.get_or_404(gist_id) | |
161 | |
162 #check if this gist is not expired | |
163 if c.gist.gist_expires != -1: | |
164 if time.time() > c.gist.gist_expires: | |
165 log.error('Gist expired at %s' % | |
166 (time_to_datetime(c.gist.gist_expires))) | |
167 raise HTTPNotFound() | |
168 try: | |
169 c.file_changeset, c.files = GistModel().get_gist_files(gist_id) | |
170 except VCSError: | |
171 log.error(traceback.format_exc()) | |
172 raise HTTPNotFound() | |
173 | |
174 return render('admin/gists/show.html') | |
175 | |
176 @LoginRequired() | |
177 @NotAnonymous() | |
178 def edit(self, id, format='html'): | |
179 """GET /admin/gists/id/edit: Form to edit an existing item""" | |
180 # url('edit_gist', id=ID) |