##// END OF EJS Templates
Moved out reposcan into hg Model....
marcink -
r665:070f3274 beta
parent child Browse files
Show More
@@ -6,7 +6,7 b' from rhodecode.config.routing import mak'
6 6 from rhodecode.lib.auth import set_available_permissions, set_base_path
7 7 from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config
8 8 from rhodecode.model import init_model
9 from rhodecode.model.hg import _get_repos_cached_initial
9 from rhodecode.model.hg import HgModel
10 10 from sqlalchemy import engine_from_config
11 11 import logging
12 12 import os
@@ -69,7 +69,8 b' def load_environment(global_conf, app_co'
69 69 #init baseui
70 70 config['pylons.app_globals'].baseui = make_ui('db')
71 71
72 repo2db_mapper(_get_repos_cached_initial(config['pylons.app_globals'], initial))
72 g = config['pylons.app_globals']
73 repo2db_mapper(HgModel().repo_scan(g.paths[0][1], g.baseui, initial))
73 74 set_available_permissions(config)
74 75 set_base_path(config)
75 76 set_rhodecode_config(config)
@@ -74,7 +74,6 b' class ReposController(BaseController):'
74 74 try:
75 75 form_result = _form.to_python(dict(request.POST))
76 76 repo_model.create(form_result, c.rhodecode_user)
77 invalidate_cache('cached_repo_list')
78 77 h.flash(_('created repository %s') % form_result['repo_name'],
79 78 category='success')
80 79
@@ -133,7 +132,7 b' class ReposController(BaseController):'
133 132 try:
134 133 form_result = _form.to_python(dict(request.POST))
135 134 repo_model.update(repo_name, form_result)
136 invalidate_cache('cached_repo_list')
135 invalidate_cache('get_repo_cached_%s' % repo_name)
137 136 h.flash(_('Repository %s updated succesfully' % repo_name),
138 137 category='success')
139 138 changed_name = form_result['repo_name']
@@ -182,7 +181,7 b' class ReposController(BaseController):'
182 181 action_logger(self.rhodecode_user, 'admin_deleted_repo',
183 182 repo_name, '', self.sa)
184 183 repo_model.delete(repo)
185 invalidate_cache('cached_repo_list')
184 invalidate_cache('get_repo_cached_%s' % repo_name)
186 185 h.flash(_('deleted repository %s') % repo_name, category='success')
187 186
188 187 except Exception, e:
@@ -33,12 +33,13 b' from rhodecode.lib.auth import LoginRequ'
33 33 from rhodecode.lib.base import BaseController, render
34 34 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
35 35 set_rhodecode_config, get_hg_settings, get_hg_ui_settings
36 from rhodecode.model.db import RhodeCodeSettings, RhodeCodeUi
36 from rhodecode.model.db import RhodeCodeSettings, RhodeCodeUi, Repository
37 37 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
38 38 ApplicationUiSettingsForm
39 39 from rhodecode.model.hg import HgModel
40 40 from rhodecode.model.user import UserModel
41 41 from rhodecode.lib.celerylib import tasks, run_task
42 from sqlalchemy import func
42 43 import formencode
43 44 import logging
44 45 import traceback
@@ -98,9 +99,12 b' class SettingsController(BaseController)'
98 99 rm_obsolete = request.POST.get('destroy', False)
99 100 log.debug('Rescanning directories with destroy=%s', rm_obsolete)
100 101
101 initial = HgModel.repo_scan(g.paths[0][0], g.paths[0][1], g.baseui)
102 initial = HgModel().repo_scan(g.paths[0][1], g.baseui)
103 for repo_name in initial.keys():
104 invalidate_cache('get_repo_cached_%s' % repo_name)
105
102 106 repo2db_mapper(initial, rm_obsolete)
103 invalidate_cache('cached_repo_list')
107
104 108 h.flash(_('Repositories successfully rescanned'), category='success')
105 109
106 110 if setting_id == 'whoosh':
@@ -238,12 +242,14 b' class SettingsController(BaseController)'
238 242 """
239 243 GET /_admin/my_account Displays info about my account
240 244 """
245
241 246 # url('admin_settings_my_account')
242 247 c.user = UserModel(self.sa).get(c.rhodecode_user.user_id, cache=False)
243 c.user_repos = []
244 for repo in c.cached_repo_list.values():
245 if repo.dbrepo.user.username == c.user.username:
246 c.user_repos.append(repo)
248 all_repos = self.sa.query(Repository)\
249 .filter(Repository.user_id == c.user.user_id)\
250 .order_by(func.lower(Repository.repo_name))\
251 .all()
252 c.user_repos = HgModel().get_repos(all_repos)
247 253
248 254 if c.user.username == 'default':
249 255 h.flash(_("You can't edit this user since it's"
@@ -78,7 +78,7 b' class SettingsController(BaseController)'
78 78 try:
79 79 form_result = _form.to_python(dict(request.POST))
80 80 repo_model.update(repo_name, form_result)
81 invalidate_cache('cached_repo_list')
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']
@@ -96,7 +96,7 b' class SettingsController(BaseController)'
96 96 encoding="UTF-8")
97 97 except Exception:
98 98 log.error(traceback.format_exc())
99 h.flash(_('error occured during update of repository %s') \
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))
@@ -126,7 +126,7 b' class SettingsController(BaseController)'
126 126 action_logger(self.rhodecode_user, 'user_deleted_repo',
127 127 repo_name, '', self.sa)
128 128 repo_model.delete(repo)
129 invalidate_cache('cached_repo_list')
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,
@@ -9,20 +9,20 b' from rhodecode import __version__'
9 9 from rhodecode.lib import auth
10 10 from rhodecode.lib.utils import get_repo_slug
11 11 from rhodecode.model import meta
12 from rhodecode.model.hg import _get_repos_cached, \
13 _get_repos_switcher_cached
12 from rhodecode.model.hg import HgModel
14 13 from vcs import BACKENDS
14
15 15 class BaseController(WSGIController):
16 16
17 17 def __before__(self):
18 18 c.rhodecode_version = __version__
19 19 c.rhodecode_name = config['rhodecode_title']
20 20 c.repo_name = get_repo_slug(request)
21 c.cached_repo_list = _get_repos_cached()
22 c.repo_switcher_list = _get_repos_switcher_cached(c.cached_repo_list)
21 c.cached_repo_list = HgModel().get_repos()
23 22 c.backends = BACKENDS.keys()
23
24 24 if c.repo_name:
25 cached_repo = c.cached_repo_list.get(c.repo_name)
25 cached_repo = HgModel().get(c.repo_name)
26 26
27 27 if cached_repo:
28 28 c.repository_tags = cached_repo.tags
@@ -83,15 +83,15 b' class SimpleGit(object):'
83 83 self.repository = None
84 84 self.username = None
85 85 self.action = None
86
86
87 87 def __call__(self, environ, start_response):
88 88 if not is_git(environ):
89 89 return self.application(environ, start_response)
90
90
91 91 proxy_key = 'HTTP_X_REAL_IP'
92 92 def_key = 'REMOTE_ADDR'
93 93 self.ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
94
94
95 95 #===================================================================
96 96 # AUTHENTICATE THIS GIT REQUEST
97 97 #===================================================================
@@ -104,7 +104,7 b' class SimpleGit(object):'
104 104 REMOTE_USER.update(environ, result)
105 105 else:
106 106 return result.wsgi_application(environ, start_response)
107
107
108 108 #=======================================================================
109 109 # GET REPOSITORY
110 110 #=======================================================================
@@ -206,5 +206,4 b' class SimpleGit(object):'
206 206 """we know that some change was made to repositories and we should
207 207 invalidate the cache to see the changes right away but only for
208 208 push requests"""
209 invalidate_cache('cached_repo_list')
210 invalidate_cache('full_changelog', repo_name)
209 invalidate_cache('get_repo_cached_%s' % repo_name)
@@ -52,20 +52,20 b' class SimpleHg(object):'
52 52 self.repository = None
53 53 self.username = None
54 54 self.action = None
55
55
56 56 def __call__(self, environ, start_response):
57 57 if not is_mercurial(environ):
58 58 return self.application(environ, start_response)
59
59
60 60 proxy_key = 'HTTP_X_REAL_IP'
61 61 def_key = 'REMOTE_ADDR'
62 62 self.ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
63
63
64 64 #===================================================================
65 65 # AUTHENTICATE THIS MERCURIAL REQUEST
66 66 #===================================================================
67 67 username = REMOTE_USER(environ)
68
68
69 69 if not username:
70 70 self.authenticate.realm = self.config['rhodecode_realm']
71 71 result = self.authenticate(environ)
@@ -74,7 +74,7 b' class SimpleHg(object):'
74 74 REMOTE_USER.update(environ, result)
75 75 else:
76 76 return result.wsgi_application(environ, start_response)
77
77
78 78 #=======================================================================
79 79 # GET REPOSITORY
80 80 #=======================================================================
@@ -114,7 +114,7 b' class SimpleHg(object):'
114 114 'repository.admin')\
115 115 (user, repo_name):
116 116 return HTTPForbidden()(environ, start_response)
117
117
118 118 self.extras = {'ip':self.ipaddr,
119 119 'username':self.username,
120 120 'action':self.action,
@@ -200,8 +200,7 b' class SimpleHg(object):'
200 200 """we know that some change was made to repositories and we should
201 201 invalidate the cache to see the changes right away but only for
202 202 push requests"""
203 invalidate_cache('cached_repo_list')
204 invalidate_cache('full_changelog', repo_name)
203 invalidate_cache('get_repo_cached_%s' % repo_name)
205 204
206 205
207 206 def __load_web_settings(self, hgserve, extras={}):
@@ -209,12 +208,12 b' class SimpleHg(object):'
209 208 hgserve.repo.ui = self.baseui
210 209
211 210 hgrc = os.path.join(self.repo_path, '.hg', 'hgrc')
212
211
213 212 #inject some additional parameters that will be available in ui
214 213 #for hooks
215 214 for k, v in extras.items():
216 215 hgserve.repo.ui.setconfig('rhodecode_extras', k, v)
217
216
218 217 repoui = make_ui('file', hgrc, False)
219 218
220 219 if repoui:
@@ -222,7 +221,7 b' class SimpleHg(object):'
222 221 for section in ui_sections:
223 222 for k, v in repoui.configitems(section):
224 223 hgserve.repo.ui.setconfig(section, k, v)
225
224
226 225 return hgserve
227 226
228 227
@@ -275,25 +275,11 b' def set_rhodecode_config(config):'
275 275 config[k] = v
276 276
277 277 def invalidate_cache(name, *args):
278 """Invalidates given name cache"""
279
280 from beaker.cache import region_invalidate
281 log.info('INVALIDATING CACHE FOR %s', name)
282
283 """propagate our arguments to make sure invalidation works. First
284 argument has to be the name of cached func name give to cache decorator
285 without that the invalidation would not work"""
286 tmp = [name]
287 tmp.extend(args)
288 args = tuple(tmp)
289
290 if name == 'cached_repo_list':
291 from rhodecode.model.hg import _get_repos_cached
292 region_invalidate(_get_repos_cached, None, *args)
293
294 if name == 'full_changelog':
295 from rhodecode.model.hg import _full_changelog_cached
296 region_invalidate(_full_changelog_cached, None, *args)
278 """
279 Puts cache invalidation task into db for
280 further global cache invalidation
281 """
282 pass
297 283
298 284 class EmptyChangeset(BaseChangeset):
299 285 """
@@ -352,7 +338,6 b' def repo2db_mapper(initial_repo_list, re'
352 338 }
353 339 rm.create(form_data, user, just_db=True)
354 340
355
356 341 if remove_obsolete:
357 342 #remove from database those repositories that are not in the filesystem
358 343 for repo in sa.query(Repository).all():
@@ -360,10 +345,6 b' def repo2db_mapper(initial_repo_list, re'
360 345 sa.delete(repo)
361 346 sa.commit()
362 347
363
364 meta.Session.remove()
365
366
367 348 class OrderedDict(dict, DictMixin):
368 349
369 350 def __init__(self, *args, **kwds):
@@ -22,57 +22,25 b' Created on April 9, 2010'
22 22 Model for RhodeCode
23 23 @author: marcink
24 24 """
25 from beaker.cache import cache_region
25 from beaker.cache import cache_region, region_invalidate
26 26 from mercurial import ui
27 27 from rhodecode.lib import helpers as h
28 from rhodecode.lib.utils import invalidate_cache
29 28 from rhodecode.lib.auth import HasRepoPermissionAny
29 from rhodecode.lib.utils import get_repos
30 30 from rhodecode.model import meta
31 from rhodecode.model.db import Repository, User
31 from rhodecode.model.caching_query import FromCache
32 from rhodecode.model.db import Repository, User, RhodeCodeUi
32 33 from sqlalchemy.orm import joinedload
34 from vcs import get_repo as vcs_get_repo, get_backend
35 from vcs.backends.hg import MercurialRepository
33 36 from vcs.exceptions import RepositoryError, VCSError
37 from vcs.utils.lazy import LazyProperty
34 38 import logging
35 import sys
39 import os
36 40 import time
37 41
38 42 log = logging.getLogger(__name__)
39 43
40 try:
41 from vcs.backends.hg import MercurialRepository
42 from vcs.backends.git import GitRepository
43 except ImportError:
44 sys.stderr.write('You have to import vcs module')
45 raise Exception('Unable to import vcs')
46
47 def _get_repos_cached_initial(app_globals, initial):
48 """return cached dict with repos
49 """
50 g = app_globals
51 return HgModel().repo_scan(g.paths[0][1], g.baseui, initial)
52
53 @cache_region('long_term', 'cached_repo_list')
54 def _get_repos_cached():
55 """return cached dict with repos
56 """
57 log.info('getting all repositories list')
58 from pylons import app_globals as g
59 return HgModel().repo_scan(g.paths[0][1], g.baseui)
60
61 @cache_region('super_short_term', 'cached_repos_switcher_list')
62 def _get_repos_switcher_cached(cached_repo_list):
63 repos_lst = []
64 for repo in [x for x in cached_repo_list.values()]:
65 if HasRepoPermissionAny('repository.write', 'repository.read',
66 'repository.admin')(repo.name, 'main page check'):
67 repos_lst.append((repo.name, repo.dbrepo.private,))
68
69 return sorted(repos_lst, key=lambda k:k[0].lower())
70
71 @cache_region('long_term', 'full_changelog')
72 def _full_changelog_cached(repo_name):
73 log.info('getting full changelog for %s', repo_name)
74 return list(reversed(list(HgModel().get_repo(repo_name))))
75
76 44 class HgModel(object):
77 45 """
78 46 Mercurial Model
@@ -84,6 +52,16 b' class HgModel(object):'
84 52 else:
85 53 self.sa = sa
86 54
55
56 @LazyProperty
57 def repos_path(self):
58 """
59 Get's the repositories root path from database
60 """
61 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
62
63 return q.ui_value
64
87 65 def repo_scan(self, repos_path, baseui, initial=False):
88 66 """
89 67 Listing of repositories in given path. This path should not be a
@@ -91,93 +69,100 b' class HgModel(object):'
91 69
92 70 :param repos_path: path to directory containing repositories
93 71 :param baseui
94 :param initial: initial scann
72 :param initial: initial scan
95 73 """
96 74 log.info('scanning for repositories in %s', repos_path)
97 75
98 76 if not isinstance(baseui, ui.ui):
99 77 baseui = ui.ui()
100
101 from rhodecode.lib.utils import get_repos
102 repos = get_repos(repos_path)
103
104
105 78 repos_list = {}
106 for name, path in repos:
79 for name, path in get_repos(repos_path):
107 80 try:
108 #name = name.split('/')[-1]
109 81 if repos_list.has_key(name):
110 raise RepositoryError('Duplicate repository name %s found in'
111 ' %s' % (name, path))
82 raise RepositoryError('Duplicate repository name %s '
83 'found in %s' % (name, path))
112 84 else:
85
86 klass = get_backend(path[0])
87
113 88 if path[0] == 'hg':
114 repos_list[name] = MercurialRepository(path[1], baseui=baseui)
115 repos_list[name].name = name
89 repos_list[name] = klass(path[1], baseui=baseui)
116 90
117 91 if path[0] == 'git':
118 repos_list[name] = GitRepository(path[1])
119 repos_list[name].name = name
120
121 dbrepo = None
122 if not initial:
123 #for initial scann on application first run we don't
124 #have db repos yet.
125 dbrepo = self.sa.query(Repository)\
126 .options(joinedload(Repository.fork))\
127 .filter(Repository.repo_name == name)\
128 .scalar()
129
130 if dbrepo:
131 log.info('Adding db instance to cached list')
132 repos_list[name].dbrepo = dbrepo
133 repos_list[name].description = dbrepo.description
134 if dbrepo.user:
135 repos_list[name].contact = dbrepo.user.full_contact
136 else:
137 repos_list[name].contact = self.sa.query(User)\
138 .filter(User.admin == True).first().full_contact
92 repos_list[name] = klass(path[1])
139 93 except OSError:
140 94 continue
141 95
142 96 return repos_list
143 97
144 def get_repos(self):
145 for name, repo in _get_repos_cached().items():
98 def get_repos(self, all_repos=None):
99 """
100 Get all repos from db and for each such repo make backend and
101 fetch dependent data from db
102 """
103 if not all_repos:
104 all_repos = self.sa.query(Repository).all()
146 105
147 if isinstance(repo, MercurialRepository) and repo._get_hidden():
148 #skip hidden web repository
149 continue
106 for r in all_repos:
107
108 repo = self.get(r.repo_name)
150 109
151 last_change = repo.last_change
152 tip = h.get_changeset_safe(repo, 'tip')
110 if repo is not None:
111 last_change = repo.last_change
112 tip = h.get_changeset_safe(repo, 'tip')
153 113
154 tmp_d = {}
155 tmp_d['name'] = repo.name
156 tmp_d['name_sort'] = tmp_d['name'].lower()
157 tmp_d['description'] = repo.description
158 tmp_d['description_sort'] = tmp_d['description']
159 tmp_d['last_change'] = last_change
160 tmp_d['last_change_sort'] = time.mktime(last_change.timetuple())
161 tmp_d['tip'] = tip.raw_id
162 tmp_d['tip_sort'] = tip.revision
163 tmp_d['rev'] = tip.revision
164 tmp_d['contact'] = repo.contact
165 tmp_d['contact_sort'] = tmp_d['contact']
166 tmp_d['repo_archives'] = list(repo._get_archives())
167 tmp_d['last_msg'] = tip.message
168 tmp_d['repo'] = repo
169 yield tmp_d
114 tmp_d = {}
115 tmp_d['name'] = repo.name
116 tmp_d['name_sort'] = tmp_d['name'].lower()
117 tmp_d['description'] = repo.dbrepo.description
118 tmp_d['description_sort'] = tmp_d['description']
119 tmp_d['last_change'] = last_change
120 tmp_d['last_change_sort'] = time.mktime(last_change.timetuple())
121 tmp_d['tip'] = tip.raw_id
122 tmp_d['tip_sort'] = tip.revision
123 tmp_d['rev'] = tip.revision
124 tmp_d['contact'] = repo.dbrepo.user.full_contact
125 tmp_d['contact_sort'] = tmp_d['contact']
126 tmp_d['repo_archives'] = list(repo._get_archives())
127 tmp_d['last_msg'] = tip.message
128 tmp_d['repo'] = repo
129 yield tmp_d
170 130
171 131 def get_repo(self, repo_name):
172 try:
173 repo = _get_repos_cached()[repo_name]
174 return repo
175 except KeyError:
176 #i we're here and we got key errors let's try to invalidate the
177 #cahce and try again
178 invalidate_cache('cached_repo_list')
179 repo = _get_repos_cached()[repo_name]
132 return self.get(repo_name)
133
134 def get(self, repo_name):
135 """
136 Get's repository from given name, creates BackendInstance and
137 propagates it's data from database with all additional information
138 :param repo_name:
139 """
140 if not HasRepoPermissionAny('repository.read', 'repository.write',
141 'repository.admin')(repo_name, 'get repo check'):
142 return
143
144 @cache_region('long_term', 'get_repo_cached_%s' % repo_name)
145 def _get_repo(repo_name):
146
147 repo = vcs_get_repo(os.path.join(self.repos_path, repo_name),
148 alias=None, create=False)
149
150 #skip hidden web repository
151 if isinstance(repo, MercurialRepository) and repo._get_hidden():
152 return
153
154 dbrepo = self.sa.query(Repository)\
155 .options(joinedload(Repository.fork))\
156 .options(joinedload(Repository.user))\
157 .filter(Repository.repo_name == repo_name)\
158 .scalar()
159 repo.dbrepo = dbrepo
180 160 return repo
181 161
162 invalidate = False
163 if invalidate:
164 log.info('INVALIDATING CACHE FOR %s', repo_name)
165 region_invalidate(_get_repo, None, repo_name)
182 166
167 return _get_repo(repo_name)
183 168
@@ -100,32 +100,32 b''
100 100 %for repo in c.user_repos:
101 101 <tr>
102 102 <td>
103 %if repo.dbrepo.repo_type =='hg':
103 %if repo['repo'].dbrepo.repo_type =='hg':
104 104 <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="/images/icons/hgicon.png"/>
105 %elif repo.dbrepo.repo_type =='git':
105 %elif repo['repo'].dbrepo.repo_type =='git':
106 106 <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="/images/icons/giticon.png"/>
107 107 %else:
108 108
109 109 %endif
110 %if repo.dbrepo.private:
110 %if repo['repo'].dbrepo.private:
111 111 <img class="icon" alt="${_('private')}" src="/images/icons/lock.png"/>
112 112 %else:
113 113 <img class="icon" alt="${_('public')}" src="/images/icons/lock_open.png"/>
114 114 %endif
115 115
116 ${h.link_to(repo.name, h.url('summary_home',repo_name=repo.name),class_="repo_name")}
117 %if repo.dbrepo.fork:
118 <a href="${h.url('summary_home',repo_name=repo.dbrepo.fork.repo_name)}">
116 ${h.link_to(repo['repo'].name, h.url('summary_home',repo_name=repo['repo'].name),class_="repo_name")}
117 %if repo['repo'].dbrepo.fork:
118 <a href="${h.url('summary_home',repo_name=repo['repo'].dbrepo.fork.repo_name)}">
119 119 <img class="icon" alt="${_('public')}"
120 title="${_('Fork of')} ${repo.dbrepo.fork.repo_name}"
120 title="${_('Fork of')} ${repo['repo'].dbrepo.fork.repo_name}"
121 121 src="/images/icons/arrow_divide.png"/></a>
122 122 %endif
123 123 </td>
124 <td><span class="tooltip" tooltip_title="${repo.last_change}">${("r%s:%s") % (h.get_changeset_safe(repo,'tip').revision,h.short_id(h.get_changeset_safe(repo,'tip').raw_id))}</span></td>
125 <td><a href="${h.url('repo_settings_home',repo_name=repo.name)}" title="${_('edit')}"><img class="icon" alt="${_('private')}" src="/images/icons/application_form_edit.png"/></a></td>
124 <td><span class="tooltip" tooltip_title="${repo['repo'].last_change}">${("r%s:%s") % (h.get_changeset_safe(repo['repo'],'tip').revision,h.short_id(h.get_changeset_safe(repo['repo'],'tip').raw_id))}</span></td>
125 <td><a href="${h.url('repo_settings_home',repo_name=repo['repo'].name)}" title="${_('edit')}"><img class="icon" alt="${_('private')}" src="/images/icons/application_form_edit.png"/></a></td>
126 126 <td>
127 ${h.form(url('repo_settings_delete', repo_name=repo.name),method='delete')}
128 ${h.submit('remove_%s' % repo.name,'',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
127 ${h.form(url('repo_settings_delete', repo_name=repo['repo'].name),method='delete')}
128 ${h.submit('remove_%s' % repo['repo'].name,'',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
129 129 ${h.end_form()}
130 130 </td>
131 131 </tr>
@@ -98,11 +98,12 b''
98 98 <span>&darr;</span>
99 99 </a>
100 100 <ul class="repo_switcher">
101 %for repo,private in c.repo_switcher_list:
102 %if private:
103 <li>${h.link_to(repo,h.url('summary_home',repo_name=repo),class_="private_repo")}</li>
101 %for repo in c.cached_repo_list:
102
103 %if repo['repo'].dbrepo.private:
104 <li>${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="private_repo %s" % repo['repo'].dbrepo.repo_type)}</li>
104 105 %else:
105 <li>${h.link_to(repo,h.url('summary_home',repo_name=repo),class_="public_repo")}</li>
106 <li>${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="public_repo %s" % repo['repo'].dbrepo.repo_type)}</li>
106 107 %endif
107 108 %endfor
108 109 </ul>
General Comments 0
You need to be logged in to leave comments. Login now