mirror of
https://github.com/hrfee/jfa-go.git
synced 2025-01-01 05:50:12 +00:00
Compare commits
2 Commits
90a2c1f2e7
...
a2c344de83
Author | SHA1 | Date | |
---|---|---|---|
a2c344de83 | |||
886ae64feb |
3
Makefile
3
Makefile
@ -94,6 +94,8 @@ copy:
|
||||
$(info copying static data)
|
||||
-mkdir -p $(DATA)/web
|
||||
cp -r static/* $(DATA)/web/
|
||||
$(info copying systemd service)
|
||||
cp jfa-go.service $(DATA)/
|
||||
$(info copying language files)
|
||||
cp -r lang $(DATA)/
|
||||
cp LICENSE $(DATA)/
|
||||
@ -114,7 +116,6 @@ clean:
|
||||
-rm -r $(DATA)
|
||||
-rm -r build
|
||||
-rm mail/*.html
|
||||
-rm embed.go
|
||||
-rm docs/docs.go docs/swagger.json docs/swagger.yaml
|
||||
go clean
|
||||
|
||||
|
13
README.md
13
README.md
@ -8,8 +8,6 @@
|
||||
---
|
||||
jfa-go is a user management app for [Jellyfin](https://github.com/jellyfin/jellyfin) (and now [Emby](https://emby.media/)) that provides invite-based account creation as well as other features that make one's instance much easier to manage.
|
||||
|
||||
I chose to rewrite the python [jellyfin-accounts](https://github.com/hrfee/jellyfin-accounts) in Go mainly as a learning experience, but also to slightly improve speeds and efficiency.
|
||||
|
||||
#### Features
|
||||
* 🧑 Invite based account creation: Sends invites to your friends or family, and let them choose their own username and password without relying on you.
|
||||
* Send invites via a link and/or email
|
||||
@ -26,8 +24,8 @@ I chose to rewrite the python [jellyfin-accounts](https://github.com/hrfee/jelly
|
||||
* 📣 Announcements: Bulk email your users with announcements about your server.
|
||||
* Authentication via Jellyfin: Instead of using separate credentials for jfa-go and Jellyfin, jfa-go can use it as the authentication provider.
|
||||
* Enables the usage of jfa-go by multiple people
|
||||
* 🌓 Customizable look
|
||||
* Edit emails with variables and markdown
|
||||
* 🌓 Customizations
|
||||
* Customize emails with variables and markdown
|
||||
* Specify contact and help messages to appear in emails and pages
|
||||
* Light and dark themes available
|
||||
|
||||
@ -71,8 +69,6 @@ Otherwise, full build instructions can be found [here](https://github.com/hrfee/
|
||||
#### Usage
|
||||
Simply run `jfa-go` to start the application. A setup wizard will start on `localhost:8056` (or your own specified address). Upon completion, refresh the page.
|
||||
|
||||
Note: jfa-go does not run as a daemon by default. You'll need to figure this out yourself.
|
||||
|
||||
```
|
||||
Usage of ./jfa-go:
|
||||
-config string
|
||||
@ -89,6 +85,11 @@ Usage of ./jfa-go:
|
||||
Enable swagger at /swagger/index.html
|
||||
```
|
||||
|
||||
#### Systemd
|
||||
jfa-go does not run as a daemon by default. Run `jfa-go systemd` to create a systemd `.service` file in your current directory, which you can copy into `~/.config/systemd/user` or somewhere else.
|
||||
|
||||
---
|
||||
|
||||
If you're switching from jellyfin-accounts, copy your existing `~/.jf-accounts` to:
|
||||
|
||||
* `XDG_CONFIG_DIR/jfa-go` (usually ~/.config/jfa-go) on \*nix systems,
|
||||
|
1
go.mod
1
go.mod
@ -33,6 +33,7 @@ require (
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14
|
||||
github.com/swaggo/gin-swagger v1.3.0
|
||||
github.com/swaggo/swag v1.7.0 // indirect
|
||||
|
2
go.sum
2
go.sum
@ -197,6 +197,8 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykE
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
|
88
help.go
Normal file
88
help.go
Normal file
@ -0,0 +1,88 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/* Adds start/stop/systemd to help message, and
|
||||
also gets rid of usage for shorthand flags, and merge them with the full-length one.
|
||||
implementation is 🤢, will clean this up eventually.
|
||||
-h SHORTHAND
|
||||
-help
|
||||
prints this message.
|
||||
becomes:
|
||||
-help, -h
|
||||
prints this message.
|
||||
*/
|
||||
func helpFunc() {
|
||||
fmt.Fprint(os.Stderr, `Usage of jfa-go:
|
||||
start
|
||||
start jfa-go as a daemon and run in the background.
|
||||
stop
|
||||
stop a daemonized instance of jfa-go.
|
||||
systemd
|
||||
generate a systemd .service file.
|
||||
`)
|
||||
shortHands := []string{"-help", "-data", "-config", "-port"}
|
||||
var b bytes.Buffer
|
||||
// Write defaults into buffer then remove any shorthands
|
||||
flag.CommandLine.SetOutput(&b)
|
||||
flag.PrintDefaults()
|
||||
flag.CommandLine.SetOutput(os.Stderr)
|
||||
scanner := bufio.NewScanner(&b)
|
||||
out := ""
|
||||
line := scanner.Text()
|
||||
eof := !scanner.Scan()
|
||||
lastLine := false
|
||||
for !eof || lastLine {
|
||||
nextline := scanner.Text()
|
||||
start := 0
|
||||
if len(nextline) != 0 {
|
||||
for nextline[start] == ' ' && start < len(nextline) {
|
||||
start++
|
||||
}
|
||||
}
|
||||
if strings.Contains(line, "SHORTHAND") || (len(nextline) != 0 && strings.Contains(nextline, "SHORTHAND") && nextline[start] != '-') {
|
||||
line = nextline
|
||||
if lastLine {
|
||||
break
|
||||
}
|
||||
eof := !scanner.Scan()
|
||||
if eof {
|
||||
lastLine = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
// if !strings.Contains(line, "SHORTHAND") && !(strings.Contains(nextline, "SHORTHAND") && !strings.Contains(nextline, "-")) {
|
||||
match := false
|
||||
for i, c := range line {
|
||||
if c != '-' {
|
||||
continue
|
||||
}
|
||||
for _, s := range shortHands {
|
||||
if i+len(s) <= len(line) && line[i:i+len(s)] == s {
|
||||
out += line[:i+len(s)] + ", " + s[:2] + line[i+len(s):] + "\n"
|
||||
match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
out += line + "\n"
|
||||
}
|
||||
line = nextline
|
||||
if lastLine {
|
||||
break
|
||||
}
|
||||
eof := !scanner.Scan()
|
||||
if eof {
|
||||
lastLine = true
|
||||
}
|
||||
}
|
||||
fmt.Fprint(os.Stderr, out)
|
||||
}
|
45
main.go
45
main.go
@ -169,15 +169,26 @@ func start(asDaemon, firstCall bool) {
|
||||
app.err = NewLogger(os.Stdout, "[ERROR] ", log.Ltime, color.FgRed)
|
||||
|
||||
if firstCall {
|
||||
flag.Usage = helpFunc
|
||||
help := flag.Bool("help", false, "prints this message.")
|
||||
flag.BoolVar(help, "h", false, "SHORTHAND")
|
||||
|
||||
DATA = flag.String("data", app.dataPath, "alternate path to data directory.")
|
||||
flag.StringVar(DATA, "d", app.dataPath, "SHORTHAND")
|
||||
CONFIG = flag.String("config", app.configPath, "alternate path to config file.")
|
||||
flag.StringVar(CONFIG, "c", app.configPath, "SHORTHAND")
|
||||
HOST = flag.String("host", "", "alternate address to host web ui on.")
|
||||
PORT = flag.Int("port", 0, "alternate port to host web ui on.")
|
||||
flag.IntVar(PORT, "p", 0, "SHORTHAND")
|
||||
DEBUG = flag.Bool("debug", false, "Enables debug logging.")
|
||||
PPROF = flag.Bool("pprof", false, "Exposes pprof profiler on /debug/pprof.")
|
||||
SWAGGER = flag.Bool("swagger", false, "Enable swagger at /swagger/index.html")
|
||||
|
||||
flag.Parse()
|
||||
if *help {
|
||||
flag.Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
if *SWAGGER {
|
||||
os.Setenv("SWAGGER", "1")
|
||||
}
|
||||
@ -739,6 +750,40 @@ func main() {
|
||||
fmt.Println("Sent.")
|
||||
} else if flagPassed("daemon") {
|
||||
start(true, true)
|
||||
} else if flagPassed("systemd") {
|
||||
service, err := fs.ReadFile(localFS, "jfa-go.service")
|
||||
if err != nil {
|
||||
fmt.Printf("Couldn't read jfa-go.service: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
absPath, err := filepath.Abs(os.Args[0])
|
||||
if err != nil {
|
||||
absPath = os.Args[0]
|
||||
}
|
||||
command := absPath
|
||||
for i, v := range os.Args {
|
||||
if i != 0 && v != "systemd" {
|
||||
command += " " + v
|
||||
}
|
||||
}
|
||||
service = []byte(strings.Replace(string(service), "{executable}", command, 1))
|
||||
err = os.WriteFile("jfa-go.service", service, 0666)
|
||||
if err != nil {
|
||||
fmt.Printf("Couldn't write jfa-go.service: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Print(info(`If you want to execute jfa-go with special arguments, re-run this command with them.
|
||||
Move the newly created "jfa-go.service" file to ~/.config/systemd/user (Creating it if necessary).
|
||||
Then run "systemctl --user daemon-reload".
|
||||
You can then run:
|
||||
|
||||
`))
|
||||
color.New(color.FgGreen).PrintFunc()("To start: ")
|
||||
fmt.Print(info("systemctl --user start jfa-go\n\n"))
|
||||
color.New(color.FgRed).PrintFunc()("To stop: ")
|
||||
fmt.Print(info("systemctl --user stop jfa-go\n\n"))
|
||||
color.New(color.FgYellow).PrintFunc()("To restart: ")
|
||||
fmt.Print(info("systemctl --user stop jfa-go\n"))
|
||||
} else {
|
||||
RESTART = make(chan bool, 1)
|
||||
start(false, true)
|
||||
|
Loading…
Reference in New Issue
Block a user