Small changes and Snap Frame addition.

Snap allows for the retrieval of a single frame from the current Camera video stream.
PEP8 standard implemented.
This commit is contained in:
Alano Terblanche
2019-08-10 21:47:57 +02:00
parent 28a361b44d
commit e7cdd19dfe
8 changed files with 97 additions and 5 deletions

2
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml

11
.idea/ReolinkCameraAPI.iml generated Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ReolinkCameraAPI.iml" filepath="$PROJECT_DIR$/.idea/ReolinkCameraAPI.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -1,26 +1,46 @@
import io
import json import json
import random
import string
from urllib.request import urlopen
from PIL import Image
from resthandle import Request from resthandle import Request
class APIHandler: 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.url = "http://" + ip + "/cgi-bin/api.cgi"
self.token = None self.token = None
self.username = username
self.password = password
# Token # Token
def login(self, username: str, password: str): def login(self):
""" """
Get login token Get login token
Must be called first, before any other operation can be performed Must be called first, before any other operation can be performed
:param username:
:param password:
:return: :return:
""" """
try: 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"} param = {"cmd": "Login", "token": "null"}
response = Request.post(self.url, data=body, params=param) response = Request.post(self.url, data=body, params=param)
if response is not None: if response is not None:
@@ -176,3 +196,30 @@ class APIHandler:
except Exception as e: except Exception as e:
print("Could not get General System settings\n", e) print("Could not get General System settings\n", e)
raise 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