Blob Blame History Raw
#!/usr/bin/python3 -tt
# skvidal@fedoraproject.org
# (c) red hat, inc 2013, 2015
# gpl whatever
# this is a direct port of exo-compos-mail-1 from xfce
# from perl to python
# the idea is to dump the 2000000000 perl pkgs pulled in
# by this for a single item :(
# it should handle all the behaviour the same
# it probably has bugs

# TODO:
# - figure out what the attachment parsing is trying to do
# - figure out if rebuilding the mailto for evo, sylpheed and balsa
#    is actually necessary or not - feels silly but I'm not shocked by silly
# - would be nice to have an actual set of tests :)


import sys
import posix
import os
import urllib.parse


def parse_url(mailto):
    url = urllib.parse.urlparse(mailto, 'mailto')
    res = {}
    to = []
    query = None

    if url.query or '?' not in url.path:
        if url.path:
            to.append(urllib.parse.unquote(url.path))

    else:
        (thisto, ques, query) = url.path.partition('?')
        if thisto.strip():
            to.append(urllib.parse.unquote(thisto))

    if not query:
        query = url.query

    q_dict = urllib.parse.parse_qs(query)
    to.extend(q_dict.get('to', []))
    res['to'] = to
    if 'to' in q_dict:
        del(q_dict['to'])

    res.update(q_dict)
    return res


if len(sys.argv) < 3:
    sys.stderr.write("Usage: %s <style> <binary> <mailto>\n" % (sys.argv[0]))
    sys.exit(1)


style = sys.argv[1]
binary = sys.argv[2]
raw_mailto = sys.argv[3]
mailto = parse_url(raw_mailto)


to = mailto.get('to', [])
cc = mailto.get('cc', [])
bcc = mailto.get('bcc', [])
subject = ' '.join(mailto.get('subject', []))
body = '\n'.join(mailto.get('body', []))
attachments = mailto.get('attachment', [])

# hackish
if isinstance(subject, list):
    subject = subject[0]


args = [binary]
if style == 'mozilla':

    command = "to='" + ','.join(to) + "'"
    command += ",cc='" + ','.join(cc) + "'"
    command += ",bcc='" + ','.join(bcc) + "'"
    command += ",attachment='" + ','.join(attachments) + "'"
    if subject:
        command += ",subject='" + subject + "'"
    if body:
        command += ",body='" + body + "'"

    args.append('-compose')
    args.append(command)

elif style == 'mozilla-remote':
    # generate xfeDoCommand(composeMessage, ...) string
    command = 'xfeDoCommand(composeMessage'
    command += ",to='" + ','.join(to) + "'"
    command += ",cc='" + ','.join(cc) + "'"
    command += ",bcc='" + ','.join(bcc) + "'"
    command += ",attachment='" + ','.join(attachments) + "'"
    if subject:
        command += ",subject='" + subject + "'"
    if body:
        command += ",body='" + body + "'"

    command += ')'

    # and add the parameters to the argv
    args.append('-remote')
    args.append(command)

elif style == 'evolution':
    # evo takes a mailto uri and parses it itself
    # just hand back what we were handed originally
    # note - it my want them to be url_escaped first? or not?
    args.append(raw_mailto)

elif style == 'kmail':
    if len(to) >= 1:
        baseaddr = to[0]
        cc.extend(to[1:])
    else:
        baseaddr = " "

    for item in cc:
        args.append('--cc')
        args.append(item)
    for item in bcc:
        args.append('--bcc')
        args.append(item)
    for item in attachments:
        args.append('--attach')
        args.append(item)
    if subject:
        args.append('--subject')
        args.append(subject)
    if body:
        args.append('--body')
        args.append('\n'.join(body))
    args.append('--composer')
    args.append(baseaddr)

elif style == 'sylpheed':
    args.append('--compose')
    args.append(raw_mailto)
    # fixme - do attachments separately

elif style == 'balsa':  # cmon, balsa? really?
    args.append('--compose')
    args.append(raw_mailto)
    # fixme - do attachments separately

elif style == 'mutt':
    for item in cc:
        args.append('-c')
        args.append(item)
    for item in attachments:
        args.append('-a')
        args.append(item)
    if subject:
        args.append('-s')
        args.append(subject)
    for item in to:
        args.append(item)
    if to:
        args.append('')


else:
    sys.stderr.write("%s: Unsupported style '%s'.\n" % (sys.argv[0], style))
    sys.exit(1)

# try to execute the generated command
posix.execv(binary, args)
# DEBUG
# print binary,
# print ' '.join(args)
# sys.exit(0)
# ENDDEBUG
# something went wrong
sys.exit(1)