Skip to content

Commit 847d2ca

Browse files
author
3aa49ec6bfc910647fa1c5a013e48eef
committed
Moved to config json, added config editor
1 parent 995629c commit 847d2ca

File tree

13 files changed

+256
-19
lines changed

13 files changed

+256
-19
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/3aa49ec6bfc910647fa
3737
- [x] Fix project structure
3838
- [x] Clean up the install process
3939
- [x] Clean up the configuration process
40-
- [x] Package the project properly
40+
- [x] Package the project
41+
- [ ] Package the project properly
4142
- [ ] Add lifecycle management for destination (retention policy etc)
4243
- [ ] Add web server for configuration (managing rclone, network settings), status (system, network, copy, usb host) and statistics (uptime, copy, storage)
4344
- [ ] Add functionality to handle scenarios such as keeping car awake for transfers

deploy/install.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,25 @@ sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/3aa49ec6bfc910647fa
3434
# Create log directory
3535
mkdir /logs
3636

37+
# Create config directory
38+
mkdir /config
39+
40+
# Set default config
41+
cat << EOF > /config/node-teslausb.json
42+
{
43+
"archive": {
44+
"rcloneConfig": "node-teslausb",
45+
"destinationPath": "teslausb/TeslaCam"
46+
},
47+
"paths": {
48+
"sentryClips": "/mnt/TeslaCam/TeslaCam/SentryClips",
49+
"savedClips": "/mnt/TeslaCam/TeslaCam/SavedClips"
50+
},
51+
"delayBetweenCopyRetryInSeconds": 3600,
52+
"mainLoopIntervalInSeconds": 120
53+
}
54+
EOF
55+
3756
# Clean unused packages
3857
# sudo apt-get autoremove --purge
3958

website/package-lock.json

Lines changed: 36 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

website/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"@typescript-eslint/eslint-plugin": "^6.0.0",
2323
"@typescript-eslint/parser": "^6.0.0",
2424
"autoprefixer": "^10.4.16",
25+
"cl-editor": "^2.3.0",
2526
"eslint": "^8.28.0",
2627
"eslint-config-prettier": "^9.1.0",
2728
"eslint-plugin-svelte": "^2.30.0",

website/src/lib/constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,9 @@ export const logNameToPathMapping: { [key: string]: string } = {
55
'worker': '/logs/worker.log',
66
'website': '/logs/website.log',
77
'resources': '/logs/resources.log',
8+
};
9+
10+
export const configNameToPathMapping: { [key: string]: string } = {
11+
'rclone': isDevMode ? '/Users/blake/logs/rclone.log' : '/root/.config/rclone/rclone.conf',
12+
'node-teslausb': isDevMode ? '/Users/blake/config/node-teslausb.json' : '/config/node-teslausb.json',
813
};

