[SCHEMA] Properly reconcile Inbox-created messages in IMAP sync.

Summary:
If we sync a message with an X-INBOX-ID header and already have it in that
namespace's data store, don't create a new message. Just update the existing
thread instead.

Fixes a bug in which a message sent via the Inbox API causes duplicate threads
to appear once you sync the sent message from the backend.

Note: Requires migration, but can be run online. Takes <15 minutes.

Test Plan:
Check that syncing a sent message updates the existing thread,
instead of creating an old one.

Reviewers: spang, kav-ya

Reviewed By: kav-ya

Differential Revision: https://review.inboxapp.com/D528

Conflicts:
	inbox/models/util.py
Limit scope of reconciliation test.

EAS seems to be stripping the X-INBOX-ID header. Needs more investigation;
restrict the test to other providers for now.
Create tags when we create folders in save_folder_names.

Fixes an odd bug in which, when a user somehow has both a [Gmail]/Trash folder
and a Trash label, we try to create the 'trash' tag twice, causing
IntegrityErrors.
Fix logging when g_thrid duplicate is encountered.
Download Gmail threads oldest-to-newest for better reconciliation.

Summary:
This fixes the following situation:
1) You send a message via the Inbox API. We create a Message object m1 and thread t1.

2) Somebody replies to that message.

3) We sync that reply, and create a new message m2 and new thread t2.

4) We sync the next oldest message in the thread, which was the message we sent originally. How do we reconcile? Currently, we don't create a new thread, and just update t1 with the g_thrid. But now we've actually split the thread across t1 and t2, and have two objects with the same g_thrid. That's not good.

You could imagine alternatively deleting m1 and t1 at this point, and adding a
new message m3 onto t2. But this breaks the API for users who might want to do
things like "check the original thread t1 for replies to the message that they
sent via the API".

So this seems like the best alternative solution to me. Now the first message
you sync is your original one, so the replies can be bolted on to t1.
This adds a few seconds of latency if you get new mail on a long thread during
initial sync, but that seems like a relatively small cost.

Test Plan: Not really sure how to programatically test this :/

Reviewers: spang

Reviewed By: spang

Subscribers: khamidou

Differential Revision: https://review.inboxapp.com/D535
Create canonical tags before saving folder names.

Otherwise if a user has their own 'archive' folder or similar, we may not map
it correctly to our canonical tags.
Only raise actions exceptions if it's useful.

Summary:
To reduce error-reporting noise.
For example EAS exceptions require special handling that a blind retry won't fix.
Therefore until we allow custom-retry for the actions code too, we simply log.

Test Plan: None.

Reviewers: emfree

Reviewed By: emfree

Differential Revision: https://review.inboxapp.com/D530
Fix broken link in docs.
Handle excessively many message recipients.

Summary:
We do this by emptying out the offending field and logging it as a decode error
for now.

Test Plan: Regression test added.

Reviewers: kav-ya

Differential Revision: https://review.inboxapp.com/D552
Log provider_name in commit_uids() for more
dashboard graphs.

Conflicts:
	inbox/mailsync/backends/base.py
Allow Gmail inbox and All Mail initial syncs to proceed in parallel.

Summary:
This is, for now, the most straightforward way for us to get changes to mail
that's not in the inbox while the inbox initial sync is ongoing.

Main changes:
* We do thread expansion in both the All Mail and inbox syncs.
* Thread downloads are serialized via the thread_download_lock, so that we
  don't end up trying to download the same thread twice concurrently. We might
  not *technically* have to do this, but it's definitely easier to reason
  about.

Arguably a better approach would be to have one greenlet responsible for
downloading, one for checking changes on the inbox, and one for checking
changes on All Mail, instead of having two download threads. But that's a
refactor for another day.

Associated changes:
 * Don't cache g_metadata on disk. Gnarly stuff can happen with the
   highestmodseq update, in which you're syncing, your change poller greenlet
   detects a changed highestmodseq, so you get the uids, put them on the
   download queue and update your saved highestmodseq. Then you kill the
   process. Now when you restart, you have the new highestmodseq, but not the
   uids that were dropped. So don't realize that you should actually update the
   cache, and you just lost those uids forever.

Test Plan:
Um, well, it seems to work. It definitely is correctly syncing
messages that were sent via the Inbox API (so appear in All Mail in Gmail, but
not in the inbox). I'll add a system test for this behavior.

Reviewers: spang

Differential Revision: https://review.inboxapp.com/D550
Ensure All Mail folder is selected when doing thread download.
Call crispin_client.select_folder() with proper args.
Strip message body parts.

Fixes a ParserError where we accidentally try to do quote extraction
from blank HTML.
Fix uidvalidity_cb in inbox.console.
[WIP] resync-uids script for Gmail.

We've encountered this in the wild several times at this point. It
happens.

As a first step, we provide a script which can be run manually to fix up
a specific folder on a given account. It is more difficult to deal with
a UID resync in the course of a sync, because if it's All Mail which
needs a resync, we need to block the Inbox sync as well while we fix up
the UIDs.