Example #1
0
class ClientTest(unittest.TestCase):
    def setUp(self):
        self.client = ActivityWatchClient("unittest", testing=True)
        self.client.setup_bucket("test", "testevents")
        self.client.connect()

    def test_send_event(self):
        self.client.send_event("test",
                               Event(timestamp=datetime.now(), label="test"))

    def test_send_events(self):
        self.client.send_events("test", [
            Event(timestamp=datetime.now(), label="test"),
            Event(timestamp=datetime.now(), label="test2"),
        ])
Example #2
0
class AFKWatcher:
    def __init__(self, testing=False, settings=None):
        # Read settings from config
        configsection = "aw-watcher-afk" if not testing else "aw-watcher-afk-testing"
        self.settings = Settings(watcher_config[configsection])

        self.client = ActivityWatchClient("aw-watcher-afk", testing=testing)
        self.bucketname = "{}_{}".format(self.client.client_name, self.client.client_hostname)

        eventtype = "afkstatus"
        self.client.setup_bucket(self.bucketname, eventtype)
        self.client.connect()

    def set_state(self, status, duration, timestamp=None):
        data = {"status": status}
        if timestamp is None:
            timestamp = self.now
        e = Event(data=data, timestamp=timestamp, duration=duration)
        self.client.heartbeat(self.bucketname, e, pulsetime=self.settings.timeout, queued=True)

    def ping(self, afk):
        data = {"status": "afk" if afk else "not-afk"}
        e = Event(data=data, timestamp=self.now)
        self.client.heartbeat(self.bucketname, e, pulsetime=self.settings.timeout, queued=True)

    def run(self):
        # TODO: All usage of last_input can probably be replaced the self.seconds_since_last_input equivalent
        logger.info("afkwatcher started")

        """ Initialization """
        sleep(1)

        """ Init variables """
        self.afk = False
        self.now = datetime.now(timezone.utc)
        self.last_check = self.now
        self.seconds_since_last_input = 0

        """ Start afk checking loop """
        while True:
            try:
                self.last_check = self.now
                self.now = datetime.now(timezone.utc)

                self.seconds_since_last_input = get_seconds_since_last_input()
                self.timedelta_since_last_input = timedelta(seconds=self.seconds_since_last_input)
                self.last_input = self.now - self.timedelta_since_last_input
                logger.debug("Time since last input: {}".format(self.timedelta_since_last_input))

                # If program is not allowed to run for more than polling_interval+10s it will assume that the computer has gone into suspend/hibernation
                if self.now > self.last_check + timedelta(seconds=10 + self.settings.polling_interval):
                    logger.info("Woke up from suspend/hibernation")
                    time_since_last_check = self.now - self.last_check
                    self.set_state("hibernating", timedelta(seconds=time_since_last_check.total_seconds()), self.last_check)
                # If no longer AFK
                elif self.afk and self.seconds_since_last_input < self.settings.timeout:
                    logger.info("No longer AFK")
                    self.ping(self.afk)  # End afk period
                    self.afk = False
                    self.set_state("not-afk", timedelta())
                # If becomes AFK
                elif not self.afk and self.seconds_since_last_input > self.settings.timeout:
                    logger.info("Became AFK")
                    self.afk = True
                    self.set_state("afk", self.timedelta_since_last_input, self.last_input)
                # Send a heartbeat if no state change was made
                else:
                    if self.afk:
                        self.ping(self.afk)
                    elif self.seconds_since_last_input < self.settings.polling_interval:
                        self.ping(self.afk)

                sleep(self.settings.polling_interval)

            except KeyboardInterrupt:
                logger.info("afkwatcher stopped by keyboard interrupt")
                self.ping(self.afk)
                break