You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
256 lines
9.0 KiB
256 lines
9.0 KiB
#!/usr/bin/python3 -OO
|
|
# Copyright 2007-2018 The SABnzbd-Team <team@sabnzbd.org>
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program 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 this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
"""
|
|
sabnzbd.powersup - System power management support
|
|
"""
|
|
|
|
import os
|
|
import subprocess
|
|
import logging
|
|
import time
|
|
|
|
|
|
##############################################################################
|
|
# Power management for Windows
|
|
##############################################################################
|
|
try:
|
|
import win32security
|
|
import win32api
|
|
import ntsecuritycon
|
|
except ImportError:
|
|
pass
|
|
|
|
|
|
def win_power_privileges():
|
|
""" To do any power-options, the process needs higher privileges """
|
|
flags = ntsecuritycon.TOKEN_ADJUST_PRIVILEGES | ntsecuritycon.TOKEN_QUERY
|
|
htoken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), flags)
|
|
id_ = win32security.LookupPrivilegeValue(None, ntsecuritycon.SE_SHUTDOWN_NAME)
|
|
newPrivileges = [(id_, ntsecuritycon.SE_PRIVILEGE_ENABLED)]
|
|
win32security.AdjustTokenPrivileges(htoken, 0, newPrivileges)
|
|
|
|
|
|
def win_hibernate():
|
|
""" Hibernate Windows system, returns after wakeup """
|
|
try:
|
|
win_power_privileges()
|
|
win32api.SetSystemPowerState(False, True)
|
|
except:
|
|
logging.error(T('Failed to hibernate system'))
|
|
logging.info("Traceback: ", exc_info=True)
|
|
|
|
|
|
def win_standby():
|
|
""" Standby Windows system, returns after wakeup """
|
|
try:
|
|
win_power_privileges()
|
|
win32api.SetSystemPowerState(True, True)
|
|
except:
|
|
logging.error(T('Failed to standby system'))
|
|
logging.info("Traceback: ", exc_info=True)
|
|
|
|
|
|
def win_shutdown():
|
|
""" Shutdown Windows system, never returns """
|
|
try:
|
|
win_power_privileges()
|
|
win32api.InitiateSystemShutdown("", "", 30, 1, 0)
|
|
finally:
|
|
os._exit(0)
|
|
|
|
|
|
##############################################################################
|
|
# Power management for OSX
|
|
##############################################################################
|
|
|
|
def osx_shutdown():
|
|
""" Shutdown OSX system, never returns """
|
|
try:
|
|
subprocess.call(['osascript', '-e', 'tell app "System Events" to shut down'])
|
|
except:
|
|
logging.error(T('Error while shutting down system'))
|
|
logging.info("Traceback: ", exc_info=True)
|
|
os._exit(0)
|
|
|
|
|
|
def osx_standby():
|
|
""" Make OSX system sleep, returns after wakeup """
|
|
try:
|
|
subprocess.call(['osascript', '-e', 'tell app "System Events" to sleep'])
|
|
time.sleep(10)
|
|
except:
|
|
logging.error(T('Failed to standby system'))
|
|
logging.info("Traceback: ", exc_info=True)
|
|
|
|
|
|
def osx_hibernate():
|
|
""" Make OSX system sleep, returns after wakeup """
|
|
osx_standby()
|
|
|
|
|
|
##############################################################################
|
|
# Power management for Linux
|
|
##############################################################################
|
|
|
|
# Requires DBus plus either HAL [1] or the more modern ConsoleKit [2] and
|
|
# DeviceKit(-power) [3]. HAL will eventually be deprecated but older systems
|
|
# might still use it.
|
|
# [1] http://people.freedesktop.org/~hughsient/temp/dbus-interface.html
|
|
# [2] http://www.freedesktop.org/software/ConsoleKit/doc/ConsoleKit.html
|
|
# [3] http://hal.freedesktop.org/docs/DeviceKit-power/
|
|
#
|
|
# Original code was contributed by Marcel de Vries <marceldevries@phannet.cc>
|
|
#
|
|
|
|
try:
|
|
import dbus
|
|
HAVE_DBUS = True
|
|
except ImportError:
|
|
HAVE_DBUS = False
|
|
|
|
|
|
_IS_NOT_INTERACTIVE = False
|
|
_LOGIND_SUCCESSFUL_RESULT = 'yes'
|
|
|
|
|
|
def _get_sessionproxy():
|
|
""" Return (proxy-object, interface), (None, None) if not available """
|
|
name = 'org.freedesktop.PowerManagement'
|
|
path = '/org/freedesktop/PowerManagement'
|
|
interface = 'org.freedesktop.PowerManagement'
|
|
try:
|
|
bus = dbus.SessionBus()
|
|
return bus.get_object(name, path), interface
|
|
except dbus.exceptions.DBusException:
|
|
return None, None
|
|
|
|
|
|
def _get_systemproxy(method):
|
|
""" Return (proxy-object, interface, pinterface), (None, None, None) if not available """
|
|
if method == 'ConsoleKit':
|
|
name = 'org.freedesktop.ConsoleKit'
|
|
path = '/org/freedesktop/ConsoleKit/Manager'
|
|
interface = 'org.freedesktop.ConsoleKit.Manager'
|
|
pinterface = None
|
|
elif method == 'DeviceKit':
|
|
name = 'org.freedesktop.DeviceKit.Power'
|
|
path = '/org/freedesktop/DeviceKit/Power'
|
|
interface = 'org.freedesktop.DeviceKit.Power'
|
|
pinterface = 'org.freedesktop.DBus.Properties'
|
|
elif method == 'UPower':
|
|
name = 'org.freedesktop.UPower'
|
|
path = '/org/freedesktop/UPower'
|
|
interface = 'org.freedesktop.UPower'
|
|
pinterface = 'org.freedesktop.DBus.Properties'
|
|
elif method == 'Logind':
|
|
name = 'org.freedesktop.login1'
|
|
path = '/org/freedesktop/login1'
|
|
interface = 'org.freedesktop.login1.Manager'
|
|
pinterface = None
|
|
try:
|
|
bus = dbus.SystemBus()
|
|
return bus.get_object(name, path), interface, pinterface
|
|
except dbus.exceptions.DBusException as msg:
|
|
logging.info('DBus not reachable (%s)', msg)
|
|
return None, None, None
|
|
|
|
|
|
def linux_shutdown():
|
|
""" Make Linux system shutdown, never returns """
|
|
if not HAVE_DBUS:
|
|
os._exit(0)
|
|
|
|
try:
|
|
proxy, interface = _get_sessionproxy()
|
|
|
|
if proxy:
|
|
if proxy.CanShutdown():
|
|
proxy.Shutdown(dbus_interface=interface)
|
|
else:
|
|
proxy, interface, pinterface = _get_systemproxy('Logind')
|
|
if proxy:
|
|
if proxy.CanPowerOff(dbus_interface=interface) == _LOGIND_SUCCESSFUL_RESULT:
|
|
proxy.PowerOff(_IS_NOT_INTERACTIVE, dbus_interface=interface)
|
|
else:
|
|
proxy, interface, _pinterface = _get_systemproxy('ConsoleKit')
|
|
if proxy:
|
|
if proxy.CanStop(dbus_interface=interface):
|
|
proxy.Stop(dbus_interface=interface)
|
|
else:
|
|
logging.info('DBus does not support Stop (shutdown)')
|
|
except dbus.exceptions.DBusException as msg:
|
|
logging.error('Received a DBus exception %s', msg)
|
|
os._exit(0)
|
|
|
|
|
|
def linux_hibernate():
|
|
""" Make Linux system go into hibernate, returns after wakeup """
|
|
if not HAVE_DBUS:
|
|
return
|
|
|
|
try:
|
|
proxy, interface = _get_sessionproxy()
|
|
if proxy:
|
|
if proxy.CanHibernate():
|
|
proxy.Hibernate(dbus_interface=interface)
|
|
else:
|
|
proxy, interface, pinterface = _get_systemproxy('Logind')
|
|
if proxy:
|
|
if proxy.CanHibernate(dbus_interface=interface) == _LOGIND_SUCCESSFUL_RESULT:
|
|
proxy.Hibernate(_IS_NOT_INTERACTIVE, dbus_interface=interface)
|
|
else:
|
|
proxy, interface, pinterface = _get_systemproxy('UPower')
|
|
if not proxy:
|
|
proxy, interface, pinterface = _get_systemproxy('DeviceKit')
|
|
if proxy:
|
|
if proxy.Get(interface, 'can-hibernate', dbus_interface=pinterface):
|
|
proxy.Hibernate(dbus_interface=interface)
|
|
else:
|
|
logging.info('DBus does not support Hibernate')
|
|
time.sleep(10)
|
|
except dbus.exceptions.DBusException as msg:
|
|
logging.error('Received a DBus exception %s', msg)
|
|
|
|
|
|
def linux_standby():
|
|
""" Make Linux system go into standby, returns after wakeup """
|
|
if not HAVE_DBUS:
|
|
return
|
|
|
|
try:
|
|
proxy, interface = _get_sessionproxy()
|
|
if proxy:
|
|
if proxy.CanSuspend():
|
|
proxy.Suspend(dbus_interface=interface)
|
|
else:
|
|
proxy, interface, pinterface = _get_systemproxy('Logind')
|
|
if proxy:
|
|
if proxy.CanSuspend(dbus_interface=interface) == _LOGIND_SUCCESSFUL_RESULT:
|
|
proxy.Suspend(_IS_NOT_INTERACTIVE, dbus_interface=interface)
|
|
else:
|
|
proxy, interface, pinterface = _get_systemproxy('UPower')
|
|
if not proxy:
|
|
proxy, interface, pinterface = _get_systemproxy('DeviceKit')
|
|
if proxy:
|
|
if proxy.Get(interface, 'can-suspend', dbus_interface=pinterface):
|
|
proxy.Suspend(dbus_interface=interface)
|
|
else:
|
|
logging.info('DBus does not support Suspend (standby)')
|
|
time.sleep(10)
|
|
except dbus.exceptions.DBusException as msg:
|
|
logging.error('Received a DBus exception %s', msg)
|
|
|