# -*- coding: utf-8 ; test-case-name: bridgedb.test.test_strings ; -*-
#
# This file is part of BridgeDB, a Tor bridge distribution system.
#
# :authors: Isis Lovecruft 0xA3ADB67A2CDB8B35 <isis@torproject.org>
# :copyright: (c) 2007-2015, The Tor Project, Inc.
#             (c) 2013-2015, Isis Lovecruft
#             (c) 2007-2015, all entities within the AUTHORS file
# :license: 3-clause BSD, see included LICENSE for information

"""Commonly used string constants.

.. todo:: The instructions for the OpenPGP keys in
    :data:`BRIDGEDB_OPENPGP_KEY` are not translated… should we translate them?
    Should we tell users where to obtain GPG4Win/GPGTools/gnupg?  Should those
    instruction be that verbose?  Or should we get rid of the instructions
    altogether, and assume that any encouragement towards using GPG will just
    make users more frustrated, and (possibly) (mis-)direct that frustration
    at Tor or BridgeDB?
"""

from __future__ import unicode_literals

# This won't work on Python2.6, however
#     1) We don't use Python2.6, and
#     2) We don't care about supporting Python2.6, because Python 2.6 (and,
#        honestly, all of Python2) should die.
from collections import OrderedDict


def _(text):
    """This is necessary because strings are translated when they're imported.
    Otherwise this would make it impossible to switch languages more than
    once.

    :returns: The **text**.
    """
    return text


# TRANSLATORS: Please do not translate the word "TYPE".
EMAIL_MISC_TEXT = {
    0: _("""\
[This is an automated message; please do not reply.]"""),
    1: _("""\
Here are your bridges:"""),
    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: _("""\
COMMANDs: (combine COMMANDs to specify multiple options simultaneously)"""),
    # TRANSLATORS: Please DO NOT translate the word "BridgeDB".
    4: _("Welcome to BridgeDB!"),
    # TRANSLATORS: Please DO NOT translate the words "transport" or "TYPE".
    5: _("Currently supported transport TYPEs:"),
    6: _("Hey, %s!"),
    7: _("Hello, friend!"),
    8: _("Public Keys"),
    # TRANSLATORS: This string will end up saying something like:
    # "This email was generated with rainbows, unicorns, and sparkles
    #  for alice@example.com on Friday, 09 May, 2014 at 18:59:39."
    9: _("""\
This email was generated with rainbows, unicorns, and sparkles
for %s on %s at %s."""),
}

WELCOME = {
    # TRANSLATORS: Please DO NOT translate "BridgeDB".
    # TRANSLATORS: Please DO NOT translate "Pluggable Transports".
    # TRANSLATORS: Please DO NOT translate "Tor".
    # TRANSLATORS: Please DO NOT translate "Tor Network".
    0: _("""\
BridgeDB can provide bridges with several %stypes of Pluggable Transports%s,
which can help obfuscate your connections to the Tor Network, making it more
difficult for anyone watching your internet traffic to determine that you are
using Tor.\n\n"""),

    # TRANSLATORS: Please DO NOT translate "Pluggable Transports".
    1: _("""\
Some bridges with IPv6 addresses are also available, though some Pluggable
Transports aren't IPv6 compatible.\n\n"""),

    # TRANSLATORS: Please DO NOT translate "BridgeDB".
    # TRANSLATORS: The phrase "plain-ol'-vanilla" means "plain, boring,
    # regular, or unexciting". Like vanilla ice cream. It refers to bridges
    # which do not have Pluggable Transports, and only speak the regular,
    # boring Tor protocol. Translate it as you see fit. Have fun with it.
    2: _("""\
Additionally, BridgeDB has plenty of plain-ol'-vanilla bridges %s without any
Pluggable Transports %s which maybe doesn't sound as cool, but they can still
help to circumvent internet censorship in many cases.\n\n"""),
}
"""These strings should go on the first "Welcome" email sent by the
:mod:`~bridgedb.EmailServer`, as well as on the ``index.html`` template used
by the :mod:`~bridgedb.https.server`. They are used as an introduction to
explain what Tor bridges are, what bridges do, and why someone might want to
use bridges.
"""

