##// END OF EJS Templates
Fixed age, for new vcs implementation. Removed all obsolete date formatters...
marcink -
r635:fd63782c beta
parent child Browse files
Show More
@@ -1,72 +1,74 b''
1 1 """Pylons middleware initialization"""
2 2 from beaker.middleware import SessionMiddleware
3 3 from paste.cascade import Cascade
4 4 from paste.registry import RegistryManager
5 5 from paste.urlparser import StaticURLParser
6 6 from paste.deploy.converters import asbool
7 7 from pylons.middleware import ErrorHandler, StatusCodeRedirect
8 8 from pylons.wsgiapp import PylonsApp
9 9 from routes.middleware import RoutesMiddleware
10 10 from rhodecode.lib.middleware.simplehg import SimpleHg
11 from rhodecode.lib.middleware.simplegit import SimpleGit
11 12 from rhodecode.lib.middleware.https_fixup import HttpsFixup
12 13 from rhodecode.config.environment import load_environment
13 14
14 15 def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
15 16 """Create a Pylons WSGI application and return it
16 17
17 18 ``global_conf``
18 19 The inherited configuration for this application. Normally from
19 20 the [DEFAULT] section of the Paste ini file.
20 21
21 22 ``full_stack``
22 23 Whether or not this application provides a full WSGI stack (by
23 24 default, meaning it handles its own exceptions and errors).
24 25 Disable full_stack when this application is "managed" by
25 26 another WSGI middleware.
26 27
27 28 ``app_conf``
28 29 The application's local configuration. Normally specified in
29 30 the [app:<name>] section of the Paste ini file (where <name>
30 31 defaults to main).
31 32
32 33 """
33 34 # Configure the Pylons environment
34 35 config = load_environment(global_conf, app_conf)
35 36
36 37 # The Pylons WSGI app
37 38 app = PylonsApp(config=config)
38
39
39 40 # Routing/Session/Cache Middleware
40 41 app = RoutesMiddleware(app, config['routes.map'])
41 42 app = SessionMiddleware(app, config)
42
43
43 44 # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
44
45
45 46 app = SimpleHg(app, config)
46
47 app = SimpleGit(app, config)
48
47 49 if asbool(full_stack):
48 50 # Handle Python exceptions
49 51 app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
50 52
51 53 # Display error documents for 401, 403, 404 status codes (and
52 54 # 500 when debug is disabled)
53 55 if asbool(config['debug']):
54 56 app = StatusCodeRedirect(app)
55 57 else:
56 58 app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
57
59
58 60 #enable https redirets based on HTTP_X_URL_SCHEME set by proxy
59 61 app = HttpsFixup(app)
60
62
61 63 # Establish the Registry for this application
62 64 app = RegistryManager(app)
63 65
64 66 if asbool(static_files):
65 67 # Serve static files
66 68 static_app = StaticURLParser(config['pylons.paths']['static_files'])
67 69 app = Cascade([static_app, app])
68
70
69 71 app.config = config
70 72
71 73 return app
72 74
@@ -1,336 +1,334 b''
1 1 from celery.decorators import task
2 2
3 3 from operator import itemgetter
4 4 from pylons.i18n.translation import _
5 5 from rhodecode.lib.celerylib import run_task, locked_task
6 6 from rhodecode.lib.helpers import person
7 7 from rhodecode.lib.smtp_mailer import SmtpMailer
8 8 from rhodecode.lib.utils import OrderedDict
9 9 from time import mktime
10 10 from vcs.backends.hg import MercurialRepository
11 11 from vcs.backends.git import GitRepository
12 12 import os
13 13 import traceback
14 14 from vcs.backends import get_repo
15 15 from vcs.utils.helpers import get_scm
16 16
17 17 try:
18 18 import json
19 19 except ImportError:
20 20 #python 2.5 compatibility
21 21 import simplejson as json
22 22
23 23 try:
24 24 from celeryconfig import PYLONS_CONFIG as config
25 25 celery_on = True
26 26 except ImportError:
27 27 #if celeryconfig is not present let's just load our pylons
28 28 #config instead
29 29 from pylons import config
30 30 celery_on = False
31 31
32 32
33 33 __all__ = ['whoosh_index', 'get_commits_stats',
34 34 'reset_user_password', 'send_email']
35 35
36 36 def get_session():
37 37 if celery_on:
38 38 from sqlalchemy import engine_from_config
39 39 from sqlalchemy.orm import sessionmaker, scoped_session
40 40 engine = engine_from_config(dict(config.items('app:main')), 'sqlalchemy.db1.')
41 41 sa = scoped_session(sessionmaker(bind=engine))
42 42 else:
43 43 #If we don't use celery reuse our current application Session
44 44 from rhodecode.model.meta import Session
45 45 sa = Session()
46 46
47 47 return sa
48 48
49 49 def get_hg_settings():
50 50 from rhodecode.model.db import RhodeCodeSettings
51 51 sa = get_session()
52 52 ret = sa.query(RhodeCodeSettings).all()
53 53
54 54 if not ret:
55 55 raise Exception('Could not get application settings !')
56 56 settings = {}
57 57 for each in ret:
58 58 settings['rhodecode_' + each.app_settings_name] = each.app_settings_value
59 59
60 60 return settings
61 61
62 62 def get_hg_ui_settings():
63 63 from rhodecode.model.db import RhodeCodeUi
64 64 sa = get_session()
65 65 ret = sa.query(RhodeCodeUi).all()
66 66
67 67 if not ret:
68 68 raise Exception('Could not get application ui settings !')
69 69 settings = {}
70 70 for each in ret:
71 71 k = each.ui_key
72 72 v = each.ui_value
73 73 if k == '/':
74 74 k = 'root_path'
75 75
76 76 if k.find('.') != -1:
77 77 k = k.replace('.', '_')
78 78
79 79 if each.ui_section == 'hooks':
80 80 v = each.ui_active
81 81
82 82 settings[each.ui_section + '_' + k] = v
83 83
84 84 return settings
85 85
86 86 @task
87 87 @locked_task
88 88 def whoosh_index(repo_location, full_index):
89 89 log = whoosh_index.get_logger()
90 90 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
91 91 WhooshIndexingDaemon(repo_location=repo_location).run(full_index=full_index)
92 92
93 93 @task
94 94 @locked_task
95 95 def get_commits_stats(repo_name, ts_min_y, ts_max_y):
96 96 from rhodecode.model.db import Statistics, Repository
97 97 log = get_commits_stats.get_logger()
98 98 author_key_cleaner = lambda k: person(k).replace('"', "") #for js data compatibilty
99 99
100 100 commits_by_day_author_aggregate = {}
101 101 commits_by_day_aggregate = {}
102 102 repos_path = get_hg_ui_settings()['paths_root_path']
103 103 p = os.path.join(repos_path, repo_name)
104 repo = get_repo(get_scm(p)[0], p)
104 repo = get_repo(p)
105 105
106 106 skip_date_limit = True
107 107 parse_limit = 250 #limit for single task changeset parsing optimal for
108 108 last_rev = 0
109 109 last_cs = None
110 110 timegetter = itemgetter('time')
111 111
112 112 sa = get_session()
113 113
114 114 dbrepo = sa.query(Repository)\
115 115 .filter(Repository.repo_name == repo_name).scalar()
116 116 cur_stats = sa.query(Statistics)\
117 117 .filter(Statistics.repository == dbrepo).scalar()
118 118 if cur_stats:
119 119 last_rev = cur_stats.stat_on_revision
120 120 if not repo.revisions:
121 121 return True
122 122
123 123 if last_rev == repo.revisions[-1] and len(repo.revisions) > 1:
124 124 #pass silently without any work if we're not on first revision or current
125 125 #state of parsing revision(from db marker) is the last revision
126 126 return True
127 127
128 128 if cur_stats:
129 129 commits_by_day_aggregate = OrderedDict(
130 130 json.loads(
131 131 cur_stats.commit_activity_combined))
132 132 commits_by_day_author_aggregate = json.loads(cur_stats.commit_activity)
133 133
134 134 log.debug('starting parsing %s', parse_limit)
135 135 lmktime = mktime
136 136
137 137 for cnt, rev in enumerate(repo.revisions[last_rev:]):
138 138 last_cs = cs = repo.get_changeset(rev)
139 139 k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
140 140 cs.date.timetuple()[2])
141 141 timetupple = [int(x) for x in k.split('-')]
142 142 timetupple.extend([0 for _ in xrange(6)])
143 143 k = lmktime(timetupple)
144 144 if commits_by_day_author_aggregate.has_key(author_key_cleaner(cs.author)):
145 145 try:
146 146 l = [timegetter(x) for x in commits_by_day_author_aggregate\
147 147 [author_key_cleaner(cs.author)]['data']]
148 148 time_pos = l.index(k)
149 149 except ValueError:
150 150 time_pos = False
151 151
152 152 if time_pos >= 0 and time_pos is not False:
153 153
154 154 datadict = commits_by_day_author_aggregate\
155 155 [author_key_cleaner(cs.author)]['data'][time_pos]
156 156
157 157 datadict["commits"] += 1
158 158 datadict["added"] += len(cs.added)
159 159 datadict["changed"] += len(cs.changed)
160 160 datadict["removed"] += len(cs.removed)
161 161
162 162 else:
163 163 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
164 164
165 165 datadict = {"time":k,
166 166 "commits":1,
167 167 "added":len(cs.added),
168 168 "changed":len(cs.changed),
169 169 "removed":len(cs.removed),
170 170 }
171 171 commits_by_day_author_aggregate\
172 172 [author_key_cleaner(cs.author)]['data'].append(datadict)
173 173
174 174 else:
175 175 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
176 176 commits_by_day_author_aggregate[author_key_cleaner(cs.author)] = {
177 177 "label":author_key_cleaner(cs.author),
178 178 "data":[{"time":k,
179 179 "commits":1,
180 180 "added":len(cs.added),
181 181 "changed":len(cs.changed),
182 182 "removed":len(cs.removed),
183 183 }],
184 184 "schema":["commits"],
185 185 }
186 186
187 187 #gather all data by day
188 188 if commits_by_day_aggregate.has_key(k):
189 189 commits_by_day_aggregate[k] += 1
190 190 else:
191 191 commits_by_day_aggregate[k] = 1
192 192
193 193 if cnt >= parse_limit:
194 194 #don't fetch to much data since we can freeze application
195 195 break
196 196 overview_data = []
197 197 for k, v in commits_by_day_aggregate.items():
198 198 overview_data.append([k, v])
199 199 overview_data = sorted(overview_data, key=itemgetter(0))
200 200 if not commits_by_day_author_aggregate:
201 201 commits_by_day_author_aggregate[author_key_cleaner(repo.contact)] = {
202 202 "label":author_key_cleaner(repo.contact),
203 203 "data":[0, 1],
204 204 "schema":["commits"],
205 205 }
206 206
207 207 stats = cur_stats if cur_stats else Statistics()
208 208 stats.commit_activity = json.dumps(commits_by_day_author_aggregate)
209 209 stats.commit_activity_combined = json.dumps(overview_data)
210 210
211 211 log.debug('last revison %s', last_rev)
212 212 leftovers = len(repo.revisions[last_rev:])
213 213 log.debug('revisions to parse %s', leftovers)
214 214
215 215 if last_rev == 0 or leftovers < parse_limit:
216 216 stats.languages = json.dumps(__get_codes_stats(repo_name))
217 217
218 218 stats.repository = dbrepo
219 219 stats.stat_on_revision = last_cs.revision
220 220
221 221 try:
222 222 sa.add(stats)
223 223 sa.commit()
224 224 except:
225 225 log.error(traceback.format_exc())
226 226 sa.rollback()
227 227 return False
228 228 if len(repo.revisions) > 1:
229 229 run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
230 230
231 231 return True
232 232
233 233 @task
234 234 def reset_user_password(user_email):
235 235 log = reset_user_password.get_logger()
236 236 from rhodecode.lib import auth
237 237 from rhodecode.model.db import User
238 238
239 239 try:
240 240 try:
241 241 sa = get_session()
242 242 user = sa.query(User).filter(User.email == user_email).scalar()
243 243 new_passwd = auth.PasswordGenerator().gen_password(8,
244 244 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
245 245 if user:
246 246 user.password = auth.get_crypt_password(new_passwd)
247 247 sa.add(user)
248 248 sa.commit()
249 249 log.info('change password for %s', user_email)
250 250 if new_passwd is None:
251 251 raise Exception('unable to generate new password')
252 252
253 253 except:
254 254 log.error(traceback.format_exc())
255 255 sa.rollback()
256 256
257 257 run_task(send_email, user_email,
258 258 "Your new rhodecode password",
259 259 'Your new rhodecode password:%s' % (new_passwd))
260 260 log.info('send new password mail to %s', user_email)
261 261
262 262
263 263 except:
264 264 log.error('Failed to update user password')
265 265 log.error(traceback.format_exc())
266 266 return True
267 267
268 268 @task
269 269 def send_email(recipients, subject, body):
270 270 log = send_email.get_logger()
271 271 email_config = dict(config.items('DEFAULT'))
272 272 mail_from = email_config.get('app_email_from')
273 273 user = email_config.get('smtp_username')
274 274 passwd = email_config.get('smtp_password')
275 275 mail_server = email_config.get('smtp_server')
276 276 mail_port = email_config.get('smtp_port')
277 277 tls = email_config.get('smtp_use_tls')
278 278 ssl = False
279 279
280 280 try:
281 281 m = SmtpMailer(mail_from, user, passwd, mail_server,
282 282 mail_port, ssl, tls)
283 283 m.send(recipients, subject, body)
284 284 except:
285 285 log.error('Mail sending failed')
286 286 log.error(traceback.format_exc())
287 287 return False
288 288 return True
289 289
290 290 @task
291 291 def create_repo_fork(form_data, cur_user):
292 292 import os
293 293 from rhodecode.model.repo import RepoModel
294 294
295 295 repo_model = RepoModel(get_session())
296 296 repo_model.create(form_data, cur_user, just_db=True, fork=True)
297 297
298 298 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
299 299 repo_path = os.path.join(repos_path, form_data['repo_name'])
300 300 repo_fork_path = os.path.join(repos_path, form_data['fork_name'])
301 301
302 302 MercurialRepository(str(repo_fork_path), True, clone_url=str(repo_path))
303 303
304 304
305 305 def __get_codes_stats(repo_name):
306 306 LANGUAGES_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx',
307 307 'aspx', 'asx', 'axd', 'c', 'cfg', 'cfm', 'cpp', 'cs', 'diff', 'do', 'el',
308 308 'erl', 'h', 'java', 'js', 'jsp', 'jspx', 'lisp', 'lua', 'm', 'mako', 'ml',
309 309 'pas', 'patch', 'php', 'php3', 'php4', 'phtml', 'pm', 'py', 'rb', 'rst',
310 310 's', 'sh', 'tpl', 'txt', 'vim', 'wss', 'xhtml', 'xml', 'xsl', 'xslt', 'yaws']
311 311
312 312
313 313 repos_path = get_hg_ui_settings()['paths_root_path']
314 314 p = os.path.join(repos_path, repo_name)
315 repo = get_repo(get_scm(p)[0], p)
316
315 repo = get_repo(p)
317 316 tip = repo.get_changeset()
318
319 317 code_stats = {}
320 318
321 319 def aggregate(cs):
322 320 for f in cs[2]:
323 321 k = f.mimetype
324 322 if f.extension in LANGUAGES_EXTENSIONS:
325 323 if code_stats.has_key(k):
326 324 code_stats[k] += 1
327 325 else:
328 326 code_stats[k] = 1
329 327
330 328 map(aggregate, tip.walk('/'))
331 329
332 330 return code_stats or {}
333 331
334 332
335 333
336 334
@@ -1,383 +1,397 b''
1 1 """Helper functions
2 2
3 3 Consists of functions to typically be used within templates, but also
4 4 available to Controllers. This module is available to both as 'h'.
5 5 """
6 6 from pygments.formatters import HtmlFormatter
7 7 from pygments import highlight as code_highlight
8 8 from pylons import url, app_globals as g
9 9 from pylons.i18n.translation import _, ungettext
10 10 from vcs.utils.annotate import annotate_highlight
11 11 from webhelpers.html import literal, HTML, escape
12 12 from webhelpers.html.tools import *
13 13 from webhelpers.html.builder import make_tag
14 14 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
15 15 end_form, file, form, hidden, image, javascript_link, link_to, link_to_if, \
16 16 link_to_unless, ol, required_legend, select, stylesheet_link, submit, text, \
17 17 password, textarea, title, ul, xml_declaration, radio
18 18 from webhelpers.html.tools import auto_link, button_to, highlight, js_obfuscate, \
19 19 mail_to, strip_links, strip_tags, tag_re
20 20 from webhelpers.number import format_byte_size, format_bit_size
21 21 from webhelpers.pylonslib import Flash as _Flash
22 22 from webhelpers.pylonslib.secure_form import secure_form
23 23 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
24 24 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
25 25 replace_whitespace, urlify, truncate, wrap_paragraphs
26 from webhelpers.date import time_ago_in_words
26 27
27 28 #Custom helpers here :)
28 29 class _Link(object):
29 30 '''
30 31 Make a url based on label and url with help of url_for
31 32 :param label:name of link if not defined url is used
32 33 :param url: the url for link
33 34 '''
34 35
35 36 def __call__(self, label='', *url_, **urlargs):
36 37 if label is None or '':
37 38 label = url
38 39 link_fn = link_to(label, url(*url_, **urlargs))
39 40 return link_fn
40 41
41 42 link = _Link()
42 43
43 44 class _GetError(object):
44 45
45 46 def __call__(self, field_name, form_errors):
46 47 tmpl = """<span class="error_msg">%s</span>"""
47 48 if form_errors and form_errors.has_key(field_name):
48 49 return literal(tmpl % form_errors.get(field_name))
49 50
50 51 get_error = _GetError()
51 52
52 53 def recursive_replace(str, replace=' '):
53 54 """
54 55 Recursive replace of given sign to just one instance
55 56 :param str: given string
56 57 :param replace:char to find and replace multiple instances
57 58
58 59 Examples::
59 60 >>> recursive_replace("Mighty---Mighty-Bo--sstones",'-')
60 61 'Mighty-Mighty-Bo-sstones'
61 62 """
62 63
63 64 if str.find(replace * 2) == -1:
64 65 return str
65 66 else:
66 67 str = str.replace(replace * 2, replace)
67 68 return recursive_replace(str, replace)
68 69
69 70 class _ToolTip(object):
70 71
71 72 def __call__(self, tooltip_title, trim_at=50):
72 73 """
73 74 Special function just to wrap our text into nice formatted autowrapped
74 75 text
75 76 :param tooltip_title:
76 77 """
77 78
78 79 return wrap_paragraphs(escape(tooltip_title), trim_at)\
79 80 .replace('\n', '<br/>')
80 81
81 82 def activate(self):
82 83 """
83 84 Adds tooltip mechanism to the given Html all tooltips have to have
84 85 set class tooltip and set attribute tooltip_title.
85 86 Then a tooltip will be generated based on that
86 87 All with yui js tooltip
87 88 """
88 89
89 90 js = '''
90 91 YAHOO.util.Event.onDOMReady(function(){
91 92 function toolTipsId(){
92 93 var ids = [];
93 94 var tts = YAHOO.util.Dom.getElementsByClassName('tooltip');
94 95
95 96 for (var i = 0; i < tts.length; i++) {
96 97 //if element doesn not have and id autgenerate one for tooltip
97 98
98 99 if (!tts[i].id){
99 100 tts[i].id='tt'+i*100;
100 101 }
101 102 ids.push(tts[i].id);
102 103 }
103 104 return ids
104 105 };
105 106 var myToolTips = new YAHOO.widget.Tooltip("tooltip", {
106 107 context: toolTipsId(),
107 108 monitorresize:false,
108 109 xyoffset :[0,0],
109 110 autodismissdelay:300000,
110 111 hidedelay:5,
111 112 showdelay:20,
112 113 });
113 114
114 115 //Mouse Over event disabled for new repositories since they dont
115 116 //have last commit message
116 117 myToolTips.contextMouseOverEvent.subscribe(
117 118 function(type, args) {
118 119 var context = args[0];
119 120 var txt = context.getAttribute('tooltip_title');
120 121 if(txt){
121 122 return true;
122 123 }
123 124 else{
124 125 return false;
125 126 }
126 127 });
127 128
128 129
129 130 // Set the text for the tooltip just before we display it. Lazy method
130 131 myToolTips.contextTriggerEvent.subscribe(
131 132 function(type, args) {
132 133
133 134
134 135 var context = args[0];
135 136
136 137 var txt = context.getAttribute('tooltip_title');
137 138 this.cfg.setProperty("text", txt);
138 139
139 140
140 141 // positioning of tooltip
141 142 var tt_w = this.element.clientWidth;
142 143 var tt_h = this.element.clientHeight;
143 144
144 145 var context_w = context.offsetWidth;
145 146 var context_h = context.offsetHeight;
146 147
147 148 var pos_x = YAHOO.util.Dom.getX(context);
148 149 var pos_y = YAHOO.util.Dom.getY(context);
149 150
150 151 var display_strategy = 'top';
151 152 var xy_pos = [0,0];
152 153 switch (display_strategy){
153 154
154 155 case 'top':
155 156 var cur_x = (pos_x+context_w/2)-(tt_w/2);
156 157 var cur_y = pos_y-tt_h-4;
157 158 xy_pos = [cur_x,cur_y];
158 159 break;
159 160 case 'bottom':
160 161 var cur_x = (pos_x+context_w/2)-(tt_w/2);
161 162 var cur_y = pos_y+context_h+4;
162 163 xy_pos = [cur_x,cur_y];
163 164 break;
164 165 case 'left':
165 166 var cur_x = (pos_x-tt_w-4);
166 167 var cur_y = pos_y-((tt_h/2)-context_h/2);
167 168 xy_pos = [cur_x,cur_y];
168 169 break;
169 170 case 'right':
170 171 var cur_x = (pos_x+context_w+4);
171 172 var cur_y = pos_y-((tt_h/2)-context_h/2);
172 173 xy_pos = [cur_x,cur_y];
173 174 break;
174 175 default:
175 176 var cur_x = (pos_x+context_w/2)-(tt_w/2);
176 177 var cur_y = pos_y-tt_h-4;
177 178 xy_pos = [cur_x,cur_y];
178 179 break;
179 180
180 181 }
181 182
182 183 this.cfg.setProperty("xy",xy_pos);
183 184
184 185 });
185 186
186 187 //Mouse out
187 188 myToolTips.contextMouseOutEvent.subscribe(
188 189 function(type, args) {
189 190 var context = args[0];
190 191
191 192 });
192 193 });
193 194 '''
194 195 return literal(js)
195 196
196 197 tooltip = _ToolTip()
197 198
198 199 class _FilesBreadCrumbs(object):
199 200
200 201 def __call__(self, repo_name, rev, paths):
201 202 url_l = [link_to(repo_name, url('files_home',
202 203 repo_name=repo_name,
203 204 revision=rev, f_path=''))]
204 205 paths_l = paths.split('/')
205 206
206 207 for cnt, p in enumerate(paths_l, 1):
207 208 if p != '':
208 209 url_l.append(link_to(p, url('files_home',
209 210 repo_name=repo_name,
210 211 revision=rev,
211 212 f_path='/'.join(paths_l[:cnt]))))
212 213
213 214 return literal('/'.join(url_l))
214 215
215 216 files_breadcrumbs = _FilesBreadCrumbs()
216 217 class CodeHtmlFormatter(HtmlFormatter):
217 218
218 219 def wrap(self, source, outfile):
219 220 return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
220 221
221 222 def _wrap_code(self, source):
222 223 for cnt, it in enumerate(source, 1):
223 224 i, t = it
224 225 t = '<div id="#S-%s">%s</div>' % (cnt, t)
225 226 yield i, t
226 227 def pygmentize(filenode, **kwargs):
227 228 """
228 229 pygmentize function using pygments
229 230 :param filenode:
230 231 """
231 232 return literal(code_highlight(filenode.content,
232 233 filenode.lexer, CodeHtmlFormatter(**kwargs)))
233 234
234 235 def pygmentize_annotation(filenode, **kwargs):
235 236 """
236 237 pygmentize function for annotation
237 238 :param filenode:
238 239 """
239 240
240 241 color_dict = {}
241 242 def gen_color():
242 243 """generator for getting 10k of evenly distibuted colors using hsv color
243 244 and golden ratio.
244 245 """
245 246 import colorsys
246 247 n = 10000
247 248 golden_ratio = 0.618033988749895
248 249 h = 0.22717784590367374
249 250 #generate 10k nice web friendly colors in the same order
250 251 for c in xrange(n):
251 252 h += golden_ratio
252 253 h %= 1
253 254 HSV_tuple = [h, 0.95, 0.95]
254 255 RGB_tuple = colorsys.hsv_to_rgb(*HSV_tuple)
255 256 yield map(lambda x:str(int(x * 256)), RGB_tuple)
256 257
257 258 cgenerator = gen_color()
258 259
259 260 def get_color_string(cs):
260 261 if color_dict.has_key(cs):
261 262 col = color_dict[cs]
262 263 else:
263 264 col = color_dict[cs] = cgenerator.next()
264 265 return "color: rgb(%s)! important;" % (', '.join(col))
265 266
266 267 def url_func(changeset):
267 268 tooltip_html = "<div style='font-size:0.8em'><b>Author:</b>" + \
268 269 " %s<br/><b>Date:</b> %s</b><br/><b>Message:</b> %s<br/></div>"
269 270
270 271 tooltip_html = tooltip_html % (changeset.author,
271 272 changeset.date,
272 273 tooltip(changeset.message))
273 274 lnk_format = 'r%-5s:%s' % (changeset.revision,
274 275 changeset.short_id)
275 276 uri = link_to(
276 277 lnk_format,
277 278 url('changeset_home', repo_name=changeset.repository.name,
278 279 revision=changeset.short_id),
279 280 style=get_color_string(changeset.short_id),
280 281 class_='tooltip',
281 282 tooltip_title=tooltip_html
282 283 )
283 284
284 285 uri += '\n'
285 286 return uri
286 287 return literal(annotate_highlight(filenode, url_func, **kwargs))
287 288
288 289 def repo_name_slug(value):
289 290 """Return slug of name of repository
290 291 This function is called on each creation/modification
291 292 of repository to prevent bad names in repo
292 293 """
293 294 slug = remove_formatting(value)
294 295 slug = strip_tags(slug)
295 296
296 297 for c in """=[]\;'"<>,/~!@#$%^&*()+{}|: """:
297 298 slug = slug.replace(c, '-')
298 299 slug = recursive_replace(slug, '-')
299 300 slug = collapse(slug, '-')
300 301 return slug
301 302
302 303 def get_changeset_safe(repo, rev):
303 304 from vcs.backends.base import BaseRepository
304 305 from vcs.exceptions import RepositoryError
305 306 if not isinstance(repo, BaseRepository):
306 307 raise Exception('You must pass an Repository '
307 308 'object as first argument got %s', type(repo))
308 309
309 310 try:
310 311 cs = repo.get_changeset(rev)
311 312 except RepositoryError:
312 313 from rhodecode.lib.utils import EmptyChangeset
313 314 cs = EmptyChangeset()
314 315 return cs
315 316
316 317
317 318 flash = _Flash()
318 319
319 320
320 #===============================================================================
321 #==============================================================================
321 322 # MERCURIAL FILTERS available via h.
322 #===============================================================================
323 #==============================================================================
323 324 from mercurial import util
324 from mercurial.templatefilters import age as _age, person as _person
325 from mercurial.templatefilters import person as _person
326
327
328
329 def _age(curdate):
330 """turns a datetime into an age string."""
325 331
326 age = lambda x:x
332 from datetime import timedelta, datetime
333 agescales = [("year", 3600 * 24 * 365),
334 ("month", 3600 * 24 * 30),
335 #("week", 3600 * 24 * 7),
336 ("day", 3600 * 24),
337 ("hour", 3600),
338 ("minute", 60),
339 ("second", 1)]
340
341 age = datetime.now() - curdate
342 age_seconds = (age.days * agescales[2][1]) + age.seconds
343
344 pos = 1
345 for scale in agescales:
346 if scale[1] <= age_seconds:
347 return time_ago_in_words(curdate, agescales[pos][0])
348 pos += 1
349
350 age = lambda x:_age(x)
327 351 capitalize = lambda x: x.capitalize()
328 date = lambda x: util.datestr(x)
329 352 email = util.email
330 353 email_or_none = lambda x: util.email(x) if util.email(x) != x else None
331 354 person = lambda x: _person(x)
332 hgdate = lambda x: "%d %d" % x
333 isodate = lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2')
334 isodatesec = lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2')
335 localdate = lambda x: (x[0], util.makedate()[1])
336 rfc822date = lambda x: x#util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2")
337 rfc822date_notz = lambda x: x#util.datestr(x, "%a, %d %b %Y %H:%M:%S")
338 rfc3339date = lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2")
339 time_ago = lambda x: util.datestr(_age(x), "%a, %d %b %Y %H:%M:%S %1%2")
340 355
341
342 #===============================================================================
356 #==============================================================================
343 357 # PERMS
344 #===============================================================================
358 #==============================================================================
345 359 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
346 360 HasRepoPermissionAny, HasRepoPermissionAll
347 361
348 #===============================================================================
362 #==============================================================================
349 363 # GRAVATAR URL
350 #===============================================================================
364 #==============================================================================
351 365 import hashlib
352 366 import urllib
353 367 from pylons import request
354 368
355 369 def gravatar_url(email_address, size=30):
356 370 ssl_enabled = 'https' == request.environ.get('HTTP_X_URL_SCHEME')
357 371 default = 'identicon'
358 372 baseurl_nossl = "http://www.gravatar.com/avatar/"
359 373 baseurl_ssl = "https://secure.gravatar.com/avatar/"
360 374 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
361 375
362 376
363 377 # construct the url
364 378 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
365 379 gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
366 380
367 381 return gravatar_url
368 382
369 383 def safe_unicode(str):
370 384 """safe unicode function. In case of UnicodeDecode error we try to return
371 385 unicode with errors replace, if this failes we return unicode with
372 386 string_escape decoding """
373 387
374 388 try:
375 389 u_str = unicode(str)
376 390 except UnicodeDecodeError:
377 391 try:
378 392 u_str = unicode(str, 'utf-8', 'replace')
379 393 except UnicodeDecodeError:
380 394 #incase we have a decode error just represent as byte string
381 395 u_str = unicode(str(str).encode('string_escape'))
382 396
383 397 return u_str
@@ -1,204 +1,204 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # middleware to handle git api calls
4 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; version 2
9 9 # of the License or (at your opinion) any later version of the license.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 19 # MA 02110-1301, USA.
20 """
21 Created on 2010-04-28
22
23 @author: marcink
24 SimpleGit middleware for handling git protocol request (push/clone etc.)
25 It's implemented with basic auth function
26 """
27
20 28 from dulwich import server as dulserver
21 29
22 30 class SimpleGitUploadPackHandler(dulserver.UploadPackHandler):
23 31
24 32 def handle(self):
25 33 write = lambda x: self.proto.write_sideband(1, x)
26 34
27 35 graph_walker = dulserver.ProtocolGraphWalker(self, self.repo.object_store,
28 36 self.repo.get_peeled)
29 37 objects_iter = self.repo.fetch_objects(
30 38 graph_walker.determine_wants, graph_walker, self.progress,
31 39 get_tagged=self.get_tagged)
32 40
33 41 # Do they want any objects?
34 42 if len(objects_iter) == 0:
35 43 return
36 44
37 45 self.progress("counting objects: %d, done.\n" % len(objects_iter))
38 46 dulserver.write_pack_data(dulserver.ProtocolFile(None, write), objects_iter,
39 47 len(objects_iter))
40 48 messages = []
41 49 messages.append('thank you for using rhodecode')
42 50
43 51 for msg in messages:
44 52 self.progress(msg + "\n")
45 53 # we are done
46 54 self.proto.write("0000")
47 55
48 56 dulserver.DEFAULT_HANDLERS = {
49 57 'git-upload-pack': SimpleGitUploadPackHandler,
50 58 'git-receive-pack': dulserver.ReceivePackHandler,
51 59 }
52 60
53 61 from dulwich.repo import Repo
54 62 from dulwich.web import HTTPGitApplication
55 63 from paste.auth.basic import AuthBasicAuthenticator
56 64 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
57 from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware, \
58 get_user_cached
65 from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware
59 66 from rhodecode.lib.utils import action_logger, is_git, invalidate_cache, \
60 67 check_repo_fast
68 from rhodecode.model.user import UserModel
61 69 from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
62 70 import logging
63 71 import os
64 72 import traceback
65 """
66 Created on 2010-04-28
67
68 @author: marcink
69 SimpleGit middleware for handling git protocol request (push/clone etc.)
70 It's implemented with basic auth function
71 """
72
73 73
74 74
75 75 log = logging.getLogger(__name__)
76 76
77 77 class SimpleGit(object):
78 78
79 79 def __init__(self, application, config):
80 80 self.application = application
81 81 self.config = config
82 82 #authenticate this git request using
83 83 self.authenticate = AuthBasicAuthenticator('', authfunc)
84 84
85 85 def __call__(self, environ, start_response):
86 86 if not is_git(environ):
87 87 return self.application(environ, start_response)
88 88
89 89 #===================================================================
90 90 # AUTHENTICATE THIS GIT REQUEST
91 91 #===================================================================
92 92 username = REMOTE_USER(environ)
93 93 if not username:
94 94 self.authenticate.realm = self.config['rhodecode_realm']
95 95 result = self.authenticate(environ)
96 96 if isinstance(result, str):
97 97 AUTH_TYPE.update(environ, 'basic')
98 98 REMOTE_USER.update(environ, result)
99 99 else:
100 100 return result.wsgi_application(environ, start_response)
101 101
102 102 try:
103 103 self.repo_name = environ['PATH_INFO'].split('/')[1]
104 104 if self.repo_name.endswith('/'):
105 105 self.repo_name = self.repo_name.rstrip('/')
106 106 except:
107 107 log.error(traceback.format_exc())
108 108 return HTTPInternalServerError()(environ, start_response)
109 109
110 110 #===================================================================
111 111 # CHECK PERMISSIONS FOR THIS REQUEST
112 112 #===================================================================
113 113 action = self.__get_action(environ)
114 114 if action:
115 115 username = self.__get_environ_user(environ)
116 116 try:
117 117 user = self.__get_user(username)
118 118 except:
119 119 log.error(traceback.format_exc())
120 120 return HTTPInternalServerError()(environ, start_response)
121 121
122 122 #check permissions for this repository
123 123 if action == 'push':
124 124 if not HasPermissionAnyMiddleware('repository.write',
125 125 'repository.admin')\
126 126 (user, self.repo_name):
127 127 return HTTPForbidden()(environ, start_response)
128 128
129 129 else:
130 130 #any other action need at least read permission
131 131 if not HasPermissionAnyMiddleware('repository.read',
132 132 'repository.write',
133 133 'repository.admin')\
134 134 (user, self.repo_name):
135 135 return HTTPForbidden()(environ, start_response)
136 136
137 137 #log action
138 138 if action in ('push', 'pull', 'clone'):
139 139 proxy_key = 'HTTP_X_REAL_IP'
140 140 def_key = 'REMOTE_ADDR'
141 141 ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
142 142 self.__log_user_action(user, action, self.repo_name, ipaddr)
143 143
144 144 #===================================================================
145 145 # GIT REQUEST HANDLING
146 146 #===================================================================
147 147 self.basepath = self.config['base_path']
148 148 self.repo_path = os.path.join(self.basepath, self.repo_name)
149 149 #quick check if that dir exists...
150 150 if check_repo_fast(self.repo_name, self.basepath):
151 151 return HTTPNotFound()(environ, start_response)
152 152 try:
153 153 app = self.__make_app()
154 154 except Exception:
155 155 log.error(traceback.format_exc())
156 156 return HTTPInternalServerError()(environ, start_response)
157 157
158 158 #invalidate cache on push
159 159 if action == 'push':
160 160 self.__invalidate_cache(self.repo_name)
161 161 messages = []
162 162 messages.append('thank you for using rhodecode')
163 163 return app(environ, start_response)
164 164 else:
165 165 return app(environ, start_response)
166 166
167 167
168 168 def __make_app(self):
169 169 backend = dulserver.DictBackend({'/' + self.repo_name: Repo(self.repo_path)})
170 170 gitserve = HTTPGitApplication(backend)
171 171
172 172 return gitserve
173 173
174 174 def __get_environ_user(self, environ):
175 175 return environ.get('REMOTE_USER')
176 176
177 177 def __get_user(self, username):
178 return get_user_cached(username)
178 return UserModel().get_by_username(username, cache=True)
179 179
180 180 def __get_action(self, environ):
181 181 """
182 182 Maps git request commands into a pull or push command.
183 183 :param environ:
184 184 """
185 185 service = environ['QUERY_STRING'].split('=')
186 186 if len(service) > 1:
187 187 service_cmd = service[1]
188 188 mapping = {'git-receive-pack': 'push',
189 189 'git-upload-pack': 'pull',
190 190 }
191 191
192 192 return mapping.get(service_cmd, service_cmd if service_cmd else 'other')
193 193 else:
194 194 return 'other'
195 195
196 196 def __log_user_action(self, user, action, repo, ipaddr):
197 197 action_logger(user, action, repo, ipaddr)
198 198
199 199 def __invalidate_cache(self, repo_name):
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 203 invalidate_cache('cached_repo_list')
204 204 invalidate_cache('full_changelog', repo_name)
@@ -1,2312 +1,2312 b''
1 1 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td {
2 2 border:0;
3 3 outline:0;
4 4 font-size:100%;
5 5 vertical-align:baseline;
6 6 background:transparent;
7 7 margin:0;
8 8 padding:0;
9 9 }
10 10
11 11 body {
12 12 line-height:1;
13 13 height:100%;
14 14 background:url("../images/background.png") repeat scroll 0 0 #B0B0B0;
15 15 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
16 16 font-size:12px;
17 17 color:#000;
18 18 margin:0;
19 19 padding:0;
20 20 }
21 21
22 22 ol,ul {
23 23 list-style:none;
24 24 }
25 25
26 26 blockquote,q {
27 27 quotes:none;
28 28 }
29 29
30 30 blockquote:before,blockquote:after,q:before,q:after {
31 31 content:none;
32 32 }
33 33
34 34 :focus {
35 35 outline:0;
36 36 }
37 37
38 38 del {
39 39 text-decoration:line-through;
40 40 }
41 41
42 42 table {
43 43 border-collapse:collapse;
44 44 border-spacing:0;
45 45 }
46 46
47 47 html {
48 48 height:100%;
49 49 }
50 50
51 51 a {
52 52 color:#003367;
53 53 text-decoration:none;
54 54 cursor:pointer;
55 55 font-weight:700;
56 56 }
57 57
58 58 a:hover {
59 59 color:#316293;
60 60 text-decoration:underline;
61 61 }
62 62
63 63 h1,h2,h3,h4,h5,h6 {
64 64 color:#292929;
65 65 font-weight:700;
66 66 }
67 67
68 68 h1 {
69 69 font-size:22px;
70 70 }
71 71
72 72 h2 {
73 73 font-size:20px;
74 74 }
75 75
76 76 h3 {
77 77 font-size:18px;
78 78 }
79 79
80 80 h4 {
81 81 font-size:16px;
82 82 }
83 83
84 84 h5 {
85 85 font-size:14px;
86 86 }
87 87
88 88 h6 {
89 89 font-size:11px;
90 90 }
91 91
92 92 ul.circle {
93 93 list-style-type:circle;
94 94 }
95 95
96 96 ul.disc {
97 97 list-style-type:disc;
98 98 }
99 99
100 100 ul.square {
101 101 list-style-type:square;
102 102 }
103 103
104 104 ol.lower-roman {
105 105 list-style-type:lower-roman;
106 106 }
107 107
108 108 ol.upper-roman {
109 109 list-style-type:upper-roman;
110 110 }
111 111
112 112 ol.lower-alpha {
113 113 list-style-type:lower-alpha;
114 114 }
115 115
116 116 ol.upper-alpha {
117 117 list-style-type:upper-alpha;
118 118 }
119 119
120 120 ol.decimal {
121 121 list-style-type:decimal;
122 122 }
123 123
124 124 div.color {
125 125 clear:both;
126 126 overflow:hidden;
127 127 position:absolute;
128 128 background:#FFF;
129 129 margin:7px 0 0 60px;
130 130 padding:1px 1px 1px 0;
131 131 }
132 132
133 133 div.color a {
134 134 width:15px;
135 135 height:15px;
136 136 display:block;
137 137 float:left;
138 138 margin:0 0 0 1px;
139 139 padding:0;
140 140 }
141 141
142 142 div.options {
143 143 clear:both;
144 144 overflow:hidden;
145 145 position:absolute;
146 146 background:#FFF;
147 147 margin:7px 0 0 162px;
148 148 padding:0;
149 149 }
150 150
151 151 div.options a {
152 152 height:1%;
153 153 display:block;
154 154 text-decoration:none;
155 155 margin:0;
156 156 padding:3px 8px;
157 157 }
158 158
159 159 .top-left-rounded-corner {
160 160 -webkit-border-top-left-radius: 8px;
161 161 -khtml-border-radius-topleft: 8px;
162 162 -moz-border-radius-topleft: 8px;
163 163 border-top-left-radius: 8px;
164 164 }
165 165
166 166 .top-right-rounded-corner {
167 167 -webkit-border-top-right-radius: 8px;
168 168 -khtml-border-radius-topright: 8px;
169 169 -moz-border-radius-topright: 8px;
170 170 border-top-right-radius: 8px;
171 171 }
172 172
173 173 .bottom-left-rounded-corner {
174 174 -webkit-border-bottom-left-radius: 8px;
175 175 -khtml-border-radius-bottomleft: 8px;
176 176 -moz-border-radius-bottomleft: 8px;
177 177 border-bottom-left-radius: 8px;
178 178 }
179 179
180 180 .bottom-right-rounded-corner {
181 181 -webkit-border-bottom-right-radius: 8px;
182 182 -khtml-border-radius-bottomright: 8px;
183 183 -moz-border-radius-bottomright: 8px;
184 184 border-bottom-right-radius: 8px;
185 185 }
186 186
187 187
188 188 #header {
189 189 margin:0;
190 190 padding:0 30px;
191 191 }
192 192
193 193 #header ul#logged-user li {
194 194 list-style:none;
195 195 float:left;
196 196 border-left:1px solid #bbb;
197 197 border-right:1px solid #a5a5a5;
198 198 margin:-2px 0 0;
199 199 padding:10px 12px;
200 200 }
201 201
202 202 #header ul#logged-user li.first {
203 203 border-left:none;
204 204 margin:-6px;
205 205 }
206 206
207 207 #header ul#logged-user li.first div.account {
208 208 padding-top:4px;
209 209 float:left;
210 210 }
211 211
212 212 #header ul#logged-user li.last {
213 213 border-right:none;
214 214 }
215 215
216 216 #header ul#logged-user li a {
217 217 color:#4e4e4e;
218 218 font-weight:700;
219 219 text-decoration:none;
220 220 }
221 221
222 222 #header ul#logged-user li a:hover {
223 223 color:#376ea6;
224 224 text-decoration:underline;
225 225 }
226 226
227 227 #header ul#logged-user li.highlight a {
228 228 color:#fff;
229 229 }
230 230
231 231 #header ul#logged-user li.highlight a:hover {
232 232 color:#376ea6;
233 233 }
234 234
235 235 #header #header-inner {
236 236 height:40px;
237 237 clear:both;
238 238 position:relative;
239 239 background:#003367 url("../images/header_inner.png") repeat-x;
240 240 border-bottom:2px solid #fff;
241 241 margin:0;
242 242 padding:0;
243 243 }
244 244
245 245 #header #header-inner #home a {
246 246 height:40px;
247 247 width:46px;
248 248 display:block;
249 249 background:url("../images/button_home.png");
250 250 background-position:0 0;
251 251 margin:0;
252 252 padding:0;
253 253 }
254 254
255 255 #header #header-inner #home a:hover {
256 256 background-position:0 -40px;
257 257 }
258 258
259 259 #header #header-inner #logo h1 {
260 260 color:#FFF;
261 261 font-size:14px;
262 262 text-transform:uppercase;
263 263 margin:13px 0 0 13px;
264 264 padding:0;
265 265 }
266 266
267 267 #header #header-inner #logo a {
268 268 color:#fff;
269 269 text-decoration:none;
270 270 }
271 271
272 272 #header #header-inner #logo a:hover {
273 273 color:#dabf29;
274 274 }
275 275
276 276 #header #header-inner #quick,#header #header-inner #quick ul {
277 277 position:relative;
278 278 float:right;
279 279 list-style-type:none;
280 280 list-style-position:outside;
281 281 margin:10px 5px 0 0;
282 282 padding:0;
283 283 }
284 284
285 285 #header #header-inner #quick li {
286 286 position:relative;
287 287 float:left;
288 288 margin:0 5px 0 0;
289 289 padding:0;
290 290 }
291 291
292 292 #header #header-inner #quick li a {
293 293 top:0;
294 294 left:0;
295 295 height:1%;
296 296 display:block;
297 297 clear:both;
298 298 overflow:hidden;
299 299 color:#FFF;
300 300 font-weight:700;
301 301 text-decoration:none;
302 302 background:#369 url("../../images/quick_l.png") no-repeat top left;
303 303 padding:0;
304 304 }
305 305
306 306 #header #header-inner #quick li span {
307 307 top:0;
308 308 right:0;
309 309 height:1%;
310 310 display:block;
311 311 float:left;
312 312 background:url("../../images/quick_r.png") no-repeat top right;
313 313 border-left:1px solid #3f6f9f;
314 314 margin:0;
315 315 padding:10px 12px 8px 10px;
316 316 }
317 317
318 318 #header #header-inner #quick li span.normal {
319 319 border:none;
320 320 padding:10px 12px 8px;
321 321 }
322 322
323 323 #header #header-inner #quick li span.icon {
324 324 top:0;
325 325 left:0;
326 326 border-left:none;
327 327 background:url("../../images/quick_l.png") no-repeat top left;
328 328 border-right:1px solid #2e5c89;
329 329 padding:8px 8px 4px;
330 330 }
331 331
332 332 #header #header-inner #quick li a:hover {
333 333 background:#4e4e4e url("../../images/quick_l_selected.png") no-repeat top left;
334 334 }
335 335
336 336 #header #header-inner #quick li a:hover span {
337 337 border-left:1px solid #545454;
338 338 background:url("../../images/quick_r_selected.png") no-repeat top right;
339 339 }
340 340
341 341 #header #header-inner #quick li a:hover span.icon {
342 342 border-left:none;
343 343 border-right:1px solid #464646;
344 344 background:url("../../images/quick_l_selected.png") no-repeat top left;
345 345 }
346 346
347 347 #header #header-inner #quick ul {
348 348 top:29px;
349 349 right:0;
350 350 min-width:200px;
351 351 display:none;
352 352 position:absolute;
353 353 background:#FFF;
354 354 border:1px solid #666;
355 355 border-top:1px solid #003367;
356 356 z-index:100;
357 357 margin:0;
358 358 padding:0;
359 359 }
360 360
361 361 #header #header-inner #quick ul.repo_switcher {
362 362 max-height:275px;
363 363 overflow-x:hidden;
364 364 overflow-y:auto;
365 365 }
366 366
367 367 #header #header-inner #quick li ul li {
368 368 border-bottom:1px solid #ddd;
369 369 }
370 370
371 371 #header #header-inner #quick li ul li a {
372 372 width:182px;
373 373 height:auto;
374 374 display:block;
375 375 float:left;
376 376 background:#FFF;
377 377 color:#003367;
378 378 font-weight:400;
379 379 margin:0;
380 380 padding:7px 9px;
381 381 }
382 382
383 383 #header #header-inner #quick li ul li a:hover {
384 384 color:#000;
385 385 background:#FFF;
386 386 }
387 387
388 388 #header #header-inner #quick ul ul {
389 389 top:auto;
390 390 }
391 391
392 392 #header #header-inner #quick li ul ul {
393 393 right:200px;
394 394 max-height:275px;
395 395 overflow:auto;
396 396 overflow-x:hidden;
397 397 white-space:nowrap;
398 398 }
399 399
400 400 #header #header-inner #quick li ul li a.journal,#header #header-inner #quick li ul li a.journal:hover {
401 401 background:url("../images/icons/book.png") no-repeat scroll 4px 9px #FFF;
402 402 width:167px;
403 403 margin:0;
404 404 padding:12px 9px 7px 24px;
405 405 }
406 406
407 407 #header #header-inner #quick li ul li a.private_repo,#header #header-inner #quick li ul li a.private_repo:hover {
408 408 background:url("../images/icons/lock.png") no-repeat scroll 4px 9px #FFF;
409 409 min-width:167px;
410 410 margin:0;
411 411 padding:12px 9px 7px 24px;
412 412 }
413 413
414 414 #header #header-inner #quick li ul li a.public_repo,#header #header-inner #quick li ul li a.public_repo:hover {
415 415 background:url("../images/icons/lock_open.png") no-repeat scroll 4px 9px #FFF;
416 416 min-width:167px;
417 417 margin:0;
418 418 padding:12px 9px 7px 24px;
419 419 }
420 420
421 421 #header #header-inner #quick li ul li a.repos,#header #header-inner #quick li ul li a.repos:hover {
422 422 background:url("../images/icons/folder_edit.png") no-repeat scroll 4px 9px #FFF;
423 423 width:167px;
424 424 margin:0;
425 425 padding:12px 9px 7px 24px;
426 426 }
427 427
428 428 #header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover {
429 429 background:#FFF url("../images/icons/user_edit.png") no-repeat 4px 9px;
430 430 width:167px;
431 431 margin:0;
432 432 padding:12px 9px 7px 24px;
433 433 }
434 434
435 435 #header #header-inner #quick li ul li a.settings,#header #header-inner #quick li ul li a.settings:hover {
436 436 background:#FFF url("../images/icons/cog.png") no-repeat 4px 9px;
437 437 width:167px;
438 438 margin:0;
439 439 padding:12px 9px 7px 24px;
440 440 }
441 441
442 442 #header #header-inner #quick li ul li a.permissions,#header #header-inner #quick li ul li a.permissions:hover {
443 443 background:#FFF url("../images/icons/key.png") no-repeat 4px 9px;
444 444 width:167px;
445 445 margin:0;
446 446 padding:12px 9px 7px 24px;
447 447 }
448 448
449 449 #header #header-inner #quick li ul li a.fork,#header #header-inner #quick li ul li a.fork:hover {
450 450 background:#FFF url("../images/icons/arrow_divide.png") no-repeat 4px 9px;
451 451 width:167px;
452 452 margin:0;
453 453 padding:12px 9px 7px 24px;
454 454 }
455 455
456 456 #header #header-inner #quick li ul li a.search,#header #header-inner #quick li ul li a.search:hover {
457 457 background:#FFF url("../images/icons/search_16.png") no-repeat 4px 9px;
458 458 width:167px;
459 459 margin:0;
460 460 padding:12px 9px 7px 24px;
461 461 }
462 462
463 463 #header #header-inner #quick li ul li a.delete,#header #header-inner #quick li ul li a.delete:hover {
464 464 background:#FFF url("../images/icons/delete.png") no-repeat 4px 9px;
465 465 width:167px;
466 466 margin:0;
467 467 padding:12px 9px 7px 24px;
468 468 }
469 469
470 470 #header #header-inner #quick li ul li a.branches,#header #header-inner #quick li ul li a.branches:hover {
471 471 background:#FFF url("../images/icons/arrow_branch.png") no-repeat 4px 9px;
472 472 width:167px;
473 473 margin:0;
474 474 padding:12px 9px 7px 24px;
475 475 }
476 476
477 477 #header #header-inner #quick li ul li a.tags,#header #header-inner #quick li ul li a.tags:hover {
478 478 background:#FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
479 479 width:167px;
480 480 margin:0;
481 481 padding:12px 9px 7px 24px;
482 482 }
483 483
484 484 #header #header-inner #quick li ul li a.admin,#header #header-inner #quick li ul li a.admin:hover {
485 485 background:#FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
486 486 width:167px;
487 487 margin:0;
488 488 padding:12px 9px 7px 24px;
489 489 }
490 490
491 491 #content #left {
492 492 left:0;
493 493 width:280px;
494 494 position:absolute;
495 495 }
496 496
497 497 #content #right {
498 498 margin:0 60px 10px 290px;
499 499 }
500 500
501 501 #content div.box {
502 502 clear:both;
503 503 overflow:hidden;
504 504 background:#fff;
505 505 margin:0 0 10px;
506 506 padding:0 0 10px;
507 507 }
508 508
509 509 #content div.box-left {
510 510 width:49%;
511 511 clear:none;
512 512 float:left;
513 513 margin:0 0 10px;
514 514 }
515 515
516 516 #content div.box-right {
517 517 width:49%;
518 518 clear:none;
519 519 float:right;
520 520 margin:0 0 10px;
521 521 }
522 522
523 523 #content div.box div.title {
524 524 clear:both;
525 525 overflow:hidden;
526 526 background:#369 url("../images/header_inner.png") repeat-x;
527 527 margin:0 0 20px;
528 528 padding:0;
529 529 }
530 530
531 531 #content div.box div.title h5 {
532 532 float:left;
533 533 border:none;
534 534 color:#fff;
535 535 text-transform:uppercase;
536 536 margin:0;
537 537 padding:11px 0 11px 10px;
538 538 }
539 539
540 540 #content div.box div.title ul.links li {
541 541 list-style:none;
542 542 float:left;
543 543 margin:0;
544 544 padding:0;
545 545 }
546 546
547 547 #content div.box div.title ul.links li a {
548 548 height:1%;
549 549 display:block;
550 550 float:left;
551 551 border-left:1px solid #316293;
552 552 color:#fff;
553 553 font-size:11px;
554 554 font-weight:700;
555 555 text-decoration:none;
556 556 margin:0;
557 557 padding:13px 16px 12px;
558 558 }
559 559
560 560 #content div.box h1,#content div.box h2,#content div.box h3,#content div.box h4,#content div.box h5,#content div.box h6 {
561 561 clear:both;
562 562 overflow:hidden;
563 563 border-bottom:1px solid #DDD;
564 564 margin:10px 20px;
565 565 padding:0 0 15px;
566 566 }
567 567
568 568 #content div.box p {
569 569 color:#5f5f5f;
570 570 font-size:12px;
571 571 line-height:150%;
572 572 margin:0 24px 10px;
573 573 padding:0;
574 574 }
575 575
576 576 #content div.box blockquote {
577 577 border-left:4px solid #DDD;
578 578 color:#5f5f5f;
579 579 font-size:11px;
580 580 line-height:150%;
581 581 margin:0 34px;
582 582 padding:0 0 0 14px;
583 583 }
584 584
585 585 #content div.box blockquote p {
586 586 margin:10px 0;
587 587 padding:0;
588 588 }
589 589
590 590 #content div.box dl {
591 591 margin:10px 24px;
592 592 }
593 593
594 594 #content div.box dt {
595 595 font-size:12px;
596 596 margin:0;
597 597 }
598 598
599 599 #content div.box dd {
600 600 font-size:12px;
601 601 margin:0;
602 602 padding:8px 0 8px 15px;
603 603 }
604 604
605 605 #content div.box li {
606 606 font-size:12px;
607 607 padding:4px 0;
608 608 }
609 609
610 610 #content div.box ul.disc,#content div.box ul.circle {
611 611 margin:10px 24px 10px 38px;
612 612 }
613 613
614 614 #content div.box ul.square {
615 615 margin:10px 24px 10px 40px;
616 616 }
617 617
618 618 #content div.box img.left {
619 619 border:none;
620 620 float:left;
621 621 margin:10px 10px 10px 0;
622 622 }
623 623
624 624 #content div.box img.right {
625 625 border:none;
626 626 float:right;
627 627 margin:10px 0 10px 10px;
628 628 }
629 629
630 630 #content div.box div.messages {
631 631 clear:both;
632 632 overflow:hidden;
633 633 margin:0 20px;
634 634 padding:0;
635 635 }
636 636
637 637 #content div.box div.message {
638 638 clear:both;
639 639 overflow:hidden;
640 640 margin:0;
641 641 padding:10px 0;
642 642 }
643 643
644 644 #content div.box div.message a {
645 645 font-weight:400 !important;
646 646 }
647 647
648 648 #content div.box div.message div.image {
649 649 float:left;
650 650 margin:9px 0 0 5px;
651 651 padding:6px;
652 652 }
653 653
654 654 #content div.box div.message div.image img {
655 655 vertical-align:middle;
656 656 margin:0;
657 657 }
658 658
659 659 #content div.box div.message div.text {
660 660 float:left;
661 661 margin:0;
662 662 padding:9px 6px;
663 663 }
664 664
665 665 #content div.box div.message div.dismiss a {
666 666 height:16px;
667 667 width:16px;
668 668 display:block;
669 669 background:url("../images/icons/cross.png") no-repeat;
670 670 margin:15px 14px 0 0;
671 671 padding:0;
672 672 }
673 673
674 674 #content div.box div.message div.text h1,#content div.box div.message div.text h2,#content div.box div.message div.text h3,#content div.box div.message div.text h4,#content div.box div.message div.text h5,#content div.box div.message div.text h6 {
675 675 border:none;
676 676 margin:0;
677 677 padding:0;
678 678 }
679 679
680 680 #content div.box div.message div.text span {
681 681 height:1%;
682 682 display:block;
683 683 margin:0;
684 684 padding:5px 0 0;
685 685 }
686 686
687 687 #content div.box div.message-error {
688 688 height:1%;
689 689 clear:both;
690 690 overflow:hidden;
691 691 background:#FBE3E4;
692 692 border:1px solid #FBC2C4;
693 693 color:#860006;
694 694 }
695 695
696 696 #content div.box div.message-error h6 {
697 697 color:#860006;
698 698 }
699 699
700 700 #content div.box div.message-warning {
701 701 height:1%;
702 702 clear:both;
703 703 overflow:hidden;
704 704 background:#FFF6BF;
705 705 border:1px solid #FFD324;
706 706 color:#5f5200;
707 707 }
708 708
709 709 #content div.box div.message-warning h6 {
710 710 color:#5f5200;
711 711 }
712 712
713 713 #content div.box div.message-notice {
714 714 height:1%;
715 715 clear:both;
716 716 overflow:hidden;
717 717 background:#8FBDE0;
718 718 border:1px solid #6BACDE;
719 719 color:#003863;
720 720 }
721 721
722 722 #content div.box div.message-notice h6 {
723 723 color:#003863;
724 724 }
725 725
726 726 #content div.box div.message-success {
727 727 height:1%;
728 728 clear:both;
729 729 overflow:hidden;
730 730 background:#E6EFC2;
731 731 border:1px solid #C6D880;
732 732 color:#4e6100;
733 733 }
734 734
735 735 #content div.box div.message-success h6 {
736 736 color:#4e6100;
737 737 }
738 738
739 739 #content div.box div.form div.fields div.field {
740 740 height:1%;
741 741 border-bottom:1px solid #DDD;
742 742 clear:both;
743 743 margin:0;
744 744 padding:10px 0;
745 745 }
746 746
747 747 #content div.box div.form div.fields div.field-first {
748 748 padding:0 0 10px;
749 749 }
750 750
751 751 #content div.box div.form div.fields div.field-noborder {
752 752 border-bottom:0 !important;
753 753 }
754 754
755 755 #content div.box div.form div.fields div.field span.error-message {
756 756 height:1%;
757 757 display:inline-block;
758 758 color:red;
759 759 margin:8px 0 0 4px;
760 760 padding:0;
761 761 }
762 762
763 763 #content div.box div.form div.fields div.field span.success {
764 764 height:1%;
765 765 display:block;
766 766 color:#316309;
767 767 margin:8px 0 0;
768 768 padding:0;
769 769 }
770 770
771 771 #content div.box div.form div.fields div.field div.label {
772 772 left:80px;
773 773 width:auto;
774 774 position:absolute;
775 775 margin:0;
776 776 padding:8px 0 0 5px;
777 777 }
778 778
779 779 #content div.box-left div.form div.fields div.field div.label,#content div.box-right div.form div.fields div.field div.label {
780 780 clear:both;
781 781 overflow:hidden;
782 782 left:0;
783 783 width:auto;
784 784 position:relative;
785 785 margin:0;
786 786 padding:0 0 8px;
787 787 }
788 788
789 789 #content div.box div.form div.fields div.field div.label-select {
790 790 padding:2px 0 0 5px;
791 791 }
792 792
793 793 #content div.box-left div.form div.fields div.field div.label-select,#content div.box-right div.form div.fields div.field div.label-select {
794 794 padding:0 0 8px;
795 795 }
796 796
797 797 #content div.box-left div.form div.fields div.field div.label-textarea,#content div.box-right div.form div.fields div.field div.label-textarea {
798 798 padding:0 0 8px !important;
799 799 }
800 800
801 801 #content div.box div.form div.fields div.field div.label label {
802 802 color:#393939;
803 803 font-weight:700;
804 804 }
805 805
806 806 #content div.box div.form div.fields div.field div.input {
807 807 margin:0 0 0 200px;
808 808 }
809 809
810 810 #content div.box-left div.form div.fields div.field div.input,#content div.box-right div.form div.fields div.field div.input {
811 811 clear:both;
812 812 overflow:hidden;
813 813 border-top:1px solid #b3b3b3;
814 814 border-left:1px solid #b3b3b3;
815 815 border-right:1px solid #eaeaea;
816 816 border-bottom:1px solid #eaeaea;
817 817 margin:0;
818 818 padding:7px 7px 6px;
819 819 }
820 820
821 821 #content div.box div.form div.fields div.field div.input input {
822 822 background:#FFF;
823 823 border-top:1px solid #b3b3b3;
824 824 border-left:1px solid #b3b3b3;
825 825 border-right:1px solid #eaeaea;
826 826 border-bottom:1px solid #eaeaea;
827 827 color:#000;
828 828 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
829 829 font-size:11px;
830 830 margin:0;
831 831 padding:7px 7px 6px;
832 832 }
833 833
834 834 #content div.box-left div.form div.fields div.field div.input input,#content div.box-right div.form div.fields div.field div.input input {
835 835 width:100%;
836 836 border:none;
837 837 padding:0;
838 838 }
839 839
840 840 #content div.box div.form div.fields div.field div.input input.small {
841 841 width:30%;
842 842 }
843 843
844 844 #content div.box div.form div.fields div.field div.input input.medium {
845 845 width:55%;
846 846 }
847 847
848 848 #content div.box div.form div.fields div.field div.input input.large {
849 849 width:85%;
850 850 }
851 851
852 852 #content div.box div.form div.fields div.field div.input input.date {
853 853 width:177px;
854 854 }
855 855
856 856 #content div.box div.form div.fields div.field div.input input.button {
857 857 background:#D4D0C8;
858 858 border-top:1px solid #FFF;
859 859 border-left:1px solid #FFF;
860 860 border-right:1px solid #404040;
861 861 border-bottom:1px solid #404040;
862 862 color:#000;
863 863 margin:0;
864 864 padding:4px 8px;
865 865 }
866 866
867 867 #content div.box div.form div.fields div.field div.input a.ui-input-file {
868 868 width:28px;
869 869 height:28px;
870 870 display:inline;
871 871 position:absolute;
872 872 overflow:hidden;
873 873 cursor:pointer;
874 874 background:#e5e3e3 url("../images/button_browse.png") no-repeat;
875 875 border:none;
876 876 text-decoration:none;
877 877 margin:0 0 0 6px;
878 878 padding:0;
879 879 }
880 880
881 881 #content div.box div.form div.fields div.field div.textarea {
882 882 border-top:1px solid #b3b3b3;
883 883 border-left:1px solid #b3b3b3;
884 884 border-right:1px solid #eaeaea;
885 885 border-bottom:1px solid #eaeaea;
886 886 margin:0 0 0 200px;
887 887 padding:10px;
888 888 }
889 889
890 890 #content div.box div.form div.fields div.field div.textarea-editor {
891 891 border:1px solid #ddd;
892 892 padding:0;
893 893 }
894 894
895 895 #content div.box div.form div.fields div.field div.textarea textarea {
896 896 width:100%;
897 897 height:220px;
898 898 overflow:hidden;
899 899 background:#FFF;
900 900 color:#000;
901 901 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
902 902 font-size:11px;
903 903 outline:none;
904 904 border-width:0;
905 905 margin:0;
906 906 padding:0;
907 907 }
908 908
909 909 #content div.box-left div.form div.fields div.field div.textarea textarea,#content div.box-right div.form div.fields div.field div.textarea textarea {
910 910 width:100%;
911 911 height:100px;
912 912 }
913 913
914 914 #content div.box div.form div.fields div.field div.textarea table {
915 915 width:100%;
916 916 border:none;
917 917 margin:0;
918 918 padding:0;
919 919 }
920 920
921 921 #content div.box div.form div.fields div.field div.textarea table td {
922 922 background:#DDD;
923 923 border:none;
924 924 padding:0;
925 925 }
926 926
927 927 #content div.box div.form div.fields div.field div.textarea table td table {
928 928 width:auto;
929 929 border:none;
930 930 margin:0;
931 931 padding:0;
932 932 }
933 933
934 934 #content div.box div.form div.fields div.field div.textarea table td table td {
935 935 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
936 936 font-size:11px;
937 937 padding:5px 5px 5px 0;
938 938 }
939 939
940 940 #content div.box div.form div.fields div.field div.textarea table td table td a.mceButtonActive {
941 941 background:#b1b1b1;
942 942 }
943 943
944 944 #content div.box div.form div.fields div.field div.select a.ui-selectmenu {
945 945 color:#565656;
946 946 text-decoration:none;
947 947 }
948 948
949 949 #content div.box div.form div.fields div.field input[type=text]:focus,#content div.box div.form div.fields div.field input[type=password]:focus,#content div.box div.form div.fields div.field input[type=file]:focus,#content div.box div.form div.fields div.field textarea:focus,#content div.box div.form div.fields div.field select:focus {
950 950 background:#f6f6f6;
951 951 border-color:#666;
952 952 }
953 953
954 954 div.form div.fields div.field div.button {
955 955 margin:0;
956 956 padding:0 0 0 8px;
957 957 }
958 958
959 959 div.form div.fields div.field div.highlight .ui-state-default {
960 960 background:#4e85bb url("../images/button_highlight.png") repeat-x;
961 961 border-top:1px solid #5c91a4;
962 962 border-left:1px solid #2a6f89;
963 963 border-right:1px solid #2b7089;
964 964 border-bottom:1px solid #1a6480;
965 965 color:#FFF;
966 966 margin:0;
967 967 padding:6px 12px;
968 968 }
969 969
970 970 div.form div.fields div.field div.highlight .ui-state-hover {
971 971 background:#46a0c1 url("../images/button_highlight_selected.png") repeat-x;
972 972 border-top:1px solid #78acbf;
973 973 border-left:1px solid #34819e;
974 974 border-right:1px solid #35829f;
975 975 border-bottom:1px solid #257897;
976 976 color:#FFF;
977 977 margin:0;
978 978 padding:6px 12px;
979 979 }
980 980
981 981 #content div.box div.form div.fields div.buttons div.highlight input.ui-state-default {
982 982 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
983 983 border-top:1px solid #5c91a4;
984 984 border-left:1px solid #2a6f89;
985 985 border-right:1px solid #2b7089;
986 986 border-bottom:1px solid #1a6480;
987 987 color:#fff;
988 988 margin:0;
989 989 padding:6px 12px;
990 990 }
991 991
992 992 #content div.box div.form div.fields div.buttons div.highlight input.ui-state-hover {
993 993 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
994 994 border-top:1px solid #78acbf;
995 995 border-left:1px solid #34819e;
996 996 border-right:1px solid #35829f;
997 997 border-bottom:1px solid #257897;
998 998 color:#fff;
999 999 margin:0;
1000 1000 padding:6px 12px;
1001 1001 }
1002 1002
1003 1003 #content div.box table {
1004 1004 width:100%;
1005 1005 border-collapse:collapse;
1006 1006 margin:0;
1007 1007 padding:0;
1008 1008 }
1009 1009
1010 1010 #content div.box table th {
1011 1011 background:#eee;
1012 1012 border-bottom:1px solid #ddd;
1013 padding:10px;
1013 padding:5px 0px 5px 5px;
1014 1014 }
1015 1015
1016 1016 #content div.box table th.left {
1017 1017 text-align:left;
1018 1018 }
1019 1019
1020 1020 #content div.box table th.right {
1021 1021 text-align:right;
1022 1022 }
1023 1023
1024 1024 #content div.box table th.center {
1025 1025 text-align:center;
1026 1026 }
1027 1027
1028 1028 #content div.box table th.selected {
1029 1029 vertical-align:middle;
1030 1030 padding:0;
1031 1031 }
1032 1032
1033 1033 #content div.box table td {
1034 1034 background:#fff;
1035 1035 border-bottom:1px solid #cdcdcd;
1036 1036 vertical-align:middle;
1037 1037 padding:5px;
1038 1038 }
1039 1039
1040 1040 #content div.box table tr.selected td {
1041 1041 background:#FFC;
1042 1042 }
1043 1043
1044 1044 #content div.box table td.selected {
1045 1045 width:3%;
1046 1046 text-align:center;
1047 1047 vertical-align:middle;
1048 1048 padding:0;
1049 1049 }
1050 1050
1051 1051 #content div.box table td.action {
1052 1052 width:45%;
1053 1053 text-align:left;
1054 1054 }
1055 1055
1056 1056 #content div.box table td.date {
1057 1057 width:33%;
1058 1058 text-align:center;
1059 1059 }
1060 1060
1061 1061 #content div.box div.action {
1062 1062 float:right;
1063 1063 background:#FFF;
1064 1064 text-align:right;
1065 1065 margin:10px 0 0;
1066 1066 padding:0;
1067 1067 }
1068 1068
1069 1069 #content div.box div.action select {
1070 1070 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1071 1071 font-size:11px;
1072 1072 margin:0;
1073 1073 }
1074 1074
1075 1075 #content div.box div.action .ui-selectmenu {
1076 1076 margin:0;
1077 1077 padding:0;
1078 1078 }
1079 1079
1080 1080 #content div.box div.pagination {
1081 1081 height:1%;
1082 1082 clear:both;
1083 1083 overflow:hidden;
1084 1084 margin:10px 0 0;
1085 1085 padding:0;
1086 1086 }
1087 1087
1088 1088 #content div.box div.pagination ul.pager {
1089 1089 float:right;
1090 1090 text-align:right;
1091 1091 margin:0;
1092 1092 padding:0;
1093 1093 }
1094 1094
1095 1095 #content div.box div.pagination ul.pager li {
1096 1096 height:1%;
1097 1097 float:left;
1098 1098 list-style:none;
1099 1099 background:#ebebeb url("../images/pager.png") repeat-x;
1100 1100 border-top:1px solid #dedede;
1101 1101 border-left:1px solid #cfcfcf;
1102 1102 border-right:1px solid #c4c4c4;
1103 1103 border-bottom:1px solid #c4c4c4;
1104 1104 color:#4A4A4A;
1105 1105 font-weight:700;
1106 1106 margin:0 0 0 4px;
1107 1107 padding:0;
1108 1108 }
1109 1109
1110 1110 #content div.box div.pagination ul.pager li.separator {
1111 1111 padding:6px;
1112 1112 }
1113 1113
1114 1114 #content div.box div.pagination ul.pager li.current {
1115 1115 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1116 1116 border-top:1px solid #ccc;
1117 1117 border-left:1px solid #bebebe;
1118 1118 border-right:1px solid #b1b1b1;
1119 1119 border-bottom:1px solid #afafaf;
1120 1120 color:#515151;
1121 1121 padding:6px;
1122 1122 }
1123 1123
1124 1124 #content div.box div.pagination ul.pager li a {
1125 1125 height:1%;
1126 1126 display:block;
1127 1127 float:left;
1128 1128 color:#515151;
1129 1129 text-decoration:none;
1130 1130 margin:0;
1131 1131 padding:6px;
1132 1132 }
1133 1133
1134 1134 #content div.box div.pagination ul.pager li a:hover,#content div.box div.pagination ul.pager li a:active {
1135 1135 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1136 1136 border-top:1px solid #ccc;
1137 1137 border-left:1px solid #bebebe;
1138 1138 border-right:1px solid #b1b1b1;
1139 1139 border-bottom:1px solid #afafaf;
1140 1140 margin:-1px;
1141 1141 }
1142 1142
1143 1143 #content div.box div.pagination-wh {
1144 1144 height:1%;
1145 1145 clear:both;
1146 1146 overflow:hidden;
1147 1147 text-align:right;
1148 1148 margin:10px 0 0;
1149 1149 padding:0;
1150 1150 }
1151 1151
1152 1152 #content div.box div.pagination-right {
1153 1153 float:right;
1154 1154 }
1155 1155
1156 1156 #content div.box div.pagination-wh a,#content div.box div.pagination-wh span.pager_dotdot {
1157 1157 height:1%;
1158 1158 float:left;
1159 1159 background:#ebebeb url("../images/pager.png") repeat-x;
1160 1160 border-top:1px solid #dedede;
1161 1161 border-left:1px solid #cfcfcf;
1162 1162 border-right:1px solid #c4c4c4;
1163 1163 border-bottom:1px solid #c4c4c4;
1164 1164 color:#4A4A4A;
1165 1165 font-weight:700;
1166 1166 margin:0 0 0 4px;
1167 1167 padding:6px;
1168 1168 }
1169 1169
1170 1170 #content div.box div.pagination-wh span.pager_curpage {
1171 1171 height:1%;
1172 1172 float:left;
1173 1173 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1174 1174 border-top:1px solid #ccc;
1175 1175 border-left:1px solid #bebebe;
1176 1176 border-right:1px solid #b1b1b1;
1177 1177 border-bottom:1px solid #afafaf;
1178 1178 color:#515151;
1179 1179 font-weight:700;
1180 1180 margin:0 0 0 4px;
1181 1181 padding:6px;
1182 1182 }
1183 1183
1184 1184 #content div.box div.pagination-wh a:hover,#content div.box div.pagination-wh a:active {
1185 1185 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1186 1186 border-top:1px solid #ccc;
1187 1187 border-left:1px solid #bebebe;
1188 1188 border-right:1px solid #b1b1b1;
1189 1189 border-bottom:1px solid #afafaf;
1190 1190 text-decoration:none;
1191 1191 }
1192 1192
1193 1193 #content div.box div.traffic div.legend {
1194 1194 clear:both;
1195 1195 overflow:hidden;
1196 1196 border-bottom:1px solid #ddd;
1197 1197 margin:0 0 10px;
1198 1198 padding:0 0 10px;
1199 1199 }
1200 1200
1201 1201 #content div.box div.traffic div.legend h6 {
1202 1202 float:left;
1203 1203 border:none;
1204 1204 margin:0;
1205 1205 padding:0;
1206 1206 }
1207 1207
1208 1208 #content div.box div.traffic div.legend li {
1209 1209 list-style:none;
1210 1210 float:left;
1211 1211 font-size:11px;
1212 1212 margin:0;
1213 1213 padding:0 8px 0 4px;
1214 1214 }
1215 1215
1216 1216 #content div.box div.traffic div.legend li.visits {
1217 1217 border-left:12px solid #edc240;
1218 1218 }
1219 1219
1220 1220 #content div.box div.traffic div.legend li.pageviews {
1221 1221 border-left:12px solid #afd8f8;
1222 1222 }
1223 1223
1224 1224 #content div.box div.traffic table {
1225 1225 width:auto;
1226 1226 }
1227 1227
1228 1228 #content div.box div.traffic table td {
1229 1229 background:transparent;
1230 1230 border:none;
1231 1231 padding:2px 3px 3px;
1232 1232 }
1233 1233
1234 1234 #content div.box div.traffic table td.legendLabel {
1235 1235 padding:0 3px 2px;
1236 1236 }
1237 1237
1238 1238 #footer {
1239 1239 clear:both;
1240 1240 overflow:hidden;
1241 1241 text-align:right;
1242 1242 margin:0;
1243 1243 padding:0 30px 4px;
1244 1244 margin:-10px 0 0;
1245 1245 }
1246 1246
1247 1247 #footer div#footer-inner {
1248 1248 background:url("../images/header_inner.png") repeat-x scroll 0 0 #003367;
1249 1249 border-top:2px solid #FFFFFF;
1250 1250 }
1251 1251
1252 1252 #footer div#footer-inner p {
1253 1253 padding:15px 25px 15px 0;
1254 1254 color:#FFF;
1255 1255 font-weight:700;
1256 1256 }
1257 1257 #footer div#footer-inner .footer-link {
1258 1258 float:left;
1259 1259 padding-left:10px;
1260 1260 }
1261 1261 #footer div#footer-inner .footer-link a {
1262 1262 color:#FFF;
1263 1263 }
1264 1264
1265 1265 #login div.title {
1266 1266 width:420px;
1267 1267 clear:both;
1268 1268 overflow:hidden;
1269 1269 position:relative;
1270 1270 background:#003367 url("../../images/header_inner.png") repeat-x;
1271 1271 margin:0 auto;
1272 1272 padding:0;
1273 1273 }
1274 1274
1275 1275 #login div.inner {
1276 1276 width:380px;
1277 1277 background:#FFF url("../images/login.png") no-repeat top left;
1278 1278 border-top:none;
1279 1279 border-bottom:none;
1280 1280 margin:0 auto;
1281 1281 padding:20px;
1282 1282 }
1283 1283
1284 1284 #login div.form div.fields div.field div.label {
1285 1285 width:173px;
1286 1286 float:left;
1287 1287 text-align:right;
1288 1288 margin:2px 10px 0 0;
1289 1289 padding:5px 0 0 5px;
1290 1290 }
1291 1291
1292 1292 #login div.form div.fields div.field div.input input {
1293 1293 width:176px;
1294 1294 background:#FFF;
1295 1295 border-top:1px solid #b3b3b3;
1296 1296 border-left:1px solid #b3b3b3;
1297 1297 border-right:1px solid #eaeaea;
1298 1298 border-bottom:1px solid #eaeaea;
1299 1299 color:#000;
1300 1300 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1301 1301 font-size:11px;
1302 1302 margin:0;
1303 1303 padding:7px 7px 6px;
1304 1304 }
1305 1305
1306 1306 #login div.form div.fields div.buttons {
1307 1307 clear:both;
1308 1308 overflow:hidden;
1309 1309 border-top:1px solid #DDD;
1310 1310 text-align:right;
1311 1311 margin:0;
1312 1312 padding:10px 0 0;
1313 1313 }
1314 1314
1315 1315 #login div.form div.links {
1316 1316 clear:both;
1317 1317 overflow:hidden;
1318 1318 margin:10px 0 0;
1319 1319 padding:0 0 2px;
1320 1320 }
1321 1321
1322 1322 #register div.title {
1323 1323 width:420px;
1324 1324 clear:both;
1325 1325 overflow:hidden;
1326 1326 position:relative;
1327 1327 background:#003367 url("../images/header_inner.png") repeat-x;
1328 1328 margin:0 auto;
1329 1329 padding:0;
1330 1330 }
1331 1331
1332 1332 #register div.inner {
1333 1333 width:380px;
1334 1334 background:#FFF;
1335 1335 border-top:none;
1336 1336 border-bottom:none;
1337 1337 margin:0 auto;
1338 1338 padding:20px;
1339 1339 }
1340 1340
1341 1341 #register div.form div.fields div.field div.label {
1342 1342 width:100px;
1343 1343 float:left;
1344 1344 text-align:right;
1345 1345 margin:2px 10px 0 0;
1346 1346 padding:5px 0 0 5px;
1347 1347 }
1348 1348
1349 1349 #register div.form div.fields div.field div.input input {
1350 1350 width:245px;
1351 1351 background:#FFF;
1352 1352 border-top:1px solid #b3b3b3;
1353 1353 border-left:1px solid #b3b3b3;
1354 1354 border-right:1px solid #eaeaea;
1355 1355 border-bottom:1px solid #eaeaea;
1356 1356 color:#000;
1357 1357 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1358 1358 font-size:11px;
1359 1359 margin:0;
1360 1360 padding:7px 7px 6px;
1361 1361 }
1362 1362
1363 1363 #register div.form div.fields div.buttons {
1364 1364 clear:both;
1365 1365 overflow:hidden;
1366 1366 border-top:1px solid #DDD;
1367 1367 text-align:left;
1368 1368 margin:0;
1369 1369 padding:10px 0 0 114px;
1370 1370 }
1371 1371
1372 1372 #register div.form div.fields div.buttons div.highlight input.ui-state-default {
1373 1373 background:url("../images/button_highlight.png") repeat-x scroll 0 0 #4E85BB;
1374 1374 color:#FFF;
1375 1375 border-color:#5C91A4 #2B7089 #1A6480 #2A6F89;
1376 1376 border-style:solid;
1377 1377 border-width:1px;
1378 1378 }
1379 1379
1380 1380 #register div.form div.activation_msg {
1381 1381 padding-top:4px;
1382 1382 padding-bottom:4px;
1383 1383 }
1384 1384
1385 1385 .trending_language_tbl,.trending_language_tbl td {
1386 1386 border:0 !important;
1387 1387 margin:0 !important;
1388 1388 padding:0 !important;
1389 1389 }
1390 1390
1391 1391 .trending_language {
1392 1392 background-color:#003367;
1393 1393 color:#FFF;
1394 1394 display:block;
1395 1395 min-width:20px;
1396 1396 max-width:400px;
1397 1397 text-decoration:none;
1398 1398 height:12px;
1399 1399 margin-bottom:4px;
1400 1400 margin-left:5px;
1401 1401 white-space:pre;
1402 1402 padding:3px;
1403 1403 }
1404 1404
1405 1405 h3.files_location {
1406 1406 font-size:1.8em;
1407 1407 font-weight:700;
1408 1408 border-bottom:none !important;
1409 1409 margin:10px 0 !important;
1410 1410 }
1411 1411
1412 1412 #files_data dl dt {
1413 1413 float:left;
1414 1414 width:115px;
1415 1415 margin:0 !important;
1416 1416 padding:5px;
1417 1417 }
1418 1418
1419 1419 #files_data dl dd {
1420 1420 margin:0 !important;
1421 1421 padding:5px !important;
1422 1422 }
1423 1423
1424 1424 #changeset_content {
1425 1425 border:1px solid #CCC;
1426 1426 padding:5px;
1427 1427 }
1428 1428
1429 1429 #changeset_content .container {
1430 1430 min-height:120px;
1431 1431 font-size:1.2em;
1432 1432 overflow:hidden;
1433 1433 }
1434 1434
1435 1435 #changeset_content .container .right {
1436 1436 float:right;
1437 1437 width:25%;
1438 1438 text-align:right;
1439 1439 }
1440 1440
1441 1441 #changeset_content .container .left .message {
1442 1442 font-style:italic;
1443 1443 color:#556CB5;
1444 1444 white-space:pre-wrap;
1445 1445 }
1446 1446
1447 1447 .cs_files .cs_added {
1448 1448 background:url("../images/icons/page_white_add.png") no-repeat scroll 3px;
1449 1449 height:16px;
1450 1450 padding-left:20px;
1451 1451 margin-top:7px;
1452 1452 text-align:left;
1453 1453 }
1454 1454
1455 1455 .cs_files .cs_changed {
1456 1456 background:url("../images/icons/page_white_edit.png") no-repeat scroll 3px;
1457 1457 height:16px;
1458 1458 padding-left:20px;
1459 1459 margin-top:7px;
1460 1460 text-align:left;
1461 1461 }
1462 1462
1463 1463 .cs_files .cs_removed {
1464 1464 background:url("../images/icons/page_white_delete.png") no-repeat scroll 3px;
1465 1465 height:16px;
1466 1466 padding-left:20px;
1467 1467 margin-top:7px;
1468 1468 text-align:left;
1469 1469 }
1470 1470
1471 1471 #graph {
1472 1472 overflow:hidden;
1473 1473 }
1474 1474
1475 1475 #graph_nodes {
1476 1476 width:160px;
1477 1477 float:left;
1478 1478 margin-left:-50px;
1479 1479 margin-top:5px;
1480 1480 }
1481 1481
1482 1482 #graph_content {
1483 1483 width:800px;
1484 1484 float:left;
1485 1485 }
1486 1486
1487 1487 #graph_content .container_header {
1488 1488 border:1px solid #CCC;
1489 1489 padding:10px;
1490 1490 }
1491 1491
1492 1492 #graph_content .container {
1493 1493 border-bottom:1px solid #CCC;
1494 1494 border-left:1px solid #CCC;
1495 1495 border-right:1px solid #CCC;
1496 1496 min-height:80px;
1497 1497 overflow:hidden;
1498 1498 font-size:1.2em;
1499 1499 }
1500 1500
1501 1501 #graph_content .container .right {
1502 1502 float:right;
1503 1503 width:28%;
1504 1504 text-align:right;
1505 1505 padding-bottom:5px;
1506 1506 }
1507 1507
1508 1508 #graph_content .container .left .date {
1509 1509 font-weight:700;
1510 1510 padding-bottom:5px;
1511 1511 }
1512 1512
1513 1513 #graph_content .container .left .message {
1514 1514 font-size:100%;
1515 1515 padding-top:3px;
1516 1516 white-space:pre-wrap;
1517 1517 }
1518 1518
1519 1519 .right div {
1520 1520 clear:both;
1521 1521 }
1522 1522
1523 1523 .right .changes .added,.changed,.removed {
1524 1524 border:1px solid #DDD;
1525 1525 display:block;
1526 1526 float:right;
1527 1527 text-align:center;
1528 1528 min-width:15px;
1529 1529 }
1530 1530
1531 1531 .right .changes .added {
1532 1532 background:#BFB;
1533 1533 }
1534 1534
1535 1535 .right .changes .changed {
1536 1536 background:#FD8;
1537 1537 }
1538 1538
1539 1539 .right .changes .removed {
1540 1540 background:#F88;
1541 1541 }
1542 1542
1543 1543 .right .merge {
1544 1544 vertical-align:top;
1545 1545 font-size:60%;
1546 1546 font-weight:700;
1547 1547 }
1548 1548
1549 1549 .right .parent {
1550 1550 font-size:90%;
1551 1551 font-family:monospace;
1552 1552 }
1553 1553
1554 1554 .right .logtags .branchtag {
1555 1555 background:#FFF url("../images/icons/arrow_branch.png") no-repeat right 6px;
1556 1556 display:block;
1557 1557 padding:8px 16px 0 0;
1558 1558 }
1559 1559
1560 1560 .right .logtags .tagtag {
1561 1561 background:#FFF url("../images/icons/tag_blue.png") no-repeat right 6px;
1562 1562 display:block;
1563 1563 padding:6px 18px 0 0;
1564 1564 }
1565 1565
1566 1566 div.browserblock {
1567 1567 overflow:hidden;
1568 1568 border:1px solid #ccc;
1569 1569 background:#f8f8f8;
1570 1570 font-size:100%;
1571 1571 line-height:125%;
1572 1572 padding:0;
1573 1573 }
1574 1574
1575 1575 div.browserblock .browser-header {
1576 1576 border-bottom:1px solid #CCC;
1577 1577 background:#FFF;
1578 1578 color:blue;
1579 1579 padding:10px 0;
1580 1580 }
1581 1581
1582 1582 div.browserblock .browser-header span {
1583 1583 margin-left:25px;
1584 1584 font-weight:700;
1585 1585 }
1586 1586
1587 1587 div.browserblock .browser-body {
1588 1588 background:#EEE;
1589 1589 }
1590 1590
1591 1591 table.code-browser {
1592 1592 border-collapse:collapse;
1593 1593 width:100%;
1594 1594 }
1595 1595
1596 1596 table.code-browser tr {
1597 1597 margin:3px;
1598 1598 }
1599 1599
1600 1600 table.code-browser thead th {
1601 1601 background-color:#EEE;
1602 1602 height:20px;
1603 1603 font-size:1.1em;
1604 1604 font-weight:700;
1605 1605 text-align:left;
1606 1606 padding-left:10px;
1607 1607 }
1608 1608
1609 1609 table.code-browser tbody td {
1610 1610 padding-left:10px;
1611 1611 height:20px;
1612 1612 }
1613 1613
1614 1614 table.code-browser .browser-file {
1615 1615 background:url("../images/icons/document_16.png") no-repeat scroll 3px;
1616 1616 height:16px;
1617 1617 padding-left:20px;
1618 1618 text-align:left;
1619 1619 }
1620 1620
1621 1621 table.code-browser .browser-dir {
1622 1622 background:url("../images/icons/folder_16.png") no-repeat scroll 3px;
1623 1623 height:16px;
1624 1624 padding-left:20px;
1625 1625 text-align:left;
1626 1626 }
1627 1627
1628 1628 .box .search {
1629 1629 clear:both;
1630 1630 overflow:hidden;
1631 1631 margin:0;
1632 1632 padding:0 20px 10px;
1633 1633 }
1634 1634
1635 1635 .box .search div.search_path {
1636 1636 background:none repeat scroll 0 0 #EEE;
1637 1637 border:1px solid #CCC;
1638 1638 color:blue;
1639 1639 margin-bottom:10px;
1640 1640 padding:10px 0;
1641 1641 }
1642 1642
1643 1643 .box .search div.search_path div.link {
1644 1644 font-weight:700;
1645 1645 margin-left:25px;
1646 1646 }
1647 1647
1648 1648 .box .search div.search_path div.link a {
1649 1649 color:#003367;
1650 1650 cursor:pointer;
1651 1651 text-decoration:none;
1652 1652 }
1653 1653
1654 1654 #path_unlock {
1655 1655 color:red;
1656 1656 font-size:1.2em;
1657 1657 padding-left:4px;
1658 1658 }
1659 1659
1660 1660 .info_box * {
1661 1661 background:url("../../images/pager.png") repeat-x scroll 0 0 #EBEBEB;
1662 1662 color:#4A4A4A;
1663 1663 font-weight:700;
1664 1664 height:1%;
1665 1665 display:inline;
1666 1666 border-color:#DEDEDE #C4C4C4 #C4C4C4 #CFCFCF;
1667 1667 border-style:solid;
1668 1668 border-width:1px;
1669 1669 padding:4px 6px;
1670 1670 }
1671 1671
1672 1672 .info_box span {
1673 1673 margin-left:3px;
1674 1674 margin-right:3px;
1675 1675 }
1676 1676
1677 1677 .info_box input#at_rev {
1678 1678 text-align:center;
1679 1679 padding:5px 3px 3px 2px;
1680 1680 }
1681 1681
1682 1682 .info_box input#view {
1683 1683 text-align:center;
1684 1684 padding:4px 3px 2px 2px;
1685 1685 }
1686 1686
1687 1687 .yui-overlay,.yui-panel-container {
1688 1688 visibility:hidden;
1689 1689 position:absolute;
1690 1690 z-index:2;
1691 1691 }
1692 1692
1693 1693 .yui-tt {
1694 1694 visibility:hidden;
1695 1695 position:absolute;
1696 1696 color:#666;
1697 1697 background-color:#FFF;
1698 1698 font-family:arial, helvetica, verdana, sans-serif;
1699 1699 border:2px solid #003367;
1700 1700 font:100% sans-serif;
1701 1701 width:auto;
1702 1702 opacity:1px;
1703 1703 padding:8px;
1704 1704 }
1705 1705
1706 1706 .ac {
1707 1707 vertical-align:top;
1708 1708 }
1709 1709
1710 1710 .ac .yui-ac {
1711 1711 position:relative;
1712 1712 font-family:arial;
1713 1713 font-size:100%;
1714 1714 }
1715 1715
1716 1716 .ac .perm_ac {
1717 1717 width:15em;
1718 1718 }
1719 1719
1720 1720 .ac .yui-ac-input {
1721 1721 width:100%;
1722 1722 }
1723 1723
1724 1724 .ac .yui-ac-container {
1725 1725 position:absolute;
1726 1726 top:1.6em;
1727 1727 width:100%;
1728 1728 }
1729 1729
1730 1730 .ac .yui-ac-content {
1731 1731 position:absolute;
1732 1732 width:100%;
1733 1733 border:1px solid gray;
1734 1734 background:#fff;
1735 1735 overflow:hidden;
1736 1736 z-index:9050;
1737 1737 }
1738 1738
1739 1739 .ac .yui-ac-shadow {
1740 1740 position:absolute;
1741 1741 width:100%;
1742 1742 background:#000;
1743 1743 -moz-opacity:0.1px;
1744 1744 opacity:.10;
1745 1745 filter:alpha(opacity = 10);
1746 1746 z-index:9049;
1747 1747 margin:.3em;
1748 1748 }
1749 1749
1750 1750 .ac .yui-ac-content ul {
1751 1751 width:100%;
1752 1752 margin:0;
1753 1753 padding:0;
1754 1754 }
1755 1755
1756 1756 .ac .yui-ac-content li {
1757 1757 cursor:default;
1758 1758 white-space:nowrap;
1759 1759 margin:0;
1760 1760 padding:2px 5px;
1761 1761 }
1762 1762
1763 1763 .ac .yui-ac-content li.yui-ac-prehighlight {
1764 1764 background:#B3D4FF;
1765 1765 }
1766 1766
1767 1767 .ac .yui-ac-content li.yui-ac-highlight {
1768 1768 background:#556CB5;
1769 1769 color:#FFF;
1770 1770 }
1771 1771
1772 1772 .add_icon {
1773 1773 background:url("../images/icons/add.png") no-repeat scroll 3px;
1774 1774 height:16px;
1775 1775 padding-left:20px;
1776 1776 padding-top:1px;
1777 1777 text-align:left;
1778 1778 }
1779 1779
1780 1780 .edit_icon {
1781 1781 background:url("../images/icons/folder_edit.png") no-repeat scroll 3px;
1782 1782 height:16px;
1783 1783 padding-left:20px;
1784 1784 padding-top:1px;
1785 1785 text-align:left;
1786 1786 }
1787 1787
1788 1788 .delete_icon {
1789 1789 background:url("../images/icons/delete.png") no-repeat scroll 3px;
1790 1790 height:16px;
1791 1791 padding-left:20px;
1792 1792 padding-top:1px;
1793 1793 text-align:left;
1794 1794 }
1795 1795
1796 1796 .rss_icon {
1797 1797 background:url("../images/icons/rss_16.png") no-repeat scroll 3px;
1798 1798 height:16px;
1799 1799 padding-left:20px;
1800 1800 padding-top:1px;
1801 1801 text-align:left;
1802 1802 }
1803 1803
1804 1804 .atom_icon {
1805 1805 background:url("../images/icons/atom.png") no-repeat scroll 3px;
1806 1806 height:16px;
1807 1807 padding-left:20px;
1808 1808 padding-top:1px;
1809 1809 text-align:left;
1810 1810 }
1811 1811
1812 1812 .archive_icon {
1813 1813 background:url("../images/icons/compress.png") no-repeat scroll 3px;
1814 1814 height:16px;
1815 1815 padding-left:20px;
1816 1816 text-align:left;
1817 1817 padding-top:1px;
1818 1818 }
1819 1819
1820 1820 .action_button {
1821 1821 border:0;
1822 1822 display:block;
1823 1823 }
1824 1824
1825 1825 .action_button:hover {
1826 1826 border:0;
1827 1827 text-decoration:underline;
1828 1828 cursor:pointer;
1829 1829 }
1830 1830
1831 1831 #switch_repos {
1832 1832 position:absolute;
1833 1833 height:25px;
1834 1834 z-index:1;
1835 1835 }
1836 1836
1837 1837 #switch_repos select {
1838 1838 min-width:150px;
1839 1839 max-height:250px;
1840 1840 z-index:1;
1841 1841 }
1842 1842
1843 1843 .breadcrumbs {
1844 1844 border:medium none;
1845 1845 color:#FFF;
1846 1846 float:left;
1847 1847 text-transform:uppercase;
1848 1848 font-weight:700;
1849 1849 font-size:14px;
1850 1850 margin:0;
1851 1851 padding:11px 0 11px 10px;
1852 1852 }
1853 1853
1854 1854 .breadcrumbs a {
1855 1855 color:#FFF;
1856 1856 }
1857 1857
1858 1858 .flash_msg ul {
1859 1859 margin:0;
1860 1860 padding:0 0 10px;
1861 1861 }
1862 1862
1863 1863 .error_msg {
1864 1864 background-color:#FFCFCF;
1865 1865 background-image:url("../../images/icons/error_msg.png");
1866 1866 border:1px solid #FF9595;
1867 1867 color:#C30;
1868 1868 }
1869 1869
1870 1870 .warning_msg {
1871 1871 background-color:#FFFBCC;
1872 1872 background-image:url("../../images/icons/warning_msg.png");
1873 1873 border:1px solid #FFF35E;
1874 1874 color:#C69E00;
1875 1875 }
1876 1876
1877 1877 .success_msg {
1878 1878 background-color:#D5FFCF;
1879 1879 background-image:url("../../images/icons/success_msg.png");
1880 1880 border:1px solid #97FF88;
1881 1881 color:#090;
1882 1882 }
1883 1883
1884 1884 .notice_msg {
1885 1885 background-color:#DCE3FF;
1886 1886 background-image:url("../../images/icons/notice_msg.png");
1887 1887 border:1px solid #93A8FF;
1888 1888 color:#556CB5;
1889 1889 }
1890 1890
1891 1891 .success_msg,.error_msg,.notice_msg,.warning_msg {
1892 1892 background-position:10px center;
1893 1893 background-repeat:no-repeat;
1894 1894 font-size:12px;
1895 1895 font-weight:700;
1896 1896 min-height:14px;
1897 1897 line-height:14px;
1898 1898 margin-bottom:0;
1899 1899 margin-top:0;
1900 1900 display:block;
1901 1901 overflow:auto;
1902 1902 padding:6px 10px 6px 40px;
1903 1903 }
1904 1904
1905 1905 #msg_close {
1906 1906 background:transparent url("../../icons/cross_grey_small.png") no-repeat scroll 0 0;
1907 1907 cursor:pointer;
1908 1908 height:16px;
1909 1909 position:absolute;
1910 1910 right:5px;
1911 1911 top:5px;
1912 1912 width:16px;
1913 1913 }
1914 1914
1915 1915 div#legend_container table,div#legend_choices table {
1916 1916 width:auto !important;
1917 1917 }
1918 1918
1919 1919 table#permissions_manage {
1920 1920 width:0 !important;
1921 1921 }
1922 1922
1923 1923 table#permissions_manage span.private_repo_msg {
1924 1924 font-size:0.8em;
1925 1925 opacity:0.6px;
1926 1926 }
1927 1927
1928 1928 table#permissions_manage td.private_repo_msg {
1929 1929 font-size:0.8em;
1930 1930 }
1931 1931
1932 1932 table#permissions_manage tr#add_perm_input td {
1933 1933 vertical-align:middle;
1934 1934 }
1935 1935
1936 1936 div.gravatar {
1937 1937 background-color:#FFF;
1938 1938 border:1px solid #D0D0D0;
1939 1939 float:left;
1940 1940 margin-right:0.7em;
1941 1941 padding:2px 2px 0;
1942 1942 }
1943 1943
1944 1944 #header,#content,#footer {
1945 1945 min-width:1224px;
1946 1946 }
1947 1947
1948 1948 #content {
1949 1949 min-height:100%;
1950 1950 clear:both;
1951 1951 overflow:hidden;
1952 1952 padding:14px 30px;
1953 1953 }
1954 1954
1955 1955 #content div.box div.title div.search {
1956 1956 background:url("../../images/title_link.png") no-repeat top left;
1957 1957 border-left:1px solid #316293;
1958 1958 }
1959 1959
1960 1960 #content div.box div.title div.search div.input input {
1961 1961 border:1px solid #316293;
1962 1962 }
1963 1963
1964 1964 #content div.box div.title div.search div.button input.ui-state-default {
1965 1965 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
1966 1966 border:1px solid #316293;
1967 1967 border-left:none;
1968 1968 color:#FFF;
1969 1969 }
1970 1970
1971 1971 #content div.box div.title div.search div.button input.ui-state-hover {
1972 1972 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
1973 1973 border:1px solid #316293;
1974 1974 border-left:none;
1975 1975 color:#FFF;
1976 1976 }
1977 1977
1978 1978 #content div.box div.form div.fields div.field div.highlight .ui-state-default {
1979 1979 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
1980 1980 border-top:1px solid #5c91a4;
1981 1981 border-left:1px solid #2a6f89;
1982 1982 border-right:1px solid #2b7089;
1983 1983 border-bottom:1px solid #1a6480;
1984 1984 color:#fff;
1985 1985 }
1986 1986
1987 1987 #content div.box div.form div.fields div.field div.highlight .ui-state-hover {
1988 1988 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
1989 1989 border-top:1px solid #78acbf;
1990 1990 border-left:1px solid #34819e;
1991 1991 border-right:1px solid #35829f;
1992 1992 border-bottom:1px solid #257897;
1993 1993 color:#fff;
1994 1994 }
1995 1995
1996 1996 ins,div.options a:hover {
1997 1997 text-decoration:none;
1998 1998 }
1999 1999
2000 2000 img,#header #header-inner #quick li a:hover span.normal,#header #header-inner #quick li ul li.last,#content div.box div.form div.fields div.field div.textarea table td table td a,#clone_url {
2001 2001 border:none;
2002 2002 }
2003 2003
2004 2004 img.icon,.right .merge img {
2005 2005 vertical-align:bottom;
2006 2006 }
2007 2007
2008 2008 #header ul#logged-user,#content div.box div.title ul.links,#content div.box div.message div.dismiss,#content div.box div.traffic div.legend ul {
2009 2009 float:right;
2010 2010 margin:0;
2011 2011 padding:0;
2012 2012 }
2013 2013
2014 2014 #header #header-inner #home,#header #header-inner #logo,#content div.box ul.left,#content div.box ol.left,#content div.box div.pagination-left,div#commit_history,div#legend_data,div#legend_container,div#legend_choices {
2015 2015 float:left;
2016 2016 }
2017 2017
2018 2018 #header #header-inner #quick li:hover ul ul,#header #header-inner #quick li:hover ul ul ul,#header #header-inner #quick li:hover ul ul ul ul,#content #left #menu ul.closed,#content #left #menu li ul.collapsed,.yui-tt-shadow {
2019 2019 display:none;
2020 2020 }
2021 2021
2022 2022 #header #header-inner #quick li:hover ul,#header #header-inner #quick li li:hover ul,#header #header-inner #quick li li li:hover ul,#header #header-inner #quick li li li li:hover ul,#content #left #menu ul.opened,#content #left #menu li ul.expanded {
2023 2023 display:block;
2024 2024 }
2025 2025
2026 2026 #content div.box div.title ul.links li a:hover,#content div.box div.title ul.links li.ui-tabs-selected a {
2027 2027 background:url("../../images/title_tab_selected.png") no-repeat bottom center;
2028 2028 color:#bfe3ff;
2029 2029 }
2030 2030
2031 2031 #content div.box ol.lower-roman,#content div.box ol.upper-roman,#content div.box ol.lower-alpha,#content div.box ol.upper-alpha,#content div.box ol.decimal {
2032 2032 margin:10px 24px 10px 44px;
2033 2033 }
2034 2034
2035 2035 #content div.box div.form,#content div.box div.table,#content div.box div.traffic {
2036 2036 clear:both;
2037 2037 overflow:hidden;
2038 2038 margin:0;
2039 2039 padding:0 20px 10px;
2040 2040 }
2041 2041
2042 2042 #content div.box div.form div.fields,#login div.form,#login div.form div.fields,#register div.form,#register div.form div.fields {
2043 2043 clear:both;
2044 2044 overflow:hidden;
2045 2045 margin:0;
2046 2046 padding:0;
2047 2047 }
2048 2048
2049 2049 #content div.box div.form div.fields div.field div.label-checkbox,#content div.box div.form div.fields div.field div.label-radio,#content div.box div.form div.fields div.field div.label-textarea {
2050 2050 padding:0 0 0 5px !important;
2051 2051 }
2052 2052
2053 2053 #content div.box div.form div.fields div.field div.label span,#login div.form div.fields div.field div.label span,#register div.form div.fields div.field div.label span {
2054 2054 height:1%;
2055 2055 display:block;
2056 2056 color:#363636;
2057 2057 margin:0;
2058 2058 padding:2px 0 0;
2059 2059 }
2060 2060
2061 2061 #content div.box div.form div.fields div.field div.input input.error,#login div.form div.fields div.field div.input input.error,#register div.form div.fields div.field div.input input.error {
2062 2062 background:#FBE3E4;
2063 2063 border-top:1px solid #e1b2b3;
2064 2064 border-left:1px solid #e1b2b3;
2065 2065 border-right:1px solid #FBC2C4;
2066 2066 border-bottom:1px solid #FBC2C4;
2067 2067 }
2068 2068
2069 2069 #content div.box div.form div.fields div.field div.input input.success,#login div.form div.fields div.field div.input input.success,#register div.form div.fields div.field div.input input.success {
2070 2070 background:#E6EFC2;
2071 2071 border-top:1px solid #cebb98;
2072 2072 border-left:1px solid #cebb98;
2073 2073 border-right:1px solid #c6d880;
2074 2074 border-bottom:1px solid #c6d880;
2075 2075 }
2076 2076
2077 2077 #content div.box-left div.form div.fields div.field div.textarea,#content div.box-right div.form div.fields div.field div.textarea,#content div.box div.form div.fields div.field div.select select,#content div.box table th.selected input,#content div.box table td.selected input {
2078 2078 margin:0;
2079 2079 }
2080 2080
2081 2081 #content div.box div.form div.fields div.field div.select,#content div.box div.form div.fields div.field div.checkboxes,#content div.box div.form div.fields div.field div.radios {
2082 2082 margin:0 0 0 200px;
2083 2083 padding:0;
2084 2084 }
2085 2085
2086 2086 #content div.box div.form div.fields div.field div.select a:hover,#content div.box div.form div.fields div.field div.select a.ui-selectmenu:hover,#content div.box div.action a:hover {
2087 2087 color:#000;
2088 2088 text-decoration:none;
2089 2089 }
2090 2090
2091 2091 #content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus,#content div.box div.action a.ui-selectmenu-focus {
2092 2092 border:1px solid #666;
2093 2093 }
2094 2094
2095 2095 #content div.box div.form div.fields div.field div.checkboxes div.checkbox,#content div.box div.form div.fields div.field div.radios div.radio {
2096 2096 clear:both;
2097 2097 overflow:hidden;
2098 2098 margin:0;
2099 2099 padding:2px 0;
2100 2100 }
2101 2101
2102 2102 #content div.box div.form div.fields div.field div.checkboxes div.checkbox input,#content div.box div.form div.fields div.field div.radios div.radio input {
2103 2103 float:left;
2104 2104 margin:0;
2105 2105 }
2106 2106
2107 2107 #content div.box div.form div.fields div.field div.checkboxes div.checkbox label,#content div.box div.form div.fields div.field div.radios div.radio label {
2108 2108 height:1%;
2109 2109 display:block;
2110 2110 float:left;
2111 2111 margin:3px 0 0 4px;
2112 2112 }
2113 2113
2114 2114 div.form div.fields div.field div.button input,#content div.box div.form div.fields div.buttons input,div.form div.fields div.buttons input,#content div.box div.action div.button input {
2115 2115 color:#000;
2116 2116 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
2117 2117 font-size:11px;
2118 2118 font-weight:700;
2119 2119 margin:0;
2120 2120 }
2121 2121
2122 2122 div.form div.fields div.field div.button .ui-state-default,#content div.box div.form div.fields div.buttons input.ui-state-default {
2123 2123 background:#e5e3e3 url("../images/button.png") repeat-x;
2124 2124 border-top:1px solid #DDD;
2125 2125 border-left:1px solid #c6c6c6;
2126 2126 border-right:1px solid #DDD;
2127 2127 border-bottom:1px solid #c6c6c6;
2128 2128 color:#515151;
2129 2129 outline:none;
2130 2130 margin:0;
2131 2131 padding:6px 12px;
2132 2132 }
2133 2133
2134 2134 div.form div.fields div.field div.button .ui-state-hover,#content div.box div.form div.fields div.buttons input.ui-state-hover {
2135 2135 background:#b4b4b4 url("../images/button_selected.png") repeat-x;
2136 2136 border-top:1px solid #ccc;
2137 2137 border-left:1px solid #bebebe;
2138 2138 border-right:1px solid #b1b1b1;
2139 2139 border-bottom:1px solid #afafaf;
2140 2140 color:#515151;
2141 2141 outline:none;
2142 2142 margin:0;
2143 2143 padding:6px 12px;
2144 2144 }
2145 2145
2146 2146 div.form div.fields div.field div.highlight,#content div.box div.form div.fields div.buttons div.highlight {
2147 2147 display:inline;
2148 2148 }
2149 2149
2150 2150 #content div.box div.form div.fields div.buttons,div.form div.fields div.buttons {
2151 2151 margin:10px 0 0 200px;
2152 2152 padding:0;
2153 2153 }
2154 2154
2155 2155 #content div.box-left div.form div.fields div.buttons,#content div.box-right div.form div.fields div.buttons,div.box-left div.form div.fields div.buttons,div.box-right div.form div.fields div.buttons {
2156 2156 margin:10px 0 0;
2157 2157 }
2158 2158
2159 2159 #content div.box table td.user,#content div.box table td.address {
2160 2160 width:10%;
2161 2161 text-align:center;
2162 2162 }
2163 2163
2164 2164 #content div.box div.action div.button,#login div.form div.fields div.field div.input div.link,#register div.form div.fields div.field div.input div.link {
2165 2165 text-align:right;
2166 2166 margin:6px 0 0;
2167 2167 padding:0;
2168 2168 }
2169 2169
2170 2170 #content div.box div.action div.button input.ui-state-default,#login div.form div.fields div.buttons input.ui-state-default,#register div.form div.fields div.buttons input.ui-state-default {
2171 2171 background:#e5e3e3 url("../images/button.png") repeat-x;
2172 2172 border-top:1px solid #DDD;
2173 2173 border-left:1px solid #c6c6c6;
2174 2174 border-right:1px solid #DDD;
2175 2175 border-bottom:1px solid #c6c6c6;
2176 2176 color:#515151;
2177 2177 margin:0;
2178 2178 padding:6px 12px;
2179 2179 }
2180 2180
2181 2181 #content div.box div.action div.button input.ui-state-hover,#login div.form div.fields div.buttons input.ui-state-hover,#register div.form div.fields div.buttons input.ui-state-hover {
2182 2182 background:#b4b4b4 url("../images/button_selected.png") repeat-x;
2183 2183 border-top:1px solid #ccc;
2184 2184 border-left:1px solid #bebebe;
2185 2185 border-right:1px solid #b1b1b1;
2186 2186 border-bottom:1px solid #afafaf;
2187 2187 color:#515151;
2188 2188 margin:0;
2189 2189 padding:6px 12px;
2190 2190 }
2191 2191
2192 2192 #content div.box div.pagination div.results,#content div.box div.pagination-wh div.results {
2193 2193 text-align:left;
2194 2194 float:left;
2195 2195 margin:0;
2196 2196 padding:0;
2197 2197 }
2198 2198
2199 2199 #content div.box div.pagination div.results span,#content div.box div.pagination-wh div.results span {
2200 2200 height:1%;
2201 2201 display:block;
2202 2202 float:left;
2203 2203 background:#ebebeb url("../images/pager.png") repeat-x;
2204 2204 border-top:1px solid #dedede;
2205 2205 border-left:1px solid #cfcfcf;
2206 2206 border-right:1px solid #c4c4c4;
2207 2207 border-bottom:1px solid #c4c4c4;
2208 2208 color:#4A4A4A;
2209 2209 font-weight:700;
2210 2210 margin:0;
2211 2211 padding:6px 8px;
2212 2212 }
2213 2213
2214 2214 #content div.box div.pagination ul.pager li.disabled,#content div.box div.pagination-wh a.disabled {
2215 2215 color:#B4B4B4;
2216 2216 padding:6px;
2217 2217 }
2218 2218
2219 2219 #login,#register {
2220 2220 width:420px;
2221 2221 margin:10% auto 0;
2222 2222 padding:0;
2223 2223 }
2224 2224
2225 2225 #login div.color,#register div.color {
2226 2226 clear:both;
2227 2227 overflow:hidden;
2228 2228 background:#FFF;
2229 2229 margin:10px auto 0;
2230 2230 padding:3px 3px 3px 0;
2231 2231 }
2232 2232
2233 2233 #login div.color a,#register div.color a {
2234 2234 width:20px;
2235 2235 height:20px;
2236 2236 display:block;
2237 2237 float:left;
2238 2238 margin:0 0 0 3px;
2239 2239 padding:0;
2240 2240 }
2241 2241
2242 2242 #login div.title h5,#register div.title h5 {
2243 2243 color:#fff;
2244 2244 margin:10px;
2245 2245 padding:0;
2246 2246 }
2247 2247
2248 2248 #login div.form div.fields div.field,#register div.form div.fields div.field {
2249 2249 clear:both;
2250 2250 overflow:hidden;
2251 2251 margin:0;
2252 2252 padding:0 0 10px;
2253 2253 }
2254 2254
2255 2255 #login div.form div.fields div.field span.error-message,#register div.form div.fields div.field span.error-message {
2256 2256 height:1%;
2257 2257 display:block;
2258 2258 color:red;
2259 2259 margin:8px 0 0;
2260 2260 padding:0;
2261 2261 }
2262 2262
2263 2263 #login div.form div.fields div.field div.label label,#register div.form div.fields div.field div.label label {
2264 2264 color:#000;
2265 2265 font-weight:700;
2266 2266 }
2267 2267
2268 2268 #login div.form div.fields div.field div.input,#register div.form div.fields div.field div.input {
2269 2269 float:left;
2270 2270 margin:0;
2271 2271 padding:0;
2272 2272 }
2273 2273
2274 2274 #login div.form div.fields div.field div.checkbox,#register div.form div.fields div.field div.checkbox {
2275 2275 margin:0 0 0 184px;
2276 2276 padding:0;
2277 2277 }
2278 2278
2279 2279 #login div.form div.fields div.field div.checkbox label,#register div.form div.fields div.field div.checkbox label {
2280 2280 color:#565656;
2281 2281 font-weight:700;
2282 2282 }
2283 2283
2284 2284 #login div.form div.fields div.buttons input,#register div.form div.fields div.buttons input {
2285 2285 color:#000;
2286 2286 font-size:1em;
2287 2287 font-weight:700;
2288 2288 font-family:Verdana, Helvetica, Sans-Serif;
2289 2289 margin:0;
2290 2290 }
2291 2291
2292 2292 #changeset_content .container .wrapper,#graph_content .container .wrapper {
2293 2293 width:600px;
2294 2294 }
2295 2295
2296 2296 #changeset_content .container .left,#graph_content .container .left {
2297 2297 float:left;
2298 2298 width:70%;
2299 2299 padding-left:5px;
2300 2300 }
2301 2301
2302 2302 #changeset_content .container .left .date,.ac .match {
2303 2303 font-weight:700;
2304 2304 padding-top: 5px;
2305 2305 padding-bottom:5px;
2306 2306 }
2307 2307
2308 2308 div#legend_container table td,div#legend_choices table td {
2309 2309 border:none !important;
2310 2310 height:20px !important;
2311 2311 padding:0 !important;
2312 2312 } No newline at end of file
1 NO CONTENT: modified file, binary diff hidden
@@ -1,98 +1,107 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="base/base.html"/>
3 3 <%def name="title()">
4 4 ${_('Dashboard')} - ${c.rhodecode_name}
5 5 </%def>
6 6 <%def name="breadcrumbs()">
7 7 ${c.rhodecode_name}
8 8 </%def>
9 9 <%def name="page_nav()">
10 10 ${self.menu('home')}
11 11 </%def>
12 12 <%def name="main()">
13 13 <%def name="get_sort(name)">
14 14 <%name_slug = name.lower().replace(' ','_') %>
15 15
16 16 %if name_slug == c.sort_slug:
17 17 %if c.sort_by.startswith('-'):
18 18 <a href="?sort=${name_slug}">${name}&uarr;</a>
19 19 %else:
20 20 <a href="?sort=-${name_slug}">${name}&darr;</a>
21 21 %endif:
22 22 %else:
23 23 <a href="?sort=${name_slug}">${name}</a>
24 24 %endif
25 25 </%def>
26 26
27 27 <div class="box">
28 28 <!-- box / title -->
29 29 <div class="title">
30 30 <h5>${_('Dashboard')}</h5>
31 31 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
32 32 <ul class="links">
33 33 <li>
34 34 <span>${h.link_to(_('ADD NEW REPOSITORY'),h.url('admin_settings_create_repository'))}</span>
35 35 </li>
36 36 </ul>
37 37 %endif
38 38 </div>
39 39 <!-- end box / title -->
40 40 <div class="table">
41 41 <table>
42 42 <thead>
43 43 <tr>
44 44 <th class="left">${get_sort(_('Name'))}</th>
45 45 <th class="left">${get_sort(_('Description'))}</th>
46 46 <th class="left">${get_sort(_('Last change'))}</th>
47 47 <th class="left">${get_sort(_('Tip'))}</th>
48 48 <th class="left">${get_sort(_('Owner'))}</th>
49 49 <th class="left">${_('RSS')}</th>
50 50 <th class="left">${_('Atom')}</th>
51 51 </tr>
52 52 </thead>
53 53 <tbody>
54 54 %for cnt,repo in enumerate(c.repos_list):
55 55 %if h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(repo['name'],'main page check'):
56 56 <tr class="parity${cnt%2}">
57 57 <td>
58 %if repo['repo'].dbrepo.repo_type =='hg':
59 <img class="icon" alt="${_('Mercurial repository')}" src="/images/icons/hgicon.png"/>
60 %elif repo['repo'].dbrepo.repo_type =='git':
61 <img class="icon" alt="${_('Git repository')}" src="/images/icons/giticon.png"/>
62 %else:
63
64 %endif
65
58 66 %if repo['repo'].dbrepo.private:
59 67 <img class="icon" alt="${_('private')}" src="/images/icons/lock.png"/>
60 68 %else:
61 69 <img class="icon" alt="${_('public')}" src="/images/icons/lock_open.png"/>
62 70 %endif
63 71 ${h.link_to(repo['name'],
64 72 h.url('summary_home',repo_name=repo['name']))}
65 73 %if repo['repo'].dbrepo.fork:
66 74 <a href="${h.url('summary_home',repo_name=repo['repo'].dbrepo.fork.repo_name)}">
67 75 <img class="icon" alt="${_('public')}"
68 76 title="${_('Fork of')} ${repo['repo'].dbrepo.fork.repo_name}"
69 77 src="/images/icons/arrow_divide.png"/></a>
70 78 %endif
71 79 </td>
72 80 <td title="${repo['description']}">${h.truncate(repo['description'],60)}</td>
73 <td>${h.age(repo['last_change'])}</td>
81 <td><span class="tooltip" tooltip_title="${repo['last_change']}">
82 ${h.age(repo['last_change'])} </span></td>
74 83 <td>
75 84 %if repo['rev']>=0:
76 85 ${h.link_to('r%s:%s' % (repo['rev'],repo['tip']),
77 86 h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']),
78 87 class_="tooltip",
79 88 tooltip_title=h.tooltip(repo['last_msg']))}
80 89 %else:
81 90 ${_('No changesets yet')}
82 91 %endif
83 92 </td>
84 93 <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
85 94 <td>
86 95 <a title="${_('Subscribe to %s rss feed')%repo['name']}" class="rss_icon" href="${h.url('rss_feed_home',repo_name=repo['name'])}"></a>
87 96 </td>
88 97 <td>
89 98 <a title="${_('Subscribe to %s atom feed')%repo['name']}" class="atom_icon" href="${h.url('atom_feed_home',repo_name=repo['name'])}"></a>
90 99 </td>
91 100 </tr>
92 101 %endif
93 102 %endfor
94 103 </tbody>
95 104 </table>
96 105 </div>
97 106 </div>
98 107 </%def>
@@ -1,63 +1,63 b''
1 1 ## -*- coding: utf-8 -*-
2 2 % if c.repo_changesets:
3 3 <table>
4 4 <tr>
5 5 <th class="left">${_('date')}</th>
6 6 <th class="left">${_('author')}</th>
7 7 <th class="left">${_('revision')}</th>
8 8 <th class="left">${_('commit message')}</th>
9 9 <th class="left">${_('branch')}</th>
10 10 <th class="left">${_('tags')}</th>
11 11 <th class="left">${_('links')}</th>
12 12
13 13 </tr>
14 14 %for cnt,cs in enumerate(c.repo_changesets):
15 15 <tr class="parity${cnt%2}">
16 <td>${h.age(cs.date)} - ${h.rfc822date_notz(cs.date)} </td>
16 <td>${h.age(cs.date)} - ${cs.date} </td>
17 17 <td title="${cs.author}">${h.person(cs.author)}</td>
18 18 <td>r${cs.revision}:${cs.short_id}</td>
19 19 <td>
20 20 ${h.link_to(h.truncate(cs.message,60),
21 21 h.url('changeset_home',repo_name=c.repo_name,revision=cs.short_id),
22 22 title=cs.message)}
23 23 </td>
24 24 <td>
25 25 <span class="logtags">
26 26 <span class="branchtag">${cs.branch}</span>
27 27 </span>
28 28 </td>
29 29 <td>
30 30 <span class="logtags">
31 31 %for tag in cs.tags:
32 32 <span class="tagtag">${tag}</span>
33 33 %endfor
34 34 </span>
35 35 </td>
36 36 <td class="nowrap">
37 37 ${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=cs.short_id))}
38 38 |
39 39 ${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=cs.short_id))}
40 40 </td>
41 41 </tr>
42 42 %endfor
43 43
44 44 </table>
45 45
46 46 <script type="text/javascript">
47 47 var data_div = 'shortlog_data';
48 48 YAHOO.util.Event.onDOMReady(function(){
49 49 YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
50 50 YAHOO.util.Dom.setStyle('shortlog_data','opacity','0.3');});});
51 51 </script>
52 52
53 53 <div class="pagination-wh pagination-left">
54 54 ${c.repo_changesets.pager('$link_previous ~2~ $link_next',
55 55 onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{
56 56 success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText;
57 57 YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
58 58 YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');});
59 59 YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")}
60 60 </div>
61 61 %else:
62 62 ${_('There are no changes yet')}
63 63 %endif
@@ -1,584 +1,584 b''
1 1 <%inherit file="/base/base.html"/>
2 2
3 3 <%def name="title()">
4 4 ${c.repo_name} ${_('Summary')} - ${c.rhodecode_name}
5 5 </%def>
6 6
7 7 <%def name="breadcrumbs_links()">
8 8 ${h.link_to(u'Home',h.url('/'))}
9 9 &raquo;
10 10 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
11 11 &raquo;
12 12 ${_('summary')}
13 13 </%def>
14 14
15 15 <%def name="page_nav()">
16 16 ${self.menu('summary')}
17 17 </%def>
18 18
19 19 <%def name="main()">
20 20 <script type="text/javascript">
21 21 var E = YAHOO.util.Event;
22 22 var D = YAHOO.util.Dom;
23 23
24 24 E.onDOMReady(function(e){
25 25 id = 'clone_url';
26 26 E.addListener(id,'click',function(e){
27 27 D.get('clone_url').select();
28 28 })
29 29 })
30 30 </script>
31 31 <div class="box box-left">
32 32 <!-- box / title -->
33 33 <div class="title">
34 34 ${self.breadcrumbs()}
35 35 </div>
36 36 <!-- end box / title -->
37 37 <div class="form">
38 38 <div class="fields">
39 39
40 40 <div class="field">
41 41 <div class="label">
42 42 <label>${_('Name')}:</label>
43 43 </div>
44 44 <div class="input-short">
45 45 %if c.repo_info.dbrepo.private:
46 46 <img style="margin-bottom:2px" class="icon" title="${_('private repository')}" alt="${_('private')}" src="/images/icons/lock.png"/>
47 47 %else:
48 48 <img style="margin-bottom:2px" class="icon" title="${_('public repository')}" alt="${_('public')}" src="/images/icons/lock_open.png"/>
49 49 %endif
50 50 <span style="font-size: 1.6em;font-weight: bold;vertical-align: baseline;">${c.repo_info.name}</span>
51 51 <br/>
52 52 %if c.repo_info.dbrepo.fork:
53 53 <span style="margin-top:5px">
54 54 <a href="${h.url('summary_home',repo_name=c.repo_info.dbrepo.fork.repo_name)}">
55 55 <img class="icon" alt="${_('public')}"
56 56 title="${_('Fork of')} ${c.repo_info.dbrepo.fork.repo_name}"
57 57 src="/images/icons/arrow_divide.png"/>
58 58 ${_('Fork of')} ${c.repo_info.dbrepo.fork.repo_name}
59 59 </a>
60 60 </span>
61 61 %endif
62 62 </div>
63 63 </div>
64 64
65 65
66 66 <div class="field">
67 67 <div class="label">
68 68 <label>${_('Description')}:</label>
69 69 </div>
70 70 <div class="input-short">
71 71 ${c.repo_info.description}
72 72 </div>
73 73 </div>
74 74
75 75
76 76 <div class="field">
77 77 <div class="label">
78 78 <label>${_('Contact')}:</label>
79 79 </div>
80 80 <div class="input-short">
81 81 <div class="gravatar">
82 82 <img alt="gravatar" src="${h.gravatar_url(c.repo_info.dbrepo.user.email)}"/>
83 83 </div>
84 84 ${_('Username')}: ${c.repo_info.dbrepo.user.username}<br/>
85 85 ${_('Name')}: ${c.repo_info.dbrepo.user.name} ${c.repo_info.dbrepo.user.lastname}<br/>
86 86 ${_('Email')}: <a href="mailto:${c.repo_info.dbrepo.user.email}">${c.repo_info.dbrepo.user.email}</a>
87 87 </div>
88 88 </div>
89 89
90 90 <div class="field">
91 91 <div class="label">
92 92 <label>${_('Last change')}:</label>
93 93 </div>
94 94 <div class="input-short">
95 ${h.age(c.repo_info.last_change)} - ${h.rfc822date_notz(c.repo_info.last_change)}
95 ${h.age(c.repo_info.last_change)} - ${c.repo_info.last_change}
96 96 ${_('by')} ${h.get_changeset_safe(c.repo_info,'tip').author}
97 97
98 98 </div>
99 99 </div>
100 100
101 101 <div class="field">
102 102 <div class="label">
103 103 <label>${_('Clone url')}:</label>
104 104 </div>
105 105 <div class="input-short">
106 106 <input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/>
107 107 </div>
108 108 </div>
109 109
110 110 <div class="field">
111 111 <div class="label">
112 112 <label>${_('Trending languages')}:</label>
113 113 </div>
114 114 <div class="input-short">
115 115 <div id="lang_stats">
116 116
117 117 </div>
118 118 <script type="text/javascript">
119 119 var data = ${c.trending_languages|n};
120 120 var total = 0;
121 121 var no_data = true;
122 122 for (k in data){
123 123 total += data[k];
124 124 no_data = false;
125 125 }
126 126 var tbl = document.createElement('table');
127 127 tbl.setAttribute('class','trending_language_tbl');
128 128 for (k in data){
129 129 var tr = document.createElement('tr');
130 130 var percentage = Math.round((data[k]/total*100),2);
131 131 var value = data[k];
132 132 var td1 = document.createElement('td');
133 133 td1.width=150;
134 134 var trending_language_label = document.createElement('div');
135 135 trending_language_label.innerHTML = k;
136 136 td1.appendChild(trending_language_label);
137 137
138 138 var td2 = document.createElement('td');
139 139 var trending_language = document.createElement('div');
140 140 trending_language.title = k;
141 141 trending_language.innerHTML = "<b>"+percentage+"% "+value+" ${_('files')}</b>";
142 142 trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
143 143 trending_language.style.width=percentage+"%";
144 144 td2.appendChild(trending_language);
145 145
146 146 tr.appendChild(td1);
147 147 tr.appendChild(td2);
148 148 tbl.appendChild(tr);
149 149
150 150 }
151 151 if(no_data){
152 152 var tr = document.createElement('tr');
153 153 var td1 = document.createElement('td');
154 154 td1.innerHTML = "${_('No data loaded yet')}";
155 155 tr.appendChild(td1);
156 156 tbl.appendChild(tr);
157 157 }
158 158 YAHOO.util.Dom.get('lang_stats').appendChild(tbl);
159 159 </script>
160 160
161 161 </div>
162 162 </div>
163 163
164 164 <div class="field">
165 165 <div class="label">
166 166 <label>${_('Download')}:</label>
167 167 </div>
168 168 <div class="input-short">
169 169 %for cnt,archive in enumerate(c.repo_info._get_archives()):
170 170 %if cnt >=1:
171 171 |
172 172 %endif
173 173 ${h.link_to(c.repo_info.name+'.'+archive['type'],
174 174 h.url('files_archive_home',repo_name=c.repo_info.name,
175 175 revision='tip',fileformat=archive['extension']),class_="archive_icon")}
176 176 %endfor
177 177 </div>
178 178 </div>
179 179
180 180 <div class="field">
181 181 <div class="label">
182 182 <label>${_('Feeds')}:</label>
183 183 </div>
184 184 <div class="input-short">
185 185 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_icon')}
186 186 ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_icon')}
187 187 </div>
188 188 </div>
189 189 </div>
190 190 </div>
191 191 </div>
192 192
193 193 <div class="box box-right" style="min-height:455px">
194 194 <!-- box / title -->
195 195 <div class="title">
196 196 <h5>${_('Commit activity by day / author')}</h5>
197 197 </div>
198 198
199 199 <div class="table">
200 200 <div id="commit_history" style="width:560px;height:300px;float:left"></div>
201 201 <div style="clear: both;height: 10px"></div>
202 202 <div id="overview" style="width:560px;height:100px;float:left"></div>
203 203
204 204 <div id="legend_data" style="clear:both;margin-top:10px;">
205 205 <div id="legend_container"></div>
206 206 <div id="legend_choices">
207 207 <table id="legend_choices_tables" style="font-size:smaller;color:#545454"></table>
208 208 </div>
209 209 </div>
210 210 <script type="text/javascript">
211 211 /**
212 212 * Plots summary graph
213 213 *
214 214 * @class SummaryPlot
215 215 * @param {from} initial from for detailed graph
216 216 * @param {to} initial to for detailed graph
217 217 * @param {dataset}
218 218 * @param {overview_dataset}
219 219 */
220 220 function SummaryPlot(from,to,dataset,overview_dataset) {
221 221 var initial_ranges = {
222 222 "xaxis":{
223 223 "from":from,
224 224 "to":to,
225 225 },
226 226 };
227 227 var dataset = dataset;
228 228 var overview_dataset = [overview_dataset];
229 229 var choiceContainer = YAHOO.util.Dom.get("legend_choices");
230 230 var choiceContainerTable = YAHOO.util.Dom.get("legend_choices_tables");
231 231 var plotContainer = YAHOO.util.Dom.get('commit_history');
232 232 var overviewContainer = YAHOO.util.Dom.get('overview');
233 233
234 234 var plot_options = {
235 235 bars: {show:true,align:'center',lineWidth:4},
236 236 legend: {show:true, container:"legend_container"},
237 237 points: {show:true,radius:0,fill:false},
238 238 yaxis: {tickDecimals:0,},
239 239 xaxis: {
240 240 mode: "time",
241 241 timeformat: "%d/%m",
242 242 min:from,
243 243 max:to,
244 244 },
245 245 grid: {
246 246 hoverable: true,
247 247 clickable: true,
248 248 autoHighlight:true,
249 249 color: "#999"
250 250 },
251 251 //selection: {mode: "x"}
252 252 };
253 253 var overview_options = {
254 254 legend:{show:false},
255 255 bars: {show:true,barWidth: 2,},
256 256 shadowSize: 0,
257 257 xaxis: {mode: "time", timeformat: "%d/%m/%y",},
258 258 yaxis: {ticks: 3, min: 0,},
259 259 grid: {color: "#999",},
260 260 selection: {mode: "x"}
261 261 };
262 262
263 263 /**
264 264 *get dummy data needed in few places
265 265 */
266 266 function getDummyData(label){
267 267 return {"label":label,
268 268 "data":[{"time":0,
269 269 "commits":0,
270 270 "added":0,
271 271 "changed":0,
272 272 "removed":0,
273 273 }],
274 274 "schema":["commits"],
275 275 "color":'#ffffff',
276 276 }
277 277 }
278 278
279 279 /**
280 280 * generate checkboxes accordindly to data
281 281 * @param keys
282 282 * @returns
283 283 */
284 284 function generateCheckboxes(data) {
285 285 //append checkboxes
286 286 var i = 0;
287 287 choiceContainerTable.innerHTML = '';
288 288 for(var pos in data) {
289 289
290 290 data[pos].color = i;
291 291 i++;
292 292 if(data[pos].label != ''){
293 293 choiceContainerTable.innerHTML += '<tr><td>'+
294 294 '<input type="checkbox" name="' + data[pos].label +'" checked="checked" />'
295 295 +data[pos].label+
296 296 '</td></tr>';
297 297 }
298 298 }
299 299 }
300 300
301 301 /**
302 302 * ToolTip show
303 303 */
304 304 function showTooltip(x, y, contents) {
305 305 var div=document.getElementById('tooltip');
306 306 if(!div) {
307 307 div = document.createElement('div');
308 308 div.id="tooltip";
309 309 div.style.position="absolute";
310 310 div.style.border='1px solid #fdd';
311 311 div.style.padding='2px';
312 312 div.style.backgroundColor='#fee';
313 313 document.body.appendChild(div);
314 314 }
315 315 YAHOO.util.Dom.setStyle(div, 'opacity', 0);
316 316 div.innerHTML = contents;
317 317 div.style.top=(y + 5) + "px";
318 318 div.style.left=(x + 5) + "px";
319 319
320 320 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
321 321 anim.animate();
322 322 }
323 323
324 324 /**
325 325 * This function will detect if selected period has some changesets for this user
326 326 if it does this data is then pushed for displaying
327 327 Additionally it will only display users that are selected by the checkbox
328 328 */
329 329 function getDataAccordingToRanges(ranges) {
330 330
331 331 var data = [];
332 332 var keys = [];
333 333 for(var key in dataset){
334 334 var push = false;
335 335 //method1 slow !!
336 336 ///*
337 337 for(var ds in dataset[key].data){
338 338 commit_data = dataset[key].data[ds];
339 339 //console.log(key);
340 340 //console.log(new Date(commit_data.time*1000));
341 341 //console.log(new Date(ranges.xaxis.from*1000));
342 342 //console.log(new Date(ranges.xaxis.to*1000));
343 343 if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){
344 344 push = true;
345 345 break;
346 346 }
347 347 }
348 348 //*/
349 349 /*//method2 sorted commit data !!!
350 350 var first_commit = dataset[key].data[0].time;
351 351 var last_commit = dataset[key].data[dataset[key].data.length-1].time;
352 352
353 353 console.log(first_commit);
354 354 console.log(last_commit);
355 355
356 356 if (first_commit >= ranges.xaxis.from && last_commit <= ranges.xaxis.to){
357 357 push = true;
358 358 }
359 359 */
360 360 if(push){
361 361 data.push(dataset[key]);
362 362 }
363 363 }
364 364 if(data.length >= 1){
365 365 return data;
366 366 }
367 367 else{
368 368 //just return dummy data for graph to plot itself
369 369 return [getDummyData('')];
370 370 }
371 371
372 372 }
373 373
374 374 /**
375 375 * redraw using new checkbox data
376 376 */
377 377 function plotchoiced(e,args){
378 378 var cur_data = args[0];
379 379 var cur_ranges = args[1];
380 380
381 381 var new_data = [];
382 382 var inputs = choiceContainer.getElementsByTagName("input");
383 383
384 384 //show only checked labels
385 385 for(var i=0; i<inputs.length; i++) {
386 386 var checkbox_key = inputs[i].name;
387 387
388 388 if(inputs[i].checked){
389 389 for(var d in cur_data){
390 390 if(cur_data[d].label == checkbox_key){
391 391 new_data.push(cur_data[d]);
392 392 }
393 393 }
394 394 }
395 395 else{
396 396 //push dummy data to not hide the label
397 397 new_data.push(getDummyData(checkbox_key));
398 398 }
399 399 }
400 400
401 401 var new_options = YAHOO.lang.merge(plot_options, {
402 402 xaxis: {
403 403 min: cur_ranges.xaxis.from,
404 404 max: cur_ranges.xaxis.to,
405 405 mode:"time",
406 406 timeformat: "%d/%m",
407 407 }
408 408 });
409 409 if (!new_data){
410 410 new_data = [[0,1]];
411 411 }
412 412 // do the zooming
413 413 plot = YAHOO.widget.Flot(plotContainer, new_data, new_options);
414 414
415 415 plot.subscribe("plotselected", plotselected);
416 416
417 417 //resubscribe plothover
418 418 plot.subscribe("plothover", plothover);
419 419
420 420 // don't fire event on the overview to prevent eternal loop
421 421 overview.setSelection(cur_ranges, true);
422 422
423 423 }
424 424
425 425 /**
426 426 * plot only selected items from overview
427 427 * @param ranges
428 428 * @returns
429 429 */
430 430 function plotselected(ranges,cur_data) {
431 431 //updates the data for new plot
432 432 data = getDataAccordingToRanges(ranges);
433 433 generateCheckboxes(data);
434 434
435 435 var new_options = YAHOO.lang.merge(plot_options, {
436 436 xaxis: {
437 437 min: ranges.xaxis.from,
438 438 max: ranges.xaxis.to,
439 439 mode:"time",
440 440 timeformat: "%d/%m",
441 441 }
442 442 });
443 443 // do the zooming
444 444 plot = YAHOO.widget.Flot(plotContainer, data, new_options);
445 445
446 446 plot.subscribe("plotselected", plotselected);
447 447
448 448 //resubscribe plothover
449 449 plot.subscribe("plothover", plothover);
450 450
451 451 // don't fire event on the overview to prevent eternal loop
452 452 overview.setSelection(ranges, true);
453 453
454 454 //resubscribe choiced
455 455 YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]);
456 456 }
457 457
458 458 var previousPoint = null;
459 459
460 460 function plothover(o) {
461 461 var pos = o.pos;
462 462 var item = o.item;
463 463
464 464 //YAHOO.util.Dom.get("x").innerHTML = pos.x.toFixed(2);
465 465 //YAHOO.util.Dom.get("y").innerHTML = pos.y.toFixed(2);
466 466 if (item) {
467 467 if (previousPoint != item.datapoint) {
468 468 previousPoint = item.datapoint;
469 469
470 470 var tooltip = YAHOO.util.Dom.get("tooltip");
471 471 if(tooltip) {
472 472 tooltip.parentNode.removeChild(tooltip);
473 473 }
474 474 var x = item.datapoint.x.toFixed(2);
475 475 var y = item.datapoint.y.toFixed(2);
476 476
477 477 if (!item.series.label){
478 478 item.series.label = 'commits';
479 479 }
480 480 var d = new Date(x*1000);
481 481 var fd = d.toDateString()
482 482 var nr_commits = parseInt(y);
483 483
484 484 var cur_data = dataset[item.series.label].data[item.dataIndex];
485 485 var added = cur_data.added;
486 486 var changed = cur_data.changed;
487 487 var removed = cur_data.removed;
488 488
489 489 var nr_commits_suffix = " ${_('commits')} ";
490 490 var added_suffix = " ${_('files added')} ";
491 491 var changed_suffix = " ${_('files changed')} ";
492 492 var removed_suffix = " ${_('files removed')} ";
493 493
494 494
495 495 if(nr_commits == 1){nr_commits_suffix = " ${_('commit')} ";}
496 496 if(added==1){added_suffix=" ${_('file added')} ";}
497 497 if(changed==1){changed_suffix=" ${_('file changed')} ";}
498 498 if(removed==1){removed_suffix=" ${_('file removed')} ";}
499 499
500 500 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd
501 501 +'<br/>'+
502 502 nr_commits + nr_commits_suffix+'<br/>'+
503 503 added + added_suffix +'<br/>'+
504 504 changed + changed_suffix + '<br/>'+
505 505 removed + removed_suffix + '<br/>');
506 506 }
507 507 }
508 508 else {
509 509 var tooltip = YAHOO.util.Dom.get("tooltip");
510 510
511 511 if(tooltip) {
512 512 tooltip.parentNode.removeChild(tooltip);
513 513 }
514 514 previousPoint = null;
515 515 }
516 516 }
517 517
518 518 /**
519 519 * MAIN EXECUTION
520 520 */
521 521
522 522 var data = getDataAccordingToRanges(initial_ranges);
523 523 generateCheckboxes(data);
524 524
525 525 //main plot
526 526 var plot = YAHOO.widget.Flot(plotContainer,data,plot_options);
527 527
528 528 //overview
529 529 var overview = YAHOO.widget.Flot(overviewContainer, overview_dataset, overview_options);
530 530
531 531 //show initial selection on overview
532 532 overview.setSelection(initial_ranges);
533 533
534 534 plot.subscribe("plotselected", plotselected);
535 535
536 536 overview.subscribe("plotselected", function (ranges) {
537 537 plot.setSelection(ranges);
538 538 });
539 539
540 540 plot.subscribe("plothover", plothover);
541 541
542 542 YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]);
543 543 }
544 544 SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n});
545 545 </script>
546 546
547 547 </div>
548 548 </div>
549 549
550 550 <div class="box">
551 551 <div class="title">
552 552 <div class="breadcrumbs">${h.link_to(_('Last ten changes'),h.url('changelog_home',repo_name=c.repo_name))}</div>
553 553 </div>
554 554 <div class="table">
555 555 <%include file='../shortlog/shortlog_data.html'/>
556 556 %if c.repo_changesets:
557 557 ${h.link_to(_('show more'),h.url('changelog_home',repo_name=c.repo_name))}
558 558 %endif
559 559 </div>
560 560 </div>
561 561 <div class="box">
562 562 <div class="title">
563 563 <div class="breadcrumbs">${h.link_to(_('Last ten tags'),h.url('tags_home',repo_name=c.repo_name))}</div>
564 564 </div>
565 565 <div class="table">
566 566 <%include file='../tags/tags_data.html'/>
567 567 %if c.repo_changesets:
568 568 ${h.link_to(_('show more'),h.url('tags_home',repo_name=c.repo_name))}
569 569 %endif
570 570 </div>
571 571 </div>
572 572 <div class="box">
573 573 <div class="title">
574 574 <div class="breadcrumbs">${h.link_to(_('Last ten branches'),h.url('branches_home',repo_name=c.repo_name))}</div>
575 575 </div>
576 576 <div class="table">
577 577 <%include file='../branches/branches_data.html'/>
578 578 %if c.repo_changesets:
579 579 ${h.link_to(_('show more'),h.url('branches_home',repo_name=c.repo_name))}
580 580 %endif
581 581 </div>
582 582 </div>
583 583
584 584 </%def> No newline at end of file
@@ -1,88 +1,88 b''
1 1 from rhodecode import get_version
2 2 import sys
3 3 py_version = sys.version_info
4 4
5 5 requirements = [
6 6 "Pylons>=1.0.0",
7 "SQLAlchemy>=0.6",
8 "Mako>=0.3.2",
9 "vcs==0.1.8",
7 "SQLAlchemy>=0.6.4",
8 "Mako>=0.3.5",
9 "vcs==0.1.10",
10 10 "pygments>=1.3.0",
11 "mercurial>=1.6",
12 "whoosh==1.0.0",
13 "celery>=2.0.0",
11 "mercurial==1.6.4",
12 "whoosh==1.1.0",
13 "celery==2.1.1",
14 14 "py-bcrypt",
15 15 "babel",
16 16 ]
17 17
18 18 classifiers = ['Development Status :: 4 - Beta',
19 19 'Environment :: Web Environment',
20 20 'Framework :: Pylons',
21 21 'Intended Audience :: Developers',
22 22 'License :: OSI Approved :: BSD License',
23 23 'Operating System :: OS Independent',
24 24 'Programming Language :: Python', ]
25 25
26 26 if sys.version_info < (2, 6):
27 27 requirements.append("simplejson")
28 28 requirements.append("pysqlite")
29 29
30 30 #additional files from project that goes somewhere in the filesystem
31 31 #relative to sys.prefix
32 32 data_files = []
33 33
34 34 #additional files that goes into package itself
35 35 package_data = {'rhodecode': ['i18n/*/LC_MESSAGES/*.mo', ], }
36 36
37 37 description = 'Mercurial repository serving and browsing app'
38 38 #long description
39 39 try:
40 40 readme_file = 'README.rst'
41 41 long_description = open(readme_file).read()
42 42 except IOError, err:
43 43 sys.stderr.write("[WARNING] Cannot find file specified as "
44 44 "long_description (%s)\n skipping that file" % readme_file)
45 45 long_description = description
46 46
47 47
48 48 try:
49 49 from setuptools import setup, find_packages
50 50 except ImportError:
51 51 from ez_setup import use_setuptools
52 52 use_setuptools()
53 53 from setuptools import setup, find_packages
54 54 #packages
55 55 packages = find_packages(exclude=['ez_setup'])
56 56
57 57 setup(
58 58 name='RhodeCode',
59 59 version=get_version(),
60 60 description=description,
61 61 long_description=long_description,
62 62 keywords='rhodiumcode mercurial web hgwebdir replacement serving hgweb rhodecode',
63 63 license='BSD',
64 64 author='Marcin Kuzminski',
65 65 author_email='marcin@python-works.com',
66 66 url='http://hg.python-works.com',
67 67 install_requires=requirements,
68 68 classifiers=classifiers,
69 69 setup_requires=["PasteScript>=1.6.3"],
70 70 data_files=data_files,
71 71 packages=packages,
72 72 include_package_data=True,
73 73 test_suite='nose.collector',
74 74 package_data=package_data,
75 75 message_extractors={'rhodecode': [
76 76 ('**.py', 'python', None),
77 77 ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
78 78 ('public/**', 'ignore', None)]},
79 79 zip_safe=False,
80 80 paster_plugins=['PasteScript', 'Pylons'],
81 81 entry_points="""
82 82 [paste.app_factory]
83 83 main = rhodecode.config.middleware:make_app
84 84
85 85 [paste.app_install]
86 86 main = pylons.util:PylonsInstaller
87 87 """,
88 88 )
General Comments 0
You need to be logged in to leave comments. Login now