- Add typing information to `Plugin.session`
- Implement `http_session` stub file due to the `HTTPSession` subclass
of `requests.Session` which adds additional keywords to the
`request()` method, including all other HTTP-verb methods
- Add `flake8-pyi` and `typing_extensions` to dev-requirements.txt
(`typing_extensions` is not a runtime dependency)
This restores support for custom plugins with constructors which only
take the formal `url` argument instead of variable arguments via
`*args, **kwargs` that get then passed to the super-class's constructor,
so a breaking API change can temporarily be avoided.
This is done by wrapping the custom plugin class's MRO with two
compatibility classes via `__new__()`.
Also add a deprecation message (info log channel) and add tests.
This changes the way how the Streamlink session and other objects like
the plugin cache and logger are stored on each plugin.
Previously, those objects were set as class attributes on every `Plugin`
class via `Plugin.bind()` when loading plugins via the session's
`load_plugins()` method that gets called on initialization.
This meant that whenever a new Streamlink session was initialized,
references to it (including a dict of every loaded plugin) were set
on each `Plugin` class as a class attribute, and Python's garbage
collector could not get rid of this memory when deleting the session
instance that was created last.
Removing `Plugin.bind()`, passing the session via the `Plugin.__init__`
constructor, and setting the cache, logger, etc. on `Plugin` instances
instead (only one gets initialized by `streamlink_cli`), removes those
static references that prevent the garbage collector to work.
Since the plugin "module" name now doesn't get set via `Plugin.bind()`
anymore, it derives its name via `self.__class__.__module__` on its own,
which means a change of the return type of `Streamlink.resolve_url()`
is necessary in order to pass the plugin name to `streamlink_cli`,
so that it can load config files and initialize plugin arguments, etc.
Breaking changes:
- Remove `Plugin.bind()`
- Pass the `session` instance via the Plugin constructor and set the
`module`, `cache` and `logger` on the plugin instance instead.
Derive `module` from the actual module name.
- Change the return type of `Session.resolve_url()` and include the
resolved plugin name in the returned tuple
Other changes:
- Remove `pluginclass.bind()` call from `Session.load_plugins()` and
use the loader's module name directly on the `Session.plugins` dict
- Remove initialization check from `Plugin` cookie methods
- Update streamlink_cli.main module according to breaking changes
- Update tests respectively
- Add explicit plugin initialization test
- Update tests with plugin constructors and custom plugin names
- Move testplugin override module, so that it shares the same module
name as the main testplugin module. Rel `Session.load_plugins()`
- Refactor most session tests and replace unneeded `resolve_url()`
wrappers in favor of calling `session.streams()`
- Add docstrings for the `pluginmatcher` and `pluginargument` decorators
- Update typing information of `Plugin.arguments` and add docstring
- Update docstrings of `Argument` and `Arguments`
- Fix minor issue in `Arguments.requires()`
Use the same signature as the Argument class and initialize the plugin's
`arguments` class attribute if it's `None`.
Defining plugin arguments the old way is still supported and unchanged.
- Remove `user_input_requester` from `Plugin.bind()`, don't set it in
`Session.load_plugins()` and remove `Plugin._user_input_requester`
- Make `Plugin.input_ask{,_password}` read input requester from session
- Move `UserInputRequester` to the new `streamlink.user_input` module,
turn it into an abstract base class, and update imports
- Fix docstring of `Session.set_option()`
- Rewrite tests
- Replace collection.OrderedDict with builtins.dict where possible:
Python 3.7+ ensures the correct order in builtins.dict objects and is
no longer an implementation detail of cpython.
- Fix OrderedDict type annotation in streamlink.utils.cache.LRUCache
- Add unit test for streamlink.utils.cache.LRUCache
- drop RTMP stream implementation
- drop RTMP plugin
- drop RTMPDump dependency
- remove stream.streamprocess and utils.{rtmp,swf}
- remove "rtmp" from default stream types list
- remove "rtmp" from player-passthrough options list
- remove all `--rtmp*` CLI args and `rtmp-*` session options
- remove all `--subprocess-*` CLI args and `subprocess` session options,
as these were used only by StreamProcess which is no longer needed
- update tests
- update docs and CLI argument help texts
- drop HDS and AkamaiHD stream implementations
- drop HDS and AkamaiHD plugins
- drop streamlink.packages.flashmedia
- remove stream.flvconcat, stream.playlist and plugins.common_swf
- remove "hds" from default stream types list
- remove all `--hds-*` CLI arguments and `hds-*` session options
- remove unneeded flashmedia license text files
- update tests
- update docs and CLI argument help texts
- Add `Plugin.get_metadata()` which returns a dict of all metadata.
- Add `metadata` property to list of all resolved streams, but merge
all metadata properties with the specific stream output in order to
not introduce a breaking change in the JSON output format.
- add author, category and title attributes to base Plugin class
- make getters return attributes instead of None
- remove unnecessary duplicate attributes and getters from plugins
- keep getters in plugins which use custom logic
- drop `Plugin.can_handle_url` and `Plugin.priority`
- introduce `Plugin.matchers`
- implement `pluginmatcher` decorator
- automatically match url (on change) and store result
- update `Session.resolve_url`
- add and fix related tests
since https://github.com/streamlink/streamlink/pull/33665e7a04b006/src/streamlink/session.py (L412)
the logger is `[plugins.afreeca]` which was `[plugin.afreeca]` before
update the cls.logger so it will be `[plugins.afreeca]` also
after this PR
```
[plugins.afreeca][debug] Restored cookies: ...
...
[plugins.afreeca][debug] Attempting to authenticate using cached cookies
```
This replaces calls like this
`log.info("foo {0}", bar)`
with
`log.info(f"foo {bar}")`
so that no custom LogRecord args are set.
This enables the removal of Streamlink's custom LogRecord class, which
currently overrides the default behavior of percent-formatted log
messages with curly-brace-formatted log messages. By using pre-formatted
log messages via f-strings or string.format, the custom LogRecord class
and distinction between external loggers become unnecessary.
Add special stream synonyms "best-unfiltered" and "worst-unfiltered" in
cases when all available streams have been filtered out by the
`--stream-sorting-excludes` parameter and the "best" and "worst" stream
synonyms don't exist. These new synonyms point towards the respective
streams of the unfiltered streams list so that the user is able to
select a fallback stream.
Example:
streamlink --stream-sorting-excludes '>=480p' URL best,best-unfiltered
Will try to open the best stream below 480p, but if none is available
will continue with the best of all streams as a fallback selection.
Resolves#1055
- removed versionchange references as Streamlink does not use it.
- removed old code that was deprecated in Livestreamer
- removed DeprecatedWarning for 2.6 as it is already mentioned in
`setup.py`
a14f170a04/setup.py (L82)
- removed unittest2
- Flake8 for some lines/files that I changed.
* Largely untested, introduces custom title attributes pulled from site APIs
Included is support for {title}, {category}/{game}, and {author}
for Twitch and Youtube
Only tested (briefly) for Python 3 + Linux.
Committing to test on other platforms (Windows)
* bug-fix 1
* bug-fix 2
changing to list2cmdline turns out to not be necessary, since subprocess.call has already disabled the ability to break out by using `shell=False`
also broke launching on windows.
* bug-fix 3
move this to the pi3 area
* allow user to escape $ with \$
in case the user wants to use format codes.
comes at the expense of allowing streamers to insert format codes
that only appear for streamlink users, but is not a security risk
* API for plugins to request input from the user
* console: handle lack of TTY for user input
* New fatal plugin error, for unrecoverable errors
* tests: remove deprecated calls
* plugins: store cookies between sessions
Adds some new methods to Plugin to simplify the process of storing and
loading cookies between sessions.
* plugins: store the rest/_rest attribute from Cookie
* plugins: add filter for clear cookies
* plugins: doc tidy-up
* plugins: test coverage
* logging: refactor to use python logging module
The logging output remains identical to before. The API has changed,
instead of passing a Logger instance around, a module level `log`
instance is used. This is the standard way to do logging in most Python
applications and module.
There are a number of advantages to doing this:
1. more Pythonic
2. easier to add logging message from utils and other methods without
passing session or loggers around
3. if required, log messages from other Python modules can be enabled
4. the log destination could be changed to (or duplicated to)
other places, syslog for example
5. when other applications include streamlink they can get the
streamlink logging message
* tests: refactor deprecated warnings for Session.logger
* logging: added Logger compatibility class
* fix issue in argparse docs
* fix rebase issue
* de-flaked
* plugins: PluginArguments API
Allow plugins to specify arguments within the Plugin class.
This makes it easier to add and test plugin specific arguments, as well
as enabling sideloaded plugins to support command line arguments.
* update docs build to work with the new plugin arguments
* fix argument name override for funimation and ustream
* add some more tests for options/arguments
* rebase with abweb plugin
* switch to RuntimeException for py2 compat
* fix bug where required arguments were not prompted
* bug fixes for option names in plugins, should match existing names
* restore "normal" exception messages
* missed a RecursionError -> RuntimeError
* updated the api slightly with better (I think) argument name
added some docs for the Argument and Arguments classes
* options/args: normalise option names to replace - with _, and ensure the defaults are set
* normalise the plugin module name, replacing _ with -
* style issues pointed out by @back-to
* plugin.btsports: update to use PluginArguments
* plugins.bbciplayer: add hd argument
* plugins.twitch: move --twitch-oauth-authenticate back to argparser
Moved the option back to argparser as it's a special case.
* test: fixed typo
* E265 - Fix spacing after comment hash for block comments.
* W293 - Remove trailing whitespace on blank line.
* E305 - Add missing 2 blank lines after end of function or class.
* E123 - Align closing bracket to match opening bracket.
* E202 - Remove extraneous whitespace before bracket.
* Remaining fixes.
Plugins can return a priority level for the URLs that they support.
If two plugins match the same URLs then the plugin with the higher
priority will be used. This means that the built-in HLS and HDS
plugins can support `.m3u8` and `.f4m` URLs with a lower priority
without causing issues with overlapping URL patterns.
By default plugins return NORMAL priority for any URL. It is expected
that the `priority` method will only be called with URLs that are
actually supported by the plugin.
The new HLSPlugin auto-detects hlsvariant vs. hls, using either URL
prefix will work for variant and non-variant playlists.
There are some additional tweaks to support functions to support
these changes.