commit 1ebe00e786a5a36856cd8db6c3ea54e8c0681907 Author: Christian Fromme kaner@strace.org Date: Sun Oct 16 21:04:29 2011 +0200
Allowed attachment size of your provider too small? Get a nice response by GetTor telling you so. Fixes #4166, #2520 and parts of #3920 --- gettor.conf | 5 +++++ lib/gettor/i18n.py | 10 +++++++++- lib/gettor/requests.py | 4 +++- lib/gettor/responses.py | 41 +++++++++++++++++++++++++++++++++++++++-- lib/gettor/utils.py | 34 +++++++++++++++++++++++++++++----- 5 files changed, 85 insertions(+), 9 deletions(-)
diff --git a/gettor.conf b/gettor.conf index 56f8c35..c022e88 100644 --- a/gettor.conf +++ b/gettor.conf @@ -33,6 +33,11 @@ BLACKLIST_THRES = 3 # Which mirror to sync packages from RSYNC_MIRROR = "rsync.torproject.org"
+# Which email provider allows for what size of attachments? (Size in MB) +PROVIDER_ATTACHMENT_SIZES = { "gmail.com": 25, + "yahoo.com": 25, + "yahoo.cn": 25 } + # Default locale DEFAULT_LOCALE = "en"
diff --git a/lib/gettor/i18n.py b/lib/gettor/i18n.py index 64c9a5c..6c77fd2 100644 --- a/lib/gettor/i18n.py +++ b/lib/gettor/i18n.py @@ -269,5 +269,13 @@ _("""How do I extract the file(s) you sent me?"""), # GETTOR_TEXT[63] _("""QUESTION:"""), # GETTOR_TEXT[64] -_("""ANSWER:""") +_("""ANSWER:"""), + # GETTOR_TEXT[65] +_("""Sorry, but the package you requested (%s) is too large for your +provider to accept as an attachment. Try using another provider that allows +for larger email attachments. Or try one of the following mirrors: + + https://www.oignon.net/dist/torbrowser/ + https://tor.beme-it.de/dist/torbrowser/ + https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/""") ] diff --git a/lib/gettor/requests.py b/lib/gettor/requests.py index 0a2741e..4383813 100644 --- a/lib/gettor/requests.py +++ b/lib/gettor/requests.py @@ -24,13 +24,15 @@ class requestMail: self.request['user'] = self.parsedMessage["Return-Path"] # Normalize address before hashing normalized_addr = gettor.utils.normalizeAddress(self.request['user']) + max_attach = gettor.utils.getMaxAttSize(normalized_addr, config) self.request['hashed_user'] = gettor.utils.getHash(normalized_addr) self.request['ouraddr'] = self.getRealTo(self.parsedMessage["to"]) self.request['locale'] = self.getLocaleInTo(self.request['ouraddr']) self.request['package'] = None self.request['split'] = False self.request['forward'] = None - self.request['valid'] = False # This will get set by gettor.filters + self.request['valid'] = False # This will get set by gettor.filters + self.request['max_attach'] = max_attach
def getRealTo(self, toField): """If someone wrote to `gettor+zh_CN@torproject.org', the `From:' field diff --git a/lib/gettor/responses.py b/lib/gettor/responses.py index 6a5adf7..6448f37 100644 --- a/lib/gettor/responses.py +++ b/lib/gettor/responses.py @@ -165,6 +165,11 @@ def getDelayAlertMsg(t, packageInfo): + t.gettext(i18n.GETTOR_TEXT[39]) + "\n\n" \ + getSupportText(t)
+def getSorrySizeMsg(t, packageInfo): + return getGreetingText(t) \ + + t.gettext(i18n.GETTOR_TEXT[65] % packageInfo) + "\n\n" \ + + getSupportText(t) + def getNoSplitAvailable(t): return getGreetingText(t) \ + t.gettext(i18n.GETTOR_TEXT[1]) + "\n\n" \ @@ -210,7 +215,27 @@ class Response: if self.reqInfo['split']: return self.sendSplitPackage() else: - return self.sendPackage() + # Check if the user's allowed attachment size is okay. + if self.attachmentSizeOk(self.reqInfo['package'], self.reqInfo['max_attach']): + return self.sendPackage() + else: + return self.sendSorrySize() + + def attachmentSizeOk(self, package, max_attach): + """Check if the user is allowed to receive a certain attachment size-wise. + """ + if max_attach == 0: + return True + + try: + package_path = os.path.join(self.config.BASEDIR, "packages", package + ".z") + package_size = os.path.getsize(package_path) + if package_size <= max_attach: + return True + except OSError: + log.error("Ugh, this is bad. package %s isnt available!" % package_path) + + return False
def isAllowed(self): """Do all checks necessary to decide whether the reply-to user is @@ -365,7 +390,19 @@ class Response:
logging.info("Sending delay alert to %s" % self.reqInfo['hashed_user']) return self.sendTextEmail(getDelayAlertMsg(self.t, packageInfo)) - + + + def sendSorrySize(self): + """Send a polite note that the user's provider doesn't support the + attachment size necessary for a given package. + """ + if self.isBlacklistedForMessageType("sendSorrySize"): + # Don't send anything + return False + + logging.info("Sending sorry size email to %s" % self.reqInfo['hashed_user']) + return self.sendTextEmail(getSorrySizeMsg(self.t, self.reqInfo['package'])) + def sendHelp(self): """Send a help mail. This happens when a user sent us a request we didn't really understand diff --git a/lib/gettor/utils.py b/lib/gettor/utils.py index c06e40f..edcd945 100644 --- a/lib/gettor/utils.py +++ b/lib/gettor/utils.py @@ -298,6 +298,25 @@ def removeFromListByRegex(l, string):
return l
+def getBase64Size(unencoded_size): + """Return the number of bytes a given byte sequence will expand to if it + is base64 (MIME) encoded. + + Source for the formula: Wikipedia + """ + return (unencoded_size + 814) * 1.37 + +def getMaxAttSize(addr, config): + """Return the maximum attachment size allowed for a certain email + provider. If the provider isn't known by us, return 0, indicating + an unlimited attachment size. + """ + (_, domain) = emailGetLocalAndDomainPart(addr) + if domain in config.PROVIDER_ATTACHMENT_SIZES: + return config.PROVIDER_ATTACHMENT_SIZES[domain] * 1024 * 1024 + else: + return 0 + # The following code is more or less taken from BridgeDB
class BadEmail(Exception): @@ -355,10 +374,10 @@ def extractAddrSpec(addr): localpart, domain = m.groups() return localpart, domain
-def normalizeEmail(addr): - """Given the contents of a from line, and a map of supported email - domains (in lowercase), raise BadEmail or return a normalized - email address. +def emailGetLocalAndDomainPart(addr): + """For a given email address, return a touple of localpart, domainpart. + Example: + bla@foo.org -> bla, foo.org """ addr = addr.lower() localpart, domain = extractAddrSpec(addr) @@ -369,5 +388,10 @@ def normalizeEmail(addr): localpart = localpart[:idx] localpart = localpart.replace(".", "")
- return "%s@%s"%(localpart, domain) + return localpart, domain + +def normalizeEmail(addr): + """Return normalized email address. + """ + return "%s@%s" % emailGetLocalAndDomainPart(addr)
tor-commits@lists.torproject.org