def main(): # Verify python version is >=3.5 # req_version is 3.5 due to usage of subprocess.run assert_version((3, 5)) if sys.platform.startswith("linux") and ("DISPLAY" not in os.environ or not os.environ["DISPLAY"]): raise Exception("DISPLAY environment variable not set") # Read settings from config config = load_config() args = parse_args(default_poll_time=config.getfloat("poll_time"), default_exclude_title=config.getboolean("exclude_title")) setup_logging(name="aw-watcher-window", testing=args.testing, verbose=args.verbose, log_stderr=True, log_file=True) client = ActivityWatchClient("aw-watcher-window", testing=args.testing) bucket_id = "{}_{}".format(client.client_name, client.client_hostname) event_type = "currentwindow" client.create_bucket(bucket_id, event_type, queued=True) logger.info("aw-watcher-window started") sleep(1) # wait for server to start with client: heartbeat_loop(client, bucket_id, poll_time=args.poll_time, exclude_title=args.exclude_title)
def heartbeat(bucket_name,start_time,activity): client = ActivityWatchClient("aw-watcher-cli", testing=False) bucket_id = "{}_{}".format(bucket_name, client.hostname) event_type = "cli_ping" client.create_bucket(bucket_id, event_type=event_type) # Asynchronous loop with client: heartbeat_data = {"label": "heartbeat"} now = datetime.now(timezone.utc) heartbeat_event = Event(timestamp=now, data=heartbeat_data) sleeptime = 1 #Sending hearbeat until keyboard interrup second = 1 while(True): # The duration between the heartbeats will be less than pulsetime, so they will get merged. rd = relativedelta.relativedelta (now, start_time) print("Doing: {} for {:02}:{:02}:{:02}".format(activity,rd.hours, rd.minutes, rd.seconds),end="\r") client.heartbeat(bucket_id, heartbeat_event, pulsetime=sleeptime+1, queued=True) # Sleep a second until next heartbeat sleep(sleeptime) # Update timestamp for next heartbeat heartbeat_event.timestamp = datetime.now(timezone.utc) # update now now = heartbeat_event.timestamp second += 1
def main(): # Verify python version is >=3.5 # req_version is 3.5 due to usage of subprocess.run assert_version((3, 5)) if sys.platform.startswith("linux") and ("DISPLAY" not in os.environ or not os.environ["DISPLAY"]): raise Exception("DISPLAY environment variable not set") # Read settings from config config = load_config() args = parse_args(default_poll_time=config.getfloat("poll_time")) setup_logging(name="aw-watcher-window", testing=args.testing, verbose=args.verbose, log_stderr=True, log_file=True) client = ActivityWatchClient("aw-watcher-window", testing=args.testing) bucket_id = "{}_{}".format(client.client_name, client.client_hostname) event_type = "currentwindow" client.create_bucket(bucket_id, event_type, queued=True) logger.info("aw-watcher-window started") sleep(1) # wait for server to start with client: heartbeat_loop(client, bucket_id, poll_time=args.poll_time, exclude_title=args.exclude_title)
def main(): import argparse parser = argparse.ArgumentParser("A watcher for ping") parser.add_argument("--testing", action="store_true") args = parser.parse_args() logging.basicConfig(level=logging.DEBUG if args.testing else logging.INFO) client = ActivityWatchClient("aw-watcher-network", testing=args.testing) bucketname = "{}_{}".format(client.client_name, client.client_hostname) eventtype = "ping" client.create_bucket(bucketname, eventtype) logger.info("Starting to log ping") while True: t = datetime.utcnow() sleeptime = 60 - (t.second + t.microsecond/1000000.0) sleep(sleeptime) timestamp = datetime.now(pytz.utc) wifiname = Wireless().current() try: out = ping(30) client.send_events(bucketname, createEvents(out,timestamp,wifiname)) logger.info("Sent events") except Exception as e: import sys, traceback traceback.print_exc() logger.error("Exception thrown while pinging {}".format(e))
def main(): import argparse parser = argparse.ArgumentParser("A watcher for ping") parser.add_argument("--testing", action="store_true") args = parser.parse_args() logging.basicConfig(level=logging.DEBUG if args.testing else logging.INFO) client = ActivityWatchClient("aw-watcher-network", testing=args.testing) bucketname = "{}_{}".format(client.client_name, client.client_hostname) eventtype = "ping" client.create_bucket(bucketname, eventtype) logger.info("Starting to log ping") while True: t = datetime.utcnow() sleeptime = 60 - (t.second + t.microsecond / 1000000.0) sleep(sleeptime) timestamp = datetime.now(pytz.utc) wifiname = Wireless().current() try: out = ping(30) client.send_events(bucketname, createEvents(out, timestamp, wifiname)) logger.info("Sent events") except Exception as e: import sys, traceback traceback.print_exc() logger.error("Exception thrown while pinging {}".format(e))
def main(): import argparse poll_time = 1.0 parser = argparse.ArgumentParser("A watcher for windows in X11") parser.add_argument("--testing", action="store_true") args = parser.parse_args() logging.basicConfig(level=logging.DEBUG if args.testing else logging.INFO) client = ActivityWatchClient("x11watcher", testing=args.testing) bucketname = "{}_{}".format(client.client_name, client.client_hostname) eventtype = "currentwindow" client.create_bucket(bucketname, eventtype) # get_only_active = True last_window = [] while True: try: # wids = xprop.get_window_ids() active_window_id = xprop.get_active_window_id() if active_window_id == "0x0": print("Failed to find active window, id found was 0x0") sleep(poll_time) continue # Always true, getting all windows currently not supported # if get_only_active: current_window = xprop.get_windows([active_window_id], active_window_id)[0] # else: # current_windows = get_windows(wids, active_window_id) """ if last_windows != current_windows: last_windows = current_windows print("Windows changed") client.send_event(Event(windows=last_windows, timestamp=datetime.now())) print(current_windows) """ if last_window != current_window: last_window = current_window print("Window changed") labels = ["title:" + current_window["name"]] labels.extend( ["class:" + cls for cls in set(current_window["class"])]) client.send_event( bucketname, Event(label=labels, timestamp=datetime.now(pytz.utc))) print(current_window) except Exception as e: logger.error( "Exception thrown while trying to get active window: {}". format(e)) traceback.print_exc(e) sleep(poll_time)
def shutdown(bucket_name,start_time,end_time,activity): client = ActivityWatchClient("aw-watcher-cli", testing=False) bucket_id = "{}_{}".format(bucket_name, client.hostname) event_type = "cli_activity" client.create_bucket(bucket_id, event_type=event_type) shutdown_data = {"label": activity} shutdown_event = Event(timestamp=start_time, data=shutdown_data, duration=(end_time -start_time)) inserted_event = client.insert_event(bucket_id, shutdown_event) rd = relativedelta.relativedelta (end_time, start_time) print("Spent {:02}:{:02}:{:02} doing {}:".format(rd.hours, rd.minutes, rd.seconds,activity))
def windows_watcher_run() -> None: client = ActivityWatchClient("aw-watcher-window", testing=False) bucket_id = "{}_{}".format(client.client_name, client.client_hostname) event_type = "currentwindow" client.create_bucket(bucket_id, event_type, queued=True) sleep(1) # wait for server to start with client: heartbeat_loop(client, bucket_id, poll_time=2.0, exclude_title=False)
def main(): import argparse poll_time = 1.0 parser = argparse.ArgumentParser("A watcher for windows in X11") parser.add_argument("--testing", action="store_true") args = parser.parse_args() logging.basicConfig(level=logging.DEBUG if args.testing else logging.INFO) client = ActivityWatchClient("x11watcher", testing=args.testing) bucketname = "{}_{}".format(client.client_name, client.client_hostname) eventtype = "currentwindow" client.create_bucket(bucketname, eventtype) # get_only_active = True last_window = [] while True: try: # wids = xprop.get_window_ids() active_window_id = xprop.get_active_window_id() if active_window_id == "0x0": print("Failed to find active window, id found was 0x0") sleep(poll_time) continue # Always true, getting all windows currently not supported # if get_only_active: current_window = xprop.get_windows([active_window_id], active_window_id)[0] # else: # current_windows = get_windows(wids, active_window_id) """ if last_windows != current_windows: last_windows = current_windows print("Windows changed") client.send_event(Event(windows=last_windows, timestamp=datetime.now())) print(current_windows) """ if last_window != current_window: last_window = current_window print("Window changed") labels = ["title:" + current_window["name"]] labels.extend(["class:" + cls for cls in set(current_window["class"])]) client.send_event(bucketname, Event(label=labels, timestamp=datetime.now(pytz.utc))) print(current_window) except Exception as e: logger.error("Exception thrown while trying to get active window: {}".format(e)) traceback.print_exc(e) sleep(poll_time)
def setup_client(): logging.info("Setting up client") client = ActivityWatchClient("aw-fake-client", testing=True) client.client_hostname = hostname eventtype = "currentwindow" client.create_bucket(window_bucket_name, eventtype) eventtype = "afkstatus" client.create_bucket(afk_bucket_name, eventtype) client.connect() return client
def main(): import argparse parser = argparse.ArgumentParser( "A watcher for applications with activationPolicy=regular") parser.add_argument("--testing", action="store_true") args = parser.parse_args() logging.basicConfig(level=logging.DEBUG if args.testing else logging.INFO) client = ActivityWatchClient("macoswatcher", testing=args.testing) bucketname = "{}_{}".format(client.client_name, client.client_hostname) eventtype = "currentwindow" client.create_bucket(bucketname, eventtype) last_app = "" last_title = "" info = getInfo() print(info) active_app = getApp(info) active_title = getTitle(info) if (active_title == ""): logger.error( "Title of active window not found. Does the terminal have access to accessibility API? See README for how to give access!" ) while True: try: info = getInfo() active_app = getApp(info) active_title = getTitle(info) if (last_app != active_app or last_title != active_title): last_app = active_app last_title = active_title client.send_event( bucketname, Event(label=[active_app, active_title], timestamp=datetime.now(pytz.utc))) print(active_app + ", " + active_title) except Exception as e: logger.error( "Exception thrown while trying to get active applications {}". format(e)) sleep(0.5)
def end_current_event(start_ts, category, item, end_dt=None): start_dt = datetime.utcfromtimestamp(start_ts) if end_dt is None: end_dt = datetime.utcnow() app.logger.debug('Instantiating client (127.0.0.1:5600)') client = ActivityWatchClient( "aw-watcher-manual-flaskweb", host='127.0.0.1:5600' ) bucket_id = "{}_{}".format("aw-watcher-manual-flaskweb", client.hostname) app.logger.debug('Creating bucket: %s', bucket_id) client.create_bucket(bucket_id, event_type="currentwindow") t = 'manual: %s/%s' % (category, item) evt = Event( timestamp=start_dt, duration=(end_dt - start_dt).total_seconds(), data={'app': t, 'title': t, 'category': category, 'item': item} ) inserted_event = client.insert_event(bucket_id, evt) app.logger.info('Inserted event: %s', inserted_event)
def send_to_activitywatch(events): print("Sending events to ActivityWatch...") hostname = "macos-screentime-test" # NOTE: 'aw-watcher-android' string is only there for aw-webui to detect it as a mobile device bucket = f"aw-watcher-android_aw-import-screentime_{hostname}" aw = ActivityWatchClient(client_name="aw-import-screentime") aw.client_hostname = hostname # buckets = aw.get_buckets() # if bucket in buckets.keys(): # ans = input("Bucket already found, overwrite? (y/N): ") # if ans == "y": # aw.delete_bucket(bucket, force=True) aw.create_bucket(bucket, "currentwindow") aw.send_events(bucket, events)
class CLIWatcher: def __init__(self, bucket, etype, testing=False): self.client = ActivityWatchClient("aw-watcher-cli", testing=testing) self.bucketname = bucket self.etype = etype self.client.create_bucket(self.bucketname, event_type=self.etype) def run(self): logger.info( "aw-watcher-cli started for bucket '%s' containing events of type '%s'" % (self.bucketname, self.etype)) def updateLastEvent(self): logger.info("Updating previous event duration.") try: last = self.client.get_events(bucket_id=self.bucketname, limit=1)[0] except IndexError: logger.info("No previous event found.") return duration = abs((datetime.now(timezone.utc) - last.timestamp).seconds) logger.info( "Previous event '%s' occurred at %s. Duration since: %ss" % (last.data, last.timestamp.strftime("%Y-%m-%d %T%z"), duration)) last.duration = duration self.client.insert_event(self.bucketname, last) def addStringEvent(self, eventString, duration): logger.info("Adding event %s (duration: %s) to bucket %s" % (eventString, duration, self.bucketname)) data = {"label": eventString} event = Event(timestamp=datetime.now(timezone.utc), data=data, duration=duration) inserted_event = self.client.insert_event(self.bucketname, event) assert inserted_event.id is not None
def main(): # Read settings from config config = load_config() args = parse_args( default_poll_time=config.getfloat("poll_time"), default_exclude_title=config.getboolean("exclude_title"), ) if sys.platform.startswith("linux") and ("DISPLAY" not in os.environ or not os.environ["DISPLAY"]): raise Exception("DISPLAY environment variable not set") setup_logging(name="aw-watcher-window", testing=args.testing, verbose=args.verbose, log_stderr=True, log_file=True) if sys.platform == "darwin": from . import macos macos.background_ensure_permissions() client = ActivityWatchClient("aw-watcher-window", testing=args.testing) bucket_id = "{}_{}".format(client.client_name, client.client_hostname) event_type = "currentwindow" client.create_bucket(bucket_id, event_type, queued=True) logger.info("aw-watcher-window started") sleep(1) # wait for server to start with client: heartbeat_loop(client, bucket_id, poll_time=args.poll_time, exclude_title=args.exclude_title)
def setup_client() -> ActivityWatchClient: logger.info("Setting up client") # Default is to run in testing mode, can be run in prod mode if set to exactly 'false' testing = os.getenv("AW_TESTING", "true").lower() not in ["false"] if testing: logger.info( "Using testing parameters (set the env var AW_TESTING to false to run in prod mode)" ) client = ActivityWatchClient(client_name, testing=testing) client.client_hostname = hostname buckets = client.get_buckets() logger.info("Deleting old buckets") buckets_all = [ bucket_afk, bucket_window, bucket_browser_chrome, bucket_browser_firefox, ] if not testing: ans = input( f"Running in prod, are you sure you want to delete all existing buckets?\n{buckets_all}\nAre you sure? (y/N)" ) if ans != "y": print("Exiting") sys.exit(0) for bucket in [ bucket_window, bucket_afk, bucket_browser_chrome, bucket_browser_firefox, ]: if bucket in buckets: client.delete_bucket(bucket, force=True) client.create_bucket(bucket_window, "currentwindow") client.create_bucket(bucket_afk, "afkstatus") client.create_bucket(bucket_browser_chrome, "web.tab.current") client.create_bucket(bucket_browser_firefox, "web.tab.current") client.connect() return client
def test_failqueue(): client_name = "aw-test-client-" + str(randint(0, 10000)) bucket_id = "test-bucket-" + str(randint(0, 10000)) bucket_etype = "test" input("Make sure aw-server isn't running, then press enter > ") client1 = ActivityWatchClient(client_name, testing=True) client1.create_bucket(bucket_id, bucket_etype, queued=True) print("Creating events") events = [create_unique_event() for _ in range(3)] for i, e in enumerate(events): e.timestamp += timedelta(seconds=i) client1.heartbeat(bucket_id, e, pulsetime=1, queued=True) print("Trying to send events (should fail)") with client1: time.sleep(1) input("Start aw-server with --testing, then press enter > ") client2 = ActivityWatchClient(client_name, testing=True) client2.create_bucket(bucket_id, bucket_etype, queued=True) # Here the previously queued events should be sent with client2: time.sleep(1) print("Getting events") recv_events = client2.get_events(bucket_id) print("Asserting latest event") pprint(recv_events) pprint(recv_events[0].data['label']) pprint(events[2].data['label']) assert recv_events[0].data['label'] == events[2].data['label']
now = datetime.now(tz=timezone.utc) # We'll run with testing=True so we don't mess up any production instance. # Make sure you've started aw-server with the `--testing` flag as well. client = ActivityWatchClient("test-client", testing=True) bucket_id = "test-bucket" example_data = {"label": "example"} example_event = Event(timestamp=now, data=example_data) # Asynchronous example with client: # This context manager starts the queue dispatcher thread and stops it when done, always use it when setting queued=True. # First we need a bucket to send events/heartbeats to. client.create_bucket(bucket_id, event_type="test", queued=True) # Now we can send some heartbeats. # The duration between them will be less than pulsetime, so they will get merged. client.heartbeat(bucket_id, example_event, pulsetime=10, queued=True) example_event.timestamp += timedelta(seconds=5) client.heartbeat(bucket_id, example_event, pulsetime=10, queued=True) # Give the dispatcher thread some time to complete sending the events sleep(1) # Synchronous example example_event.timestamp += timedelta(minutes=1) inserted_event = client.insert_event(bucket_id, example_event)
return Event(timestamp=datetime.now(timezone.utc), duration=timedelta(), data={"label": str(random())}) client = ActivityWatchClient("aw-test-client", testing=True) client.connect() bucket_name = "test-bucket" bucket_etype = "test" # Delete bucket before creating it, and handle error if it doesn't already exist try: client.delete_bucket(bucket_name) except HTTPError as e: pass client.create_bucket(bucket_name, bucket_etype) e1 = create_unique_event() client.insert_event(bucket_name, e1) print("Getting events") events = client.get_events(bucket_name) print("Asserting events") assert events[0]['data']['label'] == e1['data']['label'] print("Getting eventcount") eventcount = client.get_eventcount(bucket_name) assert eventcount == 1 print("Getting bucket")
from aw_core.models import Event from aw_client import ActivityWatchClient client = ActivityWatchClient("test-client", testing=True) now = datetime.now(timezone.utc) start = now query = "RETURN=0;" res = client.query(query, "1970-01-01", "2100-01-01") print(res) # Should print 0 bucket_id = "{}_{}".format("test-client-bucket", client.hostname) event_type = "dummydata" client.create_bucket(bucket_id, event_type="test") def insert_events(label: str, count: int): global now events = [] for i in range(count): e = Event(timestamp=now, duration=timedelta(seconds=1), data={"label": label}) events.append(e) now = now + timedelta(seconds=1) client.insert_events(bucket_id, events) insert_events("a", 5) query = "RETURN = query_bucket('{}');".format(bucket_id)
class AfkRunner: def __init__(self, poll_time: int = 5, timeout: int = 180) -> None: self.client = ActivityWatchClient("aw-watcher-afk", testing=False) self.bucketname = "{}_{}".format( self.client.client_name, self.client.client_hostname ) self.poll_time = poll_time self.timeout = timeout self.initiated_shutdown: bool = False def ping(self, afk: bool, timestamp: datetime, duration: float = 0 ) -> None: data = {"status": "afk" if afk else "not-afk"} e = Event(timestamp=timestamp, duration=duration, data=data) pulsetime = self.timeout + self.poll_time self.client.heartbeat( self.bucketname, e, pulsetime=pulsetime, queued=True ) def run(self) -> None: # Initialization sleep(1) eventtype = "afkstatus" self.client.create_bucket(self.bucketname, eventtype, queued=True) with self.client: self.heartbeat_loop() def stop(self) -> None: self.initiated_shutdown = True def heartbeat_loop(self) -> None: afk = False while True: if self.initiated_shutdown: self.initiated_shutdown = False break try: if system() in ["Darwin", "Linux"] and os.getppid() == 1: break now = datetime.now(timezone.utc) seconds_since_input = seconds_since_last_input() last_input = now - timedelta(seconds=seconds_since_input) # If no longer AFK if afk and seconds_since_input < self.timeout: self.ping(afk, timestamp=last_input) afk = False self.ping(afk, timestamp=last_input) # If becomes AFK elif not afk and seconds_since_input >= self.timeout: self.ping(afk, timestamp=last_input) afk = True self.ping( afk, timestamp=last_input, duration=seconds_since_input ) # Send a heartbeat if no state change was made else: if afk: self.ping( afk, timestamp=last_input, duration=seconds_since_input ) else: self.ping(afk, timestamp=last_input) sleep(self.poll_time) except KeyboardInterrupt: break
# print(title) # print(start, duration) # if attendees: # for attendee in attendees: # print(attendee) # print(e) # print(component) # print(80 * "-") return events if __name__ == "__main__": filename = sys.argv.pop() events = load_events(filename) print(f"Loaded {len(events)} events") aw = ActivityWatchClient(testing=True) bucket_name = 'ical-import' if bucket_name in aw.get_buckets(): aw.delete_bucket(bucket_name) aw.create_bucket(bucket_name, 'calendar') aw.insert_events(bucket_name, events) """ Basic query: events = query_bucket(find_bucket('ical-import')); RETURN = filter_keyvals_regex(events, 'title', '\<\>')); """
class MessageHandler: def __init__(self, testing=False, send_commands=True, send_heartbeats=True): # Create client self._client = ActivityWatchClient(client_id, testing=testing) self._client.connect() self._init_buckets() # Settings self.pulsetime = 10 self.send_commands = send_commands self.send_heartbeats = send_heartbeats # Initialize the EventQueue self._event_queue = EventQueue(callback=self._handle_event, time_buffer=(self.pulsetime / 2)) self._event_handlers = { 'preopen': self._preopen, 'preexec': self._preexec, 'precmd': self._precmd, 'preclose': self._preclose } self._terminal_sessions = {} def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self._client.disconnect() def _init_buckets(self): """Set self._buckets and create these buckets if not existing""" self._buckets = { 'commands': { 'id': "{}-commands_{}".format(client_id, self._client.hostname), 'event_type': 'app.terminal.command' }, 'activity': { 'id': "{}-activity_{}".format(client_id, self._client.hostname), 'event_type': 'app.terminal.activity' } } # Create buckets if not existing for key, bucket in self._buckets.items(): logger.debug("Creating bucket: {}".format(bucket['id'])) self._client.create_bucket(bucket['id'], bucket['event_type'], queued=True) def update_event_queue(self): self._event_queue.update() def handle_fifo_message(self, message): for line in message.split('\n'): if not len(line): continue cli_args = shlex.split(line) args, unknown_args = parser_base.parse_known_args(cli_args) # Make sure that events are called in the right order # (based on args.timestamp) by passing it to the event queue # The event queue will trigger the callback when the time_buffer # is exceeded logger.debug("adding event to event_queue: {}".format(cli_args)) self._event_queue.add_event(cli_args, args.timestamp) def _handle_event(self, cli_args): logger.debug("handling event: {}".format(cli_args)) args, unknown_args = parser_base.parse_known_args(cli_args) # Store terminal session if not already existing pid = args.pid if pid not in self._terminal_sessions: self._terminal_sessions[pid] = TerminalSessionData(pid) if self.send_commands: if args.event not in self._event_handlers: logger.error("Unknown event: {}".format(args.event)) else: self._event_handlers[args.event](cli_args) if self.send_heartbeats: self._heartbeat(cli_args) def _preopen(self, cli_args: list) -> None: """Handle terminal creation""" pass def _preexec(self, cli_args: list) -> None: """Send event containing command execution data""" args, unknown_args = parser_preexec.parse_known_args(cli_args) process = self._terminal_sessions[args.pid] event_data = { 'command': args.command, 'path': args.path, 'shell': args.shell, 'exit_code': 'unknown', 'session_id': process.unique_id } process.event = self._insert_event(data=event_data, timestamp=args.timestamp) def _precmd(self, cli_args: list) -> None: """Update the stored event with duration and exit_code""" args, unknown_args = parser_precmd.parse_known_args(cli_args) process = self._terminal_sessions[args.pid] if process.event is None: return event_data = process.event.data # Calculate time delta between preexec and precmd timestamp = process.event.timestamp cur_time = args.timestamp time_delta = cur_time - timestamp event_data['exit_code'] = args.exit_code self._insert_event(data=event_data, id=process.event.id, timestamp=timestamp, duration=time_delta) process.event = None def _preclose(self, args: argparse.Namespace, args_raw: list) -> None: """Remove pid and related data from terminal_processes_data""" args, unknown_args = parser_preclose.parse_known_args(cli_args) self._terminal_sessions.pop(args.pid) def _heartbeat(self, cli_args: list) -> None: """Send heartbeat to activity bucket""" args, unknown_args = parser_heartbeat.parse_known_args(cli_args) process = self._terminal_sessions[args.pid] event_data = { 'session_id': process.unique_id, 'shell': args.shell, 'path': args.path } event = Event(data=event_data, timestamp=args.timestamp) inserted_heartbeat = self._client.heartbeat( self._buckets['activity']['id'], event, pulsetime=self.pulsetime, queued=True) if inserted_heartbeat and inserted_heartbeat.id: logger.debug('Successfully sent heartbeat') def _insert_event(self, *args, **kwargs) -> Event: """Send event to the aw-server""" event = Event(*args, **kwargs) inserted_event = self._client.insert_event( self._buckets['commands']['id'], event) # aw-server assigned the event an id assert inserted_event.id is not None logger.debug("Successfully sent event") return inserted_event
#!/usr/bin/env python3 from datetime import datetime, timezone from aw_core.models import Event from aw_client import ActivityWatchClient # We'll run with testing=True so we don't mess up any production instance. # Make sure you've started aw-server with the `--testing` flag as well. client = ActivityWatchClient("test-client", testing=True) bucket_id = "{}_{}".format("test-client-bucket", client.client_hostname) client.create_bucket(bucket_id, event_type="dummydata") shutdown_data = {"label": "some interesting data"} now = datetime.now(timezone.utc) shutdown_event = Event(timestamp=now, data=shutdown_data) inserted_event = client.insert_event(bucket_id, shutdown_event) events = client.get_events(bucket_id=bucket_id, limit=1) print(events) # Should print a single event in a list client.delete_bucket(bucket_id)
class AFKWatcher: def __init__(self, testing=False): # 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) def ping(self, afk: bool, timestamp: datetime, duration: float = 0): data = {"status": "afk" if afk else "not-afk"} e = Event(timestamp=timestamp, duration=duration, data=data) pulsetime = self.settings.timeout + self.settings.poll_time self.client.heartbeat(self.bucketname, e, pulsetime=pulsetime, queued=True) def run(self): logger.info("aw-watcher-afk started") # Initialization sleep(1) eventtype = "afkstatus" self.client.create_bucket(self.bucketname, eventtype, queued=True) # Start afk checking loop with self.client: self.heartbeat_loop() def heartbeat_loop(self): afk = False while True: try: if system in ["Darwin", "Linux"] and os.getppid() == 1: # TODO: This won't work with PyInstaller which starts a bootloader process which will become the parent. # There is a solution however. # See: https://github.com/ActivityWatch/aw-qt/issues/19#issuecomment-316741125 logger.info( "afkwatcher stopped because parent process died") break now = datetime.now(timezone.utc) seconds_since_input = seconds_since_last_input() last_input = now - timedelta(seconds=seconds_since_input) logger.debug( "Seconds since last input: {}".format(seconds_since_input)) # If no longer AFK if afk and seconds_since_input < self.settings.timeout: logger.info("No longer AFK") self.ping(afk, timestamp=last_input) afk = False self.ping(afk, timestamp=last_input) # If becomes AFK elif not afk and seconds_since_input >= self.settings.timeout: logger.info("Became AFK") self.ping(afk, timestamp=last_input) afk = True self.ping(afk, timestamp=last_input, duration=seconds_since_input) # Send a heartbeat if no state change was made else: if afk: self.ping(afk, timestamp=last_input, duration=seconds_since_input) else: self.ping(afk, timestamp=last_input) sleep(self.settings.poll_time) except KeyboardInterrupt: logger.info("aw-watcher-afk stopped by keyboard interrupt") break
#!/usr/bin/env python3 from datetime import datetime, timezone from aw_core.models import Event from aw_client import ActivityWatchClient # We'll run with testing=True so we don't mess up any production instance. # Make sure you've started aw-server with the `--testing` flag as well. client = ActivityWatchClient("test-client", testing=True) bucket_id = "{}_{}".format("test-client-bucket", client.hostname) client.create_bucket(bucket_id, event_type="dummydata") shutdown_data = {"label": "some interesting data"} now = datetime.now(timezone.utc) shutdown_event = Event(timestamp=now, data=shutdown_data) inserted_event = client.insert_event(bucket_id, shutdown_event) events = client.get_events(bucket_id=bucket_id, limit=1) print(events) # Should print a single event in a list client.delete_bucket(bucket_id)
class AFKWatcher: def __init__(self, testing=False): # 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) def ping(self, afk: bool, timestamp: datetime, duration: float = 0): data = {"status": "afk" if afk else "not-afk"} e = Event(timestamp=timestamp, duration=duration, data=data) pulsetime = self.settings.timeout + self.settings.poll_time self.client.heartbeat(self.bucketname, e, pulsetime=pulsetime, queued=True) def run(self): logger.info("aw-watcher-afk started") # Initialization sleep(1) eventtype = "afkstatus" self.client.create_bucket(self.bucketname, eventtype, queued=True) # Start afk checking loop with self.client: self.heartbeat_loop() def heartbeat_loop(self): afk = False while True: try: if system in ["Darwin", "Linux"] and os.getppid() == 1: # TODO: This won't work with PyInstaller which starts a bootloader process which will become the parent. # There is a solution however. # See: https://github.com/ActivityWatch/aw-qt/issues/19#issuecomment-316741125 logger.info("afkwatcher stopped because parent process died") break now = datetime.now(timezone.utc) seconds_since_input = seconds_since_last_input() last_input = now - timedelta(seconds=seconds_since_input) logger.debug("Seconds since last input: {}".format(seconds_since_input)) # If no longer AFK if afk and seconds_since_input < self.settings.timeout: logger.info("No longer AFK") self.ping(afk, timestamp=last_input) afk = False self.ping(afk, timestamp=last_input) # If becomes AFK elif not afk and seconds_since_input >= self.settings.timeout: logger.info("Became AFK") self.ping(afk, timestamp=last_input) afk = True self.ping(afk, timestamp=last_input, duration=seconds_since_input) # Send a heartbeat if no state change was made else: if afk: self.ping(afk, timestamp=last_input, duration=seconds_since_input) else: self.ping(afk, timestamp=last_input) sleep(self.settings.poll_time) except KeyboardInterrupt: logger.info("aw-watcher-afk stopped by keyboard interrupt") break
# print(title) # print(start, duration) # if attendees: # for attendee in attendees: # print(attendee) # print(e) # print(component) # print(80 * "-") return events if __name__ == "__main__": filename = sys.argv.pop() events = load_events(filename) print(f"Loaded {len(events)} events") aw = ActivityWatchClient(testing=True) bucket_name = "ical-import" if bucket_name in aw.get_buckets(): aw.delete_bucket(bucket_name) aw.create_bucket(bucket_name, "calendar") aw.insert_events(bucket_name, events) """ Basic query: events = query_bucket(find_bucket('ical-import')); RETURN = filter_keyvals_regex(events, 'title', '\<\>')); """
class TableWatcher: def __init__(self, testing=False): config_section = "aw-watcher-table" if not testing else "aw-watcher-table-testing" self.settings = Settings(watcher_config[config_section]) self.client = ActivityWatchClient("aw-watcher-table", testing=testing) self.bucket_id = "{}_{}".format(self.client.client_name, self.client.client_hostname) def run(self): logger.info("aw-watcher-table started") # Initialization sleep(1) self.client.create_bucket(self.bucket_id, event_type='table_state', queued=True) # Start table checking loop with self.client: self.heartbeat_loop() def ping(self, table_height: Optional[int]): event = Event(timestamp=datetime.datetime.now(datetime.timezone.utc), data={"status": self.get_table_status(table_height)}) # 10 seconds request timeout self.client.heartbeat(self.bucket_id, event, pulsetime=self.settings.poll_time + 1 + 10, queued=True) def get_table_height(self) -> Optional[int]: try: r = requests.get(f'http://{self.settings.ip}/measure') return r.json()['table_height'] except Exception as ex: logger.warning( f'aw-watcher-table: Measurement failed! Please make sure http://{self.settings.ip}/measure ' f'delivers a JSON object which includes the field "table_height"' ) return None def get_table_status(self, table_height): return self.settings.get_height_level(table_height) def heartbeat_loop(self): while True: try: table_height = self.get_table_height() if table_height is None: logger.warning( f'aw-watcher-table: table_height corrected from None to -1!' ) table_height = -1 self.ping(table_height) sleep(self.settings.poll_time) except KeyboardInterrupt: logger.info("aw-watcher-table stopped by keyboard interrupt") break