Cleanup and Fixes and Inplace - Oh My

Add option to extract all archives to torrent root, destination folder, or true in-place.
Add sonarr/radarr support (marks torrent "incomplete" until extraction is done).
Bundle 7z.exe for windows users.
Fix GTK UI not working...at all.
Improve web and GTK UI so they're uniform, have radio buttons, etc.
This commit is contained in:
d8ahazard
2019-12-27 16:05:53 -06:00
parent a9140d33a1
commit 3d4740b95b
14 changed files with 537 additions and 438 deletions

1
.gitignore vendored
View File

@@ -73,3 +73,4 @@ docs/_build/
# PyBuilder
target/
/venv*

Binary file not shown.

Binary file not shown.

View File

@@ -20,4 +20,4 @@ from pkg_resources import resource_filename
def get_resource(filename):
return resource_filename("simpleextractor", os.path.join('data', filename))
return resource_filename(__package__, os.path.join('data', filename))

View File

@@ -29,7 +29,11 @@ from deluge.plugins.pluginbase import CorePluginBase
log = logging.getLogger(__name__)
DEFAULT_PREFS = {'extract_path': '', 'use_name_folder': False, 'in_place_extraction': True, 'extract_labels': ''}
DEFAULT_PREFS = {'extract_path': '',
'extract_in_place': False,
'extract_selected_folder': False,
'extract_torrent_root': True,
'label_filter': ''}
if windows_check():
win_7z_exes = [
@@ -38,20 +42,6 @@ if windows_check():
'C:\\Program Files (x86)\\7-Zip\\7z.exe',
]
try:
import winreg
except ImportError:
import _winreg as winreg # For Python 2.
try:
hkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\7-Zip')
except WindowsError:
pass
else:
win_7z_path = os.path.join(winreg.QueryValueEx(hkey, 'Path')[0], '7z.exe')
winreg.CloseKey(hkey)
win_7z_exes.insert(1, win_7z_path)
switch_7z = 'x -y'
# Future suport:
# 7-zip cannot extract tar.* with single command.
@@ -128,12 +118,16 @@ class Core(CorePluginBase):
tid_status = tid.get_status(['download_location', 'name'])
tstatus = tid.get_status([], False, False, True)
do_extract = False
tid = component.get("TorrentManager").torrents[torrent_id]
tid_status = tid.get_status(["save_path", "name"])
tid.is_finished = False
log.info("Processing completed torrent %s", tstatus)
# Fetch our torrent's label
labels = self.get_labels(torrent_id)
log.info("Schmancy label collector: %s", labels)
# If we've set a label filter, process it
if self.config['extract_labels'] is not "":
if self.config['label_filter'] is not "":
log.info("We should filter by label(s): %s", self.config['extract_labels'])
# Make sure there's actually a label
if len(labels) > 0:
@@ -165,6 +159,9 @@ class Core(CorePluginBase):
do_extract = True
# Now, extract if filter match or no filter set
extract_in_place = self.config["extract_in_place"]
extract_torrent_root = self.config["extract_torrent_root"]
if do_extract:
files = tid.get_files()
for f in files:
@@ -183,28 +180,29 @@ class Core(CorePluginBase):
continue
cmd = EXTRACT_COMMANDS[file_ext]
fpath = os.path.join(
tid_status['download_location'], os.path.normpath(f['path'])
)
dest = os.path.normpath(self.config['extract_path'])
if self.config['use_name_folder']:
dest = os.path.join(dest, tid_status['name'])
# Get the destination path
dest = os.path.normpath(self.config["extract_path"])
name_dest = os.path.join(dest, tid_status["name"])
# Override destination if in_place_extraction is set
if self.config["in_place_extraction"]:
name = tid_status["name"]
save_path = tid_status["download_location"]
dest = os.path.join(save_path, name)
log.info("Save path is %s, dest is %s, fpath is %s", save_path, dest, fpath)
if extract_torrent_root:
dest = tid_status["save_path"]
name_dest = os.path.join(dest, tid_status["name"])
# Create the destination folder if it doesn't exist
if not os.path.exists(dest):
try:
os.makedirs(dest)
except OSError as ex:
if not (ex.errno == errno.EEXIST and os.path.isdir(dest)):
log.error('Error creating destination folder: %s', ex)
break
if extract_in_place and ((not os.path.exists(name_dest)) or os.path.isdir(name_dest)):
dest = name_dest
try:
os.makedirs(dest)
except OSError as ex:
if not (ex.errno == errno.EEXIST and os.path.isdir(dest)):
log.error("EXTRACTOR: Error creating destination folder: %s", ex)
break
def on_extract(result, torrent_id, fpath):
# Check command exit code.
@@ -228,6 +226,7 @@ class Core(CorePluginBase):
cmd[0], cmd[1].split() + [str(fpath)], os.environ, str(dest)
)
d.addCallback(on_extract, torrent_id, fpath)
tid.is_finished = True
def get_labels(self, torrent_id):
"""

View File

@@ -0,0 +1,178 @@
/*!
* simpleextractor.js
*
* Copyright (c) Damien Churchill 2010 <damoxc@gmail.com>
* Copyright (C) Digitalhigh 2019 <donate.to.digitalhigh@gmail.com>
*
*
*/
Ext.ns('Deluge.ux.preferences');
/**
* @class Deluge.ux.preferences.SimpleExtractorPage
* @extends Ext.Panel
*/
Deluge.ux.preferences.SimpleExtractorPage = Ext.extend(Ext.Panel, {
title: _('SimpleExtractor'),
layout: 'fit',
border: false,
initComponent: function() {
Deluge.ux.preferences.SimpleExtractorPage.superclass.initComponent.call(this);
this.form = this.add({
xtype: 'form',
layout: 'form',
border: false,
autoHeight: true
});
this.behaviorSet = this.form.add({
xtype: 'fieldset',
border: false,
title: '',
autoHeight: true,
labelAlign: 'top',
labelWidth: 80,
defaultType: 'textfield'
});
this.behaviorSet.add({
xtype: 'label',
fieldLabel: _('<b>Extract Behavior:</b></br>'),
labelSeparator : '',
name: '',
width: '97%'
});
// Behavior Label
// Add radio group for extract behavior
this.extractBehavior = this.behaviorSet.add({
xtype: 'radiogroup',
columns: 1,
colspan: 2,
style: 'margin-left: 10px',
items: [
{
boxLabel: _('Selected Folder'),
name: 'extract_behavior',
inputValue: "extract_selected_folder"
},
{
boxLabel: _('Torrent Root'),
name: 'extract_behavior',
inputValue: "extract_torrent_root"
},
{
boxLabel: _('In-Place'),
name: 'extract_behavior',
inputValue: "extract_in_place"
}
],
});
this.destinationSet = this.form.add({
xtype: 'fieldset',
border: false,
title: '',
autoHeight: true,
labelAlign: 'top',
labelWidth: 80,
defaultType: 'textfield'
});
// Destination label
this.extractPath = this.destinationSet.add({
fieldLabel: _('<b>Destination:</b></br>'),
name: 'extract_path',
labelSeparator : '',
width: '97%'
});
this.labelSet = this.form.add({
xtype: 'fieldset',
border: false,
title: '',
autoHeight: true,
labelAlign: 'top',
labelWidth: 80,
defaultType: 'textfield'
});
// Label Filter Label
this.labelFilter = this.labelSet.add({
fieldLabel: _('<b>Label Filtering:</b></br>'),
name: 'label_filter',
labelSeparator : '',
width: '97%'
});
this.labelSet.add({
xtype: 'label',
fieldLabel: _('</br>Comma-separated, leave blank for none.'),
labelSeparator : '',
name: '',
width: '97%'
});
this.on('show', this.updateConfig, this);
},
onApply: function() {
// build settings object
var config = {};
config['extract_path'] = this.extractPath.getValue();
var eBehavior = this.extractBehavior.getValue();
config['extract_in_place'] = false;
config['extract_torrent_root'] = false;
config['extract_selected_folder'] = false;
config[eBehavior] = true;
config['label_filter'] = this.labelFilter.getValue();
deluge.client.simpleextractor.set_config(config);
},
onOk: function() {
this.onApply();
},
updateConfig: function() {
deluge.client.simpleextractor.get_config({
success: function(config) {
this.extractPath.setValue(config['extract_path']);
var behavior = "extract_selected_folder";
if (config['extract_in_place']) {
behavior = 'extract_in_place';
}
if (config['extract_torrent_root']) {
behavior = 'extract_torrent_root';
}
this.extractBehavior.setValue(behavior);
this.labelFilter.setValue(config['label_filter']);
},
scope: this
});
}
});
Deluge.plugins.SimpleExtractorPlugin = Ext.extend(Deluge.Plugin, {
name: 'SimpleExtractor',
onDisable: function() {
deluge.preferences.removePage(this.prefsPage);
},
onEnable: function() {
this.prefsPage = deluge.preferences.addPage(new Deluge.ux.preferences.SimpleExtractorPage());
}
});
Deluge.registerPlugin('SimpleExtractor', Deluge.plugins.SimpleExtractorPlugin);

View File

@@ -0,0 +1,221 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.10 -->
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="extractor_prefs_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">start</property>
<property name="border_width">5</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkBox" id="extract_behavior">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkRadioButton" id="extract_selected_folder">
<property name="label" translatable="yes">Selected Folder</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">All torrents will be extracted to the selected folder below.</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">extract_torrent_root</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="extract_torrent_root">
<property name="label" translatable="yes">Torrent Root</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Any found archives will be extracted to the root of the torrent directory.</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="extract_in_place">
<property name="label" translatable="yes">In-Place</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Found archives will be extracted where they are found.</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">extract_torrent_root</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Extract Behavior:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkBox" id="destination_path">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">5</property>
<child>
<object class="GtkFileChooserButton" id="folderchooser_path">
<property name="can_focus">False</property>
<property name="action">select-folder</property>
<property name="title" translatable="yes">Select A Folder</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="extract_path">
<property name="can_focus">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Destination:&lt;/b&gt;
</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkBox" id="hbox3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkEntry" id="label_filter">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Enter one or more labels to extract, separated by commas. Leave to extract any archive found.</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_labels">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Enter labels to extract (comma-separated, leave blank for all)</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Label Filtering:&lt;/b&gt;
</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
#
# Basic plugin template created by:
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2019-2020 Digitalhigh <donate.to.digitalhigh@gmail.com>
#
#
from __future__ import unicode_literals
import logging
import gi # isort:skip (Required before Gtk import).
gi.require_version('Gtk', '3.0') # NOQA: E402
# isort:imports-thirdparty
from gi.repository import Gtk
# isort:imports-firstparty
import deluge.component as component
from deluge.plugins.pluginbase import Gtk3PluginBase
from deluge.ui.client import client
# isort:imports-localfolder
from .common import get_resource
log = logging.getLogger(__name__)
class GtkUI(Gtk3PluginBase):
def enable(self):
self.plugin = component.get('PluginManager')
self.builder = Gtk.Builder()
self.builder.add_from_file(get_resource('simpleextractor_prefs.ui'))
component.get('Preferences').add_page(
_('Simple Extractor'), self.builder.get_object('extractor_prefs_box')
)
self.plugin.register_hook('on_apply_prefs', self.on_apply_prefs)
self.plugin.register_hook('on_show_prefs', self.on_show_prefs)
self.on_show_prefs()
def disable(self):
component.get('Preferences').remove_page(_('Simple Extractor'))
self.plugin.deregister_hook(
'on_apply_prefs', self.on_apply_prefs
)
self.plugin.deregister_hook(
'on_show_prefs', self.on_show_prefs
)
del self.builder
def on_apply_prefs(self):
log.debug('applying prefs for Simple Extractor')
if client.is_localhost():
path = self.builder.get_object('folderchooser_path').get_filename()
else:
path = self.builder.get_object('extract_path').get_text()
config = {
'extract_path': path,
'extract_selected_folder': self.builder.get_object("extract_selected_folder").get_active(),
'extract_in_place': self.builder.get_object("extract_in_place").get_active(),
'extract_torrent_root': self.builder.get_object("extract_torrent_root").get_active(),
'label_filter': self.builder.get_object("label_filter").get_text()
}
client.simpleextractor.set_config(config)
def on_show_prefs(self):
def on_get_config(config):
if client.is_localhost():
self.builder.get_object('folderchooser_path').set_current_folder(config['extract_path'])
self.builder.get_object('folderchooser_path').show()
self.builder.get_object('extract_path').hide()
else:
self.builder.get_object('extract_path').set_text(config['extract_path'])
self.builder.get_object('folderchooser_path').hide()
self.builder.get_object('extract_path').show()
self.builder.get_object('extract_selected_folder').set_active(
config['extract_selected_folder']
)
self.builder.get_object('extract_torrent_root').set_active(
config['extract_torrent_root']
)
self.builder.get_object('extract_in_place').set_active(
config['extract_in_place']
)
self.builder.get_object('label_filter').set_text(config['label_filter'])
client.simpleextractor.get_config().addCallback(on_get_config)

View File

@@ -16,7 +16,7 @@ from setuptools import find_packages, setup
__plugin_name__ = 'SimpleExtractor'
__author__ = 'Digitalhigh'
__author_email__ = 'donate.to.digitalhigh@gmail.com'
__version__ = '1.0'
__version__ = '1.1'
__url__ = 'github.com/d8ahazard/deluge-extractor'
__license__ = 'GPLv3'
__description__ = 'Extract files upon torrent completion'
@@ -30,7 +30,7 @@ Windows support: .rar, .zip, .tar, .7z, .xz, .lzma
Note: Will not extract with 'Move Completed' enabled
"""
__pkg_data__ = {__plugin_name__.lower(): ['template/*', 'data/*']}
__pkg_data__ = {'deluge_' + __plugin_name__.lower(): ['data/*', '7z.dll', '7z.exe']}
setup(
name=__plugin_name__,
@@ -40,16 +40,17 @@ setup(
author_email=__author_email__,
url=__url__,
license=__license__,
long_description=__long_description__ if __long_description__ else __description__,
packages=[__plugin_name__.lower()],
zip_safe=False,
long_description=__long_description__,
packages=find_packages(),
package_data=__pkg_data__,
entry_points="""
[deluge.plugin.core]
%s = %s:CorePlugin
%s = deluge_%s:CorePlugin
[deluge.plugin.gtk3ui]
%s = %s:GtkUIPlugin
%s = deluge_%s:GtkUIPlugin
[deluge.plugin.web]
%s = %s:WebUIPlugin
%s = deluge_%s:WebUIPlugin
"""
% ((__plugin_name__, __plugin_name__.lower()) * 3),
)

View File

@@ -1,131 +0,0 @@
/*!
* simpleextractor.js
*
* Copyright (c) Damien Churchill 2010 <damoxc@gmail.com>
* Copyright (C) Digitalhigh 2019 <donate.to.digitalhigh@gmail.com>
*
* This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
* the additional special exception to link portions of this program with the OpenSSL library.
* See LICENSE for more details.
*
*/
Ext.ns('Deluge.ux.preferences');
/**
* @class Deluge.ux.preferences.SimpleExtractorPage
* @extends Ext.Panel
*/
Deluge.ux.preferences.SimpleExtractorPage = Ext.extend(Ext.Panel, {
title: _('SimpleExtractor'),
layout: 'fit',
border: false,
initComponent: function() {
Deluge.ux.preferences.SimpleExtractorPage.superclass.initComponent.call(this);
this.form = this.add({
xtype: 'form',
layout: 'form',
border: false,
autoHeight: true
});
fieldset = this.form.add({
xtype: 'fieldset',
border: false,
title: '',
autoHeight: true,
labelAlign: 'top',
labelWidth: 80,
defaultType: 'textfield'
});
this.extract_path = fieldset.add({
fieldLabel: _('Extract to:'),
labelSeparator : '',
name: 'extract_path',
width: '97%'
});
this.use_name_folder = fieldset.add({
xtype: 'checkbox',
name: 'use_name_folder',
height: 22,
hideLabel: true,
boxLabel: _('Create torrent name sub-folder')
});
this.in_place_extraction = fieldset.add({
xtype: 'checkbox',
name: 'in_place_extraction',
height: 22,
hideLabel: true,
boxLabel: _('Extract torrent in-place')
});
fieldset2 = this.form.add({
xtype: 'fieldset',
border: false,
title: '',
autoHeight: true,
labelAlign: 'top',
labelWidth: 80,
defaultType: 'textfield'
});
this.extract_labels = fieldset.add({
fieldLabel: _('Label Filter:'),
labelSeparator : '',
name: 'extract_labels',
width: '97%'
});
this.on('show', this.updateConfig, this);
},
onApply: function() {
// build settings object
var config = { }
config['extract_path'] = this.extract_path.getValue();
config['use_name_folder'] = this.use_name_folder.getValue();
config['in_place_extraction'] = this.in_place_extraction.getValue();
config['extract_labels'] = this.extract_labels.getValue();
deluge.client.simpleextractor.set_config(config);
},
onOk: function() {
this.onApply();
},
updateConfig: function() {
deluge.client.simpleextractor.get_config({
success: function(config) {
this.extract_path.setValue(config['extract_path']);
this.use_name_folder.setValue(config['use_name_folder']);
this.in_place_extraction.setValue(config['in_place_extraction']);
this.extract_labels.setValue(config['extract_labels']);
},
scope: this
});
}
});
Deluge.plugins.SimpleExtractorPlugin = Ext.extend(Deluge.Plugin, {
name: 'SimpleExtractor',
onDisable: function() {
deluge.preferences.removePage(this.prefsPage);
},
onEnable: function() {
this.prefsPage = deluge.preferences.addPage(new Deluge.ux.preferences.SimpleExtractorPage());
}
});
Deluge.registerPlugin('SimpleExtractor', Deluge.plugins.SimpleExtractorPlugin);

View File

@@ -1,167 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkBox" id="extractor_prefs_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="spacing">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">5</property>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Extract to:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkFileChooserButton" id="folderchooser_path">
<property name="can_focus">False</property>
<property name="action">select-folder</property>
<property name="title" translatable="yes">Select A Folder</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_path">
<property name="can_focus">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="chk_use_name">
<property name="label" translatable="yes">Create torrent name sub-folder</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">This option will create a sub-folder using the torrent's name within the selected extract folder and put the extracted files there.</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">5</property>
<child>
<object class="GtkLabel" id="label_labels">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Enter labels to extract (comma-separated, leave blank for all)</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_labels">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Enter one or more labels to extract, separated by commas. Leave to extract any archive found.</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child type="label">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;General&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -1,100 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
#
# Basic plugin template created by:
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
#
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
#
from __future__ import unicode_literals
import logging
import gi # isort:skip (Required before Gtk import).
gi.require_version('Gtk', '3.0') # NOQA: E402
# isort:imports-thirdparty
from gi.repository import Gtk
# isort:imports-firstparty
import deluge.component as component
from deluge.plugins.pluginbase import Gtk3PluginBase
from deluge.ui.client import client
# isort:imports-localfolder
from .common import get_resource
log = logging.getLogger(__name__)
class GtkUI(Gtk3PluginBase):
def enable(self):
self.builder = Gtk.Builder()
self.builder.add_from_file(get_resource('extractor_prefs.ui'))
component.get('Preferences').add_page(
_('SimpleExtractor'), self.builder.get_object('extractor_prefs_box')
)
component.get('PluginManager').register_hook(
'on_apply_prefs', self.on_apply_prefs
)
component.get('PluginManager').register_hook(
'on_show_prefs', self.on_show_prefs
)
self.on_show_prefs()
def disable(self):
component.get('Preferences').remove_page(_('SimpleExtractor'))
component.get('PluginManager').deregister_hook(
'on_apply_prefs', self.on_apply_prefs
)
component.get('PluginManager').deregister_hook(
'on_show_prefs', self.on_show_prefs
)
del self.builder
def on_apply_prefs(self):
log.debug('applying prefs for Simple Extractor')
if client.is_localhost():
path = self.builder.get_object('folderchooser_path').get_filename()
else:
path = self.builder.get_object('entry_path').get_text()
config = {
'extract_path': path,
'use_name_folder': self.builder.get_object('chk_use_name').get_active(),
'in_place_extraction': self.builder.get_object("chk_in_place_extraction").get_active(),
'extract_labels': self.builder.get_object("entry_labels").get_text()
}
client.extractor.set_config(config)
def on_show_prefs(self):
if client.is_localhost():
self.builder.get_object('folderchooser_path').show()
self.builder.get_object('entry_path').hide()
else:
self.builder.get_object('folderchooser_path').hide()
self.builder.get_object('entry_path').show()
def on_get_config(config):
if client.is_localhost():
self.builder.get_object('folderchooser_path').set_current_folder(
config['extract_path']
)
else:
self.builder.get_object('entry_path').set_text(config['extract_path'])
self.builder.get_object('chk_use_name').set_active(
config['use_name_folder']
)
self.builder.get_object('chk_in_place_extraction').set_active(config['in_place_extraction'])
self.builder.get_object('entry_labels').set_text(config['extract_labels'])
client.extractor.get_config().addCallback(on_get_config)