##// END OF EJS Templates
few validation bugfixes/ new repo changesets, first commit changesets
marcink -
r285:42f5c368 default
parent child Browse files
Show More
@@ -1,86 +1,96 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # changeset controller for pylons
3 # changeset controller for pylons
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 from pylons import tmpl_context as c, url
6 from pylons.controllers.util import redirect
7 from pylons_app.lib.auth import LoginRequired
8 from pylons_app.lib.base import BaseController, render
9 from pylons_app.model.hg_model import HgModel
10 from vcs.exceptions import RepositoryError
11 from vcs.nodes import FileNode
12 from vcs.utils import diffs as differ
13 import logging
14 import traceback
5
15
6 # This program is free software; you can redistribute it and/or
16 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
17 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
18 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
19 # of the License or (at your opinion) any later version of the license.
10 #
20 #
11 # This program is distributed in the hope that it will be useful,
21 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
24 # GNU General Public License for more details.
15 #
25 #
16 # You should have received a copy of the GNU General Public License
26 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
27 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
28 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
29 # MA 02110-1301, USA.
20 """
30 """
21 Created on April 25, 2010
31 Created on April 25, 2010
22 changeset controller for pylons
32 changeset controller for pylons
23 @author: marcink
33 @author: marcink
24 """
34 """
25 from pylons import tmpl_context as c
26 from pylons_app.lib.auth import LoginRequired
27 from pylons_app.lib.base import BaseController, render
28 from pylons_app.model.hg_model import HgModel
29 from vcs.utils import diffs as differ
30 import logging
31 from vcs.nodes import FileNode
32
35
33
36
34 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
35
38
36 class ChangesetController(BaseController):
39 class ChangesetController(BaseController):
37
40
38 @LoginRequired()
41 @LoginRequired()
39 def __before__(self):
42 def __before__(self):
40 super(ChangesetController, self).__before__()
43 super(ChangesetController, self).__before__()
41
44
42 def index(self, revision):
45 def index(self, revision):
43 hg_model = HgModel()
46 hg_model = HgModel()
44 c.changeset = hg_model.get_repo(c.repo_name).get_changeset(revision)
47 try:
45 c.changeset_old = c.changeset.parents[0]
48 c.changeset = hg_model.get_repo(c.repo_name).get_changeset(revision)
46 c.changes = []
49 except RepositoryError:
47
50 log.error(traceback.format_exc())
51 return redirect(url('hg_home'))
52 else:
53 try:
54 c.changeset_old = c.changeset.parents[0]
55 except IndexError:
56 c.changeset_old = None
57 c.changes = []
58
59 for node in c.changeset.added:
60 filenode_old = FileNode(node.path, '')
61 if filenode_old.is_binary or node.is_binary:
62 diff = 'binary file'
63 else:
64 f_udiff = differ.get_udiff(filenode_old, node)
65 diff = differ.DiffProcessor(f_udiff).as_html()
66 try:
67 diff = unicode(diff)
68 except:
69 log.warning('Decoding failed of %s', filenode_old)
70 log.warning('Decoding failed of %s', node)
71 diff = 'unsupported type'
72 cs1 = None
73 cs2 = node.last_changeset.raw_id
74 c.changes.append(('added', node, diff, cs1, cs2))
48
75
49 for node in c.changeset.added:
76 for node in c.changeset.changed:
50 filenode_old = FileNode(node.path, '')
77 filenode_old = c.changeset_old.get_node(node.path)
51 if filenode_old.is_binary or node.is_binary:
78 if filenode_old.is_binary or node.is_binary:
52 diff = 'binary file'
79 diff = 'binary file'
53 else:
80 else:
54 f_udiff = differ.get_udiff(filenode_old, node)
81 f_udiff = differ.get_udiff(filenode_old, node)
55 diff = differ.DiffProcessor(f_udiff).as_html()
82 diff = differ.DiffProcessor(f_udiff).as_html()
56 try:
83 try:
57 diff = unicode(diff)
84 diff = unicode(diff)
58 except:
85 except:
59 log.warning('Decoding failed of %s', filenode_old)
86 log.warning('Decoding failed of %s', filenode_old)
60 log.warning('Decoding failed of %s', node)
87 log.warning('Decoding failed of %s', node)
61 diff = 'unsupported type'
88 diff = 'unsupported type'
62 cs1 = None
89 cs1 = filenode_old.last_changeset.raw_id
63 cs2 = node.last_changeset.raw_id
90 cs2 = node.last_changeset.raw_id
64 c.changes.append(('added', node, diff, cs1, cs2))
91 c.changes.append(('changed', node, diff, cs1, cs2))
65
92
66 for node in c.changeset.changed:
93 for node in c.changeset.removed:
67 filenode_old = c.changeset_old.get_node(node.path)
94 c.changes.append(('removed', node, None, None, None))
68 if filenode_old.is_binary or node.is_binary:
69 diff = 'binary file'
70 else:
71 f_udiff = differ.get_udiff(filenode_old, node)
72 diff = differ.DiffProcessor(f_udiff).as_html()
73 try:
74 diff = unicode(diff)
75 except:
76 log.warning('Decoding failed of %s', filenode_old)
77 log.warning('Decoding failed of %s', node)
78 diff = 'unsupported type'
79 cs1 = filenode_old.last_changeset.raw_id
80 cs2 = node.last_changeset.raw_id
81 c.changes.append(('changed', node, diff, cs1, cs2))
82
83 for node in c.changeset.removed:
84 c.changes.append(('removed', node, None, None, None))
85
95
86 return render('changeset/changeset.html')
96 return render('changeset/changeset.html')
@@ -1,92 +1,92 b''
1 <%inherit file="/base/base.html"/>
1 <%inherit file="/base/base.html"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${_('Changeset')}
4 ${_('Changeset')}
5 </%def>
5 </%def>
6 <%def name="breadcrumbs()">
6 <%def name="breadcrumbs()">
7 ${h.link_to(u'Home',h.url('/'))}
7 ${h.link_to(u'Home',h.url('/'))}
8 /
8 /
9 ${h.link_to(c.repo_name,h.url('changeset_home',repo_name=c.repo_name))}
9 ${h.link_to(c.repo_name,h.url('changeset_home',repo_name=c.repo_name))}
10 /
10 /
11 ${_('changeset')}
11 ${_('changeset')}
12 </%def>
12 </%def>
13 <%def name="page_nav()">
13 <%def name="page_nav()">
14 ${self.menu('changelog')}
14 ${self.menu('changelog')}
15 </%def>
15 </%def>
16 <%def name="css()">
16 <%def name="css()">
17 <link rel="stylesheet" href="/css/monoblue_custom.css" type="text/css" />
17 <link rel="stylesheet" href="/css/monoblue_custom.css" type="text/css" />
18 <link rel="stylesheet" href="/css/diff.css" type="text/css" />
18 <link rel="stylesheet" href="/css/diff.css" type="text/css" />
19 </%def>
19 </%def>
20 <%def name="main()">
20 <%def name="main()">
21 <h2 class="no-link no-border">${_('Changeset')} - r${c.changeset.revision}:${c.changeset.raw_id}</h2>
21 <h2 class="no-link no-border">${_('Changeset')} - r${c.changeset.revision}:${c.changeset.raw_id}</h2>
22
22
23 <div id="changeset_content">
23 <div id="changeset_content">
24 <div class="container">
24 <div class="container">
25 <div class="left">
25 <div class="left">
26 <div class="date">${_('Date')}: ${c.changeset.date}</div>
26 <div class="date">${_('Date')}: ${c.changeset.date}</div>
27 <div class="author">${_('Author')}: ${c.changeset.author}</div>
27 <div class="author">${_('Author')}: ${c.changeset.author}</div>
28 <div class="message">
28 <div class="message">
29 ${c.changeset.message}
29 ${h.wrap_paragraphs(c.changeset.message)}
30 </div>
30 </div>
31 </div>
31 </div>
32 <div class="right">
32 <div class="right">
33 <span class="logtags">
33 <span class="logtags">
34 <span class="branchtag">${c.changeset.branch}</span>
34 <span class="branchtag">${c.changeset.branch}</span>
35 %for tag in c.changeset.tags:
35 %for tag in c.changeset.tags:
36 <span class="tagtag">${tag}</span>
36 <span class="tagtag">${tag}</span>
37 %endfor
37 %endfor
38 </span>
38 </span>
39 %if len(c.changeset.parents)>1:
39 %if len(c.changeset.parents)>1:
40 <div class="merge">
40 <div class="merge">
41 ${_('merge')}
41 ${_('merge')}
42 <img alt="merge" src="/images/icons/arrow_join.png">
42 <img alt="merge" src="/images/icons/arrow_join.png">
43 </div>
43 </div>
44 %endif
44 %endif
45 %for p_cs in reversed(c.changeset.parents):
45 %for p_cs in reversed(c.changeset.parents):
46 <div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(p_cs.raw_id,
46 <div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(p_cs.raw_id,
47 h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}
47 h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}
48 </div>
48 </div>
49 %endfor
49 %endfor
50 </div>
50 </div>
51 </div>
51 </div>
52 </div>
52 </div>
53
53
54 <div style="clear:both;height:10px"></div>
54 <div style="clear:both;height:10px"></div>
55 <div class="cs_files">
55 <div class="cs_files">
56 %for change,filenode,diff,cs1,cs2 in c.changes:
56 %for change,filenode,diff,cs1,cs2 in c.changes:
57 <div class="cs_${change}">${h.link_to(filenode.path,h.url.current(anchor='CHANGE-%s'%filenode.path))}</div>
57 <div class="cs_${change}">${h.link_to(filenode.path,h.url.current(anchor='CHANGE-%s'%filenode.path))}</div>
58 %endfor
58 %endfor
59 </div>
59 </div>
60
60
61 %for change,filenode,diff,cs1,cs2 in c.changes:
61 %for change,filenode,diff,cs1,cs2 in c.changes:
62 %if change !='removed':
62 %if change !='removed':
63 <div style="clear:both;height:10px"></div>
63 <div style="clear:both;height:10px"></div>
64 <div id="body" class="diffblock">
64 <div id="body" class="diffblock">
65 <div id="${'CHANGE-%s'%filenode.path}" class="code-header">
65 <div id="${'CHANGE-%s'%filenode.path}" class="code-header">
66 <div>
66 <div>
67 <span>
67 <span>
68 ${h.link_to_if(change!='removed',filenode.path,h.url('files_home',repo_name=c.repo_name,
68 ${h.link_to_if(change!='removed',filenode.path,h.url('files_home',repo_name=c.repo_name,
69 revision=filenode.changeset.raw_id,f_path=filenode.path))}
69 revision=filenode.changeset.raw_id,f_path=filenode.path))}
70 </span>
70 </span>
71 %if 1:
71 %if 1:
72 &raquo; <span style="font-size:77%">${h.link_to(_('diff'),
72 &raquo; <span style="font-size:77%">${h.link_to(_('diff'),
73 h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='diff'))}</span>
73 h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='diff'))}</span>
74 &raquo; <span style="font-size:77%">${h.link_to(_('raw diff'),
74 &raquo; <span style="font-size:77%">${h.link_to(_('raw diff'),
75 h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='raw'))}</span>
75 h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='raw'))}</span>
76 &raquo; <span style="font-size:77%">${h.link_to(_('download diff'),
76 &raquo; <span style="font-size:77%">${h.link_to(_('download diff'),
77 h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='download'))}</span>
77 h.url('files_diff_home',repo_name=c.repo_name,f_path=filenode.path,diff2=cs2,diff1=cs1,diff='download'))}</span>
78 %endif
78 %endif
79 </div>
79 </div>
80 </div>
80 </div>
81 <div class="code-body">
81 <div class="code-body">
82 %if diff:
82 %if diff:
83 ${diff|n}
83 ${diff|n}
84 %else:
84 %else:
85 ${_('No changes in this file')}
85 ${_('No changes in this file')}
86 %endif
86 %endif
87 </div>
87 </div>
88 </div>
88 </div>
89 %endif
89 %endif
90 %endfor
90 %endfor
91
91
92 </%def> No newline at end of file
92 </%def>
@@ -1,53 +1,53 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="base/base.html"/>
2 <%inherit file="base/base.html"/>
3 <%def name="title()">
3 <%def name="title()">
4 ${c.repos_prefix} Mercurial Repositories
4 ${c.repos_prefix} Mercurial Repositories
5 </%def>
5 </%def>
6 <%def name="breadcrumbs()">
6 <%def name="breadcrumbs()">
7 ${c.repos_prefix} Mercurial Repositories
7 ${c.repos_prefix} Mercurial Repositories
8 </%def>
8 </%def>
9 <%def name="page_nav()">
9 <%def name="page_nav()">
10 ${self.menu('home')}
10 ${self.menu('home')}
11 </%def>
11 </%def>
12 <%def name="main()">
12 <%def name="main()">
13 <%def name="get_sort(name)">
13 <%def name="get_sort(name)">
14 <%name_slug = name.lower().replace(' ','_') %>
14 <%name_slug = name.lower().replace(' ','_') %>
15 %if name_slug == c.cs_slug:
15 %if name_slug == c.cs_slug:
16 <span style="font-weight: bold;text-decoration: underline;">${name}</span>
16 <span style="font-weight: bold;text-decoration: underline;">${name}</span>
17 %else:
17 %else:
18 <span style="font-weight: bold">${name}</span>
18 <span style="font-weight: bold">${name}</span>
19 %endif
19 %endif
20 <a style="color:#FFF" href="?sort=${name_slug}">&darr;</a>
20 <a style="color:#FFF" href="?sort=${name_slug}">&darr;</a>
21 <a style="color:#FFF" href="?sort=-${name_slug}">&uarr;</a>
21 <a style="color:#FFF" href="?sort=-${name_slug}">&uarr;</a>
22 </%def>
22 </%def>
23 <table class="table_disp">
23 <table class="table_disp">
24 <tr class="header">
24 <tr class="header">
25 <td>${get_sort(_('Name'))}</td>
25 <td>${get_sort(_('Name'))}</td>
26 <td>${get_sort(_('Description'))}</td>
26 <td>${get_sort(_('Description'))}</td>
27 <td>${get_sort(_('Last change'))}</td>
27 <td>${get_sort(_('Last change'))}</td>
28 <td>${get_sort(_('Tip'))}</td>
28 <td>${get_sort(_('Tip'))}</td>
29 <td>${get_sort(_('Contact'))}</td>
29 <td>${get_sort(_('Contact'))}</td>
30 <td>${_('RSS')}</td>
30 <td>${_('RSS')}</td>
31 <td>${_('Atom')}</td>
31 <td>${_('Atom')}</td>
32 </tr>
32 </tr>
33 %for cnt,repo in enumerate(c.repos_list):
33 %for cnt,repo in enumerate(c.repos_list):
34 <tr class="parity${cnt%2}">
34 <tr class="parity${cnt%2}">
35 <td>${h.link_to(repo['name'],
35 <td>${h.link_to(repo['name'],
36 h.url('summary_home',repo_name=repo['name']))}</td>
36 h.url('summary_home',repo_name=repo['name']))}</td>
37 <td title="${repo['description']}">${h.truncate(repo['description'],60)}</td>
37 <td title="${repo['description']}">${h.truncate(repo['description'],60)}</td>
38 <td>${h.age(repo['last_change'])}</td>
38 <td>${h.age(repo['last_change'])}</td>
39 <td>${h.link_to('r%s:%s' % (repo['rev'],repo['tip']),
39 <td>${h.link_to_if(repo['rev']>=0,'r%s:%s' % (repo['rev'],repo['tip']),
40 h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']),
40 h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']),
41 class_="tooltip",
41 class_="tooltip",
42 tooltip_title=h.tooltip(repo['last_msg']))}</td>
42 tooltip_title=h.tooltip(repo['last_msg']))}</td>
43 <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
43 <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
44 <td>
44 <td>
45 <a title="${_('Subscribe to %s rss feed')%repo['name']}" class="rss_logo" href="${h.url('rss_feed_home',repo_name=repo['name'])}"></a>
45 <a title="${_('Subscribe to %s rss feed')%repo['name']}" class="rss_logo" href="${h.url('rss_feed_home',repo_name=repo['name'])}"></a>
46 </td>
46 </td>
47 <td>
47 <td>
48 <a title="${_('Subscribe to %s atom feed')%repo['name']}" class="atom_logo" href="${h.url('atom_feed_home',repo_name=repo['name'])}"></a>
48 <a title="${_('Subscribe to %s atom feed')%repo['name']}" class="atom_logo" href="${h.url('atom_feed_home',repo_name=repo['name'])}"></a>
49 </td>
49 </td>
50 </tr>
50 </tr>
51 %endfor
51 %endfor
52 </table>
52 </table>
53 </%def>
53 </%def>
General Comments 0
You need to be logged in to leave comments. Login now