2015-06-18 09:37:08 +00:00
{% macro pluginmanager_printing() %}
<div class="alert" data-bind="visible: !enableManagement()">
{{ _('Take note that all plugin management functionality is disabled while your printer is printing.') }}
</div>
{% endmacro %}
2015-09-22 09:36:57 +00:00
{% macro pluginmanager_nopip() %}
<div class="alert" data-bind="visible: !pipAvailable()">{% trans %}
2015-09-30 13:59:08 +00:00
The <code>pip</code> command could not be found or does not work correctly
for this installation of OctoPrint - please consult the log file for details
and if necessary configure it manually. No installation and uninstallation of plugin
2015-09-22 09:36:57 +00:00
packages is possible while <code>pip</code> is unavailable.
{% endtrans %}</div>
{% endmacro %}
2016-11-18 12:01:14 +00:00
{% macro pluginmanager_safemode() %}
<div class="alert" data-bind="visible: safeMode">{% trans %}
Safe mode is currently active. All third party plugins are disabled and cannot be
enabled. Installation of plugin packages is disabled.
{% endtrans %}</div>
{% endmacro %}
2015-06-18 09:37:08 +00:00
{{ pluginmanager_printing() }}
2015-09-22 09:36:57 +00:00
{{ pluginmanager_nopip() }}
2016-11-18 12:01:14 +00:00
{{ pluginmanager_safemode() }}
2015-09-22 09:36:57 +00:00
<div class="pull-right">
<button class="btn btn-small" data-bind="click: function() { $root.showPluginSettings(); }" title="{{ _('Plugin Configuration') }}"><i class="icon-wrench"></i></button>
</div>
2015-06-18 09:37:08 +00:00
2015-05-29 14:31:43 +00:00
<h3>{{ _('Installed Plugins') }}</h3>
<table class="table table-striped table-hover table-condensed table-hover">
<thead>
<tr>
<th class="settings_plugin_plugin_manager_plugins_name">{{ _('Name') }}</th>
<th class="settings_plugin_plugin_manager_plugins_actions">{{ _('Actions') }}</th>
</tr>
</thead>
<tbody data-bind="foreach: plugins.paginatedItems">
<tr>
<td class="settings_plugin_plugin_manager_plugins_name">
2017-03-31 14:52:48 +00:00
<div data-bind="css: {muted: !enabled}"><span data-bind="text: name"></span> <span data-bind="visible: version">(<span data-bind="text: version"></span>)</span> <i title="{{ _('Bundled with OctoPrint') }}" class="icon-th-large" data-bind="visible: bundled"></i> <i class="icon-lock" title="{{ _('Cannot be uninstalled through OctoPrint') }}" data-bind="visible: !managable"></i> <i title="{{ _('Restart of OctoPrint needed for changes to take effect') }}" class="icon-refresh" data-bind="visible: pending_enable || pending_disable || pending_install || pending_uninstall"></i> <i title="{{ _('Pending install') }}" class="icon-plus" data-bind="visible: pending_install"></i> <i title="{{ _('Pending uninstall') }}" class="icon-minus" data-bind="visible: pending_uninstall"></i> <i title="{{ _('Disabled due to safe mode') }}" class="icon-medkit" data-bind="visible: safe_mode_victim"></i> <i class="icon-exclamation-sign" title="{{ _('There are notices available regarding this plugin') }}" data-bind="visible: notifications && notifications.length"></i></div>
<div data-bind="visible: notifications && notifications.length"><a href="javascript:void(0)" class="text-error" style="text-decoration: underline" data-bind="click: function() { $root.showPluginNotifications($data) }, text: $root.showPluginNotificationsLinkText($data)"></a></div>
2015-05-29 14:31:43 +00:00
<div><small class="muted" data-bind="text: description"> </small></div>
<div data-bind="css: {muted: !enabled}">
2015-07-09 13:43:11 +00:00
<small data-bind="visible: url"><i class="icon-home"></i> <a data-bind="attr: {href: url}" target="_blank" rel="noreferrer noopener">{{ _('Homepage') }}</a></small>
2015-05-29 14:31:43 +00:00
<small data-bind="visible: license"><i class="icon-legal"></i> <span data-bind="text: license"></span></small>
<small data-bind="visible: author"><i class="icon-user"></i> <span data-bind="text: author"></span></small>
<small> </small>
</div>
</td>
<td class="settings_plugin_plugin_manager_plugins_actions">
2015-06-18 09:37:08 +00:00
<a href="#" data-bind="css: $root.toggleButtonCss($data), attr: {title: $root.toggleButtonTitle($data)}, enable: $root.enableToggle($data), click: function() { $root.togglePlugin($data) }"></a> | <a href="#" class="icon-trash" title="{{ _('Uninstall Plugin') }}" data-bind="css: {disabled: !$root.enableUninstall($data)}, enable: $root.enableUninstall($data), click: function() { $root.uninstallPlugin($data) }"></a>
2015-05-29 14:31:43 +00:00
</td>
</tr>
</tbody>
</table>
<div class="pagination pagination-mini pagination-centered">
<ul>
<li data-bind="css: {disabled: plugins.currentPage() === 0}"><a href="#" data-bind="click: plugins.prevPage">«</a></li>
</ul>
<ul data-bind="foreach: plugins.pages">
<li data-bind="css: { active: $data.number === $root.plugins.currentPage(), disabled: $data.number === -1 }"><a href="#" data-bind="text: $data.text, click: function() { $root.plugins.changePage($data.number); }"></a></li>
</ul>
<ul>
<li data-bind="css: {disabled: plugins.currentPage() === plugins.lastPage()}"><a href="#" data-bind="click: plugins.nextPage">»</a></li>
</ul>
</div>
<button class="btn btn-block" data-bind="click: $root.showRepository">{{ _('Get More...') }}</button>
2015-09-29 12:51:58 +00:00
<div class="muted" data-bind="visible: pipAvailable()">
<div>
<small>
2017-03-31 14:52:48 +00:00
<a href="javascript:void(0)" class="muted" onclick="$(this).children('i.toggle-arrow').toggleClass('icon-caret-right icon-caret-down').parent().parent().parent().next().slideToggle('fast')">
2016-02-11 08:38:35 +00:00
<i class="toggle-arrow icon-caret-right"></i> Using pip of "<span data-bind="text: pipPython"></span>", Version <span data-bind="text: pipVersion"></span>
2015-09-29 12:51:58 +00:00
</a>
</small>
</div>
<div class="hide">
<small>
2016-02-11 08:38:35 +00:00
Installation directory: <span data-bind="text: pipInstallDir"></span> ("--user" flag: <span data-bind="text: pipUseUserString"></span>)<br />
2015-09-30 11:36:45 +00:00
Virtual environment: <span data-bind="text: pipVirtualEnvString"></span><br />
2015-09-29 12:51:58 +00:00
<span data-bind="visible: pipAdditionalArgs">Additional Arguments: <span data-bind="text: pipAdditionalArgs"></span></span>
</small>
</div>
</div>
2015-09-22 09:36:57 +00:00
2017-03-31 14:52:48 +00:00
<div class="muted">
<div>
<small>
<a href="javascript:void(0)" class="muted" onclick="$(this).children('i.toggle-arrow').toggleClass('icon-caret-right icon-caret-down').parent().parent().parent().next().slideToggle('fast')">
<i class="toggle-arrow icon-caret-right"></i> <span data-bind="text: noticeCountText"></span>
</a>
</small>
</div>
<div class="hide">
<small>
<!-- ko if: noticeCount() > 0 --><a href="javascript:void(0)" data-bind="click: function() { reshowNotices(); }">{{ _('Reshow current notices') }}</a> ·<!-- /ko -->
<a href="javascript:void(0)" data-bind="click: function() { refreshNotices(); }">{{ _('Refresh notices from repository') }}</a>
</small>
</div>
</div>
2015-05-29 14:31:43 +00:00
<div id="settings_plugin_pluginmanager_workingdialog" class="modal hide fade">
<div class="modal-header">
<h3 data-bind="text: workingTitle"></h3>
</div>
<div class="modal-body">
2017-04-12 16:54:08 +00:00
<pre id="settings_plugin_pluginmanager_workingdialog_output" class="terminal pre-scrollable" style="height: 170px" data-bind="fastForEach: loglines"><span data-bind="text: line, css: {stdout: stream == 'stdout', stderr: stream == 'stderr', call: stream == 'call', message: stream == 'message', error: stream == 'error'}"></span></pre>
2015-05-29 14:31:43 +00:00
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" data-bind="enable: !$root.working()" aria-hidden="true">{{ _('Close') }}</button>
</div>
</div>
<div id="settings_plugin_pluginmanager_repositorydialog" class="modal hide fade">
<div class="modal-header">
<a href="#" class="close" data-dismiss="modal" aria-hidden="true">×</a>
<h3>{{ _('Install new Plugins...') }}</h3>
</div>
<div class="modal-body">
2015-06-18 09:37:08 +00:00
{{ pluginmanager_printing() }}
2015-09-22 09:36:57 +00:00
{{ pluginmanager_nopip() }}
2016-11-18 12:01:14 +00:00
{{ pluginmanager_safemode() }}
2015-05-29 14:31:43 +00:00
<h4 style="position: relative">
{{ _('... from the <a href="%(url)s" target="_blank">Plugin Repository</a>', url='http://plugins.octoprint.org') }}
2015-10-27 14:02:47 +00:00
<div class="dropdown pull-right">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<span class="icon-wrench"></span>
</a>
2015-05-29 14:31:43 +00:00
<ul class="dropdown-menu pull-right">
<li><a href="#" data-bind="click: function() { repositoryplugins.changeSorting('title'); }"><i class="icon-ok" data-bind="style: {visibility: repositoryplugins.currentSorting() == 'title' ? 'visible' : 'hidden'}"></i> {{ _('Sort by title') }} ({{ _('ascending') }})</a></li>
<li><a href="#" data-bind="click: function() { repositoryplugins.changeSorting('published'); }"><i class="icon-ok" data-bind="style: {visibility: repositoryplugins.currentSorting() == 'published' ? 'visible' : 'hidden'}"></i> {{ _('Sort by publication date') }} ({{ _('descending') }})</a></li>
<li class="divider"></li>
<li><a href="#" data-bind="click: function() { repositoryplugins.toggleFilter('filter_installed'); }"><i class="icon-ok" data-bind="style: {visibility: _.contains(repositoryplugins.currentFilters(), 'filter_installed') ? 'visible' : 'hidden'}"></i> {{ _('Only show uninstalled plugins') }}</a></li>
<li><a href="#" data-bind="click: function() { repositoryplugins.toggleFilter('filter_incompatible'); }"><i class="icon-ok" data-bind="style: {visibility: _.contains(repositoryplugins.currentFilters(), 'filter_incompatible') ? 'visible' : 'hidden'}"></i> {{ _('Only show compatible plugins') }}</a></li>
<li class="divider"></li>
<li><a href="#" data-bind="click: function() { refreshRepository(); }"><i class="icon-refresh"></i> {{ _('Refresh list from repository') }}</a></li>
</ul>
2015-10-27 14:02:47 +00:00
</div>
2015-05-29 14:31:43 +00:00
</h4>
2015-06-29 15:39:56 +00:00
<form class="form-search" data-bind="submit: performRepositorySearch">
2015-05-29 14:31:43 +00:00
<input type="text" class="input-block search-query" data-bind="value: repositorySearchQuery, valueUpdate: 'input'" placeholder="{{ _('Search...') }}">
</form>
<div data-bind="visible: repositoryAvailable()">
<div id="settings_plugin_pluginmanager_repositorydialog_list" data-bind="slimScrolledForeach: repositoryplugins.paginatedItems">
<div class="entry">
<div class="row-fluid">
<div class="span9">
<div><span data-bind="text: title"></span></div>
<div><small class="muted" data-bind="text: description"> </small></div>
<div>
<small data-bind="visible: page"><i class="icon-info"></i> <a data-bind="attr: {href: page}" target="_blank">{{ _('Details') }}</a></small>
<small data-bind="visible: homepage"><i class="icon-home"></i> <a data-bind="attr: {href: homepage}" target="_blank">{{ _('Homepage') }}</a></small>
<small data-bind="visible: license"><i class="icon-legal"></i> <span data-bind="text: license"></span></small>
<small data-bind="visible: author"><i class="icon-user"></i> <span data-bind="text: author"></span></small>
<small> </small>
</div>
</div>
<div class="span3">
2015-06-18 09:37:08 +00:00
<button class="btn btn-primary btn-block" data-bind="enable: $root.enableRepoInstall($data), css: {disabled: !$root.enableRepoInstall($data)}, click: function() { if ($root.enableRepoInstall($data)) { $root.installFromRepository($data); } else { return false; } }"><i class="icon-add"></i> <span data-bind="text: $root.installButtonText($data)"></span></button>
2017-03-31 15:53:49 +00:00
<div data-bind="visible: $data.disabled !== undefined" style="text-align: center"><small><a data-bind="attr: {href: page}" target="_blank">{{ _('"Why?"') }}</a></small></div>
2015-05-29 14:31:43 +00:00
</div>
</div>
</div>
</div>
</div>
<div id="settings_plugin_pluginmanager_repositorydialog_unavailable" data-bind="visible: !repositoryAvailable()">
<div>
<p>
<strong>{{ _('Sadly the repository is currently not available') }}</strong>
</p>
<p>
<small>{{ _('Is your OctoPrint installation connected to the internet?') }}</small>
</p>
</div>
</div>
<h4>{{ _('... from URL') }}</h4>
<form class="form-inline">
<div class="control-group row-fluid" data-bind="css: {error: invalidUrl}">
<div class="span9">
<input type="text" class="input-block-level" data-bind="value: installUrl, valueUpdate: 'input'" placeholder="{{ _('Enter URL...') }}" >
</div>
<button class="btn btn-primary span3" data-bind="enable: enableUrlInstall, css: {disabled: !enableUrlInstall()}, click: function() { if (enableUrlInstall()) { $root.installPlugin(); } }">{{ _('Install') }}</button>
</div>
<span class="help-block" data-bind="visible: invalidUrl">{{ _('This does not look like a valid "http://" or "https://" URL.') }}</span>
</form>
<h4>{{ _('... from an uploaded archive') }}</h4>
<form class="form-inline">
<div class="control-group row-fluid" data-bind="css: {error: invalidArchive}">
<div class="input-prepend span9">
<span class="btn fileinput-button">
<span>{{ _('Browse...') }}</span>
2016-10-17 09:33:23 +00:00
<input id="settings_plugin_pluginmanager_repositorydialog_upload" type="file" name="file" accept="{{ ",".join(plugin_pluginmanager_archive_extensions) }}" data-url="{{ url_for("plugin.pluginmanager.upload_archive") }}">
2015-05-29 14:31:43 +00:00
</span>
<span class="add-on add-on-limited text-left" data-bind="text: uploadFilename, attr: {title: uploadFilename}"></span>
</div>
<button id="settings_plugin_pluginmanager_repositorydialog_upload_start" class="btn btn-primary span3" data-bind="enable: enableArchiveInstall, css: {disabled: !enableArchiveInstall()}, click: function(){}">{{ _('Install') }}</button>
</div>
<span class="help-block" data-bind="visible: invalidArchive">{{ _('This does not look like a valid plugin archive. Valid plugin archives should be either zip files or tarballs and have the extension ".zip", ".tar.gz", ".tgz" or ".tar"') }}</span>
</form>
2015-07-22 14:57:32 +00:00
<div>
<div><small><a href="#" class="muted" onclick="$(this).children().toggleClass('icon-caret-right icon-caret-down').parent().parent().parent().next().slideToggle('fast')"><i class="icon-caret-right"></i> {{ _('Advanced options') }}</a></small></div>
<div class="hide">
<form class="form-horizontal">
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: followDependencyLinks"> {{ _('Use <code>--process-dependency-links</code> with <code>pip install</code>') }}
</label>
</div>
</div>
</form>
</div>
</div>
2015-05-29 14:31:43 +00:00
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">{{ _('Close') }}</button>
</div>
</div>
2015-09-22 09:36:57 +00:00
<div id="settings_plugin_pluginmanager_configurationdialog" class="modal hide fade">
<div class="modal-header">
<a href="#" class="close" data-dismiss="modal" aria-hidden="true">×</a>
<h3>{{ _('Plugin Configuration') }}</h3>
</div>
<div class="modal-body">
<form class="form-horizontal">
2016-02-04 12:55:10 +00:00
<p>{% trans %}You should normally <strong>not</strong> have to change <strong>any</strong> of the following settings, they are purely provided for convenience here.{% endtrans %}</p>
2015-09-30 11:36:00 +00:00
<legend>{{ _('Plugin repository configuration') }}</legend>
2015-09-22 09:36:57 +00:00
<div class="control-group" title="{{ _('URL of the Plugin Repository to use. You should normally not have to change this.') }}">
<label class="control-label">{{ _('Repository URL') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: config_repositoryUrl">
</div>
</div>
<div class="control-group" title="{{ _('How long to cache repository data, in minutes. You should normally not have to change this.') }}">
<label class="control-label">{{ _('Repository cache TTL') }}</label>
<div class="controls">
<div class="input-append">
<input type="number" class="input-mini" data-bind="value: config_repositoryTtl">
<span class="add-on">min</span>
</div>
</div>
</div>
2016-02-04 12:55:10 +00:00
2017-03-31 14:52:48 +00:00
<legend>{{ _('Notices configuration') }}</legend>
<div class="control-group" title="{{ _('URL of the Notices source to use. You should normally not have to change this.') }}">
<label class="control-label">{{ _('Notices URL') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: config_noticesUrl">
</div>
</div>
<div class="control-group" title="{{ _('How long to cache notices, in minutes. You should normally not have to change this.') }}">
<label class="control-label">{{ _('Notices cache TTL') }}</label>
<div class="controls">
<div class="input-append">
<input type="number" class="input-mini" data-bind="value: config_noticesTtl">
<span class="add-on">min</span>
</div>
</div>
</div>
2016-02-04 12:55:10 +00:00
<legend>{{ _('pip configuration') }}</legend>
<div class="control-group" title="{{ _('Additional arguments for the pip command. You should normally not have to change this.') }}">
<label class="control-label">{{ _('Additional arguments') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: config_pipAdditionalArgs">
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: config_pipForceUser"> {{ _('Force the use of the <code>--user</code> flag with <code>pip install</code>') }}
</label>
</div>
</div>
2015-09-22 09:36:57 +00:00
</form>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">{{ _('Cancel') }}</button>
<button class="btn btn-primary" data-bind="click: savePluginSettings" aria-hidden="true">{{ _('Save') }}</button>
</div>
</div>