Commit Graph

56 Commits

Author SHA1 Message Date
bastimeyer 45e515eb5a session/plugin: fix DeprecationWarning stacklevel 2023-03-24 09:41:23 -07:00
bastimeyer 5e6f03c3cd chore: add "B" rules to ruff config 2023-03-24 09:41:23 -07:00
bastimeyer 57fa6f80e8 chore: add "COM" rules to ruff config 2023-02-09 10:26:50 -08:00
bastimeyer faab9200c7 chore: add "I" and "TID" rules to ruff config 2023-02-09 10:26:50 -08:00
bastimeyer 0c8375beb4 plugin: add support for named plugin matchers 2023-01-19 18:41:38 -08:00
bastimeyer d5b2981fbe logger: turn deprecation log msgs into warnings
- Replace all deprecation warning log messages with `FutureWarning`s
- Fix deprecated session options in tests
- Update and fix tests
2023-01-12 15:54:18 -08:00
bastimeyer 4b6077d1da plugin: fix get_argument() 2022-09-27 11:49:07 -07:00
bastimeyer 3708c736b9 plugin: remove broken decorator 2022-09-27 11:45:16 -07:00
bastimeyer 283e177ba6 plugin: fix type of url property 2022-09-10 14:13:41 -07:00
bastimeyer 95df07c165 plugin: add session typing information
- 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)
2022-09-09 18:13:39 -07:00
bastimeyer f020259832 logger: log deprecation messages as warnings 2022-08-29 22:56:58 -07:00
bastimeyer 9e4429d981 plugin: wrappers for incompatible custom plugins
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.
2022-08-28 12:24:56 -07:00
bastimeyer 6ec535f88f plugin: remove Plugin.bind()
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()`
2022-08-28 12:24:56 -07:00
bastimeyer 5a540001fc docs: add plugin{matcher,argument} docstrings
- 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()`
2022-08-27 11:31:28 +02:00
bastimeyer c1a14d6338 tests: rewrite plugin cookies tests 2022-08-20 13:18:45 -07:00
bastimeyer 2c0925335e plugin: add explicit pluginargument tests 2022-08-19 12:06:14 -07:00
bastimeyer 70b8ba8c2b plugin: add pluginargument decorator
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.
2022-08-18 20:27:30 -07:00
bastimeyer e529337acc plugin: set Plugin.arguments class attr to None
Don't let plugins with no arguments share a common Arguments instance
2022-08-18 20:27:30 -07:00
bastimeyer 6ca780e91f plugin: remove user_input_requester from bind()
- 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
2022-08-18 11:28:09 -07:00
bastimeyer dc548ab4b7 session: fix typing issues 2022-05-22 19:30:15 +02:00
bastimeyer 6325c74e68 chore: remove unnecessary collection.OrderedDict
- 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
2022-04-17 11:06:29 -07:00
bastimeyer b72f23fd69 docs: update API page, add type annotations 2022-04-05 19:19:22 +02:00
bastimeyer 01df2f00c8 plugin: add 'id' metadata property 2021-11-24 18:41:21 +01:00
bastimeyer a7063e1d70 stream: remove RTMP and RTMPDump dependency
- 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
2021-11-13 13:24:25 +01:00
bastimeyer 46817a1cff streams: remove HDS/AkamaiHD and flashmedia pkg
- 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
2021-11-12 20:09:53 +01:00
bastimeyer 6e07f55257 plugin: trim metadata strings 2021-10-24 15:34:05 -07:00
bastimeyer 67cf4e6caa cli: include plugin metadata in --json output
- 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.
2021-09-03 21:53:35 +02:00
bastimeyer 3231977011 plugin: metadata attributes
- 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
2021-08-31 19:21:08 -07:00
bastimeyer 9e853e69bc plugin: fix cookie related error messages 2021-08-17 20:16:27 -07:00
bastimeyer 8314871e31 plugins: update protocol plugins
- update protocol plugins: akamaihd, dash, hds, hls, http and rtmp
- remove `plugin.parse_url_params`, update `plugin.parse_params`
- refactor DASH tests
2021-06-29 16:45:36 +02:00
bastimeyer 8d5712a306 plugin: new matchers API
- 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
2021-06-29 16:45:36 +02:00
back-to 0871778d5b plugins.plugin: use the same cls.logger 'plugins'
since https://github.com/streamlink/streamlink/pull/3366
5e7a04b006/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
```
2020-12-14 12:28:50 -08:00
bastimeyer 5a6398afb1 chore: replace old errors classes with OSError
See PEP 3151
https://docs.python.org/3/library/exceptions.html#OSError
2020-11-27 16:04:45 +01:00
bastimeyer bf5d3efa6c chore: inherit from object implicitly 2020-11-27 16:04:45 +01:00
beardypig a585e88297 chore: sort imports, fix a dependency cycle and use absolute imports
Co-authored-by: bastimeyer <mail@bastimeyer.de>
2020-10-27 17:17:49 +01:00
bastimeyer cf8cf070eb logger: format all log messages directly
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.
2020-10-19 21:45:15 +02:00
resloved 5059d64be2 fixed typo 2020-06-07 11:31:57 -07:00
bastimeyer ca0ddd8e7f flake8: W504
W504 line break after binary operator
2020-02-23 09:53:55 +01:00
bastimeyer 0e8e4f5911 flake8: E302, E305
E302 expected 2 blank lines, found 1
E305 expected 2 blank lines after class or function definition, found 1
2020-02-19 18:42:11 +01:00
bastimeyer 5c03dbf639 feature: {best,worst}-unfiltered stream synonyms
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
2018-10-24 17:37:02 +02:00
back-to cd6f94a5a4
Removed old Livestreamer deprecations and API references
- 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.
2018-08-04 16:31:09 +02:00
Hubcapp 5c3cf571ee Window Titles = Stream Titles + Other Attributes (#1576)
* 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
2018-07-11 11:52:17 -07:00
beardypig f6068e8cff
plugin: support stream weights returned by DASHStream.parse_manifest 2018-06-28 16:31:39 +02:00
beardypig 9d63e64bbc API for plugins to request input from the user (#1827)
* 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
2018-06-21 16:15:21 -07:00
beardypig 4924b8a15a plugins: store cookies between sessions (#1724)
* 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
2018-06-03 11:17:11 -07:00
beardypig 60efe3bfd4 logging: refactor to use python logging module (#1690)
* 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
2018-05-29 18:15:11 -07:00
beardypig d7a27b31b0 Plugin Arguments API (#1638)
* 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
2018-05-25 14:25:15 -07:00
hicrop 55db9e0f1e PEP8 (#1427)
* 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.
2018-01-15 18:49:52 -08:00
beardypig b0c093155e plugins: add priority ordering to plugins
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.
2017-08-16 10:41:04 +01:00
beardypig 88b4f44926 plugins: separated the built-in plugins in to separate plugins
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.
2017-08-03 10:38:40 +01:00