1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-10-18 17:10:11 +00:00

Compare commits

..

No commits in common. "7bd8fadf7654dc6c1e1717cf3021d5f0ede1e041" and "9787fce275256cd3bf71a295911fd1ce826c30a4" have entirely different histories.

27 changed files with 50 additions and 870 deletions

View File

@ -11,8 +11,6 @@ steps:
- name: release - name: release
image: golang:latest image: golang:latest
environment: environment:
BUILDRONE_KEY:
from_secret: BUILDRONE_KEY
GITHUB_TOKEN: GITHUB_TOKEN:
from_secret: github_token from_secret: github_token
commands: commands:
@ -20,12 +18,7 @@ steps:
- apt install build-essential python3-pip curl software-properties-common sed upx -y - apt install build-essential python3-pip curl software-properties-common sed upx -y
- (curl -sL https://deb.nodesource.com/setup_14.x | bash -) - (curl -sL https://deb.nodesource.com/setup_14.x | bash -)
- apt install nodejs - apt install nodejs
- curl -sL https://git.io/goreleaser > goreleaser - curl -sL https://git.io/goreleaser | bash
- chmod +x goreleaser
- ./scripts/version.sh ./goreleaser
- wget https://builds.hrfee.pw/upload.py
- pip3 install requests
- bash -c 'python3 upload.py https://builds.hrfee.pw hrfee jfa-go --tag internal=true'
trigger: trigger:
event: event:
- tag - tag
@ -40,9 +33,6 @@ steps:
volumes: volumes:
- name: ssh_key - name: ssh_key
path: /root/drone_rsa path: /root/drone_rsa
environment:
BUILDRONE_KEY:
from_secret: BUILDRONE_KEY
settings: settings:
host: host:
from_secret: ssh2_host from_secret: ssh2_host
@ -54,14 +44,8 @@ steps:
- /root/.ssh/docker-build:/root/drone_rsa - /root/.ssh/docker-build:/root/drone_rsa
key_path: /root/drone_rsa key_path: /root/drone_rsa
command_timeout: 50m command_timeout: 50m
envs:
- BUILDRONE_KEY
script: script:
- /mnt/buildx/jfa-go/build.sh stable - /mnt/buildx/jfa-go/build.sh stable
- wget https://builds.hrfee.pw/upload.py -O /mnt/buildx/jfa-go/jfa-go/upload.py
- pip3 install requests
- bash -c 'cd /mnt/buildx/jfa-go/jfa-go && BUILDRONE_KEY=$(cat /mnt/buildx/jfa-go/key) python3 upload.py https://builds.hrfee.pw hrfee jfa-go --tag docker-stable=true'
- rm -f /mnt/buildx/jfa-go/jfa-go/upload.py
trigger: trigger:
event: event:
- tag - tag
@ -82,12 +66,12 @@ steps:
- apt install build-essential python3-pip curl software-properties-common sed upx -y - apt install build-essential python3-pip curl software-properties-common sed upx -y
- (curl -sL https://deb.nodesource.com/setup_14.x | bash -) - (curl -sL https://deb.nodesource.com/setup_14.x | bash -)
- apt install nodejs - apt install nodejs
- curl -sL https://git.io/goreleaser > goreleaser - curl -sL https://git.io/goreleaser > goreleaser.sh
- chmod +x goreleaser - chmod +x goreleaser.sh
- ./scripts/version.sh ./goreleaser --snapshot --skip-publish --rm-dist - ./goreleaser.sh --snapshot --skip-publish --rm-dist
- wget https://builds.hrfee.pw/upload.py - wget https://builds.hrfee.pw/upload.py
- pip3 install requests - pip3 install requests
- bash -c 'python3 upload.py https://builds.hrfee.pw hrfee jfa-go --upload ./dist/*.tar.gz --tag internal-git=true' - bash -c 'python3 upload.py https://builds.hrfee.pw hrfee jfa-go ./dist/*.tar.gz'
environment: environment:
BUILDRONE_KEY: BUILDRONE_KEY:
from_secret: BUILDRONE_KEY from_secret: BUILDRONE_KEY
@ -124,10 +108,6 @@ steps:
command_timeout: 50m command_timeout: 50m
script: script:
- /mnt/buildx/jfa-go/build.sh - /mnt/buildx/jfa-go/build.sh
- wget https://builds.hrfee.pw/upload.py -O /mnt/buildx/jfa-go/jfa-go/upload.py
- pip3 install requests
- bash -c 'cd /mnt/buildx/jfa-go/jfa-go && BUILDRONE_KEY=$(cat /mnt/buildx/jfa-go/key) python3 upload.py https://builds.hrfee.pw hrfee jfa-go --tag docker-unstable=true'
- rm -f /mnt/buildx/jfa-go/jfa-go/upload.py
trigger: trigger:
branch: branch:
- main - main
@ -152,9 +132,9 @@ steps:
- apt install build-essential python3-pip curl software-properties-common sed upx -y - apt install build-essential python3-pip curl software-properties-common sed upx -y
- (curl -sL https://deb.nodesource.com/setup_14.x | bash -) - (curl -sL https://deb.nodesource.com/setup_14.x | bash -)
- apt install nodejs - apt install nodejs
- curl -sL https://git.io/goreleaser > goreleaser - curl -sL https://git.io/goreleaser > goreleaser.sh
- chmod +x goreleaser - chmod +x goreleaser.sh
- ./scripts/version.sh ./goreleaser --snapshot --skip-publish --rm-dist - ./goreleaser.sh --snapshot --skip-publish --rm-dist
trigger: trigger:
event: event:

View File

@ -17,7 +17,6 @@ before:
- cp node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 data/web/css/ - cp node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 data/web/css/
- cp -r html data/ - cp -r html data/
- cp -r lang data/ - cp -r lang data/
- cp LICENSE data/
- python3 scripts/enumerate_config.py -i config/config-base.json -o data/config-base.json - python3 scripts/enumerate_config.py -i config/config-base.json -o data/config-base.json
- python3 scripts/generate_ini.py -i config/config-base.json -o data/config-default.ini - python3 scripts/generate_ini.py -i config/config-base.json -o data/config-default.ini
- python3 scripts/compile_mjml.py -o data/ - python3 scripts/compile_mjml.py -o data/
@ -31,8 +30,6 @@ builds:
- dir: ./ - dir: ./
env: env:
- CGO_ENABLED=0 - CGO_ENABLED=0
ldflags:
- -s -w -X main.version={{.Env.JFA_GO_VERSION}} -X main.commit={{.ShortCommit}} -X main.updater=binary
goos: goos:
- linux - linux
- windows - windows

View File

@ -16,7 +16,7 @@ ENV GOARCH=$TARGETARCH
COPY --from=support /opt/build /opt/build COPY --from=support /opt/build /opt/build
RUN (cd /opt/build; make compile UPDATER=docker) RUN (cd /opt/build; make compile)
FROM golang:latest FROM golang:latest

View File

@ -10,14 +10,6 @@ VERSION ?= $(shell git describe --exact-match HEAD 2> /dev/null || echo vgit)
VERSION := $(shell echo $(VERSION) | sed 's/v//g') VERSION := $(shell echo $(VERSION) | sed 's/v//g')
COMMIT ?= $(shell git rev-parse --short HEAD || echo unknown) COMMIT ?= $(shell git rev-parse --short HEAD || echo unknown)
UPDATER ?= off
BUILDFLAGS := -X main.version=$(VERSION) -X main.commit=$(COMMIT)
ifeq ($(UPDATER), on)
BUILDFLAGS := $(BUILDFLAGS) -X main.updater=binary
else ifneq ($(UPDATER), off)
BUILDFLAGS := $(BUILDFLAGS) -X main.updater=$(UPDATER)
endif
npm: npm:
$(info installing npm dependencies) $(info installing npm dependencies)
npm install npm install
@ -64,14 +56,14 @@ compile:
$(GOBINARY) mod download $(GOBINARY) mod download
$(info Building) $(info Building)
mkdir -p build mkdir -p build
cd build && CGO_ENABLED=0 $(GOBINARY) build -ldflags="-s -w $(BUILDFLAGS)" -o ./jfa-go ../*.go cd build && CGO_ENABLED=0 $(GOBINARY) build -ldflags="-s -w -X main.version=$(VERSION) -X main.commit=$(COMMIT)" -o ./jfa-go ../*.go
compile-debug: compile-debug:
$(info Downloading deps) $(info Downloading deps)
$(GOBINARY) mod download $(GOBINARY) mod download
$(info Building) $(info Building)
mkdir -p build mkdir -p build
cd build && CGO_ENABLED=0 $(GOBINARY) build -ldflags "$(BUILDFLAGS)" -o ./jfa-go ../*.go cd build && CGO_ENABLED=0 $(GOBINARY) build -ldflags "-X main.version=$(VERSION) -X main.commit=$(COMMIT)" -o ./jfa-go ../*.go
compress: compress:
upx --lzma build/jfa-go upx --lzma build/jfa-go

33
api.go
View File

@ -1440,39 +1440,6 @@ func (app *appContext) SetEmailState(gc *gin.Context) {
respondBool(200, true, gc) respondBool(200, true, gc)
} }
// @Summary Returns whether there's a new update, and extra info if there is.
// @Produce json
// @Success 200 {object} checkUpdateDTO
// @Router /config/update [get]
// @tags Configuration
func (app *appContext) CheckUpdate(gc *gin.Context) {
if !app.newUpdate {
app.update = Update{}
}
gc.JSON(200, checkUpdateDTO{New: app.newUpdate, Update: app.update})
}
// @Summary Apply an update.
// @Produce json
// @Success 200 {object} boolResponse
// @Success 400 {object} stringResponse
// @Success 500 {object} boolResponse
// @Router /config/update [post]
// @tags Configuration
func (app *appContext) ApplyUpdate(gc *gin.Context) {
if !app.update.CanUpdate {
respond(400, "Update is manual", gc)
return
}
err := app.update.update()
if err != nil {
app.err.Printf("Failed to apply update: %s", err)
respondBool(500, false, gc)
return
}
respondBool(200, true, gc)
}
// @Summary Returns the custom email (generating it if not set) and list of used variables in it. // @Summary Returns the custom email (generating it if not set) and list of used variables in it.
// @Produce json // @Produce json
// @Success 200 {object} customEmailDTO // @Success 200 {object} customEmailDTO

View File

@ -84,28 +84,6 @@ func (app *appContext) loadConfig() error {
emailEnabled = true emailEnabled = true
} }
app.MustSetValue("updates", "enabled", "true")
releaseChannel := app.config.Section("updates").Key("channel").String()
if app.config.Section("updates").Key("enabled").MustBool(false) {
v := version
if releaseChannel == "stable" {
if version == "git" {
v = "0.0.0"
}
} else if releaseChannel == "unstable" {
v = "git"
}
app.updater = newUpdater(baseURL, namespace, repo, v, commit, updater)
}
if releaseChannel == "" {
if version == "git" {
releaseChannel = "unstable"
} else {
releaseChannel = "stable"
}
app.MustSetValue("updates", "channel", releaseChannel)
}
app.storage.customEmails_path = app.config.Section("files").Key("custom_emails").String() app.storage.customEmails_path = app.config.Section("files").Key("custom_emails").String()
app.storage.loadCustomEmails() app.storage.loadCustomEmails()

View File

@ -1,35 +1,6 @@
{ {
"order": [], "order": [],
"sections": { "sections": {
"updates": {
"order": [],
"meta": {
"name": "Updates",
"description": "Settings for update notifications and release channel."
},
"settings": {
"enabled": {
"name": "Enabled",
"required": true,
"requires_restart": true,
"type": "bool",
"value": true,
"description": "Enable/disable updating notifications and downloading/applying updates."
},
"channel": {
"name": "Release Channel",
"required": true,
"requires_restart": false,
"type": "select",
"options": [
["stable", "Stable"],
["unstable", "Unstable"]
],
"value": "",
"description": "Release channel for updates."
}
}
},
"jellyfin": { "jellyfin": {
"order": [], "order": [],
"meta": { "meta": {

View File

@ -417,31 +417,3 @@ pre {
white-space: -o-pre-wrap; /* Opera 7 */ white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */ word-wrap: break-word; /* Internet Explorer 5.5+ */
} }
.circle {
height: 0.5rem;
width: 0.5rem;
border-radius: 50%;
}
.circle.\~urge {
background-color: var(--color-urge-200);
}
.markdown-box {
max-height: 20rem;
display: block;
overflow-y: scroll;
}
a:link {
color: var(--color-urge-200);
}
a:visited {
color: var(--color-urge-100);
}
a:hover, a:active {
color: var(--color-urge-200);
}

View File

@ -8,8 +8,6 @@ import (
"strings" "strings"
) )
const binaryType = "external"
var localFS fs.FS var localFS fs.FS
var langFS fs.FS var langFS fs.FS

