#!/usr/bin/python3 import ssl import json import xml.etree.ElementTree as ET from urllib.request import urlopen, Request from urllib.parse import urljoin from urllib.error import HTTPError def get_context(verify): ctx = None if not verify: ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE return ctx def get_apikey(configfile="/root/.config/syncthing/config.xml"): try: tree = ET.parse(configfile) root = tree.getroot() apikey = root.find("./gui/apikey").text return apikey except (FileNotFoundError, ET.ParseError, AttributeError) as exc: raise f"Exception {exc} occured" return None def get_config(url="http://localhost:8384", verify=False, apikey=get_apikey()): fullurl = f"{url}/rest/config" req = Request(method="GET", url=fullurl) req.add_header("X-API-Key", apikey) res = urlopen(req, context=get_context(verify)) ret = json.loads(res.read()) if res.status == 200: return ret return None def set_config_options(url="http://localhost:8384", verify=False, apikey=get_apikey(), options={}): fullurl = f"{url}/rest/config/options" req = Request(method="PUT", url=fullurl, data=json.dumps(options).encode()) req.add_header("Content-Type", "application/json") req.add_header("X-API-Key", apikey) try: res = urlopen(req, context=get_context(verify)) except HTTPError as err: if err.status != 307: return False req.full_url = urljoin(url, err.headers['Location']) res = urlopen(req, context=get_context(verify)) if res.status == 200: return True return None def set_config_gui(url="http://localhost:8384", verify=False, apikey=get_apikey(), gui={}): fullurl = f"{url}/rest/config/gui" req = Request(method="PUT", url=fullurl, data=json.dumps(gui).encode()) req.add_header("Content-Type", "application/json") req.add_header("X-API-Key", apikey) try: res = urlopen(req, context=get_context(verify)) except HTTPError as err: if err.status != 307: return False req.full_url = urljoin(url, err.headers['Location']) res = urlopen(req, context=get_context(verify)) except http.client.RemoteDisconnected as err: return True if res.status == 200: return True return None ## deprecated def _set_config(url="http://localhost:8384", verify=False, apikey=get_apikey(), config={}): fullurl = f"{url}/rest/config" req = Request(method="POST", url=fullurl, data=json.dumps(config).encode()) req.add_header("Content-Type", "application/json") req.add_header("X-API-Key", apikey) try: res = urlopen(req, context=get_context(verify)) except HTTPError as err: if err.status != 307: return None req.full_url = urljoin(url, err.headers['Location']) res = urlopen(req, context=get_context(verify)) if res.status == 200: return True return None def insync(url="http://localhost:8384", verify=False, apikey=get_apikey()): fullurl = f"{url}/rest/config/restart-required" req = Request(method="GET", url=fullurl) req.add_header("X-API-Key", apikey) res = urlopen(req, context=get_context(verify)) ret = json.loads(res.read()) if res.status == 200: return ret return None def restart(url="http://localhost:8384", verify=False, apikey=get_apikey()): fullurl = f"{url}/rest/system/restart" req = Request(method="POST", url=fullurl) req.add_header("X-API-Key", apikey) res = urlopen(req, context=get_context(verify)) if res.status == 200: return {} return None