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)