extra/runner/run: Make `exit-status` available to user `post_run` script
extra/runner/run: Save `stbt` version to `stbt-version.log`
extra/runner/server: Serve ".log" files as "text/plain"

When `server` is used to serve all files (i.e. `server` isn't proxied
behind a web server like apache) the browser would download these files
to disk instead of displaying them in the browser.
extra/runner/server: Sort directory listings alphabetically
extra/runner: "Notes" field that can be edited interactively

This is for arbitrary user notes, entered via the web interface.

This information is stored in the file "notes.manual". Unlike
"failure-reason" (created by the automatic classifier script) and
"failure-reason.manual" (containing the text manually entered by the
user), there is no "notes" file, only "notes.manual". There might be
other "*.manual" files in the future, hence the changes to
`Run.__init__` and `Run.read`.
extra/runner/report.py: Cleanup: Move `strip()` into `Run.read`

So that each caller of `Run.read` doesn't have to do it.
extra/runner: Handle unicode input from web form

The javascript in static/edit-testrun.js sends the POST request with
utf-8 encoding (at least according to my tests on Firefox). The
`*.manual` files are only created from such user input via this `server`
script, so they will also always be utf-8.
extra/runner/report: Exit early on invalid arguments

Otherwise this would try to run `report.py $(dirname $arg)/index.html`
to generate the summary report, which would fail with a confusing python
backtrace if the argument was a directory that didn't contain any
testruns.
extra/runner/run: Export `PYTHONUNBUFFERED=x` to user hooks' environment

Setting `PYTHONUNBUFFERED` to any value prevents python from buffering
standard output, which causes wrong timestamps in the log files when a
python script's output is piped through `ts`.

This change means that if any scripts called from `run` (like the
user-specified pre-run, post-run, and classify scripts) use the same
`ts` technique, they won't have to set `PYTHONUNBUFFERED` themselves.
I'll use this in the next commit.
extra/runner/run: If NoVideo, check Blackmagic video-capture hardware freeze

Sometimes the Blackmagic video-capture card fails and never delivers
video again until the PC is rebooted. If this happens we don't continue
running any tests (because they would all fail; restarting the PC
requires human intervention).

We can detect this by running a capture with `GST_DEBUG` enabled. If the
card is functional, then the message "VideoInputFrameArrived" is printed
to stderr *even if the Blackmagic card has no video on its input* (for
example if the set-top box is off). But if the card has failed then the
message is never printed.

For each of the following scenarios the GStreamer debug output looks
like:

* Working Blackmagic card, video source (the system under test) is on:

    activating push
    activatepush
    VideoInputFrameArrived: Frame received [<timecode>] - Valid Frame - Size: <n>

* Working Blackmagic card, video source is off:

    activating push
    activatepush
    VideoInputFrameArrived: Frame received - No input signal detected

  (Sometimes even when the video source is off, you can get
  "VideoInputFrameArrived: Frame received [<timecode>] - Valid Frame".
  Maybe this is only when the Blackmagic card has been configured to
  deliver the last seen frame when there is no video; I'm not sure.)

* Blackmagic card in use by another process (e.g. `stbt tv`):

    enable video input failed

  (and the GStreamer pipeline exits)

* Blackmagic card crashed (requiring a reboot of the PC):

    activating push
    activatepush

  (and the GStreamer pipeline just hangs after that output; eventually a
  stbt function like `wait_for_match` will timeout and raise `NoVideo`).

Note also that this writes to `failure-reason.manual`, because
`failure-reason` can be overwritten if you (manually) re-run `report`.
This Blackmagic failure can only be detected "online" (at the time the
test failed, on the same system that ran the test).
`failure-reason.manual` was introduced in commit 56aa1db9 to store
failure reasons entered manually by the user via the web interface, but
it is useful in this case too. Hopefully the "manual" name isn't too
confusing.

Thanks to Aiman Baharna <aiman.baharna@youview.com> for figuring out
how to detect Blackmagic failures.
extra/runner/run: Do Blackmagic failure detection before user recovery script

The user `recover` script might choose to power-cycle the
system-under-test, which isn't necessary if the failure was the fault
of the Blackmagic video-capture card.

`check_capture_hardware` now writes to `failure-reason` as well as
`failure-reason.manual` (even though `failure-reason` will be
overwritten the next time the user manually runs `report`) so that the
user `recover` script sees a failure reason of "Blackmagic card in use"
instead of "NoVideo".
extra/runner/server: Allow user to remove test results from report

This doesn't delete results altogether, it just hides them by renaming
the testrun folder with a leading ".".

We add the "Hide this result" link with javascript instead of adding it
to `templates/testrun.html`, so that the link only appears if a server
capable of handling it is running (i.e. the `server` script, which also
serves `edit-testrun.js`).

You'll still need to manually press "refresh" in the browser to see the
summary report without the deleted testrun. This is because the test-run
details html is in a separate iframe, and I don't know how javascript in
the iframe can access the parent document.

Note that we now need to call `report` so that it regenerates *only* the
summary html; call `report path/to/index.html`. I've also updated
`report.py` to provide a nicer error message if `report` is called in
this way with a path that doesn't contain testruns.

I'm testing this in the existing unit test rather than creating a
separate test, because the test setup is relatively complicated and it
takes a few secondns to run.
extra/runner/server: Cleanup: `update_file` uses `d` instead of `testrun`

For consistency with the rest of this function, and to encapsulate into
the function `testrun_directory` the knowledge that the `testrun` path
in the url is relative to `app.instance_path`.
extra/runner/report: Debug for "skipping in-progress test" includes directory name

Also use `echo "$rundir: ...` explicitly instead of the function `debug`
because to call `debug` you had to know whether the `rundir` variable
was set to the right value. There is already a lot of global state and
tight coupling in these scripts, but every little improvement helps. :-)
extra/runner: Upgrate to x-editable.js 1.4.6

This fixes newline handling in editable textareas. See
https://github.com/vitalets/x-editable/commit/081135a2