8000 Refactor API by previ · Pull Request #166 · CoderBotOrg/backend · GitHub
[go: up one dir, main page]

Skip to content
8000

Refactor API #166

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 114 commits into from
Oct 23, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
d4b7eee
wip #164
Aug 21, 2022
c582ee1
wip #164
previ Aug 21, 2022
24ab82a
wip #164
previ Aug 22, 2022
157a5a2
wip #164
previ Aug 22, 2022
739aeec
wip #164
previ Aug 22, 2022
191df8b
wip #164
previ Aug 22, 2022
80f26cb
merge remove_old_ui
previ Aug 22, 2022
caa85dc
merge remove_old_ui
previ Aug 22, 2022
d677736
merge remove_old_ui
previ Aug 24, 2022
06f61b2
fix merge
previ Aug 24, 2022
834f96d
wip #164
previ Sep 2, 2022
5a24396
wip #164
previ Sep 10, 2022
aa262c3
wip #164
previ Sep 10, 2022
1a556fe
wip #164
previ Sep 10, 2022
9dd82d6
wip #164
previ Sep 12, 2022
7b13eb7
wip #164
previ Sep 18, 2022
4c2649b
wip #164 10000
previ Sep 18, 2022
f12fcfc
Merge branch 'refactor_api_v3' of https://github.com/CoderBotOrg/back…
previ Sep 18, 2022
6e3c210
wip #164
previ Sep 18, 2022
f045ae9
wip #164
previ Sep 18, 2022
84b1f40
wip #164
previ Sep 18, 2022
9806fe4
wip #164
previ Sep 18, 2022
a4eb24c
wip #164
previ Sep 21, 2022
1a799d8
wip #164
previ Sep 23, 2022
78ca38f
wip #164
previ Sep 23, 2022
a4a75de
wip #164
previ Sep 24, 2022
8be5af0
wip #164
previ Sep 24, 2022
de56046
wip #164
previ Sep 24, 2022
8917d89
wip #164
previ Sep 24, 2022
0ed383a
wip #164
previ Sep 24, 2022
ef3b307
wip #164
previ Sep 24, 2022
564be4f
wip #164
previ Sep 24, 2022
374c760
wip #164
previ Sep 24, 2022
58a343b
wip #164
previ Sep 24, 2022
b3ffdb5
wip #164
previ Sep 24, 2022
8cd3942
wip #164
previ Sep 24, 2022
f07bde3
wip #164
previ Sep 24, 2022
e1dbba1
wip #164
previ Sep 24, 2022
b052a1c
wip #164
previ Sep 24, 2022
d2cc499
wip #164
previ Sep 30, 2022
3858e87
wip #164
previ Sep 30, 2022
cc41784
wip #164
previ Oct 1, 2022
f45fe0b
wip #164
previ Oct 1, 2022
f48f454
wip #164
previ Oct 1, 2022
651ed1d
wip #164
previ Oct 3, 2022
552c04c
wip #164
previ Oct 3, 2022
154212b
wip #164
previ Oct 3, 2022
d78b12d
wip #164
previ Oct 3, 2022
0d0328a
wip #164
previ Oct 3, 2022
714b5da
wip #164
previ Oct 3, 2022
f2afc19
wip #164
previ Oct 3, 2022
81c2053
wip #164
previ Oct 4, 2022
537c16d
wip #164
previ Oct 4, 2022
76bc708
wip #164
previ Oct 4, 2022
caa98d0
wip #164
previ Oct 4, 2022
0f61760
wip #164
previ Oct 4, 2022
bb6ad58
wip #164
previ Oct 4, 2022
19d44bb
wip #164
previ Oct 5, 2022
77dad87
wip #164
previ Oct 6, 2022
7387537
wip #164
previ Oct 15, 2022
49622f5
wip #164
previ Oct 15, 2022
27a029f
wip #164
previ Oct 15, 2022
000d819
wip #164
previ Oct 15, 2022
3df1918
wip #164
previ Oct 15, 2022
17d0d29
WIP #164
previ Oct 15, 2022
a4d8a8b
wip #164
previ Oct 15, 2022
140c0b0
wip #164
previ Oct 15, 2022
0aa6635
wip #164
previ Oct 15, 2022
34ca5b3
wip #164
previ Oct 15, 2022
05e6c99
wip #164
previ Oct 15, 2022
a7c0c48
wip #164
previ Oct 15, 2022
cc244bd
wip #164
previ Oct 15, 2022
a5ac40a
wip #164
previ Oct 15, 2022
deb3d4e
wip #164
previ Oct 15, 2022
2b4ed11
wip #164
previ Oct 15, 2022
b563297
wip #164
previ Oct 15, 2022
9004cf6
wip #164
previ Oct 15, 2022
0996b71
wip #164
previ Oct 16, 2022
72c5c7f
wip #164
previ Oct 16, 2022
afb3e20
wip #164
previ Oct 16, 2022
7245366
wip #164
previ Oct 16, 2022
a4bf5b3
wip #164
previ Oct 16, 2022
ac0942a
wip #164
previ Oct 16, 2022
ba569d7
wop #164
previ Oct 16, 2022
9ea27ee
wip #164
previ Oct 16, 2022
4880941
wip #164
previ Oct 16, 2022
29f6cf6
wip #164
previ Oct 16, 2022
0dc2b2c
wip #164
previ Oct 16, 2022
de2a878
wip #164
previ Oct 16, 2022
748ebba
wip #164
previ Oct 16, 2022
b2b1366
wip #184
previ Oct 16, 2022
2515002
wip #164
previ Oct 16, 2022
2b8d45f
wip #164
previ Oct 16, 2022
4ae5f95
wip #164
previ Oct 16, 2022
89e3e66
wip #164
previ Oct 16, 2022
e4899ae
wip #164
previ Oct 16, 2022
f44ece9
wip #164
previ Oct 18, 2022
454bc27
wip #164
previ Oct 18, 2022
a1688fd
wip #164
previ Oct 18, 2022
893e925
wip #164
previ Oct 18, 2022
ce29c09
wip #164
previ Oct 18, 2022
c3ef5a5
wip #164
previ Oct 18, 2022
1a9a095
wip #164
previ Oct 18, 2022
3462482
wip #164
previ Oct 18, 2022
e812592
wip #164
previ Oct 18, 2022
35913cf
wip #164
previ Oct 18, 2022
561d1fe
wip #164
previ Oct 18, 2022
c32d4ba
wip #164
previ Oct 22, 2022
cd07d87
wip #164
previ Oct 22, 2022
1f72632
wip #164
previ Oct 22, 2022
019e7a4
wip #164
previ Oct 22, 2022
63854d7
wip #164
previ Oct 23, 2022
4fb2dbf
wip #164
previ Oct 23, 2022
cccf500
wip #164
previ Oct 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
8000
  •  
  •  
  •  
