mirror of
https://github.com/agregarr/agregarr.git
synced 2026-05-07 19:30:28 -05:00
fix(posters): add custom fonts support
add fonts to /config/fonts/ and they will be auto detected fix #219
This commit is contained in:
+3
-2
@@ -47,14 +47,15 @@ config/posters/*.*
|
||||
config/temp/*.*
|
||||
config/plex-base-posters/**
|
||||
|
||||
|
||||
|
||||
# wallpaper storage
|
||||
config/wallpapers/*.*
|
||||
|
||||
# theme music storage
|
||||
config/themes/*.*
|
||||
|
||||
# fonts storage
|
||||
config/fonts/*.*
|
||||
|
||||
# logs
|
||||
config/logs/*.log*
|
||||
config/logs/*.json
|
||||
|
||||
@@ -72,6 +72,14 @@ RUN apk add --no-cache \
|
||||
fc-cache -fv && \
|
||||
rm -rf /tmp/*
|
||||
|
||||
# Configure fontconfig to scan custom fonts directory
|
||||
RUN mkdir -p /etc/fonts/conf.d && \
|
||||
echo '<?xml version="1.0"?>' > /etc/fonts/conf.d/99-agregarr-custom-fonts.conf && \
|
||||
echo '<!DOCTYPE fontconfig SYSTEM "fonts.dtd">' >> /etc/fonts/conf.d/99-agregarr-custom-fonts.conf && \
|
||||
echo '<fontconfig>' >> /etc/fonts/conf.d/99-agregarr-custom-fonts.conf && \
|
||||
echo ' <dir>/app/config/fonts</dir>' >> /etc/fonts/conf.d/99-agregarr-custom-fonts.conf && \
|
||||
echo '</fontconfig>' >> /etc/fonts/conf.d/99-agregarr-custom-fonts.conf
|
||||
|
||||
# Install Deno - yt-dlp requires a JS runtime as of 2025-11-12
|
||||
RUN echo "@edge https://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories && \
|
||||
echo "@edge https://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories && \
|
||||
|
||||
@@ -24,6 +24,7 @@ import express from 'express';
|
||||
import * as OpenApiValidator from 'express-openapi-validator';
|
||||
import type { Store } from 'express-session';
|
||||
import session from 'express-session';
|
||||
import fs from 'fs';
|
||||
import next from 'next';
|
||||
import path from 'path';
|
||||
import swaggerUi from 'swagger-ui-express';
|
||||
@@ -157,6 +158,17 @@ app
|
||||
logger.error('Failed to initialize icon storage:', error);
|
||||
}
|
||||
|
||||
// Initialize fonts directory for custom fonts
|
||||
try {
|
||||
const fontsDir = path.join(process.cwd(), 'config', 'fonts');
|
||||
if (!fs.existsSync(fontsDir)) {
|
||||
fs.mkdirSync(fontsDir, { recursive: true });
|
||||
logger.info('Created fonts directory successfully');
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Failed to initialize fonts directory:', error);
|
||||
}
|
||||
|
||||
// Initialize base poster storage directory
|
||||
try {
|
||||
const { plexBasePosterManager } = await import(
|
||||
@@ -518,6 +530,22 @@ app
|
||||
})
|
||||
);
|
||||
|
||||
// Serve custom fonts
|
||||
const customFontsPath = path.join(process.cwd(), 'config', 'fonts');
|
||||
server.use(
|
||||
'/custom-fonts',
|
||||
express.static(customFontsPath, {
|
||||
setHeaders: (res, path) => {
|
||||
if (path.endsWith('.ttf')) {
|
||||
res.setHeader('Content-Type', 'font/ttf');
|
||||
} else if (path.endsWith('.otf')) {
|
||||
res.setHeader('Content-Type', 'font/otf');
|
||||
}
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
server.post('/upload-icon', async (req, res) => {
|
||||
try {
|
||||
const multer = (await import('multer')).default;
|
||||
|
||||
+19
-6
@@ -1,6 +1,7 @@
|
||||
import logger from '@server/logger';
|
||||
import { exec } from 'child_process';
|
||||
import { Router } from 'express';
|
||||
import path from 'path';
|
||||
import { promisify } from 'util';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
@@ -48,8 +49,8 @@ fontsRoutes.get('/', async (req, res) => {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only include TTF fonts for web serving
|
||||
if (filePath.endsWith('.ttf')) {
|
||||
// Include both TTF and OTF fonts for web serving
|
||||
if (filePath.endsWith('.ttf') || filePath.endsWith('.otf')) {
|
||||
// Prioritize system fonts over local fonts for unified behavior
|
||||
if (
|
||||
!fontMap.has(family) ||
|
||||
@@ -62,18 +63,30 @@ fontsRoutes.get('/', async (req, res) => {
|
||||
}
|
||||
|
||||
// Convert to final format with exact CSS values and font URLs
|
||||
const configFontsPath = path.join(process.cwd(), 'config', 'fonts');
|
||||
const fonts: FontInfo[] = [];
|
||||
|
||||
for (const [family, filePath] of fontMap) {
|
||||
// Only include fonts from /usr/share/fonts/ for unified Docker/local behavior
|
||||
if (!filePath.startsWith('/usr/share/fonts/')) {
|
||||
// Include fonts from system directory OR custom directory
|
||||
if (
|
||||
!filePath.startsWith('/usr/share/fonts/') &&
|
||||
!filePath.startsWith(configFontsPath)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Store clean font name - quotes will be added during CSS/SVG generation when needed
|
||||
const cssValue = family;
|
||||
|
||||
// Convert system path to web URL
|
||||
const fontUrl = filePath.replace('/usr/share/fonts/', '/fonts/');
|
||||
// Convert path to web URL
|
||||
let fontUrl: string;
|
||||
if (filePath.startsWith('/usr/share/fonts/')) {
|
||||
fontUrl = filePath.replace('/usr/share/fonts/', '/fonts/');
|
||||
} else if (filePath.startsWith(configFontsPath)) {
|
||||
fontUrl = filePath.replace(configFontsPath, '/custom-fonts');
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
fonts.push({
|
||||
family,
|
||||
|
||||
Reference in New Issue
Block a user