Commit Graph

2635 Commits

Author SHA1 Message Date
Steve Howell a2747517a3 Extract StreamTopicTarget.get_active_subscriptions().
Note that this code leads to a slightly different query, because
we join to one row in the small Recipient table to match
stream_id to recipient.type_id.
2017-10-29 18:36:35 -07:00
Steve Howell 8e0b417bd9 Extract get_active_subscriptions_for_stream_ids(). 2017-10-29 18:36:35 -07:00
Steve Howell 126e14d1de Add zerver/lib/stream_subscription.py.
The first method we extract to this library is
get_active_subscriptions_for_stream_id().

We also move num_subscribers_for_stream_id() to here, which
is slightly annoying (having the method on Stream was nice)
but avoids some circular dependency issues.
2017-10-29 18:36:35 -07:00
Steve Howell 138568f4f4 refactor: Extract get_stream_recipients(). 2017-10-29 18:36:35 -07:00
Steve Howell f64c780d5c Extract get_huddle_user_ids(). 2017-10-29 18:36:35 -07:00
neiljp (Neil Pilgrim) 0781237b1f mypy: Improve typing to profile.py & remove FuncT from decorator.py.
FuncT was unused in decorator.py, and only imported into profile.py.
The @profiled decorator is now more strongly typed on return-type.
Annotations were converted to python3 format.
2017-10-29 17:10:13 -07:00
Steve Howell 8302689789 Extract Message.is_stream_message().
This sets us up to denormalize on to Message some notion of
whether a message is for a stream (without having to hit the
Recipient table).
2017-10-28 17:57:39 -07:00
Steve Howell 8b012c6210 Extract get_personal_recipient(). 2017-10-28 17:57:39 -07:00
Steve Howell 64211512f8 Avoid mutation in get_recipient_from_user_ids.
We shouldn't mutate parameters in a `get_foo` function.
2017-10-28 17:57:39 -07:00
Steve Howell 370ffe389c Extract get_huddle_recipient().
This extraction moves all the huddle logic into models.py, which
hopefully can reduce friction for things like re-organizing our
caches (there are two cache entries for every huddle) and/or
just putting huddle_id on Message directly.
2017-10-28 17:57:39 -07:00
Steve Howell a28841e8aa Extract get_stream_recipient().
Do you call get_recipient(Recipient.STREAM, stream_id) or
get_recipient(stream_id, Recipient.STREAM)?  I could never
remember, and it was not very type safe, since both parameters
are integers.
2017-10-28 17:57:39 -07:00
Harshit Bansal 4c077a77ed notifications: Instead of regex use lxml for fixing emojis. 2017-10-28 10:38:33 -07:00
Steve Howell d132c30c24 Remove `active` parameter from `do_create_user()`.
Almost all callers to do_create_user were trying to
create active users, except for one test.  The
active=False codepath was kind of broken (things
like sending welcome messages had sort of undefined
behavior there), so instead of trying to maintain it,
we just update the one test (`test_people`) to flip the
`is_active` flag manually.

Fixes #7197
2017-10-28 10:32:01 -07:00
Steve Howell d6c47573b2 Eliminate ZulipTestCase.send_message().
Now all tests use these three messages instead:

    send_stream_message
    send_personal_message
    send_huddle_message
2017-10-28 10:20:59 -07:00
Tim Abbott f2e3e779eb mypy: Properly annotate generic_bulk_cached_fetch.
Along with fixing some minor bugs, this requires extracting out the
default functions so that we can do type: ignores on them properly.

