##// 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 controller='settings', action='index',
171 controller='settings', action='index',
172 conditions=dict(function=check_repo))
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 map.connect('repo_fork_home', '/{repo_name:.*}/fork',
177 map.connect('repo_fork_home', '/{repo_name:.*}/fork',
175 controller='settings', action='fork',
178 controller='settings', action='fork',
176 conditions=dict(function=check_repo))
179 conditions=dict(function=check_repo))
180
177 return map
181 return map
@@ -29,7 +29,7 b' from pylons.i18n.translation import _'
29 from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAllDecorator
29 from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAllDecorator
30 from pylons_app.lib.base import BaseController, render
30 from pylons_app.lib.base import BaseController, render
31 from pylons_app.lib.utils import invalidate_cache
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 from pylons_app.model.repo_model import RepoModel
33 from pylons_app.model.repo_model import RepoModel
34 import formencode
34 import formencode
35 import logging
35 import logging
@@ -140,5 +140,33 b' class SettingsController(BaseController)'
140 ' in order to rescan repositories') % repo_name,
140 ' in order to rescan repositories') % repo_name,
141 category='error')
141 category='error')
142
142
143 return redirect(url('hg_home'))
143 return redirect(url('hg_home'))
144
144 return render('settings/repo_fork.html')
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 return False
271 return False
272 return True
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 def __get_codes_stats(repo_name):
292 def __get_codes_stats(repo_name):
275 LANGUAGES_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c',
293 LANGUAGES_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c',
276 'cfg', 'cfm', 'cpp', 'cs', 'diff', 'do', 'el', 'erl',
294 'cfg', 'cfm', 'cpp', 'cs', 'diff', 'do', 'el', 'erl',
@@ -81,8 +81,10 b' class Repository(Base):'
81 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None)
81 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None)
82 private = Column("private", BOOLEAN(), nullable=True, unique=None, default=None)
82 private = Column("private", BOOLEAN(), nullable=True, unique=None, default=None)
83 description = Column("description", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
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 user = relation('User')
86 user = relation('User')
87 fork = relation('Repository', remote_side=repo_id)
86 repo_to_perm = relation('RepoToPerm', cascade='all')
88 repo_to_perm = relation('RepoToPerm', cascade='all')
87
89
88 def __repr__(self):
90 def __repr__(self):
@@ -307,6 +307,16 b' def RepoForm(edit=False, old_data={}):'
307 chained_validators = [ValidPerms]
307 chained_validators = [ValidPerms]
308 return _RepoForm
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 def RepoSettingsForm(edit=False, old_data={}):
320 def RepoSettingsForm(edit=False, old_data={}):
311 class _RepoForm(formencode.Schema):
321 class _RepoForm(formencode.Schema):
312 allow_extra_fields = True
322 allow_extra_fields = True
@@ -27,6 +27,7 b' from pylons_app.lib.utils import check_r'
27 from pylons_app.model.db import Repository, RepoToPerm, User, Permission
27 from pylons_app.model.db import Repository, RepoToPerm, User, Permission
28 from pylons_app.model.meta import Session
28 from pylons_app.model.meta import Session
29 from pylons_app.model.user_model import UserModel
29 from pylons_app.model.user_model import UserModel
30 from pylons_app.lib.celerylib.tasks import create_repo_fork, run_task
30 import logging
31 import logging
31 import os
32 import os
32 import shutil
33 import shutil
@@ -35,11 +36,15 b' log = logging.getLogger(__name__)'
35
36
36 class RepoModel(object):
37 class RepoModel(object):
37
38
38 def __init__(self):
39 def __init__(self, sa=None):
39 self.sa = Session()
40 if not sa:
41 self.sa = Session()
42 else:
43 self.sa = sa
40
44
41 def get(self, id):
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 def get_users_js(self):
49 def get_users_js(self):
45
50
@@ -100,20 +105,32 b' class RepoModel(object):'
100 self.sa.rollback()
105 self.sa.rollback()
101 raise
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 try:
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 new_repo = Repository()
116 new_repo = Repository()
107 for k, v in form_data.items():
117 for k, v in form_data.items():
118 if k == 'repo_name':
119 v = repo_name
108 setattr(new_repo, k, v)
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 new_repo.user_id = cur_user.user_id
127 new_repo.user_id = cur_user.user_id
111 self.sa.add(new_repo)
128 self.sa.add(new_repo)
112
129
113 #create default permission
130 #create default permission
114 repo_to_perm = RepoToPerm()
131 repo_to_perm = RepoToPerm()
115 default = 'repository.read'
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 if p.permission.permission_name.startswith('repository.'):
134 if p.permission.permission_name.startswith('repository.'):
118 default = p.permission.permission_name
135 default = p.permission.permission_name
119 break
136 break
@@ -136,7 +153,10 b' class RepoModel(object):'
136 log.error(traceback.format_exc())
153 log.error(traceback.format_exc())
137 self.sa.rollback()
154 self.sa.rollback()
138 raise
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 def delete(self, repo):
160 def delete(self, repo):
141 try:
161 try:
142 self.sa.delete(repo)
162 self.sa.delete(repo)
@@ -36,8 +36,11 b' class DefaultUserException(Exception):pa'
36
36
37 class UserModel(object):
37 class UserModel(object):
38
38
39 def __init__(self):
39 def __init__(self, sa=None):
40 self.sa = Session()
40 if not sa:
41 self.sa = Session()
42 else:
43 self.sa = sa
41
44
42 def get_default(self):
45 def get_default(self):
43 return self.sa.query(User).filter(User.username == 'default').scalar()
46 return self.sa.query(User).filter(User.username == 'default').scalar()
@@ -20,7 +20,7 b''
20 <div class="title">
20 <div class="title">
21 ${self.breadcrumbs()}
21 ${self.breadcrumbs()}
22 </div>
22 </div>
23 ${h.form(url('repos'))}
23 ${h.form(url('repo_fork_create_home',repo_name=c.repo_info.repo_name))}
24 <div class="form">
24 <div class="form">
25 <!-- fields -->
25 <!-- fields -->
26 <div class="fields">
26 <div class="fields">
@@ -49,7 +49,7 b''
49 </div>
49 </div>
50 </div>
50 </div>
51 <div class="buttons">
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 </div>
53 </div>
54 </div>
54 </div>
55 </div>
55 </div>
General Comments 0
You need to be logged in to leave comments. Login now