add contents webservice

This mainly renames the 'notebooks' service to 'contents' and teaches it about regular files. There is no longer special treatment of directories, just different forms for `content`. Tree view now shows all files.

As usual, modeled on GitHub [contents API](https://developer.github.com/v3/repos/contents/).

I will enumerate the changes to the models and API, but the gist:

- all contents models have name, path, dates, type
- type is one of: directory, file, notebook
- if content is requested:
  - additional `format` key will be `json`, `text`, or `base64`, describing `content`
  - `content` will be
    - list of JSON models for directory contents
    - notebook JSON for notebooks (format=json)
    - file text for text files (format=text)
    - b64-encoded data for binary files (format=base64)
Since in our API we divide the path and file into separate components, we can't have a situation where it's ambiguous whether we're referring to a file or a directory, unlike standard OS paths, where there's no way of telling without interrogating the filesystem what kind of thing `~/foo` is. So I question the need for a generic `exists()` that can handle both.