While we're at it, we switch to the Python 3 syntax.
2017-10-28 10:07:15 -07:00
Tim Abbott 73c27e1277 cache: Fix type aliasing of cached_objects.
Previously, it was converted from a CompressedItemT to an ItemT
without changing the variable name.
2017-10-28 10:01:44 -07:00
Tim Abbott 94c1da7025 cache: Move generic_bulk_cached_fetch typevars up a bit. 2017-10-28 10:00:43 -07:00
Tim Abbott 6c242379f4 bugdown: Remove unused caching imports. 2017-10-28 09:02:36 -07:00
neiljp (Neil Pilgrim) c063ba72a2 mypy: Improve typing of cache_with_key and cache decorators.
Fixes #1348.
2017-10-28 08:57:49 -07:00
Tim Abbott fa55d7ed33 retry_event: Remove requirement of failed_tries being already there.
This fixes a bug where retries in the signups queue threw an exception.
2017-10-27 18:15:53 -07:00
Tim Abbott bfa148ab39 requirements: Update mypy to latest version.
This involves fixing the mypy annotations in one file
2017-10-27 17:05:52 -07:00
Tim Abbott e5df05fd35 tests: Suppress logging spam in email mirror tests. 2017-10-27 16:06:03 -07:00
Tim Abbott 073c81bbe8 slow_tests: Increase limit for TOO slow notices. 2017-10-27 15:38:17 -07:00
Greg Price 6d403ff255 tests: Simplify set_http_host to dedupe its logic.
This will make it easier to change this logic.
2017-10-27 14:42:24 -07:00
Greg Price e4b4f67b44 subdomains: Tighten search for EXTERNAL_HOST in get_subdomain.
If a Zulip install at example.org got a request at an HTTP `Host`
like foo.example.org.evil.com (or even foo.example.orgevil.com),
we would accept it as subdomain foo.  This isn't likely to happen
in practice because it shouldn't pass ALLOWED_HOSTS, and it's not
obvious to me that anything untoward could be done with it even
if ALLOWED_HOSTS were set wide open, but if nothing else it
multiplies the cases in analyzing this logic.

The reason we had a loose match like this, I assume, is to allow
the user to come from arbitrary ports -- especially in development.
So tighten the pattern to allow just that, and add some tests for
that behavior and a comment explaining why this complication is
needed.
2017-10-27 14:42:24 -07:00
Greg Price 318682fd52 auth: Use URL rather than cookie to pass signed data cross-domain.
The cookie mechanism only works when passing the login token to a
subdomain.  URLs work across domains, which is why they're the
standard transport for SSO on the web.  Switch to URLs.

Tweaked by tabbott to add a test for an expired token.
2017-10-27 14:42:04 -07:00
Henrik Pettersson 09cd47c6ad Add UI for viewing and cancelling open Zulip invitations.
Lets administrators view a list of open(unconfirmed) invitations and
resend or revoke a chosen invitation.

There are a few changes that we can expect for the future:

  * It is currently possible to invite an email that you have already
    invited, it might make sense to change this behavior.

  * Resend currently sends an invite reminder instead of resending the
    original invite, this is because 'custom_body' was not stored when
    the first invite was sent.

Tweaked in various minor ways, primarily in the backend, by tabbott,
mostly for style consistency with the rest of the codebase.

Fixes: #1180.
2017-10-27 13:07:43 -07:00
Vishnu Ks 8c68a167fe backend: Allow Administrators to invite new users as admins.
Tweaked by tabbott to have the field before the invitation is
completed be called invite_as_admins, not invited_as_admins, for
readability.

Fixes #6834.
2017-10-27 11:19:38 -07:00
Steve Howell 4b78f69a87 tests: Introduce send_huddle_message().
The tighter interface here makes for shorter lines (or
fewer multi-line calls) and it leads to stricter type
checking.
2017-10-27 11:00:23 -07:00
Steve Howell 9707767b21 tests: Introduce send_personal_message().
The tighter interface prevents the need to specify
Recipient.PERSONAL (which can often be inaccurate in the
huddle case, anyway), and it prevents tests from confusingly
specifying a "subject" field for PMs.
2017-10-27 11:00:23 -07:00
Steve Howell 25a6fbd05d tests: Introduce send_stream_message().
Having send_stream_message() avoids the need to supply
Recipient.STREAM as a parameter, and it also uses the more
modern name of `topic_name` for topics.  Under the hood, it
avoids some annoying steps for re-formatting the recipients,
since we just have a single stream name.
2017-10-27 11:00:23 -07:00
Steve Howell 65b6676844 minor: Remove unused import (internal_send_message). 2017-10-27 10:48:11 -07:00
Steve Howell e5c5d10375 Rename subject vars in do_update_message(). 2017-10-27 10:48:11 -07:00
Steve Howell fbe5f93141 Rename subject -> topic_name in internal_send_message. 2017-10-27 10:48:11 -07:00
Steve Howell 973ee97612 Rename subject -> topic_name in internal_prep_message(). 2017-10-27 10:48:11 -07:00
Steve Howell f04550d143 Rename subject -> topic_name as var in check_message().
There were two variables, subject and subject_name, that
really had no clear distinction, so now they're just
topic_name.
2017-10-27 10:48:11 -07:00
Steve Howell 70b05998b1 Rename subject_name -> topic_name in check_send_message(). 2017-10-27 10:48:11 -07:00
derAnfaenger 64025d2ce7 integrations: Add Errbot documentation.
Fixes zulip/python-zulip-api#49.
2017-10-27 09:22:51 -07:00
Tim Abbott cab39dc6eb get_service_bot_events: Add some future-proofing.
The comment is the most important part here, but the new code
structure should help, too.
2017-10-26 22:16:47 -07:00
Tim Abbott b897c763f8 get_recipient_info: Simplify active_user_ids construction. 2017-10-26 22:16:47 -07:00
Steve Howell a70ede6c75 Allow "default" bots to see mentions on all streams.
This change allows normal bots to get UserMessage rows when
they are mentioned on a stream, even if they are not actually
subscribed to the stream.

