[tor-commits] [bridgedb/main] Improve the email text for small screens

meskio at torproject.org meskio at torproject.org
Fri Nov 19 17:50:25 UTC 2021


commit 44992aaa7b78cfaf563892971ac4133bf37ca59a
Author: meskio <meskio at torproject.org>
Date:   Tue Nov 16 18:35:26 2021 +0100

    Improve the email text for small screens
    
    Split bridges so they are easier to distinguis and add instructions for
    Tails.
    
    Colses: #40028
---
 bridgedb/distributors/email/autoresponder.py |  5 ++---
 bridgedb/distributors/email/templates.py     | 29 ++++++++++++++++++----------
 bridgedb/strings.py                          | 18 +++++++++++++----
 bridgedb/test/test_email_autoresponder.py    | 16 +++++++--------
 bridgedb/test/test_email_templates.py        | 13 +++++++------
 bridgedb/test/test_smtp.py                   |  6 +++---
 scripts/nagios-email-check                   |  2 +-
 7 files changed, 54 insertions(+), 35 deletions(-)

diff --git a/bridgedb/distributors/email/autoresponder.py b/bridgedb/distributors/email/autoresponder.py
index 12f0ae1..6e901d7 100644
--- a/bridgedb/distributors/email/autoresponder.py
+++ b/bridgedb/distributors/email/autoresponder.py
@@ -111,17 +111,16 @@ def createResponseBody(lines, context, client, lang='en'):
         # invalid, or if we've already warned them about rate-limiting:
         return None, None
     else:
-        answer = "(no bridges currently available)\r\n"
+        bridgeLines = []
         qrcode = None
         if bridges:
             transport = bridgeRequest.justOnePTType()
             bridgeLines = [b.getBridgeLine(bridgeRequest, context.includeFingerprints) for b in bridges]
-            answer = "".join("  %s\r\n" % line for line in bridgeLines)
             qrcode = generateQR(bridgeLines)
             internalMetrix.recordHandoutsPerBridge(bridgeRequest, bridges)
         else:
             internalMetrix.recordEmptyEmailResponse()
-        return templates.buildAnswerMessage(translator, client, answer), qrcode
+        return templates.buildAnswerMessage(translator, client, bridgeLines), qrcode
 
 def generateResponse(fromAddress, client, body, subject=None,
                      messageID=None, qrcode=None):
diff --git a/bridgedb/distributors/email/templates.py b/bridgedb/distributors/email/templates.py
index 44450ea..e058cac 100644
--- a/bridgedb/distributors/email/templates.py
+++ b/bridgedb/distributors/email/templates.py
@@ -67,14 +67,20 @@ def addGreeting(template):
 
     return greeting
 
-def addBridgeAnswer(template, answer):
+def addBridgeAnswer(template, bridgeLines):
     # Give the user their bridges, i.e. the `answer`:
-    bridgeLines = u""
-    bridgeLines += template.gettext(strings.EMAIL_MISC_TEXT[1])
-    bridgeLines += u"\n\n"
-    bridgeLines += u"%s\n" % answer
-
-    return bridgeLines
+    bridgeText = u""
+    bridgeText += template.gettext(strings.EMAIL_MISC_TEXT[1])
+    bridgeText += u"\n\n"
+    bridgeText += "%s\r\n" % bridgeLines[0]
+    bridgeText += u"\n"
+    for line in bridgeLines[1:]:
+        bridgeText += template.gettext(strings.EMAIL_MISC_TEXT[4])
+        bridgeText += u"\n\n"
+        bridgeText += "%s\r\n" % line
+        bridgeText += u"\n"
+
+    return bridgeText
 
 def addHowto(template):
     """Add help text on how to add bridges to Tor Browser.
@@ -85,11 +91,14 @@ def addHowto(template):
     """
     return template.gettext(strings.HOWTO_TBB[2])
 
-def buildAnswerMessage(template, clientAddress=None, answer=None):
+def buildAnswerMessage(template, clientAddress=None, bridgeLines=None):
     try:
         message  = addGreeting(template)
-        message += addBridgeAnswer(template, answer)
-        message += addHowto(template)
+        if bridgeLines:
+            message += addBridgeAnswer(template, bridgeLines)
+            message += addHowto(template)
+        else:
+            message += template.gettext(strings.EMAIL_MISC_TEXT[5])
         message += u'\n\n'
         message += addCommands(template)
     except Exception as error:  # pragma: no cover
