So far using the "... from URL" or "... from an uploaded archive"
mechanism for installing a plugin would fail without further
information if the plugin to be installed was already installed.
The plugin manager will now detect this situation by parsing the
corresponding message from the pip output and trigger a reinstall
instantly.
A message about this will be logged to octoprint.log and the install
output.
Additionally the error handling for installation errors has been
slightly improved (install output no longer says "Done!" but "Error!"
with the reason as provided by the server) and the "could not install
plugin from URL unknown" issue should also be solved.
Evaluates json data file as e.g. published on
plugins.octoprint.org/notices.json and displays notices for plugins
installed and matching (optional) version lists.
* Extended plugin metadata by new property, only evaluated for bundled
plugins.
* Adjusted plugin manager to evaluate new metadata and add
confirmation dialog with details when attempting to disable such
a plugin.
Can be enabled either through new --safe command line
parameter or through server.startOnceInSafeMode in
config.yaml
When running in safe mode the plugin manager will
only allow to disable or uninstall third party plugins. Enabling
third party plugins or installing new plugins is disabled.
That will hopefully allow for more straightforward recovery
in case of a misbehaving plugin.
Most caching is left to the client, by utilizing ETag and Last-Modified headers.
Where it was easily achievable, an additional server side miniature cache of intermediary
results was introduced (e.g. for the files). The regular cached decorator was not used
since it targets caching full responses, and the responses in question already contained
client request specific data. Caching "one step earlier" allows better usage of the cache here.
Also introduced a dependency on the scandir module, to get a bit of a performance boost
on os.walk and os.listdir (which have been replaced with scandir.walk and scandir.listdir
respectively). See https://github.com/benhoyt/scandir#background on why that made
sense.
We don't need user-definable pip command paths here,
that will only lead to tears when the pip command belongs
to a wrong Python environment and nothing installs as
expected.
Also make sure that if we have a pkg_resources version that returns
tuples we not only remove any intermediary version parts if the base
version is requested, but we also append "*final" to the tuple afterwards,
otherwise the compatibility check will fail.
The class knows about which pip versions support --process-dependency-links, which
need --no-use-wheel and which are broken altogether and adds/removes these parameters
accordingly or outright reports the broken pip version.
Depending on the pip version pip might first fetch the full index of packages available
on PyPI instead of just directly processing the provided link.
Display corresponding message to user from backend to make sure they don't
think something broke.
Lines taking from the asynchronous processing of stdout/stderr where
left as str, leading to encoding problems when utf8 characters showed
up in the stream and were being interpreted as ascii encoding.
(cherry picked from commit 9373be3)
Old versions of setuptools return a tuple for their
pkg_resources.parse_version method instead of a Version object with
a base_version attribute that we can use to retrieve the base version.
So some manually parsing is needed instead.