Fixes #7140.
2017-10-26 22:16:47 -07:00
Steve Howell 53dbcbe2a4 refactor: Handle service bot mentions earlier in the code.
We now find all (possibly) relevant service bots for a message
in the call to get_recipient_info.  This allows us to eliminate
some code that would patch them after we rendered.

The get_service_bot_events() function will ignore any service
bots that weren't actually mentioned in the message (due to
backticks) or part of the active user ids.
2017-10-26 22:16:47 -07:00
Steve Howell 87b48f722d Add MentionData.get_user_ids().
This prepares us to take advantage of the user_ids
in subsequent commits related to `do_send_messages()`.
2017-10-26 22:16:47 -07:00
Steve Howell 8ac26dfb9b refactor: Introduce bugdown.MentionData class.
We now have a MentionData class that encapsulates
the users who are possibly mentioned in a message.

Not that the rendering code may not keep all the mentions,
since things like backticks will suppress the mention.

We populate this now in do_send_messages, so that we can use
the info earlier in the message-sending process.  This info
now gets passed down the call stack as an optional parameter.

Note that bugdown.convert() still populates the data when its
callers decline to pass in a MentionData object.

This is mostly a preparatory commit, as we don't take advantage
of the data yet in do_send_messages.
2017-10-26 22:16:47 -07:00
Tim Abbott 8e2cdedf9a lint: Fix lines in Python codebase longer than 120 characters. 2017-10-26 17:47:30 -07:00
Tim Abbott be619fe881 lint: Wrap many very long lines in the Python codebase.
This decreases the maximum line length in our Python codebase to 130.
2017-10-26 17:31:58 -07:00
Steve Howell 635675fe48 Reduce queries needed for sending messages.
In do_send_messages, we only produce one dictionary for
the event queues, instead of different flavors for text
vs. html.  This prevents two unnecessary queries to the
database.

It also means we only put one dictionary on the "message"
event queue instead of two, albeit a wider one that has
some values that won't be sent to the actual clients.

This wider dictionary from MessageDict.wide_dict is also
used for the `feedback_messages` queue and service bot
queues.  Since the extra fields are possibly useful down
the road, and they'll just be ignored for now, we don't
bother to remove them.  Also, those queue processors won't
have access to `content_type`, which they shouldn't need.

Fixes #6947
2017-10-26 16:35:28 -07:00
Steve Howell 9b6a4d0b16 refactor: Extract MessageDict.finalize_payload(). 2017-10-26 16:35:28 -07:00
Steve Howell df93a99b50 Cache only one row per message.
Before this change, we populated two cache entries for each
message that we sent.  The entries were largely redundant,
with the only difference being whether we sent the content
as raw markdown or as the rendered HTML.

This commit makes it so we only have one cache entry per
message, and it includes both content and rendered_content.

One legacy source on confusion here is that `content`
changes meaning when you're on the front end.  Here is the
situation going forward:

    database:
        content = raw
        rendered_contented = rendered

    cache entry:
        content = raw
        rendered_contented = rendered

    payload for the frontend:
        content = raw (for apply_markdown=False)
        content = rendered (for apply_markdown=True)
