Преглед изворни кода

Set timeout POP3 session using pop_timeout in conf.py

version-14
Pratik Vyas пре 11 година
committed by Anand Doshi
родитељ
комит
46b2a3019b
2 измењених фајлова са 44 додато и 18 уклоњено
  1. +2
    -2
      conf/conf.py
  2. +42
    -16
      webnotes/utils/email_lib/receive.py

+ 2
- 2
conf/conf.py Прегледај датотеку

@@ -18,8 +18,8 @@ max_file_size = 1000000
# max email size in bytes # max email size in bytes
max_email_size = 0 max_email_size = 0


# max total email pulling time in seconds
max_email_time = 0
# total pop session timeout in seconds
pop_timeout = 0


# generate schema (.txt files) # generate schema (.txt files)
developer_mode = 0 developer_mode = 0


+ 42
- 16
webnotes/utils/email_lib/receive.py Прегледај датотеку

@@ -7,11 +7,10 @@ import poplib
import webnotes import webnotes
from webnotes.utils import extract_email_id, convert_utc_to_user_timezone, now, cint from webnotes.utils import extract_email_id, convert_utc_to_user_timezone, now, cint
from webnotes.utils.scheduler import log from webnotes.utils.scheduler import log
import time


class EmailSizeExceededError(webnotes.ValidationError): pass class EmailSizeExceededError(webnotes.ValidationError): pass
class EmailTimeoutError(webnotes.ValidationError): pass
class TotalSizeExceededError(webnotes.ValidationError): pass class TotalSizeExceededError(webnotes.ValidationError): pass
class TotalTimeExceededError(webnotes.ValidationError): pass


class IncomingMail: class IncomingMail:
""" """
@@ -142,7 +141,7 @@ class POP3Mailbox:
self.pop.user(self.settings.username) self.pop.user(self.settings.username)
self.pop.pass_(self.settings.password) self.pop.pass_(self.settings.password)
def get_messages(self): def get_messages(self):
if not self.check_mails(): if not self.check_mails():
return # nothing to do return # nothing to do
@@ -159,23 +158,19 @@ class POP3Mailbox:
# WARNING: Hard coded max no. of messages to be popped # WARNING: Hard coded max no. of messages to be popped
if num > 20: num = 20 if num > 20: num = 20
# time limits
self.start_time = time.time()
self.max_email_time = cint(webnotes.local.conf.get("max_email_time"))
# size limits # size limits
self.total_size = 0 self.total_size = 0
self.max_email_size = cint(webnotes.local.conf.get("max_email_size")) self.max_email_size = cint(webnotes.local.conf.get("max_email_size"))
self.max_total_size = 5 * self.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(pop_list):
# do not pull more than NUM emails # do not pull more than NUM emails
if (i+1) > num: if (i+1) > num:
break break
try: try:
self.retrieve_message(pop_meta, i+1) self.retrieve_message(pop_meta, i+1)
except (TotalSizeExceededError, TotalTimeExceededError):
except (TotalSizeExceededError, EmailTimeoutError):
break break
# WARNING: Mark as read - message number 101 onwards from the pop list # WARNING: Mark as read - message number 101 onwards from the pop list
@@ -198,8 +193,8 @@ class POP3Mailbox:
webnotes.conn.begin() webnotes.conn.begin()
self.process_message(incoming_mail) self.process_message(incoming_mail)
webnotes.conn.commit() webnotes.conn.commit()
except (TotalSizeExceededError, TotalTimeExceededError):
except (TotalSizeExceededError, EmailTimeoutError):
# propagate this error to break the loop # propagate this error to break the loop
raise raise
@@ -214,10 +209,6 @@ class POP3Mailbox:
self.pop.dele(msg_num) self.pop.dele(msg_num)
def validate_pop(self, pop_meta): def validate_pop(self, pop_meta):
# throttle based on time restriction
if self.max_email_time and (time.time() - self.start_time) > self.max_email_time:
raise TotalTimeExceededError
# throttle based on email size # throttle based on email size
if not self.max_email_size: if not self.max_email_size:
return return
@@ -247,3 +238,38 @@ class POP3Mailbox:
return error_msg return error_msg
class Timed_POP3(poplib.POP3):
def __init__(self, *args, **kwargs):
self.timeout = kwargs.pop('timeout', 0.0)
self.elapsed_time = 0.0
poplib.POP3.__init__(self, *args, **kwargs)
def _getline(self, *args, **kwargs):
start_time = time.time()
ret = poplib.POP3._getline(self, *args, **kwargs)
self.elapsed_time += time.time() - start_time
if self.timeout and self.elapsed_time > self.timeout:
raise EmailTimeoutError
return ret
def quit(self, *args, **kwargs):
self.elapsed_time = 0.0
return poplib.POP3.quit(self, *args, **kwargs)
class Timed_POP3_SSL(poplib.POP3_SSL):
def __init__(self, *args, **kwargs):
self.timeout = kwargs.pop('timeout', 0.0)
self.elapsed_time = 0
poplib.POP3_SSL.__init__(self, *args, **kwargs)
def _getline(self, *args, **kwargs):
start_time = time.time()
ret = poplib.POP3_SSL._getline(self, *args, **kwargs)
self.elapsed_time += time.time() - start_time
if self.timeout and self.elapsed_time > self.timeout:
raise EmailTimeoutError
return ret
def quit(self, *args, **kwargs):
self.elapsed_time = 0.0
return poplib.POP3_SSL.quit(self, *args, **kwargs)

Loading…
Откажи
Сачувај