##// END OF EJS Templates
merges for stable
marcink -
r1232:0dc8d578 default
parent child Browse files
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-2010 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
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-2010 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
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} &copy; 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} &copy; 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>&darr;</span>
126 <span>&darr;</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+= '&amp;auth_token='+token;
351 args+= '&amp;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+= '&amp;auth_token='+token;
362 args+= '&amp;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 &raquo;
11 &raquo;
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 &raquo;
13 &raquo;
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("/js/graph.js")}"></script>
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 &raquo;
11 &raquo;
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 &raquo;
13 &raquo;
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 &raquo; <span>${h.link_to(_('raw diff'),
32 &raquo; <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 &raquo; <span>${h.link_to(_('download diff'),
34 &raquo; <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 &raquo; <span>${h.link_to(_('diff'),
104 &raquo; <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 &raquo; <span>${h.link_to(_('raw diff'),
106 &raquo; <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 &raquo; <span>${h.link_to(_('download diff'),
108 &raquo; <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 &raquo;
9 &raquo;
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 &raquo;
11 &raquo;
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 ui-widget ui-state-default ui-corner-all")}
54 ${h.submit('diff','diff to revision',class_="ui-button")}
55 ${h.submit('show_rev','show at revision',class_="ui-button ui-widget ui-state-default ui-corner-all")}
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='S',cssclass="code-highlight")}
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')}">&laquo;</a>
13 <a href="${c.url_prev}" title="${_('previous revision')}">&laquo;</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')}">&raquo;</a>
15 <a href="${c.url_next}" title="${_('next revision')}">&raquo;</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 ui-widget ui-state-default ui-corner-all")}
25 ${h.submit('diff','diff to revision',class_="ui-button")}
26 ${h.submit('show_rev','show at revision',class_="ui-button ui-widget ui-state-default ui-corner-all")}
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='S',cssclass="code-highlight")}
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