-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
99 lines (89 loc) · 2.74 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main
import (
"encoding/base64"
"flag"
"log"
"os"
"strings"
)
const (
uiAddress = ":61337"
contentTypeHeader = "Content-Type"
jsonMime = "application/json"
mp3Mime = "audio/mpeg"
m4aMime = "audio/mp4"
flacMime = "audio/flac"
backupMime = "application/octet-stream"
minParallel = 1
maxParallel = 64
)
func main() {
var (
root string
parallel int
gui bool
address string
db string
doRescanDb bool
mobile string
doSyncMobile bool
)
flag.StringVar(&root, "root", "", "root music library folder")
flag.IntVar(¶llel, "p", 1, "parallelism of library loading")
flag.BoolVar(&gui, "gui", true, "enable web gui")
flag.StringVar(&address, "address", uiAddress, "address to listen to for rest api and gui")
flag.StringVar(&db, "database", "", "location of database file, default is no persistence")
flag.BoolVar(&doRescanDb, "rescan-database", false, "if true, rescans existing database")
flag.StringVar(&mobile, "mobile", "", "optional mobile music library folder")
flag.BoolVar(&doSyncMobile, "sync-mobile", false, "run mobile library sync")
flag.Parse()
if len(root) == 0 {
panic("Must provide --root argument for music library root folder")
}
if parallel < minParallel {
parallel = minParallel
} else if parallel > maxParallel {
parallel = maxParallel
}
loadLog := log.New(os.Stdout, "[load] ", log.LstdFlags|log.Lmicroseconds)
lib := loadLibrary(loadLibraryArgs{
root: root,
parallel: parallel,
logger: loadLog,
db: db,
rescan: doRescanDb,
})
aad := ArtistAblumDateCollection(lib, loadLog)
loadLog.Println("================================")
if "" != mobile {
loadLog.Println("mobile library:", mobile)
if doSyncMobile {
loadLog.Print(mobileSyncWarning)
forbidErr(syncMobile(ensurePathSep(root), lib, ensurePathSep(mobile)))
return
}
}
loadLog.Println("================================")
server := buildServer(aad, lib, gui)
server.Addr = address
logAddress := address
if strings.HasPrefix(logAddress, ":") {
logAddress = "localhost" + logAddress
}
loadLog.Printf("Serving UI on http://%v\n", logAddress)
forbidErr(server.ListenAndServe())
}
// Don't use this on user error, use 4XX HTTP codes instead.
// Don't use this for ordinary or exceptional errors, use errors and 5xx HTTP codes instead.
// This is fine for things that should be absolutely impossible (server bugs).
func forbidErr(err error) {
if err != nil {
log.Println("forbidden error!", err)
panic(err)
}
}
// converts a byte slice into an url safe base64 string without padding
func bytesToString(data []byte) string {
hash64 := base64.URLEncoding.EncodeToString(data)
return strings.Replace(hash64, "=", "", -1)
}