mirror of
https://github.com/imgfloat/server.git
synced 2026-02-05 03:39:26 +00:00
Configurable filesystem paths
This commit is contained in:
26
README.md
26
README.md
@@ -50,6 +50,32 @@ make docker-build
|
||||
TWITCH_CLIENT_ID=your_id TWITCH_CLIENT_SECRET=your_secret docker run -p 8080:8080 imgfloat:latest
|
||||
```
|
||||
|
||||
### Data storage configuration
|
||||
- `IMGFLOAT_DB_PATH` – filesystem location for the SQLite database (default: `imgfloat.db`).
|
||||
- `IMGFLOAT_ASSETS_PATH` – root directory where uploaded assets are persisted (default: `assets`).
|
||||
- `IMGFLOAT_PREVIEWS_PATH` – root directory for generated preview images (default: `previews`).
|
||||
|
||||
### Docker Compose example with persistent storage
|
||||
```yaml
|
||||
services:
|
||||
imgfloat:
|
||||
image: imgfloat:latest
|
||||
environment:
|
||||
TWITCH_CLIENT_ID: your_id
|
||||
TWITCH_CLIENT_SECRET: your_secret
|
||||
TWITCH_REDIRECT_URI: https://yourdomain/login/oauth2/code/twitch
|
||||
IMGFLOAT_DB_PATH: /var/lib/imgfloat/imgfloat.db
|
||||
IMGFLOAT_ASSETS_PATH: /var/lib/imgfloat/assets
|
||||
IMGFLOAT_PREVIEWS_PATH: /var/lib/imgfloat/previews
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ./data/db:/var/lib/imgfloat
|
||||
- ./data/assets:/var/lib/imgfloat/assets
|
||||
- ./data/previews:/var/lib/imgfloat/previews
|
||||
```
|
||||
The `volumes` map local folders into the container so database and uploaded files survive container restarts.
|
||||
|
||||
### OAuth configuration
|
||||
Spring Boot reads Twitch credentials from `TWITCH_CLIENT_ID` and `TWITCH_CLIENT_SECRET`. The redirect URI comes from `TWITCH_REDIRECT_URI` (defaulting to `{baseUrl}/login/oauth2/code/twitch`).
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.jcodec.common.model.Picture;
|
||||
import org.jcodec.scale.AWTUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@@ -57,19 +58,23 @@ import org.w3c.dom.NodeList;
|
||||
public class ChannelDirectoryService {
|
||||
private static final int MIN_GIF_DELAY_MS = 20;
|
||||
private static final String PREVIEW_MEDIA_TYPE = "image/png";
|
||||
private static final Path ASSET_ROOT = Paths.get("assets");
|
||||
private static final Path PREVIEW_ROOT = Paths.get("previews");
|
||||
private static final Logger logger = LoggerFactory.getLogger(ChannelDirectoryService.class);
|
||||
private final ChannelRepository channelRepository;
|
||||
private final AssetRepository assetRepository;
|
||||
private final SimpMessagingTemplate messagingTemplate;
|
||||
private final Path assetRoot;
|
||||
private final Path previewRoot;
|
||||
|
||||
public ChannelDirectoryService(ChannelRepository channelRepository,
|
||||
AssetRepository assetRepository,
|
||||
SimpMessagingTemplate messagingTemplate) {
|
||||
SimpMessagingTemplate messagingTemplate,
|
||||
@Value("${IMGFLOAT_ASSETS_PATH:assets}") String assetRoot,
|
||||
@Value("${IMGFLOAT_PREVIEWS_PATH:previews}") String previewRoot) {
|
||||
this.channelRepository = channelRepository;
|
||||
this.assetRepository = assetRepository;
|
||||
this.messagingTemplate = messagingTemplate;
|
||||
this.assetRoot = Paths.get(assetRoot);
|
||||
this.previewRoot = Paths.get(previewRoot);
|
||||
}
|
||||
|
||||
public Channel getOrCreateChannel(String broadcaster) {
|
||||
@@ -408,7 +413,7 @@ public class ChannelDirectoryService {
|
||||
if (assetBytes == null || assetBytes.length == 0) {
|
||||
throw new IOException("Asset content is empty");
|
||||
}
|
||||
Path directory = ASSET_ROOT.resolve(normalize(broadcaster));
|
||||
Path directory = assetRoot.resolve(normalize(broadcaster));
|
||||
Files.createDirectories(directory);
|
||||
String extension = extensionForMediaType(mediaType);
|
||||
Path assetFile = directory.resolve(assetId + extension);
|
||||
@@ -460,7 +465,7 @@ public class ChannelDirectoryService {
|
||||
if (previewBytes == null || previewBytes.length == 0) {
|
||||
return null;
|
||||
}
|
||||
Path directory = PREVIEW_ROOT.resolve(normalize(broadcaster));
|
||||
Path directory = previewRoot.resolve(normalize(broadcaster));
|
||||
Files.createDirectories(directory);
|
||||
Path previewFile = directory.resolve(assetId + ".png");
|
||||
Files.write(previewFile, previewBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE);
|
||||
|
||||
@@ -23,7 +23,7 @@ spring:
|
||||
thymeleaf:
|
||||
cache: false
|
||||
datasource:
|
||||
url: jdbc:sqlite:imgfloat.db?busy_timeout=5000&journal_mode=WAL
|
||||
url: jdbc:sqlite:${IMGFLOAT_DB_PATH:imgfloat.db}?busy_timeout=5000&journal_mode=WAL
|
||||
driver-class-name: org.sqlite.JDBC
|
||||
hikari:
|
||||
connection-init-sql: "PRAGMA journal_mode=WAL; PRAGMA busy_timeout=5000;"
|
||||
|
||||
@@ -17,6 +17,8 @@ import org.springframework.mock.web.MockMultipartFile;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -40,12 +42,15 @@ class ChannelDirectoryServiceTest {
|
||||
private AssetRepository assetRepository;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
void setup() throws Exception {
|
||||
messagingTemplate = mock(SimpMessagingTemplate.class);
|
||||
channelRepository = mock(ChannelRepository.class);
|
||||
assetRepository = mock(AssetRepository.class);
|
||||
setupInMemoryPersistence();
|
||||
service = new ChannelDirectoryService(channelRepository, assetRepository, messagingTemplate);
|
||||
Path assetRoot = Files.createTempDirectory("imgfloat-assets-test");
|
||||
Path previewRoot = Files.createTempDirectory("imgfloat-previews-test");
|
||||
service = new ChannelDirectoryService(channelRepository, assetRepository, messagingTemplate,
|
||||
assetRoot.toString(), previewRoot.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user