Move the main diffviewer views to extensible class-based views.

Django's pushing for class-based generic views for things, and in the
case of the diff viewer, it provides a lot of advantages.

So far, diffviewer has had a nice separation, where the code in
diffviewer was able to focus solely on diff-related work, and the code
in reviews was able to focus on objects related to review requests. This
was getting hard to maintain with the new review UI support in the diff
viewer, though, and it was clear a more extensible solution was needed.

Now, the code for rendering the diff viewer and diff fragments are
class-based. This simplifies part of the code, and gives us a foundation
for some better extensibility by subclasses. The code in reviews will
soon be able to do a lot more with the resulting renders without having
to inject a bunch of new code into diffviewer.

No logic was changed, but much of the code moved around.

Going forward, some mixins for things like fetching review request data
and checking login support will be created to reduce what these classes
have to do. I'm leaving them out of this change, though.
Remove the base_url parameter for diff rendering.

We used to need this silly base_url parameter for rendering diffs. We
used it for bits of the JavaScript. It's unused now, but we're still
passing it around, so stop doing that.
Add rendering of binary file attachments in the diff viewer.

This introduces the ability to associate a FileAttachment with a files
in a repository. The diff viewer can make use of this to render
thumbnails for binary files.

There's no way yet of associating a file outside of modifying the
database. Later, there will be API and UI for this.

This work is based on Tina Yang's work, with some fixes and a change in
the association model. Previously, FileAttachments were associated with
FileDiffs solely. Now, they're associated with FileDiffs only for newly
introduced files (which don't have a revision yet), and otherwise
associated with a tuple of (repository, file path, revision). This helps
reduce duplicates, meaning that if we fetch a binary file for a path +
revision, we'll have that file for future diffs.

The actions in the diff viewer for Download and Review are temporary. I
have some other thoughts for the interface, but they won't be done in
this change.
Fix parsing git diffs with binary changes.

Git diffs containing binary changes could appear as empty files if
they're the last file in the diff. This was due to how the
_is_empty_change code worked. It assumed there was at least 3 more lines
in the file to work with, and if not, it would assume the change was
empty. Binary changes appearing at the end of the file would fail this
test.

That function is now gone. Instead, we do an initial check that we're
not at the end of the file, before parsing content, and then we keep an
empty_change state around. It defaults to True, but if we find any diff
content or a binary file, we set it to False. We use this state to
determine, at the end of the function, what to return.