diff --git a/bridgedb/strings.py b/bridgedb/strings.py
index 09eb91b..8310be6 100644
--- a/bridgedb/strings.py
+++ b/bridgedb/strings.py
@@ -33,13 +33,18 @@ EMAIL_MISC_TEXT = {
     0: _("""\
 [This is an automated email.]"""),
     1: _("""\
-Here are your bridges:"""),
+Here is your bridge:"""),
     2: _("""\
 You have exceeded the rate limit. Please slow down! The minimum time between
 emails is %s hours. All further emails during this time period will be ignored."""),
     3: _("""\
 If these bridges are not what you need, reply to this email with one of
 the following commands in the message body:"""),
+    # TRANSLATORS: "it" here is a bridge, this sentence comes after giving a first bridge to provide a second one
+    4: _("""\
+If it doesn't work, you can try this other bridge:"""),
+    5: _("""\
+There are no bridges currently available, sorry."""),
 }
 
 WELCOME = {
@@ -163,10 +168,15 @@ HOWTO_TBB = {
  Manual explains how you can add your bridges to Tor Browser. If you are
  using Windows, Linux, or OS X, %sclick here%s to learn more. If you
  are using Android, %sclick here%s."""),
+    # TRANSLATORS: Please DO NOT translate "Tor Browser" neither "Tails".
     2: _("""\
-Add these bridges to your Tor Browser by opening your browser
-preferences, clicking on "Tor", and then adding them to the "Provide a
-bridge" field."""),
+If you are using Tor Browser:
+
+1. Choose "☰ ▸ Settings ▸ Tor" to open your Tor settings.
+
+2. In the "Bridges" section, enter your bridge in the "Provide a bridge" field.
+
+If you are using Tails, enter your bridge in the Tor Connection assistant."""),
 }
 
 EMAIL_COMMANDS = {
diff --git a/bridgedb/test/test_email_autoresponder.py b/bridgedb/test/test_email_autoresponder.py
index 566d837..7be492b 100644
--- a/bridgedb/test/test_email_autoresponder.py
+++ b/bridgedb/test/test_email_autoresponder.py
@@ -60,7 +60,7 @@ class CreateResponseBodyTests(unittest.TestCase):
         lines = self._getIncomingLines("testing at localhost")
         lines[4] = "transport obfs3"
         ret, qrcode = autoresponder.createResponseBody(lines, self.ctx, self.toAddress)
-        self.assertSubstring("Here are your bridges:", ret)
+        self.assertSubstring("Here is your bridge:", ret)
         self.assertIsNotNone(qrcode)
 
     def test_createResponseBody_bridges_obfs3(self):
@@ -68,7 +68,7 @@ class CreateResponseBodyTests(unittest.TestCase):
         lines = self._getIncomingLines("testing at localhost")
         lines[4] = "get transport obfs3"
         ret, qrcode = autoresponder.createResponseBody(lines, self.ctx, self.toAddress)
-        self.assertSubstring("Here are your bridges", ret)
+        self.assertSubstring("Here is your bridge", ret)
         self.assertSubstring("obfs3", ret)
         self.assertIsInstance(qrcode, bytes)
 
@@ -79,7 +79,7 @@ class CreateResponseBodyTests(unittest.TestCase):
         lines.append("get transport obfs2")
         lines.append("get transport obfs3")
         ret, qrcode = autoresponder.createResponseBody(lines, self.ctx, self.toAddress)
-        self.assertSubstring("Here are your bridges", ret)
+        self.assertSubstring("Here is your bridge", ret)
         self.assertSubstring("obfs3", ret)
         self.assertIsInstance(qrcode, bytes)
 
@@ -91,7 +91,7 @@ class CreateResponseBodyTests(unittest.TestCase):
         lines.append("get ipv6")
         lines.append("get transport obfs2")
         ret, qrcode = autoresponder.createResponseBody(lines, self.ctx, self.toAddress)
-        self.assertSubstring("Here are your bridges", ret)
+        self.assertSubstring("Here is your bridge", ret)
         self.assertSubstring("obfs2", ret)
         self.assertIsInstance(qrcode, bytes)
 
@@ -105,7 +105,7 @@ class CreateResponseBodyTests(unittest.TestCase):
 
         lines = self._getIncomingLines("testing at localhost")
         first, qrcode = autoresponder.createResponseBody(lines, ctx, self.toAddress)
-        self.assertSubstring("Here are your bridges", first)
+        self.assertSubstring("Here is your bridge", first)
         self.assertIsInstance(qrcode, bytes)
         second, qrcode = autoresponder.createResponseBody(lines, ctx, self.toAddress)
         self.assertSubstring("Please slow down", second)
@@ -123,13 +123,13 @@ class CreateResponseBodyTests(unittest.TestCase):
         aliceLines = self._getIncomingLines("alice at localhost")
         aliceFirst, qrcode = autoresponder.createResponseBody(aliceLines, ctx,
                                                               self.toAddress)
-        self.assertSubstring("Here are your bridges", aliceFirst)
+        self.assertSubstring("Here is your bridge", aliceFirst)
         self.assertIsInstance(qrcode, bytes)
 
         bobLines = self._getIncomingLines("bob at localhost")
         bobFirst, qrcode = autoresponder.createResponseBody(bobLines, ctx,
                                                             self.toAddress)
-        self.assertSubstring("Here are your bridges", bobFirst)
+        self.assertSubstring("Here is your bridge", bobFirst)
         self.assertIsInstance(qrcode, bytes)
 
         aliceSecond, qrcode  = autoresponder.createResponseBody(aliceLines, ctx,
@@ -148,7 +148,7 @@ class CreateResponseBodyTests(unittest.TestCase):
 
         lines = self._getIncomingLines("testing at localhost")
         first, qrcode = autoresponder.createResponseBody(lines, ctx, self.toAddress)
-        self.assertSubstring("Here are your bridges", first)
+        self.assertSubstring("Here is your bridge", first)
         self.assertIsInstance(qrcode, bytes)
         second, qrcode = autoresponder.createResponseBody(lines, ctx, self.toAddress)
         self.assertSubstring("Please slow down", second)
diff --git a/bridgedb/test/test_email_templates.py b/bridgedb/test/test_email_templates.py
index a948c91..3be3e03 100644
--- a/bridgedb/test/test_email_templates.py
+++ b/bridgedb/test/test_email_templates.py
@@ -29,7 +29,7 @@ class EmailTemplatesTests(unittest.TestCase):
     def setUp(self):
         self.t = NullTranslations(StringIO('test'))
         self.client = Address('blackhole at torproject.org')
-        self.answer = 'obfs3 1.1.1.1:1111\nobfs3 2.2.2.2:2222'
+        self.bridgeLines = ['obfs3 1.1.1.1:1111', 'obfs3 2.2.2.2:2222']
 
     def shouldIncludeCommands(self, text):
         self.assertSubstring('commands', text)
@@ -38,8 +38,9 @@ class EmailTemplatesTests(unittest.TestCase):
         self.assertSubstring('Tor Browser', text)
 
     def shouldIncludeBridges(self, text):
-        self.assertSubstring(self.answer, text)
-        self.assertSubstring('Here are your bridges:', text)
+        for line in self.bridgeLines:
+            self.assertSubstring(line, text)
+        self.assertSubstring('Here is your bridge:', text)
 
     def shouldIncludeGreeting(self, text):
         self.assertSubstring('This is an automated email', text)
@@ -60,12 +61,12 @@ class EmailTemplatesTests(unittest.TestCase):
         self.shouldIncludeInstructions(text)
 
     def test_templates_addBridgeAnswer(self):
-        text = templates.addBridgeAnswer(self.t, self.answer)
+        text = templates.addBridgeAnswer(self.t, self.bridgeLines)
         self.shouldIncludeBridges(text)
 
     def test_templates_buildAnswerMessage(self):
-        text = templates.buildAnswerMessage(self.t, self.client, self.answer)
-        self.assertSubstring(self.answer, text)
+        text = templates.buildAnswerMessage(self.t, self.client, self.bridgeLines)
+        self.shouldIncludeBridges(text)
         self.shouldIncludeAutomationNotice(text)
         self.shouldIncludeCommands(text)
 
diff --git a/bridgedb/test/test_smtp.py b/bridgedb/test/test_smtp.py
index f7261da..ab70e9b 100644
--- a/bridgedb/test/test_smtp.py
+++ b/bridgedb/test/test_smtp.py
@@ -152,7 +152,7 @@ class SMTPTests(unittest.TestCase):
 
         # then check that our local SMTP server received a response
         # and that response contained some bridges
-        self.server.getAndCheckMessageContains(b"Here are your bridges")
+        self.server.getAndCheckMessageContains(b"Here is your bridge")
 
     def test_getBridges_rateLimitExceeded(self):
         if os.environ.get("CI"):
@@ -168,7 +168,7 @@ class SMTPTests(unittest.TestCase):
 
         # then check that our local SMTP server received a response
         # and that response contained some bridges
-        self.server.getAndCheckMessageContains(b"Here are your bridges")
+        self.server.getAndCheckMessageContains(b"Here is your bridge")
 
         # send another request from the same email address
         sendMail(FROM_ADDRESS)
@@ -203,4 +203,4 @@ class SMTPTests(unittest.TestCase):
                      % random.randint(MIN_FROM_ADDRESS, MAX_FROM_ADDRESS))
 
         for i in range(NUM_MAILS):
-            self.server.getAndCheckMessageContains(b"Here are your bridges")
+            self.server.getAndCheckMessageContains(b"Here is your bridge")
diff --git a/scripts/nagios-email-check b/scripts/nagios-email-check
index 51c63a1..983943e 100755
--- a/scripts/nagios-email-check
+++ b/scripts/nagios-email-check
@@ -32,7 +32,7 @@ SMTP_SERVER = "imap.gmail.com"
 SMTP_PORT = 993
 
 MESSAGE_FROM = TO_EMAIL
-MESSAGE_BODY = "Here are your bridges:"
+MESSAGE_BODY = "Here is your bridge:"
 
 STATUS_FILE = "/srv/bridges.torproject.org/check/status"
 



More information about the tor-commits mailing list