malojaserver 3.2.1__py3-none-any.whl → 3.2.3__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- maloja/__main__.py +1 -1
- maloja/__pkginfo__.py +1 -1
- maloja/apis/_base.py +26 -19
- maloja/apis/_exceptions.py +1 -1
- maloja/apis/audioscrobbler.py +35 -7
- maloja/apis/audioscrobbler_legacy.py +5 -5
- maloja/apis/listenbrainz.py +7 -5
- maloja/apis/native_v1.py +43 -26
- maloja/cleanup.py +9 -7
- maloja/data_files/config/rules/predefined/krateng_kpopgirlgroups.tsv +4 -2
- maloja/database/__init__.py +55 -23
- maloja/database/associated.py +10 -6
- maloja/database/exceptions.py +28 -3
- maloja/database/sqldb.py +216 -168
- maloja/dev/profiler.py +3 -4
- maloja/images.py +6 -0
- maloja/malojauri.py +2 -0
- maloja/pkg_global/conf.py +97 -72
- maloja/proccontrol/tasks/export.py +2 -1
- maloja/proccontrol/tasks/import_scrobbles.py +57 -15
- maloja/server.py +4 -5
- maloja/setup.py +56 -44
- maloja/thirdparty/lastfm.py +18 -17
- maloja/web/jinja/abstracts/base.jinja +1 -1
- maloja/web/jinja/admin_albumless.jinja +2 -0
- maloja/web/jinja/admin_overview.jinja +3 -3
- maloja/web/jinja/admin_setup.jinja +1 -1
- maloja/web/jinja/error.jinja +2 -2
- maloja/web/jinja/partials/album_showcase.jinja +1 -1
- maloja/web/jinja/partials/awards_album.jinja +1 -1
- maloja/web/jinja/partials/awards_artist.jinja +2 -2
- maloja/web/jinja/partials/charts_albums_tiles.jinja +4 -0
- maloja/web/jinja/partials/charts_artists_tiles.jinja +5 -1
- maloja/web/jinja/partials/charts_tracks_tiles.jinja +4 -0
- maloja/web/jinja/snippets/entityrow.jinja +2 -2
- maloja/web/jinja/snippets/links.jinja +3 -1
- maloja/web/static/css/maloja.css +14 -2
- maloja/web/static/css/startpage.css +2 -2
- maloja/web/static/js/manualscrobble.js +1 -1
- maloja/web/static/js/notifications.js +16 -8
- {malojaserver-3.2.1.dist-info → malojaserver-3.2.3.dist-info}/METADATA +10 -46
- {malojaserver-3.2.1.dist-info → malojaserver-3.2.3.dist-info}/RECORD +45 -45
- {malojaserver-3.2.1.dist-info → malojaserver-3.2.3.dist-info}/WHEEL +1 -1
- {malojaserver-3.2.1.dist-info → malojaserver-3.2.3.dist-info}/LICENSE +0 -0
- {malojaserver-3.2.1.dist-info → malojaserver-3.2.3.dist-info}/entry_points.txt +0 -0
maloja/thirdparty/lastfm.py
CHANGED
@@ -55,24 +55,25 @@ class LastFM(MetadataInterface, ProxyScrobbleInterface):
|
|
55
55
|
})
|
56
56
|
|
57
57
|
def authorize(self):
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
58
|
+
if all(self.settings[key] not in [None,"ASK",False] for key in ["username","password","apikey","secret"]):
|
59
|
+
try:
|
60
|
+
response = requests.post(
|
61
|
+
url=self.proxyscrobble['scrobbleurl'],
|
62
|
+
params=self.query_compose({
|
63
|
+
"method":"auth.getMobileSession",
|
64
|
+
"username":self.settings["username"],
|
65
|
+
"password":self.settings["password"],
|
66
|
+
"api_key":self.settings["apikey"]
|
67
|
+
}),
|
68
|
+
headers={
|
69
|
+
"User-Agent":self.useragent
|
70
|
+
}
|
71
|
+
)
|
71
72
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
data = ElementTree.fromstring(response.text)
|
74
|
+
self.settings["sk"] = data.find("session").findtext("key")
|
75
|
+
except Exception as e:
|
76
|
+
log("Error while authenticating with LastFM: " + repr(e))
|
76
77
|
|
77
78
|
|
78
79
|
# creates signature and returns full query
|
@@ -75,7 +75,7 @@
|
|
75
75
|
<a href="/"><img style="display:block;" src="/favicon.png" /></a>
|
76
76
|
</div>
|
77
77
|
<div id="right-side">
|
78
|
-
<span><input id="searchinput" placeholder="Search for an artist or track..." oninput="search(this)" onblur="clearresults()" /></span>
|
78
|
+
<span><input id="searchinput" placeholder="Search for an album, artist or track..." oninput="search(this)" onblur="clearresults()" /></span>
|
79
79
|
</div>
|
80
80
|
|
81
81
|
|
@@ -67,9 +67,9 @@
|
|
67
67
|
<li>manually scrobble from track pages</li>
|
68
68
|
<li>delete scrobbles</li>
|
69
69
|
<li>reparse scrobbles</li>
|
70
|
-
<li>edit tracks and artists</li>
|
71
|
-
<li>merge tracks and artists</li>
|
72
|
-
<li>upload artist and track art by dropping a file on the existing image on an artist or track page</li>
|
70
|
+
<li>edit tracks, albums and artists</li>
|
71
|
+
<li>merge tracks, albums and artists</li>
|
72
|
+
<li>upload artist, album and track art by dropping a file on the existing image on an artist or track page</li>
|
73
73
|
<li>see more detailed error pages</li>
|
74
74
|
</ul>
|
75
75
|
|
@@ -56,7 +56,7 @@
|
|
56
56
|
|
57
57
|
If you use a Chromium-based browser and listen to music on Plex, Spotify, Soundcloud, Bandcamp or YouTube Music, download the extension and simply enter the server URL as well as your API key in the relevant fields. They will turn green if the server is accessible.
|
58
58
|
<br/><br/>
|
59
|
-
You can also use any standard-compliant scrobbler. For GNUFM (audioscrobbler) scrobblers, enter <span class="stats"><span name="serverurl">yourserver.tld</span>/apis/audioscrobbler</span> as your Gnukebox server and your API key as the password. For Listenbrainz scrobblers, use <span class="stats"><span name="serverurl">yourserver.tld</span>/apis/listenbrainz</span> as the API URL and your API key as token.
|
59
|
+
You can also use any standard-compliant scrobbler. For GNUFM (audioscrobbler) scrobblers, enter <span class="stats"><span name="serverurl">yourserver.tld</span>/apis/audioscrobbler</span> as your Gnukebox server and your API key as the password. For Listenbrainz scrobblers, use <span class="stats"><span name="serverurl">yourserver.tld</span>/apis/listenbrainz</span> as the API URL (depending on the implementation, you might need to add a <span class="stats">/1</span> at the end) and your API key as token.
|
60
60
|
<br/><br/>
|
61
61
|
If you use another browser or another music player, you could try to code your own extension. The API is super simple! Just send a POST HTTP request to
|
62
62
|
|
maloja/web/jinja/error.jinja
CHANGED
@@ -29,7 +29,7 @@
|
|
29
29
|
{% for entry in dbc.get_charts_albums(filterkeys,limitkeys,{'only_own_albums':False}) %}
|
30
30
|
|
31
31
|
|
32
|
-
{% if artist not in (entry.album.artists or []) %}
|
32
|
+
{% if info.artist not in (entry.album.artists or []) %}
|
33
33
|
|
34
34
|
{%- set cert = None -%}
|
35
35
|
{%- if entry.scrobbles >= settings.scrobbles_gold_album -%}{% set cert = 'gold' %}{%- endif -%}
|
@@ -63,7 +63,7 @@
|
|
63
63
|
{%- if e.scrobbles >= settings.scrobbles_diamond -%}{% set cert = 'diamond' %}{%- endif -%}
|
64
64
|
|
65
65
|
{%- if cert -%}
|
66
|
-
<a href='{{ links.url(e.track) }}' class="hidelink certified certified_{{ cert }} smallcerticon" title="{{ e.track.title }} has reached {{ cert.capitalize() }} status">
|
66
|
+
<a href='{{ links.url(e.track) }}' class="hidelink certified certified_{{ cert }} smallcerticon" title="{{ e.track.title | e }} has reached {{ cert.capitalize() }} status">
|
67
67
|
{% include 'icons/cert_track.jinja' %}
|
68
68
|
</a>
|
69
69
|
{%- endif %}
|
@@ -72,7 +72,7 @@
|
|
72
72
|
{%- if e.scrobbles >= settings.scrobbles_diamond_album -%}{% set cert = 'diamond' %}{%- endif -%}
|
73
73
|
|
74
74
|
{%- if cert -%}
|
75
|
-
<a href='{{ links.url(e.album) }}' class="hidelink certified certified_{{ cert }} smallcerticon" title="{{ e.album.albumtitle }} has reached {{ cert.capitalize() }} status">
|
75
|
+
<a href='{{ links.url(e.album) }}' class="hidelink certified certified_{{ cert }} smallcerticon" title="{{ e.album.albumtitle | e }} has reached {{ cert.capitalize() }} status">
|
76
76
|
{% include 'icons/cert_album.jinja' %}
|
77
77
|
</a>
|
78
78
|
{%- endif %}
|
@@ -87,7 +87,7 @@
|
|
87
87
|
{%- if e.scrobbles >= settings.scrobbles_diamond -%}{% set cert = 'diamond' %}{%- endif -%}
|
88
88
|
|
89
89
|
{%- if cert -%}
|
90
|
-
<a href='{{ links.url(e.track) }}' class="hidelink certified certified_{{ cert }} smallcerticon" title="{{ e.track.title }} has reached {{ cert.capitalize() }} status">
|
90
|
+
<a href='{{ links.url(e.track) }}' class="hidelink certified certified_{{ cert }} smallcerticon" title="{{ e.track.title | e }} has reached {{ cert.capitalize() }} status">
|
91
91
|
{% include 'icons/cert_track.jinja' %}
|
92
92
|
</a>
|
93
93
|
{%- endif %}
|
@@ -16,10 +16,14 @@
|
|
16
16
|
{% if entry is not none %}
|
17
17
|
{% set album = entry.album %}
|
18
18
|
{% set rank = entry.rank %}
|
19
|
+
{% set scrobbles = entry.scrobbles %}
|
19
20
|
<div class="tile">
|
20
21
|
<a href="{{ links.url(album) }}">
|
21
22
|
<div class="lazy" data-bg="{{ images.get_album_image(album) }}"'>
|
22
23
|
<span class='stats'>#{{ rank }}</span> <span>{{ album.albumtitle }}</span>
|
24
|
+
{% if settings['SHOW_PLAY_NUMBER_ON_TILES'] %}
|
25
|
+
<p class="scrobbles"><span>{{ scrobbles }} {{ 'play' if scrobbles == 1 else 'plays' }}</span> </p>
|
26
|
+
{% endif %}
|
23
27
|
</div>
|
24
28
|
</a>
|
25
29
|
</div>
|
@@ -16,10 +16,14 @@
|
|
16
16
|
{% if entry is not none %}
|
17
17
|
{% set artist = entry.artist %}
|
18
18
|
{% set rank = entry.rank %}
|
19
|
+
{% set scrobbles = entry.scrobbles %}
|
19
20
|
<div class="tile">
|
20
21
|
<a href="{{ links.url(artist) }}">
|
21
22
|
<div class="lazy" data-bg="{{ images.get_artist_image(artist) }}"'>
|
22
|
-
<span class='stats'>#{{ rank }}</span> <span>{{ artist }}</span>
|
23
|
+
<span class='stats'>#{{ rank }}</span> <span>{{ artist }}</span>
|
24
|
+
{% if settings['SHOW_PLAY_NUMBER_ON_TILES'] %}
|
25
|
+
<p class="scrobbles"><span>{{ scrobbles }} {{ 'play' if scrobbles == 1 else 'plays' }}</span> </p>
|
26
|
+
{% endif %}
|
23
27
|
</div>
|
24
28
|
</a>
|
25
29
|
</div>
|
@@ -16,10 +16,14 @@
|
|
16
16
|
{% if entry is not none %}
|
17
17
|
{% set track = entry.track %}
|
18
18
|
{% set rank = entry.rank %}
|
19
|
+
{% set scrobbles = entry.scrobbles %}
|
19
20
|
<div class="tile">
|
20
21
|
<a href="{{ links.url(track) }}">
|
21
22
|
<div class="lazy" data-bg="{{ images.get_track_image(track) }}"'>
|
22
23
|
<span class='stats'>#{{ rank }}</span> <span>{{ track.title }}</span>
|
24
|
+
{% if settings['SHOW_PLAY_NUMBER_ON_TILES'] %}
|
25
|
+
<p class="scrobbles"><span>{{ scrobbles }} {{ 'play' if scrobbles == 1 else 'plays' }}</span> </p>
|
26
|
+
{% endif %}
|
23
27
|
</div>
|
24
28
|
</a>
|
25
29
|
</div>
|
@@ -20,11 +20,11 @@
|
|
20
20
|
<td class='searchProvider'>{{ links.link_search(entity) }}</td>
|
21
21
|
{% endif %}
|
22
22
|
<td class='track'>
|
23
|
-
<span class='artist_in_trackcolumn'>{{ links.links(entity.artists) }}</span> – {{ links.link(entity) }}
|
23
|
+
<span class='artist_in_trackcolumn'>{{ links.links(entity.artists, restrict_amount=True) }}</span> – {{ links.link(entity) }}
|
24
24
|
</td>
|
25
25
|
{% elif entity is mapping and 'albumtitle' in entity %}
|
26
26
|
<td class='album'>
|
27
|
-
<span class='
|
27
|
+
<span class='artist_in_albumcolumn'>{{ links.links(entity.artists, restrict_amount=True) }}</span> – {{ links.link(entity) }}
|
28
28
|
</td>
|
29
29
|
{% else %}
|
30
30
|
<td class='artist'>{{ links.link(entity) }}
|
@@ -8,9 +8,11 @@
|
|
8
8
|
<a href="{{ url(entity) }}">{{ name | e }}</a>
|
9
9
|
{%- endmacro %}
|
10
10
|
|
11
|
-
{% macro links(entities) -%}
|
11
|
+
{% macro links(entities, restrict_amount=False) -%}
|
12
12
|
{% if entities is none or entities == [] %}
|
13
13
|
{{ settings["DEFAULT_ALBUM_ARTIST"] }}
|
14
|
+
{% elif entities.__len__() > 3 and restrict_amount %}
|
15
|
+
{{ link(entities[0]) }} et al.
|
14
16
|
{% else %}
|
15
17
|
{% for entity in entities -%}
|
16
18
|
{{ link(entity) }}{{ ", " if not loop.last }}
|
maloja/web/static/css/maloja.css
CHANGED
@@ -363,12 +363,14 @@ div#notification_area {
|
|
363
363
|
right:20px;
|
364
364
|
}
|
365
365
|
div#notification_area div.notification {
|
366
|
-
background-color:
|
366
|
+
background-color:black;
|
367
367
|
width:400px;
|
368
368
|
min-height:50px;
|
369
369
|
margin-bottom:7px;
|
370
370
|
padding:9px;
|
371
|
-
opacity:0.
|
371
|
+
opacity:0.5;
|
372
|
+
border-left: 8px solid var(--notification-color);
|
373
|
+
border-radius: 3px;
|
372
374
|
}
|
373
375
|
div#notification_area div.notification:hover {
|
374
376
|
opacity:0.95;
|
@@ -781,6 +783,9 @@ table.list td.artists,td.artist,td.title,td.track {
|
|
781
783
|
table.list td.track span.artist_in_trackcolumn {
|
782
784
|
color: var(--text-color-secondary);
|
783
785
|
}
|
786
|
+
table.list td.album span.artist_in_albumcolumn {
|
787
|
+
color: var(--text-color-secondary);
|
788
|
+
}
|
784
789
|
|
785
790
|
table.list td.searchProvider {
|
786
791
|
width: 20px;
|
@@ -987,6 +992,7 @@ table.misc td {
|
|
987
992
|
|
988
993
|
|
989
994
|
div.tiles {
|
995
|
+
max-height: 600px;
|
990
996
|
display: grid;
|
991
997
|
grid-template-columns: repeat(18, calc(100% / 18));
|
992
998
|
grid-template-rows: repeat(6, calc(100% / 6));
|
@@ -1069,6 +1075,12 @@ div.tiles span {
|
|
1069
1075
|
overflow-wrap: anywhere;
|
1070
1076
|
}
|
1071
1077
|
|
1078
|
+
div.tiles p.scrobbles {
|
1079
|
+
margin: 0;
|
1080
|
+
top:100%;
|
1081
|
+
position: sticky;
|
1082
|
+
}
|
1083
|
+
|
1072
1084
|
div.tiles a:hover {
|
1073
1085
|
text-decoration: none;
|
1074
1086
|
}
|
@@ -22,8 +22,8 @@ div#startpage {
|
|
22
22
|
|
23
23
|
@media (min-width: 1401px) and (max-width: 2200px) {
|
24
24
|
div#startpage {
|
25
|
-
grid-template-columns:
|
26
|
-
grid-template-rows:
|
25
|
+
grid-template-columns: repeat(2, 45vw);
|
26
|
+
grid-template-rows: repeat(3, 45vh);
|
27
27
|
|
28
28
|
grid-template-areas:
|
29
29
|
"charts_artists lastscrobbles"
|
@@ -126,7 +126,7 @@ function scrobble(artists,title,albumartists,album,timestamp) {
|
|
126
126
|
lastArtists = artists;
|
127
127
|
lastTrack = title;
|
128
128
|
lastAlbum = album;
|
129
|
-
lastAlbumartists = albumartists;
|
129
|
+
lastAlbumartists = albumartists || [];
|
130
130
|
|
131
131
|
var payload = {
|
132
132
|
"artists":artists,
|
@@ -1,12 +1,14 @@
|
|
1
1
|
// JS for feedback to the user whenever any XHTTP action is taken
|
2
2
|
|
3
3
|
const colors = {
|
4
|
-
|
4
|
+
'error': 'red',
|
5
|
+
'warning':'#8ACC26',
|
5
6
|
'info':'green'
|
6
7
|
}
|
7
8
|
|
9
|
+
|
8
10
|
const notification_template = info => `
|
9
|
-
<div class="notification" style="
|
11
|
+
<div class="notification" style="--notification-color: ${colors[info.notification_type]};">
|
10
12
|
<b>${info.title}</b><br/>
|
11
13
|
<span>${info.body}</span>
|
12
14
|
|
@@ -35,18 +37,24 @@ function notify(title,msg,notification_type='info',reload=false) {
|
|
35
37
|
}
|
36
38
|
|
37
39
|
function notifyCallback(request) {
|
38
|
-
var
|
40
|
+
var response = request.response;
|
39
41
|
var status = request.status;
|
40
42
|
|
41
43
|
if (status == 200) {
|
42
|
-
|
44
|
+
if (response.hasOwnProperty('warnings') && response.warnings.length > 0) {
|
45
|
+
var notification_type = 'warning';
|
46
|
+
}
|
47
|
+
else {
|
48
|
+
var notification_type = 'info';
|
49
|
+
}
|
50
|
+
|
43
51
|
var title = "Success!";
|
44
|
-
var msg =
|
52
|
+
var msg = response.desc || response;
|
45
53
|
}
|
46
54
|
else {
|
47
|
-
var notification_type = '
|
48
|
-
var title = "Error: " +
|
49
|
-
var msg =
|
55
|
+
var notification_type = 'error';
|
56
|
+
var title = "Error: " + response.error.type;
|
57
|
+
var msg = response.error.desc || "";
|
50
58
|
}
|
51
59
|
|
52
60
|
|
@@ -1,17 +1,17 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.3
|
2
2
|
Name: malojaserver
|
3
|
-
Version: 3.2.
|
3
|
+
Version: 3.2.3
|
4
4
|
Summary: Self-hosted music scrobble database
|
5
5
|
Keywords: scrobbling,music,selfhosted,database,charts,statistics
|
6
6
|
Author-email: Johannes Krattenmacher <maloja@dev.krateng.ch>
|
7
|
-
Requires-Python: >=3.
|
7
|
+
Requires-Python: >=3.11
|
8
8
|
Description-Content-Type: text/markdown
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
10
10
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
11
11
|
Classifier: Operating System :: OS Independent
|
12
12
|
Requires-Dist: bottle>=0.12.16
|
13
13
|
Requires-Dist: waitress>=2.1.0
|
14
|
-
Requires-Dist: doreah>=
|
14
|
+
Requires-Dist: doreah>=2.0.1, <3
|
15
15
|
Requires-Dist: nimrodel>=0.8.0
|
16
16
|
Requires-Dist: setproctitle>=1.1.10
|
17
17
|
Requires-Dist: jinja2>=3.0.0
|
@@ -21,6 +21,8 @@ Requires-Dist: sqlalchemy>=2.0
|
|
21
21
|
Requires-Dist: python-datauri>=1.1.0
|
22
22
|
Requires-Dist: requests>=2.27.1
|
23
23
|
Requires-Dist: setuptools>68.0.0
|
24
|
+
Requires-Dist: toml>=0.10.2
|
25
|
+
Requires-Dist: PyYAML>=6.0.1
|
24
26
|
Requires-Dist: pyvips>=2.1 ; extra == "full"
|
25
27
|
Project-URL: documentation, https://github.com/krateng/maloja
|
26
28
|
Project-URL: homepage, https://github.com/krateng/maloja
|
@@ -69,15 +71,8 @@ You can check [my own Maloja page](https://maloja.krateng.ch) as an example inst
|
|
69
71
|
|
70
72
|
## How to install
|
71
73
|
|
72
|
-
|
73
|
-
|
74
|
-
Maloja should run on any x86 or ARM machine that runs Python.
|
75
|
-
|
76
|
-
It is highly recommended to use **Docker** or **Podman**.
|
77
|
-
|
78
|
-
Your CPU should have a single core passmark score of at the very least 1500. 500 MB RAM should give you a decent experience, but performance will benefit greatly from up to 2 GB.
|
79
|
-
|
80
|
-
### Docker / Podman
|
74
|
+
To avoid issues with version / dependency mismatches, Maloja should only be used in **Docker** or **Podman**, not on bare metal.
|
75
|
+
I cannot offer any help for bare metal installations.
|
81
76
|
|
82
77
|
Pull the [latest image](https://hub.docker.com/r/krateng/maloja) or check out the repository and use the included Containerfile.
|
83
78
|
|
@@ -96,11 +91,7 @@ An example of a minimum run configuration to access maloja via `localhost:42010`
|
|
96
91
|
docker run -p 42010:42010 -v $PWD/malojadata:/mljdata -e MALOJA_DATA_DIRECTORY=/mljdata krateng/maloja
|
97
92
|
```
|
98
93
|
|
99
|
-
|
100
|
-
|
101
|
-
**NOTE:** If you are using [rootless containers with Podman](https://developers.redhat.com/blog/2020/09/25/rootless-containers-with-podman-the-basics#why_podman_) this DOES NOT apply to you.
|
102
|
-
|
103
|
-
If you are running Docker on a **Linux Host** you should specify `user:group` ids of the user who owns the folder on the host machine bound to `MALOJA_DATA_DIRECTORY` in order to avoid [docker file permission problems.](https://ikriv.com/blog/?p=4698) These can be specified using the [environmental variables **PUID** and **PGID**.](https://docs.linuxserver.io/general/understanding-puid-and-pgid)
|
94
|
+
If you are using [rootless containers with Podman](https://developers.redhat.com/blog/2020/09/25/rootless-containers-with-podman-the-basics#why_podman_) the following DOES NOT apply to you, but if you are running **Docker** on a **Linux Host** you should specify `user:group` ids of the user who owns the folder on the host machine bound to `MALOJA_DATA_DIRECTORY` in order to avoid [docker file permission problems.](https://ikriv.com/blog/?p=4698) These can be specified using the [environmental variables **PUID** and **PGID**.](https://docs.linuxserver.io/general/understanding-puid-and-pgid)
|
104
95
|
|
105
96
|
To get the UID and GID for the current user run these commands from a terminal:
|
106
97
|
|
@@ -113,33 +104,6 @@ The modified run command with these variables would look like:
|
|
113
104
|
docker run -e PUID=1000 -e PGID=1001 -p 42010:42010 -v $PWD/malojadata:/mljdata -e MALOJA_DATA_DIRECTORY=/mljdata krateng/maloja
|
114
105
|
```
|
115
106
|
|
116
|
-
### PyPI
|
117
|
-
|
118
|
-
You can install Maloja with
|
119
|
-
|
120
|
-
```console
|
121
|
-
pip install malojaserver
|
122
|
-
```
|
123
|
-
|
124
|
-
To make sure all dependencies are installed, you can also use one of the included scripts in the `install` folder.
|
125
|
-
|
126
|
-
### From Source
|
127
|
-
|
128
|
-
Clone this repository and enter the directory with
|
129
|
-
|
130
|
-
```console
|
131
|
-
git clone https://github.com/krateng/maloja
|
132
|
-
cd maloja
|
133
|
-
```
|
134
|
-
|
135
|
-
Then install all the requirements and build the package, e.g.:
|
136
|
-
|
137
|
-
```console
|
138
|
-
sh ./install/install_dependencies_alpine.sh
|
139
|
-
pip install -r requirements.txt
|
140
|
-
pip install .
|
141
|
-
```
|
142
|
-
|
143
107
|
|
144
108
|
### Extras
|
145
109
|
|
@@ -160,7 +124,7 @@ When not running in a container, you can run the application with `maloja run`.
|
|
160
124
|
|
161
125
|
If you would like to import your previous scrobbles, use the command `maloja import *filename*`. This works on:
|
162
126
|
|
163
|
-
* a Last.fm export generated by [
|
127
|
+
* a Last.fm export generated by [ghan64's website](https://lastfm.ghan.nl/export/)
|
164
128
|
* an official [Spotify data export file](https://www.spotify.com/us/account/privacy/)
|
165
129
|
* an official [ListenBrainz export file](https://listenbrainz.org/profile/export/)
|
166
130
|
* the export of another Maloja instance
|