Skip to content

Commit

Permalink
chore: Update SystemMonitor component and settings.json
Browse files Browse the repository at this point in the history
  • Loading branch information
infinitel8p committed Aug 21, 2024
1 parent f4e3974 commit 4d19f7c
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 31 deletions.
16 changes: 16 additions & 0 deletions client/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from flask import Flask, Response, jsonify, request
from flask_cors import CORS
from urllib.parse import unquote
import system_helpers
import stream_helpers
import settings_helpers
Expand Down Expand Up @@ -38,6 +39,7 @@ def toggle_recording():
stream_helpers.start_recording()
return jsonify({"message": "Recording started"})


@app.route('/settings', methods=['GET', 'POST'])
def settings():
if request.method == 'GET':
Expand All @@ -55,6 +57,20 @@ def settings():
return jsonify({"message": "Settings updated"})


@app.route('/list_directories', methods=['GET'])
def list_directories():
path = request.args.get('path', "./")
decoded_path = unquote(path) # Decode the path

if settings_helpers.is_directory(decoded_path):
directories, error = settings_helpers.list_directories(decoded_path)
if error:
print(f"Error listing directories: {error}")
return jsonify({"error": error}), 500
return jsonify(directories)
else:
return jsonify({"error": "Invalid directory path"}), 400


