From e7cdd19dfef1934899b0312d602737af0124cbea Mon Sep 17 00:00:00 2001 From: Alano Terblanche Date: Sat, 10 Aug 2019 21:47:57 +0200 Subject: [PATCH] Small changes and Snap Frame addition. Snap allows for the retrieval of a single frame from the current Camera video stream. PEP8 standard implemented. --- .idea/.gitignore | 2 + .idea/ReolinkCameraAPI.iml | 11 ++++ .idea/codeStyles/codeStyleConfig.xml | 5 ++ .../inspectionProfiles/profiles_settings.xml | 6 ++ .idea/misc.xml | 7 +++ .idea/modules.xml | 8 +++ .idea/vcs.xml | 6 ++ APIHandler.py | 57 +++++++++++++++++-- 8 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/ReolinkCameraAPI.iml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..5c98b42 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml \ No newline at end of file diff --git a/.idea/ReolinkCameraAPI.iml b/.idea/ReolinkCameraAPI.iml new file mode 100644 index 0000000..6711606 --- /dev/null +++ b/.idea/ReolinkCameraAPI.iml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..3999087 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..8125795 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/APIHandler.py b/APIHandler.py index 2653081..33f5472 100644 --- a/APIHandler.py +++ b/APIHandler.py @@ -1,26 +1,46 @@ +import io import json +import random +import string +from urllib.request import urlopen + +from PIL import Image from resthandle import Request class APIHandler: + """ + The APIHandler class is the backend part of the API. + This handles communication directly with the camera. - def __init__(self, ip): + All Code will try to follow the PEP 8 standard as described here: https://www.python.org/dev/peps/pep-0008/ + + """ + + def __init__(self, ip: str, username: str, password: str): + """ + Initialise the Camera API Handler (maps api calls into python) + :param ip: + :param username: + :param password: + """ self.url = "http://" + ip + "/cgi-bin/api.cgi" self.token = None + self.username = username + self.password = password # Token - def login(self, username: str, password: str): + def login(self): """ Get login token Must be called first, before any other operation can be performed - :param username: - :param password: :return: """ try: - body = [{"cmd": "Login", "action": 0, "param": {"User": {"userName": username, "password": password}}}] + body = [{"cmd": "Login", "action": 0, + "param": {"User": {"userName": self.username, "password": self.password}}}] param = {"cmd": "Login", "token": "null"} response = Request.post(self.url, data=body, params=param) if response is not None: @@ -176,3 +196,30 @@ class APIHandler: except Exception as e: print("Could not get General System settings\n", e) raise + + ########## + # Image Data + ########## + def get_snap(self, timeout=3) -> Image or None: + """ + Gets a "snap" of the current camera video data and returns a Pillow Image or None + :param timeout: + :return: + """ + try: + randomstr = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10)) + snap = "?cmd=Snap&channel=0&rs=" \ + + randomstr \ + + "&user=" + self.username \ + + "&password=" + self.password + reader = urlopen(self.url + snap, timeout) + if reader.status == 200: + b = bytearray(reader.read()) + return Image.open(io.BytesIO(b)) + print("Could not retrieve data from camera successfully. Status:", reader.status) + return None + + except Exception as e: + print("Could not get Image data\n", e) + raise +