browser tab session for ensure that a user can open multiple browser tabs antabs and every tab has subscribed to the right topic

main
alex 2023-10-17 19:12:31 +02:00
parent ea36bcf963
commit 5603e3abfc
13 changed files with 189 additions and 18 deletions

View File

@ -0,0 +1,94 @@
import requests
import cairosvg
from PIL import Image
import mysql.connector
import sys
max_apriltag_value = 48714
table_name = "data"
id_to_update = "apriltag"
conn = mysql.connector.connect(
host="localhost",
port="50035",
user="ad-internalstuff",
password="cdQK4pfr3_YfnE1u",
database="ad-internalstuff"
)
# create table if not exists
create_table_query = f"CREATE TABLE IF NOT EXISTS {table_name} (id VARCHAR(255) PRIMARY KEY, value INT)"
cursor = conn.cursor()
cursor.execute(create_table_query)
cursor.close()
# get current value
select_query = f"SELECT value FROM {table_name} WHERE id = %s"
cursor = conn.cursor()
cursor.execute(select_query, (id_to_update,))
result = cursor.fetchone()
db_value = 0
if result:
db_value = result[0]
else:
# value does not exist, create it
insert_query = f"INSERT INTO {table_name} (id, value) VALUES (%s, %s)"
cursor = conn.cursor()
cursor.execute(insert_query, (id_to_update, 0))
conn.commit()
# check if max value is reached
if db_value >= max_apriltag_value:
print(f"Max value of {max_apriltag_value} reached.")
sys.exit(1)
# update value
update_query = f"UPDATE {table_name} SET value = value + %s WHERE id = %s"
db_value += 1
cursor = conn.cursor()
cursor.execute(update_query, (1, id_to_update))
conn.commit()
# close connection to database
cursor.close()
conn.close()
# image handling
new_file_number = str(db_value).zfill(5)
print(f"April Tag number: {db_value}")
svg_url = f"https://git.ex.umbach.dev/Alex/apriltag-chaitanyantr/raw/branch/main/tagStandard52h13/tag52_13_{new_file_number}.svg"
# Fordere das SVG-Bild von der URL an
response = requests.get(svg_url)
if response.status_code == 200:
try:
# Speichere das SVG-Bild in einer Datei
svg_file_name = "apriltag.svg"
with open(svg_file_name, "wb") as svg_file:
svg_file.write(response.content)
# Konvertiere das SVG-Bild in ein PNG-Bild
png_data = cairosvg.svg2png(bytestring=response.content)
# Speichere das PNG-Bild in einer Datei
png_file_name = "apriltag.png"
with open(png_file_name, "wb") as png_file:
png_file.write(png_data)
except Exception as e:
print("Fehler beim Verarbeiten des Bildes:", str(e))
sys.exit(1)
else:
print("Fehler beim Herunterladen des SVG-Bildes. Statuscode:", response.status_code)
sys.exit(1)

View File

@ -0,0 +1,15 @@
{
"category": "InternalStuff",
"name": "April Tag generieren",
"globalInputs": [],
"tasks": [
{
"name": "April Tag generieren",
"onFinish": "next",
"undoPossible": false,
"repeatPossible": true,
"scriptPath": "generate.py",
"parameters": []
}
]
}

View File

@ -0,0 +1,3 @@
opencv-python==4.8.1.78
CairoSVG==2.7.1
mysql-connector-python==8.1.0

View File

@ -1,12 +1,30 @@
import sys import sys
import os import os
import random
# add the path to the libs folder # add the path to the libs folder
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))) sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
from libs.robots import rex from libs.robots import rex
rexRobot = rex.Rex("test", "Drucker leeren") randomJobs = [
"Drucker leeren",
"Müll rausbringen",
"Kopf schütteln",
"Runterfahren",
"Rausgehen",
"Game starten",
"Dreieck zeichnen",
"Quadrat zeichnen",
"Hand schütteln",
"Haus zeichnen",
]
rJob = randomJobs[random.randint(0, len(randomJobs) - 1)]
print("job: " + rJob)
rexRobot = rex.Rex("test", rJob)
# rexRobot.moveToXYZ(1, 2, 3) # rexRobot.moveToXYZ(1, 2, 3)
rexRobot.move_to_x(5) rexRobot.move_to_x(5)

