I've written about my submission management system on my livejournal for a while, and there seems to be some interest, and I'm proud of what I've done, so here it is in all its "glory".

There is a discussion of this on my LJ. Post any comments or questions there.

Here's what you need to know:

Here are the files you'll need:

Note on the XML.

Data is stored in two XML files. I call them "stories.xml" and "subs.xml" but you can name them anything you want. If you don't know much about XML, I suggest W3C's XML class.

<inventory path="Marvin:Documents:Fiction:stories.xml" 
  mod_date="Tue Sep 12 15:06:14 2006">
  <story code="picnic">
    <title>A Picnic on the Event Horizon</title>
    <wordcount>2700</wordcount>
    <status>OnMarket</status>
    <wordos/>
    <file>inmail/picnic.doc</file>
    <history>
      <item>Jan 19, 2005: First Draft.  Title taken from Mischa DeNola story. Core idea about 12 years old</item>
      <item>Jan 24, 2005: Third Draft to Stephanie</item>
      <item>Jan 25, 2005: Fourth Draft to Wordos</item>
      <item>Mar 31, 2005: After several updates, sent to WotF</item>
    </history>
    <submission>WotF20050331</submission>
    <submission>FSF20050614</submission>
    <submission>Anlg20050625</submission>
    <submission>Asmv20050804</submission>
    <submission>SFoe20051223</submission>
    <submission>Muse20060409</submission>
    <plot>Liana Prewitt is a time traveller going back in time to prevent a Titanic-like disaster on the Opsimath.</plot>
    </story>
    ...
</inventory>

Hopefully all of this is self explanatory. The submissions are codes found in the submission file. Here are examples of closed submissions and open submissions:

<submissionlist path="Marvin:Documents:Fiction:subs.xml" mod_date="Tue Sep 12 15:06:09 2006">
  <submission>
    <code>WotF20050331</code>
    <story>A Picnic on the Event Horizon</story>
    <storycode>picnic</storycode>
    <cost>1.43</cost>
    <dateback>Jun  8, 2005</dateback>
    <datesent>Mar 31, 2005</datesent>
    <daysout>69</daysout>
    <market>WotF</market>
    <method>mail</method>
    <status type="2">Reject</status>
    <note>2ndQ 2005 Quarterfinalist</note>
  </submission>
  <submission>
    <code>Muse20060409</code>
    <story>A Picnic on the Event Horizon</story>
    <storycode>picnic</storycode>
    <market>QuantumMuse</market>
    <datesent>Apr 09, 2006</datesent>
    <status>InMail</status>
    <method>email</method>
    <cost>0.00</cost>
  </submission>
  ...
</submissionlist>

Again, hopefully this makes some obvious sense. It isn't necessary to do anything in XML, expect fix odd errors, like once I made a new submission with the wrong market code, and I had to delete it. I don't have any simple program for deleting submissions.

Now some things are inconsistent. The code tag should be unique for both stories and submissions, and since they are required, proper XML formatting states that they should be attributes. They will be attributes in the next major revision, which I'm working on.

There is no xml file to keep track of market information (that, like most things, is forthcoming). The IMS.py file has the marketdict object that keeps track of market names and the four letter code that is used to identify each submission, so the submission code tells you which market and when it was sent.

Using NewSub and CloseSub

It's time I explain part of the process of what happens when you run any of these files. A lot of what IMS does is read the XML files as minidom objects, then creates Python objects that represent those XML records, and various methods (such as closing a sub) can manipulate the data. This may not be the most elegant solution, and it is memory intenstive as I pushed the 80-submissions mark.

NewSub and CloseSub simply call those methods, and then tell the filers to save the new information. Here's the code:

import IMS

newsub = IMS.Submission(
   "Wolves Take Care of Their Own",			## Title sent
   "wolf",									## Story code
   "Gryphonwood",							## MarketName
   "Sep 10, 2006",							## Date sent
   "email",									## Method (mail or email)
   0.00+0.0)								## Postage + SASE Stamp

stFiler = IMS.StoryFiler()
sbFiler = IMS.SubFiler()

try:
	story = stFiler.getStory(newsub.storycode)
except:
	raise "Unknown Story %s" % newsub.storycode

p = IMS.Printer(newsub.toElement())

sbFiler.New(newsub.code,p.write())
story.addSubmission(newsub.code)
stFiler.replace(newsub.storycode,story.toElement())

sbFiler.Save()
stFiler.Save()

So all I do is open this file, change the parameters in the newsub declaration, and it does everything else. Closing a sub is also easy:

import IMS

subfiler = IMS.SubFiler()

def CloseSub(code,date,status,note=""):
   thisSub=IMS.NodeToSubmission(subfiler.getXML(code))
   thisSub.Close(date,status,note)
   subfiler.replace(code,thisSub.toElement())
   subfiler.Save()
	
CloseSub("Abys20060829","Sep 10, 06",'Reject',"Well received, but decided against it")

ListSubmissions

My workhorse. It has a fairly good documentation built in:

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 <tr><td>TL</td><td>MK</td><td>DS</td><td>DO</td></tr>")
Table data cells (<td>) are converted to table header cells (<th>) automatically.

Yes, you pass arguments to the program: list_submissions("-sReject -t TL MK DS DO nl NT") will print some nice features.