comparison pylons_app/controllers/repos.py @ 265:0e5455fda8fd

Implemented basic repository managment. Implemented repo2db mappings, model, helpers updates and code cleanups
author Marcin Kuzminski <marcin@python-works.com>
date Mon, 07 Jun 2010 00:18:33 +0200
parents 3782a6d698af
children 32d6c955218c
comparison
equal deleted inserted replaced
264:0d68a749db33 265:0e5455fda8fd
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # encoding: utf-8 2 # encoding: utf-8
3 # repos controller for pylons 3 # repos controller for pylons
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com> 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5
6 # This program is free software; you can redistribute it and/or 5 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License 6 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2 7 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license. 8 # of the License or (at your opinion) any later version of the license.
10 # 9 #
20 """ 19 """
21 Created on April 7, 2010 20 Created on April 7, 2010
22 admin controller for pylons 21 admin controller for pylons
23 @author: marcink 22 @author: marcink
24 """ 23 """
25 import logging 24 from operator import itemgetter
26 from pylons import request, response, session, tmpl_context as c, url, \ 25 from pylons import request, response, session, tmpl_context as c, url, \
27 app_globals as g 26 app_globals as g
28 from pylons.controllers.util import abort, redirect 27 from pylons.controllers.util import abort, redirect
29 from pylons_app.lib.auth import LoginRequired
30 from pylons.i18n.translation import _ 28 from pylons.i18n.translation import _
31 from pylons_app.lib import helpers as h 29 from pylons_app.lib import helpers as h
30 from pylons_app.lib.auth import LoginRequired
32 from pylons_app.lib.base import BaseController, render 31 from pylons_app.lib.base import BaseController, render
33 from pylons_app.lib.filters import clean_repo 32 from pylons_app.lib.utils import invalidate_cache
34 from pylons_app.lib.utils import check_repo, invalidate_cache 33 from pylons_app.model.repo_model import RepoModel
35 from pylons_app.model.hg_model import HgModel 34 from pylons_app.model.hg_model import HgModel
35 from pylons_app.model.forms import RepoForm
36 from pylons_app.model.meta import Session
37 from datetime import datetime
38 import formencode
39 from formencode import htmlfill
40 import logging
36 import os 41 import os
37 import shutil 42 import shutil
38 from operator import itemgetter
39 log = logging.getLogger(__name__) 43 log = logging.getLogger(__name__)
40 44
41 class ReposController(BaseController): 45 class ReposController(BaseController):
42 """REST Controller styled on the Atom Publishing Protocol""" 46 """REST Controller styled on the Atom Publishing Protocol"""
43 # To properly map this controller, ensure your config/routing.py 47 # To properly map this controller, ensure your config/routing.py
57 return render('admin/repos/repos.html') 61 return render('admin/repos/repos.html')
58 62
59 def create(self): 63 def create(self):
60 """POST /repos: Create a new item""" 64 """POST /repos: Create a new item"""
61 # url('repos') 65 # url('repos')
62 name = request.POST.get('name') 66 repo_model = RepoModel()
67 _form = RepoForm()()
68 try:
69 form_result = _form.to_python(dict(request.POST))
70 repo_model.create(form_result, c.hg_app_user)
71 invalidate_cache('cached_repo_list')
72 h.flash(_('created repository %s') % form_result['repo_name'],
73 category='success')
74
75 except formencode.Invalid as errors:
76 c.form_errors = errors.error_dict
77 c.new_repo = errors.value['repo_name']
78 return htmlfill.render(
79 render('admin/repos/repo_add.html'),
80 defaults=errors.value,
81 encoding="UTF-8")
63 82
64 try: 83 except Exception:
65 self._create_repo(name) 84 h.flash(_('error occured during creation of repository %s') \
66 #clear our cached list for refresh with new repo 85 % form_result['repo_name'], category='error')
67 invalidate_cache('cached_repo_list') 86
68 h.flash(_('created repository %s') % name, category='success')
69 except Exception as e:
70 log.error(e)
71
72 return redirect('repos') 87 return redirect('repos')
73
74 def _create_repo(self, repo_name):
75 repo_path = os.path.join(g.base_path, repo_name)
76 if check_repo(repo_name, g.base_path):
77 log.info('creating repo %s in %s', repo_name, repo_path)
78 from vcs.backends.hg import MercurialRepository
79 MercurialRepository(repo_path, create=True)
80
81 88
82 def new(self, format='html'): 89 def new(self, format='html'):
83 """GET /repos/new: Form to create a new item""" 90 """GET /repos/new: Form to create a new item"""
84 new_repo = request.GET.get('repo', '') 91 new_repo = request.GET.get('repo', '')
85 c.new_repo = clean_repo(new_repo) 92 c.new_repo = h.repo_name_slug(new_repo)
86 93
87 return render('admin/repos/repo_add.html') 94 return render('admin/repos/repo_add.html')
88 95
89 def update(self, id): 96 def update(self, id):
90 """PUT /repos/id: Update an existing item""" 97 """PUT /repos/id: Update an existing item"""
92 # <input type="hidden" name="_method" value="PUT" /> 99 # <input type="hidden" name="_method" value="PUT" />
93 # Or using helpers: 100 # Or using helpers:
94 # h.form(url('repo', id=ID), 101 # h.form(url('repo', id=ID),
95 # method='put') 102 # method='put')
96 # url('repo', id=ID) 103 # url('repo', id=ID)
97 104 repo_model = RepoModel()
105 _form = RepoForm(edit=True)()
106 try:
107 form_result = _form.to_python(dict(request.POST))
108 repo_model.update(id, form_result)
109 invalidate_cache('cached_repo_list')
110 h.flash(_('Repository updated succesfully'), category='success')
111
112 except formencode.Invalid as errors:
113 c.repo_info = repo_model.get(id)
114 c.form_errors = errors.error_dict
115 return htmlfill.render(
116 render('admin/repos/repo_edit.html'),
117 defaults=errors.value,
118 encoding="UTF-8")
119 except Exception:
120 h.flash(_('error occured during update of repository %s') \
121 % form_result['repo_name'], category='error')
122 return redirect(url('repos'))
123
98 def delete(self, id): 124 def delete(self, id):
99 """DELETE /repos/id: Delete an existing item""" 125 """DELETE /repos/id: Delete an existing item"""
100 # Forms posted to this method should contain a hidden field: 126 # Forms posted to this method should contain a hidden field:
101 # <input type="hidden" name="_method" value="DELETE" /> 127 # <input type="hidden" name="_method" value="DELETE" />
102 # Or using helpers: 128 # Or using helpers:
103 # h.form(url('repo', id=ID), 129 # h.form(url('repo', id=ID),
104 # method='delete') 130 # method='delete')
105 # url('repo', id=ID) 131 # url('repo', id=ID)
106 from datetime import datetime
107 path = g.paths[0][1].replace('*', '')
108 rm_path = os.path.join(path, id)
109 log.info("Removing %s", rm_path)
110 shutil.move(os.path.join(rm_path, '.hg'), os.path.join(rm_path, 'rm__.hg'))
111 shutil.move(rm_path, os.path.join(path, 'rm__%s-%s' % (datetime.today(), id)))
112 132
113 #clear our cached list for refresh with new repo 133 repo_model = RepoModel()
114 invalidate_cache('cached_repo_list') 134 repo = repo_model.get(id)
115 h.flash(_('deleted repository %s') % rm_path, category='success') 135 if not repo:
136 h.flash(_('%s repository is not mapped to db perhaps'
137 ' it was moved or renamed please run the application again'
138 ' in order to rescan repositories') % id, category='error')
139
140 return redirect(url('repos'))
141 try:
142 repo_model.delete(repo)
143 invalidate_cache('cached_repo_list')
144 h.flash(_('deleted repository %s') % id, category='success')
145 except Exception:
146 h.flash(_('An error occured during deletion of %s') % id,
147 category='error')
148
116 return redirect(url('repos')) 149 return redirect(url('repos'))
117 150
118
119 def show(self, id, format='html'): 151 def show(self, id, format='html'):
120 """GET /repos/id: Show a specific item""" 152 """GET /repos/id: Show a specific item"""
121 # url('repo', id=ID) 153 # url('repo', id=ID)
122 154
123 def edit(self, id, format='html'): 155 def edit(self, id, format='html'):
124 """GET /repos/id/edit: Form to edit an existing item""" 156 """GET /repos/id/edit: Form to edit an existing item"""
125 # url('edit_repo', id=ID) 157 # url('edit_repo', id=ID)
126 c.new_repo = id 158 repo_model = RepoModel()
127 return render('admin/repos/repo_edit.html') 159 c.repo_info = repo_model.get(id)
160 defaults = c.repo_info.__dict__
161 defaults.update({'user':c.repo_info.user.username})
162 return htmlfill.render(
163 render('admin/repos/repo_edit.html'),
164 defaults=defaults,
165 encoding="UTF-8",
166 force_defaults=False
167 )