1
Fork 0

Switch to Debian testing and `imagemagick`. (#1021)

This commit is contained in:
Googol Lee 2024-08-29 10:30:06 +02:00 committed by GitHub
parent 6c5c304492
commit ad13172a32
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 191 additions and 75 deletions

View File

@ -12,43 +12,39 @@ env:
DOCKER_USERNAME: viktorstrate
DOCKER_IMAGE: viktorstrate/photoview
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
PLATFORMS: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6
jobs:
build:
name: Build Docker Image
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Delete huge unnecessary tools folder
run: rm -rf /opt/hostedtoolcache
- name: Cache Docker layers
uses: actions/cache@v2
id: cache
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ secrets.CACHE_KEY }}-${{ matrix.target_platform }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-${{ secrets.CACHE_KEY }}-${{ matrix.target_platform }}-
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v3
with:
platforms: ${{ matrix.target_platform }}
platforms: ${{ env.PLATFORMS }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v3
- name: Docker Login
if: success() && github.event_name != 'pull_request' && github.repository == 'photoview/photoview'
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ env.DOCKER_PASSWORD }}
- name: Docker meta
id: docker_meta
uses: docker/metadata-action@v3
uses: docker/metadata-action@v5
with:
# list of Docker images to use as base name for tags
images: ${{ env.DOCKER_IMAGE }}
@ -63,13 +59,19 @@ jobs:
type=sha
- name: Build and push
uses: docker/build-push-action@v2
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6
platforms: ${{ env.PLATFORMS }}
pull: true
push: ${{ github.event_name != 'pull_request' && github.repository == 'photoview/photoview' }}
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
sbom: true
provenance: mode=max
annotations: ${{ steps.docker_meta.outputs.annotations }}
build-args: |
VERSION=${{ github.ref_name }}
COMMIT_SHA=${{ github.sha }}

View File