2017-10-26 16:35:28 -07:00
derAnfaenger 1792dcbd09 tests: Call real consume method of queue processors.
This switches to more real tests for a first batch of
queue_json_publish() calls that don't cause trouble when
used with call_consume_tests=True.
2017-10-26 14:58:03 -07:00
derAnfaenger 18e5bcbbb1 tests: Enable call_consume_in_tests for email mirror queue. 2017-10-26 14:53:27 -07:00
derAnfaenger 17949adf11 embedded bots: Add StateHandler remove() function. 2017-10-26 14:49:50 -07:00
Tim Abbott b8658c6901 default stream groups: Use cleaner system for error handling.
Wherever possible, we always want to move checking for error
conditions to the views code, so that we don't need to worry about
handling failures with (in this case) a user that's half-created
because a DefaultStreamGroup doesn't exist.
2017-10-26 11:38:27 -07:00
Vishnu Ks eecdc5bb61 registration: Add option to choose default stream groups.
This effectively implements the feature of default stream groups,
except for a UI, nice styling, etc.

Note that we're careful to not have this do anything in an
organization that doesn't have any default stream groups.
2017-10-26 11:34:06 -07:00
Greg Price 66ebe9720f subdomains: Refactor get_subdomain a bit.
The helper _extract_subdomain doesn't have a super meaningful
interface, and this is its one callsite.  So just inline it.
2017-10-26 10:29:17 -07:00
Greg Price cc32634439 subdomains: Simplify is_subdomain_root_or_alias.
This logic is equivalent, though it takes a couple of readings
to convince oneself of that.  This version should then be
easier to reason about.
2017-10-26 10:29:17 -07:00
Greg Price 093bae4bc5 subdomains: Fix some implicit uses of "" for the root subdomain.
These are just instances that jumped out at me while working on the
subdomains code, mostly while grepping for get_subdomain call sites.
I haven't attempted a comprehensive search, and there are likely
still others left.
2017-10-26 10:29:17 -07:00
Greg Price be309bc8b1 subdomains: Complete the refactor to user_matches_subdomain.
Now that the old `check_subdomain` has no callers except in
implementing the new, improved interface `user_matches_subdomain`,
inline it into that.  Also simplify the Boolean logic a bit.
2017-10-26 10:29:17 -07:00
Greg Price c9457d4af0 subdomains: Refactor check_subdomain to a clearer interface.
Now that every call site of check_subdomain produces its second
argument in exactly the same way, push that shared bit of logic
into a new wrapper for check_subdomain.

Also give that new function a name that says more specifically what
it's checking -- which I think is easier to articulate for this
interface than for that of check_subdomain.
2017-10-26 10:29:17 -07:00
derAnfaenger 8680541912 embedded bots: Add message flow tests. 2017-10-25 16:13:37 -07:00
derAnfaenger ce4ba9c178 bot services: Use call_consume_in_tests. 2017-10-25 15:56:12 -07:00
derAnfaenger 0473692abd embedded bots: Properly reply to PMs and streams
This fixes an exception occurring when engaging an embedded
bot in a PM, makes it respond as itself instead of the sender,
and makes it respond to the PM conversation it is engaded in.
2017-10-25 15:56:12 -07:00
derAnfaenger e041abd300 tests: Add create_test_bot() helper function. 2017-10-25 15:46:07 -07:00
derAnfaenger 3cf88d8c09 embedded bots: Add virtual_fs bot.
This will be our main bot for testing the StateHandler code.
2017-10-25 15:39:28 -07:00
derAnfaenger 0d0c8fee7e embedded bots: Migrate StateHandler API to use get and put.
This moves away from handling a StateHandler object like a dict
and gives it the methods get, put, and contains.
2017-10-25 15:39:28 -07:00
derAnfaenger 34e3eb8c67 embedded bots: Rename state and state_handler to storage. 2017-10-25 15:39:28 -07:00
derAnfaenger cd600b8677 embedded bots: Add StateHandler marshaling functions. 2017-10-25 15:39:28 -07:00
Vishnu Ks 1d94119d31 actions: Call send_initial_pms from process_new_human_user. 2017-10-25 14:14:59 -07:00
Steve Howell 14d2d4e506 Fix bug in flush_user_profile().
Every time we updated a UserProfile object, we were calling
delete_display_recipient_cache(), which churns the cache and
does an extra database hop to find subscriptions.  This was
due to saying `updated_fields` instead of `update_fields`.

This made us prone to cache churn for fields like UserProfile.pointer
that are fairly volatile.

