mirror of
https://github.com/hrfee/jfa-go.git
synced 2025-01-06 08:20:11 +00:00
Compare commits
No commits in common. "7bd8fadf7654dc6c1e1717cf3021d5f0ede1e041" and "9787fce275256cd3bf71a295911fd1ce826c30a4" have entirely different histories.
7bd8fadf76
...
9787fce275
36
.drone.yml
36
.drone.yml
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
12
Makefile
12
Makefile
@ -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
33
api.go
@ -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
|
||||||
|
22
config.go
22
config.go
@ -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()
|
||||||
|
|
||||||
|
@ -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": {
|
||||||
|
28
css/base.css
28
css/base.css
@ -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);
|
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
5
go.mod
@ -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
10
go.sum
@ -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=
|
||||||
|
@ -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">×</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">
|
||||||
|
@ -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
22
main.go
@ -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
|
||||||
|
@ -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
6
package-lock.json
generated
@ -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",
|
||||||
|
@ -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",
|
||||||
|
@ -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
27
scripts/version.py
Normal 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)
|
||||||
|
|
@ -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')" $@
|
|
@ -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;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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]);
|
||||||
}
|
}
|
||||||
|
@ -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"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -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 {
|
||||||
|
486
updater.go
486
updater.go
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
1
views.go
1
views.go
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user