##// END OF EJS Templates
implements #215 Repository view uses a README (text/markdown + rst)
marcink -
r1605:df59c050 beta
parent child Browse files
Show More
@@ -23,23 +23,25 b''
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import traceback
26 import calendar
27 import calendar
27 import logging
28 import logging
28 from time import mktime
29 from time import mktime
29 from datetime import datetime, timedelta, date
30 from datetime import timedelta, date
31 from itertools import product
30
32
31 from vcs.exceptions import ChangesetError
33 from vcs.exceptions import ChangesetError, EmptyRepositoryError, \
34 NodeDoesNotExistError
32
35
33 from pylons import tmpl_context as c, request, url
36 from pylons import tmpl_context as c, request, url
34 from pylons.i18n.translation import _
37 from pylons.i18n.translation import _
35
38
36 from rhodecode.model.db import Statistics, Repository
39 from rhodecode.model.db import Statistics
37 from rhodecode.model.repo import RepoModel
40 from rhodecode.lib import ALL_READMES, ALL_EXTS
38
39 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
41 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
40 from rhodecode.lib.base import BaseRepoController, render
42 from rhodecode.lib.base import BaseRepoController, render
41 from rhodecode.lib.utils import EmptyChangeset
43 from rhodecode.lib.utils import EmptyChangeset
42
44 from rhodecode.lib.markup_renderer import MarkupRenderer
43 from rhodecode.lib.celerylib import run_task
45 from rhodecode.lib.celerylib import run_task
44 from rhodecode.lib.celerylib.tasks import get_commits_stats, \
46 from rhodecode.lib.celerylib.tasks import get_commits_stats, \
45 LANGUAGES_EXTENSIONS_MAP
47 LANGUAGES_EXTENSIONS_MAP
@@ -48,6 +50,9 b' from rhodecode.lib.compat import json, O'
48
50
49 log = logging.getLogger(__name__)
51 log = logging.getLogger(__name__)
50
52
53 README_FILES = [''.join([x[0][0], x[1][0]]) for x in
54 sorted(list(product(ALL_READMES, ALL_EXTS)),
55 key=lambda y:y[0][1] + y[1][1])]
51
56
52 class SummaryController(BaseRepoController):
57 class SummaryController(BaseRepoController):
53
58
@@ -161,8 +166,33 b' class SummaryController(BaseRepoControll'
161 if c.enable_downloads:
166 if c.enable_downloads:
162 c.download_options = self._get_download_links(c.rhodecode_repo)
167 c.download_options = self._get_download_links(c.rhodecode_repo)
163
168
169 c.readme_data,c.readme_file = self.__get_readme_data()
164 return render('summary/summary.html')
170 return render('summary/summary.html')
165
171
172 def __get_readme_data(self):
173 readme_data = None
174 readme_file = None
175
176 try:
177 cs = c.rhodecode_repo.get_changeset('tip')
178 renderer = MarkupRenderer()
179 for f in README_FILES:
180 try:
181 readme = cs.get_node(f)
182 readme_file = f
183 readme_data = renderer.render(readme.content, f)
184 break
185 except NodeDoesNotExistError:
186 continue
187 except ChangesetError:
188 pass
189 except EmptyRepositoryError:
190 pass
191 except Exception:
192 log.error(traceback.format_exc())
193
194 return readme_data, readme_file
195
166 def _get_download_links(self, repo):
196 def _get_download_links(self, repo):
167
197
168 download_l = []
198 download_l = []
@@ -181,3 +211,4 b' class SummaryController(BaseRepoControll'
181 download_l.append(tags_group)
211 download_l.append(tags_group)
182
212
183 return download_l
213 return download_l
214
@@ -66,6 +66,34 b" ADDITIONAL_MAPPINGS = {'xaml': 'XAML'}"
66
66
67 LANGUAGES_EXTENSIONS_MAP.update(ADDITIONAL_MAPPINGS)
67 LANGUAGES_EXTENSIONS_MAP.update(ADDITIONAL_MAPPINGS)
68
68
69 # list of readme files to search in file tree and display in summary
70 # attached weights defines the search order lower is first
71 ALL_READMES = [
72 ('readme', 0), ('README', 0), ('Readme', 0),
73 ('doc/readme', 1), ('doc/README', 1), ('doc/Readme', 1),
74 ('Docs/readme', 2), ('Docs/README', 2), ('Docs/Readme', 2),
75 ('DOCS/readme', 2), ('DOCS/README', 2), ('DOCS/Readme', 2),
76 ('docs/readme', 2), ('docs/README', 2), ('docs/Readme', 2),
77 ]
78
79 # extension together with weights to search lower is first
80 RST_EXTS = [
81 ('', 0), ('.rst', 1),('.rest', 1),
82 ('.RST', 2) ,('.REST', 2),
83 ('.txt', 3), ('.TXT', 3)
84 ]
85
86 MARKDOWN_EXTS = [
87 ('.md', 1), ('.MD', 1),
88 ('.mkdn', 2), ('.MKDN', 2),
89 ('.mdown', 3), ('.MDOWN', 3),
90 ('.markdown', 4), ('.MARKDOWN', 4)
91 ]
92
93 PLAIN_EXTS = [('.text', 2),('.TEXT', 2)]
94
95 ALL_EXTS = MARKDOWN_EXTS + RST_EXTS + PLAIN_EXTS
96
69
97
70 def str2bool(_str):
98 def str2bool(_str):
71 """
99 """
@@ -3011,4 +3011,96 b' div#legend_container table td,div#legend'
3011 border: 0px solid #545454;
3011 border: 0px solid #545454;
3012 color: #AAAAAA;
3012 color: #AAAAAA;
3013 padding-left: 3px;
3013 padding-left: 3px;
3014 } No newline at end of file
3014 }
3015
3016 /*README STYLE*/
3017
3018 div.readme {
3019 padding:0px;
3020 }
3021
3022 div.readme h2 {
3023 font-weight: normal;
3024 }
3025
3026 div.readme .readme_box {
3027 background-color: #fafafa;
3028 }
3029
3030 div.readme .readme_box {
3031 clear:both;
3032 overflow:hidden;
3033 margin:0;
3034 padding:0 20px 10px;
3035 }
3036
3037 div.readme .readme_box h1, div.readme .readme_box h2, div.readme .readme_box h3, div.readme .readme_box h4, div.readme .readme_box h5, div.readme .readme_box h6 {
3038 border-bottom: 0 !important;
3039 margin: 0 !important;
3040 padding: 0 !important;
3041 line-height: 1.5em !important;
3042 }
3043
3044
3045 div.readme .readme_box h1:first-child {
3046 padding-top: .25em !important;
3047 }
3048
3049 div.readme .readme_box h2, div.readme .readme_box h3 {
3050 margin: 1em 0 !important;
3051 }
3052
3053 div.readme .readme_box h2 {
3054 margin-top: 1.5em !important;
3055 border-top: 4px solid #e0e0e0 !important;
3056 padding-top: .5em !important;
3057 }
3058
3059 div.readme .readme_box p {
3060 color: black !important;
3061 margin: 1em 0 !important;
3062 line-height: 1.5em !important;
3063 }
3064
3065 div.readme .readme_box ul {
3066 list-style: disc !important;
3067 margin: 1em 0 1em 2em !important;
3068 }
3069
3070 div.readme .readme_box ol {
3071 list-style: decimal;
3072 margin: 1em 0 1em 2em !important;
3073 }
3074
3075 div.readme .readme_box pre, code {
3076 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
3077 }
3078
3079 div.readme .readme_box code {
3080 font-size: 12px !important;
3081 background-color: ghostWhite !important;
3082 color: #444 !important;
3083 padding: 0 .2em !important;
3084 border: 1px solid #dedede !important;
3085 }
3086
3087 div.readme .readme_box pre code {
3088 padding: 0 !important;
3089 font-size: 12px !important;
3090 background-color: #eee !important;
3091 border: none !important;
3092 }
3093
3094 div.readme .readme_box pre {
3095 margin: 1em 0;
3096 font-size: 12px;
3097 background-color: #eee;
3098 border: 1px solid #ddd;
3099 padding: 5px;
3100 color: #444;
3101 overflow: auto;
3102 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
3103 -webkit-border-radius: 3px;
3104 -moz-border-radius: 3px;
3105 border-radius: 3px;
3106 }
@@ -64,10 +64,7 b''
64 ##FORK
64 ##FORK
65 %if c.dbrepo.fork:
65 %if c.dbrepo.fork:
66 <div style="margin-top:5px;clear:both"">
66 <div style="margin-top:5px;clear:both"">
67 <a href="${h.url('summary_home',repo_name=c.dbrepo.fork.repo_name)}">
67 <a href="${h.url('summary_home',repo_name=c.dbrepo.fork.repo_name)}"><img class="icon" alt="${_('public')}" title="${_('Fork of')} ${c.dbrepo.fork.repo_name}" src="${h.url('/images/icons/arrow_divide.png')}"/>
68 <img class="icon" alt="${_('public')}"
69 title="${_('Fork of')} ${c.dbrepo.fork.repo_name}"
70 src="${h.url('/images/icons/arrow_divide.png')}"/>
71 ${_('Fork of')} ${c.dbrepo.fork.repo_name}
68 ${_('Fork of')} ${c.dbrepo.fork.repo_name}
72 </a>
69 </a>
73 </div>
70 </div>
@@ -75,10 +72,7 b''
75 ##REMOTE
72 ##REMOTE
76 %if c.dbrepo.clone_uri:
73 %if c.dbrepo.clone_uri:
77 <div style="margin-top:5px;clear:both">
74 <div style="margin-top:5px;clear:both">
78 <a href="${h.url(str(h.hide_credentials(c.dbrepo.clone_uri)))}">
75 <a href="${h.url(str(h.hide_credentials(c.dbrepo.clone_uri)))}"><img class="icon" alt="${_('remote clone')}" title="${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}" src="${h.url('/images/icons/connect.png')}"/>
79 <img class="icon" alt="${_('remote clone')}"
80 title="${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}"
81 src="${h.url('/images/icons/connect.png')}"/>
82 ${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}
76 ${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}
83 </a>
77 </a>
84 </div>
78 </div>
@@ -86,7 +80,6 b''
86 </div>
80 </div>
87 </div>
81 </div>
88
82
89
90 <div class="field">
83 <div class="field">
91 <div class="label">
84 <div class="label">
92 <label>${_('Description')}:</label>
85 <label>${_('Description')}:</label>
@@ -94,7 +87,6 b''
94 <div class="input-short desc">${h.urlify_text(c.dbrepo.description)}</div>
87 <div class="input-short desc">${h.urlify_text(c.dbrepo.description)}</div>
95 </div>
88 </div>
96
89
97
98 <div class="field">
90 <div class="field">
99 <div class="label">
91 <div class="label">
100 <label>${_('Contact')}:</label>
92 <label>${_('Contact')}:</label>
@@ -119,7 +111,6 b''
119 <span class="tooltip" title="${c.rhodecode_repo.last_change}">
111 <span class="tooltip" title="${c.rhodecode_repo.last_change}">
120 ${h.age(c.rhodecode_repo.last_change)}</span><br/>
112 ${h.age(c.rhodecode_repo.last_change)}</span><br/>
121 ${_('by')} ${h.get_changeset_safe(c.rhodecode_repo,'tip').author}
113 ${_('by')} ${h.get_changeset_safe(c.rhodecode_repo,'tip').author}
122
123 </div>
114 </div>
124 </div>
115 </div>
125
116
@@ -187,6 +178,62 b''
187 </div>
178 </div>
188 </div>
179 </div>
189 </div>
180 </div>
181 </div>
182
183 <div class="box box-right" style="min-height:455px">
184 <!-- box / title -->
185 <div class="title">
186 <h5>${_('Commit activity by day / author')}</h5>
187 </div>
188
189 <div class="graph">
190 <div style="padding:0 10px 10px 15px;font-size: 1.2em;">
191 %if c.no_data:
192 ${c.no_data_msg}
193 %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
194 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-button-small")}
195 %endif
196 %else:
197 ${_('Loaded in')} ${c.stats_percentage} %
198 %endif
199 </div>
200 <div id="commit_history" style="width:450px;height:300px;float:left"></div>
201 <div style="clear: both;height: 10px"></div>
202 <div id="overview" style="width:450px;height:100px;float:left"></div>
203
204 <div id="legend_data" style="clear:both;margin-top:10px;">
205 <div id="legend_container"></div>
206 <div id="legend_choices">
207 <table id="legend_choices_tables" class="noborder" style="font-size:smaller;color:#545454"></table>
208 </div>
209 </div>
210 </div>
211 </div>
212
213 <div class="box">
214 <div class="title">
215 <div class="breadcrumbs">${h.link_to(_('Shortlog'),h.url('shortlog_home',repo_name=c.repo_name))}</div>
216 </div>
217 <div class="table">
218 <div id="shortlog_data">
219 <%include file='../shortlog/shortlog_data.html'/>
220 </div>
221 </div>
222 </div>
223
224 %if c.readme_data:
225 <div class="box" style="background-color: #FAFAFA">
226 <div class="title">
227 <div class="breadcrumbs"><a href="${h.url('files_home',repo_name=c.repo_name,revision='tip',f_path=c.readme_file)}">${c.readme_file}</a></div>
228 </div>
229 <div class="readme">
230 <div class="readme_box">
231 ${c.readme_data|n}
232 </div>
233 </div>
234 </div>
235 %endif
236
190 <script type="text/javascript">
237 <script type="text/javascript">
191 YUE.onDOMReady(function(e){
238 YUE.onDOMReady(function(e){
192 id = 'clone_url';
239 id = 'clone_url';
@@ -304,36 +351,6 b''
304 }
351 }
305 });
352 });
306 </script>
353 </script>
307 </div>
308
309 <div class="box box-right" style="min-height:455px">
310 <!-- box / title -->
311 <div class="title">
312 <h5>${_('Commit activity by day / author')}</h5>
313 </div>
314
315 <div class="graph">
316 <div style="padding:0 10px 10px 15px;font-size: 1.2em;">
317 %if c.no_data:
318 ${c.no_data_msg}
319 %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
320 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-button-small")}
321 %endif
322
323 %else:
324 ${_('Loaded in')} ${c.stats_percentage} %
325 %endif
326 </div>
327 <div id="commit_history" style="width:450px;height:300px;float:left"></div>
328 <div style="clear: both;height: 10px"></div>
329 <div id="overview" style="width:450px;height:100px;float:left"></div>
330
331 <div id="legend_data" style="clear:both;margin-top:10px;">
332 <div id="legend_container"></div>
333 <div id="legend_choices">
334 <table id="legend_choices_tables" style="font-size:smaller;color:#545454"></table>
335 </div>
336 </div>
337 <script type="text/javascript">
354 <script type="text/javascript">
338 /**
355 /**
339 * Plots summary graph
356 * Plots summary graph
@@ -658,43 +675,4 b''
658 SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n});
675 SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n});
659 </script>
676 </script>
660
677
661 </div>
662 </div>
663
664 <div class="box">
665 <div class="title">
666 <div class="breadcrumbs">${h.link_to(_('Shortlog'),h.url('shortlog_home',repo_name=c.repo_name))}</div>
667 </div>
668 <div class="table">
669 <div id="shortlog_data">
670 <%include file='../shortlog/shortlog_data.html'/>
671 </div>
672 ##%if c.repo_changesets:
673 ## ${h.link_to(_('show more'),h.url('changelog_home',repo_name=c.repo_name))}
674 ##%endif
675 </div>
676 </div>
677 <div class="box">
678 <div class="title">
679 <div class="breadcrumbs">${h.link_to(_('Tags'),h.url('tags_home',repo_name=c.repo_name))}</div>
680 </div>
681 <div class="table">
682 <%include file='../tags/tags_data.html'/>
683 %if c.repo_changesets:
684 ${h.link_to(_('show more'),h.url('tags_home',repo_name=c.repo_name))}
685 %endif
686 </div>
687 </div>
688 <div class="box">
689 <div class="title">
690 <div class="breadcrumbs">${h.link_to(_('Branches'),h.url('branches_home',repo_name=c.repo_name))}</div>
691 </div>
692 <div class="table">
693 <%include file='../branches/branches_data.html'/>
694 %if c.repo_changesets:
695 ${h.link_to(_('show more'),h.url('branches_home',repo_name=c.repo_name))}
696 %endif
697 </div>
698 </div>
699
700 </%def>
678 </%def>
@@ -24,7 +24,9 b' requirements = ['
24 "python-dateutil>=1.5.0,<2.0.0",
24 "python-dateutil>=1.5.0,<2.0.0",
25 "dulwich>=0.8.0,<0.9.0",
25 "dulwich>=0.8.0,<0.9.0",
26 "vcs>=0.2.3.dev",
26 "vcs>=0.2.3.dev",
27 "webob==1.0.8"
27 "webob==1.0.8",
28 "markdown==2.0.3",
29 "docutils==0.8.1",
28 ]
30 ]
29
31
30 dependency_links = [
32 dependency_links = [
General Comments 0
You need to be logged in to leave comments. Login now