85 lines
3.4 KiB
JavaScript
85 lines
3.4 KiB
JavaScript
const { execFile, execFileSync, execSync } = require('child_process');
|
|
const util = require('util');
|
|
const fs = require('fs');
|
|
const execFileAsync = util.promisify(execFile);
|
|
|
|
const SCRIPTS = {
|
|
spotify_play: 'tell application "Spotify" to play',
|
|
spotify_pause: 'tell application "Spotify" to pause',
|
|
spotify_next: 'tell application "Spotify" to next track',
|
|
spotify_prev: 'tell application "Spotify" to previous track',
|
|
music_play: 'tell application "Music" to play',
|
|
music_pause: 'tell application "Music" to pause',
|
|
music_next: 'tell application "Music" to next track',
|
|
mail_open: 'tell application "Mail" to activate',
|
|
mail_unread: 'tell application "Mail" to return (count of (messages of inbox whose read status is false))',
|
|
calendar_open: 'tell application "Calendar" to activate',
|
|
notes_open: 'tell application "Notes" to activate',
|
|
volume_up: 'set volume output volume (output volume of (get volume settings) + 10)',
|
|
volume_down: 'set volume output volume (output volume of (get volume settings) - 10)',
|
|
volume_mute: 'set volume output muted true',
|
|
volume_unmute: 'set volume output muted false',
|
|
dark_mode_on: 'tell app "System Events" to tell appearance preferences to set dark mode to true',
|
|
dark_mode_off: 'tell app "System Events" to tell appearance preferences to set dark mode to false',
|
|
screenshot: 'do shell script "screencapture -x ~/Desktop/fox-screenshot-$(date +%Y%m%d-%H%M%S).png"',
|
|
};
|
|
|
|
function resolveCommand(command) {
|
|
if (SCRIPTS[command]) {
|
|
return { type: 'applescript', script: SCRIPTS[command] };
|
|
}
|
|
if (command.startsWith('script:')) {
|
|
return { type: 'applescript', script: command.slice(7) };
|
|
}
|
|
if (command.startsWith('open:')) {
|
|
return { type: 'open', url: command.slice(5) };
|
|
}
|
|
if (command.startsWith('app:')) {
|
|
return { type: 'app', name: command.slice(4) };
|
|
}
|
|
if (command.startsWith('save:')) {
|
|
try {
|
|
return { type: 'save', ...JSON.parse(command.slice(5)) };
|
|
} catch {
|
|
return { type: 'unknown' };
|
|
}
|
|
}
|
|
return { type: 'unknown' };
|
|
}
|
|
|
|
async function executeMacCommand(command) {
|
|
try {
|
|
const resolved = resolveCommand(command);
|
|
|
|
if (resolved.type === 'applescript') {
|
|
const { stdout } = await execFileAsync('osascript', ['-e', resolved.script]);
|
|
return { success: true, output: stdout.trim() };
|
|
}
|
|
if (resolved.type === 'open') {
|
|
execFileSync('open', [resolved.url]);
|
|
return { success: true, output: 'Geöffnet' };
|
|
}
|
|
if (resolved.type === 'app') {
|
|
execFileSync('open', ['-a', resolved.name]);
|
|
return { success: true, output: `${resolved.name} geöffnet` };
|
|
}
|
|
if (resolved.type === 'save') {
|
|
if (resolved.filename.includes('/') || resolved.filename.includes('\\')) {
|
|
return { success: false, output: 'Ungültiger Dateiname' };
|
|
}
|
|
if (typeof resolved.content === 'string' && resolved.content.length > 10 * 1024 * 1024) {
|
|
return { success: false, output: 'Inhalt zu groß (max. 10 MB)' };
|
|
}
|
|
const filePath = `${process.env.HOME}/Desktop/${resolved.filename}`;
|
|
fs.writeFileSync(filePath, resolved.content, 'utf8');
|
|
return { success: true, output: `Gespeichert: ${filePath}` };
|
|
}
|
|
return { success: false, output: 'Unbekannter Befehl' };
|
|
|
|
} catch (err) {
|
|
return { success: false, output: err.message };
|
|
}
|
|
}
|
|
|
|
module.exports = { executeMacCommand, resolveCommand, SCRIPTS };
|