In Python on Unix, determine if I am using my computer? or idle?
Asked Answered
U

5

8

I would like to write a script to do an heavy network upload, in the background. However, I would like it to pause when I am using my computer (either by detecting network activity or keyboard activity or that I am not idle).

What is the best way to detect that I am using the computer, on Python on Unix?

Unsay answered 6/5, 2011 at 16:40 Comment(3)
Maybe check if the screensaver is on?Harpist
What operating system? For Linux, google for "linux keyboard activity" for assorted solutions, then call them from python. For Windows... uhh dunno.Killough
Maybe this can help too : ru1.sourceforge.netTahsildar
M
10

Unixy solution using X11/XScreenSaver to get idle time:

#!/usr/bin/python
import ctypes
import os

class XScreenSaverInfo( ctypes.Structure):
  """ typedef struct { ... } XScreenSaverInfo; """
  _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

xlib = ctypes.cdll.LoadLibrary('libX11.so')
display = xlib.XOpenDisplay(os.environ['DISPLAY'])
xss = ctypes.cdll.LoadLibrary('libXss.so.1')
xss.XScreenSaverAllocInfo.restype = ctypes.POINTER(XScreenSaverInfo)
xssinfo = xss.XScreenSaverAllocInfo()
xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), xssinfo)

print "idle: %d ms" % xssinfo.contents.idle

# cleanup
xss.XCloseDisplay(display)
xss.XFree(xssinfo)

(From "X11 idle time and focused window in Python", originally found on thp.io, now apparently only the GitHub gist by the same author survives.)

A cleanup section was added to the code in a later edit by another user so that it can be called periodically.

As noted in a comment to the answer they reference, note that you should also do proper return code checking on function calls to avoid ungraceful program termination when X display and other initializations fail for some reason.

Meprobamate answered 6/5, 2011 at 18:17 Comment(2)
You've accepted a solution that tells you whether or not the user is interacting with the input devices. But what's really going to burn is whether or not the network is busy. It's obviously your choice, but it seems odd to me.Hulk
on my system you have to call xss.XFree(xssinfo) after reading xssinfo.contents.idle, or will be set to 0Insecure
H
2

I guess that you are concerned about the network activity of the file transfer getting in the way of the interactive user. You don't need to worry about whether or not the user is typing on the keyboard. Really all that matters is whether or not there are competing network activities.

On Windows, for example, you can use Background Intelligent Transfer Service. This is the same service that Windows Update uses to deliver updates to your desktop without getting in the way of your use of the machine. To script it you might consider Powershell. If you are dead set on using Python you can do it with win32com.bits.

Other platforms will, no doubt, have similar offerings.

Hulk answered 6/5, 2011 at 16:59 Comment(2)
I'm curious what the offering for Unix is.Unsay
@Joseph - For unix, setsockopt(fd, IPPROTO_IP, IP_TOS, IPTOS_MINCOST) should mark your networking data as less important than most other data. See ip(7) and socket(7) for more info. Combined with nice(1) or setpriority(2), you could down-prioritize your application compared to any interactive apps present.Colombia
F
2

Most Linux distributions come with ConsoleKit, which provides some session information over DBus, including an "idle hint"; this works for both X11 and text logins.

(However, there are plans to deprecate ConsoleKit, moving parts of it into systemd; the future for the "idle hint" feature hasn't been decided yet.)


Just for completeness, os.stat(ttydev).st_mtime or os.fstat(1).st_mtime returns last input time for tty/pty devices.

Fitful answered 6/5, 2011 at 18:30 Comment(0)
K
0

Stick a webcam on your computer that grabs an image every five seconds, then there's some python modules for image analysis that can check if you are still sitting in your seat.

Or get a microswitch wired into your chair, connect that to your PC serial port (or one of those modern USB ports) and read that from Python...

Killough answered 6/5, 2011 at 16:53 Comment(4)
How does this even address the question!?Error
@André: If webcam output contains a humanoid face, "active"; otherwise, "idle".Fitful
Sorry, I forgot stack overflow doesn't have a sense of humour.Killough
it does have a sense of humour, if you post as a commentHulk
J
0

import this script. When another app like firefox starts grabbing bandwidth, pause the main program. There's some simple addition involed but other than that it's pretty easy

Jungjungfrau answered 6/5, 2011 at 16:55 Comment(2)
I think the challenge is in detecting that another app is demanding bandwidth. What's your suggestion for doing that?Hulk
I'm terrible with networking, but couldn't he just define a class to count the packets, average the rate, then pause when it hits a predefined deviation from the norm?Jungjungfrau

© 2022 - 2024 — McMap. All rights reserved.