Show More
@@ -1,261 +1,261 b'' | |||||
1 | .. _changelog: |
|
1 | .. _changelog: | |
2 |
|
2 | |||
3 | Changelog |
|
3 | Changelog | |
4 | ========= |
|
4 | ========= | |
5 |
|
5 | |||
6 |
|
6 | |||
7 | 1.1.8 (**2011-04-XX**) |
|
7 | 1.1.8 (**2011-04-XX**) | |
8 | ====================== |
|
8 | ====================== | |
9 |
|
9 | |||
10 | news |
|
10 | news | |
11 | ---- |
|
11 | ---- | |
12 |
|
12 | |||
13 | fixes |
|
13 | fixes | |
14 | ----- |
|
14 | ----- | |
15 |
|
15 | |||
16 | - fixed #140 freeze of python dateutil library, since new version is python2.x |
|
16 | - fixed #140 freeze of python dateutil library, since new version is python2.x | |
17 | incompatible |
|
17 | incompatible | |
18 | - setup-app will check for write permission in given path |
|
18 | - setup-app will check for write permission in given path | |
19 | - cleaned up license info issue #149 |
|
19 | - cleaned up license info issue #149 | |
20 | - fixes for issues #137,#116 and #116, problems with unicode and |
|
20 | - fixes for issues #137,#116 and #116, problems with unicode and | |
21 | accented characters. |
|
21 | accented characters. | |
22 | - fixes crashes on gravatar, when passed in email as unicode |
|
22 | - fixes crashes on gravatar, when passed in email as unicode | |
23 | - fixed tooltip flickering problems |
|
23 | - fixed tooltip flickering problems | |
24 | - fixed came_from redirection on windows |
|
24 | - fixed came_from redirection on windows | |
25 | - fixed logging modules,and sql formatters |
|
25 | - fixed logging modules,and sql formatters | |
26 | - windows fixes for os.kill #133 |
|
26 | - windows fixes for os.kill #133 | |
27 | - fixes path splitting for windows issues #148 |
|
27 | - fixes path splitting for windows issues #148 | |
28 | - fixed issue #143 wrong import on migration to 1.1.X |
|
28 | - fixed issue #143 wrong import on migration to 1.1.X | |
29 |
|
29 | - fixed problems with displaying binary files, thanks to Thomas Waldmann | ||
30 |
|
30 | |||
31 | 1.1.7 (**2011-03-23**) |
|
31 | 1.1.7 (**2011-03-23**) | |
32 | ====================== |
|
32 | ====================== | |
33 |
|
33 | |||
34 | news |
|
34 | news | |
35 | ---- |
|
35 | ---- | |
36 |
|
36 | |||
37 | fixes |
|
37 | fixes | |
38 | ----- |
|
38 | ----- | |
39 |
|
39 | |||
40 | - fixed (again) #136 installation support for FreeBSD |
|
40 | - fixed (again) #136 installation support for FreeBSD | |
41 |
|
41 | |||
42 |
|
42 | |||
43 | 1.1.6 (**2011-03-21**) |
|
43 | 1.1.6 (**2011-03-21**) | |
44 | ====================== |
|
44 | ====================== | |
45 |
|
45 | |||
46 | news |
|
46 | news | |
47 | ---- |
|
47 | ---- | |
48 |
|
48 | |||
49 | fixes |
|
49 | fixes | |
50 | ----- |
|
50 | ----- | |
51 |
|
51 | |||
52 | - fixed #136 installation support for FreeBSD |
|
52 | - fixed #136 installation support for FreeBSD | |
53 | - RhodeCode will check for python version during installation |
|
53 | - RhodeCode will check for python version during installation | |
54 |
|
54 | |||
55 | 1.1.5 (**2011-03-17**) |
|
55 | 1.1.5 (**2011-03-17**) | |
56 | ====================== |
|
56 | ====================== | |
57 |
|
57 | |||
58 | news |
|
58 | news | |
59 | ---- |
|
59 | ---- | |
60 |
|
60 | |||
61 | - basic windows support, by exchanging pybcrypt into sha256 for windows only |
|
61 | - basic windows support, by exchanging pybcrypt into sha256 for windows only | |
62 | highly inspired by idea of mantis406 |
|
62 | highly inspired by idea of mantis406 | |
63 |
|
63 | |||
64 | fixes |
|
64 | fixes | |
65 | ----- |
|
65 | ----- | |
66 |
|
66 | |||
67 | - fixed sorting by author in main page |
|
67 | - fixed sorting by author in main page | |
68 | - fixed crashes with diffs on binary files |
|
68 | - fixed crashes with diffs on binary files | |
69 | - fixed #131 problem with boolean values for LDAP |
|
69 | - fixed #131 problem with boolean values for LDAP | |
70 | - fixed #122 mysql problems thanks to striker69 |
|
70 | - fixed #122 mysql problems thanks to striker69 | |
71 | - fixed problem with errors on calling raw/raw_files/annotate functions |
|
71 | - fixed problem with errors on calling raw/raw_files/annotate functions | |
72 | with unknown revisions |
|
72 | with unknown revisions | |
73 | - fixed returned rawfiles attachment names with international character |
|
73 | - fixed returned rawfiles attachment names with international character | |
74 | - cleaned out docs, big thanks to Jason Harris |
|
74 | - cleaned out docs, big thanks to Jason Harris | |
75 |
|
75 | |||
76 | 1.1.4 (**2011-02-19**) |
|
76 | 1.1.4 (**2011-02-19**) | |
77 | ====================== |
|
77 | ====================== | |
78 |
|
78 | |||
79 | news |
|
79 | news | |
80 | ---- |
|
80 | ---- | |
81 |
|
81 | |||
82 | fixes |
|
82 | fixes | |
83 | ----- |
|
83 | ----- | |
84 |
|
84 | |||
85 | - fixed formencode import problem on settings page, that caused server crash |
|
85 | - fixed formencode import problem on settings page, that caused server crash | |
86 | when that page was accessed as first after server start |
|
86 | when that page was accessed as first after server start | |
87 | - journal fixes |
|
87 | - journal fixes | |
88 | - fixed option to access repository just by entering http://server/<repo_name> |
|
88 | - fixed option to access repository just by entering http://server/<repo_name> | |
89 |
|
89 | |||
90 |
|
90 | |||
91 | 1.1.3 (**2011-02-16**) |
|
91 | 1.1.3 (**2011-02-16**) | |
92 | ====================== |
|
92 | ====================== | |
93 |
|
93 | |||
94 | news |
|
94 | news | |
95 | ---- |
|
95 | ---- | |
96 |
|
96 | |||
97 | - implemented #102 allowing the '.' character in username |
|
97 | - implemented #102 allowing the '.' character in username | |
98 | - added option to access repository just by entering http://server/<repo_name> |
|
98 | - added option to access repository just by entering http://server/<repo_name> | |
99 | - celery task ignores result for better performance |
|
99 | - celery task ignores result for better performance | |
100 |
|
100 | |||
101 | fixes |
|
101 | fixes | |
102 | ----- |
|
102 | ----- | |
103 |
|
103 | |||
104 | - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to |
|
104 | - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to | |
105 | apollo13 and Johan Walles |
|
105 | apollo13 and Johan Walles | |
106 | - small fixes in journal |
|
106 | - small fixes in journal | |
107 | - fixed problems with getting setting for celery from .ini files |
|
107 | - fixed problems with getting setting for celery from .ini files | |
108 | - registration, password reset and login boxes share the same title as main |
|
108 | - registration, password reset and login boxes share the same title as main | |
109 | application now |
|
109 | application now | |
110 | - fixed #113: to high permissions to fork repository |
|
110 | - fixed #113: to high permissions to fork repository | |
111 | - fixed problem with '[' chars in commit messages in journal |
|
111 | - fixed problem with '[' chars in commit messages in journal | |
112 | - removed issue with space inside renamed repository after deletion |
|
112 | - removed issue with space inside renamed repository after deletion | |
113 | - db transaction fixes when filesystem repository creation failed |
|
113 | - db transaction fixes when filesystem repository creation failed | |
114 | - fixed #106 relation issues on databases different than sqlite |
|
114 | - fixed #106 relation issues on databases different than sqlite | |
115 | - fixed static files paths links to use of url() method |
|
115 | - fixed static files paths links to use of url() method | |
116 |
|
116 | |||
117 | 1.1.2 (**2011-01-12**) |
|
117 | 1.1.2 (**2011-01-12**) | |
118 | ====================== |
|
118 | ====================== | |
119 |
|
119 | |||
120 | news |
|
120 | news | |
121 | ---- |
|
121 | ---- | |
122 |
|
122 | |||
123 |
|
123 | |||
124 | fixes |
|
124 | fixes | |
125 | ----- |
|
125 | ----- | |
126 |
|
126 | |||
127 | - fixes #98 protection against float division of percentage stats |
|
127 | - fixes #98 protection against float division of percentage stats | |
128 | - fixed graph bug |
|
128 | - fixed graph bug | |
129 | - forced webhelpers version since it was making troubles during installation |
|
129 | - forced webhelpers version since it was making troubles during installation | |
130 |
|
130 | |||
131 | 1.1.1 (**2011-01-06**) |
|
131 | 1.1.1 (**2011-01-06**) | |
132 | ====================== |
|
132 | ====================== | |
133 |
|
133 | |||
134 | news |
|
134 | news | |
135 | ---- |
|
135 | ---- | |
136 |
|
136 | |||
137 | - added force https option into ini files for easier https usage (no need to |
|
137 | - added force https option into ini files for easier https usage (no need to | |
138 | set server headers with this options) |
|
138 | set server headers with this options) | |
139 | - small css updates |
|
139 | - small css updates | |
140 |
|
140 | |||
141 | fixes |
|
141 | fixes | |
142 | ----- |
|
142 | ----- | |
143 |
|
143 | |||
144 | - fixed #96 redirect loop on files view on repositories without changesets |
|
144 | - fixed #96 redirect loop on files view on repositories without changesets | |
145 | - fixed #97 unicode string passed into server header in special cases (mod_wsgi) |
|
145 | - fixed #97 unicode string passed into server header in special cases (mod_wsgi) | |
146 | and server crashed with errors |
|
146 | and server crashed with errors | |
147 | - fixed large tooltips problems on main page |
|
147 | - fixed large tooltips problems on main page | |
148 | - fixed #92 whoosh indexer is more error proof |
|
148 | - fixed #92 whoosh indexer is more error proof | |
149 |
|
149 | |||
150 | 1.1.0 (**2010-12-18**) |
|
150 | 1.1.0 (**2010-12-18**) | |
151 | ====================== |
|
151 | ====================== | |
152 |
|
152 | |||
153 | news |
|
153 | news | |
154 | ---- |
|
154 | ---- | |
155 |
|
155 | |||
156 | - rewrite of internals for vcs >=0.1.10 |
|
156 | - rewrite of internals for vcs >=0.1.10 | |
157 | - uses mercurial 1.7 with dotencode disabled for maintaining compatibility |
|
157 | - uses mercurial 1.7 with dotencode disabled for maintaining compatibility | |
158 | with older clients |
|
158 | with older clients | |
159 | - anonymous access, authentication via ldap |
|
159 | - anonymous access, authentication via ldap | |
160 | - performance upgrade for cached repos list - each repository has it's own |
|
160 | - performance upgrade for cached repos list - each repository has it's own | |
161 | cache that's invalidated when needed. |
|
161 | cache that's invalidated when needed. | |
162 | - performance upgrades on repositories with large amount of commits (20K+) |
|
162 | - performance upgrades on repositories with large amount of commits (20K+) | |
163 | - main page quick filter for filtering repositories |
|
163 | - main page quick filter for filtering repositories | |
164 | - user dashboards with ability to follow chosen repositories actions |
|
164 | - user dashboards with ability to follow chosen repositories actions | |
165 | - sends email to admin on new user registration |
|
165 | - sends email to admin on new user registration | |
166 | - added cache/statistics reset options into repository settings |
|
166 | - added cache/statistics reset options into repository settings | |
167 | - more detailed action logger (based on hooks) with pushed changesets lists |
|
167 | - more detailed action logger (based on hooks) with pushed changesets lists | |
168 | and options to disable those hooks from admin panel |
|
168 | and options to disable those hooks from admin panel | |
169 | - introduced new enhanced changelog for merges that shows more accurate results |
|
169 | - introduced new enhanced changelog for merges that shows more accurate results | |
170 | - new improved and faster code stats (based on pygments lexers mapping tables, |
|
170 | - new improved and faster code stats (based on pygments lexers mapping tables, | |
171 | showing up to 10 trending sources for each repository. Additionally stats |
|
171 | showing up to 10 trending sources for each repository. Additionally stats | |
172 | can be disabled in repository settings. |
|
172 | can be disabled in repository settings. | |
173 | - gui optimizations, fixed application width to 1024px |
|
173 | - gui optimizations, fixed application width to 1024px | |
174 | - added cut off (for large files/changesets) limit into config files |
|
174 | - added cut off (for large files/changesets) limit into config files | |
175 | - whoosh, celeryd, upgrade moved to paster command |
|
175 | - whoosh, celeryd, upgrade moved to paster command | |
176 | - other than sqlite database backends can be used |
|
176 | - other than sqlite database backends can be used | |
177 |
|
177 | |||
178 | fixes |
|
178 | fixes | |
179 | ----- |
|
179 | ----- | |
180 |
|
180 | |||
181 | - fixes #61 forked repo was showing only after cache expired |
|
181 | - fixes #61 forked repo was showing only after cache expired | |
182 | - fixes #76 no confirmation on user deletes |
|
182 | - fixes #76 no confirmation on user deletes | |
183 | - fixes #66 Name field misspelled |
|
183 | - fixes #66 Name field misspelled | |
184 | - fixes #72 block user removal when he owns repositories |
|
184 | - fixes #72 block user removal when he owns repositories | |
185 | - fixes #69 added password confirmation fields |
|
185 | - fixes #69 added password confirmation fields | |
186 | - fixes #87 RhodeCode crashes occasionally on updating repository owner |
|
186 | - fixes #87 RhodeCode crashes occasionally on updating repository owner | |
187 | - fixes #82 broken annotations on files with more than 1 blank line at the end |
|
187 | - fixes #82 broken annotations on files with more than 1 blank line at the end | |
188 | - a lot of fixes and tweaks for file browser |
|
188 | - a lot of fixes and tweaks for file browser | |
189 | - fixed detached session issues |
|
189 | - fixed detached session issues | |
190 | - fixed when user had no repos he would see all repos listed in my account |
|
190 | - fixed when user had no repos he would see all repos listed in my account | |
191 | - fixed ui() instance bug when global hgrc settings was loaded for server |
|
191 | - fixed ui() instance bug when global hgrc settings was loaded for server | |
192 | instance and all hgrc options were merged with our db ui() object |
|
192 | instance and all hgrc options were merged with our db ui() object | |
193 | - numerous small bugfixes |
|
193 | - numerous small bugfixes | |
194 |
|
194 | |||
195 | (special thanks for TkSoh for detailed feedback) |
|
195 | (special thanks for TkSoh for detailed feedback) | |
196 |
|
196 | |||
197 |
|
197 | |||
198 | 1.0.2 (**2010-11-12**) |
|
198 | 1.0.2 (**2010-11-12**) | |
199 | ====================== |
|
199 | ====================== | |
200 |
|
200 | |||
201 | news |
|
201 | news | |
202 | ---- |
|
202 | ---- | |
203 |
|
203 | |||
204 | - tested under python2.7 |
|
204 | - tested under python2.7 | |
205 | - bumped sqlalchemy and celery versions |
|
205 | - bumped sqlalchemy and celery versions | |
206 |
|
206 | |||
207 | fixes |
|
207 | fixes | |
208 | ----- |
|
208 | ----- | |
209 |
|
209 | |||
210 | - fixed #59 missing graph.js |
|
210 | - fixed #59 missing graph.js | |
211 | - fixed repo_size crash when repository had broken symlinks |
|
211 | - fixed repo_size crash when repository had broken symlinks | |
212 | - fixed python2.5 crashes. |
|
212 | - fixed python2.5 crashes. | |
213 |
|
213 | |||
214 |
|
214 | |||
215 | 1.0.1 (**2010-11-10**) |
|
215 | 1.0.1 (**2010-11-10**) | |
216 | ====================== |
|
216 | ====================== | |
217 |
|
217 | |||
218 | news |
|
218 | news | |
219 | ---- |
|
219 | ---- | |
220 |
|
220 | |||
221 | - small css updated |
|
221 | - small css updated | |
222 |
|
222 | |||
223 | fixes |
|
223 | fixes | |
224 | ----- |
|
224 | ----- | |
225 |
|
225 | |||
226 | - fixed #53 python2.5 incompatible enumerate calls |
|
226 | - fixed #53 python2.5 incompatible enumerate calls | |
227 | - fixed #52 disable mercurial extension for web |
|
227 | - fixed #52 disable mercurial extension for web | |
228 | - fixed #51 deleting repositories don't delete it's dependent objects |
|
228 | - fixed #51 deleting repositories don't delete it's dependent objects | |
229 |
|
229 | |||
230 |
|
230 | |||
231 | 1.0.0 (**2010-11-02**) |
|
231 | 1.0.0 (**2010-11-02**) | |
232 | ====================== |
|
232 | ====================== | |
233 |
|
233 | |||
234 | - security bugfix simplehg wasn't checking for permissions on commands |
|
234 | - security bugfix simplehg wasn't checking for permissions on commands | |
235 | other than pull or push. |
|
235 | other than pull or push. | |
236 | - fixed doubled messages after push or pull in admin journal |
|
236 | - fixed doubled messages after push or pull in admin journal | |
237 | - templating and css corrections, fixed repo switcher on chrome, updated titles |
|
237 | - templating and css corrections, fixed repo switcher on chrome, updated titles | |
238 | - admin menu accessible from options menu on repository view |
|
238 | - admin menu accessible from options menu on repository view | |
239 | - permissions cached queries |
|
239 | - permissions cached queries | |
240 |
|
240 | |||
241 | 1.0.0rc4 (**2010-10-12**) |
|
241 | 1.0.0rc4 (**2010-10-12**) | |
242 | ========================== |
|
242 | ========================== | |
243 |
|
243 | |||
244 | - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman) |
|
244 | - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman) | |
245 | - removed cache_manager settings from sqlalchemy meta |
|
245 | - removed cache_manager settings from sqlalchemy meta | |
246 | - added sqlalchemy cache settings to ini files |
|
246 | - added sqlalchemy cache settings to ini files | |
247 | - validated password length and added second try of failure on paster setup-app |
|
247 | - validated password length and added second try of failure on paster setup-app | |
248 | - fixed setup database destroy prompt even when there was no db |
|
248 | - fixed setup database destroy prompt even when there was no db | |
249 |
|
249 | |||
250 |
|
250 | |||
251 | 1.0.0rc3 (**2010-10-11**) |
|
251 | 1.0.0rc3 (**2010-10-11**) | |
252 | ========================= |
|
252 | ========================= | |
253 |
|
253 | |||
254 | - fixed i18n during installation. |
|
254 | - fixed i18n during installation. | |
255 |
|
255 | |||
256 | 1.0.0rc2 (**2010-10-11**) |
|
256 | 1.0.0rc2 (**2010-10-11**) | |
257 | ========================= |
|
257 | ========================= | |
258 |
|
258 | |||
259 | - Disabled dirsize in file browser, it's causing nasty bug when dir renames |
|
259 | - Disabled dirsize in file browser, it's causing nasty bug when dir renames | |
260 | occure. After vcs is fixed it'll be put back again. |
|
260 | occure. After vcs is fixed it'll be put back again. | |
261 | - templating/css rewrites, optimized css. No newline at end of file |
|
261 | - templating/css rewrites, optimized css. |
@@ -1,88 +1,88 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """ | |
3 | rhodecode.controllers.feed |
|
3 | rhodecode.controllers.feed | |
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
5 |
|
5 | |||
6 | Feed controller for rhodecode |
|
6 | Feed controller for rhodecode | |
7 |
|
7 | |||
8 | :created_on: Apr 23, 2010 |
|
8 | :created_on: Apr 23, 2010 | |
9 | :author: marcink |
|
9 | :author: marcink | |
10 |
:copyright: (C) 2009-201 |
|
10 | :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com> | |
11 | :license: GPLv3, see COPYING for more details. |
|
11 | :license: GPLv3, see COPYING for more details. | |
12 | """ |
|
12 | """ | |
13 | # This program is free software: you can redistribute it and/or modify |
|
13 | # This program is free software: you can redistribute it and/or modify | |
14 | # it under the terms of the GNU General Public License as published by |
|
14 | # it under the terms of the GNU General Public License as published by | |
15 | # the Free Software Foundation, either version 3 of the License, or |
|
15 | # the Free Software Foundation, either version 3 of the License, or | |
16 | # (at your option) any later version. |
|
16 | # (at your option) any later version. | |
17 | # |
|
17 | # | |
18 | # This program is distributed in the hope that it will be useful, |
|
18 | # This program is distributed in the hope that it will be useful, | |
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 | # GNU General Public License for more details. |
|
21 | # GNU General Public License for more details. | |
22 | # |
|
22 | # | |
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 logging |
|
26 | import logging | |
27 |
|
27 | |||
28 | from pylons import url, response |
|
28 | from pylons import url, response | |
29 |
|
29 | |||
30 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator |
|
30 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator | |
31 | from rhodecode.lib.base import BaseController |
|
31 | from rhodecode.lib.base import BaseController | |
32 | from rhodecode.model.scm import ScmModel |
|
32 | from rhodecode.model.scm import ScmModel | |
33 |
|
33 | |||
34 | from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed |
|
34 | from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed | |
35 |
|
35 | |||
36 | log = logging.getLogger(__name__) |
|
36 | log = logging.getLogger(__name__) | |
37 |
|
37 | |||
38 | class FeedController(BaseController): |
|
38 | class FeedController(BaseController): | |
39 |
|
39 | |||
40 | @LoginRequired() |
|
40 | @LoginRequired() | |
41 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
41 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
42 | 'repository.admin') |
|
42 | 'repository.admin') | |
43 | def __before__(self): |
|
43 | def __before__(self): | |
44 | super(FeedController, self).__before__() |
|
44 | super(FeedController, self).__before__() | |
45 | #common values for feeds |
|
45 | #common values for feeds | |
46 | self.description = 'Changes on %s repository' |
|
46 | self.description = 'Changes on %s repository' | |
47 | self.title = "%s feed" |
|
47 | self.title = "%s feed" | |
48 | self.language = 'en-us' |
|
48 | self.language = 'en-us' | |
49 | self.ttl = "5" |
|
49 | self.ttl = "5" | |
50 | self.feed_nr = 10 |
|
50 | self.feed_nr = 10 | |
51 |
|
51 | |||
52 | def atom(self, repo_name): |
|
52 | def atom(self, repo_name): | |
53 | """Produce an atom-1.0 feed via feedgenerator module""" |
|
53 | """Produce an atom-1.0 feed via feedgenerator module""" | |
54 | feed = Atom1Feed(title=self.title % repo_name, |
|
54 | feed = Atom1Feed(title=self.title % repo_name, | |
55 | link=url('summary_home', repo_name=repo_name, qualified=True), |
|
55 | link=url('summary_home', repo_name=repo_name, qualified=True), | |
56 | description=self.description % repo_name, |
|
56 | description=self.description % repo_name, | |
57 | language=self.language, |
|
57 | language=self.language, | |
58 | ttl=self.ttl) |
|
58 | ttl=self.ttl) | |
59 |
|
59 | |||
60 | changesets = ScmModel().get_repo(repo_name) |
|
60 | changesets = ScmModel().get_repo(repo_name) | |
61 |
|
61 | |||
62 | for cs in changesets[:self.feed_nr]: |
|
62 | for cs in changesets[:self.feed_nr]: | |
63 | feed.add_item(title=cs.message, |
|
63 | feed.add_item(title=cs.message, | |
64 | link=url('changeset_home', repo_name=repo_name, |
|
64 | link=url('changeset_home', repo_name=repo_name, | |
65 | revision=cs.raw_id, qualified=True), |
|
65 | revision=cs.raw_id, qualified=True), | |
66 | description=str(cs.date)) |
|
66 | description=str(cs.date)) | |
67 |
|
67 | |||
68 | response.content_type = feed.mime_type |
|
68 | response.content_type = feed.mime_type | |
69 | return feed.writeString('utf-8') |
|
69 | return feed.writeString('utf-8') | |
70 |
|
70 | |||
71 |
|
71 | |||
72 | def rss(self, repo_name): |
|
72 | def rss(self, repo_name): | |
73 | """Produce an rss2 feed via feedgenerator module""" |
|
73 | """Produce an rss2 feed via feedgenerator module""" | |
74 | feed = Rss201rev2Feed(title=self.title % repo_name, |
|
74 | feed = Rss201rev2Feed(title=self.title % repo_name, | |
75 | link=url('summary_home', repo_name=repo_name, qualified=True), |
|
75 | link=url('summary_home', repo_name=repo_name, qualified=True), | |
76 | description=self.description % repo_name, |
|
76 | description=self.description % repo_name, | |
77 | language=self.language, |
|
77 | language=self.language, | |
78 | ttl=self.ttl) |
|
78 | ttl=self.ttl) | |
79 |
|
79 | |||
80 | changesets = ScmModel().get_repo(repo_name) |
|
80 | changesets = ScmModel().get_repo(repo_name) | |
81 | for cs in changesets[:self.feed_nr]: |
|
81 | for cs in changesets[:self.feed_nr]: | |
82 | feed.add_item(title=cs.message, |
|
82 | feed.add_item(title=cs.message, | |
83 | link=url('changeset_home', repo_name=repo_name, |
|
83 | link=url('changeset_home', repo_name=repo_name, | |
84 | revision=cs.raw_id, qualified=True), |
|
84 | revision=cs.raw_id, qualified=True), | |
85 | description=str(cs.date)) |
|
85 | description=str(cs.date)) | |
86 |
|
86 | |||
87 | response.content_type = feed.mime_type |
|
87 | response.content_type = feed.mime_type | |
88 | return feed.writeString('utf-8') |
|
88 | return feed.writeString('utf-8') |
@@ -1,277 +1,279 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """ | |
3 | rhodecode.controllers.files |
|
3 | rhodecode.controllers.files | |
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
5 |
|
5 | |||
6 | Files controller for RhodeCode |
|
6 | Files controller for RhodeCode | |
7 |
|
7 | |||
8 | :created_on: Apr 21, 2010 |
|
8 | :created_on: Apr 21, 2010 | |
9 | :author: marcink |
|
9 | :author: marcink | |
10 |
:copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com> |
|
10 | :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com> | |
11 | :license: GPLv3, see COPYING for more details. |
|
11 | :license: GPLv3, see COPYING for more details. | |
12 | """ |
|
12 | """ | |
13 | # This program is free software: you can redistribute it and/or modify |
|
13 | # This program is free software: you can redistribute it and/or modify | |
14 | # it under the terms of the GNU General Public License as published by |
|
14 | # it under the terms of the GNU General Public License as published by | |
15 | # the Free Software Foundation, either version 3 of the License, or |
|
15 | # the Free Software Foundation, either version 3 of the License, or | |
16 | # (at your option) any later version. |
|
16 | # (at your option) any later version. | |
17 | # |
|
17 | # | |
18 | # This program is distributed in the hope that it will be useful, |
|
18 | # This program is distributed in the hope that it will be useful, | |
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 | # GNU General Public License for more details. |
|
21 | # GNU General Public License for more details. | |
22 | # |
|
22 | # | |
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 | import os |
|
25 | import os | |
26 | import tempfile |
|
26 | import tempfile | |
27 | import logging |
|
27 | import logging | |
28 | import rhodecode.lib.helpers as h |
|
28 | import rhodecode.lib.helpers as h | |
29 |
|
29 | |||
30 | from mercurial import archival |
|
30 | from mercurial import archival | |
31 |
|
31 | |||
32 | from pylons import request, response, session, tmpl_context as c, url |
|
32 | from pylons import request, response, session, tmpl_context as c, url | |
33 | from pylons.i18n.translation import _ |
|
33 | from pylons.i18n.translation import _ | |
34 | from pylons.controllers.util import redirect |
|
34 | from pylons.controllers.util import redirect | |
35 |
|
35 | |||
36 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator |
|
36 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator | |
37 | from rhodecode.lib.base import BaseController, render |
|
37 | from rhodecode.lib.base import BaseController, render | |
38 | from rhodecode.lib.utils import EmptyChangeset |
|
38 | from rhodecode.lib.utils import EmptyChangeset | |
39 | from rhodecode.model.scm import ScmModel |
|
39 | from rhodecode.model.scm import ScmModel | |
40 |
|
40 | |||
41 | from vcs.exceptions import RepositoryError, ChangesetError, \ |
|
41 | from vcs.exceptions import RepositoryError, ChangesetError, \ | |
42 | ChangesetDoesNotExistError, EmptyRepositoryError |
|
42 | ChangesetDoesNotExistError, EmptyRepositoryError | |
43 | from vcs.nodes import FileNode |
|
43 | from vcs.nodes import FileNode | |
44 | from vcs.utils import diffs as differ |
|
44 | from vcs.utils import diffs as differ | |
45 |
|
45 | |||
46 | log = logging.getLogger(__name__) |
|
46 | log = logging.getLogger(__name__) | |
47 |
|
47 | |||
|
48 | ||||
48 | class FilesController(BaseController): |
|
49 | class FilesController(BaseController): | |
49 |
|
50 | |||
50 | @LoginRequired() |
|
51 | @LoginRequired() | |
51 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
52 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
52 | 'repository.admin') |
|
53 | 'repository.admin') | |
53 | def __before__(self): |
|
54 | def __before__(self): | |
54 | super(FilesController, self).__before__() |
|
55 | super(FilesController, self).__before__() | |
55 | c.cut_off_limit = self.cut_off_limit |
|
56 | c.cut_off_limit = self.cut_off_limit | |
56 |
|
57 | |||
57 | def __get_cs_or_redirect(self, rev, repo_name): |
|
58 | def __get_cs_or_redirect(self, rev, repo_name): | |
58 | """ |
|
59 | """ | |
59 | Safe way to get changeset if error occur it redirects to tip with |
|
60 | Safe way to get changeset if error occur it redirects to tip with | |
60 | proper message |
|
61 | proper message | |
61 |
|
62 | |||
62 | :param rev: revision to fetch |
|
63 | :param rev: revision to fetch | |
63 | :param repo_name: repo name to redirect after |
|
64 | :param repo_name: repo name to redirect after | |
64 | """ |
|
65 | """ | |
65 |
|
66 | |||
66 | _repo = ScmModel().get_repo(c.repo_name) |
|
67 | _repo = ScmModel().get_repo(c.repo_name) | |
67 | try: |
|
68 | try: | |
68 | return _repo.get_changeset(rev) |
|
69 | return _repo.get_changeset(rev) | |
69 | except EmptyRepositoryError, e: |
|
70 | except EmptyRepositoryError, e: | |
70 | h.flash(_('There are no files yet'), category='warning') |
|
71 | h.flash(_('There are no files yet'), category='warning') | |
71 | redirect(h.url('summary_home', repo_name=repo_name)) |
|
72 | redirect(h.url('summary_home', repo_name=repo_name)) | |
72 |
|
73 | |||
73 | except RepositoryError, e: |
|
74 | except RepositoryError, e: | |
74 | h.flash(str(e), category='warning') |
|
75 | h.flash(str(e), category='warning') | |
75 | redirect(h.url('files_home', repo_name=repo_name, revision='tip')) |
|
76 | redirect(h.url('files_home', repo_name=repo_name, revision='tip')) | |
76 |
|
77 | |||
77 | def index(self, repo_name, revision, f_path): |
|
78 | def index(self, repo_name, revision, f_path): | |
78 | cs = self.__get_cs_or_redirect(revision, repo_name) |
|
79 | cs = self.__get_cs_or_redirect(revision, repo_name) | |
79 | c.repo = ScmModel().get_repo(c.repo_name) |
|
80 | c.repo = ScmModel().get_repo(c.repo_name) | |
80 |
|
81 | |||
81 | revision = request.POST.get('at_rev', None) or revision |
|
82 | revision = request.POST.get('at_rev', None) or revision | |
82 |
|
83 | |||
83 | def get_next_rev(cur): |
|
84 | def get_next_rev(cur): | |
84 | max_rev = len(c.repo.revisions) - 1 |
|
85 | max_rev = len(c.repo.revisions) - 1 | |
85 | r = cur + 1 |
|
86 | r = cur + 1 | |
86 | if r > max_rev: |
|
87 | if r > max_rev: | |
87 | r = max_rev |
|
88 | r = max_rev | |
88 | return r |
|
89 | return r | |
89 |
|
90 | |||
90 | def get_prev_rev(cur): |
|
91 | def get_prev_rev(cur): | |
91 | r = cur - 1 |
|
92 | r = cur - 1 | |
92 | return r |
|
93 | return r | |
93 |
|
94 | |||
94 | c.f_path = f_path |
|
95 | c.f_path = f_path | |
95 | c.changeset = cs |
|
96 | c.changeset = cs | |
96 | cur_rev = c.changeset.revision |
|
97 | cur_rev = c.changeset.revision | |
97 | prev_rev = c.repo.get_changeset(get_prev_rev(cur_rev)).raw_id |
|
98 | prev_rev = c.repo.get_changeset(get_prev_rev(cur_rev)).raw_id | |
98 | next_rev = c.repo.get_changeset(get_next_rev(cur_rev)).raw_id |
|
99 | next_rev = c.repo.get_changeset(get_next_rev(cur_rev)).raw_id | |
99 |
|
100 | |||
100 | c.url_prev = url('files_home', repo_name=c.repo_name, |
|
101 | c.url_prev = url('files_home', repo_name=c.repo_name, | |
101 | revision=prev_rev, f_path=f_path) |
|
102 | revision=prev_rev, f_path=f_path) | |
102 | c.url_next = url('files_home', repo_name=c.repo_name, |
|
103 | c.url_next = url('files_home', repo_name=c.repo_name, | |
103 | revision=next_rev, f_path=f_path) |
|
104 | revision=next_rev, f_path=f_path) | |
104 |
|
105 | |||
105 | try: |
|
106 | try: | |
106 | c.files_list = c.changeset.get_node(f_path) |
|
107 | c.files_list = c.changeset.get_node(f_path) | |
107 | c.file_history = self._get_history(c.repo, c.files_list, f_path) |
|
108 | c.file_history = self._get_history(c.repo, c.files_list, f_path) | |
108 | except RepositoryError, e: |
|
109 | except RepositoryError, e: | |
109 | h.flash(str(e), category='warning') |
|
110 | h.flash(str(e), category='warning') | |
110 | redirect(h.url('files_home', repo_name=repo_name, |
|
111 | redirect(h.url('files_home', repo_name=repo_name, | |
111 | revision=revision)) |
|
112 | revision=revision)) | |
112 |
|
113 | |||
113 |
|
114 | |||
114 | return render('files/files.html') |
|
115 | return render('files/files.html') | |
115 |
|
116 | |||
116 | def rawfile(self, repo_name, revision, f_path): |
|
117 | def rawfile(self, repo_name, revision, f_path): | |
117 | cs = self.__get_cs_or_redirect(revision, repo_name) |
|
118 | cs = self.__get_cs_or_redirect(revision, repo_name) | |
118 | try: |
|
119 | try: | |
119 | file_node = cs.get_node(f_path) |
|
120 | file_node = cs.get_node(f_path) | |
120 | except RepositoryError, e: |
|
121 | except RepositoryError, e: | |
121 | h.flash(str(e), category='warning') |
|
122 | h.flash(str(e), category='warning') | |
122 | redirect(h.url('files_home', repo_name=repo_name, |
|
123 | redirect(h.url('files_home', repo_name=repo_name, | |
123 | revision=cs.raw_id)) |
|
124 | revision=cs.raw_id)) | |
124 |
|
125 | |||
125 | fname = f_path.split(os.sep)[-1].encode('utf8', 'replace') |
|
126 | fname = f_path.split(os.sep)[-1].encode('utf8', 'replace') | |
126 |
|
127 | |||
127 | response.content_disposition = 'attachment; filename=%s' % fname |
|
128 | response.content_disposition = 'attachment; filename=%s' % fname | |
128 | response.content_type = file_node.mimetype |
|
129 | response.content_type = file_node.mimetype | |
129 | return file_node.content |
|
130 | return file_node.content | |
130 |
|
131 | |||
131 | def raw(self, repo_name, revision, f_path): |
|
132 | def raw(self, repo_name, revision, f_path): | |
132 | cs = self.__get_cs_or_redirect(revision, repo_name) |
|
133 | cs = self.__get_cs_or_redirect(revision, repo_name) | |
133 | try: |
|
134 | try: | |
134 | file_node = cs.get_node(f_path) |
|
135 | file_node = cs.get_node(f_path) | |
135 | except RepositoryError, e: |
|
136 | except RepositoryError, e: | |
136 | h.flash(str(e), category='warning') |
|
137 | h.flash(str(e), category='warning') | |
137 | redirect(h.url('files_home', repo_name=repo_name, |
|
138 | redirect(h.url('files_home', repo_name=repo_name, | |
138 | revision=cs.raw_id)) |
|
139 | revision=cs.raw_id)) | |
139 |
|
140 | |||
140 | response.content_type = 'text/plain' |
|
141 | response.content_type = 'text/plain' | |
141 | return file_node.content |
|
142 | return file_node.content | |
142 |
|
143 | |||
143 | def annotate(self, repo_name, revision, f_path): |
|
144 | def annotate(self, repo_name, revision, f_path): | |
144 | cs = self.__get_cs_or_redirect(revision, repo_name) |
|
145 | cs = self.__get_cs_or_redirect(revision, repo_name) | |
145 | try: |
|
146 | try: | |
146 | c.file = cs.get_node(f_path) |
|
147 | c.file = cs.get_node(f_path) | |
147 | except RepositoryError, e: |
|
148 | except RepositoryError, e: | |
148 | h.flash(str(e), category='warning') |
|
149 | h.flash(str(e), category='warning') | |
149 | redirect(h.url('files_home', repo_name=repo_name, revision=cs.raw_id)) |
|
150 | redirect(h.url('files_home', repo_name=repo_name, revision=cs.raw_id)) | |
150 |
|
151 | |||
151 | c.file_history = self._get_history(ScmModel().get_repo(c.repo_name), c.file, f_path) |
|
152 | c.file_history = self._get_history(ScmModel().get_repo(c.repo_name), c.file, f_path) | |
152 | c.cs = cs |
|
153 | c.cs = cs | |
153 | c.f_path = f_path |
|
154 | c.f_path = f_path | |
154 |
|
155 | |||
155 | return render('files/files_annotate.html') |
|
156 | return render('files/files_annotate.html') | |
156 |
|
157 | |||
157 | def archivefile(self, repo_name, revision, fileformat): |
|
158 | def archivefile(self, repo_name, revision, fileformat): | |
158 | archive_specs = { |
|
159 | archive_specs = { | |
159 | '.tar.bz2': ('application/x-tar', 'tbz2'), |
|
160 | '.tar.bz2': ('application/x-tar', 'tbz2'), | |
160 | '.tar.gz': ('application/x-tar', 'tgz'), |
|
161 | '.tar.gz': ('application/x-tar', 'tgz'), | |
161 | '.zip': ('application/zip', 'zip'), |
|
162 | '.zip': ('application/zip', 'zip'), | |
162 | } |
|
163 | } | |
163 | if not archive_specs.has_key(fileformat): |
|
164 | if not archive_specs.has_key(fileformat): | |
164 | return 'Unknown archive type %s' % fileformat |
|
165 | return 'Unknown archive type %s' % fileformat | |
165 |
|
166 | |||
166 | def read_in_chunks(file_object, chunk_size=1024 * 40): |
|
167 | def read_in_chunks(file_object, chunk_size=1024 * 40): | |
167 | """Lazy function (generator) to read a file piece by piece. |
|
168 | """Lazy function (generator) to read a file piece by piece. | |
168 | Default chunk size: 40k.""" |
|
169 | Default chunk size: 40k.""" | |
169 | while True: |
|
170 | while True: | |
170 | data = file_object.read(chunk_size) |
|
171 | data = file_object.read(chunk_size) | |
171 | if not data: |
|
172 | if not data: | |
172 | break |
|
173 | break | |
173 | yield data |
|
174 | yield data | |
174 |
|
175 | |||
175 | archive = tempfile.TemporaryFile() |
|
176 | archive = tempfile.TemporaryFile() | |
176 | repo = ScmModel().get_repo(repo_name).repo |
|
177 | repo = ScmModel().get_repo(repo_name).repo | |
177 | fname = '%s-%s%s' % (repo_name, revision, fileformat) |
|
178 | fname = '%s-%s%s' % (repo_name, revision, fileformat) | |
178 | archival.archive(repo, archive, revision, archive_specs[fileformat][1], |
|
179 | archival.archive(repo, archive, revision, archive_specs[fileformat][1], | |
179 | prefix='%s-%s' % (repo_name, revision)) |
|
180 | prefix='%s-%s' % (repo_name, revision)) | |
180 | response.content_type = archive_specs[fileformat][0] |
|
181 | response.content_type = archive_specs[fileformat][0] | |
181 | response.content_disposition = 'attachment; filename=%s' % fname |
|
182 | response.content_disposition = 'attachment; filename=%s' % fname | |
182 | archive.seek(0) |
|
183 | archive.seek(0) | |
183 | return read_in_chunks(archive) |
|
184 | return read_in_chunks(archive) | |
184 |
|
185 | |||
185 | def diff(self, repo_name, f_path): |
|
186 | def diff(self, repo_name, f_path): | |
186 | hg_model = ScmModel() |
|
187 | hg_model = ScmModel() | |
187 | diff1 = request.GET.get('diff1') |
|
188 | diff1 = request.GET.get('diff1') | |
188 | diff2 = request.GET.get('diff2') |
|
189 | diff2 = request.GET.get('diff2') | |
189 | c.action = request.GET.get('diff') |
|
190 | c.action = request.GET.get('diff') | |
190 | c.no_changes = diff1 == diff2 |
|
191 | c.no_changes = diff1 == diff2 | |
191 | c.f_path = f_path |
|
192 | c.f_path = f_path | |
192 | c.repo = hg_model.get_repo(c.repo_name) |
|
193 | c.repo = hg_model.get_repo(c.repo_name) | |
193 |
|
194 | |||
194 | try: |
|
195 | try: | |
195 | if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]: |
|
196 | if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]: | |
196 | c.changeset_1 = c.repo.get_changeset(diff1) |
|
197 | c.changeset_1 = c.repo.get_changeset(diff1) | |
197 | node1 = c.changeset_1.get_node(f_path) |
|
198 | node1 = c.changeset_1.get_node(f_path) | |
198 | else: |
|
199 | else: | |
199 | c.changeset_1 = EmptyChangeset() |
|
200 | c.changeset_1 = EmptyChangeset() | |
200 | node1 = FileNode('.', '', changeset=c.changeset_1) |
|
201 | node1 = FileNode('.', '', changeset=c.changeset_1) | |
201 |
|
202 | |||
202 | if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]: |
|
203 | if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]: | |
203 | c.changeset_2 = c.repo.get_changeset(diff2) |
|
204 | c.changeset_2 = c.repo.get_changeset(diff2) | |
204 | node2 = c.changeset_2.get_node(f_path) |
|
205 | node2 = c.changeset_2.get_node(f_path) | |
205 | else: |
|
206 | else: | |
206 | c.changeset_2 = EmptyChangeset() |
|
207 | c.changeset_2 = EmptyChangeset() | |
207 | node2 = FileNode('.', '', changeset=c.changeset_2) |
|
208 | node2 = FileNode('.', '', changeset=c.changeset_2) | |
208 | except RepositoryError: |
|
209 | except RepositoryError: | |
209 | return redirect(url('files_home', |
|
210 | return redirect(url('files_home', | |
210 | repo_name=c.repo_name, f_path=f_path)) |
|
211 | repo_name=c.repo_name, f_path=f_path)) | |
211 |
|
212 | |||
212 | f_udiff = differ.get_udiff(node1, node2) |
|
213 | f_udiff = differ.get_udiff(node1, node2) | |
213 | diff = differ.DiffProcessor(f_udiff) |
|
214 | diff = differ.DiffProcessor(f_udiff) | |
214 |
|
215 | |||
215 | if c.action == 'download': |
|
216 | if c.action == 'download': | |
216 | diff_name = '%s_vs_%s.diff' % (diff1, diff2) |
|
217 | diff_name = '%s_vs_%s.diff' % (diff1, diff2) | |
217 | response.content_type = 'text/plain' |
|
218 | response.content_type = 'text/plain' | |
218 | response.content_disposition = 'attachment; filename=%s' \ |
|
219 | response.content_disposition = 'attachment; filename=%s' \ | |
219 | % diff_name |
|
220 | % diff_name | |
220 | if node1.is_binary or node2.is_binary: |
|
221 | if node1.is_binary or node2.is_binary: | |
221 | return _('binary file changed') |
|
222 | return _('binary file changed') | |
222 | return diff.raw_diff() |
|
223 | return diff.raw_diff() | |
223 |
|
224 | |||
224 | elif c.action == 'raw': |
|
225 | elif c.action == 'raw': | |
225 | response.content_type = 'text/plain' |
|
226 | response.content_type = 'text/plain' | |
226 | if node1.is_binary or node2.is_binary: |
|
227 | if node1.is_binary or node2.is_binary: | |
227 | return _('binary file changed') |
|
228 | return _('binary file changed') | |
228 | return diff.raw_diff() |
|
229 | return diff.raw_diff() | |
229 |
|
230 | |||
230 | elif c.action == 'diff': |
|
231 | elif c.action == 'diff': | |
231 | if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit: |
|
232 | if node1.is_binary or node2.is_binary: | |
232 | c.cur_diff = _('Diff is to big to display') |
|
|||
233 | elif node1.is_binary or node2.is_binary: |
|
|||
234 | c.cur_diff = _('Binary file') |
|
233 | c.cur_diff = _('Binary file') | |
|
234 | elif node1.size > self.cut_off_limit or \ | |||
|
235 | node2.size > self.cut_off_limit: | |||
|
236 | c.cur_diff = _('Diff is too big to display') | |||
235 | else: |
|
237 | else: | |
236 | c.cur_diff = diff.as_html() |
|
238 | c.cur_diff = diff.as_html() | |
237 | else: |
|
239 | else: | |
238 | #default option |
|
240 | #default option | |
239 | if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit: |
|
241 | if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit: | |
240 | c.cur_diff = _('Diff is to big to display') |
|
242 | c.cur_diff = _('Diff is to big to display') | |
241 | elif node1.is_binary or node2.is_binary: |
|
243 | elif node1.is_binary or node2.is_binary: | |
242 | c.cur_diff = _('Binary file') |
|
244 | c.cur_diff = _('Binary file') | |
243 | else: |
|
245 | else: | |
244 | c.cur_diff = diff.as_html() |
|
246 | c.cur_diff = diff.as_html() | |
245 |
|
247 | |||
246 | if not c.cur_diff: |
|
248 | if not c.cur_diff: | |
247 | c.no_changes = True |
|
249 | c.no_changes = True | |
248 | return render('files/file_diff.html') |
|
250 | return render('files/file_diff.html') | |
249 |
|
251 | |||
250 | def _get_history(self, repo, node, f_path): |
|
252 | def _get_history(self, repo, node, f_path): | |
251 | from vcs.nodes import NodeKind |
|
253 | from vcs.nodes import NodeKind | |
252 | if not node.kind is NodeKind.FILE: |
|
254 | if not node.kind is NodeKind.FILE: | |
253 | return [] |
|
255 | return [] | |
254 | changesets = node.history |
|
256 | changesets = node.history | |
255 | hist_l = [] |
|
257 | hist_l = [] | |
256 |
|
258 | |||
257 | changesets_group = ([], _("Changesets")) |
|
259 | changesets_group = ([], _("Changesets")) | |
258 | branches_group = ([], _("Branches")) |
|
260 | branches_group = ([], _("Branches")) | |
259 | tags_group = ([], _("Tags")) |
|
261 | tags_group = ([], _("Tags")) | |
260 |
|
262 | |||
261 | for chs in changesets: |
|
263 | for chs in changesets: | |
262 | n_desc = 'r%s:%s' % (chs.revision, chs.short_id) |
|
264 | n_desc = 'r%s:%s' % (chs.revision, chs.short_id) | |
263 | changesets_group[0].append((chs.raw_id, n_desc,)) |
|
265 | changesets_group[0].append((chs.raw_id, n_desc,)) | |
264 |
|
266 | |||
265 | hist_l.append(changesets_group) |
|
267 | hist_l.append(changesets_group) | |
266 |
|
268 | |||
267 | for name, chs in c.repository_branches.items(): |
|
269 | for name, chs in c.repository_branches.items(): | |
268 | #chs = chs.split(':')[-1] |
|
270 | #chs = chs.split(':')[-1] | |
269 | branches_group[0].append((chs, name),) |
|
271 | branches_group[0].append((chs, name),) | |
270 | hist_l.append(branches_group) |
|
272 | hist_l.append(branches_group) | |
271 |
|
273 | |||
272 | for name, chs in c.repository_tags.items(): |
|
274 | for name, chs in c.repository_tags.items(): | |
273 | #chs = chs.split(':')[-1] |
|
275 | #chs = chs.split(':')[-1] | |
274 | tags_group[0].append((chs, name),) |
|
276 | tags_group[0].append((chs, name),) | |
275 | hist_l.append(tags_group) |
|
277 | hist_l.append(tags_group) | |
276 |
|
278 | |||
277 | return hist_l |
|
279 | return hist_l |
@@ -1,64 +1,64 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """ | |
3 | rhodecode.controllers.home |
|
3 | rhodecode.controllers.home | |
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
5 |
|
5 | |||
6 | Home controller for Rhodecode |
|
6 | Home controller for Rhodecode | |
7 |
|
7 | |||
8 | :created_on: Feb 18, 2010 |
|
8 | :created_on: Feb 18, 2010 | |
9 | :author: marcink |
|
9 | :author: marcink | |
10 |
:copyright: (C) 2009-201 |
|
10 | :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com> | |
11 | :license: GPLv3, see COPYING for more details. |
|
11 | :license: GPLv3, see COPYING for more details. | |
12 | """ |
|
12 | """ | |
13 | # This program is free software: you can redistribute it and/or modify |
|
13 | # This program is free software: you can redistribute it and/or modify | |
14 | # it under the terms of the GNU General Public License as published by |
|
14 | # it under the terms of the GNU General Public License as published by | |
15 | # the Free Software Foundation, either version 3 of the License, or |
|
15 | # the Free Software Foundation, either version 3 of the License, or | |
16 | # (at your option) any later version. |
|
16 | # (at your option) any later version. | |
17 | # |
|
17 | # | |
18 | # This program is distributed in the hope that it will be useful, |
|
18 | # This program is distributed in the hope that it will be useful, | |
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 | # GNU General Public License for more details. |
|
21 | # GNU General Public License for more details. | |
22 | # |
|
22 | # | |
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 logging |
|
26 | import logging | |
27 | from operator import itemgetter |
|
27 | from operator import itemgetter | |
28 |
|
28 | |||
29 | from pylons import tmpl_context as c, request |
|
29 | from pylons import tmpl_context as c, request | |
30 |
|
30 | |||
31 | from rhodecode.lib.auth import LoginRequired |
|
31 | from rhodecode.lib.auth import LoginRequired | |
32 | from rhodecode.lib.base import BaseController, render |
|
32 | from rhodecode.lib.base import BaseController, render | |
33 | from rhodecode.model.scm import ScmModel |
|
33 | from rhodecode.model.scm import ScmModel | |
34 |
|
34 | |||
35 | log = logging.getLogger(__name__) |
|
35 | log = logging.getLogger(__name__) | |
36 |
|
36 | |||
37 | class HomeController(BaseController): |
|
37 | class HomeController(BaseController): | |
38 |
|
38 | |||
39 | @LoginRequired() |
|
39 | @LoginRequired() | |
40 | def __before__(self): |
|
40 | def __before__(self): | |
41 | super(HomeController, self).__before__() |
|
41 | super(HomeController, self).__before__() | |
42 |
|
42 | |||
43 | def index(self): |
|
43 | def index(self): | |
44 | sortables = ['name', 'description', 'last_change', 'tip', 'owner'] |
|
44 | sortables = ['name', 'description', 'last_change', 'tip', 'owner'] | |
45 | current_sort = request.GET.get('sort', 'name') |
|
45 | current_sort = request.GET.get('sort', 'name') | |
46 | current_sort_slug = current_sort.replace('-', '') |
|
46 | current_sort_slug = current_sort.replace('-', '') | |
47 |
|
47 | |||
48 | if current_sort_slug not in sortables: |
|
48 | if current_sort_slug not in sortables: | |
49 | c.sort_by = 'name' |
|
49 | c.sort_by = 'name' | |
50 | current_sort_slug = c.sort_by |
|
50 | current_sort_slug = c.sort_by | |
51 | else: |
|
51 | else: | |
52 | c.sort_by = current_sort |
|
52 | c.sort_by = current_sort | |
53 | c.sort_slug = current_sort_slug |
|
53 | c.sort_slug = current_sort_slug | |
54 | cached_repo_list = ScmModel().get_repos() |
|
54 | cached_repo_list = ScmModel().get_repos() | |
55 |
|
55 | |||
56 | sort_key = current_sort_slug + '_sort' |
|
56 | sort_key = current_sort_slug + '_sort' | |
57 | if c.sort_by.startswith('-'): |
|
57 | if c.sort_by.startswith('-'): | |
58 | c.repos_list = sorted(cached_repo_list, key=itemgetter(sort_key), |
|
58 | c.repos_list = sorted(cached_repo_list, key=itemgetter(sort_key), | |
59 | reverse=True) |
|
59 | reverse=True) | |
60 | else: |
|
60 | else: | |
61 | c.repos_list = sorted(cached_repo_list, key=itemgetter(sort_key), |
|
61 | c.repos_list = sorted(cached_repo_list, key=itemgetter(sort_key), | |
62 | reverse=False) |
|
62 | reverse=False) | |
63 |
|
63 | |||
64 | return render('/index.html') |
|
64 | return render('/index.html') |
@@ -1,374 +1,377 b'' | |||||
1 | ## -*- coding: utf-8 -*- |
|
1 | ## -*- coding: utf-8 -*- | |
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
3 | <html xmlns="http://www.w3.org/1999/xhtml"> |
|
3 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
4 | <head> |
|
4 | <head> | |
5 | <title>${next.title()}</title> |
|
5 | <title>${next.title()}</title> | |
6 | <link rel="icon" href="${h.url('/images/icons/database_gear.png')}" type="image/png" /> |
|
6 | <link rel="icon" href="${h.url('/images/icons/database_gear.png')}" type="image/png" /> | |
7 | <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> |
|
7 | <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> | |
8 | <meta name="robots" content="index, nofollow"/> |
|
8 | <meta name="robots" content="index, nofollow"/> | |
9 | <!-- stylesheets --> |
|
9 | <!-- stylesheets --> | |
10 | ${self.css()} |
|
10 | ${self.css()} | |
11 | <!-- scripts --> |
|
11 | <!-- scripts --> | |
12 | ${self.js()} |
|
12 | ${self.js()} | |
13 | </head> |
|
13 | </head> | |
14 | <body> |
|
14 | <body> | |
15 | <!-- header --> |
|
15 | <!-- header --> | |
16 | <div id="header"> |
|
16 | <div id="header"> | |
17 | <!-- user --> |
|
17 | <!-- user --> | |
18 | <ul id="logged-user"> |
|
18 | <ul id="logged-user"> | |
19 | <li class="first"> |
|
19 | <li class="first"> | |
20 | <div class="gravatar"> |
|
20 | <div class="gravatar"> | |
21 | <img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,20)}" /> |
|
21 | <img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,20)}" /> | |
22 | </div> |
|
22 | </div> | |
23 | <div class="account"> |
|
23 | <div class="account"> | |
24 | %if c.rhodecode_user.username == 'default': |
|
24 | %if c.rhodecode_user.username == 'default': | |
25 | %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')(): |
|
25 | %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')(): | |
26 | ${h.link_to('anonymous',h.url('register'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))} |
|
26 | ${h.link_to('anonymous',h.url('register'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))} | |
27 | %else: |
|
27 | %else: | |
28 | ${h.link_to('anonymous',h.url('#'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))} |
|
28 | ${h.link_to('anonymous',h.url('#'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))} | |
29 | %endif |
|
29 | %endif | |
30 |
|
30 | |||
31 | %else: |
|
31 | %else: | |
32 | ${h.link_to(c.rhodecode_user.username,h.url('admin_settings_my_account'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))} |
|
32 | ${h.link_to(c.rhodecode_user.username,h.url('admin_settings_my_account'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))} | |
33 | %endif |
|
33 | %endif | |
34 | </div> |
|
34 | </div> | |
35 | </li> |
|
35 | </li> | |
36 | <li> |
|
36 | <li> | |
37 | <a href="${h.url('home')}">${_('Home')}</a> |
|
37 | <a href="${h.url('home')}">${_('Home')}</a> | |
38 | </li> |
|
38 | </li> | |
39 | %if c.rhodecode_user.username != 'default': |
|
39 | %if c.rhodecode_user.username != 'default': | |
40 | <li> |
|
40 | <li> | |
41 | <a href="${h.url('journal')}">${_('Journal')}</a> |
|
41 | <a href="${h.url('journal')}">${_('Journal')}</a> | |
42 | ##(${c.unread_journal})</a> |
|
42 | ##(${c.unread_journal})</a> | |
43 | </li> |
|
43 | </li> | |
44 | %endif |
|
44 | %endif | |
45 | %if c.rhodecode_user.username == 'default': |
|
45 | %if c.rhodecode_user.username == 'default': | |
46 | <li class="last highlight">${h.link_to(u'Login',h.url('login_home'))}</li> |
|
46 | <li class="last highlight">${h.link_to(u'Login',h.url('login_home'))}</li> | |
47 | %else: |
|
47 | %else: | |
48 | <li class="last highlight">${h.link_to(u'Log Out',h.url('logout_home'))}</li> |
|
48 | <li class="last highlight">${h.link_to(u'Log Out',h.url('logout_home'))}</li> | |
49 | %endif |
|
49 | %endif | |
50 | </ul> |
|
50 | </ul> | |
51 | <!-- end user --> |
|
51 | <!-- end user --> | |
52 | <div id="header-inner" class="title top-left-rounded-corner top-right-rounded-corner"> |
|
52 | <div id="header-inner" class="title top-left-rounded-corner top-right-rounded-corner"> | |
53 | <!-- logo --> |
|
53 | <!-- logo --> | |
54 | <div id="logo"> |
|
54 | <div id="logo"> | |
55 | <h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1> |
|
55 | <h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1> | |
56 | </div> |
|
56 | </div> | |
57 | <!-- end logo --> |
|
57 | <!-- end logo --> | |
58 | <!-- menu --> |
|
58 | <!-- menu --> | |
59 | ${self.page_nav()} |
|
59 | ${self.page_nav()} | |
60 | <!-- quick --> |
|
60 | <!-- quick --> | |
61 | </div> |
|
61 | </div> | |
62 | </div> |
|
62 | </div> | |
63 | <!-- end header --> |
|
63 | <!-- end header --> | |
64 |
|
64 | |||
65 | <!-- CONTENT --> |
|
65 | <!-- CONTENT --> | |
66 | <div id="content"> |
|
66 | <div id="content"> | |
67 | <div class="flash_msg"> |
|
67 | <div class="flash_msg"> | |
68 | <% messages = h.flash.pop_messages() %> |
|
68 | <% messages = h.flash.pop_messages() %> | |
69 | % if messages: |
|
69 | % if messages: | |
70 | <ul id="flash-messages"> |
|
70 | <ul id="flash-messages"> | |
71 | % for message in messages: |
|
71 | % for message in messages: | |
72 | <li class="${message.category}_msg">${message}</li> |
|
72 | <li class="${message.category}_msg">${message}</li> | |
73 | % endfor |
|
73 | % endfor | |
74 | </ul> |
|
74 | </ul> | |
75 | % endif |
|
75 | % endif | |
76 | </div> |
|
76 | </div> | |
77 | <div id="main"> |
|
77 | <div id="main"> | |
78 | ${next.main()} |
|
78 | ${next.main()} | |
79 | </div> |
|
79 | </div> | |
80 | </div> |
|
80 | </div> | |
81 | <!-- END CONTENT --> |
|
81 | <!-- END CONTENT --> | |
82 |
|
82 | |||
83 | <!-- footer --> |
|
83 | <!-- footer --> | |
84 | <div id="footer"> |
|
84 | <div id="footer"> | |
85 | <div id="footer-inner" class="title bottom-left-rounded-corner bottom-right-rounded-corner"> |
|
85 | <div id="footer-inner" class="title bottom-left-rounded-corner bottom-right-rounded-corner"> | |
86 | <div> |
|
86 | <div> | |
87 | <p class="footer-link">${h.link_to(_('Submit a bug'),h.url('bugtracker'))}</p> |
|
87 | <p class="footer-link">${h.link_to(_('Submit a bug'),h.url('bugtracker'))}</p> | |
88 | <p class="footer-link-right"><a href="${h.url('rhodecode_official')}">RhodeCode</a> ${c.rhodecode_version} © 2010-2011 by Marcin Kuzminski</p> |
|
88 | <p class="footer-link-right"> | |
|
89 | <a href="${h.url('rhodecode_official')}">RhodeCode</a> | |||
|
90 | ${c.rhodecode_version} © 2010-${h.datetime.today().year} by Marcin Kuzminski | |||
|
91 | </p> | |||
89 | </div> |
|
92 | </div> | |
90 | </div> |
|
93 | </div> | |
91 | <script type="text/javascript"> |
|
94 | <script type="text/javascript"> | |
92 | function tooltip_activate(){ |
|
95 | function tooltip_activate(){ | |
93 | ${h.tooltip.activate()} |
|
96 | ${h.tooltip.activate()} | |
94 | } |
|
97 | } | |
95 | tooltip_activate(); |
|
98 | tooltip_activate(); | |
96 | </script> |
|
99 | </script> | |
97 | </div> |
|
100 | </div> | |
98 | <!-- end footer --> |
|
101 | <!-- end footer --> | |
99 | </body> |
|
102 | </body> | |
100 |
|
103 | |||
101 | </html> |
|
104 | </html> | |
102 |
|
105 | |||
103 | ### MAKO DEFS ### |
|
106 | ### MAKO DEFS ### | |
104 | <%def name="page_nav()"> |
|
107 | <%def name="page_nav()"> | |
105 | ${self.menu()} |
|
108 | ${self.menu()} | |
106 | </%def> |
|
109 | </%def> | |
107 |
|
110 | |||
108 | <%def name="menu(current=None)"> |
|
111 | <%def name="menu(current=None)"> | |
109 | <% |
|
112 | <% | |
110 | def is_current(selected): |
|
113 | def is_current(selected): | |
111 | if selected == current: |
|
114 | if selected == current: | |
112 | return h.literal('class="current"') |
|
115 | return h.literal('class="current"') | |
113 | %> |
|
116 | %> | |
114 | %if current not in ['home','admin']: |
|
117 | %if current not in ['home','admin']: | |
115 | ##REGULAR MENU |
|
118 | ##REGULAR MENU | |
116 | <ul id="quick"> |
|
119 | <ul id="quick"> | |
117 | <!-- repo switcher --> |
|
120 | <!-- repo switcher --> | |
118 | <li> |
|
121 | <li> | |
119 | <a id="repo_switcher" title="${_('Switch repository')}" href="#"> |
|
122 | <a id="repo_switcher" title="${_('Switch repository')}" href="#"> | |
120 | <span class="icon"> |
|
123 | <span class="icon"> | |
121 | <img src="${h.url("/images/icons/database.png")}" alt="${_('Products')}" /> |
|
124 | <img src="${h.url("/images/icons/database.png")}" alt="${_('Products')}" /> | |
122 | </span> |
|
125 | </span> | |
123 | <span>↓</span> |
|
126 | <span>↓</span> | |
124 | </a> |
|
127 | </a> | |
125 | <ul class="repo_switcher"> |
|
128 | <ul class="repo_switcher"> | |
126 | %for repo in c.cached_repo_list: |
|
129 | %for repo in c.cached_repo_list: | |
127 |
|
130 | |||
128 | %if repo['repo'].dbrepo.private: |
|
131 | %if repo['repo'].dbrepo.private: | |
129 | <li><img src="${h.url("/images/icons/lock.png")}" alt="${_('Private repository')}" class="repo_switcher_type"/>${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="%s" % repo['repo'].dbrepo.repo_type)}</li> |
|
132 | <li><img src="${h.url("/images/icons/lock.png")}" alt="${_('Private repository')}" class="repo_switcher_type"/>${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="%s" % repo['repo'].dbrepo.repo_type)}</li> | |
130 | %else: |
|
133 | %else: | |
131 | <li><img src="${h.url("/images/icons/lock_open.png")}" alt="${_('Public repository')}" class="repo_switcher_type" />${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="%s" % repo['repo'].dbrepo.repo_type)}</li> |
|
134 | <li><img src="${h.url("/images/icons/lock_open.png")}" alt="${_('Public repository')}" class="repo_switcher_type" />${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="%s" % repo['repo'].dbrepo.repo_type)}</li> | |
132 | %endif |
|
135 | %endif | |
133 | %endfor |
|
136 | %endfor | |
134 | </ul> |
|
137 | </ul> | |
135 | </li> |
|
138 | </li> | |
136 |
|
139 | |||
137 | <li ${is_current('summary')}> |
|
140 | <li ${is_current('summary')}> | |
138 | <a title="${_('Summary')}" href="${h.url('summary_home',repo_name=c.repo_name)}"> |
|
141 | <a title="${_('Summary')}" href="${h.url('summary_home',repo_name=c.repo_name)}"> | |
139 | <span class="icon"> |
|
142 | <span class="icon"> | |
140 | <img src="${h.url("/images/icons/clipboard_16.png")}" alt="${_('Summary')}" /> |
|
143 | <img src="${h.url("/images/icons/clipboard_16.png")}" alt="${_('Summary')}" /> | |
141 | </span> |
|
144 | </span> | |
142 | <span>${_('Summary')}</span> |
|
145 | <span>${_('Summary')}</span> | |
143 | </a> |
|
146 | </a> | |
144 | </li> |
|
147 | </li> | |
145 | ##<li ${is_current('shortlog')}> |
|
148 | ##<li ${is_current('shortlog')}> | |
146 | ## <a title="${_('Shortlog')}" href="${h.url('shortlog_home',repo_name=c.repo_name)}"> |
|
149 | ## <a title="${_('Shortlog')}" href="${h.url('shortlog_home',repo_name=c.repo_name)}"> | |
147 | ## <span class="icon"> |
|
150 | ## <span class="icon"> | |
148 | ## <img src="${h.url("/images/icons/application_view_list.png")}" alt="${_('Shortlog')}" /> |
|
151 | ## <img src="${h.url("/images/icons/application_view_list.png")}" alt="${_('Shortlog')}" /> | |
149 | ## </span> |
|
152 | ## </span> | |
150 | ## <span>${_('Shortlog')}</span> |
|
153 | ## <span>${_('Shortlog')}</span> | |
151 | ## </a> |
|
154 | ## </a> | |
152 | ##</li> |
|
155 | ##</li> | |
153 | <li ${is_current('changelog')}> |
|
156 | <li ${is_current('changelog')}> | |
154 | <a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=c.repo_name)}"> |
|
157 | <a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=c.repo_name)}"> | |
155 | <span class="icon"> |
|
158 | <span class="icon"> | |
156 | <img src="${h.url("/images/icons/time.png")}" alt="${_('Changelog')}" /> |
|
159 | <img src="${h.url("/images/icons/time.png")}" alt="${_('Changelog')}" /> | |
157 | </span> |
|
160 | </span> | |
158 | <span>${_('Changelog')}</span> |
|
161 | <span>${_('Changelog')}</span> | |
159 | </a> |
|
162 | </a> | |
160 | </li> |
|
163 | </li> | |
161 |
|
164 | |||
162 | <li ${is_current('switch_to')}> |
|
165 | <li ${is_current('switch_to')}> | |
163 | <a title="${_('Switch to')}" href="#"> |
|
166 | <a title="${_('Switch to')}" href="#"> | |
164 | <span class="icon"> |
|
167 | <span class="icon"> | |
165 | <img src="${h.url("/images/icons/arrow_switch.png")}" alt="${_('Switch to')}" /> |
|
168 | <img src="${h.url("/images/icons/arrow_switch.png")}" alt="${_('Switch to')}" /> | |
166 | </span> |
|
169 | </span> | |
167 | <span>${_('Switch to')}</span> |
|
170 | <span>${_('Switch to')}</span> | |
168 | </a> |
|
171 | </a> | |
169 | <ul> |
|
172 | <ul> | |
170 | <li> |
|
173 | <li> | |
171 | ${h.link_to('%s (%s)' % (_('branches'),len(c.repository_branches.values()),),h.url('branches_home',repo_name=c.repo_name),class_='branches childs')} |
|
174 | ${h.link_to('%s (%s)' % (_('branches'),len(c.repository_branches.values()),),h.url('branches_home',repo_name=c.repo_name),class_='branches childs')} | |
172 | <ul> |
|
175 | <ul> | |
173 | %if c.repository_branches.values(): |
|
176 | %if c.repository_branches.values(): | |
174 | %for cnt,branch in enumerate(c.repository_branches.items()): |
|
177 | %for cnt,branch in enumerate(c.repository_branches.items()): | |
175 | <li>${h.link_to('%s - %s' % (branch[0],h.short_id(branch[1])),h.url('files_home',repo_name=c.repo_name,revision=branch[1]))}</li> |
|
178 | <li>${h.link_to('%s - %s' % (branch[0],h.short_id(branch[1])),h.url('files_home',repo_name=c.repo_name,revision=branch[1]))}</li> | |
176 | %endfor |
|
179 | %endfor | |
177 | %else: |
|
180 | %else: | |
178 | <li>${h.link_to(_('There are no branches yet'),'#')}</li> |
|
181 | <li>${h.link_to(_('There are no branches yet'),'#')}</li> | |
179 | %endif |
|
182 | %endif | |
180 | </ul> |
|
183 | </ul> | |
181 | </li> |
|
184 | </li> | |
182 | <li> |
|
185 | <li> | |
183 | ${h.link_to('%s (%s)' % (_('tags'),len(c.repository_tags.values()),),h.url('tags_home',repo_name=c.repo_name),class_='tags childs')} |
|
186 | ${h.link_to('%s (%s)' % (_('tags'),len(c.repository_tags.values()),),h.url('tags_home',repo_name=c.repo_name),class_='tags childs')} | |
184 | <ul> |
|
187 | <ul> | |
185 | %if c.repository_tags.values(): |
|
188 | %if c.repository_tags.values(): | |
186 | %for cnt,tag in enumerate(c.repository_tags.items()): |
|
189 | %for cnt,tag in enumerate(c.repository_tags.items()): | |
187 | <li>${h.link_to('%s - %s' % (tag[0],h.short_id(tag[1])),h.url('files_home',repo_name=c.repo_name,revision=tag[1]))}</li> |
|
190 | <li>${h.link_to('%s - %s' % (tag[0],h.short_id(tag[1])),h.url('files_home',repo_name=c.repo_name,revision=tag[1]))}</li> | |
188 | %endfor |
|
191 | %endfor | |
189 | %else: |
|
192 | %else: | |
190 | <li>${h.link_to(_('There are no tags yet'),'#')}</li> |
|
193 | <li>${h.link_to(_('There are no tags yet'),'#')}</li> | |
191 | %endif |
|
194 | %endif | |
192 | </ul> |
|
195 | </ul> | |
193 | </li> |
|
196 | </li> | |
194 | </ul> |
|
197 | </ul> | |
195 | </li> |
|
198 | </li> | |
196 | <li ${is_current('files')}> |
|
199 | <li ${is_current('files')}> | |
197 | <a title="${_('Files')}" href="${h.url('files_home',repo_name=c.repo_name)}"> |
|
200 | <a title="${_('Files')}" href="${h.url('files_home',repo_name=c.repo_name)}"> | |
198 | <span class="icon"> |
|
201 | <span class="icon"> | |
199 | <img src="${h.url("/images/icons/file.png")}" alt="${_('Files')}" /> |
|
202 | <img src="${h.url("/images/icons/file.png")}" alt="${_('Files')}" /> | |
200 | </span> |
|
203 | </span> | |
201 | <span>${_('Files')}</span> |
|
204 | <span>${_('Files')}</span> | |
202 | </a> |
|
205 | </a> | |
203 | </li> |
|
206 | </li> | |
204 |
|
207 | |||
205 | <li ${is_current('options')}> |
|
208 | <li ${is_current('options')}> | |
206 | <a title="${_('Options')}" href="#"> |
|
209 | <a title="${_('Options')}" href="#"> | |
207 | <span class="icon"> |
|
210 | <span class="icon"> | |
208 | <img src="${h.url("/images/icons/table_gear.png")}" alt="${_('Admin')}" /> |
|
211 | <img src="${h.url("/images/icons/table_gear.png")}" alt="${_('Admin')}" /> | |
209 | </span> |
|
212 | </span> | |
210 | <span>${_('Options')}</span> |
|
213 | <span>${_('Options')}</span> | |
211 | </a> |
|
214 | </a> | |
212 | <ul> |
|
215 | <ul> | |
213 | %if h.HasRepoPermissionAll('repository.admin')(c.repo_name): |
|
216 | %if h.HasRepoPermissionAll('repository.admin')(c.repo_name): | |
214 | %if h.HasPermissionAll('hg.admin')('access settings on repository'): |
|
217 | %if h.HasPermissionAll('hg.admin')('access settings on repository'): | |
215 | <li>${h.link_to(_('settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li> |
|
218 | <li>${h.link_to(_('settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li> | |
216 | %else: |
|
219 | %else: | |
217 | <li>${h.link_to(_('settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li> |
|
220 | <li>${h.link_to(_('settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li> | |
218 | %endif |
|
221 | %endif | |
219 | %endif |
|
222 | %endif | |
220 | <li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li> |
|
223 | <li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li> | |
221 | <li>${h.link_to(_('search'),h.url('search_repo',search_repo=c.repo_name),class_='search')}</li> |
|
224 | <li>${h.link_to(_('search'),h.url('search_repo',search_repo=c.repo_name),class_='search')}</li> | |
222 |
|
225 | |||
223 | %if h.HasPermissionAll('hg.admin')('access admin main page'): |
|
226 | %if h.HasPermissionAll('hg.admin')('access admin main page'): | |
224 | <li> |
|
227 | <li> | |
225 | ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')} |
|
228 | ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')} | |
226 | <%def name="admin_menu()"> |
|
229 | <%def name="admin_menu()"> | |
227 | <ul> |
|
230 | <ul> | |
228 | <li>${h.link_to(_('journal'),h.url('admin_home'),class_='journal')}</li> |
|
231 | <li>${h.link_to(_('journal'),h.url('admin_home'),class_='journal')}</li> | |
229 | <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li> |
|
232 | <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li> | |
230 | <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li> |
|
233 | <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li> | |
231 | <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li> |
|
234 | <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li> | |
232 | <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li> |
|
235 | <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li> | |
233 | <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li> |
|
236 | <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li> | |
234 | </ul> |
|
237 | </ul> | |
235 | </%def> |
|
238 | </%def> | |
236 |
|
239 | |||
237 | ${admin_menu()} |
|
240 | ${admin_menu()} | |
238 | </li> |
|
241 | </li> | |
239 | %endif |
|
242 | %endif | |
240 |
|
243 | |||
241 | </ul> |
|
244 | </ul> | |
242 | </li> |
|
245 | </li> | |
243 |
|
246 | |||
244 | <li> |
|
247 | <li> | |
245 | <a title="${_('Followers')}" href="#"> |
|
248 | <a title="${_('Followers')}" href="#"> | |
246 | <span class="icon_short"> |
|
249 | <span class="icon_short"> | |
247 | <img src="${h.url("/images/icons/heart.png")}" alt="${_('Followers')}" /> |
|
250 | <img src="${h.url("/images/icons/heart.png")}" alt="${_('Followers')}" /> | |
248 | </span> |
|
251 | </span> | |
249 | <span class="short">${c.repository_followers}</span> |
|
252 | <span class="short">${c.repository_followers}</span> | |
250 | </a> |
|
253 | </a> | |
251 | </li> |
|
254 | </li> | |
252 | <li> |
|
255 | <li> | |
253 | <a title="${_('Forks')}" href="#"> |
|
256 | <a title="${_('Forks')}" href="#"> | |
254 | <span class="icon_short"> |
|
257 | <span class="icon_short"> | |
255 | <img src="${h.url("/images/icons/arrow_divide.png")}" alt="${_('Forks')}" /> |
|
258 | <img src="${h.url("/images/icons/arrow_divide.png")}" alt="${_('Forks')}" /> | |
256 | </span> |
|
259 | </span> | |
257 | <span class="short">${c.repository_forks}</span> |
|
260 | <span class="short">${c.repository_forks}</span> | |
258 | </a> |
|
261 | </a> | |
259 | </li> |
|
262 | </li> | |
260 |
|
263 | |||
261 |
|
264 | |||
262 |
|
265 | |||
263 | </ul> |
|
266 | </ul> | |
264 | %else: |
|
267 | %else: | |
265 | ##ROOT MENU |
|
268 | ##ROOT MENU | |
266 | <ul id="quick"> |
|
269 | <ul id="quick"> | |
267 | <li> |
|
270 | <li> | |
268 | <a title="${_('Home')}" href="${h.url('home')}"> |
|
271 | <a title="${_('Home')}" href="${h.url('home')}"> | |
269 | <span class="icon"> |
|
272 | <span class="icon"> | |
270 | <img src="${h.url("/images/icons/home_16.png")}" alt="${_('Home')}" /> |
|
273 | <img src="${h.url("/images/icons/home_16.png")}" alt="${_('Home')}" /> | |
271 | </span> |
|
274 | </span> | |
272 | <span>${_('Home')}</span> |
|
275 | <span>${_('Home')}</span> | |
273 | </a> |
|
276 | </a> | |
274 | </li> |
|
277 | </li> | |
275 | %if c.rhodecode_user.username != 'default': |
|
278 | %if c.rhodecode_user.username != 'default': | |
276 | <li> |
|
279 | <li> | |
277 | <a title="${_('Journal')}" href="${h.url('journal')}"> |
|
280 | <a title="${_('Journal')}" href="${h.url('journal')}"> | |
278 | <span class="icon"> |
|
281 | <span class="icon"> | |
279 | <img src="${h.url("/images/icons/book.png")}" alt="${_('Journal')}" /> |
|
282 | <img src="${h.url("/images/icons/book.png")}" alt="${_('Journal')}" /> | |
280 | </span> |
|
283 | </span> | |
281 | <span>${_('Journal')}</span> |
|
284 | <span>${_('Journal')}</span> | |
282 | </a> |
|
285 | </a> | |
283 | </li> |
|
286 | </li> | |
284 | %endif |
|
287 | %endif | |
285 | <li> |
|
288 | <li> | |
286 | <a title="${_('Search')}" href="${h.url('search')}"> |
|
289 | <a title="${_('Search')}" href="${h.url('search')}"> | |
287 | <span class="icon"> |
|
290 | <span class="icon"> | |
288 | <img src="${h.url("/images/icons/search_16.png")}" alt="${_('Search')}" /> |
|
291 | <img src="${h.url("/images/icons/search_16.png")}" alt="${_('Search')}" /> | |
289 | </span> |
|
292 | </span> | |
290 | <span>${_('Search')}</span> |
|
293 | <span>${_('Search')}</span> | |
291 | </a> |
|
294 | </a> | |
292 | </li> |
|
295 | </li> | |
293 |
|
296 | |||
294 | %if h.HasPermissionAll('hg.admin')('access admin main page'): |
|
297 | %if h.HasPermissionAll('hg.admin')('access admin main page'): | |
295 | <li ${is_current('admin')}> |
|
298 | <li ${is_current('admin')}> | |
296 | <a title="${_('Admin')}" href="${h.url('admin_home')}"> |
|
299 | <a title="${_('Admin')}" href="${h.url('admin_home')}"> | |
297 | <span class="icon"> |
|
300 | <span class="icon"> | |
298 | <img src="${h.url("/images/icons/cog_edit.png")}" alt="${_('Admin')}" /> |
|
301 | <img src="${h.url("/images/icons/cog_edit.png")}" alt="${_('Admin')}" /> | |
299 | </span> |
|
302 | </span> | |
300 | <span>${_('Admin')}</span> |
|
303 | <span>${_('Admin')}</span> | |
301 | </a> |
|
304 | </a> | |
302 | ${admin_menu()} |
|
305 | ${admin_menu()} | |
303 | </li> |
|
306 | </li> | |
304 | %endif |
|
307 | %endif | |
305 | </ul> |
|
308 | </ul> | |
306 | %endif |
|
309 | %endif | |
307 | </%def> |
|
310 | </%def> | |
308 |
|
311 | |||
309 |
|
312 | |||
310 | <%def name="css()"> |
|
313 | <%def name="css()"> | |
311 | <link rel="stylesheet" type="text/css" href="${h.url('/css/style.css')}" media="screen" /> |
|
314 | <link rel="stylesheet" type="text/css" href="${h.url('/css/style.css')}" media="screen" /> | |
312 | <link rel="stylesheet" type="text/css" href="${h.url('/css/pygments.css')}" /> |
|
315 | <link rel="stylesheet" type="text/css" href="${h.url('/css/pygments.css')}" /> | |
313 | <link rel="stylesheet" type="text/css" href="${h.url('/css/diff.css')}" /> |
|
316 | <link rel="stylesheet" type="text/css" href="${h.url('/css/diff.css')}" /> | |
314 | </%def> |
|
317 | </%def> | |
315 |
|
318 | |||
316 | <%def name="js()"> |
|
319 | <%def name="js()"> | |
317 | ##<script type="text/javascript" src="${h.url('/js/yui/utilities/utilities.js')}"></script> |
|
320 | ##<script type="text/javascript" src="${h.url('/js/yui/utilities/utilities.js')}"></script> | |
318 | ##<script type="text/javascript" src="${h.url('/js/yui/container/container.js')}"></script> |
|
321 | ##<script type="text/javascript" src="${h.url('/js/yui/container/container.js')}"></script> | |
319 | ##<script type="text/javascript" src="${h.url('/js/yui/datasource/datasource.js')}"></script> |
|
322 | ##<script type="text/javascript" src="${h.url('/js/yui/datasource/datasource.js')}"></script> | |
320 | ##<script type="text/javascript" src="${h.url('/js/yui/autocomplete/autocomplete.js')}"></script> |
|
323 | ##<script type="text/javascript" src="${h.url('/js/yui/autocomplete/autocomplete.js')}"></script> | |
321 | ##<script type="text/javascript" src="${h.url('/js/yui/selector/selector-min.js')}"></script> |
|
324 | ##<script type="text/javascript" src="${h.url('/js/yui/selector/selector-min.js')}"></script> | |
322 |
|
325 | |||
323 | <script type="text/javascript" src="${h.url('/js/yui2a.js')}"></script> |
|
326 | <script type="text/javascript" src="${h.url('/js/yui2a.js')}"></script> | |
324 | <!--[if IE]><script language="javascript" type="text/javascript" src="${h.url('/js/excanvas.min.js')}"></script><![endif]--> |
|
327 | <!--[if IE]><script language="javascript" type="text/javascript" src="${h.url('/js/excanvas.min.js')}"></script><![endif]--> | |
325 | <script type="text/javascript" src="${h.url('/js/yui.flot.js')}"></script> |
|
328 | <script type="text/javascript" src="${h.url('/js/yui.flot.js')}"></script> | |
326 |
|
329 | |||
327 | <script type="text/javascript"> |
|
330 | <script type="text/javascript"> | |
328 | var base_url = "${h.url('toggle_following')}"; |
|
331 | var base_url = "${h.url('toggle_following')}"; | |
329 | var YUC = YAHOO.util.Connect; |
|
332 | var YUC = YAHOO.util.Connect; | |
330 | var YUD = YAHOO.util.Dom; |
|
333 | var YUD = YAHOO.util.Dom; | |
331 | var YUE = YAHOO.util.Event; |
|
334 | var YUE = YAHOO.util.Event; | |
332 |
|
335 | |||
333 | function onSuccess(target){ |
|
336 | function onSuccess(target){ | |
334 |
|
337 | |||
335 | var f = YUD.get(target.id); |
|
338 | var f = YUD.get(target.id); | |
336 | if(f.getAttribute('class')=='follow'){ |
|
339 | if(f.getAttribute('class')=='follow'){ | |
337 | f.setAttribute('class','following'); |
|
340 | f.setAttribute('class','following'); | |
338 | f.setAttribute('title',"${_('Stop following this repository')}"); |
|
341 | f.setAttribute('title',"${_('Stop following this repository')}"); | |
339 | } |
|
342 | } | |
340 | else{ |
|
343 | else{ | |
341 | f.setAttribute('class','follow'); |
|
344 | f.setAttribute('class','follow'); | |
342 | f.setAttribute('title',"${_('Start following this repository')}"); |
|
345 | f.setAttribute('title',"${_('Start following this repository')}"); | |
343 | } |
|
346 | } | |
344 | } |
|
347 | } | |
345 |
|
348 | |||
346 | function toggleFollowingUser(fallows_user_id,token){ |
|
349 | function toggleFollowingUser(fallows_user_id,token){ | |
347 | args = 'follows_user_id='+fallows_user_id; |
|
350 | args = 'follows_user_id='+fallows_user_id; | |
348 | args+= '&auth_token='+token; |
|
351 | args+= '&auth_token='+token; | |
349 | YUC.asyncRequest('POST',base_url,{ |
|
352 | YUC.asyncRequest('POST',base_url,{ | |
350 | success:function(o){ |
|
353 | success:function(o){ | |
351 | onSuccess(); |
|
354 | onSuccess(); | |
352 | } |
|
355 | } | |
353 | },args); return false; |
|
356 | },args); return false; | |
354 | } |
|
357 | } | |
355 |
|
358 | |||
356 | function toggleFollowingRepo(target,fallows_repo_id,token){ |
|
359 | function toggleFollowingRepo(target,fallows_repo_id,token){ | |
357 |
|
360 | |||
358 | args = 'follows_repo_id='+fallows_repo_id; |
|
361 | args = 'follows_repo_id='+fallows_repo_id; | |
359 | args+= '&auth_token='+token; |
|
362 | args+= '&auth_token='+token; | |
360 | YUC.asyncRequest('POST',base_url,{ |
|
363 | YUC.asyncRequest('POST',base_url,{ | |
361 | success:function(o){ |
|
364 | success:function(o){ | |
362 | onSuccess(target); |
|
365 | onSuccess(target); | |
363 | } |
|
366 | } | |
364 | },args); return false; |
|
367 | },args); return false; | |
365 | } |
|
368 | } | |
366 | </script> |
|
369 | </script> | |
367 |
|
370 | |||
368 | </%def> |
|
371 | </%def> | |
369 |
|
372 | |||
370 | <%def name="breadcrumbs()"> |
|
373 | <%def name="breadcrumbs()"> | |
371 | <div class="breadcrumbs"> |
|
374 | <div class="breadcrumbs"> | |
372 | ${self.breadcrumbs_links()} |
|
375 | ${self.breadcrumbs_links()} | |
373 | </div> |
|
376 | </div> | |
374 | </%def> No newline at end of file |
|
377 | </%def> |
@@ -1,123 +1,122 b'' | |||||
1 | ## -*- coding: utf-8 -*- |
|
1 | ## -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 | <%inherit file="/base/base.html"/> |
|
3 | <%inherit file="/base/base.html"/> | |
4 |
|
4 | |||
5 | <%def name="title()"> |
|
5 | <%def name="title()"> | |
6 | ${c.repo_name} ${_('Changelog')} - ${c.rhodecode_name} |
|
6 | ${c.repo_name} ${_('Changelog')} - ${c.rhodecode_name} | |
7 | </%def> |
|
7 | </%def> | |
8 |
|
8 | |||
9 | <%def name="breadcrumbs_links()"> |
|
9 | <%def name="breadcrumbs_links()"> | |
10 | ${h.link_to(u'Home',h.url('/'))} |
|
10 | ${h.link_to(u'Home',h.url('/'))} | |
11 | » |
|
11 | » | |
12 | ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} |
|
12 | ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} | |
13 | » |
|
13 | » | |
14 | ${_('Changelog')} - ${_('showing ')} ${c.size if c.size <= c.total_cs else c.total_cs} ${_('out of')} ${c.total_cs} ${_('revisions')} |
|
14 | ${_('Changelog')} - ${_('showing ')} ${c.size if c.size <= c.total_cs else c.total_cs} ${_('out of')} ${c.total_cs} ${_('revisions')} | |
15 | </%def> |
|
15 | </%def> | |
16 |
|
16 | |||
17 | <%def name="page_nav()"> |
|
17 | <%def name="page_nav()"> | |
18 | ${self.menu('changelog')} |
|
18 | ${self.menu('changelog')} | |
19 | </%def> |
|
19 | </%def> | |
20 |
|
20 | |||
21 | <%def name="main()"> |
|
21 | <%def name="main()"> | |
22 | <div class="box"> |
|
22 | <div class="box"> | |
23 | <!-- box / title --> |
|
23 | <!-- box / title --> | |
24 | <div class="title"> |
|
24 | <div class="title"> | |
25 | ${self.breadcrumbs()} |
|
25 | ${self.breadcrumbs()} | |
26 | </div> |
|
26 | </div> | |
27 | <div class="table"> |
|
27 | <div class="table"> | |
28 | % if c.pagination: |
|
28 | % if c.pagination: | |
29 | <div id="graph"> |
|
29 | <div id="graph"> | |
30 | <div id="graph_nodes"> |
|
30 | <div id="graph_nodes"> | |
31 | <canvas id="graph_canvas"></canvas> |
|
31 | <canvas id="graph_canvas"></canvas> | |
32 | </div> |
|
32 | </div> | |
33 | <div id="graph_content"> |
|
33 | <div id="graph_content"> | |
34 | <div class="container_header"> |
|
34 | <div class="container_header"> | |
35 |
|
35 | ${h.form(h.url.current(),method='get')} | ||
36 | ${h.form(h.url.current(),method='get')} |
|
36 | <div class="info_box"> | |
37 | <div class="info_box"> |
|
37 | <span>${_('Show')}:</span> | |
38 | <span>${_('Show')}:</span> |
|
38 | ${h.text('size',size=1,value=c.size)} | |
39 | ${h.text('size',size=1,value=c.size)} |
|
39 | <span>${_('revisions')}</span> | |
40 | <span>${_('revisions')}</span> |
|
40 | ${h.submit('set',_('set'))} | |
41 | ${h.submit('set',_('set'))} |
|
41 | ||
42 | </div> |
|
42 | </div> | |
43 | ${h.end_form()} |
|
43 | ${h.end_form()} | |
44 |
|
||||
45 | </div> |
|
44 | </div> | |
46 | %for cnt,cs in enumerate(c.pagination): |
|
45 | %for cnt,cs in enumerate(c.pagination): | |
47 | <div id="chg_${cnt+1}" class="container"> |
|
46 | <div id="chg_${cnt+1}" class="container"> | |
48 | <div class="left"> |
|
47 | <div class="left"> | |
49 | <div class="date">${_('commit')} ${cs.revision}: ${h.short_id(cs.raw_id)}@${cs.date}</div> |
|
48 | <div class="date">${_('commit')} ${cs.revision}: ${h.short_id(cs.raw_id)}@${cs.date}</div> | |
50 | <div class="author"> |
|
49 | <div class="author"> | |
51 | <div class="gravatar"> |
|
50 | <div class="gravatar"> | |
52 | <img alt="gravatar" src="${h.gravatar_url(h.email(cs.author),20)}"/> |
|
51 | <img alt="gravatar" src="${h.gravatar_url(h.email(cs.author),20)}"/> | |
53 | </div> |
|
52 | </div> | |
54 | <span>${h.person(cs.author)}</span><br/> |
|
53 | <span>${h.person(cs.author)}</span><br/> | |
55 | <span><a href="mailto:${h.email_or_none(cs.author)}">${h.email_or_none(cs.author)}</a></span><br/> |
|
54 | <span><a href="mailto:${h.email_or_none(cs.author)}">${h.email_or_none(cs.author)}</a></span><br/> | |
56 | </div> |
|
55 | </div> | |
57 | <div class="message">${h.link_to(h.wrap_paragraphs(cs.message),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div> |
|
56 | <div class="message">${h.link_to(h.wrap_paragraphs(cs.message),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div> | |
58 | </div> |
|
57 | </div> | |
59 | <div class="right"> |
|
58 | <div class="right"> | |
60 | <div class="changes"> |
|
59 | <div class="changes"> | |
61 | <span class="removed tooltip" title="${_('removed')}${h.literal(h.changed_tooltip(cs.removed))}">${len(cs.removed)}</span> |
|
60 | <span class="removed tooltip" title="${_('removed')}${h.literal(h.changed_tooltip(cs.removed))}">${len(cs.removed)}</span> | |
62 | <span class="changed tooltip" title="${_('changed')}${h.literal(h.changed_tooltip(cs.changed))}">${len(cs.changed)}</span> |
|
61 | <span class="changed tooltip" title="${_('changed')}${h.literal(h.changed_tooltip(cs.changed))}">${len(cs.changed)}</span> | |
63 | <span class="added tooltip" title="${_('added')}${h.literal(h.changed_tooltip(cs.added))}">${len(cs.added)}</span> |
|
62 | <span class="added tooltip" title="${_('added')}${h.literal(h.changed_tooltip(cs.added))}">${len(cs.added)}</span> | |
64 | </div> |
|
63 | </div> | |
65 | %if len(cs.parents)>1: |
|
64 | %if len(cs.parents)>1: | |
66 | <div class="merge"> |
|
65 | <div class="merge"> | |
67 | ${_('merge')}<img alt="merge" src="${h.url("/images/icons/arrow_join.png")}"/> |
|
66 | ${_('merge')}<img alt="merge" src="${h.url("/images/icons/arrow_join.png")}"/> | |
68 | </div> |
|
67 | </div> | |
69 | %endif |
|
68 | %endif | |
70 | %if cs.parents: |
|
69 | %if cs.parents: | |
71 | %for p_cs in reversed(cs.parents): |
|
70 | %for p_cs in reversed(cs.parents): | |
72 | <div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(h.short_id(p_cs.raw_id), |
|
71 | <div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(h.short_id(p_cs.raw_id), | |
73 | h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)} |
|
72 | h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)} | |
74 | </div> |
|
73 | </div> | |
75 | %endfor |
|
74 | %endfor | |
76 | %else: |
|
75 | %else: | |
77 | <div class="parent">${_('No parents')}</div> |
|
76 | <div class="parent">${_('No parents')}</div> | |
78 | %endif |
|
77 | %endif | |
79 |
|
78 | |||
80 | <span class="logtags"> |
|
79 | <span class="logtags"> | |
81 | %if cs.branch: |
|
80 | %if cs.branch: | |
82 | <span class="branchtag" title="${'%s %s' % (_('branch'),cs.branch)}"> |
|
81 | <span class="branchtag" title="${'%s %s' % (_('branch'),cs.branch)}"> | |
83 | ${h.link_to(cs.branch,h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}</span> |
|
82 | ${h.link_to(cs.branch,h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}</span> | |
84 | %endif |
|
83 | %endif | |
85 | %for tag in cs.tags: |
|
84 | %for tag in cs.tags: | |
86 | <span class="tagtag" title="${'%s %s' % (_('tag'),tag)}"> |
|
85 | <span class="tagtag" title="${'%s %s' % (_('tag'),tag)}"> | |
87 | ${h.link_to(tag,h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}</span> |
|
86 | ${h.link_to(tag,h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}</span> | |
88 | %endfor |
|
87 | %endfor | |
89 | </span> |
|
88 | </span> | |
90 | </div> |
|
89 | </div> | |
91 | </div> |
|
90 | </div> | |
92 |
|
91 | |||
93 | %endfor |
|
92 | %endfor | |
94 | <div class="pagination-wh pagination-left"> |
|
93 | <div class="pagination-wh pagination-left"> | |
95 | ${c.pagination.pager('$link_previous ~2~ $link_next')} |
|
94 | ${c.pagination.pager('$link_previous ~2~ $link_next')} | |
96 | </div> |
|
95 | </div> | |
97 | </div> |
|
96 | </div> | |
98 | </div> |
|
97 | </div> | |
99 |
|
98 | |||
100 |
<script type="text/javascript" src="${h.url( |
|
99 | <script type="text/javascript" src="${h.url('/js/graph.js')}"></script> | |
101 | <script type="text/javascript"> |
|
100 | <script type="text/javascript"> | |
102 | YAHOO.util.Event.onDOMReady(function(){ |
|
101 | YAHOO.util.Event.onDOMReady(function(){ | |
103 | function set_canvas() { |
|
102 | function set_canvas() { | |
104 | var c = document.getElementById('graph_nodes'); |
|
103 | var c = document.getElementById('graph_nodes'); | |
105 | var t = document.getElementById('graph_content'); |
|
104 | var t = document.getElementById('graph_content'); | |
106 | canvas = document.getElementById('graph_canvas'); |
|
105 | canvas = document.getElementById('graph_canvas'); | |
107 | var div_h = t.clientHeight; |
|
106 | var div_h = t.clientHeight; | |
108 | c.style.height=div_h+'px'; |
|
107 | c.style.height=div_h+'px'; | |
109 | canvas.setAttribute('height',div_h); |
|
108 | canvas.setAttribute('height',div_h); | |
110 | canvas.setAttribute('width',160); |
|
109 | canvas.setAttribute('width',160); | |
111 | }; |
|
110 | }; | |
112 | set_canvas(); |
|
111 | set_canvas(); | |
113 | var jsdata = ${c.jsdata|n}; |
|
112 | var jsdata = ${c.jsdata|n}; | |
114 | var r = new BranchRenderer(); |
|
113 | var r = new BranchRenderer(); | |
115 | r.render(jsdata); |
|
114 | r.render(jsdata); | |
116 | }); |
|
115 | }); | |
117 | </script> |
|
116 | </script> | |
118 | %else: |
|
117 | %else: | |
119 | ${_('There are no changes yet')} |
|
118 | ${_('There are no changes yet')} | |
120 | %endif |
|
119 | %endif | |
121 | </div> |
|
120 | </div> | |
122 | </div> |
|
121 | </div> | |
123 | </%def> No newline at end of file |
|
122 | </%def> |
@@ -1,124 +1,126 b'' | |||||
|
1 | ## -*- coding: utf-8 -*- | |||
|
2 | ||||
1 | <%inherit file="/base/base.html"/> |
|
3 | <%inherit file="/base/base.html"/> | |
2 |
|
4 | |||
3 | <%def name="title()"> |
|
5 | <%def name="title()"> | |
4 | ${c.repo_name} ${_('Changeset')} - r${c.changeset.revision}:${h.short_id(c.changeset.raw_id)} - ${c.rhodecode_name} |
|
6 | ${c.repo_name} ${_('Changeset')} - r${c.changeset.revision}:${h.short_id(c.changeset.raw_id)} - ${c.rhodecode_name} | |
5 | </%def> |
|
7 | </%def> | |
6 |
|
8 | |||
7 | <%def name="breadcrumbs_links()"> |
|
9 | <%def name="breadcrumbs_links()"> | |
8 | ${h.link_to(u'Home',h.url('/'))} |
|
10 | ${h.link_to(u'Home',h.url('/'))} | |
9 | » |
|
11 | » | |
10 | ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} |
|
12 | ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} | |
11 | » |
|
13 | » | |
12 | ${_('Changeset')} - r${c.changeset.revision}:${h.short_id(c.changeset.raw_id)} |
|
14 | ${_('Changeset')} - r${c.changeset.revision}:${h.short_id(c.changeset.raw_id)} | |
13 | </%def> |
|
15 | </%def> | |
14 |
|
16 | |||
15 | <%def name="page_nav()"> |
|
17 | <%def name="page_nav()"> | |
16 | ${self.menu('changelog')} |
|
18 | ${self.menu('changelog')} | |
17 | </%def> |
|
19 | </%def> | |
18 |
|
20 | |||
19 | <%def name="main()"> |
|
21 | <%def name="main()"> | |
20 | <div class="box"> |
|
22 | <div class="box"> | |
21 | <!-- box / title --> |
|
23 | <!-- box / title --> | |
22 | <div class="title"> |
|
24 | <div class="title"> | |
23 | ${self.breadcrumbs()} |
|
25 | ${self.breadcrumbs()} | |
24 | </div> |
|
26 | </div> | |
25 | <div class="table"> |
|
27 | <div class="table"> | |
26 | <div id="body" class="diffblock"> |
|
28 | <div id="body" class="diffblock"> | |
27 | <div class="code-header"> |
|
29 | <div class="code-header"> | |
28 | <div> |
|
30 | <div> | |
29 | ${_('Changeset')} - r${c.changeset.revision}:${h.short_id(c.changeset.raw_id)} |
|
31 | ${_('Changeset')} - r${c.changeset.revision}:${h.short_id(c.changeset.raw_id)} | |
30 | » <span>${h.link_to(_('raw diff'), |
|
32 | » <span>${h.link_to(_('raw diff'), | |
31 | h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='show'))}</span> |
|
33 | h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='show'))}</span> | |
32 | » <span>${h.link_to(_('download diff'), |
|
34 | » <span>${h.link_to(_('download diff'), | |
33 | h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='download'))}</span> |
|
35 | h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='download'))}</span> | |
34 | </div> |
|
36 | </div> | |
35 | </div> |
|
37 | </div> | |
36 | </div> |
|
38 | </div> | |
37 | <div id="changeset_content"> |
|
39 | <div id="changeset_content"> | |
38 | <div class="container"> |
|
40 | <div class="container"> | |
39 | <div class="left"> |
|
41 | <div class="left"> | |
40 | <div class="date">${_('commit')} ${c.changeset.revision}: ${h.short_id(c.changeset.raw_id)}@${c.changeset.date}</div> |
|
42 | <div class="date">${_('commit')} ${c.changeset.revision}: ${h.short_id(c.changeset.raw_id)}@${c.changeset.date}</div> | |
41 | <div class="author"> |
|
43 | <div class="author"> | |
42 | <div class="gravatar"> |
|
44 | <div class="gravatar"> | |
43 | <img alt="gravatar" src="${h.gravatar_url(h.email(c.changeset.author),20)}"/> |
|
45 | <img alt="gravatar" src="${h.gravatar_url(h.email(c.changeset.author),20)}"/> | |
44 | </div> |
|
46 | </div> | |
45 | <span>${h.person(c.changeset.author)}</span><br/> |
|
47 | <span>${h.person(c.changeset.author)}</span><br/> | |
46 | <span><a href="mailto:${h.email_or_none(c.changeset.author)}">${h.email_or_none(c.changeset.author)}</a></span><br/> |
|
48 | <span><a href="mailto:${h.email_or_none(c.changeset.author)}">${h.email_or_none(c.changeset.author)}</a></span><br/> | |
47 | </div> |
|
49 | </div> | |
48 | <div class="message">${h.link_to(h.wrap_paragraphs(c.changeset.message),h.url('changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id))}</div> |
|
50 | <div class="message">${h.link_to(h.wrap_paragraphs(c.changeset.message),h.url('changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id))}</div> | |
49 | </div> |
|
51 | </div> | |
50 | <div class="right"> |
|
52 | <div class="right"> | |
51 | <div class="changes"> |
|
53 | <div class="changes"> | |
52 | <span class="removed" title="${_('removed')}">${len(c.changeset.removed)}</span> |
|
54 | <span class="removed" title="${_('removed')}">${len(c.changeset.removed)}</span> | |
53 | <span class="changed" title="${_('changed')}">${len(c.changeset.changed)}</span> |
|
55 | <span class="changed" title="${_('changed')}">${len(c.changeset.changed)}</span> | |
54 | <span class="added" title="${_('added')}">${len(c.changeset.added)}</span> |
|
56 | <span class="added" title="${_('added')}">${len(c.changeset.added)}</span> | |
55 | </div> |
|
57 | </div> | |
56 | %if len(c.changeset.parents)>1: |
|
58 | %if len(c.changeset.parents)>1: | |
57 | <div class="merge"> |
|
59 | <div class="merge"> | |
58 | ${_('merge')}<img alt="merge" src="${h.url("/images/icons/arrow_join.png")}"/> |
|
60 | ${_('merge')}<img alt="merge" src="${h.url("/images/icons/arrow_join.png")}"/> | |
59 | </div> |
|
61 | </div> | |
60 | %endif |
|
62 | %endif | |
61 |
|
63 | |||
62 | %if c.changeset.parents: |
|
64 | %if c.changeset.parents: | |
63 | %for p_cs in reversed(c.changeset.parents): |
|
65 | %for p_cs in reversed(c.changeset.parents): | |
64 | <div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(h.short_id(p_cs.raw_id), |
|
66 | <div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(h.short_id(p_cs.raw_id), | |
65 | h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)} |
|
67 | h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)} | |
66 | </div> |
|
68 | </div> | |
67 | %endfor |
|
69 | %endfor | |
68 | %else: |
|
70 | %else: | |
69 | <div class="parent">${_('No parents')}</div> |
|
71 | <div class="parent">${_('No parents')}</div> | |
70 | %endif |
|
72 | %endif | |
71 | <span class="logtags"> |
|
73 | <span class="logtags"> | |
72 | <span class="branchtag" title="${'%s %s' % (_('branch'),c.changeset.branch)}"> |
|
74 | <span class="branchtag" title="${'%s %s' % (_('branch'),c.changeset.branch)}"> | |
73 | ${h.link_to(c.changeset.branch,h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id))}</span> |
|
75 | ${h.link_to(c.changeset.branch,h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id))}</span> | |
74 | %for tag in c.changeset.tags: |
|
76 | %for tag in c.changeset.tags: | |
75 | <span class="tagtag" title="${'%s %s' % (_('tag'),tag)}"> |
|
77 | <span class="tagtag" title="${'%s %s' % (_('tag'),tag)}"> | |
76 | ${h.link_to(tag,h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id))}</span> |
|
78 | ${h.link_to(tag,h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id))}</span> | |
77 | %endfor |
|
79 | %endfor | |
78 | </span> |
|
80 | </span> | |
79 | </div> |
|
81 | </div> | |
80 | </div> |
|
82 | </div> | |
81 | <span style="font-size:1.1em;font-weight: bold">${_('Files affected')}</span> |
|
83 | <span style="font-size:1.1em;font-weight: bold">${_('Files affected')}</span> | |
82 | <div class="cs_files"> |
|
84 | <div class="cs_files"> | |
83 | %for change,filenode,diff,cs1,cs2 in c.changes: |
|
85 | %for change,filenode,diff,cs1,cs2 in c.changes: | |
84 | <div class="cs_${change}">${h.link_to(filenode.path,h.url.current(anchor='CHANGE-%s'%filenode.path))}</div> |
|
86 | <div class="cs_${change}">${h.link_to(h.safe_unicode(filenode.path),h.url.current(anchor=h.repo_name_slug('CHANGE-%s' % h.safe_unicode(filenode.path))))}</div> | |
85 | %endfor |
|
87 | %endfor | |
86 | </div> |
|
88 | </div> | |
87 | </div> |
|
89 | </div> | |
88 |
|
90 | |||
89 | </div> |
|
91 | </div> | |
90 |
|
92 | |||
91 | %for change,filenode,diff,cs1,cs2 in c.changes: |
|
93 | %for change,filenode,diff,cs1,cs2 in c.changes: | |
92 | %if change !='removed': |
|
94 | %if change !='removed': | |
93 | <div style="clear:both;height:10px"></div> |
|
95 | <div style="clear:both;height:10px"></div> | |
94 | <div id="body" class="diffblock"> |
|
96 | <div id="body" class="diffblock"> | |
95 | <div id="${'CHANGE-%s'%filenode.path}" class="code-header"> |
|
97 | <div id="${h.repo_name_slug('CHANGE-%s' % h.safe_unicode(filenode.path))}" class="code-header"> | |
96 | <div class="changeset_header"> |
|
98 | <div class="changeset_header"> | |
97 | <span class="changeset_file"> |
|
99 | <span class="changeset_file"> | |
98 | ${h.link_to_if(change!='removed',filenode.path,h.url('files_home',repo_name=c.repo_name, |
|
100 | ${h.link_to_if(change!='removed',h.safe_unicode(filenode.path),h.url('files_home',repo_name=c.repo_name, | |
99 | revision=filenode.changeset.raw_id,f_path=filenode.path))} |
|
101 | revision=filenode.changeset.raw_id,f_path=h.safe_unicode(filenode.path)))} | |
100 | </span> |
|
102 | </span> | |
101 | %if 1: |
|
103 | %if 1: | |
102 | » <span>${h.link_to(_('diff'), |
|
104 | » <span>${h.link_to(_('diff'), | |
103 | h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='diff'))}</span> |
|
105 | h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='diff'))}</span> | |
104 | » <span>${h.link_to(_('raw diff'), |
|
106 | » <span>${h.link_to(_('raw diff'), | |
105 | h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='raw'))}</span> |
|
107 | h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='raw'))}</span> | |
106 | » <span>${h.link_to(_('download diff'), |
|
108 | » <span>${h.link_to(_('download diff'), | |
107 | h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='download'))}</span> |
|
109 | h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='download'))}</span> | |
108 | %endif |
|
110 | %endif | |
109 | </div> |
|
111 | </div> | |
110 | </div> |
|
112 | </div> | |
111 | <div class="code-body"> |
|
113 | <div class="code-body"> | |
112 | %if diff: |
|
114 | %if diff: | |
113 | ${diff|n} |
|
115 | ${diff|n} | |
114 | %else: |
|
116 | %else: | |
115 | ${_('No changes in this file')} |
|
117 | ${_('No changes in this file')} | |
116 | %endif |
|
118 | %endif | |
117 | </div> |
|
119 | </div> | |
118 | </div> |
|
120 | </div> | |
119 | %endif |
|
121 | %endif | |
120 | %endfor |
|
122 | %endfor | |
121 | </div> |
|
123 | </div> | |
122 | </div> |
|
124 | </div> | |
123 |
|
125 | |||
124 | </%def> No newline at end of file |
|
126 | </%def> |
@@ -1,87 +1,91 b'' | |||||
1 | <%inherit file="/base/base.html"/> |
|
1 | <%inherit file="/base/base.html"/> | |
2 |
|
2 | |||
3 | <%def name="title()"> |
|
3 | <%def name="title()"> | |
4 | ${c.repo_name} ${_('File annotate')} - ${c.rhodecode_name} |
|
4 | ${c.repo_name} ${_('File annotate')} - ${c.rhodecode_name} | |
5 | </%def> |
|
5 | </%def> | |
6 |
|
6 | |||
7 | <%def name="breadcrumbs_links()"> |
|
7 | <%def name="breadcrumbs_links()"> | |
8 | ${h.link_to(u'Home',h.url('/'))} |
|
8 | ${h.link_to(u'Home',h.url('/'))} | |
9 | » |
|
9 | » | |
10 | ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} |
|
10 | ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} | |
11 | » |
|
11 | » | |
12 | ${_('annotate')} @ R${c.cs.revision}:${h.short_id(c.cs.raw_id)} |
|
12 | ${_('annotate')} @ R${c.cs.revision}:${h.short_id(c.cs.raw_id)} | |
13 | </%def> |
|
13 | </%def> | |
14 |
|
14 | |||
15 | <%def name="page_nav()"> |
|
15 | <%def name="page_nav()"> | |
16 | ${self.menu('files')} |
|
16 | ${self.menu('files')} | |
17 | </%def> |
|
17 | </%def> | |
18 | <%def name="main()"> |
|
18 | <%def name="main()"> | |
19 | <div class="box"> |
|
19 | <div class="box"> | |
20 | <!-- box / title --> |
|
20 | <!-- box / title --> | |
21 | <div class="title"> |
|
21 | <div class="title"> | |
22 | ${self.breadcrumbs()} |
|
22 | ${self.breadcrumbs()} | |
23 | <ul class="links"> |
|
23 | <ul class="links"> | |
24 | <li> |
|
24 | <li> | |
25 | <span style="text-transform: uppercase;"><a href="#">${_('branch')}: ${c.cs.branch}</a></span> |
|
25 | <span style="text-transform: uppercase;"><a href="#">${_('branch')}: ${c.cs.branch}</a></span> | |
26 | </li> |
|
26 | </li> | |
27 | </ul> |
|
27 | </ul> | |
28 | </div> |
|
28 | </div> | |
29 | <div class="table"> |
|
29 | <div class="table"> | |
30 | <div id="files_data"> |
|
30 | <div id="files_data"> | |
31 | <h3 class="files_location">${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cs.revision,c.file.path)}</h3> |
|
31 | <h3 class="files_location">${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cs.revision,c.file.path)}</h3> | |
32 | <dl class="overview"> |
|
32 | <dl class="overview"> | |
33 | <dt>${_('Revision')}</dt> |
|
33 | <dt>${_('Revision')}</dt> | |
34 | <dd>${h.link_to("r%s:%s" % (c.file.last_changeset.revision,h.short_id(c.file.last_changeset.raw_id)), |
|
34 | <dd>${h.link_to("r%s:%s" % (c.file.last_changeset.revision,h.short_id(c.file.last_changeset.raw_id)), | |
35 | h.url('changeset_home',repo_name=c.repo_name,revision=c.file.last_changeset.raw_id))} </dd> |
|
35 | h.url('changeset_home',repo_name=c.repo_name,revision=c.file.last_changeset.raw_id))} </dd> | |
36 | <dt>${_('Size')}</dt> |
|
36 | <dt>${_('Size')}</dt> | |
37 | <dd>${h.format_byte_size(c.file.size,binary=True)}</dd> |
|
37 | <dd>${h.format_byte_size(c.file.size,binary=True)}</dd> | |
38 | <dt>${_('Mimetype')}</dt> |
|
38 | <dt>${_('Mimetype')}</dt> | |
39 | <dd>${c.file.mimetype}</dd> |
|
39 | <dd>${c.file.mimetype}</dd> | |
40 | <dt>${_('Options')}</dt> |
|
40 | <dt>${_('Options')}</dt> | |
41 | <dd>${h.link_to(_('show source'), |
|
41 | <dd>${h.link_to(_('show source'), | |
42 | h.url('files_home',repo_name=c.repo_name,revision=c.cs.raw_id,f_path=c.f_path))} |
|
42 | h.url('files_home',repo_name=c.repo_name,revision=c.cs.raw_id,f_path=c.f_path))} | |
43 | / ${h.link_to(_('show as raw'), |
|
43 | / ${h.link_to(_('show as raw'), | |
44 | h.url('files_raw_home',repo_name=c.repo_name,revision=c.cs.raw_id,f_path=c.f_path))} |
|
44 | h.url('files_raw_home',repo_name=c.repo_name,revision=c.cs.raw_id,f_path=c.f_path))} | |
45 | / ${h.link_to(_('download as raw'), |
|
45 | / ${h.link_to(_('download as raw'), | |
46 | h.url('files_rawfile_home',repo_name=c.repo_name,revision=c.cs.raw_id,f_path=c.f_path))} |
|
46 | h.url('files_rawfile_home',repo_name=c.repo_name,revision=c.cs.raw_id,f_path=c.f_path))} | |
47 | </dd> |
|
47 | </dd> | |
48 | <dt>${_('History')}</dt> |
|
48 | <dt>${_('History')}</dt> | |
49 | <dd> |
|
49 | <dd> | |
50 | <div> |
|
50 | <div> | |
51 | ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')} |
|
51 | ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')} | |
52 | ${h.hidden('diff2',c.file.last_changeset.raw_id)} |
|
52 | ${h.hidden('diff2',c.file.last_changeset.raw_id)} | |
53 | ${h.select('diff1',c.file.last_changeset.raw_id,c.file_history)} |
|
53 | ${h.select('diff1',c.file.last_changeset.raw_id,c.file_history)} | |
54 |
${h.submit('diff','diff to revision',class_="ui-button |
|
54 | ${h.submit('diff','diff to revision',class_="ui-button")} | |
55 |
${h.submit('show_rev','show at revision',class_="ui-button |
|
55 | ${h.submit('show_rev','show at revision',class_="ui-button")} | |
56 | ${h.end_form()} |
|
56 | ${h.end_form()} | |
57 | </div> |
|
57 | </div> | |
58 | </dd> |
|
58 | </dd> | |
59 | </dl> |
|
59 | </dl> | |
60 | <div id="body" class="codeblock"> |
|
60 | <div id="body" class="codeblock"> | |
61 | <div class="code-header"> |
|
61 | <div class="code-header"> | |
62 | <div class="revision">${c.file.name}@r${c.file.last_changeset.revision}:${h.short_id(c.file.last_changeset.raw_id)}</div> |
|
62 | <div class="revision">${c.file.name}@r${c.file.last_changeset.revision}:${h.short_id(c.file.last_changeset.raw_id)}</div> | |
63 | <div class="commit">"${c.file.message}"</div> |
|
63 | <div class="commit">"${c.file.message}"</div> | |
64 | </div> |
|
64 | </div> | |
65 | <div class="code-body"> |
|
65 | <div class="code-body"> | |
|
66 | %if c.file.is_binary: | |||
|
67 | ${_('Binary file')} | |||
|
68 | %else: | |||
66 | % if c.file.size < c.cut_off_limit: |
|
69 | % if c.file.size < c.cut_off_limit: | |
67 |
${h.pygmentize_annotation(c.file,linenos=True,anchorlinenos=True,lineanchors=' |
|
70 | ${h.pygmentize_annotation(c.file,linenos=True,anchorlinenos=True,lineanchors='L',cssclass="code-highlight")} | |
68 | %else: |
|
71 | %else: | |
69 | ${_('File is to big to display')} ${h.link_to(_('show as raw'), |
|
72 | ${_('File is to big to display')} ${h.link_to(_('show as raw'), | |
70 | h.url('files_raw_home',repo_name=c.repo_name,revision=c.cs.revision,f_path=c.f_path))} |
|
73 | h.url('files_raw_home',repo_name=c.repo_name,revision=c.cs.revision,f_path=c.f_path))} | |
71 |
%endif |
|
74 | %endif | |
|
75 | <script type="text/javascript"> | |||
|
76 | YAHOO.util.Event.onDOMReady(function(){ | |||
|
77 | YAHOO.util.Event.addListener('show_rev','click',function(e){ | |||
|
78 | YAHOO.util.Event.preventDefault(e); | |||
|
79 | var cs = YAHOO.util.Dom.get('diff1').value; | |||
|
80 | var url = "${h.url('files_annotate_home',repo_name=c.repo_name,revision='__CS__',f_path=c.f_path)}".replace('__CS__',cs); | |||
|
81 | window.location = url; | |||
|
82 | }); | |||
|
83 | }); | |||
|
84 | </script> | |||
|
85 | %endif | |||
72 | </div> |
|
86 | </div> | |
73 | </div> |
|
87 | </div> | |
74 | <script type="text/javascript"> |
|
|||
75 | YAHOO.util.Event.onDOMReady(function(){ |
|
|||
76 | YAHOO.util.Event.addListener('show_rev','click',function(e){ |
|
|||
77 | YAHOO.util.Event.preventDefault(e); |
|
|||
78 | var cs = YAHOO.util.Dom.get('diff1').value; |
|
|||
79 | var url = "${h.url('files_annotate_home',repo_name=c.repo_name,revision='__CS__',f_path=c.f_path)}".replace('__CS__',cs); |
|
|||
80 | window.location = url; |
|
|||
81 | }); |
|
|||
82 | }); |
|
|||
83 | </script> |
|
|||
84 | </div> |
|
88 | </div> | |
85 | </div> |
|
89 | </div> | |
86 | </div> |
|
90 | </div> | |
87 | </%def> No newline at end of file |
|
91 | </%def> |
@@ -1,85 +1,85 b'' | |||||
1 | <%def name="file_class(node)"> |
|
1 | <%def name="file_class(node)"> | |
2 | %if node.is_file(): |
|
2 | %if node.is_file(): | |
3 | <%return "browser-file" %> |
|
3 | <%return "browser-file" %> | |
4 | %else: |
|
4 | %else: | |
5 | <%return "browser-dir"%> |
|
5 | <%return "browser-dir"%> | |
6 | %endif |
|
6 | %endif | |
7 | </%def> |
|
7 | </%def> | |
8 | <div id="body" class="browserblock"> |
|
8 | <div id="body" class="browserblock"> | |
9 | <div class="browser-header"> |
|
9 | <div class="browser-header"> | |
10 | ${h.form(h.url.current())} |
|
10 | ${h.form(h.url.current())} | |
11 | <div class="info_box"> |
|
11 | <div class="info_box"> | |
12 | <span >${_('view')}@rev</span> |
|
12 | <span >${_('view')}@rev</span> | |
13 | <a href="${c.url_prev}" title="${_('previous revision')}">«</a> |
|
13 | <a href="${c.url_prev}" title="${_('previous revision')}">«</a> | |
14 | ${h.text('at_rev',value=c.changeset.revision,size=3)} |
|
14 | ${h.text('at_rev',value=c.changeset.revision,size=3)} | |
15 | <a href="${c.url_next}" title="${_('next revision')}">»</a> |
|
15 | <a href="${c.url_next}" title="${_('next revision')}">»</a> | |
16 | ${h.submit('view','view')} |
|
16 | ${h.submit('view','view')} | |
17 | </div> |
|
17 | </div> | |
18 | ${h.end_form()} |
|
18 | ${h.end_form()} | |
19 | </div> |
|
19 | </div> | |
20 | <div class="browser-branch"> |
|
20 | <div class="browser-branch"> | |
21 | </div> |
|
21 | </div> | |
22 | <div style="clear:both"></div> |
|
22 | <div style="clear:both"></div> | |
23 | <div class="browser-body"> |
|
23 | <div class="browser-body"> | |
24 | <table class="code-browser"> |
|
24 | <table class="code-browser"> | |
25 | <thead> |
|
25 | <thead> | |
26 | <tr> |
|
26 | <tr> | |
27 | <th>${_('Name')}</th> |
|
27 | <th>${_('Name')}</th> | |
28 | <th>${_('Size')}</th> |
|
28 | <th>${_('Size')}</th> | |
29 | <th>${_('Mimetype')}</th> |
|
29 | <th>${_('Mimetype')}</th> | |
30 | <th>${_('Revision')}</th> |
|
30 | <th>${_('Revision')}</th> | |
31 | <th>${_('Last modified')}</th> |
|
31 | <th>${_('Last modified')}</th> | |
32 | <th>${_('Last commiter')}</th> |
|
32 | <th>${_('Last commiter')}</th> | |
33 | </tr> |
|
33 | </tr> | |
34 | </thead> |
|
34 | </thead> | |
35 |
|
35 | |||
36 | %if c.files_list.parent: |
|
36 | %if c.files_list.parent: | |
37 | <tr class="parity0"> |
|
37 | <tr class="parity0"> | |
38 | <td> |
|
38 | <td> | |
39 | ${h.link_to('..',h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.files_list.parent.path),class_="browser-dir")} |
|
39 | ${h.link_to('..',h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.files_list.parent.path),class_="browser-dir")} | |
40 | </td> |
|
40 | </td> | |
41 | <td></td> |
|
41 | <td></td> | |
42 | <td></td> |
|
42 | <td></td> | |
43 | <td></td> |
|
43 | <td></td> | |
44 | <td></td> |
|
44 | <td></td> | |
45 | <td></td> |
|
45 | <td></td> | |
46 | </tr> |
|
46 | </tr> | |
47 | %endif |
|
47 | %endif | |
48 |
|
48 | |||
49 | %for cnt,node in enumerate(c.files_list): |
|
49 | %for cnt,node in enumerate(c.files_list): | |
50 | <tr class="parity${cnt%2}"> |
|
50 | <tr class="parity${cnt%2}"> | |
51 | <td> |
|
51 | <td> | |
52 | ${h.link_to(node.name,h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=node.path),class_=file_class(node))} |
|
52 | ${h.link_to(node.name,h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=h.safe_unicode(node.path)),class_=file_class(node))} | |
53 | </td> |
|
53 | </td> | |
54 | <td> |
|
54 | <td> | |
55 | %if node.is_file(): |
|
55 | %if node.is_file(): | |
56 | ${h.format_byte_size(node.size,binary=True)} |
|
56 | ${h.format_byte_size(node.size,binary=True)} | |
57 | %endif |
|
57 | %endif | |
58 | </td> |
|
58 | </td> | |
59 | <td> |
|
59 | <td> | |
60 | %if node.is_file(): |
|
60 | %if node.is_file(): | |
61 | ${node.mimetype} |
|
61 | ${node.mimetype} | |
62 | %endif |
|
62 | %endif | |
63 | </td> |
|
63 | </td> | |
64 | <td> |
|
64 | <td> | |
65 | %if node.is_file(): |
|
65 | %if node.is_file(): | |
66 | <span class="tooltip" title="${node.last_changeset.raw_id}"> |
|
66 | <span class="tooltip" title="${node.last_changeset.raw_id}"> | |
67 | ${node.last_changeset.revision}</span> |
|
67 | ${'r%s:%s' % (node.last_changeset.revision,node.last_changeset.short_id)}</span> | |
68 | %endif |
|
68 | %endif | |
69 | </td> |
|
69 | </td> | |
70 | <td> |
|
70 | <td> | |
71 | %if node.is_file(): |
|
71 | %if node.is_file(): | |
72 | <span class="tooltip" title="${node.last_changeset.date}"> |
|
72 | <span class="tooltip" title="${node.last_changeset.date}"> | |
73 | ${h.age(node.last_changeset.date)}</span> |
|
73 | ${h.age(node.last_changeset.date)}</span> | |
74 | %endif |
|
74 | %endif | |
75 | </td> |
|
75 | </td> | |
76 | <td> |
|
76 | <td> | |
77 | %if node.is_file(): |
|
77 | %if node.is_file(): | |
78 | ${node.last_changeset.author} |
|
78 | ${node.last_changeset.author} | |
79 | %endif |
|
79 | %endif | |
80 | </td> |
|
80 | </td> | |
81 | </tr> |
|
81 | </tr> | |
82 | %endfor |
|
82 | %endfor | |
83 | </table> |
|
83 | </table> | |
84 | </div> |
|
84 | </div> | |
85 | </div> No newline at end of file |
|
85 | </div> |
@@ -1,57 +1,61 b'' | |||||
1 | <dl> |
|
1 | <dl> | |
2 | <dt>${_('Revision')}</dt> |
|
2 | <dt>${_('Revision')}</dt> | |
3 | <dd> |
|
3 | <dd> | |
4 | ${h.link_to("r%s:%s" % (c.files_list.last_changeset.revision,h.short_id(c.files_list.last_changeset.raw_id)), |
|
4 | ${h.link_to("r%s:%s" % (c.files_list.last_changeset.revision,h.short_id(c.files_list.last_changeset.raw_id)), | |
5 | h.url('changeset_home',repo_name=c.repo_name,revision=c.files_list.last_changeset.raw_id))} |
|
5 | h.url('changeset_home',repo_name=c.repo_name,revision=c.files_list.last_changeset.raw_id))} | |
6 | </dd> |
|
6 | </dd> | |
7 | <dt>${_('Size')}</dt> |
|
7 | <dt>${_('Size')}</dt> | |
8 | <dd>${h.format_byte_size(c.files_list.size,binary=True)}</dd> |
|
8 | <dd>${h.format_byte_size(c.files_list.size,binary=True)}</dd> | |
9 | <dt>${_('Mimetype')}</dt> |
|
9 | <dt>${_('Mimetype')}</dt> | |
10 | <dd>${c.files_list.mimetype}</dd> |
|
10 | <dd>${c.files_list.mimetype}</dd> | |
11 | <dt>${_('Options')}</dt> |
|
11 | <dt>${_('Options')}</dt> | |
12 | <dd>${h.link_to(_('show annotation'), |
|
12 | <dd>${h.link_to(_('show annotation'), | |
13 | h.url('files_annotate_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))} |
|
13 | h.url('files_annotate_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))} | |
14 | / ${h.link_to(_('show as raw'), |
|
14 | / ${h.link_to(_('show as raw'), | |
15 | h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))} |
|
15 | h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))} | |
16 | / ${h.link_to(_('download as raw'), |
|
16 | / ${h.link_to(_('download as raw'), | |
17 | h.url('files_rawfile_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))} |
|
17 | h.url('files_rawfile_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))} | |
18 | </dd> |
|
18 | </dd> | |
19 | <dt>${_('History')}</dt> |
|
19 | <dt>${_('History')}</dt> | |
20 | <dd> |
|
20 | <dd> | |
21 | <div> |
|
21 | <div> | |
22 | ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')} |
|
22 | ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')} | |
23 | ${h.hidden('diff2',c.files_list.last_changeset.raw_id)} |
|
23 | ${h.hidden('diff2',c.files_list.last_changeset.raw_id)} | |
24 | ${h.select('diff1',c.files_list.last_changeset.raw_id,c.file_history)} |
|
24 | ${h.select('diff1',c.files_list.last_changeset.raw_id,c.file_history)} | |
25 |
${h.submit('diff','diff to revision',class_="ui-button |
|
25 | ${h.submit('diff','diff to revision',class_="ui-button")} | |
26 |
${h.submit('show_rev','show at revision',class_="ui-button |
|
26 | ${h.submit('show_rev','show at revision',class_="ui-button")} | |
27 | ${h.end_form()} |
|
27 | ${h.end_form()} | |
28 | </div> |
|
28 | </div> | |
29 | </dd> |
|
29 | </dd> | |
30 | </dl> |
|
30 | </dl> | |
31 |
|
31 | |||
32 |
|
32 | |||
33 | <div id="body" class="codeblock"> |
|
33 | <div id="body" class="codeblock"> | |
34 | <div class="code-header"> |
|
34 | <div class="code-header"> | |
35 | <div class="revision">${c.files_list.name}@r${c.files_list.last_changeset.revision}:${h.short_id(c.files_list.last_changeset.raw_id)}</div> |
|
35 | <div class="revision">${c.files_list.name}@r${c.files_list.last_changeset.revision}:${h.short_id(c.files_list.last_changeset.raw_id)}</div> | |
36 | <div class="commit">"${c.files_list.last_changeset.message}"</div> |
|
36 | <div class="commit">"${c.files_list.last_changeset.message}"</div> | |
37 | </div> |
|
37 | </div> | |
38 | <div class="code-body"> |
|
38 | <div class="code-body"> | |
|
39 | %if c.files_list.is_binary: | |||
|
40 | ${_('Binary file')} | |||
|
41 | %else: | |||
39 | % if c.files_list.size < c.cut_off_limit: |
|
42 | % if c.files_list.size < c.cut_off_limit: | |
40 |
${h.pygmentize(c.files_list,linenos=True,anchorlinenos=True,lineanchors=' |
|
43 | ${h.pygmentize(c.files_list,linenos=True,anchorlinenos=True,lineanchors='L',cssclass="code-highlight")} | |
41 | %else: |
|
44 | %else: | |
42 | ${_('File is to big to display')} ${h.link_to(_('show as raw'), |
|
45 | ${_('File is to big to display')} ${h.link_to(_('show as raw'), | |
43 | h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))} |
|
46 | h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))} | |
44 | %endif |
|
47 | %endif | |
|
48 | %endif | |||
45 | </div> |
|
49 | </div> | |
46 | </div> |
|
50 | </div> | |
47 |
|
51 | |||
48 | <script type="text/javascript"> |
|
52 | <script type="text/javascript"> | |
49 | YAHOO.util.Event.onDOMReady(function(){ |
|
53 | YAHOO.util.Event.onDOMReady(function(){ | |
50 | YAHOO.util.Event.addListener('show_rev','click',function(e){ |
|
54 | YAHOO.util.Event.addListener('show_rev','click',function(e){ | |
51 | YAHOO.util.Event.preventDefault(e); |
|
55 | YAHOO.util.Event.preventDefault(e); | |
52 | var cs = YAHOO.util.Dom.get('diff1').value; |
|
56 | var cs = YAHOO.util.Dom.get('diff1').value; | |
53 | var url = "${h.url('files_home',repo_name=c.repo_name,revision='__CS__',f_path=c.f_path)}".replace('__CS__',cs); |
|
57 | var url = "${h.url('files_home',repo_name=c.repo_name,revision='__CS__',f_path=c.f_path)}".replace('__CS__',cs); | |
54 | window.location = url; |
|
58 | window.location = url; | |
55 | }); |
|
59 | }); | |
56 | }); |
|
60 | }); | |
57 | </script> No newline at end of file |
|
61 | </script> |
General Comments 0
You need to be logged in to leave comments.
Login now