Now we use the helper function changed().  To prevent the
opposite problem, we use all the fields that could invalidate
the cache.
2017-10-25 11:30:56 -07:00
Steve Howell c8875693c8 Extract changed() helper in flush_user_profile().
The verbose style of `changed` is partly to appease mypy.
2017-10-25 11:29:09 -07:00
Steve Howell 70c053d86f Call get_realm_stream() in access_stream_by_name(). 2017-10-25 11:29:09 -07:00
Steve Howell 305fe6106b Add `realm_non_active_users` data to initial payload.
We now add `realm_non_active_users` to the result of
`do_events_register` (and thus `page_params`).  It has
the same structure as `realm_users`, but it's for
non-active users.  Clients need data on non-active users
when they process old messages that were sent by those
users when they were active.  Clients can currently get
most of the data they need in the message events, but it
makes for ugly client code.

Fixes #4322
2017-10-25 11:18:30 -07:00
Steve Howell b94c062368 Make the realm user cache include non-active users.
This is a prepatory commit that adds non-active users to
the realm user cache.  It mostly involves name changes and
removing an `is_active` filter from the relevant DB query.

The only consumer of this cache is `get_raw_user_data`, which
now filters on `is_active` in a dictionary comprehension (but
this will get moved around a bit in a subsequent commit).
2017-10-25 11:18:30 -07:00
Steve Howell 769c741c7c refactor: Simplify event updates for `realm_users`.
We make a few things cleaner for populating `realm_users`
in `do_event_register` and `apply_events`:

    * We have a `raw_users` intermediate dictionary that
      makes event updates O(1) and cleaner to read.

    * We extract an `is_me` section for all updates that
      apply to the current user.

    * For `update` events, we do a more surgical copying
      of fields from the event into our dict.  This
      prevents us from mutating fields in the event,
      which was sketchy (at least in test mode).  In
      particular, this allowed us to remove some ugly
      `del` code related to avatars.

    * We introduce local vars `was_admin` and `now_admin`.

The cleanup had two test implications:

    * We no longer need to normalize `realm_users`, since
      `apply_events` now sees `raw_users` instead.  Since
      `raw_users` is a dict, there is no need to normalize
      it, unlike lists with possibly random order.

    * We updated the schema for avatar updates to include
      the two fields that we used to hackily delete from
      an event.
2017-10-25 11:18:30 -07:00
Shekh Ataul d239f77966 refactor: Replace mkdir_p functions with Python 3 builtin.
This didn't exist in Python 2, but it does in Python 3, so we get to
reap the rewards of dropping Python 2 support.

Fixes #7082.
2017-10-25 11:06:11 -07:00
Steve Howell 74081ff2d5 Add assert() on stream_topic in get_recipient_info(). 2017-10-24 16:02:33 -07:00
Steve Howell 6ed2a9b9f2 refactor: Rename user_ids -> message_to_user_ids.
This renaming sets the stage for the next change (and passes
all tests).
2017-10-24 14:32:17 -07:00
Tim Abbott 3ee53d5de3 auth: Don't offer password reset links when useless.
If an organization doesn't have the EmailAuthBackend (which allows
password auth) enabled, then our password reset form doesn't do
anything, so we should hide it in the UI.
2017-10-24 12:07:43 -07:00
Tim Abbott bc3569f6ab actions: Move user activate/reactivate closer to creation.
This is just to create greater locality of this batch of code in the file.
2017-10-24 09:05:55 -07:00
Steve Howell b851020b1e Excluded topic-muted users from stream push notifications.
Fixes #7059
2017-10-23 17:26:15 -07:00
Steve Howell 78b1a8442b Add StreamTopicTarget.user_ids_muting_topic(). 2017-10-23 17:26:15 -07:00
Steve Howell a66409de2e tests: Add FetchQueriesTest.test_queries().
This new test solves the problem that when we
made changes to the page-load codepath in the past,
it's been hard to identify what new code caused
more database queries.  Now you can see query
counts broken out by event type.

This requires a small, harmless change to extract
an `always_want` function in `lib/events.py`.
2017-10-23 11:11:19 -07:00
Steve Howell 0e106a2488 Add client_gratavar support to GET /messages.
Clients fetching messages can now specify that they are able
to compute their avatar, and if they set client_gratavar to
True in the request (w/our normal encoding scheme), then the
backend will not compute it, and the payload will be smaller.

The fix starts with get_messages_backend.  The flag gets
passed down through these functions:

    * MessageDict.post_process_dicts.
    * MessageDict.set_sender_avatar.

