From 0f82e5beb6aa50680567a1ef0fd0656ed2674f72 Mon Sep 17 00:00:00 2001 From: shamanec Date: Wed, 26 Jun 2024 15:35:50 +0300 Subject: [PATCH 01/79] improve stream resizing, reduce selection filter size --- .../components/DeviceControl/StreamCanvas.js | 42 +++++++++++++++---- .../DeviceSelection/DeviceSelection.js | 2 +- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/hub/gads-ui/src/components/DeviceControl/StreamCanvas.js b/hub/gads-ui/src/components/DeviceControl/StreamCanvas.js index 20255c12..ac766b93 100644 --- a/hub/gads-ui/src/components/DeviceControl/StreamCanvas.js +++ b/hub/gads-ui/src/components/DeviceControl/StreamCanvas.js @@ -1,5 +1,5 @@ import { Auth } from "../../contexts/Auth" -import {useContext, useEffect} from "react" +import { useContext, useEffect, useState } from "react" import './StreamCanvas.css' import { Button, Divider, Grid, Stack } from "@mui/material" import HomeIcon from '@mui/icons-material/Home'; @@ -11,20 +11,24 @@ import { api } from '../../services/api.js' export default function StreamCanvas({ deviceData }) { const { authToken, logout } = useContext(Auth) const { setDialog } = useDialog() + const [canvasSize, setCanvasSize] = useState({ + width: 0, + height: 0 + }); let deviceX = parseInt(deviceData.screen_width, 10) let deviceY = parseInt(deviceData.screen_height, 10) let screen_ratio = deviceX / deviceY - let canvasHeight = (window.innerHeight * 0.7) - let canvasWidth = (window.innerHeight * 0.7) * screen_ratio + // let canvasHeight = (window.innerHeight * 0.7) + // let canvasWidth = (window.innerHeight * 0.7) * screen_ratio const streamData = { udid: deviceData.udid, deviceX: deviceX, deviceY: deviceY, screen_ratio: screen_ratio, - canvasHeight: canvasHeight, - canvasWidth: canvasWidth + canvasHeight: canvasSize.height, + canvasWidth: canvasSize.width } let streamUrl = "" @@ -37,8 +41,24 @@ export default function StreamCanvas({ deviceData }) { } useEffect(() => { + const updateCanvasSize = () => { + let canvasHeight = window.innerHeight * 0.7 + let canvasWidth = canvasHeight * screen_ratio + + setCanvasSize({ + width: canvasWidth, + height: canvasHeight + }) + } + + updateCanvasSize() + + // Set resize listener + window.addEventListener('resize', updateCanvasSize); + return () => { window.stop() + window.removeEventListener('resize', updateCanvasSize); } }, []); @@ -56,18 +76,22 @@ export default function StreamCanvas({ deviceData }) { >{deviceData.model}
diff --git a/hub/gads-ui/src/components/DeviceSelection/DeviceSelection.js b/hub/gads-ui/src/components/DeviceSelection/DeviceSelection.js index 15e7e107..5eeb3232 100644 --- a/hub/gads-ui/src/components/DeviceSelection/DeviceSelection.js +++ b/hub/gads-ui/src/components/DeviceSelection/DeviceSelection.js @@ -131,7 +131,7 @@ function OSSelection({ devices, handleAlert }) { alignItems='center' className='filters-stack' sx={{ - height: '500px', + height: '200px', backgroundColor: '#9ba984', borderRadius: '10px' }} From c360c56b0568f1bf61df891ba1af14b8e7a9837f Mon Sep 17 00:00:00 2001 From: shamanec Date: Wed, 26 Jun 2024 15:41:11 +0300 Subject: [PATCH 02/79] resize skeleton loaders --- hub/gads-ui/src/components/DeviceControl/DeviceControl.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hub/gads-ui/src/components/DeviceControl/DeviceControl.js b/hub/gads-ui/src/components/DeviceControl/DeviceControl.js index fea7d29c..a83f6876 100644 --- a/hub/gads-ui/src/components/DeviceControl/DeviceControl.js +++ b/hub/gads-ui/src/components/DeviceControl/DeviceControl.js @@ -15,6 +15,7 @@ export default function DeviceControl() { const navigate = useNavigate(); const [deviceData, setDeviceData] = useState(null) const [isLoading, setIsLoading] = useState(true) + let screenRatio = window.innerHeight / window.innerWidth let url = `/device/${id}/info` let in_use_socket = null @@ -104,8 +105,8 @@ export default function DeviceControl() { style={{ backgroundColor: 'gray', animationDuration: '1s', - height: '950px', - width: '500px', + height: (window.innerHeight * 0.7), + width: (window.innerHeight * 0.7) * screenRatio, borderRadius: '30px' }} /> @@ -114,7 +115,7 @@ export default function DeviceControl() { style={{ backgroundColor: 'gray', animationDuration: '1s', - height: '850px', + height: (window.innerHeight * 0.7), width: '100%', marginRight: '10px' }} From 4a7f139a19a36892691a7297b4c3feac88701e69 Mon Sep 17 00:00:00 2001 From: shamanec Date: Wed, 26 Jun 2024 16:00:52 +0300 Subject: [PATCH 03/79] do not run automation on devices currently in use --- hub/router/appiumgrid.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hub/router/appiumgrid.go b/hub/router/appiumgrid.go index fc6fe2e3..56eef41a 100644 --- a/hub/router/appiumgrid.go +++ b/hub/router/appiumgrid.go @@ -386,6 +386,7 @@ func findAvailableDevice(appiumSessionBody AppiumSession) (*models.LocalHubDevic // Loop through all latest devices looking for an iOS device that is not currently `being prepared` for automation and the last time it was updated from provider was less than 3 seconds ago for _, localDevice := range devices.HubDevicesMap { if strings.EqualFold(localDevice.Device.OS, "ios") && + !localDevice.InUse && localDevice.Device.LastUpdatedTimestamp >= (time.Now().UnixMilli()-3000) && localDevice.IsAvailableForAutomation { availableDevices = append(availableDevices, localDevice) @@ -399,7 +400,7 @@ func findAvailableDevice(appiumSessionBody AppiumSession) (*models.LocalHubDevic // Loop through all latest devices looking for an Android device that is not currently `being prepared` for automation and the last time it was updated from provider was less than 3 seconds ago for _, localDevice := range devices.HubDevicesMap { if strings.EqualFold(localDevice.Device.OS, "android") && - !localDevice.IsRunningAutomation && + !localDevice.InUse && localDevice.Device.LastUpdatedTimestamp >= (time.Now().UnixMilli()-3000) && localDevice.IsAvailableForAutomation { availableDevices = append(availableDevices, localDevice) From 1ac1bd14bf436d24d6589dee1c2d28af65869e29 Mon Sep 17 00:00:00 2001 From: shamanec Date: Wed, 26 Jun 2024 16:06:15 +0300 Subject: [PATCH 04/79] set in use in devices update, not in sse stream --- hub/devices/devices.go | 12 ++++++++++++ hub/router/routes.go | 25 +++++-------------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/hub/devices/devices.go b/hub/devices/devices.go index 1fd5dee5..7d6ea0f0 100644 --- a/hub/devices/devices.go +++ b/hub/devices/devices.go @@ -40,6 +40,18 @@ func GetLatestDBDevices() { hubDevice, ok := HubDevicesMap[dbDevice.UDID] if ok { hubDevice.Device = dbDevice + if hubDevice.Device.Connected && hubDevice.Device.LastUpdatedTimestamp >= (time.Now().UnixMilli()-3000) { + hubDevice.Device.Available = true + + if hubDevice.InUseTS >= (time.Now().UnixMilli() - 3000) { + hubDevice.InUse = true + } else { + hubDevice.InUse = false + } + } else { + hubDevice.InUse = false + hubDevice.Device.Available = false + } } else { HubDevicesMap[dbDevice.UDID] = &models.LocalHubDevice{ Device: dbDevice, diff --git a/hub/router/routes.go b/hub/router/routes.go index 01ec0113..0c6a98be 100644 --- a/hub/router/routes.go +++ b/hub/router/routes.go @@ -7,10 +7,6 @@ import ( "GADS/provider/logger" "encoding/json" "fmt" - "github.com/gobwas/ws" - "github.com/gobwas/ws/wsutil" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo/options" "io" "net/http" "path/filepath" @@ -21,6 +17,11 @@ import ( "sync" "time" + "github.com/gobwas/ws" + "github.com/gobwas/ws/wsutil" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo/options" + "github.com/gin-gonic/gin" "go.mongodb.org/mongo-driver/mongo" ) @@ -458,22 +459,6 @@ func AvailableDevicesSSE(c *gin.Context) { c.Stream(func(w io.Writer) bool { availableMu.Lock() - for _, device := range devices.HubDevicesMap { - - if device.Device.Connected && device.Device.LastUpdatedTimestamp >= (time.Now().UnixMilli()-3000) { - device.Device.Available = true - - if device.InUseTS >= (time.Now().UnixMilli() - 3000) { - device.InUse = true - } else { - device.InUse = false - } - continue - } - device.InUse = false - device.Device.Available = false - } - // Extract the keys from the map and order them var hubDeviceMapKeys []string for key := range devices.HubDevicesMap { From 06aa39e15308b98eded523e462cb670a533956b0 Mon Sep 17 00:00:00 2001 From: shamanec Date: Wed, 26 Jun 2024 16:06:37 +0300 Subject: [PATCH 05/79] remove commented code in stream canvas --- hub/gads-ui/src/components/DeviceControl/StreamCanvas.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/hub/gads-ui/src/components/DeviceControl/StreamCanvas.js b/hub/gads-ui/src/components/DeviceControl/StreamCanvas.js index ac766b93..c9162cbb 100644 --- a/hub/gads-ui/src/components/DeviceControl/StreamCanvas.js +++ b/hub/gads-ui/src/components/DeviceControl/StreamCanvas.js @@ -19,8 +19,6 @@ export default function StreamCanvas({ deviceData }) { let deviceX = parseInt(deviceData.screen_width, 10) let deviceY = parseInt(deviceData.screen_height, 10) let screen_ratio = deviceX / deviceY - // let canvasHeight = (window.innerHeight * 0.7) - // let canvasWidth = (window.innerHeight * 0.7) * screen_ratio const streamData = { udid: deviceData.udid, From a7bbbb5517ad1ad364104e9e0cf68213ac314c7d Mon Sep 17 00:00:00 2001 From: shamanec Date: Wed, 26 Jun 2024 19:52:03 +0300 Subject: [PATCH 06/79] start adding devices administration --- common/db/db.go | 52 +++++- common/models/models.go | 2 +- .../src/components/Admin/AdminDashboard.js | 10 ++ .../components/Admin/Devices/DeviceList.js | 157 +++++++++++++++++ .../Admin/Devices/DevicesAdministration.js | 138 +++++++++++++++ .../src/components/Admin/Users/AddUser.js | 7 +- .../DeviceSelection/DeviceSelection.js | 3 +- hub/router/handler.go | 10 +- hub/router/routes.go | 161 ++++++++++++++---- provider/devices/common.go | 115 +++---------- 10 files changed, 517 insertions(+), 138 deletions(-) create mode 100644 hub/gads-ui/src/components/Admin/Devices/DeviceList.js create mode 100644 hub/gads-ui/src/components/Admin/Devices/DevicesAdministration.js diff --git a/common/db/db.go b/common/db/db.go index 63c19508..0d8ff6fc 100644 --- a/common/db/db.go +++ b/common/db/db.go @@ -5,11 +5,12 @@ import ( "GADS/common/models" "context" "fmt" - "go.mongodb.org/mongo-driver/bson/primitive" - "go.mongodb.org/mongo-driver/mongo/gridfs" "io" "time" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo/gridfs" + "slices" "go.mongodb.org/mongo-driver/bson" @@ -244,6 +245,35 @@ func GetDBDevices() []models.Device { return dbDevices } +func GetDBDeviceNew() []models.Device { + var dbDevices []models.Device + // Access the database and collection + collection := MongoClient().Database("gads").Collection("new_devices") + + cursor, err := collection.Find(context.Background(), bson.D{{}}, nil) + if err != nil { + log.WithFields(log.Fields{ + "event": "get_db_devices", + }).Error(fmt.Sprintf("Could not get db cursor when trying to get latest device info from db - %s", err)) + } + + if err := cursor.All(context.Background(), &dbDevices); err != nil { + log.WithFields(log.Fields{ + "event": "get_db_devices", + }).Error(fmt.Sprintf("Could not get devices latest info from db cursor - %s", err)) + } + + if err := cursor.Err(); err != nil { + log.WithFields(log.Fields{ + "event": "get_db_devices", + }).Error(fmt.Sprintf("Encountered db cursor error - %s", err)) + } + + cursor.Close(context.TODO()) + + return dbDevices +} + func GetDBDevicesUDIDs() []string { dbDevices := GetDBDevices() var udids []string @@ -259,7 +289,7 @@ func UpsertDeviceDB(device models.Device) error { update := bson.M{ "$set": device, } - coll := mongoClient.Database("gads").Collection("devices") + coll := mongoClient.Database("gads").Collection("new_devices") filter := bson.D{{Key: "udid", Value: device.UDID}} opts := options.Update().SetUpsert(true) _, err := coll.UpdateOne(mongoClientCtx, filter, update, opts) @@ -269,6 +299,18 @@ func UpsertDeviceDB(device models.Device) error { return nil } +func DeleteDeviceDB(udid string) error { + coll := mongoClient.Database("gads").Collection("new_devices") + filter := bson.M{"udid": udid} + + _, err := coll.DeleteOne(mongoClientCtx, filter) + if err != nil { + return err + } + + return nil +} + func GetDevices() []models.Device { // Access the database and collection collection := MongoClient().Database("gads").Collection("devices") @@ -375,7 +417,3 @@ func UploadFileGridFS(file io.Reader, fileName string, force bool) error { return nil } } - -func DownloadFileGridFS(fileName string, filePath string) { - -} diff --git a/common/models/models.go b/common/models/models.go index b5fee136..cec0952d 100644 --- a/common/models/models.go +++ b/common/models/models.go @@ -2,6 +2,7 @@ package models import ( "context" + "github.com/danielpaulus/go-ios/ios" ) @@ -43,7 +44,6 @@ type Device struct { OS string `json:"os" bson:"os"` // common value - device OS Name string `json:"name" bson:"name"` // common value - name of the device OSVersion string `json:"os_version" bson:"os_version"` // common value - OS version of the device - Model string `json:"model" bson:"model"` // common value - device model Host string `json:"host" bson:"host"` // common value - IP address of the device host(provider) Provider string `json:"provider" bson:"provider"` // common value - nickname of the device host(provider) ScreenWidth string `json:"screen_width" bson:"screen_width"` // common value - screen width of device diff --git a/hub/gads-ui/src/components/Admin/AdminDashboard.js b/hub/gads-ui/src/components/Admin/AdminDashboard.js index 02f55e33..d086605f 100644 --- a/hub/gads-ui/src/components/Admin/AdminDashboard.js +++ b/hub/gads-ui/src/components/Admin/AdminDashboard.js @@ -5,6 +5,7 @@ import { Box } from "@mui/material"; import UsersAdministration from "./Users/UsersAdministration"; import ProvidersAdministration from "./Providers/ProvidersAdministration"; import FilesAdministration from "./Files/FilesAdministration"; +import DevicesAdministration from './Devices/DevicesAdministration'; export default function AdminDashboard() { @@ -61,10 +62,19 @@ export default function AdminDashboard() { fontWeight: "bold" }} /> + {currentTabIndex === 0 && } {currentTabIndex === 1 && } {currentTabIndex === 2 && } + {currentTabIndex === 3 && } ) } \ No newline at end of file diff --git a/hub/gads-ui/src/components/Admin/Devices/DeviceList.js b/hub/gads-ui/src/components/Admin/Devices/DeviceList.js new file mode 100644 index 00000000..c50d19d9 --- /dev/null +++ b/hub/gads-ui/src/components/Admin/Devices/DeviceList.js @@ -0,0 +1,157 @@ +import { useContext, useEffect, useState } from "react"; +import { api } from "../../../services/api"; +import { Auth } from "../../../contexts/Auth"; +import { Box, Button, Grid, MenuItem, Select, Stack, TextField } from "@mui/material"; + +export default function DeviceList() { + const [devices, setDevices] = useState([]) + const [providers, setProviders] = useState([]) + const { logout } = useContext(Auth) + + useEffect(() => { + let url = `/admin/devices` + + api.get(url) + .then(response => { + setDevices(response.data.devices) + setProviders(response.data.providers) + }) + .catch(error => { + if (error.response) { + if (error.response.status === 401) { + logout() + } + } + }); + }, []) + + return ( + + + {devices.map((device) => { + return ( + + + + + ) + }) + } + + + ) +} + +function ExistingDevice({ deviceData, providersData }) { + const [provider, setProvider] = useState(deviceData.provider) + const [os, setOS] = useState(deviceData.os) + const [name, setName] = useState(deviceData.name) + const [osVersion, setOSVersion] = useState(deviceData.os_version) + const [screenHeight, setScreenHeight] = useState(deviceData.screen_height) + const [screenWidth, setScreenWidth] = useState(deviceData.screen_width) + const udid = deviceData.udid + + function handleUpdateDevice(event) { + event.preventDefault() + + let url = `/admin/device` + + const deviceData = { + udid: udid, + name: name, + os_version: osVersion, + provider: provider, + screen_height: screenHeight, + screen_width: screenWidth, + os: os + } + + api.put(url, deviceData) + .catch(e => { + console.log('wtf') + console.log(e) + }) + } + + return ( + +
+ + + setName(event.target.value)} + /> + setOSVersion(event.target.value)} + /> + setScreenHeight(event.target.value)} + /> + setScreenWidth(event.target.value)} + /> + + + + +
+
+ ) +} \ No newline at end of file diff --git a/hub/gads-ui/src/components/Admin/Devices/DevicesAdministration.js b/hub/gads-ui/src/components/Admin/Devices/DevicesAdministration.js new file mode 100644 index 00000000..a6d8ac65 --- /dev/null +++ b/hub/gads-ui/src/components/Admin/Devices/DevicesAdministration.js @@ -0,0 +1,138 @@ +import DeviceList from "./DeviceList"; +import { useContext, useState, useEffect } from "react"; +import { api } from "../../../services/api"; +import { Box, Button, Divider, MenuItem, Select, Stack, TextField } from "@mui/material"; +import { Auth } from "../../../contexts/Auth"; + +export default function DevicesAdministration() { + const [devices, setDevices] = useState([]) + const [providers, setProviders] = useState([]) + const { logout } = useContext(Auth) + + useEffect(() => { + let url = `/admin/devices` + + api.get(url) + .then(response => { + setDevices(response.data.devices) + setProviders(response.data.providers) + }) + .catch(error => { + if (error.response) { + if (error.response.status === 401) { + logout() + } + } + }); + }, []) + + return ( + + + + + + + ) +} + +function NewDevice({ providersData }) { + const [udid, setUdid] = useState('') + const [provider, setProvider] = useState(providersData[0]) + const [os, setOS] = useState('') + const [name, setName] = useState('') + const [osVersion, setOSVersion] = useState('') + const [screenHeight, setScreenHeight] = useState('') + const [screenWidth, setScreenWidth] = useState('') + + function handleUpdateDevice(event) { + event.preventDefault() + + let url = `/admin/device` + + const deviceData = { + udid: udid, + name: name, + os_version: osVersion, + provider: provider, + screen_height: screenHeight, + screen_width: screenWidth, + os: os + } + + api.post(url, deviceData) + .catch(e => { + console.log('wtf') + console.log(e) + }) + } + + return ( + +
+ + setUdid(event.target.value)} + /> + setName(event.target.value)} + /> + setOSVersion(event.target.value)} + /> + setScreenHeight(event.target.value)} + /> + setScreenWidth(event.target.value)} + /> + + + + +
+
+ ) +} \ No newline at end of file diff --git a/hub/gads-ui/src/components/Admin/Users/AddUser.js b/hub/gads-ui/src/components/Admin/Users/AddUser.js index 54239626..fe67a77e 100644 --- a/hub/gads-ui/src/components/Admin/Users/AddUser.js +++ b/hub/gads-ui/src/components/Admin/Users/AddUser.js @@ -110,7 +110,7 @@ export default function AddUser() { spacing={2} >

Add user

-