dashcam 1.3.25 → 1.3.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/dashcam-background.js +39 -25
- package/bin/dashcam.js +35 -73
- package/lib/processManager.js +16 -7
- package/package.json +1 -1
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { startRecording, stopRecording } from '../lib/recorder.js';
|
|
8
|
-
import { upload } from '../lib/uploader.js';
|
|
9
8
|
import { logger, setVerbose } from '../lib/logger.js';
|
|
10
9
|
import fs from 'fs';
|
|
11
10
|
import path from 'path';
|
|
@@ -14,7 +13,7 @@ import os from 'os';
|
|
|
14
13
|
// Use user home directory for cross-session communication
|
|
15
14
|
const PROCESS_DIR = path.join(os.homedir(), '.dashcam-cli');
|
|
16
15
|
const STATUS_FILE = path.join(PROCESS_DIR, 'status.json');
|
|
17
|
-
const RESULT_FILE = path.join(PROCESS_DIR, '
|
|
16
|
+
const RESULT_FILE = path.join(PROCESS_DIR, 'recording-result.json');
|
|
18
17
|
|
|
19
18
|
console.log('[Background INIT] Process directory:', PROCESS_DIR);
|
|
20
19
|
console.log('[Background INIT] Status file:', STATUS_FILE);
|
|
@@ -92,16 +91,24 @@ function writeStatus(status) {
|
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
// Write
|
|
96
|
-
function
|
|
94
|
+
// Write recording result file
|
|
95
|
+
function writeRecordingResult(result) {
|
|
97
96
|
try {
|
|
97
|
+
console.log('[Background] Writing upload result to file:', RESULT_FILE);
|
|
98
|
+
console.log('[Background] Upload result data:', result);
|
|
98
99
|
logger.info('Writing upload result to file', { path: RESULT_FILE, shareLink: result.shareLink });
|
|
99
|
-
|
|
100
|
+
|
|
101
|
+
const resultData = {
|
|
100
102
|
...result,
|
|
101
103
|
timestamp: Date.now()
|
|
102
|
-
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
fs.writeFileSync(RESULT_FILE, JSON.stringify(resultData, null, 2));
|
|
107
|
+
console.log('[Background] Successfully wrote upload result to file');
|
|
108
|
+
console.log('[Background] File exists after write:', fs.existsSync(RESULT_FILE));
|
|
103
109
|
logger.info('Successfully wrote upload result to file');
|
|
104
110
|
} catch (error) {
|
|
111
|
+
console.error('[Background] Failed to write upload result file:', error.message);
|
|
105
112
|
logger.error('Failed to write upload result file', { error });
|
|
106
113
|
}
|
|
107
114
|
}
|
|
@@ -146,7 +153,7 @@ async function runBackgroundRecording() {
|
|
|
146
153
|
pid: process.pid
|
|
147
154
|
});
|
|
148
155
|
|
|
149
|
-
// Set up signal handlers for graceful shutdown
|
|
156
|
+
// Set up signal handlers for graceful shutdown BEFORE entering wait loop
|
|
150
157
|
const handleShutdown = async (signal) => {
|
|
151
158
|
if (isShuttingDown) {
|
|
152
159
|
logger.info('Shutdown already in progress...');
|
|
@@ -155,6 +162,7 @@ async function runBackgroundRecording() {
|
|
|
155
162
|
isShuttingDown = true;
|
|
156
163
|
|
|
157
164
|
logger.info(`Received ${signal}, stopping background recording...`);
|
|
165
|
+
console.log('[Background] Received stop signal, stopping recording...');
|
|
158
166
|
|
|
159
167
|
try {
|
|
160
168
|
// Stop the recording
|
|
@@ -165,28 +173,27 @@ async function runBackgroundRecording() {
|
|
|
165
173
|
outputPath: stopResult.outputPath,
|
|
166
174
|
duration: stopResult.duration
|
|
167
175
|
});
|
|
176
|
+
console.log('[Background] Recording stopped successfully:', {
|
|
177
|
+
outputPath: stopResult.outputPath,
|
|
178
|
+
duration: stopResult.duration
|
|
179
|
+
});
|
|
168
180
|
|
|
169
|
-
//
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
description: options.description || 'Recorded with Dashcam CLI',
|
|
174
|
-
project: options.project || options.k,
|
|
181
|
+
// Write recording result for stop command to upload
|
|
182
|
+
console.log('[Background] Writing recording result for stop command...');
|
|
183
|
+
writeRecordingResult({
|
|
184
|
+
outputPath: stopResult.outputPath,
|
|
175
185
|
duration: stopResult.duration,
|
|
176
186
|
clientStartDate: stopResult.clientStartDate,
|
|
177
187
|
apps: stopResult.apps,
|
|
178
188
|
logs: stopResult.logs,
|
|
179
189
|
gifPath: stopResult.gifPath,
|
|
180
|
-
snapshotPath: stopResult.snapshotPath
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
// Write upload result for stop command to read
|
|
186
|
-
writeUploadResult({
|
|
187
|
-
shareLink: uploadResult.shareLink,
|
|
188
|
-
replayId: uploadResult.replay?.id
|
|
190
|
+
snapshotPath: stopResult.snapshotPath,
|
|
191
|
+
// Include options so stop command can use them for upload
|
|
192
|
+
title: options.title,
|
|
193
|
+
description: options.description,
|
|
194
|
+
project: options.project || options.k
|
|
189
195
|
});
|
|
196
|
+
console.log('[Background] Recording result written successfully');
|
|
190
197
|
}
|
|
191
198
|
|
|
192
199
|
// Update status to indicate recording stopped
|
|
@@ -196,23 +203,27 @@ async function runBackgroundRecording() {
|
|
|
196
203
|
pid: process.pid
|
|
197
204
|
});
|
|
198
205
|
|
|
206
|
+
console.log('[Background] Background process exiting successfully');
|
|
199
207
|
logger.info('Background process exiting successfully');
|
|
200
208
|
process.exit(0);
|
|
201
209
|
} catch (error) {
|
|
210
|
+
console.error('[Background] Error during shutdown:', error.message);
|
|
202
211
|
logger.error('Error during shutdown:', error);
|
|
203
212
|
process.exit(1);
|
|
204
213
|
}
|
|
205
214
|
};
|
|
206
215
|
|
|
216
|
+
// Register signal handlers
|
|
207
217
|
process.on('SIGINT', () => handleShutdown('SIGINT'));
|
|
208
218
|
process.on('SIGTERM', () => handleShutdown('SIGTERM'));
|
|
209
219
|
|
|
210
|
-
// Keep the process alive
|
|
220
|
+
// Keep the process alive - wait indefinitely for signals
|
|
211
221
|
logger.info('Background recording is now running. Waiting for stop signal...');
|
|
212
|
-
|
|
222
|
+
console.log('[Background] Waiting for stop signal...');
|
|
213
223
|
|
|
214
224
|
} catch (error) {
|
|
215
|
-
logger.error('Background recording failed:', error);
|
|
225
|
+
logger.error('Background recording setup failed:', error);
|
|
226
|
+
console.error('[Background] Recording setup failed:', error.message);
|
|
216
227
|
|
|
217
228
|
// Update status to indicate failure
|
|
218
229
|
writeStatus({
|
|
@@ -223,6 +234,9 @@ async function runBackgroundRecording() {
|
|
|
223
234
|
|
|
224
235
|
process.exit(1);
|
|
225
236
|
}
|
|
237
|
+
|
|
238
|
+
// Infinite loop - process will only exit via signal handlers
|
|
239
|
+
await new Promise(() => {});
|
|
226
240
|
}
|
|
227
241
|
|
|
228
242
|
// Run the background recording
|
package/bin/dashcam.js
CHANGED
|
@@ -469,94 +469,56 @@ program
|
|
|
469
469
|
console.log('Recording stopped successfully');
|
|
470
470
|
logger.debug('Stop result:', result);
|
|
471
471
|
|
|
472
|
-
// Wait for
|
|
473
|
-
logger.debug('Waiting for
|
|
474
|
-
console.log('
|
|
472
|
+
// Wait for background process to write recording result
|
|
473
|
+
logger.debug('Waiting for recording result from background process...');
|
|
474
|
+
console.log('Waiting for recording result...');
|
|
475
475
|
|
|
476
|
-
// Wait up to
|
|
477
|
-
const
|
|
478
|
-
const
|
|
479
|
-
let
|
|
476
|
+
// Wait up to 30 seconds for recording result to appear
|
|
477
|
+
const maxWaitForResult = 30000;
|
|
478
|
+
const startWaitForResult = Date.now();
|
|
479
|
+
let recordingResult = null;
|
|
480
480
|
let checkCount = 0;
|
|
481
481
|
|
|
482
|
-
while (!
|
|
483
|
-
|
|
482
|
+
while (!recordingResult && (Date.now() - startWaitForResult) < maxWaitForResult) {
|
|
483
|
+
recordingResult = processManager.readRecordingResult();
|
|
484
484
|
checkCount++;
|
|
485
485
|
|
|
486
|
-
if (!
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
logger.debug(`Still waiting for background upload... (${elapsed}s elapsed)`);
|
|
491
|
-
console.log(`Waiting for background upload... (${elapsed}s)`);
|
|
486
|
+
if (!recordingResult) {
|
|
487
|
+
if (checkCount % 5 === 0) {
|
|
488
|
+
const elapsed = Math.round((Date.now() - startWaitForResult) / 1000);
|
|
489
|
+
console.log(`Waiting for recording result... (${elapsed}s)`);
|
|
492
490
|
}
|
|
493
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
491
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
494
492
|
}
|
|
495
493
|
}
|
|
496
494
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
timeElapsed: Math.round((Date.now() - startWaitForUpload) / 1000) + 's'
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
if (uploadResult && uploadResult.shareLink) {
|
|
505
|
-
console.log('Watch your recording:', uploadResult.shareLink);
|
|
506
|
-
logger.info('Background process upload succeeded');
|
|
507
|
-
// Clean up the result file now that we've read it
|
|
508
|
-
processManager.cleanup();
|
|
509
|
-
process.exit(0);
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
logger.debug('No upload result from background process, checking files...');
|
|
513
|
-
|
|
514
|
-
// Check if files still exist - if not, background process already uploaded
|
|
515
|
-
const videoExists = fs.existsSync(result.outputPath);
|
|
516
|
-
const gifExists = !result.gifPath || fs.existsSync(result.gifPath);
|
|
517
|
-
const snapshotExists = !result.snapshotPath || fs.existsSync(result.snapshotPath);
|
|
518
|
-
|
|
519
|
-
logger.debug('File existence check:', {
|
|
520
|
-
video: videoExists,
|
|
521
|
-
gif: gifExists,
|
|
522
|
-
snapshot: snapshotExists,
|
|
523
|
-
outputPath: result.outputPath,
|
|
524
|
-
gifPath: result.gifPath,
|
|
525
|
-
snapshotPath: result.snapshotPath
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
const filesExist = videoExists && gifExists && snapshotExists;
|
|
529
|
-
|
|
530
|
-
if (!filesExist) {
|
|
531
|
-
console.log('Recording appears to be uploaded by background process (files deleted)');
|
|
532
|
-
logger.info('Files were cleaned up by background process, assuming upload succeeded');
|
|
533
|
-
process.exit(0);
|
|
495
|
+
if (!recordingResult || !recordingResult.outputPath) {
|
|
496
|
+
console.error('Failed to get recording result from background process');
|
|
497
|
+
logger.error('No recording result received', { recordingResult });
|
|
498
|
+
process.exit(1);
|
|
534
499
|
}
|
|
535
500
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
logger.debug('Starting foreground upload with metadata:', {
|
|
539
|
-
title: activeStatus?.options?.title,
|
|
540
|
-
project: activeStatus?.options?.project,
|
|
541
|
-
duration: result.duration,
|
|
542
|
-
outputPath: result.outputPath
|
|
543
|
-
});
|
|
501
|
+
console.log('Recording result received, uploading...');
|
|
502
|
+
logger.debug('Recording result:', recordingResult);
|
|
544
503
|
|
|
545
504
|
try {
|
|
546
|
-
const uploadResult = await upload(
|
|
547
|
-
title: activeStatus?.options?.title,
|
|
548
|
-
description: activeStatus?.options?.description,
|
|
549
|
-
project: activeStatus?.options?.project,
|
|
550
|
-
duration:
|
|
551
|
-
clientStartDate:
|
|
552
|
-
apps:
|
|
553
|
-
|
|
554
|
-
gifPath:
|
|
555
|
-
snapshotPath:
|
|
505
|
+
const uploadResult = await upload(recordingResult.outputPath, {
|
|
506
|
+
title: recordingResult.title || activeStatus?.options?.title || 'Dashcam Recording',
|
|
507
|
+
description: recordingResult.description || activeStatus?.options?.description,
|
|
508
|
+
project: recordingResult.project || activeStatus?.options?.project,
|
|
509
|
+
duration: recordingResult.duration,
|
|
510
|
+
clientStartDate: recordingResult.clientStartDate,
|
|
511
|
+
apps: recordingResult.apps,
|
|
512
|
+
logs: recordingResult.logs,
|
|
513
|
+
gifPath: recordingResult.gifPath,
|
|
514
|
+
snapshotPath: recordingResult.snapshotPath
|
|
556
515
|
});
|
|
557
516
|
|
|
558
517
|
console.log('Watch your recording:', uploadResult.shareLink);
|
|
559
|
-
logger.info('
|
|
518
|
+
logger.info('Upload succeeded');
|
|
519
|
+
|
|
520
|
+
// Clean up the result file
|
|
521
|
+
processManager.cleanup();
|
|
560
522
|
} catch (uploadError) {
|
|
561
523
|
console.error('Upload failed:', uploadError.message);
|
|
562
524
|
logger.error('Upload error details:', {
|
|
@@ -565,7 +527,7 @@ program
|
|
|
565
527
|
code: uploadError.code,
|
|
566
528
|
statusCode: uploadError.response?.statusCode
|
|
567
529
|
});
|
|
568
|
-
console.log('Recording saved locally:',
|
|
530
|
+
console.log('Recording saved locally:', recordingResult.outputPath);
|
|
569
531
|
}
|
|
570
532
|
} catch (error) {
|
|
571
533
|
console.error('Failed to stop recording:', error.message);
|
package/lib/processManager.js
CHANGED
|
@@ -11,7 +11,7 @@ const __dirname = path.dirname(__filename);
|
|
|
11
11
|
// Use user home directory for cross-session communication
|
|
12
12
|
const PROCESS_DIR = path.join(os.homedir(), '.dashcam-cli');
|
|
13
13
|
const STATUS_FILE = path.join(PROCESS_DIR, 'status.json');
|
|
14
|
-
const RESULT_FILE = path.join(PROCESS_DIR, '
|
|
14
|
+
const RESULT_FILE = path.join(PROCESS_DIR, 'recording-result.json');
|
|
15
15
|
|
|
16
16
|
console.log('[INIT] Process Manager initialized');
|
|
17
17
|
console.log('[INIT] Process directory:', PROCESS_DIR);
|
|
@@ -118,9 +118,9 @@ class ProcessManager {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
writeRecordingResult(result) {
|
|
122
122
|
try {
|
|
123
|
-
logger.info('Writing
|
|
123
|
+
logger.info('Writing recording result to file', { path: RESULT_FILE });
|
|
124
124
|
fs.writeFileSync(RESULT_FILE, JSON.stringify({
|
|
125
125
|
...result,
|
|
126
126
|
timestamp: Date.now()
|
|
@@ -137,13 +137,22 @@ class ProcessManager {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
readRecordingResult() {
|
|
141
141
|
try {
|
|
142
|
-
|
|
142
|
+
console.log('[ProcessManager] Checking for recording result file:', RESULT_FILE);
|
|
143
|
+
const exists = fs.existsSync(RESULT_FILE);
|
|
144
|
+
console.log('[ProcessManager] Recording result file exists:', exists);
|
|
145
|
+
|
|
146
|
+
if (!exists) return null;
|
|
147
|
+
|
|
143
148
|
const data = fs.readFileSync(RESULT_FILE, 'utf8');
|
|
144
|
-
|
|
149
|
+
console.log('[ProcessManager] Recording result file contents:', data);
|
|
150
|
+
const result = JSON.parse(data);
|
|
151
|
+
console.log('[ProcessManager] Parsed recording result:', result);
|
|
152
|
+
return result;
|
|
145
153
|
} catch (error) {
|
|
146
|
-
|
|
154
|
+
console.error('[ProcessManager] Failed to read recording result file:', error.message);
|
|
155
|
+
logger.error('Failed to read recording result file', { error });
|
|
147
156
|
return null;
|
|
148
157
|
}
|
|
149
158
|
}
|