def handle_msg(uidpath,rfc822): global l_timedep_tasks print "In handle_msg for "+uidpath sys.stdout.flush() #Ignore reflections except for MID dictionary processing if uidpath in mirror: print "Found in mirror." #Examine References header and update msg_dict msg_dict.process_msg(email.parser.Parser().parsestr(rfc822),uidpath) print "removing from mirror: done." mirror.remove(uidpath) print "mirror: "+repr(mirror) sys.stdout.flush() return #Ignore specified accounts for acct in ignored_accounts: if uidpath.find(acct+"/")==0: print "In ignored account: done." sys.stdout.flush() return msg = email.parser.Parser().parsestr(rfc822) #We need to handle an updated Task, following protocol if uidpath.find("Tasks")==0: task_revised = False if msg['X-MailTask-Completion-Status']=="Incomplete" and uidpath!="Tasks/BLACKHOLE": if 'X-MailTask-Virgin' not in msg and (type(msg.get_payload())==str or len(msg.get_payload())==1) or 'X-MailTask-Forced-Complete' in msg: del msg['X-MailTask-Completion-Status'] msg['X-MailTask-Completion-Status']="Completed" task_revised = True elif 'X-MailTask-Virgin' in msg and len(msg.get_payload())>1: del msg['X-MailTask-Virgin'] task_revised = True elif msg['X-MailTask-Completion-Status']=="Completed": del msg['X-MailTask-Forced-Complete'] del msg['X-MailTask-Completion-Status'] msg['X-MailTask-Completion-Status']="Incomplete" if 'X-MailTask-Virgin' not in msg and (type(msg.get_payload())==str or len(msg.get_payload())==1): msg['X-MailTask-Virgin']="" task_revised = True elif msg['X-MailTask-Completion-Status']=="Time-Dependent": l_timedep_tasks[uidpath]=msg elif uidpath!="Tasks/BLACKHOLE": print "*BUG!*: We found a Task with no or invalid X-MailTask-Completion-Status." sys.stdout.flush() #Examine References header and update msg_dict msg_dict.process_msg(msg,uidpath) #If necessary, update task if task_revised: nsync.node_update(uidpath,msg.as_string()) mirror.add(uidpath) print "handle_msg: update "+uidpath+" and add to mirror" print "mirror: "+repr(mirror) sys.stdout.flush() else: #not a Task: scan email headers and, if appropriate, create a new related task or update an existing one if 'From' not in msg or 'Message-ID' not in msg or client.get_email_addr_from_header(msg['From']) in ignored_senders: print "handle_msg: "+uidpath+" is from an ignored sender." sys.stdout.flush() return #Okay, now, first check if there is a Task out there that refers to a Message-ID that is also referred to by this message task_mid = None if 'References' in msg: print "handle_msg: searching "+uidpath+" related_mids for referring Task" sys.stdout.flush() related_mids = msg['References'].replace("\r","").replace("\n",",").replace("\t",",").replace(" ",",") print "handle_msg: "+repr(related_mids) sys.stdout.flush() for rmid_ in related_mids.split(","): rmid = rmid_.strip() if rmid=="": continue print "handle_msg: examining "+rmid sys.stdout.flush() if rmid in msg_dict.rev_mid_dict: print "handle_msg: msg_dict.rev_mid_dict["+rmid+"]: "+repr(msg_dict.rev_mid_dict[rmid]) sys.stdout.flush() for referring_mid in msg_dict.rev_mid_dict[rmid]: if referring_mid.find("Tasks/")==0: task_mid = referring_mid break if task_mid!=None: break #We found one: update its References and Date headers and completion status. if task_mid!=None: print "handle_msg: Updating reference header of task "+task_mid sys.stdout.flush() task_msg = email.parser.Parser().parse(open(os.path.join(client.cachedir,task_mid))) #Update related IDs relmids = mt_utils.get_related_ids(task_msg) relmids.append(msg['Message-ID']) mt_utils.set_related_ids(task_msg,relmids) #Update task_msg Date field del task_msg['Date'] task_msg['Date']=email.utils.formatdate(localtime=True) #Update task completion status del task_msg['X-MailTask-Forced-Complete'] del task_msg['X-MailTask-Completion-Status'] task_msg['X-MailTask-Completion-Status']="Incomplete" nsync.node_update(task_mid,task_msg.as_string()) mirror.add(task_mid) else: #No existing task, so we must make one print "handle_msg: Creating new task referencing MID "+msg['Message-ID'] sys.stdout.flush() newtask=email.message.Message() nt_body = email.message.Message() nt_body['Content-Type'] = "text/plain" payload="" if client.get_email_addr_from_header(msg['From']) in email_info: payload=email_info[client.get_email_addr_from_header(msg['From'])] elif client.get_nick_from_header(msg['From']) in email_info: payload=email_info[client.get_nick_from_header(msg['From'])] nt_body.set_payload(payload) mt_utils.attach_payload(newtask,nt_body) newtask['Content-Type']="multipart/x.MailTask" newtask['Date']=email.utils.formatdate(localtime=True) newtask['Subject'] = client.get_nick_from_header(msg['From'])+": "+msg['Subject'] if 'Subject' in msg and 'From' in msg else "New Task" newtask['X-MailTask-Type'] = "Checklist" newtask['X-MailTask-Completion-Status'] = "Incomplete" newtask['X-MailTask-Virgin'] = "Yes" mt_utils.set_related_ids(newtask,[msg['Message-ID']]) nsync.node_update("Tasks/NEWMESSAGE",newtask.as_string())
def handle_msg(uidpath,rfc822,mirror_flag): global l_timedep_tasks print "In handle_msg for "+uidpath sys.stdout.flush() #Ignore reflections except for MID dictionary processing if mirror_flag: print "Found in mirror." #Examine References header and update msg_dict msg_dict.process_msg(email.parser.Parser().parsestr(rfc822),uidpath) print "mirror: "+repr(nsync.mirror) sys.stdout.flush() return msg = email.parser.Parser().parsestr(rfc822) #Ignore specified accounts, unless sender in unignored_senders if 'From' in msg and client.get_email_addr_from_header(msg['From']) not in unignored_senders and client.get_nick_from_header(msg['From']) not in unignored_senders: for acct in ignored_accounts: if uidpath.find(acct+"/")==0: print "In ignored account: done." sys.stdout.flush() return else: print "Sender in unignored_senders or not in ignored account." #We need to handle an updated Task, following protocol if uidpath.find("Tasks")==0: task_revised = False if msg['X-MailTask-Completion-Status']=="Incomplete" and uidpath!="Tasks/BLACKHOLE": if 'X-MailTask-Virgin' not in msg and (type(msg.get_payload())==str or len(msg.get_payload())==1) or 'X-MailTask-Forced-Complete' in msg: del msg['X-MailTask-Completion-Status'] msg['X-MailTask-Completion-Status']="Completed" task_revised = True elif 'X-MailTask-Virgin' in msg and len(msg.get_payload())>1: del msg['X-MailTask-Virgin'] task_revised = True elif msg['X-MailTask-Completion-Status']=="Completed": del msg['X-MailTask-Forced-Complete'] del msg['X-MailTask-Completion-Status'] msg['X-MailTask-Completion-Status']="Incomplete" if 'X-MailTask-Virgin' not in msg and (type(msg.get_payload())==str or len(msg.get_payload())==1): msg['X-MailTask-Virgin']="" task_revised = True elif msg['X-MailTask-Completion-Status']=="Time-Dependent": l_timedep_tasks[uidpath]=msg elif uidpath!="Tasks/BLACKHOLE": print "*BUG!*: We found a Task with no or invalid X-MailTask-Completion-Status." sys.stdout.flush() #Examine References header and update msg_dict msg_dict.process_msg(msg,uidpath) #Handle Google Calendar Sync try: if do_gcal: dinfo = None gcal_id = msg['X-MailTask-GCalID'] subject_str = "MailTask: "+msg.get('Subject',"No Subject") body_str = mt_utils.get_body(msg).get_payload() if 'X-MailTask-Date-Info' in msg: dinfo = mt_utils.gtstfxmdis(msg['X-MailTask-Date-Info']) if len(dinfo)==1: dinfo = (dinfo[0],dinfo[0]) if not gcal_id and 'X-MailTask-Date-Info' in msg: gcal_id = mt_gcal_sync.insert_gcal_event((subject_str,body_str,dinfo[0],dinfo[1])) msg['X-MailTask-GCalID']=gcal_id task_revised = True elif gcal_id and 'X-MailTask-Date-Info' not in msg: mt_gcal_sync.delete_gcal_event(gcal_id) del msg['X-MailTask-GCalID'] task_revised = True elif gcal_id and 'X-MailTask-Date-Info' in msg: mt_gcal_sync.update_gcal_event(gcal_id,(subject_str,body_str,dinfo[0],dinfo[1])) except Exception as e: print "WARNING: Google Calendar Error: "+e.message #If necessary, update task if task_revised: nsync.node_update(uidpath,msg.as_string()) print "handle_msg: update "+uidpath+" and add to mirror" print "mirror: "+repr(nsync.mirror) sys.stdout.flush() else: #not a Task: scan email headers and, if appropriate, create a new related task or update an existing one if 'From' not in msg or 'Message-ID' not in msg or client.get_email_addr_from_header(msg['From']) in ignored_senders: print "handle_msg: "+uidpath+" is from an ignored sender." sys.stdout.flush() return #If we're doing the calendar thing, check for the codeword in the subject if do_gcal and 'Subject' in msg and msg['Subject'].find(mt_gcal_sync.codeword)!=-1: chronos_tuples = [] def scan_component(component): result = mt_chronos.extract_calendar_event(component.get_payload(decode=True)) if result!=None: chronos_tuples.append(result) try: mt_utils.walk_attachments(msg,scan_component) for entry in chronos_tuples: mt_gcal_sync.insert_gcal_event(entry) return except Exception as e: print "ERROR: Attempted to schedule calendar event and failed; probable bug." print "The exception: "+repr(e) sys.stdout.flush() #Okay, now, first check if there is a Task out there that refers to a Message-ID that is also referred to by this message task_mid = None if 'References' in msg: print "handle_msg: searching "+uidpath+" related_mids for referring Task" sys.stdout.flush() related_mids = msg['References'].replace("\r","").replace("\n",",").replace("\t",",").replace(" ",",") print "handle_msg: "+repr(related_mids) sys.stdout.flush() for rmid_ in related_mids.split(","): rmid = rmid_.strip() if rmid=="": continue print "handle_msg: examining "+rmid sys.stdout.flush() if rmid in msg_dict.rev_mid_dict: print "handle_msg: msg_dict.rev_mid_dict["+rmid+"]: "+repr(msg_dict.rev_mid_dict[rmid]) sys.stdout.flush() for referring_mid in msg_dict.rev_mid_dict[rmid]: if referring_mid.find("Tasks/")==0: task_mid = referring_mid break if task_mid!=None: break #We found one: update its References and Date headers and completion status. if task_mid!=None: print "handle_msg: Updating reference header of task "+task_mid sys.stdout.flush() task_msg = email.parser.Parser().parse(open(os.path.join(client.cachedir,task_mid))) #Update related IDs relmids = mt_utils.get_related_ids(task_msg) relmids.append(msg['Message-ID']) mt_utils.set_related_ids(task_msg,relmids) #Update task_msg Date field del task_msg['Date'] task_msg['Date']=email.utils.formatdate(localtime=True) #Update task completion status del task_msg['X-MailTask-Forced-Complete'] del task_msg['X-MailTask-Completion-Status'] task_msg['X-MailTask-Completion-Status']="Incomplete" nsync.node_update(task_mid,task_msg.as_string()) else: #No existing task, so we must make one print "handle_msg: Creating new task referencing MID "+msg['Message-ID'] sys.stdout.flush() newtask=email.message.Message() nt_body = email.message.Message() nt_body['Content-Type'] = "text/plain" payload="" if client.get_email_addr_from_header(msg['From']) in email_info: payload=email_info[client.get_email_addr_from_header(msg['From'])] elif client.get_nick_from_header(msg['From']) in email_info: payload=email_info[client.get_nick_from_header(msg['From'])] nt_body.set_payload(payload) mt_utils.attach_payload(newtask,nt_body) newtask['Content-Type']="multipart/x.MailTask" newtask['Date']=email.utils.formatdate(localtime=True) newtask['Subject'] = client.get_nick_from_header(msg['From'])+": "+msg['Subject'] if 'Subject' in msg and 'From' in msg and client.get_nick_from_header(msg['From']) else "New Task" newtask['X-MailTask-Type'] = "Checklist" newtask['X-MailTask-Completion-Status'] = "Incomplete" newtask['X-MailTask-Virgin'] = "Yes" mt_utils.set_related_ids(newtask,[msg['Message-ID']]) nsync.node_update("Tasks/NEWMESSAGE",newtask.as_string())