"""ListSubmissions.py Lists submissions, limiting search with options, and using remaining arguments to format the final output. Options: -cCODE, --code=CODE Gets submission for the story code -mMARKET, --market=MARKET Gets the stories that have gone to that market -yYEAR, --year=YEAR Limits results to given year -sSTATUS, --status=STATUS Limits results to given status (InMail,Reject,Sale) -e, --email Limits results to email submissions only -p, --postal Limits results to postal submissions only -b, --usedateback Sorts results by return date [false by default] -i, --in-order Sorts results by oldest first [default] -r, --reverse Reverses results sorting -t, --tabs Prints report using tabs rather than spaces Arguments given in order will print the following information: CD code TL title MK market DS date sent DB date back DO days out ST status NT notes nl new line tb tab Customized printing also available through Python's formatting strings. The following keys can be used: code, story, market, dateback, datesent, daysout, status, note. These can be combined with the two-letter codes. Creating an HMTL table of stories in the mail is easy: listsubmissions("-sInMail -t TLMKDSDO") Table data cells () are converted to table header cells () automatically. """ __author__ = "Josh English (Joshua.R.English@gmail.com)" __version__ = "$Revision: 1.00 $" __date__ = "$Date: 2006/09/16 23:17:42 $" __copyright__ = "Copyright (c) 2006 Josh English" __license__ = "Python" __history__ = """History: 1.00 (Sep 16, 2006) First version. Custom filters and custom displays. """ __future_plans__ = """Future Plans: Ability to turn off the header entirely Ability to turn off the header separator Return a list of lines for printing outside SubHandler """ from xml.sax import make_parser, SAXException from xml.sax.handler import ContentHandler from optparse import OptionParser from datetime import date import time ### Printing headers ### this dictionary is similar to the format of the dictionarys compiled in the ContentHandler headers={ 'code':'Code', 'story':'Story', 'market':'Market', 'datesent':'Sent', 'dateback':'Back', 'note':'Notes', 'daysout':'Out', 'status':'Status', } ### Date procedures dateformats = ['%b %d, %Y','%b %d, %y','%m %d %Y','%Y %m %d','%m/%d/%y','%m-%d-%y'] preffereddateformat = dateformats[0] def StringToDate(ts): """StringToDate(string) Takes a string and returns a Date object """ for df in dateformats: try: t = time.strptime(ts,df) return date(t[0],t[1],t[2]) except: pass raise "Cannot parse date string" sub_opt_parser = OptionParser(usage="SubmissionFilter.py [options]",version = "%prog 0.1") sub_opt_parser.add_option("-c","--code", action="store",type="string",dest="code", help="Gets submission for the story code",default="All") sub_opt_parser.add_option("-m","--market", action="store",type="string",dest="market", help="Gets the stories that have gone to that market",default="All") sub_opt_parser.add_option("-y","--year", action="store",type="string",dest="year", help="Limits results to given year",default="All") sub_opt_parser.add_option("-s","--status", action="store",type="string",dest="status",default="All", help="Limits results to given status (InMail,Reject,Sale)") sub_opt_parser.add_option("-e","--email", action="store_true",dest="email",default=False, help="Limits results to email submissions only") sub_opt_parser.add_option("-p","--postal", action="store_true",dest="postal",default=False, help="Limits results to postal submissions only") sub_opt_parser.add_option("-b","--usedateback", action="store_true",dest="usereturndate",default=False, help="Sorts results by return date [false by default]") sub_opt_parser.add_option("-i","--in-order", action="store_false",dest="reverse", default=False, help="Sorts results by oldest first [default]") sub_opt_parser.add_option("-r","--reverse", action="store_true",dest="reverse", help="Reverses results sorting") sub_opt_parser.add_option("-t","--tabs", action="store_true",dest="usetabs",default=False, help="Prints report using tabs rather than spaces") subfile = "marvin:documents:fiction:subs.xml" class SubHandler(ContentHandler): def __init__(self,argstring=''): (self.options,self.args) = sub_opt_parser.parse_args(argstring.split()) if not self.args: self.args = "TL MK DS DB nl NT".split() self.write = False ### write to the buffer? self.buffer = '' self.keep_track_of = ['code','storycode','story','market','datesent','dateback','status','method','note'] self.sub_list = [] def startElement(self,name,attrs): if name == 'submission': self.data = {} self.write = name in self.keep_track_of def endElement(self,name): if name in self.keep_track_of: self.data[name] = str(self.buffer.strip()) self.clearbuffer() self.write = False elif name == "submission": ### check if our data matches, if so, add current_code to sub_list match = True match = match and self.options.code in ["All",self.data['storycode']] match = match and self.options.status in ["All",self.data['status']] match = match and self.options.market in ["All",self.data['market']] match = match and self.options.year in ["All",self.data['datesent'][-4:]] if self.options.email:match = match and self.data['method']=='email' if self.options.postal: match = match and self.data['method']=='mail' if match: self.sub_list.append((self.data)) elif name == "submissionlist": ### sort the results res = [] for d in self.sub_list: if self.options.usereturndate: res.append((StringToDate(d['dateback']),d)) else: res.append((StringToDate(d['datesent']),d)) res.sort() if self.options.reverse: res.reverse() self.sub_list = [b for a,b in res] #exit if nothing to print if self.options.code !="All": print "Searching for code %s" % self.options.code if self.options.market !="All": print "Searching for stories sent to %s" % self.options.market if self.options.status !="All": print "Searching for %s stories" % self.options.status if self.options.email: print "Searching for stories that were submitted electronically" if self.options.postal: print "Searching for stories that were mailed" if not self.sub_list: return None longest_story = 0 longest_market = 0 for sub in self.sub_list: longest_story = max(longest_story,len(sub['story'])) longest_market = max(longest_market,len(sub['market'])) format = ' '.join(self.args) format=format.replace('CD',"%(code)s") format=format.replace('TL',"%(story)s") format=format.replace('MK',"%(market)s") format=format.replace('DB',"%(dateback)s") format=format.replace('DS',"%(datesent)s") format=format.replace('DO',"%(daysout)s") format=format.replace('ST',"%(status)s") format=format.replace('nl',"\n") format=format.replace('tb',"\t") format=format.replace('NT',"%(note)s") if self.options.usetabs: format=format.replace(" ","\t") headerformat = format.split('\n')[0] if not self.options.usetabs: headers['story'] = headers['story'].ljust(longest_story) headers['market'] = headers['market'].ljust(longest_market) headers['status'] = headers['status'].ljust(6) # length of longest status headers['code'] = headers['code'].ljust(12) headers['datesent'] = headers['datesent'].ljust(12) headers['dateback'] = headers['dateback'].ljust(12) #just in case of HTML headerformat = headerformat.replace('','/th>') header = headerformat % headers print header print '-'*len(header) for d in self.sub_list: if not d.has_key('note'): d['note']='' if d.has_key('dateback'): d['daysout']=(StringToDate(d['dateback'])-StringToDate(d['datesent'])).days else: d['daysout']=(date.today()-StringToDate(d['datesent'])).days d['dateback']=' ' if not self.options.usetabs: d['story'] = d['story'].ljust(longest_story) d['market'] = d['market'].ljust(longest_market) d['status'] = d['status'].ljust(6) # length of longest status d['code'] = d['code'].ljust(12) d['dateback']=d['dateback'].ljust(12) d['daysout']='%3d' % d['daysout'] print format % d print "Found %d submissions" % len(self.sub_list) def characters(self,chars): if self.write: self.buffer += chars def clearbuffer(self): self.buffer = '' def list_submissions(argstring): sh=SubHandler(argstring) parser = make_parser() parser.setContentHandler(sh) parser.parse(open(subfile)) if not sh.sub_list: print "No submissions found" print "============" list_submissions("-sInMail -t TLMKDSDO")