-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathinhibitors.py
117 lines (93 loc) · 3.34 KB
/
inhibitors.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright 2013 Benn Snyder
Espresso keeps your computer awake from the system tray.
Espresso is freely available under the terms of the GNU Public License, version 3. The license appears in GPLv3.txt.
"""
import sys
import platform
from abc import ABCMeta, abstractmethod
def AutoSelect():
if platform.system() == "Linux":
return DBusInhibitor()
elif platform.system() == "Windows" and sys.getwindowsversion().build >= 7601:
return WinInhibitor()
else:
raise NotImplementedError("Platform not supported")
# Implementations need only implement the methods marked with the `@abstractmethod` decorator and
# make sure `self.inhibited` is `None` only when not inhibited.
class SleepInhibitor(metaclass=ABCMeta):
"""
A SleepInhibitor implementation can be used to keep a machine awake in one of two ways.
Explicitly:
inhibitor = ConcreteInhibitor()
inhibitor.Inhibit()
# AWAKE
inhibitor.UnInhibit() # or inhibitor.Toggle()
In a `with` statement:
with ConcreteInhibitor() as inhibitor:
# AWAKE
"""
def __init__(self):
self.inhibited = None # Attention Children: set to None when not inhibited
def __del__(self):
self.UnInhibit()
def __enter__(self):
self.Inhibit()
return self
def __exit__(self, type, value, traceback):
self.UnInhibit()
@property
def Inhibited(self):
return self.inhibited is not None
def Toggle(self):
if not self.Inhibited:
self.Inhibit()
else:
self.UnInhibit()
@abstractmethod
def Inhibit(self):
pass
@abstractmethod
def UnInhibit(self):
pass
class DBusInhibitor(SleepInhibitor):
def __init__(self):
super().__init__()
import dbus
self.pm = dbus.SessionBus().get_object("org.freedesktop.PowerManagement", "/org/freedesktop/PowerManagement/Inhibit")
def Inhibit(self):
if not self.Inhibited:
self.inhibited = self.pm.Inhibit("Espresso", "Inhibited by user")
def UnInhibit(self):
if self.Inhibited:
self.pm.UnInhibit(self.inhibited)
self.inhibited = None
class WinInhibitor(SleepInhibitor):
# _POWER_REQUEST_TYPE enum from WinNT.h
(
PowerRequestDisplayRequired,
PowerRequestSystemRequired,
PowerRequestAwayModeRequired,
PowerRequestExecutionRequred, # Windows 8 only
) = map(int, range(4))
def __init__(self):
super().__init__()
global ctypes
import ctypes
self.request = ctypes.windll.kernel32.PowerCreateRequest(None) # todo: reason
def Inhibit(self):
if not self.Inhibited:
result = ctypes.windll.kernel32.PowerSetRequest(self.request, self.PowerRequestSystemRequired)
if result != 0: # yes, this function returns 0 on failure
self.inhibited = True
else:
raise OSError(result, "SetPowerRequest() failed")
def UnInhibit(self):
if self.Inhibited:
result = ctypes.windll.kernel32.PowerClearRequest(self.request, self.PowerRequestSystemRequired)
if result != 0:
self.inhibited = None
else:
raise OSError(result, "PowerClearRequest() failed")