forked from novoid/Memacs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmemacs_svn.py
executable file
·225 lines (190 loc) · 6.67 KB
/
memacs_svn.py
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time-stamp: <2011-10-28 15:13:31 aw>
import sys
import os
import logging
import xml.sax
from xml.sax._exceptions import SAXParseException
# needed to import common.*
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from common.orgproperty import OrgProperties
from common.orgformat import OrgFormat
from common.memacs import Memacs
from common.reader import CommonReader
PROG_VERSION_NUMBER = u"0.1"
PROG_VERSION_DATE = u"2011-12-27"
PROG_SHORT_DESCRIPTION = u"Memacs for svn"
PROG_TAG = u"svn"
PROG_DESCRIPTION = u"""
This Memacs module will parse output of svn log --xml
sample xml:
<?xml version="1.0"?>
<log>
<logentry
revision="13">
<author>bob</author>
<date>2011-11-05T18:18:22.936127Z</date>
<msg>Bugfix.</msg>
</logentry>
</log>
Then an Org-mode file is generated that contains information
about the log messages, author, and revision
"""
COPYRIGHT_YEAR = "2011-2012"
COPYRIGHT_AUTHORS = """Karl Voit <[email protected]>,
Armin Wieser <[email protected]>"""
class SvnSaxHandler(xml.sax.handler.ContentHandler):
"""
Sax handler for following xml's:
<?xml version="1.0"?>
<log>
<logentry
revision="13">
<author>bob</author>
<date>2011-11-05T18:18:22.936127Z</date>
<msg>Bugfix.</msg>
</logentry>
</log>
"""
def __init__(self, writer, grepauthor):
"""
Ctor
@param writer: orgwriter
"""
self.__reset()
self._writer = writer
self.__grepauthor = grepauthor
def __reset(self):
"""
resets all variables
"""
self.__author = ""
self.__date = ""
self.__msg = ""
self.__rev = -1
self.__on_node_name = "" # used to store on which element we are
self.__id_prefix = "rev-"
def __write(self):
"""
write attributes to writer (make an org_sub_item)
"""
logging.debug("msg:%s", self.__msg)
self.__msg = self.__msg.splitlines()
subject = ""
notes = ""
# idea: look for the first -nonempty- message
if len(self.__msg) > 0:
start_notes = 0
for i in range(len(self.__msg)):
if self.__msg[i].strip() != "":
subject = self.__msg[i].strip()
start_notes = i + 1
break
if len(self.__msg) > start_notes:
for n in self.__msg[start_notes:]:
if n != "":
notes += n + "\n"
output = "%s (r%d): %s" % (self.__author, self.__rev, subject)
properties = OrgProperties(data_for_hashing=self.__author + subject)
timestamp = OrgFormat.datetime(
OrgFormat.datetupelutctimestamp(self.__date))
properties.add("REVISION", self.__rev)
if self.__grepauthor == None or \
(self.__author.strip() == self.__grepauthor.strip()):
self._writer.write_org_subitem(output=output,
timestamp=timestamp,
note=notes,
properties=properties)
def characters(self, content):
"""
handles xml tags:
- <author/>
- <date/>
- <msg/>
and set those attributes
"""
logging.debug("Handler @characters @%s , content=%s",
self.__on_node_name, content)
if self.__on_node_name == "author":
self.__author += content
elif self.__on_node_name == "date":
self.__date += content
elif self.__on_node_name == "msg":
self.__msg += content
def startElement(self, name, attrs):
"""
at every <tag> remember the tagname
* sets the revision when in tag "logentry"
"""
logging.debug("Handler @startElement name=%s,attrs=%s", name, attrs)
if name == "logentry":
self.__rev = int(attrs['revision'])
self.__on_node_name = name
def endElement(self, name):
"""
at every </tag> clear the remembered tagname
if we are at </logentry> then we can write a entry to stream
"""
logging.debug("Handler @endElement name=%s", name)
self.__on_node_name = ""
if name == "logentry":
self.__write()
self.__reset()
class SvnMemacs(Memacs):
def _parser_add_arguments(self):
"""
overwritten method of class Memacs
add additional arguments
"""
Memacs._parser_add_arguments(self)
self._parser.add_argument(
"-f", "--file", dest="svnlogxmlfile",
action="store",
help="path to a an file which contains output from " + \
" following svn command: svn log --xml")
self._parser.add_argument(
"-g", "--grep-author", dest="grepauthor",
action="store",
help="if you wanna parse only messages from a specific person. " + \
"format:<author> of author to grep")
def _parser_parse_args(self):
"""
overwritten method of class Memacs
all additional arguments are parsed in here
"""
Memacs._parser_parse_args(self)
if self._args.svnlogxmlfile and not \
(os.path.exists(self._args.svnlogxmlfile) or \
os.access(self._args.svnlogxmlfile, os.R_OK)):
self._parser.error("input file not found or not readable")
def _main(self):
"""
get's automatically called from Memacs class
read the lines from svn xml file, parse and write them to org file
"""
# read file
if self._args.svnlogxmlfile:
logging.debug("using as %s input_stream", self._args.svnlogxmlfile)
data = CommonReader.get_data_from_file(self._args.svnlogxmlfile)
else:
logging.info("Using stdin as input_stream")
data = CommonReader.get_data_from_stdin()
try:
xml.sax.parseString(data.encode('utf-8'),
SvnSaxHandler(self._writer,
self._args.grepauthor))
except SAXParseException:
logging.error("No correct XML given")
sys.exit(1)
if __name__ == "__main__":
memacs = SvnMemacs(
prog_version=PROG_VERSION_NUMBER,
prog_version_date=PROG_VERSION_DATE,
prog_description=PROG_DESCRIPTION,
prog_short_description=PROG_SHORT_DESCRIPTION,
prog_tag=PROG_TAG,
copyright_year=COPYRIGHT_YEAR,
copyright_authors=COPYRIGHT_AUTHORS
)
memacs.handle_main()