mirror of
https://github.com/samuelthomas2774/nxapi.git
synced 2026-10-22 17:44:36 -05:00
Add command/menu item to export log files
This commit is contained in:
@@ -69,7 +69,7 @@ export const menus = {
|
||||
friend: {
|
||||
presence_online: 'Online',
|
||||
game_first_played: 'Zuerst gespielt: {{date, datetime}}',
|
||||
|
||||
|
||||
game_play_time_h: 'Spielzeit: $t(friend.hours, {"count": {{hours}}})',
|
||||
game_play_time_hm: 'Spielzeit: $t(friend.hours, {"count": {{hours}}}), $t(friend.minutes, {"count": {{minutes}}})',
|
||||
game_play_time_m: 'Spielzeit: $t(friend.minutes, {"count": {{minutes}}})',
|
||||
@@ -109,7 +109,7 @@ export const na_auth = {
|
||||
|
||||
text: `Um Zugriff auf die API der Nintendo Switch Online App zu erhalten, muss nxapi einige Daten an Drittanbieter-APIs senden. Dieser Schritt wird benötigt, um Daten zu generieren, damit Nintendo denkt, dass du die echte Nintendo Switch Online App verwendest.
|
||||
Standardmäßig wird nxapi-znca-api.fancy.org.uk oder api.imink.app benutzt. Ein anderer Service kann ebenfalls benutzt werden, indem eine Umgebungsvariable gesetzt wird. Die standardmäßige API könnte sich jederzeit ohne Hinweis ändern, wenn du keinen spezifischen Service erzwingst.
|
||||
|
||||
|
||||
Die gesendeten Daten beinhalten:
|
||||
|
||||
- Deine Nintendo Account ID
|
||||
|
||||
@@ -14,6 +14,7 @@ export const app_menu = {
|
||||
learn_more: 'Learn More',
|
||||
learn_more_github: 'Learn More (GitHub)',
|
||||
search_issues: 'Search Issues',
|
||||
export_logs: 'Export Logs',
|
||||
|
||||
refresh: 'Refresh',
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@ import { i18n } from 'i18next';
|
||||
import { GITHUB_MIRROR_URL, GITLAB_URL, ISSUES_URL } from '../../common/constants.js';
|
||||
import { app, BrowserWindow, Menu, MenuItem, shell } from 'electron';
|
||||
import { App } from './index.js';
|
||||
import { createLogArchive } from './support.js';
|
||||
|
||||
let appinstance: App | null;
|
||||
|
||||
@@ -59,6 +60,12 @@ function createAppMenuItems(i18n?: i18n) {
|
||||
await shell.openExternal(ISSUES_URL);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n?.t('app_menu:export_logs') ?? 'Export Logs',
|
||||
click: () => {
|
||||
createLogArchive();
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ function buildUserMenu(app: App, user: NintendoAccountUser, nso?: CurrentUser, m
|
||||
new MenuItem({label: t('discord_disable')!,
|
||||
click: () => app.menu?.setActiveDiscordPresenceUser(null)}),
|
||||
] : monitor?.presence_user ? [
|
||||
new MenuItem({label: t('discord_enabled_for', {name:
|
||||
new MenuItem({label: t('discord_enabled_for', {name:
|
||||
monitor.user?.friends.result.friends.find(f => f.nsaId === monitor.presence_user)?.name ??
|
||||
monitor.presence_user})!,
|
||||
enabled: false}),
|
||||
|
||||
88
src/app/main/support.ts
Normal file
88
src/app/main/support.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { Buffer } from 'node:buffer';
|
||||
import { createWriteStream, WriteStream } from 'node:fs';
|
||||
import { app, dialog, Notification, shell } from 'electron';
|
||||
import createDebug from '../../util/debug.js';
|
||||
import { generateEncryptedLogArchive } from '../../util/support.js';
|
||||
import { join } from 'node:path';
|
||||
import { showErrorDialog } from './util.js';
|
||||
|
||||
const debug = createDebug('app:main:support');
|
||||
|
||||
export async function createLogArchive() {
|
||||
let start_notification: Notification | null = null;
|
||||
|
||||
try {
|
||||
const { default: config } = await import('../../common/remote-config.js');
|
||||
|
||||
if (!config.log_encryption_key) {
|
||||
throw new Error('No log encryption key in remote configuration');
|
||||
}
|
||||
|
||||
const default_name = 'nxapi-logs-' +
|
||||
new Date().toISOString().replace(/[-:Z]/g, '').replace(/\.\d+/, '').replace(/T/, '-') +
|
||||
'.tar.gz';
|
||||
|
||||
const result = await dialog.showSaveDialog({
|
||||
defaultPath: join(app.getPath('downloads'), default_name),
|
||||
filters: [{name: 'Tape archive (encrypted)', extensions: ['tgz', 'tar.gz']}],
|
||||
});
|
||||
|
||||
if (result.canceled) return;
|
||||
|
||||
const out = await createOutputStream(result.filePath);
|
||||
|
||||
debug('creating log archive');
|
||||
|
||||
start_notification = new Notification({
|
||||
title: 'Creating log archive',
|
||||
});
|
||||
start_notification.show();
|
||||
|
||||
const key = Buffer.from(config.log_encryption_key, 'base64url');
|
||||
const [encrypt] = await generateEncryptedLogArchive(key);
|
||||
|
||||
encrypt.pipe(out);
|
||||
|
||||
await new Promise((rs, rj) => {
|
||||
encrypt.on('end', rs);
|
||||
encrypt.on('error', rj);
|
||||
});
|
||||
|
||||
debug('done');
|
||||
|
||||
start_notification.close();
|
||||
|
||||
new Notification({
|
||||
title: 'Created log archive',
|
||||
}).show();
|
||||
|
||||
shell.showItemInFolder(result.filePath);
|
||||
} catch (err) {
|
||||
start_notification?.close();
|
||||
|
||||
showErrorDialog({
|
||||
message: 'Error creating log archive',
|
||||
error: err,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function createOutputStream(path: string) {
|
||||
return new Promise<WriteStream>((rs, rj) => {
|
||||
const out = createWriteStream(path);
|
||||
|
||||
const onready = () => {
|
||||
out.removeListener('ready', onready);
|
||||
out.removeListener('error', onerror);
|
||||
rs(out);
|
||||
};
|
||||
const onerror = () => {
|
||||
out.removeListener('ready', onready);
|
||||
out.removeListener('error', onerror);
|
||||
rs(out);
|
||||
};
|
||||
|
||||
out.on('ready', onready);
|
||||
out.on('error', onerror);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user