##// END OF EJS Templates
new improved models with helper functions for easier data fetching
marcink -
r832:634596f8 beta
parent child Browse files
Show More
@@ -1,313 +1,313
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.admin.repos
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Admin controller for RhodeCode
7 7
8 8 :created_on: Apr 7, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software; you can redistribute it and/or
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program; if not, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27
28 28 import logging
29 29 import traceback
30 30 import formencode
31 31 from operator import itemgetter
32 32 from formencode import htmlfill
33 33
34 34 from paste.httpexceptions import HTTPInternalServerError
35 35 from pylons import request, response, session, tmpl_context as c, url
36 36 from pylons.controllers.util import abort, redirect
37 37 from pylons.i18n.translation import _
38 38
39 39 from rhodecode.lib import helpers as h
40 40 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
41 41 HasPermissionAnyDecorator
42 42 from rhodecode.lib.base import BaseController, render
43 43 from rhodecode.lib.utils import invalidate_cache, action_logger
44 44 from rhodecode.model.db import User
45 45 from rhodecode.model.forms import RepoForm
46 46 from rhodecode.model.scm import ScmModel
47 47 from rhodecode.model.repo import RepoModel
48 48
49 49
50 50 log = logging.getLogger(__name__)
51 51
52 52 class ReposController(BaseController):
53 53 """REST Controller styled on the Atom Publishing Protocol"""
54 54 # To properly map this controller, ensure your config/routing.py
55 55 # file has a resource setup:
56 56 # map.resource('repo', 'repos')
57 57
58 58 @LoginRequired()
59 59 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
60 60 def __before__(self):
61 61 c.admin_user = session.get('admin_user')
62 62 c.admin_username = session.get('admin_username')
63 63 super(ReposController, self).__before__()
64 64
65 65 @HasPermissionAllDecorator('hg.admin')
66 66 def index(self, format='html'):
67 67 """GET /repos: All items in the collection"""
68 68 # url('repos')
69 69 cached_repo_list = ScmModel().get_repos()
70 70 c.repos_list = sorted(cached_repo_list, key=itemgetter('name_sort'))
71 71 return render('admin/repos/repos.html')
72 72
73 73 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
74 74 def create(self):
75 75 """POST /repos: Create a new item"""
76 76 # url('repos')
77 77 repo_model = RepoModel()
78 78 _form = RepoForm()()
79 79 form_result = {}
80 80 try:
81 81 form_result = _form.to_python(dict(request.POST))
82 82 repo_model.create(form_result, c.rhodecode_user)
83 83 h.flash(_('created repository %s') % form_result['repo_name'],
84 84 category='success')
85 85
86 86 if request.POST.get('user_created'):
87 87 action_logger(self.rhodecode_user, 'user_created_repo',
88 88 form_result['repo_name'], '', self.sa)
89 89 else:
90 90 action_logger(self.rhodecode_user, 'admin_created_repo',
91 91 form_result['repo_name'], '', self.sa)
92 92
93 93 except formencode.Invalid, errors:
94 94 c.new_repo = errors.value['repo_name']
95 95
96 96 if request.POST.get('user_created'):
97 97 r = render('admin/repos/repo_add_create_repository.html')
98 98 else:
99 99 r = render('admin/repos/repo_add.html')
100 100
101 101 return htmlfill.render(
102 102 r,
103 103 defaults=errors.value,
104 104 errors=errors.error_dict or {},
105 105 prefix_error=False,
106 106 encoding="UTF-8")
107 107
108 108 except Exception:
109 109 log.error(traceback.format_exc())
110 110 msg = _('error occured during creation of repository %s') \
111 111 % form_result.get('repo_name')
112 112 h.flash(msg, category='error')
113 113 if request.POST.get('user_created'):
114 114 return redirect(url('home'))
115 115 return redirect(url('repos'))
116 116
117 117 @HasPermissionAllDecorator('hg.admin')
118 118 def new(self, format='html'):
119 119 """GET /repos/new: Form to create a new item"""
120 120 new_repo = request.GET.get('repo', '')
121 121 c.new_repo = h.repo_name_slug(new_repo)
122 122
123 123 return render('admin/repos/repo_add.html')
124 124
125 125 @HasPermissionAllDecorator('hg.admin')
126 126 def update(self, repo_name):
127 127 """PUT /repos/repo_name: Update an existing item"""
128 128 # Forms posted to this method should contain a hidden field:
129 129 # <input type="hidden" name="_method" value="PUT" />
130 130 # Or using helpers:
131 131 # h.form(url('repo', repo_name=ID),
132 132 # method='put')
133 133 # url('repo', repo_name=ID)
134 134 repo_model = RepoModel()
135 135 changed_name = repo_name
136 136 _form = RepoForm(edit=True, old_data={'repo_name':repo_name})()
137 137
138 138 try:
139 139 form_result = _form.to_python(dict(request.POST))
140 140 repo_model.update(repo_name, form_result)
141 141 invalidate_cache('get_repo_cached_%s' % repo_name)
142 142 h.flash(_('Repository %s updated successfully' % repo_name),
143 143 category='success')
144 144 changed_name = form_result['repo_name']
145 145 action_logger(self.rhodecode_user, 'admin_updated_repo',
146 146 changed_name, '', self.sa)
147 147
148 148 except formencode.Invalid, errors:
149 149 c.repo_info = repo_model.get_by_repo_name(repo_name)
150 150 if c.repo_info.stats:
151 151 last_rev = c.repo_info.stats.stat_on_revision
152 152 else:
153 153 last_rev = 0
154 154 c.stats_revision = last_rev
155 155 r = ScmModel().get(repo_name)
156 156 c.repo_last_rev = r.revisions[-1] if r.revisions else 0
157 157
158 158 if last_rev == 0:
159 159 c.stats_percentage = 0
160 160 else:
161 161 c.stats_percentage = '%.2f' % ((float((last_rev)) /
162 162 c.repo_last_rev) * 100)
163 163
164 164 c.users_array = repo_model.get_users_js()
165 165 errors.value.update({'user':c.repo_info.user.username})
166 166 return htmlfill.render(
167 167 render('admin/repos/repo_edit.html'),
168 168 defaults=errors.value,
169 169 errors=errors.error_dict or {},
170 170 prefix_error=False,
171 171 encoding="UTF-8")
172 172
173 173 except Exception:
174 174 log.error(traceback.format_exc())
175 175 h.flash(_('error occurred during update of repository %s') \
176 176 % repo_name, category='error')
177 177
178 178 return redirect(url('edit_repo', repo_name=changed_name))
179 179
180 180 @HasPermissionAllDecorator('hg.admin')
181 181 def delete(self, repo_name):
182 182 """DELETE /repos/repo_name: Delete an existing item"""
183 183 # Forms posted to this method should contain a hidden field:
184 184 # <input type="hidden" name="_method" value="DELETE" />
185 185 # Or using helpers:
186 186 # h.form(url('repo', repo_name=ID),
187 187 # method='delete')
188 188 # url('repo', repo_name=ID)
189 189
190 190 repo_model = RepoModel()
191 191 repo = repo_model.get_by_repo_name(repo_name)
192 192 if not repo:
193 193 h.flash(_('%s repository is not mapped to db perhaps'
194 194 ' it was moved or renamed from the filesystem'
195 195 ' please run the application again'
196 196 ' in order to rescan repositories') % repo_name,
197 197 category='error')
198 198
199 199 return redirect(url('repos'))
200 200 try:
201 201 action_logger(self.rhodecode_user, 'admin_deleted_repo',
202 202 repo_name, '', self.sa)
203 203 repo_model.delete(repo)
204 204 invalidate_cache('get_repo_cached_%s' % repo_name)
205 205 h.flash(_('deleted repository %s') % repo_name, category='success')
206 206
207 207 except Exception, e:
208 208 log.error(traceback.format_exc())
209 209 h.flash(_('An error occured during deletion of %s') % repo_name,
210 210 category='error')
211 211
212 212 return redirect(url('repos'))
213 213
214 214 @HasPermissionAllDecorator('hg.admin')
215 215 def delete_perm_user(self, repo_name):
216 216 """
217 217 DELETE an existing repository permission user
218 218 :param repo_name:
219 219 """
220 220
221 221 try:
222 222 repo_model = RepoModel()
223 223 repo_model.delete_perm_user(request.POST, repo_name)
224 224 except Exception, e:
225 225 h.flash(_('An error occured during deletion of repository user'),
226 226 category='error')
227 227 raise HTTPInternalServerError()
228 228
229 229 @HasPermissionAllDecorator('hg.admin')
230 230 def repo_stats(self, repo_name):
231 231 """
232 232 DELETE an existing repository statistics
233 233 :param repo_name:
234 234 """
235 235
236 236 try:
237 237 repo_model = RepoModel()
238 238 repo_model.delete_stats(repo_name)
239 239 except Exception, e:
240 240 h.flash(_('An error occured during deletion of repository stats'),
241 241 category='error')
242 242 return redirect(url('edit_repo', repo_name=repo_name))
243 243
244 244 @HasPermissionAllDecorator('hg.admin')
245 245 def repo_cache(self, repo_name):
246 246 """
247 247 INVALIDATE exisitings repository cache
248 248 :param repo_name:
249 249 """
250 250
251 251 try:
252 252 ScmModel().mark_for_invalidation(repo_name)
253 253 except Exception, e:
254 254 h.flash(_('An error occurred during cache invalidation'),
255 255 category='error')
256 256 return redirect(url('edit_repo', repo_name=repo_name))
257 257
258 258 @HasPermissionAllDecorator('hg.admin')
259 259 def show(self, repo_name, format='html'):
260 260 """GET /repos/repo_name: Show a specific item"""
261 261 # url('repo', repo_name=ID)
262 262
263 263 @HasPermissionAllDecorator('hg.admin')
264 264 def edit(self, repo_name, format='html'):
265 265 """GET /repos/repo_name/edit: Form to edit an existing item"""
266 266 # url('edit_repo', repo_name=ID)
267 267 repo_model = RepoModel()
268 268 r = ScmModel().get(repo_name)
269 269 c.repo_info = repo_model.get_by_repo_name(repo_name)
270 270
271 271 if c.repo_info is None:
272 272 h.flash(_('%s repository is not mapped to db perhaps'
273 273 ' it was created or renamed from the filesystem'
274 274 ' please run the application again'
275 275 ' in order to rescan repositories') % repo_name,
276 276 category='error')
277 277
278 278 return redirect(url('repos'))
279 279
280 280 if c.repo_info.stats:
281 281 last_rev = c.repo_info.stats.stat_on_revision
282 282 else:
283 283 last_rev = 0
284 284 c.stats_revision = last_rev
285 285
286 286 c.repo_last_rev = r.revisions[-1] if r.revisions else 0
287 287
288 288 if last_rev == 0:
289 289 c.stats_percentage = 0
290 290 else:
291 291 c.stats_percentage = '%.2f' % ((float((last_rev)) /
292 292 c.repo_last_rev) * 100)
293 293
294 defaults = c.repo_info.__dict__.copy()
294 defaults = c.repo_info.get_dict()
295 295 if c.repo_info.user:
296 296 defaults.update({'user':c.repo_info.user.username})
297 297 else:
298 298 replacement_user = self.sa.query(User)\
299 299 .filter(User.admin == True).first().username
300 300 defaults.update({'user':replacement_user})
301 301
302 302 c.users_array = repo_model.get_users_js()
303 303
304 304 for p in c.repo_info.repo_to_perm:
305 305 defaults.update({'perm_%s' % p.user.username:
306 306 p.permission.permission_name})
307 307
308 308 return htmlfill.render(
309 309 render('admin/repos/repo_edit.html'),
310 310 defaults=defaults,
311 311 encoding="UTF-8",
312 312 force_defaults=False
313 313 )
@@ -1,339 +1,339
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 package.rhodecode.controllers.admin.settings
4 4 ~~~~~~~~~~~~~~
5 5 settings controller for rhodecode admin
6 6
7 7 :created_on: Jul 14, 2010
8 8 :author: marcink
9 9 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
10 10 :license: GPLv3, see COPYING for more details.
11 11 """
12 12 # This program is free software; you can redistribute it and/or
13 13 # modify it under the terms of the GNU General Public License
14 14 # as published by the Free Software Foundation; version 2
15 15 # of the License or (at your opinion) any later version of the license.
16 16 #
17 17 # This program is distributed in the hope that it will be useful,
18 18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 20 # GNU General Public License for more details.
21 21 #
22 22 # You should have received a copy of the GNU General Public License
23 23 # along with this program; if not, write to the Free Software
24 24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 25 # MA 02110-1301, USA.
26 26
27 27 from formencode import htmlfill
28 28 from pylons import request, session, tmpl_context as c, url, app_globals as g, \
29 29 config
30 30 from pylons.controllers.util import abort, redirect
31 31 from pylons.i18n.translation import _
32 32 from rhodecode.lib import helpers as h
33 33 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
34 34 HasPermissionAnyDecorator, NotAnonymous
35 35 from rhodecode.lib.base import BaseController, render
36 36 from rhodecode.lib.celerylib import tasks, run_task
37 37 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
38 38 set_rhodecode_config
39 39 from rhodecode.model.db import RhodeCodeUi, Repository
40 40 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
41 41 ApplicationUiSettingsForm
42 42 from rhodecode.model.scm import ScmModel
43 43 from rhodecode.model.settings import SettingsModel
44 44 from rhodecode.model.user import UserModel
45 45 from sqlalchemy import func
46 46 import formencode
47 47 import logging
48 48 import traceback
49 49
50 50 log = logging.getLogger(__name__)
51 51
52 52
53 53 class SettingsController(BaseController):
54 54 """REST Controller styled on the Atom Publishing Protocol"""
55 55 # To properly map this controller, ensure your config/routing.py
56 56 # file has a resource setup:
57 57 # map.resource('setting', 'settings', controller='admin/settings',
58 58 # path_prefix='/admin', name_prefix='admin_')
59 59
60 60
61 61 @LoginRequired()
62 62 def __before__(self):
63 63 c.admin_user = session.get('admin_user')
64 64 c.admin_username = session.get('admin_username')
65 65 super(SettingsController, self).__before__()
66 66
67 67
68 68 @HasPermissionAllDecorator('hg.admin')
69 69 def index(self, format='html'):
70 70 """GET /admin/settings: All items in the collection"""
71 71 # url('admin_settings')
72 72
73 73 defaults = SettingsModel().get_app_settings()
74 74 defaults.update(self.get_hg_ui_settings())
75 75 return htmlfill.render(
76 76 render('admin/settings/settings.html'),
77 77 defaults=defaults,
78 78 encoding="UTF-8",
79 79 force_defaults=False
80 80 )
81 81
82 82 @HasPermissionAllDecorator('hg.admin')
83 83 def create(self):
84 84 """POST /admin/settings: Create a new item"""
85 85 # url('admin_settings')
86 86
87 87 @HasPermissionAllDecorator('hg.admin')
88 88 def new(self, format='html'):
89 89 """GET /admin/settings/new: Form to create a new item"""
90 90 # url('admin_new_setting')
91 91
92 92 @HasPermissionAllDecorator('hg.admin')
93 93 def update(self, setting_id):
94 94 """PUT /admin/settings/setting_id: Update an existing item"""
95 95 # Forms posted to this method should contain a hidden field:
96 96 # <input type="hidden" name="_method" value="PUT" />
97 97 # Or using helpers:
98 98 # h.form(url('admin_setting', setting_id=ID),
99 99 # method='put')
100 100 # url('admin_setting', setting_id=ID)
101 101 if setting_id == 'mapping':
102 102 rm_obsolete = request.POST.get('destroy', False)
103 103 log.debug('Rescanning directories with destroy=%s', rm_obsolete)
104 104
105 105 initial = ScmModel().repo_scan(g.paths[0][1], g.baseui)
106 106 for repo_name in initial.keys():
107 107 invalidate_cache('get_repo_cached_%s' % repo_name)
108 108
109 109 repo2db_mapper(initial, rm_obsolete)
110 110
111 111 h.flash(_('Repositories successfully rescanned'), category='success')
112 112
113 113 if setting_id == 'whoosh':
114 114 repo_location = self.get_hg_ui_settings()['paths_root_path']
115 115 full_index = request.POST.get('full_index', False)
116 116 task = run_task(tasks.whoosh_index, repo_location, full_index)
117 117
118 118 h.flash(_('Whoosh reindex task scheduled'), category='success')
119 119 if setting_id == 'global':
120 120
121 121 application_form = ApplicationSettingsForm()()
122 122 try:
123 123 form_result = application_form.to_python(dict(request.POST))
124 124 settings_model = SettingsModel()
125 125 try:
126 126 hgsettings1 = settings_model.get('title')
127 127 hgsettings1.app_settings_value = form_result['rhodecode_title']
128 128
129 129 hgsettings2 = settings_model.get('realm')
130 130 hgsettings2.app_settings_value = form_result['rhodecode_realm']
131 131
132 132
133 133 self.sa.add(hgsettings1)
134 134 self.sa.add(hgsettings2)
135 135 self.sa.commit()
136 136 set_rhodecode_config(config)
137 137 h.flash(_('Updated application settings'),
138 138 category='success')
139 139
140 140 except:
141 141 log.error(traceback.format_exc())
142 142 h.flash(_('error occurred during updating application settings'),
143 143 category='error')
144 144
145 145 self.sa.rollback()
146 146
147 147
148 148 except formencode.Invalid, errors:
149 149 return htmlfill.render(
150 150 render('admin/settings/settings.html'),
151 151 defaults=errors.value,
152 152 errors=errors.error_dict or {},
153 153 prefix_error=False,
154 154 encoding="UTF-8")
155 155
156 156 if setting_id == 'mercurial':
157 157 application_form = ApplicationUiSettingsForm()()
158 158 try:
159 159 form_result = application_form.to_python(dict(request.POST))
160 160
161 161 try:
162 162
163 163 hgsettings1 = self.sa.query(RhodeCodeUi)\
164 164 .filter(RhodeCodeUi.ui_key == 'push_ssl').one()
165 165 hgsettings1.ui_value = form_result['web_push_ssl']
166 166
167 167 hgsettings2 = self.sa.query(RhodeCodeUi)\
168 168 .filter(RhodeCodeUi.ui_key == '/').one()
169 169 hgsettings2.ui_value = form_result['paths_root_path']
170 170
171 171
172 172 #HOOKS
173 173 hgsettings3 = self.sa.query(RhodeCodeUi)\
174 174 .filter(RhodeCodeUi.ui_key == 'changegroup.update').one()
175 175 hgsettings3.ui_active = bool(form_result['hooks_changegroup_update'])
176 176
177 177 hgsettings4 = self.sa.query(RhodeCodeUi)\
178 178 .filter(RhodeCodeUi.ui_key == 'changegroup.repo_size').one()
179 179 hgsettings4.ui_active = bool(form_result['hooks_changegroup_repo_size'])
180 180
181 181 hgsettings5 = self.sa.query(RhodeCodeUi)\
182 182 .filter(RhodeCodeUi.ui_key == 'pretxnchangegroup.push_logger').one()
183 183 hgsettings5.ui_active = bool(form_result['hooks_pretxnchangegroup_push_logger'])
184 184
185 185 hgsettings6 = self.sa.query(RhodeCodeUi)\
186 186 .filter(RhodeCodeUi.ui_key == 'preoutgoing.pull_logger').one()
187 187 hgsettings6.ui_active = bool(form_result['hooks_preoutgoing_pull_logger'])
188 188
189 189
190 190 self.sa.add(hgsettings1)
191 191 self.sa.add(hgsettings2)
192 192 self.sa.add(hgsettings3)
193 193 self.sa.add(hgsettings4)
194 194 self.sa.add(hgsettings5)
195 195 self.sa.add(hgsettings6)
196 196 self.sa.commit()
197 197
198 198 h.flash(_('Updated mercurial settings'),
199 199 category='success')
200 200
201 201 except:
202 202 log.error(traceback.format_exc())
203 203 h.flash(_('error occurred during updating application settings'),
204 204 category='error')
205 205
206 206 self.sa.rollback()
207 207
208 208
209 209 except formencode.Invalid, errors:
210 210 return htmlfill.render(
211 211 render('admin/settings/settings.html'),
212 212 defaults=errors.value,
213 213 errors=errors.error_dict or {},
214 214 prefix_error=False,
215 215 encoding="UTF-8")
216 216
217 217
218 218
219 219 return redirect(url('admin_settings'))
220 220
221 221 @HasPermissionAllDecorator('hg.admin')
222 222 def delete(self, setting_id):
223 223 """DELETE /admin/settings/setting_id: Delete an existing item"""
224 224 # Forms posted to this method should contain a hidden field:
225 225 # <input type="hidden" name="_method" value="DELETE" />
226 226 # Or using helpers:
227 227 # h.form(url('admin_setting', setting_id=ID),
228 228 # method='delete')
229 229 # url('admin_setting', setting_id=ID)
230 230
231 231 @HasPermissionAllDecorator('hg.admin')
232 232 def show(self, setting_id, format='html'):
233 233 """GET /admin/settings/setting_id: Show a specific item"""
234 234 # url('admin_setting', setting_id=ID)
235 235
236 236 @HasPermissionAllDecorator('hg.admin')
237 237 def edit(self, setting_id, format='html'):
238 238 """GET /admin/settings/setting_id/edit: Form to edit an existing item"""
239 239 # url('admin_edit_setting', setting_id=ID)
240 240
241 241 @NotAnonymous()
242 242 def my_account(self):
243 243 """
244 244 GET /_admin/my_account Displays info about my account
245 245 """
246 246 # url('admin_settings_my_account')
247 247
248 248 c.user = UserModel().get(c.rhodecode_user.user_id, cache=False)
249 249 all_repos = self.sa.query(Repository)\
250 250 .filter(Repository.user_id == c.user.user_id)\
251 251 .order_by(func.lower(Repository.repo_name))\
252 252 .all()
253 253
254 254 c.user_repos = ScmModel().get_repos(all_repos)
255 255
256 256 if c.user.username == 'default':
257 257 h.flash(_("You can't edit this user since it's"
258 258 " crucial for entire application"), category='warning')
259 259 return redirect(url('users'))
260 260
261 defaults = c.user.__dict__.copy()
261 defaults = c.user.get_dict()
262 262 return htmlfill.render(
263 263 render('admin/users/user_edit_my_account.html'),
264 264 defaults=defaults,
265 265 encoding="UTF-8",
266 266 force_defaults=False
267 267 )
268 268
269 269 def my_account_update(self):
270 270 """PUT /_admin/my_account_update: Update an existing item"""
271 271 # Forms posted to this method should contain a hidden field:
272 272 # <input type="hidden" name="_method" value="PUT" />
273 273 # Or using helpers:
274 274 # h.form(url('admin_settings_my_account_update'),
275 275 # method='put')
276 276 # url('admin_settings_my_account_update', id=ID)
277 277 user_model = UserModel()
278 278 uid = c.rhodecode_user.user_id
279 279 _form = UserForm(edit=True, old_data={'user_id':uid,
280 280 'email':c.rhodecode_user.email})()
281 281 form_result = {}
282 282 try:
283 283 form_result = _form.to_python(dict(request.POST))
284 284 user_model.update_my_account(uid, form_result)
285 285 h.flash(_('Your account was updated successfully'),
286 286 category='success')
287 287
288 288 except formencode.Invalid, errors:
289 289 c.user = user_model.get(c.rhodecode_user.user_id, cache=False)
290 290 c.user = UserModel().get(c.rhodecode_user.user_id, cache=False)
291 291 all_repos = self.sa.query(Repository)\
292 292 .filter(Repository.user_id == c.user.user_id)\
293 293 .order_by(func.lower(Repository.repo_name))\
294 294 .all()
295 295 c.user_repos = ScmModel().get_repos(all_repos)
296 296
297 297 return htmlfill.render(
298 298 render('admin/users/user_edit_my_account.html'),
299 299 defaults=errors.value,
300 300 errors=errors.error_dict or {},
301 301 prefix_error=False,
302 302 encoding="UTF-8")
303 303 except Exception:
304 304 log.error(traceback.format_exc())
305 305 h.flash(_('error occurred during update of user %s') \
306 306 % form_result.get('username'), category='error')
307 307
308 308 return redirect(url('my_account'))
309 309
310 310 @NotAnonymous()
311 311 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
312 312 def create_repository(self):
313 313 """GET /_admin/create_repository: Form to create a new item"""
314 314 new_repo = request.GET.get('repo', '')
315 315 c.new_repo = h.repo_name_slug(new_repo)
316 316
317 317 return render('admin/repos/repo_add_create_repository.html')
318 318
319 319 def get_hg_ui_settings(self):
320 320 ret = self.sa.query(RhodeCodeUi).all()
321 321
322 322 if not ret:
323 323 raise Exception('Could not get application ui settings !')
324 324 settings = {}
325 325 for each in ret:
326 326 k = each.ui_key
327 327 v = each.ui_value
328 328 if k == '/':
329 329 k = 'root_path'
330 330
331 331 if k.find('.') != -1:
332 332 k = k.replace('.', '_')
333 333
334 334 if each.ui_section == 'hooks':
335 335 v = each.ui_active
336 336
337 337 settings[each.ui_section + '_' + k] = v
338 338
339 339 return settings
@@ -1,167 +1,167
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # users controller for pylons
4 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; version 2
9 9 # of the License or (at your opinion) any later version of the license.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 19 # MA 02110-1301, USA.
20 20 """
21 21 Created on April 4, 2010
22 22 users controller for pylons
23 23 @author: marcink
24 24 """
25 25
26 26 from formencode import htmlfill
27 27 from pylons import request, session, tmpl_context as c, url
28 28 from pylons.controllers.util import abort, redirect
29 29 from pylons.i18n.translation import _
30 30 from rhodecode.lib.exceptions import *
31 31 from rhodecode.lib import helpers as h
32 32 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
33 33 from rhodecode.lib.base import BaseController, render
34 34 from rhodecode.model.db import User
35 35 from rhodecode.model.forms import UserForm
36 36 from rhodecode.model.user import UserModel
37 37 import formencode
38 38 import logging
39 39 import traceback
40 40
41 41 log = logging.getLogger(__name__)
42 42
43 43 class UsersController(BaseController):
44 44 """REST Controller styled on the Atom Publishing Protocol"""
45 45 # To properly map this controller, ensure your config/routing.py
46 46 # file has a resource setup:
47 47 # map.resource('user', 'users')
48 48
49 49 @LoginRequired()
50 50 @HasPermissionAllDecorator('hg.admin')
51 51 def __before__(self):
52 52 c.admin_user = session.get('admin_user')
53 53 c.admin_username = session.get('admin_username')
54 54 super(UsersController, self).__before__()
55 55
56 56
57 57 def index(self, format='html'):
58 58 """GET /users: All items in the collection"""
59 59 # url('users')
60 60
61 61 c.users_list = self.sa.query(User).all()
62 62 return render('admin/users/users.html')
63 63
64 64 def create(self):
65 65 """POST /users: Create a new item"""
66 66 # url('users')
67 67
68 68 user_model = UserModel()
69 69 login_form = UserForm()()
70 70 try:
71 71 form_result = login_form.to_python(dict(request.POST))
72 72 user_model.create(form_result)
73 73 h.flash(_('created user %s') % form_result['username'],
74 74 category='success')
75 75 #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa)
76 76 except formencode.Invalid, errors:
77 77 return htmlfill.render(
78 78 render('admin/users/user_add.html'),
79 79 defaults=errors.value,
80 80 errors=errors.error_dict or {},
81 81 prefix_error=False,
82 82 encoding="UTF-8")
83 83 except Exception:
84 84 log.error(traceback.format_exc())
85 85 h.flash(_('error occured during creation of user %s') \
86 86 % request.POST.get('username'), category='error')
87 87 return redirect(url('users'))
88 88
89 89 def new(self, format='html'):
90 90 """GET /users/new: Form to create a new item"""
91 91 # url('new_user')
92 92 return render('admin/users/user_add.html')
93 93
94 94 def update(self, id):
95 95 """PUT /users/id: Update an existing item"""
96 96 # Forms posted to this method should contain a hidden field:
97 97 # <input type="hidden" name="_method" value="PUT" />
98 98 # Or using helpers:
99 99 # h.form(url('user', id=ID),
100 100 # method='put')
101 101 # url('user', id=ID)
102 102 user_model = UserModel()
103 103 c.user = user_model.get(id)
104 104
105 105 _form = UserForm(edit=True, old_data={'user_id':id,
106 106 'email':c.user.email})()
107 107 form_result = {}
108 108 try:
109 109 form_result = _form.to_python(dict(request.POST))
110 110 user_model.update(id, form_result)
111 111 h.flash(_('User updated succesfully'), category='success')
112 112
113 113 except formencode.Invalid, errors:
114 114 return htmlfill.render(
115 115 render('admin/users/user_edit.html'),
116 116 defaults=errors.value,
117 117 errors=errors.error_dict or {},
118 118 prefix_error=False,
119 119 encoding="UTF-8")
120 120 except Exception:
121 121 log.error(traceback.format_exc())
122 122 h.flash(_('error occured during update of user %s') \
123 123 % form_result.get('username'), category='error')
124 124
125 125 return redirect(url('users'))
126 126
127 127 def delete(self, id):
128 128 """DELETE /users/id: Delete an existing item"""
129 129 # Forms posted to this method should contain a hidden field:
130 130 # <input type="hidden" name="_method" value="DELETE" />
131 131 # Or using helpers:
132 132 # h.form(url('user', id=ID),
133 133 # method='delete')
134 134 # url('user', id=ID)
135 135 user_model = UserModel()
136 136 try:
137 137 user_model.delete(id)
138 138 h.flash(_('sucessfully deleted user'), category='success')
139 139 except (UserOwnsReposException, DefaultUserException), e:
140 140 h.flash(str(e), category='warning')
141 141 except Exception:
142 142 h.flash(_('An error occured during deletion of user'),
143 143 category='error')
144 144 return redirect(url('users'))
145 145
146 146 def show(self, id, format='html'):
147 147 """GET /users/id: Show a specific item"""
148 148 # url('user', id=ID)
149 149
150 150
151 151 def edit(self, id, format='html'):
152 152 """GET /users/id/edit: Form to edit an existing item"""
153 153 # url('edit_user', id=ID)
154 154 c.user = self.sa.query(User).get(id)
155 155 if not c.user:
156 156 return redirect(url('users'))
157 157 if c.user.username == 'default':
158 158 h.flash(_("You can't edit this user"), category='warning')
159 159 return redirect(url('users'))
160 160
161 defaults = c.user.__dict__.copy()
161 defaults = c.user.get_dict()
162 162 return htmlfill.render(
163 163 render('admin/users/user_edit.html'),
164 164 defaults=defaults,
165 165 encoding="UTF-8",
166 166 force_defaults=False
167 167 )
@@ -1,178 +1,178
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # settings controller for pylons
4 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; version 2
9 9 # of the License or (at your opinion) any later version of the license.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 19 # MA 02110-1301, USA.
20 20 """
21 21 Created on June 30, 2010
22 22 settings controller for pylons
23 23 @author: marcink
24 24 """
25 25 from formencode import htmlfill
26 26 from pylons import tmpl_context as c, request, url
27 27 from pylons.controllers.util import redirect
28 28 from pylons.i18n.translation import _
29 29 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator
30 30 from rhodecode.lib.base import BaseController, render
31 31 from rhodecode.lib.utils import invalidate_cache, action_logger
32 32 from rhodecode.model.forms import RepoSettingsForm, RepoForkForm
33 33 from rhodecode.model.repo import RepoModel
34 34 import formencode
35 35 import logging
36 36 import rhodecode.lib.helpers as h
37 37 import traceback
38 38
39 39 log = logging.getLogger(__name__)
40 40
41 41 class SettingsController(BaseController):
42 42
43 43 @LoginRequired()
44 44 @HasRepoPermissionAllDecorator('repository.admin')
45 45 def __before__(self):
46 46 super(SettingsController, self).__before__()
47 47
48 48 def index(self, repo_name):
49 49 repo_model = RepoModel()
50 50 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
51 51 if not repo:
52 52 h.flash(_('%s repository is not mapped to db perhaps'
53 53 ' it was created or renamed from the filesystem'
54 54 ' please run the application again'
55 55 ' in order to rescan repositories') % repo_name,
56 56 category='error')
57 57
58 58 return redirect(url('home'))
59 defaults = c.repo_info.__dict__.copy()
59 defaults = c.repo_info.get_dict()
60 60 defaults.update({'user':c.repo_info.user.username})
61 61 c.users_array = repo_model.get_users_js()
62 62
63 63 for p in c.repo_info.repo_to_perm:
64 64 defaults.update({'perm_%s' % p.user.username:
65 65 p.permission.permission_name})
66 66
67 67 return htmlfill.render(
68 68 render('settings/repo_settings.html'),
69 69 defaults=defaults,
70 70 encoding="UTF-8",
71 71 force_defaults=False
72 72 )
73 73
74 74 def update(self, repo_name):
75 75 repo_model = RepoModel()
76 76 changed_name = repo_name
77 77 _form = RepoSettingsForm(edit=True, old_data={'repo_name':repo_name})()
78 78 try:
79 79 form_result = _form.to_python(dict(request.POST))
80 80 repo_model.update(repo_name, form_result)
81 81 invalidate_cache('get_repo_cached_%s' % repo_name)
82 82 h.flash(_('Repository %s updated successfully' % repo_name),
83 83 category='success')
84 84 changed_name = form_result['repo_name']
85 85 action_logger(self.rhodecode_user, 'user_updated_repo',
86 86 changed_name, '', self.sa)
87 87 except formencode.Invalid, errors:
88 88 c.repo_info = repo_model.get_by_repo_name(repo_name)
89 89 c.users_array = repo_model.get_users_js()
90 90 errors.value.update({'user':c.repo_info.user.username})
91 91 return htmlfill.render(
92 92 render('settings/repo_settings.html'),
93 93 defaults=errors.value,
94 94 errors=errors.error_dict or {},
95 95 prefix_error=False,
96 96 encoding="UTF-8")
97 97 except Exception:
98 98 log.error(traceback.format_exc())
99 99 h.flash(_('error occurred during update of repository %s') \
100 100 % repo_name, category='error')
101 101
102 102 return redirect(url('repo_settings_home', repo_name=changed_name))
103 103
104 104
105 105
106 106 def delete(self, repo_name):
107 107 """DELETE /repos/repo_name: Delete an existing item"""
108 108 # Forms posted to this method should contain a hidden field:
109 109 # <input type="hidden" name="_method" value="DELETE" />
110 110 # Or using helpers:
111 111 # h.form(url('repo_settings_delete', repo_name=ID),
112 112 # method='delete')
113 113 # url('repo_settings_delete', repo_name=ID)
114 114
115 115 repo_model = RepoModel()
116 116 repo = repo_model.get_by_repo_name(repo_name)
117 117 if not repo:
118 118 h.flash(_('%s repository is not mapped to db perhaps'
119 119 ' it was moved or renamed from the filesystem'
120 120 ' please run the application again'
121 121 ' in order to rescan repositories') % repo_name,
122 122 category='error')
123 123
124 124 return redirect(url('home'))
125 125 try:
126 126 action_logger(self.rhodecode_user, 'user_deleted_repo',
127 127 repo_name, '', self.sa)
128 128 repo_model.delete(repo)
129 129 invalidate_cache('get_repo_cached_%s' % repo_name)
130 130 h.flash(_('deleted repository %s') % repo_name, category='success')
131 131 except Exception:
132 132 h.flash(_('An error occurred during deletion of %s') % repo_name,
133 133 category='error')
134 134
135 135 return redirect(url('home'))
136 136
137 137 def fork(self, repo_name):
138 138 repo_model = RepoModel()
139 139 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
140 140 if not repo:
141 141 h.flash(_('%s repository is not mapped to db perhaps'
142 142 ' it was created or renamed from the filesystem'
143 143 ' please run the application again'
144 144 ' in order to rescan repositories') % repo_name,
145 145 category='error')
146 146
147 147 return redirect(url('home'))
148 148
149 149 return render('settings/repo_fork.html')
150 150
151 151
152 152
153 153 def fork_create(self, repo_name):
154 154 repo_model = RepoModel()
155 155 c.repo_info = repo_model.get_by_repo_name(repo_name)
156 156 _form = RepoForkForm(old_data={'repo_type':c.repo_info.repo_type})()
157 157 form_result = {}
158 158 try:
159 159 form_result = _form.to_python(dict(request.POST))
160 160 form_result.update({'repo_name':repo_name})
161 161 repo_model.create_fork(form_result, c.rhodecode_user)
162 162 h.flash(_('forked %s repository as %s') \
163 163 % (repo_name, form_result['fork_name']),
164 164 category='success')
165 165 action_logger(self.rhodecode_user,
166 166 'user_forked_repo:%s' % form_result['fork_name'],
167 167 repo_name, '', self.sa)
168 168 except formencode.Invalid, errors:
169 169 c.new_repo = errors.value['fork_name']
170 170 r = render('settings/repo_fork.html')
171 171
172 172 return htmlfill.render(
173 173 r,
174 174 defaults=errors.value,
175 175 errors=errors.error_dict or {},
176 176 prefix_error=False,
177 177 encoding="UTF-8")
178 178 return redirect(url('home'))
@@ -1,216 +1,248
1 1 # -*- coding: utf-8 -*-
2 2 """
3 package.rhodecode.model.db
4 ~~~~~~~~~~~~~~
3 rhodecode.model.db
4 ~~~~~~~~~~~~~~~~~~
5 5
6 6 Database Models for RhodeCode
7 7 :created_on: Apr 08, 2010
8 8 :author: marcink
9 9 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
10 10 :license: GPLv3, see COPYING for more details.
11 11 """
12 12 # This program is free software; you can redistribute it and/or
13 13 # modify it under the terms of the GNU General Public License
14 14 # as published by the Free Software Foundation; version 2
15 15 # of the License or (at your opinion) any later version of the license.
16 16 #
17 17 # This program is distributed in the hope that it will be useful,
18 18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 20 # GNU General Public License for more details.
21 21 #
22 22 # You should have received a copy of the GNU General Public License
23 23 # along with this program; if not, write to the Free Software
24 24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 25 # MA 02110-1301, USA.
26 26 import logging
27 27 import datetime
28 28
29 29 from sqlalchemy import *
30 30 from sqlalchemy.exc import DatabaseError
31 from sqlalchemy.orm import relation, backref
31 from sqlalchemy.orm import relation, backref, class_mapper
32 32 from sqlalchemy.orm.session import Session
33 33
34 34 from rhodecode.model.meta import Base
35 35
36 36 log = logging.getLogger(__name__)
37 37
38 class RhodeCodeSettings(Base):
38 class BaseModel(object):
39
40 @classmethod
41 def _get_keys(cls):
42 """return column names for this model """
43 return class_mapper(cls).c.keys()
44
45 def get_dict(self):
46 """return dict with keys and values corresponding
47 to this model data """
48
49 d = {}
50 for k in self._get_keys():
51 d[k] = getattr(self, k)
52 return d
53
54 def get_appstruct(self):
55 """return list with keys and values tupples corresponding
56 to this model data """
57
58 l = []
59 for k in self._get_keys():
60 l.append((k, getattr(self, k),))
61 return l
62
63 def populate_obj(self, populate_dict):
64 """populate model with data from given populate_dict"""
65
66 for k in self._get_keys():
67 if k in populate_dict:
68 setattr(self, k, populate_dict[k])
69
70 class RhodeCodeSettings(Base, BaseModel):
39 71 __tablename__ = 'rhodecode_settings'
40 72 __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
41 73 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
42 74 app_settings_name = Column("app_settings_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
43 75 app_settings_value = Column("app_settings_value", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
44 76
45 77 def __init__(self, k, v):
46 78 self.app_settings_name = k
47 79 self.app_settings_value = v
48 80
49 81 def __repr__(self):
50 82 return "<RhodeCodeSetting('%s:%s')>" % (self.app_settings_name,
51 83 self.app_settings_value)
52 84
53 class RhodeCodeUi(Base):
85 class RhodeCodeUi(Base, BaseModel):
54 86 __tablename__ = 'rhodecode_ui'
55 87 __table_args__ = {'useexisting':True}
56 88 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
57 89 ui_section = Column("ui_section", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
58 90 ui_key = Column("ui_key", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
59 91 ui_value = Column("ui_value", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
60 92 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
61 93
62 94
63 class User(Base):
95 class User(Base, BaseModel):
64 96 __tablename__ = 'users'
65 97 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
66 98 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
67 99 username = Column("username", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
68 100 password = Column("password", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
69 101 active = Column("active", Boolean(), nullable=True, unique=None, default=None)
70 102 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
71 103 name = Column("name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
72 104 lastname = Column("lastname", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
73 105 email = Column("email", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
74 106 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
75 107 is_ldap = Column("is_ldap", Boolean(), nullable=False, unique=None, default=False)
76 108
77 109 user_log = relation('UserLog', cascade='all')
78 110 user_perms = relation('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
79 111
80 112 repositories = relation('Repository')
81 113 user_followers = relation('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
82 114
83 115 @property
84 116 def full_contact(self):
85 117 return '%s %s <%s>' % (self.name, self.lastname, self.email)
86 118
87 119 def __repr__(self):
88 120 return "<User('id:%s:%s')>" % (self.user_id, self.username)
89 121
90 122 def update_lastlogin(self):
91 123 """Update user lastlogin"""
92 124
93 125 try:
94 126 session = Session.object_session(self)
95 127 self.last_login = datetime.datetime.now()
96 128 session.add(self)
97 129 session.commit()
98 130 log.debug('updated user %s lastlogin', self.username)
99 131 except (DatabaseError,):
100 132 session.rollback()
101 133
102 134
103 class UserLog(Base):
135 class UserLog(Base, BaseModel):
104 136 __tablename__ = 'user_logs'
105 137 __table_args__ = {'useexisting':True}
106 138 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
107 139 user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
108 140 repository_id = Column("repository_id", Integer(length=None, convert_unicode=False, assert_unicode=None), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
109 141 repository_name = Column("repository_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
110 142 user_ip = Column("user_ip", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
111 143 action = Column("action", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
112 144 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
113 145
114 146 user = relation('User')
115 147 repository = relation('Repository')
116 148
117 class Repository(Base):
149 class Repository(Base, BaseModel):
118 150 __tablename__ = 'repositories'
119 151 __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
120 152 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
121 153 repo_name = Column("repo_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
122 154 repo_type = Column("repo_type", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default=None)
123 155 user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None)
124 156 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
125 157 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
126 158 description = Column("description", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
127 159 fork_id = Column("fork_id", Integer(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=False, default=None)
128 160
129 161 user = relation('User')
130 162 fork = relation('Repository', remote_side=repo_id)
131 163 repo_to_perm = relation('RepoToPerm', cascade='all')
132 164 stats = relation('Statistics', cascade='all', uselist=False)
133 165
134 166 repo_followers = relation('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all')
135 167
136 168
137 169 def __repr__(self):
138 170 return "<Repository('%s:%s')>" % (self.repo_id, self.repo_name)
139 171
140 class Permission(Base):
172 class Permission(Base, BaseModel):
141 173 __tablename__ = 'permissions'
142 174 __table_args__ = {'useexisting':True}
143 175 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
144 176 permission_name = Column("permission_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
145 177 permission_longname = Column("permission_longname", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
146 178
147 179 def __repr__(self):
148 180 return "<Permission('%s:%s')>" % (self.permission_id, self.permission_name)
149 181
150 class RepoToPerm(Base):
182 class RepoToPerm(Base, BaseModel):
151 183 __tablename__ = 'repo_to_perm'
152 184 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
153 185 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
154 186 user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
155 187 permission_id = Column("permission_id", Integer(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
156 188 repository_id = Column("repository_id", Integer(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
157 189
158 190 user = relation('User')
159 191 permission = relation('Permission')
160 192 repository = relation('Repository')
161 193
162 class UserToPerm(Base):
194 class UserToPerm(Base, BaseModel):
163 195 __tablename__ = 'user_to_perm'
164 196 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
165 197 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
166 198 user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
167 199 permission_id = Column("permission_id", Integer(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
168 200
169 201 user = relation('User')
170 202 permission = relation('Permission')
171 203
172 class Statistics(Base):
204 class Statistics(Base, BaseModel):
173 205 __tablename__ = 'statistics'
174 206 __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
175 207 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
176 208 repository_id = Column("repository_id", Integer(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=True, default=None)
177 209 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
178 210 commit_activity = Column("commit_activity", LargeBinary(), nullable=False)#JSON data
179 211 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
180 212 languages = Column("languages", LargeBinary(), nullable=False)#JSON data
181 213
182 214 repository = relation('Repository', single_parent=True)
183 215
184 class UserFollowing(Base):
216 class UserFollowing(Base, BaseModel):
185 217 __tablename__ = 'user_followings'
186 218 __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
187 219 UniqueConstraint('user_id', 'follows_user_id')
188 220 , {'useexisting':True})
189 221
190 222 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
191 223 user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
192 224 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=None, default=None)
193 225 follows_user_id = Column("follows_user_id", Integer(), ForeignKey(u'users.user_id'), nullable=True, unique=None, default=None)
194 226
195 227 user = relation('User', primaryjoin='User.user_id==UserFollowing.user_id')
196 228
197 229 follows_user = relation('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
198 230 follows_repository = relation('Repository')
199 231
200 232
201 class CacheInvalidation(Base):
233 class CacheInvalidation(Base, BaseModel):
202 234 __tablename__ = 'cache_invalidation'
203 235 __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True})
204 236 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
205 237 cache_key = Column("cache_key", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
206 238 cache_args = Column("cache_args", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
207 239 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
208 240
209 241
210 242 def __init__(self, cache_key, cache_args=''):
211 243 self.cache_key = cache_key
212 244 self.cache_args = cache_args
213 245 self.cache_active = False
214 246
215 247 def __repr__(self):
216 248 return "<CacheInvalidation('%s:%s')>" % (self.cache_id, self.cache_key)
General Comments 0
You need to be logged in to leave comments. Login now