1
0
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:
Krateng 2019-11-21 23:14:53 +01:00
parent 3ebde4a187
commit 3c12462d36
9 changed files with 73 additions and 12 deletions

View File

@ -885,6 +885,18 @@ def search(**keys):
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
####

View File

@ -5,6 +5,6 @@ author = {
"email":"maloja@krateng.dev",
"github": "krateng"
}
version = 1,5,14
version = 1,5,15
versionstr = ".".join(str(n) for n in version)
dev = os.path.exists("./.dev")

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
# 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
# monkey patching
import monkey
@ -35,6 +35,8 @@ import urllib
#settings.update("settings/default.ini","settings/settings.ini")
MAIN_PORT = settings.get_settings("WEB_PORT")
HOST = settings.get_settings("HOST")
THREADS = 12
BaseRequest.MEMFILE_MAX = 15 * 1024 * 1024
webserver = Bottle()
@ -251,4 +253,5 @@ database.start_db()
database.dbserver.mount(server=webserver)
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)

View File

@ -8,6 +8,7 @@ import urllib
import datetime
import random
import itertools
import base64
from doreah import settings
from doreah import caching
from doreah.logging import log
@ -144,10 +145,10 @@ track_cache = caching.Cache(name="imgcache_tracks",maxage=cacheage,maxage_negati
def clean(name):
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
# (only remove non-alphanumeric, allow korean and stuff)
if title is not None and artists is not None:
track = True
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))
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 = []
for purename in filenames:
# direct files
for ext in ["png","jpg","jpeg","gif"]:
#for num in [""] + [str(n) for n in range(0,10)]:
if os.path.exists(superfolder + purename + "." + ext):
images.append("/" + superfolder + purename + "." + ext)
if os.path.exists(purename + "." + ext):
images.append("/" + purename + "." + ext)
# folder
try:
for f in os.listdir(superfolder + purename + "/"):
for f in os.listdir(purename + "/"):
if f.split(".")[-1] in ["png","jpg","jpeg","gif"]:
images.append("/" + superfolder + purename + "/" + f)
images.append("/" + purename + "/" + f)
except:
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))

View File

@ -48,7 +48,8 @@
<table class="top_info">
<tr>
<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 class="text">
<h1><pyhp echo="artist" /></h1>

View File

@ -8,3 +8,4 @@
<link rel="stylesheet" href="/css/style.css" />
<script src="/javascript/search.js" async></script>
<script src="/javascript/neopolitan.js"></script>
<script src="/javascript/upload.js"></script>

View File

@ -25,4 +25,12 @@ if(functions.length>0){supervisor();}
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();}}
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;}})

View File

@ -0,0 +1,3 @@
function upload(encodedentity,apikey,b64) {
neo.xhttprequest("/api/addpicture?key=" + apikey + "&" + encodedentity,{"b64":b64},"POST")
}

View File

@ -30,7 +30,8 @@
<table class="top_info">
<tr>
<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 class="text">
<span><pyhp echo="htmlgenerators.artistLinks(track['artists'])" /></span><br/>