Show More
@@ -1,62 +1,62 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | # This program is free software: you can redistribute it and/or modify |
|
3 | 3 | # it under the terms of the GNU General Public License as published by |
|
4 | 4 | # the Free Software Foundation, either version 3 of the License, or |
|
5 | 5 | # (at your option) any later version. |
|
6 | 6 | # |
|
7 | 7 | # This program is distributed in the hope that it will be useful, |
|
8 | 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
9 | 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
10 | 10 | # GNU General Public License for more details. |
|
11 | 11 | # |
|
12 | 12 | # You should have received a copy of the GNU General Public License |
|
13 | 13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
14 | 14 | """ |
|
15 | 15 | kallithea |
|
16 | 16 | ~~~~~~~~~ |
|
17 | 17 | |
|
18 | 18 | Kallithea, a web based repository management system. |
|
19 | 19 | |
|
20 | 20 | Versioning implementation: http://www.python.org/dev/peps/pep-0386/ |
|
21 | 21 | |
|
22 | 22 | This file was forked by the Kallithea project in July 2014. |
|
23 | 23 | Original author and date, and relevant copyright and licensing information is below: |
|
24 | 24 | :created_on: Apr 9, 2010 |
|
25 | 25 | :author: marcink |
|
26 | 26 | :copyright: (c) 2013 RhodeCode GmbH, (C) 2014 Bradley M. Kuhn, and others. |
|
27 | 27 | :license: GPLv3, see LICENSE.md for more details. |
|
28 | 28 | """ |
|
29 | 29 | |
|
30 | 30 | import platform |
|
31 | 31 | import sys |
|
32 | 32 | |
|
33 | 33 | |
|
34 | 34 | if sys.version_info < (3, 6): |
|
35 | 35 | raise Exception('Kallithea requires python 3.6 or later') |
|
36 | 36 | |
|
37 | 37 | VERSION = (0, 6, 99) |
|
38 | 38 | BACKENDS = { |
|
39 | 39 | 'hg': 'Mercurial repository', |
|
40 | 40 | 'git': 'Git repository', |
|
41 | 41 | } |
|
42 | 42 | |
|
43 | 43 | CELERY_APP = None # set to Celery app instance if using Celery |
|
44 | 44 | |
|
45 | CONFIG = {} | |
|
45 | CONFIG = {} # set to tg.config when TG app is initialized and calls app_cfg | |
|
46 | 46 | |
|
47 | 47 | # URL prefix for non repository related links - must start with `/` |
|
48 | 48 | ADMIN_PREFIX = '/_admin' |
|
49 | 49 | URL_SEP = '/' |
|
50 | 50 | |
|
51 | 51 | # Linked module for extensions |
|
52 | 52 | EXTENSIONS = {} |
|
53 | 53 | |
|
54 | 54 | __version__ = '.'.join(str(each) for each in VERSION) |
|
55 | 55 | __platform__ = platform.system() |
|
56 | 56 | __license__ = 'GPLv3' |
|
57 | 57 | __py_version__ = sys.version_info |
|
58 | 58 | __author__ = "Various Authors" |
|
59 | 59 | __url__ = 'https://kallithea-scm.org/' |
|
60 | 60 | |
|
61 | 61 | is_windows = __platform__ in ['Windows'] |
|
62 | 62 | is_unix = not is_windows |
@@ -1,88 +1,86 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | # This program is free software: you can redistribute it and/or modify |
|
3 | 3 | # it under the terms of the GNU General Public License as published by |
|
4 | 4 | # the Free Software Foundation, either version 3 of the License, or |
|
5 | 5 | # (at your option) any later version. |
|
6 | 6 | # |
|
7 | 7 | # This program is distributed in the hope that it will be useful, |
|
8 | 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
9 | 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
10 | 10 | # GNU General Public License for more details. |
|
11 | 11 | # |
|
12 | 12 | # You should have received a copy of the GNU General Public License |
|
13 | 13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
14 | 14 | |
|
15 | 15 | import configparser |
|
16 | 16 | import functools |
|
17 | 17 | import logging.config |
|
18 | 18 | import os |
|
19 | 19 | import re |
|
20 | 20 | import sys |
|
21 | 21 | |
|
22 | 22 | import click |
|
23 | 23 | import paste.deploy |
|
24 | 24 | |
|
25 | 25 | import kallithea |
|
26 | 26 | import kallithea.config.application |
|
27 | 27 | |
|
28 | 28 | |
|
29 | 29 | # kallithea_cli is usually invoked through the 'kallithea-cli' wrapper script |
|
30 | 30 | # that is installed by setuptools, as specified in setup.py console_scripts |
|
31 | 31 | # entry_points. The script will be using the right virtualenv (if any), and for |
|
32 | 32 | # Unix, it will contain #! pointing at the right python executable. The script |
|
33 | 33 | # also makes sure sys.argv[0] points back at the script path, and that is what |
|
34 | 34 | # can be used to invoke 'kallithea-cli' later. |
|
35 | 35 | kallithea_cli_path = sys.argv[0] |
|
36 | 36 | |
|
37 | 37 | |
|
38 | 38 | def read_config(ini_file_name, strip_section_prefix): |
|
39 | 39 | """Read ini_file_name content, and for all sections like '[X:Y]' where X is |
|
40 | 40 | strip_section_prefix, replace the section name with '[Y]'.""" |
|
41 | 41 | |
|
42 | 42 | def repl(m): |
|
43 | 43 | if m.group(1) == strip_section_prefix: |
|
44 | 44 | return '[%s]' % m.group(2) |
|
45 | 45 | return m.group(0) |
|
46 | 46 | |
|
47 | 47 | with open(ini_file_name) as f: |
|
48 | 48 | return re.sub(r'^\[([^:]+):(.*)]', repl, f.read(), flags=re.MULTILINE) |
|
49 | 49 | |
|
50 | 50 | |
|
51 | 51 | # This placeholder is the main entry point for the kallithea-cli command |
|
52 | 52 | @click.group(context_settings=dict(help_option_names=['-h', '--help'])) |
|
53 | 53 | def cli(): |
|
54 | 54 | """Various commands to manage a Kallithea instance.""" |
|
55 | 55 | |
|
56 | 56 | def register_command(needs_config_file=False, config_file_initialize_app=False, hidden=False): |
|
57 | 57 | """Register a kallithea-cli subcommand. |
|
58 | 58 | |
|
59 | 59 | If one of the needs_config_file flags are true, a config file must be specified |
|
60 | 60 | with -c and it is read and logging is configured. The configuration is |
|
61 | 61 | available in the kallithea.CONFIG dict. |
|
62 | 62 | |
|
63 | 63 | If config_file_initialize_app is true, Kallithea, TurboGears global state |
|
64 | 64 | (including tg.config), and database access will also be fully initialized. |
|
65 | 65 | """ |
|
66 | 66 | cli_command = cli.command(hidden=hidden) |
|
67 | 67 | if needs_config_file or config_file_initialize_app: |
|
68 | 68 | def annotator(annotated): |
|
69 | 69 | @click.option('--config_file', '-c', help="Path to .ini file with app configuration.", |
|
70 | 70 | type=click.Path(dir_okay=False, exists=True, readable=True), required=True) |
|
71 | 71 | @functools.wraps(annotated) # reuse meta data from the wrapped function so click can see other options |
|
72 | 72 | def runtime_wrapper(config_file, *args, **kwargs): |
|
73 | 73 | path_to_ini_file = os.path.realpath(config_file) |
|
74 | 74 | config = paste.deploy.appconfig('config:' + path_to_ini_file) |
|
75 | 75 | cp = configparser.ConfigParser(strict=False) |
|
76 | 76 | cp.read_string(read_config(path_to_ini_file, strip_section_prefix=annotated.__name__)) |
|
77 | 77 | logging.config.fileConfig(cp, |
|
78 | 78 | {'__file__': path_to_ini_file, 'here': os.path.dirname(path_to_ini_file)}) |
|
79 |
if config_file |
|
|
80 | if needs_config_file: # special case for db creation: also call annotated function (with config parameter) *before* app initialization | |
|
79 | if needs_config_file: | |
|
81 | 80 |
|
|
81 | if config_file_initialize_app: | |
|
82 | 82 | kallithea.config.application.make_app(config.global_conf, **config.local_conf) |
|
83 | else: | |
|
84 | kallithea.CONFIG = dict(config) # config is a dict subclass | |
|
85 | 83 | annotated(*args, **kwargs) |
|
86 | 84 | return cli_command(runtime_wrapper) |
|
87 | 85 | return annotator |
|
88 | 86 | return cli_command |
@@ -1,57 +1,56 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | # This program is free software: you can redistribute it and/or modify |
|
3 | 3 | # it under the terms of the GNU General Public License as published by |
|
4 | 4 | # the Free Software Foundation, either version 3 of the License, or |
|
5 | 5 | # (at your option) any later version. |
|
6 | 6 | # |
|
7 | 7 | # This program is distributed in the hope that it will be useful, |
|
8 | 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
9 | 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
10 | 10 | # GNU General Public License for more details. |
|
11 | 11 | # |
|
12 | 12 | # You should have received a copy of the GNU General Public License |
|
13 | 13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
14 | 14 | """ |
|
15 | 15 | This file was forked by the Kallithea project in July 2014 and later moved. |
|
16 | 16 | Original author and date, and relevant copyright and licensing information is below: |
|
17 | 17 | :created_on: Mar 6, 2012 |
|
18 | 18 | :author: marcink |
|
19 | 19 | :copyright: (c) 2013 RhodeCode GmbH, and others. |
|
20 | 20 | :license: GPLv3, see LICENSE.md for more details. |
|
21 | 21 | """ |
|
22 | 22 | import os |
|
23 | 23 | |
|
24 | 24 | import click |
|
25 | 25 | import pkg_resources |
|
26 | 26 | |
|
27 | import kallithea | |
|
28 | 27 | import kallithea.bin.kallithea_cli_base as cli_base |
|
29 | 28 | from kallithea.lib.utils2 import ask_ok |
|
30 | 29 | |
|
31 | 30 | |
|
32 | 31 | @cli_base.register_command(needs_config_file=True) |
|
33 | def extensions_create(): | |
|
32 | def extensions_create(config): | |
|
34 | 33 | """Write template file for extending Kallithea in Python. |
|
35 | 34 | |
|
36 | 35 | Create a template `extensions.py` file next to the ini file. Local |
|
37 | 36 | customizations in that file will survive upgrades. The file contains |
|
38 | 37 | instructions on how it can be customized. |
|
39 | 38 | """ |
|
40 |
here = |
|
|
39 | here = config['here'] | |
|
41 | 40 | content = pkg_resources.resource_string( |
|
42 | 41 | 'kallithea', os.path.join('templates', 'py', 'extensions.py') |
|
43 | 42 | ) |
|
44 | 43 | ext_file = os.path.join(here, 'extensions.py') |
|
45 | 44 | if os.path.exists(ext_file): |
|
46 | 45 | msg = ('Extension file %s already exists, do you want ' |
|
47 | 46 | 'to overwrite it ? [y/n] ') % ext_file |
|
48 | 47 | if not ask_ok(msg): |
|
49 | 48 | click.echo('Nothing done, exiting...') |
|
50 | 49 | return |
|
51 | 50 | |
|
52 | 51 | dirname = os.path.dirname(ext_file) |
|
53 | 52 | if not os.path.isdir(dirname): |
|
54 | 53 | os.makedirs(dirname) |
|
55 | 54 | with open(ext_file, 'wb') as f: |
|
56 | 55 | f.write(content) |
|
57 | 56 | click.echo('Wrote new extensions file to %s' % ext_file) |
@@ -1,86 +1,85 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | # This program is free software: you can redistribute it and/or modify |
|
3 | 3 | # it under the terms of the GNU General Public License as published by |
|
4 | 4 | # the Free Software Foundation, either version 3 of the License, or |
|
5 | 5 | # (at your option) any later version. |
|
6 | 6 | # |
|
7 | 7 | # This program is distributed in the hope that it will be useful, |
|
8 | 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
9 | 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
10 | 10 | # GNU General Public License for more details. |
|
11 | 11 | # |
|
12 | 12 | # You should have received a copy of the GNU General Public License |
|
13 | 13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
14 | 14 | import os |
|
15 | 15 | import sys |
|
16 | 16 | |
|
17 | 17 | import click |
|
18 | 18 | |
|
19 | import kallithea | |
|
20 | 19 | import kallithea.bin.kallithea_cli_base as cli_base |
|
21 | 20 | |
|
22 | 21 | |
|
23 | 22 | dispath_py_template = '''\ |
|
24 | 23 | # Created by Kallithea 'kallithea-cli iis-install' |
|
25 | 24 | import sys |
|
26 | 25 | |
|
27 | 26 | if hasattr(sys, "isapidllhandle"): |
|
28 | 27 | import win32traceutil |
|
29 | 28 | |
|
30 | 29 | import isapi_wsgi |
|
31 | 30 | import os |
|
32 | 31 | |
|
33 | 32 | def __ExtensionFactory__(): |
|
34 | 33 | from paste.deploy import loadapp |
|
35 | 34 | from logging.config import fileConfig |
|
36 | 35 | fileConfig('%(inifile)s', {'__file__': '%(inifile)s', 'here': '%(inifiledir)s'}) |
|
37 | 36 | |
|
38 | 37 | application = loadapp('config:%(inifile)s') |
|
39 | 38 | |
|
40 | 39 | def app(environ, start_response): |
|
41 | 40 | user = environ.get('REMOTE_USER', None) |
|
42 | 41 | if user is not None: |
|
43 | 42 | os.environ['REMOTE_USER'] = user |
|
44 | 43 | return application(environ, start_response) |
|
45 | 44 | |
|
46 | 45 | return isapi_wsgi.ISAPIThreadPoolHandler(app) |
|
47 | 46 | |
|
48 | 47 | if __name__=='__main__': |
|
49 | 48 | from isapi.install import * |
|
50 | 49 | params = ISAPIParameters() |
|
51 | 50 | sm = [ScriptMapParams(Extension="*", Flags=0)] |
|
52 | 51 | vd = VirtualDirParameters(Name="%(virtualdir)s", |
|
53 | 52 | Description = "Kallithea", |
|
54 | 53 | ScriptMaps = sm, |
|
55 | 54 | ScriptMapUpdate = "replace") |
|
56 | 55 | params.VirtualDirs = [vd] |
|
57 | 56 | HandleCommandLine(params) |
|
58 | 57 | ''' |
|
59 | 58 | |
|
60 | 59 | @cli_base.register_command(needs_config_file=True) |
|
61 | 60 | @click.option('--virtualdir', default='/', |
|
62 | 61 | help='The virtual folder to install into on IIS.') |
|
63 | def iis_install(virtualdir): | |
|
62 | def iis_install(virtualdir, config): | |
|
64 | 63 | """Install into IIS using isapi-wsgi.""" |
|
65 | 64 | |
|
66 |
config_file_abs = |
|
|
65 | config_file_abs = config['__file__'] | |
|
67 | 66 | |
|
68 | 67 | try: |
|
69 | 68 | import isapi_wsgi |
|
70 | 69 | assert isapi_wsgi |
|
71 | 70 | except ImportError: |
|
72 | 71 | sys.stderr.write('missing requirement: isapi-wsgi not installed\n') |
|
73 | 72 | sys.exit(1) |
|
74 | 73 | |
|
75 | 74 | dispatchfile = os.path.join(os.getcwd(), 'dispatch.py') |
|
76 | 75 | click.echo('Writing %s' % dispatchfile) |
|
77 | 76 | with open(dispatchfile, 'w') as f: |
|
78 | 77 | f.write(dispath_py_template % { |
|
79 | 78 | 'inifile': config_file_abs.replace('\\', '\\\\'), |
|
80 | 79 | 'inifiledir': os.path.dirname(config_file_abs).replace('\\', '\\\\'), |
|
81 | 80 | 'virtualdir': virtualdir, |
|
82 | 81 | }) |
|
83 | 82 | |
|
84 | 83 | click.echo('Run \'python "%s" install\' with administrative privileges ' |
|
85 | 84 | 'to generate the _dispatch.dll file and install it into the ' |
|
86 | 85 | 'default web site' % dispatchfile) |
General Comments 0
You need to be logged in to leave comments.
Login now