This commit is contained in:
Antonio J. Delgado 2025-01-06 22:20:20 +02:00
parent ae1381c4b7
commit 34166d0ccf
2 changed files with 122 additions and 3 deletions

View file

@ -9,8 +9,15 @@ import sys
import os import os
import logging import logging
from logging.handlers import SysLogHandler from logging.handlers import SysLogHandler
import subprocess
import re
import json
import time
from datetime import datetime, timezone
import socket
import click import click
import click_config_file import click_config_file
import requests
class PublishActiveWindows: class PublishActiveWindows:
@ -30,6 +37,101 @@ class PublishActiveWindows:
'publish_active_windows.log' 'publish_active_windows.log'
) )
self._init_log() self._init_log()
self.session = requests.Session()
hostname = socket.gethostname()
while True:
windows = self._get_windows_list()
self._log.debug(
json.dumps(windows, indent=2)
)
self._log.debug(
'Sleeping %s seconds',
self.config['update_frequency']
)
for window in windows:
command_line = self._get_process_command_line(window['pid'])
if window['title']:
state = window['title']
else:
state = command_line
share_attributes = {
"command_line": command_line,
"hostname": hostname
}
window['pid'] = f"{window['pid']}"
window['id'] = f"{window['id']}"
window['maximized'] = f"{window['maximized']}"
attributes = {**share_attributes, **window}
if window['focus']:
entity_id = f'sensor.{hostname}_active_window'
attributes['focus'] = 'True'
else:
entity_id = f'sensor.{hostname}_open_window'
attributes['focus'] = 'False'
if not self._publish_state(entity_id=entity_id, state=state, attributes=attributes):
sys.exit(1)
time.sleep(self.config['update_frequency'])
def _get_process_command_line(self, process_id):
with open(f"/proc/{process_id}/cmdline", 'r', encoding='utf-8') as cmdline_file:
raw_cmdline = cmdline_file.read()
return ' '.join(raw_cmdline.split('\0')).strip()
return None
def _publish_state(self, entity_id, state, attributes):
now = datetime.now(timezone.utc)
data = {
"state": state,
"attributes": attributes,
"last_changed": now.strftime("%Y-%m-%dT%H:%M:%S.%f+00:00"),
"last_updated": now.strftime("%Y-%m-%dT%H:%M:%S.%f+00:00")
}
headers = {
"Authorization": f"Bearer {self.config['ha_token']}",
"Content-Type": "application/json"
}
uri = f"{self.config['ha_url']}/api/states/{entity_id}"
self._log.debug(
"Publishing data to HomeAssistant in '%s'. Headers: %s. Data: '%s",
uri,
headers,
json.dumps(data, indent=2)
)
result = self.session.post(
uri,
json=data,
headers=headers
)
if result.status_code > 399:
self._log.error(
"Result: %s. %s. %s",
result.status_code,
result.reason,
result.text
)
return None
self._log.debug(
"Result: %s. %s. %s",
result.status_code,
result.reason,
result.text
)
return result.json
def _get_windows_list(self):
command = [
'gdbus',
'call',
'--session',
'--dest',
'org.gnome.Shell',
'--object-path',
'/org/gnome/Shell/Extensions/WindowsExt',
'--method',
'org.gnome.Shell.Extensions.WindowsExt.List'
]
result = subprocess.run(command, capture_output=True, check=True)
return json.loads(re.sub(b"',\\)$", b'', re.sub(b"^\\('", b'', result.stdout)))
def _init_log(self): def _init_log(self):
''' Initialize log object ''' ''' Initialize log object '''
@ -83,8 +185,24 @@ class PublishActiveWindows:
help='Set the debug level for the standard output.' help='Set the debug level for the standard output.'
) )
@click.option('--log-file', '-l', help="File to store all debug messages.") @click.option('--log-file', '-l', help="File to store all debug messages.")
# @click.option("--dummy","-n", is_flag=True, @click.option(
# help="Don't do anything, just show what would be done.") '--ha-token',
'-t',
required=True,
help='Token to talk with HomeAssistant'
)
@click.option(
'--ha-url',
'-u',
required=True,
help='HomeAssistant URL'
)
@click.option(
'--update-frequency',
'-f',
default=60,
help='Frequency in seconds to update HomeAssistant status'
)
@click_config_file.configuration_option() @click_config_file.configuration_option()
def __main__(**kwargs): def __main__(**kwargs):
return PublishActiveWindows(**kwargs) return PublishActiveWindows(**kwargs)

View file

@ -1,2 +1,3 @@
click click
click_config_file click_config_file
requests