[MERGE/PQM] Add XMLRPC support
Daniel Watkins
daniel at daniel-watkins.co.uk
Thu Aug 7 03:47:57 BST 2008
On Wed, 6 Aug 2008 10:39:27 +1200
"Jonathan Lange" <jml at mumak.net> wrote:
> I've decided to leap in and review your XMLRPC patch. I'm in a bit of
> a rush so I've occasionally been terse -- please forgive me.
Thanks again for the review, it's much appreciated (and you're
forgiven :p).
> > === modified file 'bin/pqm'
> > + (sender, subject, msg, sig) = \
> > + read_email_from_file(logger, open(script.filename))
>
> I'd personally prefer breaking the line at the first paren after
> read_email_from_file.
Yup, not sure what I was thinking. Fixed in attached.
> > @@ -203,19 +204,10 @@
> > def do_read_mode(logger, options):
> > sender = None
> > try:
> > - (sender, subject, msg, sig) = read_email(logger)
> > - if options.verify_sigs:
> > - sigid, siguid = verify_sig(
> > - sender, msg, sig, 1, logger, options.keyring)
> > - open(transaction_file, 'a').write(sigid + '\n')
> > - fname = 'patch.%d' % (time.time())
> > - logger.info('new patch ' + fname)
> > - f = open('tmp.' + fname, 'w')
> > - f.write('From: ' + sender + '\n')
> > - f.write('Subject: ' + subject + '\n')
> > - f.write(string.join(re.split('\r?\n', msg), '\n')) # canonicalize line endings
> > - f.close()
> > - os.rename('tmp.' + fname, fname)
> > + email = read_email_from_file(logger, sys.stdin)
> > + email_string = get_email_string(logger, options, email)
> > + queuedir = os.path.abspath('.')
>
> This smells a bit to me.
>
> Unfortunately, I don't really understand PQM well enough, so it may
> be the right thing to do.
If you mean the use of "abspath('.')", then yes, it does smell a
little. It's correct, because the queue directory is changed into at
~line 326. I'd prefer to leave it as-is for the time being, until
a more thorough refactoring of that part of the code can take place.
If you mean something else, I can't smell it so could you clarify which
part you did mean?
> > === modified file 'pqm/script.py'
> > --- pqm/script.py 2008-07-17 02:03:01 +0000
> > +++ pqm/script.py 2008-07-31 06:17:16 +0000
> > @@ -72,6 +69,36 @@
> > return (sender, subject, msg.get_payload(), None)
> >
> >
> > +def read_email_from_file(logger, file=None):
>
> Docstring please.
Done.
> > + if not file:
>
> I'd rather 'if file is None'.
Done.
> > + file = sys.stdin
> > + msg = email.message_from_file(file)
> > + return get_email_structure(logger, msg)
> > +
> > +
> > +def read_email_from_string(logger, string):
>
> Docstring please.
Done.
> > + msg = email.message_from_string(string)
> > + return get_email_structure(logger, msg)
> > +
> > +
> > +def get_email_string(logger, options, email):
>
> Docstring please!
Done.
> > + (sender, subject, msg, sig) = email
> > + if options.verify_sigs:
> > + # TODO: Daniel Watkins, 2008-07-31
> > + # Get rid of the imports from pqm module itself.
> > + from pqm import verify_sig
> > + sigid, siguid = verify_sig(sender, msg, sig, 1, logger,
> > + options.keyring)
> > + open(transaction_file, 'a').write(sigid + '\n')
> > + # canonicalize line endings
> > + body = '\n'.join(re.split('\r?\n', msg))
> > + return ("From: %(sender)s\n"
> > + "Subject: %(subject)s\n"
> > + "%(body)s" % {'sender': sender,
> > + 'subject': subject,
> > + 'body': body,})
> > +
> > +
>
> I'm not super clear what this last function is for, but in general I
> think this is an improvement to the structure of the mail handling
> code.
This gets the standard representation of an email used by PQM.
> > === added file 'pqm/ui/tests/test_xmlrpc.py'
> > --- pqm/ui/tests/test_xmlrpc.py 1970-01-01 00:00:00 +0000
> > +++ pqm/ui/tests/test_xmlrpc.py 2008-08-01 01:01:52 +0000
> > +class TestPQM_XMLRPC(TestCaseWithQueue):
> > +
> > + def test_empty_submission(self):
> > + xmlrpc = self.get_xmlrpc()
> > + out = xmlrpc.xmlrpc_submit('')
> > + self.assertEqual("Error: 'No From specified'", out)
> > +
> > + def test_valid_submission(self):
>
> It would be good if you could add a comment explaining the behaviour
> you want. This is especially important since the casual reader
> (that's me) doesn't know what sample_message is.
>
> Something like:
> # Submitting a message like ______ makes PQM do _____
Done.
> > + xmlrpc = self.get_xmlrpc()
> > + out = xmlrpc.xmlrpc_submit(sample_message)
> > + self.assertEqual('Success!', out)
> > + queuedir = xmlrpc.pqminfo.queuedir
> > + patches = [f for f in os.listdir(queuedir) if
> > f.startswith('patch.')]
> > + self.assertEqual(1, len(patches)) # We should have only
> > one patch
> > + self.assertFileEqual(sample_message,
> > + os.path.join(queuedir, patches[0]))
> >
>
> I think it would also be good to add a test for a malformed
> submission.
Done.
> > === modified file 'pqm/ui/twistd.py'
> > --- pqm/ui/twistd.py 2008-04-16 10:23:52 +0000
> > +++ pqm/ui/twistd.py 2008-08-01 00:33:29 +0000
> > @@ -156,14 +157,16 @@
> > def __init__(self, filenames):
> > self.filenames = filenames
> > self.messages = []
> > + self.configp = ConfigParser()
> > + self.configp.read(self.filenames)
> > + self.queuedir = pqm.get_queuedir(self.configp, logging, [])
> >
>
> Two things here.
>
> configp should probably be config_parser. Characters are cheap.
configp is used throughout the PQM code to refer to a ConfigParser, so
I'm loath to change that.
> The other thing is that if you have a lot of big files that take a
> while to parse, this operation will block, preventing the process
> from handling any other incoming requests. I'm not sure if it's an
> issue now, but it's something to be aware of.
This is just modifying the existing code, so it's presumably not an
issue currently. It will be borne in mind, however.
> > === added file 'pqm/ui/xmlrpc.py'
> > --- pqm/ui/xmlrpc.py 1970-01-01 00:00:00 +0000
> > +++ pqm/ui/xmlrpc.py 2008-08-01 00:43:22 +0000
> > +
> > +class PQM_XMLRPC(XMLRPC):
> > +
>
> Docstring please.
Done.
> > + def __init__(self, pqminfo):
> > + XMLRPC.__init__(self)
> > + self.pqminfo = pqminfo
> > + self.logger = logging.getLogger('pqm')
> > +
> > + def xmlrpc_submit(self, text):
>
> And here too!
Done.
> > + try:
> > + queuedir = self.pqminfo.queuedir
> > + queuedir = os.path.abspath(queuedir)
> > + # Set up options for processing
> > + options = FakeOptions()
> > + options.verify_sigs =
> > self.pqminfo.configp.get_boolean_option(
> > + 'DEFAULT', 'verify_sigs', True)
> > + if options.verify_sigs:
> > + options.keyring =
> > self.pqminfo.configp.get('DEFAULT',
> > +
> > 'keyring')
> > + # TODO: Eww.
>
> Please say *why* it's eww and what can be done about it.
Done.
> > + pqm.gpgv_path =
> > self.pqminfo.configp.get_option('DEFAULT',
> > + 'gpgv_path', 'gpgv')
> > + pqm_subdir = os.path.join(queuedir, 'pqm')
> > + pqm.pqm_subdir = pqm_subdir
> > + # Process input
>
> This isn't a particularly enlightening comment.
Removed.
> > + email = read_email_from_string(self.logger, text)
> > + email_string = get_email_string(self.logger, options,
> > email)
> > + # Write script
>
> Neither is this :)
Removed also.
> > + pqm.write_script(queuedir, email_string)
> > + return "Success!"
>
> I think returning a human-readable string sends mixed messages.
> Perhaps just return True instead.
>
> > + except PQMException, e:
> > + return "Error: %s" % (e,)
> >
>
> Could you please raise a Fault instead?
Done.
> Thanks for the patch!
Thanks again for the review. The adjusted patch is attached.
Dan
--
Daniel Watkins (Odd_Bloke)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: xmlrpc.2.patch
Type: text/x-patch
Size: 39466 bytes
Desc: not available
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20080807/e64a619d/attachment-0001.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20080807/e64a619d/attachment-0001.pgp
More information about the bazaar
mailing list