FAQ = {
    0: _("What are bridges?"),
    1: _("""\
%s Bridges %s are Tor relays that help you circumvent censorship."""),
}

OTHER_DISTRIBUTORS = {
    0: _("I need an alternative way of getting bridges!"),
    1: _("""\
Another way to get bridges is to send an email to %s. Please note that you must
send the email using an address from one of the following email providers:
%s, %s or %s."""),
}

HELP = {
    0: _("My bridges don't work! I need help!"),
    # TRANSLATORS: Please DO NOT translate "Tor".
    1: _("""If your Tor doesn't work, you should email %s."""),
    # TRANSLATORS: Please DO NOT translate "Pluggable Transports".
    # TRANSLATORS: Please DO NOT translate "Tor Browser".
    # TRANSLATORS: Please DO NOT translate "Tor".
    2: _("""\
Try including as much info about your case as you can, including the list of
bridges and Pluggable Transports you tried to use, your Tor Browser version,
and any messages which Tor gave out, etc."""),
}

BRIDGES = {
    0: _("Here are your bridge lines:"),
    1: _("Get Bridges!"),
}

OPTIONS = {
    0: _("Please select options for bridge type:"),
    1: _("Do you need IPv6 addresses?"),
    2: _("Do you need a %s?"),
}

CAPTCHA = {
    0: _('Your browser is not displaying images properly.'),
    1: _('Enter the characters from the image above...'),
}

HOWTO_TBB = {
    0: _("""How to start using your bridges"""),
    # TRANSLATORS: Please DO NOT translate "Tor Browser".
    1: _("""\
To enter bridges into Tor Browser, first go to the %s Tor Browser download
page %s and then follow the instructions there for downloading and starting
Tor Browser."""),
    # TRANSLATORS: Please DO NOT translate "Tor".
    2: _("""\
When the 'Tor Network Settings' dialogue pops up, click 'Configure' and follow
the wizard until it asks:"""),
    # TRANSLATORS: Please DO NOT translate "Tor".
    3: _("""\
Does your Internet Service Provider (ISP) block or otherwise censor connections
to the Tor network?"""),
    # TRANSLATORS: Please DO NOT translate "Tor".
    4: _("""\
Select 'Yes' and then click 'Next'. To configure your new bridges, copy and
paste the bridge lines into the text input box. Finally, click 'Connect', and
you should be good to go! If you experience trouble, try clicking the 'Help'
button in the 'Tor Network Settings' wizard for further assistance."""),
}

EMAIL_COMMANDS = {
    "get help":             _("Displays this message."),
# TRANSLATORS: Please try to make it clear that "vanilla" here refers to the
# same non-Pluggable Transport bridges described above as being
# "plain-ol'-vanilla" bridges.
    "get bridges":          _("Request vanilla bridges."),
    "get ipv6":             _("Request IPv6 bridges."),
    # TRANSLATORS: Please DO NOT translate the word the word "TYPE".
    "get transport [TYPE]": _("Request a Pluggable Transport by TYPE."),
    # TRANSLATORS: Please DO NOT translate "BridgeDB".
    # TRANSLATORS: Please DO NOT translate "GnuPG".
    "get key":              _("Get a copy of BridgeDB's public GnuPG key."),
    #"subscribe":            _("Subscribe to receive new bridges once per week"),
    #"unsubscribe":          _("Cancel a subscription to new bridges"),
}

#-----------------------------------------------------------------------------
#           All of the following containers are untranslated!
#-----------------------------------------------------------------------------

