Run test modules whose name matches the given regexp.
This is quick-and-dirty, there's probably a better way,
but the TestSuite system is really complicated and this is
super-easy.
Out of @yan12125's concern that the presumption that JWPlayer data as
an array representing multiple formats rather than a playlist might be
specific to IQM2, move this code from jwplatform.py to iqm2.py.
JWPlatformBase now reverts to throwing a TypeError if it gets an
array.
Now IQM2 redefines the _extract_jwplayer_data() method as well, but it
continues to leverage JWPlatformBase for _parse_jwplayer_data(), which
is the bulk of the work.
Video IDs should be based on the unique ID of the video, not the
meeting ID of the parent page that links to the media
page. Unfortunately we don't learn the media ID until after
downloading the first page.
Per @yan12125's suggestion:
* Redefine _find_jwplayer_data() to use the SetupJWPlayer RE that's IQM2-specific
* Retreive the 2ndary webpage on our own
* Search for the title just like generic does
* If our parsed JSON ends up as a list, rather than a dict, then store
it in ['sources'] as that list, rather than trying to wrap it in an
array, which leads to type errors. (Such a list indicates multiple
file formats/sources, rather than a playlist.)
* Allow format labels like 'SD 480' and 'HD 720' in addition to '1080p'
In the absence of the total_bytes key, just say "Completed" (looks
better than a bare "100%").
Compose the msg_template additively.
In practice, for pipes (where we lack total bytes) we also lack
elapsed time, so we end up with:
[download] Completed
though if elapsed time were somehow set we'd have:
[download] Completed in 00:10
Per @yan12125, traceback.print_exc() can send output to the wrong
place under some circumstances (e.g. use of logger), so send it to
stderr. Which requires a compat_str.
An OSError or IOError generally indicates something a little more
wrong than a "simple" UnavailableVideoError, so print the actual
traceback that leads to the exception. Otherwise meaningful postmortem
debugging a bug report is essentially infeasible.
Oops, when I created this extractor I copied the sample code from the
2014 manpage on my system, thus missing 4bc77c8417ca0340d09dcebb311d06aa7d5ba0ac's
introduction of the _match_id() helper function.
I change the URL of the third test case, because now the original URL
does not contain a video anymore, and there's no easy to get the real
URL from the /film/ one.
Shell assignment operator in BSD make != is ported to GNU make in
version 4.0, so 3.x doesn't work. I choose to drop BSD make support as
installing GNU make on *BSD systems is easier than installing newer GNU
make.
In the real_download() method of the ExternalFD class:
Special-case output to stdout, when filename=='-', because otherwise
the call to os.path.getsize() raises
OSError: [Errno 2] No such file or directory: '-'
which in turn gets masked by a try block and re-raised as
UnavailableVideoError().
And even if getsize had succeeded, we would fail on renaming, and then
we would also fail on reporting progress as report_progress() expects
to have file size information.
So report download completion with self.to_screen() just as
report_progress() would in the noprogress==True case.
You might ask whether it's an abstraction violation for external.py to
have to know and think about '-' as a filename, but unfortunately
we're there already. _call_downloader() thinks about it, and also
real_download() calls common.py's temp_name() which special-cases the
'-' filename to preserve it instead of returnign a temp file. So we
already worry about this case at this abstraction level, as well as
both below and above. Perhaps that should change, but that's for
another day.
An OSError or IOError generally indicates something a little more
wrong than a "simple" UnavailableVideoError, so print the actual
traceback that leads to the exception. Otherwise meaningful postmortem
debugging a bug report is essentially infeasible.