I did detect one problem thus far<br><br> File "test.py", line 152<br>    if len(args) == 1 and args[0] = "-c":<br><br><br><div class="gmail_quote">On Sat, Aug 15, 2009 at 7:23 PM, Dennis Lee Bieber <span dir="ltr"><<a href="mailto:wlfraed@ix.netcom.com">wlfraed@ix.netcom.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">On Sat, 15 Aug 2009 14:23:26 -0600, John Haggerty <<a href="mailto:bouncyinc@gmail.com">bouncyinc@gmail.com</a>><br>

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