@ -49,7 +49,10 @@ ENV PATH="${GOPATH}/bin:${PATH}"
ENV CGO_ENABLED=1
# Download dependencies
COPY scripts/*.sh /app/scripts/
COPY scripts/apt/debian-testing.sources /etc/apt/sources.list.d/
COPY scripts/set_compiler_env.sh /app/scripts/
COPY scripts/install_build_dependencies.sh /app/scripts/
COPY scripts/install_runtime_dependencies.sh /app/scripts/
RUN chmod +x /app/scripts/*.sh \
&& /app/scripts/install_build_dependencies.sh \
&& /app/scripts/install_runtime_dependencies.sh
@ -70,7 +73,7 @@ RUN source /app/scripts/set_compiler_env.sh \
&& go build -v -o photoview .
### Build release image ###
FROM --platform=${BUILDPLATFORM:-linux/amd64} debian:bookworm-slim AS release
FROM --platform=${BUILDPLATFORM:-linux/amd64} debian:testing-slim AS release
ARG TARGETPLATFORM
# See for details: https://github.com/hadolint/hadolint/wiki/DL4006

View File

@ -266,7 +266,7 @@ In macOS, install dependencies:
```sh
$ brew update # Update the package list
$ brew install golang gcc libheif dlib jpeg # For API
$ brew install golang gcc pkg-config libheif dlib jpeg # For API
$ brew install reflex sqlite3 # For API optional tools
```

View File

@ -18,7 +18,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
github.com/stretchr/testify v1.9.0
github.com/strukturag/libheif v1.15.1
github.com/strukturag/libheif v1.17.6
github.com/vektah/gqlparser/v2 v2.5.16
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0
github.com/xor-gate/goexif2 v1.1.0

View File

@ -91,8 +91,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/strukturag/libheif v1.15.1 h1:PWMRTk+9HG0a9avvlV597iI0AdHk25zKVV33lSl6a+I=
github.com/strukturag/libheif v1.15.1/go.mod h1:E/PNRlmVtrtj9j2AvBZlrO4dsBDu6KfwDZn7X1Ce8Ks=
github.com/strukturag/libheif v1.17.6 h1:UFz4FI7kKLINWyL7bcNEBu4gZxK7rHRkwq49IOzHyvE=
github.com/strukturag/libheif v1.17.6/go.mod h1:E/PNRlmVtrtj9j2AvBZlrO4dsBDu6KfwDZn7X1Ce8Ks=
github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8=

View File

@ -108,10 +108,10 @@ func (img *EncodeMediaData) EncodeHighRes(outputPath string) error {
return errors.New("could not convert photo as file format is not supported")
}
// Use darktable if there is no counterpart JPEG file to use instead
// Use ImageMagick if there is no counterpart JPEG file to use instead
if contentType.IsRaw() && img.CounterpartPath == nil {
if executable_worker.DarktableCli.IsInstalled() {
err := executable_worker.DarktableCli.EncodeJpeg(img.Media.Path, outputPath, 70)
if executable_worker.MagickCli.IsInstalled() {
err := executable_worker.MagickCli.EncodeJpeg(img.Media.Path, outputPath, 70)
if err != nil {
return err
}

View File

@ -2,9 +2,7 @@ package executable_worker
import (
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
@ -14,18 +12,18 @@ import (
)
func InitializeExecutableWorkers() {
DarktableCli = newDarktableWorker()
MagickCli = newMagickWorker()
FfmpegCli = newFfmpegWorker()
}
var DarktableCli *DarktableWorker = nil
var MagickCli *MagickWorker = nil
var FfmpegCli *FfmpegWorker = nil
type ExecutableWorker interface {
Path() string
}
type DarktableWorker struct {
type MagickWorker struct {
path string
}
@ -33,25 +31,25 @@ type FfmpegWorker struct {
path string
}
func newDarktableWorker() *DarktableWorker {
func newMagickWorker() *MagickWorker {
if utils.EnvDisableRawProcessing.GetBool() {
log.Printf("Executable worker disabled (%s=1): darktable\n", utils.EnvDisableRawProcessing.GetName())
log.Printf("Executable worker disabled (%s=1): ImageMagick\n", utils.EnvDisableRawProcessing.GetName())
return nil
}
path, err := exec.LookPath("darktable-cli")
path, err := exec.LookPath("convert")
if err != nil {
log.Println("Executable worker not found: darktable")
log.Println("Executable worker not found: ImageMagick convert")
} else {
version, err := exec.Command(path, "--version").Output()
if err != nil {
log.Printf("Error getting version of darktable: %s\n", err)
log.Printf("Error getting version of ImageMagick convert: %s\n", err)
return nil
}
log.Printf("Found executable worker: darktable (%s)\n", strings.Split(string(version), "\n")[0])
log.Printf("Found executable worker: ImageMagick convert (%s)\n", strings.Split(string(version), "\n")[0])
return &DarktableWorker{
return &MagickWorker{
path: path,
}
}
@ -85,7 +83,7 @@ func newFfmpegWorker() *FfmpegWorker {
return nil
}
func (worker *DarktableWorker) IsInstalled() bool {
func (worker *MagickWorker) IsInstalled() bool {
return worker != nil
}
@ -93,27 +91,17 @@ func (worker *FfmpegWorker) IsInstalled() bool {
return worker != nil
}
func (worker *DarktableWorker) EncodeJpeg(inputPath string, outputPath string, jpegQuality int) error {
tmpDir, err := ioutil.TempDir("/tmp", "photoview-darktable")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(tmpDir)
func (worker *MagickWorker) EncodeJpeg(inputPath string, outputPath string, jpegQuality int) error {
args := []string{
inputPath,
"-quality", fmt.Sprintf("%d", jpegQuality),
outputPath,
"--core",
"--conf",
fmt.Sprintf("plugins/imageio/format/jpeg/quality=%d", jpegQuality),
"--configdir",
tmpDir,
}
cmd := exec.Command(worker.path, args...)
if err := cmd.Run(); err != nil {
return errors.Wrapf(err, "encoding image using: %s %v", worker.path, args)
return fmt.Errorf("encoding image with \"%s %v\" error: %w", worker.path, args, err)
}
return nil

View File

@ -0,0 +1,35 @@
package executable_worker_test
import (
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/photoview/photoview/api/test_utils"
)
func TestMain(m *testing.M) {
os.Exit(test_utils.IntegrationTestRun(m))
}
func setPathWithCurrent(paths ...string) func() {
_, file, _, ok := runtime.Caller(0)
if !ok {
return func() {}
}
base := filepath.Dir(file)
for i, path := range paths {
paths[i] = filepath.Join(base, path)
}
originalPath := os.Getenv("PATH")
os.Setenv("PATH", strings.Join(paths, ":"))
return func() {
os.Setenv("PATH", originalPath)
}
}

View File

@ -0,0 +1,63 @@
package executable_worker_test
import (
"os"
"regexp"
"testing"
"github.com/photoview/photoview/api/scanner/media_encoding/executable_worker"
)
func TestMagickWorkerNotExist(t *testing.T) {
done := setPathWithCurrent()
defer done()
executable_worker.InitializeExecutableWorkers()
if executable_worker.MagickCli.IsInstalled() {
t.Error("MagickCli should not be installed, but is found:", executable_worker.MagickCli)
}
}
func TestMagickWorkerIgnore(t *testing.T) {
done := setPathWithCurrent("./testdata/bin")
defer done()
org := os.Getenv("PHOTOVIEW_DISABLE_RAW_PROCESSING")
os.Setenv("PHOTOVIEW_DISABLE_RAW_PROCESSING", "true")
defer os.Setenv("PHOTOVIEW_DISABLE_RAW_PROCESSING", org)
executable_worker.InitializeExecutableWorkers()
if executable_worker.MagickCli.IsInstalled() {
t.Error("MagickCli should not be installed, but is found:", executable_worker.MagickCli)
}
}
func TestMagickWorker(t *testing.T) {
done := setPathWithCurrent("./testdata/bin")
defer done()
executable_worker.InitializeExecutableWorkers()
if !executable_worker.MagickCli.IsInstalled() {
t.Error("MagickCli should be installed")
}
t.Run("Failed", func(t *testing.T) {
err := executable_worker.MagickCli.EncodeJpeg("input", "output", 0)
if err == nil {
t.Fatalf("MagickCli.EncodeJpeg(\"input\", \"output\", 0) = nil, should be an error.")
}
if got, want := err.Error(), "^encoding image with \".*?/testdata/bin/convert .*?\" error: .*$"; !regexp.MustCompile(want).MatchString(got) {
t.Errorf("MagickCli.EncodeJpeg(\"input\", \"output\", 0) = %q, should be as reg pattern %q", got, want)
}
})
t.Run("Succeeded", func(t *testing.T) {
err := executable_worker.MagickCli.EncodeJpeg("input", "output", 70)
if err != nil {
t.Fatalf("MagickCli.EncodeJpeg(\"input\", \"output\", 0) = %v, should be nil.", err)
}
})
}

View File

@ -0,0 +1,13 @@
#!/bin/sh
case "$1" in
"--version")
echo convert: version fake
;;
esac
echo $@
if [ "$3" = "0" ] # quality parameter
then
exit -1
fi

View File

@ -260,7 +260,7 @@ func (imgType *MediaType) IsSupported() bool {
return true
}
if executable_worker.DarktableCli.IsInstalled() && imgType.IsRaw() {
if executable_worker.MagickCli.IsInstalled() && imgType.IsRaw() {
return true
}

View File

@ -0,0 +1,13 @@
Types: deb
# http://snapshot.debian.org/archive/debian/20240722T000000Z
URIs: http://deb.debian.org/debian
Suites: testing testing-updates
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Types: deb
# http://snapshot.debian.org/archive/debian-security/20240722T000000Z
URIs: http://deb.debian.org/debian-security
Suites: testing-security
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

11
scripts/apt/default.pref Normal file
View File

@ -0,0 +1,11 @@
Package: *
Pin: release n=bookworm
Pin-Priority: 700
Package: *
Pin: release n=bookworm-updates
Pin-Priority: 700
Package: *
Pin: release n=bookworm-security
Pin-Priority: 700

View File

@ -1,5 +1,5 @@
#!/bin/bash
set -e
set -euo pipefail
if [ "$TARGETPLATFORM" == "linux/arm64" ]; then
dpkg --add-architecture arm64

View File

@ -1,22 +1,10 @@
#!/bin/bash
set -euo pipefail
apt-get update
apt-get install -y curl libdlib19.1 ffmpeg exiftool libheif1
# Install Darktable if building for a supported architecture
if [ "${TARGETPLATFORM}" = "linux/amd64" ] || [ "${TARGETPLATFORM}" = "linux/arm64" ]; then
echo 'deb [trusted=true] https://download.opensuse.org/repositories/graphics:/darktable/Debian_12/ /' > /etc/apt/sources.list.d/darktable.list
# Release key is invalid, just trust the repo
curl -fsSL https://download.opensuse.org/repositories/graphics:/darktable/Debian_12/Release.key \
| gpg --dearmor -o /etc/apt/trusted.gpg.d/darktable.gpg
gpg --show-keys --with-fingerprint --dry-run /etc/apt/trusted.gpg.d/darktable.gpg
apt-get update
apt-get install -y darktable
fi
apt-get install -y curl libdlib19.2 ffmpeg exiftool libheif1 imagemagick
# Remove build dependencies and cleanup
apt-get purge -y ${BUILD_DEPENDS[@]}
apt-get autoremove -y
apt-get clean
rm -rf /var/lib/apt/lists/*