Always use ignore_soft_deletes=False in sync backends.

We do this because otherwise the sync logic becomes horrendously complex.
There were just a couple spots where we'd made this mistake.
Use a gevent pool for actions syncback instead of Redis-plus-workers.

Summary:
This is much simpler, and we were probably going to change this eventually
anyways. The immediate reason for doing it right now is that the rq module
reconfigures the root logger, which is really annoying when you are trying to
actually configure it yourself.

Also, start the SyncbackService as a simple greenlet instead of a ZeroRPC
service (which it isn't really).

Test Plan: Unit tests updated, end-to-end syncback behavior manually verified.

Reviewers: spang

Reviewed By: spang

Differential Revision: https://review.inboxapp.com/D229
[inbox/vault] Move refresh token storage to a local vault.

Summary: Moves the storage of refresh_tokens to use the prototype vault API.

Test Plan: Run regression

Reviewers: emfree

Reviewed By: emfree

Maniphest Tasks: T117

Differential Revision: https://review.inboxapp.com/D228
Deduplicate a thread's participants by email address.
Use a less aggressive participant deduplication strategy.

Fixes T123.
Make bin/clear-db also keep 'secret' table if --with-users isn't specified.

Needed now that auth credentials are stored in that table.
* Update _process_log() for drafts.

* Test drafts reconciliation without a sync.
We now do this via two tests:
test_drafts_syncback.test_remote_save_draft() and test_reconcile_message.py,
which each test a separate chunk of that logic.
Remove old defn. of register_backends() from inbox.mailsync.backends.base
Fix crasher when Gmail 'Important' folder disabled in IMAP.

Summary:
We solve this by creating folder rows with a NULL 'name' when we have
the special Gmail label on messages but the corresponding IMAP folder is
disabled. If the folder is later re-enabled, we reconcile the existing
Folder row with the detected folder name, so messages will be properly
synced.

Note that adding `nullable=True` is merely making an existing default
explicit.

Test Plan: Manually disable Important on test account, sync messages, re-enable and verify resolution.

Reviewers: emfree

Reviewed By: emfree

Differential Revision: https://review.inboxapp.com/D232
Port logging to structlog.

Summary:
Our existing log infrastructure was not a scalable solution. We'll
funnel these structured logs into LogStash+Kibana or a similar toolchain
for searchable logs and visualizations.

structlog makes it easy to bind specific params to a given logger, so we
get more context for debugging. Awesome!

Also configure logging to just write to syslog instead of various files. This
requires a bit of configuration of rsyslog, but I think will ultimately make it
easier to set up remote log forwarding, log rotation and similar fancy stuff,
without having to worry about any of it in the actual application code.

Test Plan: Unit tests updated, and mailsync/api servers run.

Reviewers: spang

Reviewed By: spang

Differential Revision: https://review.inboxapp.com/D231
Fix merge error between previous two commits.
Adapt logging setup to work when the API server is run under gunicorn.

Summary:
Run with:
  gunicorn --worker-class inbox.api.wsgi.InboxWSGIWorker --logger-class inbox.api.wsgi.GunicornLogger inbox.api.srv:app ...

This also requires some minor changes to our existing logging setup, because
gunicorn passes positional arguments in its logging messages
(`self.log.info('message %s', some_value)`) but structlog can't currently
handle that (https://github.com/hynek/structlog/issues/19).

Test Plan:
Run `bin/inbox-api` and `gunicorn --worker-class
inbox.api.wsgi.InboxWSGIWorker --logger-class inbox.api.wsgi.GunicornLogger
--workers=1 --bind 127.0.0.1:5555 inbox.api.srv:app` and make some API
requests.

Reviewers: spang

Reviewed By: spang

Differential Revision: https://review.inboxapp.com/D235
Add LOGDIR back to config.

This is actually still needed with the new logging infrastructure, because we
save messsages with decode errors to separate files in that directory in
inbox.models.message._get_errfile_name().
Fixes Github #43: document Thread#subject_date

Summary: Rename to 'first_message_timestamp'
Update docs.

Test Plan: tests/api pass as before.

Reviewers: emfree

Differential Revision: https://review.inboxapp.com/D239
Fixed coma issues in json examples
Merge pull request #47 from lheyberger/master

Fixed coma issues in json examples
Return the same API representation for 'blocks' and 'parts'.

Summary:
Fixes issue #41. For files which have been uploaded but not actually attached
to a message, we simply set thee 'message' attribute to null.

Also remove some outdated code which defined a namespace property for Part
objects -- we now explicitly save the namespace_id in the Block parent class.

Test Plan: curl http://localhost:5555/n/<ns_id>/files

Reviewers: spang

Reviewed By: spang

Differential Revision: https://review.inboxapp.com/D234
Automatically start syncs for newly-registered accounts.

Summary:
In inbox/mailsync/service.py, poll for accounts that have been registered but
don't have syncs started, and start them.

Also remove support for the 'startall/stopall' functionality in bin/inbox-sync,
which is not that useful and adds unnecessary complexity to the normal
start/stop sync implementation.

Test Plan:
Auth a new account and check that the sync starts; run
`bin/inbox-sync start <email_address>` and `bin/inbox-sync stop <email_address>`.

Reviewers: kav-ya, spang

Reviewed By: kav-ya, spang

Subscribers: kav-ya

Differential Revision: https://review.inboxapp.com/D237
Set load_on_pending=True for namespace relationship of versioned objects.

This prevents errors when constructing the transaction log. Otherwise, if e.g.
a Block object was constructed with
block = Block(namespace_id=ns_id, ...)
then attempts to access block.namespace in the after_flush handler may
erroneously return None.
Set load_on_pending for Part.message.

Like commit 526f9620, fixes errors when constructing the transaction log.