10 changes: 5 additions & 5 deletions activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def __init__(self):
self.query = Query()

def load(self, name, default):
if name:
if name and default is None:
return self.activities.search(self.query.name == name)[0]
elif default is not None:
default_Activities = self.activities.search(self.query.default == True)
Expand All @@ -26,16 +26,16 @@ def load(self, name, default):
else:
return None

def save(self, activity):
if self.activities.search(self.query.name == activity["name"]) == []:
def save(self, name, activity):
if self.activities.search(self.query.name == name) == []:
self.activities.insert(activity)
else:
if activity.get("default", False) == True:
self.activities.update({'default': False})
self.activities.update(activity, self.query.name == activity["name"])

def delete(self, activity):
activity = self.activities.search(self.query.name == activity["name"])[0]
def delete(self, name):
activity = self.activities.search(self.query.name == name)[0]
if activity.get("default", False) == True:
self.activities.update({'default': True}, self.query.stock == True)
self.activities.remove(self.query.name == activity["name"])
Expand Down
237 changes: 210 additions & 27 deletions api.py
8000 F438 10000
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,23 @@
import subprocess
import json
import logging
import connexion
import pigpio
from werkzeug.datastructures import Headers
from flask import (request,
send_file,
Response,
jsonify)
from cachetools import cached, TTLCache
from coderbot import CoderBot
from program import ProgramEngine, Program
from config import Config
from activity import Activities
from coderbotTestUnit import run_test as runCoderbotTestUnit
from camera import Camera
from cnn_manager import CNNManager
from musicPackages import MusicPackageManager
from audio import Audio
from event import EventManager
from audioControls import AudioCtrl
from coderbotTestUnit import run_test as runCoderbotTestUnit

