Skip to content

Commit c8c0dd7

Browse files
authored
Google Document AI (#208)
* feat(ocr): implement OCR provider interface and add Google Document AI and LLM providers * chore(deps): reorder dependencies in go.mod for better readability * chore: update version numbers and adjust Docker configuration for Google Document AI integration * feat(logging): add structured logging to Google Document AI and LLM providers * chore: add placeholder file to maintain directory structure in web-app/dist * chore(docker): remove Google Application Credentials configuration from docker-compose
1 parent b1a7b99 commit c8c0dd7

14 files changed

+581
-120
lines changed

.github/workflows/docker-build-and-push.yml

+1
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ jobs:
241241
run: npm run test:e2e
242242
env:
243243
CI: true
244+
DEBUG: testcontainers:containers
244245
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
245246
PAPERLESS_GPT_IMAGE: ${{ env.PAPERLESS_GPT_IMAGE }}
246247
- name: Upload Playwright Report

Dockerfile

+2-1
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ RUN go mod download
6060
RUN CGO_ENABLED=1 go build -tags musl -o /dev/null github.com/mattn/go-sqlite3
6161

6262
# Copy the frontend build
63-
COPY --from=frontend /app/dist /app/dist
63+
COPY --from=frontend /app/dist /app/web-app/dist
6464

6565
# Copy the Go source files
6666
COPY *.go .
67+
COPY ocr ./ocr
6768

6869
# Import ARGs from top level
6970
ARG VERSION

README.md

+123-79
Large diffs are not rendered by default.

embedded_assets.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import (
1111
"github.com/gin-gonic/gin"
1212
)
1313

14-
//go:embed dist/*
14+
//go:embed web-app/dist/*
1515
var webappContent embed.FS
1616

1717
// CreateEmbeddedFileServer creates a http.FileSystem from our embedded files
1818
func createEmbeddedFileServer() http.FileSystem {
1919
// Strip the "dist" prefix from the embedded files
20-
stripped, err := fs.Sub(webappContent, "dist")
20+
stripped, err := fs.Sub(webappContent, "web-app/dist")
2121
if err != nil {
2222
panic(err)
2323
}
@@ -32,7 +32,7 @@ func serveEmbeddedFile(c *gin.Context, prefix string, filepath string) {
3232
}
3333

3434
// Try to open the file from our embedded filesystem
35-
fullPath := path.Join("dist", prefix, filepath)
35+
fullPath := path.Join("web-app/dist", prefix, filepath)
3636
f, err := webappContent.Open(fullPath)
3737
if err != nil {
3838
// If file not found, serve 404

go.mod

+30-6
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,28 @@ go 1.22.0
55
toolchain go1.23.6
66

77
require (
8+
cloud.google.com/go/documentai v1.35.1
89
github.com/Masterminds/sprig/v3 v3.3.0
910
github.com/fatih/color v1.18.0
11+
github.com/gabriel-vasile/mimetype v1.4.3
1012
github.com/gen2brain/go-fitz v1.24.14
1113
github.com/gin-gonic/gin v1.10.0
1214
github.com/google/uuid v1.6.0
1315
github.com/sirupsen/logrus v1.9.3
1416
github.com/stretchr/testify v1.10.0
1517
github.com/tmc/langchaingo v0.1.13-pre.1
1618
golang.org/x/sync v0.11.0
19+
google.golang.org/api v0.214.0
1720
gorm.io/driver/sqlite v1.5.7
1821
gorm.io/gorm v1.25.12
1922
)
2023

2124
require (
25+
cloud.google.com/go v0.116.0 // indirect
26+
cloud.google.com/go/auth v0.13.0 // indirect
27+
cloud.google.com/go/auth/oauth2adapt v0.2.6 // indirect
28+
cloud.google.com/go/compute/metadata v0.6.0 // indirect
29+
cloud.google.com/go/longrunning v0.6.2 // indirect
2230
dario.cat/mergo v1.0.1 // indirect
2331
github.com/Masterminds/goutils v1.1.1 // indirect
2432
github.com/Masterminds/semver/v3 v3.3.0 // indirect
@@ -29,12 +37,17 @@ require (
2937
github.com/davecgh/go-spew v1.1.1 // indirect
3038
github.com/dlclark/regexp2 v1.10.0 // indirect
3139
github.com/ebitengine/purego v0.8.0 // indirect
32-
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
40+
github.com/felixge/httpsnoop v1.0.4 // indirect
3341
github.com/gin-contrib/sse v0.1.0 // indirect
42+
github.com/go-logr/logr v1.4.2 // indirect
43+
github.com/go-logr/stdr v1.2.2 // indirect
3444
github.com/go-playground/locales v0.14.1 // indirect
3545
github.com/go-playground/universal-translator v0.18.1 // indirect
3646
github.com/go-playground/validator/v10 v10.20.0 // indirect
3747
github.com/goccy/go-json v0.10.2 // indirect
48+
github.com/google/s2a-go v0.1.8 // indirect
49+
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
50+
github.com/googleapis/gax-go/v2 v2.14.0 // indirect
3851
github.com/huandu/xstrings v1.5.0 // indirect
3952
github.com/jinzhu/inflection v1.0.0 // indirect
4053
github.com/jinzhu/now v1.1.5 // indirect
@@ -61,11 +74,22 @@ require (
6174
gitlab.com/golang-commonmark/markdown v0.0.0-20211110145824-bf3e522c626a // indirect
6275
gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84 // indirect
6376
gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f // indirect
77+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
78+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
79+
go.opentelemetry.io/otel v1.29.0 // indirect
80+
go.opentelemetry.io/otel/metric v1.29.0 // indirect
81+
go.opentelemetry.io/otel/trace v1.29.0 // indirect
6482
golang.org/x/arch v0.8.0 // indirect
65-
golang.org/x/crypto v0.29.0 // indirect
66-
golang.org/x/net v0.25.0 // indirect
67-
golang.org/x/sys v0.27.0 // indirect
68-
golang.org/x/text v0.20.0 // indirect
69-
google.golang.org/protobuf v1.34.1 // indirect
83+
golang.org/x/crypto v0.31.0 // indirect
84+
golang.org/x/net v0.33.0 // indirect
85+
golang.org/x/oauth2 v0.24.0 // indirect
86+
golang.org/x/sys v0.28.0 // indirect
87+
golang.org/x/text v0.21.0 // indirect
88+
golang.org/x/time v0.8.0 // indirect
89+
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect
90+
google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 // indirect
91+
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
92+
google.golang.org/grpc v1.67.3 // indirect
93+
google.golang.org/protobuf v1.35.2 // indirect
7094
gopkg.in/yaml.v3 v3.0.1 // indirect
7195
)

go.sum

+59-20
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE=
2+
cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U=
3+
cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs=
4+
cloud.google.com/go/auth v0.13.0/go.mod h1:COOjD9gwfKNKz+IIduatIhYJQIc0mG3H102r/EMxX6Q=
5+
cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyTuciBG5hFkU=
6+
cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8=
7+
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
8+
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
9+
cloud.google.com/go/documentai v1.35.1 h1:52RfiUsoblXcE57CfKJGnITWLxRM30BcqNk/BKZl2LI=
10+
cloud.google.com/go/documentai v1.35.1/go.mod h1:WJjwUAQfwQPJORW8fjz7RODprMULDzEGLA2E6WxenFw=
11+
cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc=
12+
cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI=
113
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
214
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
315
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
@@ -23,6 +35,8 @@ github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+Gv
2335
github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
2436
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
2537
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
38+
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
39+
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
2640
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
2741
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
2842
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
@@ -33,6 +47,11 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
3347
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
3448
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
3549
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
50+
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
51+
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
52+
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
53+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
54+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
3655
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
3756
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
3857
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@@ -46,8 +65,14 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG
4665
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
4766
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
4867
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
68+
github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
69+
github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=
4970
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
5071
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
72+
github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
73+
github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
74+
github.com/googleapis/gax-go/v2 v2.14.0 h1:f+jMrjBPl+DL9nI4IQzLUxMq7XrAqFYB7hBPqMNIe8o=
75+
github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk=
5176
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
5277
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
5378
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
@@ -113,10 +138,6 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
113138
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
114139
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
115140
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
116-
github.com/tmc/langchaingo v0.1.12 h1:yXwSu54f3b1IKw0jJ5/DWu+qFVH1NBblwC0xddBzGJE=
117-
github.com/tmc/langchaingo v0.1.12/go.mod h1:cd62xD6h+ouk8k/QQFhOsjRYBSA1JJ5UVKXSIgm7Ni4=
118-
github.com/tmc/langchaingo v0.1.13-pre.0.0.20250202074804-0672790bb23a h1:uEmyBuBfueLWqdvxHYi9/smSb1BfHfXJpDjJAGI38A4=
119-
github.com/tmc/langchaingo v0.1.13-pre.0.0.20250202074804-0672790bb23a/go.mod h1:vpQ5NOIhpzxDfTZK9B6tf2GM/MoaHewPWM5KXXGh7hg=
120141
github.com/tmc/langchaingo v0.1.13-pre.1 h1:r+ma9kl0NuFJGtIrnMPFjEn4RhXktwSI31fIpgiiMm4=
121142
github.com/tmc/langchaingo v0.1.13-pre.1/go.mod h1:vpQ5NOIhpzxDfTZK9B6tf2GM/MoaHewPWM5KXXGh7hg=
122143
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
@@ -135,33 +156,51 @@ gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f h1:Wku8eEde
135156
gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f/go.mod h1:Tiuhl+njh/JIg0uS/sOJVYi0x2HEa5rc1OAaVsb5tAs=
136157
gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638 h1:uPZaMiz6Sz0PZs3IZJWpU5qHKGNy///1pacZC9txiUI=
137158
gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638/go.mod h1:EGRJaqe2eO9XGmFtQCvV3Lm9NLico3UhFwUpCG/+mVU=
159+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc=
160+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI=
161+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
162+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
163+
go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
164+
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
165+
go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
166+
go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
167+
go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
168+
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
138169
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
139170
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
140171
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
141-
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
142-
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
143-
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
144-
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
145-
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
146-
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
147-
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
148-
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
172+
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
173+
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
174+
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
175+
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
176+
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
177+
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
149178
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
150179
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
151180
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
152181
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
153182
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
154183
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
155-
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
156-
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
157-
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
158-
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
184+
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
185+
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
159186
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
160-
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
161-
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
187+
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
188+
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
189+
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
190+
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
162191
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
163-
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
164-
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
192+
google.golang.org/api v0.214.0 h1:h2Gkq07OYi6kusGOaT/9rnNljuXmqPnaig7WGPmKbwA=
193+
google.golang.org/api v0.214.0/go.mod h1:bYPpLG8AyeMWwDU6NXoB00xC0DFkikVvd5MfwoxjLqE=
194+
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk=
195+
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc=
196+
google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 h1:pgr/4QbFyktUv9CtQ/Fq4gzEE6/Xs7iCXbktaGzLHbQ=
197+
google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88=
198+
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY=
199+
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
200+
google.golang.org/grpc v1.67.3 h1:OgPcDAFKHnH8X3O4WcO4XUc8GRDeKsKReqbQtiCj7N8=
201+
google.golang.org/grpc v1.67.3/go.mod h1:YGaHCc6Oap+FzBJTZLBzkGSYt/cvGPFTPxkn7QfSU8s=
202+
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
203+
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
165204
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
166205
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
167206
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=

main.go

+37-8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"net/http"
77
"os"
8+
"paperless-gpt/ocr"
89
"path/filepath"
910
"runtime"
1011
"strconv"
@@ -113,10 +114,11 @@ Document Content:
113114

114115
// App struct to hold dependencies
115116
type App struct {
116-
Client *PaperlessClient
117-
Database *gorm.DB
118-
LLM llms.Model
119-
VisionLLM llms.Model
117+
Client *PaperlessClient
118+
Database *gorm.DB
119+
LLM llms.Model
120+
VisionLLM llms.Model
121+
ocrProvider ocr.Provider // OCR provider interface
120122
}
121123

122124
func main() {
@@ -150,12 +152,39 @@ func main() {
150152
log.Fatalf("Failed to create Vision LLM client: %v", err)
151153
}
152154

155+
// Initialize OCR provider
156+
var ocrProvider ocr.Provider
157+
providerType := os.Getenv("OCR_PROVIDER")
158+
if providerType == "" {
159+
providerType = "llm" // Default to LLM provider
160+
}
161+
162+
ocrConfig := ocr.Config{
163+
Provider: providerType,
164+
GoogleProjectID: os.Getenv("GOOGLE_PROJECT_ID"),
165+
GoogleLocation: os.Getenv("GOOGLE_LOCATION"),
166+
GoogleProcessorID: os.Getenv("GOOGLE_PROCESSOR_ID"),
167+
VisionLLMProvider: visionLlmProvider,
168+
VisionLLMModel: visionLlmModel,
169+
}
170+
171+
// If provider is LLM, but no VISION_LLM_PROVIDER is set, don't initialize OCR provider
172+
if providerType == "llm" && visionLlmProvider == "" {
173+
log.Warn("OCR provider is set to LLM, but no VISION_LLM_PROVIDER is set. Disabling OCR.")
174+
} else {
175+
ocrProvider, err = ocr.NewProvider(ocrConfig)
176+
if err != nil {
177+
log.Fatalf("Failed to initialize OCR provider: %v", err)
178+
}
179+
}
180+
153181
// Initialize App with dependencies
154182
app := &App{
155-
Client: client,
156-
Database: database,
157-
LLM: llm,
158-
VisionLLM: visionLlm,
183+
Client: client,
184+
Database: database,
185+
LLM: llm,
186+
VisionLLM: visionLlm,
187+
ocrProvider: ocrProvider,
159188
}
160189

161190
// Start background process for auto-tagging

ocr.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func (app *App) ProcessDocumentOCR(ctx context.Context, documentID int) (string,
3636
return "", fmt.Errorf("error reading image file for document %d, page %d: %w", documentID, i+1, err)
3737
}
3838

39-
ocrText, err := app.doOCRViaLLM(ctx, imageContent, pageLogger)
39+
ocrText, err := app.ocrProvider.ProcessImage(ctx, imageContent)
4040
if err != nil {
4141
return "", fmt.Errorf("error performing OCR for document %d, page %d: %w", documentID, i+1, err)
4242
}

0 commit comments

Comments
 (0)