Show More
@@ -0,0 +1,16 b'' | |||||
|
1 | import logging | |||
|
2 | ||||
|
3 | from pylons import request, response, session, tmpl_context as c, url | |||
|
4 | from pylons.controllers.util import abort, redirect | |||
|
5 | ||||
|
6 | from pylons_app.lib.base import BaseController, render | |||
|
7 | ||||
|
8 | log = logging.getLogger(__name__) | |||
|
9 | ||||
|
10 | class BranchesController(BaseController): | |||
|
11 | ||||
|
12 | def index(self): | |||
|
13 | # Return a rendered template | |||
|
14 | #return render('/branches.mako') | |||
|
15 | # or, return a string | |||
|
16 | return 'Hello World' |
@@ -0,0 +1,29 b'' | |||||
|
1 | import logging | |||
|
2 | ||||
|
3 | from pylons import tmpl_context as c, app_globals as g, session, request, config, url | |||
|
4 | from pylons.controllers.util import abort, redirect | |||
|
5 | ||||
|
6 | from pylons_app.lib.base import BaseController, render | |||
|
7 | from pylons_app.lib.utils import get_repo_slug | |||
|
8 | from pylons_app.model.hg_model import HgModel | |||
|
9 | from webhelpers.paginate import Page | |||
|
10 | ||||
|
11 | log = logging.getLogger(__name__) | |||
|
12 | ||||
|
13 | class ChangelogController(BaseController): | |||
|
14 | def __before__(self): | |||
|
15 | c.repos_prefix = config['repos_name'] | |||
|
16 | c.staticurl = g.statics | |||
|
17 | c.repo_name = get_repo_slug(request) | |||
|
18 | ||||
|
19 | ||||
|
20 | def index(self): | |||
|
21 | hg_model = HgModel() | |||
|
22 | p = int(request.params.get('page', 1)) | |||
|
23 | repo = hg_model.get_repo(c.repo_name) | |||
|
24 | c.repo_changesets = Page(repo, page=p, items_per_page=20) | |||
|
25 | c.shortlog_data = render('shortlog_data.html') | |||
|
26 | if request.params.get('partial'): | |||
|
27 | return c.shortlog_data | |||
|
28 | r = render('/shortlog.html') | |||
|
29 | return r |
@@ -0,0 +1,16 b'' | |||||
|
1 | import logging | |||
|
2 | ||||
|
3 | from pylons import request, response, session, tmpl_context as c, url | |||
|
4 | from pylons.controllers.util import abort, redirect | |||
|
5 | ||||
|
6 | from pylons_app.lib.base import BaseController, render | |||
|
7 | ||||
|
8 | log = logging.getLogger(__name__) | |||
|
9 | ||||
|
10 | class FileController(BaseController): | |||
|
11 | ||||
|
12 | def index(self): | |||
|
13 | # Return a rendered template | |||
|
14 | #return render('/file.mako') | |||
|
15 | # or, return a string | |||
|
16 | return 'Hello World' |
@@ -0,0 +1,16 b'' | |||||
|
1 | import logging | |||
|
2 | ||||
|
3 | from pylons import request, response, session, tmpl_context as c, url | |||
|
4 | from pylons.controllers.util import abort, redirect | |||
|
5 | ||||
|
6 | from pylons_app.lib.base import BaseController, render | |||
|
7 | ||||
|
8 | log = logging.getLogger(__name__) | |||
|
9 | ||||
|
10 | class FilesController(BaseController): | |||
|
11 | ||||
|
12 | def index(self): | |||
|
13 | # Return a rendered template | |||
|
14 | #return render('/files.mako') | |||
|
15 | # or, return a string | |||
|
16 | return 'Hello World' |
@@ -0,0 +1,16 b'' | |||||
|
1 | import logging | |||
|
2 | ||||
|
3 | from pylons import request, response, session, tmpl_context as c, url | |||
|
4 | from pylons.controllers.util import abort, redirect | |||
|
5 | ||||
|
6 | from pylons_app.lib.base import BaseController, render | |||
|
7 | ||||
|
8 | log = logging.getLogger(__name__) | |||
|
9 | ||||
|
10 | class GraphController(BaseController): | |||
|
11 | ||||
|
12 | def index(self): | |||
|
13 | # Return a rendered template | |||
|
14 | #return render('/graph.mako') | |||
|
15 | # or, return a string | |||
|
16 | return 'Hello World' |
@@ -0,0 +1,16 b'' | |||||
|
1 | import logging | |||
|
2 | ||||
|
3 | from pylons import request, response, session, tmpl_context as c, url | |||
|
4 | from pylons.controllers.util import abort, redirect | |||
|
5 | ||||
|
6 | from pylons_app.lib.base import BaseController, render | |||
|
7 | ||||
|
8 | log = logging.getLogger(__name__) | |||
|
9 | ||||
|
10 | class TagsController(BaseController): | |||
|
11 | ||||
|
12 | def index(self): | |||
|
13 | # Return a rendered template | |||
|
14 | #return render('/tags.mako') | |||
|
15 | # or, return a string | |||
|
16 | return 'Hello World' |
@@ -0,0 +1,7 b'' | |||||
|
1 | from pylons_app.tests import * | |||
|
2 | ||||
|
3 | class TestBranchesController(TestController): | |||
|
4 | ||||
|
5 | def test_index(self): | |||
|
6 | response = self.app.get(url(controller='branches', action='index')) | |||
|
7 | # Test response... |
@@ -0,0 +1,7 b'' | |||||
|
1 | from pylons_app.tests import * | |||
|
2 | ||||
|
3 | class TestChangelogController(TestController): | |||
|
4 | ||||
|
5 | def test_index(self): | |||
|
6 | response = self.app.get(url(controller='changelog', action='index')) | |||
|
7 | # Test response... |
@@ -0,0 +1,7 b'' | |||||
|
1 | from pylons_app.tests import * | |||
|
2 | ||||
|
3 | class TestFileController(TestController): | |||
|
4 | ||||
|
5 | def test_index(self): | |||
|
6 | response = self.app.get(url(controller='file', action='index')) | |||
|
7 | # Test response... |
@@ -0,0 +1,7 b'' | |||||
|
1 | from pylons_app.tests import * | |||
|
2 | ||||
|
3 | class TestFilesController(TestController): | |||
|
4 | ||||
|
5 | def test_index(self): | |||
|
6 | response = self.app.get(url(controller='files', action='index')) | |||
|
7 | # Test response... |
@@ -0,0 +1,7 b'' | |||||
|
1 | from pylons_app.tests import * | |||
|
2 | ||||
|
3 | class TestGraphController(TestController): | |||
|
4 | ||||
|
5 | def test_index(self): | |||
|
6 | response = self.app.get(url(controller='graph', action='index')) | |||
|
7 | # Test response... |
@@ -0,0 +1,7 b'' | |||||
|
1 | from pylons_app.tests import * | |||
|
2 | ||||
|
3 | class TestTagsController(TestController): | |||
|
4 | ||||
|
5 | def test_index(self): | |||
|
6 | response = self.app.get(url(controller='tags', action='index')) | |||
|
7 | # Test response... |
@@ -1,127 +1,128 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 | ##nr of threads to spawn |
|
22 | ##nr of threads to spawn | |
23 | threadpool_workers = 5 |
|
23 | threadpool_workers = 5 | |
24 |
|
24 | |||
25 | ##max request before |
|
25 | ##max request before | |
26 | threadpool_max_requests = 2 |
|
26 | threadpool_max_requests = 2 | |
27 |
|
27 | |||
28 | ##option to use threads of process |
|
28 | ##option to use threads of process | |
29 | use_threadpool = true |
|
29 | use_threadpool = true | |
30 |
|
30 | |||
31 | use = egg:Paste#http |
|
31 | use = egg:Paste#http | |
32 | host = 127.0.0.1 |
|
32 | host = 127.0.0.1 | |
33 | port = 5000 |
|
33 | port = 5000 | |
34 |
|
34 | |||
35 | [app:main] |
|
35 | [app:main] | |
36 | use = egg:pylons_app |
|
36 | use = egg:pylons_app | |
37 | full_stack = true |
|
37 | full_stack = true | |
38 | static_files = true |
|
38 | static_files = true | |
39 | lang=en |
|
39 | lang=en | |
40 | cache_dir = %(here)s/data |
|
40 | cache_dir = %(here)s/data | |
41 | repos_name = Python-works |
|
41 | repos_name = Python-works | |
42 |
|
42 | |||
43 | #################################### |
|
43 | #################################### | |
44 | ### BEAKER CACHE #### |
|
44 | ### BEAKER CACHE #### | |
45 | #################################### |
|
45 | #################################### | |
46 | beaker.cache.data_dir=/tmp/cache/data |
|
46 | beaker.cache.data_dir=/tmp/cache/data | |
47 | beaker.cache.lock_dir=/tmp/cache/lock |
|
47 | beaker.cache.lock_dir=/tmp/cache/lock | |
48 | beaker.cache.regions=short_term |
|
48 | beaker.cache.regions=short_term | |
49 | beaker.cache.short_term.type=memory |
|
49 | beaker.cache.short_term.type=memory | |
50 |
beaker.cache.short_term.expire= |
|
50 | beaker.cache.short_term.expire=60 | |
51 |
|
51 | |||
52 | ################################################################################ |
|
52 | ################################################################################ | |
53 | ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ## |
|
53 | ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ## | |
54 | ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ## |
|
54 | ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ## | |
55 | ## execute malicious code after an exception is raised. ## |
|
55 | ## execute malicious code after an exception is raised. ## | |
56 | ################################################################################ |
|
56 | ################################################################################ | |
57 | #set debug = false |
|
57 | #set debug = false | |
58 |
|
58 | |||
59 | ################################## |
|
59 | ################################## | |
60 | ### LOGVIEW CONFIG ### |
|
60 | ### LOGVIEW CONFIG ### | |
61 | ################################## |
|
61 | ################################## | |
62 | logview.sqlalchemy = #faa |
|
62 | logview.sqlalchemy = #faa | |
63 | logview.pylons.templating = #bfb |
|
63 | logview.pylons.templating = #bfb | |
64 | logview.pylons.util = #eee |
|
64 | logview.pylons.util = #eee | |
65 |
|
65 | |||
66 | ######################################################### |
|
66 | ######################################################### | |
67 | ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ### |
|
67 | ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ### | |
68 | ######################################################### |
|
68 | ######################################################### | |
69 | sqlalchemy.db1.url = sqlite:///%(here)s/hg_app.db |
|
69 | sqlalchemy.db1.url = sqlite:///%(here)s/hg_app.db | |
70 |
#sqlalchemy.db1.echo = |
|
70 | #sqlalchemy.db1.echo = False | |
71 | #sqlalchemy.db1.pool_recycle = 3600 |
|
71 | #sqlalchemy.db1.pool_recycle = 3600 | |
72 | sqlalchemy.convert_unicode = true |
|
72 | sqlalchemy.convert_unicode = true | |
73 |
|
73 | |||
74 | ################################ |
|
74 | ################################ | |
75 | ### LOGGING CONFIGURATION #### |
|
75 | ### LOGGING CONFIGURATION #### | |
76 | ################################ |
|
76 | ################################ | |
77 | [loggers] |
|
77 | [loggers] | |
78 | keys = root, routes, pylons_app, sqlalchemy |
|
78 | keys = root, routes, pylons_app, sqlalchemy | |
79 |
|
79 | |||
80 | [handlers] |
|
80 | [handlers] | |
81 | keys = console |
|
81 | keys = console | |
82 |
|
82 | |||
83 | [formatters] |
|
83 | [formatters] | |
84 | keys = generic |
|
84 | keys = generic | |
85 |
|
85 | |||
86 | ############# |
|
86 | ############# | |
87 | ## LOGGERS ## |
|
87 | ## LOGGERS ## | |
88 | ############# |
|
88 | ############# | |
89 | [logger_root] |
|
89 | [logger_root] | |
90 | level = NOTSET |
|
90 | level = NOTSET | |
91 | handlers = console |
|
91 | handlers = console | |
92 |
|
92 | |||
93 | [logger_routes] |
|
93 | [logger_routes] | |
94 | level = DEBUG |
|
94 | level = DEBUG | |
95 | handlers = console |
|
95 | handlers = console | |
96 | qualname = routes.middleware |
|
96 | qualname = routes.middleware | |
97 | # "level = DEBUG" logs the route matched and routing variables. |
|
97 | # "level = DEBUG" logs the route matched and routing variables. | |
98 |
|
98 | |||
99 | [logger_pylons_app] |
|
99 | [logger_pylons_app] | |
100 | level = DEBUG |
|
100 | level = DEBUG | |
101 | handlers = console |
|
101 | handlers = console | |
102 | qualname = pylons_app |
|
102 | qualname = pylons_app | |
103 |
|
103 | |||
104 |
|
104 | |||
105 | [logger_sqlalchemy] |
|
105 | [logger_sqlalchemy] | |
106 |
level = |
|
106 | level = INFO | |
107 | handlers = console |
|
107 | handlers = console | |
108 | qualname = sqlalchemy.engine |
|
108 | qualname = sqlalchemy.engine | |
|
109 | propagate = 0 | |||
109 |
|
110 | |||
110 | ############## |
|
111 | ############## | |
111 | ## HANDLERS ## |
|
112 | ## HANDLERS ## | |
112 | ############## |
|
113 | ############## | |
113 |
|
114 | |||
114 | [handler_console] |
|
115 | [handler_console] | |
115 | class = StreamHandler |
|
116 | class = StreamHandler | |
116 | args = (sys.stderr,) |
|
117 | args = (sys.stderr,) | |
117 | level = NOTSET |
|
118 | level = NOTSET | |
118 | formatter = generic |
|
119 | formatter = generic | |
119 |
|
120 | |||
120 | ################ |
|
121 | ################ | |
121 | ## FORMATTERS ## |
|
122 | ## FORMATTERS ## | |
122 | ################ |
|
123 | ################ | |
123 |
|
124 | |||
124 | [formatter_generic] |
|
125 | [formatter_generic] | |
125 | format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s |
|
126 | format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s | |
126 | datefmt = %Y-%m-%d %H:%M:%S |
|
127 | datefmt = %Y-%m-%d %H:%M:%S | |
127 |
|
128 |
@@ -1,65 +1,84 b'' | |||||
1 | #!/usr/bin/python |
|
1 | #!/usr/bin/python | |
2 | # -*- coding: utf-8 -*- |
|
2 | # -*- coding: utf-8 -*- | |
3 | import logging |
|
3 | from mako.template import Template | |
|
4 | from mercurial.hg import repository | |||
|
5 | from mercurial.hgweb import hgweb | |||
|
6 | from mercurial.hgweb.request import wsgiapplication | |||
|
7 | from mercurial.localrepo import localrepository | |||
|
8 | from operator import itemgetter | |||
4 | from pylons import tmpl_context as c, app_globals as g, session, request, config |
|
9 | from pylons import tmpl_context as c, app_globals as g, session, request, config | |
|
10 | from pylons.controllers.util import abort | |||
5 | from pylons_app.lib import helpers as h |
|
11 | from pylons_app.lib import helpers as h | |
6 | from pylons_app.lib.base import BaseController, render |
|
12 | from pylons_app.lib.base import BaseController, render | |
7 | from mako.template import Template |
|
|||
8 | from pylons.controllers.util import abort |
|
|||
9 | from pylons_app.lib.utils import get_repo_slug |
|
13 | from pylons_app.lib.utils import get_repo_slug | |
10 | from operator import itemgetter |
|
|||
11 | from pylons_app.model.hg_model import HgModel |
|
14 | from pylons_app.model.hg_model import HgModel | |
|
15 | import logging | |||
|
16 | import os | |||
|
17 | from beaker.cache import cache_region | |||
12 | log = logging.getLogger(__name__) |
|
18 | log = logging.getLogger(__name__) | |
13 |
|
19 | |||
14 | class HgController(BaseController): |
|
20 | class HgController(BaseController): | |
15 |
|
21 | |||
16 | def __before__(self): |
|
22 | def __before__(self): | |
17 | c.repos_prefix = config['repos_name'] |
|
23 | c.repos_prefix = config['repos_name'] | |
18 | c.staticurl = g.statics |
|
24 | c.staticurl = g.statics | |
19 | c.repo_name = get_repo_slug(request) |
|
25 | c.repo_name = get_repo_slug(request) | |
20 |
|
26 | |||
21 | def index(self): |
|
27 | def index(self): | |
|
28 | ||||
|
29 | ||||
22 | hg_model = HgModel() |
|
30 | hg_model = HgModel() | |
23 | c.repos_list = list(hg_model.get_repos()) |
|
31 | @cache_region('short_term', 'repo_list') | |
|
32 | def _list(): | |||
|
33 | return list(hg_model.get_repos()) | |||
|
34 | ||||
|
35 | c.repos_list = _list() | |||
24 | c.current_sort = request.GET.get('sort', 'name') |
|
36 | c.current_sort = request.GET.get('sort', 'name') | |
25 |
|
37 | |||
26 | cs = c.current_sort |
|
38 | cs = c.current_sort | |
27 | c.cs_slug = cs.replace('-', '') |
|
39 | c.cs_slug = cs.replace('-', '') | |
28 | sortables = ['name', 'description', 'last_change', 'tip', 'contact'] |
|
40 | sortables = ['name', 'description', 'last_change', 'tip', 'contact'] | |
29 |
|
41 | |||
30 | if cs and c.cs_slug in sortables: |
|
42 | if cs and c.cs_slug in sortables: | |
31 | sort_key = c.cs_slug + '_sort' |
|
43 | sort_key = c.cs_slug + '_sort' | |
32 | if cs.startswith('-'): |
|
44 | if cs.startswith('-'): | |
33 | c.repos_list.sort(key=itemgetter(sort_key), reverse=True) |
|
45 | c.repos_list.sort(key=itemgetter(sort_key), reverse=True) | |
34 | else: |
|
46 | else: | |
35 | c.repos_list.sort(key=itemgetter(sort_key), reverse=False) |
|
47 | c.repos_list.sort(key=itemgetter(sort_key), reverse=False) | |
36 |
|
48 | |||
37 | return render('/index.html') |
|
49 | return render('/index.html') | |
38 |
|
50 | |||
39 | def view(self, *args, **kwargs): |
|
51 | def view(self, environ, start_response, path_info): | |
40 | #TODO: reimplement this not tu use hgwebdir |
|
52 | print path_info | |
|
53 | ||||
|
54 | def app_maker(): | |||
41 |
|
55 | |||
42 | response = g.hgapp(request.environ, self.start_response) |
|
56 | path = os.path.join(g.base_path, c.repo_name) | |
|
57 | repo = repository(g.baseui, path) | |||
|
58 | hgwebapp = hgweb(repo, c.repo_name) | |||
|
59 | return hgwebapp | |||
|
60 | ||||
|
61 | a = wsgiapplication(app_maker) | |||
|
62 | resp = a(environ, start_response) | |||
43 |
|
63 | |||
44 | http_accept = request.environ.get('HTTP_ACCEPT', False) |
|
64 | http_accept = request.environ.get('HTTP_ACCEPT', False) | |
45 | if not http_accept: |
|
65 | if not http_accept: | |
46 | return abort(status_code=400, detail='no http accept in header') |
|
66 | return abort(status_code=400, detail='no http accept in header') | |
47 |
|
67 | |||
48 | #for mercurial protocols and raw files we can't wrap into mako |
|
68 | #for mercurial protocols and raw files we can't wrap into mako | |
49 | if http_accept.find("mercurial") != -1 or \ |
|
69 | if http_accept.find("mercurial") != -1 or \ | |
50 | request.environ['PATH_INFO'].find('raw-file') != -1: |
|
70 | request.environ['PATH_INFO'].find('raw-file') != -1: | |
51 |
return resp |
|
71 | return resp | |
52 | try: |
|
72 | try: | |
53 |
tmpl = u''.join(resp |
|
73 | tmpl = u''.join(resp) | |
54 | template = Template(tmpl, lookup=request.environ['pylons.pylons']\ |
|
74 | template = Template(tmpl, lookup=request.environ['pylons.pylons']\ | |
55 | .config['pylons.app_globals'].mako_lookup) |
|
75 | .config['pylons.app_globals'].mako_lookup) | |
56 |
|
76 | |||
57 | except (RuntimeError, UnicodeDecodeError): |
|
77 | except (RuntimeError, UnicodeDecodeError): | |
58 | log.info('disabling unicode due to encoding error') |
|
78 | log.info('disabling unicode due to encoding error') | |
59 |
resp |
|
79 | resp = g.hgapp(request.environ, self.start_response) | |
60 |
tmpl = ''.join(resp |
|
80 | tmpl = ''.join(resp) | |
61 | template = Template(tmpl, lookup=request.environ['pylons.pylons']\ |
|
81 | template = Template(tmpl, lookup=request.environ['pylons.pylons']\ | |
62 | .config['pylons.app_globals'].mako_lookup, disable_unicode=True) |
|
82 | .config['pylons.app_globals'].mako_lookup, disable_unicode=True) | |
63 |
|
83 | |||
64 |
|
||||
65 | return template.render(g=g, c=c, session=session, h=h) |
|
84 | return template.render(g=g, c=c, session=session, h=h) |
@@ -1,34 +1,29 b'' | |||||
1 | import logging |
|
1 | import logging | |
2 |
|
2 | |||
3 | from pylons import tmpl_context as c, app_globals as g, session, request, config, url |
|
3 | from pylons import tmpl_context as c, app_globals as g, session, request, config, url | |
4 | from pylons.controllers.util import abort, redirect |
|
4 | from pylons.controllers.util import abort, redirect | |
5 |
|
5 | |||
6 | from pylons_app.lib.base import BaseController, render |
|
6 | from pylons_app.lib.base import BaseController, render | |
7 | from pylons_app.lib.utils import get_repo_slug |
|
7 | from pylons_app.lib.utils import get_repo_slug | |
8 | from pylons_app.model.hg_model import HgModel |
|
8 | from pylons_app.model.hg_model import HgModel | |
9 | from webhelpers.paginate import Page |
|
9 | from webhelpers.paginate import Page | |
10 |
|
10 | |||
11 | log = logging.getLogger(__name__) |
|
11 | log = logging.getLogger(__name__) | |
12 |
|
12 | |||
13 | class ShortlogController(BaseController): |
|
13 | class ShortlogController(BaseController): | |
14 | def __before__(self): |
|
14 | def __before__(self): | |
15 | c.repos_prefix = config['repos_name'] |
|
15 | c.repos_prefix = config['repos_name'] | |
16 | c.staticurl = g.statics |
|
16 | c.staticurl = g.statics | |
17 | c.repo_name = get_repo_slug(request) |
|
17 | c.repo_name = get_repo_slug(request) | |
18 |
|
18 | |||
19 |
|
19 | |||
20 | def index(self): |
|
20 | def index(self): | |
21 | hg_model = HgModel() |
|
21 | hg_model = HgModel() | |
22 | lim = 20 |
|
|||
23 | p = int(request.params.get('page', 1)) |
|
22 | p = int(request.params.get('page', 1)) | |
24 | repo = hg_model.get_repo(c.repo_name) |
|
23 | repo = hg_model.get_repo(c.repo_name) | |
25 | cnt = repo.revisions[-1] |
|
24 | c.repo_changesets = Page(repo, page=p, items_per_page=20) | |
26 | gen = repo.get_changesets(None) |
|
|||
27 | repo_changesets = list(gen) |
|
|||
28 |
|
||||
29 | c.repo_changesets = Page(repo_changesets, page=p, item_count=cnt, items_per_page=lim) |
|
|||
30 | c.shortlog_data = render('shortlog_data.html') |
|
25 | c.shortlog_data = render('shortlog_data.html') | |
31 | if request.params.get('partial'): |
|
26 | if request.params.get('partial'): | |
32 | return c.shortlog_data |
|
27 | return c.shortlog_data | |
33 | r = render('/shortlog.html') |
|
28 | r = render('/shortlog.html') | |
34 | return r |
|
29 | return r |
@@ -1,74 +1,92 b'' | |||||
1 | """The application's Globals object""" |
|
1 | """The application's Globals object""" | |
2 | #uncomment the following if you want to serve a single repo |
|
2 | #uncomment the following if you want to serve a single repo | |
3 | #from mercurial.hgweb.hgweb_mod import hgweb |
|
3 | #from mercurial.hgweb.hgweb_mod import hgweb | |
4 | from mercurial.hgweb.hgwebdir_mod import hgwebdir |
|
4 | from mercurial.hgweb.hgwebdir_mod import hgwebdir | |
5 | from mercurial import templater |
|
5 | from mercurial import templater | |
6 | from mercurial.hgweb.request import wsgiapplication |
|
6 | from mercurial.hgweb.request import wsgiapplication | |
7 | from mercurial import ui, config |
|
7 | from mercurial import ui, config | |
8 | import os |
|
8 | import os | |
9 | from beaker.cache import CacheManager |
|
9 | from beaker.cache import CacheManager | |
10 | from beaker.util import parse_cache_config_options |
|
10 | from beaker.util import parse_cache_config_options | |
11 |
|
11 | |||
12 | class Globals(object): |
|
12 | class Globals(object): | |
13 |
|
13 | |||
14 | """Globals acts as a container for objects available throughout the |
|
14 | """Globals acts as a container for objects available throughout the | |
15 | life of the application |
|
15 | life of the application | |
16 |
|
16 | |||
17 | """ |
|
17 | """ | |
18 |
|
18 | |||
19 | def __init__(self, config): |
|
19 | def __init__(self, config): | |
20 | """One instance of Globals is created during application |
|
20 | """One instance of Globals is created during application | |
21 | initialization and is available during requests via the |
|
21 | initialization and is available during requests via the | |
22 | 'app_globals' variable |
|
22 | 'app_globals' variable | |
23 |
|
23 | |||
24 | """ |
|
24 | """ | |
25 | self.cache = CacheManager(**parse_cache_config_options(config)) |
|
25 | self.cache = CacheManager(**parse_cache_config_options(config)) | |
26 | self.hgapp = wsgiapplication(self.make_web_app) |
|
26 | self.baseui = self.make_ui('hgwebdir.config') | |
|
27 | ||||
|
28 | ||||
|
29 | def make_ui(self, path='hgwebdir.config'): | |||
|
30 | """ | |||
|
31 | A funcion that will read python rc files and make an ui from read options | |||
27 |
|
32 | |||
28 | def make_web_app(self): |
|
33 | @param path: path to mercurial config file | |
29 | repos = "hgwebdir.config" |
|
34 | """ | |
|
35 | #propagated from mercurial documentation | |||
|
36 | sections = [ | |||
|
37 | 'alias', | |||
|
38 | 'auth', | |||
|
39 | 'decode/encode', | |||
|
40 | 'defaults', | |||
|
41 | 'diff', | |||
|
42 | 'email', | |||
|
43 | 'extensions', | |||
|
44 | 'format', | |||
|
45 | 'merge-patterns', | |||
|
46 | 'merge-tools', | |||
|
47 | 'hooks', | |||
|
48 | 'http_proxy', | |||
|
49 | 'smtp', | |||
|
50 | 'patch', | |||
|
51 | 'paths', | |||
|
52 | 'profiling', | |||
|
53 | 'server', | |||
|
54 | 'trusted', | |||
|
55 | 'ui', | |||
|
56 | 'web', | |||
|
57 | ] | |||
|
58 | ||||
|
59 | repos = path | |||
30 | baseui = ui.ui() |
|
60 | baseui = ui.ui() | |
31 | cfg = config.config() |
|
61 | cfg = config.config() | |
32 | cfg.read(repos) |
|
62 | cfg.read(repos) | |
33 | paths = cfg.items('paths') |
|
63 | self.paths = cfg.items('paths') | |
34 | self.paths = paths |
|
64 | self.base_path = self.paths[0][1].replace('*', '') | |
35 | self.check_repo_dir(paths) |
|
65 | self.check_repo_dir(self.paths) | |
36 |
|
||||
37 | self.set_statics(cfg) |
|
66 | self.set_statics(cfg) | |
38 |
|
67 | |||
39 | for k, v in cfg.items('web'): |
|
68 | for section in sections: | |
40 | baseui.setconfig('web', k, v) |
|
69 | for k, v in cfg.items(section): | |
41 | #magic trick to make our custom template dir working |
|
70 | baseui.setconfig(section, k, v) | |
42 | templater.path.append(cfg.get('web', 'templates', None)) |
|
|||
43 | self.baseui = baseui |
|
|||
44 | #baseui.setconfig('web', 'description', '') |
|
|||
45 | #baseui.setconfig('web', 'name', '') |
|
|||
46 | #baseui.setconfig('web', 'contact', '') |
|
|||
47 | #baseui.setconfig('web', 'allow_archive', '') |
|
|||
48 | #baseui.setconfig('web', 'style', 'monoblue_plain') |
|
|||
49 | #baseui.setconfig('web', 'baseurl', '') |
|
|||
50 | #baseui.setconfig('web', 'staticurl', '') |
|
|||
51 |
|
71 | |||
52 | hgwebapp = hgwebdir(paths, baseui=baseui) |
|
72 | return baseui | |
53 | return hgwebapp |
|
|||
54 |
|
||||
55 |
|
73 | |||
56 | def set_statics(self, cfg): |
|
74 | def set_statics(self, cfg): | |
57 | ''' |
|
75 | ''' | |
58 | set's the statics for use in mako templates |
|
76 | set's the statics for use in mako templates | |
59 | @param cfg: |
|
77 | @param cfg: | |
60 | ''' |
|
78 | ''' | |
61 | self.statics = cfg.get('web', 'staticurl', '/static') |
|
79 | self.statics = cfg.get('web', 'staticurl', '/static') | |
62 | if not self.statics.endswith('/'): |
|
80 | if not self.statics.endswith('/'): | |
63 | self.statics += '/' |
|
81 | self.statics += '/' | |
64 |
|
82 | |||
65 |
|
83 | |||
66 | def check_repo_dir(self, paths): |
|
84 | def check_repo_dir(self, paths): | |
67 | repos_path = paths[0][1].split('/') |
|
85 | repos_path = paths[0][1].split('/') | |
68 | if repos_path[-1] in ['*', '**']: |
|
86 | if repos_path[-1] in ['*', '**']: | |
69 | repos_path = repos_path[:-1] |
|
87 | repos_path = repos_path[:-1] | |
70 | if repos_path[0] != '/': |
|
88 | if repos_path[0] != '/': | |
71 | repos_path[0] = '/' |
|
89 | repos_path[0] = '/' | |
72 | if not os.path.isdir(os.path.join(*repos_path)): |
|
90 | if not os.path.isdir(os.path.join(*repos_path)): | |
73 | raise Exception('Not a valid repository in %s' % paths[0][1]) |
|
91 | raise Exception('Not a valid repository in %s' % paths[0][1]) | |
74 |
|
92 |
@@ -1,7 +1,8 b'' | |||||
1 |
|
1 | |||
2 | def get_repo_slug(request): |
|
2 | def get_repo_slug(request): | |
3 | path_info = request.environ.get('PATH_INFO') |
|
3 | path_info = request.environ.get('PATH_INFO') | |
4 |
|
|
4 | uri_lst = path_info.split('/') | |
5 | action = path_info.split('/')[-1] |
|
5 | print uri_lst | |
6 |
|
6 | print 'len', len(uri_lst) | ||
|
7 | repo_name = uri_lst[1] | |||
7 | return repo_name |
|
8 | return repo_name |
@@ -1,59 +1,60 b'' | |||||
1 | #!/usr/bin/env python |
|
1 | #!/usr/bin/env python | |
2 | # encoding: utf-8 |
|
2 | # encoding: utf-8 | |
3 | # |
|
3 | # | |
4 | # Copyright (c) 2010 marcink. All rights reserved. |
|
4 | # Copyright (c) 2010 marcink. All rights reserved. | |
5 | # |
|
5 | # | |
6 | ''' |
|
6 | ''' | |
7 | Created on Apr 9, 2010 |
|
7 | Created on Apr 9, 2010 | |
8 |
|
8 | |||
9 | @author: marcink |
|
9 | @author: marcink | |
10 | ''' |
|
10 | ''' | |
11 | import os |
|
11 | import os | |
12 | from pylons import tmpl_context as c, app_globals as g, session, request, config |
|
12 | from pylons import tmpl_context as c, app_globals as g, session, request, config | |
13 | from pylons.controllers.util import abort |
|
13 | from pylons.controllers.util import abort | |
14 | try: |
|
14 | try: | |
15 | from vcs.backends.hg import get_repositories, MercurialRepository |
|
15 | from vcs.backends.hg import get_repositories, MercurialRepository | |
16 | except ImportError: |
|
16 | except ImportError: | |
17 | print 'You have to import vcs module' |
|
17 | print 'You have to import vcs module' | |
|
18 | raise | |||
18 |
|
19 | |||
19 | class HgModel(object): |
|
20 | class HgModel(object): | |
20 | """ |
|
21 | """ | |
21 | Mercurial Model |
|
22 | Mercurial Model | |
22 | """ |
|
23 | """ | |
23 |
|
24 | |||
24 |
|
25 | |||
25 | def __init__(self): |
|
26 | def __init__(self): | |
26 | """ |
|
27 | """ | |
27 | Constructor |
|
28 | Constructor | |
28 | """ |
|
29 | """ | |
29 | pass |
|
30 | pass | |
30 |
|
31 | |||
31 | def get_repos(self): |
|
32 | def get_repos(self): | |
32 | for mercurial_repo in get_repositories(g.paths[0][0], g.paths[0][1], g.baseui): |
|
33 | for mercurial_repo in get_repositories(g.paths[0][0], g.paths[0][1], g.baseui): | |
33 |
|
34 | |||
34 | if mercurial_repo._get_hidden(): |
|
35 | if mercurial_repo._get_hidden(): | |
35 | #skip hidden web repository |
|
36 | #skip hidden web repository | |
36 | continue |
|
37 | continue | |
37 |
|
38 | |||
38 | last_change = mercurial_repo.last_change |
|
39 | last_change = mercurial_repo.last_change | |
39 | tip = mercurial_repo.repo.changectx('tip') |
|
40 | tip = mercurial_repo.repo.changectx('tip') | |
40 | tmp_d = {} |
|
41 | tmp_d = {} | |
41 | tmp_d['name'] = mercurial_repo.name |
|
42 | tmp_d['name'] = mercurial_repo.name | |
42 | tmp_d['name_sort'] = tmp_d['name'] |
|
43 | tmp_d['name_sort'] = tmp_d['name'] | |
43 | tmp_d['description'] = mercurial_repo.description |
|
44 | tmp_d['description'] = mercurial_repo.description | |
44 | tmp_d['description_sort'] = tmp_d['description'] |
|
45 | tmp_d['description_sort'] = tmp_d['description'] | |
45 | tmp_d['last_change'] = last_change |
|
46 | tmp_d['last_change'] = last_change | |
46 | tmp_d['last_change_sort'] = last_change[1] - last_change[0] |
|
47 | tmp_d['last_change_sort'] = last_change[1] - last_change[0] | |
47 | tmp_d['tip'] = str(tip) |
|
48 | tmp_d['tip'] = str(tip) | |
48 | tmp_d['tip_sort'] = tip.rev() |
|
49 | tmp_d['tip_sort'] = tip.rev() | |
49 | tmp_d['rev'] = tip.rev() |
|
50 | tmp_d['rev'] = tip.rev() | |
50 | tmp_d['contact'] = mercurial_repo.contact |
|
51 | tmp_d['contact'] = mercurial_repo.contact | |
51 | tmp_d['contact_sort'] = tmp_d['contact'] |
|
52 | tmp_d['contact_sort'] = tmp_d['contact'] | |
52 | tmp_d['repo_archives'] = mercurial_repo._get_archives() |
|
53 | tmp_d['repo_archives'] = list(mercurial_repo._get_archives()) | |
53 |
|
54 | |||
54 | yield tmp_d |
|
55 | yield tmp_d | |
55 |
|
56 | |||
56 | def get_repo(self, repo_name): |
|
57 | def get_repo(self, repo_name): | |
57 | path = g.paths[0][1].replace('*', '') |
|
58 | path = g.paths[0][1].replace('*', '') | |
58 | repo = MercurialRepository(os.path.join(path, repo_name), baseui=g.baseui) |
|
59 | repo = MercurialRepository(os.path.join(path, repo_name), baseui=g.baseui) | |
59 | return repo |
|
60 | return repo |
General Comments 0
You need to be logged in to leave comments.
Login now