BUTTON_PIN = 16

Expand Down Expand Up @@ -115,11 +122,11 @@ def stop():
bot.stop()
return 200

def move(data):
def move(body):
try:
bot.move(speed=data["speed"], elapse=data["elapse"], distance=data["distance"])
bot.move(speed=body["speed"], elapse=body["elapse"], distance=body["distance"])
except Exception as e:
bot.move(speed=data["speed"], elapse=data["elapse"], distance=0)
bot.move(speed=body["speed"], elapse=body["elapse"], distance=0)
return 200

def turn(data):
Expand All @@ -129,10 +136,99 @@ def turn(data):
bot.turn(speed=data["speed"], elapse=-1)
return 200

def exec(data):
program = prog_engine.create(data["name"], data["code"])
options = data["options"]
return json.dumps(program.execute(options))
def takePhoto():
try:
cam.photo_take()
audio.say(app.bot_config.get("sound_shutter"))
except Exception:
logging.warning("Camera not present")

def recVideo():
try:
cam.video_rec()
audio.say(app.bot_config.get("sound_shutter"))
except Exception:
logging.warning("Camera not present")

def stopVideo():
try:
cam.video_stop()
audio.say(app.bot_config.get("sound_shutter"))
except Exception:
logging.warning("Camera not present")

def speak():
logging.info("say: " + str(param1) + " in: " + str(get_locale()))
audio.say(param1, get_locale())

def halt():
logging.info("shutting down")
audio.say(app.bot_config.get("sound_stop"))
bot.halt()

def restart():
logging.info("restarting bot")
bot.restart()

def reboot():
logging.info("rebooting")
bot.reboot()

def video_stream(a_cam):
while True:
frame = a_cam.get_image_jpeg()
yield ("--BOUNDARYSTRING\r\n" +
"Content-type: image/jpeg\r\n" +
"Content-Length: " + str(len(frame)) + "\r\n\r\n")
yield frame
yield "\r\n"

def streamVideo():
try:
cam = Camera.get_instance()
h = Headers()
h.add('Age', 0)
h.add('Cache-Control', 'no-cache, private')
h.add('Pragma', 'no-cache')
return Response(video_stream(cam), headers=h, mimetype="multipart/x-mixed-replace; boundary=--BOUNDARYSTRING")
except Exception:
pass

def listPhotos():
"""
Expose the list of taken photos
"""
cam = Camera.get_instance()
return json.dumps(cam.get_photo_list())

def getPhoto(filename):
cam = Camera.get_instance()
mimetype = {'jpg': 'image/jpeg', 'mp4': 'video/mp4'}
try:
media_file = cam.get_photo_file(filename)
return send_file(media_file, mimetype=mimetype.get(filename[:-3], 'image/jpeg'), cache_timeout=0)
except picamera.exc.PiCameraError as e:
logging.error("Error: %s", str(e))

def takePhoto():
cam = Camera.get_instance()
try:
cam.photo_take()
except picamera.exc.PiCameraError as e:
logging.error("Error: %s", str(e))

def savePhoto(filename):
cam = Camera.get_instance()
data = request.get_data(as_text=True)
data = json.loads(data)
cam.update_photo({"name": filename, "tag": data["tag"]})
return jsonify({"res":"ok"})

def deletePhoto(filename):
cam = Camera.get_instance()
logging.debug("photo delete")
cam.delete_photo(filename)
return "ok"

## System

Expand Down Expand Up @@ -170,8 +266,30 @@ def restoreSettings():
with open("data/defaults/config.json") as f:
Config.write(json.loads(f.read()))
Config.get()
return "ok"

def loadSettings():
return Config.get()

def saveSettings():
Config.write()

def saveWifiSettings(data):
"""
Passes the received Wi-Fi configuration to the wifi.py script, applying it.
Then reboots
"""
mode = data.get("wifi_mode")
ssid = data.get("wifi_ssid")
psk = data.get("wifi_psk")

logging.info("mode " + mode +" ssid: " + ssid + " psk: " + psk)
client_params = " --ssid \"" + ssid + "\" --pwd \"" + psk + "\"" if ssid != "" and psk != "" else ""
logging.info(client_params)
os.system("sudo ./wifi.py updatecfg --mode " + mode + client_params)
os.system("sudo reboot")
if mode == "ap":
return "http://coder.bot"
return "http://coderbot.local"

