Done all
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
/vendor
|
/vendor
|
||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
**/.~lock*
|
**/.~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 \
|
libzip-dev \
|
||||||
libreoffice \
|
libreoffice \
|
||||||
fontconfig \
|
fontconfig \
|
||||||
|
gcc \
|
||||||
|
g++ \
|
||||||
|
build-essential \
|
||||||
ttf-mscorefonts-installer \
|
ttf-mscorefonts-installer \
|
||||||
&& docker-php-ext-install zip \
|
&& docker-php-ext-install zip \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& 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
|
# Verify Composer installation
|
||||||
RUN composer --version
|
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
|
dockerfile: dev.Dockerfile
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/app
|
- ./:/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
|
class Generate extends Command
|
||||||
{
|
{
|
||||||
protected static $defaultName = "generate";
|
protected static $defaultName = "generate:ebook";
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
@@ -35,7 +35,7 @@ class Generate extends Command
|
|||||||
"--convert-to",
|
"--convert-to",
|
||||||
"pdf",
|
"pdf",
|
||||||
"--outdir",
|
"--outdir",
|
||||||
"storage/",
|
"/app/storage/",
|
||||||
$path
|
$path
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ class Generate extends Command
|
|||||||
throw new ProcessFailedException($cmd);
|
throw new ProcessFailedException($cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
$output->writeln($cmd->getOutput());
|
$output->writeln(rootPath("storage/" . pathinfo($path, PATHINFO_FILENAME) . ".pdf"));
|
||||||
|
|
||||||
return Command::SUCCESS;
|
return Command::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class Register
|
|||||||
public function init(): array
|
public function init(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
new Generate("generate")
|
new Generate("generate:ebook")
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user