museria 0.2.40 → 0.2.44
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/README.md +0 -2
- package/dist/client/museria.client.js +4 -4
- package/dist/face/museria.face.js +8 -8
- package/dist/face/style.css +5 -5
- package/package.json +7 -7
- package/src/browser/face/controllers/app/app.html +1 -1
- package/src/browser/face/controllers/app/app.js +1 -1
- package/src/node.js +14 -10
- package/src/server/transports/express/client/controllers.js +1 -1
- package/src/server/transports/express/midds.js +1 -1
- package/src/utils.js +22 -13
- package/test/node.js +5 -9
- package/test/utils.js +4 -5
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "museria",
|
3
|
-
"version": "0.2.
|
3
|
+
"version": "0.2.44",
|
4
4
|
"description": "Decentralized music storage",
|
5
5
|
"main": "./src/index.js",
|
6
6
|
"bin": {
|
@@ -13,7 +13,7 @@
|
|
13
13
|
"homepage": "https://github.com/ortexx/museria",
|
14
14
|
"scripts": {
|
15
15
|
"eslint": "eslint src bin test",
|
16
|
-
"test": "mocha ./test/index.js --timeout=
|
16
|
+
"test": "mocha ./test/index.js --timeout=30000",
|
17
17
|
"build-client": "webpack --config=webpack.client.js",
|
18
18
|
"build-client-prod": "cross-env NODE_ENV=production webpack --config=webpack.client.js",
|
19
19
|
"build-face": "webpack --config=webpack.face.js",
|
@@ -59,7 +59,7 @@
|
|
59
59
|
"mini-css-extract-plugin": "^1.3.9",
|
60
60
|
"mocha": "^9.1.3",
|
61
61
|
"node-polyfill-webpack-plugin": "^1.0.3",
|
62
|
-
"resolve-url-loader": "^
|
62
|
+
"resolve-url-loader": "^5.0.0",
|
63
63
|
"sass": "^1.43.4",
|
64
64
|
"sass-loader": "^12.3.0",
|
65
65
|
"terser-webpack-plugin": "^5.0.0",
|
@@ -77,16 +77,16 @@
|
|
77
77
|
"express": "^4.17.1",
|
78
78
|
"fs-extra": "^9.0.1",
|
79
79
|
"lodash": "^4.17.20",
|
80
|
-
"metastocle": "^0.2.
|
80
|
+
"metastocle": "^0.2.29",
|
81
81
|
"music-metadata": "^6.4.0",
|
82
82
|
"node-fetch": "^2.6.1",
|
83
83
|
"node-id3": "^0.2.2",
|
84
84
|
"sanitize-filename": "^1.6.3",
|
85
85
|
"serve-favicon": "^2.5.0",
|
86
|
-
"sharp": "^0.
|
86
|
+
"sharp": "^0.29.3",
|
87
87
|
"splaytree": "^3.1.0",
|
88
|
-
"spreadable": "^0.2.
|
89
|
-
"storacle": "^0.2.
|
88
|
+
"spreadable": "^0.2.25",
|
89
|
+
"storacle": "^0.2.25",
|
90
90
|
"transliteration": "^2.2.0"
|
91
91
|
},
|
92
92
|
"repository": {
|
@@ -49,7 +49,7 @@
|
|
49
49
|
</if>
|
50
50
|
<header class="header row">
|
51
51
|
<div class="songs-counter-text">
|
52
|
-
There ${this.songsCount == 1? 'is': 'are'} <b>${ this.songsCount }</b> song${this.songsCount == 1? '': 's'} on the network
|
52
|
+
There ${this.songsCount == 1? 'is': 'are'} <b>${ Number(this.songsCount).toLocaleString() }</b> song${this.songsCount == 1? '': 's'} on the network
|
53
53
|
</div>
|
54
54
|
<a state="app" class="logo mx-auto px-4">
|
55
55
|
<div>
|
@@ -18,7 +18,7 @@ export default class App extends Akili.Component {
|
|
18
18
|
created() {
|
19
19
|
this.captchaWidth = 240;
|
20
20
|
this.findingSongsLimit = 10;
|
21
|
-
this.songsCountInterval =
|
21
|
+
this.songsCountInterval = 15 * 1000;
|
22
22
|
this.songsCountIntervalObj = null;
|
23
23
|
this.scope.songsCount = 0;
|
24
24
|
this.scope.searchInputValue = this.transition.query.f;
|
package/src/node.js
CHANGED
@@ -78,8 +78,7 @@ module.exports = (Parent) => {
|
|
78
78
|
]
|
79
79
|
},
|
80
80
|
task: {
|
81
|
-
cleanUpMusicInterval: '1m'
|
82
|
-
normalizeSongTitlesInterval: '10m',
|
81
|
+
cleanUpMusicInterval: '1m'
|
83
82
|
}
|
84
83
|
}, options);
|
85
84
|
|
@@ -120,10 +119,6 @@ module.exports = (Parent) => {
|
|
120
119
|
if(this.options.task.cleanUpMusicInterval) {
|
121
120
|
await this.task.add('cleanUpMusic', this.options.task.cleanUpMusicInterval, () => this.cleanUpMusic());
|
122
121
|
}
|
123
|
-
|
124
|
-
if(this.options.task.normalizeSongTitlesInterval) {
|
125
|
-
await this.task.add('normalizeSongTitles', this.options.task.normalizeSongTitlesInterval, () => this.normalizeSongTitles());
|
126
|
-
}
|
127
122
|
}
|
128
123
|
|
129
124
|
/**
|
@@ -133,9 +128,19 @@ module.exports = (Parent) => {
|
|
133
128
|
*/
|
134
129
|
async normalizeSongTitles() {
|
135
130
|
const docs = await this.db.getDocuments('music');
|
131
|
+
const titles = {};
|
132
|
+
|
136
133
|
for(let i = 0; i < docs.length; i++) {
|
137
134
|
const doc = docs[i];
|
138
|
-
|
135
|
+
const title = utils.beautifySongTitle(doc.title);
|
136
|
+
|
137
|
+
if(titles[title] && titles[title] != doc.$loki) {
|
138
|
+
await this.db.deleteDocument(doc);
|
139
|
+
continue;
|
140
|
+
}
|
141
|
+
|
142
|
+
doc.title = title;
|
143
|
+
titles[title] = doc.$loki;
|
139
144
|
await this.db.updateMusicDocument(doc, { beautify: false });
|
140
145
|
}
|
141
146
|
}
|
@@ -421,8 +426,7 @@ module.exports = (Parent) => {
|
|
421
426
|
* @returns {object[]}
|
422
427
|
*/
|
423
428
|
async getSongInfo(title, options = {}) {
|
424
|
-
title = utils.
|
425
|
-
this.songTitleTest(title);
|
429
|
+
title = utils.prepareComparisonSongTitle(title);
|
426
430
|
const collection = await this.getCollection('music');
|
427
431
|
const actions = utils.prepareDocumentGettingActions({
|
428
432
|
offset: 0,
|
@@ -467,7 +471,7 @@ module.exports = (Parent) => {
|
|
467
471
|
* @returns {object[]}
|
468
472
|
*/
|
469
473
|
async findSongs(str, options = {}) {
|
470
|
-
const title = utils.
|
474
|
+
const title = utils.prepareComparisonSongTitle(str);
|
471
475
|
str = utils.prepareSongFindingString(str);
|
472
476
|
|
473
477
|
if(str.length < this.options.music.findingStringMinLength) {
|
package/src/utils.js
CHANGED
@@ -9,7 +9,7 @@ const mm = require('music-metadata');
|
|
9
9
|
const base64url = require('base64url');
|
10
10
|
|
11
11
|
utils.regexSongLinks = /(([a-z]+:\/\/)?[-\p{L}\p{N}]+\.[\p{L}]{2,}|[a-z]+:\/\/(\[:*[\w\d]+:[\w\d:]+\]|\d+\.[\d.]+))\S*/igu;
|
12
|
-
utils.regexSongFeats = /[([\s]+((ft
|
12
|
+
utils.regexSongFeats = /[([\s]+((ft\.|feat\.)[\s]+((?!(\s+[-([)\]]+))[^)\]])+)\s*[)\]]*([\s]+[-([]+|$)/iu;
|
13
13
|
|
14
14
|
utils.heritableSongTags = [
|
15
15
|
'TALB', 'TCOM', 'TCON', 'TCOP', 'TDAT', 'TEXT', 'TIT1', 'TIT3', 'TLAN',
|
@@ -37,7 +37,7 @@ utils.MusicDocumentsHandler = class extends utils.DocumentsHandler {
|
|
37
37
|
|
38
38
|
return this.$ilk(value, filter);
|
39
39
|
}
|
40
|
-
|
40
|
+
}
|
41
41
|
|
42
42
|
/**
|
43
43
|
* @see stUtils.getFileInfo
|
@@ -125,11 +125,20 @@ utils.beautifySongTitle = function (title) {
|
|
125
125
|
.replace(/[\sᅠ]+/g, ' ')
|
126
126
|
.replace(/([([])\s+/g, '$1')
|
127
127
|
.replace(/\s+([)\]])/g, '$1')
|
128
|
+
.replace(/([([]+)(featuring|feat|ft)(\s)/ig, '$1feat.$3')
|
129
|
+
.replace(/([([\s]+)(feat\.|ft\.)(\s)/ig, '$1feat.$3')
|
128
130
|
.toLowerCase();
|
129
131
|
|
130
132
|
if(!/[^\s]+ - [^\s]+/.test(title)) {
|
131
133
|
return '';
|
132
134
|
}
|
135
|
+
|
136
|
+
const arr = title.split(/\(?feat\./i);
|
137
|
+
|
138
|
+
if(arr.length > 2) {
|
139
|
+
arr.splice(2, arr.length - 2);
|
140
|
+
title = arr.join('(feat.').trim();
|
141
|
+
}
|
133
142
|
|
134
143
|
const sides = this.splitSongTitle(title);
|
135
144
|
let artists = sides[0].split(/,[\s]*/);
|
@@ -139,26 +148,26 @@ utils.beautifySongTitle = function (title) {
|
|
139
148
|
if(!mainArtist) {
|
140
149
|
return '';
|
141
150
|
}
|
142
|
-
|
143
|
-
const match =
|
151
|
+
|
152
|
+
const match = sides[1].match(this.regexSongFeats);
|
144
153
|
let feats = (match? match[1]: '').replace(/,([^\s])/, ', $1').trim();
|
145
154
|
title = `${mainArtist} - ${sides[1]}`;
|
146
|
-
title = title.replace(this.regexSongFeats, '$5');
|
147
|
-
artists = artists.
|
148
|
-
|
155
|
+
title = title.replace(this.regexSongFeats, '$5');
|
156
|
+
feats && (artists = artists.concat(feats.replace(/feat\./i, '').split(',')));
|
157
|
+
artists = [...new Set(artists.map(a => a.trim()).filter(v => v))];
|
158
|
+
|
149
159
|
if(artists.length) {
|
150
|
-
feats =
|
160
|
+
feats = `feat. ${ artists.join(', ') }`;
|
151
161
|
}
|
152
162
|
|
153
163
|
feats && (title += ` (${feats})`);
|
154
|
-
title = title
|
155
|
-
.replace(/([([\s]+)(feat\.?|ft\.?|featuring)(\s)/i, '$1feat.$3')
|
164
|
+
title = title
|
156
165
|
.replace(/\[\]|\(\)/g, '')
|
157
166
|
.replace(/\s+/g, ' ')
|
158
167
|
.split(' ')
|
159
168
|
.map(p => p? (p[0].toUpperCase() + p.slice(1)): p)
|
160
169
|
.join(' ')
|
161
|
-
.trim()
|
170
|
+
.trim();
|
162
171
|
return title;
|
163
172
|
};
|
164
173
|
|
@@ -234,8 +243,8 @@ utils.getSongArtists = function (title, options = {}) {
|
|
234
243
|
const sides = this.splitSongTitle(title);
|
235
244
|
let artists = sides[0].split(/,/);
|
236
245
|
const match = title.match(this.regexSongFeats);
|
237
|
-
let feats = (match? match[1]: '').replace(
|
238
|
-
return artists.concat(feats.split(',')).map(v => v.trim()).filter(v => v);
|
246
|
+
let feats = (match? match[1]: '').replace(/^feat\./i, '');
|
247
|
+
return [...new Set(artists.concat(feats.split(',')).map(v => v.trim()).filter(v => v))];
|
239
248
|
};
|
240
249
|
|
241
250
|
/**
|
package/test/node.js
CHANGED
@@ -108,17 +108,13 @@ describe('Node', () => {
|
|
108
108
|
});
|
109
109
|
|
110
110
|
describe('.getSongInfo()', () => {
|
111
|
-
it('should
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
}
|
116
|
-
catch (err) {
|
117
|
-
assert.isOk(err.message.match('Wrong song title'));
|
118
|
-
}
|
111
|
+
it('should return an empty array with a wrong title', async () => {
|
112
|
+
const title = 'unexistent';
|
113
|
+
const result = await node.getSongInfo(title);
|
114
|
+
assert.lengthOf(result, 0);
|
119
115
|
});
|
120
116
|
|
121
|
-
it('should return an empty array', async () => {
|
117
|
+
it('should return an empty array with a right title', async () => {
|
122
118
|
const title = 'unexistent - unexistent';
|
123
119
|
const result = await node.getSongInfo(title);
|
124
120
|
assert.lengthOf(result, 0);
|
package/test/utils.js
CHANGED
@@ -67,14 +67,13 @@ describe('utils', () => {
|
|
67
67
|
|
68
68
|
it('should place feats together', () => {
|
69
69
|
const res = utils.beautifySongTitle('artist1, artist2,artist3 - title (feat. artist4, artist5,artist6)');
|
70
|
-
assert.equal(res, 'Artist1 - Title (feat.
|
70
|
+
assert.equal(res, 'Artist1 - Title (feat. Artist2, Artist3, Artist4, Artist5, Artist6)');
|
71
71
|
});
|
72
72
|
|
73
73
|
it('should bring all feats to a single form', () => {
|
74
74
|
assert.equal(utils.beautifySongTitle('artist - title (ft. Artist)'), 'Artist - Title (feat. Artist)', 'check "ft"');
|
75
75
|
assert.equal(utils.beautifySongTitle('artist - title (feat. Artist)'), 'Artist - Title (feat. Artist)', 'check "feat"');
|
76
|
-
assert.equal(utils.beautifySongTitle('artist - title
|
77
|
-
assert.equal(utils.beautifySongTitle('artist - title ft Artist'), 'Artist - Title (feat. Artist)', 'check without brackets');
|
76
|
+
assert.equal(utils.beautifySongTitle('artist - title ft. Artist'), 'Artist - Title (feat. Artist)', 'check without brackets');
|
78
77
|
});
|
79
78
|
|
80
79
|
it('should change the dash type', () => {
|
@@ -133,8 +132,8 @@ describe('utils', () => {
|
|
133
132
|
});
|
134
133
|
|
135
134
|
it('should return the right array', () => {
|
136
|
-
const artists = utils.getSongArtists('artist,artist2 - title ft. artist3, artist4'
|
137
|
-
assert.equal(artists.join(','), '
|
135
|
+
const artists = utils.getSongArtists('artist,artist2 - title ft. artist3, artist4');
|
136
|
+
assert.equal(artists.join(','), 'Artist,Artist2,Artist3,Artist4');
|
138
137
|
});
|
139
138
|
});
|
140
139
|
|