museria 0.2.49 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +10 -2
- package/.github/workflows/build.yml +3 -3
- package/.github/workflows/publish.yml +3 -3
- package/README.md +55 -59
- package/bin/actions.js +28 -28
- package/bin/index.js +4 -4
- package/bin/runner.js +1 -1
- package/bin/utils.js +6 -2
- package/dist/client/museria.client.js +7 -7
- package/dist/face/45a265d0f07b31cde85f.ttf +0 -0
- package/dist/face/6205fd00fb1b573e9f0f.ttf +0 -0
- package/dist/face/8d3cabfc66809162fb4d.woff2 +0 -0
- package/dist/face/fb8184add5a3101ad0a3.woff2 +0 -0
- package/dist/face/museria.face.js +33 -13
- package/dist/face/style.css +13 -11
- package/package.json +41 -40
- package/src/browser/client/index.js +2 -1
- package/src/browser/face/client.js +2 -1
- package/src/browser/face/controllers/app/app.html +77 -69
- package/src/browser/face/controllers/app/app.js +14 -7
- package/src/browser/face/controllers/app/app.scss +2 -22
- package/src/browser/face/index.js +3 -3
- package/src/browser/face/styles/main.scss +91 -11
- package/src/browser/face/styles/vars.scss +0 -1
- package/src/client.js +73 -74
- package/src/collection/transports/music/index.js +20 -18
- package/src/db/transports/database/index.js +7 -5
- package/src/db/transports/loki/index.js +30 -25
- package/src/errors.js +2 -1
- package/src/index.js +8 -6
- package/src/node.js +312 -323
- package/src/schema.js +27 -29
- package/src/server/transports/express/api/butler/controllers.js +7 -10
- package/src/server/transports/express/api/butler/routes.js +5 -5
- package/src/server/transports/express/api/master/controllers.js +7 -10
- package/src/server/transports/express/api/master/routes.js +5 -5
- package/src/server/transports/express/api/node/controllers.js +52 -61
- package/src/server/transports/express/api/node/routes.js +10 -10
- package/src/server/transports/express/api/routes.js +1 -1
- package/src/server/transports/express/api/slave/controllers.js +7 -10
- package/src/server/transports/express/api/slave/routes.js +6 -6
- package/src/server/transports/express/client/controllers.js +40 -61
- package/src/server/transports/express/client/routes.js +33 -39
- package/src/server/transports/express/controllers.js +10 -21
- package/src/server/transports/express/index.js +23 -20
- package/src/server/transports/express/midds.js +67 -67
- package/src/server/transports/express/routes.js +12 -12
- package/src/utils.js +175 -184
- package/test/client.js +311 -305
- package/test/db/database.js +32 -28
- package/test/db/loki.js +78 -74
- package/test/group.js +161 -156
- package/test/index.js +20 -10
- package/test/node.js +461 -460
- package/test/routes.js +404 -399
- package/test/server/express.js +35 -31
- package/test/services.js +25 -18
- package/test/tools.js +8 -6
- package/test/utils.js +236 -234
- package/webpack.client.js +9 -7
- package/webpack.face.js +8 -6
- package/dist/face/fa-brands-400.eot +0 -0
- package/dist/face/fa-brands-400.svg +0 -3717
- package/dist/face/fa-brands-400.ttf +0 -0
- package/dist/face/fa-brands-400.woff +0 -0
- package/dist/face/fa-brands-400.woff2 +0 -0
- package/dist/face/fa-solid-900.eot +0 -0
- package/dist/face/fa-solid-900.svg +0 -5034
- package/dist/face/fa-solid-900.ttf +0 -0
- package/dist/face/fa-solid-900.woff +0 -0
- package/dist/face/fa-solid-900.woff2 +0 -0
- /package/dist/face/{open-sans.ttf → 17e98b9e5586529b13cc.ttf} +0 -0
- /package/dist/face/{proxima-nova.ttf → 326601dfabd91e3f016c.ttf} +0 -0
- /package/dist/face/{logo.svg → ee9c6af64aa224827cec.svg} +0 -0
@@ -1,11 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
import fse from "fs-extra";
|
2
|
+
import sanitize from "sanitize-filename";
|
3
|
+
import * as transliteration from "transliteration";
|
4
|
+
import errors from "../../../errors.js";
|
5
|
+
import utils from "../../../utils.js";
|
6
|
+
import utilsMetastocle from "metastocle/src/server/transports/express/midds.js";
|
7
|
+
import utilsStoracle from "storacle/src/server/transports/express/midds.js";
|
8
|
+
|
9
|
+
const midds = Object.assign({}, utilsMetastocle, utilsStoracle);
|
9
10
|
|
10
11
|
/**
|
11
12
|
* Song addition control
|
@@ -13,20 +14,20 @@ const midds = Object.assign({}, mtUtils, stUtils);
|
|
13
14
|
midds.songAdditionControl = node => {
|
14
15
|
return async (req, res, next) => {
|
15
16
|
try {
|
16
|
-
if(req.clientAddress != node.address && await node.isAddressTrusted(req.clientAddress)) {
|
17
|
+
if (req.clientAddress != node.address && await node.isAddressTrusted(req.clientAddress)) {
|
17
18
|
return next();
|
18
19
|
}
|
19
|
-
|
20
|
-
if(!req.body.controlled) {
|
20
|
+
|
21
|
+
if (!req.body.controlled) {
|
21
22
|
return next();
|
22
23
|
}
|
23
24
|
|
24
25
|
return midds.approval(node)(req, res, next);
|
25
26
|
}
|
26
|
-
catch(err) {
|
27
|
+
catch (err) {
|
27
28
|
next(err);
|
28
29
|
}
|
29
|
-
}
|
30
|
+
};
|
30
31
|
};
|
31
32
|
|
32
33
|
/**
|
@@ -36,19 +37,19 @@ midds.songRemovalControl = node => {
|
|
36
37
|
return async (req, res, next) => {
|
37
38
|
try {
|
38
39
|
const title = req.body.title;
|
39
|
-
node.songTitleTest(title);
|
40
|
+
node.songTitleTest(title);
|
40
41
|
req.document = await node.db.getMusicByPk(title);
|
41
|
-
|
42
|
-
if(!req.document || req.document.priority < 1) {
|
42
|
+
|
43
|
+
if (!req.document || req.document.priority < 1) {
|
43
44
|
return next();
|
44
45
|
}
|
45
|
-
|
46
|
+
|
46
47
|
return midds.approval(node)(req, res, next);
|
47
48
|
}
|
48
|
-
catch(err) {
|
49
|
+
catch (err) {
|
49
50
|
next(err);
|
50
51
|
}
|
51
|
-
}
|
52
|
+
};
|
52
53
|
};
|
53
54
|
|
54
55
|
/**
|
@@ -58,26 +59,26 @@ midds.fileAccess = node => {
|
|
58
59
|
return async (req, res, next) => {
|
59
60
|
try {
|
60
61
|
let doc;
|
61
|
-
|
62
|
-
if(req.query.f) {
|
62
|
+
|
63
|
+
if (req.query.f) {
|
63
64
|
const fileHash = String(req.query.f);
|
64
65
|
doc = await node.db.getMusicByFileHash(fileHash);
|
65
66
|
}
|
66
67
|
|
67
|
-
if(!doc) {
|
68
|
+
if (!doc) {
|
68
69
|
const titleHash = String(req.params.hash).split('.')[0];
|
69
|
-
const title = utils.decodeSongTitle(titleHash);
|
70
|
+
const title = utils.decodeSongTitle(titleHash);
|
70
71
|
doc = await node.db.getMusicByPk(title);
|
71
72
|
}
|
72
|
-
|
73
|
+
|
73
74
|
doc && await node.db.accessDocument(doc);
|
74
75
|
req.document = doc;
|
75
76
|
next();
|
76
77
|
}
|
77
|
-
catch(err) {
|
78
|
+
catch (err) {
|
78
79
|
next(err);
|
79
80
|
}
|
80
|
-
}
|
81
|
+
};
|
81
82
|
};
|
82
83
|
|
83
84
|
/**
|
@@ -85,57 +86,57 @@ midds.fileAccess = node => {
|
|
85
86
|
*/
|
86
87
|
midds.audio = node => {
|
87
88
|
return async (req, res, next) => {
|
88
|
-
try {
|
89
|
-
const err404 = new errors.NotFoundError('File not found');
|
89
|
+
try {
|
90
|
+
const err404 = new errors.NotFoundError('File not found');
|
90
91
|
|
91
|
-
if(!req.document) {
|
92
|
+
if (!req.document) {
|
92
93
|
throw err404;
|
93
|
-
}
|
94
|
-
|
94
|
+
}
|
95
|
+
|
95
96
|
const hash = req.document.fileHash;
|
96
97
|
|
97
|
-
if(!await node.hasFile(hash)) {
|
98
|
+
if (!await node.hasFile(hash)) {
|
98
99
|
throw err404;
|
99
100
|
}
|
100
|
-
|
101
|
-
if(req.headers['storacle-cache-check']) {
|
102
|
-
return hash == req.query.f? res.send(''): next(err404);
|
101
|
+
|
102
|
+
if (req.headers['storacle-cache-check']) {
|
103
|
+
return hash == req.query.f ? res.send('') : next(err404);
|
103
104
|
}
|
104
105
|
|
105
106
|
const cache = Math.ceil(node.options.file.responseCacheLifetime / 1000);
|
106
107
|
const filePath = node.getFilePath(hash);
|
107
|
-
const info = await utils.getFileInfo(filePath, { hash: false });
|
108
|
+
const info = await utils.getFileInfo(filePath, { hash: false });
|
108
109
|
const filename = sanitize(transliteration.transliterate(req.document.title));
|
109
110
|
const range = String(req.headers.range);
|
110
111
|
cache && res.set('Cache-Control', `public, max-age=${cache}`);
|
111
112
|
info.mime && res.setHeader('Content-Type', info.mime);
|
112
|
-
res.setHeader('Content-Disposition', `inline; filename="${
|
113
|
+
res.setHeader('Content-Disposition', `inline; filename="${filename}.${info.ext || 'mp3'}"`);
|
113
114
|
|
114
115
|
if (range.match('bytes=')) {
|
115
116
|
const maxEnd = info.size - 1;
|
116
117
|
const parts = range.replace(/bytes=/, '').split('-');
|
117
|
-
let start = parseInt(parts[0], 10) || 0;
|
118
|
-
let end = parts[1]? parseInt(parts[1], 10): maxEnd;
|
118
|
+
let start = parseInt(parts[0], 10) || 0;
|
119
|
+
let end = parts[1] ? parseInt(parts[1], 10) : maxEnd;
|
119
120
|
start > maxEnd && (start = maxEnd);
|
120
121
|
end > maxEnd && (end = maxEnd);
|
121
122
|
const chunkSize = (end - start) + 1;
|
122
|
-
const stream =
|
123
|
-
res.setHeader("Content-Range", `bytes ${
|
123
|
+
const stream = fse.createReadStream(filePath, { start, end });
|
124
|
+
res.setHeader("Content-Range", `bytes ${start}-${end}/${info.size}`);
|
124
125
|
res.setHeader("Accept-Ranges", 'bytes');
|
125
126
|
res.setHeader("Content-Length", chunkSize);
|
126
127
|
res.status(206);
|
127
128
|
stream.on('error', next).pipe(res);
|
128
129
|
return;
|
129
|
-
}
|
130
|
-
|
130
|
+
}
|
131
|
+
|
131
132
|
res.setHeader("Content-Length", info.size);
|
132
|
-
const stream =
|
133
|
+
const stream = fse.createReadStream(filePath);
|
133
134
|
stream.on('error', next).pipe(res);
|
134
135
|
}
|
135
|
-
catch(err) {
|
136
|
+
catch (err) {
|
136
137
|
next(err);
|
137
138
|
}
|
138
|
-
}
|
139
|
+
};
|
139
140
|
};
|
140
141
|
|
141
142
|
/**
|
@@ -143,57 +144,56 @@ midds.audio = node => {
|
|
143
144
|
*/
|
144
145
|
midds.cover = node => {
|
145
146
|
return async (req, res, next) => {
|
146
|
-
try {
|
147
|
+
try {
|
147
148
|
const err404 = new errors.NotFoundError('File not found');
|
148
|
-
|
149
|
-
if(!req.document) {
|
149
|
+
|
150
|
+
if (!req.document) {
|
150
151
|
throw err404;
|
151
152
|
}
|
152
|
-
|
153
|
+
|
153
154
|
const hash = req.document.fileHash;
|
154
|
-
const filePath = node.getFilePath(hash);
|
155
|
+
const filePath = node.getFilePath(hash);
|
155
156
|
const tags = await utils.getSongTags(filePath);
|
156
157
|
|
157
|
-
if(!tags.APIC) {
|
158
|
+
if (!tags.APIC) {
|
158
159
|
throw err404;
|
159
160
|
}
|
160
161
|
|
161
|
-
if(req.headers['storacle-cache-check']) {
|
162
|
-
return hash == req.query.f? res.send(''): next(err404);
|
162
|
+
if (req.headers['storacle-cache-check']) {
|
163
|
+
return hash == req.query.f ? res.send('') : next(err404);
|
163
164
|
}
|
164
|
-
|
165
|
-
const cache = Math.ceil(node.options.file.responseCacheLifetime / 1000);
|
165
|
+
|
166
|
+
const cache = Math.ceil(node.options.file.responseCacheLifetime / 1000);
|
166
167
|
const info = await utils.getFileInfo(tags.APIC, { hash: false });
|
167
|
-
const filename = sanitize(transliteration.transliterate(req.document.title));
|
168
|
-
info.mime && res.setHeader("Content-Type", info.mime);
|
169
|
-
res.setHeader('Content-Disposition', `inline; filename="${
|
168
|
+
const filename = sanitize(transliteration.transliterate(req.document.title));
|
169
|
+
info.mime && res.setHeader("Content-Type", info.mime);
|
170
|
+
res.setHeader('Content-Disposition', `inline; filename="${filename}.${info.ext || 'jpg'}"`);
|
170
171
|
cache && res.set('Cache-Control', `public, max-age=${cache}`);
|
171
172
|
res.setHeader("Content-Length", info.size);
|
172
173
|
res.end(tags.APIC, 'binary');
|
173
174
|
}
|
174
|
-
catch(err) {
|
175
|
+
catch (err) {
|
175
176
|
next(err);
|
176
177
|
}
|
177
|
-
}
|
178
|
+
};
|
178
179
|
};
|
179
|
-
|
180
180
|
/**
|
181
181
|
* Control song requests limit by a title and hash
|
182
182
|
*/
|
183
183
|
midds.requestQueueSong = (node) => {
|
184
184
|
return async (req, res, next) => {
|
185
185
|
const options = { limit: 1, fnHash: key => key };
|
186
|
-
const title = String(req.query.title? req.query.title: req.body.title);
|
186
|
+
const title = String(req.query.title ? req.query.title : req.body.title);
|
187
187
|
const arr = [title];
|
188
188
|
|
189
|
-
for(let key in node.__requestQueue) {
|
190
|
-
if(utils.getSongSimilarity(key, title) >= node.options.music.similarity) {
|
189
|
+
for (let key in node.__requestQueue) {
|
190
|
+
if (utils.getSongSimilarity(key, title) >= node.options.music.similarity) {
|
191
191
|
arr.push(key);
|
192
192
|
}
|
193
193
|
}
|
194
194
|
|
195
195
|
return midds.requestQueue(node, arr, options)(req, res, next);
|
196
|
-
}
|
196
|
+
};
|
197
197
|
};
|
198
198
|
|
199
|
-
|
199
|
+
export default midds;
|
@@ -1,23 +1,23 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
import midds from "./midds.js";
|
2
|
+
import * as controllers from "./controllers.js";
|
3
3
|
|
4
|
-
|
4
|
+
export default [
|
5
5
|
{ name: 'favicon', fn: controllers.favicon },
|
6
6
|
{ name: 'static', url: '/', fn: controllers.static },
|
7
|
-
{
|
8
|
-
name: 'audio',
|
9
|
-
method: 'get',
|
10
|
-
url: '/audio/:hash',
|
7
|
+
{
|
8
|
+
name: 'audio',
|
9
|
+
method: 'get',
|
10
|
+
url: '/audio/:hash',
|
11
11
|
fn: [
|
12
12
|
midds.networkAccess,
|
13
13
|
midds.fileAccess,
|
14
14
|
midds.audio
|
15
15
|
]
|
16
16
|
},
|
17
|
-
{
|
18
|
-
name: 'cover',
|
19
|
-
method: 'get',
|
20
|
-
url: '/cover/:hash',
|
17
|
+
{
|
18
|
+
name: 'cover',
|
19
|
+
method: 'get',
|
20
|
+
url: '/cover/:hash',
|
21
21
|
fn: [
|
22
22
|
midds.networkAccess,
|
23
23
|
midds.fileAccess,
|
@@ -25,4 +25,4 @@ module.exports = [
|
|
25
25
|
]
|
26
26
|
},
|
27
27
|
{ name: 'indexPage', method: 'get', url: '*', fn: [midds.networkAccess, controllers.indexPage] }
|
28
|
-
];
|
28
|
+
];
|