2013-05-14 63 views
0

我在我的服務器上運行此腳本以便在新郵件到達時發送推送通知。它工作的很好,但有時腳本會崩潰,下面的錯誤。我不知道它爲什麼會崩潰,我不能自己複製它。當它失敗時,它將不會進入除外部分。 我已經試過:except self.abort:except M.abort:except M.error:線程中的異常線程4 - 查找原因或發現異常

  1. 任何想法,爲什麼它的崩潰?

  2. 對於短期解決方案,是否可以終止所有線程並從except部分重新啓動腳本?

.......

import socket, ssl, json, struct, re 
import imaplib2, time 
from threading import * 

# enter gmail login details here 
USER="[email protected]" 
PASSWORD="YOUR-GMAIL-PASSWORD" 
# enter device token here 
deviceToken = 'XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX ' 
deviceToken = deviceToken.replace(' ','').decode('hex') 
currentBadgeNum = -1 

def getUnseen(): 
    (resp, data) = M.status("INBOX", '(UNSEEN)') 
    print data 
    return int(re.findall("UNSEEN (\d)*\)", data[0])[0])  

def sendPushNotification(badgeNum): 
    global currentBadgeNum, deviceToken 
    if badgeNum != currentBadgeNum: 
     currentBadgeNum = badgeNum 
     thePayLoad = { 
      'aps': { 
     #   'alert':'Hello world!', 
        'sound':'', 
        'badge': badgeNum, 
        }, 
      'test_data': { 'foo': 'bar' }, 
      } 
     theCertfile = 'certfile.pem' 
     theHost = ('gateway.sandbox.push.apple.com', 2195) 

     data = json.dumps(thePayLoad) 
     theFormat = '!BH32sH%ds' % len(data) 
     theNotification = struct.pack(theFormat, 0, 32, deviceToken, len(data), data) 

     ssl_sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM), certfile=theCertfile) 
     ssl_sock.connect(theHost) 
     ssl_sock.write(theNotification) 
     ssl_sock.close() 
     print "Sent Push alert." 

# This is the threading object that does all the waiting on 
# the event 
class Idler(object): 
    def __init__(self, conn): 
     self.thread = Thread(target=self.idle) 
     self.M = conn 
     self.event = Event() 

    def start(self): 
     self.thread.start() 

    def stop(self): 
     # This is a neat trick to make thread end. Took me a 
     # while to figure that one out! 
     self.event.set() 

    def join(self): 
     self.thread.join() 

    def idle(self): 
     # Starting an unending loop here 
     while True: 
      # This is part of the trick to make the loop stop 
      # when the stop() command is given 
      if self.event.isSet(): 
       return 
      self.needsync = False 
      # A callback method that gets called when a new 
      # email arrives. Very basic, but that's good. 
      def callback(args): 
       if not self.event.isSet(): 
        self.needsync = True 
        self.event.set() 
      # Do the actual idle call. This returns immediately, 
      # since it's asynchronous. 
      self.M.idle(callback=callback) 
      # This waits until the event is set. The event is 
      # set by the callback, when the server 'answers' 
      # the idle call and the callback function gets 
      # called. 
      self.event.wait() 
      # Because the function sets the needsync variable, 
      # this helps escape the loop without doing 
      # anything if the stop() is called. Kinda neat 
      # solution. 
      if self.needsync: 
       self.event.clear() 
       self.dosync() 

    # The method that gets called when a new email arrives. 
    def dosync(self): 
     print "Got an event!" 
     numUnseen = getUnseen() 
     sendPushNotification(numUnseen) 

try: 
    # Set the following two lines to your creds and server 
    print 'starting' 
    global M 
    M = imaplib2.IMAP4_SSL("imap.gmail.com") 
    M.login(USER, PASSWORD) 
    # We need to get out of the AUTH state, so we just select 
    # the INBOX. 
    #M.list() 
    M.select('INBOX', readonly=True) 
    numUnseen = getUnseen() 
    getText() 
    #print M.status("INBOX", '(UNSEEN)') 
    # Start the Idler thread 
    sendPushNotification(numUnseen) 
    idler = Idler(M) 
    idler.start() 
    # Sleep forever, one minute at a time 
    while True: 
     time.sleep(60) 

except self.abort: 
    print 'we had a problem, dont worry! Ill fix it!' 
    idler = Idler(M) 
finally: 
    # Clean up. 
    idler.stop() 
    idler.join() 
    M.close() 
    # This is important! 
    M.logout() 

.....................

.... .................

17:35.99 imap.gmail.com reader last 20 log messages: 
    17:36.02 imap.gmail.com handler last 20 log messages: 
Got an event! 
Exception in thread Thread-4: 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/threading.py", line 551, in __bootstrap_inner 
    self.run() 
    File "/usr/local/lib/python2.7/threading.py", line 504, in run 
    self.__target(*self.__args, **self.__kwargs) 
    File "serverx.py", line 229, in idle 
    self.dosync() 
    File "serverx.py", line 235, in dosync 
    numUnseen = getUnseen() 
    File "serverx.py", line 150, in getUnseen 
    (resp, data) = M.status("INBOX", '(UNSEEN)') 
    File "/home/myuser/lib/python2.7/imaplib2/imaplib2.py", line 1121, in status 
    return self._simple_command(name, mailbox, names, **kw) 
    File "/home/myuser/lib/python2.7/imaplib2/imaplib2.py", line 1607, in _simple_command 
    return self._command_complete(self._command(name, *args), kw) 
    File "/home/myuser/lib/python2.7/imaplib2/imaplib2.py", line 1305, in _command 
    raise self.abort('connection closed') 
abort: connection closed 

回答

0

嘗試追趕imaplib2.IMAP4.abort

try: 
    # ... 
except imaplib2.IMAP4.abort: 
    # Oh no! An error! 
+0

我會但我怎麼能從除了重新啓動腳本? – Segev 2013-05-14 06:15:15

+0

@EXEC_BAD_ACCESS:你可能想要在循環中運行'try'。當/如果失敗,你會想要關閉現有的連接,(可能)稍微等一下,然後再次進入'try'並重新連接。 – icktoofay 2013-05-14 06:17:33

+0

對不起,愚蠢的問題(新的python)如何從'except'內再次運行'try'? – Segev 2013-05-14 06:19:51