mirror of
https://github.com/mickael-kerjean/filestash.git
synced 2025-10-29 17:18:43 +08:00
feature (dynamic): make configuration dynamic
This commit is contained in:
11
cmd/main.go
11
cmd/main.go
@ -27,6 +27,11 @@ func start(routes *mux.Router) {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
InitConfig()
|
||||||
|
InitPluginList(embed.EmbedPluginList)
|
||||||
|
for _, fn := range Hooks.Get.Onload() {
|
||||||
|
fn()
|
||||||
|
}
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for _, obj := range Hooks.Get.Starter() {
|
for _, obj := range Hooks.Get.Starter() {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
@ -35,11 +40,5 @@ func start(routes *mux.Router) {
|
|||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
go func() {
|
|
||||||
InitPluginList(embed.EmbedPluginList)
|
|
||||||
for _, fn := range Hooks.Get.Onload() {
|
|
||||||
go fn()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,7 +49,7 @@ type FormElement struct {
|
|||||||
Required bool `json:"required"`
|
Required bool `json:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func InitConfig() {
|
||||||
Config = NewConfiguration()
|
Config = NewConfiguration()
|
||||||
Config.Load()
|
Config.Load()
|
||||||
Config.Initialise()
|
Config.Initialise()
|
||||||
|
|||||||
@ -21,16 +21,17 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var configKeysToEncrypt []string = []string{
|
||||||
configPath string = GetAbsolutePath(CONFIG_PATH, "config.json")
|
|
||||||
configKeysToEncrypt []string = []string{
|
|
||||||
"middleware.identity_provider.params",
|
"middleware.identity_provider.params",
|
||||||
"middleware.attribute_mapping.params",
|
"middleware.attribute_mapping.params",
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
func configPath() string {
|
||||||
|
return GetAbsolutePath(CONFIG_PATH, "config.json")
|
||||||
|
}
|
||||||
|
|
||||||
func LoadConfig() ([]byte, error) {
|
func LoadConfig() ([]byte, error) {
|
||||||
file, err := os.OpenFile(configPath, os.O_RDONLY, os.ModePerm)
|
file, err := os.OpenFile(configPath(), os.O_RDONLY, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
os.MkdirAll(GetAbsolutePath(CONFIG_PATH), os.ModePerm)
|
os.MkdirAll(GetAbsolutePath(CONFIG_PATH), os.ModePerm)
|
||||||
@ -70,12 +71,12 @@ func LoadConfig() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SaveConfig(v []byte) error {
|
func SaveConfig(v []byte) error {
|
||||||
file, err := os.Create(configPath)
|
file, err := os.Create(configPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"Filestash needs to be able to create/edit its own configuration which it can't at the moment. "+
|
"Filestash needs to be able to create/edit its own configuration which it can't at the moment. "+
|
||||||
"Change the permission for filestash to create and edit `%s`",
|
"Change the permission for filestash to create and edit `%s`",
|
||||||
configPath,
|
configPath(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,17 +17,32 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
LOG_PATH = "data/state/log/"
|
CONFIG_PATH = "state/config/"
|
||||||
CONFIG_PATH = "data/state/config/"
|
CERT_PATH = "state/certs/"
|
||||||
DB_PATH = "data/state/db/"
|
DB_PATH = "state/db/"
|
||||||
FTS_PATH = "data/state/search/"
|
FTS_PATH = "state/search/"
|
||||||
CERT_PATH = "data/state/certs/"
|
LOG_PATH = "state/log/"
|
||||||
TMP_PATH = "data/cache/tmp/"
|
TMP_PATH = "cache/tmp/"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
os.MkdirAll(filepath.Join(GetCurrentDir(), LOG_PATH), os.ModePerm)
|
// STEP1: setup app path
|
||||||
|
rootPath := "data/"
|
||||||
|
if p := os.Getenv("FILESTASH_PATH"); p != "" {
|
||||||
|
rootPath = p
|
||||||
|
}
|
||||||
|
LOG_PATH = filepath.Join(rootPath, LOG_PATH)
|
||||||
|
CONFIG_PATH = filepath.Join(rootPath, CONFIG_PATH)
|
||||||
|
DB_PATH = filepath.Join(rootPath, DB_PATH)
|
||||||
|
FTS_PATH = filepath.Join(rootPath, FTS_PATH)
|
||||||
|
CERT_PATH = filepath.Join(rootPath, CERT_PATH)
|
||||||
|
TMP_PATH = filepath.Join(rootPath, TMP_PATH)
|
||||||
|
|
||||||
|
// STEP2: initialise the config
|
||||||
|
os.MkdirAll(filepath.Join(GetCurrentDir(), CERT_PATH), os.ModePerm)
|
||||||
|
os.MkdirAll(filepath.Join(GetCurrentDir(), DB_PATH), os.ModePerm)
|
||||||
os.MkdirAll(filepath.Join(GetCurrentDir(), FTS_PATH), os.ModePerm)
|
os.MkdirAll(filepath.Join(GetCurrentDir(), FTS_PATH), os.ModePerm)
|
||||||
|
os.MkdirAll(filepath.Join(GetCurrentDir(), LOG_PATH), os.ModePerm)
|
||||||
os.RemoveAll(filepath.Join(GetCurrentDir(), TMP_PATH))
|
os.RemoveAll(filepath.Join(GetCurrentDir(), TMP_PATH))
|
||||||
os.MkdirAll(filepath.Join(GetCurrentDir(), TMP_PATH), os.ModePerm)
|
os.MkdirAll(filepath.Join(GetCurrentDir(), TMP_PATH), os.ModePerm)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Plugin struct {
|
type Plugin struct {
|
||||||
|
|||||||
@ -40,7 +40,7 @@ func generateNewCertificate(root *x509.Certificate, key *rsa.PrivateKey) (*x509.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func pullCertificateFromFS() (*x509.Certificate, []byte, error) {
|
func pullCertificateFromFS() (*x509.Certificate, []byte, error) {
|
||||||
file, err := os.OpenFile(certPEMPath, os.O_RDONLY, os.ModePerm)
|
file, err := os.OpenFile(certPEMPath(), os.O_RDONLY, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ func pullCertificateFromFS() (*x509.Certificate, []byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func saveCertificateToFS(certPEM []byte) error {
|
func saveCertificateToFS(certPEM []byte) error {
|
||||||
file, err := os.OpenFile(certPEMPath, os.O_WRONLY|os.O_CREATE, 0600)
|
file, err := os.OpenFile(certPEMPath(), os.O_WRONLY|os.O_CREATE, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -69,5 +69,5 @@ func saveCertificateToFS(certPEM []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func clearCert() {
|
func clearCert() {
|
||||||
os.Remove(certPEMPath)
|
os.Remove(certPEMPath())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,14 +2,20 @@ package ssl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/mickael-kerjean/filestash/server/common"
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var keyPEMPath string = GetAbsolutePath(CERT_PATH, "key.pem")
|
var (
|
||||||
var certPEMPath string = GetAbsolutePath(CERT_PATH, "cert.pem")
|
keyPEMPath func() string
|
||||||
|
certPEMPath func() string
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
os.MkdirAll(GetAbsolutePath(CERT_PATH), os.ModePerm)
|
keyPEMPath = func() string {
|
||||||
|
return GetAbsolutePath(CERT_PATH, "key.pem")
|
||||||
|
}
|
||||||
|
certPEMPath = func() string {
|
||||||
|
return GetAbsolutePath(CERT_PATH, "cert.pem")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Clear() {
|
func Clear() {
|
||||||
|
|||||||
@ -37,7 +37,7 @@ func generateNewPrivateKey() (*rsa.PrivateKey, []byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func pullPrivateKeyFromFS() (*rsa.PrivateKey, []byte, error) {
|
func pullPrivateKeyFromFS() (*rsa.PrivateKey, []byte, error) {
|
||||||
file, err := os.OpenFile(keyPEMPath, os.O_RDONLY, os.ModePerm)
|
file, err := os.OpenFile(keyPEMPath(), os.O_RDONLY, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ func pullPrivateKeyFromFS() (*rsa.PrivateKey, []byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func savePrivateKeyToFS(privatePEM []byte) error {
|
func savePrivateKeyToFS(privatePEM []byte) error {
|
||||||
file, err := os.OpenFile(keyPEMPath, os.O_WRONLY|os.O_CREATE, 0600)
|
file, err := os.OpenFile(keyPEMPath(), os.O_WRONLY|os.O_CREATE, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -69,5 +69,5 @@ func savePrivateKeyToFS(privatePEM []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func clearPrivateKey() {
|
func clearPrivateKey() {
|
||||||
os.Remove(keyPEMPath)
|
os.Remove(keyPEMPath())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,11 +32,6 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
FileCache = NewAppCache()
|
|
||||||
cachePath := GetAbsolutePath(TMP_PATH)
|
|
||||||
FileCache.OnEvict(func(key string, value interface{}) {
|
|
||||||
os.RemoveAll(filepath.Join(cachePath, key))
|
|
||||||
})
|
|
||||||
ZipTimeout = func() int {
|
ZipTimeout = func() int {
|
||||||
return Config.Get("features.protection.zip_timeout").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.protection.zip_timeout").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -50,7 +45,13 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()
|
}).Int()
|
||||||
}
|
}
|
||||||
|
FileCache = NewAppCache()
|
||||||
|
FileCache.OnEvict(func(key string, value interface{}) {
|
||||||
|
os.RemoveAll(filepath.Join(GetAbsolutePath(TMP_PATH), key))
|
||||||
|
})
|
||||||
|
Hooks.Register.Onload(func() {
|
||||||
ZipTimeout()
|
ZipTimeout()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func FileLs(ctx *App, res http.ResponseWriter, req *http.Request) {
|
func FileLs(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||||
|
|||||||
@ -9,6 +9,19 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var telemetry = Telemetry{Data: make([]LogEntry, 0)}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Hooks.Register.Onload(func() {
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
telemetry.Flush()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type Middleware func(func(*App, http.ResponseWriter, *http.Request)) func(*App, http.ResponseWriter, *http.Request)
|
type Middleware func(func(*App, http.ResponseWriter, *http.Request)) func(*App, http.ResponseWriter, *http.Request)
|
||||||
|
|
||||||
func NewMiddlewareChain(fn func(*App, http.ResponseWriter, *http.Request), m []Middleware, app App) http.HandlerFunc {
|
func NewMiddlewareChain(fn func(*App, http.ResponseWriter, *http.Request), m []Middleware, app App) http.HandlerFunc {
|
||||||
@ -108,7 +121,7 @@ func Logger(ctx App, res http.ResponseWriter, req *http.Request) {
|
|||||||
RequestID: func() string {
|
RequestID: func() string {
|
||||||
defer func() string {
|
defer func() string {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
Log.Debug("middleware::index get header '%s'", r)
|
return "oops"
|
||||||
}
|
}
|
||||||
return "null"
|
return "null"
|
||||||
}()
|
}()
|
||||||
@ -161,14 +174,3 @@ func (this *Telemetry) Flush() {
|
|||||||
}
|
}
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
var telemetry Telemetry = Telemetry{Data: make([]LogEntry, 0)}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
time.Sleep(10 * time.Second)
|
|
||||||
telemetry.Flush()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|||||||
@ -4,17 +4,15 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
. "github.com/mickael-kerjean/filestash/server/common"
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
"os"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var DB *sql.DB
|
var DB *sql.DB
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cachePath := GetAbsolutePath(DB_PATH)
|
Hooks.Register.Onload(func() {
|
||||||
os.MkdirAll(cachePath, os.ModePerm)
|
|
||||||
var err error
|
var err error
|
||||||
if DB, err = sql.Open("sqlite", cachePath+"/share.sql?_fk=true"); err != nil {
|
if DB, err = sql.Open("sqlite", GetAbsolutePath(DB_PATH)+"/share.sql?_fk=true"); err != nil {
|
||||||
Log.Error("model::index sqlite open error '%s'", err.Error())
|
Log.Error("model::index sqlite open error '%s'", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -37,6 +35,7 @@ func init() {
|
|||||||
go func() {
|
go func() {
|
||||||
autovacuum()
|
autovacuum()
|
||||||
}()
|
}()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func autovacuum() {
|
func autovacuum() {
|
||||||
|
|||||||
@ -10,28 +10,20 @@ package model
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
. "github.com/mickael-kerjean/filestash/server/common"
|
|
||||||
"github.com/mickael-kerjean/net/webdav"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
|
"github.com/mickael-kerjean/net/webdav"
|
||||||
)
|
)
|
||||||
|
|
||||||
const DAVCachePath = "data/cache/webdav/"
|
var webdavCache AppCache
|
||||||
|
|
||||||
var (
|
|
||||||
cachePath string
|
|
||||||
webdavCache AppCache
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cachePath = GetAbsolutePath(DAVCachePath) + "/"
|
|
||||||
os.RemoveAll(cachePath)
|
|
||||||
os.MkdirAll(cachePath, os.ModePerm)
|
|
||||||
|
|
||||||
webdavCache = NewQuickCache(20, 10)
|
webdavCache = NewQuickCache(20, 10)
|
||||||
webdavCache.OnEvict(func(filename string, _ interface{}) {
|
webdavCache.OnEvict(func(filename string, _ interface{}) {
|
||||||
os.Remove(filename)
|
os.Remove(filename)
|
||||||
@ -64,7 +56,7 @@ func (this WebdavFs) Mkdir(ctx context.Context, name string, perm os.FileMode) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *WebdavFs) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (webdav.File, error) {
|
func (this *WebdavFs) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (webdav.File, error) {
|
||||||
cachePath := fmt.Sprintf("%stmp_%s", cachePath, Hash(this.id+name, 20))
|
cachePath := filepath.Join(GetAbsolutePath(TMP_PATH), "webdav_"+Hash(this.id+name, 20))
|
||||||
fwriteFile := func() *os.File {
|
fwriteFile := func() *os.File {
|
||||||
if this.req.Method == "PUT" {
|
if this.req.Method == "PUT" {
|
||||||
f, err := os.OpenFile(cachePath+"_writer", os.O_WRONLY|os.O_CREATE|os.O_EXCL, os.ModePerm)
|
f, err := os.OpenFile(cachePath+"_writer", os.O_WRONLY|os.O_CREATE|os.O_EXCL, os.ModePerm)
|
||||||
@ -119,7 +111,7 @@ func (this *WebdavFs) Stat(ctx context.Context, name string) (os.FileInfo, error
|
|||||||
this.webdavFile = &WebdavFile{
|
this.webdavFile = &WebdavFile{
|
||||||
path: fullname,
|
path: fullname,
|
||||||
backend: this.backend,
|
backend: this.backend,
|
||||||
cache: fmt.Sprintf("%stmp_%s", cachePath, Hash(this.id+name, 20)),
|
cache: filepath.Join(GetAbsolutePath(TMP_PATH), "webdav_"+Hash(this.id+name, 20)),
|
||||||
}
|
}
|
||||||
return this.webdavFile.Stat()
|
return this.webdavFile.Stat()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import (
|
|||||||
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_local"
|
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_local"
|
||||||
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_mysql"
|
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_mysql"
|
||||||
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_nfs"
|
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_nfs"
|
||||||
|
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_nfs4"
|
||||||
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_nop"
|
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_nop"
|
||||||
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_s3"
|
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_s3"
|
||||||
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_samba"
|
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_samba"
|
||||||
@ -39,5 +40,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Log.Debug("Plugin loader")
|
Hooks.Register.Onload(func() { Log.Debug("plugins loaded") })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,21 +6,20 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
. "github.com/mickael-kerjean/filestash/server/common"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var BackblazeCache AppCache
|
||||||
BackblazeCachePath string = "data/cache/tmp/"
|
|
||||||
BackblazeCache AppCache
|
|
||||||
)
|
|
||||||
|
|
||||||
type Backblaze struct {
|
type Backblaze struct {
|
||||||
params map[string]string
|
params map[string]string
|
||||||
@ -41,9 +40,6 @@ type BackblazeError struct {
|
|||||||
func init() {
|
func init() {
|
||||||
Backend.Register("backblaze", Backblaze{})
|
Backend.Register("backblaze", Backblaze{})
|
||||||
BackblazeCache = NewAppCache()
|
BackblazeCache = NewAppCache()
|
||||||
cachePath := GetAbsolutePath(BackblazeCachePath)
|
|
||||||
os.RemoveAll(cachePath)
|
|
||||||
os.MkdirAll(cachePath, os.ModePerm)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this Backblaze) Init(params map[string]string, app *App) (IBackend, error) {
|
func (this Backblaze) Init(params map[string]string, app *App) (IBackend, error) {
|
||||||
@ -429,7 +425,10 @@ func (this Backblaze) Save(path string, file io.Reader) error {
|
|||||||
ContentLength int64
|
ContentLength int64
|
||||||
Sha1 []byte
|
Sha1 []byte
|
||||||
}{}
|
}{}
|
||||||
backblazeFileDetail.path = GetAbsolutePath(BackblazeCachePath + "data_" + QuickString(20) + ".dat")
|
backblazeFileDetail.path = filepath.Join(
|
||||||
|
GetAbsolutePath(TMP_PATH),
|
||||||
|
"data_"+QuickString(20)+".dat",
|
||||||
|
)
|
||||||
f, err := os.OpenFile(backblazeFileDetail.path, os.O_CREATE|os.O_RDWR, os.ModePerm)
|
f, err := os.OpenFile(backblazeFileDetail.path, os.O_CREATE|os.O_RDWR, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -1,17 +1,18 @@
|
|||||||
package plg_backend_ftp_only
|
package plg_backend_ftp_only
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
. "github.com/mickael-kerjean/filestash/server/common"
|
|
||||||
//"github.com/secsy/goftp" <- FTP issue with microsoft FTP
|
|
||||||
"github.com/prasad83/goftp"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
|
|
||||||
|
//"github.com/secsy/goftp" <- FTP issue with microsoft FTP
|
||||||
|
"github.com/prasad83/goftp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var FtpCache AppCache
|
var FtpCache AppCache
|
||||||
|
|||||||
@ -17,8 +17,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const GitCachePath = "data/cache/git/"
|
|
||||||
|
|
||||||
var GitCache AppCache
|
var GitCache AppCache
|
||||||
|
|
||||||
type Git struct {
|
type Git struct {
|
||||||
@ -29,9 +27,6 @@ func init() {
|
|||||||
Backend.Register("git", Git{})
|
Backend.Register("git", Git{})
|
||||||
|
|
||||||
GitCache = NewAppCache()
|
GitCache = NewAppCache()
|
||||||
cachePath := GetAbsolutePath(GitCachePath)
|
|
||||||
os.RemoveAll(cachePath)
|
|
||||||
os.MkdirAll(cachePath, os.ModePerm)
|
|
||||||
GitCache.OnEvict(func(key string, value interface{}) {
|
GitCache.OnEvict(func(key string, value interface{}) {
|
||||||
g := value.(*Git)
|
g := value.(*Git)
|
||||||
g.Close()
|
g.Close()
|
||||||
@ -94,7 +89,10 @@ func (git Git) Init(params map[string]string, app *App) (IBackend, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hash := GenerateID(app)
|
hash := GenerateID(app)
|
||||||
p.basePath = GetAbsolutePath(GitCachePath + "repo_" + hash + "/")
|
p.basePath = filepath.Join(
|
||||||
|
GetAbsolutePath(TMP_PATH),
|
||||||
|
"git_"+hash,
|
||||||
|
) + "/"
|
||||||
|
|
||||||
repo, err := g.git.open(p, p.basePath)
|
repo, err := g.git.open(p, p.basePath)
|
||||||
g.git.repo = repo
|
g.git.repo = repo
|
||||||
|
|||||||
@ -195,7 +195,7 @@ func (this Mysql) Ls(path string) ([]os.FileInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rows, err := this.db.Query(fmt.Sprintf(
|
rows, err := this.db.Query(fmt.Sprintf(
|
||||||
"SELECT CONCAT(%s) as filename %sFROM %s.%s %s LIMIT 15000",
|
"SELECT CONCAT(%s) as filename %sFROM %s.%s %s LIMIT 500000",
|
||||||
func() string {
|
func() string {
|
||||||
q := strings.Join(extractNamePlus(sqlFields.Select), ", ' - ', ")
|
q := strings.Join(extractNamePlus(sqlFields.Select), ", ' - ', ")
|
||||||
if len(sqlFields.Esthetics) != 0 {
|
if len(sqlFields.Esthetics) != 0 {
|
||||||
|
|||||||
@ -154,7 +154,7 @@ func (this Nfs4Share) Rm(path string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this Nfs4Share) Mv(from string, to string) error {
|
func (this Nfs4Share) Mv(from string, to string) error {
|
||||||
return ErrNotImplemented
|
return this.client.Rename(from, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this Nfs4Share) Touch(path string) error {
|
func (this Nfs4Share) Touch(path string) error {
|
||||||
|
|||||||
@ -23,6 +23,10 @@ import (
|
|||||||
var (
|
var (
|
||||||
SECRET_KEY_DERIVATE_FOR_ONLYOFFICE string
|
SECRET_KEY_DERIVATE_FOR_ONLYOFFICE string
|
||||||
OnlyOfficeCache *cache.Cache
|
OnlyOfficeCache *cache.Cache
|
||||||
|
|
||||||
|
plugin_enable func() bool
|
||||||
|
server_url func() string
|
||||||
|
can_download func() bool
|
||||||
)
|
)
|
||||||
|
|
||||||
type OnlyOfficeCacheData struct {
|
type OnlyOfficeCacheData struct {
|
||||||
@ -32,7 +36,9 @@ type OnlyOfficeCacheData struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin_enable := func() bool {
|
SECRET_KEY_DERIVATE_FOR_ONLYOFFICE = Hash("ONLYOFFICE_"+SECRET_KEY, len(SECRET_KEY))
|
||||||
|
OnlyOfficeCache = cache.New(720*time.Minute, 720*time.Minute)
|
||||||
|
plugin_enable = func() bool {
|
||||||
return Config.Get("features.office.enable").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.office.enable").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
f = &FormElement{}
|
f = &FormElement{}
|
||||||
@ -47,8 +53,9 @@ func init() {
|
|||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
}).Bool()
|
}).Bool()
|
||||||
}()
|
}
|
||||||
Config.Get("features.office.onlyoffice_server").Schema(func(f *FormElement) *FormElement {
|
server_url = func() string {
|
||||||
|
return Config.Get("features.office.onlyoffice_server").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
f = &FormElement{}
|
f = &FormElement{}
|
||||||
}
|
}
|
||||||
@ -63,8 +70,10 @@ func init() {
|
|||||||
f.Placeholder = fmt.Sprintf("Default: '%s'", u)
|
f.Placeholder = fmt.Sprintf("Default: '%s'", u)
|
||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
})
|
}).String()
|
||||||
Config.Get("features.office.can_download").Schema(func(f *FormElement) *FormElement {
|
}
|
||||||
|
can_download = func() bool {
|
||||||
|
return Config.Get("features.office.can_download").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
f = &FormElement{}
|
f = &FormElement{}
|
||||||
}
|
}
|
||||||
@ -74,13 +83,13 @@ func init() {
|
|||||||
f.Description = "Display Download button in onlyoffice"
|
f.Description = "Display Download button in onlyoffice"
|
||||||
f.Default = true
|
f.Default = true
|
||||||
return f
|
return f
|
||||||
})
|
}).Bool()
|
||||||
|
|
||||||
if plugin_enable == false {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECRET_KEY_DERIVATE_FOR_ONLYOFFICE = Hash("ONLYOFFICE_"+SECRET_KEY, len(SECRET_KEY))
|
Hooks.Register.Onload(func() {
|
||||||
|
if plugin_enable() == false {
|
||||||
|
return
|
||||||
|
}
|
||||||
Hooks.Register.HttpEndpoint(func(r *mux.Router, app *App) error {
|
Hooks.Register.HttpEndpoint(func(r *mux.Router, app *App) error {
|
||||||
oods := r.PathPrefix("/onlyoffice").Subrouter()
|
oods := r.PathPrefix("/onlyoffice").Subrouter()
|
||||||
oods.PathPrefix("/static/").HandlerFunc(StaticHandler).Methods("GET", "POST")
|
oods.PathPrefix("/static/").HandlerFunc(StaticHandler).Methods("GET", "POST")
|
||||||
@ -105,13 +114,12 @@ func init() {
|
|||||||
return ["appframe", {"endpoint": "/api/onlyoffice/iframe"}];
|
return ["appframe", {"endpoint": "/api/onlyoffice/iframe"}];
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
OnlyOfficeCache = cache.New(720*time.Minute, 720*time.Minute)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func StaticHandler(res http.ResponseWriter, req *http.Request) {
|
func StaticHandler(res http.ResponseWriter, req *http.Request) {
|
||||||
req.URL.Path = strings.TrimPrefix(req.URL.Path, "/onlyoffice/static")
|
req.URL.Path = strings.TrimPrefix(req.URL.Path, "/onlyoffice/static")
|
||||||
oodsLocation := Config.Get("features.office.onlyoffice_server").String()
|
u, err := url.Parse(server_url())
|
||||||
u, err := url.Parse(oodsLocation)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
SendErrorResult(res, err)
|
SendErrorResult(res, err)
|
||||||
return
|
return
|
||||||
@ -161,7 +169,7 @@ func IframeContentHandler(ctx *App, res http.ResponseWriter, req *http.Request)
|
|||||||
if model.CanRead(ctx) == false {
|
if model.CanRead(ctx) == false {
|
||||||
SendErrorResult(res, ErrPermissionDenied)
|
SendErrorResult(res, ErrPermissionDenied)
|
||||||
return
|
return
|
||||||
} else if oodsLocation := Config.Get("features.office.onlyoffice_server").String(); oodsLocation == "" {
|
} else if server_url() == "" {
|
||||||
res.WriteHeader(http.StatusServiceUnavailable)
|
res.WriteHeader(http.StatusServiceUnavailable)
|
||||||
res.Write([]byte("<p>The Onlyoffice server hasn't been configured</p>"))
|
res.Write([]byte("<p>The Onlyoffice server hasn't been configured</p>"))
|
||||||
res.Write([]byte("<style>p {color: white; text-align: center; margin-top: 50px; font-size: 20px; opacity: 0.6; font-family: monospace; } </style>"))
|
res.Write([]byte("<style>p {color: white; text-align: center; margin-top: 50px; font-size: 20px; opacity: 0.6; font-family: monospace; } </style>"))
|
||||||
@ -365,7 +373,7 @@ func IframeContentHandler(ctx *App, res http.ResponseWriter, req *http.Request)
|
|||||||
filetype,
|
filetype,
|
||||||
key,
|
key,
|
||||||
func() string {
|
func() string {
|
||||||
if Config.Get("features.office.can_download").Bool() {
|
if can_download() {
|
||||||
return "true"
|
return "true"
|
||||||
}
|
}
|
||||||
return "false"
|
return "false"
|
||||||
|
|||||||
@ -8,11 +8,6 @@ import (
|
|||||||
_ "embed"
|
_ "embed"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/creack/pty"
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"github.com/gorilla/websocket"
|
|
||||||
. "github.com/mickael-kerjean/filestash/server/common"
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -21,6 +16,13 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
|
|
||||||
|
"github.com/creack/pty"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed src/app.css
|
//go:embed src/app.css
|
||||||
@ -47,11 +49,11 @@ var console_enable = func() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
console_enable()
|
Hooks.Register.Onload(func() {
|
||||||
Hooks.Register.HttpEndpoint(func(r *mux.Router, _ *App) error {
|
|
||||||
if console_enable() == false {
|
if console_enable() == false {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
Hooks.Register.HttpEndpoint(func(r *mux.Router, _ *App) error {
|
||||||
r.PathPrefix("/admin/tty/").Handler(
|
r.PathPrefix("/admin/tty/").Handler(
|
||||||
AuthBasic(
|
AuthBasic(
|
||||||
func() (string, string) { return "admin", Config.Get("auth.admin").String() },
|
func() (string, string) { return "admin", Config.Get("auth.admin").String() },
|
||||||
@ -60,6 +62,7 @@ func init() {
|
|||||||
)
|
)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var notAuthorised = func(res http.ResponseWriter, req *http.Request) {
|
var notAuthorised = func(res http.ResponseWriter, req *http.Request) {
|
||||||
|
|||||||
@ -19,8 +19,14 @@ import (
|
|||||||
|
|
||||||
const SYNCTHING_URI = "/admin/syncthing"
|
const SYNCTHING_URI = "/admin/syncthing"
|
||||||
|
|
||||||
|
var (
|
||||||
|
plugin_enable func() bool
|
||||||
|
server_url func() string
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin_enable := Config.Get("features.syncthing.enable").Schema(func(f *FormElement) *FormElement {
|
plugin_enable = func() bool {
|
||||||
|
return Config.Get("features.syncthing.enable").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
f = &FormElement{}
|
f = &FormElement{}
|
||||||
}
|
}
|
||||||
@ -34,7 +40,9 @@ func init() {
|
|||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
}).Bool()
|
}).Bool()
|
||||||
Config.Get("features.syncthing.server_url").Schema(func(f *FormElement) *FormElement {
|
}
|
||||||
|
server_url = func() string {
|
||||||
|
return Config.Get("features.syncthing.server_url").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
f = &FormElement{}
|
f = &FormElement{}
|
||||||
}
|
}
|
||||||
@ -49,10 +57,15 @@ func init() {
|
|||||||
f.Placeholder = fmt.Sprintf("Default: '%s'", u)
|
f.Placeholder = fmt.Sprintf("Default: '%s'", u)
|
||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
|
}).String()
|
||||||
|
}
|
||||||
|
Hooks.Register.Onload(func() {
|
||||||
|
plugin_enable()
|
||||||
|
server_url()
|
||||||
})
|
})
|
||||||
|
|
||||||
Hooks.Register.HttpEndpoint(func(r *mux.Router, _ *App) error {
|
Hooks.Register.HttpEndpoint(func(r *mux.Router, _ *App) error {
|
||||||
if plugin_enable == false {
|
if plugin_enable() == false {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
r.HandleFunc(SYNCTHING_URI, func(res http.ResponseWriter, req *http.Request) {
|
r.HandleFunc(SYNCTHING_URI, func(res http.ResponseWriter, req *http.Request) {
|
||||||
@ -121,7 +134,7 @@ func SyncthingProxyHandler(res http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
return "http"
|
return "http"
|
||||||
}())
|
}())
|
||||||
u, err := url.Parse(Config.Get("features.syncthing.server_url").String())
|
u, err := url.Parse(server_url())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
SendErrorResult(res, err)
|
SendErrorResult(res, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@ -2,15 +2,15 @@ package plg_image_light
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
. "github.com/mickael-kerjean/filestash/server/common"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
|
||||||
|
|
||||||
const ImageCachePath = "data/cache/image/"
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin_enable := func() bool {
|
plugin_enable := func() bool {
|
||||||
@ -25,8 +25,6 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Bool()
|
}).Bool()
|
||||||
}
|
}
|
||||||
plugin_enable()
|
|
||||||
|
|
||||||
thumb_size := func() int {
|
thumb_size := func() int {
|
||||||
return Config.Get("features.image.thumbnail_size").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.image.thumbnail_size").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -41,8 +39,6 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()
|
}).Int()
|
||||||
}
|
}
|
||||||
thumb_size()
|
|
||||||
|
|
||||||
thumb_quality := func() int {
|
thumb_quality := func() int {
|
||||||
return Config.Get("features.image.thumbnail_quality").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.image.thumbnail_quality").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -57,8 +53,6 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()
|
}).Int()
|
||||||
}
|
}
|
||||||
thumb_quality()
|
|
||||||
|
|
||||||
thumb_caching := func() int {
|
thumb_caching := func() int {
|
||||||
return Config.Get("features.image.thumbnail_caching").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.image.thumbnail_caching").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -73,8 +67,6 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()
|
}).Int()
|
||||||
}
|
}
|
||||||
thumb_caching()
|
|
||||||
|
|
||||||
image_quality := func() int {
|
image_quality := func() int {
|
||||||
return Config.Get("features.image.image_quality").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.image.image_quality").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -89,8 +81,6 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()
|
}).Int()
|
||||||
}
|
}
|
||||||
image_quality()
|
|
||||||
|
|
||||||
image_caching := func() int {
|
image_caching := func() int {
|
||||||
return Config.Get("features.image.image_caching").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.image.image_caching").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -105,11 +95,14 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()
|
}).Int()
|
||||||
}
|
}
|
||||||
|
Hooks.Register.Onload(func() {
|
||||||
|
plugin_enable()
|
||||||
|
thumb_size()
|
||||||
|
thumb_quality()
|
||||||
|
thumb_caching()
|
||||||
|
image_quality()
|
||||||
image_caching()
|
image_caching()
|
||||||
|
})
|
||||||
cachePath := GetAbsolutePath(ImageCachePath)
|
|
||||||
os.RemoveAll(cachePath)
|
|
||||||
os.MkdirAll(cachePath, os.ModePerm)
|
|
||||||
|
|
||||||
Hooks.Register.ProcessFileContentBeforeSend(func(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
|
Hooks.Register.ProcessFileContentBeforeSend(func(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
|
||||||
if plugin_enable() == false {
|
if plugin_enable() == false {
|
||||||
@ -134,7 +127,7 @@ func init() {
|
|||||||
/////////////////////////
|
/////////////////////////
|
||||||
// Specify transformation
|
// Specify transformation
|
||||||
transform := &Transform{
|
transform := &Transform{
|
||||||
Input: GetAbsolutePath(ImageCachePath + "imagein_" + QuickString(10)),
|
Input: filepath.Join(GetAbsolutePath(TMP_PATH), "imagein_"+QuickString(10)),
|
||||||
Size: thumb_size(),
|
Size: thumb_size(),
|
||||||
Crop: true,
|
Crop: true,
|
||||||
Quality: thumb_quality(),
|
Quality: thumb_quality(),
|
||||||
|
|||||||
@ -37,7 +37,6 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Bool()
|
}).Bool()
|
||||||
}
|
}
|
||||||
SEARCH_ENABLE()
|
|
||||||
SEARCH_PROCESS_MAX = func() int {
|
SEARCH_PROCESS_MAX = func() int {
|
||||||
return Config.Get("features.search.process_max").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.search.process_max").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -52,7 +51,6 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()
|
}).Int()
|
||||||
}
|
}
|
||||||
SEARCH_PROCESS_MAX()
|
|
||||||
SEARCH_PROCESS_PAR = func() int {
|
SEARCH_PROCESS_PAR = func() int {
|
||||||
return Config.Get("features.search.process_par").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.search.process_par").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -67,7 +65,6 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()
|
}).Int()
|
||||||
}
|
}
|
||||||
SEARCH_PROCESS_PAR()
|
|
||||||
SEARCH_REINDEX = func() int {
|
SEARCH_REINDEX = func() int {
|
||||||
return Config.Get("features.search.reindex_time").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.search.reindex_time").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -82,7 +79,6 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()
|
}).Int()
|
||||||
}
|
}
|
||||||
SEARCH_REINDEX()
|
|
||||||
CYCLE_TIME = func() int {
|
CYCLE_TIME = func() int {
|
||||||
return Config.Get("features.search.cycle_time").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.search.cycle_time").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -97,7 +93,6 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()
|
}).Int()
|
||||||
}
|
}
|
||||||
CYCLE_TIME()
|
|
||||||
MAX_INDEXING_FSIZE = func() int {
|
MAX_INDEXING_FSIZE = func() int {
|
||||||
return Config.Get("features.search.max_size").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.search.max_size").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -112,7 +107,6 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()
|
}).Int()
|
||||||
}
|
}
|
||||||
MAX_INDEXING_FSIZE()
|
|
||||||
INDEXING_EXT = func() string {
|
INDEXING_EXT = func() string {
|
||||||
return Config.Get("features.search.indexer_ext").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.search.indexer_ext").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@ -127,6 +121,14 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).String()
|
}).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Hooks.Register.Onload(func() {
|
||||||
|
SEARCH_ENABLE()
|
||||||
|
SEARCH_PROCESS_MAX()
|
||||||
|
SEARCH_PROCESS_PAR()
|
||||||
|
SEARCH_REINDEX()
|
||||||
|
CYCLE_TIME()
|
||||||
|
MAX_INDEXING_FSIZE()
|
||||||
INDEXING_EXT()
|
INDEXING_EXT()
|
||||||
|
|
||||||
onChange := Config.ListenForChange()
|
onChange := Config.ListenForChange()
|
||||||
@ -155,4 +157,5 @@ func init() {
|
|||||||
for i := 0; i < SEARCH_PROCESS_PAR(); i++ {
|
for i := 0; i < SEARCH_PROCESS_PAR(); i++ {
|
||||||
go runner()
|
go runner()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Int()) * time.Millisecond
|
}).Int()) * time.Millisecond
|
||||||
}
|
}
|
||||||
|
Hooks.Register.Onload(func() {
|
||||||
SEARCH_TIMEOUT()
|
SEARCH_TIMEOUT()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -8,8 +8,12 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
disable_svg func() bool
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
disable_svg := func() bool {
|
disable_svg = func() bool {
|
||||||
return Config.Get("features.protection.disable_svg").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.protection.disable_svg").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
f = &FormElement{}
|
f = &FormElement{}
|
||||||
@ -23,8 +27,10 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Bool()
|
}).Bool()
|
||||||
}
|
}
|
||||||
disable_svg()
|
Hooks.Register.Onload(func() {
|
||||||
|
if disable_svg() == false {
|
||||||
|
return
|
||||||
|
}
|
||||||
Hooks.Register.ProcessFileContentBeforeSend(func(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
|
Hooks.Register.ProcessFileContentBeforeSend(func(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
|
||||||
if GetMimeType(req.URL.Query().Get("path")) != "image/svg+xml" {
|
if GetMimeType(req.URL.Query().Get("path")) != "image/svg+xml" {
|
||||||
return reader, nil
|
return reader, nil
|
||||||
@ -41,4 +47,5 @@ func init() {
|
|||||||
}
|
}
|
||||||
return NewReadCloserFromBytes(txt), nil
|
return NewReadCloserFromBytes(txt), nil
|
||||||
})
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,22 +2,26 @@ package plg_starter_http
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gorilla/mux"
|
|
||||||
. "github.com/mickael-kerjean/filestash/server/common"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
port := Config.Get("general.port").Int()
|
|
||||||
|
|
||||||
Hooks.Register.Starter(func(r *mux.Router) {
|
Hooks.Register.Starter(func(r *mux.Router) {
|
||||||
Log.Info("[http] starting ...")
|
Log.Info("[http] starting ...")
|
||||||
|
port := Config.Get("general.port").Int()
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
Addr: fmt.Sprintf(":%d", port),
|
Addr: fmt.Sprintf(":%d", port),
|
||||||
Handler: r,
|
Handler: r,
|
||||||
}
|
}
|
||||||
go ensureAppHasBooted(fmt.Sprintf("http://127.0.0.1:%d/about", port), fmt.Sprintf("[http] listening on :%d", port))
|
go ensureAppHasBooted(
|
||||||
|
fmt.Sprintf("http://127.0.0.1:%d/about", port),
|
||||||
|
fmt.Sprintf("[http] listening on :%d", port),
|
||||||
|
)
|
||||||
if err := srv.ListenAndServe(); err != nil {
|
if err := srv.ListenAndServe(); err != nil {
|
||||||
Log.Error("error: %v", err)
|
Log.Error("error: %v", err)
|
||||||
return
|
return
|
||||||
|
|||||||
@ -9,26 +9,37 @@ package plg_starter_http2
|
|||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gorilla/mux"
|
|
||||||
. "github.com/mickael-kerjean/filestash/server/common"
|
|
||||||
"github.com/mickael-kerjean/filestash/server/common/ssl"
|
|
||||||
"golang.org/x/crypto/acme/autocert"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
|
"github.com/mickael-kerjean/filestash/server/common/ssl"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"golang.org/x/crypto/acme/autocert"
|
||||||
)
|
)
|
||||||
|
|
||||||
var SSL_PATH string = GetAbsolutePath(CERT_PATH, "ssl")
|
var (
|
||||||
|
SSL_PATH string
|
||||||
|
config_port func() int
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
config_port = func() int {
|
||||||
|
return Config.Get("general.port").Int()
|
||||||
|
}
|
||||||
|
Hooks.Register.Onload(func() {
|
||||||
|
SSL_PATH = filepath.Join(GetAbsolutePath(CERT_PATH), "ssl")
|
||||||
os.MkdirAll(SSL_PATH, os.ModePerm)
|
os.MkdirAll(SSL_PATH, os.ModePerm)
|
||||||
domain := Config.Get("general.host").String()
|
})
|
||||||
|
|
||||||
Hooks.Register.Starter(func(r *mux.Router) {
|
Hooks.Register.Starter(func(r *mux.Router) {
|
||||||
|
domain := Config.Get("general.host").String()
|
||||||
Log.Info("[https] starting ...%s", domain)
|
Log.Info("[https] starting ...%s", domain)
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
Addr: fmt.Sprintf(":https"),
|
Addr: fmt.Sprintf(":%d", config_port()),
|
||||||
Handler: r,
|
Handler: r,
|
||||||
TLSConfig: &DefaultTLSConfig,
|
TLSConfig: &DefaultTLSConfig,
|
||||||
ErrorLog: NewNilLogger(),
|
ErrorLog: NewNilLogger(),
|
||||||
@ -56,14 +67,8 @@ func init() {
|
|||||||
srv.TLSConfig.GetCertificate = mngr.GetCertificate
|
srv.TLSConfig.GetCertificate = mngr.GetCertificate
|
||||||
}
|
}
|
||||||
|
|
||||||
go ensureAppHasBooted("https://127.0.0.1/about", fmt.Sprintf("[https] started"))
|
|
||||||
go func() {
|
go func() {
|
||||||
if err := srv.ListenAndServeTLS("", ""); err != nil {
|
srv = &http.Server{
|
||||||
Log.Error("[https]: listen_serve %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
srv := http.Server{
|
|
||||||
Addr: fmt.Sprintf(":http"),
|
Addr: fmt.Sprintf(":http"),
|
||||||
ReadTimeout: 5 * time.Second,
|
ReadTimeout: 5 * time.Second,
|
||||||
WriteTimeout: 5 * time.Second,
|
WriteTimeout: 5 * time.Second,
|
||||||
@ -78,7 +83,16 @@ func init() {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
if err := srv.ListenAndServe(); err != nil {
|
if err := srv.ListenAndServe(); err != nil {
|
||||||
Log.Error("[https]: http_redirect %v", err)
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
go ensureAppHasBooted(
|
||||||
|
fmt.Sprintf("https://127.0.0.1:%d/about", config_port()),
|
||||||
|
fmt.Sprintf("[https] started"),
|
||||||
|
)
|
||||||
|
if err := srv.ListenAndServeTLS("", ""); err != nil {
|
||||||
|
Log.Error("[https]: listen_serve %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -11,10 +11,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
Hooks.Register.Starter(func(r *mux.Router) {
|
||||||
domain := Config.Get("general.host").String()
|
domain := Config.Get("general.host").String()
|
||||||
port := Config.Get("general.port").Int()
|
port := Config.Get("general.port").Int()
|
||||||
|
|
||||||
Hooks.Register.Starter(func(r *mux.Router) {
|
|
||||||
Log.Info("[https] starting ...%s", domain)
|
Log.Info("[https] starting ...%s", domain)
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
Addr: fmt.Sprintf(":%d", port),
|
Addr: fmt.Sprintf(":%d", port),
|
||||||
|
|||||||
@ -7,15 +7,16 @@ import (
|
|||||||
. "github.com/mickael-kerjean/filestash/server/common"
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var TOR_PATH string = GetAbsolutePath(CERT_PATH, "tor")
|
var (
|
||||||
|
enable_plugin func() bool
|
||||||
|
tor_url func() string
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
os.MkdirAll(TOR_PATH, os.ModePerm)
|
enable_plugin = func() bool {
|
||||||
enable_tor := func() bool {
|
|
||||||
return Config.Get("features.server.tor_enable").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.server.tor_enable").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
f = &FormElement{}
|
f = &FormElement{}
|
||||||
@ -29,8 +30,8 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Bool()
|
}).Bool()
|
||||||
}
|
}
|
||||||
enable_tor()
|
tor_url = func() string {
|
||||||
Config.Get("features.server.tor_url").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.server.tor_url").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
f = &FormElement{}
|
f = &FormElement{}
|
||||||
}
|
}
|
||||||
@ -42,16 +43,24 @@ func init() {
|
|||||||
f.ReadOnly = true
|
f.ReadOnly = true
|
||||||
f.Placeholder = "LOADING... Refresh the page in a few seconds"
|
f.Placeholder = "LOADING... Refresh the page in a few seconds"
|
||||||
return f
|
return f
|
||||||
})
|
}).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
Hooks.Register.Onload(func() {
|
||||||
|
tor_url()
|
||||||
|
enable_plugin()
|
||||||
|
})
|
||||||
Hooks.Register.Starter(func(r *mux.Router) {
|
Hooks.Register.Starter(func(r *mux.Router) {
|
||||||
if enable_tor() == false {
|
torPath := GetAbsolutePath(CERT_PATH, "tor")
|
||||||
|
os.MkdirAll(torPath, os.ModePerm)
|
||||||
|
|
||||||
|
if enable_plugin() == false {
|
||||||
startTor := false
|
startTor := false
|
||||||
onChange := Config.ListenForChange()
|
onChange := Config.ListenForChange()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-onChange.Listener:
|
case <-onChange.Listener:
|
||||||
startTor = enable_tor()
|
startTor = enable_plugin()
|
||||||
}
|
}
|
||||||
if startTor == true {
|
if startTor == true {
|
||||||
break
|
break
|
||||||
@ -62,7 +71,7 @@ func init() {
|
|||||||
|
|
||||||
Log.Info("[tor] starting ...")
|
Log.Info("[tor] starting ...")
|
||||||
t, err := tor.Start(nil, &tor.StartConf{
|
t, err := tor.Start(nil, &tor.StartConf{
|
||||||
DataDir: TOR_PATH,
|
DataDir: torPath,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Log.Error("[tor] Unable to start Tor: %v", err)
|
Log.Error("[tor] Unable to start Tor: %v", err)
|
||||||
|
|||||||
@ -2,8 +2,10 @@ package plg_video_transcoder
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
@ -20,11 +22,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
HLS_SEGMENT_LENGTH = 30
|
HLS_SEGMENT_LENGTH = 5
|
||||||
|
FPS = 30
|
||||||
CLEAR_CACHE_AFTER = 12
|
CLEAR_CACHE_AFTER = 12
|
||||||
VideoCachePath = "data/cache/video/"
|
VideoCachePath = "data/cache/video/"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
plugin_enable func() bool
|
||||||
|
blacklist_format func() string
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
ffmpegIsInstalled := false
|
ffmpegIsInstalled := false
|
||||||
ffprobeIsInstalled := false
|
ffprobeIsInstalled := false
|
||||||
@ -34,7 +42,7 @@ func init() {
|
|||||||
if _, err := exec.LookPath("ffprobe"); err == nil {
|
if _, err := exec.LookPath("ffprobe"); err == nil {
|
||||||
ffprobeIsInstalled = true
|
ffprobeIsInstalled = true
|
||||||
}
|
}
|
||||||
plugin_enable := func() bool {
|
plugin_enable = func() bool {
|
||||||
return Config.Get("features.video.enable_transcoder").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.video.enable_transcoder").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
f = &FormElement{}
|
f = &FormElement{}
|
||||||
@ -50,8 +58,7 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).Bool()
|
}).Bool()
|
||||||
}
|
}
|
||||||
|
blacklist_format = func() string {
|
||||||
blacklist_format := func() string {
|
|
||||||
return Config.Get("features.video.blacklist_format").Schema(func(f *FormElement) *FormElement {
|
return Config.Get("features.video.blacklist_format").Schema(func(f *FormElement) *FormElement {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
f = &FormElement{}
|
f = &FormElement{}
|
||||||
@ -67,8 +74,9 @@ func init() {
|
|||||||
return f
|
return f
|
||||||
}).String()
|
}).String()
|
||||||
}
|
}
|
||||||
blacklist_format()
|
|
||||||
|
|
||||||
|
Hooks.Register.Onload(func() {
|
||||||
|
blacklist_format()
|
||||||
if plugin_enable() == false {
|
if plugin_enable() == false {
|
||||||
return
|
return
|
||||||
} else if ffmpegIsInstalled == false {
|
} else if ffmpegIsInstalled == false {
|
||||||
@ -112,6 +120,7 @@ func init() {
|
|||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func hls_playlist(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
|
func hls_playlist(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user