"""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
| TL | MK | DS | DO |
")
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 | | TL | MK | DS | DO |
")