Changeset - faaefd08f790
[Not reviewed]
kallithea/config/routing.py
Show inline comments
 
@@ -4,192 +4,193 @@
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
Routes configuration
 

	
 
The more specific and detailed routes should be defined first so they
 
may take precedent over the more generic routes. For more information
 
refer to the routes manual at http://routes.groovie.org/docs/
 
"""
 

	
 
from tg import request
 
from routes import Mapper
 

	
 
# prefix for non repository related links needs to be prefixed with `/`
 
ADMIN_PREFIX = '/_admin'
 

	
 

	
 
def make_map(config):
 
    """Create, configure and return the routes Mapper"""
 
    rmap = Mapper(directory=config['paths']['controllers'],
 
                  always_scan=config['debug'])
 
    rmap.minimization = False
 
    rmap.explicit = False
 

	
 
    from kallithea.lib.utils import (is_valid_repo, is_valid_repo_group,
 
                                     get_repo_by_id)
 

	
 
    def check_repo(environ, match_dict):
 
        """
 
        check for valid repository for proper 404 handling
 

	
 
        :param environ:
 
        :param match_dict:
 
        """
 
        repo_name = match_dict.get('repo_name')
 

	
 
        if match_dict.get('f_path'):
 
            # fix for multiple initial slashes that causes errors
 
            match_dict['f_path'] = match_dict['f_path'].lstrip('/')
 

	
 
        by_id_match = get_repo_by_id(repo_name)
 
        if by_id_match:
 
            repo_name = by_id_match
 
            match_dict['repo_name'] = repo_name
 

	
 
        return is_valid_repo(repo_name, config['base_path'])
 

	
 
    def check_group(environ, match_dict):
 
        """
 
        check for valid repository group for proper 404 handling
 

	
 
        :param environ:
 
        :param match_dict:
 
        """
 
        repo_group_name = match_dict.get('group_name')
 
        return is_valid_repo_group(repo_group_name, config['base_path'])
 

	
 
    def check_group_skip_path(environ, match_dict):
 
        """
 
        check for valid repository group for proper 404 handling, but skips
 
        verification of existing path
 

	
 
        :param environ:
 
        :param match_dict:
 
        """
 
        repo_group_name = match_dict.get('group_name')
 
        return is_valid_repo_group(repo_group_name, config['base_path'],
 
                                   skip_path_check=True)
 

	
 
    def check_user_group(environ, match_dict):
 
        """
 
        check for valid user group for proper 404 handling
 

	
 
        :param environ:
 
        :param match_dict:
 
        """
 
        return True
 

	
 
    def check_int(environ, match_dict):
 
        return match_dict.get('id').isdigit()
 

	
 
    #==========================================================================
 
    # CUSTOM ROUTES HERE
 
    #==========================================================================
 

	
 
    # MAIN PAGE
 
    rmap.connect('home', '/', controller='home', action='index')
 
    rmap.connect('about', '/about', controller='home', action='about')
 
    rmap.redirect('/favicon.ico', '/images/favicon.ico')
 
    rmap.connect('repo_switcher_data', '/_repos', controller='home',
 
                 action='repo_switcher_data')
 
    rmap.connect('users_and_groups_data', '/_users_and_groups', controller='home',
 
                 action='users_and_groups_data')
 

	
 
    rmap.connect('rst_help',
 
                 "http://docutils.sourceforge.net/docs/user/rst/quickref.html",
 
                 _static=True)
 
    rmap.connect('kallithea_project_url', "https://kallithea-scm.org/", _static=True)
 
    rmap.connect('issues_url', 'https://bitbucket.org/conservancy/kallithea/issues', _static=True)
 

	
 
    # ADMIN REPOSITORY ROUTES
 
    with rmap.submapper(path_prefix=ADMIN_PREFIX,
 
                        controller='admin/repos') as m:
 
        m.connect("repos", "/repos",
 
                  action="create", conditions=dict(method=["POST"]))
 
        m.connect("repos", "/repos",
 
                  action="index", conditions=dict(method=["GET"]))
 
        m.connect("new_repo", "/create_repository",
 
                  action="create_repository", conditions=dict(method=["GET"]))
 
        m.connect("update_repo", "/repos/{repo_name:.*?}",
 
                  action="update", conditions=dict(method=["POST"],
 
                  function=check_repo))
 
        m.connect("delete_repo", "/repos/{repo_name:.*?}/delete",
 
                  action="delete", conditions=dict(method=["POST"]))
 

	
 
    # ADMIN REPOSITORY GROUPS ROUTES
 
    with rmap.submapper(path_prefix=ADMIN_PREFIX,
 
                        controller='admin/repo_groups') as m:
 
        m.connect("repos_groups", "/repo_groups",
 
                  action="create", conditions=dict(method=["POST"]))
 
        m.connect("repos_groups", "/repo_groups",
 
                  action="index", conditions=dict(method=["GET"]))
 
        m.connect("new_repos_group", "/repo_groups/new",
 
                  action="new", conditions=dict(method=["GET"]))
 
        m.connect("update_repos_group", "/repo_groups/{group_name:.*?}",
 
                  action="update", conditions=dict(method=["POST"],
 
                                                   function=check_group))
 

	
 
        m.connect("repos_group", "/repo_groups/{group_name:.*?}",
 
                  action="show", conditions=dict(method=["GET"],
 
                                                 function=check_group))
 

	
 
        # EXTRAS REPO GROUP ROUTES
 
        m.connect("edit_repo_group", "/repo_groups/{group_name:.*?}/edit",
 
                  action="edit",
 
                  conditions=dict(method=["GET"], function=check_group))
 

	
 
        m.connect("edit_repo_group_advanced", "/repo_groups/{group_name:.*?}/edit/advanced",
 
                  action="edit_repo_group_advanced",
 
                  conditions=dict(method=["GET"], function=check_group))
 

	
 
        m.connect("edit_repo_group_perms", "/repo_groups/{group_name:.*?}/edit/permissions",
 
                  action="edit_repo_group_perms",
 
                  conditions=dict(method=["GET"], function=check_group))
 
        m.connect("edit_repo_group_perms_update", "/repo_groups/{group_name:.*?}/edit/permissions",
 
                  action="update_perms",
 
                  conditions=dict(method=["POST"], function=check_group))
 
        m.connect("edit_repo_group_perms_delete", "/repo_groups/{group_name:.*?}/edit/permissions/delete",
 
                  action="delete_perms",
 
                  conditions=dict(method=["POST"], function=check_group))
 

	
 
        m.connect("delete_repo_group", "/repo_groups/{group_name:.*?}/delete",
 
                  action="delete", conditions=dict(method=["POST"],
 
                                                   function=check_group_skip_path))
 

	
 
    # ADMIN USER ROUTES
 
    with rmap.submapper(path_prefix=ADMIN_PREFIX,
 
                        controller='admin/users') as m:
 
        m.connect("new_user", "/users/new",
 
                  action="create", conditions=dict(method=["POST"]))
 
        m.connect("users", "/users",
 
                  action="index", conditions=dict(method=["GET"]))
 
        m.connect("formatted_users", "/users.{format}",
 
                  action="index", conditions=dict(method=["GET"]))
 
        m.connect("new_user", "/users/new",
 
                  action="new", conditions=dict(method=["GET"]))
 
        m.connect("update_user", "/users/{id}",
 
                  action="update", conditions=dict(method=["POST"]))
 
        m.connect("delete_user", "/users/{id}/delete",
 
                  action="delete", conditions=dict(method=["POST"]))
 
        m.connect("edit_user", "/users/{id}/edit",
 
                  action="edit", conditions=dict(method=["GET"]))
 

	
 
        # EXTRAS USER ROUTES
 
        m.connect("edit_user_advanced", "/users/{id}/edit/advanced",
 
                  action="edit_advanced", conditions=dict(method=["GET"]))
 

	
 
        m.connect("edit_user_api_keys", "/users/{id}/edit/api_keys",
 
                  action="edit_api_keys", conditions=dict(method=["GET"]))
 
        m.connect("edit_user_api_keys_update", "/users/{id}/edit/api_keys",
 
                  action="add_api_key", conditions=dict(method=["POST"]))
 
        m.connect("edit_user_api_keys_delete", "/users/{id}/edit/api_keys/delete",
 
                  action="delete_api_key", conditions=dict(method=["POST"]))
 

	
 
        m.connect("edit_user_perms", "/users/{id}/edit/permissions",
kallithea/public/images/android-chrome-192x192.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
kallithea/public/images/android-chrome-512x512.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
kallithea/public/images/apple-touch-icon.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
kallithea/public/images/browserconfig.xml
Show inline comments
 
new file 100644
 
<?xml version="1.0" encoding="utf-8"?>
 
<browserconfig>
 
    <msapplication>
 
        <tile>
 
            <square150x150logo src="/images/mstile-150x150.png"/>
 
            <TileColor>#da532c</TileColor>
 
        </tile>
 
    </msapplication>
 
</browserconfig>
kallithea/public/images/favicon-16x16.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
kallithea/public/images/favicon-32x32.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
kallithea/public/images/favicon.ico
Show inline comments
 
binary diff not shown
kallithea/public/images/favicon.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
kallithea/public/images/manifest.json
Show inline comments
 
new file 100644
 
{
 
    "name": "Kallithea",
 
    "icons": [
 
        {
 
            "src": "/images/android-chrome-192x192.png",
 
            "sizes": "192x192",
 
            "type": "image/png"
 
        },
 
        {
 
            "src": "/images/android-chrome-512x512.png",
 
            "sizes": "512x512",
 
            "type": "image/png"
 
        }
 
    ],
 
    "theme_color": "#ffffff",
 
    "background_color": "#ffffff",
 
    "display": "standalone"
 
}
 
\ No newline at end of file
kallithea/public/images/mstile-144x144.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
kallithea/public/images/mstile-150x150.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
kallithea/public/images/mstile-310x150.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
kallithea/public/images/mstile-310x310.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
kallithea/public/images/mstile-70x70.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
kallithea/public/images/safari-pinned-tab.svg
Show inline comments
 
new file 100644
 
<?xml version="1.0" standalone="no"?>
 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
 
 "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
 
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 
 width="16.000000pt" height="16.000000pt" viewBox="0 0 16.000000 16.000000"
 
 preserveAspectRatio="xMidYMid meet">
 
<metadata>
 
Created by potrace 1.11, written by Peter Selinger 2001-2013
 
</metadata>
 
<g transform="translate(0.000000,16.000000) scale(0.002286,-0.002286)"
 
fill="#000000" stroke="none">
 
<path d="M1800 6948 c-369 -33 -683 -232 -888 -560 -23 -38 -40 -68 -37 -68 3
 
0 -1 -10 -9 -22 -26 -40 -67 -160 -88 -258 -23 -105 -32 -316 -17 -397 35
 
-188 77 -306 156 -437 107 -178 284 -341 473 -436 81 -41 210 -86 273 -95 26
 
-4 50 -11 52 -16 3 -4 7 -174 10 -376 2 -202 7 -595 10 -873 12 -1069 15
 
-1227 19 -1263 7 -48 34 -109 83 -179 50 -73 74 -98 353 -368 128 -124 270
 
-261 315 -305 45 -44 179 -174 298 -288 151 -147 223 -224 243 -260 15 -29 32
 
-55 38 -59 8 -5 11 -110 12 -325 l1 -318 232 0 c127 0 231 2 232 5 1 9 8 959
 
13 1960 3 538 10 980 15 1012 5 31 17 71 27 90 9 18 87 103 173 189 86 86 292
 
295 457 465 166 170 359 368 429 439 160 165 209 229 226 297 17 74 17 160 -6
 
1353 -2 116 -7 381 -11 590 -3 209 -7 409 -8 445 l-1 65 -235 1 -235 1 1 -46
 
c1 -25 5 -302 8 -616 11 -945 16 -1273 20 -1424 5 -156 -1 -187 -55 -266 -28
 
-41 -49 -63 -539 -565 -484 -495 -509 -521 -587 -614 -98 -117 -140 -182 -148
 
-231 -3 -22 -6 -469 -6 -994 l0 -954 -32 29 c-17 16 -34 31 -37 34 -6 6 -121
 
114 -319 300 -79 74 -156 146 -171 160 -14 14 -86 81 -160 150 -207 194 -216
 
203 -239 247 -11 23 -23 57 -26 75 -3 18 -7 231 -10 473 -7 674 -16 1434 -20
 
1695 -3 240 0 260 35 260 34 0 193 51 269 86 231 107 445 318 555 548 30 63
 
73 184 81 226 3 14 7 36 10 50 30 139 24 364 -14 505 -97 370 -363 664 -721
 
798 -57 21 -156 49 -185 52 -5 0 -35 4 -65 8 -91 12 -160 13 -250 5z m254
 
-580 c106 -29 183 -74 262 -153 76 -75 114 -136 145 -229 25 -72 29 -101 30
 
-187 0 -164 -58 -300 -183 -421 -116 -114 -258 -168 -424 -163 -317 11 -567
 
267 -567 580 0 100 16 170 59 260 81 171 236 289 429 328 56 11 183 4 249 -15z"/>
 
<path d="M5350 3192 c-271 -39 -523 -241 -612 -492 -14 -40 -20 -59 -35 -120
 
-2 -8 -5 -61 -7 -116 -5 -141 25 -276 89 -390 34 -62 126 -175 168 -207 18
 
-14 43 -35 57 -47 33 -29 173 -96 232 -110 l46 -12 0 -391 c-1 -365 -2 -396
 
-20 -444 -22 -56 -18 -52 -418 -464 -135 -138 -261 -268 -280 -288 -69 -72
 
-85 -66 187 -65 l246 0 95 100 c52 54 185 192 296 306 135 139 210 225 229
 
260 50 97 55 147 56 573 0 215 0 399 0 410 1 15 14 25 49 37 106 38 241 141
 
330 251 40 49 94 155 119 235 32 101 40 274 17 377 -66 293 -296 525 -580 586
 
-57 12 -213 19 -264 11z m225 -471 c57 -25 128 -97 157 -158 34 -72 32 -189
 
-5 -259 -58 -113 -183 -183 -303 -171 -236 24 -360 291 -223 481 84 119 245
 
164 374 107z"/>
 
</g>
 
</svg>
kallithea/templates/base/root.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<!DOCTYPE html>
 
<html xmlns="http://www.w3.org/1999/xhtml">
 
    <head>
 
        <title><%block name="title"/><%block name="branding_title"/></title>
 
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 
        <meta name="robots" content="index, nofollow"/>
 
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 
        <link rel="icon" href="${h.url('/images/favicon.ico')}" type="image/x-icon" />
 
        <link rel="shortcut icon" href="${h.url('/images/favicon.ico')}" type="image/x-icon" />
 
        <link rel="icon" type="image/png" href="${h.url('/images/favicon-32x32.png')}" sizes="32x32">
 
        <link rel="icon" type="image/png" href="${h.url('/images/favicon-16x16.png')}" sizes="16x16">
 
        <link rel="apple-touch-icon" sizes="180x180" href="${h.url('/images/apple-touch-icon.png')}">
 
        <link rel="manifest" href="${h.url('/images/manifest.json')}">
 
        <link rel="mask-icon" href="${h.url('/images/safari-pinned-tab.svg')}" color="#b1d579">
 
        <meta name="msapplication-config" content="${h.url('/images/browserconfig.xml')}">
 
        <meta name="theme-color" content="#ffffff">
 

	
 
        ## CSS ###
 
        <link rel="stylesheet" type="text/css" href="${h.url('/css/pygments.css', ver=c.kallithea_version)}"/>
 
        <link rel="stylesheet" type="text/css" href="${h.url('/css/style.css', ver=c.kallithea_version)}" media="screen"/>
 
        <link rel="stylesheet" type="text/css" href="${h.url('/fontello/css/kallithea.css', ver=c.kallithea_version)}">
 
        <%block name="css_extra"/>
 

	
 
        ## JAVASCRIPT ##
 
        <script type="text/javascript">
 
            ## JS translations map
 
            var TRANSLATION_MAP = {
 
                'Cancel': ${h.jshtml(_("Cancel"))},
 
                'Retry': ${h.jshtml(_("Retry"))},
 
                'Submitting ...': ${h.jshtml(_("Submitting ..."))},
 
                'Unable to post': ${h.jshtml(_("Unable to post"))},
 
                'Add Another Comment': ${h.jshtml(_("Add Another Comment"))},
 
                'Stop following this repository': ${h.jshtml(_('Stop following this repository'))},
 
                'Start following this repository': ${h.jshtml(_('Start following this repository'))},
 
                'Group': ${h.jshtml(_('Group'))},
 
                'Loading ...': ${h.jshtml(_('Loading ...'))},
 
                'loading ...': ${h.jshtml(_('loading ...'))},
 
                'Search truncated': ${h.jshtml(_('Search truncated'))},
 
                'No matching files': ${h.jshtml(_('No matching files'))},
 
                'Open New Pull Request from {0}': ${h.jshtml(_('Open New Pull Request from {0}'))},
 
                'Open New Pull Request for {0} &rarr; {1}': ${h.js(_('Open New Pull Request for {0} &rarr; {1}'))},
 
                'Show Selected Changesets {0} &rarr; {1}': ${h.js(_('Show Selected Changesets {0} &rarr; {1}'))},
 
                'Selection Link': ${h.jshtml(_('Selection Link'))},
 
                'Collapse Diff': ${h.jshtml(_('Collapse Diff'))},
 
                'Expand Diff': ${h.jshtml(_('Expand Diff'))},
 
                'No revisions': ${h.jshtml(_('No revisions'))},
 
                'Type name of user or member to grant permission': ${h.jshtml(_('Type name of user or member to grant permission'))},
 
                'Failed to revoke permission': ${h.jshtml(_('Failed to revoke permission'))},
 
                'Confirm to revoke permission for {0}: {1} ?': ${h.jshtml(_('Confirm to revoke permission for {0}: {1} ?'))},
 
                'Enabled': ${h.jshtml(_('Enabled'))},
 
                'Disabled': ${h.jshtml(_('Disabled'))},
 
                'Select changeset': ${h.jshtml(_('Select changeset'))},
 
                'Specify changeset': ${h.jshtml(_('Specify changeset'))},
 
                'MSG_SORTASC': ${h.jshtml(_('Click to sort ascending'))},
 
                'MSG_SORTDESC': ${h.jshtml(_('Click to sort descending'))},
 
                'MSG_EMPTY': ${h.jshtml(_('No records found.'))},
 
                'MSG_ERROR': ${h.jshtml(_('Data error.'))},
 
                'MSG_LOADING': ${h.jshtml(_('Loading...'))}
 
            };
 
            var _TM = TRANSLATION_MAP;
 

	
 
            var TOGGLE_FOLLOW_URL  = ${h.js(h.url('toggle_following'))};
 

	
 
            var REPO_NAME = "";
 
            %if hasattr(c, 'repo_name'):
 
                var REPO_NAME = ${h.js(c.repo_name)};
 
            %endif
 

	
 
            var _authentication_token = ${h.js(h.authentication_token())};
 
        </script>
 
        <script type="text/javascript" src="${h.url('/js/yui.2.9.js', ver=c.kallithea_version)}"></script>
 
        <script type="text/javascript" src="${h.url('/js/jquery.min.js', ver=c.kallithea_version)}"></script>
 
        <script type="text/javascript" src="${h.url('/js/jquery.dataTables.min.js', ver=c.kallithea_version)}"></script>
 
        <script type="text/javascript" src="${h.url('/js/bootstrap.js', ver=c.kallithea_version)}"></script>
 
        <script type="text/javascript" src="${h.url('/js/select2/select2.js', ver=c.kallithea_version)}"></script>
 
        <script type="text/javascript" src="${h.url('/js/native.history.js', ver=c.kallithea_version)}"></script>
 
        <script type="text/javascript" src="${h.url('/js/base.js', ver=c.kallithea_version)}"></script>
 
        ## EXTRA FOR JS
 
        <%block name="js_extra"/>
 
        <script type="text/javascript">
 
            (function(window,undefined){
 
                var History = window.History; // Note: We are using a capital H instead of a lower h
 
                if ( !History.enabled ) {
 
                     // History.js is disabled for this browser.
 
                     // This is because we can optionally choose to support HTML4 browsers or not.
 
                    return false;
 
                }
 
            })(window);
 

	
 
            $(document).ready(function(){
 
              tooltip_activate();
 
              show_more_event();
 
              // routes registration
 
              pyroutes.register('home', ${h.js(h.url('home'))}, []);
 
              pyroutes.register('new_gist', ${h.js(h.url('new_gist'))}, []);
 
              pyroutes.register('gists', ${h.js(h.url('gists'))}, []);
 
              pyroutes.register('new_repo', ${h.js(h.url('new_repo'))}, []);
 

	
 
              pyroutes.register('summary_home', ${h.js(h.url('summary_home', repo_name='%(repo_name)s'))}, ['repo_name']);
 
              pyroutes.register('changelog_home', ${h.js(h.url('changelog_home', repo_name='%(repo_name)s'))}, ['repo_name']);
 
              pyroutes.register('files_home', ${h.js(h.url('files_home', repo_name='%(repo_name)s',revision='%(revision)s',f_path='%(f_path)s'))}, ['repo_name', 'revision', 'f_path']);
 
              pyroutes.register('edit_repo', ${h.js(h.url('edit_repo', repo_name='%(repo_name)s'))}, ['repo_name']);
 
              pyroutes.register('edit_repo_perms', ${h.js(h.url('edit_repo_perms', repo_name='%(repo_name)s'))}, ['repo_name']);
 
              pyroutes.register('pullrequest_home', ${h.js(h.url('pullrequest_home', repo_name='%(repo_name)s'))}, ['repo_name']);
 

	
 
              pyroutes.register('toggle_following', ${h.js(h.url('toggle_following'))});
 
              pyroutes.register('changeset_info', ${h.js(h.url('changeset_info', repo_name='%(repo_name)s', revision='%(revision)s'))}, ['repo_name', 'revision']);
 
              pyroutes.register('changeset_home', ${h.js(h.url('changeset_home', repo_name='%(repo_name)s', revision='%(revision)s'))}, ['repo_name', 'revision']);
 
              pyroutes.register('repo_size', ${h.js(h.url('repo_size', repo_name='%(repo_name)s'))}, ['repo_name']);
 
              pyroutes.register('repo_refs_data', ${h.js(h.url('repo_refs_data', repo_name='%(repo_name)s'))}, ['repo_name']);
 
              pyroutes.register('users_and_groups_data', ${h.js(h.url('users_and_groups_data'))}, []);
 
             });
0 comments (0 inline, 0 general)