##// END OF EJS Templates
Added app basic auth....
Marcin Kuzminski -
r41:71ffa932 default
parent child Browse files
Show More
@@ -0,0 +1,105 b''
1 import sqlite3
2 import os
3 import logging
4 from os.path import dirname as dn
5 from datetime import datetime
6 import crypt
7
8 log = logging.getLogger(__name__)
9 ROOT = dn(dn(dn(os.path.realpath(__file__))))
10
11 def get_sqlite_cur_conn():
12 conn = sqlite3.connect(os.path.join(ROOT, 'auth.sqlite'))
13 cur = conn.cursor()
14 return conn, cur
15
16 def authfunc(environ, username, password):
17 conn, cur = get_sqlite_cur_conn()
18 password_crypt = crypt.crypt(password, '6a')
19
20 cur.execute("SELECT * FROM users WHERE username=?", (username,))
21 data = cur.fetchone()
22
23 if data:
24 if data[3]:
25 if data[1] == username and data[2] == password_crypt:
26 log.info('user %s authenticated correctly', username)
27
28 http_accept = environ.get('HTTP_ACCEPT')
29
30 if http_accept.startswith('application/mercurial') or \
31 environ['PATH_INFO'].find('raw-file') != -1:
32 cmd = environ['PATH_INFO']
33 for qry in environ['QUERY_STRING'].split('&'):
34 if qry.startswith('cmd'):
35 cmd += "|" + qry
36
37 try:
38 cur.execute('''INSERT INTO
39 user_logs
40 VALUES(?,?,?,?)''',
41 (None, data[0], cmd, datetime.now()))
42 conn.commit()
43 except Exception as e:
44 conn.rollback()
45 log.error(e)
46
47
48 return True
49 else:
50 log.error('user %s is disabled', username)
51
52 return False
53
54 def create_user_table():
55 '''
56 Create a auth database
57 '''
58 conn, cur = get_sqlite_cur_conn()
59 try:
60 log.info('creating table %s', 'users')
61 cur.execute('''DROP TABLE IF EXISTS users ''')
62 cur.execute('''CREATE TABLE users
63 (id INTEGER PRIMARY KEY AUTOINCREMENT,
64 username TEXT,
65 password TEXT,
66 active INTEGER)''')
67 log.info('creating table %s', 'user_logs')
68 cur.execute('''DROP TABLE IF EXISTS user_logs ''')
69 cur.execute('''CREATE TABLE user_logs
70 (id INTEGER PRIMARY KEY AUTOINCREMENT,
71 user_id INTEGER,
72 last_action TEXT,
73 last_action_date DATETIME)''')
74 conn.commit()
75 except:
76 conn.rollback()
77 raise
78
79 cur.close()
80
81 def create_user(username, password):
82 conn, cur = get_sqlite_cur_conn()
83 password_crypt = crypt.crypt(password, '6a')
84 cur_date = datetime.now()
85 log.info('creating user %s', username)
86 try:
87 cur.execute('''INSERT INTO users values (?,?,?,?) ''',
88 (None, username, password_crypt, 1,))
89 conn.commit()
90 except:
91 conn.rollback()
92 raise
93
94 if __name__ == "__main__":
95 create_user_table()
96 create_user('marcink', 'qweqwe')
97 create_user('lukaszd', 'qweqwe')
98 create_user('adriand', 'qweqwe')
99 create_user('radek', 'qweqwe')
100 create_user('skrzeka', 'qweqwe')
101 create_user('bart', 'qweqwe')
102 create_user('maho', 'qweqwe')
103 create_user('michalg', 'qweqwe')
104
105 #authfunc('', 'marcink', 'qweqwe')
@@ -1,94 +1,95 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # pylons_app - Pylons environment configuration #
3 # pylons_app - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 ############################################
10 ############################################
11 ## Uncomment and replace with the address ##
11 ## Uncomment and replace with the address ##
12 ## which should receive any error reports ##
12 ## which should receive any error reports ##
13 ############################################
13 ############################################
14 #email_to = marcin.kuzminski@etelko.pl
14 #email_to = marcin.kuzminski@etelko.pl
15 #smtp_server = mail.etelko.pl
15 #smtp_server = mail.etelko.pl
16 #error_email_from = paste_error@localhost
16 #error_email_from = paste_error@localhost
17 #smtp_username =
17 #smtp_username =
18 #smtp_password =
18 #smtp_password =
19 #error_message = 'mercurial crash !'
19 #error_message = 'mercurial crash !'
20
20
21 [server:main]
21 [server:main]
22 use = egg:Paste#http
22 use = egg:Paste#http
23 host = 127.0.0.1
23 host = 127.0.0.1
24 port = 5000
24 port = 5000
25
25
26 [app:main]
26 [app:main]
27 use = egg:pylons_app
27 use = egg:pylons_app
28 full_stack = true
28 full_stack = true
29 static_files = true
29 static_files = true
30 lang=en
30 lang=en
31 cache_dir = %(here)s/data
31 cache_dir = %(here)s/data
32 repos_name = etelko
32
33
33 ################################################################################
34 ################################################################################
34 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
35 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
35 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
36 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
36 ## execute malicious code after an exception is raised. ##
37 ## execute malicious code after an exception is raised. ##
37 ################################################################################
38 ################################################################################
38 #set debug = false
39 #set debug = false
39
40
40
41
41 ################################
42 ################################
42 ### LOGGING CONFIGURATION ####
43 ### LOGGING CONFIGURATION ####
43 ################################
44 ################################
44 [loggers]
45 [loggers]
45 keys = root, routes, pylons_app, sqlalchemy
46 keys = root, routes, pylons_app, sqlalchemy
46
47
47 [handlers]
48 [handlers]
48 keys = console
49 keys = console
49
50
50 [formatters]
51 [formatters]
51 keys = generic
52 keys = generic
52
53
53 #############
54 #############
54 ## LOGGERS ##
55 ## LOGGERS ##
55 #############
56 #############
56 [logger_root]
57 [logger_root]
57 level = NOTSET
58 level = NOTSET
58 handlers = console
59 handlers = console
59
60
60 [logger_routes]
61 [logger_routes]
61 level = INFO
62 level = INFO
62 handlers = console
63 handlers = console
63 qualname = routes.middleware
64 qualname = routes.middleware
64 # "level = DEBUG" logs the route matched and routing variables.
65 # "level = DEBUG" logs the route matched and routing variables.
65
66
66 [logger_pylons_app]
67 [logger_pylons_app]
67 level = DEBUG
68 level = DEBUG
68 handlers = console
69 handlers = console
69 qualname = pylons_app
70 qualname = pylons_app
70
71
71
72
72 [logger_sqlalchemy]
73 [logger_sqlalchemy]
73 level = DEBUG
74 level = DEBUG
74 handlers = console
75 handlers = console
75 qualname = sqlalchemy.engine
76 qualname = sqlalchemy.engine
76
77
77 ##############
78 ##############
78 ## HANDLERS ##
79 ## HANDLERS ##
79 ##############
80 ##############
80
81
81 [handler_console]
82 [handler_console]
82 class = StreamHandler
83 class = StreamHandler
83 args = (sys.stderr,)
84 args = (sys.stderr,)
84 level = NOTSET
85 level = NOTSET
85 formatter = generic
86 formatter = generic
86
87
87 ################
88 ################
88 ## FORMATTERS ##
89 ## FORMATTERS ##
89 ################
90 ################
90
91
91 [formatter_generic]
92 [formatter_generic]
92 format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
93 format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
93 datefmt = %H:%M:%S
94 datefmt = %H:%M:%S
94
95
@@ -1,93 +1,94 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # pylons_app - Pylons environment configuration #
3 # pylons_app - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 ############################################
10 ############################################
11 ## Uncomment and replace with the address ##
11 ## Uncomment and replace with the address ##
12 ## which should receive any error reports ##
12 ## which should receive any error reports ##
13 ############################################
13 ############################################
14 #email_to = marcin.kuzminski@etelko.pl
14 #email_to = marcin.kuzminski@etelko.pl
15 #smtp_server = mail.etelko.pl
15 #smtp_server = mail.etelko.pl
16 #error_email_from = paste_error@localhost
16 #error_email_from = paste_error@localhost
17 #smtp_username =
17 #smtp_username =
18 #smtp_password =
18 #smtp_password =
19 #error_message = 'mercurial crash !'
19 #error_message = 'mercurial crash !'
20
20
21 [server:main]
21 [server:main]
22 use = egg:Paste#http
22 use = egg:Paste#http
23 host = 127.0.0.1
23 host = 127.0.0.1
24 port = 8001
24 port = 8001
25
25
26 [app:main]
26 [app:main]
27 use = egg:pylons_app
27 use = egg:pylons_app
28 full_stack = true
28 full_stack = true
29 static_files = false
29 static_files = false
30 lang=en
30 lang=en
31 cache_dir = %(here)s/data
31 cache_dir = %(here)s/data
32 repos_name = etelko
32
33
33 ################################################################################
34 ################################################################################
34 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
35 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
35 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
36 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
36 ## execute malicious code after an exception is raised. ##
37 ## execute malicious code after an exception is raised. ##
37 ################################################################################
38 ################################################################################
38 #set debug = false
39 #set debug = false
39
40
40 ################################
41 ################################
41 ### LOGGING CONFIGURATION ####
42 ### LOGGING CONFIGURATION ####
42 ################################
43 ################################
43 [loggers]
44 [loggers]
44 keys = root, routes, pylons_app, sqlalchemy
45 keys = root, routes, pylons_app, sqlalchemy
45
46
46 [handlers]
47 [handlers]
47 keys = console
48 keys = console
48
49
49 [formatters]
50 [formatters]
50 keys = generic
51 keys = generic
51
52
52 #############
53 #############
53 ## LOGGERS ##
54 ## LOGGERS ##
54 #############
55 #############
55 [logger_root]
56 [logger_root]
56 level = INFO
57 level = INFO
57 handlers = console
58 handlers = console
58
59
59 [logger_routes]
60 [logger_routes]
60 level = INFO
61 level = INFO
61 handlers = console
62 handlers = console
62 qualname = routes.middleware
63 qualname = routes.middleware
63 # "level = DEBUG" logs the route matched and routing variables.
64 # "level = DEBUG" logs the route matched and routing variables.
64
65
65 [logger_pylons_app]
66 [logger_pylons_app]
66 level = DEBUG
67 level = DEBUG
67 handlers = console
68 handlers = console
68 qualname = pylons_app
69 qualname = pylons_app
69
70
70
71
71 [logger_sqlalchemy]
72 [logger_sqlalchemy]
72 level = DEBUG
73 level = DEBUG
73 handlers = console
74 handlers = console
74 qualname = sqlalchemy.engine
75 qualname = sqlalchemy.engine
75
76
76 ##############
77 ##############
77 ## HANDLERS ##
78 ## HANDLERS ##
78 ##############
79 ##############
79
80
80 [handler_console]
81 [handler_console]
81 class = StreamHandler
82 class = StreamHandler
82 args = (sys.stderr,)
83 args = (sys.stderr,)
83 level = NOTSET
84 level = NOTSET
84 formatter = generic
85 formatter = generic
85
86
86 ################
87 ################
87 ## FORMATTERS ##
88 ## FORMATTERS ##
88 ################
89 ################
89
90
90 [formatter_generic]
91 [formatter_generic]
91 format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
92 format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
92 datefmt = %H:%M:%S
93 datefmt = %H:%M:%S
93
94
@@ -1,44 +1,43 b''
1 """Pylons environment configuration"""
1 """Pylons environment configuration"""
2 import logging
2 import logging
3 import os
3 import os
4
4
5 from mako.lookup import TemplateLookup
5 from mako.lookup import TemplateLookup
6 from pylons.error import handle_mako_error
6 from pylons.error import handle_mako_error
7 from pylons import config
7 from pylons import config
8
8
9 import pylons_app.lib.app_globals as app_globals
9 import pylons_app.lib.app_globals as app_globals
10 import pylons_app.lib.helpers
10 import pylons_app.lib.helpers
11 from pylons_app.config.routing import make_map
11 from pylons_app.config.routing import make_map
12
12
13 log = logging.getLogger(__name__)
13 log = logging.getLogger(__name__)
14
14
15 def load_environment(global_conf, app_conf):
15 def load_environment(global_conf, app_conf):
16 """Configure the Pylons environment via the ``pylons.config``
16 """Configure the Pylons environment via the ``pylons.config``
17 object
17 object
18 """
18 """
19 # Pylons paths
19 # Pylons paths
20 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
20 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
21 paths = dict(root=root,
21 paths = dict(root=root,
22 controllers=os.path.join(root, 'controllers'),
22 controllers=os.path.join(root, 'controllers'),
23 static_files=os.path.join(root, 'public'),
23 static_files=os.path.join(root, 'public'),
24 templates=[os.path.join(root, 'templates')])
24 templates=[os.path.join(root, 'templates')])
25
25
26 # Initialize config with the basic options
26 # Initialize config with the basic options
27 config.init_app(global_conf, app_conf, package='pylons_app',
27 config.init_app(global_conf, app_conf, package='pylons_app',
28 template_engine='mako', paths=paths)
28 template_engine='mako', paths=paths)
29
29
30 config['routes.map'] = make_map()
30 config['routes.map'] = make_map()
31 config['pylons.g'] = app_globals.Globals()
31 config['pylons.app_globals'] = app_globals.Globals()
32 config['pylons.h'] = pylons_app.lib.helpers
32 config['pylons.h'] = pylons_app.lib.helpers
33
33
34 # Create the Mako TemplateLookup, with the default auto-escaping
34 # Create the Mako TemplateLookup, with the default auto-escaping
35 config['pylons.g'].mako_lookup = TemplateLookup(
35 config['pylons.app_globals'].mako_lookup = TemplateLookup(
36 directories=paths['templates'],
36 directories=paths['templates'],
37 error_handler=handle_mako_error,
37 error_handler=handle_mako_error,
38 module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
38 module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
39 output_encoding='utf-8',
39 input_encoding='utf-8', default_filters=['escape'],
40 imports=['from webhelpers.html import escape'],
40 imports=['from webhelpers.html import escape'])
41 default_filters=['escape'])
42
41
43 # CONFIGURATION OPTIONS HERE (note: all config options will override
42 # CONFIGURATION OPTIONS HERE (note: all config options will override
44 # any Pylons config options)
43 # any Pylons config options)
@@ -1,67 +1,68 b''
1 """Pylons middleware initialization"""
1 """Pylons middleware initialization"""
2 from beaker.middleware import CacheMiddleware, SessionMiddleware
2 from beaker.middleware import CacheMiddleware, SessionMiddleware
3 from paste.cascade import Cascade
3 from paste.cascade import Cascade
4 from paste.registry import RegistryManager
4 from paste.registry import RegistryManager
5 from paste.urlparser import StaticURLParser
5 from paste.urlparser import StaticURLParser
6 from paste.deploy.converters import asbool
6 from paste.deploy.converters import asbool
7 from pylons import config
7 from pylons import config
8 from pylons.middleware import ErrorHandler, StatusCodeRedirect
8 from pylons.middleware import ErrorHandler, StatusCodeRedirect
9 from pylons.wsgiapp import PylonsApp
9 from pylons.wsgiapp import PylonsApp
10 from routes.middleware import RoutesMiddleware
10 from routes.middleware import RoutesMiddleware
11
11 from paste.auth.basic import AuthBasicHandler
12 from pylons_app.config.environment import load_environment
12 from pylons_app.config.environment import load_environment
13
13 from pylons_app.lib.auth import authfunc
14
14
15 def make_app(global_conf, full_stack=True, **app_conf):
15 def make_app(global_conf, full_stack=True, **app_conf):
16 """Create a Pylons WSGI application and return it
16 """Create a Pylons WSGI application and return it
17
17
18 ``global_conf``
18 ``global_conf``
19 The inherited configuration for this application. Normally from
19 The inherited configuration for this application. Normally from
20 the [DEFAULT] section of the Paste ini file.
20 the [DEFAULT] section of the Paste ini file.
21
21
22 ``full_stack``
22 ``full_stack``
23 Whether or not this application provides a full WSGI stack (by
23 Whether or not this application provides a full WSGI stack (by
24 default, meaning it handles its own exceptions and errors).
24 default, meaning it handles its own exceptions and errors).
25 Disable full_stack when this application is "managed" by
25 Disable full_stack when this application is "managed" by
26 another WSGI middleware.
26 another WSGI middleware.
27
27
28 ``app_conf``
28 ``app_conf``
29 The application's local configuration. Normally specified in
29 The application's local configuration. Normally specified in
30 the [app:<name>] section of the Paste ini file (where <name>
30 the [app:<name>] section of the Paste ini file (where <name>
31 defaults to main).
31 defaults to main).
32
32
33 """
33 """
34 # Configure the Pylons environment
34 # Configure the Pylons environment
35 load_environment(global_conf, app_conf)
35 load_environment(global_conf, app_conf)
36
36
37 # The Pylons WSGI app
37 # The Pylons WSGI app
38 app = PylonsApp()
38 app = PylonsApp()
39
39
40 # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
40 # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
41
41
42 # Routing/Session/Cache Middleware
42 # Routing/Session/Cache Middleware
43 app = RoutesMiddleware(app, config['routes.map'])
43 app = RoutesMiddleware(app, config['routes.map'])
44 app = SessionMiddleware(app, config)
44 app = SessionMiddleware(app, config)
45 app = CacheMiddleware(app, config)
45 app = CacheMiddleware(app, config)
46
46 app = AuthBasicHandler(app, config['repos_name'] + ' mercurial repository', authfunc)
47
47 if asbool(full_stack):
48 if asbool(full_stack):
48 # Handle Python exceptions
49 # Handle Python exceptions
49 app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
50 app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
50
51
51 # Display error documents for 401, 403, 404 status codes (and
52 # Display error documents for 401, 403, 404 status codes (and
52 # 500 when debug is disabled)
53 # 500 when debug is disabled)
53 if asbool(config['debug']):
54 if asbool(config['debug']):
54 #don't handle 404, since mercurial does it for us.
55 #don't handle 404, since mercurial does it for us.
55 app = StatusCodeRedirect(app, [400, 401, 403, 500])
56 app = StatusCodeRedirect(app, [400, 401, 403, 500])
56 else:
57 else:
57 app = StatusCodeRedirect(app, [400, 401, 403, 500])
58 app = StatusCodeRedirect(app, [400, 401, 403, 500])
58
59
59 # Establish the Registry for this application
60 # Establish the Registry for this application
60 app = RegistryManager(app)
61 app = RegistryManager(app)
61
62
62 # Static files (If running in production, and Apache or another web
63 # Static files (If running in production, and Apache or another web
63 # server is handling this static content, remove the following 3 lines)
64 # server is handling this static content, remove the following 3 lines)
64 static_app = StaticURLParser(config['pylons.paths']['static_files'])
65 static_app = StaticURLParser(config['pylons.paths']['static_files'])
65 app = Cascade([static_app, app])
66 app = Cascade([static_app, app])
66 return app
67 return app
67
68
@@ -1,135 +1,134 b''
1 #!/usr/bin/python
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
2 # -*- coding: utf-8 -*-
3 import logging
3 import logging
4 import os
4 from pylons_app.lib.base import BaseController, render
5 from pylons_app.lib.base import BaseController, render
5 from pylons import c, g, session, request
6 from pylons import tmpl_context as c, app_globals as g, session, request, config
6 from pylons_app.lib import helpers as h
7 from pylons_app.lib import helpers as h
7 from mako.template import Template
8 from mako.template import Template
8 from pprint import pprint
9 import os
10 from mercurial import ui, hg
9 from mercurial import ui, hg
11 from mercurial.error import RepoError
10 from mercurial.error import RepoError
12 from ConfigParser import ConfigParser
11 from ConfigParser import ConfigParser
13 import encodings
14 from pylons.controllers.util import abort
12 from pylons.controllers.util import abort
13
15 log = logging.getLogger(__name__)
14 log = logging.getLogger(__name__)
16
15
17 class HgController(BaseController):
16 class HgController(BaseController):
18
17
19 def __before__(self):
18 def __before__(self):
20 c.repos_prefix = 'etelko'
19 c.repos_prefix = config['repos_name']
21
20
22 def view(self, *args, **kwargs):
21 def view(self, *args, **kwargs):
23 response = g.hgapp(request.environ, self.start_response)
22 response = g.hgapp(request.environ, self.start_response)
24
23
25 http_accept = request.environ.get('HTTP_ACCEPT', False)
24 http_accept = request.environ.get('HTTP_ACCEPT', False)
26 if not http_accept:
25 if not http_accept:
27 return abort(status_code=400, detail='no http accept in header')
26 return abort(status_code=400, detail='no http accept in header')
28
27
29 #for mercurial protocols and raw files we can't wrap into mako
28 #for mercurial protocols and raw files we can't wrap into mako
30 if http_accept.find("mercurial") != -1 or \
29 if http_accept.find("mercurial") != -1 or \
31 request.environ['PATH_INFO'].find('raw-file') != -1:
30 request.environ['PATH_INFO'].find('raw-file') != -1:
32 return response
31 return response
33 try:
32 try:
34 tmpl = u''.join(response)
33 tmpl = u''.join(response)
35 template = Template(tmpl, lookup=request.environ['pylons.pylons']\
34 template = Template(tmpl, lookup=request.environ['pylons.pylons']\
36 .config['pylons.g'].mako_lookup)
35 .config['pylons.app_globals'].mako_lookup)
37
36
38 except (RuntimeError, UnicodeDecodeError):
37 except (RuntimeError, UnicodeDecodeError):
39 log.info('disabling unicode due to encoding error')
38 log.info('disabling unicode due to encoding error')
40 response = g.hgapp(request.environ, self.start_response)
39 response = g.hgapp(request.environ, self.start_response)
41 tmpl = ''.join(response)
40 tmpl = ''.join(response)
42 template = Template(tmpl, lookup=request.environ['pylons.pylons']\
41 template = Template(tmpl, lookup=request.environ['pylons.pylons']\
43 .config['pylons.g'].mako_lookup, disable_unicode=True)
42 .config['pylons.app_globals'].mako_lookup, disable_unicode=True)
44
43
45
44
46 return template.render(g=g, c=c, session=session, h=h)
45 return template.render(g=g, c=c, session=session, h=h)
47
46
48
47
49 def manage_hgrc(self):
48 def manage_hgrc(self):
50 pass
49 pass
51
50
52 def hgrc(self, dirname):
51 def hgrc(self, dirname):
53 filename = os.path.join(dirname, '.hg', 'hgrc')
52 filename = os.path.join(dirname, '.hg', 'hgrc')
54 return filename
53 return filename
55
54
56 def add_repo(self, new_repo):
55 def add_repo(self, new_repo):
57 c.staticurl = g.statics
56 c.staticurl = g.statics
58
57
59 #extra check it can be add since it's the command
58 #extra check it can be add since it's the command
60 if new_repo == 'add':
59 if new_repo == 'add':
61 c.msg = 'you basstard ! this repo is a command'
60 c.msg = 'you basstard ! this repo is a command'
62 c.new_repo = ''
61 c.new_repo = ''
63 return render('add.html')
62 return render('add.html')
64
63
65 new_repo = new_repo.replace(" ", "_")
64 new_repo = new_repo.replace(" ", "_")
66 new_repo = new_repo.replace("-", "_")
65 new_repo = new_repo.replace("-", "_")
67
66
68 try:
67 try:
69 self._create_repo(new_repo)
68 self._create_repo(new_repo)
70 c.new_repo = new_repo
69 c.new_repo = new_repo
71 c.msg = 'added repo'
70 c.msg = 'added repo'
72 except Exception as e:
71 except Exception as e:
73 c.new_repo = 'Exception when adding: %s' % new_repo
72 c.new_repo = 'Exception when adding: %s' % new_repo
74 c.msg = str(e)
73 c.msg = str(e)
75
74
76 return render('add.html')
75 return render('add.html')
77
76
78 def _check_repo(self, repo_name):
77 def _check_repo(self, repo_name):
79 p = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
78 p = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
80 config_path = os.path.join(p, 'hgwebdir.config')
79 config_path = os.path.join(p, 'hgwebdir.config')
81
80
82 cp = ConfigParser()
81 cp = ConfigParser()
83
82
84 cp.read(config_path)
83 cp.read(config_path)
85 repos_path = cp.get('paths', '/').replace("**", '')
84 repos_path = cp.get('paths', '/').replace("**", '')
86
85
87 if not repos_path:
86 if not repos_path:
88 raise Exception('Could not read config !')
87 raise Exception('Could not read config !')
89
88
90 self.repo_path = os.path.join(repos_path, repo_name)
89 self.repo_path = os.path.join(repos_path, repo_name)
91
90
92 try:
91 try:
93 r = hg.repository(ui.ui(), self.repo_path)
92 r = hg.repository(ui.ui(), self.repo_path)
94 hg.verify(r)
93 hg.verify(r)
95 #here we hnow that repo exists it was verified
94 #here we hnow that repo exists it was verified
96 log.info('%s repo is already created', repo_name)
95 log.info('%s repo is already created', repo_name)
97 raise Exception('Repo exists')
96 raise Exception('Repo exists')
98 except RepoError:
97 except RepoError:
99 log.info('%s repo is free for creation', repo_name)
98 log.info('%s repo is free for creation', repo_name)
100 #it means that there is no valid repo there...
99 #it means that there is no valid repo there...
101 return True
100 return True
102
101
103
102
104 def _create_repo(self, repo_name):
103 def _create_repo(self, repo_name):
105 if repo_name in [None, '', 'add']:
104 if repo_name in [None, '', 'add']:
106 raise Exception('undefined repo_name of repo')
105 raise Exception('undefined repo_name of repo')
107
106
108 if self._check_repo(repo_name):
107 if self._check_repo(repo_name):
109 log.info('creating repo %s in %s', repo_name, self.repo_path)
108 log.info('creating repo %s in %s', repo_name, self.repo_path)
110 cmd = """mkdir %s && hg init %s""" \
109 cmd = """mkdir %s && hg init %s""" \
111 % (self.repo_path, self.repo_path)
110 % (self.repo_path, self.repo_path)
112 os.popen(cmd)
111 os.popen(cmd)
113
112
114 #def _make_app():
113 #def _make_app():
115 # #for single a repo
114 # #for single a repo
116 # #return hgweb("/path/to/repo", "Name")
115 # #return hgweb("/path/to/repo", "Name")
117 # repos = "hgwebdir.config"
116 # repos = "hgwebdir.config"
118 # return hgwebdir(repos)
117 # return hgwebdir(repos)
119 #
118 #
120
119
121 # def view(self, environ, start_response):
120 # def view(self, environ, start_response):
122 # #the following is only needed when using hgwebdir
121 # #the following is only needed when using hgwebdir
123 # app = _make_app()
122 # app = _make_app()
124 # #return wsgi_app(environ, start_response)
123 # #return wsgi_app(environ, start_response)
125 # response = app(request.environ, self.start_response)
124 # response = app(request.environ, self.start_response)
126 #
125 #
127 # if environ['PATH_INFO'].find("static") != -1:
126 # if environ['PATH_INFO'].find("static") != -1:
128 # return response
127 # return response
129 # else:
128 # else:
130 # #wrap the murcurial response in a mako template.
129 # #wrap the murcurial response in a mako template.
131 # template = Template("".join(response),
130 # template = Template("".join(response),
132 # lookup = environ['pylons.pylons']\
131 # lookup = environ['pylons.pylons']\
133 # .config['pylons.g'].mako_lookup)
132 # .config['pylons.g'].mako_lookup)
134 #
133 #
135 # return template.render(g = g, c = c, session = session, h = h)
134 # return template.render(g = g, c = c, session = session, h = h)
General Comments 0
You need to be logged in to leave comments. Login now