View File

@ -6,8 +6,6 @@ import (
"log" "log"
) )
const binaryType = "internal"
//go:embed data data/html data/web data/web/css data/web/js //go:embed data data/html data/web data/web/css data/web/js
var loFS embed.FS var loFS embed.FS

5
go.mod
View File

@ -11,7 +11,6 @@ replace github.com/hrfee/jfa-go/common => ./common
replace github.com/hrfee/jfa-go/ombi => ./ombi replace github.com/hrfee/jfa-go/ombi => ./ombi
require ( require (
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/evanw/esbuild v0.8.50 // indirect github.com/evanw/esbuild v0.8.50 // indirect
github.com/fatih/color v1.10.0 github.com/fatih/color v1.10.0
@ -35,7 +34,6 @@ require (
github.com/mailgun/mailgun-go/v4 v4.3.0 github.com/mailgun/mailgun-go/v4 v4.3.0
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14
github.com/swaggo/gin-swagger v1.3.0 github.com/swaggo/gin-swagger v1.3.0
@ -43,8 +41,7 @@ require (
github.com/ugorji/go v1.2.0 // indirect github.com/ugorji/go v1.2.0 // indirect
github.com/writeas/go-strip-markdown v2.0.1+incompatible github.com/writeas/go-strip-markdown v2.0.1+incompatible
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 // indirect golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 // indirect
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 // indirect
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b // indirect
golang.org/x/tools v0.1.0 // indirect golang.org/x/tools v0.1.0 // indirect
google.golang.org/protobuf v1.25.0 // indirect google.golang.org/protobuf v1.25.0 // indirect
gopkg.in/ini.v1 v1.62.0 gopkg.in/ini.v1 v1.62.0

10
go.sum
View File

@ -17,8 +17,6 @@ github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJ
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -190,8 +188,6 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCb
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
@ -270,8 +266,6 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew= golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -299,10 +293,6 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbq
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 h1:SgQ6LNaYJU0JIuEHv9+s6EbhSCwYeAf5Yvj6lpYlqAE= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 h1:SgQ6LNaYJU0JIuEHv9+s6EbhSCwYeAf5Yvj6lpYlqAE=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04 h1:cEhElsAv9LUt9ZUUocxzWe05oFLVd+AA2nstydTeI8g=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b h1:ggRgirZABFolTmi3sn6Ivd9SipZwLedQ5wR0aAKnFxU=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -254,21 +254,6 @@
</label> </label>
</form> </form>
</div> </div>
<div id="modal-update" class="modal">
<div class="modal-content wide card">
<span class="heading">{{ .strings.updates }} <span class="modal-close">&times;</span></span>
<p class="content">
<h2>
<a id="update-version"></a> (<span class="monospace" id="update-commit"></span>)
</h2>
<p class="content" id="update-description"></p>
<p class="support" id="update-date"></p>
<div class="content markdown-box" id="update-changelog"></div>
</p>
<span class="button ~info !normal full-width center" id="update-download">{{ .strings.download }}</span>
<span class="button ~urge !normal full-width center" id="update-update">{{ .strings.update }}</span>
</div>
</div>
<div id="notification-box"></div> <div id="notification-box"></div>
<span class="dropdown" tabindex="0" id="lang-dropdown"> <span class="dropdown" tabindex="0" id="lang-dropdown">
<span class="button ~urge dropdown-button"> <span class="button ~urge dropdown-button">

View File

@ -24,9 +24,6 @@
"enabled": "Enabled", "enabled": "Enabled",
"disabled": "Disabled", "disabled": "Disabled",
"admin": "Admin", "admin": "Admin",
"updates": "Updates",
"update": "Update",
"download": "Download",
"lastActiveTime": "Last Active", "lastActiveTime": "Last Active",
"from": "From", "from": "From",
"user": "User", "user": "User",
@ -96,7 +93,6 @@
"saveEmail": "Email saved.", "saveEmail": "Email saved.",
"sentAnnouncement": "Announcement sent.", "sentAnnouncement": "Announcement sent.",
"setOmbiDefaults": "Stored ombi defaults.", "setOmbiDefaults": "Stored ombi defaults.",
"updateApplied": "Update applied, please restart.",
"errorConnection": "Couldn't connect to jfa-go.", "errorConnection": "Couldn't connect to jfa-go.",
"error401Unauthorized": "Unauthorized. Try refreshing the page.", "error401Unauthorized": "Unauthorized. Try refreshing the page.",
"errorSettingsAppliedNoHomescreenLayout": "Settings were applied, but applying homescreen layout may have failed.", "errorSettingsAppliedNoHomescreenLayout": "Settings were applied, but applying homescreen layout may have failed.",
@ -119,11 +115,7 @@
"errorFailureCheckLogs": "Failed (check console/logs)", "errorFailureCheckLogs": "Failed (check console/logs)",
"errorPartialFailureCheckLogs": "Partial failure (check console/logs)", "errorPartialFailureCheckLogs": "Partial failure (check console/logs)",
"errorUserCreated": "Failed to create user {n}.", "errorUserCreated": "Failed to create user {n}.",
"errorSendWelcomeEmail": "Failed to send welcome email (check console/logs)", "errorSendWelcomeEmail": "Failed to send welcome email (check console/logs)"
"errorApplyUpdate": "Failed to apply update, try manually.",
"errorCheckUpdate": "Failed to check for update.",
"updateAvailable": "A new update is available, check settings.",
"noUpdatesAvailable": "No new updates available."
}, },
"quantityStrings": { "quantityStrings": {
"modifySettingsFor": { "modifySettingsFor": {

22
main.go
View File

@ -48,14 +48,6 @@ var (
commit string commit string
) )
var temp = func() string {
temp := "/tmp"
if PLATFORM == "windows" {
temp = os.Getenv("TEMP")
}
return temp
}()
var serverTypes = map[string]string{ var serverTypes = map[string]string{
"jellyfin": "Jellyfin", "jellyfin": "Jellyfin",
"emby": "Emby (experimental)", "emby": "Emby (experimental)",
@ -98,10 +90,6 @@ type appContext struct {
version string version string
quit chan os.Signal quit chan os.Signal
URLBase string URLBase string
updater *Updater
newUpdate bool // Whether whatever's in update is new.
tag Tag
update Update
} }
func generateSecret(length int) (string, error) { func generateSecret(length int) (string, error) {
@ -533,10 +521,6 @@ func start(asDaemon, firstCall bool) {
if app.config.Section("password_resets").Key("enabled").MustBool(false) && serverType == mediabrowser.JellyfinServer { if app.config.Section("password_resets").Key("enabled").MustBool(false) && serverType == mediabrowser.JellyfinServer {
go app.StartPWR() go app.StartPWR()
} }
if app.config.Section("updates").Key("enabled").MustBool(false) {
go app.checkForUpdates()
}
} else { } else {
debugMode = false debugMode = false
address = "0.0.0.0:8056" address = "0.0.0.0:8056"
@ -652,7 +636,11 @@ func printVersion() {
func main() { func main() {
printVersion() printVersion()
SOCK = filepath.Join(temp, SOCK) folder := "/tmp"
if PLATFORM == "windows" {
folder = os.Getenv("TEMP")
}
SOCK = filepath.Join(folder, SOCK)
fmt.Println("Socket:", SOCK) fmt.Println("Socket:", SOCK)
if flagPassed("test") { if flagPassed("test") {
TEST = true TEST = true

View File

@ -214,8 +214,3 @@ type extendExpiryDTO struct {
Hours int `json:"hours" example:"2"` // Number of hours to add. Hours int `json:"hours" example:"2"` // Number of hours to add.
Minutes int `json:"minutes" example:"3"` // Number of minutes to add. Minutes int `json:"minutes" example:"3"` // Number of minutes to add.
} }
type checkUpdateDTO struct {
New bool `json:"new"` // Whether or not there's a new update.
Update Update `json:"update"`
}

6
package-lock.json generated
View File

@ -236,9 +236,9 @@
"integrity": "sha1-vfpzUplmTfr9NFKe1PhSKidf6lY=" "integrity": "sha1-vfpzUplmTfr9NFKe1PhSKidf6lY="
}, },
"esbuild": { "esbuild": {
"version": "0.8.56", "version": "0.8.53",
"resolved": "https://registry.npm.taobao.org/esbuild/download/esbuild-0.8.56.tgz", "resolved": "https://registry.npm.taobao.org/esbuild/download/esbuild-0.8.53.tgz",
"integrity": "sha1-nHw9bmFNtzZ6+jSK2wqyh8KWc14=" "integrity": "sha1-tAi7DKGynasT2Lv31Z9Zr+Z3boY="
}, },
"escalade": { "escalade": {
"version": "3.1.1", "version": "3.1.1",

View File

@ -19,7 +19,7 @@
"dependencies": { "dependencies": {
"@ts-stack/markdown": "^1.3.0", "@ts-stack/markdown": "^1.3.0",
"a17t": "^0.4.0", "a17t": "^0.4.0",
"esbuild": "^0.8.56", "esbuild": "^0.8.53",
"lodash": "^4.17.19", "lodash": "^4.17.19",
"mjml": "^4.8.0", "mjml": "^4.8.0",
"remixicon": "^2.5.0", "remixicon": "^2.5.0",

View File

@ -140,8 +140,6 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
// api.POST(p + "/setDefaults", app.SetDefaults) // api.POST(p + "/setDefaults", app.SetDefaults)
api.POST(p+"/users/settings", app.ApplySettings) api.POST(p+"/users/settings", app.ApplySettings)
api.POST(p+"/users/announce", app.Announce) api.POST(p+"/users/announce", app.Announce)
api.GET(p+"/config/update", app.CheckUpdate)
api.POST(p+"/config/update", app.ApplyUpdate)
api.GET(p+"/config/emails", app.GetEmails) api.GET(p+"/config/emails", app.GetEmails)
api.GET(p+"/config/emails/:id", app.GetEmail) api.GET(p+"/config/emails/:id", app.GetEmail)
api.POST(p+"/config/emails/:id", app.SetEmail) api.POST(p+"/config/emails/:id", app.SetEmail)

27
scripts/version.py Normal file
View File

@ -0,0 +1,27 @@
import subprocess
import sys
try:
version = sys.argv[1].replace('v', '')
except IndexError:
version = "git"
if version == "auto":
try:
version = subprocess.check_output("git describe --exact-match HEAD".split()).decode("utf-8").rstrip().replace('v', '')
except subprocess.CalledProcessError as e:
if e.returncode == 128:
version = "git"
commit = subprocess.check_output("git rev-parse --short HEAD".split()).decode("utf-8").rstrip()
file = f'package main; const VERSION = "{version}"; const COMMIT = "{commit}";'
try:
writeto = sys.argv[2]
except IndexError:
writeto = "version.go"
with open(writeto, 'w') as f:
f.write(file)

View File

@ -1,3 +0,0 @@
#!/bin/bash
JFA_GO_VERSION=$(git describe --exact-match HEAD 2> /dev/null || echo 'vgit')
JFA_GO_VERSION="$(echo $JFA_GO_VERSION | sed 's/v//g')" $@

View File

@ -7,7 +7,6 @@ import { accountsList } from "./modules/accounts.js";
import { settingsList } from "./modules/settings.js"; import { settingsList } from "./modules/settings.js";
import { ProfileEditor } from "./modules/profiles.js"; import { ProfileEditor } from "./modules/profiles.js";
import { _get, _post, notificationBox, whichAnimationEvent, toggleLoader } from "./modules/common.js"; import { _get, _post, notificationBox, whichAnimationEvent, toggleLoader } from "./modules/common.js";
import { Updater } from "./modules/update.js";
loadTheme(); loadTheme();
(document.getElementById('button-theme') as HTMLSpanElement).onclick = toggleTheme; (document.getElementById('button-theme') as HTMLSpanElement).onclick = toggleTheme;
@ -60,12 +59,9 @@ window.availableProfiles = window.availableProfiles || [];
window.modals.customizeEmails = new Modal(document.getElementById("modal-customize")); window.modals.customizeEmails = new Modal(document.getElementById("modal-customize"));
window.modals.extendExpiry = new Modal(document.getElementById("modal-extend-expiry")); window.modals.extendExpiry = new Modal(document.getElementById("modal-extend-expiry"));
window.modals.updateInfo = new Modal(document.getElementById("modal-update"));
})(); })();
var inviteCreator = new createInvite(); var inviteCreator = new createInvite();
var accounts = new accountsList(); var accounts = new accountsList();
window.invites = new inviteList(); window.invites = new inviteList();
@ -158,7 +154,6 @@ function login(username: string, password: string, run?: (state?: number) => voi
} else { } else {
const data = this.response; const data = this.response;
window.token = data["token"]; window.token = data["token"];
window.updater = new Updater(); // mmm, a race condition
window.modals.login.close(); window.modals.login.close();
setInterval(() => { window.invites.reload(); accounts.reload(); }, 30*1000); setInterval(() => { window.invites.reload(); accounts.reload(); }, 30*1000);
const currentTab = window.tabs.current; const currentTab = window.tabs.current;
@ -203,3 +198,4 @@ login("", "");
return false; return false;
} }
}); });

View File

@ -598,14 +598,6 @@ export class settingsList {
`; `;
(editButton.querySelector("span.button") as HTMLSpanElement).onclick = this._emailEditor.showList; (editButton.querySelector("span.button") as HTMLSpanElement).onclick = this._emailEditor.showList;
this.addSection(name, settings.sections[name], editButton); this.addSection(name, settings.sections[name], editButton);
} else if (name == "updates") {
const icon = document.createElement("span") as HTMLSpanElement;
if (window.updater.updateAvailable) {
icon.classList.add("button", "~urge");
icon.innerHTML = `<i class="ri-download-line" title="${window.lang.strings("update")}"></i>`;
icon.onclick = () => window.updater.checkForUpdates(window.modals.updateInfo.show);
}
this.addSection(name, settings.sections[name], icon);
} else { } else {
this.addSection(name, settings.sections[name]); this.addSection(name, settings.sections[name]);
} }

View File

@ -1,124 +0,0 @@
import { _get, _post, toggleLoader } from "../modules/common.js";
import { Marked, Renderer } from "@ts-stack/markdown";
interface updateDTO {
new: boolean;
update: Update;
}
export class Updater implements updater {
private _update: Update;
private _date: Date;
updateAvailable = false;
checkForUpdates = (run?: (req: XMLHttpRequest) => void) => _get("/config/update", null, (req: XMLHttpRequest) => {
if (req.readyState == 4) {
if (req.status != 200) {
window.notifications.customError("errorCheckUpdate", window.lang.notif("errorCheckUpdate"));
return
}
let resp = req.response as updateDTO;
if (resp.new) {
this.update = resp.update;
if (run) { run(req); }
// } else {
// window.notifications.customPositive("noUpdatesAvailable", "", window.lang.notif("noUpdatesAvailable"));
}
}
});
get date(): number { return Math.floor(this._date.getTime() / 1000); }
set date(unix: number) {
this._date = new Date(unix * 1000);
document.getElementById("update-date").textContent = this._date.toDateString() + " " + this._date.toLocaleTimeString();
}
get description(): string { return this._update.description; }
set description(description: string) {
this._update.description = description;
const el = document.getElementById("update-description") as HTMLParagraphElement;
el.textContent = description;
if (this.version == "git") {
el.classList.add("monospace");
} else {
el.classList.remove("monospace");
}
}
get changelog(): string { return this._update.changelog; }
set changelog(changelog: string) {
this._update.changelog = changelog;
document.getElementById("update-changelog").innerHTML = Marked.parse(changelog);
}
get version(): string { return this._update.version; }
set version(version: string) {
this._update.version = version;
document.getElementById("update-version").textContent = version;
}
get commit(): string { return this._update.commit; }
set commit(commit: string) {
this._update.commit = commit;
document.getElementById("update-commit").textContent = commit.slice(0, 7);
}
get link(): string { return this._update.link; }
set link(link: string) {
this._update.link = link;
(document.getElementById("update-version") as HTMLAnchorElement).href = link;
}
get download_link(): string { return this._update.download_link; }
set download_link(link: string) { this._update.download_link = link; }
get can_update(): boolean { return this._update.can_update; }
set can_update(can: boolean) {
this._update.can_update = can;
const download = document.getElementById("update-download") as HTMLSpanElement;
const update = document.getElementById("update-update") as HTMLSpanElement;
if (can) {
download.classList.add("unfocused");
update.classList.remove("unfocused");
} else {
download.onclick = () => window.open(this._update.download_link || this._update.link);
download.classList.remove("unfocused");
update.classList.add("unfocused");
}
}
get update(): Update { return this._update; }
set update(update: Update) {
this._update = update;
this.version = update.version;
this.commit = update.commit;
this.date = update.date;
this.description = update.description;
this.changelog = update.changelog;
this.link = update.link;
this.download_link = update.download_link;
this.can_update = update.can_update;
}
constructor() {
const update = document.getElementById("update-update") as HTMLSpanElement;
update.onclick = () => {
toggleLoader(update);
_post("/config/update", null, (req: XMLHttpRequest) => {
if (req.readyState == 4) {
toggleLoader(update);
if (req.status != 200) {
window.notifications.customError("applyUpdateError", window.lang.notif("errorApplyUpdate"));
} else {
window.notifications.customSuccess("applyUpdate", window.lang.notif("updateApplied"));
}
window.modals.updateInfo.close();
}
});
};
this.checkForUpdates(() => {
this.updateAvailable = true;
window.notifications.customPositive("updateAvailable", "", window.lang.notif("updateAvailable"));
});
}
}

View File

@ -30,24 +30,6 @@ declare interface Window {
language: string; language: string;
lang: Lang; lang: Lang;
langFile: {}; langFile: {};
updater: updater;
}
declare interface Update {
version: string;
commit: string;
date: number;
description: string;
changelog: string;
link: string;
download_link?: string;
can_update: boolean;
}
declare interface updater extends Update {
checkForUpdates: (run?: (req: XMLHttpRequest) => void) => void;
updateAvailable: boolean;
update: Update;
} }
declare interface Lang { declare interface Lang {
@ -96,7 +78,6 @@ declare interface Modals {
editor: Modal; editor: Modal;
customizeEmails: Modal; customizeEmails: Modal;
extendExpiry: Modal; extendExpiry: Modal;
updateInfo: Modal;
} }
interface Invite { interface Invite {

View File

@ -1,486 +0,0 @@
package main
import (
"archive/tar"
"compress/gzip"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
"time"
"github.com/hrfee/jfa-go/common"
)
const (
baseURL = "https://builds.hrfee.pw"
namespace = "hrfee"
repo = "jfa-go"
)
type GHRelease struct {
HTMLURL string `json:"html_url"`
ID int `json:"id"`
TagName string `json:"tag_name"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
PublishedAt time.Time `json:"published_at"`
Assets []GHAsset `json:"assets"`
Body string `json:"body"`
}
type GHAsset struct {
Name string `json:"name"`
State string `json:"state"`
UpdatedAt time.Time `json:"updated_at"`
BrowserDownloadURL string `json:"browser_download_url"`
}
type UnixTime struct {
time.Time
}
func (t *UnixTime) UnmarshalJSON(b []byte) (err error) {
unix, err := strconv.ParseInt(strings.TrimPrefix(strings.TrimSuffix(string(b), "\""), "\""), 10, 64)
if err != nil {
return
}
t.Time = time.Unix(unix, 0)
return
}
func (t UnixTime) MarshalJSON() ([]byte, error) {
if t.Time == (time.Time{}) {
return []byte("\"\""), nil
}
return []byte("\"" + strconv.FormatInt(t.Time.Unix(), 10) + "\""), nil
}
var updater string
type BuildType int
const (
off BuildType = iota
internal // Internal assets through go:embed, no data/.
external // External assets in data/, accesses through app.localFS.
docker // Only notify of new updates, no self-updating.
)
type ApplyUpdate func() error
type Update struct {
Version string `json:"version"` // vX.X.X or git
Commit string `json:"commit"`
ReleaseDate int64 `json:"date"` // unix time
Description string `json:"description"` // Commit Name/Release title.
Changelog string `json:"changelog"` // Changelog, if applicable
Link string `json:"link"` // Link to commit/release page,
DownloadLink string `json:"download_link"` // Optional link to download page.
CanUpdate bool `json:"can_update"` // Whether or not update can be done automatically.
update ApplyUpdate `json:"-"` // Function to apply update if possible.
}
type Tag struct {
Ready bool `json:"ready"` // Whether or not build on this tag has completed.
Version string `json:"version,omitempty"` // Version/Commit
ReleaseDate UnixTime `json:"date"`
}
var goos = map[string]string{
"darwin": "macOS",
"linux": "Linux",
"windows": "Windows",
}
var goarch = map[string]string{
"amd64": "x86_64",
"arm64": "arm64",
"arm": "armv6",
}
// func newDockerBuild() Update {
// var tag string
// if version == "git" {
// tag = "docker-unstable"
// } else {
// tag = "docker-latest"
// }
// }
type Updater struct {
version, commit, tag, url, namespace, name string
stable bool
buildType BuildType
httpClient *http.Client
timeoutHandler common.TimeoutHandler
binary string
}
func newUpdater(buildroneURL, namespace, repo, version, commit, buildType string) *Updater {
bType := off
tag := ""
switch buildType {
case "binary":
if binaryType == "internal" {
bType = internal
tag = "internal"
} else {
bType = external
tag = "external"
}
case "docker":
bType = docker
if version == "git" {
tag = "docker-unstable"
} else {
tag = "docker-latest"
}
default:
bType = off
}
if commit == "unknown" {
bType = off
}
if version == "git" && bType != docker {
tag += "-git"
}
binary := "jfa-go"
if runtime.GOOS == "windows" {
binary += ".exe"
}
return &Updater{
httpClient: &http.Client{Timeout: 10 * time.Second},
timeoutHandler: common.NewTimeoutHandler("updater", buildroneURL, true),
version: version,
commit: commit,
buildType: bType,
tag: tag,
url: buildroneURL,
namespace: namespace,
name: repo,
binary: binary,
}
}
type BuildDTO struct {
ID int64 // `json:"id"`
Name string // `json:"name"`
Date time.Time // `json:"date"`
Link string // `json:"link"`
Message string
Branch string // `json:"branch"`
Tags map[string]Tag
}
func (ud *Updater) GetTag() (Tag, int, error) {
if ud.buildType == off {
return Tag{}, -1, nil
}
url := fmt.Sprintf("%s/repo/%s/%s/tag/latest/%s", ud.url, ud.namespace, ud.name, ud.tag)
req, _ := http.NewRequest("GET", url, nil)
resp, err := ud.httpClient.Do(req)
defer ud.timeoutHandler()
if err != nil || resp.StatusCode != 200 {
return Tag{}, resp.StatusCode, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return Tag{}, -1, err
}
var tag Tag
err = json.Unmarshal(body, &tag)
return tag, resp.StatusCode, err
}
func (t *Tag) IsNew() bool {
return t.Version != commit
}
func (ud *Updater) getRelease() (release GHRelease, status int, err error) {
url := fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/latest", ud.namespace, ud.name)
req, _ := http.NewRequest("GET", url, nil)
resp, err := ud.httpClient.Do(req)
status = resp.StatusCode
defer ud.timeoutHandler()
if err != nil || resp.StatusCode != 200 {
return
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return
}
err = json.Unmarshal(body, &release)
return
}
func (ud *Updater) GetUpdate(tag Tag) (update Update, status int, err error) {
switch ud.buildType {
case internal:
if ud.tag == "internal-git" {
update, status, err = ud.getUpdateInternalGit(tag)
} else if ud.tag == "internal" {
update, status, err = ud.getUpdateInternal(tag)
}
case external, docker:
if strings.Contains(ud.tag, "git") || ud.tag == "docker-unstable" {
update, status, err = ud.getCommitGit(tag)
} else {
var release GHRelease
release, status, err = ud.getRelease()
if err != nil {
return
}
update = Update{
Changelog: release.Body,
Description: release.Name,
Version: release.TagName,
Commit: tag.Version,
Link: release.HTMLURL,
ReleaseDate: release.PublishedAt.Unix(),
}
}
if ud.buildType == docker {
update.DownloadLink = fmt.Sprintf("https://hub.docker.com/r/%s/%s/tags", ud.namespace, ud.name)
}
}
return
}
func (ud *Updater) getUpdateInternal(tag Tag) (update Update, status int, err error) {
release, status, err := ud.getRelease()
update = Update{
Changelog: release.Body,
Description: release.Name,
Version: release.TagName,
Commit: tag.Version,
Link: release.HTMLURL,
ReleaseDate: release.PublishedAt.Unix(),
}
if err != nil || status != 200 {
return
}
updateFunc, status, err := ud.downloadInternal(&release.Assets, tag)
if err == nil && status == 200 {
update.CanUpdate = true
update.update = updateFunc
}
return
}
func (ud *Updater) getCommitGit(tag Tag) (update Update, status int, err error) {
url := fmt.Sprintf("%s/repo/%s/%s/build/%s", ud.url, ud.namespace, ud.name, tag.Version)
req, _ := http.NewRequest("GET", url, nil)
resp, err := ud.httpClient.Do(req)
status = resp.StatusCode
defer ud.timeoutHandler()
if err != nil || resp.StatusCode != 200 {
return
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return
}
var build BuildDTO
err = json.Unmarshal(body, &build)
if err != nil {
return
}
update = Update{
Description: build.Name,
Version: "git",
Commit: tag.Version,
Link: build.Link,
ReleaseDate: tag.ReleaseDate.Unix(),
}
return
}
func (ud *Updater) getUpdateInternalGit(tag Tag) (update Update, status int, err error) {
update, status, err = ud.getCommitGit(tag)
if err != nil || status != 200 {
return
}
updateFunc, status, err := ud.downloadInternalGit()
if err == nil && status == 200 {
update.CanUpdate = true
update.update = updateFunc
}
return
}
func getBuildName() string {
operatingSystem, ok := goos[runtime.GOOS]
if !ok {
for _, v := range goos {
if strings.Contains(v, runtime.GOOS) {
operatingSystem = v
break
}
}
}
if operatingSystem == "" {
return ""
}
arch, ok := goarch[runtime.GOARCH]
if !ok {
for _, v := range goarch {
if strings.Contains(v, runtime.GOARCH) {
arch = v
break
}
}
}
if arch == "" {
return ""
}
return operatingSystem + "_" + arch
}
func (ud *Updater) downloadInternal(assets *[]GHAsset, tag Tag) (applyUpdate ApplyUpdate, status int, err error) {
return ud.pullInternal(ud.getInternalURL(assets, tag))
}
func (ud *Updater) downloadInternalGit() (applyUpdate ApplyUpdate, status int, err error) {
return ud.pullInternal(ud.getInternalGitURL())
}
func (ud *Updater) getInternalURL(assets *[]GHAsset, tag Tag) string {
buildName := getBuildName()
if buildName == "" {
return ""
}
url := ""
for _, asset := range *assets {
if strings.Contains(asset.Name, buildName) {
url = asset.BrowserDownloadURL
break
}
}
return url
}
func (ud *Updater) getInternalGitURL() string {
buildName := getBuildName()
if buildName == "" {
return ""
}
return fmt.Sprintf("%s/repo/%s/%s/latest/file/%s", ud.url, ud.namespace, ud.name, buildName)
}
func (ud *Updater) pullInternal(url string) (applyUpdate ApplyUpdate, status int, err error) {
if url == "" {
return
}
req, _ := http.NewRequest("GET", url, nil)
resp, err := ud.httpClient.Do(req)
status = resp.StatusCode
if err != nil || resp.StatusCode != 200 {
return
}
gz, err := gzip.NewReader(resp.Body)
if err != nil {
status = -1
return
}
tarReader := tar.NewReader(gz)
var header *tar.Header
for {
header, err = tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
status = -1
return
}
switch header.Typeflag {
case tar.TypeReg:
// Search only for file named ud.binary
if header.Name == ud.binary {
applyUpdate = func() error {
defer gz.Close()
defer resp.Body.Close()
file, err := os.Executable()
if err != nil {
return err
}
path, err := filepath.EvalSymlinks(file)
if err != nil {
return err
}
info, err := os.Stat(path)
if err != nil {
return err
}
mode := info.Mode()
f, err := os.OpenFile(path+"_", os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(f, tarReader)
if err != nil {
return err
}
return os.Rename(path+"_", path)
}
return
}
}
}
err = errors.New("Couldn't find file: " + ud.binary)
return
}
// func newInternalBuild() Update {
// tag := "internal"
// func update(path string) err {
// if
// fp, err := os.Executable()
// if err != nil {
// return err
// }
// fullPath, err := filepath.EvalSymlinks(fp)
// if err != nil {
// return err
// }
// newBinary,
// }
func (app *appContext) checkForUpdates() {
for {
go func() {
tag, status, err := app.updater.GetTag()
if status != 200 || err != nil {
if strings.Contains(err.Error(), "strconv.ParseInt") {
app.err.Println("No new updates available.")
} else {
app.err.Printf("Failed to get latest tag (%d): %v", status, err)
}
return
}
if tag != app.tag && tag.IsNew() {
app.info.Println("Update found")
update, status, err := app.updater.GetUpdate(tag)
if status != 200 || err != nil {
app.err.Printf("Failed to get update (%d): %v", status, err)
return
}
app.tag = tag
app.update = update
app.newUpdate = true
}
}()
time.Sleep(30 * time.Minute)
}
}

View File

@ -72,7 +72,6 @@ func (app *appContext) AdminPage(gc *gin.Context) {
var license string var license string
l, err := fs.ReadFile(localFS, "LICENSE") l, err := fs.ReadFile(localFS, "LICENSE")
if err != nil { if err != nil {
app.debug.Printf("Failed to load LICENSE: %s", err)
license = "" license = ""
} }
license = string(l) license = string(l)