We also fix up the callers for post_process_dicts to explicitly
pass in the client_gravatar path, but for now they all just hard
code the value to False.
2017-10-20 15:49:21 -07:00
Umair Khan 2db1cba9cc i18n: Use language code instead of locale.
We have been assigning locale to language code. Mostly code and locale
are same but for languages like zh-Hans, locale is zh_Hans and code is
zh-hans.

After this commit, compilemessages command should be run.
2017-10-20 11:21:26 -07:00
Maarten Rijke 841f02934d push_notifications: Add setting to redact content.
This commit adds a setting that toggles redacting content of push
notifications and replacing it with "***REDACTED***".
2017-10-19 18:16:06 -07:00
Tim Abbott 1698f979d0 invites: Call confirmation worker consumer in tests.
This makes the automated tests for this queue publish more faithful.
2017-10-19 14:02:44 -07:00
derAnfaenger 3264e4f24a Remove superfluous queue_json_publish imports. 2017-10-19 13:57:54 -07:00
derAnfaenger c8a2702b9a embedded bots: Add functional state handler.
This replaces the former non-functional StateHandler
stub with a dictionary-like state object. Accessing it will
will read and store strings in the BotUserStateData model.

Each bot has a limited state size. To enforce this limit while
keeping data updates efficient, StateHandler caches the expensive
query for getting a bot's total state size. Assignments to a key
then only need to fetch that entry's previous size, if any, and
compare it to the new entry's size.
2017-10-19 13:09:23 -07:00
derAnfaenger 07703daf90 page_params: Add list of available embedded bots. 2017-10-19 10:37:55 -07:00
Rishi Gupta e7ba4c5168 emails: Send first welcome email right away.
I think an hour after signup is not the right time to try to get someone to
re-engage with a product.

This also makes the day1 email clearly a transactional email both in
experiencing the product and in the eyes of various anti-spam laws, and
allows us to remove the unsubscribe link.
2017-10-19 00:04:07 -07:00
Rishi Gupta a08543f1ce server settings: Add setting for MAILING_ADDRESS.
The rules here are fuzzy, and it's quite possible none of Zulip's emails
need an address at all. Every country has its own rules though, which makes
it hard to tell. In general, transactional emails do not need an address,
and marketing emails do.
2017-10-19 00:04:07 -07:00
Tim Abbott 63489ebfa5 subdomains: Avoid exception when creating realm on root domain. 2017-10-18 23:51:58 -07:00
Tim Abbott 85917a7269 subdomains: Improve support for using the root domain.
This modifies the realm creation form to (1) support a
realm_in_root_domain flag and (2) clearly check whether the root
domain is available inside check_subdomain_available before trying to
create a realm with it; this should avoid IntegrityErrors.
2017-10-18 23:38:55 -07:00
Tim Abbott 2604eb0a07 test_classes: Refactor submit_reg_form_for_user.
This is a pure refactor in preparation for adding another argument.
2017-10-18 23:30:51 -07:00
Tim Abbott 642086ff65 subdomains: Pass whether root domain is available to registration.
This data is necessary to determine whether to offer the root domain
in the realm creation form.
2017-10-18 22:53:10 -07:00
Tim Abbott 0884588a5e subdomains: Add a variable for how root domain is represented.
We use Realm.SUBDOMAIN_FOR_ROOT_DOMAIN as the special name for how the
root domain is referred to as a subdomain in the code.
2017-10-18 22:47:31 -07:00
Tim Abbott 4ddb812354 check_subdomain: Remove case for user_subdomain being None.
With REALMS_HAVE_SUBDOMAINS always on, user_subdomain is never None,
so this was just dead code.
2017-10-18 22:35:07 -07:00
Tim Abbott 1ab2ca5986 subdomains: Extract zerver.lib.subdomains library.
These never really belonged with the rest of zerver.lib.utils.py, and
having a separate library makes it easier to enforce full test
coverage.
2017-10-18 22:27:48 -07:00
Tim Abbott e98ca0714b notifications: Simplify how triggers are passed around.
This removes the utterly unnecessary `triggers` dict (which always was
a dict with exactly one value True) in favor of a single field,
'trigger'.

Inspired by Kunal Gupta's work in #6659.
2017-10-18 21:42:05 -07:00
Tim Abbott c61b6d06e5 email_mirror: Strip content before checking for empty emails.
This may fix an exception we were getting of the form:

"Error queueing internal message by emailgateway@zulip.com: Message
must not be empty".
2017-10-18 21:13:03 -07:00