Added imap with pop protocal for email retrive
This commit is contained in:
parent
abf04d1d05
commit
2f51b3efd0
4 changed files with 136 additions and 20 deletions
|
|
@ -33,11 +33,45 @@ email_defaults = {
|
|||
},
|
||||
};
|
||||
|
||||
email_defaults_imap = {
|
||||
"GMail": {
|
||||
"pop3_server": "imap.gmail.com"
|
||||
},
|
||||
"Outlook.com": {
|
||||
"pop3_server": "imap.live.com"
|
||||
},
|
||||
"Yahoo Mail": {
|
||||
"pop3_server": "imap.mail.yahoo.com"
|
||||
},
|
||||
"Yandex.Mail": {
|
||||
"pop3_server": "imap.yandex.com"
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
frappe.ui.form.on("Email Account", {
|
||||
service: function(frm) {
|
||||
$.each(email_defaults[frm.doc.service], function(key, value) {
|
||||
frm.set_value(key, value);
|
||||
})
|
||||
if (frm.doc.use_imap) {
|
||||
$.each(email_defaults_imap[frm.doc.service], function(key, value) {
|
||||
frm.set_value(key, value);
|
||||
})
|
||||
}
|
||||
},
|
||||
use_imap: function(frm) {
|
||||
console.log("in use imap");
|
||||
if (frm.doc.use_imap) {
|
||||
$.each(email_defaults_imap[frm.doc.service], function(key, value) {
|
||||
frm.set_value(key, value);
|
||||
})
|
||||
}
|
||||
else{
|
||||
$.each(email_defaults[frm.doc.service], function(key, value) {
|
||||
frm.set_value(key, value);
|
||||
})
|
||||
}
|
||||
},
|
||||
email_id: function(frm) {
|
||||
if(!frm.doc.email_account_name) {
|
||||
|
|
|
|||
|
|
@ -222,6 +222,30 @@
|
|||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "use_imap",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Use Imap",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
|
|
@ -808,13 +832,14 @@
|
|||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "icon-inbox",
|
||||
"idx": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2015-11-16 06:29:45.876335",
|
||||
"modified": "2015-11-24 17:45:31.001113",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Email",
|
||||
"name": "Email Account",
|
||||
|
|
|
|||
|
|
@ -9,13 +9,15 @@ from frappe.utils import validate_email_add, cint, get_datetime, DATE_FORMAT, st
|
|||
from frappe.utils.user import is_system_user
|
||||
from frappe.utils.jinja import render_template
|
||||
from frappe.email.smtp import SMTPServer
|
||||
from frappe.email.receive import POP3Server, Email
|
||||
from frappe.email.receive import POP3Server,Email
|
||||
from poplib import error_proto
|
||||
import re
|
||||
import imaplib
|
||||
import markdown2, re
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
class SentEmailInInbox(Exception): pass
|
||||
class SentEmailInInbox(Exception): pass # imap
|
||||
class error(Exception): pass # imap
|
||||
|
||||
class EmailAccount(Document):
|
||||
def autoname(self):
|
||||
|
|
@ -30,7 +32,7 @@ class EmailAccount(Document):
|
|||
self.name = self.email_account_name
|
||||
|
||||
def validate(self):
|
||||
"""Validate email id and check POP3 and SMTP connections is enabled."""
|
||||
"""Validate email id and check POP3/IMAP and SMTP connections is enabled."""
|
||||
if self.email_id:
|
||||
validate_email_add(self.email_id, True)
|
||||
|
||||
|
|
@ -102,7 +104,8 @@ class EmailAccount(Document):
|
|||
"host": self.pop3_server,
|
||||
"use_ssl": self.use_ssl,
|
||||
"username": getattr(self, "login_id", None) or self.email_id,
|
||||
"password": self.password
|
||||
"password": self.password,
|
||||
"use_imap":self.use_imap
|
||||
}
|
||||
|
||||
if not self.pop3_server:
|
||||
|
|
@ -111,7 +114,7 @@ class EmailAccount(Document):
|
|||
pop3 = POP3Server(frappe._dict(args))
|
||||
try:
|
||||
pop3.connect()
|
||||
except error_proto, e:
|
||||
except (error_proto,imaplib.IMAP4.error) , e:
|
||||
frappe.throw(e.message)
|
||||
|
||||
return pop3
|
||||
|
|
@ -315,14 +318,18 @@ def get_append_to(doctype=None, txt=None, searchfield=None, start=None, page_len
|
|||
if not txt: txt = ""
|
||||
return [[d] for d in frappe.get_hooks("email_append_to") if txt in d]
|
||||
|
||||
def pull(now=False):
|
||||
def pull(now=True):
|
||||
"""Will be called via scheduler, pull emails from all enabled POP3 email accounts."""
|
||||
import frappe.tasks
|
||||
print "in pull method "
|
||||
for email_account in frappe.get_list("Email Account", filters={"enable_incoming": 1}):
|
||||
print email_account
|
||||
#frappe.tasks.pull_from_email_account(frappe.local.site, email_account.name)
|
||||
if now:
|
||||
print "in now"
|
||||
frappe.tasks.pull_from_email_account(frappe.local.site, email_account.name)
|
||||
else:
|
||||
print "not now"
|
||||
frappe.tasks.pull_from_email_account.delay(frappe.local.site, email_account.name)
|
||||
|
||||
def notify_unreplied():
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
import time
|
||||
import _socket, poplib
|
||||
import _socket, poplib,imaplib
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import extract_email_id, convert_utc_to_user_timezone, now, cint, cstr, strip
|
||||
|
|
@ -36,6 +36,31 @@ class POP3Server:
|
|||
|
||||
def connect(self):
|
||||
"""Connect to **Email Account**."""
|
||||
responce = self.connect_imap() if cint(self.settings.use_imap) else self.connect_pop()
|
||||
return responce
|
||||
|
||||
def connect_imap(self):
|
||||
#this method return imap connection
|
||||
try:
|
||||
if cint(self.settings.use_ssl):
|
||||
self.imap = Timed_IMAP4_SSL(self.settings.host, timeout=frappe.conf.get("pop_timeout"))
|
||||
else:
|
||||
self.imap = Timed_IMAP4(self.settings.host, timeout=frappe.conf.get("pop_timeout"))
|
||||
self.imap.login(self.settings.username,self.settings.password)
|
||||
# connection established!
|
||||
return True
|
||||
|
||||
except _socket.error:
|
||||
# Invalid mail server -- due to refusing connection
|
||||
frappe.msgprint(_('Invalid Mail Server. Please rectify and try again.'))
|
||||
raise
|
||||
|
||||
except :
|
||||
frappe.msgprint(_('Invalid User Name or Support Password. Please rectify and try again.'))
|
||||
raise
|
||||
|
||||
def connect_pop(self):
|
||||
#this method return pop connection
|
||||
try:
|
||||
if cint(self.settings.use_ssl):
|
||||
self.pop = Timed_POP3_SSL(self.settings.host, timeout=frappe.conf.get("pop_timeout"))
|
||||
|
|
@ -75,8 +100,14 @@ class POP3Server:
|
|||
# track if errors arised
|
||||
self.errors = False
|
||||
self.latest_messages = []
|
||||
pop_list = self.pop.list()[1]
|
||||
num = num_copy = len(pop_list)
|
||||
# if section code below is for imap and else part is for pop3
|
||||
if cint(self.settings.use_imap):
|
||||
self.imap.select("Inbox")
|
||||
responce, message = self.imap.uid('search',None, "UNSEEN") # search and return Uids
|
||||
email_list = message[0].split()
|
||||
else:
|
||||
email_list = self.pop.list()[1]
|
||||
num = num_copy = len(email_list)
|
||||
|
||||
# WARNING: Hard coded max no. of messages to be popped
|
||||
if num > 20: num = 20
|
||||
|
|
@ -86,20 +117,24 @@ class POP3Server:
|
|||
self.max_email_size = cint(frappe.local.conf.get("max_email_size"))
|
||||
self.max_total_size = 5 * self.max_email_size
|
||||
|
||||
for i, pop_meta in enumerate(pop_list):
|
||||
for i, pop_meta in enumerate(email_list):
|
||||
# do not pull more than NUM emails
|
||||
if (i+1) > num:
|
||||
break
|
||||
|
||||
try:
|
||||
self.retrieve_message(pop_meta, i+1)
|
||||
# if section code below is for imap and else part is for pop3
|
||||
if cint(self.settings.use_imap):
|
||||
self.retrieve_message(pop_meta)
|
||||
else:
|
||||
self.retrieve_message(pop_meta, i+1)
|
||||
except (TotalSizeExceededError, EmailTimeoutError, LoginLimitExceeded):
|
||||
break
|
||||
|
||||
# WARNING: Mark as read - message number 101 onwards from the pop list
|
||||
# This is to avoid having too many messages entering the system
|
||||
num = num_copy
|
||||
if num > 100 and not self.errors:
|
||||
if num > 100 and not self.errors and not cint(self.settings.use_imap):
|
||||
for m in xrange(101, num+1):
|
||||
self.pop.dele(m)
|
||||
|
||||
|
|
@ -112,17 +147,25 @@ class POP3Server:
|
|||
|
||||
finally:
|
||||
# no matter the exception, pop should quit if connected
|
||||
self.pop.quit()
|
||||
if cint(self.settings.use_imap):
|
||||
self.imap.logout()
|
||||
else:
|
||||
self.pop.quit()
|
||||
|
||||
return self.latest_messages
|
||||
|
||||
def retrieve_message(self, pop_meta, msg_num):
|
||||
def retrieve_message(self, pop_meta,msg_num=None):
|
||||
incoming_mail = None
|
||||
try:
|
||||
self.validate_pop(pop_meta)
|
||||
msg = self.pop.retr(msg_num)
|
||||
# if section code below is for imap and else part is for pop3
|
||||
if cint(self.settings.use_imap):
|
||||
status,message = self.imap.uid('fetch', pop_meta, '(RFC822)')
|
||||
self.latest_messages.append(message[0][1])
|
||||
else:
|
||||
msg = self.pop.retr(msg_num)
|
||||
|
||||
self.latest_messages.append(b'\n'.join(msg[1]))
|
||||
self.latest_messages.append(b'\n'.join(msg[1]))
|
||||
|
||||
except (TotalSizeExceededError, EmailTimeoutError):
|
||||
# propagate this error to break the loop
|
||||
|
|
@ -140,9 +183,11 @@ class POP3Server:
|
|||
self.errors = True
|
||||
frappe.db.rollback()
|
||||
|
||||
self.pop.dele(msg_num)
|
||||
if not cint(self.settings.use_imap):
|
||||
self.pop.dele(msg_num)
|
||||
else:
|
||||
self.pop.dele(msg_num)
|
||||
if not cint(self.settings.use_imap):
|
||||
self.pop.dele(msg_num)
|
||||
|
||||
def has_login_limit_exceeded(self, e):
|
||||
return "-ERR Exceeded the login limit" in strip(cstr(e.message))
|
||||
|
|
@ -355,3 +400,8 @@ class Timed_POP3(TimerMixin, poplib.POP3):
|
|||
|
||||
class Timed_POP3_SSL(TimerMixin, poplib.POP3_SSL):
|
||||
_super = poplib.POP3_SSL
|
||||
class Timed_IMAP4(TimerMixin, imaplib.IMAP4):
|
||||
_super = imaplib.IMAP4
|
||||
|
||||
class Timed_IMAP4_SSL(TimerMixin, imaplib.IMAP4_SSL):
|
||||
_super = imaplib.IMAP4_SSL
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue