summaryrefslogtreecommitdiffstats
path: root/module/plugins/hooks/AntiStandby.py
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins/hooks/AntiStandby.py')
-rw-r--r--module/plugins/hooks/AntiStandby.py175
1 files changed, 175 insertions, 0 deletions
diff --git a/module/plugins/hooks/AntiStandby.py b/module/plugins/hooks/AntiStandby.py
new file mode 100644
index 000000000..48b86fa55
--- /dev/null
+++ b/module/plugins/hooks/AntiStandby.py
@@ -0,0 +1,175 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import with_statement
+
+import os
+import time
+import subprocess
+import sys
+
+try:
+ import caffeine
+except ImportError:
+ pass
+
+from module.plugins.internal.Addon import Addon, Expose
+from module.utils import fs_encode, save_join as fs_join
+
+
+class Kernel32(object):
+ ES_AWAYMODE_REQUIRED = 0x00000040
+ ES_CONTINUOUS = 0x80000000
+ ES_DISPLAY_REQUIRED = 0x00000002
+ ES_SYSTEM_REQUIRED = 0x00000001
+ ES_USER_PRESENT = 0x00000004
+
+
+class AntiStandby(Addon):
+ __name__ = "AntiStandby"
+ __type__ = "hook"
+ __version__ = "0.11"
+ __status__ = "testing"
+
+ __config__ = [("activated", "bool", "Activated" , True ),
+ ("hdd" , "bool", "Prevent HDD standby" , True ),
+ ("system" , "bool", "Prevent OS standby" , True ),
+ ("display" , "bool", "Prevent display standby" , False),
+ ("interval" , "int" , "HDD touching interval in seconds", 25 )]
+
+ __description__ = """Prevent OS, HDD and display standby"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ TMP_FILE = ".antistandby"
+ MIN_INTERVAL = 5
+
+
+ def init(self):
+ self.pid = None
+ self.mtime = 0
+
+
+ def activate(self):
+ hdd = self.get_config('hdd')
+ system = not self.get_config('system')
+ display = not self.get_config('display')
+
+ if hdd:
+ self.interval = max(self.get_config('interval'), self.MIN_INTERVAL)
+ self.init_periodical(threaded=True)
+
+ if os.name == "nt":
+ self.win_standby(system, display)
+
+ elif sys.platform == "darwin":
+ self.osx_standby(system, display)
+
+ else:
+ self.linux_standby(system, display)
+
+
+ def deactivate(self):
+ try:
+ os.remove(self.TMP_FILE)
+
+ except OSError:
+ pass
+
+ if os.name == "nt":
+ self.win_standby(True)
+
+ elif sys.platform == "darwin":
+ self.osx_standby(True)
+
+ else:
+ self.linux_standby(True)
+
+
+ @Expose
+ def win_standby(self, system=True, display=True):
+ import ctypes
+
+ set = ctypes.windll.kernel32.SetThreadExecutionState
+
+ if system:
+ if display:
+ set(Kernel32.ES_CONTINUOUS)
+ else:
+ set(Kernel32.ES_CONTINUOUS | Kernel32.ES_DISPLAY_REQUIRED)
+ else:
+ if display:
+ set(Kernel32.ES_CONTINUOUS | Kernel32.ES_SYSTEM_REQUIRED)
+ else:
+ set(Kernel32.ES_CONTINUOUS | Kernel32.ES_SYSTEM_REQUIRED | Kernel32.ES_DISPLAY_REQUIRED)
+
+
+ @Expose
+ def osx_standby(self, system=True, display=True):
+ try:
+ if system:
+ caffeine.off()
+ else:
+ caffeine.on(display)
+
+ except NameError:
+ self.log_warning(_("Unable to change power state"),
+ _("caffeine lib not found"))
+
+ except Exception, e:
+ self.log_warning(_("Unable to change power state"), e)
+
+
+ @Expose
+ def linux_standby(self, system=True, display=True):
+ try:
+ if system:
+ if self.pid:
+ self.pid.kill()
+
+ elif not self.pid:
+ self.pid = subprocess.Popen(["caffeine"])
+
+ except Exception, e:
+ self.log_warning(_("Unable to change system power state"), e)
+
+ try:
+ if display:
+ subprocess.call(["xset", "+dpms", "s", "default"])
+ else:
+ subprocess.call(["xset", "-dpms", "s", "off"])
+
+ except Exception, e:
+ self.log_warning(_("Unable to change display power state"), e)
+
+
+ @Expose
+ def touch(self, path):
+ with open(path, 'w'):
+ os.utime(path, None)
+
+ self.mtime = time.time()
+
+
+ @Expose
+ def max_mtime(self, path):
+ return max(0, 0,
+ *(os.path.getmtime(fs_join(root, file))
+ for root, dirs, files in os.walk(fs_encode(path), topdown=False)
+ for file in files))
+
+
+ def periodical(self):
+ if self.get_config('hdd') is False:
+ return
+
+ if (self.pyload.threadManager.pause or
+ not self.pyload.api.isTimeDownload() or
+ not self.pyload.threadManager.getActiveFiles()):
+ return
+
+ download_folder = self.pyload.config.get("general", "download_folder")
+ if (self.max_mtime(download_folder) - self.mtime) < self.interval:
+ return
+
+ self.touch(self.TMP_FILE)