##// END OF EJS Templates
extended size of some input fields...
marcink -
r562:1a77a0c3 default
parent child Browse files
Show More
@@ -1,325 +1,322 b''
1 from celery.decorators import task
1 from celery.decorators import task
2
2
3 from operator import itemgetter
3 from operator import itemgetter
4 from pylons.i18n.translation import _
4 from pylons.i18n.translation import _
5 from rhodecode.lib.celerylib import run_task, locked_task
5 from rhodecode.lib.celerylib import run_task, locked_task
6 from rhodecode.lib.helpers import person
6 from rhodecode.lib.helpers import person
7 from rhodecode.lib.smtp_mailer import SmtpMailer
7 from rhodecode.lib.smtp_mailer import SmtpMailer
8 from rhodecode.lib.utils import OrderedDict
8 from rhodecode.lib.utils import OrderedDict
9 from time import mktime
9 from time import mktime
10 from vcs.backends.hg import MercurialRepository
10 from vcs.backends.hg import MercurialRepository
11 import json
11 import json
12 import traceback
12 import traceback
13
13
14 try:
14 try:
15 from celeryconfig import PYLONS_CONFIG as config
15 from celeryconfig import PYLONS_CONFIG as config
16 celery_on = True
16 celery_on = True
17 except ImportError:
17 except ImportError:
18 #if celeryconfig is not present let's just load our pylons
18 #if celeryconfig is not present let's just load our pylons
19 #config instead
19 #config instead
20 from pylons import config
20 from pylons import config
21 celery_on = False
21 celery_on = False
22
22
23
23
24 __all__ = ['whoosh_index', 'get_commits_stats',
24 __all__ = ['whoosh_index', 'get_commits_stats',
25 'reset_user_password', 'send_email']
25 'reset_user_password', 'send_email']
26
26
27 def get_session():
27 def get_session():
28 if celery_on:
28 if celery_on:
29 from sqlalchemy import engine_from_config
29 from sqlalchemy import engine_from_config
30 from sqlalchemy.orm import sessionmaker, scoped_session
30 from sqlalchemy.orm import sessionmaker, scoped_session
31 engine = engine_from_config(dict(config.items('app:main')), 'sqlalchemy.db1.')
31 engine = engine_from_config(dict(config.items('app:main')), 'sqlalchemy.db1.')
32 sa = scoped_session(sessionmaker(bind=engine))
32 sa = scoped_session(sessionmaker(bind=engine))
33 else:
33 else:
34 #If we don't use celery reuse our current application Session
34 #If we don't use celery reuse our current application Session
35 from rhodecode.model.meta import Session
35 from rhodecode.model.meta import Session
36 sa = Session
36 sa = Session
37
37
38 return sa
38 return sa
39
39
40 def get_hg_settings():
40 def get_hg_settings():
41 from rhodecode.model.db import RhodeCodeSettings
41 from rhodecode.model.db import RhodeCodeSettings
42 sa = get_session()
42 sa = get_session()
43 ret = sa.query(RhodeCodeSettings).all()
43 ret = sa.query(RhodeCodeSettings).all()
44
44
45 if not ret:
45 if not ret:
46 raise Exception('Could not get application settings !')
46 raise Exception('Could not get application settings !')
47 settings = {}
47 settings = {}
48 for each in ret:
48 for each in ret:
49 settings['rhodecode_' + each.app_settings_name] = each.app_settings_value
49 settings['rhodecode_' + each.app_settings_name] = each.app_settings_value
50
50
51 return settings
51 return settings
52
52
53 def get_hg_ui_settings():
53 def get_hg_ui_settings():
54 from rhodecode.model.db import RhodeCodeUi
54 from rhodecode.model.db import RhodeCodeUi
55 sa = get_session()
55 sa = get_session()
56 ret = sa.query(RhodeCodeUi).all()
56 ret = sa.query(RhodeCodeUi).all()
57
57
58 if not ret:
58 if not ret:
59 raise Exception('Could not get application ui settings !')
59 raise Exception('Could not get application ui settings !')
60 settings = {}
60 settings = {}
61 for each in ret:
61 for each in ret:
62 k = each.ui_key
62 k = each.ui_key
63 v = each.ui_value
63 v = each.ui_value
64 if k == '/':
64 if k == '/':
65 k = 'root_path'
65 k = 'root_path'
66
66
67 if k.find('.') != -1:
67 if k.find('.') != -1:
68 k = k.replace('.', '_')
68 k = k.replace('.', '_')
69
69
70 if each.ui_section == 'hooks':
70 if each.ui_section == 'hooks':
71 v = each.ui_active
71 v = each.ui_active
72
72
73 settings[each.ui_section + '_' + k] = v
73 settings[each.ui_section + '_' + k] = v
74
74
75 return settings
75 return settings
76
76
77 @task
77 @task
78 @locked_task
78 @locked_task
79 def whoosh_index(repo_location, full_index):
79 def whoosh_index(repo_location, full_index):
80 log = whoosh_index.get_logger()
80 log = whoosh_index.get_logger()
81 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
81 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
82 WhooshIndexingDaemon(repo_location=repo_location).run(full_index=full_index)
82 WhooshIndexingDaemon(repo_location=repo_location).run(full_index=full_index)
83
83
84 @task
84 @task
85 @locked_task
85 @locked_task
86 def get_commits_stats(repo_name, ts_min_y, ts_max_y):
86 def get_commits_stats(repo_name, ts_min_y, ts_max_y):
87 from rhodecode.model.db import Statistics, Repository
87 from rhodecode.model.db import Statistics, Repository
88 log = get_commits_stats.get_logger()
88 log = get_commits_stats.get_logger()
89 author_key_cleaner = lambda k: person(k).replace('"', "") #for js data compatibilty
89 author_key_cleaner = lambda k: person(k).replace('"', "") #for js data compatibilty
90
90
91 commits_by_day_author_aggregate = {}
91 commits_by_day_author_aggregate = {}
92 commits_by_day_aggregate = {}
92 commits_by_day_aggregate = {}
93 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
93 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
94 repo = MercurialRepository(repos_path + repo_name)
94 repo = MercurialRepository(repos_path + repo_name)
95
95
96 skip_date_limit = True
96 skip_date_limit = True
97 parse_limit = 350 #limit for single task changeset parsing optimal for
97 parse_limit = 350 #limit for single task changeset parsing optimal for
98 last_rev = 0
98 last_rev = 0
99 last_cs = None
99 last_cs = None
100 timegetter = itemgetter('time')
100 timegetter = itemgetter('time')
101
101
102 sa = get_session()
102 sa = get_session()
103
103
104 dbrepo = sa.query(Repository)\
104 dbrepo = sa.query(Repository)\
105 .filter(Repository.repo_name == repo_name).scalar()
105 .filter(Repository.repo_name == repo_name).scalar()
106 cur_stats = sa.query(Statistics)\
106 cur_stats = sa.query(Statistics)\
107 .filter(Statistics.repository == dbrepo).scalar()
107 .filter(Statistics.repository == dbrepo).scalar()
108 if cur_stats:
108 if cur_stats:
109 last_rev = cur_stats.stat_on_revision
109 last_rev = cur_stats.stat_on_revision
110 if not repo.revisions:
110 if not repo.revisions:
111 return True
111 return True
112
112
113 if last_rev == repo.revisions[-1] and len(repo.revisions) > 1:
113 if last_rev == repo.revisions[-1] and len(repo.revisions) > 1:
114 #pass silently without any work if we're not on first revision or current
114 #pass silently without any work if we're not on first revision or current
115 #state of parsing revision(from db marker) is the last revision
115 #state of parsing revision(from db marker) is the last revision
116 return True
116 return True
117
117
118 if cur_stats:
118 if cur_stats:
119 commits_by_day_aggregate = OrderedDict(
119 commits_by_day_aggregate = OrderedDict(
120 json.loads(
120 json.loads(
121 cur_stats.commit_activity_combined))
121 cur_stats.commit_activity_combined))
122 commits_by_day_author_aggregate = json.loads(cur_stats.commit_activity)
122 commits_by_day_author_aggregate = json.loads(cur_stats.commit_activity)
123
123
124 log.debug('starting parsing %s', parse_limit)
124 log.debug('starting parsing %s', parse_limit)
125 for cnt, rev in enumerate(repo.revisions[last_rev:]):
125 for cnt, rev in enumerate(repo.revisions[last_rev:]):
126 last_cs = cs = repo.get_changeset(rev)
126 last_cs = cs = repo.get_changeset(rev)
127 k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
127 k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
128 cs.date.timetuple()[2])
128 cs.date.timetuple()[2])
129 timetupple = [int(x) for x in k.split('-')]
129 timetupple = [int(x) for x in k.split('-')]
130 timetupple.extend([0 for _ in xrange(6)])
130 timetupple.extend([0 for _ in xrange(6)])
131 k = mktime(timetupple)
131 k = mktime(timetupple)
132 if commits_by_day_author_aggregate.has_key(author_key_cleaner(cs.author)):
132 if commits_by_day_author_aggregate.has_key(author_key_cleaner(cs.author)):
133 try:
133 try:
134 l = [timegetter(x) for x in commits_by_day_author_aggregate\
134 l = [timegetter(x) for x in commits_by_day_author_aggregate\
135 [author_key_cleaner(cs.author)]['data']]
135 [author_key_cleaner(cs.author)]['data']]
136 time_pos = l.index(k)
136 time_pos = l.index(k)
137 except ValueError:
137 except ValueError:
138 time_pos = False
138 time_pos = False
139
139
140 if time_pos >= 0 and time_pos is not False:
140 if time_pos >= 0 and time_pos is not False:
141
141
142 datadict = commits_by_day_author_aggregate\
142 datadict = commits_by_day_author_aggregate\
143 [author_key_cleaner(cs.author)]['data'][time_pos]
143 [author_key_cleaner(cs.author)]['data'][time_pos]
144
144
145 datadict["commits"] += 1
145 datadict["commits"] += 1
146 datadict["added"] += len(cs.added)
146 datadict["added"] += len(cs.added)
147 datadict["changed"] += len(cs.changed)
147 datadict["changed"] += len(cs.changed)
148 datadict["removed"] += len(cs.removed)
148 datadict["removed"] += len(cs.removed)
149 #print datadict
150
149
151 else:
150 else:
152 #print 'ELSE !!!!'
153 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
151 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
154
152
155 datadict = {"time":k,
153 datadict = {"time":k,
156 "commits":1,
154 "commits":1,
157 "added":len(cs.added),
155 "added":len(cs.added),
158 "changed":len(cs.changed),
156 "changed":len(cs.changed),
159 "removed":len(cs.removed),
157 "removed":len(cs.removed),
160 }
158 }
161 commits_by_day_author_aggregate\
159 commits_by_day_author_aggregate\
162 [author_key_cleaner(cs.author)]['data'].append(datadict)
160 [author_key_cleaner(cs.author)]['data'].append(datadict)
163
161
164 else:
162 else:
165 #print k, 'nokey ADDING'
166 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
163 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
167 commits_by_day_author_aggregate[author_key_cleaner(cs.author)] = {
164 commits_by_day_author_aggregate[author_key_cleaner(cs.author)] = {
168 "label":author_key_cleaner(cs.author),
165 "label":author_key_cleaner(cs.author),
169 "data":[{"time":k,
166 "data":[{"time":k,
170 "commits":1,
167 "commits":1,
171 "added":len(cs.added),
168 "added":len(cs.added),
172 "changed":len(cs.changed),
169 "changed":len(cs.changed),
173 "removed":len(cs.removed),
170 "removed":len(cs.removed),
174 }],
171 }],
175 "schema":["commits"],
172 "schema":["commits"],
176 }
173 }
177
174
178 # #gather all data by day
175 #gather all data by day
179 if commits_by_day_aggregate.has_key(k):
176 if commits_by_day_aggregate.has_key(k):
180 commits_by_day_aggregate[k] += 1
177 commits_by_day_aggregate[k] += 1
181 else:
178 else:
182 commits_by_day_aggregate[k] = 1
179 commits_by_day_aggregate[k] = 1
183
180
184 if cnt >= parse_limit:
181 if cnt >= parse_limit:
185 #don't fetch to much data since we can freeze application
182 #don't fetch to much data since we can freeze application
186 break
183 break
187
184
188 overview_data = []
185 overview_data = []
189 for k, v in commits_by_day_aggregate.items():
186 for k, v in commits_by_day_aggregate.items():
190 overview_data.append([k, v])
187 overview_data.append([k, v])
191 overview_data = sorted(overview_data, key=itemgetter(0))
188 overview_data = sorted(overview_data, key=itemgetter(0))
192
189
193 if not commits_by_day_author_aggregate:
190 if not commits_by_day_author_aggregate:
194 commits_by_day_author_aggregate[author_key_cleaner(repo.contact)] = {
191 commits_by_day_author_aggregate[author_key_cleaner(repo.contact)] = {
195 "label":author_key_cleaner(repo.contact),
192 "label":author_key_cleaner(repo.contact),
196 "data":[0, 1],
193 "data":[0, 1],
197 "schema":["commits"],
194 "schema":["commits"],
198 }
195 }
199
196
200 stats = cur_stats if cur_stats else Statistics()
197 stats = cur_stats if cur_stats else Statistics()
201 stats.commit_activity = json.dumps(commits_by_day_author_aggregate)
198 stats.commit_activity = json.dumps(commits_by_day_author_aggregate)
202 stats.commit_activity_combined = json.dumps(overview_data)
199 stats.commit_activity_combined = json.dumps(overview_data)
203
200
204 log.debug('last revison %s', last_rev)
201 log.debug('last revison %s', last_rev)
205 leftovers = len(repo.revisions[last_rev:])
202 leftovers = len(repo.revisions[last_rev:])
206 log.debug('revisions to parse %s', leftovers)
203 log.debug('revisions to parse %s', leftovers)
207
204
208 if last_rev == 0 or leftovers < parse_limit:
205 if last_rev == 0 or leftovers < parse_limit:
209 stats.languages = json.dumps(__get_codes_stats(repo_name))
206 stats.languages = json.dumps(__get_codes_stats(repo_name))
210
207
211 stats.repository = dbrepo
208 stats.repository = dbrepo
212 stats.stat_on_revision = last_cs.revision
209 stats.stat_on_revision = last_cs.revision
213
210
214 try:
211 try:
215 sa.add(stats)
212 sa.add(stats)
216 sa.commit()
213 sa.commit()
217 except:
214 except:
218 log.error(traceback.format_exc())
215 log.error(traceback.format_exc())
219 sa.rollback()
216 sa.rollback()
220 return False
217 return False
221 if len(repo.revisions) > 1:
218 if len(repo.revisions) > 1:
222 run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
219 run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
223
220
224 return True
221 return True
225
222
226 @task
223 @task
227 def reset_user_password(user_email):
224 def reset_user_password(user_email):
228 log = reset_user_password.get_logger()
225 log = reset_user_password.get_logger()
229 from rhodecode.lib import auth
226 from rhodecode.lib import auth
230 from rhodecode.model.db import User
227 from rhodecode.model.db import User
231
228
232 try:
229 try:
233 try:
230 try:
234 sa = get_session()
231 sa = get_session()
235 user = sa.query(User).filter(User.email == user_email).scalar()
232 user = sa.query(User).filter(User.email == user_email).scalar()
236 new_passwd = auth.PasswordGenerator().gen_password(8,
233 new_passwd = auth.PasswordGenerator().gen_password(8,
237 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
234 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
238 if user:
235 if user:
239 user.password = auth.get_crypt_password(new_passwd)
236 user.password = auth.get_crypt_password(new_passwd)
240 sa.add(user)
237 sa.add(user)
241 sa.commit()
238 sa.commit()
242 log.info('change password for %s', user_email)
239 log.info('change password for %s', user_email)
243 if new_passwd is None:
240 if new_passwd is None:
244 raise Exception('unable to generate new password')
241 raise Exception('unable to generate new password')
245
242
246 except:
243 except:
247 log.error(traceback.format_exc())
244 log.error(traceback.format_exc())
248 sa.rollback()
245 sa.rollback()
249
246
250 run_task(send_email, user_email,
247 run_task(send_email, user_email,
251 "Your new rhodecode password",
248 "Your new rhodecode password",
252 'Your new rhodecode password:%s' % (new_passwd))
249 'Your new rhodecode password:%s' % (new_passwd))
253 log.info('send new password mail to %s', user_email)
250 log.info('send new password mail to %s', user_email)
254
251
255
252
256 except:
253 except:
257 log.error('Failed to update user password')
254 log.error('Failed to update user password')
258 log.error(traceback.format_exc())
255 log.error(traceback.format_exc())
259 return True
256 return True
260
257
261 @task
258 @task
262 def send_email(recipients, subject, body):
259 def send_email(recipients, subject, body):
263 log = send_email.get_logger()
260 log = send_email.get_logger()
264 email_config = dict(config.items('DEFAULT'))
261 email_config = dict(config.items('DEFAULT'))
265 mail_from = email_config.get('app_email_from')
262 mail_from = email_config.get('app_email_from')
266 user = email_config.get('smtp_username')
263 user = email_config.get('smtp_username')
267 passwd = email_config.get('smtp_password')
264 passwd = email_config.get('smtp_password')
268 mail_server = email_config.get('smtp_server')
265 mail_server = email_config.get('smtp_server')
269 mail_port = email_config.get('smtp_port')
266 mail_port = email_config.get('smtp_port')
270 tls = email_config.get('smtp_use_tls')
267 tls = email_config.get('smtp_use_tls')
271 ssl = False
268 ssl = False
272
269
273 try:
270 try:
274 m = SmtpMailer(mail_from, user, passwd, mail_server,
271 m = SmtpMailer(mail_from, user, passwd, mail_server,
275 mail_port, ssl, tls)
272 mail_port, ssl, tls)
276 m.send(recipients, subject, body)
273 m.send(recipients, subject, body)
277 except:
274 except:
278 log.error('Mail sending failed')
275 log.error('Mail sending failed')
279 log.error(traceback.format_exc())
276 log.error(traceback.format_exc())
280 return False
277 return False
281 return True
278 return True
282
279
283 @task
280 @task
284 def create_repo_fork(form_data, cur_user):
281 def create_repo_fork(form_data, cur_user):
285 import os
282 import os
286 from rhodecode.model.repo_model import RepoModel
283 from rhodecode.model.repo_model import RepoModel
287 sa = get_session()
284 sa = get_session()
288 rm = RepoModel(sa)
285 rm = RepoModel(sa)
289
286
290 rm.create(form_data, cur_user, just_db=True, fork=True)
287 rm.create(form_data, cur_user, just_db=True, fork=True)
291
288
292 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
289 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
293 repo_path = os.path.join(repos_path, form_data['repo_name'])
290 repo_path = os.path.join(repos_path, form_data['repo_name'])
294 repo_fork_path = os.path.join(repos_path, form_data['fork_name'])
291 repo_fork_path = os.path.join(repos_path, form_data['fork_name'])
295
292
296 MercurialRepository(str(repo_fork_path), True, clone_url=str(repo_path))
293 MercurialRepository(str(repo_fork_path), True, clone_url=str(repo_path))
297
294
298
295
299 def __get_codes_stats(repo_name):
296 def __get_codes_stats(repo_name):
300 LANGUAGES_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c',
297 LANGUAGES_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c',
301 'cfg', 'cfm', 'cpp', 'cs', 'diff', 'do', 'el', 'erl',
298 'cfg', 'cfm', 'cpp', 'cs', 'diff', 'do', 'el', 'erl',
302 'h', 'java', 'js', 'jsp', 'jspx', 'lisp',
299 'h', 'java', 'js', 'jsp', 'jspx', 'lisp',
303 'lua', 'm', 'mako', 'ml', 'pas', 'patch', 'php', 'php3',
300 'lua', 'm', 'mako', 'ml', 'pas', 'patch', 'php', 'php3',
304 'php4', 'phtml', 'pm', 'py', 'rb', 'rst', 's', 'sh',
301 'php4', 'phtml', 'pm', 'py', 'rb', 'rst', 's', 'sh',
305 'tpl', 'txt', 'vim', 'wss', 'xhtml', 'xml', 'xsl', 'xslt',
302 'tpl', 'txt', 'vim', 'wss', 'xhtml', 'xml', 'xsl', 'xslt',
306 'yaws']
303 'yaws']
307 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
304 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
308 repo = MercurialRepository(repos_path + repo_name)
305 repo = MercurialRepository(repos_path + repo_name)
309
306
310 code_stats = {}
307 code_stats = {}
311 for topnode, dirs, files in repo.walk('/', 'tip'):
308 for topnode, dirs, files in repo.walk('/', 'tip'):
312 for f in files:
309 for f in files:
313 k = f.mimetype
310 k = f.mimetype
314 if f.extension in LANGUAGES_EXTENSIONS:
311 if f.extension in LANGUAGES_EXTENSIONS:
315 if code_stats.has_key(k):
312 if code_stats.has_key(k):
316 code_stats[k] += 1
313 code_stats[k] += 1
317 else:
314 else:
318 code_stats[k] = 1
315 code_stats[k] = 1
319
316
320 return code_stats or {}
317 return code_stats or {}
321
318
322
319
323
320
324
321
325
322
@@ -1,60 +1,60 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('Add new repository')}
5 ${_('Add new repository')}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 ${h.link_to(_('Admin'),h.url('admin_home'))}
9 ${h.link_to(_('Admin'),h.url('admin_home'))}
10 &raquo;
10 &raquo;
11 ${h.link_to(_('Repositories'),h.url('repos'))}
11 ${h.link_to(_('Repositories'),h.url('repos'))}
12 &raquo;
12 &raquo;
13 ${_('add new')}
13 ${_('add new')}
14 </%def>
14 </%def>
15
15
16 <%def name="page_nav()">
16 <%def name="page_nav()">
17 ${self.menu('admin')}
17 ${self.menu('admin')}
18 </%def>
18 </%def>
19 <%def name="main()">
19 <%def name="main()">
20 <div class="box">
20 <div class="box">
21 <!-- box / title -->
21 <!-- box / title -->
22 <div class="title">
22 <div class="title">
23 ${self.breadcrumbs()}
23 ${self.breadcrumbs()}
24 </div>
24 </div>
25 ${h.form(url('repos'))}
25 ${h.form(url('repos'))}
26 <div class="form">
26 <div class="form">
27 <!-- fields -->
27 <!-- fields -->
28 <div class="fields">
28 <div class="fields">
29 <div class="field">
29 <div class="field">
30 <div class="label">
30 <div class="label">
31 <label for="repo_name">${_('Name')}:</label>
31 <label for="repo_name">${_('Name')}:</label>
32 </div>
32 </div>
33 <div class="input">
33 <div class="input">
34 ${h.text('repo_name',c.new_repo)}
34 ${h.text('repo_name',c.new_repo,class_="small")}
35 </div>
35 </div>
36 </div>
36 </div>
37 <div class="field">
37 <div class="field">
38 <div class="label label-textarea">
38 <div class="label label-textarea">
39 <label for="description">${_('Description')}:</label>
39 <label for="description">${_('Description')}:</label>
40 </div>
40 </div>
41 <div class="textarea text-area editor">
41 <div class="textarea text-area editor">
42 ${h.textarea('description',cols=23,rows=5)}
42 ${h.textarea('description',cols=23,rows=5)}
43 </div>
43 </div>
44 </div>
44 </div>
45 <div class="field">
45 <div class="field">
46 <div class="label label-checkbox">
46 <div class="label label-checkbox">
47 <label for="private">${_('Private')}:</label>
47 <label for="private">${_('Private')}:</label>
48 </div>
48 </div>
49 <div class="checkboxes">
49 <div class="checkboxes">
50 ${h.checkbox('private',value="True")}
50 ${h.checkbox('private',value="True")}
51 </div>
51 </div>
52 </div>
52 </div>
53 <div class="buttons">
53 <div class="buttons">
54 ${h.submit('add','add',class_="ui-button ui-widget ui-state-default ui-corner-all")}
54 ${h.submit('add','add',class_="ui-button ui-widget ui-state-default ui-corner-all")}
55 </div>
55 </div>
56 </div>
56 </div>
57 </div>
57 </div>
58 ${h.end_form()}
58 ${h.end_form()}
59 </div>
59 </div>
60 </%def>
60 </%def>
@@ -1,57 +1,57 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('Repositories administration')}
5 ${_('Repositories administration')}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 ${_('add new repository')}
9 ${_('add new repository')}
10 </%def>
10 </%def>
11
11
12 <%def name="page_nav()">
12 <%def name="page_nav()">
13 ${self.menu('admin')}
13 ${self.menu('admin')}
14 </%def>
14 </%def>
15 <%def name="main()">
15 <%def name="main()">
16 <div class="box">
16 <div class="box">
17 <!-- box / title -->
17 <!-- box / title -->
18 <div class="title">
18 <div class="title">
19 ${self.breadcrumbs()}
19 ${self.breadcrumbs()}
20 </div>
20 </div>
21 ${h.form(url('repos'))}
21 ${h.form(url('repos'))}
22 <div class="form">
22 <div class="form">
23 <!-- fields -->
23 <!-- fields -->
24 <div class="fields">
24 <div class="fields">
25 <div class="field">
25 <div class="field">
26 <div class="label">
26 <div class="label">
27 <label for="repo_name">${_('Name')}:</label>
27 <label for="repo_name">${_('Name')}:</label>
28 </div>
28 </div>
29 <div class="input">
29 <div class="input">
30 ${h.text('repo_name',c.new_repo)}
30 ${h.text('repo_name',c.new_repo,class_="small")}
31 ${h.hidden('user_created','True')}
31 ${h.hidden('user_created','True')}
32 </div>
32 </div>
33 </div>
33 </div>
34 <div class="field">
34 <div class="field">
35 <div class="label label-textarea">
35 <div class="label label-textarea">
36 <label for="description">${_('Description')}:</label>
36 <label for="description">${_('Description')}:</label>
37 </div>
37 </div>
38 <div class="textarea text-area editor">
38 <div class="textarea text-area editor">
39 ${h.textarea('description',cols=23,rows=5)}
39 ${h.textarea('description',cols=23,rows=5)}
40 </div>
40 </div>
41 </div>
41 </div>
42 <div class="field">
42 <div class="field">
43 <div class="label label-checkbox">
43 <div class="label label-checkbox">
44 <label for="private">${_('Private')}:</label>
44 <label for="private">${_('Private')}:</label>
45 </div>
45 </div>
46 <div class="checkboxes">
46 <div class="checkboxes">
47 ${h.checkbox('private',value="True")}
47 ${h.checkbox('private',value="True")}
48 </div>
48 </div>
49 </div>
49 </div>
50 <div class="buttons">
50 <div class="buttons">
51 ${h.submit('add','add',class_="ui-button ui-widget ui-state-default ui-corner-all")}
51 ${h.submit('add','add',class_="ui-button ui-widget ui-state-default ui-corner-all")}
52 </div>
52 </div>
53 </div>
53 </div>
54 </div>
54 </div>
55 ${h.end_form()}
55 ${h.end_form()}
56 </div>
56 </div>
57 </%def>
57 </%def>
@@ -1,275 +1,275 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('Repositories administration')}
5 ${_('Repositories administration')}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 ${h.link_to(_('Admin'),h.url('admin_home'))}
9 ${h.link_to(_('Admin'),h.url('admin_home'))}
10 &raquo;
10 &raquo;
11 ${h.link_to(_('Repositories'),h.url('repos'))}
11 ${h.link_to(_('Repositories'),h.url('repos'))}
12 &raquo;
12 &raquo;
13 ${_('edit')} "${c.repo_name}"
13 ${_('edit')} "${c.repo_name}"
14 </%def>
14 </%def>
15
15
16 <%def name="page_nav()">
16 <%def name="page_nav()">
17 ${self.menu('admin')}
17 ${self.menu('admin')}
18 </%def>
18 </%def>
19
19
20 <%def name="main()">
20 <%def name="main()">
21 <div class="box">
21 <div class="box">
22 <!-- box / title -->
22 <!-- box / title -->
23 <div class="title">
23 <div class="title">
24 ${self.breadcrumbs()}
24 ${self.breadcrumbs()}
25 </div>
25 </div>
26 ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')}
26 ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')}
27 <div class="form">
27 <div class="form">
28 <!-- fields -->
28 <!-- fields -->
29 <div class="fields">
29 <div class="fields">
30 <div class="field">
30 <div class="field">
31 <div class="label">
31 <div class="label">
32 <label for="repo_name">${_('Name')}:</label>
32 <label for="repo_name">${_('Name')}:</label>
33 </div>
33 </div>
34 <div class="input input-medium">
34 <div class="input input-medium">
35 ${h.text('repo_name')}
35 ${h.text('repo_name',class_="small")}
36 </div>
36 </div>
37 </div>
37 </div>
38
38
39 <div class="field">
39 <div class="field">
40 <div class="label label-textarea">
40 <div class="label label-textarea">
41 <label for="description">${_('Description')}:</label>
41 <label for="description">${_('Description')}:</label>
42 </div>
42 </div>
43 <div class="textarea text-area editor">
43 <div class="textarea text-area editor">
44 ${h.textarea('description',cols=23,rows=5)}
44 ${h.textarea('description',cols=23,rows=5)}
45 </div>
45 </div>
46 </div>
46 </div>
47
47
48 <div class="field">
48 <div class="field">
49 <div class="label label-checkbox">
49 <div class="label label-checkbox">
50 <label for="private">${_('Private')}:</label>
50 <label for="private">${_('Private')}:</label>
51 </div>
51 </div>
52 <div class="checkboxes">
52 <div class="checkboxes">
53 ${h.checkbox('private',value="True")}
53 ${h.checkbox('private',value="True")}
54 </div>
54 </div>
55 </div>
55 </div>
56
56
57 <div class="field">
57 <div class="field">
58 <div class="label label-checkbox">
58 <div class="label label-checkbox">
59 <label for="user">${_('Owner')}:</label>
59 <label for="user">${_('Owner')}:</label>
60 </div>
60 </div>
61 <div class="input input-small ac">
61 <div class="input input-small ac">
62 <div class="perm_ac">
62 <div class="perm_ac">
63 ${h.text('user',class_='yui-ac-input')}
63 ${h.text('user',class_='yui-ac-input')}
64 <div id="owner_container"></div>
64 <div id="owner_container"></div>
65 </div>
65 </div>
66 </div>
66 </div>
67 </div>
67 </div>
68
68
69 <div class="field">
69 <div class="field">
70 <div class="label">
70 <div class="label">
71 <label for="input">${_('Permissions')}:</label>
71 <label for="input">${_('Permissions')}:</label>
72 </div>
72 </div>
73 <div class="input">
73 <div class="input">
74 <table id="permissions_manage">
74 <table id="permissions_manage">
75 <tr>
75 <tr>
76 <td>${_('none')}</td>
76 <td>${_('none')}</td>
77 <td>${_('read')}</td>
77 <td>${_('read')}</td>
78 <td>${_('write')}</td>
78 <td>${_('write')}</td>
79 <td>${_('admin')}</td>
79 <td>${_('admin')}</td>
80 <td>${_('user')}</td>
80 <td>${_('user')}</td>
81 <td></td>
81 <td></td>
82 </tr>
82 </tr>
83
83
84 %for r2p in c.repo_info.repo_to_perm:
84 %for r2p in c.repo_info.repo_to_perm:
85 %if r2p.user.username =='default' and c.repo_info.private:
85 %if r2p.user.username =='default' and c.repo_info.private:
86 <tr>
86 <tr>
87 <td colspan="4">
87 <td colspan="4">
88 <span class="private_repo_msg">
88 <span class="private_repo_msg">
89 ${_('private repository')}
89 ${_('private repository')}
90 </span>
90 </span>
91 </td>
91 </td>
92 <td class="private_repo_msg">${r2p.user.username}</td>
92 <td class="private_repo_msg">${r2p.user.username}</td>
93 </tr>
93 </tr>
94 %else:
94 %else:
95 <tr id="id${id(r2p.user.username)}">
95 <tr id="id${id(r2p.user.username)}">
96 <td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
96 <td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
97 <td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
97 <td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
98 <td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
98 <td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
99 <td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
99 <td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
100 <td>${r2p.user.username}</td>
100 <td>${r2p.user.username}</td>
101 <td>
101 <td>
102 %if r2p.user.username !='default':
102 %if r2p.user.username !='default':
103 <span class="delete_icon action_button" onclick="ajaxAction(${r2p.user.user_id},'${'id%s'%id(r2p.user.username)}')">
103 <span class="delete_icon action_button" onclick="ajaxAction(${r2p.user.user_id},'${'id%s'%id(r2p.user.username)}')">
104 <script type="text/javascript">
104 <script type="text/javascript">
105 function ajaxAction(user_id,field_id){
105 function ajaxAction(user_id,field_id){
106 var sUrl = "${h.url('delete_repo_user',repo_name=c.repo_name)}";
106 var sUrl = "${h.url('delete_repo_user',repo_name=c.repo_name)}";
107 var callback = { success:function(o){
107 var callback = { success:function(o){
108 var tr = YAHOO.util.Dom.get(String(field_id));
108 var tr = YAHOO.util.Dom.get(String(field_id));
109 tr.parentNode.removeChild(tr);},failure:function(o){
109 tr.parentNode.removeChild(tr);},failure:function(o){
110 alert("${_('Failed to remove user')}");},};
110 alert("${_('Failed to remove user')}");},};
111 var postData = '_method=delete&user_id='+user_id;
111 var postData = '_method=delete&user_id='+user_id;
112 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);};
112 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);};
113 </script>
113 </script>
114 </span>
114 </span>
115 %endif
115 %endif
116 </td>
116 </td>
117 </tr>
117 </tr>
118 %endif
118 %endif
119 %endfor
119 %endfor
120
120
121 <tr id="add_perm_input">
121 <tr id="add_perm_input">
122 <td>${h.radio('perm_new_user','repository.none')}</td>
122 <td>${h.radio('perm_new_user','repository.none')}</td>
123 <td>${h.radio('perm_new_user','repository.read')}</td>
123 <td>${h.radio('perm_new_user','repository.read')}</td>
124 <td>${h.radio('perm_new_user','repository.write')}</td>
124 <td>${h.radio('perm_new_user','repository.write')}</td>
125 <td>${h.radio('perm_new_user','repository.admin')}</td>
125 <td>${h.radio('perm_new_user','repository.admin')}</td>
126 <td class='ac'>
126 <td class='ac'>
127 <div class="perm_ac" id="perm_ac">
127 <div class="perm_ac" id="perm_ac">
128 ${h.text('perm_new_user_name',class_='yui-ac-input')}
128 ${h.text('perm_new_user_name',class_='yui-ac-input')}
129 <div id="perm_container"></div>
129 <div id="perm_container"></div>
130 </div>
130 </div>
131 </td>
131 </td>
132 <td></td>
132 <td></td>
133 </tr>
133 </tr>
134 <tr>
134 <tr>
135 <td colspan="6">
135 <td colspan="6">
136 <span id="add_perm" class="add_icon" style="cursor: pointer;">
136 <span id="add_perm" class="add_icon" style="cursor: pointer;">
137 ${_('Add another user')}
137 ${_('Add another user')}
138 </span>
138 </span>
139 </td>
139 </td>
140 </tr>
140 </tr>
141 </table>
141 </table>
142 </div>
142 </div>
143
143
144 <div class="buttons">
144 <div class="buttons">
145 ${h.submit('save','save',class_="ui-button ui-widget ui-state-default ui-corner-all")}
145 ${h.submit('save','save',class_="ui-button ui-widget ui-state-default ui-corner-all")}
146 </div>
146 </div>
147 </div>
147 </div>
148 </div>
148 </div>
149 </div>
149 </div>
150 ${h.end_form()}
150 ${h.end_form()}
151 <script type="text/javascript">
151 <script type="text/javascript">
152 YAHOO.util.Event.onDOMReady(function(){
152 YAHOO.util.Event.onDOMReady(function(){
153 var D = YAHOO.util.Dom;
153 var D = YAHOO.util.Dom;
154 if(!D.hasClass('perm_new_user_name','error')){
154 if(!D.hasClass('perm_new_user_name','error')){
155 D.setStyle('add_perm_input','display','none');
155 D.setStyle('add_perm_input','display','none');
156 }
156 }
157 YAHOO.util.Event.addListener('add_perm','click',function(){
157 YAHOO.util.Event.addListener('add_perm','click',function(){
158 D.setStyle('add_perm_input','display','');
158 D.setStyle('add_perm_input','display','');
159 D.setStyle('add_perm','opacity','0.6');
159 D.setStyle('add_perm','opacity','0.6');
160 D.setStyle('add_perm','cursor','default');
160 D.setStyle('add_perm','cursor','default');
161 });
161 });
162 });
162 });
163 </script>
163 </script>
164 <script type="text/javascript">
164 <script type="text/javascript">
165 YAHOO.example.FnMultipleFields = function(){
165 YAHOO.example.FnMultipleFields = function(){
166 var myContacts = ${c.users_array|n}
166 var myContacts = ${c.users_array|n}
167
167
168 // Define a custom search function for the DataSource
168 // Define a custom search function for the DataSource
169 var matchNames = function(sQuery) {
169 var matchNames = function(sQuery) {
170 // Case insensitive matching
170 // Case insensitive matching
171 var query = sQuery.toLowerCase(),
171 var query = sQuery.toLowerCase(),
172 contact,
172 contact,
173 i=0,
173 i=0,
174 l=myContacts.length,
174 l=myContacts.length,
175 matches = [];
175 matches = [];
176
176
177 // Match against each name of each contact
177 // Match against each name of each contact
178 for(; i<l; i++) {
178 for(; i<l; i++) {
179 contact = myContacts[i];
179 contact = myContacts[i];
180 if((contact.fname.toLowerCase().indexOf(query) > -1) ||
180 if((contact.fname.toLowerCase().indexOf(query) > -1) ||
181 (contact.lname.toLowerCase().indexOf(query) > -1) ||
181 (contact.lname.toLowerCase().indexOf(query) > -1) ||
182 (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) {
182 (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) {
183 matches[matches.length] = contact;
183 matches[matches.length] = contact;
184 }
184 }
185 }
185 }
186
186
187 return matches;
187 return matches;
188 };
188 };
189
189
190 // Use a FunctionDataSource
190 // Use a FunctionDataSource
191 var oDS = new YAHOO.util.FunctionDataSource(matchNames);
191 var oDS = new YAHOO.util.FunctionDataSource(matchNames);
192 oDS.responseSchema = {
192 oDS.responseSchema = {
193 fields: ["id", "fname", "lname", "nname"]
193 fields: ["id", "fname", "lname", "nname"]
194 }
194 }
195
195
196 // Instantiate AutoComplete for perms
196 // Instantiate AutoComplete for perms
197 var oAC_perms = new YAHOO.widget.AutoComplete("perm_new_user_name", "perm_container", oDS);
197 var oAC_perms = new YAHOO.widget.AutoComplete("perm_new_user_name", "perm_container", oDS);
198 oAC_perms.useShadow = false;
198 oAC_perms.useShadow = false;
199 oAC_perms.resultTypeList = false;
199 oAC_perms.resultTypeList = false;
200
200
201 // Instantiate AutoComplete for owner
201 // Instantiate AutoComplete for owner
202 var oAC_owner = new YAHOO.widget.AutoComplete("user", "owner_container", oDS);
202 var oAC_owner = new YAHOO.widget.AutoComplete("user", "owner_container", oDS);
203 oAC_owner.useShadow = false;
203 oAC_owner.useShadow = false;
204 oAC_owner.resultTypeList = false;
204 oAC_owner.resultTypeList = false;
205
205
206
206
207 // Custom formatter to highlight the matching letters
207 // Custom formatter to highlight the matching letters
208 var custom_formatter = function(oResultData, sQuery, sResultMatch) {
208 var custom_formatter = function(oResultData, sQuery, sResultMatch) {
209 var query = sQuery.toLowerCase(),
209 var query = sQuery.toLowerCase(),
210 fname = oResultData.fname,
210 fname = oResultData.fname,
211 lname = oResultData.lname,
211 lname = oResultData.lname,
212 nname = oResultData.nname || "", // Guard against null value
212 nname = oResultData.nname || "", // Guard against null value
213 query = sQuery.toLowerCase(),
213 query = sQuery.toLowerCase(),
214 fnameMatchIndex = fname.toLowerCase().indexOf(query),
214 fnameMatchIndex = fname.toLowerCase().indexOf(query),
215 lnameMatchIndex = lname.toLowerCase().indexOf(query),
215 lnameMatchIndex = lname.toLowerCase().indexOf(query),
216 nnameMatchIndex = nname.toLowerCase().indexOf(query),
216 nnameMatchIndex = nname.toLowerCase().indexOf(query),
217 displayfname, displaylname, displaynname;
217 displayfname, displaylname, displaynname;
218
218
219 if(fnameMatchIndex > -1) {
219 if(fnameMatchIndex > -1) {
220 displayfname = highlightMatch(fname, query, fnameMatchIndex);
220 displayfname = highlightMatch(fname, query, fnameMatchIndex);
221 }
221 }
222 else {
222 else {
223 displayfname = fname;
223 displayfname = fname;
224 }
224 }
225
225
226 if(lnameMatchIndex > -1) {
226 if(lnameMatchIndex > -1) {
227 displaylname = highlightMatch(lname, query, lnameMatchIndex);
227 displaylname = highlightMatch(lname, query, lnameMatchIndex);
228 }
228 }
229 else {
229 else {
230 displaylname = lname;
230 displaylname = lname;
231 }
231 }
232
232
233 if(nnameMatchIndex > -1) {
233 if(nnameMatchIndex > -1) {
234 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
234 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
235 }
235 }
236 else {
236 else {
237 displaynname = nname ? "(" + nname + ")" : "";
237 displaynname = nname ? "(" + nname + ")" : "";
238 }
238 }
239
239
240 return displayfname + " " + displaylname + " " + displaynname;
240 return displayfname + " " + displaylname + " " + displaynname;
241
241
242 };
242 };
243 oAC_perms.formatResult = custom_formatter;
243 oAC_perms.formatResult = custom_formatter;
244 oAC_owner.formatResult = custom_formatter;
244 oAC_owner.formatResult = custom_formatter;
245
245
246 // Helper function for the formatter
246 // Helper function for the formatter
247 var highlightMatch = function(full, snippet, matchindex) {
247 var highlightMatch = function(full, snippet, matchindex) {
248 return full.substring(0, matchindex) +
248 return full.substring(0, matchindex) +
249 "<span class='match'>" +
249 "<span class='match'>" +
250 full.substr(matchindex, snippet.length) +
250 full.substr(matchindex, snippet.length) +
251 "</span>" +
251 "</span>" +
252 full.substring(matchindex + snippet.length);
252 full.substring(matchindex + snippet.length);
253 };
253 };
254
254
255 var myHandler = function(sType, aArgs) {
255 var myHandler = function(sType, aArgs) {
256 var myAC = aArgs[0]; // reference back to the AC instance
256 var myAC = aArgs[0]; // reference back to the AC instance
257 var elLI = aArgs[1]; // reference to the selected LI element
257 var elLI = aArgs[1]; // reference to the selected LI element
258 var oData = aArgs[2]; // object literal of selected item's result data
258 var oData = aArgs[2]; // object literal of selected item's result data
259 myAC.getInputEl().value = oData.nname;
259 myAC.getInputEl().value = oData.nname;
260 };
260 };
261
261
262 oAC_perms.itemSelectEvent.subscribe(myHandler);
262 oAC_perms.itemSelectEvent.subscribe(myHandler);
263 oAC_owner.itemSelectEvent.subscribe(myHandler);
263 oAC_owner.itemSelectEvent.subscribe(myHandler);
264
264
265 return {
265 return {
266 oDS: oDS,
266 oDS: oDS,
267 oAC_perms: oAC_perms,
267 oAC_perms: oAC_perms,
268 oAC_owner: oAC_owner,
268 oAC_owner: oAC_owner,
269 };
269 };
270 }();
270 }();
271
271
272 </script>
272 </script>
273
273
274 </div>
274 </div>
275 </%def> No newline at end of file
275 </%def>
@@ -1,58 +1,58 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('Fork repository')} ${c.repo_info.repo_name}
5 ${_('Fork repository')} ${c.repo_info.repo_name}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 ${h.link_to(c.repo_info.repo_name,h.url('summary_home',repo_name=c.repo_info.repo_name))}
9 ${h.link_to(c.repo_info.repo_name,h.url('summary_home',repo_name=c.repo_info.repo_name))}
10 &raquo;
10 &raquo;
11 ${_('fork')}
11 ${_('fork')}
12 </%def>
12 </%def>
13
13
14 <%def name="page_nav()">
14 <%def name="page_nav()">
15 ${self.menu('')}
15 ${self.menu('')}
16 </%def>
16 </%def>
17 <%def name="main()">
17 <%def name="main()">
18 <div class="box">
18 <div class="box">
19 <!-- box / title -->
19 <!-- box / title -->
20 <div class="title">
20 <div class="title">
21 ${self.breadcrumbs()}
21 ${self.breadcrumbs()}
22 </div>
22 </div>
23 ${h.form(url('repo_fork_create_home',repo_name=c.repo_info.repo_name))}
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">
27 <div class="field">
27 <div class="field">
28 <div class="label">
28 <div class="label">
29 <label for="repo_name">${_('Fork name')}:</label>
29 <label for="repo_name">${_('Fork name')}:</label>
30 </div>
30 </div>
31 <div class="input">
31 <div class="input">
32 ${h.text('fork_name')}
32 ${h.text('fork_name',class_="small")}
33 </div>
33 </div>
34 </div>
34 </div>
35 <div class="field">
35 <div class="field">
36 <div class="label label-textarea">
36 <div class="label label-textarea">
37 <label for="description">${_('Description')}:</label>
37 <label for="description">${_('Description')}:</label>
38 </div>
38 </div>
39 <div class="textarea text-area editor">
39 <div class="textarea text-area editor">
40 ${h.textarea('description',cols=23,rows=5)}
40 ${h.textarea('description',cols=23,rows=5)}
41 </div>
41 </div>
42 </div>
42 </div>
43 <div class="field">
43 <div class="field">
44 <div class="label label-checkbox">
44 <div class="label label-checkbox">
45 <label for="private">${_('Private')}:</label>
45 <label for="private">${_('Private')}:</label>
46 </div>
46 </div>
47 <div class="checkboxes">
47 <div class="checkboxes">
48 ${h.checkbox('private',value="True")}
48 ${h.checkbox('private',value="True")}
49 </div>
49 </div>
50 </div>
50 </div>
51 <div class="buttons">
51 <div class="buttons">
52 ${h.submit('','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>
56 ${h.end_form()}
56 ${h.end_form()}
57 </div>
57 </div>
58 </%def>
58 </%def>
@@ -1,261 +1,261 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('Repository settings')}
5 ${_('Repository settings')}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 ${h.link_to(c.repo_info.repo_name,h.url('summary_home',repo_name=c.repo_info.repo_name))}
9 ${h.link_to(c.repo_info.repo_name,h.url('summary_home',repo_name=c.repo_info.repo_name))}
10 &raquo;
10 &raquo;
11 ${_('Settings')}
11 ${_('Settings')}
12
12
13 </%def>
13 </%def>
14 <%def name="page_nav()">
14 <%def name="page_nav()">
15 ${self.menu('settings')}
15 ${self.menu('settings')}
16 </%def>
16 </%def>
17 <%def name="main()">
17 <%def name="main()">
18 <div class="box">
18 <div class="box">
19 <!-- box / title -->
19 <!-- box / title -->
20 <div class="title">
20 <div class="title">
21 ${self.breadcrumbs()}
21 ${self.breadcrumbs()}
22 </div>
22 </div>
23 ${h.form(url('repo_settings_update', repo_name=c.repo_info.repo_name),method='put')}
23 ${h.form(url('repo_settings_update', repo_name=c.repo_info.repo_name),method='put')}
24 <div class="form">
24 <div class="form">
25 <!-- fields -->
25 <!-- fields -->
26 <div class="fields">
26 <div class="fields">
27 <div class="field">
27 <div class="field">
28 <div class="label">
28 <div class="label">
29 <label for="repo_name">${_('Name')}:</label>
29 <label for="repo_name">${_('Name')}:</label>
30 </div>
30 </div>
31 <div class="input input-medium">
31 <div class="input input-medium">
32 ${h.text('repo_name')}
32 ${h.text('repo_name',class_="small")}
33 </div>
33 </div>
34 </div>
34 </div>
35
35
36 <div class="field">
36 <div class="field">
37 <div class="label label-textarea">
37 <div class="label label-textarea">
38 <label for="description">${_('Description')}:</label>
38 <label for="description">${_('Description')}:</label>
39 </div>
39 </div>
40 <div class="textarea text-area editor">
40 <div class="textarea text-area editor">
41 ${h.textarea('description',cols=23,rows=5)}
41 ${h.textarea('description',cols=23,rows=5)}
42 </div>
42 </div>
43 </div>
43 </div>
44
44
45 <div class="field">
45 <div class="field">
46 <div class="label label-checkbox">
46 <div class="label label-checkbox">
47 <label for="private">${_('Private')}:</label>
47 <label for="private">${_('Private')}:</label>
48 </div>
48 </div>
49 <div class="checkboxes">
49 <div class="checkboxes">
50 ${h.checkbox('private',value="True")}
50 ${h.checkbox('private',value="True")}
51 </div>
51 </div>
52 </div>
52 </div>
53
53
54 <div class="field">
54 <div class="field">
55 <div class="label">
55 <div class="label">
56 <label for="">${_('Permissions')}:</label>
56 <label for="">${_('Permissions')}:</label>
57 </div>
57 </div>
58 <div class="input">
58 <div class="input">
59 <table id="permissions_manage">
59 <table id="permissions_manage">
60 <tr>
60 <tr>
61 <td>${_('none')}</td>
61 <td>${_('none')}</td>
62 <td>${_('read')}</td>
62 <td>${_('read')}</td>
63 <td>${_('write')}</td>
63 <td>${_('write')}</td>
64 <td>${_('admin')}</td>
64 <td>${_('admin')}</td>
65 <td>${_('user')}</td>
65 <td>${_('user')}</td>
66 <td></td>
66 <td></td>
67 </tr>
67 </tr>
68
68
69 %for r2p in c.repo_info.repo_to_perm:
69 %for r2p in c.repo_info.repo_to_perm:
70 %if r2p.user.username =='default' and c.repo_info.private:
70 %if r2p.user.username =='default' and c.repo_info.private:
71 <tr>
71 <tr>
72 <td colspan="4">
72 <td colspan="4">
73 <span class="private_repo_msg">
73 <span class="private_repo_msg">
74 ${_('private repository')}
74 ${_('private repository')}
75 </span>
75 </span>
76 </td>
76 </td>
77 <td class="private_repo_msg">${r2p.user.username}</td>
77 <td class="private_repo_msg">${r2p.user.username}</td>
78 </tr>
78 </tr>
79 %else:
79 %else:
80 <tr id="id${id(r2p.user.username)}">
80 <tr id="id${id(r2p.user.username)}">
81 <td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
81 <td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
82 <td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
82 <td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
83 <td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
83 <td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
84 <td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
84 <td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
85 <td>${r2p.user.username}</td>
85 <td>${r2p.user.username}</td>
86 <td>
86 <td>
87 %if r2p.user.username !='default':
87 %if r2p.user.username !='default':
88 <span class="delete_icon action_button" onclick="ajaxAction(${r2p.user.user_id},'${'id%s'%id(r2p.user.username)}')">
88 <span class="delete_icon action_button" onclick="ajaxAction(${r2p.user.user_id},'${'id%s'%id(r2p.user.username)}')">
89 <script type="text/javascript">
89 <script type="text/javascript">
90 function ajaxAction(user_id,field_id){
90 function ajaxAction(user_id,field_id){
91 var sUrl = "${h.url('delete_repo_user',repo_name=c.repo_name)}";
91 var sUrl = "${h.url('delete_repo_user',repo_name=c.repo_name)}";
92 var callback = { success:function(o){
92 var callback = { success:function(o){
93 var tr = YAHOO.util.Dom.get(String(field_id));
93 var tr = YAHOO.util.Dom.get(String(field_id));
94 tr.parentNode.removeChild(tr);},failure:function(o){
94 tr.parentNode.removeChild(tr);},failure:function(o){
95 alert("${_('Failed to remove user')}");},};
95 alert("${_('Failed to remove user')}");},};
96 var postData = '_method=delete&user_id='+user_id;
96 var postData = '_method=delete&user_id='+user_id;
97 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);};
97 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);};
98 </script>
98 </script>
99 </span>
99 </span>
100 %endif
100 %endif
101 </td>
101 </td>
102 </tr>
102 </tr>
103 %endif
103 %endif
104 %endfor
104 %endfor
105
105
106
106
107 <tr id="add_perm_input">
107 <tr id="add_perm_input">
108 <td>${h.radio('perm_new_user','repository.none')}</td>
108 <td>${h.radio('perm_new_user','repository.none')}</td>
109 <td>${h.radio('perm_new_user','repository.read')}</td>
109 <td>${h.radio('perm_new_user','repository.read')}</td>
110 <td>${h.radio('perm_new_user','repository.write')}</td>
110 <td>${h.radio('perm_new_user','repository.write')}</td>
111 <td>${h.radio('perm_new_user','repository.admin')}</td>
111 <td>${h.radio('perm_new_user','repository.admin')}</td>
112 <td class='ac'>
112 <td class='ac'>
113 <div class="perm_ac" id="perm_ac">
113 <div class="perm_ac" id="perm_ac">
114 ${h.text('perm_new_user_name',class_='yui-ac-input')}
114 ${h.text('perm_new_user_name',class_='yui-ac-input')}
115 <div id="perm_container"></div>
115 <div id="perm_container"></div>
116 </div>
116 </div>
117 </td>
117 </td>
118 <td></td>
118 <td></td>
119 </tr>
119 </tr>
120 <tr>
120 <tr>
121 <td colspan="6">
121 <td colspan="6">
122 <span id="add_perm" class="add_icon" style="cursor: pointer;">
122 <span id="add_perm" class="add_icon" style="cursor: pointer;">
123 ${_('Add another user')}
123 ${_('Add another user')}
124 </span>
124 </span>
125 </td>
125 </td>
126 </tr>
126 </tr>
127 </table>
127 </table>
128 </div>
128 </div>
129
129
130 <div class="buttons">
130 <div class="buttons">
131 ${h.submit('update','update',class_="ui-button ui-widget ui-state-default ui-corner-all")}
131 ${h.submit('update','update',class_="ui-button ui-widget ui-state-default ui-corner-all")}
132 </div>
132 </div>
133 </div>
133 </div>
134 </div>
134 </div>
135 ${h.end_form()}
135 ${h.end_form()}
136 <script type="text/javascript">
136 <script type="text/javascript">
137 YAHOO.util.Event.onDOMReady(function(){
137 YAHOO.util.Event.onDOMReady(function(){
138 var D = YAHOO.util.Dom;
138 var D = YAHOO.util.Dom;
139 if(!D.hasClass('perm_new_user_name','error')){
139 if(!D.hasClass('perm_new_user_name','error')){
140 D.setStyle('add_perm_input','display','none');
140 D.setStyle('add_perm_input','display','none');
141 }
141 }
142 YAHOO.util.Event.addListener('add_perm','click',function(){
142 YAHOO.util.Event.addListener('add_perm','click',function(){
143 D.setStyle('add_perm_input','display','');
143 D.setStyle('add_perm_input','display','');
144 D.setStyle('add_perm','opacity','0.6');
144 D.setStyle('add_perm','opacity','0.6');
145 D.setStyle('add_perm','cursor','default');
145 D.setStyle('add_perm','cursor','default');
146 });
146 });
147 });
147 });
148 </script>
148 </script>
149 <script type="text/javascript">
149 <script type="text/javascript">
150 YAHOO.example.FnMultipleFields = function(){
150 YAHOO.example.FnMultipleFields = function(){
151 var myContacts = ${c.users_array|n}
151 var myContacts = ${c.users_array|n}
152
152
153 // Define a custom search function for the DataSource
153 // Define a custom search function for the DataSource
154 var matchNames = function(sQuery) {
154 var matchNames = function(sQuery) {
155 // Case insensitive matching
155 // Case insensitive matching
156 var query = sQuery.toLowerCase(),
156 var query = sQuery.toLowerCase(),
157 contact,
157 contact,
158 i=0,
158 i=0,
159 l=myContacts.length,
159 l=myContacts.length,
160 matches = [];
160 matches = [];
161
161
162 // Match against each name of each contact
162 // Match against each name of each contact
163 for(; i<l; i++) {
163 for(; i<l; i++) {
164 contact = myContacts[i];
164 contact = myContacts[i];
165 if((contact.fname.toLowerCase().indexOf(query) > -1) ||
165 if((contact.fname.toLowerCase().indexOf(query) > -1) ||
166 (contact.lname.toLowerCase().indexOf(query) > -1) ||
166 (contact.lname.toLowerCase().indexOf(query) > -1) ||
167 (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) {
167 (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) {
168 matches[matches.length] = contact;
168 matches[matches.length] = contact;
169 }
169 }
170 }
170 }
171
171
172 return matches;
172 return matches;
173 };
173 };
174
174
175 // Use a FunctionDataSource
175 // Use a FunctionDataSource
176 var oDS = new YAHOO.util.FunctionDataSource(matchNames);
176 var oDS = new YAHOO.util.FunctionDataSource(matchNames);
177 oDS.responseSchema = {
177 oDS.responseSchema = {
178 fields: ["id", "fname", "lname", "nname"]
178 fields: ["id", "fname", "lname", "nname"]
179 }
179 }
180
180
181 // Instantiate AutoComplete for perms
181 // Instantiate AutoComplete for perms
182 var oAC_perms = new YAHOO.widget.AutoComplete("perm_new_user_name", "perm_container", oDS);
182 var oAC_perms = new YAHOO.widget.AutoComplete("perm_new_user_name", "perm_container", oDS);
183 oAC_perms.useShadow = false;
183 oAC_perms.useShadow = false;
184 oAC_perms.resultTypeList = false;
184 oAC_perms.resultTypeList = false;
185
185
186 // Instantiate AutoComplete for owner
186 // Instantiate AutoComplete for owner
187 var oAC_owner = new YAHOO.widget.AutoComplete("user", "owner_container", oDS);
187 var oAC_owner = new YAHOO.widget.AutoComplete("user", "owner_container", oDS);
188 oAC_owner.useShadow = false;
188 oAC_owner.useShadow = false;
189 oAC_owner.resultTypeList = false;
189 oAC_owner.resultTypeList = false;
190
190
191
191
192 // Custom formatter to highlight the matching letters
192 // Custom formatter to highlight the matching letters
193 var custom_formatter = function(oResultData, sQuery, sResultMatch) {
193 var custom_formatter = function(oResultData, sQuery, sResultMatch) {
194 var query = sQuery.toLowerCase(),
194 var query = sQuery.toLowerCase(),
195 fname = oResultData.fname,
195 fname = oResultData.fname,
196 lname = oResultData.lname,
196 lname = oResultData.lname,
197 nname = oResultData.nname || "", // Guard against null value
197 nname = oResultData.nname || "", // Guard against null value
198 query = sQuery.toLowerCase(),
198 query = sQuery.toLowerCase(),
199 fnameMatchIndex = fname.toLowerCase().indexOf(query),
199 fnameMatchIndex = fname.toLowerCase().indexOf(query),
200 lnameMatchIndex = lname.toLowerCase().indexOf(query),
200 lnameMatchIndex = lname.toLowerCase().indexOf(query),
201 nnameMatchIndex = nname.toLowerCase().indexOf(query),
201 nnameMatchIndex = nname.toLowerCase().indexOf(query),
202 displayfname, displaylname, displaynname;
202 displayfname, displaylname, displaynname;
203
203
204 if(fnameMatchIndex > -1) {
204 if(fnameMatchIndex > -1) {
205 displayfname = highlightMatch(fname, query, fnameMatchIndex);
205 displayfname = highlightMatch(fname, query, fnameMatchIndex);
206 }
206 }
207 else {
207 else {
208 displayfname = fname;
208 displayfname = fname;
209 }
209 }
210
210
211 if(lnameMatchIndex > -1) {
211 if(lnameMatchIndex > -1) {
212 displaylname = highlightMatch(lname, query, lnameMatchIndex);
212 displaylname = highlightMatch(lname, query, lnameMatchIndex);
213 }
213 }
214 else {
214 else {
215 displaylname = lname;
215 displaylname = lname;
216 }
216 }
217
217
218 if(nnameMatchIndex > -1) {
218 if(nnameMatchIndex > -1) {
219 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
219 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
220 }
220 }
221 else {
221 else {
222 displaynname = nname ? "(" + nname + ")" : "";
222 displaynname = nname ? "(" + nname + ")" : "";
223 }
223 }
224
224
225 return displayfname + " " + displaylname + " " + displaynname;
225 return displayfname + " " + displaylname + " " + displaynname;
226
226
227 };
227 };
228 oAC_perms.formatResult = custom_formatter;
228 oAC_perms.formatResult = custom_formatter;
229 oAC_owner.formatResult = custom_formatter;
229 oAC_owner.formatResult = custom_formatter;
230
230
231 // Helper function for the formatter
231 // Helper function for the formatter
232 var highlightMatch = function(full, snippet, matchindex) {
232 var highlightMatch = function(full, snippet, matchindex) {
233 return full.substring(0, matchindex) +
233 return full.substring(0, matchindex) +
234 "<span class='match'>" +
234 "<span class='match'>" +
235 full.substr(matchindex, snippet.length) +
235 full.substr(matchindex, snippet.length) +
236 "</span>" +
236 "</span>" +
237 full.substring(matchindex + snippet.length);
237 full.substring(matchindex + snippet.length);
238 };
238 };
239
239
240 var myHandler = function(sType, aArgs) {
240 var myHandler = function(sType, aArgs) {
241 var myAC = aArgs[0]; // reference back to the AC instance
241 var myAC = aArgs[0]; // reference back to the AC instance
242 var elLI = aArgs[1]; // reference to the selected LI element
242 var elLI = aArgs[1]; // reference to the selected LI element
243 var oData = aArgs[2]; // object literal of selected item's result data
243 var oData = aArgs[2]; // object literal of selected item's result data
244 myAC.getInputEl().value = oData.nname;
244 myAC.getInputEl().value = oData.nname;
245 };
245 };
246
246
247 oAC_perms.itemSelectEvent.subscribe(myHandler);
247 oAC_perms.itemSelectEvent.subscribe(myHandler);
248 //oAC_owner.itemSelectEvent.subscribe(myHandler);
248 //oAC_owner.itemSelectEvent.subscribe(myHandler);
249
249
250 return {
250 return {
251 oDS: oDS,
251 oDS: oDS,
252 oAC_perms: oAC_perms,
252 oAC_perms: oAC_perms,
253 oAC_owner: oAC_owner,
253 oAC_owner: oAC_owner,
254 };
254 };
255 }();
255 }();
256
256
257 </script>
257 </script>
258 </div>
258 </div>
259 </%def>
259 </%def>
260
260
261
261
General Comments 0
You need to be logged in to leave comments. Login now