museria 0.2.39 → 0.2.43
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 +9 -9
- package/dist/face/style.css +2 -2
- package/package.json +5 -5
- package/src/browser/face/controllers/app/app.html +9 -7
- package/src/browser/face/controllers/app/app.js +2 -4
- package/src/browser/face/controllers/app/app.scss +21 -4
- package/src/client.js +1 -1
- package/src/node.js +14 -10
- package/src/server/transports/express/client/controllers.js +2 -2
- package/src/server/transports/express/client/routes.js +1 -1
- package/src/server/transports/express/index.js +7 -6
- package/src/server/transports/express/midds.js +1 -1
- package/src/utils.js +22 -13
- package/test/client.js +1 -1
- package/test/group.js +1 -1
- package/test/node.js +5 -9
- package/test/routes.js +1 -1
- package/test/utils.js +4 -5
package/dist/face/style.css
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*!
|
2
2
|
* museria face
|
3
|
-
* @version 0.2.
|
3
|
+
* @version 0.2.43
|
4
4
|
* {@link https://github.com/ortexx/museria}
|
5
5
|
*/
|
6
6
|
/*!
|
@@ -17,4 +17,4 @@
|
|
17
17
|
*/@font-face{font-display:block;font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:900;src:url(fa-solid-900.eot);src:url(fa-solid-900.eot) format("embedded-opentype"),url(fa-solid-900.woff2) format("woff2"),url(fa-solid-900.woff) format("woff"),url(fa-solid-900.ttf) format("truetype"),url(fa-solid-900.svg) format("svg")}.fa,.fas{font-family:Font Awesome\ 5 Free;font-weight:900}/*!
|
18
18
|
* Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com
|
19
19
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
20
|
-
*/@font-face{font-display:block;font-family:Font Awesome\ 5 Brands;font-style:normal;font-weight:400;src:url(fa-brands-400.eot);src:url(fa-brands-400.eot) format("embedded-opentype"),url(fa-brands-400.woff2) format("woff2"),url(fa-brands-400.woff) format("woff"),url(fa-brands-400.ttf) format("truetype"),url(fa-brands-400.svg) format("svg")}.fab{font-family:Font Awesome\ 5 Brands;font-weight:400}@font-face{font-family:ProximaNova;src:url(proxima-nova.ttf)}@font-face{font-family:OpenSans;src:url(open-sans.ttf)}*{margin:0;padding:0}body{background:#353535;color:#ccc;font-family:OpenSans;height:100%;overflow-y:scroll}.custom-file input{cursor:pointer;text-indent:-1000px}.custom-control-label{cursor:pointer;opacity:.8}.custom-control-label:hover{opacity:1}.btn{font-weight:700;padding:0;text-transform:uppercase}.btn:active,.btn:focus{box-shadow:none!important;outline:none!important}.btn[disabled]{cursor:not-allowed}a{color:#ccc;text-decoration:underline}a:hover{color:#ccc;text-decoration:none}.input-group-lg input[type=text]{height:auto;padding:.42rem 1rem .45rem}.alert-success{background-color:#25301f;border-color:#28a745;color:#aed3b7}.alert-danger{background-color:#301f1f;border-color:#c00;color:#d3aeae}.alert-info{background-color:#1f2730;border-color:#0af;color:#aec7d3}.invalid-feedback{color:#f39595}.close-fa{color:#666;cursor:pointer;opacity:.7;position:absolute;right:.9em;top:50%;transform:translateY(-50%);z-index:2}.close-fa:hover{opacity:1}.app{display:flex;flex-direction:column;height:100vh}.app .wmodal-overlay{align-items:center;background:rgba(34,34,34,.8);cursor:pointer;display:flex;height:100vh;justify-content:center;left:0;position:fixed;top:0;width:100%;z-index:11000}.app .wmodal-close{color:#666;cursor:pointer;font-size:1.8em;opacity:.4;position:absolute;right:.55em;top:.5em}.app .wmodal-close:hover{opacity:1}.app .wmodal-body{background:#000;box-shadow:0 0 4px 2px hsla(0,0%,40%,.6);box-sizing:border-box;cursor:default;padding:3.5em 2.5em;position:relative}.app .upload-events .wmodal-close{font-size:2em;right:1em;top:50%;transform:translateY(-50%)}.app .upload-events .wmodal-body{padding:2em 5em 2em 2em;word-break:break-all}.app .upload-events .wmodal-body.danger{box-shadow:0 0 4px 2px rgba(204,0,0,.6)}.app .upload-events .wmodal-body.success{box-shadow:0 0 4px 2px rgba(40,167,69,.6)}.app .finding-list>*{display:block}.app .finding-list>:not(:first-child){margin-top:.5em}.app .captcha input{background:#151515;border-color:#292929;width:240px}.app .captcha input:focus{background:#151515;border-color:#666}.app .captcha-preloader{color:#666;font-size:1.7em;text-align:center}.app .header{background:#333;background:radial-gradient(#666,#464646,#333);padding:8.2em 0 6.6em;text-shadow:0 0 .8em #333}.app .header .logo{display:flex;font-family:ProximaNova;font-weight:700;text-decoration:none;text-transform:uppercase}.app .header .logo-img{display:inline-block;vertical-align:middle;width:3em}.app .header .logo-title{color:#fff;display:inline-block;font-size:3em;letter-spacing:.05em;margin-left:.1em;vertical-align:middle}.app .header .logo-description-start{color:#d7cf9b;font-size:2em;letter-spacing:.07em;margin-left:.1em;margin-top:-.3em}.app .header .logo-description-end{color:#d7cf9b;font-size:7.2em;letter-spacing:.03em;margin-left:.2em;margin-top:-.21em}.app .header .logo-description-end-lg{color:#d7cf9b;font-size:3.6em;letter-spacing:.06em;margin-top:-.2em}.app .content{flex:1}.app .footer{background:#333;background:radial-gradient(#555,#424242,#333);color:#ccc;padding:1.5em 0 3em}.app .footer h5{color:#d7cf9b;font-weight:700;margin-bottom:.6em;opacity:.7;text-shadow:0 0 1em #000;text-transform:uppercase}.app .footer a{color:#ccc;text-decoration:none}.app .footer a:hover{text-decoration:underline}.app .footer ul.nav>li{font-size:.9em;line-height:1.8em;word-break:break-all}.app .song-search .alert.alert-success a{color:#aed3b7;text-decoration:none}.app .song-search .alert.alert-success a:hover{color:#28a745}.app .song-search-input{position:relative}.app .song-search-input>i{color:#888;left:.7em;position:absolute;top:50%;transform:translateY(-50%);z-index:1}.app .song-search-input>i.song-search-loading{margin-top:-.37em}.app .song-search-input>i.song-search-close{cursor:pointer;left:unset;opacity:.6;right:.7em}.app .song-search-input>i.song-search-close:hover{opacity:1}.app .song-search-input>input{padding-left:2.5em}.app .song-search-input>input:focus{z-index:0}.app .cover-img{height:2.22em;left:2px;object-fit:cover;pointer-events:none;position:absolute;top:1px;width:2.22em;z-index:2}.app .cover-remove{right:4.5em}.app .cover-label.with-img{padding-left:3em}.app .upload-preloader-btn i{color:#ccc;font-size:1.4em;margin-left:.3em;margin-top:-.1em;vertical-align:middle}.app .song-priority{font-size:.9em}.app .image-link{align-items:center;color:#fff;display:inline-flex;flex-direction:row;opacity:.7;text-decoration:none}.app .image-link:hover{opacity:1}.app .image-link-pic{font-size:3em}.app .image-link-title{font-size:3em;margin-left:.5em;text-transform:uppercase}.app #audio-file{left:-10000px}.app .questions{display:inline-block;list-style:none;margin:0;text-align:left}.app .questions>li{opacity:.9}.app .questions>li:not(:last-child){margin-bottom:2em}.app .questions>li>:first-child{color:#fff;font-size:1.5em;font-weight:700;text-transform:uppercase}.app .questions>li>:last-child{color:#ccc;font-size:1.4em}.app .questions>li>:last-child:before{color:#86e29b;content:"↵";display:inline-block;font-weight:700;margin:0 .4em 0 0;transform:scaleX(-1)}
|
20
|
+
*/@font-face{font-display:block;font-family:Font Awesome\ 5 Brands;font-style:normal;font-weight:400;src:url(fa-brands-400.eot);src:url(fa-brands-400.eot) format("embedded-opentype"),url(fa-brands-400.woff2) format("woff2"),url(fa-brands-400.woff) format("woff"),url(fa-brands-400.ttf) format("truetype"),url(fa-brands-400.svg) format("svg")}.fab{font-family:Font Awesome\ 5 Brands;font-weight:400}@font-face{font-family:ProximaNova;src:url(proxima-nova.ttf)}@font-face{font-family:OpenSans;src:url(open-sans.ttf)}*{margin:0;padding:0}body{background:#353535;color:#ccc;font-family:OpenSans;height:100%;overflow-y:scroll}.custom-file input{cursor:pointer;text-indent:-1000px}.custom-control-label{cursor:pointer;opacity:.8}.custom-control-label:hover{opacity:1}.btn{font-weight:700;padding:0;text-transform:uppercase}.btn:active,.btn:focus{box-shadow:none!important;outline:none!important}.btn[disabled]{cursor:not-allowed}a{color:#ccc;text-decoration:underline}a:hover{color:#ccc;text-decoration:none}.input-group-lg input[type=text]{height:auto;padding:.42rem 1rem .45rem}.alert-success{background-color:#25301f;border-color:#28a745;color:#aed3b7}.alert-danger{background-color:#301f1f;border-color:#c00;color:#d3aeae}.alert-info{background-color:#1f2730;border-color:#0af;color:#aec7d3}.invalid-feedback{color:#f39595}.close-fa{color:#666;cursor:pointer;opacity:.7;position:absolute;right:.9em;top:50%;transform:translateY(-50%);z-index:2}.close-fa:hover{opacity:1}.app{display:flex;flex-direction:column;height:100vh}.app .wmodal-overlay{align-items:center;background:rgba(34,34,34,.8);cursor:pointer;display:flex;height:100vh;justify-content:center;left:0;position:fixed;top:0;width:100%;z-index:11000}.app .wmodal-close{color:#666;cursor:pointer;font-size:1.8em;opacity:.4;position:absolute;right:.55em;top:.5em}.app .wmodal-close:hover{opacity:1}.app .wmodal-body{background:#000;box-shadow:0 0 4px 2px hsla(0,0%,40%,.6);box-sizing:border-box;cursor:default;padding:3.5em 2.5em;position:relative}.app .upload-events .wmodal-close{font-size:2em;right:1em;top:50%;transform:translateY(-50%)}.app .upload-events .wmodal-body{padding:2em 5em 2em 2em;word-break:break-all}.app .upload-events .wmodal-body.danger{box-shadow:0 0 4px 2px rgba(204,0,0,.6)}.app .upload-events .wmodal-body.success{box-shadow:0 0 4px 2px rgba(40,167,69,.6)}.app .finding-list>*{display:block}.app .finding-list>:not(:first-child){margin-top:.5em}.app .captcha input{background:#151515;border-color:#292929;width:240px}.app .captcha input:focus{background:#151515;border-color:#666}.app .captcha-preloader{color:#666;font-size:1.7em;text-align:center}.app .header{background:#333;background:radial-gradient(#666,#464646,#333);padding:8.2em 0 6.6em;position:relative;text-shadow:0 0 .8em #333}.app .header .songs-counter-text{bottom:1.5em;color:#666;font-weight:700;left:50%;position:absolute;text-align:center;text-transform:uppercase;transform:translateX(-50%)}.app .header .songs-counter-text b{color:#888}.app .header .logo{display:flex;font-family:ProximaNova;font-weight:700;text-decoration:none;text-transform:uppercase}.app .header .logo-img{display:inline-block;vertical-align:middle;width:3em}.app .header .logo-title{color:#fff;display:inline-block;font-size:3em;letter-spacing:.05em;margin-left:.1em;vertical-align:middle}.app .header .logo-description-start{color:#d7cf9b;font-size:2em;letter-spacing:.07em;margin-left:.1em;margin-top:-.3em}.app .header .logo-description-end{color:#d7cf9b;font-size:7.2em;letter-spacing:.03em;margin-left:.2em;margin-top:-.21em}.app .header .logo-description-end-lg{color:#d7cf9b;font-size:3.6em;letter-spacing:.06em;margin-top:-.2em}.app .content{flex:1}.app .footer{background:#333;background:radial-gradient(#555,#424242,#333);color:#ccc;padding:1.5em 0 3em}.app .footer h5{color:#d7cf9b;font-weight:700;margin-bottom:.6em;opacity:.7;text-shadow:0 0 1em #000;text-transform:uppercase}.app .footer a{color:#ccc;text-decoration:none}.app .footer a:hover{text-decoration:underline}.app .footer ul.nav>li{font-size:.9em;line-height:1.8em;word-break:break-all}.app .song-search .alert.alert-success a{color:#aed3b7;text-decoration:none}.app .song-search .alert.alert-success a:hover{color:#28a745}.app .song-search-input{position:relative}.app .song-search-input>i{color:#888;left:.7em;position:absolute;top:50%;transform:translateY(-50%);z-index:1}.app .song-search-input>i.song-search-loading{margin-top:-.37em}.app .song-search-input>i.song-search-close{cursor:pointer;left:unset;opacity:.6;right:.7em}.app .song-search-input>i.song-search-close:hover{opacity:1}.app .song-search-input>input{padding-left:2.5em;padding-right:2em}.app .song-search-input>input:focus{z-index:0}.app .cover-img{height:2.22em;left:2px;object-fit:cover;pointer-events:none;position:absolute;top:1px;width:2.22em;z-index:2}.app .cover-remove{right:4.5em}.app .cover-label.with-img{padding-left:3em}.app .upload-preloader-btn i{color:#ccc;font-size:1.4em;margin-left:.3em;margin-top:-.1em;vertical-align:middle}.app .song-priority{font-size:.9em}.app .image-link{align-items:center;color:#fff;display:inline-flex;flex-direction:row;opacity:.7;text-decoration:none}.app .image-link:hover{opacity:1}.app .image-link-pic{font-size:3em}.app .image-link-title{font-size:3em;margin-left:.5em;text-transform:uppercase}.app #audio-file{left:-10000px}.app .questions{display:inline-block;list-style:none;margin:0;text-align:left}.app .questions>li{opacity:.9}.app .questions>li:not(:last-child){margin-bottom:2em}.app .questions>li>:first-child{color:#fff;font-size:1.5em;font-weight:700;text-transform:uppercase}.app .questions>li>:last-child{color:#ccc;font-size:1.4em}.app .questions>li>:last-child:before{color:#86e29b;content:"↵";display:inline-block;font-weight:700;margin:0 .4em 0 0;transform:scaleX(-1)}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "museria",
|
3
|
-
"version": "0.2.
|
3
|
+
"version": "0.2.43",
|
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",
|
@@ -77,7 +77,7 @@
|
|
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.27",
|
81
81
|
"music-metadata": "^6.4.0",
|
82
82
|
"node-fetch": "^2.6.1",
|
83
83
|
"node-id3": "^0.2.2",
|
@@ -85,8 +85,8 @@
|
|
85
85
|
"serve-favicon": "^2.5.0",
|
86
86
|
"sharp": "^0.25.2",
|
87
87
|
"splaytree": "^3.1.0",
|
88
|
-
"spreadable": "^0.2.
|
89
|
-
"storacle": "^0.2.
|
88
|
+
"spreadable": "^0.2.23",
|
89
|
+
"storacle": "^0.2.23",
|
90
90
|
"transliteration": "^2.2.0"
|
91
91
|
},
|
92
92
|
"repository": {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<div class="app container-fluid">
|
1
|
+
<div class="app container-fluid">
|
2
2
|
<if recreate is="${ this.showCaptcha }" class="captcha wmodal">
|
3
3
|
<div
|
4
4
|
class="wmodal-overlay"
|
@@ -48,6 +48,9 @@
|
|
48
48
|
</div>
|
49
49
|
</if>
|
50
50
|
<header class="header row">
|
51
|
+
<div class="songs-counter-text">
|
52
|
+
There ${this.songsCount == 1? 'is': 'are'} <b>${ Number(this.songsCount).toLocaleString() }</b> song${this.songsCount == 1? '': 's'} on the network
|
53
|
+
</div>
|
51
54
|
<a state="app" class="logo mx-auto px-4">
|
52
55
|
<div>
|
53
56
|
<img src="./img/logo.svg" class="logo-img">
|
@@ -55,12 +58,12 @@
|
|
55
58
|
<div class="logo-description-start">decentralized</div>
|
56
59
|
<div class="logo-description-end-lg d-lg-none">storage</div>
|
57
60
|
</div>
|
58
|
-
<div class="logo-description-end d-none d-lg-block">storage</div>
|
61
|
+
<div class="logo-description-end d-none d-lg-block">storage</div>
|
59
62
|
</a>
|
60
63
|
</header>
|
61
|
-
<div class="content">
|
64
|
+
<div class="content">
|
62
65
|
<div class="row pt-5 pb-3">
|
63
|
-
<div class="song-search col-lg-6 col-12 pl-5 pr-5 pr-lg-4 pt-4">
|
66
|
+
<div class="song-search col-lg-6 col-12 pl-5 pr-5 pr-lg-4 pt-4">
|
64
67
|
<div class="song-search-input input-group input-group-lg">
|
65
68
|
<i hidden="${ this.isFinding }" class="fas fa-search fa-lg"></i>
|
66
69
|
<i hidden="${ !this.isFinding }" class="fas fa-circle-notch fa-spin song-search-loading fa-lg"></i>
|
@@ -240,10 +243,9 @@
|
|
240
243
|
</div>
|
241
244
|
</li>
|
242
245
|
<li>
|
243
|
-
<div>
|
246
|
+
<div>Where can I get the node status?</div>
|
244
247
|
<div>
|
245
|
-
There
|
246
|
-
<a href="/status?pretty" target="_blank">here</a>.
|
248
|
+
There is a special route <a href="/status?pretty" target="_blank">here</a>.
|
247
249
|
</div>
|
248
250
|
</li>
|
249
251
|
<li>
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import './app.scss';
|
2
2
|
import Akili from 'akili';
|
3
3
|
import router from 'akili/src/services/router';
|
4
|
-
import request from 'akili/src/services/request';
|
5
4
|
import client from '../../client';
|
6
5
|
|
7
6
|
export default class App extends Akili.Component {
|
@@ -19,7 +18,7 @@ export default class App extends Akili.Component {
|
|
19
18
|
created() {
|
20
19
|
this.captchaWidth = 240;
|
21
20
|
this.findingSongsLimit = 10;
|
22
|
-
this.songsCountInterval =
|
21
|
+
this.songsCountInterval = 15 * 1000;
|
23
22
|
this.songsCountIntervalObj = null;
|
24
23
|
this.scope.songsCount = 0;
|
25
24
|
this.scope.searchInputValue = this.transition.query.f;
|
@@ -83,8 +82,7 @@ export default class App extends Akili.Component {
|
|
83
82
|
}
|
84
83
|
|
85
84
|
async setSongsCount() {
|
86
|
-
|
87
|
-
this.scope.songsCount = data.filesCount;
|
85
|
+
this.scope.songsCount = await client.getNetworkFilesCount();
|
88
86
|
}
|
89
87
|
|
90
88
|
setFindingValue(val) {
|
@@ -3,7 +3,7 @@
|
|
3
3
|
.app {
|
4
4
|
display: flex;
|
5
5
|
height: 100vh;
|
6
|
-
flex-direction: column;
|
6
|
+
flex-direction: column;
|
7
7
|
|
8
8
|
.wmodal {
|
9
9
|
&-overlay {
|
@@ -96,11 +96,27 @@
|
|
96
96
|
}
|
97
97
|
|
98
98
|
& .header {
|
99
|
+
position: relative;
|
99
100
|
background: #333;
|
100
101
|
background: radial-gradient(#666,#464646, #333);
|
101
102
|
padding: 8.2em 0 6.6em 0;
|
102
103
|
text-shadow: 0px 0px 0.8em #333;
|
103
104
|
|
105
|
+
& .songs-counter-text {
|
106
|
+
position: absolute;
|
107
|
+
left: 50%;
|
108
|
+
transform: translateX(-50%);
|
109
|
+
bottom: 1.5em;
|
110
|
+
color: $gray;
|
111
|
+
text-transform: uppercase;
|
112
|
+
font-weight: bold;
|
113
|
+
text-align: center;
|
114
|
+
|
115
|
+
& b {
|
116
|
+
color: $light;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
104
120
|
& .logo {
|
105
121
|
display: flex;
|
106
122
|
font-family: ProximaNova;
|
@@ -197,7 +213,7 @@
|
|
197
213
|
}
|
198
214
|
|
199
215
|
&-input {
|
200
|
-
position: relative;
|
216
|
+
position: relative;
|
201
217
|
|
202
218
|
& > i {
|
203
219
|
position: absolute;
|
@@ -224,8 +240,9 @@
|
|
224
240
|
}
|
225
241
|
|
226
242
|
& > input {
|
227
|
-
padding-left: 2.5em;
|
228
|
-
|
243
|
+
padding-left: 2.5em;
|
244
|
+
padding-right: 2em;
|
245
|
+
|
229
246
|
&:focus {
|
230
247
|
z-index: 0;
|
231
248
|
}
|
package/src/client.js
CHANGED
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) {
|
@@ -8,7 +8,7 @@ module.exports.requestSong = node => {
|
|
8
8
|
return async (req, res, next) => {
|
9
9
|
try {
|
10
10
|
const title = req.query.title;
|
11
|
-
node.songTitleTest(title);
|
11
|
+
node.songTitleTest(title);
|
12
12
|
const link = await node.getSongLink(title, req.query.type);
|
13
13
|
|
14
14
|
if(!link) {
|
@@ -131,4 +131,4 @@ module.exports.removeSong = node => {
|
|
131
131
|
next(err);
|
132
132
|
}
|
133
133
|
}
|
134
|
-
};
|
134
|
+
};
|
@@ -1,4 +1,5 @@
|
|
1
|
-
const
|
1
|
+
const ServerExpressStoracle = require('storacle/src/server/transports/express')();
|
2
|
+
const ServerExpressMetastocle = require('metastocle/src/server/transports/express')(ServerExpressStoracle);
|
2
3
|
const routes = require('./routes');
|
3
4
|
const routesClient = require('./client/routes');
|
4
5
|
const routesApi = require('./api/routes');
|
@@ -29,7 +30,7 @@ module.exports = (Parent) => {
|
|
29
30
|
const remove = [
|
30
31
|
'addDocument', 'updateDocuments',
|
31
32
|
'deleteDocuments', 'getDocumentsCount',
|
32
|
-
'getDocumentByPk', 'getDocuments'
|
33
|
+
'getDocumentByPk', 'getDocuments', 'removeFile'
|
33
34
|
];
|
34
35
|
return super.getClientRoutes().filter(r => !remove.includes(r.name)).concat(routesClient);
|
35
36
|
}
|
@@ -45,7 +46,7 @@ module.exports = (Parent) => {
|
|
45
46
|
* @see ServerExpressMetastocle.prototype.getApiMasterRoutes
|
46
47
|
*/
|
47
48
|
getApiMasterRoutes() {
|
48
|
-
const remove = ['updateDocuments', 'deleteDocuments'];
|
49
|
+
const remove = ['updateDocuments', 'deleteDocuments', 'removeFile'];
|
49
50
|
return super.getApiMasterRoutes().filter(r => !remove.includes(r.name)).concat(routesApiMaster);
|
50
51
|
}
|
51
52
|
|
@@ -53,7 +54,7 @@ module.exports = (Parent) => {
|
|
53
54
|
* @see ServerExpressMetastocle.prototype.getApiButlerRoutes
|
54
55
|
*/
|
55
56
|
getApiButlerRoutes() {
|
56
|
-
const remove = ['updateDocuments', 'deleteDocuments'];
|
57
|
+
const remove = ['updateDocuments', 'deleteDocuments', 'removeFile'];
|
57
58
|
return super.getApiButlerRoutes().filter(r => !remove.includes(r.name)).concat(routesApiButler);
|
58
59
|
}
|
59
60
|
|
@@ -61,7 +62,7 @@ module.exports = (Parent) => {
|
|
61
62
|
* @see ServerExpressMetastocle.prototype.getApiSlaveRoutes
|
62
63
|
*/
|
63
64
|
getApiSlaveRoutes() {
|
64
|
-
const remove = ['updateDocuments', 'deleteDocuments'];
|
65
|
+
const remove = ['updateDocuments', 'deleteDocuments', 'removeFile'];
|
65
66
|
return super.getApiSlaveRoutes().filter(r => !remove.includes(r.name)).concat(routesApiSlave);
|
66
67
|
}
|
67
68
|
|
@@ -69,7 +70,7 @@ module.exports = (Parent) => {
|
|
69
70
|
* @see ServerExpressMetastocle.prototype.getApiNodeRoutes
|
70
71
|
*/
|
71
72
|
getApiNodeRoutes() {
|
72
|
-
const remove = ['addDocument'];
|
73
|
+
const remove = ['addDocument', 'storFile'];
|
73
74
|
return super.getApiNodeRoutes().filter(r => !remove.includes(r.name)).concat(routesApiNode);
|
74
75
|
}
|
75
76
|
}
|
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/client.js
CHANGED
@@ -336,7 +336,7 @@ describe('Client', () => {
|
|
336
336
|
assert.isNull(await node.db.getMusicByPk(title), 'check the database');
|
337
337
|
assert.isFalse(await node.hasFile(doc.fileHash), 'check the file');
|
338
338
|
});
|
339
|
-
});
|
339
|
+
});
|
340
340
|
|
341
341
|
describe('.createRequestedSongAudioLink()', () => {
|
342
342
|
it('should return the right link', async () => {
|
package/test/group.js
CHANGED
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/routes.js
CHANGED
@@ -361,7 +361,7 @@ describe('routes', () => {
|
|
361
361
|
assert.isNull(await node.db.getMusicByPk(title), 'check the database');
|
362
362
|
assert.isFalse(await node.hasFile(doc.fileHash), 'check the file');
|
363
363
|
});
|
364
|
-
});
|
364
|
+
});
|
365
365
|
|
366
366
|
describe('/api/master/remove-song/', function () {
|
367
367
|
it('should return an auth error', async function () {
|
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
|
|