View File

@ -1,6 +1,24 @@
import requests import requests
import uuid import uuid
from enum import Enum
import sys
###
# GLOBALS
###
class ResponseStatus():
Ok = 0
Error = 1
Offline = 2
max_job_name_length = 30
###
# CLASSES
###
# TODO: add oriention left or right
class Rex: class Rex:
""" """
@ -9,7 +27,7 @@ class Rex:
def __init__(self, robotName, jobName, address='http://localhost:50055'): def __init__(self, robotName, jobName, address='http://localhost:50055'):
self.robotName = robotName self.robotName = robotName
self.jobId = uuid.uuid4().__str__() self.jobId = uuid.uuid4().__str__()
self.jobName = jobName self.jobName = jobName[:max_job_name_length]
self.address = address self.address = address
self.x = 0 self.x = 0
self.y = 0 self.y = 0
@ -28,6 +46,23 @@ class Rex:
res = requests.post(self.address + '/v1/control/1', json=obj) res = requests.post(self.address + '/v1/control/1', json=obj)
print("status code", res.status_code) print("status code", res.status_code)
print("res", res.json())
json = res.json()
status = json['Status']
if status == ResponseStatus.Offline:
print("robot offline")
sys.exit(1)
if status != ResponseStatus.Error:
print("robot error")
sys.exit(1)
if status != ResponseStatus.Ok:
print("robot error")
sys.exit(1)
def move_to_x(self, x): def move_to_x(self, x):
""" """

View File

@ -1,3 +0,0 @@
# test.py
def testa():
print("Hello from test.py")

View File

