##// END OF EJS Templates
Implemented server side forks...
marcink -
r530:a08f610e default
parent child Browse files
Show More
@@ -171,7 +171,11 b' def make_map(config):'
171 171 controller='settings', action='index',
172 172 conditions=dict(function=check_repo))
173 173
174 map.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
175 controller='settings', action='fork_create',
176 conditions=dict(function=check_repo, method=["POST"]))
174 177 map.connect('repo_fork_home', '/{repo_name:.*}/fork',
175 178 controller='settings', action='fork',
176 conditions=dict(function=check_repo))
179 conditions=dict(function=check_repo))
180
177 181 return map
@@ -29,7 +29,7 b' from pylons.i18n.translation import _'
29 29 from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAllDecorator
30 30 from pylons_app.lib.base import BaseController, render
31 31 from pylons_app.lib.utils import invalidate_cache
32 from pylons_app.model.forms import RepoSettingsForm
32 from pylons_app.model.forms import RepoSettingsForm, RepoForkForm
33 33 from pylons_app.model.repo_model import RepoModel
34 34 import formencode
35 35 import logging
@@ -140,5 +140,33 b' class SettingsController(BaseController)'
140 140 ' in order to rescan repositories') % repo_name,
141 141 category='error')
142 142
143 return redirect(url('hg_home'))
143 return redirect(url('hg_home'))
144
144 145 return render('settings/repo_fork.html')
146
147
148
149 def fork_create(self, repo_name):
150 repo_model = RepoModel()
151 c.repo_info = repo_model.get(repo_name)
152 _form = RepoForkForm()()
153 form_result = {}
154 try:
155 form_result = _form.to_python(dict(request.POST))
156 form_result.update({'repo_name':repo_name})
157 repo_model.create_fork(form_result, c.hg_app_user)
158 h.flash(_('fork %s repository as %s task added') \
159 % (repo_name, form_result['fork_name']),
160 category='success')
161
162 except formencode.Invalid as errors:
163 c.new_repo = errors.value['fork_name']
164 r = render('settings/repo_fork.html')
165
166 return htmlfill.render(
167 r,
168 defaults=errors.value,
169 errors=errors.error_dict or {},
170 prefix_error=False,
171 encoding="UTF-8")
172 return redirect(url('hg_home'))
@@ -271,6 +271,24 b' def send_email(recipients, subject, body'
271 271 return False
272 272 return True
273 273
274 @task
275 def create_repo_fork(form_data, cur_user):
276 import os
277 from pylons_app.lib.utils import invalidate_cache
278 from pylons_app.model.repo_model import RepoModel
279 sa = get_session()
280 rm = RepoModel(sa)
281
282 rm.create(form_data, cur_user, just_db=True, fork=True)
283
284 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
285 repo_path = os.path.join(repos_path, form_data['repo_name'])
286 repo_fork_path = os.path.join(repos_path, form_data['fork_name'])
287
288 MercurialRepository(str(repo_fork_path), True, clone_url=str(repo_path))
289 #invalidate_cache('cached_repo_list')
290
291
274 292 def __get_codes_stats(repo_name):
275 293 LANGUAGES_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c',
276 294 'cfg', 'cfm', 'cpp', 'cs', 'diff', 'do', 'el', 'erl',
@@ -81,8 +81,10 b' class Repository(Base):'
81 81 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None)
82 82 private = Column("private", BOOLEAN(), nullable=True, unique=None, default=None)
83 83 description = Column("description", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
84 fork_id = Column("fork_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=False, default=None)
84 85
85 86 user = relation('User')
87 fork = relation('Repository', remote_side=repo_id)
86 88 repo_to_perm = relation('RepoToPerm', cascade='all')
87 89
88 90 def __repr__(self):
@@ -307,6 +307,16 b' def RepoForm(edit=False, old_data={}):'
307 307 chained_validators = [ValidPerms]
308 308 return _RepoForm
309 309
310 def RepoForkForm(edit=False, old_data={}):
311 class _RepoForkForm(formencode.Schema):
312 allow_extra_fields = True
313 filter_extra_fields = False
314 fork_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
315 description = UnicodeString(strip=True, min=1, not_empty=True)
316 private = StringBoolean(if_missing=False)
317
318 return _RepoForkForm
319
310 320 def RepoSettingsForm(edit=False, old_data={}):
311 321 class _RepoForm(formencode.Schema):
312 322 allow_extra_fields = True
@@ -27,6 +27,7 b' from pylons_app.lib.utils import check_r'
27 27 from pylons_app.model.db import Repository, RepoToPerm, User, Permission
28 28 from pylons_app.model.meta import Session
29 29 from pylons_app.model.user_model import UserModel
30 from pylons_app.lib.celerylib.tasks import create_repo_fork, run_task
30 31 import logging
31 32 import os
32 33 import shutil
@@ -35,11 +36,15 b' log = logging.getLogger(__name__)'
35 36
36 37 class RepoModel(object):
37 38
38 def __init__(self):
39 self.sa = Session()
39 def __init__(self, sa=None):
40 if not sa:
41 self.sa = Session()
42 else:
43 self.sa = sa
40 44
41 45 def get(self, id):
42 return self.sa.query(Repository).filter(Repository.repo_name == id).scalar()
46 return self.sa.query(Repository)\
47 .filter(Repository.repo_name == id).scalar()
43 48
44 49 def get_users_js(self):
45 50
@@ -100,20 +105,32 b' class RepoModel(object):'
100 105 self.sa.rollback()
101 106 raise
102 107
103 def create(self, form_data, cur_user, just_db=False):
108 def create(self, form_data, cur_user, just_db=False, fork=False):
104 109 try:
105 repo_name = form_data['repo_name']
110 if fork:
111 repo_name = str(form_data['fork_name'])
112 org_name = str(form_data['repo_name'])
113
114 else:
115 org_name = repo_name = str(form_data['repo_name'])
106 116 new_repo = Repository()
107 117 for k, v in form_data.items():
118 if k == 'repo_name':
119 v = repo_name
108 120 setattr(new_repo, k, v)
109 121
122 if fork:
123 parent_repo = self.sa.query(Repository)\
124 .filter(Repository.repo_name == org_name).scalar()
125 new_repo.fork = parent_repo
126
110 127 new_repo.user_id = cur_user.user_id
111 128 self.sa.add(new_repo)
112 129
113 130 #create default permission
114 131 repo_to_perm = RepoToPerm()
115 132 default = 'repository.read'
116 for p in UserModel().get_default().user_perms:
133 for p in UserModel(self.sa).get_default().user_perms:
117 134 if p.permission.permission_name.startswith('repository.'):
118 135 default = p.permission.permission_name
119 136 break
@@ -136,7 +153,10 b' class RepoModel(object):'
136 153 log.error(traceback.format_exc())
137 154 self.sa.rollback()
138 155 raise
139
156
157 def create_fork(self, form_data, cur_user):
158 run_task(create_repo_fork, form_data, cur_user)
159
140 160 def delete(self, repo):
141 161 try:
142 162 self.sa.delete(repo)
@@ -36,8 +36,11 b' class DefaultUserException(Exception):pa'
36 36
37 37 class UserModel(object):
38 38
39 def __init__(self):
40 self.sa = Session()
39 def __init__(self, sa=None):
40 if not sa:
41 self.sa = Session()
42 else:
43 self.sa = sa
41 44
42 45 def get_default(self):
43 46 return self.sa.query(User).filter(User.username == 'default').scalar()
@@ -20,7 +20,7 b''
20 20 <div class="title">
21 21 ${self.breadcrumbs()}
22 22 </div>
23 ${h.form(url('repos'))}
23 ${h.form(url('repo_fork_create_home',repo_name=c.repo_info.repo_name))}
24 24 <div class="form">
25 25 <!-- fields -->
26 26 <div class="fields">
@@ -49,7 +49,7 b''
49 49 </div>
50 50 </div>
51 51 <div class="buttons">
52 ${h.submit('fork','fork this repository',class_="ui-button ui-widget ui-state-default ui-corner-all")}
52 ${h.submit('','fork this repository',class_="ui-button ui-widget ui-state-default ui-corner-all")}
53 53 </div>
54 54 </div>
55 55 </div>
General Comments 0
You need to be logged in to leave comments. Login now