mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
Merge branch 'master' of https://github.com/grasdk/pigallery2 into feature/docker-update
This commit is contained in:
commit
7a613ecfe1
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
with:
|
||||
mysql database: 'pigallery_test'
|
||||
mysql root password: 'password'
|
||||
mysql user: 'user'
|
||||
mysql user: 'user'
|
||||
mysql password: 'password'
|
||||
- uses: actions/checkout@v4
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
@ -100,12 +100,10 @@ jobs:
|
||||
needs: [ create-release ]
|
||||
strategy:
|
||||
matrix:
|
||||
container: [alpine, debian-buster, debian-bullseye, debian-bookworm ]
|
||||
container: [alpine, debian-bullseye, debian-bookworm ]
|
||||
include:
|
||||
- container: alpine
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
- container: debian-buster
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
- container: debian-bullseye
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
- container: debian-bookworm
|
||||
|
68
MANPAGE.md
68
MANPAGE.md
File diff suppressed because one or more lines are too long
@ -135,7 +135,7 @@ apt-get install build-essential libkrb5-dev gcc g++
|
||||
## 2. Translate the page to your own language
|
||||
1. [Install Pigallery2](#121-b-install-from-source) from source (with the release it won't work)
|
||||
2. add your language e.g: fr
|
||||
* copy `src/frontend/translate/messages.en.xls` to `src/frontend/translate/messages.fr.xls`
|
||||
* copy `src/frontend/translate/messages.en.xlf` to `src/frontend/translate/messages.fr.xlf`
|
||||
* add the new translation to the `angular.json` `projects->pigallery2->i18n->locales` section
|
||||
3. translate the file by updating the `<target>` tags
|
||||
4. test if it works:
|
||||
|
@ -62,6 +62,10 @@
|
||||
"baseHref": "",
|
||||
"translation": "src/frontend/translate/messages.ru.xlf"
|
||||
},
|
||||
"sk": {
|
||||
"baseHref": "",
|
||||
"translation": "src/frontend/translate/messages.sk.xlf"
|
||||
},
|
||||
"sv": {
|
||||
"baseHref": "",
|
||||
"translation": "src/frontend/translate/messages.sv.xlf"
|
||||
|
@ -1,9 +1,8 @@
|
||||
#-----------------BUILDER-----------------
|
||||
#-----------------------------------------
|
||||
FROM node:18-alpine3.17 AS builder
|
||||
RUN apk add --no-cache --repository https://alpine.global.ssl.fastly.net/alpine/v3.17/community/ \
|
||||
python3 build-base sqlite-dev sqlite-libs vips-dev vips-heif fftw-dev gcc g++ make libc6-compat && ln -snf /usr/bin/python3 /usr/bin/python && \
|
||||
rm /var/cache/apk/*
|
||||
RUN apk add --update-cache --repository https://alpine.global.ssl.fastly.net/alpine/v3.17/community/ \
|
||||
python3 build-base sqlite-dev sqlite-libs imagemagick-dev libraw-dev vips-dev vips-heif vips-magick fftw-dev gcc g++ make libc6-compat && ln -snf /usr/bin/python3 /usr/bin/python
|
||||
COPY pigallery2-release /app
|
||||
WORKDIR /app
|
||||
RUN npm install --unsafe-perm --fetch-timeout=90000
|
||||
@ -27,16 +26,15 @@ ENV NODE_ENV=production \
|
||||
PI_DOCKER=true
|
||||
|
||||
EXPOSE 80
|
||||
RUN apk add --no-cache --repository https://alpine.global.ssl.fastly.net/alpine/v3.17/community/ \
|
||||
vips vips-cpp vips-heif ffmpeg && \
|
||||
rm /var/cache/apk/*
|
||||
RUN apk add --update-cache --repository https://alpine.global.ssl.fastly.net/alpine/v3.17/community/ \
|
||||
vips vips-cpp vips-heif vips-magick ffmpeg
|
||||
COPY --from=builder /app /app
|
||||
|
||||
# Run build time diagnostics to make sure the app would work after build is finished
|
||||
RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json"]
|
||||
RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json", "--Server-Log-level=silly"]
|
||||
HEALTHCHECK --interval=40s --timeout=30s --retries=3 --start-period=60s \
|
||||
CMD wget --quiet --tries=1 --no-check-certificate --spider \
|
||||
http://localhost:80/heartbeat || exit 1
|
||||
http://127.0.0.1:80/heartbeat || exit 1
|
||||
|
||||
# after a extensive job (like video converting), pigallery calls gc, to clean up everthing as fast as possible
|
||||
# Exec form entrypoint is need otherwise (using shell form) ENV variables are not properly passed down to the app
|
||||
|
@ -1,7 +1,7 @@
|
||||
#-----------------BUILDER-----------------
|
||||
#-----------------------------------------
|
||||
FROM node:18.19-bookworm AS builder
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends libvips-dev python3
|
||||
FROM node:18-bookworm AS builder
|
||||
RUN apt update && apt install -y --no-install-recommends libvips-dev python3
|
||||
COPY pigallery2-release /app
|
||||
WORKDIR /app
|
||||
RUN npm install --unsafe-perm --fetch-timeout=90000
|
||||
@ -32,10 +32,10 @@ RUN apt-get update \
|
||||
COPY --from=builder /app /app
|
||||
|
||||
# Run build time diagnostics to make sure the app would work after build is finished
|
||||
RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json"]
|
||||
RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json", "--Server-Log-level=silly"]
|
||||
HEALTHCHECK --interval=40s --timeout=30s --retries=3 --start-period=60s \
|
||||
CMD wget --quiet --tries=1 --no-check-certificate --spider \
|
||||
http://localhost:80/heartbeat || exit 1
|
||||
http://127.0.0.1:80/heartbeat || exit 1
|
||||
|
||||
# after a extensive job (like video converting), pigallery calls gc, to clean up everthing as fast as possible
|
||||
# Exec form entrypoint is need otherwise (using shell form) ENV variables are not properly passed down to the app
|
||||
|
@ -1,7 +1,7 @@
|
||||
#-----------------BUILDER-----------------
|
||||
#-----------------------------------------
|
||||
FROM node:18.19-bullseye AS builder
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends libvips-dev python3
|
||||
FROM node:18-bullseye AS builder
|
||||
RUN apt update && apt install -y --no-install-recommends libvips-dev python3
|
||||
COPY pigallery2-release /app
|
||||
WORKDIR /app
|
||||
RUN npm install --unsafe-perm --fetch-timeout=90000
|
||||
@ -32,10 +32,10 @@ RUN apt-get update \
|
||||
COPY --from=builder /app /app
|
||||
|
||||
# Run build time diagnostics to make sure the app would work after build is finished
|
||||
RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json"]
|
||||
RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json", "--Server-Log-level=silly"]
|
||||
HEALTHCHECK --interval=40s --timeout=30s --retries=3 --start-period=60s \
|
||||
CMD wget --quiet --tries=1 --no-check-certificate --spider \
|
||||
http://localhost:80/heartbeat || exit 1
|
||||
http://127.0.0.1:80/heartbeat || exit 1
|
||||
|
||||
# after a extensive job (like video converting), pigallery calls gc, to clean up everthing as fast as possible
|
||||
# Exec form entrypoint is need otherwise (using shell form) ENV variables are not properly passed down to the app
|
||||
|
@ -1,6 +1,6 @@
|
||||
#-----------------BUILDER-----------------
|
||||
#-----------------------------------------
|
||||
FROM node:18-buster AS builder
|
||||
FROM node:18-bullseye AS builder
|
||||
# LABEL maintainer="Patrik J. Braun"
|
||||
# copying only package{-lock}.json to make node_modules cachable
|
||||
RUN git clone https://github.com/bpatrik/pigallery2.git /build
|
||||
@ -16,7 +16,7 @@ RUN npm install --unsafe-perm
|
||||
|
||||
#-----------------MAIN--------------------
|
||||
#-----------------------------------------
|
||||
FROM node:18-buster-slim AS main
|
||||
FROM node:18-bullseye-slim AS main
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production \
|
||||
# overrides only the default value of the settings (the actualy value can be overwritten through config.json)
|
||||
@ -38,7 +38,7 @@ COPY --from=builder /build/release /app
|
||||
RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json"]
|
||||
HEALTHCHECK --interval=40s --timeout=30s --retries=3 --start-period=60s \
|
||||
CMD wget --quiet --tries=1 --no-check-certificate --spider \
|
||||
http://localhost:80/heartbeat || exit 1
|
||||
http://127.0.0.1:80/heartbeat || exit 1
|
||||
|
||||
# after a extensive job (like video converting), pigallery calls gc, to clean up everthing as fast as possible
|
||||
# Exec form entrypoint is need otherwise (using shell form) ENV variables are not properly passed down to the app
|
@ -1,42 +0,0 @@
|
||||
#-----------------BUILDER-----------------
|
||||
#-----------------------------------------
|
||||
FROM node:18.19-buster AS builder
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends libvips-dev python3
|
||||
COPY pigallery2-release /app
|
||||
WORKDIR /app
|
||||
RUN npm install --unsafe-perm --fetch-timeout=90000
|
||||
RUN mkdir -p /app/data/config && \
|
||||
mkdir -p /app/data/db && \
|
||||
mkdir -p /app/data/images && \
|
||||
mkdir -p /app/data/tmp
|
||||
|
||||
|
||||
#-----------------MAIN--------------------
|
||||
#-----------------------------------------
|
||||
FROM node:18-buster-slim AS main
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production \
|
||||
# overrides only the default value of the settings (the actualy value can be overwritten through config.json)
|
||||
default-Database-dbFolder=/app/data/db \
|
||||
default-Media-folder=/app/data/images \
|
||||
default-Media-tempFolder=/app/data/tmp \
|
||||
default-Extensions-folder=/app/data/config/extensions \
|
||||
# flagging dockerized environemnt
|
||||
PI_DOCKER=true
|
||||
|
||||
EXPOSE 80
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends ca-certificates wget ffmpeg libvips42 \
|
||||
&& apt-get clean -q -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=builder /app /app
|
||||
|
||||
# Run build time diagnostics to make sure the app would work after build is finished
|
||||
RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json"]
|
||||
HEALTHCHECK --interval=40s --timeout=30s --retries=3 --start-period=60s \
|
||||
CMD wget --quiet --tries=1 --no-check-certificate --spider \
|
||||
http://localhost:80/heartbeat || exit 1
|
||||
|
||||
# after a extensive job (like video converting), pigallery calls gc, to clean up everthing as fast as possible
|
||||
# Exec form entrypoint is need otherwise (using shell form) ENV variables are not properly passed down to the app
|
||||
ENTRYPOINT ["node", "./src/backend/index", "--expose-gc", "--config-path=/app/data/config/config.json"]
|
@ -167,6 +167,7 @@ gulp.task('copy-static', (): any =>
|
||||
gulp
|
||||
.src(
|
||||
[
|
||||
'src/backend/model/diagnostics/image_formats/**',
|
||||
'src/backend/model/diagnostics/blank.jpg',
|
||||
'README.md',
|
||||
// 'package-lock.json', should not add, it keeps optional packages optional even with --force-opt-packages.
|
||||
|
@ -3,12 +3,14 @@ import {Logger} from '../../Logger';
|
||||
import {NotificationManager} from '../NotifocationManager';
|
||||
import {SQLConnection} from '../database/SQLConnection';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import {FFmpegFactory} from '../FFmpegFactory';
|
||||
import {
|
||||
ClientAlbumConfig,
|
||||
ClientFacesConfig,
|
||||
ClientMapConfig,
|
||||
ClientMetaFileConfig,
|
||||
ClientPhotoConfig,
|
||||
ClientRandomPhotoConfig,
|
||||
ClientSearchConfig,
|
||||
ClientSharingConfig,
|
||||
@ -28,7 +30,9 @@ import {SearchQueryTypes, TextSearch,} from '../../../common/entities/SearchQuer
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {JobRepository} from '../jobs/JobRepository';
|
||||
import {ConfigClassBuilder} from '../../../../node_modules/typeconfig/node';
|
||||
import { Config } from '../../../common/config/private/Config';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {SupportedFormats} from '../../../common/SupportedFormats';
|
||||
import {MediaRendererInput, PhotoWorker, ThumbnailSourceType} from '../fileaccess/PhotoWorker';
|
||||
|
||||
const LOG_TAG = '[ConfigDiagnostics]';
|
||||
|
||||
@ -78,9 +82,9 @@ export class ConfigDiagnostics {
|
||||
jobsConfig: ServerJobConfig
|
||||
): Promise<void> {
|
||||
Logger.debug(LOG_TAG, 'Testing jobs config');
|
||||
for(let i = 0; i< jobsConfig.scheduled.length; ++i){
|
||||
for (let i = 0; i < jobsConfig.scheduled.length; ++i) {
|
||||
const j = jobsConfig.scheduled[i];
|
||||
if(!JobRepository.Instance.exists(j.name)){
|
||||
if (!JobRepository.Instance.exists(j.name)) {
|
||||
throw new Error('Unknown Job :' + j.name);
|
||||
}
|
||||
}
|
||||
@ -292,6 +296,48 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes unsupported image formats.
|
||||
* It is possible that some OS support one or the other image formats (like Mac os does with HEIC)
|
||||
* , but others not.
|
||||
* Those formats are added to the config, but dynamically removed.
|
||||
* @param config
|
||||
*/
|
||||
static async removeUnsupportedPhotoExtensions(config: ClientPhotoConfig): Promise<void> {
|
||||
Logger.verbose(LOG_TAG, 'Checking for supported image formats');
|
||||
let removedSome = false;
|
||||
let i = config.supportedFormats.length;
|
||||
while (i--) {
|
||||
const ext = config.supportedFormats[i].toLowerCase();
|
||||
const testImage = path.join(__dirname, 'image_formats', 'test.' + ext);
|
||||
// Check if a test available for this image format.
|
||||
// if not probably because it is trivial
|
||||
if (!fs.existsSync(testImage)) {
|
||||
Logger.silly(LOG_TAG, `No test for ${ext} image format. skipping.`);
|
||||
continue;
|
||||
}
|
||||
Logger.silly(LOG_TAG, `Testing ${ext} image formats.`);
|
||||
try {
|
||||
await PhotoWorker.renderFromImage({
|
||||
type: ThumbnailSourceType.Photo,
|
||||
mediaPath: testImage,
|
||||
size: 10,
|
||||
useLanczos3: Config.Media.Photo.useLanczos3,
|
||||
quality: Config.Media.Photo.quality,
|
||||
smartSubsample: Config.Media.Photo.smartSubsample,
|
||||
} as MediaRendererInput, true
|
||||
);
|
||||
} catch (e) {
|
||||
Logger.verbose(LOG_TAG, 'The current OS does not support the following photo format:' + ext + ', removing it form config.');
|
||||
config.supportedFormats.splice(i, 1);
|
||||
removedSome = true;
|
||||
}
|
||||
}
|
||||
if (removedSome) {
|
||||
SupportedFormats.init();
|
||||
}
|
||||
}
|
||||
|
||||
static async testConfig(config: PrivateConfigClass): Promise<void> {
|
||||
|
||||
await ConfigDiagnostics.testDatabase(config.Database);
|
||||
@ -310,7 +356,6 @@ export class ConfigDiagnostics {
|
||||
await ConfigDiagnostics.testRandomPhotoConfig(config.Sharing, config);
|
||||
await ConfigDiagnostics.testMapConfig(config.Map);
|
||||
await ConfigDiagnostics.testJobsConfig(config.Jobs);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -562,7 +607,7 @@ export class ConfigDiagnostics {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning(
|
||||
'Jobs error. Resetting to default for now to let the app start up. ' +
|
||||
'Please adjust the config properly.',
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
@ -575,6 +620,8 @@ export class ConfigDiagnostics {
|
||||
Config.Jobs.scheduled = pc.Jobs.scheduled;
|
||||
}
|
||||
|
||||
await this.removeUnsupportedPhotoExtensions(Config.Media.Photo);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
src/backend/model/diagnostics/image_formats/test.arw
Normal file
BIN
src/backend/model/diagnostics/image_formats/test.arw
Normal file
Binary file not shown.
BIN
src/backend/model/diagnostics/image_formats/test.avif
Normal file
BIN
src/backend/model/diagnostics/image_formats/test.avif
Normal file
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
BIN
src/backend/model/diagnostics/image_formats/test.dng
Normal file
BIN
src/backend/model/diagnostics/image_formats/test.dng
Normal file
Binary file not shown.
BIN
src/backend/model/diagnostics/image_formats/test.heic
Normal file
BIN
src/backend/model/diagnostics/image_formats/test.heic
Normal file
Binary file not shown.
BIN
src/backend/model/diagnostics/image_formats/test.jpg
Normal file
BIN
src/backend/model/diagnostics/image_formats/test.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 631 B |
@ -23,8 +23,8 @@ export class PhotoWorker {
|
||||
throw new Error('Unsupported media type to render thumbnail:' + input.type);
|
||||
}
|
||||
|
||||
public static renderFromImage(input: SvgRendererInput | MediaRendererInput): Promise<void> {
|
||||
return ImageRendererFactory.render(input);
|
||||
public static renderFromImage(input: SvgRendererInput | MediaRendererInput, dryRun = false): Promise<void> {
|
||||
return ImageRendererFactory.render(input, dryRun);
|
||||
}
|
||||
|
||||
public static renderFromVideo(input: MediaRendererInput): Promise<void> {
|
||||
@ -43,8 +43,8 @@ export enum ThumbnailSourceType {
|
||||
interface RendererInput {
|
||||
type: ThumbnailSourceType;
|
||||
size: number;
|
||||
makeSquare: boolean;
|
||||
outPath: string;
|
||||
makeSquare?: boolean;
|
||||
outPath?: string;
|
||||
quality: number;
|
||||
useLanczos3: boolean;
|
||||
animate: boolean; // animates the output. Used for Gifs
|
||||
@ -132,7 +132,7 @@ export class VideoRendererFactory {
|
||||
export class ImageRendererFactory {
|
||||
|
||||
@ExtensionDecorator(e => e.gallery.ImageRenderer.render)
|
||||
public static async render(input: MediaRendererInput | SvgRendererInput): Promise<void> {
|
||||
public static async render(input: MediaRendererInput | SvgRendererInput, dryRun = false): Promise<void> {
|
||||
|
||||
let image: Sharp;
|
||||
if ((input as MediaRendererInput).mediaPath) {
|
||||
@ -174,17 +174,24 @@ export class ImageRendererFactory {
|
||||
fit: 'cover',
|
||||
});
|
||||
}
|
||||
let processedImg: sharp.Sharp;
|
||||
if ((input as MediaRendererInput).mediaPath) {
|
||||
await image.webp({
|
||||
processedImg = image.webp({
|
||||
effort: 6,
|
||||
quality: input.quality,
|
||||
smartSubsample: (input as MediaRendererInput).smartSubsample
|
||||
}).toFile(input.outPath);
|
||||
});
|
||||
} else {
|
||||
if ((input as SvgRendererInput).svgString) {
|
||||
await image.png({effort: 6, quality: input.quality}).toFile(input.outPath);
|
||||
processedImg = image.png({effort: 6, quality: input.quality});
|
||||
}
|
||||
}
|
||||
// do not save to file
|
||||
if (dryRun) {
|
||||
await processedImg.toBuffer();
|
||||
return;
|
||||
}
|
||||
await processedImg.toFile(input.outPath);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -10,44 +10,45 @@ if (typeof window !== 'undefined') {
|
||||
Config = require('./config/private/Config').Config;
|
||||
}
|
||||
|
||||
export const SupportedFormats = {
|
||||
Photos: Config.Media.Photo.supportedFormats,
|
||||
export class SupportedFormats {
|
||||
static Photos = Config.Media.Photo.supportedFormats;
|
||||
// Browser supported video formats
|
||||
// Read more: https://www.w3schools.com/html/html5_video.asp
|
||||
Videos: Config.Media.Video.supportedFormats,
|
||||
MetaFiles: Config.MetaFile.supportedFormats,
|
||||
// These formats need to be transcoded (with the build-in ffmpeg support)
|
||||
TranscodeNeed: {
|
||||
static Videos = Config.Media.Video.supportedFormats;
|
||||
static MetaFiles = Config.MetaFile.supportedFormats;
|
||||
// These formats need to be transcoded (with the built-in ffmpeg support)
|
||||
static TranscodeNeed = {
|
||||
// based on libvips, all supported formats for sharp: https://github.com/libvips/libvips
|
||||
Photos: [] as string[],
|
||||
Videos: Config.Media.Video.supportedFormatsWithTranscoding,
|
||||
},
|
||||
};
|
||||
// --------------------------------------------
|
||||
// Below this, it is autogenerated, DO NOT EDIT
|
||||
WithDots: {
|
||||
static WithDots = {
|
||||
Photos: [] as string[],
|
||||
Videos: [] as string[],
|
||||
MetaFiles: [] as string[],
|
||||
TranscodeNeed: {
|
||||
Photos: [] as string[],
|
||||
Videos: [] as string[],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
SupportedFormats.Photos = SupportedFormats.Photos.concat(
|
||||
SupportedFormats.TranscodeNeed.Photos
|
||||
);
|
||||
SupportedFormats.Videos = SupportedFormats.Videos.concat(
|
||||
SupportedFormats.TranscodeNeed.Videos
|
||||
);
|
||||
SupportedFormats.WithDots.Photos = SupportedFormats.Photos.map((f) => '.' + f);
|
||||
SupportedFormats.WithDots.Videos = SupportedFormats.Videos.map((f) => '.' + f);
|
||||
SupportedFormats.WithDots.MetaFiles = SupportedFormats.MetaFiles.map(
|
||||
(f) => '.' + f
|
||||
);
|
||||
SupportedFormats.WithDots.TranscodeNeed.Photos =
|
||||
SupportedFormats.TranscodeNeed.Photos.map((f) => '.' + f);
|
||||
SupportedFormats.WithDots.TranscodeNeed.Videos =
|
||||
SupportedFormats.TranscodeNeed.Videos.map((f) => '.' + f);
|
||||
|
||||
}
|
||||
};
|
||||
static init(){
|
||||
SupportedFormats.Photos = SupportedFormats.Photos.concat(
|
||||
SupportedFormats.TranscodeNeed.Photos
|
||||
);
|
||||
SupportedFormats.Videos = SupportedFormats.Videos.concat(
|
||||
SupportedFormats.TranscodeNeed.Videos
|
||||
);
|
||||
SupportedFormats.WithDots.Photos = SupportedFormats.Photos.map((f) => '.' + f);
|
||||
SupportedFormats.WithDots.Videos = SupportedFormats.Videos.map((f) => '.' + f);
|
||||
SupportedFormats.WithDots.MetaFiles = SupportedFormats.MetaFiles.map(
|
||||
(f) => '.' + f
|
||||
);
|
||||
SupportedFormats.WithDots.TranscodeNeed.Photos =
|
||||
SupportedFormats.TranscodeNeed.Photos.map((f) => '.' + f);
|
||||
SupportedFormats.WithDots.TranscodeNeed.Videos =
|
||||
SupportedFormats.TranscodeNeed.Videos.map((f) => '.' + f);
|
||||
}
|
||||
}
|
||||
SupportedFormats.init();
|
||||
|
@ -525,7 +525,7 @@ export class ServerLogConfig {
|
||||
name: $localize`Server timing`,
|
||||
priority: ConfigPriority.underTheHood,
|
||||
},
|
||||
description: $localize`If enabled, the app ads "Server-Timing" http header to the response.`
|
||||
description: $localize`If enabled, the app adds "Server-Timing" http header to the response.`
|
||||
})
|
||||
logServerTiming: boolean = false;
|
||||
}
|
||||
@ -638,7 +638,7 @@ export class ServerJobConfig {
|
||||
name: $localize`Processing batch size`,
|
||||
priority: ConfigPriority.underTheHood
|
||||
},
|
||||
description: $localize`Jobs load this many photos or videos form the DB for processing at once.`
|
||||
description: $localize`Jobs load this many photos or videos from the DB for processing at once.`
|
||||
})
|
||||
mediaProcessingBatchSize: number = 1000;
|
||||
@ConfigProperty({
|
||||
@ -698,7 +698,7 @@ export class VideoTranscodingConfig {
|
||||
priority: ConfigPriority.advanced,
|
||||
unit: 'bps'
|
||||
},
|
||||
description: $localize`Target bit rate of the output video will be scaled down this this. This should be less than the upload rate of your home server.`
|
||||
description: $localize`Target bit rate of the output video will be scaled down to this. This should be less than the upload rate of your home server.`
|
||||
})
|
||||
bitRate: number = 5 * 1024 * 1024;
|
||||
@ConfigProperty({
|
||||
@ -721,7 +721,7 @@ export class VideoTranscodingConfig {
|
||||
priority: ConfigPriority.underTheHood,
|
||||
uiOptions: [24, 25, 30, 48, 50, 60]
|
||||
},
|
||||
description: $localize`Target frame per second (fps) of the output video will be scaled down this this.`
|
||||
description: $localize`Target frame per second (fps) of the output video will be scaled down to this.`
|
||||
})
|
||||
fps: number = 25;
|
||||
@ConfigProperty({
|
||||
@ -810,7 +810,7 @@ export class ServerVideoConfig extends ClientVideoConfig {
|
||||
priority: ConfigPriority.advanced,
|
||||
uiDisabled: (sb: ClientVideoConfig) => !sb.enabled
|
||||
},
|
||||
description: $localize`To ensure smooth video playback, video transcoding is recommended to a lower bit rate than the server's upload rate. The transcoded videos will be save to the thumbnail folder. You can trigger the transcoding manually, but you can also create an automatic encoding job in advanced settings mode.`
|
||||
description: $localize`To ensure smooth video playback, video transcoding is recommended to a lower bit rate than the server's upload rate. The transcoded videos will be saved to the thumbnail folder. You can trigger the transcoding manually, but you can also create an automatic encoding job in advanced settings mode.`
|
||||
})
|
||||
transcoding: VideoTranscodingConfig = new VideoTranscodingConfig();
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ export class AutoCompleteItemsPerCategoryConfig {
|
||||
name: $localize`Maximum items`,
|
||||
priority: ConfigPriority.underTheHood
|
||||
},
|
||||
description: $localize`Maximum number autocomplete items shown at once. If there is not enough items to reach this value, it takes upto double of the individual items.`
|
||||
description: $localize`Maximum number autocomplete items shown at once. If there is not enough items to reach this value, it takes up to double of the individual items.`
|
||||
})
|
||||
maxItems: number = 20;
|
||||
|
||||
@ -573,31 +573,31 @@ export class ClientMapConfig {
|
||||
)]),
|
||||
new MapPathGroupConfig('Sport',
|
||||
[new MapPathGroupThemeConfig(
|
||||
['run'],
|
||||
['(\b|_|-)run'],
|
||||
new PathThemeConfig('var(--bs-primary)',
|
||||
'',
|
||||
new SVGIconConfig('0 0 417 512', '<path d="M320 48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM125.7 175.5c9.9-9.9 23.4-15.5 37.5-15.5c1.9 0 3.8 .1 5.6 .3L137.6 254c-9.3 28 1.7 58.8 26.8 74.5l86.2 53.9-25.4 88.8c-4.9 17 5 34.7 22 39.6s34.7-5 39.6-22l28.7-100.4c5.9-20.6-2.6-42.6-20.7-53.9L238 299l30.9-82.4 5.1 12.3C289 264.7 323.9 288 362.7 288H384c17.7 0 32-14.3 32-32s-14.3-32-32-32H362.7c-12.9 0-24.6-7.8-29.5-19.7l-6.3-15c-14.6-35.1-44.1-61.9-80.5-73.1l-48.7-15c-11.1-3.4-22.7-5.2-34.4-5.2c-31 0-60.8 12.3-82.7 34.3L57.4 153.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l23.1-23.1zM91.2 352H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h69.6c19 0 36.2-11.2 43.9-28.5L157 361.6l-9.5-6c-17.5-10.9-30.5-26.8-37.9-44.9L91.2 352z"/>')
|
||||
)
|
||||
), new MapPathGroupThemeConfig(
|
||||
['walk'],
|
||||
['(\b|_|-)walk'],
|
||||
new PathThemeConfig('var(--bs-primary)',
|
||||
'',
|
||||
new SVGIconConfig('0 0 320 512', '<path d="M160 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM126.5 199.3c-1 .4-1.9 .8-2.9 1.2l-8 3.5c-16.4 7.3-29 21.2-34.7 38.2l-2.6 7.8c-5.6 16.8-23.7 25.8-40.5 20.2s-25.8-23.7-20.2-40.5l2.6-7.8c11.4-34.1 36.6-61.9 69.4-76.5l8-3.5c20.8-9.2 43.3-14 66.1-14c44.6 0 84.8 26.8 101.9 67.9L281 232.7l21.4 10.7c15.8 7.9 22.2 27.1 14.3 42.9s-27.1 22.2-42.9 14.3L247 287.3c-10.3-5.2-18.4-13.8-22.8-24.5l-9.6-23-19.3 65.5 49.5 54c5.4 5.9 9.2 13 11.2 20.8l23 92.1c4.3 17.1-6.1 34.5-23.3 38.8s-34.5-6.1-38.8-23.3l-22-88.1-70.7-77.1c-14.8-16.1-20.3-38.6-14.7-59.7l16.9-63.5zM68.7 398l25-62.4c2.1 3 4.5 5.8 7 8.6l40.7 44.4-14.5 36.2c-2.4 6-6 11.5-10.6 16.1L54.6 502.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L68.7 398z"/>')
|
||||
)
|
||||
), new MapPathGroupThemeConfig(
|
||||
['hike', 'hiking'],
|
||||
['(\b|_|-)hike', '(\b|_|-)hiking'],
|
||||
new PathThemeConfig('var(--bs-primary)',
|
||||
'',
|
||||
new SVGIconConfig('0 0 384 512', '<path d="M192 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm51.3 182.7L224.2 307l49.7 49.7c9 9 14.1 21.2 14.1 33.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V397.3l-73.9-73.9c-15.8-15.8-22.2-38.6-16.9-60.3l20.4-84c8.3-34.1 42.7-54.9 76.7-46.4c19 4.8 35.6 16.4 46.4 32.7L305.1 208H336V184c0-13.3 10.7-24 24-24s24 10.7 24 24v55.8c0 .1 0 .2 0 .2s0 .2 0 .2V488c0 13.3-10.7 24-24 24s-24-10.7-24-24V272H296.6c-16 0-31-8-39.9-21.4l-13.3-20zM81.1 471.9L117.3 334c3 4.2 6.4 8.2 10.1 11.9l41.9 41.9L142.9 488.1c-4.5 17.1-22 27.3-39.1 22.8s-27.3-22-22.8-39.1zm55.5-346L101.4 266.5c-3 12.1-14.9 19.9-27.2 17.9l-47.9-8c-14-2.3-22.9-16.3-19.2-30L31.9 155c9.5-34.8 41.1-59 77.2-59h4.2c15.6 0 27.1 14.7 23.3 29.8z"/>')
|
||||
)
|
||||
), new MapPathGroupThemeConfig(
|
||||
['bike', 'biking', 'cycling'],
|
||||
['(\b|_|-)bike', '(\b|_|-)biking', '(\b|_|-)cycling'],
|
||||
new PathThemeConfig('var(--bs-primary)',
|
||||
'',
|
||||
new SVGIconConfig('0 0 640 512', '<path d="M400 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm27.2 64l-61.8-48.8c-17.3-13.6-41.7-13.8-59.1-.3l-83.1 64.2c-30.7 23.8-28.5 70.8 4.3 91.6L288 305.1V416c0 17.7 14.3 32 32 32s32-14.3 32-32V288c0-10.7-5.3-20.7-14.2-26.6L295 232.9l60.3-48.5L396 217c5.7 4.5 12.7 7 20 7h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H427.2zM56 384a72 72 0 1 1 144 0A72 72 0 1 1 56 384zm200 0A128 128 0 1 0 0 384a128 128 0 1 0 256 0zm184 0a72 72 0 1 1 144 0 72 72 0 1 1 -144 0zm200 0a128 128 0 1 0 -256 0 128 128 0 1 0 256 0z"/>')
|
||||
)
|
||||
), new MapPathGroupThemeConfig(
|
||||
['skiing', 'ski'],
|
||||
['(\b|_|-)skiing', '(\b|_|-)ski'],
|
||||
new PathThemeConfig('var(--bs-primary)',
|
||||
'',
|
||||
new SVGIconConfig('0 0 512 512', '<path d="M380.7 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM2.7 268.9c6.1-11.8 20.6-16.3 32.4-10.2L232.7 361.3l46.2-69.2-75.1-75.1c-14.6-14.6-20.4-33.9-18.4-52.1l108.8 52 39.3 39.3c16.2 16.2 18.7 41.5 6 60.6L289.8 391l128.7 66.8c13.6 7.1 29.8 7.2 43.6 .3l15.2-7.6c11.9-5.9 26.3-1.1 32.2 10.7s1.1 26.3-10.7 32.2l-15.2 7.6c-27.5 13.7-59.9 13.5-87.2-.7L12.9 301.3C1.2 295.2-3.4 280.7 2.7 268.9zM118.9 65.6L137 74.2l8.7-17.4c4-7.9 13.6-11.1 21.5-7.2s11.1 13.6 7.2 21.5l-8.5 16.9 54.7 26.2c1.5-.7 3.1-1.4 4.7-2.1l83.4-33.4c34.2-13.7 72.8 4.2 84.5 39.2l17.1 51.2 52.1 26.1c15.8 7.9 22.2 27.1 14.3 42.9s-27.1 22.2-42.9 14.3l-58.1-29c-11.4-5.7-20-15.7-24.1-27.8l-5.8-17.3-27.3 12.1-6.8 3-6.7-3.2L151.5 116.7l-9.2 18.4c-4 7.9-13.6 11.1-21.5 7.2s-11.1-13.6-7.2-21.5l9-18-17.6-8.4c-8-3.8-11.3-13.4-7.5-21.3s13.4-11.3 21.3-7.5z"/>')
|
||||
@ -789,7 +789,7 @@ export class NavBarConfig {
|
||||
experimental: true,
|
||||
githubIssue: 174
|
||||
},
|
||||
description: $localize`Adds a button to flattens the file structure, by listing the content of all subdirectories. (Won't work if the gallery has multiple folders with the same path.)`
|
||||
description: $localize`Adds a button to flatten the file structure, by listing the content of all subdirectories. (Won't work if the gallery has multiple folders with the same path.)`
|
||||
})
|
||||
enableDirectoryFlattening: boolean = false;
|
||||
|
||||
@ -1091,8 +1091,8 @@ export class ClientGalleryConfig {
|
||||
})
|
||||
//DEVELOPER NOTE: The Database model stores the timestamp (creationDate) as milliseconds since 1970-01-01 UTC (global time). And stores and offset (creationDateOffset) as minutes.
|
||||
//Ignoring timestamp for the user is the opposite for the database. If the user wants to ignore the offset, we have to add the offset to the creationDate to give the user the right experience.
|
||||
ignoreTimestampOffset: boolean = true;
|
||||
|
||||
ignoreTimestampOffset: boolean = true;
|
||||
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
@ -1145,7 +1145,7 @@ export class ClientGalleryConfig {
|
||||
priority: ConfigPriority.advanced,
|
||||
githubIssue: 711
|
||||
},
|
||||
description: $localize`Makes inline blog (*.md files content) to be auto open.`
|
||||
description: $localize`Makes inline blog (*.md files content) auto-open.`
|
||||
})
|
||||
InlineBlogStartsOpen: boolean = false;
|
||||
|
||||
@ -1155,7 +1155,7 @@ export class ClientGalleryConfig {
|
||||
priority: ConfigPriority.advanced,
|
||||
githubIssue: 711
|
||||
},
|
||||
description: $localize`Makes inline blog (*.md files content) to be auto open.`
|
||||
description: $localize`Makes top blog (*.md files content) auto-open.`
|
||||
})
|
||||
TopBlogStartsOpen: boolean = false;
|
||||
}
|
||||
@ -1178,7 +1178,7 @@ export class ClientVideoConfig {
|
||||
uiDisabled: (sb: ClientVideoConfig) => !sb.enabled,
|
||||
uiResetNeeded: {db: true}
|
||||
} as TAGS,
|
||||
description: $localize`Video formats that are supported after transcoding (with the build-in ffmpeg support).`
|
||||
description: $localize`Video formats that are supported after transcoding (with the built-in ffmpeg support).`
|
||||
})
|
||||
supportedFormatsWithTranscoding: string[] = ['avi', 'mkv', 'mov', 'wmv', 'flv', 'mts', 'm2ts', 'mpg', '3gp', 'm4v', 'mpeg', 'vob', 'divx', 'xvid', 'ts'];
|
||||
// Browser supported video formats
|
||||
@ -1266,7 +1266,7 @@ export class ClientPhotoConfig {
|
||||
},
|
||||
description: $localize`Photo formats that are supported. Browser needs to support these formats natively. Also sharp (libvips) package should be able to convert these formats.`,
|
||||
})
|
||||
supportedFormats: string[] = ['gif', 'jpeg', 'jpg', 'jpe', 'png', 'webp', 'svg'];
|
||||
supportedFormats: string[] = ['gif', 'jpeg', 'jpg', 'jpe', 'png', 'webp', 'svg', 'avif', 'heic', 'dng', 'arw'];
|
||||
}
|
||||
|
||||
@SubConfigClass({tags: {client: true}, softReadonly: true})
|
||||
@ -1402,7 +1402,7 @@ export class ClientServiceConfig {
|
||||
applicationTitle: string = 'PiGallery 2';
|
||||
|
||||
@ConfigProperty({
|
||||
description: $localize`If you access the page from local network its good to know the public url for creating sharing link.`,
|
||||
description: $localize`If you access the page from local network it's good to know the public url for creating sharing link.`,
|
||||
tags: {
|
||||
name: $localize`Page public url`,
|
||||
hint: typeof window !== 'undefined' ? window?.origin : '',
|
||||
@ -1418,8 +1418,9 @@ export class ClientServiceConfig {
|
||||
hint: '/myGallery',
|
||||
uiResetNeeded: {server: true},
|
||||
priority: ConfigPriority.advanced,
|
||||
uiOptional: true
|
||||
}
|
||||
uiOptional: true,
|
||||
githubIssue: 854
|
||||
} as TAGS
|
||||
})
|
||||
urlBase: string = '';
|
||||
|
||||
@ -1437,7 +1438,7 @@ export class ClientServiceConfig {
|
||||
languages: string[] | undefined;
|
||||
|
||||
@ConfigProperty({
|
||||
description: $localize`Injects the content of this between the <head></head> HTML tags of the app. (You can use it add analytics or custom code to the app).`,
|
||||
description: $localize`Injects the content of this between the <head></head> HTML tags of the app. (You can use it to add analytics or custom code to the app).`,
|
||||
tags: {
|
||||
name: $localize`Custom HTML Head`,
|
||||
priority: ConfigPriority.advanced,
|
||||
|
@ -27,7 +27,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<span i18n>Are you sue you want to run this job? This will have the following effect:</span>
|
||||
<span i18n>Are you sure you want to run this job? This will have the following effect:</span>
|
||||
<div class="alert alert-secondary" role="alert">
|
||||
{{ backendTextService.getJobDescription(jobName) }}
|
||||
</div>
|
||||
|
5891
src/frontend/translate/messages.sk.xlf
Normal file
5891
src/frontend/translate/messages.sk.xlf
Normal file
File diff suppressed because it is too large
Load Diff
@ -199,9 +199,6 @@ export class TestHelper {
|
||||
} as FaceRegion, {
|
||||
box: {height: 10, width: 10, left: 104, top: 104},
|
||||
name: 'Unkle Ben'
|
||||
} as FaceRegion, {
|
||||
box: {height: 10, width: 10, left: 105, top: 105},
|
||||
name: 'Arvíztűrő Tükörfúrógép'
|
||||
} as FaceRegion, {
|
||||
box: {height: 10, width: 10, left: 201, top: 201},
|
||||
name: 'R2-D2'
|
||||
|
@ -1387,7 +1387,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
||||
resultOverflow: false
|
||||
} as SearchResultDTO));
|
||||
|
||||
query = ({value: 6, type: SearchQueryTypes.min_person_count} as MinPersonCountSearch);
|
||||
query = ({value: 5, type: SearchQueryTypes.min_person_count} as MinPersonCountSearch);
|
||||
expect(Utils.clone(await sm.search(query)))
|
||||
.to.deep.equalInAnyOrder(removeDir({
|
||||
searchQuery: query,
|
||||
|
@ -24,7 +24,8 @@ describe('DiskMangerWorker', () => {
|
||||
ProjectPath.ImageFolder = path.join(__dirname, '/../../../assets');
|
||||
const dir = await DiskManager.scanDirectory('/');
|
||||
// should match the number of media (photo/video) files in the assets folder
|
||||
expect(dir.media.length).to.be.equals(16);
|
||||
// TODO: make this test less flaky. Every time a new image is added to the folder, it fails.
|
||||
expect(dir.media.length).to.be.equals(17);
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const expected = require(path.join(__dirname, '/../../../assets/test image öüóőúéáű-.,.json'));
|
||||
const i = dir.media.findIndex(m => m.name === 'test image öüóőúéáű-.,.jpg');
|
||||
|
Loading…
x
Reference in New Issue
Block a user