forked from DusteDdk/dstream
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserver.js
145 lines (128 loc) · 4.05 KB
/
server.js
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
const compression = require("compression");
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(compression({ level: 7 }));
app.use(bodyParser.json());
const port = 3000;
const spawn = require("child_process").spawn;
const sqlite3 = require("sqlite3");
const db = new sqlite3.Database("db/metadata.sqlite");
db.serialize(() => {
db.run(
"CREATE TABLE IF NOT EXISTS track (id INTEGER PRIMARY KEY AUTOINCREMENT, file TEXT UNIQUE, artist INTEGER, album INTEGER, title TEXT, genre TEXT, lossless INTEGER, codec TEXT, bitrate INTEGER, duration REAL, track INTEGER, disk INTEGER, year INTEGER)"
);
db.run("CREATE INDEX IF NOT EXISTS trackIdx ON track (file, title, year)");
db.run(
"CREATE TABLE IF NOT EXISTS artist (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE)"
);
db.run("CREATE INDEX IF NOT EXISTS artIdx ON artist (name)");
db.run('INSERT OR IGNORE INTO artist (name) VALUES ("-")');
db.run(
"CREATE TABLE IF NOT EXISTS album (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, uniqname UNIQUE)"
);
db.run("CREATE INDEX IF NOT EXISTS alIdx ON album (name)");
db.run('INSERT OR IGNORE INTO album (name) VALUES("-")');
});
app.use("/music/", express.static("music"));
app.use("/", express.static("html/"));
app.use("/random.json", (req, res) => {
const data = [];
db.each(
"SELECT year, duration,codec, file, title, artist.name AS artistName, album.name AS albumName FROM track INNER JOIN artist ON artist.id=track.artist INNER JOIN album ON album.id=track.album ORDER BY RANDOM() LIMIT 25",
[],
(err, row) => {
if (err) {
console.log(err);
}
data.push(row);
},
() => {
return res.send(data);
}
);
});
app.use("/tracks.json", (req, res) => {
const data = [];
const query = req.query.q.split(" ");
const likes = query
.map(() => {
return " file LIKE ?";
})
.join(" AND ");
const qargs = query.map((e) => "%" + e + "%");
db.each(
"SELECT track.id as id, year, duration,codec, file, title, artist.name AS artistName, album.name AS albumName FROM track INNER JOIN artist ON artist.id=track.artist INNER JOIN album ON album.id=track.album WHERE" +
likes +
" LIMIT 5000",
qargs,
(err, row) => {
if (err) {
console.log(err);
}
data.push(row);
},
() => {
return res.send(data);
}
);
});
app.use("/browse.json", (req, res) => {
const data = [];
const offset = parseInt(req.query.p);
db.each(
"SELECT year, duration,codec, file, title, artist.name AS artistName, album.name AS albumName FROM track INNER JOIN artist ON artist.id=track.artist INNER JOIN album ON album.id=track.album LIMIT ?, 30",
[offset],
(err, row) => {
if (err) {
console.log(err);
}
data.push(row);
},
() => {
return res.send(data);
}
);
});
app.listen(port, () => {
console.log(`Server listening at on port ${port}`);
});
let scanner = null;
let lastScanIo = "No scans started..";
app.use("/scan", (req, res) => {
const query = req.query;
if (query.start) {
if (scanner) {
return res.send("Already scanning!");
}
scanner = spawn("node", ["./scanner.js"]);
lastScanIo = new Date() + " Started scanning...\n";
scanner.stdout.on("data", (data) => {
lastScanIo += data.toString();
});
scanner.stderr.on("data", (data) => {
lastScanIo += data.toString();
});
scanner.on("close", (code) => {
lastScanIo += "\nScan ended: " + new Date() + " with code: " + code;
scanner = null;
});
}
db.each("SELECT COUNT(*) as numTracks FROM track", [], (err, row) => {
if (!err && row) {
res.send(
(
row.numTracks +
" tracks in db.\n" +
(!scanner
? '<a href="/scan?start=true">Scan library</a>'
: '<a href="/scan">Refresh</a>') +
'\n<a href="/">Back to player</a>\n' +
lastScanIo
).replace(/\n/g, "<br>")
);
} else {
res.send("Error:" + err.message);
}
});
});