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.
In case the user site packages are not yet part of the used
working set OR the sys path and ENABLE_USER_SITE is true, the
manager will now make sure that the folder is searched for plugins
as well upon plugin reload.
This is necessary since Python will not automatically include the
user site directory upon firing up the program in case there's
nothing installed to it/it doesn't exist. If a plugin is installed
during run time with --user that will lead to it not being found,
which is undesirable. Hence run time manipulation of sys.path and
the workingset becomes necessary.
Managable currently pretty much only means "uninstallable".
Plugins are managable if their installation location is writable
and - if they are installed from an entry point and OctoPrint is
running in a virtual environment - within the bounds of the virtual
environment (because otherwise pip will not allow to uninstall).
Custom exception should be derived from Exception, not BaseException.
Not only is this specified in the python documentation, but also
tornado will be able to handle Exceptions in requests perfectly fine
and return an HTTP 500 for them, but crash hard (as in, server shut
down follows) for BaseExceptions.
(cherry picked from commit 29b047b)
Custom exception should be derived from Exception, not BaseException.
Not only is this specified in the python documentation, but also
tornado will be able to handle Exceptions in requests perfectly fine
and return an HTTP 500 for them, but crash hard (as in, server shut
down follows) for BaseExceptions.
Sometimes they will still get discovered by python even though their packages have since been uninstalled.
This will also lead to them being reloaded after an uninstall and a subsequent plugin reload.
Marking them as uninstalled and not handing out uninstalled plugins when collecting them solves this.
Since it cannot be reliably determined by the system if a hook is essential for a plugin's functionality or not, it makes more sense to just disable plugins that utilize obsolete hooks then risk running half working plugins.
The new hook allows extending the list of rules for maximum body sizes differing from the default of 100KB and can be used by plugins to allow uploads to them that exceed that file size.
Also extended the plugin manager to detect plugins that implement restart needing hooks (such as the above one) and handling those plugins the same as plugins containing implementations that inherit from octoprint.plugin.core.RestartNeedingPlugin
Plugins may be enabled and disabled during runtime. If they are of types which allow hot loading, this will be done. Otherwise they will be marked as pending and updated after a restart. Same for installation and uninstallation.
Plugins may be loaded, unloaded, activated and deactivated. Errors while trying to load a plugin or initializing an implementation will only result in it staying deactive but registered in the system, allowing it to be further processed e.g. by a plugin manager
Multiple mixins are allowed of course. Allowing multiple implementations lead to too many problems due to plugin names for referring to the APIs of SimpleApiPlugins or the assets of AssetPlugins.
Hence __plugin_implementations__ has been deprecated in favor of __plugin_implementation__. The plugin subsystem will automatically copy the first implementation from __plugin_implementations__ to __plugin_implementation__ and log a deprecation warning.
Adjusted documentation accordingly. Also added docs for helpers.
Detected plugins are now logged in a better readable way and with additional information.
Also marked folder for bundled plugins as bundled - forgot to do that earlier.