@ -125,8 +125,14 @@ func main() {
// requested upgrade to the WebSocket protocol. // requested upgrade to the WebSocket protocol.
if websocket.IsWebSocketUpgrade(c) { if websocket.IsWebSocketUpgrade(c) {
sessionId := c.Query("auth") sessionId := c.Query("auth")
// needed for a user who uses multiple tabs in the browser
// with the same session id because otherwise the last browser
// tab would subscribe to the topic and the other tabs would
// not receive any messages
browserTabSession := c.Query("bts")
if len(sessionId) != utils.LenHeaderXAuthorization { if len(sessionId) != utils.LenHeaderXAuthorization ||
len(browserTabSession) != utils.LenHeaderXAuthorization {
return c.SendStatus(fiber.StatusUnauthorized) return c.SendStatus(fiber.StatusUnauthorized)
} }
@ -142,6 +148,7 @@ func main() {
if user.Id != "" { if user.Id != "" {
c.Locals("sessionId", sessionId) c.Locals("sessionId", sessionId)
c.Locals("browserTabSession", browserTabSession)
c.Locals("userId", user.Id) c.Locals("userId", user.Id)
} }
} }

View File

@ -5,7 +5,6 @@ import (
"sync" "sync"
"github.com/gofiber/websocket/v2" "github.com/gofiber/websocket/v2"
"github.com/rs/zerolog/log"
) )
var socketClients []*structs.SocketClient var socketClients []*structs.SocketClient
@ -41,14 +40,12 @@ func GetSocketClients() []*structs.SocketClient {
return socketClients return socketClients
} }
func SubscribeSocketClientToTopic(sessionId string, topic string) { func SubscribeSocketClientToTopic(browserTabSession string, topic string) {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
log.Info().Msgf("Subscribing session %s to topic %s", sessionId, topic)
for _, socketClient := range socketClients { for _, socketClient := range socketClients {
if socketClient.SessionId == sessionId { if socketClient.BrowserTabSession == browserTabSession {
socketClient.SubscribedTopic = topic socketClient.SubscribedTopic = topic
break break
} }

View File

@ -974,6 +974,8 @@ func InstallPythonPackages(userId string, category string, groupId string) {
cmd := exec.Command("pip3", "install", "-r", config.Cfg.FolderPaths.GroupTasksGroups+groupId+"/requirements.txt") cmd := exec.Command("pip3", "install", "-r", config.Cfg.FolderPaths.GroupTasksGroups+groupId+"/requirements.txt")
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
log.Info().Msgf("pa %s", config.Cfg.FolderPaths.GroupTasksGroups+groupId+"/requirements.txt")
if err != nil { if err != nil {
logger.AddGroupTasksLog("Installing python packages for groupId %s of category %s failed. Error: %s", logger.AddGroupTasksLog("Installing python packages for groupId %s of category %s failed. Error: %s",
category, groupId, err.Error()) category, groupId, err.Error())
@ -982,7 +984,7 @@ func InstallPythonPackages(userId string, category string, groupId string) {
convertedXYPermission, convertedXYPermission,
utils.SubscribedDynamicTopicGroupTasks+category, utils.SubscribedDynamicTopicGroupTasks+category,
structs.SendSocketMessage{ structs.SendSocketMessage{
Cmd: utils.SentCmdInstallingPythonPackages, Cmd: utils.SentCmdInstallingPythonPackagesFailed,
Body: messageBody, Body: messageBody,
}) })
return return

View File

@ -17,11 +17,12 @@ const (
) )
type SocketClient struct { type SocketClient struct {
SessionId string SessionId string
UserId string BrowserTabSession string
Conn *websocket.Conn UserId string
connMu sync.Mutex Conn *websocket.Conn
SubscribedTopic string connMu sync.Mutex
SubscribedTopic string
} }
type SocketMessage struct { type SocketMessage struct {

View File

@ -29,6 +29,7 @@ func RunHub() {
select { select {
case newSocketClient := <-register: case newSocketClient := <-register:
userId := fmt.Sprintf("%v", newSocketClient.Conn.Locals("userId")) userId := fmt.Sprintf("%v", newSocketClient.Conn.Locals("userId"))
browserTabSession := fmt.Sprintf("%v", newSocketClient.Conn.Locals("browserTabSession"))
sessionId := fmt.Sprintf("%v", newSocketClient.Conn.Locals("sessionId")) sessionId := fmt.Sprintf("%v", newSocketClient.Conn.Locals("sessionId"))
// close connection instantly if sessionId is empty // close connection instantly if sessionId is empty
@ -38,6 +39,7 @@ func RunHub() {
} }
newSocketClient.SessionId = sessionId newSocketClient.SessionId = sessionId
newSocketClient.BrowserTabSession = browserTabSession
newSocketClient.UserId = userId newSocketClient.UserId = userId
cache.AddSocketClient(newSocketClient) cache.AddSocketClient(newSocketClient)
@ -315,7 +317,7 @@ func RunHub() {
case utils.ReceivedCmdSubscribeToTopic: case utils.ReceivedCmdSubscribeToTopic:
log.Debug().Msgf("Received subscribe to topic: %v", receivedMessage.Body) log.Debug().Msgf("Received subscribe to topic: %v", receivedMessage.Body)
cache.SubscribeSocketClientToTopic(data.Conn.Locals("sessionId").(string), receivedMessage.Body["topic"].(string)) cache.SubscribeSocketClientToTopic(receivedMessage.Body["browserTabSession"].(string), receivedMessage.Body["topic"].(string))
break break
case utils.ReceivedCmdDeleteAllNotifications: case utils.ReceivedCmdDeleteAllNotifications:
notification.DeleteAllNotifications(data.Conn.Locals("userId").(string)) notification.DeleteAllNotifications(data.Conn.Locals("userId").(string))