mirror of
https://github.com/hrfee/jfa-go.git
synced 2025-04-20 01:52:53 +00:00
Compare commits
No commits in common. "3af4607171cd0f18cee0bd52413f5f7b9d9305a5" and "42921f6a3efd5a5ca083d6b12ce68550e3a55c7b" have entirely different histories.
3af4607171
...
42921f6a3e
@ -72,7 +72,6 @@
|
|||||||
"name": "Client Name",
|
"name": "Client Name",
|
||||||
"required": true,
|
"required": true,
|
||||||
"requires_restart": true,
|
"requires_restart": true,
|
||||||
"advanced": true,
|
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "jfa-go",
|
"value": "jfa-go",
|
||||||
"description": "The name of the client that will show up in the Jellyfin dashboard."
|
"description": "The name of the client that will show up in the Jellyfin dashboard."
|
||||||
@ -81,7 +80,6 @@
|
|||||||
"name": "User cache timeout (minutes)",
|
"name": "User cache timeout (minutes)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": true,
|
"requires_restart": true,
|
||||||
"advanced": true,
|
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"value": 30,
|
"value": 30,
|
||||||
"description": "Timeout of user cache in minutes. Set to 0 to disable."
|
"description": "Timeout of user cache in minutes. Set to 0 to disable."
|
||||||
@ -385,7 +383,6 @@
|
|||||||
"name": "Date format",
|
"name": "Date format",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "method",
|
"depends_true": "method",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "%d/%m/%y",
|
"value": "%d/%m/%y",
|
||||||
@ -435,7 +432,6 @@
|
|||||||
"name": "Send emails as plain text",
|
"name": "Send emails as plain text",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "method",
|
"depends_true": "method",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"value": false,
|
"value": false,
|
||||||
@ -472,7 +468,6 @@
|
|||||||
"name": "Custom email (HTML)",
|
"name": "Custom email (HTML)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "enabled",
|
"depends_true": "enabled",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
@ -482,7 +477,6 @@
|
|||||||
"name": "Custom email (plaintext)",
|
"name": "Custom email (plaintext)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "enabled",
|
"depends_true": "enabled",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
@ -518,7 +512,6 @@
|
|||||||
"name": "Custom email (HTML)",
|
"name": "Custom email (HTML)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "enabled",
|
"depends_true": "enabled",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
@ -528,7 +521,6 @@
|
|||||||
"name": "Custom email (plaintext)",
|
"name": "Custom email (plaintext)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "enabled",
|
"depends_true": "enabled",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
@ -574,7 +566,6 @@
|
|||||||
"name": "Expiry email (HTML)",
|
"name": "Expiry email (HTML)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "enabled",
|
"depends_true": "enabled",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
@ -584,7 +575,6 @@
|
|||||||
"name": "Expiry email (Plaintext)",
|
"name": "Expiry email (Plaintext)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": "false",
|
"requires_restart": "false",
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "enabled",
|
"depends_true": "enabled",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
@ -594,7 +584,6 @@
|
|||||||
"name": "User created email (HTML)",
|
"name": "User created email (HTML)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "enabled",
|
"depends_true": "enabled",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
@ -604,7 +593,6 @@
|
|||||||
"name": "User created email (Plaintext)",
|
"name": "User created email (Plaintext)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "enabled",
|
"depends_true": "enabled",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
@ -685,15 +673,6 @@
|
|||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"type": "password",
|
"type": "password",
|
||||||
"value": "smtp password"
|
"value": "smtp password"
|
||||||
},
|
|
||||||
"ssl_cert": {
|
|
||||||
"name": "Path to custom SSL certificate",
|
|
||||||
"required": false,
|
|
||||||
"requires_restart": false,
|
|
||||||
"advanced": true,
|
|
||||||
"type": "text",
|
|
||||||
"value": "",
|
|
||||||
"description": "Use if your SMTP server's SSL Certificate is not trusted by the system."
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -760,7 +739,6 @@
|
|||||||
"name": "Custom email (HTML)",
|
"name": "Custom email (HTML)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
"description": "Path to custom email html"
|
"description": "Path to custom email html"
|
||||||
@ -769,7 +747,6 @@
|
|||||||
"name": "Custom email (plaintext)",
|
"name": "Custom email (plaintext)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
"description": "Path to custom email in plain text"
|
"description": "Path to custom email in plain text"
|
||||||
@ -803,7 +780,6 @@
|
|||||||
"name": "Custom email (HTML)",
|
"name": "Custom email (HTML)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
"description": "Path to custom email html"
|
"description": "Path to custom email html"
|
||||||
@ -812,7 +788,6 @@
|
|||||||
"name": "Custom email (plaintext)",
|
"name": "Custom email (plaintext)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
"description": "Path to custom email in plain text"
|
"description": "Path to custom email in plain text"
|
||||||
@ -860,7 +835,6 @@
|
|||||||
"name": "Custom email (HTML)",
|
"name": "Custom email (HTML)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "email|method",
|
"depends_true": "email|method",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
@ -870,7 +844,6 @@
|
|||||||
"name": "Custom email (plaintext)",
|
"name": "Custom email (plaintext)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"depends_true": "email|method",
|
"depends_true": "email|method",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
@ -898,7 +871,6 @@
|
|||||||
"name": "Custom email (HTML)",
|
"name": "Custom email (HTML)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
"description": "Path to custom email html"
|
"description": "Path to custom email html"
|
||||||
@ -907,7 +879,6 @@
|
|||||||
"name": "Custom email (plaintext)",
|
"name": "Custom email (plaintext)",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"advanced": true,
|
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
"description": "Path to custom email in plain text"
|
"description": "Path to custom email in plain text"
|
||||||
@ -918,8 +889,7 @@
|
|||||||
"order": [],
|
"order": [],
|
||||||
"meta": {
|
"meta": {
|
||||||
"name": "File Storage",
|
"name": "File Storage",
|
||||||
"description": "Optional settings for changing storage locations.",
|
"description": "Optional settings for changing storage locations."
|
||||||
"advanced": true
|
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"invites": {
|
"invites": {
|
||||||
|
44
email.go
44
email.go
@ -4,13 +4,10 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
textTemplate "text/template"
|
textTemplate "text/template"
|
||||||
@ -52,15 +49,18 @@ func (mg *Mailgun) send(fromName, fromAddr string, email *Email, address ...stri
|
|||||||
|
|
||||||
// SMTP supports SSL/TLS and STARTTLS; implements emailClient.
|
// SMTP supports SSL/TLS and STARTTLS; implements emailClient.
|
||||||
type SMTP struct {
|
type SMTP struct {
|
||||||
sslTLS bool
|
sslTLS bool
|
||||||
server string
|
server string
|
||||||
port int
|
port int
|
||||||
auth smtp.Auth
|
auth smtp.Auth
|
||||||
tlsConfig *tls.Config
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *SMTP) send(fromName, fromAddr string, email *Email, address ...string) error {
|
func (sm *SMTP) send(fromName, fromAddr string, email *Email, address ...string) error {
|
||||||
server := fmt.Sprintf("%s:%d", sm.server, sm.port)
|
server := fmt.Sprintf("%s:%d", sm.server, sm.port)
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
ServerName: sm.server,
|
||||||
|
}
|
||||||
from := fmt.Sprintf("%s <%s>", fromName, fromAddr)
|
from := fmt.Sprintf("%s <%s>", fromName, fromAddr)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
@ -75,9 +75,9 @@ func (sm *SMTP) send(fromName, fromAddr string, email *Email, address ...string)
|
|||||||
e.HTML = []byte(email.HTML)
|
e.HTML = []byte(email.HTML)
|
||||||
e.To = []string{addr}
|
e.To = []string{addr}
|
||||||
if sm.sslTLS {
|
if sm.sslTLS {
|
||||||
err = e.SendWithTLS(server, sm.auth, sm.tlsConfig)
|
err = e.SendWithTLS(server, sm.auth, tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
err = e.SendWithStartTLS(server, sm.auth, sm.tlsConfig)
|
err = e.SendWithStartTLS(server, sm.auth, tlsConfig)
|
||||||
}
|
}
|
||||||
}(addr)
|
}(addr)
|
||||||
}
|
}
|
||||||
@ -139,10 +139,7 @@ func NewEmailer(app *appContext) *Emailer {
|
|||||||
} else {
|
} else {
|
||||||
username = emailer.fromAddr
|
username = emailer.fromAddr
|
||||||
}
|
}
|
||||||
err := emailer.NewSMTP(app.config.Section("smtp").Key("server").String(), app.config.Section("smtp").Key("port").MustInt(465), username, app.config.Section("smtp").Key("password").String(), sslTls, app.config.Section("smtp").Key("ssl_cert").MustString(""))
|
emailer.NewSMTP(app.config.Section("smtp").Key("server").String(), app.config.Section("smtp").Key("port").MustInt(465), username, app.config.Section("smtp").Key("password").String(), sslTls)
|
||||||
if err != nil {
|
|
||||||
app.err.Printf("Error while initiating SMTP mailer: %v", err)
|
|
||||||
}
|
|
||||||
} else if method == "mailgun" {
|
} else if method == "mailgun" {
|
||||||
emailer.NewMailgun(app.config.Section("mailgun").Key("api_url").String(), app.config.Section("mailgun").Key("api_key").String())
|
emailer.NewMailgun(app.config.Section("mailgun").Key("api_url").String(), app.config.Section("mailgun").Key("api_key").String())
|
||||||
}
|
}
|
||||||
@ -164,30 +161,13 @@ func (emailer *Emailer) NewMailgun(url, key string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewSMTP returns an SMTP emailClient.
|
// NewSMTP returns an SMTP emailClient.
|
||||||
func (emailer *Emailer) NewSMTP(server string, port int, username, password string, sslTLS bool, certPath string) (err error) {
|
func (emailer *Emailer) NewSMTP(server string, port int, username, password string, sslTLS bool) {
|
||||||
rootCAs, err := x509.SystemCertPool()
|
|
||||||
if rootCAs == nil || err != nil {
|
|
||||||
rootCAs = x509.NewCertPool()
|
|
||||||
}
|
|
||||||
if certPath != "" {
|
|
||||||
var cert []byte
|
|
||||||
cert, err = os.ReadFile(certPath)
|
|
||||||
if rootCAs.AppendCertsFromPEM(cert) == false {
|
|
||||||
err = errors.New("Failed to append cert to pool")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emailer.sender = &SMTP{
|
emailer.sender = &SMTP{
|
||||||
auth: smtp.PlainAuth("", username, password, server),
|
auth: smtp.PlainAuth("", username, password, server),
|
||||||
server: server,
|
server: server,
|
||||||
port: port,
|
port: port,
|
||||||
sslTLS: sslTLS,
|
sslTLS: sslTLS,
|
||||||
tlsConfig: &tls.Config{
|
|
||||||
InsecureSkipVerify: false,
|
|
||||||
ServerName: server,
|
|
||||||
RootCAs: rootCAs,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type templ interface {
|
type templ interface {
|
||||||
|
@ -427,18 +427,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="tab-settings" class="unfocused">
|
<div id="tab-settings" class="unfocused">
|
||||||
<div class="card ~neutral !low settings overflow">
|
<div class="card ~neutral !low settings overflow">
|
||||||
<div class="flex-expand">
|
<span class="heading">{{ .strings.settings }}</span>
|
||||||
<div class="flex-row">
|
<div class="fr">
|
||||||
<span class="heading">{{ .strings.settings }}</span>
|
<span class="button ~neutral !normal" id="settings-restart">{{ .strings.settingsRestart }}</span>
|
||||||
<label for="settings-advanced-enabled" class="button ~neutral !normal ml-1">
|
<span class="button ~urge !normal unfocused" id="settings-save">{{ .strings.settingsSave }}</span>
|
||||||
<input type="checkbox" id="settings-advanced-enabled" aria-label="Advanced settings enabled">
|
|
||||||
<span class="ml-half">{{ .strings.advancedSettings }} </span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span class="button ~neutral !normal" id="settings-restart">{{ .strings.settingsRestart }}</span>
|
|
||||||
<span class="button ~urge !normal unfocused" id="settings-save">{{ .strings.settingsSave }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="card ~neutral !normal col" id="settings-sidebar">
|
<div class="card ~neutral !normal col" id="settings-sidebar">
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
"update": "Update",
|
"update": "Update",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
"advancedSettings": "Advanced Settings",
|
|
||||||
"lastActiveTime": "Last Active",
|
"lastActiveTime": "Last Active",
|
||||||
"from": "From",
|
"from": "From",
|
||||||
"user": "User",
|
"user": "User",
|
||||||
|
@ -83,11 +83,7 @@
|
|||||||
"admin": "Beheerder",
|
"admin": "Beheerder",
|
||||||
"expiry": "Verloop",
|
"expiry": "Verloop",
|
||||||
"userExpiry": "Gebruikersverloop",
|
"userExpiry": "Gebruikersverloop",
|
||||||
"extendExpiry": "Verleng verloop",
|
"extendExpiry": "Verleng verloop"
|
||||||
"updates": "Updates",
|
|
||||||
"update": "Bijwerken",
|
|
||||||
"download": "Download",
|
|
||||||
"search": "Zoeken"
|
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"changedEmailAddress": "E-mailadres van {n} gewijzigd.",
|
"changedEmailAddress": "E-mailadres van {n} gewijzigd.",
|
||||||
@ -119,12 +115,7 @@
|
|||||||
"errorUserCreated": "Aanmaken van gebruiker {n} is mislukt.",
|
"errorUserCreated": "Aanmaken van gebruiker {n} is mislukt.",
|
||||||
"sentAnnouncement": "Aankondiging verzonden.",
|
"sentAnnouncement": "Aankondiging verzonden.",
|
||||||
"saveEmail": "E-mail opgeslagen.",
|
"saveEmail": "E-mail opgeslagen.",
|
||||||
"errorSaveEmail": "Opslaan van e-mail mislukt.",
|
"errorSaveEmail": "Opslaan van e-mail mislukt."
|
||||||
"updateApplied": "De update is geïnstalleerd, doe alsjeblieft een herstart.",
|
|
||||||
"errorApplyUpdate": "Installatie van update mislukt, probeer handmatig.",
|
|
||||||
"errorCheckUpdate": "Controleren op update mislukt.",
|
|
||||||
"updateAvailable": "Er is een nieuwe update beschikbaar, kijk bij instellingen.",
|
|
||||||
"noUpdatesAvailable": "Geen nieuwe updates beschikbaar."
|
|
||||||
},
|
},
|
||||||
"quantityStrings": {
|
"quantityStrings": {
|
||||||
"modifySettingsFor": {
|
"modifySettingsFor": {
|
||||||
|
@ -156,7 +156,6 @@ type configDTO map[string]interface{}
|
|||||||
type meta struct {
|
type meta struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Advanced bool `json:"advanced,omitempty"`
|
|
||||||
DependsTrue string `json:"depends_true,omitempty"`
|
DependsTrue string `json:"depends_true,omitempty"`
|
||||||
DependsFalse string `json:"depends_false,omitempty"`
|
DependsFalse string `json:"depends_false,omitempty"`
|
||||||
}
|
}
|
||||||
@ -165,7 +164,6 @@ type setting struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Required bool `json:"required"`
|
Required bool `json:"required"`
|
||||||
Advanced bool `json:"advanced,omitempty"`
|
|
||||||
RequiresRestart bool `json:"requires_restart"`
|
RequiresRestart bool `json:"requires_restart"`
|
||||||
Type string `json:"type"` // Type (string, number, bool, etc.)
|
Type string `json:"type"` // Type (string, number, bool, etc.)
|
||||||
Value interface{} `json:"value"`
|
Value interface{} `json:"value"`
|
||||||
|
@ -3,7 +3,6 @@ import shutil
|
|||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from threading import Thread
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("-o", "--output", help="output directory for .html and .txt files")
|
parser.add_argument("-o", "--output", help="output directory for .html and .txt files")
|
||||||
@ -16,23 +15,15 @@ def runcmd(cmd):
|
|||||||
proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
|
proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
|
||||||
return proc.communicate()
|
return proc.communicate()
|
||||||
|
|
||||||
def compile(mjml: Path):
|
|
||||||
fname = mjml.with_suffix(".html")
|
|
||||||
runcmd(f"npx mjml {str(mjml)} -o {str(fname)}")
|
|
||||||
if fname.is_file():
|
|
||||||
print(f"Compiled {mjml.name}")
|
|
||||||
|
|
||||||
local_path = Path("mail")
|
local_path = Path("mail")
|
||||||
|
|
||||||
threads = []
|
|
||||||
|
|
||||||
for mjml in [f for f in local_path.iterdir() if f.is_file() and "mjml" in f.suffix]:
|
for mjml in [f for f in local_path.iterdir() if f.is_file() and "mjml" in f.suffix]:
|
||||||
threads.append(Thread(target=compile, args=(mjml,)))
|
print(f"Compiling {mjml.name}")
|
||||||
|
fname = mjml.with_suffix(".html")
|
||||||
for thread in threads:
|
runcmd(f"npx mjml {str(mjml)} -o {str(fname)}")
|
||||||
thread.start()
|
if fname.is_file():
|
||||||
for thread in threads:
|
print("Done.")
|
||||||
thread.join()
|
|
||||||
|
|
||||||
html = [f for f in local_path.iterdir() if f.is_file() and "html" in f.suffix]
|
html = [f for f in local_path.iterdir() if f.is_file() and "html" in f.suffix]
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
# Since go doesn't order its json, this script adds ordered lists
|
|
||||||
# of section/setting names for the settings tab to use.
|
|
||||||
import json, argparse
|
import json, argparse
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# sets version environment variable for goreleaser to use
|
|
||||||
# scripts/version.sh goreleaser ...
|
|
||||||
JFA_GO_VERSION=$(git describe --exact-match HEAD 2> /dev/null || echo 'vgit')
|
JFA_GO_VERSION=$(git describe --exact-match HEAD 2> /dev/null || echo 'vgit')
|
||||||
JFA_GO_VERSION="$(echo $JFA_GO_VERSION | sed 's/v//g')" $@
|
JFA_GO_VERSION="$(echo $JFA_GO_VERSION | sed 's/v//g')" $@
|
||||||
|
@ -9,7 +9,6 @@ interface settingsBoolEvent extends Event {
|
|||||||
interface Meta {
|
interface Meta {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
advanced?: boolean;
|
|
||||||
depends_true?: string;
|
depends_true?: string;
|
||||||
depends_false?: string;
|
depends_false?: string;
|
||||||
}
|
}
|
||||||
@ -19,7 +18,6 @@ interface Setting {
|
|||||||
description: string;
|
description: string;
|
||||||
required: boolean;
|
required: boolean;
|
||||||
requires_restart: boolean;
|
requires_restart: boolean;
|
||||||
advanced?: boolean;
|
|
||||||
type: string;
|
type: string;
|
||||||
value: string | boolean | number;
|
value: string | boolean | number;
|
||||||
depends_true?: string;
|
depends_true?: string;
|
||||||
@ -43,25 +41,6 @@ class DOMInput {
|
|||||||
private _tooltip: HTMLDivElement;
|
private _tooltip: HTMLDivElement;
|
||||||
private _required: HTMLSpanElement;
|
private _required: HTMLSpanElement;
|
||||||
private _restart: HTMLSpanElement;
|
private _restart: HTMLSpanElement;
|
||||||
private _advanced: boolean;
|
|
||||||
|
|
||||||
private _advancedListener = (event: settingsBoolEvent) => {
|
|
||||||
if (!Boolean(event.detail)) {
|
|
||||||
this._input.parentElement.classList.add("unfocused");
|
|
||||||
} else {
|
|
||||||
this._input.parentElement.classList.remove("unfocused");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get advanced(): boolean { return this._advanced; }
|
|
||||||
set advanced(advanced: boolean) {
|
|
||||||
this._advanced = advanced;
|
|
||||||
if (advanced) {
|
|
||||||
document.addEventListener("settings-advancedState", this._advancedListener);
|
|
||||||
} else {
|
|
||||||
document.removeEventListener("settings-advancedState", this._advancedListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get name(): string { return this._container.querySelector("span.setting-label").textContent; }
|
get name(): string { return this._container.querySelector("span.setting-label").textContent; }
|
||||||
set name(n: string) { this._container.querySelector("span.setting-label").textContent = n; }
|
set name(n: string) { this._container.querySelector("span.setting-label").textContent = n; }
|
||||||
@ -146,7 +125,6 @@ class DOMInput {
|
|||||||
this.required = s.required;
|
this.required = s.required;
|
||||||
this.requires_restart = s.requires_restart;
|
this.requires_restart = s.requires_restart;
|
||||||
this.value = s.value;
|
this.value = s.value;
|
||||||
this.advanced = s.advanced;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
asElement = (): HTMLDivElement => { return this._container; }
|
asElement = (): HTMLDivElement => { return this._container; }
|
||||||
@ -202,25 +180,6 @@ class DOMBool implements SBool {
|
|||||||
private _required: HTMLSpanElement;
|
private _required: HTMLSpanElement;
|
||||||
private _restart: HTMLSpanElement;
|
private _restart: HTMLSpanElement;
|
||||||
type: string = "bool";
|
type: string = "bool";
|
||||||
private _advanced: boolean;
|
|
||||||
|
|
||||||
private _advancedListener = (event: settingsBoolEvent) => {
|
|
||||||
if (!Boolean(event.detail)) {
|
|
||||||
this._input.parentElement.classList.add("unfocused");
|
|
||||||
} else {
|
|
||||||
this._input.parentElement.classList.remove("unfocused");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get advanced(): boolean { return this._advanced; }
|
|
||||||
set advanced(advanced: boolean) {
|
|
||||||
this._advanced = advanced;
|
|
||||||
if (advanced) {
|
|
||||||
document.addEventListener("settings-advancedState", this._advancedListener);
|
|
||||||
} else {
|
|
||||||
document.removeEventListener("settings-advancedState", this._advancedListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get name(): string { return this._container.querySelector("span.setting-label").textContent; }
|
get name(): string { return this._container.querySelector("span.setting-label").textContent; }
|
||||||
set name(n: string) { this._container.querySelector("span.setting-label").textContent = n; }
|
set name(n: string) { this._container.querySelector("span.setting-label").textContent = n; }
|
||||||
@ -306,7 +265,6 @@ class DOMBool implements SBool {
|
|||||||
this.required = s.required;
|
this.required = s.required;
|
||||||
this.requires_restart = s.requires_restart;
|
this.requires_restart = s.requires_restart;
|
||||||
this.value = s.value;
|
this.value = s.value;
|
||||||
this.advanced = s.advanced;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
asElement = (): HTMLDivElement => { return this._container; }
|
asElement = (): HTMLDivElement => { return this._container; }
|
||||||
@ -324,25 +282,6 @@ class DOMSelect implements SSelect {
|
|||||||
private _restart: HTMLSpanElement;
|
private _restart: HTMLSpanElement;
|
||||||
private _options: string[][];
|
private _options: string[][];
|
||||||
type: string = "bool";
|
type: string = "bool";
|
||||||
private _advanced: boolean;
|
|
||||||
|
|
||||||
private _advancedListener = (event: settingsBoolEvent) => {
|
|
||||||
if (!Boolean(event.detail)) {
|
|
||||||
this._container.classList.add("unfocused");
|
|
||||||
} else {
|
|
||||||
this._container.classList.remove("unfocused");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get advanced(): boolean { return this._advanced; }
|
|
||||||
set advanced(advanced: boolean) {
|
|
||||||
this._advanced = advanced;
|
|
||||||
if (advanced) {
|
|
||||||
document.addEventListener("settings-advancedState", this._advancedListener);
|
|
||||||
} else {
|
|
||||||
document.removeEventListener("settings-advancedState", this._advancedListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get name(): string { return this._container.querySelector("span.setting-label").textContent; }
|
get name(): string { return this._container.querySelector("span.setting-label").textContent; }
|
||||||
set name(n: string) { this._container.querySelector("span.setting-label").textContent = n; }
|
set name(n: string) { this._container.querySelector("span.setting-label").textContent = n; }
|
||||||
@ -505,7 +444,7 @@ class sectionPanel {
|
|||||||
}
|
}
|
||||||
this.values[name] = ""+setting.value;
|
this.values[name] = ""+setting.value;
|
||||||
document.addEventListener(`settings-${this._sectionName}-${name}`, (event: CustomEvent) => {
|
document.addEventListener(`settings-${this._sectionName}-${name}`, (event: CustomEvent) => {
|
||||||
// const oldValue = this.values[name];
|
const oldValue = this.values[name];
|
||||||
this.values[name] = ""+event.detail;
|
this.values[name] = ""+event.detail;
|
||||||
document.dispatchEvent(new CustomEvent("settings-section-changed"));
|
document.dispatchEvent(new CustomEvent("settings-section-changed"));
|
||||||
});
|
});
|
||||||
@ -565,15 +504,6 @@ export class settingsList {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (s.meta.advanced) {
|
|
||||||
document.addEventListener("settings-advancedState", (event: settingsBoolEvent) => {
|
|
||||||
if (!Boolean(event.detail)) {
|
|
||||||
button.classList.add("unfocused");
|
|
||||||
} else {
|
|
||||||
button.classList.remove("unfocused");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this._buttons[name] = button;
|
this._buttons[name] = button;
|
||||||
this._sidebar.appendChild(this._buttons[name]);
|
this._sidebar.appendChild(this._buttons[name]);
|
||||||
}
|
}
|
||||||
@ -637,20 +567,6 @@ export class settingsList {
|
|||||||
};
|
};
|
||||||
this._saveButton.onclick = this._save;
|
this._saveButton.onclick = this._save;
|
||||||
document.addEventListener("settings-requires-restart", () => { this._needsRestart = true; });
|
document.addEventListener("settings-requires-restart", () => { this._needsRestart = true; });
|
||||||
|
|
||||||
const advancedEnableToggle = document.getElementById("settings-advanced-enabled") as HTMLInputElement;
|
|
||||||
advancedEnableToggle.onchange = () => {
|
|
||||||
document.dispatchEvent(new CustomEvent("settings-advancedState", { detail: advancedEnableToggle.checked }));
|
|
||||||
const parent = advancedEnableToggle.parentElement;
|
|
||||||
if (advancedEnableToggle.checked) {
|
|
||||||
parent.classList.add("~urge");
|
|
||||||
parent.classList.remove("~neutral");
|
|
||||||
} else {
|
|
||||||
parent.classList.add("~neutral");
|
|
||||||
parent.classList.remove("~urge");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
advancedEnableToggle.checked = false;
|
|
||||||
|
|
||||||
if (window.ombiEnabled) {
|
if (window.ombiEnabled) {
|
||||||
let ombi = new ombiDefaults();
|
let ombi = new ombiDefaults();
|
||||||
@ -697,7 +613,6 @@ export class settingsList {
|
|||||||
}
|
}
|
||||||
this._showPanel(settings.order[0]);
|
this._showPanel(settings.order[0]);
|
||||||
document.dispatchEvent(new CustomEvent("settings-loaded"));
|
document.dispatchEvent(new CustomEvent("settings-loaded"));
|
||||||
document.dispatchEvent(new CustomEvent("settings-advancedState", { detail: false }));
|
|
||||||
this._saveButton.classList.add("unfocused");
|
this._saveButton.classList.add("unfocused");
|
||||||
this._needsRestart = false;
|
this._needsRestart = false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user