##// END OF EJS Templates
added os.sep for files controller...
marcink -
r1200:3ecaa17d beta
parent child Browse files
Show More
@@ -1,282 +1,283
1 .. _changelog:
1 .. _changelog:
2
2
3 Changelog
3 Changelog
4 =========
4 =========
5
5
6 1.2.0 (**2011-XX-XX**)
6 1.2.0 (**2011-XX-XX**)
7 ======================
7 ======================
8
8
9 :status: in-progress
9 :status: in-progress
10 :branch: beta
10 :branch: beta
11
11
12 news
12 news
13 ----
13 ----
14
14
15 - implemented #89 Can setup google analytics code from settings menu
15 - implemented #89 Can setup google analytics code from settings menu
16 - implemented #91 added nicer looking archive urls with more download options
16 - implemented #91 added nicer looking archive urls with more download options
17 like tags, branches
17 like tags, branches
18 - implemented #44 into file browsing, and added follow branch option
18 - implemented #44 into file browsing, and added follow branch option
19 - implemented #84 downloads can be enabled/disabled for each repository
19 - implemented #84 downloads can be enabled/disabled for each repository
20 - anonymous repository can be cloned without having to pass default:default
20 - anonymous repository can be cloned without having to pass default:default
21 into clone url
21 into clone url
22 - fixed #90 whoosh indexer can index chooses repositories passed in command
22 - fixed #90 whoosh indexer can index chooses repositories passed in command
23 line
23 line
24 - extended journal with day aggregates and paging
24 - extended journal with day aggregates and paging
25 - implemented #107 customizable code highlights on code sources
25 - implemented #107 source code lines highlight ranges
26 - implemented #93 customizable changelog on combined revision ranges -
26 - implemented #93 customizable changelog on combined revision ranges -
27 equivalent of githubs compare view
27 equivalent of githubs compare view
28 - implemented #108 extended and more powerful LDAP configuration
28 - implemented #108 extended and more powerful LDAP configuration
29 - implemented #56 users groups
29 - implemented #56 users groups
30 - major code rewrites optimized codes for speed and memory usage
30 - major code rewrites optimized codes for speed and memory usage
31 - raw and diff downloads are now in git format
31 - raw and diff downloads are now in git format
32 - setup command checks for write access to given path
32 - setup command checks for write access to given path
33 - fixed many issues with international characters and unicode. It uses utf8
33 - fixed many issues with international characters and unicode. It uses utf8
34 decode with replace to provide less errors even with non utf8 encoded strings
34 decode with replace to provide less errors even with non utf8 encoded strings
35 - #125 added API KEY access to feeds
35 - #125 added API KEY access to feeds
36 - #109 Repository can be created from external Mercurial link, and manually
36 - #109 Repository can be created from external Mercurial link (aka. remote
37 updated (via pull) from admin panel
37 repository, and manually updated (via pull) from admin panel
38
38
39 fixes
39 fixes
40 -----
40 -----
41
41
42 - fixed file browser bug, when switching into given form revision the url was
42 - fixed file browser bug, when switching into given form revision the url was
43 not changing
43 not changing
44 - fixed propagation to error controller on simplehg and simplegit middlewares
44 - fixed propagation to error controller on simplehg and simplegit middlewares
45 - fixed error when trying to make a download on empty repository
45 - fixed error when trying to make a download on empty repository
46 - fixed problem with '[' chars in commit messages in journal
46 - fixed problem with '[' chars in commit messages in journal
47 - fixed #99 Unicode errors, on file node paths with non utf-8 characters
47 - fixed #99 Unicode errors, on file node paths with non utf-8 characters
48 - journal fork fixes
48 - journal fork fixes
49 - removed issue with space inside renamed repository after deletion
49 - removed issue with space inside renamed repository after deletion
50 - fixed strange issue on formencode imports
50 - fixed strange issue on formencode imports
51 - fixed #126 Deleting repository on Windows, rename used incompatible chars.
51 - fixed #126 Deleting repository on Windows, rename used incompatible chars.
52 - windows fixes for os.kill and path spliting, issues #148 and #133
52
53
53 1.1.7 (**2011-03-23**)
54 1.1.7 (**2011-03-23**)
54 ======================
55 ======================
55
56
56 news
57 news
57 ----
58 ----
58
59
59 fixes
60 fixes
60 -----
61 -----
61
62
62 - fixed (again) #136 installation support for FreeBSD
63 - fixed (again) #136 installation support for FreeBSD
63
64
64
65
65 1.1.6 (**2011-03-21**)
66 1.1.6 (**2011-03-21**)
66 ======================
67 ======================
67
68
68 news
69 news
69 ----
70 ----
70
71
71 fixes
72 fixes
72 -----
73 -----
73
74
74 - fixed #136 installation support for FreeBSD
75 - fixed #136 installation support for FreeBSD
75 - RhodeCode will check for python version during installation
76 - RhodeCode will check for python version during installation
76
77
77 1.1.5 (**2011-03-17**)
78 1.1.5 (**2011-03-17**)
78 ======================
79 ======================
79
80
80 news
81 news
81 ----
82 ----
82
83
83 - basic windows support, by exchanging pybcrypt into sha256 for windows only
84 - basic windows support, by exchanging pybcrypt into sha256 for windows only
84 highly inspired by idea of mantis406
85 highly inspired by idea of mantis406
85
86
86 fixes
87 fixes
87 -----
88 -----
88
89
89 - fixed sorting by author in main page
90 - fixed sorting by author in main page
90 - fixed crashes with diffs on binary files
91 - fixed crashes with diffs on binary files
91 - fixed #131 problem with boolean values for LDAP
92 - fixed #131 problem with boolean values for LDAP
92 - fixed #122 mysql problems thanks to striker69
93 - fixed #122 mysql problems thanks to striker69
93 - fixed problem with errors on calling raw/raw_files/annotate functions
94 - fixed problem with errors on calling raw/raw_files/annotate functions
94 with unknown revisions
95 with unknown revisions
95 - fixed returned rawfiles attachment names with international character
96 - fixed returned rawfiles attachment names with international character
96 - cleaned out docs, big thanks to Jason Harris
97 - cleaned out docs, big thanks to Jason Harris
97
98
98 1.1.4 (**2011-02-19**)
99 1.1.4 (**2011-02-19**)
99 ======================
100 ======================
100
101
101 news
102 news
102 ----
103 ----
103
104
104 fixes
105 fixes
105 -----
106 -----
106
107
107 - fixed formencode import problem on settings page, that caused server crash
108 - fixed formencode import problem on settings page, that caused server crash
108 when that page was accessed as first after server start
109 when that page was accessed as first after server start
109 - journal fixes
110 - journal fixes
110 - fixed option to access repository just by entering http://server/<repo_name>
111 - fixed option to access repository just by entering http://server/<repo_name>
111
112
112 1.1.3 (**2011-02-16**)
113 1.1.3 (**2011-02-16**)
113 ======================
114 ======================
114
115
115 news
116 news
116 ----
117 ----
117
118
118 - implemented #102 allowing the '.' character in username
119 - implemented #102 allowing the '.' character in username
119 - added option to access repository just by entering http://server/<repo_name>
120 - added option to access repository just by entering http://server/<repo_name>
120 - celery task ignores result for better performance
121 - celery task ignores result for better performance
121
122
122 fixes
123 fixes
123 -----
124 -----
124
125
125 - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to
126 - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to
126 apollo13 and Johan Walles
127 apollo13 and Johan Walles
127 - small fixes in journal
128 - small fixes in journal
128 - fixed problems with getting setting for celery from .ini files
129 - fixed problems with getting setting for celery from .ini files
129 - registration, password reset and login boxes share the same title as main
130 - registration, password reset and login boxes share the same title as main
130 application now
131 application now
131 - fixed #113: to high permissions to fork repository
132 - fixed #113: to high permissions to fork repository
132 - fixed problem with '[' chars in commit messages in journal
133 - fixed problem with '[' chars in commit messages in journal
133 - removed issue with space inside renamed repository after deletion
134 - removed issue with space inside renamed repository after deletion
134 - db transaction fixes when filesystem repository creation failed
135 - db transaction fixes when filesystem repository creation failed
135 - fixed #106 relation issues on databases different than sqlite
136 - fixed #106 relation issues on databases different than sqlite
136 - fixed static files paths links to use of url() method
137 - fixed static files paths links to use of url() method
137
138
138 1.1.2 (**2011-01-12**)
139 1.1.2 (**2011-01-12**)
139 ======================
140 ======================
140
141
141 news
142 news
142 ----
143 ----
143
144
144
145
145 fixes
146 fixes
146 -----
147 -----
147
148
148 - fixes #98 protection against float division of percentage stats
149 - fixes #98 protection against float division of percentage stats
149 - fixed graph bug
150 - fixed graph bug
150 - forced webhelpers version since it was making troubles during installation
151 - forced webhelpers version since it was making troubles during installation
151
152
152 1.1.1 (**2011-01-06**)
153 1.1.1 (**2011-01-06**)
153 ======================
154 ======================
154
155
155 news
156 news
156 ----
157 ----
157
158
158 - added force https option into ini files for easier https usage (no need to
159 - added force https option into ini files for easier https usage (no need to
159 set server headers with this options)
160 set server headers with this options)
160 - small css updates
161 - small css updates
161
162
162 fixes
163 fixes
163 -----
164 -----
164
165
165 - fixed #96 redirect loop on files view on repositories without changesets
166 - fixed #96 redirect loop on files view on repositories without changesets
166 - fixed #97 unicode string passed into server header in special cases (mod_wsgi)
167 - fixed #97 unicode string passed into server header in special cases (mod_wsgi)
167 and server crashed with errors
168 and server crashed with errors
168 - fixed large tooltips problems on main page
169 - fixed large tooltips problems on main page
169 - fixed #92 whoosh indexer is more error proof
170 - fixed #92 whoosh indexer is more error proof
170
171
171 1.1.0 (**2010-12-18**)
172 1.1.0 (**2010-12-18**)
172 ======================
173 ======================
173
174
174 news
175 news
175 ----
176 ----
176
177
177 - rewrite of internals for vcs >=0.1.10
178 - rewrite of internals for vcs >=0.1.10
178 - uses mercurial 1.7 with dotencode disabled for maintaining compatibility
179 - uses mercurial 1.7 with dotencode disabled for maintaining compatibility
179 with older clients
180 with older clients
180 - anonymous access, authentication via ldap
181 - anonymous access, authentication via ldap
181 - performance upgrade for cached repos list - each repository has it's own
182 - performance upgrade for cached repos list - each repository has it's own
182 cache that's invalidated when needed.
183 cache that's invalidated when needed.
183 - performance upgrades on repositories with large amount of commits (20K+)
184 - performance upgrades on repositories with large amount of commits (20K+)
184 - main page quick filter for filtering repositories
185 - main page quick filter for filtering repositories
185 - user dashboards with ability to follow chosen repositories actions
186 - user dashboards with ability to follow chosen repositories actions
186 - sends email to admin on new user registration
187 - sends email to admin on new user registration
187 - added cache/statistics reset options into repository settings
188 - added cache/statistics reset options into repository settings
188 - more detailed action logger (based on hooks) with pushed changesets lists
189 - more detailed action logger (based on hooks) with pushed changesets lists
189 and options to disable those hooks from admin panel
190 and options to disable those hooks from admin panel
190 - introduced new enhanced changelog for merges that shows more accurate results
191 - introduced new enhanced changelog for merges that shows more accurate results
191 - new improved and faster code stats (based on pygments lexers mapping tables,
192 - new improved and faster code stats (based on pygments lexers mapping tables,
192 showing up to 10 trending sources for each repository. Additionally stats
193 showing up to 10 trending sources for each repository. Additionally stats
193 can be disabled in repository settings.
194 can be disabled in repository settings.
194 - gui optimizations, fixed application width to 1024px
195 - gui optimizations, fixed application width to 1024px
195 - added cut off (for large files/changesets) limit into config files
196 - added cut off (for large files/changesets) limit into config files
196 - whoosh, celeryd, upgrade moved to paster command
197 - whoosh, celeryd, upgrade moved to paster command
197 - other than sqlite database backends can be used
198 - other than sqlite database backends can be used
198
199
199 fixes
200 fixes
200 -----
201 -----
201
202
202 - fixes #61 forked repo was showing only after cache expired
203 - fixes #61 forked repo was showing only after cache expired
203 - fixes #76 no confirmation on user deletes
204 - fixes #76 no confirmation on user deletes
204 - fixes #66 Name field misspelled
205 - fixes #66 Name field misspelled
205 - fixes #72 block user removal when he owns repositories
206 - fixes #72 block user removal when he owns repositories
206 - fixes #69 added password confirmation fields
207 - fixes #69 added password confirmation fields
207 - fixes #87 RhodeCode crashes occasionally on updating repository owner
208 - fixes #87 RhodeCode crashes occasionally on updating repository owner
208 - fixes #82 broken annotations on files with more than 1 blank line at the end
209 - fixes #82 broken annotations on files with more than 1 blank line at the end
209 - a lot of fixes and tweaks for file browser
210 - a lot of fixes and tweaks for file browser
210 - fixed detached session issues
211 - fixed detached session issues
211 - fixed when user had no repos he would see all repos listed in my account
212 - fixed when user had no repos he would see all repos listed in my account
212 - fixed ui() instance bug when global hgrc settings was loaded for server
213 - fixed ui() instance bug when global hgrc settings was loaded for server
213 instance and all hgrc options were merged with our db ui() object
214 instance and all hgrc options were merged with our db ui() object
214 - numerous small bugfixes
215 - numerous small bugfixes
215
216
216 (special thanks for TkSoh for detailed feedback)
217 (special thanks for TkSoh for detailed feedback)
217
218
218
219
219 1.0.2 (**2010-11-12**)
220 1.0.2 (**2010-11-12**)
220 ======================
221 ======================
221
222
222 news
223 news
223 ----
224 ----
224
225
225 - tested under python2.7
226 - tested under python2.7
226 - bumped sqlalchemy and celery versions
227 - bumped sqlalchemy and celery versions
227
228
228 fixes
229 fixes
229 -----
230 -----
230
231
231 - fixed #59 missing graph.js
232 - fixed #59 missing graph.js
232 - fixed repo_size crash when repository had broken symlinks
233 - fixed repo_size crash when repository had broken symlinks
233 - fixed python2.5 crashes.
234 - fixed python2.5 crashes.
234
235
235
236
236 1.0.1 (**2010-11-10**)
237 1.0.1 (**2010-11-10**)
237 ======================
238 ======================
238
239
239 news
240 news
240 ----
241 ----
241
242
242 - small css updated
243 - small css updated
243
244
244 fixes
245 fixes
245 -----
246 -----
246
247
247 - fixed #53 python2.5 incompatible enumerate calls
248 - fixed #53 python2.5 incompatible enumerate calls
248 - fixed #52 disable mercurial extension for web
249 - fixed #52 disable mercurial extension for web
249 - fixed #51 deleting repositories don't delete it's dependent objects
250 - fixed #51 deleting repositories don't delete it's dependent objects
250
251
251
252
252 1.0.0 (**2010-11-02**)
253 1.0.0 (**2010-11-02**)
253 ======================
254 ======================
254
255
255 - security bugfix simplehg wasn't checking for permissions on commands
256 - security bugfix simplehg wasn't checking for permissions on commands
256 other than pull or push.
257 other than pull or push.
257 - fixed doubled messages after push or pull in admin journal
258 - fixed doubled messages after push or pull in admin journal
258 - templating and css corrections, fixed repo switcher on chrome, updated titles
259 - templating and css corrections, fixed repo switcher on chrome, updated titles
259 - admin menu accessible from options menu on repository view
260 - admin menu accessible from options menu on repository view
260 - permissions cached queries
261 - permissions cached queries
261
262
262 1.0.0rc4 (**2010-10-12**)
263 1.0.0rc4 (**2010-10-12**)
263 ==========================
264 ==========================
264
265
265 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
266 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
266 - removed cache_manager settings from sqlalchemy meta
267 - removed cache_manager settings from sqlalchemy meta
267 - added sqlalchemy cache settings to ini files
268 - added sqlalchemy cache settings to ini files
268 - validated password length and added second try of failure on paster setup-app
269 - validated password length and added second try of failure on paster setup-app
269 - fixed setup database destroy prompt even when there was no db
270 - fixed setup database destroy prompt even when there was no db
270
271
271
272
272 1.0.0rc3 (**2010-10-11**)
273 1.0.0rc3 (**2010-10-11**)
273 =========================
274 =========================
274
275
275 - fixed i18n during installation.
276 - fixed i18n during installation.
276
277
277 1.0.0rc2 (**2010-10-11**)
278 1.0.0rc2 (**2010-10-11**)
278 =========================
279 =========================
279
280
280 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
281 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
281 occure. After vcs is fixed it'll be put back again.
282 occure. After vcs is fixed it'll be put back again.
282 - templating/css rewrites, optimized css. No newline at end of file
283 - templating/css rewrites, optimized css.
@@ -1,303 +1,304
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
13 # This program is free software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
16 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
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, write to the Free Software
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
27
27
28 import os
28 import logging
29 import logging
29 import rhodecode.lib.helpers as h
30 import rhodecode.lib.helpers as h
30
31
31 from pylons import request, response, session, tmpl_context as c, url
32 from pylons import request, response, session, tmpl_context as c, url
32 from pylons.i18n.translation import _
33 from pylons.i18n.translation import _
33 from pylons.controllers.util import redirect
34 from pylons.controllers.util import redirect
34
35
35 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
36 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
36 from rhodecode.lib.base import BaseRepoController, render
37 from rhodecode.lib.base import BaseRepoController, render
37 from rhodecode.lib.utils import EmptyChangeset
38 from rhodecode.lib.utils import EmptyChangeset
38 from rhodecode.model.repo import RepoModel
39 from rhodecode.model.repo import RepoModel
39
40
40 from vcs.backends import ARCHIVE_SPECS
41 from vcs.backends import ARCHIVE_SPECS
41 from vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \
42 from vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \
42 EmptyRepositoryError, ImproperArchiveTypeError, VCSError
43 EmptyRepositoryError, ImproperArchiveTypeError, VCSError
43 from vcs.nodes import FileNode, NodeKind
44 from vcs.nodes import FileNode, NodeKind
44 from vcs.utils import diffs as differ
45 from vcs.utils import diffs as differ
45
46
46 log = logging.getLogger(__name__)
47 log = logging.getLogger(__name__)
47
48
48
49
49 class FilesController(BaseRepoController):
50 class FilesController(BaseRepoController):
50
51
51 @LoginRequired()
52 @LoginRequired()
52 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
53 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
53 'repository.admin')
54 'repository.admin')
54 def __before__(self):
55 def __before__(self):
55 super(FilesController, self).__before__()
56 super(FilesController, self).__before__()
56 c.cut_off_limit = self.cut_off_limit
57 c.cut_off_limit = self.cut_off_limit
57
58
58 def __get_cs_or_redirect(self, rev, repo_name):
59 def __get_cs_or_redirect(self, rev, repo_name):
59 """
60 """
60 Safe way to get changeset if error occur it redirects to tip with
61 Safe way to get changeset if error occur it redirects to tip with
61 proper message
62 proper message
62
63
63 :param rev: revision to fetch
64 :param rev: revision to fetch
64 :param repo_name: repo name to redirect after
65 :param repo_name: repo name to redirect after
65 """
66 """
66
67
67 try:
68 try:
68 return c.rhodecode_repo.get_changeset(rev)
69 return c.rhodecode_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
78
78 def __get_filenode_or_redirect(self, repo_name, cs, path):
79 def __get_filenode_or_redirect(self, repo_name, cs, path):
79 """
80 """
80 Returns file_node, if error occurs or given path is directory,
81 Returns file_node, if error occurs or given path is directory,
81 it'll redirect to top level path
82 it'll redirect to top level path
82
83
83 :param repo_name: repo_name
84 :param repo_name: repo_name
84 :param cs: given changeset
85 :param cs: given changeset
85 :param path: path to lookup
86 :param path: path to lookup
86 """
87 """
87
88
88
89
89 try:
90 try:
90 file_node = cs.get_node(path)
91 file_node = cs.get_node(path)
91 if file_node.is_dir():
92 if file_node.is_dir():
92 raise RepositoryError('given path is a directory')
93 raise RepositoryError('given path is a directory')
93 except RepositoryError, e:
94 except RepositoryError, e:
94 h.flash(str(e), category='warning')
95 h.flash(str(e), category='warning')
95 redirect(h.url('files_home', repo_name=repo_name,
96 redirect(h.url('files_home', repo_name=repo_name,
96 revision=cs.raw_id))
97 revision=cs.raw_id))
97
98
98 return file_node
99 return file_node
99
100
100 def index(self, repo_name, revision, f_path):
101 def index(self, repo_name, revision, f_path):
101 #reditect to given revision from form if given
102 #reditect to given revision from form if given
102 post_revision = request.POST.get('at_rev', None)
103 post_revision = request.POST.get('at_rev', None)
103 if post_revision:
104 if post_revision:
104 cs = self.__get_cs_or_redirect(revision, repo_name)
105 cs = self.__get_cs_or_redirect(revision, repo_name)
105 redirect(url('files_home', repo_name=c.repo_name,
106 redirect(url('files_home', repo_name=c.repo_name,
106 revision=cs.raw_id, f_path=f_path))
107 revision=cs.raw_id, f_path=f_path))
107
108
108
109
109 c.changeset = self.__get_cs_or_redirect(revision, repo_name)
110 c.changeset = self.__get_cs_or_redirect(revision, repo_name)
110 c.branch = request.GET.get('branch', None)
111 c.branch = request.GET.get('branch', None)
111 c.f_path = f_path
112 c.f_path = f_path
112
113
113 cur_rev = c.changeset.revision
114 cur_rev = c.changeset.revision
114
115
115 #prev link
116 #prev link
116 try:
117 try:
117 prev_rev = c.rhodecode_repo.get_changeset(cur_rev).prev(c.branch)
118 prev_rev = c.rhodecode_repo.get_changeset(cur_rev).prev(c.branch)
118 c.url_prev = url('files_home', repo_name=c.repo_name,
119 c.url_prev = url('files_home', repo_name=c.repo_name,
119 revision=prev_rev.raw_id, f_path=f_path)
120 revision=prev_rev.raw_id, f_path=f_path)
120 if c.branch:
121 if c.branch:
121 c.url_prev += '?branch=%s' % c.branch
122 c.url_prev += '?branch=%s' % c.branch
122 except (ChangesetDoesNotExistError, VCSError):
123 except (ChangesetDoesNotExistError, VCSError):
123 c.url_prev = '#'
124 c.url_prev = '#'
124
125
125 #next link
126 #next link
126 try:
127 try:
127 next_rev = c.rhodecode_repo.get_changeset(cur_rev).next(c.branch)
128 next_rev = c.rhodecode_repo.get_changeset(cur_rev).next(c.branch)
128 c.url_next = url('files_home', repo_name=c.repo_name,
129 c.url_next = url('files_home', repo_name=c.repo_name,
129 revision=next_rev.raw_id, f_path=f_path)
130 revision=next_rev.raw_id, f_path=f_path)
130 if c.branch:
131 if c.branch:
131 c.url_next += '?branch=%s' % c.branch
132 c.url_next += '?branch=%s' % c.branch
132 except (ChangesetDoesNotExistError, VCSError):
133 except (ChangesetDoesNotExistError, VCSError):
133 c.url_next = '#'
134 c.url_next = '#'
134
135
135 #files or dirs
136 #files or dirs
136 try:
137 try:
137 c.files_list = c.changeset.get_node(f_path)
138 c.files_list = c.changeset.get_node(f_path)
138
139
139 if c.files_list.is_file():
140 if c.files_list.is_file():
140 c.file_history = self._get_node_history(c.changeset, f_path)
141 c.file_history = self._get_node_history(c.changeset, f_path)
141 else:
142 else:
142 c.file_history = []
143 c.file_history = []
143 except RepositoryError, e:
144 except RepositoryError, e:
144 h.flash(str(e), category='warning')
145 h.flash(str(e), category='warning')
145 redirect(h.url('files_home', repo_name=repo_name,
146 redirect(h.url('files_home', repo_name=repo_name,
146 revision=revision))
147 revision=revision))
147
148
148
149
149 return render('files/files.html')
150 return render('files/files.html')
150
151
151 def rawfile(self, repo_name, revision, f_path):
152 def rawfile(self, repo_name, revision, f_path):
152 cs = self.__get_cs_or_redirect(revision, repo_name)
153 cs = self.__get_cs_or_redirect(revision, repo_name)
153 file_node = self.__get_filenode_or_redirect(repo_name, cs, f_path)
154 file_node = self.__get_filenode_or_redirect(repo_name, cs, f_path)
154
155
155 response.content_disposition = 'attachment; filename=%s' % \
156 response.content_disposition = 'attachment; filename=%s' % \
156 f_path.split('/')[-1].encode('utf8', 'replace')
157 f_path.split(os.sep)[-1].encode('utf8', 'replace')
157
158
158 response.content_type = file_node.mimetype
159 response.content_type = file_node.mimetype
159 return file_node.content
160 return file_node.content
160
161
161 def raw(self, repo_name, revision, f_path):
162 def raw(self, repo_name, revision, f_path):
162 cs = self.__get_cs_or_redirect(revision, repo_name)
163 cs = self.__get_cs_or_redirect(revision, repo_name)
163 file_node = self.__get_filenode_or_redirect(repo_name, cs, f_path)
164 file_node = self.__get_filenode_or_redirect(repo_name, cs, f_path)
164
165
165 response.content_type = 'text/plain'
166 response.content_type = 'text/plain'
166 return file_node.content
167 return file_node.content
167
168
168 def annotate(self, repo_name, revision, f_path):
169 def annotate(self, repo_name, revision, f_path):
169 c.cs = self.__get_cs_or_redirect(revision, repo_name)
170 c.cs = self.__get_cs_or_redirect(revision, repo_name)
170 c.file = self.__get_filenode_or_redirect(repo_name, c.cs, f_path)
171 c.file = self.__get_filenode_or_redirect(repo_name, c.cs, f_path)
171
172
172 c.file_history = self._get_node_history(c.cs, f_path)
173 c.file_history = self._get_node_history(c.cs, f_path)
173 c.f_path = f_path
174 c.f_path = f_path
174 return render('files/files_annotate.html')
175 return render('files/files_annotate.html')
175
176
176 def archivefile(self, repo_name, fname):
177 def archivefile(self, repo_name, fname):
177
178
178 fileformat = None
179 fileformat = None
179 revision = None
180 revision = None
180 ext = None
181 ext = None
181
182
182 for a_type, ext_data in ARCHIVE_SPECS.items():
183 for a_type, ext_data in ARCHIVE_SPECS.items():
183 archive_spec = fname.split(ext_data[1])
184 archive_spec = fname.split(ext_data[1])
184 if len(archive_spec) == 2 and archive_spec[1] == '':
185 if len(archive_spec) == 2 and archive_spec[1] == '':
185 fileformat = a_type or ext_data[1]
186 fileformat = a_type or ext_data[1]
186 revision = archive_spec[0]
187 revision = archive_spec[0]
187 ext = ext_data[1]
188 ext = ext_data[1]
188
189
189 try:
190 try:
190 dbrepo = RepoModel().get_by_repo_name(repo_name)
191 dbrepo = RepoModel().get_by_repo_name(repo_name)
191 if dbrepo.enable_downloads is False:
192 if dbrepo.enable_downloads is False:
192 return _('downloads disabled')
193 return _('downloads disabled')
193
194
194 cs = c.rhodecode_repo.get_changeset(revision)
195 cs = c.rhodecode_repo.get_changeset(revision)
195 content_type = ARCHIVE_SPECS[fileformat][0]
196 content_type = ARCHIVE_SPECS[fileformat][0]
196 except ChangesetDoesNotExistError:
197 except ChangesetDoesNotExistError:
197 return _('Unknown revision %s') % revision
198 return _('Unknown revision %s') % revision
198 except EmptyRepositoryError:
199 except EmptyRepositoryError:
199 return _('Empty repository')
200 return _('Empty repository')
200 except (ImproperArchiveTypeError, KeyError):
201 except (ImproperArchiveTypeError, KeyError):
201 return _('Unknown archive type')
202 return _('Unknown archive type')
202
203
203 response.content_type = content_type
204 response.content_type = content_type
204 response.content_disposition = 'attachment; filename=%s-%s%s' \
205 response.content_disposition = 'attachment; filename=%s-%s%s' \
205 % (repo_name, revision, ext)
206 % (repo_name, revision, ext)
206
207
207 return cs.get_chunked_archive(stream=None, kind=fileformat)
208 return cs.get_chunked_archive(stream=None, kind=fileformat)
208
209
209
210
210 def diff(self, repo_name, f_path):
211 def diff(self, repo_name, f_path):
211 diff1 = request.GET.get('diff1')
212 diff1 = request.GET.get('diff1')
212 diff2 = request.GET.get('diff2')
213 diff2 = request.GET.get('diff2')
213 c.action = request.GET.get('diff')
214 c.action = request.GET.get('diff')
214 c.no_changes = diff1 == diff2
215 c.no_changes = diff1 == diff2
215 c.f_path = f_path
216 c.f_path = f_path
216
217
217 try:
218 try:
218 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
219 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
219 c.changeset_1 = c.rhodecode_repo.get_changeset(diff1)
220 c.changeset_1 = c.rhodecode_repo.get_changeset(diff1)
220 node1 = c.changeset_1.get_node(f_path)
221 node1 = c.changeset_1.get_node(f_path)
221 else:
222 else:
222 c.changeset_1 = EmptyChangeset()
223 c.changeset_1 = EmptyChangeset()
223 node1 = FileNode('.', '', changeset=c.changeset_1)
224 node1 = FileNode('.', '', changeset=c.changeset_1)
224
225
225 if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]:
226 if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]:
226 c.changeset_2 = c.rhodecode_repo.get_changeset(diff2)
227 c.changeset_2 = c.rhodecode_repo.get_changeset(diff2)
227 node2 = c.changeset_2.get_node(f_path)
228 node2 = c.changeset_2.get_node(f_path)
228 else:
229 else:
229 c.changeset_2 = EmptyChangeset()
230 c.changeset_2 = EmptyChangeset()
230 node2 = FileNode('.', '', changeset=c.changeset_2)
231 node2 = FileNode('.', '', changeset=c.changeset_2)
231 except RepositoryError:
232 except RepositoryError:
232 return redirect(url('files_home',
233 return redirect(url('files_home',
233 repo_name=c.repo_name, f_path=f_path))
234 repo_name=c.repo_name, f_path=f_path))
234
235
235
236
236 if c.action == 'download':
237 if c.action == 'download':
237 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
238 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
238 format='gitdiff')
239 format='gitdiff')
239
240
240 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
241 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
241 response.content_type = 'text/plain'
242 response.content_type = 'text/plain'
242 response.content_disposition = 'attachment; filename=%s' \
243 response.content_disposition = 'attachment; filename=%s' \
243 % diff_name
244 % diff_name
244 return diff.raw_diff()
245 return diff.raw_diff()
245
246
246 elif c.action == 'raw':
247 elif c.action == 'raw':
247 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
248 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
248 format='gitdiff')
249 format='gitdiff')
249 response.content_type = 'text/plain'
250 response.content_type = 'text/plain'
250 return diff.raw_diff()
251 return diff.raw_diff()
251
252
252 elif c.action == 'diff':
253 elif c.action == 'diff':
253
254
254 if node1.is_binary or node2.is_binary:
255 if node1.is_binary or node2.is_binary:
255 c.cur_diff = _('Binary file')
256 c.cur_diff = _('Binary file')
256 elif node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
257 elif node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
257 c.cur_diff = _('Diff is too big to display')
258 c.cur_diff = _('Diff is too big to display')
258 else:
259 else:
259 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
260 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
260 format='gitdiff')
261 format='gitdiff')
261 c.cur_diff = diff.as_html()
262 c.cur_diff = diff.as_html()
262 else:
263 else:
263
264
264 #default option
265 #default option
265 if node1.is_binary or node2.is_binary:
266 if node1.is_binary or node2.is_binary:
266 c.cur_diff = _('Binary file')
267 c.cur_diff = _('Binary file')
267 elif node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
268 elif node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
268 c.cur_diff = _('Diff is too big to display')
269 c.cur_diff = _('Diff is too big to display')
269 else:
270 else:
270 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
271 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
271 format='gitdiff')
272 format='gitdiff')
272 c.cur_diff = diff.as_html()
273 c.cur_diff = diff.as_html()
273
274
274 if not c.cur_diff:
275 if not c.cur_diff:
275 c.no_changes = True
276 c.no_changes = True
276 return render('files/file_diff.html')
277 return render('files/file_diff.html')
277
278
278 def _get_node_history(self, cs, f_path):
279 def _get_node_history(self, cs, f_path):
279 changesets = cs.get_file_history(f_path)
280 changesets = cs.get_file_history(f_path)
280 hist_l = []
281 hist_l = []
281
282
282 changesets_group = ([], _("Changesets"))
283 changesets_group = ([], _("Changesets"))
283 branches_group = ([], _("Branches"))
284 branches_group = ([], _("Branches"))
284 tags_group = ([], _("Tags"))
285 tags_group = ([], _("Tags"))
285
286
286 for chs in changesets:
287 for chs in changesets:
287 n_desc = 'r%s:%s' % (chs.revision, chs.short_id)
288 n_desc = 'r%s:%s' % (chs.revision, chs.short_id)
288 changesets_group[0].append((chs.raw_id, n_desc,))
289 changesets_group[0].append((chs.raw_id, n_desc,))
289
290
290 hist_l.append(changesets_group)
291 hist_l.append(changesets_group)
291
292
292 for name, chs in c.rhodecode_repo.branches.items():
293 for name, chs in c.rhodecode_repo.branches.items():
293 #chs = chs.split(':')[-1]
294 #chs = chs.split(':')[-1]
294 branches_group[0].append((chs, name),)
295 branches_group[0].append((chs, name),)
295 hist_l.append(branches_group)
296 hist_l.append(branches_group)
296
297
297 for name, chs in c.rhodecode_repo.tags.items():
298 for name, chs in c.rhodecode_repo.tags.items():
298 #chs = chs.split(':')[-1]
299 #chs = chs.split(':')[-1]
299 tags_group[0].append((chs, name),)
300 tags_group[0].append((chs, name),)
300 hist_l.append(tags_group)
301 hist_l.append(tags_group)
301
302
302 return hist_l
303 return hist_l
303
304
General Comments 0
You need to be logged in to leave comments. Login now