def create_output( self, rtmp_id: int, server_url: str, shared_key: str, title: str, audio: int = 0, stream_type: Literal["rtmp", "mpegts"] = "rtmp", ) -> DeviceOutputStatus: self._check_auth() r = self.client.post( "en/out_rtmp_rtmp/ajaj", data={ "cmd": "add", "rtmp_id": rtmp_id, "oid": 0, "sign": self.form_sign, "server_url": server_url, "shared_key": shared_key, "descr": title, "type": stream_type, "audio": audio, "server": "auto", }, headers=AJAX_HEADERS, ) if r.text == "No auth": raise AuthError data = DeviceOutputStatus.parse_raw(r.content) logger.debug(f"Updated device output: {data}") return data
def update_output( self, rtmp_id: str, output_id: str, server_url: str, shared_key: str, title: str, audio: int = 0, ) -> DeviceOutput: self._check_auth() r = self.client.post( "en/out_rtmp_rtmp/ajaj", data={ "cmd": "update", "rtmp_id": rtmp_id, "oid": output_id, "sign": self.form_sign, "server_url": server_url, "shared_key": shared_key, "title": title, "audio": audio, "server": "auto", }, headers=AJAX_HEADERS, ) data = DeviceOutput.parse_raw(r.content) logger.debug(f"Updated device output: {data}") return data
def get_available_servers(self, rtmp_id: int) -> AvailableServers: self._check_auth() r = self.client.post("en/rtmp_server?mode=", data={"rtmp_id": rtmp_id}) match = re.search(r"var servers = '(\[.*\])';", r.text) if match: data = AvailableServers.parse_raw(match.group(1)) logger.debug(f"Got next servers list {data}") return data raise FacecastAPIError("Failed to get available servers")
def get_device(self, rtmp_id: int) -> DeviceInfo: self._check_auth() r = self.client.post( "en/rtmp", data={"action": "get_info"}, params={"rtmp_id": rtmp_id}, headers=AJAX_HEADERS, ) if r.url and r.url.path == "/en/main": raise DeviceNotFound(f"{rtmp_id} isn't available") data = DeviceInfo.parse_raw(r.content) logger.debug(f"Got device: {data}") return data
def delete_output(self, rtmp_id: int, oid: int) -> DeviceOutputStatus: self._check_auth() r = self.client.post( "en/out_rtmp_rtmp/ajaj", data={ "cmd": "delete", "sign": self.form_sign, "oid": oid, "rtmp_id": rtmp_id, }, headers=AJAX_HEADERS, ) data = DeviceOutputStatus.parse_raw(r.content) logger.debug(f"Deleted device output: {data}") return data
def get_outputs(self, rtmp_id: int) -> DeviceOutputs: self._check_auth() r = self.client.post( "en/rtmp_outputs/ajaj", data={ "cmd": "getlist", "rtmp_id": rtmp_id, "sign": self.form_sign }, params={"rtmp_id": rtmp_id}, headers=AJAX_HEADERS, ) data = DeviceOutputs.parse_raw(r.content) logger.debug(f"Got device outputs: {data}") return data
def delete_device(self, rtmp_id: int) -> bool: self._check_auth() r = self.client.post( "en/rtmp_popup_menu/ajaj", data={ "cmd": "delete_rtmp_source", "sign": self.form_sign, "rtmp_id": rtmp_id, }, ) if r.status_code == 200: logger.debug(f"Device {rtmp_id} was deleted") return True logger.debug(f"Device {rtmp_id} was not deleted") return False
def get_devices(self) -> BaseDevices: self._check_auth() r = self.client.get("en/main") d = pq(r.text) devices = d(".sb-streamboxes-main-list a") devices_names = devices.find(".sb-streambox-item-name") if devices_names: logger.debug( f"Got devices with following names: {[d.text for d in devices_names]}" ) else: logger.debug("No devices") return BaseDevices.parse_obj( BaseDevice( rtmp_id=device.attrib["href"].split("=")[1], name=device_name.text, ) for device, device_name in zip(devices, devices_names))
def select_server(self, rtmp_id: int, server_id: int) -> bool: self._check_auth() r = self.client.post( "en/rtmp_server/ajaj", data={ "cmd": "set_server", "sign": self.form_sign, "rtmp_id": rtmp_id, "server_id": server_id, }, params={"rtmp_id": rtmp_id}, headers=AJAX_HEADERS, ) data = BaseResponse.parse_raw(r.content) if data.ok: logger.debug(f"Server {server_id} selected for {rtmp_id}") return True raise FacecastAPIError(f"Failed to select server {rtmp_id} - {data}")
def get_status(self, rtmp_id: int) -> DeviceStatusFull: self._check_auth() r = self.client.post( "en/rtmp/ajaj", data={ "sign": self.form_sign, "requests[0][cmd]": "get_status", "requests[0][sign]": self.form_sign, "requests[1][cmd]": "input_status", "requests[1][sign]": self.form_sign, "requests[2][cmd]": "output_status", "requests[2][sign]": self.form_sign, "rtmp_id": rtmp_id, }, params={"rtmp_id": rtmp_id}, headers=AJAX_HEADERS, ) data = DeviceStatusFull.parse_raw(r.content) logger.debug(f"Got device status: {data}") return data
def do_auth(self, username: str, password: str) -> bool: r = self.client.get("en/main") if r.url == "en/main": self.is_authorized = True return True signature = self._fetch_signature(r.text) r = self.client.post( "en/login", params={"mode": "ajaj"}, data={ "login": username, "pass": password, "signature": signature }, headers=AJAX_HEADERS, ) if r.status_code == 200 and r.json().get("ok"): # type: ignore self.is_authorized = True self._update_from_sign() logger.debug("Auth successful") return True self.is_authorized = False raise AuthError("AuthService error")
def create_device(self, name: str, stream_type: Literal["rtmp"] = "rtmp") -> bool: self._check_auth() r = self.client.post( "en/main_add/ajaj", data={ "cmd": "add_restreamer", "sbin": 0, "sign": self.form_sign, "type": stream_type, "title": name, }, ) data = BaseResponse.parse_raw(r.content) if not data.ok: raise DeviceNotCreated(f"{name} wasn't created") if r.status_code == 200: logger.debug(f"Device {name} was created") return True logger.debug(f"Device {name} was not created") return False