def updateFromPackage():
os.system('sudo bash /home/pi/clean-update.sh')
Expand All @@ -188,7 +306,7 @@ def listMusicPackages():
response = musicPkg.listPackages()
return json.dumps(response)

def updateMusicPackages():
def addMusicPackage():
"""
Add a musical package an save the list of available packages on disk
also add sounds and directory
Expand Down Expand Up @@ -219,7 +337,7 @@ def deleteMusicPackage(package_data):

## Programs

def saveProgram(data):
def saveAsNewProgram(data):
overwrite = data["overwrite"]
existing_program = prog_engine.load(data["name"])
if existing_program and not overwrite:
Expand All @@ -230,28 +348,73 @@ def saveProgram(data):
prog_engine.save(program)
return 200

def saveProgram(name, data):
overwrite = data["overwrite"]
existing_program = prog_engine.load(name)
if existing_program and not overwrite:
return "askOverwrite"
elif existing_program and existing_program.is_default() == True:
return "defaultOverwrite"
program = Program(name=data["name"], code=data["code"], dom_code=data["dom_code"])
prog_engine.save(program)
return 200

def loadProgram(name):
existing_program = prog_engine.load(name)
return existing_program.as_dict(), 200

def deleteProgram(data):
prog_engine.delete(data["name"])
def deleteProgram(name):
prog_engine.delete(name)

def listPrograms():
return prog_engine.prog_list()

def runProgram(name):
"""
Execute the given program
"""
logging.debug("program_exec")
name = request.form.get('name')
code = request.form.get('code')
prog = app.prog_engine.create(name, code)
return json.dumps(prog.execute())

def stopProgram(name):
"""
Stop the program execution
"""
logging.debug("program_end")
prog = app.prog_engine.get_current_program()
if prog:
prog.end()
return "ok"

def statusProgram():
"""
Expose the program status
"""
logging.debug("program_status")
prog = app.prog_engine.get_current_program()
if prog is None:
prog = Program("")
return json.dumps({'name': prog.name, "running": prog.is_running(), "log": app.prog_engine.get_log()})


## Activities

def saveActivity(data):
activity = data["activity"]
def saveActivity(name, body):
activity = body["activity"]
activities.save(activity)

def saveAsNewActivity(body):
activity = body["activity"]
activities.save(activity["name"], activity)

def loadActivity(name=None, default=None):
return activities.load(name, default)

def deleteActivity(data):
activities.delete(data), 200
def deleteActivity(name):
activities.delete(name), 200

def listActivities():
return activities.list()
Expand All @@ -275,18 +438,38 @@ def reset():
pi.write(BUTTON_PIN, 1)
pi.write(BUTTON_PIN, 0)

return {
"status": "ok"
}

## Test
def testCoderbot(data):
def testCoderbot(body):
# taking first JSON key value (varargin)
tests_state = runCoderbotTestUnit(data[list(data.keys())[0]])
tests_state = runCoderbotTestUnit(body[list(data.keys())[0]])
return tests_state

def list_cnn_models():
def listCNNModels():
cnn = CNNManager.get_instance()
logging.info("cnn_models_list")
return json.dumps(cnn.get_models())

def trainCNNModel():
cam = Camera.get_instance()
cnn = CNNManager.get_instance()
logging.info("cnn_models_new")
data = json.loads(request.get_data(as_text=True))
cnn.train_new_model(model_name=data["model_name"],
architecture=data["architecture"],
image_tags=data["image_tags"],
photos_meta=cam.get_photo_list(),
training_steps=data["training_steps"],
learning_rate=data["learning_rate"])

return json.dumps({"name": data["model_name"], "status": 0})

def getCNNModel(model_name):
cnn = CNNManager.get_instance()
model_status = cnn.get_models().get(model_name)

return json.dumps(model_status)

def deleteCNNModel(model_name):
cnn = CNNManager.get_instance()
model_status = cnn.delete_model(model_name=model_name)

return json.dumps(model_status)
11 changes: 0 additions & 11 deletions arg.py

This file was deleted.

26 changes: 0 additions & 26 deletions init.py

This file was deleted.

Loading
0