redoing libgmail interface to "smtplib" blah?

John Haggerty bouncyinc at gmail.com
Sat Aug 15 22:58:52 EDT 2009


On Sat, Aug 15, 2009 at 7:23 PM, Dennis Lee Bieber <wlfraed at ix.netcom.com>wrote:

> On Sat, 15 Aug 2009 14:23:26 -0600, John Haggerty <bouncyinc at gmail.com>
> declaimed the following in gmane.comp.python.general:
>
> > The following program is theoretically supposed to use a supported
> library.
> > Issues have come up where the library is not working and now another
> > interface is being requierd to be used.
> >
> > At this point I'm looking at just changing the send commands but don't
> feel
> > confident in doing so. Wondering specifically what would have to be
> changed
> > to what.
> >
> > Thanks for your time :)
>
>         Ugh... I'm afraid if I attacked this program I'd have to
> restructure
> the entire thing... There are no signs of any functional decomposition
> in that -- if Python had an unstructured GOTO, I'd suspect this would
> have been a spaghetti-code program... As it is, the best I can call it
> is lasagna-code <G> (interwoven but distinct layers in a linear form
> from one end to the other).
>
>
> > if __name__ == "__main__":
> >     import os,time,sys,libgmail
> >     from subprocess import Popen,PIPE
> >     main(sys.argv)
>
>         Given the position of the import statements, this file can NOT be
> used as an importable module for use by other programs, so the whole
> breakdown of a main() is meaningless; might as well remove that if, the
> def main(): line, move the imports to the top, and unindent the rest one
> level.
>
>        All those embedded calls to exit() also offend me; I'm from the "one
> in, one out" school (though I'll use break and continue in a loop, I
> still favor just one usage of them in such)
>
>        Ideally, all the SMS related stuff would be isolated apart from the
> email stuff. Would make changing email interface a lot more intuitive.
>
>        Out of a fit of boredom, though it probably doesn't help your real
> problem, and it has not been tested at all, this is my restructuring of
> the code listing.
>
> -=-=-=-=-=-=-=-
> import os
> import time
> import sys
> import subprocess
>
> import libgmail
>
>
> CARRIERLIST = [   ("3 River Wireless", "@sms.3rivers.net"),
>                   ("7-11 Speakout","@cingularme.com"),
>                  #            ("Airtel (Karnataka","India) Alaska
> Communications Systems"),
>                  ("Alltel Wireless","@message.alltel.com"),
>                  ("AT&T Wireless","@txt.att.net"),
>                  ("Bell Mobility (Canada)","@txt.bell.ca"),
>                  ("Boost Mobile","@myboostmobile.com"),
>                  ("Cellular One (Dobson)","@mobile.celloneusa.com"),
>                  ("Cingular (Postpaid)","@cingularme.com"),
>                  ("Centennial Wireless","@cwemail.com"),
>                  ("Cingular (GoPhone prepaid)","@cingularme.com"),
>                  ("Claro (Nicaragua)","@ideasclaro-ca.com"),
>                  ("Comcel","@comcel.com.co"),
>                  ("Cricket","@sms.mycricket.com"),
>                  ("CTI","@sms.ctimovil.com.ar"),
>                  ("Emtel (Mauritius)","@emtelworld.net"),
>                  ("Fido (Canada)","@fido.ca"),
>                  ("General Communications Inc.","@msg.gci.net"),
>                  ("Globalstar","@msg.globalstarusa.com"),
>                  ("Helio","@myhelio.com"),
>                  ("Illinois Valley Cellular","@ivctext.com"),
>                  #            ("i wireless",".iws at iwspcs.net"),
>                  ("Meteor (Ireland)","@sms.mymeteor.ie"),
>                  ("Mero Mobile (Nepal)","@sms.spicenepal.com"),
>                  ("MetroPCS","@mymetropcs.com"),
>                  ("Movicom","@movimensaje.com.ar"),
>                  ("Mobitel (Sri Lanka)","@sms.mobitel.lk"),
>                  ("Movistar (Colombia)","@movistar.com.co"),
>                  ("MTN (South Africa)","@sms.co.za"),
>                  ("MTS (Canada)","@text.mtsmobility.com"),
>                  ("Nextel (Argentina)","@nextel.net.ar"),
>                  ("Orange (Poland)","@orange.pl"),
>                  ("Personal (Argentina)","@personal-net.com.ar"),
>                  ("Plus GSM (Poland)","@text.plusgsm.pl"),
>                  ("President's Choice (Canada)","@txt.bell.ca"),
>                  ("Qwest","@qwestmp.com"),
>                  ("Rogers (Canada)","@pcs.rogers.com"),
>                  ("Sasktel (Canada)","@sms.sasktel.com"),
>                  ("Setar Mobile email (Aruba)","@mas.aw"),
>                  ("Solo Mobile","@txt.bell.ca"),
>                  ("Sprint (PCS)","@messaging.sprintpcs.com"),
>                  ("Sprint (Nextel)","@page.nextel.com"),
>                  ("Suncom","@tms.suncom.com"),
>                  ("T-Mobile","@tmomail.net"),
>                  ("T-Mobile (Austria)","@sms.t-mobile.at"),
>                  ("Telus Mobility (Canada)","@msg.telus.com"),
>                  ("Thumb Cellular","@sms.thumbcellular.com"),
>                  ("Tigo (Formerly Ola)","@sms.tigo.com.co"),
>                  ("Unicel","@utext.com"),
>                  ("US Cellular","@email.uscc.net"),
>                  ("Verizon","@vtext.com"),
>                  ("Virgin Mobile (Canada)","@vmobile.ca"),
>                  ("Virgin Mobile (USA)","@vmobl.com"),
>                  ("YCC","@sms.ycc.ru"),
>                  ("Orange (UK)","@orange.net"),
>                  ("Cincinnati Bell Wireless","@gocbw.com"),
>                  ("T-Mobile Germany","@t-mobile-sms.de"),
>                  ("Vodafone Germany","@vodafone-sms.de"),
>                   ("E-Plus","@smsmail.eplus.de")    ]
>
> INSTRUCTIONS = """
> ------Usage---------------------------------------------------------------
> ------Start Service ---
>        ogss.py USERNAME PASSWORD CELL-NUMBER CARRIER-NUMBER
> ------List carriers ---
>        ogss.py -c
>
> ------Useage from
> phone----------------------------------------------------
> ------Ogss COMMAND
> """
>
> #odd notation is to split by lines, then join lines with a space
> PHONEINSTRUCTIONS = " ".join(
>     """To use OGSS reply to this message with an SMS starting with
> "Ogss". Whatever follows "Ogss" will be executed on your computer
> """.split())
>
> class Logfile(object):
>    def __init__(self):
>        self.logname = os.path.join(os.environ["HOME"], "ogss.log")
>        if not os.path.exists(self.logname):
>            try:
>                self.log = open(logname, "w+")
>            except:
>                print "Failure to create log file; check permissions"
>                self.log = None
>        else:
>            try:
>                print "Opening log file: %s" % self.logname
>                self.log = open(logname, "r+")
>            except:
>                self.log = None
>
>    def opened(self):
>        return self.log is not None
>
>    def readParse(self):
>        if self.opened():
>            self.log.seek(0, os.SEEK_SET)
>            retdata = []
>            for line in self.log:
>                 eid = line.split("~")
>                if len(eid) >= 2:
>                     retdata.append(int(eid[0]))
>        return retdata
>
>    def write(self, ID, commandLine):
>        if self.opened():
>            self.log.seek(0, os.SEEK_END)
>            self.log.write("%s %s\n" % (ID, commandLine))
>
>    def close(self):
>        if self.opened():
>            self.log.close()
>
> class MailConnection(object):
>    #might have been possible to subclass from libgmail.GmailAccount
>    #but by incorporating that as a component instead makes it
>    #a bit easier to replace with something else (SMTP?)
>    def __init__(self, uname, passwd):
>        self.uname = uname
>        self.passwd = passwd
>        self.account = libgmail.GmailAccount(self.uname, self.passwd)
>
>    def login(self):
>        self.account.login()
>
>    def sendMessage(self, message):
>        self.account.sendMessage(message)
>
>    def getMessageByQuery(qstring, flag):   #what does flag do?
>        return self.account.getMessagesByQuery(qstring, flag)
>
>    def composeMessage(self, to, subject, body):
>        return libgmail.GmailComposedMessage(to,
>                                             subject,
>                                             body)
>
>
> def parseCommandLine(args):
>    retdata = None
>    if len(args) == 1 and args[0] = "-c":
>        for i, car in enumerate(CARRIERLIST):
>            print "%5d -- %s" % (i, car[0])
>
>    elif len(args) > 3:
>        (username, password, number, carrierID) = tuple(args[:4])
>        carrier = CARRIERLIST[int(carrierID)]
>         cell_email = number + carrier[1]
>         retdata = { "User" : username,
>                    "Pass" : password,
>                    "Number" : number,
>                    "ID" : carrierID,
>                    "Carrier" : carrier,
>                    "Cell" : cell_email }
>
>    else:
>        print INSTRUCTIONS
>    return retdata
>
>
> def main(argv):
>    print "Starting ogss"
>
>     print "Opening log file"
>    logfile = Logfile()
>    if logfile.opened():
>        print "Parsing log file"
>        execd = logfile.readParse()
>
>        print "Parsing command line input"
>        callee = parseCommandLine(argv[1:]) #strip program name
>
>        if callee is not None:
>            print "Logging in to mail server"
>            account = MailConnection(callee["User"],
>                                     callee["Pass"])
>            account.login()
>
> ##            #if log file contents are empty, send instructions to
> ##            #user's phone
> ##            if not len(execd):
> ##                account.sendMessage(
> ##                    account.composeMessage(
> ##                        callee["Cell"],
> ##                        "OGSS Instructions",
> ##                        PHONEINSTRUCTIONS)  )
>
>
>            try:
>                while True:
>                    print "Listening for commands"
>                    print "Getting mailbox contents"
>                    searchResult = account.getMessagesByQuery(
>                        "from:" + callee["Cell"],
>                        True    )
>                    if searchResult:    #presume empty if no messages
>                        maxID = 0
>                        maxMessage = None
>                         for thread in searchResult:
>                            for message in thread:
>                                 if callee["Cell"] == message.sender:
>                                    mID = int(message.id, 16)
>                                    if mID > maxID:
>                                        maxID = mID
>                                        maxMessage = message
>
>                        if maxID and maxMessage:
>                            if not maxID in execd:
>                                print "Parsing command from message"
>                                ogssSplit =
> maxMessage.source.split("Ogss")
>                                command = ogssSplit[-1].split(
>                                    "</SPAN>")[0].split()
>
>                                result = subprocess.Popen(
>                                    command,
>                                    stdout = subprocess.PIPE)
>                                body = result.stdout.read()
>                                account.sendMessage(
>                                    account.composeMessage(
>                                        callee["Cell"],
>                                        "STDOUT",
>                                        "\n" + body)    )
>                                logfile.write(maxID, " ".join(command))
>
>                    #TODO add ability to choose sleep time
>                    time.sleep(2)
>             except (KeyboardInterrupt):
>                pass    #exit WHILE loop with <ctrl-c> or equivalent
> ##        else:
> ##            pass    #no login data supplied on startup
>
>        logfile.close()
>    else:
>        print "Could not open log file, check permissions"
>
>
> if __name__ == "__main__":
>    main(sys.argv)
> -=-=-=-=-=-=-=-
>
>        Everything that needs to be changed for SMTP should be in the class
> MailConnection. Note: it appears that this program expects a
> bidirectional mail connection -- similar to IMAP, where one connection
> access both outgoing mail AND incoming mail that is stored on the remote
> system. You'll probably need to use both SMTP to send the messages, and
> POP3 to retrieve the mailbox contents -- and what you do about leaving
> messages in a POP3 mailbox is up to you; most clients normally delete
> them after fetching, but if the query has to fetch all messages just to
> process one set, that may be a concern... Or you use something else to
> retrieve messages and store them in a local mailbox for subsequent
> usage.
>
>        HMMM that does bring up the point -- where is your existing problem?
> Reading GMAIL or sending to GMAIL?



Sending actually reading worked which was what really surprised me.
Especially since python had a ssl for pop and smtp as well.


>
>
>        Heh... with a bit of work, I could probably create a Eudora filter
> to invoke a Python script on each new fetched email with the proper
> subject/content, and then file it away is a different (local) mailbox --
> and do away with that whole log file search and message searching as
> messages would be processed as received and never seen again.
> --
>        Wulfraed         Dennis Lee Bieber               KD6MOG
>        wlfraed at ix.netcom.com   HTTP://wlfraed.home.netcom.com/
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20090815/def2da5c/attachment-0001.html>


More information about the Python-list mailing list