92 lines
3.0 KiB
Python
92 lines
3.0 KiB
Python
import urequests as requests
|
|
|
|
|
|
def url_quote(s):
|
|
safe = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-"
|
|
s = str(s)
|
|
res = bytearray()
|
|
for b in s.encode('utf-8'):
|
|
if b in safe:
|
|
res.append(b)
|
|
else:
|
|
res.extend(b'%' + b'%02X' % b)
|
|
return res.decode()
|
|
|
|
|
|
class TinyWebDB:
|
|
def __init__(self, *args):
|
|
if len(args) == 1:
|
|
self.init_with_mqtt(*args)
|
|
else:
|
|
self.init_with_user(*args)
|
|
|
|
def init_with_user(self, url, username, password):
|
|
self._api_url = ""
|
|
self._username = username
|
|
self._password = password
|
|
self.set_url(url)
|
|
|
|
def init_with_mqtt(self, mqtt_client):
|
|
self._api_url = ""
|
|
url, username, password = mqtt_client.get_server_info()
|
|
self.set_url('https://{}/tinydb'.format(url))
|
|
self._username = username
|
|
self._password = password
|
|
|
|
def update(self, key, value):
|
|
key = url_quote(str(key))
|
|
value = url_quote(str(value))
|
|
result = self._request("update", "tag={}&value={}".format(key, value))
|
|
if "status" in result and result["status"] == "error":
|
|
raise RuntimeError(result["message"])
|
|
|
|
def get(self, key):
|
|
key = url_quote(str(key))
|
|
result = self._request("get", "tag={}".format(key))
|
|
if "status" in result and result["status"] == "error":
|
|
raise RuntimeError(result["message"])
|
|
return result["value"]
|
|
|
|
def count(self):
|
|
result = self._request("count")
|
|
if "status" in result and result["status"] == "error":
|
|
raise RuntimeError(result["message"])
|
|
return int(result["count"])
|
|
|
|
def search(self, no=1, count=1, tag='', dtype='both'):
|
|
no = str(no)
|
|
count = str(count)
|
|
tag = url_quote(tag)
|
|
result = self._request("search", "no={}&count={}&tag={}&type={}".format(no, count, tag, dtype))
|
|
if "status" in result and result["status"] == "error":
|
|
raise RuntimeError(result["message"])
|
|
return result["data"]
|
|
|
|
def delete(self, key):
|
|
key = url_quote(str(key))
|
|
result = self._request("delete", "tag={}".format(key))
|
|
if "status" in result and result["status"] == "error":
|
|
raise RuntimeError(result["message"])
|
|
|
|
def set_url(self, url):
|
|
if url[-1] != '/':
|
|
url += '/'
|
|
self._api_url = url
|
|
|
|
def _request(self, op, param=""):
|
|
data = "user={}&secret={}&action={}".format(self._username, self._password, op)
|
|
if param:
|
|
data += '&' + param
|
|
try:
|
|
headers = {
|
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
}
|
|
response = requests.post(self._api_url, data=data, headers=headers)
|
|
result = {}
|
|
if response.status_code == 200:
|
|
result = response.json()
|
|
response.close()
|
|
return result
|
|
except Exception as e:
|
|
raise RuntimeError("API request failed or WiFi is not connected", e)
|