From 4291a3d6483808c14d76821859e023708ce775ef Mon Sep 17 00:00:00 2001 From: Ruby Iris Juric Date: Sun, 25 May 2025 23:27:23 +1000 Subject: [PATCH] add mediaDirectory config option to configure location of uploaded media --- .config/ci.yml | 4 ++++ .config/cypress-devcontainer.yml | 4 ++++ .config/docker_example.yml | 4 ++++ .config/example.yml | 4 ++++ .devcontainer/devcontainer.yml | 4 ++++ packages/backend/src/config.ts | 5 ++++- packages/backend/src/core/InternalStorageService.ts | 11 ++--------- 7 files changed, 26 insertions(+), 10 deletions(-) diff --git a/.config/ci.yml b/.config/ci.yml index 4a6d21e1d5..5657b8beae 100644 --- a/.config/ci.yml +++ b/.config/ci.yml @@ -297,6 +297,10 @@ proxyBypassHosts: #proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4 #proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5 +# Path to the directory that uploaded media will be saved to +# Defaults to a folder called "files" in the Sharkey directory +#mediaDirectory: /var/lib/sharkey + # Media Proxy #mediaProxy: https://example.com/proxy diff --git a/.config/cypress-devcontainer.yml b/.config/cypress-devcontainer.yml index 356d583611..ca62616462 100644 --- a/.config/cypress-devcontainer.yml +++ b/.config/cypress-devcontainer.yml @@ -260,6 +260,10 @@ proxyBypassHosts: #proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4 #proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5 +# Path to the directory that uploaded media will be saved to +# Defaults to a folder called "files" in the Sharkey directory +#mediaDirectory: /var/lib/sharkey + # Media Proxy #mediaProxy: https://example.com/proxy diff --git a/.config/docker_example.yml b/.config/docker_example.yml index 68679f64ed..df5d77a97f 100644 --- a/.config/docker_example.yml +++ b/.config/docker_example.yml @@ -351,6 +351,10 @@ proxyBypassHosts: #proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4 #proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5 +# Path to the directory that uploaded media will be saved to +# Defaults to a folder called "files" in the Sharkey directory +#mediaDirectory: /var/lib/sharkey + # Media Proxy # Reference Implementation: https://github.com/misskey-dev/media-proxy # * Deliver a common cache between instances diff --git a/.config/example.yml b/.config/example.yml index 9cb1e656c1..9e2b6d6da5 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -354,6 +354,10 @@ proxyBypassHosts: #proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4 #proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5 +# Path to the directory that uploaded media will be saved to +# Defaults to a folder called "files" in the Sharkey directory +#mediaDirectory: /var/lib/sharkey + # Media Proxy # Reference Implementation: https://github.com/misskey-dev/media-proxy # * Deliver a common cache between instances diff --git a/.devcontainer/devcontainer.yml b/.devcontainer/devcontainer.yml index 6d904e87b9..1f8192101b 100644 --- a/.devcontainer/devcontainer.yml +++ b/.devcontainer/devcontainer.yml @@ -199,6 +199,10 @@ proxyBypassHosts: #proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4 #proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5 +# Path to the directory that uploaded media will be saved to +# Defaults to a folder called "files" in the Sharkey directory +#mediaDirectory: /var/lib/sharkey + # Media Proxy #mediaProxy: https://example.com/proxy diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts index e02f09bbe1..392ce09142 100644 --- a/packages/backend/src/config.ts +++ b/packages/backend/src/config.ts @@ -111,6 +111,7 @@ type Source = { deliverJobMaxAttempts?: number; inboxJobMaxAttempts?: number; + mediaDirectory?: string; mediaProxy?: string; proxyRemoteFiles?: boolean; videoThumbnailGenerator?: string; @@ -297,6 +298,7 @@ export type Config = { frontendManifestExists: boolean; frontendEmbedEntry: string; frontendEmbedManifestExists: boolean; + mediaDirectory: string; mediaProxy: string; externalMediaProxyEnabled: boolean; videoThumbnailGenerator: string | null; @@ -463,6 +465,7 @@ export function loadConfig(): Config { signToActivityPubGet: config.signToActivityPubGet ?? true, attachLdSignatureForRelays: config.attachLdSignatureForRelays ?? true, checkActivityPubGetSignature: config.checkActivityPubGetSignature, + mediaDirectory: config.mediaDirectory ?? resolve(_dirname, '../../../files'), mediaProxy: externalMediaProxy ?? internalMediaProxy, externalMediaProxyEnabled: externalMediaProxy !== null && externalMediaProxy !== internalMediaProxy, videoThumbnailGenerator: config.videoThumbnailGenerator ? @@ -638,7 +641,7 @@ function applyEnvOverrides(config: Source) { _apply_top(['sentryForFrontend', 'vueIntegration', 'tracingOptions', 'timeout']); _apply_top(['sentryForFrontend', 'browserTracingIntegration', 'routeLabel']); _apply_top([['clusterLimit', 'deliverJobConcurrency', 'inboxJobConcurrency', 'relashionshipJobConcurrency', 'deliverJobPerSec', 'inboxJobPerSec', 'relashionshipJobPerSec', 'deliverJobMaxAttempts', 'inboxJobMaxAttempts']]); - _apply_top([['outgoingAddress', 'outgoingAddressFamily', 'proxy', 'proxySmtp', 'mediaProxy', 'proxyRemoteFiles', 'videoThumbnailGenerator']]); + _apply_top([['outgoingAddress', 'outgoingAddressFamily', 'proxy', 'proxySmtp', 'mediaDirectory', 'mediaProxy', 'proxyRemoteFiles', 'videoThumbnailGenerator']]); _apply_top([['maxFileSize', 'maxNoteLength', 'maxRemoteNoteLength', 'maxAltTextLength', 'maxRemoteAltTextLength', 'pidFile', 'filePermissionBits']]); _apply_top(['import', ['downloadTimeout', 'maxFileSize']]); _apply_top([['signToActivityPubGet', 'checkActivityPubGetSignature', 'setupPassword', 'disallowExternalApRedirect']]); diff --git a/packages/backend/src/core/InternalStorageService.ts b/packages/backend/src/core/InternalStorageService.ts index b00c5796d2..abdbbc61d3 100644 --- a/packages/backend/src/core/InternalStorageService.ts +++ b/packages/backend/src/core/InternalStorageService.ts @@ -6,18 +6,11 @@ import * as fs from 'node:fs'; import { copyFile, unlink, writeFile, chmod } from 'node:fs/promises'; import * as Path from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { dirname } from 'node:path'; import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import { bindThis } from '@/decorators.js'; -const _filename = fileURLToPath(import.meta.url); -const _dirname = dirname(_filename); - -const path = Path.resolve(_dirname, '../../../../files'); - @Injectable() export class InternalStorageService { constructor( @@ -25,12 +18,12 @@ export class InternalStorageService { private config: Config, ) { // No one should erase the working directory *while the server is running*. - fs.mkdirSync(path, { recursive: true }); + fs.mkdirSync(this.config.mediaDirectory, { recursive: true }); } @bindThis public resolvePath(key: string) { - return Path.resolve(path, key); + return Path.resolve(this.config.mediaDirectory, key); } @bindThis