mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 17:10:10 +00:00
fix 10.7.0 compatibility, simplify scss
Hyphens are added to user IDs from 10.7.0, so if the server is running it, emails.json will be modified to include them. The existing file is backed up. Also, scss files have been simplified since bs4-jf and bs5-jf share much of the same content.
This commit is contained in:
parent
9dbf60e3df
commit
3c952d21f7
@ -57,7 +57,7 @@ func NewJellyfin(server, client, version, device, deviceID string, timeoutHandle
|
||||
jf.deviceID = deviceID
|
||||
jf.useragent = fmt.Sprintf("%s/%s", client, version)
|
||||
jf.timeoutHandler = timeoutHandler
|
||||
jf.auth = fmt.Sprintf("MediaBrowser Client=%s, Device=%s, DeviceId=%s, Version=%s", client, device, deviceID, version)
|
||||
jf.auth = fmt.Sprintf("MediaBrowser Client=\"%s\", Device=\"%s\", DeviceId=\"%s\", Version=\"%s\"", client, device, deviceID, version)
|
||||
jf.header = map[string]string{
|
||||
"Accept": "application/json",
|
||||
"Content-type": "application/json; charset=UTF-8",
|
||||
|
42
main.go
42
main.go
@ -17,6 +17,7 @@ import (
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -460,6 +461,47 @@ func start(asDaemon, firstCall bool) {
|
||||
app.err.Fatalf("Failed to authenticate with Jellyfin @ %s: Code %d", server, status)
|
||||
}
|
||||
app.info.Printf("Authenticated with %s", server)
|
||||
// from 10.7.0, jellyfin hyphenates user IDs. This checks if the version is equal or higher.
|
||||
checkVersion := func(version string) int {
|
||||
numberStrings := strings.Split(version, ".")
|
||||
n := 0
|
||||
for _, s := range numberStrings {
|
||||
num, err := strconv.Atoi(s)
|
||||
if err == nil {
|
||||
n += num
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
if checkVersion(app.jf.ServerInfo.Version) >= checkVersion("10.7.0") {
|
||||
noHyphens := true
|
||||
for id := range app.storage.emails {
|
||||
if strings.Contains(id, "-") {
|
||||
noHyphens = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if noHyphens {
|
||||
app.info.Println(aurora.Yellow("From Jellyfin 10.7.0 onwards, user IDs are hyphenated.\nYour emails.json file will be modified to match this new format.\nA backup will be placed next to the file.\n"))
|
||||
time.Sleep(time.Second * time.Duration(3))
|
||||
newEmails, status, err := app.upgradeEmailStorage(app.storage.emails)
|
||||
if status != 200 || err != nil {
|
||||
app.err.Printf("Failed to get users from Jellyfin: Code %d", status)
|
||||
app.debug.Printf("Error: %s", err)
|
||||
app.err.Fatalf("Couldn't upgrade emails.json")
|
||||
}
|
||||
bakFile := app.storage.emails_path + ".bak"
|
||||
err = storeJSON(bakFile, app.storage.emails)
|
||||
if err != nil {
|
||||
app.err.Fatalf("couldn't store emails.json backup: %s", err)
|
||||
}
|
||||
app.storage.emails = newEmails
|
||||
err = app.storage.storeEmails()
|
||||
if err != nil {
|
||||
app.err.Fatalf("couldn't store emails.json: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
app.authJf, _ = jfapi.NewJellyfin(server, "jfa-go", app.version, "auth", "auth", common.NewTimeoutHandler("Jellyfin", server, true), cacheTimeout)
|
||||
|
||||
app.loadStrftime()
|
||||
|
@ -1,145 +1,4 @@
|
||||
$jf-blue: rgb(0, 164, 220);
|
||||
$jf-blue-hover: rgba(0, 164, 220, 0.2);
|
||||
$jf-blue-focus: rgb(12, 176, 232);
|
||||
$jf-blue-light: #4bb3dd;
|
||||
|
||||
$jf-red: rgb(204, 0, 0);
|
||||
$jf-red-light: #e12026;
|
||||
$jf-yellower: #ffc107;
|
||||
$jf-yellow: #e1b222;
|
||||
$jf-orange: #ff870f;
|
||||
$jf-green: #6fbd45;
|
||||
$jf-green-dark: #008040;
|
||||
|
||||
|
||||
$jf-black: #101010; // 16 16 16
|
||||
$jf-gray-90: #202020; // 32 32 32
|
||||
$jf-gray-80: #242424; // jf-card 36 36 36
|
||||
$jf-gray-70: #292929; // jf-input 41 41 41
|
||||
$jf-gray-60: #303030; // jf-button 48 48 48
|
||||
$jf-gray-50: #383838; // jf-button-focus 56 56 56
|
||||
$jf-text-bold: rgba(255, 255, 255, 0.87);
|
||||
$jf-text-primary: rgba(255, 255, 255, 0.8);
|
||||
$jf-text-secondary: rgb(153, 153, 153);
|
||||
|
||||
$primary: $jf-blue;
|
||||
$secondary: $jf-gray-50;
|
||||
$success: $jf-green-dark;
|
||||
$danger: $jf-red-light;
|
||||
$light: $jf-text-primary;
|
||||
$dark: $jf-gray-90;
|
||||
$info: $jf-yellow;
|
||||
$warning: $jf-yellower;
|
||||
|
||||
|
||||
|
||||
$enable-gradients: false;
|
||||
$enable-shadows: false;
|
||||
|
||||
$enable-rounded: false;
|
||||
$body-bg: $jf-black;
|
||||
$body-color: $jf-text-primary;
|
||||
$border-color: $jf-gray-60;
|
||||
$component-active-color: $jf-text-bold;
|
||||
$component-active-bg: $jf-blue-focus;
|
||||
$text-muted: $jf-text-secondary;
|
||||
$link-color: $jf-blue-focus;
|
||||
$btn-link-disabled-color: $jf-text-secondary;
|
||||
$input-bg: $jf-gray-90;
|
||||
$input-color: $jf-text-primary;
|
||||
$input-focus-bg: $jf-gray-60;
|
||||
$input-focus-border-color: $jf-blue-focus;
|
||||
$input-disabled-bg: $jf-gray-70;
|
||||
input:disabled {
|
||||
color: $text-muted;
|
||||
}
|
||||
$input-border-color: $jf-gray-60;
|
||||
$input-placeholder-color: $text-muted;
|
||||
|
||||
$form-check-input-bg: $jf-gray-60;
|
||||
$form-check-input-border: $jf-gray-50;
|
||||
$form-check-input-checked-color: $jf-blue-focus;
|
||||
$form-check-input-checked-bg-color: $jf-blue-hover;
|
||||
|
||||
$input-group-addon-bg: $input-bg;
|
||||
|
||||
$form-select-disabled-color: $jf-text-secondary;
|
||||
$form-select-disabled-bg: $input-disabled-bg;
|
||||
$form-select-indicator-color: $jf-gray-50;
|
||||
|
||||
$card-bg: $jf-gray-80;
|
||||
$card-border-color: null;
|
||||
|
||||
$tooltip-color: $jf-text-bold;
|
||||
$tooltip-bg: $jf-gray-50;
|
||||
|
||||
$modal-content-bg: $jf-gray-80;
|
||||
$modal-content-border-color: $jf-gray-50;
|
||||
$modal-header-border-color: null;
|
||||
$modal-footer-border-color: null;
|
||||
|
||||
$list-group-bg: $card-bg;
|
||||
$list-group-border-color: $jf-gray-50;
|
||||
$list-group-hover-bg: $jf-blue-hover;
|
||||
$list-group-active-bg: $jf-blue-focus;
|
||||
$list-group-action-color: $jf-text-primary;
|
||||
$list-group-action-hover-color: $jf-text-bold;
|
||||
$list-group-action-active-color: $jf-text-bold;
|
||||
$list-group-action-active-bg: $jf-blue-focus;
|
||||
|
||||
// idk why but i had to put these above and below the import
|
||||
.list-group-item-danger {
|
||||
color: $jf-text-bold;
|
||||
background-color: $danger;
|
||||
}
|
||||
|
||||
.list-group-item-success {
|
||||
color: $jf-text-bold;
|
||||
background-color: $success;
|
||||
}
|
||||
|
||||
@import "../jf-pre.scss";
|
||||
@import "../../node_modules/bootstrap4/scss/bootstrap";
|
||||
|
||||
.btn-primary, .btn-outline-primary:hover, .btn-outline-primary:active {
|
||||
color: $jf-text-bold;
|
||||
}
|
||||
|
||||
.close {
|
||||
color: $jf-text-secondary;
|
||||
}
|
||||
|
||||
.close:hover, .close:active {
|
||||
color: $jf-text-primary;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.icon-button:hover {
|
||||
color: $jf-text-bold;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.text-bright {
|
||||
color: $jf-text-bold;
|
||||
}
|
||||
|
||||
.list-group-item-danger {
|
||||
color: $jf-text-bold;
|
||||
background-color: $danger;
|
||||
}
|
||||
|
||||
.list-group-item-success {
|
||||
color: $jf-text-bold;
|
||||
background-color: $success;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
background-color: $jf-blue-hover;
|
||||
}
|
||||
|
||||
@import "../jf-post.scss";
|
||||
@import "../base.scss";
|
||||
|
@ -1,149 +1,7 @@
|
||||
$jf-blue: rgb(0, 164, 220);
|
||||
$jf-blue-hover: rgba(0, 164, 220, 0.2);
|
||||
$jf-blue-focus: rgb(12, 176, 232);
|
||||
$jf-blue-light: #4bb3dd;
|
||||
|
||||
$jf-red: rgb(204, 0, 0);
|
||||
$jf-red-light: #e12026;
|
||||
$jf-yellower: #ffc107;
|
||||
$jf-yellow: #e1b222;
|
||||
$jf-orange: #ff870f;
|
||||
$jf-green: #6fbd45;
|
||||
$jf-green-dark: #008040;
|
||||
|
||||
|
||||
$jf-black: #101010; // 16 16 16
|
||||
$jf-gray-90: #202020; // 32 32 32
|
||||
$jf-gray-80: #242424; // jf-card 36 36 36
|
||||
$jf-gray-70: #292929; // jf-input 41 41 41
|
||||
$jf-gray-60: #303030; // jf-button 48 48 48
|
||||
$jf-gray-50: #383838; // jf-button-focus 56 56 56
|
||||
$jf-text-bold: rgba(255, 255, 255, 0.87);
|
||||
$jf-text-primary: rgba(255, 255, 255, 0.8);
|
||||
$jf-text-secondary: rgb(153, 153, 153);
|
||||
|
||||
$primary: $jf-blue;
|
||||
$secondary: $jf-gray-50;
|
||||
$success: $jf-green-dark;
|
||||
$danger: $jf-red-light;
|
||||
$light: $jf-text-primary;
|
||||
$dark: $jf-gray-90;
|
||||
$info: $jf-yellow;
|
||||
$warning: $jf-yellower;
|
||||
|
||||
|
||||
|
||||
$enable-gradients: false;
|
||||
$enable-shadows: false;
|
||||
|
||||
$enable-rounded: false;
|
||||
$body-bg: $jf-black;
|
||||
$body-color: $jf-text-primary;
|
||||
$border-color: $jf-gray-60;
|
||||
$component-active-color: $jf-text-bold;
|
||||
$component-active-bg: $jf-blue-focus;
|
||||
$text-muted: $jf-text-secondary;
|
||||
$link-color: $jf-blue-focus;
|
||||
$btn-link-disabled-color: $jf-text-secondary;
|
||||
$input-bg: $jf-gray-90;
|
||||
$input-color: $jf-text-primary;
|
||||
$input-focus-bg: $jf-gray-60;
|
||||
$input-focus-border-color: $jf-blue-focus;
|
||||
$input-disabled-bg: $jf-gray-70;
|
||||
input:disabled {
|
||||
color: $text-muted;
|
||||
}
|
||||
$input-border-color: $jf-gray-60;
|
||||
$input-placeholder-color: $text-muted;
|
||||
|
||||
$form-check-input-bg: $jf-gray-60;
|
||||
$form-check-input-border: $jf-gray-50;
|
||||
$form-check-input-checked-color: $jf-blue-focus;
|
||||
$form-check-input-checked-bg-color: $jf-blue-hover;
|
||||
|
||||
$input-group-addon-bg: $input-bg;
|
||||
|
||||
$form-select-disabled-color: $jf-text-secondary;
|
||||
$form-select-disabled-bg: $input-disabled-bg;
|
||||
$form-select-indicator-color: $jf-gray-50;
|
||||
|
||||
$card-bg: $jf-gray-80;
|
||||
$card-border-color: null;
|
||||
|
||||
$tooltip-color: $jf-text-bold;
|
||||
$tooltip-bg: $jf-gray-50;
|
||||
|
||||
$modal-content-bg: $jf-gray-80;
|
||||
$modal-content-border-color: $jf-gray-50;
|
||||
$modal-header-border-color: null;
|
||||
$modal-footer-border-color: null;
|
||||
|
||||
$list-group-bg: $card-bg;
|
||||
$list-group-border-color: $jf-gray-50;
|
||||
$list-group-hover-bg: $jf-blue-hover;
|
||||
$list-group-active-bg: $jf-blue-focus;
|
||||
$list-group-action-color: $jf-text-primary;
|
||||
$list-group-action-hover-color: $jf-text-bold;
|
||||
$list-group-action-active-color: $jf-text-bold;
|
||||
$list-group-action-active-bg: $jf-blue-focus;
|
||||
|
||||
// idk why but i had to put these above and below the import
|
||||
.list-group-item-danger {
|
||||
color: $jf-text-bold;
|
||||
background-color: $danger;
|
||||
}
|
||||
|
||||
.list-group-item-success {
|
||||
color: $jf-text-bold;
|
||||
background-color: $success;
|
||||
}
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/bootstrap";
|
||||
|
||||
.btn-primary, .btn-outline-primary:hover, .btn-outline-primary:active {
|
||||
color: $jf-text-bold;
|
||||
}
|
||||
|
||||
.close {
|
||||
color: $jf-text-secondary;
|
||||
}
|
||||
|
||||
.close:hover, .close:active {
|
||||
color: $jf-text-primary;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.icon-button:hover {
|
||||
color: $jf-text-bold;
|
||||
}
|
||||
|
||||
.icon-button:active {
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.text-bright {
|
||||
color: $jf-text-bold;
|
||||
}
|
||||
|
||||
.list-group-item-danger {
|
||||
color: $jf-text-bold;
|
||||
background-color: $danger;
|
||||
}
|
||||
|
||||
.list-group-item-success {
|
||||
color: $jf-text-bold;
|
||||
background-color: $success;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
background-color: $jf-blue-hover;
|
||||
}
|
||||
|
||||
.btn-close {
|
||||
filter: invert(80%);
|
||||
}
|
||||
|
||||
@import "../jf-pre.scss";
|
||||
@import "../../node_modules/bootstrap/scss/bootstrap";
|
||||
@import "../jf-post.scss";
|
||||
@import "../base.scss";
|
||||
|
41
scss/jf-post.scss
Normal file
41
scss/jf-post.scss
Normal file
@ -0,0 +1,41 @@
|
||||
.btn-primary, .btn-outline-primary:hover, .btn-outline-primary:active {
|
||||
color: $jf-text-bold;
|
||||
}
|
||||
|
||||
.close {
|
||||
color: $jf-text-secondary;
|
||||
}
|
||||
|
||||
.close:hover, .close:active {
|
||||
color: $jf-text-primary;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.icon-button:hover {
|
||||
color: $jf-text-bold;
|
||||
}
|
||||
|
||||
.icon-button:active {
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.text-bright {
|
||||
color: $jf-text-bold;
|
||||
}
|
||||
|
||||
.list-group-item-danger {
|
||||
color: $jf-text-bold;
|
||||
background-color: $danger;
|
||||
}
|
||||
|
||||
.list-group-item-success {
|
||||
color: $jf-text-bold;
|
||||
background-color: $success;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
background-color: $jf-blue-hover;
|
||||
}
|
101
scss/jf-pre.scss
Normal file
101
scss/jf-pre.scss
Normal file
@ -0,0 +1,101 @@
|
||||
$jf-blue: rgb(0, 164, 220);
|
||||
$jf-blue-hover: rgba(0, 164, 220, 0.2);
|
||||
$jf-blue-focus: rgb(12, 176, 232);
|
||||
$jf-blue-light: #4bb3dd;
|
||||
|
||||
$jf-red: rgb(204, 0, 0);
|
||||
$jf-red-light: #e12026;
|
||||
$jf-yellower: #ffc107;
|
||||
$jf-yellow: #e1b222;
|
||||
$jf-orange: #ff870f;
|
||||
$jf-green: #6fbd45;
|
||||
$jf-green-dark: #008040;
|
||||
|
||||
|
||||
$jf-black: #101010; // 16 16 16
|
||||
$jf-gray-90: #202020; // 32 32 32
|
||||
$jf-gray-80: #242424; // jf-card 36 36 36
|
||||
$jf-gray-70: #292929; // jf-input 41 41 41
|
||||
$jf-gray-60: #303030; // jf-button 48 48 48
|
||||
$jf-gray-50: #383838; // jf-button-focus 56 56 56
|
||||
$jf-text-bold: rgba(255, 255, 255, 0.87);
|
||||
$jf-text-primary: rgba(255, 255, 255, 0.8);
|
||||
$jf-text-secondary: rgb(153, 153, 153);
|
||||
|
||||
$primary: $jf-blue;
|
||||
$secondary: $jf-gray-50;
|
||||
$success: $jf-green-dark;
|
||||
$danger: $jf-red-light;
|
||||
$light: $jf-text-primary;
|
||||
$dark: $jf-gray-90;
|
||||
$info: $jf-yellow;
|
||||
$warning: $jf-yellower;
|
||||
|
||||
|
||||
|
||||
$enable-gradients: false;
|
||||
$enable-shadows: false;
|
||||
|
||||
$enable-rounded: false;
|
||||
$body-bg: $jf-black;
|
||||
$body-color: $jf-text-primary;
|
||||
$border-color: $jf-gray-60;
|
||||
$component-active-color: $jf-text-bold;
|
||||
$component-active-bg: $jf-blue-focus;
|
||||
$text-muted: $jf-text-secondary;
|
||||
$link-color: $jf-blue-focus;
|
||||
$btn-link-disabled-color: $jf-text-secondary;
|
||||
$input-bg: $jf-gray-90;
|
||||
$input-color: $jf-text-primary;
|
||||
$input-focus-bg: $jf-gray-60;
|
||||
$input-focus-border-color: $jf-blue-focus;
|
||||
$input-disabled-bg: $jf-gray-70;
|
||||
input:disabled {
|
||||
color: $text-muted;
|
||||
}
|
||||
$input-border-color: $jf-gray-60;
|
||||
$input-placeholder-color: $text-muted;
|
||||
|
||||
$form-check-input-bg: $jf-gray-60;
|
||||
$form-check-input-border: $jf-gray-50;
|
||||
$form-check-input-checked-color: $jf-blue-focus;
|
||||
$form-check-input-checked-bg-color: $jf-blue-hover;
|
||||
|
||||
$input-group-addon-bg: $input-bg;
|
||||
|
||||
$form-select-disabled-color: $jf-text-secondary;
|
||||
$form-select-disabled-bg: $input-disabled-bg;
|
||||
$form-select-indicator-color: $jf-gray-50;
|
||||
|
||||
$card-bg: $jf-gray-80;
|
||||
$card-border-color: null;
|
||||
|
||||
$tooltip-color: $jf-text-bold;
|
||||
$tooltip-bg: $jf-gray-50;
|
||||
|
||||
$modal-content-bg: $jf-gray-80;
|
||||
$modal-content-border-color: $jf-gray-50;
|
||||
$modal-header-border-color: null;
|
||||
$modal-footer-border-color: null;
|
||||
|
||||
$list-group-bg: $card-bg;
|
||||
$list-group-border-color: $jf-gray-50;
|
||||
$list-group-hover-bg: $jf-blue-hover;
|
||||
$list-group-active-bg: $jf-blue-focus;
|
||||
$list-group-action-color: $jf-text-primary;
|
||||
$list-group-action-hover-color: $jf-text-bold;
|
||||
$list-group-action-active-color: $jf-text-bold;
|
||||
$list-group-action-active-bg: $jf-blue-focus;
|
||||
|
||||
// idk why but i had to put these above and below the import
|
||||
.list-group-item-danger {
|
||||
color: $jf-text-bold;
|
||||
background-color: $danger;
|
||||
}
|
||||
|
||||
.list-group-item-success {
|
||||
color: $jf-text-bold;
|
||||
background-color: $success;
|
||||
}
|
||||
|
||||
// @import "../../node_modules/bootstrap/scss/bootstrap";
|
21
storage.go
21
storage.go
@ -5,6 +5,7 @@ import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -190,3 +191,23 @@ func storeJSON(path string, obj interface{}) error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// JF 10.7.0 added hyphens to user IDs like this and we need to upgrade email storage to match it:
|
||||
// [8 chars]-[4]-[4]-[4]-[12]
|
||||
// This seems consistent, but we'll grab IDs from jellyfin just in case theres some variation.
|
||||
func (app *appContext) upgradeEmailStorage(old map[string]interface{}) (map[string]interface{}, int, error) {
|
||||
jfUsers, status, err := app.jf.GetUsers(false)
|
||||
if status != 200 || err != nil {
|
||||
return nil, status, err
|
||||
}
|
||||
newEmails := map[string]interface{}{}
|
||||
for _, user := range jfUsers {
|
||||
unstripped := user["Id"].(string)
|
||||
stripped := strings.ReplaceAll(unstripped, "-", "")
|
||||
email, ok := old[stripped]
|
||||
if ok {
|
||||
newEmails[unstripped] = email
|
||||
}
|
||||
}
|
||||
return newEmails, status, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user