Sessions leave redacted logs; viewers wait for a member relay's source before opening it
Logs: one redaction pass (query strings to names, member tokens,
passwords, cookies, auth headers) for every line; daily files with size
and age caps in the app (hosted server included) and the dedicated
server (--log-dir); swaps, relay channels, per-member /r /m /j outcomes,
server fetches, mpv load errors, yt-dlp runs. Settings > About: Copy
diagnostics, Open logs folder.
Bilibili through someone else: the viewer opened /r/ before the source
dialled in; the server holds that request and mpv gives up after 5 s
("could not be opened"). Viewers now open a member relay once it is
live, the putter starts its source before its own player, and track
sizes are read in parallel.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
572104f49e
commit
4ab37c55cf
25 files changed
+1124
-108
No files matched your search
@@ -15,15 +15,19 @@ import 'session.dart';
|
||||
/// [configured], else systemd's `$STATE_DIRECTORY/yt-dlp`, else `yt-dlp`
|
||||
/// next to the server binary when that is writable (not under `dart run`),
|
||||
/// else `~/.cache/watch-together/yt-dlp`.
|
||||
String serverYtDlpDir(String configured) {
|
||||
if (configured.isNotEmpty) return configured;
|
||||
String serverYtDlpDir(String configured) => configured.isNotEmpty ? configured : serverDataDir('yt-dlp');
|
||||
|
||||
/// A writable folder [name] for the dedicated server's own files:
|
||||
/// `$STATE_DIRECTORY/<name>` (systemd), else next to the binary if
|
||||
/// writable, else `~/.cache/watch-together/<name>`.
|
||||
String serverDataDir(String name) {
|
||||
final sep = Platform.pathSeparator;
|
||||
final state = (Platform.environment['STATE_DIRECTORY'] ?? '').split(':').first;
|
||||
if (state.isNotEmpty) return '$state${sep}yt-dlp';
|
||||
if (state.isNotEmpty) return '$state$sep$name';
|
||||
final exe = File(Platform.resolvedExecutable);
|
||||
final name = exe.uri.pathSegments.last.toLowerCase();
|
||||
if (name != 'dart' && name != 'dart.exe' && name != 'dartaotruntime') {
|
||||
final dir = Directory('${exe.parent.path}${sep}yt-dlp');
|
||||
final exeName = exe.uri.pathSegments.last.toLowerCase();
|
||||
if (exeName != 'dart' && exeName != 'dart.exe' && exeName != 'dartaotruntime') {
|
||||
final dir = Directory('${exe.parent.path}$sep$name');
|
||||
try {
|
||||
dir.createSync(recursive: true);
|
||||
final probe = File('${dir.path}$sep.writable')..writeAsStringSync('');
|
||||
@@ -32,7 +36,7 @@ String serverYtDlpDir(String configured) {
|
||||
} catch (_) {}
|
||||
}
|
||||
final home = Platform.environment['HOME'] ?? Platform.environment['USERPROFILE'] ?? '.';
|
||||
return '$home$sep.cache${sep}watch-together${sep}yt-dlp';
|
||||
return '$home$sep.cache${sep}watch-together$sep$name';
|
||||
}
|
||||
|
||||
class SyncServer {
|
||||
@@ -93,12 +97,15 @@ class SyncServer {
|
||||
})),
|
||||
);
|
||||
});
|
||||
mountSessionMediaRoute(_app, sessions);
|
||||
mountRelayRoutes(_app, sessions, relayAt: hub.relayAt, sourceOf: hub.sourceOf);
|
||||
final requests = MediaRequestLog();
|
||||
void logRequest(String token, MediaLog log) => requests(hub.who(token), log);
|
||||
mountSessionMediaRoute(_app, sessions, onLog: logRequest);
|
||||
mountRelayRoutes(_app, sessions, relayAt: hub.relayAt, sourceOf: hub.sourceOf, onLog: logRequest);
|
||||
mountAvatarRoute(_app, hub);
|
||||
mountArtRoute(_app, hub);
|
||||
mountJellyfinRelayRoute(
|
||||
_app, sessions, () => hub.jellyfin, () => _relayClient ??= HttpClient(), next: () => hub.nextJellyfinRef);
|
||||
_app, sessions, () => hub.jellyfin, () => _relayClient ??= HttpClient(),
|
||||
next: () => hub.nextJellyfinRef, onLog: logRequest);
|
||||
// advertiseHost is only an explicit override; otherwise echo what the client dialled.
|
||||
String authority(String dialledHost) => config.advertiseHost.isNotEmpty
|
||||
? '${config.advertiseHost}:$boundPort'
|
||||
|
||||
Reference in new issue
Block a user