website/src/routes/+page.svelte

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
let b = 0;
66
let total = 0;
77
let logFiles: string[] = [];
8+
let configFiles: string[] = [];
89
let finishedApiCalls = false;
910
let lockChimes: any[] = [];
1011
let selectedUrl = '';
@@ -35,6 +36,20 @@
3536
return logFiles.logFiles;
3637
}
3738
39+
async function listConfigFiles() {
40+
const response = await fetch('/api/configFiles', {
41+
method: 'GET',
42+
headers: {
43+
'content-type': 'application/json'
44+
}
45+
});
46+
47+
const configFiles = await response.json();
48+
console.log(configFiles.configFiles);
49+
50+
return configFiles.configFiles;
51+
}
52+
3853
async function getLockChimes() {
3954
const response = await fetch('/api/lockChimes', {
4055
method: 'GET',
@@ -64,6 +79,7 @@
6479
6580
onMount(async () => {
6681
logFiles = await listLogFiles();
82+
configFiles = await listConfigFiles();
6783
lockChimes = await getLockChimes();
6884
console.log(logFiles);
6985
finishedApiCalls = true;
@@ -86,6 +102,21 @@
86102
<p>Loading...</p>
87103
{/if}
88104

105+
<h2>Config Files</h2>
106+
{#if finishedApiCalls == true}
107+
{#if configFiles.length == 0}
108+
<p>No log files found.</p>
109+
{:else}
110+
<ul class="list-disc">
111+
{#each configFiles as configFile}
112+
<li><a href={`/editConfig/${configFile}`}>{configFile}</a></li>
113+
{/each}
114+
</ul>
115+
{/if}
116+
{:else}
117+
<p>Loading...</p>
118+
{/if}
119+
89120
{#if finishedApiCalls}
90121
<h2>Lock Chimes</h2>
91122
{#if lockChimes.length == 0}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { json } from '@sveltejs/kit';
2+
import { configNameToPathMapping } from '$lib/constants';
3+
4+
export async function GET({ request }) {
5+
const configNames = Object.keys(configNameToPathMapping);
6+
return json({ configFiles: configNames });
7+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import type { RequestEvent, RequestHandler } from '@sveltejs/kit';
2+
import { readFileSync, existsSync, unlinkSync } from 'fs';
3+
import fs from 'fs';
4+
import { configNameToPathMapping } from '$lib/constants';
5+
6+
const getConfigContent = (configName: string): string => {
7+
const configPath = configNameToPathMapping[configName];
8+
if (!configPath || !existsSync(configPath)) {
9+
return '';
10+
}
11+
12+
try {
13+
return readFileSync(configPath, 'utf8');
14+
} catch (err) {
15+
console.error(`Error reading file: ${err}`);
16+
return '';
17+
}
18+
};
19+
20+
export const GET: RequestHandler = async (event: RequestEvent) => {
21+
const configName = event.params.configName;
22+
const configContent = configName !== undefined ? getConfigContent(configName) : "";
23+
24+
console.log("configName:",configName, configContent)
25+
26+
return new Response(JSON.stringify({ message: `Config name is: ${configName}`, content: configContent }), {
27+
status: 200,
28+
headers: {
29+
'Content-Type': 'application/json'
30+
}
31+
});
32+
};
33+
34+
export const PUT: RequestHandler = async (event: RequestEvent) => {
35+
// const logName = event.params.logName ?? "";
36+
// const logPath = logNameToPathMapping[logName];
37+
38+
// clearLogFile(logPath);
39+
40+
return new Response(JSON.stringify({ message: `OK` }), {
41+
status: 200,
42+
headers: {
43+
'Content-Type': 'application/json'
44+
}
45+
});
46+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<script lang="ts">
2+
import { onMount } from 'svelte';
3+
import Editor from 'cl-editor/src/Editor.svelte';
4+
import { page } from '$app/stores';
5+
6+
let isLoading = true;
7+
8+
$: configName = $page.params.configName;
9+
10+
async function getConfig(configName: string) {
11+
isLoading = true;
12+
const response = await fetch(`/api/configFiles/${configName}`, {
13+
method: 'GET',
14+
headers: {
15+
'content-type': 'application/text'
16+
}
17+
});
18+
19+
const configContent = await response.json();
20+
// console.log(configContent);
21+
isLoading = false;
22+
return configContent.content;
23+
}
24+
25+
// let json: string = ""
26+
27+
let html = 'Loading content...';
28+
29+
let actions = ['removeFormat'];
30+
let height = 'auto';
31+
32+
const save = () => {
33+
console.log(html);
34+
};
35+
36+
const revert = () => {
37+
console.log('revert');
38+
};
39+
40+
const load = async () => {
41+
console.log('load');
42+
};
43+
44+
onMount(async () => {
45+
console.log('onMount');
46+
let json = await getConfig(configName);
47+
html = json;
48+
});
49+
</script>
50+
51+
<div class="p-2">
52+
{#if html !== 'Loading content...'}
53+
<Editor {html} on:change={(evt) => (html = evt.detail)} {actions} {height} />
54+
{:else}
55+
<p>Loading config...</p>
56+
{/if}
57+
58+
<button class="mt-2 mr-2" on:click={save}>Save</button>
59+
<button class="mt-2 bg-gray-500" on:click={revert}>Revert</button>
60+
</div>

worker/package-lock.json

Lines changed: 18 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

worker/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"sqlite3": "^5.1.6"
2121
},
2222
"devDependencies": {
23+
"@types/node": "^20.10.5",
2324
"@types/ping": "^0.4.4",
2425
"tsup": "^8.0.1",
2526
"typescript": "^5.3.3"

worker/src/index.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,10 @@ import { logWithTimestamp, errorWithTimestamp } from './modules/log.js';
55
import { restartWifi, checkIfArchiveIsReachable } from './modules/network.js';
66
import { mountTeslaCamAsReadOnly, unmountTeslaCam } from './modules/storage.js';
77
import { checkLockChime } from './modules/lockChimes.js';
8+
import { readConfigFile } from './modules/config.js';
89

9-
const config = {
10-
archive: {
11-
server: (getRcloneConfig()).host,
12-
rcloneConfig: "node-teslausb",
13-
destinationPath: "teslausb/TeslaCam"
14-
},
15-
paths: {
16-
sentryClips: "/mnt/TeslaCam/TeslaCam/SentryClips",
17-
savedClips: "/mnt/TeslaCam/TeslaCam/SavedClips",
18-
},
19-
delayBetweenCopyRetryInSeconds: 3600,
20-
mainLoopIntervalInSeconds: 120,
21-
}
10+
const configFilePath = '/config/node-teslausb.json';
11+
const config = await readConfigFile(configFilePath);
2212

2313
interface WorkerState {
2414
errorCount: number;
@@ -39,7 +29,7 @@ const processInterval = async () => {
3929

4030
await checkLockChime();
4131

42-
if (config.archive.server === false) {
32+
if (getRcloneConfig() === false) {
4333
errorWithTimestamp(`rclone config file not found at '/root/.config/rclone/rclone.conf', run 'rclone config' to set up.`);
4434
return;
4535
}

0 commit comments

Comments
 (0)