#: SUPPORTED TRANSPORTS is dictionary mapping all Pluggable Transports
#: methodname to whether or not we actively distribute them. The ones which we
#: distribute SHOULD have the following properties:
#:
#:   1. The PT is in a widely accepted, usable state for most Tor users.
#:   2. The PT is currently publicly deployed *en masse*".
#:   3. The PT is included within the transports which Tor Browser offers in
#:      the stable releases.
#:
#: These will be sorted by methodname in alphabetical order.
#:
#: ***Don't change this setting here; change it in :file:`bridgedb.conf`.***
SUPPORTED_TRANSPORTS = {}

#: DEFAULT_TRANSPORT is a string. It should be the PT methodname of the
#: transport which is selected by default (e.g. in the webserver dropdown
#: menu).
#:
#: ***Don't change this setting here; change it in :file:`bridgedb.conf`.***
DEFAULT_TRANSPORT = ''

def _getSupportedTransports():
    """Get the list of currently supported transports.

    :rtype: list
    :returns: A list of strings, one for each supported Pluggable Transport
        methodname, sorted in alphabetical order.
    """
    supported = [name.lower() for name,w00t in SUPPORTED_TRANSPORTS.items() if w00t]
    supported.sort()
    return supported

def _setDefaultTransport(transport):
    global DEFAULT_TRANSPORT
    DEFAULT_TRANSPORT = transport

def _getDefaultTransport():
    return DEFAULT_TRANSPORT

def _setSupportedTransports(transports):
    """Set the list of currently supported transports.

    .. note: You shouldn't need to touch this. This is used by the config file
        parser. You should change the SUPPORTED_TRANSPORTS dictionary in
        :file:`bridgedb.conf`.

    :param dict transports: A mapping of Pluggable Transport methodnames
        (strings) to booleans.  If the boolean is ``True``, then the Pluggable
        Transport is one which we will (more easily) distribute to clients.
        If ``False``, then we (sort of) don't distribute it.
    """
    global SUPPORTED_TRANSPORTS
    SUPPORTED_TRANSPORTS = transports

def _getSupportedAndDefaultTransports():
    """Get a dictionary of currently supported transports, along with a boolean
    marking which transport is the default.

    It is returned as a :class:`collections.OrderedDict`, because if it is a
    regular dict, then the dropdown menu would populated in random order each
    time the page is rendered.  It is sorted in alphabetical order.

    :rtype: :class:`collections.OrderedDict`
    :returns: An :class:`~collections.OrderedDict` of the Pluggable Transport
        methodnames from :data:`SUPPORTED_TRANSPORTS` whose value in
        ``SUPPORTED_TRANSPORTS`` is ``True``.  If :data:`DEFAULT_TRANSPORT` is
        set, then the PT methodname in the ``DEFAULT_TRANSPORT`` setting is
        added to the :class:`~collections.OrderedDict`, with the value
        ``True``. Every other transport in the returned ``OrderedDict`` has
        its value set to ``False``, so that only the one which should be the
        default PT is ``True``.
    """
    supported = _getSupportedTransports()
    transports = OrderedDict(zip(supported, [False for _ in range(len(supported))]))

    if DEFAULT_TRANSPORT:
        transports[DEFAULT_TRANSPORT] = True

    return transports

