homeassistant-addons/screenshotter/rootfs/app/app.py

102 lines
4.4 KiB
Python

from seleniumwire import webdriver
from selenium.webdriver import ChromeOptions
from selenium.webdriver import DesiredCapabilities
from PIL import Image
import time, os
import yaml
import datetime
import croniter
import logging
logging.basicConfig(format='%(asctime)s [%(levelname)s]:%(message)s', level=logging.DEBUG)
image_path = os.environ.get("SCREEN_IMAGE_PATH", default='/tmp')
config_file = os.environ.get("SCREEN_CONFIG", default="/app/config.yaml")
width = os.environ.get("SCREEN_WIDTH", default="640")
height = os.environ.get("SCREEN_HEIGHT", default="480")
rotate = os.environ.get("SCREEN_ROTATE", default="0")
wait = os.environ.get("SCREEN_WAIT", default="5")
ha_url = os.environ.get("SCREEN_HA_URL", default="")
ha_token = os.environ.get("SCREEN_HA_TOKEN", default="")
ha_language = os.environ.get("SCREEN_HA_LANGUAGE", default="en")
# enable browser logging
d = DesiredCapabilities.CHROME
d['loggingPrefs'] = {'browser': 'ALL'}
# Open another headless browser with height extracted above
chrome_options = ChromeOptions()
chrome_options.add_argument("--headless")
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument(f"--window-size={width},{height}")
chrome_options.add_argument(f"--lang={ha_language}")
chrome_options.add_argument("--hide-scrollbars")
chrome_options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, '
'like Gecko) Chrome/68.0.3440.84 Safari/537.36')
chrome_options.add_experimental_option('prefs', {'intl.accept_languages': ha_language})
while True:
config_file_modified_start = os.path.getmtime(config_file)
logging.info(f"Reading config file {config_file}")
config = None
with open(config_file, "r") as stream:
config = yaml.safe_load(stream)
tasks = []
for image in config["images"]:
now = datetime.datetime.now()
image["croniter"] = croniter.croniter(image["cron"], now)
image["next_execution"] = image["croniter"].get_next(datetime.datetime)
logging.info(f"First execution of {image['name']} at {image['next_execution']}.")
tasks += [image]
while True:
for i, task in enumerate(tasks):
if task["next_execution"] > datetime.datetime.now():
continue
logging.info(f"Running {task['name']}")
driver = webdriver.Chrome(options=chrome_options, desired_capabilities=d)
driver.implicitly_wait(10)
if task.get("ha_auth"):
#def interceptor(request):
# if request.headers['Authorization']:
# del request.headers['Authorization'] # Remember to delete the header first
# request.headers['Authorization'] = f"Bearer {ha_token}" # Spoof the referer
#driver.request_interceptor = interceptor
def response_interceptor(req, response):
response.headers['Access-Control-Allow-Origin'] = '*'
driver.response_interceptor = response_interceptor
driver.get("http://172.30.32.1:8123")
time.sleep(int(wait))
logging.info("Doing HA Auth")
driver.execute_script(f"window.localStorage.setItem('hassTokens', JSON.stringify({{hassUrl: '{ha_url}', access_token: '{ha_token}', token_type: 'Bearer'}}));")
driver.get(task["url"])
time.sleep(int(wait))
logging.info("Making screenshot")
# save screenshot
file_name = f'/tmp/{task["name"]}.png'
driver.save_screenshot(file_name)
# print messages
browser_out = ""
for entry in driver.get_log('browser'):
browser_out += f"{entry}\n"
logging.info(browser_out)
image = Image.open(file_name)
image = image.rotate(int(rotate), expand=True)
file_name = f'{image_path}/{task["name"]}.png'
image.save(file_name)
tasks[i]["next_execution"] = task["croniter"].get_next(datetime.datetime)
logging.info(f"Task finished, next execution: {tasks[i]['next_execution']}")
config_file_modified = os.path.getmtime(config_file)
if config_file_modified != config_file_modified_start:
logging.info("reloading config file")
break
time.sleep(1)