Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Commit

Permalink
Update plugin for deluge 2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
h3llrais3r committed Nov 7, 2019
1 parent 7984c79 commit 1c17601
Show file tree
Hide file tree
Showing 12 changed files with 319 additions and 444 deletions.
40 changes: 40 additions & 0 deletions deluge_preventsuspendplus/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Andrew Resch <[email protected]>
#
# Basic plugin template created by:
# Copyright (C) 2008 Martijn Voncken <[email protected]>
# Copyright (C) 2007-2009 Andrew Resch <[email protected]>
#
# 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

from deluge.plugins.init import PluginInitBase


class CorePlugin(PluginInitBase):
def __init__(self, plugin_name):
from .core import Core as _pluginCls

self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name)


class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtkui import GtkUI as _pluginCls

self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name)


class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .webui import WebUI as _pluginCls

self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name)
23 changes: 23 additions & 0 deletions deluge_preventsuspendplus/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
#
# Basic plugin template created by:
# Copyright (C) 2008 Martijn Voncken <[email protected]>
# 2007-2009 Andrew Resch <[email protected]>
# 2009 Damien Churchill <[email protected]>
# 2010 Pedro Algarvio <[email protected]>
# 2017 Calum Lind <[email protected]>
#
# 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 os.path

from pkg_resources import resource_filename


def get_resource(filename):
return resource_filename(__package__, os.path.join('data', filename))
195 changes: 99 additions & 96 deletions preventsuspendplus/core.py → deluge_preventsuspendplus/core.py
Original file line number Diff line number Diff line change
@@ -1,90 +1,77 @@
#
# core.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2015 h3llrais3r <[email protected]>
# Copyright (C) 2009 Ian Martin <[email protected]>
# Copyright (C) 2009 Andrew Resch <[email protected]>
#
# Basic plugin template created by:
# Copyright (C) 2008 Martijn Voncken <[email protected]>
# Copyright (C) 2007-2009 Andrew Resch <[email protected]>
# Copyright (C) 2009 Damien Churchill <[email protected]>
#
# Deluge is free software.
#
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# exception, you may extend this exception to your version of the file(s),
# but you are not obligated to do so. If you do not wish to do so, delete
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# 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.
#

import deluge
import deluge.component as component
from __future__ import unicode_literals

import logging

from twisted.internet.defer import Deferred
from twisted.internet.task import LoopingCall

import deluge.component as component
import deluge.configmanager
from deluge.common import windows_check
from deluge.core.rpcserver import export
from deluge.log import LOG as log
from deluge.plugins.pluginbase import CorePluginBase

from twisted.internet.task import LoopingCall
log = logging.getLogger(__name__)

DEFAULT_PREFS = {
"enabled": True,
"prevent_when": 1
'enabled': True,
'prevent_when': 1
}

APPNAME = "Deluge"
APPNAME = 'Deluge'
REASON = 'Downloading torrents'
LOGRPEFIX = "PreventSuspendPlus plugin: "


def check_state(states):
"""Return true if at least one of the torrents is in one of the states in states[]"""
status = component.get("Core").get_torrents_status(None, ["state"])
in_states = False
for torrent in status:
if status[torrent]["state"] in states:
in_states = True
break
return in_states
def on_torrents_status(torrent_statuses):
in_states = False
for torrent_id, status in torrent_statuses.items():
if status['state'] in states:
in_states = True
break
return in_states

d = component.get('Core').get_torrents_status(None, ['state']).addCallback(on_torrents_status)
return d


def is_downloading():
"""Checks if at least one torrent is downloading"""
def on_check_state(result):
return result

d = check_state(['Downloading'])
d.addCallback(on_check_state)
return d

def downloading():
"""Return true if at least one torrent is downloading"""
status = check_state(["Downloading"])
log.debug(LOGRPEFIX + "Downloading status: %s" % status)
return status

def is_downloading_or_seeding():
"""Checks if at least one torrent is downloading or seeding"""
def on_check_state(result):
return result

def downloading_or_seeding():
"""Return true if at least one torrent is downloading or seeding"""
status = check_state(["Downloading", "Seeding"])
log.debug(LOGRPEFIX + "Downloading or seeding status: %s" % status)
return status
d = check_state(['Downloading', 'Seeding'])
d.addCallback(on_check_state)
return d


class DBusInhibitor:
def __init__(self, name, path, interface, method=["Inhibit", "UnInhibit"]):
def __init__(self, name, path, interface, method=['Inhibit', 'UnInhibit']):
self.name = name
self.path = path
self.interface_name = interface
Expand All @@ -98,9 +85,11 @@ def __init__(self, name, path, interface, method=["Inhibit", "UnInhibit"]):
self._uninhibit = getattr(self.iface, method[1])

def inhibit(self):
log.info('Inhibit (prevent) suspend mode')
self.cookie = self._inhibit(APPNAME, REASON)

def uninhibit(self):
log.info('Uninhibit (allow) suspend mode')
self._uninhibit(self.cookie)


Expand All @@ -111,10 +100,11 @@ class GnomeSessionInhibitor(DBusInhibitor):
def __init__(self):
DBusInhibitor.__init__(self, 'org.gnome.SessionManager',
'/org/gnome/SessionManager',
"org.gnome.SessionManager",
["Inhibit", "Uninhibit"])
'org.gnome.SessionManager',
['Inhibit', 'Uninhibit'])

