Show More
@@ -1,33 +1,33 b'' | |||||
1 | Apache Reverse Proxy |
|
1 | Apache Reverse Proxy | |
2 | ^^^^^^^^^^^^^^^^^^^^ |
|
2 | ^^^^^^^^^^^^^^^^^^^^ | |
3 |
|
3 | |||
4 | Here is a sample configuration file for using Apache as a reverse proxy. |
|
4 | Here is a sample configuration file for using Apache as a reverse proxy. | |
5 |
|
5 | |||
6 | .. code-block:: apache |
|
6 | .. code-block:: apache | |
7 |
|
7 | |||
8 | <VirtualHost *:80> |
|
8 | <VirtualHost *:80> | |
9 | ServerName hg.myserver.com |
|
9 | ServerName hg.myserver.com | |
10 | ServerAlias hg.myserver.com |
|
10 | ServerAlias hg.myserver.com | |
11 |
|
11 | |||
12 | ## uncomment to serve static files by Apache |
|
12 | ## uncomment to serve static files by Apache | |
13 | ## ProxyPass /_static ! |
|
13 | ## ProxyPass /_static/rhodecode ! | |
14 | ## Alias /_static /path/to/.rccontrol/enterprise-1/static |
|
14 | ## Alias /_static/rhodecode /path/to/.rccontrol/enterprise-1/static | |
15 |
|
15 | |||
16 | <Proxy *> |
|
16 | <Proxy *> | |
17 | Order allow,deny |
|
17 | Order allow,deny | |
18 | Allow from all |
|
18 | Allow from all | |
19 | </Proxy> |
|
19 | </Proxy> | |
20 |
|
20 | |||
21 | ## Important ! |
|
21 | ## Important ! | |
22 | ## Directive to properly generate url (clone url) for pylons |
|
22 | ## Directive to properly generate url (clone url) for pylons | |
23 | ProxyPreserveHost On |
|
23 | ProxyPreserveHost On | |
24 |
|
24 | |||
25 | ## RhodeCode instance running |
|
25 | ## RhodeCode instance running | |
26 | ProxyPass / http://127.0.0.1:10002/ |
|
26 | ProxyPass / http://127.0.0.1:10002/ | |
27 | ProxyPassReverse / http://127.0.0.1:10002/ |
|
27 | ProxyPassReverse / http://127.0.0.1:10002/ | |
28 |
|
28 | |||
29 | ## to enable https use line below |
|
29 | ## to enable https use line below | |
30 | #SetEnvIf X-Url-Scheme https HTTPS=1 |
|
30 | #SetEnvIf X-Url-Scheme https HTTPS=1 | |
31 |
|
31 | |||
32 | </VirtualHost> |
|
32 | </VirtualHost> | |
33 |
|
33 |
@@ -1,92 +1,92 b'' | |||||
1 | Nginx Configuration Example |
|
1 | Nginx Configuration Example | |
2 | --------------------------- |
|
2 | --------------------------- | |
3 |
|
3 | |||
4 | Use the following example to configure Nginx as a your web server. |
|
4 | Use the following example to configure Nginx as a your web server. | |
5 |
|
5 | |||
6 | .. code-block:: nginx |
|
6 | .. code-block:: nginx | |
7 |
|
7 | |||
8 | upstream rc { |
|
8 | upstream rc { | |
9 |
|
9 | |||
10 | server 127.0.0.1:10002; |
|
10 | server 127.0.0.1:10002; | |
11 |
|
11 | |||
12 | # add more instances for load balancing |
|
12 | # add more instances for load balancing | |
13 | # server 127.0.0.1:10003; |
|
13 | # server 127.0.0.1:10003; | |
14 | # server 127.0.0.1:10004; |
|
14 | # server 127.0.0.1:10004; | |
15 | } |
|
15 | } | |
16 |
|
16 | |||
17 | ## gist alias |
|
17 | ## gist alias | |
18 |
|
18 | |||
19 | server { |
|
19 | server { | |
20 | listen 443; |
|
20 | listen 443; | |
21 | server_name gist.myserver.com; |
|
21 | server_name gist.myserver.com; | |
22 | access_log /var/log/nginx/gist.access.log; |
|
22 | access_log /var/log/nginx/gist.access.log; | |
23 | error_log /var/log/nginx/gist.error.log; |
|
23 | error_log /var/log/nginx/gist.error.log; | |
24 |
|
24 | |||
25 | ssl on; |
|
25 | ssl on; | |
26 | ssl_certificate gist.rhodecode.myserver.com.crt; |
|
26 | ssl_certificate gist.rhodecode.myserver.com.crt; | |
27 | ssl_certificate_key gist.rhodecode.myserver.com.key; |
|
27 | ssl_certificate_key gist.rhodecode.myserver.com.key; | |
28 |
|
28 | |||
29 | ssl_session_timeout 5m; |
|
29 | ssl_session_timeout 5m; | |
30 |
|
30 | |||
31 | ssl_protocols SSLv3 TLSv1; |
|
31 | ssl_protocols SSLv3 TLSv1; | |
32 | ssl_ciphers DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5; |
|
32 | ssl_ciphers DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5; | |
33 | ssl_prefer_server_ciphers on; |
|
33 | ssl_prefer_server_ciphers on; | |
34 | add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;"; |
|
34 | add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;"; | |
35 |
|
35 | |||
36 | # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits |
|
36 | # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits | |
37 | ssl_dhparam /etc/nginx/ssl/dhparam.pem; |
|
37 | ssl_dhparam /etc/nginx/ssl/dhparam.pem; | |
38 |
|
38 | |||
39 | rewrite ^/(.+)$ https://rhodecode.myserver.com/_admin/gists/$1; |
|
39 | rewrite ^/(.+)$ https://rhodecode.myserver.com/_admin/gists/$1; | |
40 | rewrite (.*) https://rhodecode.myserver.com/_admin/gists; |
|
40 | rewrite (.*) https://rhodecode.myserver.com/_admin/gists; | |
41 | } |
|
41 | } | |
42 |
|
42 | |||
43 | server { |
|
43 | server { | |
44 | listen 443; |
|
44 | listen 443; | |
45 | server_name rhodecode.myserver.com; |
|
45 | server_name rhodecode.myserver.com; | |
46 | access_log /var/log/nginx/rhodecode.access.log; |
|
46 | access_log /var/log/nginx/rhodecode.access.log; | |
47 | error_log /var/log/nginx/rhodecode.error.log; |
|
47 | error_log /var/log/nginx/rhodecode.error.log; | |
48 |
|
48 | |||
49 | ssl on; |
|
49 | ssl on; | |
50 | ssl_certificate rhodecode.myserver.com.crt; |
|
50 | ssl_certificate rhodecode.myserver.com.crt; | |
51 | ssl_certificate_key rhodecode.myserver.com.key; |
|
51 | ssl_certificate_key rhodecode.myserver.com.key; | |
52 |
|
52 | |||
53 | ssl_session_timeout 5m; |
|
53 | ssl_session_timeout 5m; | |
54 |
|
54 | |||
55 | ssl_protocols SSLv3 TLSv1; |
|
55 | ssl_protocols SSLv3 TLSv1; | |
56 | ssl_ciphers DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5; |
|
56 | ssl_ciphers DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5; | |
57 | ssl_prefer_server_ciphers on; |
|
57 | ssl_prefer_server_ciphers on; | |
58 |
|
58 | |||
59 | include /etc/nginx/proxy.conf; |
|
59 | include /etc/nginx/proxy.conf; | |
60 |
|
60 | |||
61 | ## uncomment to serve static files by nginx |
|
61 | ## uncomment to serve static files by nginx | |
62 | # location /_static { |
|
62 | # location /_static/rhodecode { | |
63 | # alias /path/to/.rccontrol/enterprise-1/static; |
|
63 | # alias /path/to/.rccontrol/enterprise-1/static; | |
64 | # } |
|
64 | # } | |
65 |
|
65 | |||
66 | ## channel stream live components |
|
66 | ## channel stream live components | |
67 | location /_channelstream { |
|
67 | location /_channelstream { | |
68 | rewrite /_channelstream/(.*) /$1 break; |
|
68 | rewrite /_channelstream/(.*) /$1 break; | |
69 | proxy_connect_timeout 10; |
|
69 | proxy_connect_timeout 10; | |
70 | proxy_send_timeout 10m; |
|
70 | proxy_send_timeout 10m; | |
71 | proxy_read_timeout 10m; |
|
71 | proxy_read_timeout 10m; | |
72 | tcp_nodelay off; |
|
72 | tcp_nodelay off; | |
73 | proxy_pass http://127.0.0.1:9800; |
|
73 | proxy_pass http://127.0.0.1:9800; | |
74 | proxy_set_header Host $host; |
|
74 | proxy_set_header Host $host; | |
75 | proxy_set_header X-Real-IP $remote_addr; |
|
75 | proxy_set_header X-Real-IP $remote_addr; | |
76 | proxy_set_header X-Url-Scheme $scheme; |
|
76 | proxy_set_header X-Url-Scheme $scheme; | |
77 | proxy_set_header X-Forwarded-Proto $scheme; |
|
77 | proxy_set_header X-Forwarded-Proto $scheme; | |
78 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
|
78 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
79 | gzip off; |
|
79 | gzip off; | |
80 | proxy_http_version 1.1; |
|
80 | proxy_http_version 1.1; | |
81 | proxy_set_header Upgrade $http_upgrade; |
|
81 | proxy_set_header Upgrade $http_upgrade; | |
82 | proxy_set_header Connection "upgrade"; |
|
82 | proxy_set_header Connection "upgrade"; | |
83 | } |
|
83 | } | |
84 |
|
84 | |||
85 | location / { |
|
85 | location / { | |
86 | try_files $uri @rhode; |
|
86 | try_files $uri @rhode; | |
87 | } |
|
87 | } | |
88 |
|
88 | |||
89 | location @rhode { |
|
89 | location @rhode { | |
90 | proxy_pass http://rc; |
|
90 | proxy_pass http://rc; | |
91 | } |
|
91 | } | |
92 | } |
|
92 | } |
@@ -1,395 +1,395 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 | # Copyright (C) 2010-2016 RhodeCode GmbH |
|
3 | # Copyright (C) 2010-2016 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
7 | # (only), as published by the Free Software Foundation. |
|
7 | # (only), as published by the Free Software Foundation. | |
8 | # |
|
8 | # | |
9 | # This program is distributed in the hope that it will be useful, |
|
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU General Public License for more details. |
|
12 | # GNU General Public License for more details. | |
13 | # |
|
13 | # | |
14 | # You should have received a copy of the GNU Affero General Public License |
|
14 | # You should have received a copy of the GNU Affero General Public License | |
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | # |
|
16 | # | |
17 | # This program is dual-licensed. If you wish to learn more about the |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | """ |
|
21 | """ | |
22 | Pylons middleware initialization |
|
22 | Pylons middleware initialization | |
23 | """ |
|
23 | """ | |
24 | import logging |
|
24 | import logging | |
25 |
|
25 | |||
26 | from paste.registry import RegistryManager |
|
26 | from paste.registry import RegistryManager | |
27 | from paste.gzipper import make_gzip_middleware |
|
27 | from paste.gzipper import make_gzip_middleware | |
28 | from pylons.wsgiapp import PylonsApp |
|
28 | from pylons.wsgiapp import PylonsApp | |
29 | from pyramid.authorization import ACLAuthorizationPolicy |
|
29 | from pyramid.authorization import ACLAuthorizationPolicy | |
30 | from pyramid.config import Configurator |
|
30 | from pyramid.config import Configurator | |
31 | from pyramid.static import static_view |
|
31 | from pyramid.static import static_view | |
32 | from pyramid.settings import asbool, aslist |
|
32 | from pyramid.settings import asbool, aslist | |
33 | from pyramid.wsgi import wsgiapp |
|
33 | from pyramid.wsgi import wsgiapp | |
34 | from pyramid.httpexceptions import HTTPError, HTTPInternalServerError |
|
34 | from pyramid.httpexceptions import HTTPError, HTTPInternalServerError | |
35 | from pylons.controllers.util import abort, redirect |
|
35 | from pylons.controllers.util import abort, redirect | |
36 | import pyramid.httpexceptions as httpexceptions |
|
36 | import pyramid.httpexceptions as httpexceptions | |
37 | from pyramid.renderers import render_to_response, render |
|
37 | from pyramid.renderers import render_to_response, render | |
38 | from routes.middleware import RoutesMiddleware |
|
38 | from routes.middleware import RoutesMiddleware | |
39 | import routes.util |
|
39 | import routes.util | |
40 |
|
40 | |||
41 | import rhodecode |
|
41 | import rhodecode | |
42 | import rhodecode.integrations # do not remove this as it registers celery tasks |
|
42 | import rhodecode.integrations # do not remove this as it registers celery tasks | |
43 | from rhodecode.config import patches |
|
43 | from rhodecode.config import patches | |
44 | from rhodecode.config.routing import STATIC_FILE_PREFIX |
|
44 | from rhodecode.config.routing import STATIC_FILE_PREFIX | |
45 | from rhodecode.config.environment import ( |
|
45 | from rhodecode.config.environment import ( | |
46 | load_environment, load_pyramid_environment) |
|
46 | load_environment, load_pyramid_environment) | |
47 | from rhodecode.lib.middleware import csrf |
|
47 | from rhodecode.lib.middleware import csrf | |
48 | from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled |
|
48 | from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled | |
49 | from rhodecode.lib.middleware.disable_vcs import DisableVCSPagesWrapper |
|
49 | from rhodecode.lib.middleware.disable_vcs import DisableVCSPagesWrapper | |
50 | from rhodecode.lib.middleware.https_fixup import HttpsFixup |
|
50 | from rhodecode.lib.middleware.https_fixup import HttpsFixup | |
51 | from rhodecode.lib.middleware.vcs import VCSMiddleware |
|
51 | from rhodecode.lib.middleware.vcs import VCSMiddleware | |
52 | from rhodecode.lib.plugins.utils import register_rhodecode_plugin |
|
52 | from rhodecode.lib.plugins.utils import register_rhodecode_plugin | |
53 |
|
53 | |||
54 |
|
54 | |||
55 | log = logging.getLogger(__name__) |
|
55 | log = logging.getLogger(__name__) | |
56 |
|
56 | |||
57 |
|
57 | |||
58 | # this is used to avoid avoid the route lookup overhead in routesmiddleware |
|
58 | # this is used to avoid avoid the route lookup overhead in routesmiddleware | |
59 | # for certain routes which won't go to pylons to - eg. static files, debugger |
|
59 | # for certain routes which won't go to pylons to - eg. static files, debugger | |
60 | # it is only needed for the pylons migration and can be removed once complete |
|
60 | # it is only needed for the pylons migration and can be removed once complete | |
61 | class SkippableRoutesMiddleware(RoutesMiddleware): |
|
61 | class SkippableRoutesMiddleware(RoutesMiddleware): | |
62 | """ Routes middleware that allows you to skip prefixes """ |
|
62 | """ Routes middleware that allows you to skip prefixes """ | |
63 |
|
63 | |||
64 | def __init__(self, *args, **kw): |
|
64 | def __init__(self, *args, **kw): | |
65 | self.skip_prefixes = kw.pop('skip_prefixes', []) |
|
65 | self.skip_prefixes = kw.pop('skip_prefixes', []) | |
66 | super(SkippableRoutesMiddleware, self).__init__(*args, **kw) |
|
66 | super(SkippableRoutesMiddleware, self).__init__(*args, **kw) | |
67 |
|
67 | |||
68 | def __call__(self, environ, start_response): |
|
68 | def __call__(self, environ, start_response): | |
69 | for prefix in self.skip_prefixes: |
|
69 | for prefix in self.skip_prefixes: | |
70 | if environ['PATH_INFO'].startswith(prefix): |
|
70 | if environ['PATH_INFO'].startswith(prefix): | |
71 | return self.app(environ, start_response) |
|
71 | return self.app(environ, start_response) | |
72 |
|
72 | |||
73 | return super(SkippableRoutesMiddleware, self).__call__( |
|
73 | return super(SkippableRoutesMiddleware, self).__call__( | |
74 | environ, start_response) |
|
74 | environ, start_response) | |
75 |
|
75 | |||
76 |
|
76 | |||
77 | def make_app(global_conf, full_stack=True, static_files=True, **app_conf): |
|
77 | def make_app(global_conf, full_stack=True, static_files=True, **app_conf): | |
78 | """Create a Pylons WSGI application and return it |
|
78 | """Create a Pylons WSGI application and return it | |
79 |
|
79 | |||
80 | ``global_conf`` |
|
80 | ``global_conf`` | |
81 | The inherited configuration for this application. Normally from |
|
81 | The inherited configuration for this application. Normally from | |
82 | the [DEFAULT] section of the Paste ini file. |
|
82 | the [DEFAULT] section of the Paste ini file. | |
83 |
|
83 | |||
84 | ``full_stack`` |
|
84 | ``full_stack`` | |
85 | Whether or not this application provides a full WSGI stack (by |
|
85 | Whether or not this application provides a full WSGI stack (by | |
86 | default, meaning it handles its own exceptions and errors). |
|
86 | default, meaning it handles its own exceptions and errors). | |
87 | Disable full_stack when this application is "managed" by |
|
87 | Disable full_stack when this application is "managed" by | |
88 | another WSGI middleware. |
|
88 | another WSGI middleware. | |
89 |
|
89 | |||
90 | ``app_conf`` |
|
90 | ``app_conf`` | |
91 | The application's local configuration. Normally specified in |
|
91 | The application's local configuration. Normally specified in | |
92 | the [app:<name>] section of the Paste ini file (where <name> |
|
92 | the [app:<name>] section of the Paste ini file (where <name> | |
93 | defaults to main). |
|
93 | defaults to main). | |
94 |
|
94 | |||
95 | """ |
|
95 | """ | |
96 | # Apply compatibility patches |
|
96 | # Apply compatibility patches | |
97 | patches.kombu_1_5_1_python_2_7_11() |
|
97 | patches.kombu_1_5_1_python_2_7_11() | |
98 | patches.inspect_getargspec() |
|
98 | patches.inspect_getargspec() | |
99 |
|
99 | |||
100 | # Configure the Pylons environment |
|
100 | # Configure the Pylons environment | |
101 | config = load_environment(global_conf, app_conf) |
|
101 | config = load_environment(global_conf, app_conf) | |
102 |
|
102 | |||
103 | # The Pylons WSGI app |
|
103 | # The Pylons WSGI app | |
104 | app = PylonsApp(config=config) |
|
104 | app = PylonsApp(config=config) | |
105 | if rhodecode.is_test: |
|
105 | if rhodecode.is_test: | |
106 | app = csrf.CSRFDetector(app) |
|
106 | app = csrf.CSRFDetector(app) | |
107 |
|
107 | |||
108 | expected_origin = config.get('expected_origin') |
|
108 | expected_origin = config.get('expected_origin') | |
109 | if expected_origin: |
|
109 | if expected_origin: | |
110 | # The API can be accessed from other Origins. |
|
110 | # The API can be accessed from other Origins. | |
111 | app = csrf.OriginChecker(app, expected_origin, |
|
111 | app = csrf.OriginChecker(app, expected_origin, | |
112 | skip_urls=[routes.util.url_for('api')]) |
|
112 | skip_urls=[routes.util.url_for('api')]) | |
113 |
|
113 | |||
114 |
|
114 | |||
115 | if asbool(full_stack): |
|
115 | if asbool(full_stack): | |
116 |
|
116 | |||
117 | # Appenlight monitoring and error handler |
|
117 | # Appenlight monitoring and error handler | |
118 | app, appenlight_client = wrap_in_appenlight_if_enabled(app, config) |
|
118 | app, appenlight_client = wrap_in_appenlight_if_enabled(app, config) | |
119 |
|
119 | |||
120 | # we want our low level middleware to get to the request ASAP. We don't |
|
120 | # we want our low level middleware to get to the request ASAP. We don't | |
121 | # need any pylons stack middleware in them |
|
121 | # need any pylons stack middleware in them | |
122 | app = VCSMiddleware(app, config, appenlight_client) |
|
122 | app = VCSMiddleware(app, config, appenlight_client) | |
123 |
|
123 | |||
124 | # Establish the Registry for this application |
|
124 | # Establish the Registry for this application | |
125 | app = RegistryManager(app) |
|
125 | app = RegistryManager(app) | |
126 |
|
126 | |||
127 | app.config = config |
|
127 | app.config = config | |
128 |
|
128 | |||
129 | return app |
|
129 | return app | |
130 |
|
130 | |||
131 |
|
131 | |||
132 | def make_pyramid_app(global_config, **settings): |
|
132 | def make_pyramid_app(global_config, **settings): | |
133 | """ |
|
133 | """ | |
134 | Constructs the WSGI application based on Pyramid and wraps the Pylons based |
|
134 | Constructs the WSGI application based on Pyramid and wraps the Pylons based | |
135 | application. |
|
135 | application. | |
136 |
|
136 | |||
137 | Specials: |
|
137 | Specials: | |
138 |
|
138 | |||
139 | * We migrate from Pylons to Pyramid. While doing this, we keep both |
|
139 | * We migrate from Pylons to Pyramid. While doing this, we keep both | |
140 | frameworks functional. This involves moving some WSGI middlewares around |
|
140 | frameworks functional. This involves moving some WSGI middlewares around | |
141 | and providing access to some data internals, so that the old code is |
|
141 | and providing access to some data internals, so that the old code is | |
142 | still functional. |
|
142 | still functional. | |
143 |
|
143 | |||
144 | * The application can also be integrated like a plugin via the call to |
|
144 | * The application can also be integrated like a plugin via the call to | |
145 | `includeme`. This is accompanied with the other utility functions which |
|
145 | `includeme`. This is accompanied with the other utility functions which | |
146 | are called. Changing this should be done with great care to not break |
|
146 | are called. Changing this should be done with great care to not break | |
147 | cases when these fragments are assembled from another place. |
|
147 | cases when these fragments are assembled from another place. | |
148 |
|
148 | |||
149 | """ |
|
149 | """ | |
150 | # The edition string should be available in pylons too, so we add it here |
|
150 | # The edition string should be available in pylons too, so we add it here | |
151 | # before copying the settings. |
|
151 | # before copying the settings. | |
152 | settings.setdefault('rhodecode.edition', 'Community Edition') |
|
152 | settings.setdefault('rhodecode.edition', 'Community Edition') | |
153 |
|
153 | |||
154 | # As long as our Pylons application does expect "unprepared" settings, make |
|
154 | # As long as our Pylons application does expect "unprepared" settings, make | |
155 | # sure that we keep an unmodified copy. This avoids unintentional change of |
|
155 | # sure that we keep an unmodified copy. This avoids unintentional change of | |
156 | # behavior in the old application. |
|
156 | # behavior in the old application. | |
157 | settings_pylons = settings.copy() |
|
157 | settings_pylons = settings.copy() | |
158 |
|
158 | |||
159 | sanitize_settings_and_apply_defaults(settings) |
|
159 | sanitize_settings_and_apply_defaults(settings) | |
160 | config = Configurator(settings=settings) |
|
160 | config = Configurator(settings=settings) | |
161 | add_pylons_compat_data(config.registry, global_config, settings_pylons) |
|
161 | add_pylons_compat_data(config.registry, global_config, settings_pylons) | |
162 |
|
162 | |||
163 | load_pyramid_environment(global_config, settings) |
|
163 | load_pyramid_environment(global_config, settings) | |
164 |
|
164 | |||
165 | includeme_first(config) |
|
165 | includeme_first(config) | |
166 | includeme(config) |
|
166 | includeme(config) | |
167 | pyramid_app = config.make_wsgi_app() |
|
167 | pyramid_app = config.make_wsgi_app() | |
168 | pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config) |
|
168 | pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config) | |
169 | return pyramid_app |
|
169 | return pyramid_app | |
170 |
|
170 | |||
171 |
|
171 | |||
172 | def add_pylons_compat_data(registry, global_config, settings): |
|
172 | def add_pylons_compat_data(registry, global_config, settings): | |
173 | """ |
|
173 | """ | |
174 | Attach data to the registry to support the Pylons integration. |
|
174 | Attach data to the registry to support the Pylons integration. | |
175 | """ |
|
175 | """ | |
176 | registry._pylons_compat_global_config = global_config |
|
176 | registry._pylons_compat_global_config = global_config | |
177 | registry._pylons_compat_settings = settings |
|
177 | registry._pylons_compat_settings = settings | |
178 |
|
178 | |||
179 |
|
179 | |||
180 | def webob_to_pyramid_http_response(webob_response): |
|
180 | def webob_to_pyramid_http_response(webob_response): | |
181 | ResponseClass = httpexceptions.status_map[webob_response.status_int] |
|
181 | ResponseClass = httpexceptions.status_map[webob_response.status_int] | |
182 | pyramid_response = ResponseClass(webob_response.status) |
|
182 | pyramid_response = ResponseClass(webob_response.status) | |
183 | pyramid_response.status = webob_response.status |
|
183 | pyramid_response.status = webob_response.status | |
184 | pyramid_response.headers.update(webob_response.headers) |
|
184 | pyramid_response.headers.update(webob_response.headers) | |
185 | if pyramid_response.headers['content-type'] == 'text/html': |
|
185 | if pyramid_response.headers['content-type'] == 'text/html': | |
186 | pyramid_response.headers['content-type'] = 'text/html; charset=UTF-8' |
|
186 | pyramid_response.headers['content-type'] = 'text/html; charset=UTF-8' | |
187 | return pyramid_response |
|
187 | return pyramid_response | |
188 |
|
188 | |||
189 |
|
189 | |||
190 | def error_handler(exception, request): |
|
190 | def error_handler(exception, request): | |
191 | # TODO: dan: replace the old pylons error controller with this |
|
191 | # TODO: dan: replace the old pylons error controller with this | |
192 | from rhodecode.model.settings import SettingsModel |
|
192 | from rhodecode.model.settings import SettingsModel | |
193 | from rhodecode.lib.utils2 import AttributeDict |
|
193 | from rhodecode.lib.utils2 import AttributeDict | |
194 |
|
194 | |||
195 | try: |
|
195 | try: | |
196 | rc_config = SettingsModel().get_all_settings() |
|
196 | rc_config = SettingsModel().get_all_settings() | |
197 | except Exception: |
|
197 | except Exception: | |
198 | log.exception('failed to fetch settings') |
|
198 | log.exception('failed to fetch settings') | |
199 | rc_config = {} |
|
199 | rc_config = {} | |
200 |
|
200 | |||
201 | base_response = HTTPInternalServerError() |
|
201 | base_response = HTTPInternalServerError() | |
202 | # prefer original exception for the response since it may have headers set |
|
202 | # prefer original exception for the response since it may have headers set | |
203 | if isinstance(exception, HTTPError): |
|
203 | if isinstance(exception, HTTPError): | |
204 | base_response = exception |
|
204 | base_response = exception | |
205 |
|
205 | |||
206 | c = AttributeDict() |
|
206 | c = AttributeDict() | |
207 | c.error_message = base_response.status |
|
207 | c.error_message = base_response.status | |
208 | c.error_explanation = base_response.explanation or str(base_response) |
|
208 | c.error_explanation = base_response.explanation or str(base_response) | |
209 | c.visual = AttributeDict() |
|
209 | c.visual = AttributeDict() | |
210 |
|
210 | |||
211 | c.visual.rhodecode_support_url = ( |
|
211 | c.visual.rhodecode_support_url = ( | |
212 | request.registry.settings.get('rhodecode_support_url') or |
|
212 | request.registry.settings.get('rhodecode_support_url') or | |
213 | request.route_url('rhodecode_support') |
|
213 | request.route_url('rhodecode_support') | |
214 | ) |
|
214 | ) | |
215 | c.redirect_time = 0 |
|
215 | c.redirect_time = 0 | |
216 | c.rhodecode_name = rc_config.get('rhodecode_title', '') |
|
216 | c.rhodecode_name = rc_config.get('rhodecode_title', '') | |
217 | if not c.rhodecode_name: |
|
217 | if not c.rhodecode_name: | |
218 | c.rhodecode_name = 'Rhodecode' |
|
218 | c.rhodecode_name = 'Rhodecode' | |
219 |
|
219 | |||
220 | response = render_to_response( |
|
220 | response = render_to_response( | |
221 | '/errors/error_document.html', {'c': c}, request=request, |
|
221 | '/errors/error_document.html', {'c': c}, request=request, | |
222 | response=base_response) |
|
222 | response=base_response) | |
223 |
|
223 | |||
224 | return response |
|
224 | return response | |
225 |
|
225 | |||
226 |
|
226 | |||
227 | def includeme(config): |
|
227 | def includeme(config): | |
228 | settings = config.registry.settings |
|
228 | settings = config.registry.settings | |
229 |
|
229 | |||
230 | # plugin information |
|
230 | # plugin information | |
231 | config.registry.rhodecode_plugins = {} |
|
231 | config.registry.rhodecode_plugins = {} | |
232 |
|
232 | |||
233 | config.add_directive( |
|
233 | config.add_directive( | |
234 | 'register_rhodecode_plugin', register_rhodecode_plugin) |
|
234 | 'register_rhodecode_plugin', register_rhodecode_plugin) | |
235 |
|
235 | |||
236 | if asbool(settings.get('appenlight', 'false')): |
|
236 | if asbool(settings.get('appenlight', 'false')): | |
237 | config.include('appenlight_client.ext.pyramid_tween') |
|
237 | config.include('appenlight_client.ext.pyramid_tween') | |
238 |
|
238 | |||
239 | # Includes which are required. The application would fail without them. |
|
239 | # Includes which are required. The application would fail without them. | |
240 | config.include('pyramid_mako') |
|
240 | config.include('pyramid_mako') | |
241 | config.include('pyramid_beaker') |
|
241 | config.include('pyramid_beaker') | |
242 | config.include('rhodecode.admin') |
|
242 | config.include('rhodecode.admin') | |
243 | config.include('rhodecode.authentication') |
|
243 | config.include('rhodecode.authentication') | |
244 | config.include('rhodecode.integrations') |
|
244 | config.include('rhodecode.integrations') | |
245 | config.include('rhodecode.login') |
|
245 | config.include('rhodecode.login') | |
246 | config.include('rhodecode.tweens') |
|
246 | config.include('rhodecode.tweens') | |
247 | config.include('rhodecode.api') |
|
247 | config.include('rhodecode.api') | |
248 | config.add_route( |
|
248 | config.add_route( | |
249 | 'rhodecode_support', 'https://rhodecode.com/help/', static=True) |
|
249 | 'rhodecode_support', 'https://rhodecode.com/help/', static=True) | |
250 |
|
250 | |||
251 | # Set the authorization policy. |
|
251 | # Set the authorization policy. | |
252 | authz_policy = ACLAuthorizationPolicy() |
|
252 | authz_policy = ACLAuthorizationPolicy() | |
253 | config.set_authorization_policy(authz_policy) |
|
253 | config.set_authorization_policy(authz_policy) | |
254 |
|
254 | |||
255 | # Set the default renderer for HTML templates to mako. |
|
255 | # Set the default renderer for HTML templates to mako. | |
256 | config.add_mako_renderer('.html') |
|
256 | config.add_mako_renderer('.html') | |
257 |
|
257 | |||
258 | # include RhodeCode plugins |
|
258 | # include RhodeCode plugins | |
259 | includes = aslist(settings.get('rhodecode.includes', [])) |
|
259 | includes = aslist(settings.get('rhodecode.includes', [])) | |
260 | for inc in includes: |
|
260 | for inc in includes: | |
261 | config.include(inc) |
|
261 | config.include(inc) | |
262 |
|
262 | |||
263 | pylons_app = make_app( |
|
263 | pylons_app = make_app( | |
264 | config.registry._pylons_compat_global_config, |
|
264 | config.registry._pylons_compat_global_config, | |
265 | **config.registry._pylons_compat_settings) |
|
265 | **config.registry._pylons_compat_settings) | |
266 | config.registry._pylons_compat_config = pylons_app.config |
|
266 | config.registry._pylons_compat_config = pylons_app.config | |
267 |
|
267 | |||
268 | pylons_app_as_view = wsgiapp(pylons_app) |
|
268 | pylons_app_as_view = wsgiapp(pylons_app) | |
269 |
|
269 | |||
270 | # Protect from VCS Server error related pages when server is not available |
|
270 | # Protect from VCS Server error related pages when server is not available | |
271 | vcs_server_enabled = asbool(settings.get('vcs.server.enable', 'true')) |
|
271 | vcs_server_enabled = asbool(settings.get('vcs.server.enable', 'true')) | |
272 | if not vcs_server_enabled: |
|
272 | if not vcs_server_enabled: | |
273 | pylons_app_as_view = DisableVCSPagesWrapper(pylons_app_as_view) |
|
273 | pylons_app_as_view = DisableVCSPagesWrapper(pylons_app_as_view) | |
274 |
|
274 | |||
275 |
|
275 | |||
276 | def pylons_app_with_error_handler(context, request): |
|
276 | def pylons_app_with_error_handler(context, request): | |
277 | """ |
|
277 | """ | |
278 | Handle exceptions from rc pylons app: |
|
278 | Handle exceptions from rc pylons app: | |
279 |
|
279 | |||
280 | - old webob type exceptions get converted to pyramid exceptions |
|
280 | - old webob type exceptions get converted to pyramid exceptions | |
281 | - pyramid exceptions are passed to the error handler view |
|
281 | - pyramid exceptions are passed to the error handler view | |
282 | """ |
|
282 | """ | |
283 | try: |
|
283 | try: | |
284 | response = pylons_app_as_view(context, request) |
|
284 | response = pylons_app_as_view(context, request) | |
285 | if 400 <= response.status_int <= 599: # webob type error responses |
|
285 | if 400 <= response.status_int <= 599: # webob type error responses | |
286 | return error_handler( |
|
286 | return error_handler( | |
287 | webob_to_pyramid_http_response(response), request) |
|
287 | webob_to_pyramid_http_response(response), request) | |
288 | except HTTPError as e: # pyramid type exceptions |
|
288 | except HTTPError as e: # pyramid type exceptions | |
289 | return error_handler(e, request) |
|
289 | return error_handler(e, request) | |
290 | except Exception: |
|
290 | except Exception: | |
291 | if settings.get('debugtoolbar.enabled', False): |
|
291 | if settings.get('debugtoolbar.enabled', False): | |
292 | raise |
|
292 | raise | |
293 | return error_handler(HTTPInternalServerError(), request) |
|
293 | return error_handler(HTTPInternalServerError(), request) | |
294 | return response |
|
294 | return response | |
295 |
|
295 | |||
296 | # This is the glue which allows us to migrate in chunks. By registering the |
|
296 | # This is the glue which allows us to migrate in chunks. By registering the | |
297 | # pylons based application as the "Not Found" view in Pyramid, we will |
|
297 | # pylons based application as the "Not Found" view in Pyramid, we will | |
298 | # fallback to the old application each time the new one does not yet know |
|
298 | # fallback to the old application each time the new one does not yet know | |
299 | # how to handle a request. |
|
299 | # how to handle a request. | |
300 | config.add_notfound_view(pylons_app_with_error_handler) |
|
300 | config.add_notfound_view(pylons_app_with_error_handler) | |
301 |
|
301 | |||
302 | if not settings.get('debugtoolbar.enabled', False): |
|
302 | if not settings.get('debugtoolbar.enabled', False): | |
303 | # if no toolbar, then any exception gets caught and rendered |
|
303 | # if no toolbar, then any exception gets caught and rendered | |
304 | config.add_view(error_handler, context=Exception) |
|
304 | config.add_view(error_handler, context=Exception) | |
305 |
|
305 | |||
306 | config.add_view(error_handler, context=HTTPError) |
|
306 | config.add_view(error_handler, context=HTTPError) | |
307 |
|
307 | |||
308 |
|
308 | |||
309 | def includeme_first(config): |
|
309 | def includeme_first(config): | |
310 | # redirect automatic browser favicon.ico requests to correct place |
|
310 | # redirect automatic browser favicon.ico requests to correct place | |
311 | def favicon_redirect(context, request): |
|
311 | def favicon_redirect(context, request): | |
312 | return redirect( |
|
312 | return redirect( | |
313 | request.static_url('rhodecode:public/images/favicon.ico')) |
|
313 | request.static_url('rhodecode:public/images/favicon.ico')) | |
314 |
|
314 | |||
315 | config.add_view(favicon_redirect, route_name='favicon') |
|
315 | config.add_view(favicon_redirect, route_name='favicon') | |
316 | config.add_route('favicon', '/favicon.ico') |
|
316 | config.add_route('favicon', '/favicon.ico') | |
317 |
|
317 | |||
318 | config.add_static_view( |
|
318 | config.add_static_view( | |
319 | '_static/deform', 'deform:static') |
|
319 | '_static/deform', 'deform:static') | |
320 | config.add_static_view( |
|
320 | config.add_static_view( | |
321 | '_static', path='rhodecode:public', cache_max_age=3600 * 24) |
|
321 | '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24) | |
322 |
|
322 | |||
323 | def wrap_app_in_wsgi_middlewares(pyramid_app, config): |
|
323 | def wrap_app_in_wsgi_middlewares(pyramid_app, config): | |
324 | """ |
|
324 | """ | |
325 | Apply outer WSGI middlewares around the application. |
|
325 | Apply outer WSGI middlewares around the application. | |
326 |
|
326 | |||
327 | Part of this has been moved up from the Pylons layer, so that the |
|
327 | Part of this has been moved up from the Pylons layer, so that the | |
328 | data is also available if old Pylons code is hit through an already ported |
|
328 | data is also available if old Pylons code is hit through an already ported | |
329 | view. |
|
329 | view. | |
330 | """ |
|
330 | """ | |
331 | settings = config.registry.settings |
|
331 | settings = config.registry.settings | |
332 |
|
332 | |||
333 | # enable https redirects based on HTTP_X_URL_SCHEME set by proxy |
|
333 | # enable https redirects based on HTTP_X_URL_SCHEME set by proxy | |
334 | pyramid_app = HttpsFixup(pyramid_app, settings) |
|
334 | pyramid_app = HttpsFixup(pyramid_app, settings) | |
335 |
|
335 | |||
336 | # Add RoutesMiddleware to support the pylons compatibility tween during |
|
336 | # Add RoutesMiddleware to support the pylons compatibility tween during | |
337 | # migration to pyramid. |
|
337 | # migration to pyramid. | |
338 | pyramid_app = SkippableRoutesMiddleware( |
|
338 | pyramid_app = SkippableRoutesMiddleware( | |
339 | pyramid_app, config.registry._pylons_compat_config['routes.map'], |
|
339 | pyramid_app, config.registry._pylons_compat_config['routes.map'], | |
340 | skip_prefixes=(STATIC_FILE_PREFIX, '/_debug_toolbar')) |
|
340 | skip_prefixes=(STATIC_FILE_PREFIX, '/_debug_toolbar')) | |
341 |
|
341 | |||
342 | if asbool(settings.get('appenlight', 'false')): |
|
342 | if asbool(settings.get('appenlight', 'false')): | |
343 | pyramid_app, _ = wrap_in_appenlight_if_enabled( |
|
343 | pyramid_app, _ = wrap_in_appenlight_if_enabled( | |
344 | pyramid_app, config.registry._pylons_compat_config) |
|
344 | pyramid_app, config.registry._pylons_compat_config) | |
345 |
|
345 | |||
346 | if asbool(settings.get('gzip_responses', 'true')): |
|
346 | if asbool(settings.get('gzip_responses', 'true')): | |
347 | pyramid_app = make_gzip_middleware( |
|
347 | pyramid_app = make_gzip_middleware( | |
348 | pyramid_app, settings, compress_level=1) |
|
348 | pyramid_app, settings, compress_level=1) | |
349 |
|
349 | |||
350 | return pyramid_app |
|
350 | return pyramid_app | |
351 |
|
351 | |||
352 |
|
352 | |||
353 | def sanitize_settings_and_apply_defaults(settings): |
|
353 | def sanitize_settings_and_apply_defaults(settings): | |
354 | """ |
|
354 | """ | |
355 | Applies settings defaults and does all type conversion. |
|
355 | Applies settings defaults and does all type conversion. | |
356 |
|
356 | |||
357 | We would move all settings parsing and preparation into this place, so that |
|
357 | We would move all settings parsing and preparation into this place, so that | |
358 | we have only one place left which deals with this part. The remaining parts |
|
358 | we have only one place left which deals with this part. The remaining parts | |
359 | of the application would start to rely fully on well prepared settings. |
|
359 | of the application would start to rely fully on well prepared settings. | |
360 |
|
360 | |||
361 | This piece would later be split up per topic to avoid a big fat monster |
|
361 | This piece would later be split up per topic to avoid a big fat monster | |
362 | function. |
|
362 | function. | |
363 | """ |
|
363 | """ | |
364 |
|
364 | |||
365 | # Pyramid's mako renderer has to search in the templates folder so that the |
|
365 | # Pyramid's mako renderer has to search in the templates folder so that the | |
366 | # old templates still work. Ported and new templates are expected to use |
|
366 | # old templates still work. Ported and new templates are expected to use | |
367 | # real asset specifications for the includes. |
|
367 | # real asset specifications for the includes. | |
368 | mako_directories = settings.setdefault('mako.directories', [ |
|
368 | mako_directories = settings.setdefault('mako.directories', [ | |
369 | # Base templates of the original Pylons application |
|
369 | # Base templates of the original Pylons application | |
370 | 'rhodecode:templates', |
|
370 | 'rhodecode:templates', | |
371 | ]) |
|
371 | ]) | |
372 | log.debug( |
|
372 | log.debug( | |
373 | "Using the following Mako template directories: %s", |
|
373 | "Using the following Mako template directories: %s", | |
374 | mako_directories) |
|
374 | mako_directories) | |
375 |
|
375 | |||
376 | # Default includes, possible to change as a user |
|
376 | # Default includes, possible to change as a user | |
377 | pyramid_includes = settings.setdefault('pyramid.includes', [ |
|
377 | pyramid_includes = settings.setdefault('pyramid.includes', [ | |
378 | 'rhodecode.lib.middleware.request_wrapper', |
|
378 | 'rhodecode.lib.middleware.request_wrapper', | |
379 | ]) |
|
379 | ]) | |
380 | log.debug( |
|
380 | log.debug( | |
381 | "Using the following pyramid.includes: %s", |
|
381 | "Using the following pyramid.includes: %s", | |
382 | pyramid_includes) |
|
382 | pyramid_includes) | |
383 |
|
383 | |||
384 | # TODO: johbo: Re-think this, usually the call to config.include |
|
384 | # TODO: johbo: Re-think this, usually the call to config.include | |
385 | # should allow to pass in a prefix. |
|
385 | # should allow to pass in a prefix. | |
386 | settings.setdefault('rhodecode.api.url', '/_admin/api') |
|
386 | settings.setdefault('rhodecode.api.url', '/_admin/api') | |
387 |
|
387 | |||
388 | _bool_setting(settings, 'vcs.server.enable', 'true') |
|
388 | _bool_setting(settings, 'vcs.server.enable', 'true') | |
389 | _bool_setting(settings, 'is_test', 'false') |
|
389 | _bool_setting(settings, 'is_test', 'false') | |
390 |
|
390 | |||
391 | return settings |
|
391 | return settings | |
392 |
|
392 | |||
393 |
|
393 | |||
394 | def _bool_setting(settings, name, default): |
|
394 | def _bool_setting(settings, name, default): | |
395 | settings[name] = asbool(settings.get(name, default)) |
|
395 | settings[name] = asbool(settings.get(name, default)) |
@@ -1,235 +1,235 b'' | |||||
1 | // # Copyright (C) 2010-2016 RhodeCode GmbH |
|
1 | // # Copyright (C) 2010-2016 RhodeCode GmbH | |
2 | // # |
|
2 | // # | |
3 | // # This program is free software: you can redistribute it and/or modify |
|
3 | // # This program is free software: you can redistribute it and/or modify | |
4 | // # it under the terms of the GNU Affero General Public License, version 3 |
|
4 | // # it under the terms of the GNU Affero General Public License, version 3 | |
5 | // # (only), as published by the Free Software Foundation. |
|
5 | // # (only), as published by the Free Software Foundation. | |
6 | // # |
|
6 | // # | |
7 | // # This program is distributed in the hope that it will be useful, |
|
7 | // # This program is distributed in the hope that it will be useful, | |
8 | // # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
8 | // # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 | // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
9 | // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 | // # GNU General Public License for more details. |
|
10 | // # GNU General Public License for more details. | |
11 | // # |
|
11 | // # | |
12 | // # You should have received a copy of the GNU Affero General Public License |
|
12 | // # You should have received a copy of the GNU Affero General Public License | |
13 | // # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
13 | // # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
14 | // # |
|
14 | // # | |
15 | // # This program is dual-licensed. If you wish to learn more about the |
|
15 | // # This program is dual-licensed. If you wish to learn more about the | |
16 | // # RhodeCode Enterprise Edition, including its added features, Support services, |
|
16 | // # RhodeCode Enterprise Edition, including its added features, Support services, | |
17 | // # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
17 | // # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
18 |
|
18 | |||
19 | /** |
|
19 | /** | |
20 | * Object holding the registered pyroutes. |
|
20 | * Object holding the registered pyroutes. | |
21 | * Routes will be registered with the generated script |
|
21 | * Routes will be registered with the generated script | |
22 | * rhodecode/public/js/rhodecode/base/pyroutes.js |
|
22 | * rhodecode/public/js/rhodecode/base/pyroutes.js | |
23 | */ |
|
23 | */ | |
24 | var PROUTES_MAP = {}; |
|
24 | var PROUTES_MAP = {}; | |
25 |
|
25 | |||
26 | /** |
|
26 | /** | |
27 | * PyRoutesJS |
|
27 | * PyRoutesJS | |
28 | * |
|
28 | * | |
29 | * Usage pyroutes.url('mark_error_fixed',{"error_id":error_id}) // /mark_error_fixed/<error_id> |
|
29 | * Usage pyroutes.url('mark_error_fixed',{"error_id":error_id}) // /mark_error_fixed/<error_id> | |
30 | */ |
|
30 | */ | |
31 | var pyroutes = (function() { |
|
31 | var pyroutes = (function() { | |
32 | // access global map defined in special file pyroutes |
|
32 | // access global map defined in special file pyroutes | |
33 | var matchlist = PROUTES_MAP; |
|
33 | var matchlist = PROUTES_MAP; | |
34 | var sprintf = (function() { |
|
34 | var sprintf = (function() { | |
35 | function get_type(variable) { |
|
35 | function get_type(variable) { | |
36 | return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); |
|
36 | return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); | |
37 | } |
|
37 | } | |
38 | function str_repeat(input, multiplier) { |
|
38 | function str_repeat(input, multiplier) { | |
39 | for (var output = []; multiplier > 0; output[--multiplier] = input) { |
|
39 | for (var output = []; multiplier > 0; output[--multiplier] = input) { | |
40 | /* do nothing */ |
|
40 | /* do nothing */ | |
41 | } |
|
41 | } | |
42 | return output.join(''); |
|
42 | return output.join(''); | |
43 | } |
|
43 | } | |
44 | var str_format = function() { |
|
44 | var str_format = function() { | |
45 | if (!str_format.cache.hasOwnProperty(arguments[0])) { |
|
45 | if (!str_format.cache.hasOwnProperty(arguments[0])) { | |
46 | str_format.cache[arguments[0]] = str_format.parse(arguments[0]); |
|
46 | str_format.cache[arguments[0]] = str_format.parse(arguments[0]); | |
47 | } |
|
47 | } | |
48 | return str_format.format.call(null, str_format.cache[arguments[0]], arguments); |
|
48 | return str_format.format.call(null, str_format.cache[arguments[0]], arguments); | |
49 | }; |
|
49 | }; | |
50 |
|
50 | |||
51 | str_format.format = function(parse_tree, argv) { |
|
51 | str_format.format = function(parse_tree, argv) { | |
52 | var cursor = 1, |
|
52 | var cursor = 1, | |
53 | tree_length = parse_tree.length, |
|
53 | tree_length = parse_tree.length, | |
54 | node_type = '', |
|
54 | node_type = '', | |
55 | arg, |
|
55 | arg, | |
56 | output = [], |
|
56 | output = [], | |
57 | i, k, |
|
57 | i, k, | |
58 | match, |
|
58 | match, | |
59 | pad, |
|
59 | pad, | |
60 | pad_character, |
|
60 | pad_character, | |
61 | pad_length; |
|
61 | pad_length; | |
62 | for (i = 0; i < tree_length; i++) { |
|
62 | for (i = 0; i < tree_length; i++) { | |
63 | node_type = get_type(parse_tree[i]); |
|
63 | node_type = get_type(parse_tree[i]); | |
64 | if (node_type === 'string') { |
|
64 | if (node_type === 'string') { | |
65 | output.push(parse_tree[i]); |
|
65 | output.push(parse_tree[i]); | |
66 | } |
|
66 | } | |
67 | else if (node_type === 'array') { |
|
67 | else if (node_type === 'array') { | |
68 | match = parse_tree[i]; // convenience purposes only |
|
68 | match = parse_tree[i]; // convenience purposes only | |
69 | if (match[2]) { // keyword argument |
|
69 | if (match[2]) { // keyword argument | |
70 | arg = argv[cursor]; |
|
70 | arg = argv[cursor]; | |
71 | for (k = 0; k < match[2].length; k++) { |
|
71 | for (k = 0; k < match[2].length; k++) { | |
72 | if (!arg.hasOwnProperty(match[2][k])) { |
|
72 | if (!arg.hasOwnProperty(match[2][k])) { | |
73 | throw(sprintf('[sprintf] property "%s" does not exist', match[2][k])); |
|
73 | throw(sprintf('[sprintf] property "%s" does not exist', match[2][k])); | |
74 | } |
|
74 | } | |
75 | arg = arg[match[2][k]]; |
|
75 | arg = arg[match[2][k]]; | |
76 | } |
|
76 | } | |
77 | } |
|
77 | } | |
78 | else if (match[1]) { // positional argument (explicit) |
|
78 | else if (match[1]) { // positional argument (explicit) | |
79 | arg = argv[match[1]]; |
|
79 | arg = argv[match[1]]; | |
80 | } |
|
80 | } | |
81 | else { // positional argument (implicit) |
|
81 | else { // positional argument (implicit) | |
82 | arg = argv[cursor++]; |
|
82 | arg = argv[cursor++]; | |
83 | } |
|
83 | } | |
84 |
|
84 | |||
85 | if (/[^s]/.test(match[8]) && (get_type(arg) !== 'number')) { |
|
85 | if (/[^s]/.test(match[8]) && (get_type(arg) !== 'number')) { | |
86 | throw(sprintf('[sprintf] expecting number but found %s', get_type(arg))); |
|
86 | throw(sprintf('[sprintf] expecting number but found %s', get_type(arg))); | |
87 | } |
|
87 | } | |
88 | switch (match[8]) { |
|
88 | switch (match[8]) { | |
89 | case 'b': arg = arg.toString(2); break; |
|
89 | case 'b': arg = arg.toString(2); break; | |
90 | case 'c': arg = String.fromCharCode(arg); break; |
|
90 | case 'c': arg = String.fromCharCode(arg); break; | |
91 | case 'd': arg = parseInt(arg, 10); break; |
|
91 | case 'd': arg = parseInt(arg, 10); break; | |
92 | case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; |
|
92 | case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; | |
93 | case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; |
|
93 | case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; | |
94 | case 'o': arg = arg.toString(8); break; |
|
94 | case 'o': arg = arg.toString(8); break; | |
95 | case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); |
|
95 | case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); | |
96 | break; |
|
96 | break; | |
97 | case 'u': arg = Math.abs(arg); break; |
|
97 | case 'u': arg = Math.abs(arg); break; | |
98 | case 'x': arg = arg.toString(16); break; |
|
98 | case 'x': arg = arg.toString(16); break; | |
99 | case 'X': arg = arg.toString(16).toUpperCase(); break; |
|
99 | case 'X': arg = arg.toString(16).toUpperCase(); break; | |
100 | } |
|
100 | } | |
101 | arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); |
|
101 | arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); | |
102 | pad_character = |
|
102 | pad_character = | |
103 | match[4] ? match[4] === '0' ? '0' : match[4].charAt(1) : ' '; |
|
103 | match[4] ? match[4] === '0' ? '0' : match[4].charAt(1) : ' '; | |
104 | pad_length = match[6] - String(arg).length; |
|
104 | pad_length = match[6] - String(arg).length; | |
105 | pad = match[6] ? str_repeat(pad_character, pad_length) : ''; |
|
105 | pad = match[6] ? str_repeat(pad_character, pad_length) : ''; | |
106 | output.push(match[5] ? arg + pad : pad + arg); |
|
106 | output.push(match[5] ? arg + pad : pad + arg); | |
107 | } |
|
107 | } | |
108 | } |
|
108 | } | |
109 | return output.join(''); |
|
109 | return output.join(''); | |
110 | }; |
|
110 | }; | |
111 |
|
111 | |||
112 | str_format.cache = {}; |
|
112 | str_format.cache = {}; | |
113 |
|
113 | |||
114 | str_format.parse = function(fmt) { |
|
114 | str_format.parse = function(fmt) { | |
115 | var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; |
|
115 | var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; | |
116 | while (_fmt) { |
|
116 | while (_fmt) { | |
117 | if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { |
|
117 | if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { | |
118 | parse_tree.push(match[0]); |
|
118 | parse_tree.push(match[0]); | |
119 | } |
|
119 | } | |
120 | else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { |
|
120 | else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { | |
121 | parse_tree.push('%'); |
|
121 | parse_tree.push('%'); | |
122 | } |
|
122 | } | |
123 | else if ( |
|
123 | else if ( | |
124 | (match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { |
|
124 | (match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { | |
125 | if (match[2]) { |
|
125 | if (match[2]) { | |
126 | arg_names |= 1; |
|
126 | arg_names |= 1; | |
127 | var field_list = [], replacement_field = match[2], field_match = []; |
|
127 | var field_list = [], replacement_field = match[2], field_match = []; | |
128 | if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { |
|
128 | if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { | |
129 | field_list.push(field_match[1]); |
|
129 | field_list.push(field_match[1]); | |
130 | while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { |
|
130 | while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { | |
131 | if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { |
|
131 | if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { | |
132 | field_list.push(field_match[1]); |
|
132 | field_list.push(field_match[1]); | |
133 | } |
|
133 | } | |
134 | else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { |
|
134 | else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { | |
135 | field_list.push(field_match[1]); |
|
135 | field_list.push(field_match[1]); | |
136 | } |
|
136 | } | |
137 | else { |
|
137 | else { | |
138 | throw('[sprintf] huh?'); |
|
138 | throw('[sprintf] huh?'); | |
139 | } |
|
139 | } | |
140 | } |
|
140 | } | |
141 | } |
|
141 | } | |
142 | else { |
|
142 | else { | |
143 | throw('[sprintf] huh?'); |
|
143 | throw('[sprintf] huh?'); | |
144 | } |
|
144 | } | |
145 | match[2] = field_list; |
|
145 | match[2] = field_list; | |
146 | } |
|
146 | } | |
147 | else { |
|
147 | else { | |
148 | arg_names |= 2; |
|
148 | arg_names |= 2; | |
149 | } |
|
149 | } | |
150 | if (arg_names === 3) { |
|
150 | if (arg_names === 3) { | |
151 | throw('[sprintf] mixing positional and named placeholders is not (yet) supported'); |
|
151 | throw('[sprintf] mixing positional and named placeholders is not (yet) supported'); | |
152 | } |
|
152 | } | |
153 | parse_tree.push(match); |
|
153 | parse_tree.push(match); | |
154 | } |
|
154 | } | |
155 | else { |
|
155 | else { | |
156 | throw('[sprintf] huh?'); |
|
156 | throw('[sprintf] huh?'); | |
157 | } |
|
157 | } | |
158 | _fmt = _fmt.substring(match[0].length); |
|
158 | _fmt = _fmt.substring(match[0].length); | |
159 | } |
|
159 | } | |
160 | return parse_tree; |
|
160 | return parse_tree; | |
161 | }; |
|
161 | }; | |
162 | return str_format; |
|
162 | return str_format; | |
163 | })(); |
|
163 | })(); | |
164 |
|
164 | |||
165 | var vsprintf = function(fmt, argv) { |
|
165 | var vsprintf = function(fmt, argv) { | |
166 | argv.unshift(fmt); |
|
166 | argv.unshift(fmt); | |
167 | return sprintf.apply(null, argv); |
|
167 | return sprintf.apply(null, argv); | |
168 | }; |
|
168 | }; | |
169 | return { |
|
169 | return { | |
170 | 'asset': function(path, ver) { |
|
170 | 'asset': function(path, ver) { | |
171 | var asset_url = ASSET_URL || '/_static/'; |
|
171 | var asset_url = ASSET_URL || '/_static/rhodecode/'; | |
172 | var ret = asset_url + path; |
|
172 | var ret = asset_url + path; | |
173 | if (ver !== undefined) { |
|
173 | if (ver !== undefined) { | |
174 | ret += '?ver=' + ver; |
|
174 | ret += '?ver=' + ver; | |
175 | } |
|
175 | } | |
176 | return ret; |
|
176 | return ret; | |
177 | }, |
|
177 | }, | |
178 | 'url': function(route_name, params) { |
|
178 | 'url': function(route_name, params) { | |
179 | var result = route_name; |
|
179 | var result = route_name; | |
180 | if (typeof(params) !== 'object'){ |
|
180 | if (typeof(params) !== 'object'){ | |
181 | params = {}; |
|
181 | params = {}; | |
182 | } |
|
182 | } | |
183 | if (matchlist.hasOwnProperty(route_name)) { |
|
183 | if (matchlist.hasOwnProperty(route_name)) { | |
184 | var route = matchlist[route_name]; |
|
184 | var route = matchlist[route_name]; | |
185 | // param substitution |
|
185 | // param substitution | |
186 | for(var i=0; i < route[1].length; i++) { |
|
186 | for(var i=0; i < route[1].length; i++) { | |
187 | var param_name = route[1][i]; |
|
187 | var param_name = route[1][i]; | |
188 | if (!params.hasOwnProperty(param_name)) |
|
188 | if (!params.hasOwnProperty(param_name)) | |
189 | throw new Error( |
|
189 | throw new Error( | |
190 | 'parameter '+ |
|
190 | 'parameter '+ | |
191 | param_name + |
|
191 | param_name + | |
192 | ' is missing in route"' + |
|
192 | ' is missing in route"' + | |
193 | route_name + '" generation'); |
|
193 | route_name + '" generation'); | |
194 | } |
|
194 | } | |
195 | result = sprintf(route[0], params); |
|
195 | result = sprintf(route[0], params); | |
196 |
|
196 | |||
197 | var ret = []; |
|
197 | var ret = []; | |
198 | // extra params => GET |
|
198 | // extra params => GET | |
199 | for (var param in params){ |
|
199 | for (var param in params){ | |
200 | if (route[1].indexOf(param) === -1){ |
|
200 | if (route[1].indexOf(param) === -1){ | |
201 | ret.push(encodeURIComponent(param) + "=" + |
|
201 | ret.push(encodeURIComponent(param) + "=" + | |
202 | encodeURIComponent(params[param])); |
|
202 | encodeURIComponent(params[param])); | |
203 | } |
|
203 | } | |
204 | } |
|
204 | } | |
205 | var _parts = ret.join("&"); |
|
205 | var _parts = ret.join("&"); | |
206 | if(_parts){ |
|
206 | if(_parts){ | |
207 | result = result +'?'+ _parts; |
|
207 | result = result +'?'+ _parts; | |
208 | } |
|
208 | } | |
209 | if(APPLICATION_URL) { |
|
209 | if(APPLICATION_URL) { | |
210 | result = APPLICATION_URL + result; |
|
210 | result = APPLICATION_URL + result; | |
211 | } |
|
211 | } | |
212 | } |
|
212 | } | |
213 |
|
213 | |||
214 | return result; |
|
214 | return result; | |
215 | }, |
|
215 | }, | |
216 | 'register': function(route_name, route_tmpl, req_params) { |
|
216 | 'register': function(route_name, route_tmpl, req_params) { | |
217 | if (typeof(req_params) !== 'object') { |
|
217 | if (typeof(req_params) !== 'object') { | |
218 | req_params = []; |
|
218 | req_params = []; | |
219 | } |
|
219 | } | |
220 | // fix escape |
|
220 | // fix escape | |
221 | route_tmpl = unescape(route_tmpl); |
|
221 | route_tmpl = unescape(route_tmpl); | |
222 | keys = []; |
|
222 | keys = []; | |
223 | for(var i=0; i < req_params.length; i++) { |
|
223 | for(var i=0; i < req_params.length; i++) { | |
224 | keys.push(req_params[i]); |
|
224 | keys.push(req_params[i]); | |
225 | } |
|
225 | } | |
226 | matchlist[route_name] = [ |
|
226 | matchlist[route_name] = [ | |
227 | route_tmpl, |
|
227 | route_tmpl, | |
228 | keys |
|
228 | keys | |
229 | ]; |
|
229 | ]; | |
230 | }, |
|
230 | }, | |
231 | '_routes': function(){ |
|
231 | '_routes': function(){ | |
232 | return matchlist; |
|
232 | return matchlist; | |
233 | } |
|
233 | } | |
234 | }; |
|
234 | }; | |
235 | })(); |
|
235 | })(); |
@@ -1,545 +1,545 b'' | |||||
1 | ## -*- coding: utf-8 -*- |
|
1 | ## -*- coding: utf-8 -*- | |
2 | <%inherit file="/debug_style/index.html"/> |
|
2 | <%inherit file="/debug_style/index.html"/> | |
3 |
|
3 | |||
4 | <%def name="breadcrumbs_links()"> |
|
4 | <%def name="breadcrumbs_links()"> | |
5 | ${h.link_to(_('Style'), h.url('debug_style_home'))} |
|
5 | ${h.link_to(_('Style'), h.url('debug_style_home'))} | |
6 | » |
|
6 | » | |
7 | ${c.active} |
|
7 | ${c.active} | |
8 | </%def> |
|
8 | </%def> | |
9 |
|
9 | |||
10 |
|
10 | |||
11 | <%def name="real_main()"> |
|
11 | <%def name="real_main()"> | |
12 | <div class="box"> |
|
12 | <div class="box"> | |
13 | <div class="title"> |
|
13 | <div class="title"> | |
14 | ${self.breadcrumbs()} |
|
14 | ${self.breadcrumbs()} | |
15 | </div> |
|
15 | </div> | |
16 |
|
16 | |||
17 | <div class='sidebar-col-wrapper'> |
|
17 | <div class='sidebar-col-wrapper'> | |
18 | ##main |
|
18 | ##main | |
19 | ${self.sidebar()} |
|
19 | ${self.sidebar()} | |
20 |
|
20 | |||
21 | <div class="main-content"> |
|
21 | <div class="main-content"> | |
22 |
|
22 | |||
23 | <div style="opacity:.5"> |
|
23 | <div style="opacity:.5"> | |
24 |
|
24 | |||
25 | <h2>Simple tables</h2> |
|
25 | <h2>Simple tables</h2> | |
26 |
|
26 | |||
27 | <p>These styles will be adjusted later to provide a baseline style |
|
27 | <p>These styles will be adjusted later to provide a baseline style | |
28 | for all tables without classes added, whether part of the |
|
28 | for all tables without classes added, whether part of the | |
29 | application or not. Currently, some of the |
|
29 | application or not. Currently, some of the | |
30 | application-specific styles are applied to this table.</p> |
|
30 | application-specific styles are applied to this table.</p> | |
31 | <p>This is a baseline style for all tables, whether part of the |
|
31 | <p>This is a baseline style for all tables, whether part of the | |
32 | application or not. It has no class applied for styling. Use |
|
32 | application or not. It has no class applied for styling. Use | |
33 | the "rctable" class as outlined before for tables which are |
|
33 | the "rctable" class as outlined before for tables which are | |
34 | part of the RhodeCode application.</p> |
|
34 | part of the RhodeCode application.</p> | |
35 | <table> |
|
35 | <table> | |
36 | <tbody> |
|
36 | <tbody> | |
37 | <tr> |
|
37 | <tr> | |
38 | <th>Header A</th> |
|
38 | <th>Header A</th> | |
39 | <th>Header B</th> |
|
39 | <th>Header B</th> | |
40 | <th>Header C</th> |
|
40 | <th>Header C</th> | |
41 | <th>Header D</th> |
|
41 | <th>Header D</th> | |
42 | </tr> |
|
42 | </tr> | |
43 | <tr> |
|
43 | <tr> | |
44 | <td>Content of col A</td> |
|
44 | <td>Content of col A</td> | |
45 | <td>Content of col B</td> |
|
45 | <td>Content of col B</td> | |
46 | <td>Content of col C</td> |
|
46 | <td>Content of col C</td> | |
47 | <td>Content of col D</td> |
|
47 | <td>Content of col D</td> | |
48 | </tr> |
|
48 | </tr> | |
49 | <tr> |
|
49 | <tr> | |
50 | <td>Content of col A</td> |
|
50 | <td>Content of col A</td> | |
51 | <td>Content of col B</td> |
|
51 | <td>Content of col B</td> | |
52 | <td>Content of col C</td> |
|
52 | <td>Content of col C</td> | |
53 | <td>Content of col D</td> |
|
53 | <td>Content of col D</td> | |
54 | </tr> |
|
54 | </tr> | |
55 | <tr> |
|
55 | <tr> | |
56 | <td>Content of col A</td> |
|
56 | <td>Content of col A</td> | |
57 | <td>Content of col B</td> |
|
57 | <td>Content of col B</td> | |
58 | <td>Content of col C</td> |
|
58 | <td>Content of col C</td> | |
59 | <td>Content of col D</td> |
|
59 | <td>Content of col D</td> | |
60 | </tr> |
|
60 | </tr> | |
61 | <tr> |
|
61 | <tr> | |
62 | <td>Content of col A</td> |
|
62 | <td>Content of col A</td> | |
63 | <td>Content of col B</td> |
|
63 | <td>Content of col B</td> | |
64 | <td>Content of col C</td> |
|
64 | <td>Content of col C</td> | |
65 | <td>Content of col D</td> |
|
65 | <td>Content of col D</td> | |
66 | </tr> |
|
66 | </tr> | |
67 | </tbody> |
|
67 | </tbody> | |
68 | </table> |
|
68 | </table> | |
69 | </div> |
|
69 | </div> | |
70 |
|
70 | |||
71 |
|
71 | |||
72 |
|
72 | |||
73 |
|
73 | |||
74 | <h2>RC application table with examples</h2> |
|
74 | <h2>RC application table with examples</h2> | |
75 |
|
75 | |||
76 | <p>This is a standard table which applies the rhodecode-specific styling to be used |
|
76 | <p>This is a standard table which applies the rhodecode-specific styling to be used | |
77 | throughout the application; it has <code><table class="rctable"></code>. |
|
77 | throughout the application; it has <code><table class="rctable"></code>. | |
78 | <br/> |
|
78 | <br/> | |
79 | By default, table data is not truncated, and wraps inside of the <code><td> |
|
79 | By default, table data is not truncated, and wraps inside of the <code><td> | |
80 | ;</code>. To prevent wrapping and contain data on one line, use the <code>< |
|
80 | ;</code>. To prevent wrapping and contain data on one line, use the <code>< | |
81 | class="truncate-wrap"></code> on the <code><td></code>, and <code>span |
|
81 | class="truncate-wrap"></code> on the <code><td></code>, and <code>span | |
82 | class="truncate"</code> around the specific data to be truncated. |
|
82 | class="truncate"</code> around the specific data to be truncated. | |
83 | </p> |
|
83 | </p> | |
84 | <p> |
|
84 | <p> | |
85 | Ellipsis is added via CSS. Please always add a row of headers using <code><th |
|
85 | Ellipsis is added via CSS. Please always add a row of headers using <code><th | |
86 | ></code> to the top of a table. |
|
86 | ></code> to the top of a table. | |
87 | </p> |
|
87 | </p> | |
88 |
|
88 | |||
89 | ## TODO: johbo: in case we have more tables with examples, we should |
|
89 | ## TODO: johbo: in case we have more tables with examples, we should | |
90 | ## create a generic class here. |
|
90 | ## create a generic class here. | |
91 | <table class="rctable issuetracker"> |
|
91 | <table class="rctable issuetracker"> | |
92 | <thead> |
|
92 | <thead> | |
93 | <tr> |
|
93 | <tr> | |
94 | <th>Header A</th> |
|
94 | <th>Header A</th> | |
95 | <th>Header B</th> |
|
95 | <th>Header B</th> | |
96 | <th>Header C</th> |
|
96 | <th>Header C</th> | |
97 | <th>Header D</th> |
|
97 | <th>Header D</th> | |
98 | </tr> |
|
98 | </tr> | |
99 | </thead> |
|
99 | </thead> | |
100 | <tbody> |
|
100 | <tbody> | |
101 | <tr> |
|
101 | <tr> | |
102 | <td class="issue-tracker-example"> |
|
102 | <td class="issue-tracker-example"> | |
103 | Example of col A |
|
103 | Example of col A | |
104 | </td> |
|
104 | </td> | |
105 | <td class="issue-tracker-example"> |
|
105 | <td class="issue-tracker-example"> | |
106 | Example of col B |
|
106 | Example of col B | |
107 | </td> |
|
107 | </td> | |
108 | <td class="issue-tracker-example"> |
|
108 | <td class="issue-tracker-example"> | |
109 | Example of col C |
|
109 | Example of col C | |
110 | </td> |
|
110 | </td> | |
111 | <td class="issue-tracker-example"> |
|
111 | <td class="issue-tracker-example"> | |
112 | Example of col D |
|
112 | Example of col D | |
113 | </td> |
|
113 | </td> | |
114 | </tr> |
|
114 | </tr> | |
115 | <tr> |
|
115 | <tr> | |
116 | <td>Content of col A</td> |
|
116 | <td>Content of col A</td> | |
117 | <td>Content of col B</td> |
|
117 | <td>Content of col B</td> | |
118 | <td>Content of col C which is very long and will not be |
|
118 | <td>Content of col C which is very long and will not be | |
119 | truncated because sometimes people just want to write |
|
119 | truncated because sometimes people just want to write | |
120 | really, really long commit messages which explain what |
|
120 | really, really long commit messages which explain what | |
121 | they did in excruciating detail and you really, really |
|
121 | they did in excruciating detail and you really, really | |
122 | want to read them.</td> |
|
122 | want to read them.</td> | |
123 | <td>Content of col D</td> |
|
123 | <td>Content of col D</td> | |
124 | </tr> |
|
124 | </tr> | |
125 | <tr> |
|
125 | <tr> | |
126 | <td>Content of col A</td> |
|
126 | <td>Content of col A</td> | |
127 | <td>Content of col B</td> |
|
127 | <td>Content of col B</td> | |
128 | <td>Content of col C</td> |
|
128 | <td>Content of col C</td> | |
129 | <td class="truncate-wrap"><span class="truncate">Truncated |
|
129 | <td class="truncate-wrap"><span class="truncate">Truncated | |
130 | content of column D truncate truncate truncatetruncate |
|
130 | content of column D truncate truncate truncatetruncate | |
131 | truncate truncate</span></td> |
|
131 | truncate truncate</span></td> | |
132 | </tr> |
|
132 | </tr> | |
133 | </tbody> |
|
133 | </tbody> | |
134 | </table> |
|
134 | </table> | |
135 |
|
135 | |||
136 | <h2>RC application table data classes</h2> |
|
136 | <h2>RC application table data classes</h2> | |
137 |
|
137 | |||
138 | <p>The following tables contain documentation of all existing table data classes. |
|
138 | <p>The following tables contain documentation of all existing table data classes. | |
139 | Please update when new classes are made. |
|
139 | Please update when new classes are made. | |
140 | </p> |
|
140 | </p> | |
141 | <table class="rctable examples"> |
|
141 | <table class="rctable examples"> | |
142 | <thead> |
|
142 | <thead> | |
143 | <tr> |
|
143 | <tr> | |
144 | <th>Class</th> |
|
144 | <th>Class</th> | |
145 | <th>Description</th> |
|
145 | <th>Description</th> | |
146 | <th>Example</th> |
|
146 | <th>Example</th> | |
147 | </tr> |
|
147 | </tr> | |
148 | </thead> |
|
148 | </thead> | |
149 | <tbody> |
|
149 | <tbody> | |
150 | <td>td-user</td> |
|
150 | <td>td-user</td> | |
151 | <td>Any username/gravatar combination (see also Icons style).</td> |
|
151 | <td>Any username/gravatar combination (see also Icons style).</td> | |
152 | <td class="td-user author"> |
|
152 | <td class="td-user author"> | |
153 | <img class="gravatar" alt="gravatar" src="https://secure.gravatar.com/avatar/0c9a7e6674b6f0b35d98dbe073e3f0ab?d=identicon&s=32" height="16" width="16"> |
|
153 | <img class="gravatar" alt="gravatar" src="https://secure.gravatar.com/avatar/0c9a7e6674b6f0b35d98dbe073e3f0ab?d=identicon&s=32" height="16" width="16"> | |
154 | <span title="Oliver Strobel <oliver@rhodecode.com>" class="user">ostrobel (Oliver Strobel)</span> |
|
154 | <span title="Oliver Strobel <oliver@rhodecode.com>" class="user">ostrobel (Oliver Strobel)</span> | |
155 | </td> |
|
155 | </td> | |
156 | </tr> |
|
156 | </tr> | |
157 | <tr> |
|
157 | <tr> | |
158 | <td>td-hash</td> |
|
158 | <td>td-hash</td> | |
159 | <td>Any hash; a commit, revision, etc. Use <code><pre></code> and header 'Commit'</td> |
|
159 | <td>Any hash; a commit, revision, etc. Use <code><pre></code> and header 'Commit'</td> | |
160 | <td class="td-commit"> |
|
160 | <td class="td-commit"> | |
161 | <pre><a href="/anothercpythonforkkkk/files/8d6b27837c6979983b037693fe975cdbb761b500/">r93699:8d6b27837c69</a></pre> |
|
161 | <pre><a href="/anothercpythonforkkkk/files/8d6b27837c6979983b037693fe975cdbb761b500/">r93699:8d6b27837c69</a></pre> | |
162 | </td> |
|
162 | </td> | |
163 | </tr> |
|
163 | </tr> | |
164 | <tr> |
|
164 | <tr> | |
165 | <td>td-rss</td> |
|
165 | <td>td-rss</td> | |
166 | <td>RSS feed link icon</td> |
|
166 | <td>RSS feed link icon</td> | |
167 | <td class="td-rss"> |
|
167 | <td class="td-rss"> | |
168 | <a title="Subscribe to rss feed" href="/feed/rss"><i class="icon-rss-sign"></i></a> |
|
168 | <a title="Subscribe to rss feed" href="/feed/rss"><i class="icon-rss-sign"></i></a> | |
169 | </td> |
|
169 | </td> | |
170 | </tr> |
|
170 | </tr> | |
171 | <tr> |
|
171 | <tr> | |
172 | <td>td-componentname</td> |
|
172 | <td>td-componentname</td> | |
173 | <td>Any group, file, gist, or directory name.</td> |
|
173 | <td>Any group, file, gist, or directory name.</td> | |
174 | <td class="td-componentname"> |
|
174 | <td class="td-componentname"> | |
175 | <a href="/cpythonfork"> |
|
175 | <a href="/cpythonfork"> | |
176 | <span title="Mercurial repository"><i class="icon-hg"></i></span> |
|
176 | <span title="Mercurial repository"><i class="icon-hg"></i></span> | |
177 | <i class="icon-unlock-alt" title="Public repository"></i> |
|
177 | <i class="icon-unlock-alt" title="Public repository"></i> | |
178 | rhodecode-dev-restyle-fork |
|
178 | rhodecode-dev-restyle-fork | |
179 | </a> |
|
179 | </a> | |
180 | </td> |
|
180 | </td> | |
181 | </tr> |
|
181 | </tr> | |
182 | <tr> |
|
182 | <tr> | |
183 | <td>td-tags</td> |
|
183 | <td>td-tags</td> | |
184 | <td>Any cell containing tags, including branches and bookmarks.</td> |
|
184 | <td>Any cell containing tags, including branches and bookmarks.</td> | |
185 | <td class="td-tags"> |
|
185 | <td class="td-tags"> | |
186 | <span class="branchtag tag" title="Branch default"> |
|
186 | <span class="branchtag tag" title="Branch default"> | |
187 | <a href="/rhodecode-dev-restyle- fork/changelog?branch=default"><i class="icon-code-fork"></i>default</a> |
|
187 | <a href="/rhodecode-dev-restyle- fork/changelog?branch=default"><i class="icon-code-fork"></i>default</a> | |
188 | </span> |
|
188 | </span> | |
189 | </td> |
|
189 | </td> | |
190 | </tr> |
|
190 | </tr> | |
191 | <tr> |
|
191 | <tr> | |
192 | <td>tags-truncate</td> |
|
192 | <td>tags-truncate</td> | |
193 | <td>Used to truncate a cell containing tags; avoid if possible.</td> |
|
193 | <td>Used to truncate a cell containing tags; avoid if possible.</td> | |
194 | <td class="td-tags truncate-wrap"> |
|
194 | <td class="td-tags truncate-wrap"> | |
195 | <div class="truncate tags-truncate"> |
|
195 | <div class="truncate tags-truncate"> | |
196 | <div class="autoexpand"> |
|
196 | <div class="autoexpand"> | |
197 | <span class="tagtag tag" title="Tag tip"> |
|
197 | <span class="tagtag tag" title="Tag tip"> | |
198 | <a href="/rhodecode-dev-restyle-fork/files/e519d5a0e71466d27257ddff921c4a13c540408e/"><i class="icon-tag"></i>tip</a> |
|
198 | <a href="/rhodecode-dev-restyle-fork/files/e519d5a0e71466d27257ddff921c4a13c540408e/"><i class="icon-tag"></i>tip</a> | |
199 | </span> |
|
199 | </span> | |
200 | <span class="branchtag tag" title="Branch default"> |
|
200 | <span class="branchtag tag" title="Branch default"> | |
201 | <a href="/rhodecode-dev-restyle-fork/changelog?branch=default"><i class="icon-code-fork"></i>default</a> |
|
201 | <a href="/rhodecode-dev-restyle-fork/changelog?branch=default"><i class="icon-code-fork"></i>default</a> | |
202 | </span> |
|
202 | </span> | |
203 | <span class="branchtag tag" title="Branch default"> |
|
203 | <span class="branchtag tag" title="Branch default"> | |
204 | <a href="/rhodecode-dev-restyle-fork/changelog?branch=default"><i class="icon-code-fork"></i>default</a> |
|
204 | <a href="/rhodecode-dev-restyle-fork/changelog?branch=default"><i class="icon-code-fork"></i>default</a> | |
205 | </span> |
|
205 | </span> | |
206 | </div> |
|
206 | </div> | |
207 | </div> |
|
207 | </div> | |
208 | </td> |
|
208 | </td> | |
209 | </tr> |
|
209 | </tr> | |
210 | <tr> |
|
210 | <tr> | |
211 | <td>td-ip</td> |
|
211 | <td>td-ip</td> | |
212 | <td>Any ip address.</td> |
|
212 | <td>Any ip address.</td> | |
213 | <td class="td-ip"> |
|
213 | <td class="td-ip"> | |
214 | 172.16.115.168 |
|
214 | 172.16.115.168 | |
215 | </td> |
|
215 | </td> | |
216 | </tr> |
|
216 | </tr> | |
217 | <tr> |
|
217 | <tr> | |
218 | <td>td-type</td> |
|
218 | <td>td-type</td> | |
219 | <td>A state or an auth type.</td> |
|
219 | <td>A state or an auth type.</td> | |
220 | <td class="td-type"> |
|
220 | <td class="td-type"> | |
221 | rhodecode |
|
221 | rhodecode | |
222 | </td> |
|
222 | </td> | |
223 | </tr> |
|
223 | </tr> | |
224 | <tr> |
|
224 | <tr> | |
225 | <td>td-authtoken</td> |
|
225 | <td>td-authtoken</td> | |
226 | <td>For auth tokens. Use truncate classes for hover expand; see html.</td> |
|
226 | <td>For auth tokens. Use truncate classes for hover expand; see html.</td> | |
227 | <td class="truncate-wrap td-authtoken"> |
|
227 | <td class="truncate-wrap td-authtoken"> | |
228 | <div class="truncate autoexpand"> |
|
228 | <div class="truncate autoexpand"> | |
229 | <code>688df65b87d3ad16ae9f8fc6338a551d40f41c7a</code> |
|
229 | <code>688df65b87d3ad16ae9f8fc6338a551d40f41c7a</code> | |
230 | </div> |
|
230 | </div> | |
231 | </td> |
|
231 | </td> | |
232 | </tr> |
|
232 | </tr> | |
233 | <tr> |
|
233 | <tr> | |
234 | <td>td-action</td> |
|
234 | <td>td-action</td> | |
235 | <td>Buttons which perform an action.</td> |
|
235 | <td>Buttons which perform an action.</td> | |
236 | <td class="td-action"> |
|
236 | <td class="td-action"> | |
237 | <div class="grid_edit"> |
|
237 | <div class="grid_edit"> | |
238 | <a href="/_admin/users/2/edit" title="edit"> |
|
238 | <a href="/_admin/users/2/edit" title="edit"> | |
239 | <i class="icon-pencil"></i>Edit</a> |
|
239 | <i class="icon-pencil"></i>Edit</a> | |
240 | </div> |
|
240 | </div> | |
241 | <div class="grid_delete"> |
|
241 | <div class="grid_delete"> | |
242 | <form action="/_admin/users/2" method="post"> |
|
242 | <form action="/_admin/users/2" method="post"> | |
243 | <i class="icon-remove-sign"></i> |
|
243 | <i class="icon-remove-sign"></i> | |
244 | <input class="btn btn-danger btn-link" id="remove_user_2" name="remove_" type="submit" value="delete"> |
|
244 | <input class="btn btn-danger btn-link" id="remove_user_2" name="remove_" type="submit" value="delete"> | |
245 | </form> |
|
245 | </form> | |
246 | </div> |
|
246 | </div> | |
247 | </td> |
|
247 | </td> | |
248 | </tr> |
|
248 | </tr> | |
249 | <tr> |
|
249 | <tr> | |
250 | <td>td-radio</td> |
|
250 | <td>td-radio</td> | |
251 | <td>Radio buttons for a form. Centers element.</td> |
|
251 | <td>Radio buttons for a form. Centers element.</td> | |
252 | <td class="td-radio"> |
|
252 | <td class="td-radio"> | |
253 | <input type="radio" checked="checked" value="" name="1" id="read"></td> |
|
253 | <input type="radio" checked="checked" value="" name="1" id="read"></td> | |
254 | </tr> |
|
254 | </tr> | |
255 | <tr> |
|
255 | <tr> | |
256 | <td>td-checkbox</td> |
|
256 | <td>td-checkbox</td> | |
257 | <td>Checkbox for a form. Centers element.</td> |
|
257 | <td>Checkbox for a form. Centers element.</td> | |
258 | <td class="td-checkbox"> |
|
258 | <td class="td-checkbox"> | |
259 | <input type="checkbox" checked="checked" value="" name="1" id="read"></td> |
|
259 | <input type="checkbox" checked="checked" value="" name="1" id="read"></td> | |
260 | </tr> |
|
260 | </tr> | |
261 | <tr> |
|
261 | <tr> | |
262 | <tr> |
|
262 | <tr> | |
263 | <td>td-buttons</td> |
|
263 | <td>td-buttons</td> | |
264 | <td>Buttons.</td> |
|
264 | <td>Buttons.</td> | |
265 | <td class="td-buttons"> |
|
265 | <td class="td-buttons"> | |
266 | <span class="btn btn-mini btn-primary">feed access</span> |
|
266 | <span class="btn btn-mini btn-primary">feed access</span> | |
267 | </td> |
|
267 | </td> | |
268 | </tr> |
|
268 | </tr> | |
269 | <tr> |
|
269 | <tr> | |
270 | <td>td-compare</td> |
|
270 | <td>td-compare</td> | |
271 | <td>Radio buttons to compare commits.</td> |
|
271 | <td>Radio buttons to compare commits.</td> | |
272 | <td class=" td-compare"> |
|
272 | <td class=" td-compare"> | |
273 | <input class="compare-radio-button" type="radio" name="compare_source" value="2.0"> |
|
273 | <input class="compare-radio-button" type="radio" name="compare_source" value="2.0"> | |
274 | <input class="compare-radio-button" type="radio" name="compare_target" value="2.0"> |
|
274 | <input class="compare-radio-button" type="radio" name="compare_target" value="2.0"> | |
275 | </td> |
|
275 | </td> | |
276 | </tr> |
|
276 | </tr> | |
277 | <tr> |
|
277 | <tr> | |
278 | <td>td-comments</td> |
|
278 | <td>td-comments</td> | |
279 | <td>Comments indicator icon.</td> |
|
279 | <td>Comments indicator icon.</td> | |
280 | <td> |
|
280 | <td> | |
281 | <i class="icon-comment icon-comment-colored"></i> 0 |
|
281 | <i class="icon-comment icon-comment-colored"></i> 0 | |
282 | </td> |
|
282 | </td> | |
283 | </tr> |
|
283 | </tr> | |
284 | <tr> |
|
284 | <tr> | |
285 | <td>td-status</td> |
|
285 | <td>td-status</td> | |
286 | <td>Status indicator icon.</td> |
|
286 | <td>Status indicator icon.</td> | |
287 | <td class="td-description"> |
|
287 | <td class="td-description"> | |
288 | <div class="flag_status under_review pull-left"></div> |
|
288 | <div class="flag_status under_review pull-left"></div> | |
289 | </td> |
|
289 | </td> | |
290 | </tr> |
|
290 | </tr> | |
291 | </tbody> |
|
291 | </tbody> | |
292 | </table> |
|
292 | </table> | |
293 | <table class="dataTable rctable examples"> |
|
293 | <table class="dataTable rctable examples"> | |
294 | <tbody> |
|
294 | <tbody> | |
295 | <tr> |
|
295 | <tr> | |
296 | <td>quick_repo_menu</td> |
|
296 | <td>quick_repo_menu</td> | |
297 | <td>Hidden menu generated by dataTable.</td> |
|
297 | <td>Hidden menu generated by dataTable.</td> | |
298 | <td class="quick_repo_menu"> |
|
298 | <td class="quick_repo_menu"> | |
299 | <i class="pointer icon-more"></i> |
|
299 | <i class="pointer icon-more"></i> | |
300 | <div class="menu_items_container" style="display: none;"> |
|
300 | <div class="menu_items_container" style="display: none;"> | |
301 | <ul class="menu_items"> |
|
301 | <ul class="menu_items"> | |
302 | <li> |
|
302 | <li> | |
303 | <a title="Summary" href="/anothercpythonforkkkk-fork"> |
|
303 | <a title="Summary" href="/anothercpythonforkkkk-fork"> | |
304 | <span>Summary</span> |
|
304 | <span>Summary</span> | |
305 | </a> |
|
305 | </a> | |
306 | </li> |
|
306 | </li> | |
307 | <li> |
|
307 | <li> | |
308 | <a title="Changelog" href="/anothercpythonforkkkk-fork/changelog"> |
|
308 | <a title="Changelog" href="/anothercpythonforkkkk-fork/changelog"> | |
309 | <span>Changelog</span> |
|
309 | <span>Changelog</span> | |
310 | </a> |
|
310 | </a> | |
311 | </li> |
|
311 | </li> | |
312 | <li> |
|
312 | <li> | |
313 | <a title="Files" href="/anothercpythonforkkkk-fork/files/tip/"> |
|
313 | <a title="Files" href="/anothercpythonforkkkk-fork/files/tip/"> | |
314 | <span>Files</span> |
|
314 | <span>Files</span> | |
315 | </a> |
|
315 | </a> | |
316 | </li> |
|
316 | </li> | |
317 | <li> |
|
317 | <li> | |
318 | <a title="Fork" href="/anothercpythonforkkkk-fork/fork"> |
|
318 | <a title="Fork" href="/anothercpythonforkkkk-fork/fork"> | |
319 | <span>Fork</span> |
|
319 | <span>Fork</span> | |
320 | </a> |
|
320 | </a> | |
321 | </li> |
|
321 | </li> | |
322 | </ul> |
|
322 | </ul> | |
323 | </div> |
|
323 | </div> | |
324 | </td> |
|
324 | </td> | |
325 | <td></td> |
|
325 | <td></td> | |
326 | </tr> |
|
326 | </tr> | |
327 | </tbody> |
|
327 | </tbody> | |
328 | </table> |
|
328 | </table> | |
329 | <script>quick_repo_menu();</script> |
|
329 | <script>quick_repo_menu();</script> | |
330 | <table class="rctable examples"> |
|
330 | <table class="rctable examples"> | |
331 | <tbody> |
|
331 | <tbody> | |
332 | <tr> |
|
332 | <tr> | |
333 | <td>td-description</td> |
|
333 | <td>td-description</td> | |
334 | <td>Any description. They may be rather long, and using the expand_commit outlined below is recommended.</td> |
|
334 | <td>Any description. They may be rather long, and using the expand_commit outlined below is recommended.</td> | |
335 | <td class="td-description"> |
|
335 | <td class="td-description"> | |
336 | Ultrices mattis! Enim pellentesque lacus, sit magna natoque risus turpis ut, auctor ultrices facilisis dapibus odio? Parturient! Porta egestas nascetur, quis, elementum dolor, in magna ac dis sit etiam turpis, scelerisque! Integer tristique aliquam. |
|
336 | Ultrices mattis! Enim pellentesque lacus, sit magna natoque risus turpis ut, auctor ultrices facilisis dapibus odio? Parturient! Porta egestas nascetur, quis, elementum dolor, in magna ac dis sit etiam turpis, scelerisque! Integer tristique aliquam. | |
337 | </td> |
|
337 | </td> | |
338 | </tr> |
|
338 | </tr> | |
339 | </tbody> |
|
339 | </tbody> | |
340 | </table> |
|
340 | </table> | |
341 | <table id="changesets" class="rctable examples end"> |
|
341 | <table id="changesets" class="rctable examples end"> | |
342 | <tbody> |
|
342 | <tbody> | |
343 | <tr> |
|
343 | <tr> | |
344 | <td>expand_commit</td> |
|
344 | <td>expand_commit</td> | |
345 | <td>Expands a long message; see html+js.</td> |
|
345 | <td>Expands a long message; see html+js.</td> | |
346 | <td class="expand_commit" data-commit-id="2ffc6faabc7a9c790b1b452943a3f0c047b8b436" title="Expand commit message"> |
|
346 | <td class="expand_commit" data-commit-id="2ffc6faabc7a9c790b1b452943a3f0c047b8b436" title="Expand commit message"> | |
347 | <div class="show_more_col"> |
|
347 | <div class="show_more_col"> | |
348 | <i class="show_more"></i> |
|
348 | <i class="show_more"></i> | |
349 | </div> |
|
349 | </div> | |
350 | </td> |
|
350 | </td> | |
351 | <td class="mid td-description"> |
|
351 | <td class="mid td-description"> | |
352 | <div class="log-container truncate-wrap"> |
|
352 | <div class="log-container truncate-wrap"> | |
353 | <div id="c-2ffc6faabc7a9c790b1b452943a3f0c047b8b436" class="message truncate" data-message-raw="tests: Test echo method on the server object |
|
353 | <div id="c-2ffc6faabc7a9c790b1b452943a3f0c047b8b436" class="message truncate" data-message-raw="tests: Test echo method on the server object | |
354 |
|
354 | |||
355 | This only works for Pyro4 so far, have to extend it still for HTTP to work.">tests: Test echo method on the server object |
|
355 | This only works for Pyro4 so far, have to extend it still for HTTP to work.">tests: Test echo method on the server object | |
356 |
|
356 | |||
357 | This only works for Pyro4 so far, have to extend it still for HTTP to work.</div> |
|
357 | This only works for Pyro4 so far, have to extend it still for HTTP to work.</div> | |
358 | </div> |
|
358 | </div> | |
359 | </td> |
|
359 | </td> | |
360 | </tr> |
|
360 | </tr> | |
361 | </tbody> |
|
361 | </tbody> | |
362 | </table> |
|
362 | </table> | |
363 | <script type="text/javascript"> |
|
363 | <script type="text/javascript"> | |
364 | var cache = {} |
|
364 | var cache = {} | |
365 | $('.expand_commit').on('click',function(e){ |
|
365 | $('.expand_commit').on('click',function(e){ | |
366 | var target_expand = $(this); |
|
366 | var target_expand = $(this); | |
367 | var cid = target_expand.data('commitId'); |
|
367 | var cid = target_expand.data('commitId'); | |
368 |
|
368 | |||
369 | if (target_expand.hasClass('open')){ |
|
369 | if (target_expand.hasClass('open')){ | |
370 | $('#c-'+cid).css({'height': '1.5em', 'white-space': 'nowrap', 'text-overflow': 'ellipsis', 'overflow':'hidden'}); |
|
370 | $('#c-'+cid).css({'height': '1.5em', 'white-space': 'nowrap', 'text-overflow': 'ellipsis', 'overflow':'hidden'}); | |
371 | $('#t-'+cid).css({'height': '1.5em', 'max-height': '1.5em', 'text-overflow': 'ellipsis', 'overflow':'hidden', 'white-space':'nowrap'}); |
|
371 | $('#t-'+cid).css({'height': '1.5em', 'max-height': '1.5em', 'text-overflow': 'ellipsis', 'overflow':'hidden', 'white-space':'nowrap'}); | |
372 | target_expand.removeClass('open'); |
|
372 | target_expand.removeClass('open'); | |
373 | } |
|
373 | } | |
374 | else { |
|
374 | else { | |
375 | $('#c-'+cid).css({'height': 'auto', 'white-space': 'pre-line', 'text-overflow': 'initial', 'overflow':'visible'}); |
|
375 | $('#c-'+cid).css({'height': 'auto', 'white-space': 'pre-line', 'text-overflow': 'initial', 'overflow':'visible'}); | |
376 | $('#t-'+cid).css({'height': 'auto', 'max-height': 'none', 'text-overflow': 'initial', 'overflow':'visible', 'white-space':'normal'}); |
|
376 | $('#t-'+cid).css({'height': 'auto', 'max-height': 'none', 'text-overflow': 'initial', 'overflow':'visible', 'white-space':'normal'}); | |
377 | target_expand.addClass('open'); |
|
377 | target_expand.addClass('open'); | |
378 | } |
|
378 | } | |
379 | }); |
|
379 | }); | |
380 |
|
380 | |||
381 | </script> |
|
381 | </script> | |
382 | <p>The following classes currently do not have unique styles applied.</p> |
|
382 | <p>The following classes currently do not have unique styles applied.</p> | |
383 | <table class="rctable examples end"> |
|
383 | <table class="rctable examples end"> | |
384 | <tbody> |
|
384 | <tbody> | |
385 | <tr> |
|
385 | <tr> | |
386 | <td>td-regex</td> |
|
386 | <td>td-regex</td> | |
387 | <td>Regex patterns</td> |
|
387 | <td>Regex patterns</td> | |
388 | <td class="td-regex">(?:#)(?P<issue_id>\d+)</td> |
|
388 | <td class="td-regex">(?:#)(?P<issue_id>\d+)</td> | |
389 | </tr> |
|
389 | </tr> | |
390 | <tr> |
|
390 | <tr> | |
391 | <td>td-url</td> |
|
391 | <td>td-url</td> | |
392 | <td>Any URL.</td> |
|
392 | <td>Any URL.</td> | |
393 | <td class="td-url">https://rhodecode.com</td> |
|
393 | <td class="td-url">https://rhodecode.com</td> | |
394 | </tr> |
|
394 | </tr> | |
395 | <tr> |
|
395 | <tr> | |
396 | <td>td-journalaction</td> |
|
396 | <td>td-journalaction</td> | |
397 | <td>Action listed in a journal</td> |
|
397 | <td>Action listed in a journal</td> | |
398 | <td class="td-journalaction">started following repository supervisor-fork-4</td> |
|
398 | <td class="td-journalaction">started following repository supervisor-fork-4</td> | |
399 | </tr> |
|
399 | </tr> | |
400 | <tr> |
|
400 | <tr> | |
401 | <td>td-iprange</td> |
|
401 | <td>td-iprange</td> | |
402 | <td>Any ip address.</td> |
|
402 | <td>Any ip address.</td> | |
403 | <td class="td-ip">127.0.0.1-127.0.0.10</td> |
|
403 | <td class="td-ip">127.0.0.1-127.0.0.10</td> | |
404 | </tr> |
|
404 | </tr> | |
405 | <tr> |
|
405 | <tr> | |
406 | <td>td-exp</td> |
|
406 | <td>td-exp</td> | |
407 | <td>Expiration time.</td> |
|
407 | <td>Expiration time.</td> | |
408 | <td class="td-exp">never</td> |
|
408 | <td class="td-exp">never</td> | |
409 | </tr> |
|
409 | </tr> | |
410 | <tr> |
|
410 | <tr> | |
411 | <td>td-prefix</td> |
|
411 | <td>td-prefix</td> | |
412 | <td>Prefixes outlined in settings.</td> |
|
412 | <td>Prefixes outlined in settings.</td> | |
413 | <td class="td-prefix">ubuntu-92539</td> |
|
413 | <td class="td-prefix">ubuntu-92539</td> | |
414 | </tr> |
|
414 | </tr> | |
415 | <tr> |
|
415 | <tr> | |
416 | <td>td-cachekey</td> |
|
416 | <td>td-cachekey</td> | |
417 | <td>Cache key value.</td> |
|
417 | <td>Cache key value.</td> | |
418 | <td class="td-cachekey">ubuntu-92539supervisor</td> |
|
418 | <td class="td-cachekey">ubuntu-92539supervisor</td> | |
419 | </tr> |
|
419 | </tr> | |
420 | <tr> |
|
420 | <tr> | |
421 | <td>td-email</td> |
|
421 | <td>td-email</td> | |
422 | <td>Any email address.</td> |
|
422 | <td>Any email address.</td> | |
423 | <td class="td-email">example@rhodecode.com</td> |
|
423 | <td class="td-email">example@rhodecode.com</td> | |
424 | </tr> |
|
424 | </tr> | |
425 | <tr> |
|
425 | <tr> | |
426 | <td>td-active</td> |
|
426 | <td>td-active</td> | |
427 | <td>Shows active state with icon-true/icon-false.</td> |
|
427 | <td>Shows active state with icon-true/icon-false.</td> | |
428 | <td class="td-active"><i class="icon-false"></i></td> |
|
428 | <td class="td-active"><i class="icon-false"></i></td> | |
429 | </tr> |
|
429 | </tr> | |
430 | <tr> |
|
430 | <tr> | |
431 | <td>td-size</td> |
|
431 | <td>td-size</td> | |
432 | <td>File, repo, or directory size.</td> |
|
432 | <td>File, repo, or directory size.</td> | |
433 | <td class="td-size">89 MB</td> |
|
433 | <td class="td-size">89 MB</td> | |
434 | </tr> |
|
434 | </tr> | |
435 | <tr> |
|
435 | <tr> | |
436 | <td>td-number</td> |
|
436 | <td>td-number</td> | |
437 | <td>Any numerical data.</td> |
|
437 | <td>Any numerical data.</td> | |
438 | <td class="td-number">42</td> |
|
438 | <td class="td-number">42</td> | |
439 | </tr> |
|
439 | </tr> | |
440 | <tr> |
|
440 | <tr> | |
441 | <td>td-message</td> |
|
441 | <td>td-message</td> | |
442 | <td>Any commit message. Often treated with the truncate class used for descriptions as well.</td> |
|
442 | <td>Any commit message. Often treated with the truncate class used for descriptions as well.</td> | |
443 | <td class="td-message">Updated the files</td> |
|
443 | <td class="td-message">Updated the files</td> | |
444 | </tr> |
|
444 | </tr> | |
445 | </tbody> |
|
445 | </tbody> | |
446 | </table> |
|
446 | </table> | |
447 |
|
447 | |||
448 |
|
448 | |||
449 | <h2>Permissions table</h2> |
|
449 | <h2>Permissions table</h2> | |
450 |
|
450 | |||
451 | <p> |
|
451 | <p> | |
452 | This is a special-case table; it has |
|
452 | This is a special-case table; it has | |
453 | <code>table class="rctable permissions"</code> |
|
453 | <code>table class="rctable permissions"</code> | |
454 | where "rctable" applies the rhodecode styling as above, and |
|
454 | where "rctable" applies the rhodecode styling as above, and | |
455 | "permissions" adds an extra layer of customization specific to |
|
455 | "permissions" adds an extra layer of customization specific to | |
456 | permissions tables. Other special-case tables may exist or be |
|
456 | permissions tables. Other special-case tables may exist or be | |
457 | created if necessary. |
|
457 | created if necessary. | |
458 | </p> |
|
458 | </p> | |
459 |
|
459 | |||
460 | <table class="rctable permissions"> |
|
460 | <table class="rctable permissions"> | |
461 | <tr> |
|
461 | <tr> | |
462 | <th class="td-radio">none</th> |
|
462 | <th class="td-radio">none</th> | |
463 | <th class="td-radio">read</th> |
|
463 | <th class="td-radio">read</th> | |
464 | <th class="td-radio">write</th> |
|
464 | <th class="td-radio">write</th> | |
465 | <th class="td-radio">admin</th> |
|
465 | <th class="td-radio">admin</th> | |
466 | <th>user/user group</th> |
|
466 | <th>user/user group</th> | |
467 | <th></th> |
|
467 | <th></th> | |
468 | </tr> |
|
468 | </tr> | |
469 | <tr class="perm_admin_row"> |
|
469 | <tr class="perm_admin_row"> | |
470 | <td class="td-radio"><input type="radio" value="repository.none" |
|
470 | <td class="td-radio"><input type="radio" value="repository.none" | |
471 | name="admin_perm_2" id="admin_perm_2_repositorynone" |
|
471 | name="admin_perm_2" id="admin_perm_2_repositorynone" | |
472 | disabled="disabled"></td> |
|
472 | disabled="disabled"></td> | |
473 | <td class="td-radio"><input type="radio" value="repository.read" |
|
473 | <td class="td-radio"><input type="radio" value="repository.read" | |
474 | name="admin_perm_2" id="admin_perm_2_repositoryread" |
|
474 | name="admin_perm_2" id="admin_perm_2_repositoryread" | |
475 | disabled="disabled"></td> |
|
475 | disabled="disabled"></td> | |
476 | <td class="td-radio"><input type="radio" value="repository.write" |
|
476 | <td class="td-radio"><input type="radio" value="repository.write" | |
477 | name="admin_perm_2" id="admin_perm_2_repositorywrite" |
|
477 | name="admin_perm_2" id="admin_perm_2_repositorywrite" | |
478 | disabled="disabled"></td> |
|
478 | disabled="disabled"></td> | |
479 | <td class="td-radio"><input type="radio" value="repository.admin" |
|
479 | <td class="td-radio"><input type="radio" value="repository.admin" | |
480 | name="admin_perm_2" id="admin_perm_2_repositoryadmin" |
|
480 | name="admin_perm_2" id="admin_perm_2_repositoryadmin" | |
481 | disabled="disabled" checked="checked"></td> |
|
481 | disabled="disabled" checked="checked"></td> | |
482 | <td> |
|
482 | <td> | |
483 | <img class="gravatar" src="https://secure.gravatar.com/avatar/be9d18f611892a738e54f2a3a171e2f9?d=identicon&s=32" height="16" width="16"> |
|
483 | <img class="gravatar" src="https://secure.gravatar.com/avatar/be9d18f611892a738e54f2a3a171e2f9?d=identicon&s=32" height="16" width="16"> | |
484 | <span class="user">dev (super admin) (owner)</span> |
|
484 | <span class="user">dev (super admin) (owner)</span> | |
485 | </td> |
|
485 | </td> | |
486 | <td></td> |
|
486 | <td></td> | |
487 | </tr> |
|
487 | </tr> | |
488 | <tr> |
|
488 | <tr> | |
489 | <td colspan="4"> |
|
489 | <td colspan="4"> | |
490 | <span class="private_repo_msg"> |
|
490 | <span class="private_repo_msg"> | |
491 | private repository |
|
491 | private repository | |
492 | </span> |
|
492 | </span> | |
493 | </td> |
|
493 | </td> | |
494 | <td class="private_repo_msg"> |
|
494 | <td class="private_repo_msg"> | |
495 | <i class="icon-user"></i> |
|
495 | <i class="icon-user"></i> | |
496 | default - only people explicitly added here will have access</td> |
|
496 | default - only people explicitly added here will have access</td> | |
497 | <td></td> |
|
497 | <td></td> | |
498 | </tr> |
|
498 | </tr> | |
499 | <tr> |
|
499 | <tr> | |
500 | <td class="td-radio"><input type="radio" value="repository.none" |
|
500 | <td class="td-radio"><input type="radio" value="repository.none" | |
501 | name="u_perm_1" id="u_perm_1_repositorynone"></td> |
|
501 | name="u_perm_1" id="u_perm_1_repositorynone"></td> | |
502 | <td class="td-radio"><input type="radio" checked="checked" |
|
502 | <td class="td-radio"><input type="radio" checked="checked" | |
503 | value="repository.read" name="u_perm_1" |
|
503 | value="repository.read" name="u_perm_1" | |
504 | id="u_perm_1_repositoryread"></td> |
|
504 | id="u_perm_1_repositoryread"></td> | |
505 | <td class="td-radio"><input type="radio" value="repository.write" |
|
505 | <td class="td-radio"><input type="radio" value="repository.write" | |
506 | name="u_perm_1" id="u_perm_1_repositorywrite"></td> |
|
506 | name="u_perm_1" id="u_perm_1_repositorywrite"></td> | |
507 | <td class="td-radio"><input type="radio" value="repository.admin" |
|
507 | <td class="td-radio"><input type="radio" value="repository.admin" | |
508 | name="u_perm_1" id="u_perm_1_repositoryadmin"></td> |
|
508 | name="u_perm_1" id="u_perm_1_repositoryadmin"></td> | |
509 | <td> |
|
509 | <td> | |
510 | <img class="gravatar" src="/_static/images/user30.png" height="16" width="16"> |
|
510 | <img class="gravatar" src="/_static/rhodecode/images/user30.png" height="16" width="16"> | |
511 | <span class="user">default</span> |
|
511 | <span class="user">default</span> | |
512 | </td> |
|
512 | </td> | |
513 | <td></td> |
|
513 | <td></td> | |
514 | </tr> |
|
514 | </tr> | |
515 | <tr> |
|
515 | <tr> | |
516 | <td class="td-radio"><input type="radio" value="repository.none" |
|
516 | <td class="td-radio"><input type="radio" value="repository.none" | |
517 | name="u_perm_2" id="u_perm_2_repositorynone"></td> |
|
517 | name="u_perm_2" id="u_perm_2_repositorynone"></td> | |
518 | <td class="td-radio"><input type="radio" checked="checked" |
|
518 | <td class="td-radio"><input type="radio" checked="checked" | |
519 | value="repository.read" name="u_perm_2" |
|
519 | value="repository.read" name="u_perm_2" | |
520 | id="u_perm_2_repositoryread"></td> |
|
520 | id="u_perm_2_repositoryread"></td> | |
521 | <td class="td-radio"><input type="radio" value="repository.write" |
|
521 | <td class="td-radio"><input type="radio" value="repository.write" | |
522 | name="u_perm_2" id="u_perm_2_repositorywrite"></td> |
|
522 | name="u_perm_2" id="u_perm_2_repositorywrite"></td> | |
523 | <td class="td-radio"><input type="radio" value="repository.admin" |
|
523 | <td class="td-radio"><input type="radio" value="repository.admin" | |
524 | name="u_perm_2" id="u_perm_2_repositoryadmin"></td> |
|
524 | name="u_perm_2" id="u_perm_2_repositoryadmin"></td> | |
525 | <td> |
|
525 | <td> | |
526 | <img class="gravatar" src="https://secure.gravatar.com/avatar/be9d18f611892a738e54f2a3a171e2f9?d=identicon&s=32" height="16" width="16"> |
|
526 | <img class="gravatar" src="https://secure.gravatar.com/avatar/be9d18f611892a738e54f2a3a171e2f9?d=identicon&s=32" height="16" width="16"> | |
527 | <a class="user" href="/_admin/users/2/edit">dev</a> |
|
527 | <a class="user" href="/_admin/users/2/edit">dev</a> | |
528 | </td> |
|
528 | </td> | |
529 | <td> |
|
529 | <td> | |
530 | <span member_type="user" member="2" |
|
530 | <span member_type="user" member="2" | |
531 | class="btn action_button btn-link btn-danger">revoke</span> |
|
531 | class="btn action_button btn-link btn-danger">revoke</span> | |
532 | </td> |
|
532 | </td> | |
533 | </tr> |
|
533 | </tr> | |
534 | </tbody> |
|
534 | </tbody> | |
535 | </table> |
|
535 | </table> | |
536 | <div class="link" id="add_perm"> |
|
536 | <div class="link" id="add_perm"> | |
537 | Add new |
|
537 | Add new | |
538 | </div> |
|
538 | </div> | |
539 |
|
539 | |||
540 |
|
540 | |||
541 |
|
541 | |||
542 | </div> |
|
542 | </div> | |
543 | </div> |
|
543 | </div> | |
544 | </div> |
|
544 | </div> | |
545 | </%def> |
|
545 | </%def> |
General Comments 0
You need to be logged in to leave comments.
Login now