[api/drafts] Accept PUT to /drafts/ID instead of POST.

Summary:
According to Wikipedia (see: http://en.wikipedia.org/wiki/Representational_state_transfer), here are the following definitions for POST and PUT to an Element URI (e.g. /drafts/<draft_id>):

PUT:
Replace the addressed member of the collection, or if it doesn't exist, create it.

POST:
Not generally used. Treat the addressed member as a collection in its own right and create a new entry in it.

Technically, we are abusing 'PUT' as an 'UPDATE' call, which is certainly bending the RESTful semantics (see: http://jcalcote.wordpress.com/2008/10/16/put-or-post-the-rest-of-the-story/ , http://cafe.elharo.com/web/put-is-not-update/ ). However, we are using the PUT method in other places within the project to mean UPDATE (it's even called draft_update_api). Therefore, we should at least be consistent and use the PUT method on drafts for updating them.

Fixes T360

Test Plan: Review code, references, run tests.

Reviewers: spang

Reviewed By: spang

Maniphest Tasks: T360

Differential Revision: https://review.inboxapp.com/D391
[api/tags] Accept the namespace_id parameter for tag creation and updates. Add tests for better coverage of /tags api endpoint.

Summary:
The /tags endpoint previously would not accept a "namespace_id" parameter, even though it returns one when you create it. This not only doesn't agree with RESTful semantics (you should be able to replace the object in-full using a PUT / POST), it also doesn't gel with other endpoints and requires some work-arounds in the python libraries to special case tags. Instead we now accept the 'namespace_id' parameter as well as tests for full coverage of the /tags endpoint.

Fixes T359

Test Plan: run the tests.

Reviewers: spang

Reviewed By: spang

Maniphest Tasks: T359

Differential Revision: https://review.inboxapp.com/D392
[calendar/api] Initial calendar api support.

Summary:
[calendar+event/api] Add filtering + testing.

Fixes T364

Test Plan: Review code + tests

Reviewers: spang

Reviewed By: spang

Maniphest Tasks: T364

Differential Revision: https://review.inboxapp.com/D386
Fix bugs in migration 085 which caused OOM on large datasets.

It was trying to load all threads and all messages into memory at the
same time, and also does not seem to explicitly commit changed data.
[api/filtering] Update filtering for a few endpoints (drafts, files). Add tests.

Summary:
[api/filtering] Update filtering for a few endpoints (drafts, files). Add tests.

Fixes T365

Test Plan: run regression

Reviewers: spang

Reviewed By: spang

Maniphest Tasks: T365

Differential Revision: https://review.inboxapp.com/D390
[misc] Fix alembic branch.
[build/setup.sh] Add libsodium setup to install flow. NOTE: for some reason we hang on pip install -e .

Summary:
We now require libsodium as a dependency, however it wasn't a part of the install flow. This patch adds it to the install flow. Since there isn't an ubuntu package available we download (check hash) and install from source. As noted in the title, the setup for some reasn seems to be hanging on 'pip install -e .' for me. If that happens for others we should file a task, otherwise I can ignore.

Fixes T366

Test Plan: checkout master without libsodium installed, run the setup and verify that you can install the pynacl package.

Reviewers: kav-ya, spang, dlitz

Reviewed By: spang, dlitz

Subscribers: dlitz

Projects: #security

Maniphest Tasks: T366

Differential Revision: https://review.inboxapp.com/D393
[setup/libsodium] Update to latest version of libsodium.
Show API-uploaded files along attachments

Summary:
The problem: a GET request on /files/ returns only email attachments. To change this I modified the filtering options. Instead of only querying Parts I changed the code to query Blocks and filter blocks who don't have a content type (IIRC email parts must have a content type and we force API-uploaded files to have one too).

Emfree, could you tell me what you think of this?

Also, could you tell me why we are making an api-uploaded file a block? Wouldn't it make more sense to have it be a part which could be linked to a Draft?

Fixes T298.

Test Plan: Applied the changes. Checked that a request on /files returned API-uploaded files.

Reviewers: emfree, spang

Reviewed By: spang

Maniphest Tasks: T298

Differential Revision: https://review.inboxapp.com/D334
Fix spacing.
Fix pushd usage in setup.sh
[misc] Merge error.
Fix console.
Fix another bug in console.
Revert "Show API-uploaded files along attachments"

This reverts commit 8f55c46e4b5f73864df7247e4b2bdb33fc9007f4, which
fails regression.
Don't validate S3 buckets.

This is an extra call every time that's pretty much wasted.
s/message/message_id in File API repr
Fix 'error: sodium.h: No such file or directory' while installing pynacl

This removes -e (`pip install --editable`) from the pynacl line in
requirements.txt, and uses git+https:// because pip will break if the
URI isn't in the format `vcs+protocol://...`

This may be related to the following pynacl issue:

    https://github.com/pyca/pynacl/issues/79

Test Plan:
- Destroy my vagrant VM, then run "vagrant up" to re-provision it.

Differential Revision: https://review.inboxapp.com/D394
requirements.txt: Consistently use HTTPS to fetch code from GitHub

Differential Revision: https://review.inboxapp.com/D394
Don't ship with editable (-e) repos in requirements.txt

pip clones such repos into src/, and it prompts you if you try to change the
location of the remote:

    Obtaining zerorpc from git+https://github.com/inboxapp/zerorpc-python.git@master#egg=zerorpc (from -r requirements.txt (line 21))
      git clone in ./src/zerorpc exists with URL git://github.com/inboxapp/zerorpc-python.git
      The plan is to install the git repository https://github.com/inboxapp/zerorpc-python.git
    What to do?  (s)witch, (i)gnore, (w)ipe, (b)ackup Your response ('exit') was not one of the expected responses: s, i, w, b
    What to do?  (s)witch, (i)gnore, (w)ipe, (b)ackup Exception:
    Traceback (most recent call last):
      File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 126, in main
        self.run(options, args)
      File "/usr/lib/python2.7/dist-packages/pip/commands/install.py", line 223, in run
        requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
      File "/usr/lib/python2.7/dist-packages/pip/req.py", line 930, in prepare_files
        req_to_install.update_editable(not self.is_download)
      File "/usr/lib/python2.7/dist-packages/pip/req.py", line 378, in update_editable
        vcs_backend.obtain(self.source_dir)
      File "/usr/lib/python2.7/dist-packages/pip/vcs/git.py", line 105, in obtain
        if self.check_destination(dest, url, rev_options, rev_display):
      File "/usr/lib/python2.7/dist-packages/pip/vcs/__init__.py", line 204, in check_destination
        response = ask('What to do?  %s' % prompt[0], prompt[1])
      File "/usr/lib/python2.7/dist-packages/pip/util.py", line 103, in ask
        response = raw_input(message)
    EOFError: EOF when reading a line

Having real repos in src/ also annoyingly breaks "git clean".