##// END OF EJS Templates
merged found bugs and fixed for stable release:...
marcink -
r921:136af52f default
parent child Browse files
Show More
@@ -1,215 +1,216 b''
1 1 ################################################################################
2 2 ################################################################################
3 3 # RhodeCode - Pylons environment configuration #
4 4 # #
5 5 # The %(here)s variable will be replaced with the parent directory of this file#
6 6 ################################################################################
7 7
8 8 [DEFAULT]
9 9 debug = true
10 10 ################################################################################
11 11 ## Uncomment and replace with the address which should receive ##
12 12 ## any error reports after application crash ##
13 13 ## Additionally those settings will be used by RhodeCode mailing system ##
14 14 ################################################################################
15 15 #email_to = admin@localhost
16 16 #error_email_from = paste_error@localhost
17 17 #app_email_from = rhodecode-noreply@localhost
18 18 #error_message =
19 19
20 20 #smtp_server = mail.server.com
21 21 #smtp_username =
22 22 #smtp_password =
23 23 #smtp_port =
24 24 #smtp_use_tls = false
25 25 #smtp_use_ssl = true
26 26
27 27 [server:main]
28 28 ##nr of threads to spawn
29 29 threadpool_workers = 5
30 30
31 31 ##max request before thread respawn
32 32 threadpool_max_requests = 6
33 33
34 34 ##option to use threads of process
35 35 use_threadpool = false
36 36
37 37 use = egg:Paste#http
38 38 host = 0.0.0.0
39 39 port = 5000
40 40
41 41 [app:main]
42 42 use = egg:rhodecode
43 43 full_stack = true
44 44 static_files = true
45 45 lang=en
46 46 cache_dir = %(here)s/data
47 47 index_dir = %(here)s/data/index
48 48 cut_off_limit = 256000
49 force_https = false
49 50
50 51 ####################################
51 52 ### CELERY CONFIG ####
52 53 ####################################
53 54 use_celery = false
54 55 broker.host = localhost
55 56 broker.vhost = rabbitmqhost
56 57 broker.port = 5672
57 58 broker.user = rabbitmq
58 59 broker.password = qweqwe
59 60
60 61 celery.imports = rhodecode.lib.celerylib.tasks
61 62
62 63 celery.result.backend = amqp
63 64 celery.result.dburi = amqp://
64 65 celery.result.serialier = json
65 66
66 67 #celery.send.task.error.emails = true
67 68 #celery.amqp.task.result.expires = 18000
68 69
69 70 celeryd.concurrency = 2
70 71 #celeryd.log.file = celeryd.log
71 72 celeryd.log.level = debug
72 73 celeryd.max.tasks.per.child = 3
73 74
74 75 #tasks will never be sent to the queue, but executed locally instead.
75 76 celery.always.eager = false
76 77
77 78 ####################################
78 79 ### BEAKER CACHE ####
79 80 ####################################
80 81 beaker.cache.data_dir=/%(here)s/data/cache/data
81 82 beaker.cache.lock_dir=/%(here)s/data/cache/lock
82 83 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
83 84
84 85 beaker.cache.super_short_term.type=memory
85 86 beaker.cache.super_short_term.expire=10
86 87
87 88 beaker.cache.short_term.type=memory
88 89 beaker.cache.short_term.expire=60
89 90
90 91 beaker.cache.long_term.type=memory
91 92 beaker.cache.long_term.expire=36000
92 93
93 94 beaker.cache.sql_cache_short.type=memory
94 95 beaker.cache.sql_cache_short.expire=10
95 96
96 97 beaker.cache.sql_cache_med.type=memory
97 98 beaker.cache.sql_cache_med.expire=360
98 99
99 100 beaker.cache.sql_cache_long.type=file
100 101 beaker.cache.sql_cache_long.expire=3600
101 102
102 103 ####################################
103 104 ### BEAKER SESSION ####
104 105 ####################################
105 106 ## Type of storage used for the session, current types are
106 107 ## dbm, file, memcached, database, and memory.
107 108 ## The storage uses the Container API
108 109 ##that is also used by the cache system.
109 110 beaker.session.type = file
110 111
111 112 beaker.session.key = rhodecode
112 113 beaker.session.secret = g654dcno0-9873jhgfreyu
113 114 beaker.session.timeout = 36000
114 115
115 116 ##auto save the session to not to use .save()
116 117 beaker.session.auto = False
117 118
118 119 ##true exire at browser close
119 120 #beaker.session.cookie_expires = 3600
120 121
121 122
122 123 ################################################################################
123 124 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
124 125 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
125 126 ## execute malicious code after an exception is raised. ##
126 127 ################################################################################
127 128 #set debug = false
128 129
129 130 ##################################
130 131 ### LOGVIEW CONFIG ###
131 132 ##################################
132 133 logview.sqlalchemy = #faa
133 134 logview.pylons.templating = #bfb
134 135 logview.pylons.util = #eee
135 136
136 137 #########################################################
137 138 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
138 139 #########################################################
139 140 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
140 141 #sqlalchemy.db1.echo = False
141 142 #sqlalchemy.db1.pool_recycle = 3600
142 143 sqlalchemy.convert_unicode = true
143 144
144 145 ################################
145 146 ### LOGGING CONFIGURATION ####
146 147 ################################
147 148 [loggers]
148 149 keys = root, routes, rhodecode, sqlalchemy,beaker,templates
149 150
150 151 [handlers]
151 152 keys = console
152 153
153 154 [formatters]
154 155 keys = generic,color_formatter
155 156
156 157 #############
157 158 ## LOGGERS ##
158 159 #############
159 160 [logger_root]
160 161 level = NOTSET
161 162 handlers = console
162 163
163 164 [logger_routes]
164 165 level = DEBUG
165 166 handlers = console
166 167 qualname = routes.middleware
167 168 # "level = DEBUG" logs the route matched and routing variables.
168 169 propagate = 0
169 170
170 171 [logger_beaker]
171 172 level = ERROR
172 173 handlers = console
173 174 qualname = beaker.container
174 175 propagate = 0
175 176
176 177 [logger_templates]
177 178 level = INFO
178 179 handlers = console
179 180 qualname = pylons.templating
180 181 propagate = 0
181 182
182 183 [logger_rhodecode]
183 184 level = DEBUG
184 185 handlers = console
185 186 qualname = rhodecode
186 187 propagate = 0
187 188
188 189 [logger_sqlalchemy]
189 190 level = ERROR
190 191 handlers = console
191 192 qualname = sqlalchemy.engine
192 193 propagate = 0
193 194
194 195 ##############
195 196 ## HANDLERS ##
196 197 ##############
197 198
198 199 [handler_console]
199 200 class = StreamHandler
200 201 args = (sys.stderr,)
201 202 level = NOTSET
202 203 formatter = color_formatter
203 204
204 205 ################
205 206 ## FORMATTERS ##
206 207 ################
207 208
208 209 [formatter_generic]
209 210 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
210 211 datefmt = %Y-%m-%d %H:%M:%S
211 212
212 213 [formatter_color_formatter]
213 214 class=rhodecode.lib.colored_formatter.ColorFormatter
214 215 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
215 216 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
@@ -1,118 +1,137 b''
1 1 .. _changelog:
2 2
3 3 Changelog
4 4 =========
5 5
6 1.1.1 (**2011-01-06**)
7 ----------------------
8
9 news
10 ++++
11
12 - added force https option into ini files for easier https usage (no need to
13 set server headers with this options)
14 - small css updates
15
16 fixes
17 ++++
18
19 - fixed #96 redirect loop on files view on repositories without changesets
20 - fixed #97 unicode string passed into server header in special cases (mod_wsgi)
21 and server crashed with errors
22 - fixed large tooltips problems on main page
23 - fixed #92 whoosh indexer is more error proof
24
6 25 1.1.0 (**2010-12-18**)
7 26 ----------------------
8 27
9 28 news
10 29 ++++
11 30
12 31 - rewrite of internals for vcs >=0.1.10
13 32 - uses mercurial 1.7 with dotencode disabled for maintaining compatibility
14 33 with older clients
15 34 - anonymous access, authentication via ldap
16 35 - performance upgrade for cached repos list - each repository has it's own
17 36 cache that's invalidated when needed.
18 37 - performance upgrades on repositories with large amount of commits (20K+)
19 38 - main page quick filter for filtering repositories
20 39 - user dashboards with ability to follow chosen repositories actions
21 40 - sends email to admin on new user registration
22 41 - added cache/statistics reset options into repository settings
23 42 - more detailed action logger (based on hooks) with pushed changesets lists
24 43 and options to disable those hooks from admin panel
25 44 - introduced new enhanced changelog for merges that shows more accurate results
26 45 - new improved and faster code stats (based on pygments lexers mapping tables,
27 46 showing up to 10 trending sources for each repository. Additionally stats
28 47 can be disabled in repository settings.
29 48 - gui optimizations, fixed application width to 1024px
30 49 - added cut off (for large files/changesets) limit into config files
31 50 - whoosh, celeryd, upgrade moved to paster command
32 51 - other than sqlite database backends can be used
33 52
34 53 fixes
35 54 +++++
36 55
37 56 - fixes #61 forked repo was showing only after cache expired
38 57 - fixes #76 no confirmation on user deletes
39 58 - fixes #66 Name field misspelled
40 59 - fixes #72 block user removal when he owns repositories
41 60 - fixes #69 added password confirmation fields
42 61 - fixes #87 RhodeCode crashes occasionally on updating repository owner
43 62 - fixes #82 broken annotations on files with more than 1 blank line at the end
44 63 - a lot of fixes and tweaks for file browser
45 64 - fixed detached session issues
46 65 - fixed when user had no repos he would see all repos listed in my account
47 66 - fixed ui() instance bug when global hgrc settings was loaded for server
48 67 instance and all hgrc options were merged with our db ui() object
49 68 - numerous small bugfixes
50 69
51 70 (special thanks for TkSoh for detailed feedback)
52 71
53 72
54 73 1.0.2 (**2010-11-12**)
55 74 ----------------------
56 75
57 76 news
58 77 ++++
59 78
60 79 - tested under python2.7
61 80 - bumped sqlalchemy and celery versions
62 81
63 82 fixes
64 83 +++++
65 84
66 85 - fixed #59 missing graph.js
67 86 - fixed repo_size crash when repository had broken symlinks
68 87 - fixed python2.5 crashes.
69 88
70 89
71 90 1.0.1 (**2010-11-10**)
72 91 ----------------------
73 92
74 93 news
75 94 ++++
76 95
77 96 - small css updated
78 97
79 98 fixes
80 99 +++++
81 100
82 101 - fixed #53 python2.5 incompatible enumerate calls
83 102 - fixed #52 disable mercurial extension for web
84 103 - fixed #51 deleting repositories don't delete it's dependent objects
85 104
86 105
87 106 1.0.0 (**2010-11-02**)
88 107 ----------------------
89 108
90 109 - security bugfix simplehg wasn't checking for permissions on commands
91 110 other than pull or push.
92 111 - fixed doubled messages after push or pull in admin journal
93 112 - templating and css corrections, fixed repo switcher on chrome, updated titles
94 113 - admin menu accessible from options menu on repository view
95 114 - permissions cached queries
96 115
97 116 1.0.0rc4 (**2010-10-12**)
98 117 --------------------------
99 118
100 119 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
101 120 - removed cache_manager settings from sqlalchemy meta
102 121 - added sqlalchemy cache settings to ini files
103 122 - validated password length and added second try of failure on paster setup-app
104 123 - fixed setup database destroy prompt even when there was no db
105 124
106 125
107 126 1.0.0rc3 (**2010-10-11**)
108 127 -------------------------
109 128
110 129 - fixed i18n during installation.
111 130
112 131 1.0.0rc2 (**2010-10-11**)
113 132 -------------------------
114 133
115 134 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
116 135 occure. After vcs is fixed it'll be put back again.
117 136 - templating/css rewrites, optimized css.
118 137
@@ -1,262 +1,299 b''
1 1 .. _setup:
2 2
3 3 Setup
4 4 =====
5 5
6 6
7 7 Setting up the application
8 8 --------------------------
9 9
10 10 First You'll ned to create RhodeCode config file. Run the following command
11 11 to do this
12 12
13 13 ::
14 14
15 15 paster make-config RhodeCode production.ini
16 16
17 17 - This will create `production.ini` config inside the directory
18 18 this config contains various settings for RhodeCode, e.g proxy port,
19 19 email settings, usage of static files, cache, celery settings and logging.
20 20
21 21
22 22
23 23 Next we need to create the database.
24 24
25 25 ::
26 26
27 27 paster setup-app production.ini
28 28
29 29 - This command will create all needed tables and an admin account.
30 30 When asked for a path You can either use a new location of one with already
31 31 existing ones. RhodeCode will simply add all new found repositories to
32 32 it's database. Also make sure You specify correct path to repositories.
33 33 - Remember that the given path for mercurial_ repositories must be write
34 34 accessible for the application. It's very important since RhodeCode web
35 35 interface will work even without such an access but, when trying to do a
36 36 push it'll eventually fail with permission denied errors.
37 37
38 38 You are ready to use rhodecode, to run it simply execute
39 39
40 40 ::
41 41
42 42 paster serve production.ini
43 43
44 44 - This command runs the RhodeCode server the app should be available at the
45 45 127.0.0.1:5000. This ip and port is configurable via the production.ini
46 46 file created in previous step
47 47 - Use admin account you created to login.
48 48 - Default permissions on each repository is read, and owner is admin. So
49 49 remember to update these if needed. In the admin panel You can toggle ldap,
50 50 anonymous, permissions settings. As well as edit more advanced options on
51 51 users and repositories
52 52
53 53
54 54 Setting up Whoosh full text search
55 55 ----------------------------------
56 56
57 57 Index for whoosh can be build starting from version 1.1 using paster command
58 58 passing repo locations to index, as well as Your config file that stores
59 59 whoosh index files locations. There is possible to pass `-f` to the options
60 60 to enable full index rebuild. Without that indexing will run always in in
61 61 incremental mode.
62 62
63 63 ::
64 64
65 65 paster make-index production.ini --repo-location=<location for repos>
66 66
67 67 for full index rebuild You can use
68 68
69 69 ::
70 70
71 71 paster make-index production.ini -f --repo-location=<location for repos>
72 72
73 73 - For full text search You can either put crontab entry for
74 74
75 75 This command can be run even from crontab in order to do periodical
76 76 index builds and keep Your index always up to date. An example entry might
77 77 look like this
78 78
79 79 ::
80 80
81 81 /path/to/python/bin/paster /path/to/rhodecode/production.ini --repo-location=<location for repos>
82 82
83 83 When using incremental(default) mode whoosh will check last modification date
84 84 of each file and add it to reindex if newer file is available. Also indexing
85 85 daemon checks for removed files and removes them from index.
86 86
87 87 Sometime You might want to rebuild index from scratch. You can do that using
88 88 the `-f` flag passed to paster command or, in admin panel You can check
89 89 `build from scratch` flag.
90 90
91 91
92 92 Setting up LDAP support
93 93 -----------------------
94 94
95 95 RhodeCode starting from version 1.1 supports ldap authentication. In order
96 96 to use ldap, You have to install python-ldap package. This package is available
97 97 via pypi, so You can install it by running
98 98
99 99 ::
100 100
101 101 easy_install python-ldap
102 102
103 103 ::
104 104
105 105 pip install python-ldap
106 106
107 107 .. note::
108 108 python-ldap requires some certain libs on Your system, so before installing
109 109 it check that You have at least `openldap`, and `sasl` libraries.
110 110
111 111 ldap settings are located in admin->ldap section,
112 112
113 113 Here's a typical ldap setup::
114 114
115 115 Enable ldap = checked #controls if ldap access is enabled
116 116 Host = host.domain.org #actual ldap server to connect
117 117 Port = 389 or 689 for ldaps #ldap server ports
118 118 Enable LDAPS = unchecked #enable disable ldaps
119 119 Account = <account> #access for ldap server(if required)
120 120 Password = <password> #password for ldap server(if required)
121 121 Base DN = uid=%(user)s,CN=users,DC=host,DC=domain,DC=org
122 122
123 123
124 124 `Account` and `Password` are optional, and used for two-phase ldap
125 125 authentication so those are credentials to access Your ldap, if it doesn't
126 126 support anonymous search/user lookups.
127 127
128 128 Base DN must have %(user)s template inside, it's a placer where Your uid used
129 129 to login would go, it allows admins to specify not standard schema for uid
130 130 variable
131 131
132 132 If all data are entered correctly, and `python-ldap` is properly installed
133 133 Users should be granted to access RhodeCode wit ldap accounts. When
134 134 logging at the first time an special ldap account is created inside RhodeCode,
135 135 so You can control over permissions even on ldap users. If such user exists
136 136 already in RhodeCode database ldap user with the same username would be not
137 137 able to access RhodeCode.
138 138
139 139 If You have problems with ldap access and believe You entered correct
140 140 information check out the RhodeCode logs,any error messages sent from
141 141 ldap will be saved there.
142 142
143 143
144 144
145 145 Setting Up Celery
146 146 -----------------
147 147
148 148 Since version 1.1 celery is configured by the rhodecode ini configuration files
149 149 simply set use_celery=true in the ini file then add / change the configuration
150 150 variables inside the ini file.
151 151
152 152 Remember that the ini files uses format with '.' not with '_' like celery
153 153 so for example setting `BROKER_HOST` in celery means setting `broker.host` in
154 154 the config file.
155 155
156 156 In order to make start using celery run::
157 157 paster celeryd <configfile.ini>
158 158
159 159
160 HTTPS support
161 -------------
162
163 There are two ways to enable https, first is to set HTTP_X_URL_SCHEME in
164 Your http server headers, than rhodecode will recognise this headers and make
165 proper https redirections, another way is to set `force_https = true`
166 in the ini cofiguration to force using https, no headers are needed than to
167 enable https
168
169
160 170 Nginx virtual host example
161 171 --------------------------
162 172
163 173 Sample config for nginx using proxy::
164 174
165 175 server {
166 176 listen 80;
167 177 server_name hg.myserver.com;
168 178 access_log /var/log/nginx/rhodecode.access.log;
169 179 error_log /var/log/nginx/rhodecode.error.log;
170 180 location / {
171 181 root /var/www/rhodecode/rhodecode/public/;
172 182 if (!-f $request_filename){
173 183 proxy_pass http://127.0.0.1:5000;
174 184 }
175 185 #this is important for https !!!
176 186 proxy_set_header X-Url-Scheme $scheme;
177 187 include /etc/nginx/proxy.conf;
178 188 }
179 189 }
180 190
181 191 Here's the proxy.conf. It's tuned so it'll not timeout on long
182 192 pushes and also on large pushes::
183 193
184 194 proxy_redirect off;
185 195 proxy_set_header Host $host;
186 196 proxy_set_header X-Host $http_host;
187 197 proxy_set_header X-Real-IP $remote_addr;
188 198 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
189 199 proxy_set_header Proxy-host $proxy_host;
190 200 client_max_body_size 400m;
191 201 client_body_buffer_size 128k;
192 202 proxy_buffering off;
193 203 proxy_connect_timeout 3600;
194 204 proxy_send_timeout 3600;
195 205 proxy_read_timeout 3600;
196 206 proxy_buffer_size 8k;
197 207 proxy_buffers 8 32k;
198 208 proxy_busy_buffers_size 64k;
199 209 proxy_temp_file_write_size 64k;
200 210
201 211 Also when using root path with nginx You might set the static files to false
202 212 in production.ini file::
203 213
204 214 [app:main]
205 215 use = egg:rhodecode
206 216 full_stack = true
207 217 static_files = false
208 218 lang=en
209 219 cache_dir = %(here)s/data
210 220
211 221 To not have the statics served by the application. And improve speed.
212 222
213 Apache reverse proxy
214 --------------------
215 Tutorial can be found here
223
224 Apache virtual host example
225 ---------------------------
226
227 Sample config for apache using proxy::
228
229 <VirtualHost *:80>
230 ServerName hg.myserver.com
231 ServerAlias hg.myserver.com
232
233 <Proxy *>
234 Order allow,deny
235 Allow from all
236 </Proxy>
237
238 #important !
239 #Directive to properly generate url (clone url) for pylons
240 ProxyPreserveHost On
241
242 #rhodecode instance
243 ProxyPass / http://127.0.0.1:5000/
244 ProxyPassReverse / http://127.0.0.1:5000/
245
246 #to enable https use line below
247 #SetEnvIf X-Url-Scheme https HTTPS=1
248
249 </VirtualHost>
250
251
252 Additional tutorial
216 253 http://wiki.pylonshq.com/display/pylonscookbook/Apache+as+a+reverse+proxy+for+Pylons
217 254
218 255
219 256 Apache's example FCGI config
220 257 ----------------------------
221 258
222 259 TODO !
223 260
224 261 Other configuration files
225 262 -------------------------
226 263
227 264 Some extra configuration files and examples can be found here:
228 265 http://hg.python-works.com/rhodecode/files/tip/init.d
229 266
230 267 and also an celeryconfig file can be use from here:
231 268 http://hg.python-works.com/rhodecode/files/tip/celeryconfig.py
232 269
233 270 Troubleshooting
234 271 ---------------
235 272
236 273 - missing static files ?
237 274
238 275 - make sure either to set the `static_files = true` in the .ini file or
239 276 double check the root path for Your http setup. It should point to
240 277 for example:
241 278 /home/my-virtual-python/lib/python2.6/site-packages/rhodecode/public
242 279
243 280 - can't install celery/rabbitmq
244 281
245 282 - don't worry RhodeCode works without them too. No extra setup required
246 283
247 284 - long lasting push timeouts ?
248 285
249 286 - make sure You set a longer timeouts in Your proxy/fcgi settings, timeouts
250 287 are caused by https server and not RhodeCode
251 288
252 289 - large pushes timeouts ?
253 290
254 291 - make sure You set a proper max_body_size for the http server
255 292
256 293
257 294
258 295 .. _virtualenv: http://pypi.python.org/pypi/virtualenv
259 296 .. _python: http://www.python.org/
260 297 .. _mercurial: http://mercurial.selenic.com/
261 298 .. _celery: http://celeryproject.org/
262 299 .. _rabbitmq: http://www.rabbitmq.com/ No newline at end of file
@@ -1,204 +1,205 b''
1 1 ################################################################################
2 2 ################################################################################
3 3 # rhodecode - Pylons environment configuration #
4 4 # #
5 5 # The %(here)s variable will be replaced with the parent directory of this file#
6 6 ################################################################################
7 7
8 8 [DEFAULT]
9 9 debug = true
10 10 ################################################################################
11 11 ## Uncomment and replace with the address which should receive ##
12 12 ## any error reports after application crash ##
13 13 ## Additionally those settings will be used by rhodecode mailing system ##
14 14 ################################################################################
15 15 #email_to = admin@localhost
16 16 #error_email_from = paste_error@localhost
17 17 #app_email_from = rhodecode-noreply@localhost
18 18 #error_message =
19 19
20 20 #smtp_server = mail.server.com
21 21 #smtp_username =
22 22 #smtp_password =
23 23 #smtp_port =
24 24 #smtp_use_tls = false
25 25 #smtp_use_ssl = true
26 26
27 27 [server:main]
28 28 ##nr of threads to spawn
29 29 threadpool_workers = 5
30 30
31 31 ##max request before thread respawn
32 32 threadpool_max_requests = 2
33 33
34 34 ##option to use threads of process
35 35 use_threadpool = true
36 36
37 37 use = egg:Paste#http
38 38 host = 127.0.0.1
39 39 port = 8001
40 40
41 41 [app:main]
42 42 use = egg:rhodecode
43 43 full_stack = true
44 44 static_files = false
45 45 lang=en
46 46 cache_dir = %(here)s/data
47 47 index_dir = %(here)s/data/index
48 48 cut_off_limit = 256000
49 force_https = false
49 50
50 51 ####################################
51 52 ### CELERY CONFIG ####
52 53 ####################################
53 54 use_celery = false
54 55 broker.host = localhost
55 56 broker.vhost = rabbitmqhost
56 57 broker.port = 5672
57 58 broker.user = rabbitmq
58 59 broker.password = qweqwe
59 60
60 61 celery.imports = rhodecode.lib.celerylib.tasks
61 62
62 63 celery.result.backend = amqp
63 64 celery.result.dburi = amqp://
64 65 celery.result.serialier = json
65 66
66 67 #celery.send.task.error.emails = true
67 68 #celery.amqp.task.result.expires = 18000
68 69
69 70 celeryd.concurrency = 2
70 71 #celeryd.log.file = celeryd.log
71 72 celeryd.log.level = debug
72 73 celeryd.max.tasks.per.child = 3
73 74
74 75 #tasks will never be sent to the queue, but executed locally instead.
75 76 celery.always.eager = false
76 77
77 78 ####################################
78 79 ### BEAKER CACHE ####
79 80 ####################################
80 81 beaker.cache.data_dir=/%(here)s/data/cache/data
81 82 beaker.cache.lock_dir=/%(here)s/data/cache/lock
82 83 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
83 84
84 85 beaker.cache.super_short_term.type=memory
85 86 beaker.cache.super_short_term.expire=10
86 87
87 88 beaker.cache.short_term.type=memory
88 89 beaker.cache.short_term.expire=60
89 90
90 91 beaker.cache.long_term.type=memory
91 92 beaker.cache.long_term.expire=36000
92 93
93 94
94 95 beaker.cache.sql_cache_short.type=memory
95 96 beaker.cache.sql_cache_short.expire=5
96 97
97 98 beaker.cache.sql_cache_med.type=memory
98 99 beaker.cache.sql_cache_med.expire=360
99 100
100 101 beaker.cache.sql_cache_long.type=file
101 102 beaker.cache.sql_cache_long.expire=3600
102 103
103 104 ####################################
104 105 ### BEAKER SESSION ####
105 106 ####################################
106 107 ## Type of storage used for the session, current types are
107 108 ## dbm, file, memcached, database, and memory.
108 109 ## The storage uses the Container API
109 110 ##that is also used by the cache system.
110 111 beaker.session.type = file
111 112
112 113 beaker.session.key = rhodecode
113 114 beaker.session.secret = g654dcno0-9873jhgfreyu
114 115 beaker.session.timeout = 36000
115 116
116 117 ##auto save the session to not to use .save()
117 118 beaker.session.auto = False
118 119
119 120 ##true exire at browser close
120 121 #beaker.session.cookie_expires = 3600
121 122
122 123
123 124 ################################################################################
124 125 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
125 126 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
126 127 ## execute malicious code after an exception is raised. ##
127 128 ################################################################################
128 129 set debug = false
129 130
130 131 ##################################
131 132 ### LOGVIEW CONFIG ###
132 133 ##################################
133 134 logview.sqlalchemy = #faa
134 135 logview.pylons.templating = #bfb
135 136 logview.pylons.util = #eee
136 137
137 138 #########################################################
138 139 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
139 140 #########################################################
140 141 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
141 142 #sqlalchemy.db1.echo = False
142 143 #sqlalchemy.db1.pool_recycle = 3600
143 144 sqlalchemy.convert_unicode = true
144 145
145 146 ################################
146 147 ### LOGGING CONFIGURATION ####
147 148 ################################
148 149 [loggers]
149 150 keys = root, routes, rhodecode, sqlalchemy
150 151
151 152 [handlers]
152 153 keys = console
153 154
154 155 [formatters]
155 156 keys = generic,color_formatter
156 157
157 158 #############
158 159 ## LOGGERS ##
159 160 #############
160 161 [logger_root]
161 162 level = INFO
162 163 handlers = console
163 164
164 165 [logger_routes]
165 166 level = INFO
166 167 handlers = console
167 168 qualname = routes.middleware
168 169 # "level = DEBUG" logs the route matched and routing variables.
169 170 propagate = 0
170 171
171 172 [logger_rhodecode]
172 173 level = DEBUG
173 174 handlers = console
174 175 qualname = rhodecode
175 176 propagate = 0
176 177
177 178 [logger_sqlalchemy]
178 179 level = ERROR
179 180 handlers = console
180 181 qualname = sqlalchemy.engine
181 182 propagate = 0
182 183
183 184 ##############
184 185 ## HANDLERS ##
185 186 ##############
186 187
187 188 [handler_console]
188 189 class = StreamHandler
189 190 args = (sys.stderr,)
190 191 level = NOTSET
191 192 formatter = color_formatter
192 193
193 194 ################
194 195 ## FORMATTERS ##
195 196 ################
196 197
197 198 [formatter_generic]
198 199 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
199 200 datefmt = %Y-%m-%d %H:%M:%S
200 201
201 202 [formatter_color_formatter]
202 203 class=rhodecode.lib.colored_formatter.ColorFormatter
203 204 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
204 205 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
@@ -1,204 +1,205 b''
1 1 ################################################################################
2 2 ################################################################################
3 3 # RhodeCode - Pylons environment configuration #
4 4 # #
5 5 # The %(here)s variable will be replaced with the parent directory of this file#
6 6 ################################################################################
7 7
8 8 [DEFAULT]
9 9 debug = true
10 10 ################################################################################
11 11 ## Uncomment and replace with the address which should receive ##
12 12 ## any error reports after application crash ##
13 13 ## Additionally those settings will be used by RhodeCode mailing system ##
14 14 ################################################################################
15 15 #email_to = admin@localhost
16 16 #error_email_from = paste_error@localhost
17 17 #app_email_from = rhodecode-noreply@localhost
18 18 #error_message =
19 19
20 20 #smtp_server = mail.server.com
21 21 #smtp_username =
22 22 #smtp_password =
23 23 #smtp_port =
24 24 #smtp_use_tls = false
25 25 #smtp_use_ssl = true
26 26
27 27 [server:main]
28 28 ##nr of threads to spawn
29 29 threadpool_workers = 5
30 30
31 31 ##max request before thread respawn
32 32 threadpool_max_requests = 10
33 33
34 34 ##option to use threads of process
35 35 use_threadpool = true
36 36
37 37 use = egg:Paste#http
38 38 host = 127.0.0.1
39 39 port = 5000
40 40
41 41 [app:main]
42 42 use = egg:rhodecode
43 43 full_stack = true
44 44 static_files = true
45 45 lang=en
46 46 cache_dir = %(here)s/data
47 47 index_dir = %(here)s/data/index
48 48 app_instance_uuid = ${app_instance_uuid}
49 49 cut_off_limit = 256000
50 force_https = false
50 51
51 52 ####################################
52 53 ### CELERY CONFIG ####
53 54 ####################################
54 55 use_celery = false
55 56 broker.host = localhost
56 57 broker.vhost = rabbitmqhost
57 58 broker.port = 5672
58 59 broker.user = rabbitmq
59 60 broker.password = qweqwe
60 61
61 62 celery.imports = rhodecode.lib.celerylib.tasks
62 63
63 64 celery.result.backend = amqp
64 65 celery.result.dburi = amqp://
65 66 celery.result.serialier = json
66 67
67 68 #celery.send.task.error.emails = true
68 69 #celery.amqp.task.result.expires = 18000
69 70
70 71 celeryd.concurrency = 2
71 72 #celeryd.log.file = celeryd.log
72 73 celeryd.log.level = debug
73 74 celeryd.max.tasks.per.child = 3
74 75
75 76 #tasks will never be sent to the queue, but executed locally instead.
76 77 celery.always.eager = false
77 78
78 79 ####################################
79 80 ### BEAKER CACHE ####
80 81 ####################################
81 82 beaker.cache.data_dir=/%(here)s/data/cache/data
82 83 beaker.cache.lock_dir=/%(here)s/data/cache/lock
83 84 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
84 85
85 86 beaker.cache.super_short_term.type=memory
86 87 beaker.cache.super_short_term.expire=10
87 88
88 89 beaker.cache.short_term.type=memory
89 90 beaker.cache.short_term.expire=60
90 91
91 92 beaker.cache.long_term.type=memory
92 93 beaker.cache.long_term.expire=36000
93 94
94 95 beaker.cache.sql_cache_short.type=memory
95 96 beaker.cache.sql_cache_short.expire=10
96 97
97 98 beaker.cache.sql_cache_med.type=memory
98 99 beaker.cache.sql_cache_med.expire=360
99 100
100 101 beaker.cache.sql_cache_long.type=file
101 102 beaker.cache.sql_cache_long.expire=3600
102 103
103 104 ####################################
104 105 ### BEAKER SESSION ####
105 106 ####################################
106 107 ## Type of storage used for the session, current types are
107 108 ## dbm, file, memcached, database, and memory.
108 109 ## The storage uses the Container API
109 110 ##that is also used by the cache system.
110 111 beaker.session.type = file
111 112
112 113 beaker.session.key = rhodecode
113 114 beaker.session.secret = ${app_instance_secret}
114 115 beaker.session.timeout = 36000
115 116
116 117 ##auto save the session to not to use .save()
117 118 beaker.session.auto = False
118 119
119 120 ##true exire at browser close
120 121 #beaker.session.cookie_expires = 3600
121 122
122 123
123 124 ################################################################################
124 125 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
125 126 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
126 127 ## execute malicious code after an exception is raised. ##
127 128 ################################################################################
128 129 set debug = false
129 130
130 131 ##################################
131 132 ### LOGVIEW CONFIG ###
132 133 ##################################
133 134 logview.sqlalchemy = #faa
134 135 logview.pylons.templating = #bfb
135 136 logview.pylons.util = #eee
136 137
137 138 #########################################################
138 139 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
139 140 #########################################################
140 141 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
141 142 #sqlalchemy.db1.echo = False
142 143 #sqlalchemy.db1.pool_recycle = 3600
143 144 sqlalchemy.convert_unicode = true
144 145
145 146 ################################
146 147 ### LOGGING CONFIGURATION ####
147 148 ################################
148 149 [loggers]
149 150 keys = root, routes, rhodecode, sqlalchemy
150 151
151 152 [handlers]
152 153 keys = console
153 154
154 155 [formatters]
155 156 keys = generic,color_formatter
156 157
157 158 #############
158 159 ## LOGGERS ##
159 160 #############
160 161 [logger_root]
161 162 level = INFO
162 163 handlers = console
163 164
164 165 [logger_routes]
165 166 level = INFO
166 167 handlers = console
167 168 qualname = routes.middleware
168 169 # "level = DEBUG" logs the route matched and routing variables.
169 170 propagate = 0
170 171
171 172 [logger_rhodecode]
172 173 level = DEBUG
173 174 handlers = console
174 175 qualname = rhodecode
175 176 propagate = 0
176 177
177 178 [logger_sqlalchemy]
178 179 level = ERROR
179 180 handlers = console
180 181 qualname = sqlalchemy.engine
181 182 propagate = 0
182 183
183 184 ##############
184 185 ## HANDLERS ##
185 186 ##############
186 187
187 188 [handler_console]
188 189 class = StreamHandler
189 190 args = (sys.stderr,)
190 191 level = NOTSET
191 192 formatter = color_formatter
192 193
193 194 ################
194 195 ## FORMATTERS ##
195 196 ################
196 197
197 198 [formatter_generic]
198 199 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
199 200 datefmt = %Y-%m-%d %H:%M:%S
200 201
201 202 [formatter_color_formatter]
202 203 class=rhodecode.lib.colored_formatter.ColorFormatter
203 204 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
204 205 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
@@ -1,253 +1,258 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.files
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Files controller for RhodeCode
7 7
8 8 :created_on: Apr 21, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software; you can redistribute it and/or
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program; if not, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27 import tempfile
28 28 import logging
29 29 import rhodecode.lib.helpers as h
30 30
31 31 from mercurial import archival
32 32
33 33 from pylons import request, response, session, tmpl_context as c, url
34 34 from pylons.i18n.translation import _
35 35 from pylons.controllers.util import redirect
36 36
37 37 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
38 38 from rhodecode.lib.base import BaseController, render
39 39 from rhodecode.lib.utils import EmptyChangeset
40 40 from rhodecode.model.scm import ScmModel
41 41
42 from vcs.exceptions import RepositoryError, ChangesetError
42 from vcs.exceptions import RepositoryError, ChangesetError, \
43 ChangesetDoesNotExistError, EmptyRepositoryError
43 44 from vcs.nodes import FileNode
44 45 from vcs.utils import diffs as differ
45 46
46 47 log = logging.getLogger(__name__)
47 48
48 49 class FilesController(BaseController):
49 50
50 51 @LoginRequired()
51 52 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
52 53 'repository.admin')
53 54 def __before__(self):
54 55 super(FilesController, self).__before__()
55 56 c.cut_off_limit = self.cut_off_limit
56 57
57 58 def index(self, repo_name, revision, f_path):
58 59 hg_model = ScmModel()
59 60 c.repo = hg_model.get_repo(c.repo_name)
60 61 revision = request.POST.get('at_rev', None) or revision
61 62
62 63 def get_next_rev(cur):
63 64 max_rev = len(c.repo.revisions) - 1
64 65 r = cur + 1
65 66 if r > max_rev:
66 67 r = max_rev
67 68 return r
68 69
69 70 def get_prev_rev(cur):
70 71 r = cur - 1
71 72 return r
72 73
73 74 c.f_path = f_path
74 75
75 76
76 77 try:
77 78 c.changeset = c.repo.get_changeset(revision)
78 79 cur_rev = c.changeset.revision
79 80 prev_rev = c.repo.get_changeset(get_prev_rev(cur_rev)).raw_id
80 81 next_rev = c.repo.get_changeset(get_next_rev(cur_rev)).raw_id
81 82
82 83 c.url_prev = url('files_home', repo_name=c.repo_name,
83 84 revision=prev_rev, f_path=f_path)
84 85 c.url_next = url('files_home', repo_name=c.repo_name,
85 86 revision=next_rev, f_path=f_path)
86 87
87 88 try:
88 89 c.files_list = c.changeset.get_node(f_path)
89 90 c.file_history = self._get_history(c.repo, c.files_list, f_path)
90 91 except RepositoryError, e:
91 92 h.flash(str(e), category='warning')
92 93 redirect(h.url('files_home', repo_name=repo_name, revision=revision))
93 94
95 except EmptyRepositoryError, e:
96 h.flash(_('There are no files yet'), category='warning')
97 redirect(h.url('summary_home', repo_name=repo_name))
98
94 99 except RepositoryError, e:
95 100 h.flash(str(e), category='warning')
96 101 redirect(h.url('files_home', repo_name=repo_name, revision='tip'))
97 102
98 103
99 104
100 105 return render('files/files.html')
101 106
102 107 def rawfile(self, repo_name, revision, f_path):
103 108 hg_model = ScmModel()
104 109 c.repo = hg_model.get_repo(c.repo_name)
105 110 file_node = c.repo.get_changeset(revision).get_node(f_path)
106 111 response.content_type = file_node.mimetype
107 112 response.content_disposition = 'attachment; filename=%s' \
108 113 % f_path.split('/')[-1]
109 114 return file_node.content
110 115
111 116 def raw(self, repo_name, revision, f_path):
112 117 hg_model = ScmModel()
113 118 c.repo = hg_model.get_repo(c.repo_name)
114 119 file_node = c.repo.get_changeset(revision).get_node(f_path)
115 120 response.content_type = 'text/plain'
116 121
117 122 return file_node.content
118 123
119 124 def annotate(self, repo_name, revision, f_path):
120 125 hg_model = ScmModel()
121 126 c.repo = hg_model.get_repo(c.repo_name)
122 127
123 128 try:
124 129 c.cs = c.repo.get_changeset(revision)
125 130 c.file = c.cs.get_node(f_path)
126 131 except RepositoryError, e:
127 132 h.flash(str(e), category='warning')
128 133 redirect(h.url('files_home', repo_name=repo_name, revision=revision))
129 134
130 135 c.file_history = self._get_history(c.repo, c.file, f_path)
131 136
132 137 c.f_path = f_path
133 138
134 139 return render('files/files_annotate.html')
135 140
136 141 def archivefile(self, repo_name, revision, fileformat):
137 142 archive_specs = {
138 143 '.tar.bz2': ('application/x-tar', 'tbz2'),
139 144 '.tar.gz': ('application/x-tar', 'tgz'),
140 145 '.zip': ('application/zip', 'zip'),
141 146 }
142 147 if not archive_specs.has_key(fileformat):
143 148 return 'Unknown archive type %s' % fileformat
144 149
145 150 def read_in_chunks(file_object, chunk_size=1024 * 40):
146 151 """Lazy function (generator) to read a file piece by piece.
147 152 Default chunk size: 40k."""
148 153 while True:
149 154 data = file_object.read(chunk_size)
150 155 if not data:
151 156 break
152 157 yield data
153 158
154 159 archive = tempfile.TemporaryFile()
155 160 repo = ScmModel().get_repo(repo_name).repo
156 161 fname = '%s-%s%s' % (repo_name, revision, fileformat)
157 162 archival.archive(repo, archive, revision, archive_specs[fileformat][1],
158 163 prefix='%s-%s' % (repo_name, revision))
159 164 response.content_type = archive_specs[fileformat][0]
160 165 response.content_disposition = 'attachment; filename=%s' % fname
161 166 archive.seek(0)
162 167 return read_in_chunks(archive)
163 168
164 169 def diff(self, repo_name, f_path):
165 170 hg_model = ScmModel()
166 171 diff1 = request.GET.get('diff1')
167 172 diff2 = request.GET.get('diff2')
168 173 c.action = request.GET.get('diff')
169 174 c.no_changes = diff1 == diff2
170 175 c.f_path = f_path
171 176 c.repo = hg_model.get_repo(c.repo_name)
172 177
173 178 try:
174 179 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
175 180 c.changeset_1 = c.repo.get_changeset(diff1)
176 181 node1 = c.changeset_1.get_node(f_path)
177 182 else:
178 183 c.changeset_1 = EmptyChangeset()
179 184 node1 = FileNode('.', '', changeset=c.changeset_1)
180 185
181 186 if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]:
182 187 c.changeset_2 = c.repo.get_changeset(diff2)
183 188 node2 = c.changeset_2.get_node(f_path)
184 189 else:
185 190 c.changeset_2 = EmptyChangeset()
186 191 node2 = FileNode('.', '', changeset=c.changeset_2)
187 192 except RepositoryError:
188 193 return redirect(url('files_home',
189 194 repo_name=c.repo_name, f_path=f_path))
190 195
191 196 f_udiff = differ.get_udiff(node1, node2)
192 197 diff = differ.DiffProcessor(f_udiff)
193 198
194 199 if c.action == 'download':
195 200 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
196 201 response.content_type = 'text/plain'
197 202 response.content_disposition = 'attachment; filename=%s' \
198 203 % diff_name
199 204 return diff.raw_diff()
200 205
201 206 elif c.action == 'raw':
202 207 response.content_type = 'text/plain'
203 208 return diff.raw_diff()
204 209
205 210 elif c.action == 'diff':
206 211 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
207 212 c.cur_diff = _('Diff is to big to display')
208 213 else:
209 214 c.cur_diff = diff.as_html()
210 215 else:
211 216 #default option
212 217 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
213 218 c.cur_diff = _('Diff is to big to display')
214 219 else:
215 220 c.cur_diff = diff.as_html()
216 221
217 222 if not c.cur_diff: c.no_changes = True
218 223 return render('files/file_diff.html')
219 224
220 225 def _get_history(self, repo, node, f_path):
221 226 from vcs.nodes import NodeKind
222 227 if not node.kind is NodeKind.FILE:
223 228 return []
224 229 changesets = node.history
225 230 hist_l = []
226 231
227 232 changesets_group = ([], _("Changesets"))
228 233 branches_group = ([], _("Branches"))
229 234 tags_group = ([], _("Tags"))
230 235
231 236 for chs in changesets:
232 237 n_desc = 'r%s:%s' % (chs.revision, chs.short_id)
233 238 changesets_group[0].append((chs.raw_id, n_desc,))
234 239
235 240 hist_l.append(changesets_group)
236 241
237 242 for name, chs in c.repository_branches.items():
238 243 #chs = chs.split(':')[-1]
239 244 branches_group[0].append((chs, name),)
240 245 hist_l.append(branches_group)
241 246
242 247 for name, chs in c.repository_tags.items():
243 248 #chs = chs.split(':')[-1]
244 249 tags_group[0].append((chs, name),)
245 250 hist_l.append(tags_group)
246 251
247 252 return hist_l
248 253
249 254 # [
250 255 # ([("u1", "User1"), ("u2", "User2")], "Users"),
251 256 # ([("g1", "Group1"), ("g2", "Group2")], "Groups")
252 257 # ]
253 258
@@ -1,215 +1,222 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # whoosh indexer daemon for rhodecode
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 20 """
21 21 Created on Jan 26, 2010
22 22
23 23 @author: marcink
24 24 A deamon will read from task table and run tasks
25 25 """
26 26 import sys
27 27 import os
28 28 from os.path import dirname as dn
29 29 from os.path import join as jn
30 30
31 31 #to get the rhodecode import
32 32 project_path = dn(dn(dn(dn(os.path.realpath(__file__)))))
33 33 sys.path.append(project_path)
34 34
35 35
36 36 from rhodecode.model.scm import ScmModel
37 37 from rhodecode.lib.helpers import safe_unicode
38 38 from whoosh.index import create_in, open_dir
39 39 from shutil import rmtree
40 40 from rhodecode.lib.indexers import INDEX_EXTENSIONS, SCHEMA, IDX_NAME
41 41
42 42 from time import mktime
43 43 from vcs.exceptions import ChangesetError, RepositoryError
44 44
45 45 import logging
46 46
47 47 log = logging.getLogger('whooshIndexer')
48 48 # create logger
49 49 log.setLevel(logging.DEBUG)
50 50 log.propagate = False
51 51 # create console handler and set level to debug
52 52 ch = logging.StreamHandler()
53 53 ch.setLevel(logging.DEBUG)
54 54
55 55 # create formatter
56 56 formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
57 57
58 58 # add formatter to ch
59 59 ch.setFormatter(formatter)
60 60
61 61 # add ch to logger
62 62 log.addHandler(ch)
63 63
64 64 class WhooshIndexingDaemon(object):
65 65 """
66 66 Deamon for atomic jobs
67 67 """
68 68
69 69 def __init__(self, indexname='HG_INDEX', index_location=None,
70 70 repo_location=None, sa=None):
71 71 self.indexname = indexname
72 72
73 73 self.index_location = index_location
74 74 if not index_location:
75 75 raise Exception('You have to provide index location')
76 76
77 77 self.repo_location = repo_location
78 78 if not repo_location:
79 79 raise Exception('You have to provide repositories location')
80 80
81 81 self.repo_paths = ScmModel(sa).repo_scan(self.repo_location, None)
82 82 self.initial = False
83 83 if not os.path.isdir(self.index_location):
84 84 os.makedirs(self.index_location)
85 85 log.info('Cannot run incremental index since it does not'
86 86 ' yet exist running full build')
87 87 self.initial = True
88 88
89 89 def get_paths(self, repo):
90 90 """recursive walk in root dir and return a set of all path in that dir
91 91 based on repository walk function
92 92 """
93 93 index_paths_ = set()
94 94 try:
95 95 for topnode, dirs, files in repo.walk('/', 'tip'):
96 96 for f in files:
97 97 index_paths_.add(jn(repo.path, f.path))
98 98 for dir in dirs:
99 99 for f in files:
100 100 index_paths_.add(jn(repo.path, f.path))
101 101
102 102 except RepositoryError:
103 103 pass
104 104 return index_paths_
105 105
106 106 def get_node(self, repo, path):
107 107 n_path = path[len(repo.path) + 1:]
108 108 node = repo.get_changeset().get_node(n_path)
109 109 return node
110 110
111 111 def get_node_mtime(self, node):
112 112 return mktime(node.last_changeset.date.timetuple())
113 113
114 114 def add_doc(self, writer, path, repo):
115 115 """Adding doc to writer this function itself fetches data from
116 116 the instance of vcs backend"""
117 117 node = self.get_node(repo, path)
118 118
119 #we just index the content of chosen files
120 if node.extension in INDEX_EXTENSIONS:
121 log.debug(' >> %s [WITH CONTENT]' % path)
119 #we just index the content of chosen files, and skip binary files
120 if node.extension in INDEX_EXTENSIONS and not node.is_binary:
121
122 122 u_content = node.content
123 if not isinstance(u_content, unicode):
124 log.warning(' >> %s Could not get this content as unicode '
125 'replacing with empty content', path)
126 u_content = u''
127 else:
128 log.debug(' >> %s [WITH CONTENT]' % path)
129
123 130 else:
124 131 log.debug(' >> %s' % path)
125 132 #just index file name without it's content
126 133 u_content = u''
127 134
128 135 writer.add_document(owner=unicode(repo.contact),
129 136 repository=safe_unicode(repo.name),
130 137 path=safe_unicode(path),
131 138 content=u_content,
132 139 modtime=self.get_node_mtime(node),
133 140 extension=node.extension)
134 141
135 142
136 143 def build_index(self):
137 144 if os.path.exists(self.index_location):
138 145 log.debug('removing previous index')
139 146 rmtree(self.index_location)
140 147
141 148 if not os.path.exists(self.index_location):
142 149 os.mkdir(self.index_location)
143 150
144 151 idx = create_in(self.index_location, SCHEMA, indexname=IDX_NAME)
145 152 writer = idx.writer()
146 153
147 154 for cnt, repo in enumerate(self.repo_paths.values()):
148 155 log.debug('building index @ %s' % repo.path)
149 156
150 157 for idx_path in self.get_paths(repo):
151 158 self.add_doc(writer, idx_path, repo)
152 159
153 160 log.debug('>> COMMITING CHANGES <<')
154 161 writer.commit(merge=True)
155 162 log.debug('>>> FINISHED BUILDING INDEX <<<')
156 163
157 164
158 165 def update_index(self):
159 166 log.debug('STARTING INCREMENTAL INDEXING UPDATE')
160 167
161 168 idx = open_dir(self.index_location, indexname=self.indexname)
162 169 # The set of all paths in the index
163 170 indexed_paths = set()
164 171 # The set of all paths we need to re-index
165 172 to_index = set()
166 173
167 174 reader = idx.reader()
168 175 writer = idx.writer()
169 176
170 177 # Loop over the stored fields in the index
171 178 for fields in reader.all_stored_fields():
172 179 indexed_path = fields['path']
173 180 indexed_paths.add(indexed_path)
174 181
175 182 repo = self.repo_paths[fields['repository']]
176 183
177 184 try:
178 185 node = self.get_node(repo, indexed_path)
179 186 except ChangesetError:
180 187 # This file was deleted since it was indexed
181 188 log.debug('removing from index %s' % indexed_path)
182 189 writer.delete_by_term('path', indexed_path)
183 190
184 191 else:
185 192 # Check if this file was changed since it was indexed
186 193 indexed_time = fields['modtime']
187 194 mtime = self.get_node_mtime(node)
188 195 if mtime > indexed_time:
189 196 # The file has changed, delete it and add it to the list of
190 197 # files to reindex
191 198 log.debug('adding to reindex list %s' % indexed_path)
192 199 writer.delete_by_term('path', indexed_path)
193 200 to_index.add(indexed_path)
194 201
195 202 # Loop over the files in the filesystem
196 203 # Assume we have a function that gathers the filenames of the
197 204 # documents to be indexed
198 205 for repo in self.repo_paths.values():
199 206 for path in self.get_paths(repo):
200 207 if path in to_index or path not in indexed_paths:
201 208 # This is either a file that's changed, or a new file
202 209 # that wasn't indexed before. So index it!
203 210 self.add_doc(writer, path, repo)
204 211 log.debug('re indexing %s' % path)
205 212
206 213 log.debug('>> COMMITING CHANGES <<')
207 214 writer.commit(merge=True)
208 215 log.debug('>>> FINISHED REBUILDING INDEX <<<')
209 216
210 217 def run(self, full_index=False):
211 218 """Run daemon"""
212 219 if full_index or self.initial:
213 220 self.build_index()
214 221 else:
215 222 self.update_index()
@@ -1,47 +1,54 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 # middleware to handle https correctly
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5
1 # -*- coding: utf-8 -*-
2 """
3 rhodecode.lib.middleware.https_fixup
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 middleware to handle https correctly
7
8 :created_on: May 23, 2010
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 13 # This program is free software; you can redistribute it and/or
7 14 # modify it under the terms of the GNU General Public License
8 15 # as published by the Free Software Foundation; version 2
9 16 # of the License or (at your opinion) any later version of the license.
10 17 #
11 18 # This program is distributed in the hope that it will be useful,
12 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 21 # GNU General Public License for more details.
15 22 #
16 23 # You should have received a copy of the GNU General Public License
17 24 # along with this program; if not, write to the Free Software
18 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 26 # MA 02110-1301, USA.
20 27
21 """
22 Created on May 23, 2010
23
24 @author: marcink
25 """
28 from rhodecode.lib import str2bool
26 29
27 30 class HttpsFixup(object):
28 def __init__(self, app):
31 def __init__(self, app, config):
29 32 self.application = app
30
33 self.config = config
34
31 35 def __call__(self, environ, start_response):
32 36 self.__fixup(environ)
33 37 return self.application(environ, start_response)
34
35
38
39
36 40 def __fixup(self, environ):
37 41 """Function to fixup the environ as needed. In order to use this
38 42 middleware you should set this header inside your
39 43 proxy ie. nginx, apache etc.
40 44 """
41 45 proto = environ.get('HTTP_X_URL_SCHEME')
42
46
47 if str2bool(self.config.get('force_https')):
48 proto = 'https'
49
43 50 if proto == 'https':
44 51 environ['wsgi.url_scheme'] = proto
45 52 else:
46 53 environ['wsgi.url_scheme'] = 'http'
47 54 return None
@@ -1,229 +1,231 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # middleware to handle mercurial 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 20 """
21 21 Created on 2010-04-28
22 22
23 23 @author: marcink
24 24 SimpleHG middleware for handling mercurial protocol request (push/clone etc.)
25 25 It's implemented with basic auth function
26 26 """
27 27 from mercurial.error import RepoError
28 28 from mercurial.hgweb import hgweb
29 29 from mercurial.hgweb.request import wsgiapplication
30 30 from paste.auth.basic import AuthBasicAuthenticator
31 31 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
32 32 from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware
33 33 from rhodecode.lib.utils import make_ui, invalidate_cache, \
34 34 check_repo_fast, ui_sections
35 35 from rhodecode.model.user import UserModel
36 36 from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
37 37 import logging
38 38 import os
39 39 import traceback
40 40
41 41 log = logging.getLogger(__name__)
42 42
43 43 def is_mercurial(environ):
44 44 """
45 45 Returns True if request's target is mercurial server - header
46 46 ``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
47 47 """
48 48 http_accept = environ.get('HTTP_ACCEPT')
49 49 if http_accept and http_accept.startswith('application/mercurial'):
50 50 return True
51 51 return False
52 52
53 53 class SimpleHg(object):
54 54
55 55 def __init__(self, application, config):
56 56 self.application = application
57 57 self.config = config
58 58 #authenticate this mercurial request using authfunc
59 59 self.authenticate = AuthBasicAuthenticator('', authfunc)
60 60 self.ipaddr = '0.0.0.0'
61 61 self.repository = None
62 62 self.username = None
63 63 self.action = None
64 64
65 65 def __call__(self, environ, start_response):
66 66 if not is_mercurial(environ):
67 67 return self.application(environ, start_response)
68 68
69 69 proxy_key = 'HTTP_X_REAL_IP'
70 70 def_key = 'REMOTE_ADDR'
71 71 self.ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
72 # skip passing error to error controller
73 environ['pylons.status_code_redirect'] = True
72 74
73 75 #===================================================================
74 76 # AUTHENTICATE THIS MERCURIAL REQUEST
75 77 #===================================================================
76 78 username = REMOTE_USER(environ)
77 79
78 80 if not username:
79 self.authenticate.realm = self.config['rhodecode_realm']
81 self.authenticate.realm = str(self.config['rhodecode_realm'])
80 82 result = self.authenticate(environ)
81 83 if isinstance(result, str):
82 84 AUTH_TYPE.update(environ, 'basic')
83 85 REMOTE_USER.update(environ, result)
84 86 else:
85 87 return result.wsgi_application(environ, start_response)
86 88
87 89 #=======================================================================
88 90 # GET REPOSITORY
89 91 #=======================================================================
90 92 try:
91 93 repo_name = '/'.join(environ['PATH_INFO'].split('/')[1:])
92 94 if repo_name.endswith('/'):
93 95 repo_name = repo_name.rstrip('/')
94 96 self.repository = repo_name
95 97 except:
96 98 log.error(traceback.format_exc())
97 99 return HTTPInternalServerError()(environ, start_response)
98 100
99 101 #===================================================================
100 102 # CHECK PERMISSIONS FOR THIS REQUEST
101 103 #===================================================================
102 104 self.action = self.__get_action(environ)
103 105 if self.action:
104 106 username = self.__get_environ_user(environ)
105 107 try:
106 108 user = self.__get_user(username)
107 109 self.username = user.username
108 110 except:
109 111 log.error(traceback.format_exc())
110 112 return HTTPInternalServerError()(environ, start_response)
111 113
112 114 #check permissions for this repository
113 115 if self.action == 'push':
114 116 if not HasPermissionAnyMiddleware('repository.write',
115 117 'repository.admin')\
116 118 (user, repo_name):
117 119 return HTTPForbidden()(environ, start_response)
118 120
119 121 else:
120 122 #any other action need at least read permission
121 123 if not HasPermissionAnyMiddleware('repository.read',
122 124 'repository.write',
123 125 'repository.admin')\
124 126 (user, repo_name):
125 127 return HTTPForbidden()(environ, start_response)
126 128
127 129 self.extras = {'ip':self.ipaddr,
128 130 'username':self.username,
129 131 'action':self.action,
130 132 'repository':self.repository}
131 133
132 134 #===================================================================
133 135 # MERCURIAL REQUEST HANDLING
134 136 #===================================================================
135 137 environ['PATH_INFO'] = '/'#since we wrap into hgweb, reset the path
136 138 self.baseui = make_ui('db')
137 139 self.basepath = self.config['base_path']
138 140 self.repo_path = os.path.join(self.basepath, repo_name)
139 141
140 142 #quick check if that dir exists...
141 143 if check_repo_fast(repo_name, self.basepath):
142 144 return HTTPNotFound()(environ, start_response)
143 145 try:
144 146 app = wsgiapplication(self.__make_app)
145 147 except RepoError, e:
146 148 if str(e).find('not found') != -1:
147 149 return HTTPNotFound()(environ, start_response)
148 150 except Exception:
149 151 log.error(traceback.format_exc())
150 152 return HTTPInternalServerError()(environ, start_response)
151 153
152 154 #invalidate cache on push
153 155 if self.action == 'push':
154 156 self.__invalidate_cache(repo_name)
155 157
156 158 return app(environ, start_response)
157 159
158 160
159 161 def __make_app(self):
160 162 hgserve = hgweb(str(self.repo_path), baseui=self.baseui)
161 163 return self.__load_web_settings(hgserve, self.extras)
162 164
163 165 def __get_environ_user(self, environ):
164 166 return environ.get('REMOTE_USER')
165 167
166 168 def __get_user(self, username):
167 169 return UserModel().get_by_username(username, cache=True)
168 170
169 171 def __get_action(self, environ):
170 172 """
171 173 Maps mercurial request commands into a clone,pull or push command.
172 174 This should always return a valid command string
173 175 :param environ:
174 176 """
175 177 mapping = {'changegroup': 'pull',
176 178 'changegroupsubset': 'pull',
177 179 'stream_out': 'pull',
178 180 'listkeys': 'pull',
179 181 'unbundle': 'push',
180 182 'pushkey': 'push', }
181 183 for qry in environ['QUERY_STRING'].split('&'):
182 184 if qry.startswith('cmd'):
183 185 cmd = qry.split('=')[-1]
184 186 if mapping.has_key(cmd):
185 187 return mapping[cmd]
186 188 else:
187 189 return cmd
188 190
189 191 def __invalidate_cache(self, repo_name):
190 192 """we know that some change was made to repositories and we should
191 193 invalidate the cache to see the changes right away but only for
192 194 push requests"""
193 195 invalidate_cache('get_repo_cached_%s' % repo_name)
194 196
195 197
196 198 def __load_web_settings(self, hgserve, extras={}):
197 199 #set the global ui for hgserve instance passed
198 200 hgserve.repo.ui = self.baseui
199 201
200 202 hgrc = os.path.join(self.repo_path, '.hg', 'hgrc')
201 203
202 204 #inject some additional parameters that will be available in ui
203 205 #for hooks
204 206 for k, v in extras.items():
205 207 hgserve.repo.ui.setconfig('rhodecode_extras', k, v)
206 208
207 209 repoui = make_ui('file', hgrc, False)
208 210
209 211 if repoui:
210 212 #overwrite our ui instance with the section from hgrc file
211 213 for section in ui_sections:
212 214 for k, v in repoui.configitems(section):
213 215 hgserve.repo.ui.setconfig(section, k, v)
214 216
215 217 return hgserve
216 218
217 219
218 220
219 221
220 222
221 223
222 224
223 225
224 226
225 227
226 228
227 229
228 230
229 231
@@ -1,2414 +1,2404 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
194 194 #header ul#logged-user{
195 195 margin-bottom:5px !important;
196 196 -webkit-border-radius: 0px 0px 8px 8px;
197 197 -khtml-border-radius: 0px 0px 8px 8px;
198 198 -moz-border-radius: 0px 0px 8px 8px;
199 199 border-radius: 0px 0px 8px 8px;
200 200 height:37px;
201 201 background:url("../images/header_inner.png") repeat-x scroll 0 0 #003367
202 202 }
203 203
204 204 #header ul#logged-user li {
205 205 list-style:none;
206 206 float:left;
207 207 margin:8px 0 0;
208 208 padding:4px 12px;
209 209 border-left: 1px solid #316293;
210 210 }
211 211
212 212 #header ul#logged-user li.first {
213 213 border-left:none;
214 214 margin:4px;
215 215 }
216 216
217 217 #header ul#logged-user li.first div.gravatar {
218 218 margin-top:-2px;
219 219 }
220 220
221 221 #header ul#logged-user li.first div.account {
222 222 padding-top:4px;
223 223 float:left;
224 224 }
225 225
226 226 #header ul#logged-user li.last {
227 227 border-right:none;
228 228 }
229 229
230 230 #header ul#logged-user li a {
231 231 color:#fff;
232 232 font-weight:700;
233 233 text-decoration:none;
234 234 }
235 235
236 236 #header ul#logged-user li a:hover {
237 237 text-decoration:underline;
238 238 }
239 239
240 240 #header ul#logged-user li.highlight a {
241 241 color:#fff;
242 242 }
243 243
244 244 #header ul#logged-user li.highlight a:hover {
245 245 color:#FFF;
246 246 }
247 247
248 248 #header #header-inner {
249 249 height:40px;
250 250 clear:both;
251 251 position:relative;
252 252 background:#003367 url("../images/header_inner.png") repeat-x;
253 253 border-bottom:2px solid #fff;
254 254 margin:0;
255 255 padding:0;
256 256 }
257 257
258 258 #header #header-inner #home a {
259 259 height:40px;
260 260 width:46px;
261 261 display:block;
262 262 background:url("../images/button_home.png");
263 263 background-position:0 0;
264 264 margin:0;
265 265 padding:0;
266 266 }
267 267
268 268 #header #header-inner #home a:hover {
269 269 background-position:0 -40px;
270 270 }
271 271
272 272 #header #header-inner #logo h1 {
273 273 color:#FFF;
274 274 font-size:18px;
275 275 margin:10px 0 0 13px;
276 276 padding:0;
277 277 }
278 278
279 279 #header #header-inner #logo a {
280 280 color:#fff;
281 281 text-decoration:none;
282 282 }
283 283
284 284 #header #header-inner #logo a:hover {
285 285 color:#bfe3ff;
286 286 }
287 287
288 288 #header #header-inner #quick,#header #header-inner #quick ul {
289 289 position:relative;
290 290 float:right;
291 291 list-style-type:none;
292 292 list-style-position:outside;
293 293 margin:10px 5px 0 0;
294 294 padding:0;
295 295 }
296 296
297 297 #header #header-inner #quick li {
298 298 position:relative;
299 299 float:left;
300 300 margin:0 5px 0 0;
301 301 padding:0;
302 302 }
303 303
304 304 #header #header-inner #quick li a {
305 305 top:0;
306 306 left:0;
307 307 height:1%;
308 308 display:block;
309 309 clear:both;
310 310 overflow:hidden;
311 311 color:#FFF;
312 312 font-weight:700;
313 313 text-decoration:none;
314 314 background:#369 url("../../images/quick_l.png") no-repeat top left;
315 315 padding:0;
316 316 }
317 317
318 318 #header #header-inner #quick li span.short {
319 319 padding:9px 6px 8px 6px;
320 320 }
321 321
322 322 #header #header-inner #quick li span {
323 323 top:0;
324 324 right:0;
325 325 height:1%;
326 326 display:block;
327 327 float:left;
328 328 background:url("../../images/quick_r.png") no-repeat top right;
329 329 border-left:1px solid #3f6f9f;
330 330 margin:0;
331 331 padding:10px 12px 8px 10px;
332 332 }
333 333
334 334 #header #header-inner #quick li span.normal {
335 335 border:none;
336 336 padding:10px 12px 8px;
337 337 }
338 338
339 339 #header #header-inner #quick li span.icon {
340 340 top:0;
341 341 left:0;
342 342 border-left:none;
343 343 background:url("../../images/quick_l.png") no-repeat top left;
344 344 border-right:1px solid #2e5c89;
345 345 padding:8px 8px 4px;
346 346 }
347 347
348 348 #header #header-inner #quick li span.icon_short {
349 349 top:0;
350 350 left:0;
351 351 border-left:none;
352 352 background:url("../../images/quick_l.png") no-repeat top left;
353 353 border-right:1px solid #2e5c89;
354 354 padding:9px 4px 4px;
355 355 }
356 356
357 357 #header #header-inner #quick li a:hover {
358 358 background:#4e4e4e url("../../images/quick_l_selected.png") no-repeat top left;
359 359 }
360 360
361 361 #header #header-inner #quick li a:hover span {
362 362 border-left:1px solid #545454;
363 363 background:url("../../images/quick_r_selected.png") no-repeat top right;
364 364 }
365 365
366 366 #header #header-inner #quick li a:hover span.icon,#header #header-inner #quick li a:hover span.icon_short {
367 367 border-left:none;
368 368 border-right:1px solid #464646;
369 369 background:url("../../images/quick_l_selected.png") no-repeat top left;
370 370 }
371 371
372 372
373 373 #header #header-inner #quick ul {
374 374 top:29px;
375 375 right:0;
376 376 min-width:200px;
377 377 display:none;
378 378 position:absolute;
379 379 background:#FFF;
380 380 border:1px solid #666;
381 381 border-top:1px solid #003367;
382 382 z-index:100;
383 383 margin:0;
384 384 padding:0;
385 385 }
386 386
387 387 #header #header-inner #quick ul.repo_switcher {
388 388 max-height:275px;
389 389 overflow-x:hidden;
390 390 overflow-y:auto;
391 391 }
392 392
393 393 #header #header-inner #quick .repo_switcher_type{
394 394 position:absolute;
395 395 left:0;
396 396 top:9px;
397 397
398 398 }
399 399 #header #header-inner #quick li ul li {
400 400 border-bottom:1px solid #ddd;
401 401 }
402 402
403 403 #header #header-inner #quick li ul li a {
404 404 width:182px;
405 405 height:auto;
406 406 display:block;
407 407 float:left;
408 408 background:#FFF;
409 409 color:#003367;
410 410 font-weight:400;
411 411 margin:0;
412 412 padding:7px 9px;
413 413 }
414 414
415 415 #header #header-inner #quick li ul li a:hover {
416 416 color:#000;
417 417 background:#FFF;
418 418 }
419 419
420 420 #header #header-inner #quick ul ul {
421 421 top:auto;
422 422 }
423 423
424 424 #header #header-inner #quick li ul ul {
425 425 right:200px;
426 426 max-height:275px;
427 427 overflow:auto;
428 428 overflow-x:hidden;
429 429 white-space:normal;
430 430 }
431 431
432 432 #header #header-inner #quick li ul li a.journal,#header #header-inner #quick li ul li a.journal:hover {
433 433 background:url("../images/icons/book.png") no-repeat scroll 4px 9px #FFF;
434 434 width:167px;
435 435 margin:0;
436 436 padding:12px 9px 7px 24px;
437 437 }
438 438
439 439 #header #header-inner #quick li ul li a.private_repo,#header #header-inner #quick li ul li a.private_repo:hover {
440 440 background:url("../images/icons/lock.png") no-repeat scroll 4px 9px #FFF;
441 441 min-width:167px;
442 442 margin:0;
443 443 padding:12px 9px 7px 24px;
444 444 }
445 445
446 446 #header #header-inner #quick li ul li a.public_repo,#header #header-inner #quick li ul li a.public_repo:hover {
447 447 background:url("../images/icons/lock_open.png") no-repeat scroll 4px 9px #FFF;
448 448 min-width:167px;
449 449 margin:0;
450 450 padding:12px 9px 7px 24px;
451 451 }
452 452
453 453 #header #header-inner #quick li ul li a.hg,#header #header-inner #quick li ul li a.hg:hover {
454 454 background:url("../images/icons/hgicon.png") no-repeat scroll 4px 9px #FFF;
455 455 min-width:167px;
456 456 margin:0 0 0 14px;
457 457 padding:12px 9px 7px 24px;
458 458 }
459 459
460 460 #header #header-inner #quick li ul li a.git,#header #header-inner #quick li ul li a.git:hover {
461 461 background:url("../images/icons/giticon.png") no-repeat scroll 4px 9px #FFF;
462 462 min-width:167px;
463 463 margin:0 0 0 14px;
464 464 padding:12px 9px 7px 24px;
465 465 }
466 466
467 467 #header #header-inner #quick li ul li a.repos,#header #header-inner #quick li ul li a.repos:hover {
468 468 background:url("../images/icons/database_edit.png") no-repeat scroll 4px 9px #FFF;
469 469 width:167px;
470 470 margin:0;
471 471 padding:12px 9px 7px 24px;
472 472 }
473 473
474 474 #header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover {
475 475 background:#FFF url("../images/icons/user_edit.png") no-repeat 4px 9px;
476 476 width:167px;
477 477 margin:0;
478 478 padding:12px 9px 7px 24px;
479 479 }
480 480
481 481 #header #header-inner #quick li ul li a.settings,#header #header-inner #quick li ul li a.settings:hover {
482 482 background:#FFF url("../images/icons/cog.png") no-repeat 4px 9px;
483 483 width:167px;
484 484 margin:0;
485 485 padding:12px 9px 7px 24px;
486 486 }
487 487
488 488 #header #header-inner #quick li ul li a.permissions,#header #header-inner #quick li ul li a.permissions:hover {
489 489 background:#FFF url("../images/icons/key.png") no-repeat 4px 9px;
490 490 width:167px;
491 491 margin:0;
492 492 padding:12px 9px 7px 24px;
493 493 }
494 494
495 495 #header #header-inner #quick li ul li a.ldap,#header #header-inner #quick li ul li a.ldap:hover {
496 496 background:#FFF url("../images/icons/server_key.png") no-repeat 4px 9px;
497 497 width:167px;
498 498 margin:0;
499 499 padding:12px 9px 7px 24px;
500 500 }
501 501
502 502 #header #header-inner #quick li ul li a.fork,#header #header-inner #quick li ul li a.fork:hover {
503 503 background:#FFF url("../images/icons/arrow_divide.png") no-repeat 4px 9px;
504 504 width:167px;
505 505 margin:0;
506 506 padding:12px 9px 7px 24px;
507 507 }
508 508
509 509 #header #header-inner #quick li ul li a.search,#header #header-inner #quick li ul li a.search:hover {
510 510 background:#FFF url("../images/icons/search_16.png") no-repeat 4px 9px;
511 511 width:167px;
512 512 margin:0;
513 513 padding:12px 9px 7px 24px;
514 514 }
515 515
516 516 #header #header-inner #quick li ul li a.delete,#header #header-inner #quick li ul li a.delete:hover {
517 517 background:#FFF url("../images/icons/delete.png") no-repeat 4px 9px;
518 518 width:167px;
519 519 margin:0;
520 520 padding:12px 9px 7px 24px;
521 521 }
522 522
523 523 #header #header-inner #quick li ul li a.branches,#header #header-inner #quick li ul li a.branches:hover {
524 524 background:#FFF url("../images/icons/arrow_branch.png") no-repeat 4px 9px;
525 525 width:167px;
526 526 margin:0;
527 527 padding:12px 9px 7px 24px;
528 528 }
529 529
530 530 #header #header-inner #quick li ul li a.tags,#header #header-inner #quick li ul li a.tags:hover {
531 531 background:#FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
532 532 width:167px;
533 533 margin:0;
534 534 padding:12px 9px 7px 24px;
535 535 }
536 536
537 537 #header #header-inner #quick li ul li a.admin,#header #header-inner #quick li ul li a.admin:hover {
538 538 background:#FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
539 539 width:167px;
540 540 margin:0;
541 541 padding:12px 9px 7px 24px;
542 542 }
543 543
544 544 #content #left {
545 545 left:0;
546 546 width:280px;
547 547 position:absolute;
548 548 }
549 549
550 550 #content #right {
551 551 margin:0 60px 10px 290px;
552 552 }
553 553
554 554 #content div.box {
555 555 clear:both;
556 556 overflow:hidden;
557 557 background:#fff;
558 558 margin:0 0 10px;
559 559 padding:0 0 10px;
560 560 }
561 561
562 562 #content div.box-left {
563 563 width:49%;
564 564 clear:none;
565 565 float:left;
566 566 margin:0 0 10px;
567 567 }
568 568
569 569 #content div.box-right {
570 570 width:49%;
571 571 clear:none;
572 572 float:right;
573 573 margin:0 0 10px;
574 574 }
575 575
576 576 #content div.box div.title {
577 577 clear:both;
578 578 overflow:hidden;
579 579 background:#369 url("../images/header_inner.png") repeat-x;
580 580 margin:0 0 20px;
581 581 padding:0;
582 582 }
583 583
584 584 #content div.box div.title h5 {
585 585 float:left;
586 586 border:none;
587 587 color:#fff;
588 588 text-transform:uppercase;
589 589 margin:0;
590 590 padding:11px 0 11px 10px;
591 591 }
592 592
593 593 #content div.box div.title ul.links li {
594 594 list-style:none;
595 595 float:left;
596 596 margin:0;
597 597 padding:0;
598 598 }
599 599
600 600 #content div.box div.title ul.links li a {
601 601 height:1%;
602 602 display:block;
603 603 float:left;
604 604 border-left:1px solid #316293;
605 605 color:#fff;
606 606 font-size:11px;
607 607 font-weight:700;
608 608 text-decoration:none;
609 609 margin:0;
610 610 padding:13px 16px 12px;
611 611 }
612 612
613 613 #content div.box h1,#content div.box h2,#content div.box h3,#content div.box h4,#content div.box h5,#content div.box h6 {
614 614 clear:both;
615 615 overflow:hidden;
616 616 border-bottom:1px solid #DDD;
617 617 margin:10px 20px;
618 618 padding:0 0 15px;
619 619 }
620 620
621 621 #content div.box p {
622 622 color:#5f5f5f;
623 623 font-size:12px;
624 624 line-height:150%;
625 625 margin:0 24px 10px;
626 626 padding:0;
627 627 }
628 628
629 629 #content div.box blockquote {
630 630 border-left:4px solid #DDD;
631 631 color:#5f5f5f;
632 632 font-size:11px;
633 633 line-height:150%;
634 634 margin:0 34px;
635 635 padding:0 0 0 14px;
636 636 }
637 637
638 638 #content div.box blockquote p {
639 639 margin:10px 0;
640 640 padding:0;
641 641 }
642 642
643 643 #content div.box dl {
644 644 margin:10px 24px;
645 645 }
646 646
647 647 #content div.box dt {
648 648 font-size:12px;
649 649 margin:0;
650 650 }
651 651
652 652 #content div.box dd {
653 653 font-size:12px;
654 654 margin:0;
655 655 padding:8px 0 8px 15px;
656 656 }
657 657
658 658 #content div.box li {
659 659 font-size:12px;
660 660 padding:4px 0;
661 661 }
662 662
663 663 #content div.box ul.disc,#content div.box ul.circle {
664 664 margin:10px 24px 10px 38px;
665 665 }
666 666
667 667 #content div.box ul.square {
668 668 margin:10px 24px 10px 40px;
669 669 }
670 670
671 671 #content div.box img.left {
672 672 border:none;
673 673 float:left;
674 674 margin:10px 10px 10px 0;
675 675 }
676 676
677 677 #content div.box img.right {
678 678 border:none;
679 679 float:right;
680 680 margin:10px 0 10px 10px;
681 681 }
682 682
683 683 #content div.box div.messages {
684 684 clear:both;
685 685 overflow:hidden;
686 686 margin:0 20px;
687 687 padding:0;
688 688 }
689 689
690 690 #content div.box div.message {
691 691 clear:both;
692 692 overflow:hidden;
693 693 margin:0;
694 694 padding:10px 0;
695 695 }
696 696
697 697 #content div.box div.message a {
698 698 font-weight:400 !important;
699 699 }
700 700
701 701 #content div.box div.message div.image {
702 702 float:left;
703 703 margin:9px 0 0 5px;
704 704 padding:6px;
705 705 }
706 706
707 707 #content div.box div.message div.image img {
708 708 vertical-align:middle;
709 709 margin:0;
710 710 }
711 711
712 712 #content div.box div.message div.text {
713 713 float:left;
714 714 margin:0;
715 715 padding:9px 6px;
716 716 }
717 717
718 718 #content div.box div.message div.dismiss a {
719 719 height:16px;
720 720 width:16px;
721 721 display:block;
722 722 background:url("../images/icons/cross.png") no-repeat;
723 723 margin:15px 14px 0 0;
724 724 padding:0;
725 725 }
726 726
727 727 #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 {
728 728 border:none;
729 729 margin:0;
730 730 padding:0;
731 731 }
732 732
733 733 #content div.box div.message div.text span {
734 734 height:1%;
735 735 display:block;
736 736 margin:0;
737 737 padding:5px 0 0;
738 738 }
739 739
740 740 #content div.box div.message-error {
741 741 height:1%;
742 742 clear:both;
743 743 overflow:hidden;
744 744 background:#FBE3E4;
745 745 border:1px solid #FBC2C4;
746 746 color:#860006;
747 747 }
748 748
749 749 #content div.box div.message-error h6 {
750 750 color:#860006;
751 751 }
752 752
753 753 #content div.box div.message-warning {
754 754 height:1%;
755 755 clear:both;
756 756 overflow:hidden;
757 757 background:#FFF6BF;
758 758 border:1px solid #FFD324;
759 759 color:#5f5200;
760 760 }
761 761
762 762 #content div.box div.message-warning h6 {
763 763 color:#5f5200;
764 764 }
765 765
766 766 #content div.box div.message-notice {
767 767 height:1%;
768 768 clear:both;
769 769 overflow:hidden;
770 770 background:#8FBDE0;
771 771 border:1px solid #6BACDE;
772 772 color:#003863;
773 773 }
774 774
775 775 #content div.box div.message-notice h6 {
776 776 color:#003863;
777 777 }
778 778
779 779 #content div.box div.message-success {
780 780 height:1%;
781 781 clear:both;
782 782 overflow:hidden;
783 783 background:#E6EFC2;
784 784 border:1px solid #C6D880;
785 785 color:#4e6100;
786 786 }
787 787
788 788 #content div.box div.message-success h6 {
789 789 color:#4e6100;
790 790 }
791 791
792 792 #content div.box div.form div.fields div.field {
793 793 height:1%;
794 794 border-bottom:1px solid #DDD;
795 795 clear:both;
796 796 margin:0;
797 797 padding:10px 0;
798 798 }
799 799
800 800 #content div.box div.form div.fields div.field-first {
801 801 padding:0 0 10px;
802 802 }
803 803
804 804 #content div.box div.form div.fields div.field-noborder {
805 805 border-bottom:0 !important;
806 806 }
807 807
808 808 #content div.box div.form div.fields div.field span.error-message {
809 809 height:1%;
810 810 display:inline-block;
811 811 color:red;
812 812 margin:8px 0 0 4px;
813 813 padding:0;
814 814 }
815 815
816 816 #content div.box div.form div.fields div.field span.success {
817 817 height:1%;
818 818 display:block;
819 819 color:#316309;
820 820 margin:8px 0 0;
821 821 padding:0;
822 822 }
823 823
824 824 #content div.box div.form div.fields div.field div.label {
825 825 left:80px;
826 826 width:auto;
827 827 position:absolute;
828 828 margin:0;
829 829 padding:8px 0 0 5px;
830 830 }
831 831
832 832 #content div.box-left div.form div.fields div.field div.label,#content div.box-right div.form div.fields div.field div.label {
833 833 clear:both;
834 834 overflow:hidden;
835 835 left:0;
836 836 width:auto;
837 837 position:relative;
838 838 margin:0;
839 839 padding:0 0 8px;
840 840 }
841 841
842 842 #content div.box div.form div.fields div.field div.label-select {
843 843 padding:5px 0 0 5px;
844 844 }
845 845
846 846 #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 {
847 847 padding:0 0 8px;
848 848 }
849 849
850 850 #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 {
851 851 padding:0 0 8px !important;
852 852 }
853 853
854 854 #content div.box div.form div.fields div.field div.label label {
855 855 color:#393939;
856 856 font-weight:700;
857 857 }
858 858
859 859 #content div.box div.form div.fields div.field div.input {
860 860 margin:0 0 0 200px;
861 861 }
862 862 #content div.box-left div.form div.fields div.field div.input,#content div.box-right div.form div.fields div.field div.input {
863 863 margin:0 0 0 0px;
864 864 }
865 865
866 866 #content div.box div.form div.fields div.field div.input input {
867 867 background:#FFF;
868 868 border-top:1px solid #b3b3b3;
869 869 border-left:1px solid #b3b3b3;
870 870 border-right:1px solid #eaeaea;
871 871 border-bottom:1px solid #eaeaea;
872 872 color:#000;
873 873 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
874 874 font-size:11px;
875 875 margin:0;
876 876 padding:7px 7px 6px;
877 877 }
878 878
879 879
880 880
881 881 #content div.box div.form div.fields div.field div.input input.small {
882 882 width:30%;
883 883 }
884 884
885 885 #content div.box div.form div.fields div.field div.input input.medium {
886 886 width:55%;
887 887 }
888 888
889 889 #content div.box div.form div.fields div.field div.input input.large {
890 890 width:85%;
891 891 }
892 892
893 893 #content div.box div.form div.fields div.field div.input input.date {
894 894 width:177px;
895 895 }
896 896
897 897 #content div.box div.form div.fields div.field div.input input.button {
898 898 background:#D4D0C8;
899 899 border-top:1px solid #FFF;
900 900 border-left:1px solid #FFF;
901 901 border-right:1px solid #404040;
902 902 border-bottom:1px solid #404040;
903 903 color:#000;
904 904 margin:0;
905 905 padding:4px 8px;
906 906 }
907 907
908 #content div.box div.form div.fields div.field div.input a.ui-input-file {
909 width:28px;
910 height:28px;
911 display:inline;
912 position:absolute;
913 overflow:hidden;
914 cursor:pointer;
915 background:#e5e3e3 url("../images/button_browse.png") no-repeat;
916 border:none;
917 text-decoration:none;
918 margin:0 0 0 6px;
919 padding:0;
920 }
921
922 908 #content div.box div.form div.fields div.field div.textarea {
923 909 border-top:1px solid #b3b3b3;
924 910 border-left:1px solid #b3b3b3;
925 911 border-right:1px solid #eaeaea;
926 912 border-bottom:1px solid #eaeaea;
927 913 margin:0 0 0 200px;
928 914 padding:10px;
929 915 }
930 916
931 917 #content div.box div.form div.fields div.field div.textarea-editor {
932 918 border:1px solid #ddd;
933 919 padding:0;
934 920 }
935 921
936 922 #content div.box div.form div.fields div.field div.textarea textarea {
937 923 width:100%;
938 924 height:220px;
939 925 overflow:hidden;
940 926 background:#FFF;
941 927 color:#000;
942 928 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
943 929 font-size:11px;
944 930 outline:none;
945 931 border-width:0;
946 932 margin:0;
947 933 padding:0;
948 934 }
949 935
950 936 #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 {
951 937 width:100%;
952 938 height:100px;
953 939 }
954 940
955 941 #content div.box div.form div.fields div.field div.textarea table {
956 942 width:100%;
957 943 border:none;
958 944 margin:0;
959 945 padding:0;
960 946 }
961 947
962 948 #content div.box div.form div.fields div.field div.textarea table td {
963 949 background:#DDD;
964 950 border:none;
965 951 padding:0;
966 952 }
967 953
968 954 #content div.box div.form div.fields div.field div.textarea table td table {
969 955 width:auto;
970 956 border:none;
971 957 margin:0;
972 958 padding:0;
973 959 }
974 960
975 961 #content div.box div.form div.fields div.field div.textarea table td table td {
976 962 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
977 963 font-size:11px;
978 964 padding:5px 5px 5px 0;
979 965 }
980 966
981 #content div.box div.form div.fields div.field div.textarea table td table td a.mceButtonActive {
982 background:#b1b1b1;
983 }
984
985 #content div.box div.form div.fields div.field div.select a.ui-selectmenu {
986 color:#565656;
987 text-decoration:none;
988 }
989
990 967 #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 {
991 968 background:#f6f6f6;
992 969 border-color:#666;
993 970 }
994 971
995 972 div.form div.fields div.field div.button {
996 973 margin:0;
997 974 padding:0 0 0 8px;
998 975 }
999 976
1000 div.form div.fields div.field div.highlight .ui-state-default {
977 div.form div.fields div.field div.highlight .ui-button {
1001 978 background:#4e85bb url("../images/button_highlight.png") repeat-x;
1002 979 border-top:1px solid #5c91a4;
1003 980 border-left:1px solid #2a6f89;
1004 981 border-right:1px solid #2b7089;
1005 982 border-bottom:1px solid #1a6480;
1006 983 color:#FFF;
1007 984 margin:0;
1008 985 padding:6px 12px;
1009 986 }
1010 987
1011 988 div.form div.fields div.field div.highlight .ui-state-hover {
1012 989 background:#46a0c1 url("../images/button_highlight_selected.png") repeat-x;
1013 990 border-top:1px solid #78acbf;
1014 991 border-left:1px solid #34819e;
1015 992 border-right:1px solid #35829f;
1016 993 border-bottom:1px solid #257897;
1017 994 color:#FFF;
1018 995 margin:0;
1019 996 padding:6px 12px;
1020 997 }
1021 998
1022 #content div.box div.form div.fields div.buttons div.highlight input.ui-state-default {
999 #content div.box div.form div.fields div.buttons div.highlight input.ui-button {
1023 1000 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
1024 1001 border-top:1px solid #5c91a4;
1025 1002 border-left:1px solid #2a6f89;
1026 1003 border-right:1px solid #2b7089;
1027 1004 border-bottom:1px solid #1a6480;
1028 1005 color:#fff;
1029 1006 margin:0;
1030 1007 padding:6px 12px;
1031 1008 }
1032 1009
1033 1010 #content div.box div.form div.fields div.buttons div.highlight input.ui-state-hover {
1034 1011 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
1035 1012 border-top:1px solid #78acbf;
1036 1013 border-left:1px solid #34819e;
1037 1014 border-right:1px solid #35829f;
1038 1015 border-bottom:1px solid #257897;
1039 1016 color:#fff;
1040 1017 margin:0;
1041 1018 padding:6px 12px;
1042 1019 }
1043 1020
1044 1021 #content div.box table {
1045 1022 width:100%;
1046 1023 border-collapse:collapse;
1047 1024 margin:0;
1048 1025 padding:0;
1049 1026 }
1050 1027
1051 1028 #content div.box table th {
1052 1029 background:#eee;
1053 1030 border-bottom:1px solid #ddd;
1054 1031 padding:5px 0px 5px 5px;
1055 1032 }
1056 1033
1057 1034 #content div.box table th.left {
1058 1035 text-align:left;
1059 1036 }
1060 1037
1061 1038 #content div.box table th.right {
1062 1039 text-align:right;
1063 1040 }
1064 1041
1065 1042 #content div.box table th.center {
1066 1043 text-align:center;
1067 1044 }
1068 1045
1069 1046 #content div.box table th.selected {
1070 1047 vertical-align:middle;
1071 1048 padding:0;
1072 1049 }
1073 1050
1074 1051 #content div.box table td {
1075 1052 background:#fff;
1076 1053 border-bottom:1px solid #cdcdcd;
1077 1054 vertical-align:middle;
1078 1055 padding:5px;
1079 1056 }
1080 1057
1081 1058 #content div.box table tr.selected td {
1082 1059 background:#FFC;
1083 1060 }
1084 1061
1085 1062 #content div.box table td.selected {
1086 1063 width:3%;
1087 1064 text-align:center;
1088 1065 vertical-align:middle;
1089 1066 padding:0;
1090 1067 }
1091 1068
1092 1069 #content div.box table td.action {
1093 1070 width:45%;
1094 1071 text-align:left;
1095 1072 }
1096 1073
1097 1074 #content div.box table td.date {
1098 1075 width:33%;
1099 1076 text-align:center;
1100 1077 }
1101 1078
1102 1079 #content div.box div.action {
1103 1080 float:right;
1104 1081 background:#FFF;
1105 1082 text-align:right;
1106 1083 margin:10px 0 0;
1107 1084 padding:0;
1108 1085 }
1109 1086
1110 1087 #content div.box div.action select {
1111 1088 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1112 1089 font-size:11px;
1113 1090 margin:0;
1114 1091 }
1115 1092
1116 1093 #content div.box div.action .ui-selectmenu {
1117 1094 margin:0;
1118 1095 padding:0;
1119 1096 }
1120 1097
1121 1098 #content div.box div.pagination {
1122 1099 height:1%;
1123 1100 clear:both;
1124 1101 overflow:hidden;
1125 1102 margin:10px 0 0;
1126 1103 padding:0;
1127 1104 }
1128 1105
1129 1106 #content div.box div.pagination ul.pager {
1130 1107 float:right;
1131 1108 text-align:right;
1132 1109 margin:0;
1133 1110 padding:0;
1134 1111 }
1135 1112
1136 1113 #content div.box div.pagination ul.pager li {
1137 1114 height:1%;
1138 1115 float:left;
1139 1116 list-style:none;
1140 1117 background:#ebebeb url("../images/pager.png") repeat-x;
1141 1118 border-top:1px solid #dedede;
1142 1119 border-left:1px solid #cfcfcf;
1143 1120 border-right:1px solid #c4c4c4;
1144 1121 border-bottom:1px solid #c4c4c4;
1145 1122 color:#4A4A4A;
1146 1123 font-weight:700;
1147 1124 margin:0 0 0 4px;
1148 1125 padding:0;
1149 1126 }
1150 1127
1151 1128 #content div.box div.pagination ul.pager li.separator {
1152 1129 padding:6px;
1153 1130 }
1154 1131
1155 1132 #content div.box div.pagination ul.pager li.current {
1156 1133 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1157 1134 border-top:1px solid #ccc;
1158 1135 border-left:1px solid #bebebe;
1159 1136 border-right:1px solid #b1b1b1;
1160 1137 border-bottom:1px solid #afafaf;
1161 1138 color:#515151;
1162 1139 padding:6px;
1163 1140 }
1164 1141
1165 1142 #content div.box div.pagination ul.pager li a {
1166 1143 height:1%;
1167 1144 display:block;
1168 1145 float:left;
1169 1146 color:#515151;
1170 1147 text-decoration:none;
1171 1148 margin:0;
1172 1149 padding:6px;
1173 1150 }
1174 1151
1175 1152 #content div.box div.pagination ul.pager li a:hover,#content div.box div.pagination ul.pager li a:active {
1176 1153 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1177 1154 border-top:1px solid #ccc;
1178 1155 border-left:1px solid #bebebe;
1179 1156 border-right:1px solid #b1b1b1;
1180 1157 border-bottom:1px solid #afafaf;
1181 1158 margin:-1px;
1182 1159 }
1183 1160
1184 1161 #content div.box div.pagination-wh {
1185 1162 height:1%;
1186 1163 clear:both;
1187 1164 overflow:hidden;
1188 1165 text-align:right;
1189 1166 margin:10px 0 0;
1190 1167 padding:0;
1191 1168 }
1192 1169
1193 1170 #content div.box div.pagination-right {
1194 1171 float:right;
1195 1172 }
1196 1173
1197 1174 #content div.box div.pagination-wh a,#content div.box div.pagination-wh span.pager_dotdot {
1198 1175 height:1%;
1199 1176 float:left;
1200 1177 background:#ebebeb url("../images/pager.png") repeat-x;
1201 1178 border-top:1px solid #dedede;
1202 1179 border-left:1px solid #cfcfcf;
1203 1180 border-right:1px solid #c4c4c4;
1204 1181 border-bottom:1px solid #c4c4c4;
1205 1182 color:#4A4A4A;
1206 1183 font-weight:700;
1207 1184 margin:0 0 0 4px;
1208 1185 padding:6px;
1209 1186 }
1210 1187
1211 1188 #content div.box div.pagination-wh span.pager_curpage {
1212 1189 height:1%;
1213 1190 float:left;
1214 1191 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1215 1192 border-top:1px solid #ccc;
1216 1193 border-left:1px solid #bebebe;
1217 1194 border-right:1px solid #b1b1b1;
1218 1195 border-bottom:1px solid #afafaf;
1219 1196 color:#515151;
1220 1197 font-weight:700;
1221 1198 margin:0 0 0 4px;
1222 1199 padding:6px;
1223 1200 }
1224 1201
1225 1202 #content div.box div.pagination-wh a:hover,#content div.box div.pagination-wh a:active {
1226 1203 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1227 1204 border-top:1px solid #ccc;
1228 1205 border-left:1px solid #bebebe;
1229 1206 border-right:1px solid #b1b1b1;
1230 1207 border-bottom:1px solid #afafaf;
1231 1208 text-decoration:none;
1232 1209 }
1233 1210
1234 1211 #content div.box div.traffic div.legend {
1235 1212 clear:both;
1236 1213 overflow:hidden;
1237 1214 border-bottom:1px solid #ddd;
1238 1215 margin:0 0 10px;
1239 1216 padding:0 0 10px;
1240 1217 }
1241 1218
1242 1219 #content div.box div.traffic div.legend h6 {
1243 1220 float:left;
1244 1221 border:none;
1245 1222 margin:0;
1246 1223 padding:0;
1247 1224 }
1248 1225
1249 1226 #content div.box div.traffic div.legend li {
1250 1227 list-style:none;
1251 1228 float:left;
1252 1229 font-size:11px;
1253 1230 margin:0;
1254 1231 padding:0 8px 0 4px;
1255 1232 }
1256 1233
1257 1234 #content div.box div.traffic div.legend li.visits {
1258 1235 border-left:12px solid #edc240;
1259 1236 }
1260 1237
1261 1238 #content div.box div.traffic div.legend li.pageviews {
1262 1239 border-left:12px solid #afd8f8;
1263 1240 }
1264 1241
1265 1242 #content div.box div.traffic table {
1266 1243 width:auto;
1267 1244 }
1268 1245
1269 1246 #content div.box div.traffic table td {
1270 1247 background:transparent;
1271 1248 border:none;
1272 1249 padding:2px 3px 3px;
1273 1250 }
1274 1251
1275 1252 #content div.box div.traffic table td.legendLabel {
1276 1253 padding:0 3px 2px;
1277 1254 }
1278 1255
1279 1256 #footer {
1280 1257 clear:both;
1281 1258 overflow:hidden;
1282 1259 text-align:right;
1283 1260 margin:0;
1284 1261 padding:0 30px 4px;
1285 1262 margin:-10px 0 0;
1286 1263 }
1287 1264
1288 1265 #footer div#footer-inner {
1289 1266 background:url("../images/header_inner.png") repeat-x scroll 0 0 #003367;
1290 1267 border-top:2px solid #FFFFFF;
1291 1268 }
1292 1269
1293 1270 #footer div#footer-inner p {
1294 1271 padding:15px 25px 15px 0;
1295 1272 color:#FFF;
1296 1273 font-weight:700;
1297 1274 }
1298 1275 #footer div#footer-inner .footer-link {
1299 1276 float:left;
1300 1277 padding-left:10px;
1301 1278 }
1302 1279 #footer div#footer-inner .footer-link a {
1303 1280 color:#FFF;
1304 1281 }
1305 1282
1306 1283 #login div.title {
1307 1284 width:420px;
1308 1285 clear:both;
1309 1286 overflow:hidden;
1310 1287 position:relative;
1311 1288 background:#003367 url("../../images/header_inner.png") repeat-x;
1312 1289 margin:0 auto;
1313 1290 padding:0;
1314 1291 }
1315 1292
1316 1293 #login div.inner {
1317 1294 width:380px;
1318 1295 background:#FFF url("../images/login.png") no-repeat top left;
1319 1296 border-top:none;
1320 1297 border-bottom:none;
1321 1298 margin:0 auto;
1322 1299 padding:20px;
1323 1300 }
1324 1301
1325 1302 #login div.form div.fields div.field div.label {
1326 1303 width:173px;
1327 1304 float:left;
1328 1305 text-align:right;
1329 1306 margin:2px 10px 0 0;
1330 1307 padding:5px 0 0 5px;
1331 1308 }
1332 1309
1333 1310 #login div.form div.fields div.field div.input input {
1334 1311 width:176px;
1335 1312 background:#FFF;
1336 1313 border-top:1px solid #b3b3b3;
1337 1314 border-left:1px solid #b3b3b3;
1338 1315 border-right:1px solid #eaeaea;
1339 1316 border-bottom:1px solid #eaeaea;
1340 1317 color:#000;
1341 1318 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1342 1319 font-size:11px;
1343 1320 margin:0;
1344 1321 padding:7px 7px 6px;
1345 1322 }
1346 1323
1347 1324 #login div.form div.fields div.buttons {
1348 1325 clear:both;
1349 1326 overflow:hidden;
1350 1327 border-top:1px solid #DDD;
1351 1328 text-align:right;
1352 1329 margin:0;
1353 1330 padding:10px 0 0;
1354 1331 }
1355 1332
1356 1333 #login div.form div.links {
1357 1334 clear:both;
1358 1335 overflow:hidden;
1359 1336 margin:10px 0 0;
1360 1337 padding:0 0 2px;
1361 1338 }
1362 1339
1363 1340 #register div.title {
1364 1341 clear:both;
1365 1342 overflow:hidden;
1366 1343 position:relative;
1367 1344 background:#003367 url("../images/header_inner.png") repeat-x;
1368 1345 margin:0 auto;
1369 1346 padding:0;
1370 1347 }
1371 1348
1372 1349 #register div.inner {
1373 1350 background:#FFF;
1374 1351 border-top:none;
1375 1352 border-bottom:none;
1376 1353 margin:0 auto;
1377 1354 padding:20px;
1378 1355 }
1379 1356
1380 1357 #register div.form div.fields div.field div.label {
1381 1358 width:135px;
1382 1359 float:left;
1383 1360 text-align:right;
1384 1361 margin:2px 10px 0 0;
1385 1362 padding:5px 0 0 5px;
1386 1363 }
1387 1364
1388 1365 #register div.form div.fields div.field div.input input {
1389 1366 width:300px;
1390 1367 background:#FFF;
1391 1368 border-top:1px solid #b3b3b3;
1392 1369 border-left:1px solid #b3b3b3;
1393 1370 border-right:1px solid #eaeaea;
1394 1371 border-bottom:1px solid #eaeaea;
1395 1372 color:#000;
1396 1373 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1397 1374 font-size:11px;
1398 1375 margin:0;
1399 1376 padding:7px 7px 6px;
1400 1377 }
1401 1378
1402 1379 #register div.form div.fields div.buttons {
1403 1380 clear:both;
1404 1381 overflow:hidden;
1405 1382 border-top:1px solid #DDD;
1406 1383 text-align:left;
1407 1384 margin:0;
1408 1385 padding:10px 0 0 150px;
1409 1386 }
1410 1387
1411 #register div.form div.fields div.buttons div.highlight input.ui-state-default {
1388 #register div.form div.fields div.buttons div.highlight input.ui-button {
1412 1389 background:url("../images/button_highlight.png") repeat-x scroll 0 0 #4E85BB;
1413 1390 color:#FFF;
1414 1391 border-color:#5C91A4 #2B7089 #1A6480 #2A6F89;
1415 1392 border-style:solid;
1416 1393 border-width:1px;
1417 1394 }
1418 1395
1419 1396 #register div.form div.activation_msg {
1420 1397 padding-top:4px;
1421 1398 padding-bottom:4px;
1422 1399 }
1423 1400
1424 1401 .trending_language_tbl,.trending_language_tbl td {
1425 1402 border:0 !important;
1426 1403 margin:0 !important;
1427 1404 padding:0 !important;
1428 1405 }
1429 1406
1430 1407 .trending_language {
1431 1408 background-color:#003367;
1432 1409 color:#FFF;
1433 1410 display:block;
1434 1411 min-width:20px;
1435 1412 text-decoration:none;
1436 1413 height:12px;
1437 1414 margin-bottom:4px;
1438 1415 margin-left:5px;
1439 1416 white-space:pre;
1440 1417 padding:3px;
1441 1418 }
1442 1419
1443 1420 h3.files_location {
1444 1421 font-size:1.8em;
1445 1422 font-weight:700;
1446 1423 border-bottom:none !important;
1447 1424 margin:10px 0 !important;
1448 1425 }
1449 1426
1450 1427 #files_data dl dt {
1451 1428 float:left;
1452 1429 width:115px;
1453 1430 margin:0 !important;
1454 1431 padding:5px;
1455 1432 }
1456 1433
1457 1434 #files_data dl dd {
1458 1435 margin:0 !important;
1459 1436 padding:5px !important;
1460 1437 }
1461 1438
1462 1439 #changeset_content {
1463 1440 border:1px solid #CCC;
1464 1441 padding:5px;
1465 1442 }
1466 1443
1467 1444 #changeset_content .container {
1468 1445 min-height:120px;
1469 1446 font-size:1.2em;
1470 1447 overflow:hidden;
1471 1448 }
1472 1449
1473 1450 #changeset_content .container .right {
1474 1451 float:right;
1475 1452 width:25%;
1476 1453 text-align:right;
1477 1454 }
1478 1455
1479 1456 #changeset_content .container .left .message {
1480 1457 font-style:italic;
1481 1458 color:#556CB5;
1482 1459 white-space:pre-wrap;
1483 1460 }
1484 1461
1485 1462 .cs_files .cs_added {
1486 1463 background:url("../images/icons/page_white_add.png") no-repeat scroll 3px;
1487 1464 height:16px;
1488 1465 padding-left:20px;
1489 1466 margin-top:7px;
1490 1467 text-align:left;
1491 1468 }
1492 1469
1493 1470 .cs_files .cs_changed {
1494 1471 background:url("../images/icons/page_white_edit.png") no-repeat scroll 3px;
1495 1472 height:16px;
1496 1473 padding-left:20px;
1497 1474 margin-top:7px;
1498 1475 text-align:left;
1499 1476 }
1500 1477
1501 1478 .cs_files .cs_removed {
1502 1479 background:url("../images/icons/page_white_delete.png") no-repeat scroll 3px;
1503 1480 height:16px;
1504 1481 padding-left:20px;
1505 1482 margin-top:7px;
1506 1483 text-align:left;
1507 1484 }
1508 1485
1509 1486 #graph {
1510 1487 overflow:hidden;
1511 1488 }
1512 1489
1513 1490 #graph_nodes {
1514 1491 width:160px;
1515 1492 float:left;
1516 1493 margin-left:-50px;
1517 1494 margin-top:5px;
1518 1495 }
1519 1496
1520 1497 #graph_content {
1521 1498 width:800px;
1522 1499 float:left;
1523 1500 }
1524 1501
1525 1502 #graph_content .container_header {
1526 1503 border:1px solid #CCC;
1527 1504 padding:10px;
1528 1505 }
1529 1506
1530 1507 #graph_content .container {
1531 1508 border-bottom:1px solid #CCC;
1532 1509 border-left:1px solid #CCC;
1533 1510 border-right:1px solid #CCC;
1534 1511 min-height:80px;
1535 1512 overflow:hidden;
1536 1513 font-size:1.2em;
1537 1514 }
1538 1515
1539 1516 #graph_content .container .right {
1540 1517 float:right;
1541 1518 width:28%;
1542 1519 text-align:right;
1543 1520 padding-bottom:5px;
1544 1521 }
1545 1522
1546 1523 #graph_content .container .left .date {
1547 1524 font-weight:700;
1548 1525 padding-bottom:5px;
1549 1526 }
1550 1527
1551 1528 #graph_content .container .left .message {
1552 1529 font-size:100%;
1553 1530 padding-top:3px;
1554 1531 white-space:pre-wrap;
1555 1532 }
1556 1533
1557 1534 .right div {
1558 1535 clear:both;
1559 1536 }
1560 1537
1561 1538 .right .changes .added,.changed,.removed {
1562 1539 border:1px solid #DDD;
1563 1540 display:block;
1564 1541 float:right;
1565 1542 text-align:center;
1566 1543 min-width:15px;
1567 1544 cursor: help;
1568 1545 }
1569 1546
1570 1547 .right .changes .added {
1571 1548 background:#BFB;
1572 1549 }
1573 1550
1574 1551 .right .changes .changed {
1575 1552 background:#FD8;
1576 1553 }
1577 1554
1578 1555 .right .changes .removed {
1579 1556 background:#F88;
1580 1557 }
1581 1558
1582 1559 .right .merge {
1583 1560 vertical-align:top;
1584 1561 font-size:0.75em;
1585 1562 font-weight:700;
1586 1563 }
1587 1564
1588 1565 .right .parent {
1589 1566 font-size:90%;
1590 1567 font-family:monospace;
1591 1568 }
1592 1569
1593 1570 .right .logtags .branchtag {
1594 1571 background:#FFF url("../images/icons/arrow_branch.png") no-repeat right 6px;
1595 1572 display:block;
1596 1573 font-size:0.8em;
1597 1574 padding:11px 16px 0 0;
1598 1575 }
1599 1576
1600 1577 .right .logtags .tagtag {
1601 1578 background:#FFF url("../images/icons/tag_blue.png") no-repeat right 6px;
1602 1579 display:block;
1603 1580 font-size:0.8em;
1604 1581 padding:11px 16px 0 0;
1605 1582 }
1606 1583
1607 1584 div.browserblock {
1608 1585 overflow:hidden;
1609 1586 border:1px solid #ccc;
1610 1587 background:#f8f8f8;
1611 1588 font-size:100%;
1612 1589 line-height:125%;
1613 1590 padding:0;
1614 1591 }
1615 1592
1616 1593 div.browserblock .browser-header {
1617 border-bottom:1px solid #CCC;
1618 1594 background:#FFF;
1619 color:blue;
1620 1595 padding:10px 0;
1596 float:left;
1597 }
1598
1599 div.browserblock .browser-branch {
1600 background:#FFF;
1601 padding:20px 0 0 0;
1602 float:left;
1603 }
1604 div.browserblock .browser-branch label {
1605 color:#4A4A4A;
1621 1606 }
1622 1607
1623 1608 div.browserblock .browser-header span {
1624 1609 margin-left:25px;
1625 1610 font-weight:700;
1626 1611 }
1627 1612
1628 1613 div.browserblock .browser-body {
1629 1614 background:#EEE;
1615 border-top:1px solid #CCC;
1630 1616 }
1631 1617
1632 1618 table.code-browser {
1633 1619 border-collapse:collapse;
1634 1620 width:100%;
1635 1621 }
1636 1622
1637 1623 table.code-browser tr {
1638 1624 margin:3px;
1639 1625 }
1640 1626
1641 1627 table.code-browser thead th {
1642 1628 background-color:#EEE;
1643 1629 height:20px;
1644 1630 font-size:1.1em;
1645 1631 font-weight:700;
1646 1632 text-align:left;
1647 1633 padding-left:10px;
1648 1634 }
1649 1635
1650 1636 table.code-browser tbody td {
1651 1637 padding-left:10px;
1652 1638 height:20px;
1653 1639 }
1654 1640
1655 1641 table.code-browser .browser-file {
1656 1642 background:url("../images/icons/document_16.png") no-repeat scroll 3px;
1657 1643 height:16px;
1658 1644 padding-left:20px;
1659 1645 text-align:left;
1660 1646 }
1661 1647 .diffblock .changeset_file{
1662 1648 background:url("../images/icons/file.png") no-repeat scroll 3px;
1663 1649 height:16px;
1664 1650 padding-left:22px;
1665 1651 text-align:left;
1666 1652 font-size: 14px;
1667 1653 }
1668 1654
1669 1655 .diffblock .changeset_header{
1670 1656 margin-left: 6px !important;
1671 1657 }
1672 1658
1673 1659 table.code-browser .browser-dir {
1674 1660 background:url("../images/icons/folder_16.png") no-repeat scroll 3px;
1675 1661 height:16px;
1676 1662 padding-left:20px;
1677 1663 text-align:left;
1678 1664 }
1679 1665
1680 1666 .box .search {
1681 1667 clear:both;
1682 1668 overflow:hidden;
1683 1669 margin:0;
1684 1670 padding:0 20px 10px;
1685 1671 }
1686 1672
1687 1673 .box .search div.search_path {
1688 1674 background:none repeat scroll 0 0 #EEE;
1689 1675 border:1px solid #CCC;
1690 1676 color:blue;
1691 1677 margin-bottom:10px;
1692 1678 padding:10px 0;
1693 1679 }
1694 1680
1695 1681 .box .search div.search_path div.link {
1696 1682 font-weight:700;
1697 1683 margin-left:25px;
1698 1684 }
1699 1685
1700 1686 .box .search div.search_path div.link a {
1701 1687 color:#003367;
1702 1688 cursor:pointer;
1703 1689 text-decoration:none;
1704 1690 }
1705 1691
1706 1692 #path_unlock {
1707 1693 color:red;
1708 1694 font-size:1.2em;
1709 1695 padding-left:4px;
1710 1696 }
1711 1697
1712 1698 .info_box * {
1713 1699 background:url("../../images/pager.png") repeat-x scroll 0 0 #EBEBEB;
1714 1700 color:#4A4A4A;
1715 1701 font-weight:700;
1716 1702 height:1%;
1717 1703 display:inline;
1718 1704 border-color:#DEDEDE #C4C4C4 #C4C4C4 #CFCFCF;
1719 1705 border-style:solid;
1720 1706 border-width:1px;
1721 1707 padding:4px 6px;
1722 1708 }
1723 1709
1724 1710 .info_box span {
1725 1711 margin-left:3px;
1726 1712 margin-right:3px;
1727 1713 }
1728 1714
1729 1715 .info_box input#at_rev {
1730 1716 text-align:center;
1731 1717 padding:5px 3px 3px 2px;
1732 1718 }
1733 1719
1734 1720 .info_box input#view {
1735 1721 text-align:center;
1736 1722 padding:4px 3px 2px 2px;
1737 1723 }
1738 1724
1739 1725 .yui-overlay,.yui-panel-container {
1740 1726 visibility:hidden;
1741 1727 position:absolute;
1742 1728 z-index:2;
1743 1729 }
1744 1730
1745 1731 .yui-tt {
1746 1732 visibility:hidden;
1747 1733 position:absolute;
1748 1734 color:#666;
1749 1735 background-color:#FFF;
1750 1736 font-family:arial, helvetica, verdana, sans-serif;
1751 1737 border:2px solid #003367;
1752 1738 font:100% sans-serif;
1753 1739 width:auto;
1754 1740 opacity:1px;
1755 1741 padding:8px;
1756 1742 white-space: pre;
1743 -webkit-border-radius: 8px 8px 8px 8px;
1744 -khtml-border-radius: 8px 8px 8px 8px;
1745 -moz-border-radius: 8px 8px 8px 8px;
1746 border-radius: 8px 8px 8px 8px;
1757 1747 }
1758 1748
1759 1749 .ac {
1760 1750 vertical-align:top;
1761 1751 }
1762 1752
1763 1753 .ac .yui-ac {
1764 1754 position:relative;
1765 1755 font-family:arial;
1766 1756 font-size:100%;
1767 1757 }
1768 1758
1769 1759 .ac .perm_ac {
1770 1760 width:15em;
1771 1761 }
1772 1762
1773 1763 .ac .yui-ac-input {
1774 1764 width:100%;
1775 1765 }
1776 1766
1777 1767 .ac .yui-ac-container {
1778 1768 position:absolute;
1779 1769 top:1.6em;
1780 1770 width:100%;
1781 1771 }
1782 1772
1783 1773 .ac .yui-ac-content {
1784 1774 position:absolute;
1785 1775 width:100%;
1786 1776 border:1px solid gray;
1787 1777 background:#fff;
1788 1778 overflow:hidden;
1789 1779 z-index:9050;
1790 1780 }
1791 1781
1792 1782 .ac .yui-ac-shadow {
1793 1783 position:absolute;
1794 1784 width:100%;
1795 1785 background:#000;
1796 1786 -moz-opacity:0.1px;
1797 1787 opacity:.10;
1798 1788 filter:alpha(opacity = 10);
1799 1789 z-index:9049;
1800 1790 margin:.3em;
1801 1791 }
1802 1792
1803 1793 .ac .yui-ac-content ul {
1804 1794 width:100%;
1805 1795 margin:0;
1806 1796 padding:0;
1807 1797 }
1808 1798
1809 1799 .ac .yui-ac-content li {
1810 1800 cursor:default;
1811 1801 white-space:nowrap;
1812 1802 margin:0;
1813 1803 padding:2px 5px;
1814 1804 }
1815 1805
1816 1806 .ac .yui-ac-content li.yui-ac-prehighlight {
1817 1807 background:#B3D4FF;
1818 1808 }
1819 1809
1820 1810 .ac .yui-ac-content li.yui-ac-highlight {
1821 1811 background:#556CB5;
1822 1812 color:#FFF;
1823 1813 }
1824 1814
1825 1815 .follow{
1826 1816 background:url("../images/icons/heart_add.png") no-repeat scroll 3px;
1827 1817 height: 16px;
1828 1818 width: 20px;
1829 1819 cursor: pointer;
1830 1820 display: block;
1831 1821 float: right;
1832 1822 margin-top: 2px;
1833 1823 }
1834 1824
1835 1825 .following{
1836 1826 background:url("../images/icons/heart_delete.png") no-repeat scroll 3px;
1837 1827 height: 16px;
1838 1828 width: 20px;
1839 1829 cursor: pointer;
1840 1830 display: block;
1841 1831 float: right;
1842 1832 margin-top: 2px;
1843 1833 }
1844 1834
1845 1835 .currently_following{
1846 1836 padding-left: 10px;
1847 1837 padding-bottom:5px;
1848 1838 }
1849 1839
1850 1840 .journal_highlight{
1851 1841 font-weight: bold;
1852 1842 text-decoration: underline;
1853 1843 }
1854 1844
1855 1845 .add_icon {
1856 1846 background:url("../images/icons/add.png") no-repeat scroll 3px;
1857 1847 height:16px;
1858 1848 padding-left:20px;
1859 1849 padding-top:1px;
1860 1850 text-align:left;
1861 1851 }
1862 1852
1863 1853 .edit_icon {
1864 1854 background:url("../images/icons/folder_edit.png") no-repeat scroll 3px;
1865 1855 height:16px;
1866 1856 padding-left:20px;
1867 1857 padding-top:1px;
1868 1858 text-align:left;
1869 1859 }
1870 1860
1871 1861 .delete_icon {
1872 1862 background:url("../images/icons/delete.png") no-repeat scroll 3px;
1873 1863 height:16px;
1874 1864 padding-left:20px;
1875 1865 padding-top:1px;
1876 1866 text-align:left;
1877 1867 }
1878 1868
1879 1869 .refresh_icon {
1880 1870 background:url("../images/icons/arrow_refresh.png") no-repeat scroll 3px;
1881 1871 height:16px;
1882 1872 padding-left:20px;
1883 1873 padding-top:1px;
1884 1874 text-align:left;
1885 1875 }
1886 1876
1887 1877 .rss_icon {
1888 1878 background:url("../images/icons/rss_16.png") no-repeat scroll 3px;
1889 1879 height:16px;
1890 1880 padding-left:20px;
1891 1881 padding-top:1px;
1892 1882 text-align:left;
1893 1883 }
1894 1884
1895 1885 .atom_icon {
1896 1886 background:url("../images/icons/atom.png") no-repeat scroll 3px;
1897 1887 height:16px;
1898 1888 padding-left:20px;
1899 1889 padding-top:1px;
1900 1890 text-align:left;
1901 1891 }
1902 1892
1903 1893 .archive_icon {
1904 1894 background:url("../images/icons/compress.png") no-repeat scroll 3px;
1905 1895 height:16px;
1906 1896 padding-left:20px;
1907 1897 text-align:left;
1908 1898 padding-top:1px;
1909 1899 }
1910 1900
1911 1901 .action_button {
1912 1902 border:0;
1913 1903 display:block;
1914 1904 }
1915 1905
1916 1906 .action_button:hover {
1917 1907 border:0;
1918 1908 text-decoration:underline;
1919 1909 cursor:pointer;
1920 1910 }
1921 1911
1922 1912 #switch_repos {
1923 1913 position:absolute;
1924 1914 height:25px;
1925 1915 z-index:1;
1926 1916 }
1927 1917
1928 1918 #switch_repos select {
1929 1919 min-width:150px;
1930 1920 max-height:250px;
1931 1921 z-index:1;
1932 1922 }
1933 1923
1934 1924 .breadcrumbs {
1935 1925 border:medium none;
1936 1926 color:#FFF;
1937 1927 float:left;
1938 1928 text-transform:uppercase;
1939 1929 font-weight:700;
1940 1930 font-size:14px;
1941 1931 margin:0;
1942 1932 padding:11px 0 11px 10px;
1943 1933 }
1944 1934
1945 1935 .breadcrumbs a {
1946 1936 color:#FFF;
1947 1937 }
1948 1938
1949 1939 .flash_msg ul {
1950 1940 margin:0;
1951 1941 padding:0 0 10px;
1952 1942 }
1953 1943
1954 1944 .error_msg {
1955 1945 background-color:#FFCFCF;
1956 1946 background-image:url("../../images/icons/error_msg.png");
1957 1947 border:1px solid #FF9595;
1958 1948 color:#C30;
1959 1949 }
1960 1950
1961 1951 .warning_msg {
1962 1952 background-color:#FFFBCC;
1963 1953 background-image:url("../../images/icons/warning_msg.png");
1964 1954 border:1px solid #FFF35E;
1965 1955 color:#C69E00;
1966 1956 }
1967 1957
1968 1958 .success_msg {
1969 1959 background-color:#D5FFCF;
1970 1960 background-image:url("../../images/icons/success_msg.png");
1971 1961 border:1px solid #97FF88;
1972 1962 color:#090;
1973 1963 }
1974 1964
1975 1965 .notice_msg {
1976 1966 background-color:#DCE3FF;
1977 1967 background-image:url("../../images/icons/notice_msg.png");
1978 1968 border:1px solid #93A8FF;
1979 1969 color:#556CB5;
1980 1970 }
1981 1971
1982 1972 .success_msg,.error_msg,.notice_msg,.warning_msg {
1983 1973 background-position:10px center;
1984 1974 background-repeat:no-repeat;
1985 1975 font-size:12px;
1986 1976 font-weight:700;
1987 1977 min-height:14px;
1988 1978 line-height:14px;
1989 1979 margin-bottom:0;
1990 1980 margin-top:0;
1991 1981 display:block;
1992 1982 overflow:auto;
1993 1983 padding:6px 10px 6px 40px;
1994 1984 }
1995 1985
1996 1986 #msg_close {
1997 1987 background:transparent url("../../icons/cross_grey_small.png") no-repeat scroll 0 0;
1998 1988 cursor:pointer;
1999 1989 height:16px;
2000 1990 position:absolute;
2001 1991 right:5px;
2002 1992 top:5px;
2003 1993 width:16px;
2004 1994 }
2005 1995
2006 1996 div#legend_container table,div#legend_choices table {
2007 1997 width:auto !important;
2008 1998 }
2009 1999
2010 2000 table#permissions_manage {
2011 2001 width:0 !important;
2012 2002 }
2013 2003
2014 2004 table#permissions_manage span.private_repo_msg {
2015 2005 font-size:0.8em;
2016 2006 opacity:0.6px;
2017 2007 }
2018 2008
2019 2009 table#permissions_manage td.private_repo_msg {
2020 2010 font-size:0.8em;
2021 2011 }
2022 2012
2023 2013 table#permissions_manage tr#add_perm_input td {
2024 2014 vertical-align:middle;
2025 2015 }
2026 2016
2027 2017 div.gravatar {
2028 2018 background-color:#FFF;
2029 2019 border:1px solid #D0D0D0;
2030 2020 float:left;
2031 2021 margin-right:0.7em;
2032 2022 padding:2px 2px 0;
2033 2023 }
2034 2024
2035 2025 #header,#content,#footer {
2036 2026 min-width:1024px;
2037 2027 }
2038 2028
2039 2029 #content {
2040 2030 min-height:100%;
2041 2031 clear:both;
2042 2032 overflow:hidden;
2043 2033 padding:14px 30px;
2044 2034 }
2045 2035
2046 2036 #content div.box div.title div.search {
2047 2037 background:url("../../images/title_link.png") no-repeat top left;
2048 2038 border-left:1px solid #316293;
2049 2039 }
2050 2040
2051 2041 #content div.box div.title div.search div.input input {
2052 2042 border:1px solid #316293;
2053 2043 }
2054 2044
2055 #content div.box div.title div.search div.button input.ui-state-default {
2045 #content div.box div.title div.search div.button input.ui-button {
2056 2046 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
2057 2047 border:1px solid #316293;
2058 2048 border-left:none;
2059 2049 color:#FFF;
2060 2050 }
2061 2051
2062 2052 #content div.box div.title div.search div.button input.ui-state-hover {
2063 2053 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
2064 2054 border:1px solid #316293;
2065 2055 border-left:none;
2066 2056 color:#FFF;
2067 2057 }
2068 2058
2069 #content div.box div.form div.fields div.field div.highlight .ui-state-default {
2059 #content div.box div.form div.fields div.field div.highlight .ui-button {
2070 2060 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
2071 2061 border-top:1px solid #5c91a4;
2072 2062 border-left:1px solid #2a6f89;
2073 2063 border-right:1px solid #2b7089;
2074 2064 border-bottom:1px solid #1a6480;
2075 2065 color:#fff;
2076 2066 }
2077 2067
2078 2068 #content div.box div.form div.fields div.field div.highlight .ui-state-hover {
2079 2069 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
2080 2070 border-top:1px solid #78acbf;
2081 2071 border-left:1px solid #34819e;
2082 2072 border-right:1px solid #35829f;
2083 2073 border-bottom:1px solid #257897;
2084 2074 color:#fff;
2085 2075 }
2086 2076
2087 2077 ins,div.options a:hover {
2088 2078 text-decoration:none;
2089 2079 }
2090 2080
2091 2081 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 {
2092 2082 border:none;
2093 2083 }
2094 2084
2095 2085 img.icon,.right .merge img {
2096 2086 vertical-align:bottom;
2097 2087 }
2098 2088
2099 2089 #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 {
2100 2090 float:right;
2101 2091 margin:0;
2102 2092 padding:0;
2103 2093 }
2104 2094
2105 2095 #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 {
2106 2096 float:left;
2107 2097 }
2108 2098
2109 2099 #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 {
2110 2100 display:none;
2111 2101 }
2112 2102
2113 2103 #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 {
2114 2104 display:block;
2115 2105 }
2116 2106
2117 2107 #content div.box div.title ul.links li a:hover,#content div.box div.title ul.links li.ui-tabs-selected a {
2118 2108 color:#bfe3ff;
2119 2109 }
2120 2110
2121 2111 #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 {
2122 2112 margin:10px 24px 10px 44px;
2123 2113 }
2124 2114
2125 2115 #content div.box div.form,#content div.box div.table,#content div.box div.traffic {
2126 2116 clear:both;
2127 2117 overflow:hidden;
2128 2118 margin:0;
2129 2119 padding:0 20px 10px;
2130 2120 }
2131 2121
2132 2122 #content div.box div.form div.fields,#login div.form,#login div.form div.fields,#register div.form,#register div.form div.fields {
2133 2123 clear:both;
2134 2124 overflow:hidden;
2135 2125 margin:0;
2136 2126 padding:0;
2137 2127 }
2138 2128
2139 2129 #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 {
2140 2130 height:1%;
2141 2131 display:block;
2142 2132 color:#363636;
2143 2133 margin:0;
2144 2134 padding:2px 0 0;
2145 2135 }
2146 2136
2147 2137 #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 {
2148 2138 background:#FBE3E4;
2149 2139 border-top:1px solid #e1b2b3;
2150 2140 border-left:1px solid #e1b2b3;
2151 2141 border-right:1px solid #FBC2C4;
2152 2142 border-bottom:1px solid #FBC2C4;
2153 2143 }
2154 2144
2155 2145 #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 {
2156 2146 background:#E6EFC2;
2157 2147 border-top:1px solid #cebb98;
2158 2148 border-left:1px solid #cebb98;
2159 2149 border-right:1px solid #c6d880;
2160 2150 border-bottom:1px solid #c6d880;
2161 2151 }
2162 2152
2163 2153 #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 {
2164 2154 margin:0;
2165 2155 }
2166 2156
2167 2157 #content div.box-left div.form div.fields div.field div.select,#content div.box-left div.form div.fields div.field div.checkboxes,#content div.box-left div.form div.fields div.field div.radios,#content div.box-right div.form div.fields div.field div.select,#content div.box-right div.form div.fields div.field div.checkboxes,#content div.box-right div.form div.fields div.field div.radios{
2168 2158 margin:0 0 0 0px !important;
2169 2159 padding:0;
2170 2160 }
2171 2161
2172 2162 #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 {
2173 2163 margin:0 0 0 200px;
2174 2164 padding:0;
2175 2165 }
2176 2166
2177 2167
2178 2168 #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 {
2179 2169 color:#000;
2180 2170 text-decoration:none;
2181 2171 }
2182 2172
2183 2173 #content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus,#content div.box div.action a.ui-selectmenu-focus {
2184 2174 border:1px solid #666;
2185 2175 }
2186 2176
2187 2177 #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 {
2188 2178 clear:both;
2189 2179 overflow:hidden;
2190 2180 margin:0;
2191 2181 padding:8px 0 2px;
2192 2182 }
2193 2183
2194 2184 #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 {
2195 2185 float:left;
2196 2186 margin:0;
2197 2187 }
2198 2188
2199 2189 #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 {
2200 2190 height:1%;
2201 2191 display:block;
2202 2192 float:left;
2203 2193 margin:2px 0 0 4px;
2204 2194 }
2205 2195
2206 2196 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 {
2207 2197 color:#000;
2208 2198 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
2209 2199 font-size:11px;
2210 2200 font-weight:700;
2211 2201 margin:0;
2212 2202 }
2213 2203
2214 div.form div.fields div.field div.button .ui-state-default,#content div.box div.form div.fields div.buttons input.ui-state-default {
2204 div.form div.fields div.field div.button .ui-button,#content div.box div.form div.fields div.buttons input.ui-button {
2215 2205 background:#e5e3e3 url("../images/button.png") repeat-x;
2216 2206 border-top:1px solid #DDD;
2217 2207 border-left:1px solid #c6c6c6;
2218 2208 border-right:1px solid #DDD;
2219 2209 border-bottom:1px solid #c6c6c6;
2220 2210 color:#515151;
2221 2211 outline:none;
2222 2212 margin:0;
2223 2213 padding:6px 12px;
2224 2214 }
2225 2215
2226 2216 div.form div.fields div.field div.button .ui-state-hover,#content div.box div.form div.fields div.buttons input.ui-state-hover {
2227 2217 background:#b4b4b4 url("../images/button_selected.png") repeat-x;
2228 2218 border-top:1px solid #ccc;
2229 2219 border-left:1px solid #bebebe;
2230 2220 border-right:1px solid #b1b1b1;
2231 2221 border-bottom:1px solid #afafaf;
2232 2222 color:#515151;
2233 2223 outline:none;
2234 2224 margin:0;
2235 2225 padding:6px 12px;
2236 2226 }
2237 2227
2238 2228 div.form div.fields div.field div.highlight,#content div.box div.form div.fields div.buttons div.highlight {
2239 2229 display:inline;
2240 2230 }
2241 2231
2242 2232 #content div.box div.form div.fields div.buttons,div.form div.fields div.buttons {
2243 2233 margin:10px 0 0 200px;
2244 2234 padding:0;
2245 2235 }
2246 2236
2247 2237 #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 {
2248 2238 margin:10px 0 0;
2249 2239 }
2250 2240
2251 2241 #content div.box table td.user,#content div.box table td.address {
2252 2242 width:10%;
2253 2243 text-align:center;
2254 2244 }
2255 2245
2256 2246 #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 {
2257 2247 text-align:right;
2258 2248 margin:6px 0 0;
2259 2249 padding:0;
2260 2250 }
2261 2251
2262 #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 {
2252 #content div.box div.action div.button input.ui-button,#login div.form div.fields div.buttons input.ui-button,#register div.form div.fields div.buttons input.ui-button {
2263 2253 background:#e5e3e3 url("../images/button.png") repeat-x;
2264 2254 border-top:1px solid #DDD;
2265 2255 border-left:1px solid #c6c6c6;
2266 2256 border-right:1px solid #DDD;
2267 2257 border-bottom:1px solid #c6c6c6;
2268 2258 color:#515151;
2269 2259 margin:0;
2270 2260 padding:6px 12px;
2271 2261 }
2272 2262
2273 2263 #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 {
2274 2264 background:#b4b4b4 url("../images/button_selected.png") repeat-x;
2275 2265 border-top:1px solid #ccc;
2276 2266 border-left:1px solid #bebebe;
2277 2267 border-right:1px solid #b1b1b1;
2278 2268 border-bottom:1px solid #afafaf;
2279 2269 color:#515151;
2280 2270 margin:0;
2281 2271 padding:6px 12px;
2282 2272 }
2283 2273
2284 2274 #content div.box div.pagination div.results,#content div.box div.pagination-wh div.results {
2285 2275 text-align:left;
2286 2276 float:left;
2287 2277 margin:0;
2288 2278 padding:0;
2289 2279 }
2290 2280
2291 2281 #content div.box div.pagination div.results span,#content div.box div.pagination-wh div.results span {
2292 2282 height:1%;
2293 2283 display:block;
2294 2284 float:left;
2295 2285 background:#ebebeb url("../images/pager.png") repeat-x;
2296 2286 border-top:1px solid #dedede;
2297 2287 border-left:1px solid #cfcfcf;
2298 2288 border-right:1px solid #c4c4c4;
2299 2289 border-bottom:1px solid #c4c4c4;
2300 2290 color:#4A4A4A;
2301 2291 font-weight:700;
2302 2292 margin:0;
2303 2293 padding:6px 8px;
2304 2294 }
2305 2295
2306 2296 #content div.box div.pagination ul.pager li.disabled,#content div.box div.pagination-wh a.disabled {
2307 2297 color:#B4B4B4;
2308 2298 padding:6px;
2309 2299 }
2310 2300
2311 2301 #login,#register {
2312 2302 width:520px;
2313 2303 margin:10% auto 0;
2314 2304 padding:0;
2315 2305 }
2316 2306
2317 2307 #login div.color,#register div.color {
2318 2308 clear:both;
2319 2309 overflow:hidden;
2320 2310 background:#FFF;
2321 2311 margin:10px auto 0;
2322 2312 padding:3px 3px 3px 0;
2323 2313 }
2324 2314
2325 2315 #login div.color a,#register div.color a {
2326 2316 width:20px;
2327 2317 height:20px;
2328 2318 display:block;
2329 2319 float:left;
2330 2320 margin:0 0 0 3px;
2331 2321 padding:0;
2332 2322 }
2333 2323
2334 2324 #login div.title h5,#register div.title h5 {
2335 2325 color:#fff;
2336 2326 margin:10px;
2337 2327 padding:0;
2338 2328 }
2339 2329
2340 2330 #login div.form div.fields div.field,#register div.form div.fields div.field {
2341 2331 clear:both;
2342 2332 overflow:hidden;
2343 2333 margin:0;
2344 2334 padding:0 0 10px;
2345 2335 }
2346 2336
2347 2337 #login div.form div.fields div.field span.error-message,#register div.form div.fields div.field span.error-message {
2348 2338 height:1%;
2349 2339 display:block;
2350 2340 color:red;
2351 2341 margin:8px 0 0;
2352 2342 padding:0;
2353 2343 max-width: 320px;
2354 2344 }
2355 2345
2356 2346 #login div.form div.fields div.field div.label label,#register div.form div.fields div.field div.label label {
2357 2347 color:#000;
2358 2348 font-weight:700;
2359 2349 }
2360 2350
2361 2351 #login div.form div.fields div.field div.input,#register div.form div.fields div.field div.input {
2362 2352 float:left;
2363 2353 margin:0;
2364 2354 padding:0;
2365 2355 }
2366 2356
2367 2357 #login div.form div.fields div.field div.checkbox,#register div.form div.fields div.field div.checkbox {
2368 2358 margin:0 0 0 184px;
2369 2359 padding:0;
2370 2360 }
2371 2361
2372 2362 #login div.form div.fields div.field div.checkbox label,#register div.form div.fields div.field div.checkbox label {
2373 2363 color:#565656;
2374 2364 font-weight:700;
2375 2365 }
2376 2366
2377 2367 #login div.form div.fields div.buttons input,#register div.form div.fields div.buttons input {
2378 2368 color:#000;
2379 2369 font-size:1em;
2380 2370 font-weight:700;
2381 2371 font-family:Verdana, Helvetica, Sans-Serif;
2382 2372 margin:0;
2383 2373 }
2384 2374
2385 2375 #changeset_content .container .wrapper,#graph_content .container .wrapper {
2386 2376 width:600px;
2387 2377 }
2388 2378
2389 2379 #changeset_content .container .left,#graph_content .container .left {
2390 2380 float:left;
2391 2381 width:70%;
2392 2382 padding-left:5px;
2393 2383 }
2394 2384
2395 2385 #changeset_content .container .left .date,.ac .match {
2396 2386 font-weight:700;
2397 2387 padding-top: 5px;
2398 2388 padding-bottom:5px;
2399 2389 }
2400 2390
2401 2391 div#legend_container table td,div#legend_choices table td {
2402 2392 border:none !important;
2403 2393 height:20px !important;
2404 2394 padding:0 !important;
2405 2395 }
2406 2396
2407 2397 #q_filter{
2408 2398 border:0 none;
2409 2399 color:#AAAAAA;
2410 2400 margin-bottom:-4px;
2411 2401 margin-top:-4px;
2412 2402 padding-left:3px;
2413 2403 }
2414 2404
@@ -1,168 +1,168 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')}
31 31 <input class="top-right-rounded-corner top-left-rounded-corner bottom-left-rounded-corner bottom-right-rounded-corner" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/>
32 32 </h5>
33 33 %if c.rhodecode_user.username != 'default':
34 34 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
35 35 <ul class="links">
36 36 <li>
37 37 <span>${h.link_to(_('ADD NEW REPOSITORY'),h.url('admin_settings_create_repository'))}</span>
38 38 </li>
39 39 </ul>
40 40 %endif
41 41 %endif
42 42 </div>
43 43 <!-- end box / title -->
44 44 <div class="table">
45 45 <table>
46 46 <thead>
47 47 <tr>
48 48 <th class="left">${get_sort(_('Name'))}</th>
49 49 <th class="left">${get_sort(_('Description'))}</th>
50 50 <th class="left">${get_sort(_('Last change'))}</th>
51 51 <th class="left">${get_sort(_('Tip'))}</th>
52 52 <th class="left">${get_sort(_('Owner'))}</th>
53 53 <th class="left">${_('RSS')}</th>
54 54 <th class="left">${_('Atom')}</th>
55 55 </tr>
56 56 </thead>
57 57 <tbody>
58 58 %for cnt,repo in enumerate(c.repos_list):
59 59 <tr class="parity${cnt%2}">
60 60 <td>
61 61 <div style="white-space: nowrap">
62 62 ## TYPE OF REPO
63 63 %if repo['repo'].dbrepo.repo_type =='hg':
64 64 <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="/images/icons/hgicon.png"/>
65 65 %elif repo['repo'].dbrepo.repo_type =='git':
66 66 <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="/images/icons/giticon.png"/>
67 67 %else:
68 68
69 69 %endif
70 70
71 71 ##PRIVATE/PUBLIC
72 72 %if repo['repo'].dbrepo.private:
73 73 <img class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="/images/icons/lock.png"/>
74 74 %else:
75 75 <img class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="/images/icons/lock_open.png"/>
76 76 %endif
77 77
78 78 ##NAME
79 79 ${h.link_to(repo['name'],
80 80 h.url('summary_home',repo_name=repo['name']),class_="repo_name")}
81 81 %if repo['repo'].dbrepo.fork:
82 82 <a href="${h.url('summary_home',repo_name=repo['repo'].dbrepo.fork.repo_name)}">
83 83 <img class="icon" alt="${_('fork')}"
84 84 title="${_('Fork of')} ${repo['repo'].dbrepo.fork.repo_name}"
85 85 src="/images/icons/arrow_divide.png"/></a>
86 86 %endif
87 87 </div>
88 88 </td>
89 89 ##DESCRIPTION
90 <td><span class="tooltip" tooltip_title="${repo['description']}">
90 <td><span class="tooltip" tooltip_title="${h.tooltip(repo['description'])}">
91 91 ${h.truncate(repo['description'],60)}</span>
92 92 </td>
93 93 ##LAST CHANGE
94 94 <td>
95 95 <span class="tooltip" tooltip_title="${repo['last_change']}">
96 96 ${h.age(repo['last_change'])}</span>
97 97 </td>
98 98 <td>
99 99 %if repo['rev']>=0:
100 100 ${h.link_to('r%s:%s' % (repo['rev'],h.short_id(repo['tip'])),
101 101 h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']),
102 102 class_="tooltip",
103 103 tooltip_title=h.tooltip(repo['last_msg']))}
104 104 %else:
105 105 ${_('No changesets yet')}
106 106 %endif
107 107 </td>
108 108 <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
109 109 <td>
110 110 <a title="${_('Subscribe to %s rss feed')%repo['name']}" class="rss_icon" href="${h.url('rss_feed_home',repo_name=repo['name'])}"></a>
111 111 </td>
112 112 <td>
113 113 <a title="${_('Subscribe to %s atom feed')%repo['name']}" class="atom_icon" href="${h.url('atom_feed_home',repo_name=repo['name'])}"></a>
114 114 </td>
115 115 </tr>
116 116 %endfor
117 117 </tbody>
118 118 </table>
119 119 </div>
120 120 </div>
121 121
122 122
123 123 <script type="text/javascript">
124 124 var D = YAHOO.util.Dom;
125 125 var E = YAHOO.util.Event;
126 126 var S = YAHOO.util.Selector;
127 127
128 128 var q_filter = D.get('q_filter');
129 129 var F = YAHOO.namespace('q_filter');
130 130
131 131 E.on(q_filter,'click',function(){
132 132 q_filter.value = '';
133 133 });
134 134
135 135 F.filterTimeout = null;
136 136
137 137 F.updateFilter = function() {
138 138 // Reset timeout
139 139 F.filterTimeout = null;
140 140
141 141 var obsolete = [];
142 142 var nodes = S.query('div.table tr td div a.repo_name');
143 143 var req = D.get('q_filter').value;
144 144 for (n in nodes){
145 145 D.setStyle(nodes[n].parentNode.parentNode.parentNode,'display','')
146 146 }
147 147 if (req){
148 148 for (n in nodes){
149 149 if (nodes[n].innerHTML.toLowerCase().indexOf(req) == -1) {
150 150 obsolete.push(nodes[n]);
151 151 }
152 152 }
153 153 if(obsolete){
154 154 for (n in obsolete){
155 155 D.setStyle(obsolete[n].parentNode.parentNode.parentNode,'display','none');
156 156 }
157 157 }
158 158 }
159 159 }
160 160
161 161 E.on(q_filter,'keyup',function(e){
162 162 clearTimeout(F.filterTimeout);
163 163 setTimeout(F.updateFilter,600);
164 164 });
165 165
166 166 </script>
167 167
168 168 </%def>
@@ -1,202 +1,203 b''
1 1 ################################################################################
2 2 ################################################################################
3 3 # rhodecode - Pylons environment configuration #
4 4 # #
5 5 # The %(here)s variable will be replaced with the parent directory of this file#
6 6 ################################################################################
7 7
8 8 [DEFAULT]
9 9 debug = true
10 10 ################################################################################
11 11 ## Uncomment and replace with the address which should receive ##
12 12 ## any error reports after application crash ##
13 13 ## Additionally those settings will be used by rhodecode mailing system ##
14 14 ################################################################################
15 15 #email_to = admin@localhost
16 16 #error_email_from = paste_error@localhost
17 17 #app_email_from = rhodecode-noreply@localhost
18 18 #error_message =
19 19
20 20 #smtp_server = mail.server.com
21 21 #smtp_username =
22 22 #smtp_password =
23 23 #smtp_port =
24 24 #smtp_use_tls = false
25 25
26 26 [server:main]
27 27 ##nr of threads to spawn
28 28 threadpool_workers = 5
29 29
30 30 ##max request before thread respawn
31 31 threadpool_max_requests = 2
32 32
33 33 ##option to use threads of process
34 34 use_threadpool = true
35 35
36 36 use = egg:Paste#http
37 37 host = 127.0.0.1
38 38 port = 5000
39 39
40 40 [app:main]
41 41 use = egg:rhodecode
42 42 full_stack = true
43 43 static_files = true
44 44 lang=en
45 45 cache_dir = %(here)s/data
46 46 index_dir = /tmp/index
47 47 cut_off_limit = 256000
48 force_https = false
48 49
49 50 ####################################
50 51 ### CELERY CONFIG ####
51 52 ####################################
52 53 use_celery = false
53 54 broker.host = localhost
54 55 broker.vhost = rabbitmqhost
55 56 broker.port = 5672
56 57 broker.user = rabbitmq
57 58 broker.password = qweqwe
58 59
59 60 celery.imports = rhodecode.lib.celerylib.tasks
60 61
61 62 celery.result.backend = amqp
62 63 celery.result.dburi = amqp://
63 64 celery.result.serialier = json
64 65
65 66 #celery.send.task.error.emails = true
66 67 #celery.amqp.task.result.expires = 18000
67 68
68 69 celeryd.concurrency = 2
69 70 #celeryd.log.file = celeryd.log
70 71 celeryd.log.level = debug
71 72 celeryd.max.tasks.per.child = 3
72 73
73 74 #tasks will never be sent to the queue, but executed locally instead.
74 75 celery.always.eager = false
75 76
76 77 ####################################
77 78 ### BEAKER CACHE ####
78 79 ####################################
79 80 beaker.cache.data_dir=/%(here)s/data/cache/data
80 81 beaker.cache.lock_dir=/%(here)s/data/cache/lock
81 82 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
82 83
83 84 beaker.cache.super_short_term.type=memory
84 85 beaker.cache.super_short_term.expire=10
85 86
86 87 beaker.cache.short_term.type=memory
87 88 beaker.cache.short_term.expire=60
88 89
89 90 beaker.cache.long_term.type=memory
90 91 beaker.cache.long_term.expire=36000
91 92
92 93
93 94 beaker.cache.sql_cache_short.type=memory
94 95 beaker.cache.sql_cache_short.expire=5
95 96
96 97 beaker.cache.sql_cache_med.type=memory
97 98 beaker.cache.sql_cache_med.expire=360
98 99
99 100 beaker.cache.sql_cache_long.type=file
100 101 beaker.cache.sql_cache_long.expire=3600
101 102
102 103 ####################################
103 104 ### BEAKER SESSION ####
104 105 ####################################
105 106 ## Type of storage used for the session, current types are
106 107 ## dbm, file, memcached, database, and memory.
107 108 ## The storage uses the Container API
108 109 ##that is also used by the cache system.
109 110 beaker.session.type = file
110 111
111 112 beaker.session.key = rhodecode
112 113 beaker.session.secret = g654dcno0-9873jhgfreyu
113 114 beaker.session.timeout = 36000
114 115
115 116 ##auto save the session to not to use .save()
116 117 beaker.session.auto = False
117 118
118 119 ##true exire at browser close
119 120 #beaker.session.cookie_expires = 3600
120 121
121 122
122 123 ################################################################################
123 124 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
124 125 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
125 126 ## execute malicious code after an exception is raised. ##
126 127 ################################################################################
127 128 #set debug = false
128 129
129 130 ##################################
130 131 ### LOGVIEW CONFIG ###
131 132 ##################################
132 133 logview.sqlalchemy = #faa
133 134 logview.pylons.templating = #bfb
134 135 logview.pylons.util = #eee
135 136
136 137 #########################################################
137 138 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
138 139 #########################################################
139 140 sqlalchemy.db1.url = sqlite:///%(here)s/test.db
140 141 #sqlalchemy.db1.echo = False
141 142 #sqlalchemy.db1.pool_recycle = 3600
142 143 sqlalchemy.convert_unicode = true
143 144
144 145 ################################
145 146 ### LOGGING CONFIGURATION ####
146 147 ################################
147 148 [loggers]
148 149 keys = root, routes, rhodecode, sqlalchemy
149 150
150 151 [handlers]
151 152 keys = console
152 153
153 154 [formatters]
154 155 keys = generic,color_formatter
155 156
156 157 #############
157 158 ## LOGGERS ##
158 159 #############
159 160 [logger_root]
160 161 level = ERROR
161 162 handlers = console
162 163
163 164 [logger_routes]
164 165 level = ERROR
165 166 handlers = console
166 167 qualname = routes.middleware
167 168 # "level = DEBUG" logs the route matched and routing variables.
168 169
169 170 [logger_rhodecode]
170 171 level = ERROR
171 172 handlers = console
172 173 qualname = rhodecode
173 174 propagate = 0
174 175
175 176 [logger_sqlalchemy]
176 177 level = ERROR
177 178 handlers = console
178 179 qualname = sqlalchemy.engine
179 180 propagate = 0
180 181
181 182 ##############
182 183 ## HANDLERS ##
183 184 ##############
184 185
185 186 [handler_console]
186 187 class = StreamHandler
187 188 args = (sys.stderr,)
188 189 level = NOTSET
189 190 formatter = color_formatter
190 191
191 192 ################
192 193 ## FORMATTERS ##
193 194 ################
194 195
195 196 [formatter_generic]
196 197 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
197 198 datefmt = %Y-%m-%d %H:%M:%S
198 199
199 200 [formatter_color_formatter]
200 201 class=rhodecode.lib.colored_formatter.ColorFormatter
201 202 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
202 203 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now