##// END OF EJS Templates
first implementation of #34 changeset raw diff based on udiff from python
marcink -
r466:183cee11 default
parent child Browse files
Show More
@@ -0,0 +1,8 b''
1 # HG changeset patch
2 # User ${c.changeset.author}
3 # Date ${"%d %d" % c.changeset._ctx.date()}
4 # Node ID ${c.changeset._hex}
5 # ${c.parent_tmpl}
6 ${c.changeset.message}
7
8 ${c.diffs|n} No newline at end of file
@@ -1,164 +1,167 b''
1 1 """Routes configuration
2 2
3 3 The more specific and detailed routes should be defined first so they
4 4 may take precedent over the more generic routes. For more information
5 5 refer to the routes manual at http://routes.groovie.org/docs/
6 6 """
7 7 from __future__ import with_statement
8 8 from routes import Mapper
9 9 from pylons_app.lib.utils import check_repo_fast as cr
10 10
11 11 def make_map(config):
12 12 """Create, configure and return the routes Mapper"""
13 13 map = Mapper(directory=config['pylons.paths']['controllers'],
14 14 always_scan=config['debug'])
15 15 map.minimization = False
16 16 map.explicit = False
17 17
18 18 # The ErrorController route (handles 404/500 error pages); it should
19 19 # likely stay at the top, ensuring it can always be resolved
20 20 map.connect('/error/{action}', controller='error')
21 21 map.connect('/error/{action}/{id}', controller='error')
22 22
23 23 # CUSTOM ROUTES HERE
24 24 map.connect('hg_home', '/', controller='hg', action='index')
25 25
26 26 def check_repo(environ, match_dict):
27 27 """
28 28 check for valid repository for proper 404 handling
29 29 @param environ:
30 30 @param match_dict:
31 31 """
32 32 repo_name = match_dict.get('repo_name')
33 33 return not cr(repo_name, config['base_path'])
34 34
35 35 #REST REPO MAP
36 36 with map.submapper(path_prefix='/_admin', controller='admin/repos') as m:
37 37 m.connect("repos", "/repos",
38 38 action="create", conditions=dict(method=["POST"]))
39 39 m.connect("repos", "/repos",
40 40 action="index", conditions=dict(method=["GET"]))
41 41 m.connect("formatted_repos", "/repos.{format}",
42 42 action="index",
43 43 conditions=dict(method=["GET"]))
44 44 m.connect("new_repo", "/repos/new",
45 45 action="new", conditions=dict(method=["GET"]))
46 46 m.connect("formatted_new_repo", "/repos/new.{format}",
47 47 action="new", conditions=dict(method=["GET"]))
48 48 m.connect("/repos/{repo_name:.*}",
49 49 action="update", conditions=dict(method=["PUT"],
50 50 function=check_repo))
51 51 m.connect("/repos/{repo_name:.*}",
52 52 action="delete", conditions=dict(method=["DELETE"],
53 53 function=check_repo))
54 54 m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
55 55 action="edit", conditions=dict(method=["GET"],
56 56 function=check_repo))
57 57 m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
58 58 action="edit", conditions=dict(method=["GET"],
59 59 function=check_repo))
60 60 m.connect("repo", "/repos/{repo_name:.*}",
61 61 action="show", conditions=dict(method=["GET"],
62 62 function=check_repo))
63 63 m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
64 64 action="show", conditions=dict(method=["GET"],
65 65 function=check_repo))
66 66 #ajax delete repo perm user
67 67 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
68 68 action="delete_perm_user", conditions=dict(method=["DELETE"],
69 69 function=check_repo))
70 70
71 71 map.resource('user', 'users', controller='admin/users', path_prefix='/_admin')
72 72 map.resource('permission', 'permissions', controller='admin/permissions', path_prefix='/_admin')
73 73
74 74 #REST SETTINGS MAP
75 75 with map.submapper(path_prefix='/_admin', controller='admin/settings') as m:
76 76 m.connect("admin_settings", "/settings",
77 77 action="create", conditions=dict(method=["POST"]))
78 78 m.connect("admin_settings", "/settings",
79 79 action="index", conditions=dict(method=["GET"]))
80 80 m.connect("formatted_admin_settings", "/settings.{format}",
81 81 action="index", conditions=dict(method=["GET"]))
82 82 m.connect("admin_new_setting", "/settings/new",
83 83 action="new", conditions=dict(method=["GET"]))
84 84 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
85 85 action="new", conditions=dict(method=["GET"]))
86 86 m.connect("/settings/{setting_id}",
87 87 action="update", conditions=dict(method=["PUT"]))
88 88 m.connect("/settings/{setting_id}",
89 89 action="delete", conditions=dict(method=["DELETE"]))
90 90 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
91 91 action="edit", conditions=dict(method=["GET"]))
92 92 m.connect("formatted_admin_edit_setting", "/settings/{setting_id}.{format}/edit",
93 93 action="edit", conditions=dict(method=["GET"]))
94 94 m.connect("admin_setting", "/settings/{setting_id}",
95 95 action="show", conditions=dict(method=["GET"]))
96 96 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
97 97 action="show", conditions=dict(method=["GET"]))
98 98 m.connect("admin_settings_my_account", "/my_account",
99 99 action="my_account", conditions=dict(method=["GET"]))
100 100 m.connect("admin_settings_my_account_update", "/my_account_update",
101 101 action="my_account_update", conditions=dict(method=["PUT"]))
102 102 m.connect("admin_settings_create_repository", "/create_repository",
103 103 action="create_repository", conditions=dict(method=["GET"]))
104 104
105 105 #ADMIN
106 106 with map.submapper(path_prefix='/_admin', controller='admin/admin') as m:
107 107 m.connect('admin_home', '', action='index')#main page
108 108 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
109 109 action='add_repo')
110 110 #SEARCH
111 111 map.connect('search', '/_admin/search', controller='search')
112 112
113 113 #LOGIN/LOGOUT
114 114 map.connect('login_home', '/_admin/login', controller='login')
115 115 map.connect('logout_home', '/_admin/logout', controller='login', action='logout')
116 116 map.connect('register', '/_admin/register', controller='login', action='register')
117 117
118 118 #FEEDS
119 119 map.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
120 120 controller='feed', action='rss',
121 121 conditions=dict(function=check_repo))
122 122 map.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
123 123 controller='feed', action='atom',
124 124 conditions=dict(function=check_repo))
125 125
126 126
127 127 #OTHERS
128 128 map.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
129 129 controller='changeset', revision='tip',
130 130 conditions=dict(function=check_repo))
131 map.connect('raw_changeset_home', '/{repo_name:.*}/raw-changeset/{revision}',
132 controller='changeset',action='raw_changeset', revision='tip',
133 conditions=dict(function=check_repo))
131 134 map.connect('summary_home', '/{repo_name:.*}/summary',
132 135 controller='summary', conditions=dict(function=check_repo))
133 136 map.connect('shortlog_home', '/{repo_name:.*}/shortlog',
134 137 controller='shortlog', conditions=dict(function=check_repo))
135 138 map.connect('branches_home', '/{repo_name:.*}/branches',
136 139 controller='branches', conditions=dict(function=check_repo))
137 140 map.connect('tags_home', '/{repo_name:.*}/tags',
138 141 controller='tags', conditions=dict(function=check_repo))
139 142 map.connect('changelog_home', '/{repo_name:.*}/changelog',
140 143 controller='changelog', conditions=dict(function=check_repo))
141 144 map.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
142 145 controller='files', revision='tip', f_path='',
143 146 conditions=dict(function=check_repo))
144 147 map.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
145 148 controller='files', action='diff', revision='tip', f_path='',
146 149 conditions=dict(function=check_repo))
147 150 map.connect('files_raw_home', '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
148 151 controller='files', action='rawfile', revision='tip', f_path='',
149 152 conditions=dict(function=check_repo))
150 153 map.connect('files_annotate_home', '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
151 154 controller='files', action='annotate', revision='tip', f_path='',
152 155 conditions=dict(function=check_repo))
153 156 map.connect('files_archive_home', '/{repo_name:.*}/archive/{revision}/{fileformat}',
154 157 controller='files', action='archivefile', revision='tip',
155 158 conditions=dict(function=check_repo))
156 159 map.connect('repo_settings_update', '/{repo_name:.*}/settings',
157 160 controller='settings', action="update",
158 161 conditions=dict(method=["PUT"], function=check_repo))
159 162 map.connect('repo_settings_home', '/{repo_name:.*}/settings',
160 163 controller='settings', action='index',
161 164 conditions=dict(function=check_repo))
162 165
163 166
164 167 return map
@@ -1,97 +1,136 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # changeset controller for pylons
4 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5
6 5 # This program is free software; you can redistribute it and/or
7 6 # modify it under the terms of the GNU General Public License
8 7 # as published by the Free Software Foundation; version 2
9 8 # of the License or (at your opinion) any later version of the license.
10 9 #
11 10 # This program is distributed in the hope that it will be useful,
12 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 13 # GNU General Public License for more details.
15 14 #
16 15 # You should have received a copy of the GNU General Public License
17 16 # along with this program; if not, write to the Free Software
18 17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 18 # MA 02110-1301, USA.
20 19 """
21 20 Created on April 25, 2010
22 21 changeset controller for pylons
23 22 @author: marcink
24 23 """
25 from pylons import tmpl_context as c, url, request
24 from pylons import tmpl_context as c, url, request, response
26 25 from pylons.controllers.util import redirect
27 26 from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
28 27 from pylons_app.lib.base import BaseController, render
29 28 from pylons_app.model.hg_model import HgModel
30 29 from vcs.exceptions import RepositoryError
31 30 from vcs.nodes import FileNode
32 31 from vcs.utils import diffs as differ
33 32 import logging
34 33 import traceback
35 34
36 35 log = logging.getLogger(__name__)
37 36
38 37 class ChangesetController(BaseController):
39 38
40 39 @LoginRequired()
41 40 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
42 41 'repository.admin')
43 42 def __before__(self):
44 43 super(ChangesetController, self).__before__()
45 44
46 45 def index(self, revision):
47 46 hg_model = HgModel()
48 47 try:
49 48 c.changeset = hg_model.get_repo(c.repo_name).get_changeset(revision)
50 49 except RepositoryError:
51 50 log.error(traceback.format_exc())
52 51 return redirect(url('hg_home'))
53 52 else:
54 53 try:
55 54 c.changeset_old = c.changeset.parents[0]
56 55 except IndexError:
57 56 c.changeset_old = None
58 57 c.changes = []
59 58
60 59 for node in c.changeset.added:
61 60 filenode_old = FileNode(node.path, '')
62 61 if filenode_old.is_binary or node.is_binary:
63 62 diff = 'binary file'
64 63 else:
65 64 f_udiff = differ.get_udiff(filenode_old, node)
66 65 diff = differ.DiffProcessor(f_udiff).as_html()
67 try:
68 diff = unicode(diff)
69 except:
70 log.warning('Decoding failed of %s', filenode_old)
71 log.warning('Decoding failed of %s', node)
72 diff = 'unsupported type'
66
73 67 cs1 = None
74 68 cs2 = node.last_changeset.raw_id
75 69 c.changes.append(('added', node, diff, cs1, cs2))
76 70
77 71 for node in c.changeset.changed:
78 72 filenode_old = c.changeset_old.get_node(node.path)
79 73 if filenode_old.is_binary or node.is_binary:
80 74 diff = 'binary file'
81 75 else:
82 76 f_udiff = differ.get_udiff(filenode_old, node)
83 77 diff = differ.DiffProcessor(f_udiff).as_html()
84 try:
85 diff = unicode(diff)
86 except:
87 log.warning('Decoding failed of %s', filenode_old)
88 log.warning('Decoding failed of %s', node)
89 diff = 'unsupported type'
78
90 79 cs1 = filenode_old.last_changeset.raw_id
91 80 cs2 = node.last_changeset.raw_id
92 81 c.changes.append(('changed', node, diff, cs1, cs2))
93 82
94 83 for node in c.changeset.removed:
95 84 c.changes.append(('removed', node, None, None, None))
96 85
97 86 return render('changeset/changeset.html')
87
88 def raw_changeset(self,revision):
89
90 hg_model = HgModel()
91 try:
92 c.changeset = hg_model.get_repo(c.repo_name).get_changeset(revision)
93 except RepositoryError:
94 log.error(traceback.format_exc())
95 return redirect(url('hg_home'))
96 else:
97 try:
98 c.changeset_old = c.changeset.parents[0]
99 except IndexError:
100 c.changeset_old = None
101 c.changes = []
102
103 for node in c.changeset.added:
104 filenode_old = FileNode(node.path, '')
105 if filenode_old.is_binary or node.is_binary:
106 diff = 'binary file'
107 else:
108 f_udiff = differ.get_udiff(filenode_old, node)
109 diff = differ.DiffProcessor(f_udiff).raw_diff()
110
111 cs1 = None
112 cs2 = node.last_changeset.raw_id
113 c.changes.append(('added', node, diff, cs1, cs2))
114
115 for node in c.changeset.changed:
116 filenode_old = c.changeset_old.get_node(node.path)
117 if filenode_old.is_binary or node.is_binary:
118 diff = 'binary file'
119 else:
120 f_udiff = differ.get_udiff(filenode_old, node)
121 diff = differ.DiffProcessor(f_udiff).raw_diff()
122
123 cs1 = filenode_old.last_changeset.raw_id
124 cs2 = node.last_changeset.raw_id
125 c.changes.append(('changed', node, diff, cs1, cs2))
126
127 response.content_type = 'text/plain'
128
129 parent = True if len(c.changeset.parents) > 0 else False
130 c.parent_tmpl = 'Parent %s' % c.changeset.parents[0]._hex if parent else ''
131
132 c.diffs = ''
133 for x in c.changes:
134 c.diffs += x[2]
135
136 return render('changeset/raw_changeset.html')
General Comments 0
You need to be logged in to leave comments. Login now