My favorites | Sign in
Project Home Downloads Wiki Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/python2.4
"""Convert output from svn log -v --xml to ATOM"""

from datetime import datetime
import re
import sys
import urllib2
from xml.sax import make_parser, SAXParseException
from xml.sax.handler import ContentHandler
from xml.sax.saxutils import escape
ATOM_ID = ''

__version__ = '1.0'

class SvnLogHandler(ContentHandler):
"""Convert Subversion Commit Log XML to Atom."""
def __init__(self):
"""Initialise instance variables."""
self._content = u''
self.paths = []
self.msg = u''
self.author = u''
self.date = u''
self.revision = u''
self.is_msg = False
self.is_author = False
self.is_date = False
self.is_path = False
ContentHandler.__init__(self)

@property
def content(self):
"""The generated Atom content."""
return self._content

def startElement(self, name, attrs):
"""Set flags depending on which Subversion log element is parsed."""
if name == 'logentry':
self.revision = attrs.get('revision', u"")
elif name == 'msg':
self.is_msg = True
elif name == 'author':
self.is_author = True
elif name == 'date':
self.is_date = True
elif name == 'path':
self.is_path = True
self.paths.append([attrs.get('action', u""),u''])
return

def characters(self, content):
"""Extract the content of the element."""
if self.is_msg:
self.msg += content
elif self.is_author:
self.author = content
elif self.is_date:
self.date = content
elif self.is_path:
self.paths[-1][1] += content

def endElement(self, name):
"""Reset all the element flags and generate Atom XML if we have
reached the end of a logentry."""
if name == 'logentry':
self._content += "<entry>"
_title = escape(u"%s: %s" % (self.revision,
self.msg.replace('\n', ' ')))
self._content += u'<title type="text">%s</title>' % _title
self._content += u"<id>%s:%s</id>" % (ATOM_ID, self.revision)
self._content += u"<updated>%s</updated>" % self.date
self._content += u'<link rel="alternate" href="#" />'
self._content += u"<author><name>%s</name></author>" % self.author
_summary = escape(u'<p>%s</p><p>Files:<ul>%s</ul></p>' %
(self.msg.replace('\n', '<br/>'),
''.join([u"<li>%s %s</li>" % (a,p) for a,p in self.paths])))
self._content += (u'<summary type="html" xml:space="preserve">%s'
'</summary>' % _summary)
self._content += u"</entry>"
self.paths = []
self.msg = u''
elif name == 'msg':
self.is_msg = False
elif name == 'author':
self.is_author = False
elif name == 'date':
self.is_date = False
elif name == 'path':
self.is_path = False

def generate(file_object, title, link):
"""Generate the Atom xml."""
global ATOM_ID
now = datetime.utcnow()
now = u"%sT%.2d:%.2d:%.2dZ" % (now.date(), now.hour, now.minute, now.second)
ATOM_ID = u'tag:svnlogatom.py,2010:%s' % re.sub(r'^.*:/+', '', file_object.url)
header = u"""<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>%s</title>
<link href="%s" />
<updated>%s</updated>
<id>%s</id>
<generator uri="svnlogatom.py" version="%s">SVN Log to Atom</generator>
""" % (title, link, now, ATOM_ID, __version__)
footer = "</feed>"
parser = make_parser()
handler = SvnLogHandler()
parser.setContentHandler(handler)
try:
parser.parse(file_object)
except SAXParseException, err:
sys.stderr.write("%s\n" % err)
sys.exit(1)
content = parser.getContentHandler().content
return u"%s%s%s" % (header, content, footer)

if __name__ == '__main__':
__title = ''
__link = ''
if len(sys.argv) < 2:
sys.stderr.write("Usage: %s uri [title] [link]\n" % sys.argv[0])
sys.exit(2)

try:
__file_obj = urllib2.urlopen(sys.argv[1])
except Exception, __err:
sys.stderr.write("%s\n" % __err)
sys.exit(2)

try:
__title = sys.argv[2]
except IndexError:
__title = sys.argv[1]
try:
__link = sys.argv[3]
except IndexError:
__link = sys.argv[1]
print generate(__file_obj, __title, __link).encode('utf8')

Change log

r56 by mattimustang on Mar 21, 2010   Diff
Most string converted to unicode and
output encoded as utf8.
Made ATOM output validate by adding proper
id tags to feed and entries, a link
rel=alternate to items.
Fixed formatting of updated date string.
Go to: 
Project members, sign in to write a code review

Older revisions

r34 by mattimustang on Jul 31, 2009   Diff
Much improved version with:

 * command line arguments for svn log
uri, title and Atom feed link.
 * better error handling.
...
r31 by mattimustang on Jul 20, 2009   Diff
svn log to atom script.
All revisions of this file

File info

Size: 4595 bytes, 138 lines

File properties

svn:eol-style
native
Powered by Google Project Hosting