Done all
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
/vendor
|
||||
**/.DS_Store
|
||||
**/.~lock*
|
||||
app
|
||||
build
|
||||
49
Dockerfile
Normal file
49
Dockerfile
Normal file
@@ -0,0 +1,49 @@
|
||||
FROM golang:1.23-alpine AS build
|
||||
|
||||
COPY ./gosrc/ /build
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
RUN go mod download
|
||||
|
||||
RUN go build -ldflags="-s -w" -o ./dist/app
|
||||
|
||||
|
||||
FROM php:8.2-cli
|
||||
|
||||
# Install dependencies needed for Composer and PHP zip extension
|
||||
RUN echo "deb http://deb.debian.org/debian bookworm contrib non-free" > /etc/apt/sources.list.d/contrib.list
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
unzip \
|
||||
libzip-dev \
|
||||
libreoffice \
|
||||
fontconfig \
|
||||
gcc \
|
||||
g++ \
|
||||
build-essential \
|
||||
ttf-mscorefonts-installer \
|
||||
&& docker-php-ext-install zip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install fonts
|
||||
RUN mkdir -p /usr/share/fonts/truetype/custom
|
||||
COPY ./fonts/gilroy/* /usr/share/fonts/truetype/custom
|
||||
COPY ./fonts/lexend/* /usr/share/fonts/truetype/custom
|
||||
RUN fc-cache -f -v
|
||||
|
||||
# Download and install Composer
|
||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||
|
||||
# Verify Composer installation
|
||||
RUN composer --version
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
|
||||
COPY --from=build /build/dist/app .
|
||||
|
||||
RUN rm -rf gosrc
|
||||
|
||||
CMD [ "/app/app" ]
|
||||
@@ -8,6 +8,9 @@ RUN apt-get update && apt-get install -y \
|
||||
libzip-dev \
|
||||
libreoffice \
|
||||
fontconfig \
|
||||
gcc \
|
||||
g++ \
|
||||
build-essential \
|
||||
ttf-mscorefonts-installer \
|
||||
&& docker-php-ext-install zip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -24,6 +27,21 @@ RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local
|
||||
# Verify Composer installation
|
||||
RUN composer --version
|
||||
|
||||
WORKDIR /app
|
||||
# Install Golang
|
||||
RUN curl -OL https://go.dev/dl/go1.23.0.linux-arm64.tar.gz \
|
||||
&& tar -C /usr/local -xzf go1.23.0.linux-arm64.tar.gz \
|
||||
&& rm go1.23.0.linux-arm64.tar.gz
|
||||
|
||||
CMD ["tail","-f", "/dev/null"]
|
||||
# Set Go environment variables
|
||||
ENV PATH="/usr/local/go/bin:${PATH}"
|
||||
|
||||
# Verify Go installation
|
||||
RUN go version
|
||||
|
||||
RUN curl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sh -s -- -b /usr/local/bin
|
||||
|
||||
WORKDIR /app/gosrc
|
||||
|
||||
CMD ["air", "-c", ".air.toml", "--", "run"]
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
@@ -5,3 +5,5 @@ services:
|
||||
dockerfile: dev.Dockerfile
|
||||
volumes:
|
||||
- ./:/app
|
||||
ports:
|
||||
- 8080:80
|
||||
|
||||
41
gosrc/.air.toml
Normal file
41
gosrc/.air.toml
Normal file
@@ -0,0 +1,41 @@
|
||||
root = "."
|
||||
testdata_dir = "testdata"
|
||||
tmp_dir = "build"
|
||||
|
||||
[build]
|
||||
args_bin = []
|
||||
bin = "./../app"
|
||||
cmd = "go build -gcflags='all=-N -l' -o ./../app ./main.go"
|
||||
delay = 0
|
||||
exclude_dir = ["assets", "build", "vendor", "testdata", "storage"]
|
||||
exclude_file = []
|
||||
exclude_regex = ["_test.go"]
|
||||
exclude_unchanged = false
|
||||
follow_symlink = false
|
||||
include_dir = []
|
||||
include_ext = ["go", "tpl", "tmpl", "html", "yaml"]
|
||||
include_file = []
|
||||
kill_delay = "0s"
|
||||
log = "build-errors.log"
|
||||
rerun = false
|
||||
rerun_delay = 500
|
||||
send_interrupt = false
|
||||
stop_on_error = true
|
||||
|
||||
[color]
|
||||
app = ""
|
||||
build = "yellow"
|
||||
main = "magenta"
|
||||
runner = "green"
|
||||
watcher = "cyan"
|
||||
|
||||
[log]
|
||||
main_only = true
|
||||
time = true
|
||||
|
||||
[misc]
|
||||
clean_on_exit = false
|
||||
|
||||
[screen]
|
||||
clear_on_rebuild = false
|
||||
keep_scroll = true
|
||||
1
gosrc/.gitignore
vendored
Normal file
1
gosrc/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
build
|
||||
18
gosrc/go.mod
Normal file
18
gosrc/go.mod
Normal file
@@ -0,0 +1,18 @@
|
||||
module menulis.ai/genpdf
|
||||
|
||||
go 1.22.0
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/gofiber/fiber/v2 v2.52.5 // indirect
|
||||
github.com/google/uuid v1.5.0 // indirect
|
||||
github.com/klauspost/compress v1.17.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
)
|
||||
27
gosrc/go.sum
Normal file
27
gosrc/go.sum
Normal file
@@ -0,0 +1,27 @@
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
|
||||
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
|
||||
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
||||
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
56
gosrc/main.go
Normal file
56
gosrc/main.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
var rootPath string
|
||||
|
||||
func main() {
|
||||
rootPath = os.Getenv("APP_ROOT_PATH")
|
||||
if rootPath == "" {
|
||||
rootPath = "/app"
|
||||
}
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Post("ebook", handleEbook)
|
||||
|
||||
log.Fatal(app.Listen(":80"))
|
||||
}
|
||||
|
||||
func handleEbook(c *fiber.Ctx) error {
|
||||
|
||||
f, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("error receiving file: %s", err))
|
||||
}
|
||||
|
||||
sp := path.Join(rootPath, fmt.Sprintf("storage/%s.json", uuid.NewString()))
|
||||
|
||||
err = c.SaveFile(f, sp)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("failed to save file: %s", err))
|
||||
}
|
||||
|
||||
cmd := exec.Command(path.Join(rootPath, "genpdf"), "generate:ebook", sp)
|
||||
|
||||
o, err := cmd.Output()
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("failed to convert ebook: %s", err))
|
||||
}
|
||||
err = c.Download(strings.TrimSpace(string(o)))
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("failed to sending ebook: %s", err))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -12,7 +12,7 @@ use Symfony\Component\Process\Exception\ProcessFailedException;
|
||||
|
||||
class Generate extends Command
|
||||
{
|
||||
protected static $defaultName = "generate";
|
||||
protected static $defaultName = "generate:ebook";
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
@@ -35,7 +35,7 @@ class Generate extends Command
|
||||
"--convert-to",
|
||||
"pdf",
|
||||
"--outdir",
|
||||
"storage/",
|
||||
"/app/storage/",
|
||||
$path
|
||||
]);
|
||||
|
||||
@@ -45,7 +45,7 @@ class Generate extends Command
|
||||
throw new ProcessFailedException($cmd);
|
||||
}
|
||||
|
||||
$output->writeln($cmd->getOutput());
|
||||
$output->writeln(rootPath("storage/" . pathinfo($path, PATHINFO_FILENAME) . ".pdf"));
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ class Register
|
||||
public function init(): array
|
||||
{
|
||||
return [
|
||||
new Generate("generate")
|
||||
new Generate("generate:ebook")
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user