Show More
@@ -25,9 +25,11 b' import operator' | |||||
25 | from pyramid import compat |
|
25 | from pyramid import compat | |
26 | from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPBadRequest |
|
26 | from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPBadRequest | |
27 |
|
27 | |||
28 | from rhodecode.lib import helpers as h, diffs |
|
28 | from rhodecode.lib import helpers as h, diffs, rc_cache | |
29 | from rhodecode.lib.utils2 import ( |
|
29 | from rhodecode.lib.utils2 import ( | |
30 | StrictAttributeDict, str2bool, safe_int, datetime_to_time, safe_unicode) |
|
30 | StrictAttributeDict, str2bool, safe_int, datetime_to_time, safe_unicode) | |
|
31 | from rhodecode.lib.markup_renderer import MarkupRenderer, relative_links | |||
|
32 | from rhodecode.lib.vcs.backends.base import EmptyCommit | |||
31 | from rhodecode.lib.vcs.exceptions import RepositoryRequirementError |
|
33 | from rhodecode.lib.vcs.exceptions import RepositoryRequirementError | |
32 | from rhodecode.model import repo |
|
34 | from rhodecode.model import repo | |
33 | from rhodecode.model import repo_group |
|
35 | from rhodecode.model import repo_group | |
@@ -36,6 +38,7 b' from rhodecode.model import user' | |||||
36 | from rhodecode.model.db import User |
|
38 | from rhodecode.model.db import User | |
37 | from rhodecode.model.scm import ScmModel |
|
39 | from rhodecode.model.scm import ScmModel | |
38 | from rhodecode.model.settings import VcsSettingsModel |
|
40 | from rhodecode.model.settings import VcsSettingsModel | |
|
41 | from rhodecode.model.repo import ReadmeFinder | |||
39 |
|
42 | |||
40 | log = logging.getLogger(__name__) |
|
43 | log = logging.getLogger(__name__) | |
41 |
|
44 | |||
@@ -310,6 +313,64 b' class RepoAppView(BaseAppView):' | |||||
310 | settings = settings_model.get_repo_settings_inherited() |
|
313 | settings = settings_model.get_repo_settings_inherited() | |
311 | return settings.get(settings_key, default) |
|
314 | return settings.get(settings_key, default) | |
312 |
|
315 | |||
|
316 | def _get_readme_data(self, db_repo, renderer_type, commit_id=None, path='/'): | |||
|
317 | log.debug('Looking for README file at path %s', path) | |||
|
318 | if commit_id: | |||
|
319 | landing_commit_id = commit_id | |||
|
320 | else: | |||
|
321 | landing_commit = db_repo.get_landing_commit() | |||
|
322 | if isinstance(landing_commit, EmptyCommit): | |||
|
323 | return None, None | |||
|
324 | landing_commit_id = landing_commit.raw_id | |||
|
325 | ||||
|
326 | cache_namespace_uid = 'cache_repo.{}'.format(db_repo.repo_id) | |||
|
327 | region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid) | |||
|
328 | start = time.time() | |||
|
329 | ||||
|
330 | @region.conditional_cache_on_arguments(namespace=cache_namespace_uid) | |||
|
331 | def generate_repo_readme(repo_id, _commit_id, _repo_name, _readme_search_path, _renderer_type): | |||
|
332 | readme_data = None | |||
|
333 | readme_filename = None | |||
|
334 | ||||
|
335 | commit = db_repo.get_commit(_commit_id) | |||
|
336 | log.debug("Searching for a README file at commit %s.", _commit_id) | |||
|
337 | readme_node = ReadmeFinder(_renderer_type).search(commit, path=_readme_search_path) | |||
|
338 | ||||
|
339 | if readme_node: | |||
|
340 | log.debug('Found README node: %s', readme_node) | |||
|
341 | relative_urls = { | |||
|
342 | 'raw': h.route_path( | |||
|
343 | 'repo_file_raw', repo_name=_repo_name, | |||
|
344 | commit_id=commit.raw_id, f_path=readme_node.path), | |||
|
345 | 'standard': h.route_path( | |||
|
346 | 'repo_files', repo_name=_repo_name, | |||
|
347 | commit_id=commit.raw_id, f_path=readme_node.path), | |||
|
348 | } | |||
|
349 | readme_data = self._render_readme_or_none(commit, readme_node, relative_urls) | |||
|
350 | readme_filename = readme_node.unicode_path | |||
|
351 | ||||
|
352 | return readme_data, readme_filename | |||
|
353 | ||||
|
354 | readme_data, readme_filename = generate_repo_readme( | |||
|
355 | db_repo.repo_id, landing_commit_id, db_repo.repo_name, path, renderer_type,) | |||
|
356 | compute_time = time.time() - start | |||
|
357 | log.debug('Repo README for path %s generated and computed in %.4fs', | |||
|
358 | path, compute_time) | |||
|
359 | return readme_data, readme_filename | |||
|
360 | ||||
|
361 | def _render_readme_or_none(self, commit, readme_node, relative_urls): | |||
|
362 | log.debug('Found README file `%s` rendering...', readme_node.path) | |||
|
363 | renderer = MarkupRenderer() | |||
|
364 | try: | |||
|
365 | html_source = renderer.render( | |||
|
366 | readme_node.content, filename=readme_node.path) | |||
|
367 | if relative_urls: | |||
|
368 | return relative_links(html_source, relative_urls) | |||
|
369 | return html_source | |||
|
370 | except Exception: | |||
|
371 | log.exception( | |||
|
372 | "Exception while trying to render the README") | |||
|
373 | ||||
313 | def get_recache_flag(self): |
|
374 | def get_recache_flag(self): | |
314 | for flag_name in ['force_recache', 'force-recache', 'no-cache']: |
|
375 | for flag_name in ['force_recache', 'force-recache', 'no-cache']: | |
315 | flag_val = self.request.GET.get(flag_name) |
|
376 | flag_val = self.request.GET.get(flag_name) |
@@ -706,6 +706,10 b' class RepoFilesView(RepoAppView):' | |||||
706 | # later via ajax we call repo_nodetree_full and fetch whole |
|
706 | # later via ajax we call repo_nodetree_full and fetch whole | |
707 | c.file_tree = self._get_tree_at_commit(c, c.commit.raw_id, f_path) |
|
707 | c.file_tree = self._get_tree_at_commit(c, c.commit.raw_id, f_path) | |
708 |
|
708 | |||
|
709 | c.readme_data, c.readme_file = \ | |||
|
710 | self._get_readme_data(self.db_repo, c.visual.default_renderer, | |||
|
711 | c.commit.raw_id, f_path) | |||
|
712 | ||||
709 | except RepositoryError as e: |
|
713 | except RepositoryError as e: | |
710 | h.flash(safe_str(h.escape(e)), category='error') |
|
714 | h.flash(safe_str(h.escape(e)), category='error') | |
711 | raise HTTPNotFound() |
|
715 | raise HTTPNotFound() |
@@ -32,14 +32,12 b' from rhodecode.config.conf import (LANGU' | |||||
32 | from rhodecode.lib import helpers as h, rc_cache |
|
32 | from rhodecode.lib import helpers as h, rc_cache | |
33 | from rhodecode.lib.utils2 import safe_str, safe_int |
|
33 | from rhodecode.lib.utils2 import safe_str, safe_int | |
34 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator |
|
34 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator | |
35 | from rhodecode.lib.markup_renderer import MarkupRenderer, relative_links |
|
|||
36 | from rhodecode.lib.ext_json import json |
|
35 | from rhodecode.lib.ext_json import json | |
37 | from rhodecode.lib.vcs.backends.base import EmptyCommit |
|
36 | from rhodecode.lib.vcs.backends.base import EmptyCommit | |
38 | from rhodecode.lib.vcs.exceptions import ( |
|
37 | from rhodecode.lib.vcs.exceptions import ( | |
39 | CommitError, EmptyRepositoryError, CommitDoesNotExistError) |
|
38 | CommitError, EmptyRepositoryError, CommitDoesNotExistError) | |
40 | from rhodecode.model.db import Statistics, CacheKey, User |
|
39 | from rhodecode.model.db import Statistics, CacheKey, User | |
41 | from rhodecode.model.meta import Session |
|
40 | from rhodecode.model.meta import Session | |
42 | from rhodecode.model.repo import ReadmeFinder |
|
|||
43 | from rhodecode.model.scm import ScmModel |
|
41 | from rhodecode.model.scm import ScmModel | |
44 |
|
42 | |||
45 | log = logging.getLogger(__name__) |
|
43 | log = logging.getLogger(__name__) | |
@@ -54,59 +52,6 b' class RepoSummaryView(RepoAppView):' | |||||
54 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
52 | c.rhodecode_repo = self.rhodecode_vcs_repo | |
55 | return c |
|
53 | return c | |
56 |
|
54 | |||
57 | def _get_readme_data(self, db_repo, renderer_type): |
|
|||
58 | log.debug('Looking for README file') |
|
|||
59 | landing_commit = db_repo.get_landing_commit() |
|
|||
60 | if isinstance(landing_commit, EmptyCommit): |
|
|||
61 | return None, None |
|
|||
62 |
|
||||
63 | cache_namespace_uid = 'cache_repo.{}'.format(db_repo.repo_id) |
|
|||
64 | region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid) |
|
|||
65 | start = time.time() |
|
|||
66 |
|
||||
67 | @region.conditional_cache_on_arguments(namespace=cache_namespace_uid) |
|
|||
68 | def generate_repo_readme(repo_id, commit_id, _repo_name, _renderer_type): |
|
|||
69 | readme_data = None |
|
|||
70 | readme_filename = None |
|
|||
71 |
|
||||
72 | commit = db_repo.get_commit(commit_id) |
|
|||
73 | log.debug("Searching for a README file at commit %s.", commit_id) |
|
|||
74 | readme_node = ReadmeFinder(_renderer_type).search(commit) |
|
|||
75 |
|
||||
76 | if readme_node: |
|
|||
77 | log.debug('Found README node: %s', readme_node) |
|
|||
78 | relative_urls = { |
|
|||
79 | 'raw': h.route_path( |
|
|||
80 | 'repo_file_raw', repo_name=_repo_name, |
|
|||
81 | commit_id=commit.raw_id, f_path=readme_node.path), |
|
|||
82 | 'standard': h.route_path( |
|
|||
83 | 'repo_files', repo_name=_repo_name, |
|
|||
84 | commit_id=commit.raw_id, f_path=readme_node.path), |
|
|||
85 | } |
|
|||
86 | readme_data = self._render_readme_or_none(commit, readme_node, relative_urls) |
|
|||
87 | readme_filename = readme_node.unicode_path |
|
|||
88 |
|
||||
89 | return readme_data, readme_filename |
|
|||
90 |
|
||||
91 | readme_data, readme_filename = generate_repo_readme( |
|
|||
92 | db_repo.repo_id, landing_commit.raw_id, db_repo.repo_name, renderer_type,) |
|
|||
93 | compute_time = time.time() - start |
|
|||
94 | log.debug('Repo readme generated and computed in %.4fs', compute_time) |
|
|||
95 | return readme_data, readme_filename |
|
|||
96 |
|
||||
97 | def _render_readme_or_none(self, commit, readme_node, relative_urls): |
|
|||
98 | log.debug('Found README file `%s` rendering...', readme_node.path) |
|
|||
99 | renderer = MarkupRenderer() |
|
|||
100 | try: |
|
|||
101 | html_source = renderer.render( |
|
|||
102 | readme_node.content, filename=readme_node.path) |
|
|||
103 | if relative_urls: |
|
|||
104 | return relative_links(html_source, relative_urls) |
|
|||
105 | return html_source |
|
|||
106 | except Exception: |
|
|||
107 | log.exception( |
|
|||
108 | "Exception while trying to render the README") |
|
|||
109 |
|
||||
110 | def _load_commits_context(self, c): |
|
55 | def _load_commits_context(self, c): | |
111 | p = safe_int(self.request.GET.get('page'), 1) |
|
56 | p = safe_int(self.request.GET.get('page'), 1) | |
112 | size = safe_int(self.request.GET.get('size'), 10) |
|
57 | size = safe_int(self.request.GET.get('size'), 10) |
@@ -61,4 +61,23 b'' | |||||
61 | ${c.file_tree |n} |
|
61 | ${c.file_tree |n} | |
62 | </div> |
|
62 | </div> | |
63 |
|
63 | |||
|
64 | %if c.readme_data: | |||
|
65 | <div id="readme" class="anchor"> | |||
|
66 | <div class="box"> | |||
|
67 | <div class="title" title="${h.tooltip(_('Readme file from commit %s:%s') % (c.rhodecode_db_repo.landing_rev[0], c.rhodecode_db_repo.landing_rev[1]))}"> | |||
|
68 | <h3 class="breadcrumbs"> | |||
|
69 | <a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.rhodecode_db_repo.landing_rev[1],f_path=c.readme_file)}"> | |||
|
70 | ${c.readme_file} | |||
|
71 | </a> | |||
|
72 | </h3> | |||
64 | </div> |
|
73 | </div> | |
|
74 | <div class="readme codeblock"> | |||
|
75 | <div class="readme_box"> | |||
|
76 | ${c.readme_data|n} | |||
|
77 | </div> | |||
|
78 | </div> | |||
|
79 | </div> | |||
|
80 | </div> | |||
|
81 | %endif | |||
|
82 | ||||
|
83 | </div> |
General Comments 0
You need to be logged in to leave comments.
Login now