Show More
@@ -30,36 +30,6 b' from rhodecode.lib.utils2 import __get_l' | |||||
30 | # extensions will index it's content |
|
30 | # extensions will index it's content | |
31 | LANGUAGES_EXTENSIONS_MAP = __get_lem() |
|
31 | LANGUAGES_EXTENSIONS_MAP = __get_lem() | |
32 |
|
32 | |||
33 | # list of readme files to search in file tree and display in summary |
|
|||
34 | # attached weights defines the search order lower is first |
|
|||
35 | ALL_READMES = [ |
|
|||
36 | ('readme', 0), ('README', 0), ('Readme', 0), |
|
|||
37 | ('doc/readme', 1), ('doc/README', 1), ('doc/Readme', 1), |
|
|||
38 | ('Docs/readme', 2), ('Docs/README', 2), ('Docs/Readme', 2), |
|
|||
39 | ('DOCS/readme', 2), ('DOCS/README', 2), ('DOCS/Readme', 2), |
|
|||
40 | ('docs/readme', 2), ('docs/README', 2), ('docs/Readme', 2), |
|
|||
41 | ] |
|
|||
42 |
|
||||
43 | # extension together with weights to search lower is first |
|
|||
44 | RST_EXTS = [ |
|
|||
45 | ('', 0), ('.rst', 1), ('.rest', 1), |
|
|||
46 | ('.RST', 2), ('.REST', 2) |
|
|||
47 | ] |
|
|||
48 |
|
||||
49 | MARKDOWN_EXTS = [ |
|
|||
50 | ('.md', 1), ('.MD', 1), |
|
|||
51 | ('.mkdn', 2), ('.MKDN', 2), |
|
|||
52 | ('.mdown', 3), ('.MDOWN', 3), |
|
|||
53 | ('.markdown', 4), ('.MARKDOWN', 4) |
|
|||
54 | ] |
|
|||
55 |
|
||||
56 | PLAIN_EXTS = [ |
|
|||
57 | ('.text', 2), ('.TEXT', 2), |
|
|||
58 | ('.txt', 3), ('.TXT', 3) |
|
|||
59 | ] |
|
|||
60 |
|
||||
61 | ALL_EXTS = MARKDOWN_EXTS + RST_EXTS + PLAIN_EXTS |
|
|||
62 |
|
||||
63 | DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S" |
|
33 | DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S" | |
64 |
|
34 | |||
65 | DATE_FORMAT = "%Y-%m-%d" |
|
35 | DATE_FORMAT = "%Y-%m-%d" |
@@ -24,14 +24,12 b' Summary controller for RhodeCode Enterpr' | |||||
24 |
|
24 | |||
25 | import logging |
|
25 | import logging | |
26 | from string import lower |
|
26 | from string import lower | |
27 | from itertools import product |
|
|||
28 |
|
27 | |||
29 | from pylons import tmpl_context as c, request |
|
28 | from pylons import tmpl_context as c, request | |
30 | from pylons.i18n.translation import _ |
|
29 | from pylons.i18n.translation import _ | |
31 | from beaker.cache import cache_region, region_invalidate |
|
30 | from beaker.cache import cache_region, region_invalidate | |
32 |
|
31 | |||
33 | from rhodecode.config.conf import ( |
|
32 | from rhodecode.config.conf import (LANGUAGES_EXTENSIONS_MAP) | |
34 | ALL_READMES, ALL_EXTS, LANGUAGES_EXTENSIONS_MAP) |
|
|||
35 | from rhodecode.controllers import utils |
|
33 | from rhodecode.controllers import utils | |
36 | from rhodecode.controllers.changelog import _load_changelog_summary |
|
34 | from rhodecode.controllers.changelog import _load_changelog_summary | |
37 | from rhodecode.lib import caches, helpers as h |
|
35 | from rhodecode.lib import caches, helpers as h | |
@@ -49,10 +47,6 b' from rhodecode.model.db import Statistic' | |||||
49 |
|
47 | |||
50 | log = logging.getLogger(__name__) |
|
48 | log = logging.getLogger(__name__) | |
51 |
|
49 | |||
52 | README_FILES = [''.join([x[0][0], x[1][0]]) |
|
|||
53 | for x in sorted(list(product(ALL_READMES, ALL_EXTS)), |
|
|||
54 | key=lambda y:y[0][1] + y[1][1])] |
|
|||
55 |
|
||||
56 |
|
50 | |||
57 | class SummaryController(BaseRepoController): |
|
51 | class SummaryController(BaseRepoController): | |
58 |
|
52 | |||
@@ -62,6 +56,7 b' class SummaryController(BaseRepoControll' | |||||
62 | def __get_readme_data(self, db_repo): |
|
56 | def __get_readme_data(self, db_repo): | |
63 | repo_name = db_repo.repo_name |
|
57 | repo_name = db_repo.repo_name | |
64 | log.debug('Looking for README file') |
|
58 | log.debug('Looking for README file') | |
|
59 | default_renderer = c.visual.default_renderer | |||
65 |
|
60 | |||
66 | @cache_region('long_term') |
|
61 | @cache_region('long_term') | |
67 | def _generate_readme(cache_key): |
|
62 | def _generate_readme(cache_key): | |
@@ -73,7 +68,7 b' class SummaryController(BaseRepoControll' | |||||
73 | if isinstance(commit, EmptyCommit): |
|
68 | if isinstance(commit, EmptyCommit): | |
74 | raise EmptyRepositoryError() |
|
69 | raise EmptyRepositoryError() | |
75 | renderer = MarkupRenderer() |
|
70 | renderer = MarkupRenderer() | |
76 | for f in README_FILES: |
|
71 | for f in renderer.pick_readme_order(default_renderer): | |
77 | try: |
|
72 | try: | |
78 | node = commit.get_node(f) |
|
73 | node = commit.get_node(f) | |
79 | except NodeDoesNotExistError: |
|
74 | except NodeDoesNotExistError: |
@@ -1726,17 +1726,7 b' def markdown(source, mentions=False):' | |||||
1726 | mentions=mentions)) |
|
1726 | mentions=mentions)) | |
1727 |
|
1727 | |||
1728 | def renderer_from_filename(filename, exclude=None): |
|
1728 | def renderer_from_filename(filename, exclude=None): | |
1729 | from rhodecode.config.conf import MARKDOWN_EXTS, RST_EXTS |
|
1729 | return MarkupRenderer.renderer_from_filename(filename, exclude=exclude) | |
1730 |
|
||||
1731 | def _filter(elements): |
|
|||
1732 | if isinstance(exclude, (list, tuple)): |
|
|||
1733 | return [x for x in elements if x not in exclude] |
|
|||
1734 | return elements |
|
|||
1735 |
|
||||
1736 | if filename.endswith(tuple(_filter([x[0] for x in MARKDOWN_EXTS if x[0]]))): |
|
|||
1737 | return 'markdown' |
|
|||
1738 | if filename.endswith(tuple(_filter([x[0] for x in RST_EXTS if x[0]]))): |
|
|||
1739 | return 'rst' |
|
|||
1740 |
|
1730 | |||
1741 |
|
1731 | |||
1742 | def render(source, renderer='rst', mentions=False): |
|
1732 | def render(source, renderer='rst', mentions=False): |
@@ -23,10 +23,11 b'' | |||||
23 | Renderer for markup languages with ability to parse using rst or markdown |
|
23 | Renderer for markup languages with ability to parse using rst or markdown | |
24 | """ |
|
24 | """ | |
25 |
|
25 | |||
26 |
|
||||
27 | import re |
|
26 | import re | |
28 | import os |
|
27 | import os | |
29 | import logging |
|
28 | import logging | |
|
29 | import itertools | |||
|
30 | ||||
30 | from mako.lookup import TemplateLookup |
|
31 | from mako.lookup import TemplateLookup | |
31 |
|
32 | |||
32 | from docutils.core import publish_parts |
|
33 | from docutils.core import publish_parts | |
@@ -50,6 +51,37 b' class MarkupRenderer(object):' | |||||
50 | RST_PAT = re.compile(r'\.re?st$', re.IGNORECASE) |
|
51 | RST_PAT = re.compile(r'\.re?st$', re.IGNORECASE) | |
51 | PLAIN_PAT = re.compile(r'^readme$', re.IGNORECASE) |
|
52 | PLAIN_PAT = re.compile(r'^readme$', re.IGNORECASE) | |
52 |
|
53 | |||
|
54 | # list of readme files to search in file tree and display in summary | |||
|
55 | # attached weights defines the search order lower is first | |||
|
56 | ALL_READMES = [ | |||
|
57 | ('readme', 0), ('README', 0), ('Readme', 0), | |||
|
58 | ('doc/readme', 1), ('doc/README', 1), ('doc/Readme', 1), | |||
|
59 | ('Docs/readme', 2), ('Docs/README', 2), ('Docs/Readme', 2), | |||
|
60 | ('DOCS/readme', 2), ('DOCS/README', 2), ('DOCS/Readme', 2), | |||
|
61 | ('docs/readme', 2), ('docs/README', 2), ('docs/Readme', 2), | |||
|
62 | ] | |||
|
63 | # extension together with weights. Lower is first means we control how | |||
|
64 | # extensions are attached to readme names with those. | |||
|
65 | PLAIN_EXTS = [ | |||
|
66 | ('', 0), # special case that renders READMES names without extension | |||
|
67 | ('.text', 2), ('.TEXT', 2), | |||
|
68 | ('.txt', 3), ('.TXT', 3) | |||
|
69 | ] | |||
|
70 | ||||
|
71 | RST_EXTS = [ | |||
|
72 | ('.rst', 1), ('.rest', 1), | |||
|
73 | ('.RST', 2), ('.REST', 2) | |||
|
74 | ] | |||
|
75 | ||||
|
76 | MARKDOWN_EXTS = [ | |||
|
77 | ('.md', 1), ('.MD', 1), | |||
|
78 | ('.mkdn', 2), ('.MKDN', 2), | |||
|
79 | ('.mdown', 3), ('.MDOWN', 3), | |||
|
80 | ('.markdown', 4), ('.MARKDOWN', 4) | |||
|
81 | ] | |||
|
82 | ||||
|
83 | ALL_EXTS = PLAIN_EXTS + MARKDOWN_EXTS + RST_EXTS | |||
|
84 | ||||
53 | def _detect_renderer(self, source, filename=None): |
|
85 | def _detect_renderer(self, source, filename=None): | |
54 | """ |
|
86 | """ | |
55 | runs detection of what renderer should be used for generating html |
|
87 | runs detection of what renderer should be used for generating html | |
@@ -72,6 +104,48 b' class MarkupRenderer(object):' | |||||
72 |
|
104 | |||
73 | return getattr(MarkupRenderer, detected_renderer) |
|
105 | return getattr(MarkupRenderer, detected_renderer) | |
74 |
|
106 | |||
|
107 | @classmethod | |||
|
108 | def renderer_from_filename(cls, filename, exclude): | |||
|
109 | """ | |||
|
110 | Detect renderer from filename and optionally use exlcude list to | |||
|
111 | remove some options. This is mostly used in helpers | |||
|
112 | """ | |||
|
113 | def _filter(elements): | |||
|
114 | if isinstance(exclude, (list, tuple)): | |||
|
115 | return [x for x in elements if x not in exclude] | |||
|
116 | return elements | |||
|
117 | ||||
|
118 | if filename.endswith( | |||
|
119 | tuple(_filter([x[0] for x in cls.MARKDOWN_EXTS if x[0]]))): | |||
|
120 | return 'markdown' | |||
|
121 | if filename.endswith(tuple(_filter([x[0] for x in cls.RST_EXTS if x[0]]))): | |||
|
122 | return 'rst' | |||
|
123 | ||||
|
124 | return 'plain' | |||
|
125 | ||||
|
126 | @classmethod | |||
|
127 | def generate_readmes(cls, all_readmes, extensions): | |||
|
128 | combined = itertools.product(all_readmes, extensions) | |||
|
129 | # sort by filename weight(y[0][1]) + extensions weight(y[1][1]) | |||
|
130 | prioritized_readmes = sorted(combined, key=lambda y: y[0][1] + y[1][1]) | |||
|
131 | # filename, extension | |||
|
132 | return [''.join([x[0][0], x[1][0]]) for x in prioritized_readmes] | |||
|
133 | ||||
|
134 | def pick_readme_order(self, default_renderer): | |||
|
135 | ||||
|
136 | if default_renderer == 'markdown': | |||
|
137 | markdown = self.generate_readmes(self.ALL_READMES, self.MARKDOWN_EXTS) | |||
|
138 | readme_order = markdown + self.generate_readmes( | |||
|
139 | self.ALL_READMES, self.RST_EXTS + self.PLAIN_EXTS) | |||
|
140 | elif default_renderer == 'rst': | |||
|
141 | markdown = self.generate_readmes(self.ALL_READMES, self.RST_EXTS) | |||
|
142 | readme_order = markdown + self.generate_readmes( | |||
|
143 | self.ALL_READMES, self.MARKDOWN_EXTS + self.PLAIN_EXTS) | |||
|
144 | else: | |||
|
145 | readme_order = self.generate_readmes(self.ALL_READMES, self.ALL_EXTS) | |||
|
146 | ||||
|
147 | return readme_order | |||
|
148 | ||||
75 | def render(self, source, filename=None): |
|
149 | def render(self, source, filename=None): | |
76 | """ |
|
150 | """ | |
77 | Renders a given filename using detected renderer |
|
151 | Renders a given filename using detected renderer |
@@ -177,3 +177,37 b' Auto status change to |new_status|' | |||||
177 | renderer = RstTemplateRenderer() |
|
177 | renderer = RstTemplateRenderer() | |
178 | rendered = renderer.render('auto_status_change.mako', **params) |
|
178 | rendered = renderer.render('auto_status_change.mako', **params) | |
179 | assert expected == rendered |
|
179 | assert expected == rendered | |
|
180 | ||||
|
181 | ||||
|
182 | @pytest.mark.parametrize( | |||
|
183 | "readmes, exts, order", | |||
|
184 | [ | |||
|
185 | ([], [], []), | |||
|
186 | ||||
|
187 | ([('readme1', 0), ('text1', 1)], [('.ext', 0), ('.txt', 1)], | |||
|
188 | ['readme1.ext', 'readme1.txt', 'text1.ext', 'text1.txt']), | |||
|
189 | ||||
|
190 | ([('readme2', 0), ('text2', 1)], [('.ext', 2), ('.txt', 1)], | |||
|
191 | ['readme2.txt', 'readme2.ext', 'text2.txt', 'text2.ext']), | |||
|
192 | ||||
|
193 | ([('readme3', 0), ('text3', 1)], [('.XXX', 1)], | |||
|
194 | ['readme3.XXX', 'text3.XXX']), | |||
|
195 | ]) | |||
|
196 | def test_generate_readmes(readmes, exts, order): | |||
|
197 | assert order == MarkupRenderer.generate_readmes(readmes, exts) | |||
|
198 | ||||
|
199 | ||||
|
200 | @pytest.mark.parametrize( | |||
|
201 | "renderer, expected_order", | |||
|
202 | [ | |||
|
203 | ('plain', ['readme', 'README', 'Readme']), | |||
|
204 | ('text', ['readme', 'README', 'Readme']), | |||
|
205 | ('markdown', MarkupRenderer.generate_readmes( | |||
|
206 | MarkupRenderer.ALL_READMES, MarkupRenderer.MARKDOWN_EXTS)), | |||
|
207 | ('rst', MarkupRenderer.generate_readmes( | |||
|
208 | MarkupRenderer.ALL_READMES, MarkupRenderer.RST_EXTS)), | |||
|
209 | ]) | |||
|
210 | def test_order_of_readme_generation(renderer, expected_order): | |||
|
211 | mkd_renderer = MarkupRenderer() | |||
|
212 | assert expected_order == mkd_renderer.pick_readme_order( | |||
|
213 | renderer)[:len(expected_order)] |
General Comments 0
You need to be logged in to leave comments.
Login now