From 5a644c2f828fc3a639d6f388ae6dab95bb19c04b Mon Sep 17 00:00:00 2001 From: Rick White Date: Tue, 31 Jan 2012 19:41:38 -0500 Subject: [PATCH] Added write support (nzb_parser.writetostring() and nzb_parser.writetofile()) --- README.rst | 21 +++++++++--- pynzb/base.py | 80 +++++++++++++++++++++++++++++++++++++++++++++- pynzb/etree_nzb.py | 5 ++- pynzb/lxml_nzb.py | 5 ++- 4 files changed, 104 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index 76dbaa9..05fef4e 100644 --- a/README.rst +++ b/README.rst @@ -67,7 +67,17 @@ argument:: files = nzb_parser.parse('') -This will return a list of ``NZBFiles`` for you to use. +This will return a list of ``NZBFiles`` for you to use. You can then pass this +list (or a list of NZBFiles populated by any other code) to one of two ``writeto`` +methods:: + + nzb_parser.writetofile(files, 'C:\\output.nzb') + +...which will write out an NZB file or:: + + nzbstring = nzb_parser.writetostring(files) + +...which will return the NZB-formatted XML as a string. NZBFile Objects @@ -114,8 +124,8 @@ on how to retrieve a part of a file. Here's what you can find on an Example -------- -In this example, we will grab an Ubuntu NZB and parse the file, printing out -some information about each file and its segments:: +In this example, we will grab an Ubuntu NZB and parse the file, print out +some information about each file and its segments, and write it back out:: from pynzb import nzb_parser from urllib2 import urlopen @@ -132,4 +142,7 @@ some information about each file and its segments:: for segment in nzb_file.segments[:2]: print ' ' + segment.message_id if len(nzb_file.segments) > 2: - print ' ...' \ No newline at end of file + print ' ...' + + #Write the NZB to the hard-drive: + nzb_parser.writetofile(files, 'C:\\sample-ubuntu-nzb.nzb') \ No newline at end of file diff --git a/pynzb/base.py b/pynzb/base.py index 8539a2e..6fa0fb9 100644 --- a/pynzb/base.py +++ b/pynzb/base.py @@ -1,5 +1,6 @@ import datetime import time +import os def parse_date(date): if isinstance(date, basestring): @@ -49,6 +50,9 @@ class BaseETreeNZBParser(BaseNZBParser): def get_etree_iter(self, xml, et=None): raise NotImplementedError + def get_etree_module(self, et=None): + raise NotImplementedError + def parse(self, xml): context = self.get_etree_iter(xml) files, current_file, current_segment = [], None, None @@ -81,4 +85,78 @@ def parse(self, xml): ) # Clear the element, we don't need it any more. elem.clear() - return files \ No newline at end of file + return files + + def NZBtoXMLElement(self, files): + + etree = self.get_etree_module() + + nzbnode = etree.Element('nzb') + nzbnode.attrib['xmlns'] = 'http://www.newzbin.com/DTD/2003/nzb' + + #Create files + for file in files: + #Create file + filenode = etree.Element('file') + filenode.attrib['poster'] = file.poster + timeformat = '%Y-%m-%d' + filenode.attrib['date'] = str(int(time.mktime(time.strptime(str(file.date), timeformat)))) + filenode.attrib['subject'] = file.subject + + #Create groups + groupsnode = etree.Element('groups') + for group in file.groups: + groupnode = etree.Element('group') + groupnode.text = group + groupsnode.append(groupnode) + + filenode.append(groupsnode) + + #Create segments + segmentsnode = etree.Element('segments') + for segment in file.segments: + segmentnode = etree.Element('segment') + segmentnode.attrib['bytes'] = str(segment.bytes) + segmentnode.attrib['number'] = str(segment.number) + segmentnode.text = segment.message_id + segmentsnode.append(segmentnode) + filenode.append(segmentsnode) + + nzbnode.append(filenode) + + def indent(elem, level=0): + i = "\n" + level*" " + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = i + " " + if not elem.tail or not elem.tail.strip(): + elem.tail = i + for elem in elem: + indent(elem, level+1) + if not elem.tail or not elem.tail.strip(): + elem.tail = i + else: + if level and (not elem.tail or not elem.tail.strip()): + elem.tail = i + + indent(nzbnode) + return nzbnode + + def writetostring(self, files): + etree = self.get_etree_module() + return etree.tostring(self.NZBtoXMLElement(files), 'iso-8859-1') + + def writetofile(self, files, path): + if os.access(os.path.dirname(os.path.abspath(path)), os.W_OK): + nzbelem = self.writetostring(files) + try: + outfile = open(path, 'w') + outfile.write(nzbelem) + outfile.close() + except IOError as (errno, strerror): + print "I/O error({0}): {1}".format(errno, strerror) + else: + print 'Path (' + path + ') does not exist!' + + + \ No newline at end of file diff --git a/pynzb/etree_nzb.py b/pynzb/etree_nzb.py index ebbb6e6..f15b791 100644 --- a/pynzb/etree_nzb.py +++ b/pynzb/etree_nzb.py @@ -16,4 +16,7 @@ class ETreeNZBParser(BaseETreeNZBParser): def get_etree_iter(self, xml, et=etree): - return iter(et.iterparse(StringIO(xml), events=("start", "end"))) \ No newline at end of file + return iter(et.iterparse(StringIO(xml), events=("start", "end"))) + + def get_etree_module(self, et=etree): + return et \ No newline at end of file diff --git a/pynzb/lxml_nzb.py b/pynzb/lxml_nzb.py index 790671d..f029efa 100644 --- a/pynzb/lxml_nzb.py +++ b/pynzb/lxml_nzb.py @@ -13,4 +13,7 @@ class LXMLNZBParser(BaseETreeNZBParser): def get_etree_iter(self, xml, et=etree): - return iter(et.iterparse(StringIO(xml), events=("start", "end"))) \ No newline at end of file + return iter(et.iterparse(StringIO(xml), events=("start", "end"))) + + def get_etree_module(self, et=etree): + return et \ No newline at end of file