if __name__ == "__main__":
app.run(host='0.0.0.0', port=5005, debug=True)
8 changes: 4 additions & 4 deletions client/settings/settings.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
{
"TARGET_BT_ADDRESSES": [
{
"address": "XX:XX:XX:XX:XX:XX",
"address": "1X:XX:XX:XX:XX:XX",
"name": "Device 1"
},
{
"address": "XX:XX:XX:XX:XX:XX",
"address": "2X:XX:XX:XX:XX:XX",
"name": "Device 2"
}
],
"TARGET_AP_MAC_ADDRESSES": [
{
"address": "XX:XX:XX:XX:XX:XX",
"address": "XX:XX:XX:XX:XX:X1",
"name": "Device 1"
},
{
"address": "XX:XX:XX:XX:XX:XX",
"address": "XX:XX:XX:XX:XX:X2",
"name": "Device 2"
}
],
Expand Down
81 changes: 77 additions & 4 deletions client/settings_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,107 @@
SETTINGS_FILE = './settings/settings.json'

def get_settings():
"""
Load and return the settings from the settings file.
Returns:
Dict[str, Any]: The settings as a dictionary.
"""

with open(SETTINGS_FILE, 'r') as f:
settings = json.load(f)
return settings

def update_settings(new_settings):
def update_settings(new_settings) -> None:
"""
Update the settings in the settings file with new values.
Args:
new_settings (Dict[str, Any]): The new settings to be updated.
"""

with open(SETTINGS_FILE, 'r+') as f:
settings = json.load(f)
settings.update(new_settings)
f.seek(0)
json.dump(settings, f, indent=4)
f.truncate()

def is_valid_directory(path):
def is_directory(path: str) -> bool:
"""
Check if a given path is a valid directory.
Args:
path (str): The path to check.
Returns:
bool: True if the path is a valid directory, False otherwise.
"""

return os.path.isdir(path)

def is_valid_directory(path: str) -> bool:
"""
Check if the provided path is a valid directory. If it does not exist,
attempt to create it.
Args:
path (str): The path to check.
Returns:
bool: True if the path is a valid directory or was successfully created,
False otherwise.
"""

if not os.path.exists(path):
try:
os.makedirs(path)
return True
except Exception as e:
print(f"Error creating directory: {e}")
return False
elif os.path.isdir(path) and os.access(path, os.W_OK):
elif is_directory(path) and os.access(path, os.W_OK):
return True
else:
return False

def update_video_save_location(new_location):
def update_video_save_location(new_location: str) -> bool:
"""
Update the video save location in the settings if the provided directory is valid.
Args:
new_location (str): The new directory path to save videos.
Returns:
bool: True if the location was updated successfully, False otherwise.
"""

if is_valid_directory(new_location):
update_settings({"VideoSaveLocation": new_location})
return True
else:
return False

def list_directories(path: str = "./"):
"""
List directories within the provided path.
Args:
path (str): The path to list directories in. Defaults to the current directory.
Returns:
Tuple[Optional[Dict[str, Any]], Optional[str]]: A tuple containing a dictionary
with the list of directories and the current path if successful, or an error
message if an exception occurs.
"""

try:
directories = [
{"name": name, "path": os.path.join(path, name)}
for name in os.listdir(path)
if is_directory(os.path.join(path, name))
]
return {"directories": directories, "current_path": path}, None
except Exception as e:
print(f"Error listing directories: {e}")
return None, str(e)
50 changes: 28 additions & 22 deletions server/src/app/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
'use client';
import React, { useState, useEffect } from "react";
import DirectoryPicker from "@/components/DirectoryPicker";
import BTDeviceList from "@/components/BTDeviceList";
import WiFiDeviceList from "@/components/WiFiDeviceList";

const Page = () => {
const [selectedDirectory, setSelectedDirectory] = useState('');
const [settings, setSettings] = useState({
VideoSaveLocation: "Loading...",
});
const [newLocation, setNewLocation] = useState("");

useEffect(() => {
const settingsFeedUrl = `${window.location.protocol}//${window.location.hostname}:5005/settings`;
const handleDirectorySelect = (path) => {
setSelectedDirectory(path);
};

useEffect(() => {
const fetchSettingsInfo = async () => {
try {
const settingsFeedUrl = `${window.location.protocol}//${window.location.hostname}:5005/settings`;
const response = await fetch(settingsFeedUrl);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log("Fetched Settings Info:", data);
setSettings(data);
} catch (error) {
console.error("Error fetching settings info:", error);
Expand All @@ -38,15 +40,15 @@ const Page = () => {
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ VideoSaveLocation: newLocation }),
body: JSON.stringify({ VideoSaveLocation: selectedDirectory }),
});

const result = await response.json();
if (!response.ok) {
alert(result.message || "Error updating settings");
} else {
alert("Settings updated successfully");
setSettings(prevSettings => ({ ...prevSettings, VideoSaveLocation: newLocation }));
setSettings(prevSettings => ({ ...prevSettings, VideoSaveLocation: selectedDirectory }));
}
} catch (error) {
console.error("Error updating settings:", error);
Expand All @@ -55,20 +57,24 @@ const Page = () => {
};

return (
<div>
<div>bt device mac</div>
<div>wifi device mac</div>
<div>{`Video save location: ${settings.VideoSaveLocation}`}</div>
<div>
<input
type="text"
value={newLocation}
onChange={(e) => setNewLocation(e.target.value)}
placeholder="Enter new video save location"
/>
<button onClick={handleSaveLocationChange}>Update Location</button>
<div className="flex flex-col gap-5 space-y-10 px-10 pt-10">
<div className="border border-red-500">
<BTDeviceList />
</div>
<div className="border border-red-500">
<WiFiDeviceList />
</div>
<div className="flex w-full border border-red-500">
<div>Video save location: <span className="text-blue-700">{settings.VideoSaveLocation}</span></div>
<div className="flex gap-5 ml-5">
<div>
<h1>Select a new directory to save the videos:</h1>
<DirectoryPicker onDirectorySelect={handleDirectorySelect} />
</div>
<button className="bg-gray-200" onClick={handleSaveLocationChange}>Update Location</button>
</div>
</div>
<div className="text-gray-300">modular trigger sensors: TBD</div>
<div className="border border-red-500 text-gray-300">modular trigger sensors: TBD</div>
</div>
);
};
Expand Down
36 changes: 36 additions & 0 deletions server/src/components/BTDeviceList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"use client";
import React, { useState, useEffect } from 'react';

const BTDeviceList = () => {
const [btDevices, setBtDevices] = useState([]);

useEffect(() => {
const fetchSettings = async () => {
try {
const settingsFeedUrl = `${window.location.protocol}//${window.location.hostname}:5005/settings`;
const response = await fetch(settingsFeedUrl);
const data = await response.json();
setBtDevices(data.TARGET_BT_ADDRESSES);
} catch (error) {
console.error("Error fetching BT devices:", error);
}
};

fetchSettings();
}, []);

return (
<div>
<h3>Bluetooth Devices:</h3>
<ul>
{btDevices.map((device, index) => (
<li key={index}>
{device.name}: {device.address}
</li>
))}
</ul>
</div>
);
};

export default BTDeviceList;
59 changes: 59 additions & 0 deletions server/src/components/DirectoryPicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"use client";
import React, { useState, useEffect } from 'react';

const DirectoryPicker = ({ onDirectorySelect }) => {
const [directories, setDirectories] = useState([]);
const [currentPath, setCurrentPath] = useState('/');
const [error, setError] = useState('');
const [directoriesUrl, setDirectoriesUrl] = useState('');

useEffect(() => {
if (typeof window !== "undefined") {
setDirectoriesUrl(`${window.location.protocol}//${window.location.hostname}:5005/list_directories`);
}
}, []);

useEffect(() => {
if (directoriesUrl) {
fetchDirectories(currentPath);
}
}, [directoriesUrl, currentPath]);

const fetchDirectories = async (path) => {
try {
const response = await fetch(`${directoriesUrl}?path=${encodeURIComponent(path)}`);
const data = await response.json();
if (response.ok) {
setDirectories(data.directories);
setCurrentPath(data.current_path);
} else {
setError(data.error);
}
} catch (error) {
setError('Failed to fetch directories.');
}
};

const handleDirectoryClick = (path) => {
setCurrentPath(path);
onDirectorySelect(path);
};

return (
<div>
<h3>Current Directory: {currentPath}</h3>
{error && <div style={{ color: 'red' }}>{error}</div>}
<ul>
{directories.map((dir) => (
<li key={dir.path}>
<button className='bg-red-500 m-1' onClick={() => handleDirectoryClick(dir.path)}>
{dir.name}
</button>
</li>
))}
</ul>
</div>
);
};

export default DirectoryPicker;
1 change: 0 additions & 1 deletion server/src/components/SystemMonitor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const SystemMonitor = () => {
try {
const response = await fetch(systemFeedUrl);
const data = await response.json();
console.log("Fetched System Info:", data); // Log the data structure
setSystemInfo(data);
} catch (error) {
console.error("Error fetching system info:", error);
Expand Down
Loading

0 comments on commit 4d19f7c

Please sign in to comment.