1111import sys
1212import tempfile
1313import xml2rfc
14+ from contextlib import ExitStack
1415
1516from email .utils import formataddr
1617from unidecode import unidecode
@@ -164,26 +165,41 @@ def format_messages(where, e, log):
164165 if self .cleaned_data .get ('xml' ):
165166 #if not self.cleaned_data.get('txt'):
166167 xml_file = self .cleaned_data .get ('xml' )
167- name , ext = os .path .splitext (os .path .basename (xml_file .name ))
168- tfh , tfn = tempfile .mkstemp (prefix = name + '-' , suffix = '.xml' )
169168 file_name = {}
170169 xml2rfc .log .write_out = io .StringIO () # open(os.devnull, "w")
171170 xml2rfc .log .write_err = io .StringIO () # open(os.devnull, "w")
172- try :
171+ tfn = None
172+ with ExitStack () as stack :
173+ @stack .callback
174+ def cleanup (): # called when context exited, even in case of exception
175+ if tfn is not None :
176+ os .unlink (tfn )
177+
173178 # We need to write the xml file to disk in order to hand it
174179 # over to the xml parser. XXX FIXME: investigate updating
175180 # xml2rfc to be able to work with file handles to in-memory
176181 # files.
177- with io .open (tfn , 'wb+' ) as tf :
182+ name , ext = os .path .splitext (os .path .basename (xml_file .name ))
183+ with tempfile .NamedTemporaryFile (prefix = name + '-' ,
184+ suffix = '.xml' ,
185+ mode = 'wb+' ,
186+ delete = False ) as tf :
187+ tfn = tf .name
178188 for chunk in xml_file .chunks ():
179189 tf .write (chunk )
180190 os .environ ["XML_LIBRARY" ] = settings .XML_LIBRARY
191+
192+ parser = xml2rfc .XmlRfcParser (str (tfn ), quiet = True )
181193 # --- Parse the xml ---
182194 try :
183- parser = xml2rfc . XmlRfcParser ( str ( tfn ), quiet = True )
184- self . xmltree = parser . parse ( remove_comments = False , quiet = True )
195+ self . xmltree = parser . parse ( remove_comments = False )
196+ # If we have v2, run it through v2v3. Keep track of the submitted version, though.
185197 self .xmlroot = self .xmltree .getroot ()
186198 self .xml_version = self .xmlroot .get ('version' , '2' )
199+ if self .xml_version == '2' :
200+ v2v3 = xml2rfc .V2v3XmlWriter (self .xmltree )
201+ self .xmltree .tree = v2v3 .convert2to3 ()
202+ self .xmlroot = self .xmltree .getroot () # update to the new root
187203
188204 draftname = self .xmlroot .attrib .get ('docName' )
189205 if draftname is None :
@@ -225,12 +241,11 @@ def format_messages(where, e, log):
225241 # --- Prep the xml ---
226242 file_name ['xml' ] = os .path .join (settings .IDSUBMIT_STAGING_PATH , '%s-%s%s' % (self .filename , self .revision , ext ))
227243 try :
228- if self .xml_version == '3' :
229- prep = xml2rfc .PrepToolWriter (self .xmltree , quiet = True , liberal = True , keep_pis = [xml2rfc .V3_PI_TARGET ])
230- prep .options .accept_prepped = True
231- self .xmltree .tree = prep .prep ()
232- if self .xmltree .tree == None :
233- self .add_error ('xml' , "Error from xml2rfc (prep): %s" % prep .errors )
244+ prep = xml2rfc .PrepToolWriter (self .xmltree , quiet = True , liberal = True , keep_pis = [xml2rfc .V3_PI_TARGET ])
245+ prep .options .accept_prepped = True
246+ self .xmltree .tree = prep .prep ()
247+ if self .xmltree .tree == None :
248+ self .add_error ('xml' , "Error from xml2rfc (prep): %s" % prep .errors )
234249 except Exception as e :
235250 msgs = format_messages ('prep' , e , xml2rfc .log )
236251 self .add_error ('xml' , msgs )
@@ -239,15 +254,9 @@ def format_messages(where, e, log):
239254 if not ('txt' in self .cleaned_data and self .cleaned_data ['txt' ]):
240255 file_name ['txt' ] = os .path .join (settings .IDSUBMIT_STAGING_PATH , '%s-%s.txt' % (self .filename , self .revision ))
241256 try :
242- if self .xml_version != '3' :
243- self .xmltree = parser .parse (remove_comments = True , quiet = True )
244- self .xmlroot = self .xmltree .getroot ()
245- pagedwriter = xml2rfc .PaginatedTextRfcWriter (self .xmltree , quiet = True )
246- pagedwriter .write (file_name ['txt' ])
247- else :
248- writer = xml2rfc .TextWriter (self .xmltree , quiet = True )
249- writer .options .accept_prepped = True
250- writer .write (file_name ['txt' ])
257+ writer = xml2rfc .TextWriter (self .xmltree , quiet = True )
258+ writer .options .accept_prepped = True
259+ writer .write (file_name ['txt' ])
251260 log .log ("In %s: xml2rfc %s generated %s from %s (version %s)" %
252261 ( os .path .dirname (file_name ['xml' ]),
253262 xml2rfc .__version__ ,
@@ -260,51 +269,28 @@ def format_messages(where, e, log):
260269 self .add_error ('xml' , msgs )
261270
262271 # --- Convert to html ---
263- if self .xml_version == '3' :
264- try :
265- file_name ['html' ] = os .path .join (settings .IDSUBMIT_STAGING_PATH , '%s-%s.html' % (self .filename , self .revision ))
266- writer = xml2rfc .HtmlWriter (self .xmltree , quiet = True )
267- writer .write (file_name ['html' ])
268- self .file_types .append ('.html' )
269- log .log ("In %s: xml2rfc %s generated %s from %s (version %s)" %
270- ( os .path .dirname (file_name ['xml' ]),
271- xml2rfc .__version__ ,
272- os .path .basename (file_name ['html' ]),
273- os .path .basename (file_name ['xml' ]),
274- self .xml_version ))
275- except Exception as e :
276- msgs = format_messages ('html' , e , xml2rfc .log )
277- self .add_error ('xml' , msgs )
272+ try :
273+ file_name ['html' ] = os .path .join (settings .IDSUBMIT_STAGING_PATH , '%s-%s.html' % (self .filename , self .revision ))
274+ writer = xml2rfc .HtmlWriter (self .xmltree , quiet = True )
275+ writer .write (file_name ['html' ])
276+ self .file_types .append ('.html' )
277+ log .log ("In %s: xml2rfc %s generated %s from %s (version %s)" %
278+ ( os .path .dirname (file_name ['xml' ]),
279+ xml2rfc .__version__ ,
280+ os .path .basename (file_name ['html' ]),
281+ os .path .basename (file_name ['xml' ]),
282+ self .xml_version ))
283+ except Exception as e :
284+ msgs = format_messages ('html' , e , xml2rfc .log )
285+ self .add_error ('xml' , msgs )
278286
279- if self .xml_version == '2' :
280- ok , errors = self .xmltree .validate ()
281- else :
282- ok , errors = True , ''
283-
284- if not ok :
285- # Each error has properties:
286- #
287- # message: the message text
288- # domain: the domain ID (see lxml.etree.ErrorDomains)
289- # type: the message type ID (see lxml.etree.ErrorTypes)
290- # level: the log level ID (see lxml.etree.ErrorLevels)
291- # line: the line at which the message originated (if applicable)
292- # column: the character column at which the message originated (if applicable)
293- # filename: the name of the file in which the message originated (if applicable)
294- self .add_error ('xml' ,
295- [ forms .ValidationError ("One or more XML validation errors occurred when processing the XML file:" ) ] +
296- [ forms .ValidationError ("%s: Line %s: %s" % (xml_file .name , r .line , r .message ), code = "%s" % r .type ) for r in errors ]
297- )
298287 except Exception as e :
299288 try :
300289 msgs = format_messages ('txt' , e , xml2rfc .log )
301290 log .log ('\n ' .join (msgs ))
302291 self .add_error ('xml' , msgs )
303292 except Exception :
304293 self .add_error ('xml' , "An exception occurred when trying to process the XML file: %s" % e )
305- finally :
306- os .close (tfh )
307- os .unlink (tfn )
308294
309295 if self .cleaned_data .get ('txt' ):
310296 # try to parse it
0 commit comments