mirror of
https://github.com/krateng/maloja.git
synced 2023-08-10 21:12:55 +03:00
Better install script, some imports moved out of functions
This commit is contained in:
parent
4b3cd8cce3
commit
b65d65326c
11
README.md
11
README.md
@ -24,8 +24,9 @@ The software works fairly well and has a few web views, but there is only one sc
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
* [bottle.py](https://github.com/bottlepy/bottle)
|
* [python3](https://www.python.org/) - [GitHub](https://github.com/python/cpython)
|
||||||
* [waitress](https://github.com/Pylons/waitress)
|
* [bottle.py](https://bottlepy.org/) - [GitHub](https://github.com/bottlepy/bottle)
|
||||||
|
* [waitress](https://docs.pylonsproject.org/projects/waitress/) - [GitHub](https://github.com/Pylons/waitress)
|
||||||
|
|
||||||
## How to install
|
## How to install
|
||||||
|
|
||||||
@ -37,6 +38,12 @@ Installing Maloja is fairly easy on a Linux machine. Don't ask me how to do it o
|
|||||||
|
|
||||||
If you're missing packages, the console output will tell you so. Install them.
|
If you're missing packages, the console output will tell you so. Install them.
|
||||||
|
|
||||||
|
You can also only download the maloja file itself and run
|
||||||
|
|
||||||
|
./maloja update
|
||||||
|
|
||||||
|
to download the rest of the repository, then start it as described above.
|
||||||
|
|
||||||
2) (Recommended) Put your server behind a reverse proxy for SSL encryption. Configure that proxy to rewrite /db/ requests to the database port. In nginx this would look as follows:
|
2) (Recommended) Put your server behind a reverse proxy for SSL encryption. Configure that proxy to rewrite /db/ requests to the database port. In nginx this would look as follows:
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
|
@ -232,7 +232,6 @@ def get_tracks_external():
|
|||||||
|
|
||||||
def get_tracks(artist=None):
|
def get_tracks(artist=None):
|
||||||
|
|
||||||
|
|
||||||
if artist is not None:
|
if artist is not None:
|
||||||
artistid = ARTISTS.index(artist)
|
artistid = ARTISTS.index(artist)
|
||||||
else:
|
else:
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
import urllib
|
||||||
|
from bottle import FormsDict
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
def artistLink(name):
|
def artistLink(name):
|
||||||
import urllib
|
|
||||||
return "<a href='/artist?artist=" + urllib.parse.quote(name) + "'>" + name + "</a>"
|
return "<a href='/artist?artist=" + urllib.parse.quote(name) + "'>" + name + "</a>"
|
||||||
|
|
||||||
def artistLinks(artists):
|
def artistLinks(artists):
|
||||||
@ -11,25 +12,21 @@ def artistLinks(artists):
|
|||||||
#def trackLink(artists,title):
|
#def trackLink(artists,title):
|
||||||
def trackLink(track):
|
def trackLink(track):
|
||||||
artists,title = track["artists"],track["title"]
|
artists,title = track["artists"],track["title"]
|
||||||
import urllib
|
|
||||||
return "<a href='/track?title=" + urllib.parse.quote(title) + "&" + "&".join(["artist=" + urllib.parse.quote(a) for a in artists]) + "'>" + title + "</a>"
|
return "<a href='/track?title=" + urllib.parse.quote(title) + "&" + "&".join(["artist=" + urllib.parse.quote(a) for a in artists]) + "'>" + title + "</a>"
|
||||||
|
|
||||||
#def scrobblesTrackLink(artists,title,timekeys,amount=None,pixels=None):
|
#def scrobblesTrackLink(artists,title,timekeys,amount=None,pixels=None):
|
||||||
def scrobblesTrackLink(track,timekeys,amount=None,percent=None):
|
def scrobblesTrackLink(track,timekeys,amount=None,percent=None):
|
||||||
artists,title = track["artists"],track["title"]
|
artists,title = track["artists"],track["title"]
|
||||||
import urllib
|
|
||||||
inner = str(amount) if amount is not None else "<div style='width:" + str(percent) + "%;'></div>"
|
inner = str(amount) if amount is not None else "<div style='width:" + str(percent) + "%;'></div>"
|
||||||
return "<a href='/scrobbles?" + "&".join(["artist=" + urllib.parse.quote(a) for a in artists]) + "&title=" + urllib.parse.quote(title) + "&" + keysToUrl(timekeys) + "'>" + inner + "</a>"
|
return "<a href='/scrobbles?" + "&".join(["artist=" + urllib.parse.quote(a) for a in artists]) + "&title=" + urllib.parse.quote(title) + "&" + keysToUrl(timekeys) + "'>" + inner + "</a>"
|
||||||
|
|
||||||
def scrobblesArtistLink(artist,timekeys,amount=None,percent=None,associated=False):
|
def scrobblesArtistLink(artist,timekeys,amount=None,percent=None,associated=False):
|
||||||
import urllib
|
|
||||||
inner = str(amount) if amount is not None else "<div style='width:" + str(percent) + "%;'></div>"
|
inner = str(amount) if amount is not None else "<div style='width:" + str(percent) + "%;'></div>"
|
||||||
askey = "&associated" if associated else ""
|
askey = "&associated" if associated else ""
|
||||||
return "<a href='/scrobbles?artist=" + urllib.parse.quote(artist) + "&" + keysToUrl(timekeys) + askey + "'>" + inner + "</a>"
|
return "<a href='/scrobbles?artist=" + urllib.parse.quote(artist) + "&" + keysToUrl(timekeys) + askey + "'>" + inner + "</a>"
|
||||||
|
|
||||||
# necessary because urllib.parse.urlencode doesnt handle multidicts
|
# necessary because urllib.parse.urlencode doesnt handle multidicts
|
||||||
def keysToUrl(*dicts):
|
def keysToUrl(*dicts):
|
||||||
import urllib
|
|
||||||
st = ""
|
st = ""
|
||||||
keys = removeIdentical(*dicts)
|
keys = removeIdentical(*dicts)
|
||||||
for k in keys:
|
for k in keys:
|
||||||
@ -39,8 +36,6 @@ def keysToUrl(*dicts):
|
|||||||
return st
|
return st
|
||||||
|
|
||||||
def removeIdentical(*dicts):
|
def removeIdentical(*dicts):
|
||||||
from bottle import FormsDict
|
|
||||||
|
|
||||||
#combine multiple dicts
|
#combine multiple dicts
|
||||||
keys = FormsDict()
|
keys = FormsDict()
|
||||||
for d in dicts:
|
for d in dicts:
|
||||||
@ -61,7 +56,6 @@ def removeIdentical(*dicts):
|
|||||||
return new
|
return new
|
||||||
|
|
||||||
def getTimeDesc(timestamp,short=False):
|
def getTimeDesc(timestamp,short=False):
|
||||||
import datetime
|
|
||||||
tim = datetime.datetime.utcfromtimestamp(timestamp)
|
tim = datetime.datetime.utcfromtimestamp(timestamp)
|
||||||
if short:
|
if short:
|
||||||
now = datetime.datetime.now(tz=datetime.timezone.utc)
|
now = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||||
@ -87,7 +81,6 @@ def getTimeDesc(timestamp,short=False):
|
|||||||
# limit a multidict to only the specified keys
|
# limit a multidict to only the specified keys
|
||||||
# would be a simple constructor expression, but multidicts apparently don't let me do that
|
# would be a simple constructor expression, but multidicts apparently don't let me do that
|
||||||
def pickKeys(d,*keys):
|
def pickKeys(d,*keys):
|
||||||
from bottle import FormsDict
|
|
||||||
if isinstance(d,dict):
|
if isinstance(d,dict):
|
||||||
return {k:d.get(k) for k in d if k in keys}
|
return {k:d.get(k) for k in d if k in keys}
|
||||||
else:
|
else:
|
||||||
@ -103,7 +96,6 @@ def pickKeys(d,*keys):
|
|||||||
|
|
||||||
# removes all duplicate keys, except artists when a title is specified
|
# removes all duplicate keys, except artists when a title is specified
|
||||||
def clean(d):
|
def clean(d):
|
||||||
from bottle import FormsDict
|
|
||||||
if isinstance(d,dict):
|
if isinstance(d,dict):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
2
logs/.gitignore
vendored
2
logs/.gitignore
vendored
@ -1 +1 @@
|
|||||||
*.txt
|
*.log
|
||||||
|
85
maloja
85
maloja
@ -13,24 +13,99 @@ neededmodules = [
|
|||||||
"setproctitle"
|
"setproctitle"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
recommendedmodules = [
|
||||||
|
"wand"
|
||||||
|
]
|
||||||
|
|
||||||
SOURCE_URL = "https://github.com/krateng/maloja/archive/master.zip"
|
SOURCE_URL = "https://github.com/krateng/maloja/archive/master.zip"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def install():
|
def install():
|
||||||
toinstall = []
|
toinstall = []
|
||||||
|
toinstallr = []
|
||||||
for m in neededmodules:
|
for m in neededmodules:
|
||||||
try:
|
try:
|
||||||
exec("import " + m) #I'm sorry
|
exec("import " + m) #I'm sorry
|
||||||
except:
|
except:
|
||||||
toinstall.append(m)
|
toinstall.append(m)
|
||||||
|
|
||||||
|
for m in recommendedmodules:
|
||||||
|
try:
|
||||||
|
exec("import " + m)
|
||||||
|
except:
|
||||||
|
toinstallr.append(m)
|
||||||
|
|
||||||
if toinstall != []:
|
if toinstall != []:
|
||||||
print("The following python modules need to be installed:")
|
print("The following python modules need to be installed:")
|
||||||
for m in toinstall:
|
for m in toinstall:
|
||||||
print("\t" + m)
|
print("\t" + m)
|
||||||
|
if toinstallr != []:
|
||||||
|
print("The following python modules are highly recommended, some features will not work without them:")
|
||||||
|
for m in toinstallr:
|
||||||
|
print("\t" + m)
|
||||||
|
|
||||||
|
if toinstall != [] or toinstallr != []:
|
||||||
|
if os.geteuid() != 0:
|
||||||
|
print("Installing python modules should be fairly straight-forward, but Maloja can try to install \
|
||||||
|
them automatically. For this, you need to run this script as a root user.")
|
||||||
|
return False
|
||||||
else:
|
else:
|
||||||
return
|
print("Installing python modules should be fairly straight-forward, but Maloja can try to install \
|
||||||
|
them automatically, This might or might not work / bloat your system / cause a nuclear war.")
|
||||||
|
fail = False
|
||||||
|
if toinstall != []:
|
||||||
|
print("Attempt to install required modules? [Y/n]")
|
||||||
|
answer = input()
|
||||||
|
|
||||||
|
if answer.lower() in ["y","yes","yea","1","positive","true"]:
|
||||||
|
for m in neededmodules:
|
||||||
|
try:
|
||||||
|
print("Installing " + m + " with pip...")
|
||||||
|
import pip
|
||||||
|
#os.system("pip3 install " + m)
|
||||||
|
pip.main(["install",m])
|
||||||
|
print("Success!")
|
||||||
|
except:
|
||||||
|
print("Failure!")
|
||||||
|
fail = True
|
||||||
|
|
||||||
|
elif answer.lower() in ["n","no","nay","0","negative","false"]:
|
||||||
|
return False #if you dont want to auto install required, you probably dont want to install recommended
|
||||||
|
else:
|
||||||
|
print("What?")
|
||||||
|
return False
|
||||||
|
if toinstallr != []:
|
||||||
|
print("Attempt to install recommended modules? [Y/n]")
|
||||||
|
answer = input()
|
||||||
|
|
||||||
|
if answer.lower() in ["y","yes","yea","1","positive","true",""]:
|
||||||
|
for m in recommendedmodules:
|
||||||
|
try:
|
||||||
|
print("Installing " + m + " with pip...")
|
||||||
|
import pip
|
||||||
|
#os.system("pip3 install " + m)
|
||||||
|
pip.main(["install",m])
|
||||||
|
print("Success!")
|
||||||
|
except:
|
||||||
|
print("Failure!")
|
||||||
|
fail = True
|
||||||
|
|
||||||
|
elif answer.lower() in ["n","no","nay","0","negative","false"]:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print("What?")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if fail: return False
|
||||||
|
print("All modules successfully installed!")
|
||||||
|
return True
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("All necessary modules seem to be installed.")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getInstance():
|
def getInstance():
|
||||||
try:
|
try:
|
||||||
@ -44,7 +119,7 @@ def getInstance():
|
|||||||
|
|
||||||
|
|
||||||
def start():
|
def start():
|
||||||
install()
|
if install():
|
||||||
|
|
||||||
try:
|
try:
|
||||||
p = subprocess.Popen(["python3","server.py"],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)
|
p = subprocess.Popen(["python3","server.py"],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)
|
||||||
@ -55,6 +130,7 @@ def start():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def restart():
|
def restart():
|
||||||
#pid = getInstance()
|
#pid = getInstance()
|
||||||
#if pid == None:
|
#if pid == None:
|
||||||
@ -73,8 +149,8 @@ def stop():
|
|||||||
print("Server is not running")
|
print("Server is not running")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
print("Stopping " + str(pid))
|
|
||||||
os.kill(pid,signal.SIGTERM)
|
os.kill(pid,signal.SIGTERM)
|
||||||
|
print("Maloja stopped! PID: " + str(pid))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update():
|
def update():
|
||||||
@ -93,7 +169,7 @@ def update():
|
|||||||
with zipfile.ZipFile(tmpfile.name,"r") as z:
|
with zipfile.ZipFile(tmpfile.name,"r") as z:
|
||||||
|
|
||||||
for f in z.namelist():
|
for f in z.namelist():
|
||||||
print("extracting " + f)
|
#print("extracting " + f)
|
||||||
z.extract(f)
|
z.extract(f)
|
||||||
|
|
||||||
|
|
||||||
@ -112,4 +188,5 @@ if __name__ == "__main__":
|
|||||||
elif sys.argv[1] == "restart": restart()
|
elif sys.argv[1] == "restart": restart()
|
||||||
elif sys.argv[1] == "stop": stop()
|
elif sys.argv[1] == "stop": stop()
|
||||||
elif sys.argv[1] == "update": update()
|
elif sys.argv[1] == "update": update()
|
||||||
|
else: print("Valid commands: start restart stop update")
|
||||||
|
|
||||||
|
@ -162,7 +162,8 @@ def log(msg):
|
|||||||
module = inspect.getmodule(inspect.stack()[1][0]).__name__
|
module = inspect.getmodule(inspect.stack()[1][0]).__name__
|
||||||
if module == "__main__": module = "mainserver"
|
if module == "__main__": module = "mainserver"
|
||||||
print("[" + module + "] " + msg)
|
print("[" + module + "] " + msg)
|
||||||
# best function ever
|
with open("logs/" + module + ".log","a") as logfile:
|
||||||
|
logfile.write(msg + "\n")
|
||||||
|
|
||||||
|
|
||||||
### Media info
|
### Media info
|
||||||
|
@ -272,7 +272,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<span>Get your own Maloja scrobble server on <a href="https://github.com/krateng/maloja">GitHub</a></span>
|
<span>Get your own Maloja scrobble server on <a target="_blank" rel="noopener noreferrer" href="https://github.com/krateng/maloja">GitHub</a></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user