def inhibit(self):
log.info('Inhibit (prevent) suspend mode')
self.cookie = self._inhibit(APPNAME,
GnomeSessionInhibitor.TOPLEVEL_XID,
REASON,
Expand All @@ -131,122 +121,135 @@ def __init__(self):

def inhibit(self):
import ctypes
log.info(LOGRPEFIX + "Prevent Windows to go to sleep")
log.info('Inhibit (prevent) suspend mode')
ctypes.windll.kernel32.SetThreadExecutionState(
WindowsInhibitor.ES_CONTINUOUS | WindowsInhibitor.ES_SYSTEM_REQUIRED)

def uninhibit(self):
import ctypes
log.info(LOGRPEFIX + "Allow Windows to go to sleep")
log.info('Uninhibit (allow) suspend mode')
ctypes.windll.kernel32.SetThreadExecutionState(WindowsInhibitor.ES_CONTINUOUS)


class Core(CorePluginBase):
def enable(self):
log.info(LOGRPEFIX + "Core plugin enabled")
self.config = deluge.configmanager.ConfigManager("preventsuspendplus.conf", DEFAULT_PREFS)
self.config = deluge.configmanager.ConfigManager('preventsuspendplus.conf', DEFAULT_PREFS)

self.inhibited = False
self.update_timer = None

self.inhibitor = self._get_inhibitor()

self.update()

def disable(self):
log.info(LOGRPEFIX + "Core plugin disabled")
self.stop_timer()

if self.inhibitor is not None:
if self.inhibited:
self.inhibitor.uninhibit()
del self.inhibitor
self.inhibitor = None

self.config.save()

def start_timer(self):
if self.update_timer is None:
self.update_timer = LoopingCall(self.update)
self.update_timer.start(10)
log.debug(LOGRPEFIX + "Timer started")

def stop_timer(self):
if self.update_timer is not None:
self.update_timer.stop()
log.debug(LOGRPEFIX + "Timer stopped")
self.update_timer = None

def should_inhibit(self):
inhibit = False
if self.config["prevent_when"] == 0:
inhibit = downloading()
elif self.config["prevent_when"] == 1:
inhibit = downloading_or_seeding()
elif self.config["prevent_when"] == 2:
inhibit = True
return inhibit

def update(self):
if self.inhibitor is None:
return False
if self.config["enabled"]:
self.start_timer()
if self.should_inhibit():
def on_should_inhibit(result):
if result:
if not self.inhibited:
self.inhibitor.inhibit()
self.inhibited = True
else:
if self.inhibited:
self.inhibitor.uninhibit()
self.inhibited = False

if self.inhibitor is None:
return False

if self.config['enabled']:
self.start_timer()
d = self.should_inhibit()
d.addCallback(on_should_inhibit)
else:
self.stop_timer()
if self.inhibited:
self.inhibitor.uninhibit()
self.inhibited = False

return True

def _get_inhibitor(self):
log.info(LOGRPEFIX + "Windows OS check: %s" % windows_check())
def should_inhibit(self):
def on_state_check(result):
return result

d = None
if self.config['prevent_when'] == 0:
d = is_downloading()
elif self.config['prevent_when'] == 1:
d = is_downloading_or_seeding()
elif self.config['prevent_when'] == 2:
d = Deferred()
d.callback(True) # Always inhibit
d.addCallback(on_state_check)
return d

def _get_inhibitor(self):
if windows_check():
try:
log.debug('Creating Windows inhibitor')
return WindowsInhibitor()
except Exception, e:
log.debug(LOGRPEFIX + "Could not initialise the windows inhibitor: %s" % e)

except Exception as e:
log.debug('Could not initialise the Windows inhibitor: %s' % e)
else:
try:
log.debug('Creating Gnome session inhibitor')
return GnomeSessionInhibitor()
except Exception as e:
log.debug(LOGRPEFIX + "Could not initialise the gnomesession inhibitor: %s" % e)
log.debug('Could not initialise the Gnome session inhibitor: %s' % e)

try:
log.debug('Creating Freedesktop inhibitor')
return DBusInhibitor('org.freedesktop.PowerManagement',
'/org/freedesktop/PowerManagement/Inhibit',
'org.freedesktop.PowerManagement.Inhibit')
except Exception, e:
log.debug(LOGRPEFIX + "Could not initialise the freedesktop inhibitor: %s" % e)
except Exception as e:
log.debug('Could not initialise the Freedesktop inhibitor: %s' % e)

try:
log.debug('Creating Gnome inhibitor')
return DBusInhibitor('org.gnome.PowerManager',
'/org/gnome/PowerManager',
'org.gnome.PowerManager')
except Exception, e:
log.debug(LOGRPEFIX + "Could not initialise the gnome inhibitor: %s" % e)
except Exception as e:
log.debug('Could not initialise the gnome inhibitor: %s' % e)

log.error('Could not initialize any inhibitor')
return None

@export
def get_config(self):
"""Returns the config dictionary"""
"""Get all the preferences as a dictionary"""
out = self.config.config
out["_can_inhibit"] = self.inhibitor is not None
# Set indication if we can inhibit (if an inhibitor is available)
out['_can_inhibit'] = self.inhibitor is not None
return out

@export
def set_config(self, config):
"""Sets the config based on values in 'config'"""
for key in config.keys():
"""Set the config with values from dictionary"""
for key in config:
self.config[key] = config[key]

# Save the config and update accordingly
self.config.save()
self.update()
Loading

0 comments on commit 1c17601

Please sign in to comment.