EMAIL_SPRINTF = {
    # Goes into the "%s types of Pluggable Transports %s" part of ``WELCOME[0]``
    "WELCOME0": ("", "[0]"),
    # Goes into the "%s without Pluggable Transport %s" part of ``WELCOME[2]``
    "WELCOME2": ("-", "-"),
    # For the "%s Tor Browser download page %s" part of ``HOWTO_TBB[1]``
    "HOWTO_TBB1": ("", "[0]"),
    # For the "you should email %s" in ``HELP[0]``
    "HELP0": ("help@rt.torproject.org"),
}
"""``EMAIL_SPRINTF`` is a dictionary that maps translated strings which
contain format specifiers (i.e. ``%s``) to what those format specifiers should
be replaced with in a given template system.

For example, a string which needs a pair of HTML ``("<a href=''">, "</a>")``
tags (for the templates used by :mod:`bridgedb.https.server`) would need some
alternative replacements for the :mod:`EmailServer`, because the latter uses
templates with a ``text/plain`` mimetype instead of HTML. For the
``EmailServer``, the format strings specifiers are replaced with an empty
string where the opening ``<a>`` tags would go, and a numbered Markdown link
specifier where the closing ``</a>`` tags would go.

The keys in this dictionary are the Python variable names of the corresponding
strings which are being formatted, i.e. ``WELCOME0`` would be the string
replacements for ``strings.WELCOME.get(0)``.


For example, the ``0`` string in :data:`WELCOME` above has the substring::

    "%s without Pluggable Transport %s"

and so to replace the two ``%s`` format specifiers, you would use this mapping
like so::

>>> from bridgedb import strings
>>> welcome = strings.WELCOME[0] % strings.EMAIL_SPRINTF["WELCOME0"]
>>> print welcome.split('\n')[0]
BridgeDB can provide bridges with several types of Pluggable Transports[0],

"""

EMAIL_REFERENCE_LINKS = {
    "WELCOME0": "[0]: https://www.torproject.org/docs/pluggable-transports.html",
    "HOWTO_TBB1": "[0]: https://www.torproject.org/projects/torbrowser.html",
}

BRIDGEDB_OPENPGP_KEY = """\
# This keypair contains BridgeDB's online signing and encryption subkeys. This
# keypair rotates because it is kept online. However, the current online
# keypair will *ALWAYS* be certified by the offline keypair (at the bottom of
# this file).
#
# If you receive an email from BridgeDB, it should be signed with the
# 21B554E95938F4D0 subkey from the following keypair:

# pub   4096R/8DC43A2848821E32 2013-09-11 [expires: 2015-09-11]
#       Key fingerprint = DF81 1109 E17C 8BF1 34B5  EEB6 8DC4 3A28 4882 1E32
# uid                          BridgeDB <bridges@bridges.torproject.org>
# sub   4096R/21B554E95938F4D0 2013-09-11 [expires: 2015-09-11]
#       Key fingerprint = 9FE3 9D1A 7438 9223 3B3F  66F2 21B5 54E9 5938 F4D0
# sub   4096R/E7793047C5B54232 2013-09-11 [expires: 2015-09-11]
#       Key fingerprint = CFFB 8469 9048 37E7 8CAE  322C E779 3047 C5B5 4232

-----BEGIN PGP PUBLIC KEY BLOCK-----


9OgcN7A8kFuNpgp2EHqj1/jrwd7mZYKsWTuGiR/7fwXf+4xbvg==
=raCx
-----END PGP PUBLIC KEY BLOCK-----

# The following keypair is BridgeDB's offline certification-only keypair. It
# is used to sign new online signing/encryption keypairs.
#
# If you import this key and mark it as trusted, emails from BridgeDB (if
# signed correctly with the online keypair above) should always be trusted. To
# do this, open a shell and do:
#
#     $ curl -O https://bridges.torproject.org/keys
#     $ gpg --import keys
#     $ gpg --check-sigs 7B78437015E63DF47BB1270ACBD97AA24E8E472E
#     $ gpg --edit-key 7B78437015E63DF47BB1270ACBD97AA24E8E472E
#
# Then type 'trust' to set the trust level. Choose a number that you like.
# Next type 'quit'. Finally, to create a local signature which will will not
# be uploaded to keyservers:
#
#     $ gpg --lsign-key 7B78437015E63DF47BB1270ACBD97AA24E8E472E
#

# pub   16384R/CBD97AA24E8E472E 2013-10-12
#      Key fingerprint = 7B78 4370 15E6 3DF4 7BB1  270A CBD9 7AA2 4E8E 472E
# uid            BridgeDB (Offline ID Key) <bridges@bridges.torproject.org>
-----BEGIN PGP PUBLIC KEY BLOCK-----


ZxOds8F/UJYDSIB97MQFzBo=
=JdC7
-----END PGP PUBLIC KEY BLOCK-----
"""
