mirror of
https://github.com/krateng/maloja.git
synced 2023-08-10 21:12:55 +03:00
Can now upload artist / track images from web
This commit is contained in:
parent
3ebde4a187
commit
3c12462d36
12
database.py
12
database.py
@ -885,6 +885,18 @@ def search(**keys):
|
|||||||
|
|
||||||
return {"artists":artists_result[:max_],"tracks":tracks_result[:max_]}
|
return {"artists":artists_result[:max_],"tracks":tracks_result[:max_]}
|
||||||
|
|
||||||
|
|
||||||
|
@dbserver.post("addpicture")
|
||||||
|
def add_picture(b64,key,artist:Multi=[],title=None):
|
||||||
|
if (checkAPIkey(key)):
|
||||||
|
keys = FormsDict()
|
||||||
|
for a in artist:
|
||||||
|
keys.append("artist",a)
|
||||||
|
if title is not None: keys.append("title",title)
|
||||||
|
k_filter, _, _, _ = uri_to_internal(keys)
|
||||||
|
if "track" in k_filter: k_filter = k_filter["track"]
|
||||||
|
utilities.set_image(b64,**k_filter)
|
||||||
|
|
||||||
####
|
####
|
||||||
## Server operation
|
## Server operation
|
||||||
####
|
####
|
||||||
|
2
info.py
2
info.py
@ -5,6 +5,6 @@ author = {
|
|||||||
"email":"maloja@krateng.dev",
|
"email":"maloja@krateng.dev",
|
||||||
"github": "krateng"
|
"github": "krateng"
|
||||||
}
|
}
|
||||||
version = 1,5,14
|
version = 1,5,15
|
||||||
versionstr = ".".join(str(n) for n in version)
|
versionstr = ".".join(str(n) for n in version)
|
||||||
dev = os.path.exists("./.dev")
|
dev = os.path.exists("./.dev")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# server stuff
|
# server stuff
|
||||||
from bottle import Bottle, route, get, post, error, run, template, static_file, request, response, FormsDict, redirect, template, HTTPResponse
|
from bottle import Bottle, route, get, post, error, run, template, static_file, request, response, FormsDict, redirect, template, HTTPResponse, BaseRequest
|
||||||
import waitress
|
import waitress
|
||||||
# monkey patching
|
# monkey patching
|
||||||
import monkey
|
import monkey
|
||||||
@ -35,6 +35,8 @@ import urllib
|
|||||||
#settings.update("settings/default.ini","settings/settings.ini")
|
#settings.update("settings/default.ini","settings/settings.ini")
|
||||||
MAIN_PORT = settings.get_settings("WEB_PORT")
|
MAIN_PORT = settings.get_settings("WEB_PORT")
|
||||||
HOST = settings.get_settings("HOST")
|
HOST = settings.get_settings("HOST")
|
||||||
|
THREADS = 12
|
||||||
|
BaseRequest.MEMFILE_MAX = 15 * 1024 * 1024
|
||||||
|
|
||||||
|
|
||||||
webserver = Bottle()
|
webserver = Bottle()
|
||||||
@ -251,4 +253,5 @@ database.start_db()
|
|||||||
database.dbserver.mount(server=webserver)
|
database.dbserver.mount(server=webserver)
|
||||||
|
|
||||||
log("Starting up Maloja server...")
|
log("Starting up Maloja server...")
|
||||||
run(webserver, host=HOST, port=MAIN_PORT, server='waitress')
|
#run(webserver, host=HOST, port=MAIN_PORT, server='waitress')
|
||||||
|
waitress.serve(webserver, host=HOST, port=MAIN_PORT, threads=THREADS)
|
||||||
|
44
utilities.py
44
utilities.py
@ -8,6 +8,7 @@ import urllib
|
|||||||
import datetime
|
import datetime
|
||||||
import random
|
import random
|
||||||
import itertools
|
import itertools
|
||||||
|
import base64
|
||||||
from doreah import settings
|
from doreah import settings
|
||||||
from doreah import caching
|
from doreah import caching
|
||||||
from doreah.logging import log
|
from doreah.logging import log
|
||||||
@ -144,10 +145,10 @@ track_cache = caching.Cache(name="imgcache_tracks",maxage=cacheage,maxage_negati
|
|||||||
def clean(name):
|
def clean(name):
|
||||||
return "".join(c for c in name if c.isalnum() or c in []).strip()
|
return "".join(c for c in name if c.isalnum() or c in []).strip()
|
||||||
|
|
||||||
def local_files(artist=None,artists=None,title=None):
|
def get_all_possible_filenames(artist=None,artists=None,title=None):
|
||||||
|
|
||||||
# check if we're dealing with a track or artist, then clean up names
|
# check if we're dealing with a track or artist, then clean up names
|
||||||
# (only remove non-alphanumeric, allow korean and stuff)
|
# (only remove non-alphanumeric, allow korean and stuff)
|
||||||
|
|
||||||
if title is not None and artists is not None:
|
if title is not None and artists is not None:
|
||||||
track = True
|
track = True
|
||||||
title, artists = clean(title), [clean(a) for a in artists]
|
title, artists = clean(title), [clean(a) for a in artists]
|
||||||
@ -203,20 +204,27 @@ def local_files(artist=None,artists=None,title=None):
|
|||||||
filenames = list(set(filenames))
|
filenames = list(set(filenames))
|
||||||
if len(filenames) == 0: filenames.append(str(hash(artist)))
|
if len(filenames) == 0: filenames.append(str(hash(artist)))
|
||||||
|
|
||||||
|
return [superfolder + name for name in filenames]
|
||||||
|
|
||||||
|
def local_files(artist=None,artists=None,title=None):
|
||||||
|
|
||||||
|
|
||||||
|
filenames = get_all_possible_filenames(artist,artists,title)
|
||||||
|
|
||||||
images = []
|
images = []
|
||||||
|
|
||||||
for purename in filenames:
|
for purename in filenames:
|
||||||
# direct files
|
# direct files
|
||||||
for ext in ["png","jpg","jpeg","gif"]:
|
for ext in ["png","jpg","jpeg","gif"]:
|
||||||
#for num in [""] + [str(n) for n in range(0,10)]:
|
#for num in [""] + [str(n) for n in range(0,10)]:
|
||||||
if os.path.exists(superfolder + purename + "." + ext):
|
if os.path.exists(purename + "." + ext):
|
||||||
images.append("/" + superfolder + purename + "." + ext)
|
images.append("/" + purename + "." + ext)
|
||||||
|
|
||||||
# folder
|
# folder
|
||||||
try:
|
try:
|
||||||
for f in os.listdir(superfolder + purename + "/"):
|
for f in os.listdir(purename + "/"):
|
||||||
if f.split(".")[-1] in ["png","jpg","jpeg","gif"]:
|
if f.split(".")[-1] in ["png","jpg","jpeg","gif"]:
|
||||||
images.append("/" + superfolder + purename + "/" + f)
|
images.append("/" + purename + "/" + f)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -416,8 +424,32 @@ def resolveImage(artist=None,track=None):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def set_image(b64,**keys):
|
||||||
|
track = "title" in keys
|
||||||
|
|
||||||
|
regex = r"data:image/(\w+);base64,(.+)"
|
||||||
|
type,b64 = re.fullmatch(regex,b64).groups()
|
||||||
|
print(b64[:40])
|
||||||
|
b64 = base64.b64decode(b64)
|
||||||
|
filename = "webupload" + str(int(datetime.datetime.now().timestamp())) + "." + type
|
||||||
|
for folder in get_all_possible_filenames(**keys):
|
||||||
|
if os.path.exists(folder):
|
||||||
|
with open(os.path.join(folder,filename),"wb") as f:
|
||||||
|
f.write(b64)
|
||||||
|
|
||||||
|
# set as current picture in rotation
|
||||||
|
if track: local_track_cache.add((frozenset(keys["artists"]),keys["title"]),os.path.join(folder,filename))
|
||||||
|
else: local_artist_cache.add(keys["artist"],os.path.join(folder,filename))
|
||||||
|
return
|
||||||
|
|
||||||
|
folder = get_all_possible_filenames(**keys)[0]
|
||||||
|
os.makedirs(folder)
|
||||||
|
with open(os.path.join(folder,filename),"wb") as f:
|
||||||
|
f.write(b64)
|
||||||
|
|
||||||
|
# set as current picture in rotation
|
||||||
|
if track: local_track_cache.add((frozenset(keys["artists"]),keys["title"]),os.path.join(folder,filename))
|
||||||
|
else: local_artist_cache.add(keys["artist"],os.path.join(folder,filename))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,7 +48,8 @@
|
|||||||
<table class="top_info">
|
<table class="top_info">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="image">
|
<td class="image">
|
||||||
<div style="background-image:url('{utilities.getArtistImage(artist=artist,fast=True)}');"></div>
|
<pyhp if="adminmode"><div class="changeable-image" data-uploader="b64=>upload('{encodedartist}','{apikey}',b64)" style="background-image:url('{utilities.getArtistImage(artist=artist,fast=True)}');"></div></pyhp>
|
||||||
|
<pyhp if="not adminmode"><div style="background-image:url('{utilities.getArtistImage(artist=artist,fast=True)}');"></div></pyhp>
|
||||||
</td>
|
</td>
|
||||||
<td class="text">
|
<td class="text">
|
||||||
<h1><pyhp echo="artist" /></h1>
|
<h1><pyhp echo="artist" /></h1>
|
||||||
|
@ -8,3 +8,4 @@
|
|||||||
<link rel="stylesheet" href="/css/style.css" />
|
<link rel="stylesheet" href="/css/style.css" />
|
||||||
<script src="/javascript/search.js" async></script>
|
<script src="/javascript/search.js" async></script>
|
||||||
<script src="/javascript/neopolitan.js"></script>
|
<script src="/javascript/neopolitan.js"></script>
|
||||||
|
<script src="/javascript/upload.js"></script>
|
||||||
|
@ -25,4 +25,12 @@ if(functions.length>0){supervisor();}
|
|||||||
var body=document.getElementsByTagName("BODY")[0]
|
var body=document.getElementsByTagName("BODY")[0]
|
||||||
if(body.getAttribute("data-linkinterceptor")!=undefined){var interceptor=eval(body.getAttribute("data-linkinterceptor"));function interceptClickEvent(e){var href;var target=e.target||e.srcElement;if(target.tagName==='A'&&!target.classList.contains("no-intercept")){href=target.getAttribute('href');e.preventDefault();history.pushState({},"",href);interceptor();}}
|
if(body.getAttribute("data-linkinterceptor")!=undefined){var interceptor=eval(body.getAttribute("data-linkinterceptor"));function interceptClickEvent(e){var href;var target=e.target||e.srcElement;if(target.tagName==='A'&&!target.classList.contains("no-intercept")){href=target.getAttribute('href');e.preventDefault();history.pushState({},"",href);interceptor();}}
|
||||||
document.addEventListener('click',interceptClickEvent);}},false);document.addEventListener('keyup',function(evt){if(evt.srcElement.tagName=="INPUT"){return;}
|
document.addEventListener('click',interceptClickEvent);}},false);document.addEventListener('keyup',function(evt){if(evt.srcElement.tagName=="INPUT"){return;}
|
||||||
var elements=document.querySelectorAll('[data-hotkey]');for(let e of elements){if(e.getAttribute("data-hotkey")==evt.code){evt.preventDefault();e.onclick();break;}}},false);
|
var elements=document.querySelectorAll('[data-hotkey]');for(let e of elements){if(e.getAttribute("data-hotkey")==evt.code){evt.preventDefault();e.onclick();break;}}},false);function dragover(evt){evt.preventDefault();}
|
||||||
|
function readImageFile(evt,crop=false){evt.preventDefault();var element=this;var file=evt.dataTransfer.files[0];var reader=new FileReader();reader.onload=(function(evt){parseImage(reader.result,element,crop);});reader.readAsArrayBuffer(file);}
|
||||||
|
function parseImage(buffer,element,crop){var binary='';var bytes=new Uint8Array(buffer);var len=bytes.byteLength;for(var i=0;i<len;i++){binary+=String.fromCharCode(bytes[i]);}
|
||||||
|
b64=window.btoa(binary);cropImage(b64,element,crop)
|
||||||
|
}
|
||||||
|
function cropImage(b64,element,crop){var img=new Image;img.src="data:image/png;base64,"+b64;img.onload=function(){if(crop){x=element.offsetWidth;y=element.offsetHeight;var canvas=document.createElement('canvas'),ctx=canvas.getContext('2d');wid=img.width;heig=img.height;wid_resize=x/wid;heig_resize=y/heig;resize=Math.max(wid_resize,heig_resize);use_wid=x/resize;use_heig=y/resize;new_wid=wid*resize;new_heig=heig*resize;crop_left=(new_wid-x)/(2*resize);crop_top=(new_heig-y)/(2*resize);canvas.width=x;canvas.height=y;ctx.drawImage(img,crop_left,crop_top,use_wid,use_heig,0,0,x,y);done=canvas.toDataURL();}
|
||||||
|
else{var canvas=document.createElement('canvas'),ctx=canvas.getContext('2d');canvas.width=img.width;canvas.height=img.height;ctx.drawImage(img,0,0);done=canvas.toDataURL();}
|
||||||
|
element.style.backgroundImage="url('"+done+"')";var callback=element.getAttribute("data-uploader");if(callback!=undefined){eval(callback)(done);}}}
|
||||||
|
document.addEventListener('DOMContentLoaded',function(){var elements=document.getElementsByClassName("changeable-image");for(var i=0;i<elements.length;i++){elements[i].ondragover=dragover;elements[i].ondrop=readImageFile;}})
|
3
website/javascript/upload.js
Normal file
3
website/javascript/upload.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function upload(encodedentity,apikey,b64) {
|
||||||
|
neo.xhttprequest("/api/addpicture?key=" + apikey + "&" + encodedentity,{"b64":b64},"POST")
|
||||||
|
}
|
@ -30,7 +30,8 @@
|
|||||||
<table class="top_info">
|
<table class="top_info">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="image">
|
<td class="image">
|
||||||
<div style="background-image:url('{utilities.getTrackImage(track['artists'],track['title'],fast=True)}')"></div>
|
<pyhp if="adminmode"><div class="changeable-image" data-uploader="b64=>upload('{encodedtrack}','{apikey}',b64)" style="background-image:url('{utilities.getTrackImage(track['artists'],track['title'],fast=True)}')"></div></pyhp>
|
||||||
|
<pyhp if="not adminmode"><div style="background-image:url('{utilities.getTrackImage(track['artists'],track['title'],fast=True)}')"></div></pyhp>
|
||||||
</td>
|
</td>
|
||||||
<td class="text">
|
<td class="text">
|
||||||
<span><pyhp echo="htmlgenerators.artistLinks(track['artists'])" /></span><br/>
|
<span><pyhp echo="htmlgenerators.artistLinks(track['artists'])" /></span><br/>
|
||||||
|
Loading…
Reference in New Issue
Block a user