Add option to only extract specific labels

Add UI element for a comma-separated list of labels to extract by.
Should work with both Label and LabelPlus plugins.
If no filter is specified, it will extract anything.
This commit is contained in:
d8ahazard
2019-10-25 11:52:23 -05:00
parent 739a93351a
commit ad8049b89a
5 changed files with 189 additions and 60 deletions

View File

@@ -16,7 +16,7 @@ from setuptools import find_packages, setup
__plugin_name__ = 'SimpleExtractor' __plugin_name__ = 'SimpleExtractor'
__author__ = 'Digitalhigh' __author__ = 'Digitalhigh'
__author_email__ = 'donate.to.digitalhigh@gmail.com' __author_email__ = 'donate.to.digitalhigh@gmail.com'
__version__ = '0.8' __version__ = '0.9'
__url__ = 'github.com/d8ahazard/deluge-extractor' __url__ = 'github.com/d8ahazard/deluge-extractor'
__license__ = 'GPLv3' __license__ = 'GPLv3'
__description__ = 'Extract files upon torrent completion' __description__ = 'Extract files upon torrent completion'

View File

@@ -22,13 +22,14 @@ from twisted.python.procutils import which
import deluge.component as component import deluge.component as component
import deluge.configmanager import deluge.configmanager
from deluge.configmanager import ConfigManager
from deluge.common import windows_check from deluge.common import windows_check
from deluge.core.rpcserver import export from deluge.core.rpcserver import export
from deluge.plugins.pluginbase import CorePluginBase from deluge.plugins.pluginbase import CorePluginBase
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
DEFAULT_PREFS = {'extract_path': '', 'use_name_folder': False, 'in_place_extraction': True} DEFAULT_PREFS = {'extract_path': '', 'use_name_folder': False, 'in_place_extraction': True, 'extract_labels': ''}
if windows_check(): if windows_check():
win_7z_exes = [ win_7z_exes = [
@@ -101,7 +102,7 @@ if not EXTRACT_COMMANDS:
class Core(CorePluginBase): class Core(CorePluginBase):
def enable(self): def enable(self):
self.config = deluge.configmanager.ConfigManager( self.config = deluge.configmanager.ConfigManager(
'extractor.conf', DEFAULT_PREFS 'simpleextractor.conf', DEFAULT_PREFS
) )
if not self.config['extract_path']: if not self.config['extract_path']:
self.config['extract_path'] = deluge.configmanager.ConfigManager( self.config['extract_path'] = deluge.configmanager.ConfigManager(
@@ -125,21 +126,60 @@ class Core(CorePluginBase):
""" """
tid = component.get('TorrentManager').torrents[torrent_id] tid = component.get('TorrentManager').torrents[torrent_id]
tid_status = tid.get_status(['download_location', 'name']) tid_status = tid.get_status(['download_location', 'name'])
tstatus = tid.get_status([], False, False, True)
do_extract = 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 "":
log.info("We should filter by label(s): %s", self.config['extract_labels'])
# Make sure there's actually a label
if len(labels) > 0:
for label in labels:
log.info("Label for torrent is %s", label)
# Check if it's more than one, split
if "," in self.config['extract_labels']:
log.info("And we have a list")
label_list = self.config['extract_labels'].split(",")
# And loop
for label in label_list:
if label.strip() == label:
log.info("This matches")
do_extract = True
break
# Otherwise, just check the whole string
else:
log.info("Single label string detected.")
if self.config['extract_labels'].strip() == label:
log.info("This matches")
do_extract = True
# We don't need to do this, but it adds sanity
else:
log.info("We have a label filter and no label, doing nothing")
do_extract = False
# Otherwise, we just extract everything
else:
log.info("No label, extracting.")
do_extract = True
# Now, extract if filter match or no filter set
if do_extract:
files = tid.get_files() files = tid.get_files()
for f in files: for f in files:
log.debug("Handling file %s", f['path']) log.info("Handling file %s", f['path'])
file_root, file_ext = os.path.splitext(f['path']) file_root, file_ext = os.path.splitext(f['path'])
file_ext_sec = os.path.splitext(file_root)[1] file_ext_sec = os.path.splitext(file_root)[1]
if file_ext_sec and file_ext_sec + file_ext in EXTRACT_COMMANDS: if file_ext_sec and file_ext_sec + file_ext in EXTRACT_COMMANDS:
file_ext = file_ext_sec + file_ext file_ext = file_ext_sec + file_ext
elif file_ext not in EXTRACT_COMMANDS or file_ext_sec == '.tar': elif file_ext not in EXTRACT_COMMANDS or file_ext_sec == '.tar':
log.debug('Cannot extract file with unknown file type: %s', f['path']) log.info('Cannot extract file with unknown file type: %s', f['path'])
continue continue
elif file_ext == '.rar' and 'part' in file_ext_sec: elif file_ext == '.rar' and 'part' in file_ext_sec:
part_num = file_ext_sec.split('part')[1] part_num = file_ext_sec.split('part')[1]
if part_num.isdigit() and int(part_num) != 1: if part_num.isdigit() and int(part_num) != 1:
log.debug('Skipping remaining multi-part rar files: %s', f['path']) log.info('Skipping remaining multi-part rar files: %s', f['path'])
continue continue
cmd = EXTRACT_COMMANDS[file_ext] cmd = EXTRACT_COMMANDS[file_ext]
@@ -155,7 +195,7 @@ class Core(CorePluginBase):
name = tid_status["name"] name = tid_status["name"]
save_path = tid_status["download_location"] save_path = tid_status["download_location"]
dest = os.path.join(save_path, name) dest = os.path.join(save_path, name)
log.debug("Save path is %s, dest is %s, fpath is %s", save_path, dest, fpath) log.info("Save path is %s, dest is %s, fpath is %s", save_path, dest, fpath)
# Create the destination folder if it doesn't exist # Create the destination folder if it doesn't exist
if not os.path.exists(dest): if not os.path.exists(dest):
@@ -176,7 +216,7 @@ class Core(CorePluginBase):
) )
# Run the command and add callback. # Run the command and add callback.
log.debug( log.info(
'Extracting %s from %s with %s %s to %s', 'Extracting %s from %s with %s %s to %s',
fpath, fpath,
torrent_id, torrent_id,
@@ -189,6 +229,30 @@ class Core(CorePluginBase):
) )
d.addCallback(on_extract, torrent_id, fpath) d.addCallback(on_extract, torrent_id, fpath)
def get_labels(self, torrent_id):
"""
Asking the system about the labels isn't very cool, so try this instead
"""
labels = []
label_config = ConfigManager('label.conf', defaults=False)
if label_config is not False:
log.info("We have a Label config")
if 'torrent_labels' in label_config:
if torrent_id in label_config['torrent_labels']:
log.info("Data from Label plugin: %s", label_config['torrent_labels'][torrent_id])
labels.append(label_config['torrent_labels'][torrent_id])
label_plus_config = ConfigManager('labelplus.conf', defaults=False)
if label_plus_config is not False:
log.info("We have a label plus config")
if 'mappings' in label_plus_config:
if torrent_id in label_plus_config['mappings']:
mapping = label_plus_config['mappings'][torrent_id]
log.info("We have a label plus mapping: %s", mapping)
labels.append(label_plus_config['labels'][mapping]['name'])
return labels
@export @export
def set_config(self, config): def set_config(self, config):
"""Sets the config dictionary.""" """Sets the config dictionary."""

View File

@@ -66,6 +66,23 @@ Deluge.ux.preferences.SimpleExtractorPage = Ext.extend(Ext.Panel, {
boxLabel: _('Extract torrent in-place') 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); this.on('show', this.updateConfig, this);
}, },
@@ -76,6 +93,7 @@ Deluge.ux.preferences.SimpleExtractorPage = Ext.extend(Ext.Panel, {
config['extract_path'] = this.extract_path.getValue(); config['extract_path'] = this.extract_path.getValue();
config['use_name_folder'] = this.use_name_folder.getValue(); config['use_name_folder'] = this.use_name_folder.getValue();
config['in_place_extraction'] = this.in_place_extraction.getValue(); config['in_place_extraction'] = this.in_place_extraction.getValue();
config['extract_labels'] = this.extract_labels.getValue();
deluge.client.simpleextractor.set_config(config); deluge.client.simpleextractor.set_config(config);
}, },
@@ -90,6 +108,7 @@ Deluge.ux.preferences.SimpleExtractorPage = Ext.extend(Ext.Panel, {
this.extract_path.setValue(config['extract_path']); this.extract_path.setValue(config['extract_path']);
this.use_name_folder.setValue(config['use_name_folder']); this.use_name_folder.setValue(config['use_name_folder']);
this.in_place_extraction.setValue(config['in_place_extraction']); this.in_place_extraction.setValue(config['in_place_extraction']);
this.extract_labels.setValue(config['extract_labels']);
}, },
scope: this scope: this
}); });

View File

@@ -100,7 +100,51 @@
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </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> </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>
<child type="label"> <child type="label">
<object class="GtkLabel" id="label1"> <object class="GtkLabel" id="label1">

View File

@@ -69,7 +69,8 @@ class GtkUI(Gtk3PluginBase):
config = { config = {
'extract_path': path, 'extract_path': path,
'use_name_folder': self.builder.get_object('chk_use_name').get_active(), '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() '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) client.extractor.set_config(config)
@@ -94,5 +95,6 @@ class GtkUI(Gtk3PluginBase):
config['use_name_folder'] config['use_name_folder']
) )
self.builder.get_object('chk_in_place_extraction').set_active(config['in_place_extraction']) 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) client.extractor.get_config().addCallback(on_get_config)