mirror of
https://github.com/krateng/maloja.git
synced 2023-08-10 21:12:55 +03:00
Moved logging and timing to doreah
This commit is contained in:
parent
5cd6752510
commit
5765687f9d
@ -6,6 +6,7 @@ import os
|
||||
import datetime
|
||||
from cleanup import *
|
||||
from utilities import *
|
||||
from doreah.logging import log
|
||||
from malojatime import *
|
||||
import sys
|
||||
import unicodedata
|
||||
|
102
doreah/logging.py
Normal file
102
doreah/logging.py
Normal file
@ -0,0 +1,102 @@
|
||||
import datetime
|
||||
import inspect
|
||||
import os
|
||||
|
||||
from ._internal import defaultarguments, gopen
|
||||
|
||||
_config = {}
|
||||
|
||||
_queue = []
|
||||
_locked = False
|
||||
|
||||
# set configuration
|
||||
# logfolder folder to store logfiles in
|
||||
# timeformat strftime format for log files
|
||||
# defaultmodule name for the main running script
|
||||
# verbosity higher means more (less important) messages are shown on console
|
||||
def config(logfolder="logs",timeformat="%Y/%m/%d %H:%M:%S",defaultmodule="main",verbosity=0):
|
||||
global _config
|
||||
_config["logfolder"] = logfolder
|
||||
_config["timeformat"] = timeformat
|
||||
_config["defaultmodule"] = defaultmodule
|
||||
_config["verbosity"] = verbosity
|
||||
|
||||
|
||||
# initial config on import, set everything to default
|
||||
config()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Log entry
|
||||
# module allows discrimination between modules of a program. Will be prepended in console output and will determine the separate file for disk storage
|
||||
# defaults to actual name of the calling module or "main" for the main script
|
||||
# header determines the hierarchical position of the entry.
|
||||
# indent adds indent to the log entry
|
||||
# importance low means important. if higher than the configured verbosity, entry will not be shown on console
|
||||
def log(*msgs,module=None,header=None,indent=0,importance=0):
|
||||
|
||||
now = datetime.datetime.utcnow().strftime(_config["timeformat"])
|
||||
|
||||
# log() can be used to add empty line
|
||||
if len(msgs) == 0: msgs = ("",)
|
||||
|
||||
# make it easier to log data structures and such
|
||||
msgs = tuple([str(msg) for msg in msgs])
|
||||
|
||||
# header formating
|
||||
if header == 2:
|
||||
msgs = ("","","####") + msgs + ("####","")
|
||||
elif header == 1:
|
||||
msgs = ("","","","# # # # #","") + msgs + ("","# # # # #","","")
|
||||
|
||||
# indent
|
||||
prefix = "\t" * indent
|
||||
|
||||
# module name
|
||||
if module is None:
|
||||
try:
|
||||
module = inspect.getmodule(inspect.stack()[1][0]).__name__
|
||||
if module == "__main__": module = _config["defaultmodule"]
|
||||
except:
|
||||
module = "interpreter"
|
||||
|
||||
global _locked, _queue
|
||||
if _locked:
|
||||
for msg in msgs:
|
||||
_queue.append({"time":now,"prefix":prefix,"msg":msg,"module":module,"console":(importance <= _config["verbosity"])})
|
||||
else:
|
||||
# console output
|
||||
if (importance <= _config["verbosity"]):
|
||||
for msg in msgs:
|
||||
print("[" + module + "] " + prefix + msg)
|
||||
|
||||
# file output
|
||||
logfilename = _config["logfolder"] + "/" + module + ".log"
|
||||
#os.makedirs(os.path.dirname(logfilename), exist_ok=True)
|
||||
with gopen(logfilename,"a") as logfile:
|
||||
for msg in msgs:
|
||||
logfile.write(now + " " + prefix + msg + "\n")
|
||||
|
||||
|
||||
def flush():
|
||||
global _queue
|
||||
for entry in _queue:
|
||||
# console output
|
||||
if entry["console"]:
|
||||
print("[" + entry["module"] + "] " + entry["prefix"] + entry["msg"])
|
||||
|
||||
# file output
|
||||
logfilename = _config["logfolder"] + "/" + entry["module"] + ".log"
|
||||
#os.makedirs(os.path.dirname(logfilename), exist_ok=True)
|
||||
with gopen(logfilename,"a") as logfile:
|
||||
logfile.write(entry["time"] + " " + entry["prefix"] + entry["msg"] + "\n")
|
||||
|
||||
_queue = []
|
||||
|
||||
# Quicker way to add header
|
||||
def logh1(*args,**kwargs):
|
||||
return log(*args,**kwargs,header=1)
|
||||
def logh2(*args,**kwargs):
|
||||
return log(*args,**kwargs,header=2)
|
40
doreah/persistence.py
Normal file
40
doreah/persistence.py
Normal file
@ -0,0 +1,40 @@
|
||||
import pickle
|
||||
import os
|
||||
|
||||
from ._internal import defaultarguments, gopen
|
||||
|
||||
_config = {}
|
||||
|
||||
# set configuration
|
||||
# folder folder to store log files
|
||||
def config(folder="storage"):
|
||||
global _config
|
||||
_config["folder"] = folder
|
||||
|
||||
|
||||
# initial config on import, set everything to default
|
||||
config()
|
||||
|
||||
@defaultarguments(_config,folder="folder")
|
||||
def save(data,name,folder):
|
||||
|
||||
filename = os.path.join(folder,name + ".gilly")
|
||||
|
||||
fl = gopen(filename,"wb")
|
||||
stream = pickle.dumps(data)
|
||||
fl.write(stream)
|
||||
fl.close()
|
||||
|
||||
@defaultarguments(_config,folder="folder")
|
||||
def load(name,folder):
|
||||
|
||||
filename = os.path.join(folder,name + ".gilly")
|
||||
|
||||
try:
|
||||
fl = gopen(filename,"rb")
|
||||
ob = pickle.loads(fl.read())
|
||||
except: ob = None
|
||||
finally:
|
||||
fl.close()
|
||||
|
||||
return ob
|
44
doreah/timing.py
Normal file
44
doreah/timing.py
Normal file
@ -0,0 +1,44 @@
|
||||
import time
|
||||
|
||||
from ._internal import defaultarguments
|
||||
|
||||
_config = {}
|
||||
|
||||
|
||||
# set configuration
|
||||
# si 0 means seconds, 1 ms, 2 μs, 3 ns etc
|
||||
def config(si=0):
|
||||
global _config
|
||||
_config["si"] = si
|
||||
|
||||
|
||||
# initial config on import, set everything to default
|
||||
config()
|
||||
|
||||
|
||||
# Take clock. Returns time passed since last call of this function. if called with an identifier, will only
|
||||
# consider calls with that identifier. No identifier means any call is valid.
|
||||
# identifiers arbitrary strings to remember different timers. guaranteed to set all timers to exactly the same time for
|
||||
# all identifiers in one call. will return tuple of all identifiers, singular value if only one identifier
|
||||
def clock(*identifiers,lastcalls={None:None}):
|
||||
|
||||
if len(identifiers) == 0: identifiers = (None,)
|
||||
|
||||
now = time.time()
|
||||
# get last calls
|
||||
stamps = (lastcalls.get(i) for i in identifiers)
|
||||
results = tuple(None if lc is None else (now - lc) * (1000**_config["si"]) for lc in stamps)
|
||||
if len(results) == 1: results = results[0]
|
||||
|
||||
# set new stamps
|
||||
for i in identifiers:
|
||||
lastcalls[i] = now
|
||||
lastcalls[None] = now # always save last overall call so we can directly access it
|
||||
|
||||
return results
|
||||
|
||||
|
||||
|
||||
def clockp(name,*identifiers):
|
||||
time = clock(*identifiers)
|
||||
print(name + ": " + str(time))
|
115
doreah/tsv.py
Normal file
115
doreah/tsv.py
Normal file
@ -0,0 +1,115 @@
|
||||
import os
|
||||
|
||||
from ._internal import defaultarguments
|
||||
|
||||
_config = {}
|
||||
|
||||
# set configuration
|
||||
# defaultextension files with this extension will be regarded as valid files. can be overwritten per request.
|
||||
# comments whether files may include commenting (indicated by #)
|
||||
# multitab whether fields can be separated by multiple tabs (this makes empty fields impossible except when trailing)
|
||||
def config(defaultextension=".tsv",comments=True,multitab=True):
|
||||
global _config
|
||||
_config["defaultextension"] = defaultextension
|
||||
_config["comments"] = comments
|
||||
_config["multitab"] = multitab
|
||||
|
||||
|
||||
# initial config on import, set everything to default
|
||||
config()
|
||||
|
||||
|
||||
@defaultarguments(_config,comments="comments",multitab="multitab")
|
||||
def parse(filename,*args,comments,multitab):
|
||||
|
||||
if not os.path.exists(filename):
|
||||
filename = filename + _config["defaultextension"]
|
||||
|
||||
f = open(filename)
|
||||
|
||||
result = []
|
||||
for l in [l for l in f if (not l.startswith("#")) and (not l.strip()=="")]:
|
||||
l = l.replace("\n","")
|
||||
|
||||
# if the file allows comments, we need to replace the escape sequence and properly stop parsing for inline comments
|
||||
if comments:
|
||||
l = l.split("#")[0]
|
||||
l = l.replace(r"\num","#")
|
||||
l = l.replace(r"\hashtag","#")
|
||||
|
||||
# we either allow multiple tabs, or we don't (in which case empty fields are possible)
|
||||
if multitab:
|
||||
data = list(filter(None,l.split("\t")))
|
||||
else:
|
||||
data = list(l.split("\t"))
|
||||
|
||||
entry = [] * len(args)
|
||||
for i in range(len(args)):
|
||||
if args[i] in ["list","ls","array"]:
|
||||
try:
|
||||
entry.append(data[i].split("␟"))
|
||||
except:
|
||||
entry.append([])
|
||||
elif args[i] in ["string","str","text"]:
|
||||
try:
|
||||
entry.append(data[i])
|
||||
except:
|
||||
entry.append("")
|
||||
elif args[i] in ["int","integer","num","number"]:
|
||||
try:
|
||||
entry.append(int(data[i]))
|
||||
except:
|
||||
entry.append(0)
|
||||
elif args[i] in ["bool","boolean"]:
|
||||
try:
|
||||
entry.append((data[i].lower() in ["true","yes","1","y"]))
|
||||
except:
|
||||
entry.append(False)
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
result.append(entry)
|
||||
|
||||
f.close()
|
||||
return result
|
||||
|
||||
@defaultarguments(_config,extension="defaultextension")
|
||||
def parse_all(path,*args,extension,**kwargs):
|
||||
|
||||
result = []
|
||||
for f in os.listdir(path + "/"):
|
||||
if (f.endswith(extension)): # use "" if all files are valid
|
||||
result += parse(path + "/" + f,*args,**kwargs)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def create(filename):
|
||||
|
||||
if not os.path.exists(filename):
|
||||
open(filename,"w").close()
|
||||
|
||||
@defaultarguments(_config,comments="comments")
|
||||
def add_entry(filename,a,comments):
|
||||
|
||||
create(filename)
|
||||
# remove all tabs and create tab-separated string
|
||||
line = "\t".join([str(e).replace("\t"," ") for e in a])
|
||||
|
||||
# replace comment symbol
|
||||
if comments: line = line.replace("#",r"\num")
|
||||
|
||||
with open(filename,"a") as f:
|
||||
f.write(line + "\n")
|
||||
|
||||
@defaultarguments(_config,comments="comments")
|
||||
def add_entries(filename,al,comments):
|
||||
|
||||
create(filename)
|
||||
|
||||
with open(filename,"a") as f:
|
||||
for a in al:
|
||||
line = "\t".join([str(e).replace("\t"," ") for e in a])
|
||||
if comments: line = line.replace("#",r"\num")
|
||||
f.write(line + "\n")
|
@ -1,7 +1,7 @@
|
||||
import os
|
||||
import re
|
||||
from cleanup import CleanerAgent
|
||||
from utilities import log
|
||||
from doreah.logging import log
|
||||
import difflib
|
||||
|
||||
wendigo = CleanerAgent()
|
||||
@ -13,34 +13,34 @@ for fn in os.listdir("scrobbles/"):
|
||||
f = open("scrobbles/" + fn)
|
||||
fnew = open("scrobbles/" + fn + "_new","w")
|
||||
for l in f:
|
||||
|
||||
|
||||
a,t = re.sub(exp,r"\3",l), re.sub(exp,r"\5",l)
|
||||
r1,r2,r3 = re.sub(exp,r"\1\2",l),re.sub(exp,r"\4",l),re.sub(exp,r"\6\7",l)
|
||||
|
||||
|
||||
a = a.replace("␟",";")
|
||||
|
||||
|
||||
(al,t) = wendigo.fullclean(a,t)
|
||||
a = "␟".join(al)
|
||||
fnew.write(r1 + a + r2 + t + r3 + "\n")
|
||||
|
||||
|
||||
#print("Artists: " + a)
|
||||
#print("Title: " + t)
|
||||
#print("1: " + r1)
|
||||
#print("2: " + r2)
|
||||
#print("3: " + r3)
|
||||
|
||||
|
||||
f.close()
|
||||
fnew.close()
|
||||
|
||||
|
||||
#os.system("diff " + "scrobbles/" + fn + "_new" + " " + "scrobbles/" + fn)
|
||||
with open("scrobbles/" + fn + "_new","r") as newfile:
|
||||
with open("scrobbles/" + fn,"r") as oldfile:
|
||||
diff = difflib.unified_diff(oldfile.read().split("\n"),newfile.read().split("\n"),lineterm="")
|
||||
diff = list(diff)[2:]
|
||||
log("Diff for scrobbles/" + fn + "".join("\n\t" + d for d in diff),module="fixer")
|
||||
|
||||
|
||||
os.rename("scrobbles/" + fn + "_new","scrobbles/" + fn)
|
||||
|
||||
|
||||
checkfile = open("scrobbles/" + fn + ".rulestate","w")
|
||||
checkfile.write(wendigo.checksums)
|
||||
checkfile.close()
|
||||
|
@ -14,26 +14,26 @@ stamps = [99999999999999]
|
||||
for l in log:
|
||||
l = l.replace("\n","")
|
||||
data = l.split(",")
|
||||
|
||||
|
||||
artist = data[0]
|
||||
album = data[1]
|
||||
title = data[2]
|
||||
time = data[3]
|
||||
|
||||
|
||||
|
||||
|
||||
(artists,title) = c.fullclean(artist,title)
|
||||
|
||||
|
||||
artistsstr = "␟".join(artists)
|
||||
|
||||
|
||||
|
||||
|
||||
timeparts = time.split(" ")
|
||||
(h,m) = timeparts[3].split(":")
|
||||
|
||||
|
||||
months = {"Jan":1,"Feb":2,"Mar":3,"Apr":4,"May":5,"Jun":6,"Jul":7,"Aug":8,"Sep":9,"Oct":10,"Nov":11,"Dec":12}
|
||||
|
||||
|
||||
timestamp = int(datetime.datetime(int(timeparts[2]),months[timeparts[1]],int(timeparts[0]),int(h),int(m)).timestamp())
|
||||
|
||||
|
||||
|
||||
|
||||
## We prevent double timestamps in the database creation, so we technically don't need them in the files
|
||||
## however since the conversion from lastfm to maloja is a one-time thing, we should take any effort to make the file as good as possible
|
||||
if (timestamp < stamps[-1]):
|
||||
@ -43,24 +43,21 @@ for l in log:
|
||||
else:
|
||||
while(timestamp in stamps):
|
||||
timestamp -= 1
|
||||
|
||||
if (timestamp < stamps[-1]):
|
||||
|
||||
if (timestamp < stamps[-1]):
|
||||
stamps.append(timestamp)
|
||||
else:
|
||||
stamps.insert(0,timestamp)
|
||||
|
||||
|
||||
|
||||
|
||||
entry = "\t".join([str(timestamp),artistsstr,title,album])
|
||||
entry = entry.replace("#",r"\num")
|
||||
|
||||
|
||||
outputlog.write(entry)
|
||||
outputlog.write("\n")
|
||||
|
||||
|
||||
checksumfile.write(c.checksums)
|
||||
|
||||
|
||||
log.close()
|
||||
outputlog.close()
|
||||
checksumfile.close()
|
||||
|
||||
|
||||
|
||||
|
@ -10,6 +10,7 @@ from utilities import *
|
||||
from htmlgenerators import KeySplit
|
||||
# doreah toolkit
|
||||
from doreah import settings
|
||||
from doreah.logging import log
|
||||
# technical
|
||||
from importlib.machinery import SourceFileLoader
|
||||
import _thread
|
||||
|
36
utilities.py
36
utilities.py
@ -164,27 +164,29 @@ def addEntries(filename,al,escape=True):
|
||||
|
||||
|
||||
### Logging
|
||||
# now handled by doreah
|
||||
|
||||
def log(msg,module=None):
|
||||
now = datetime.datetime.utcnow().strftime("%Y/%m/%d %H:%M:%S")
|
||||
if module is None:
|
||||
import inspect
|
||||
module = inspect.getmodule(inspect.stack()[1][0]).__name__
|
||||
if module == "__main__": module = "mainserver"
|
||||
print("[" + module + "] " + msg)
|
||||
with open("logs/" + module + ".log","a") as logfile:
|
||||
logfile.write(now + " " + msg + "\n")
|
||||
#def log(msg,module=None):
|
||||
# now = datetime.datetime.utcnow().strftime("%Y/%m/%d %H:%M:%S")
|
||||
# if module is None:
|
||||
# import inspect
|
||||
# module = inspect.getmodule(inspect.stack()[1][0]).__name__
|
||||
# if module == "__main__": module = "mainserver"
|
||||
# print("[" + module + "] " + msg)
|
||||
# with open("logs/" + module + ".log","a") as logfile:
|
||||
# logfile.write(now + " " + msg + "\n")
|
||||
|
||||
|
||||
### not meant to be precise, just for a rough idea
|
||||
measurement = 0
|
||||
def clock(*args):
|
||||
import time
|
||||
global measurement
|
||||
now = time.time()
|
||||
if len(args) > 0:
|
||||
print(args[0] + ": " + str(now - measurement))
|
||||
measurement = now
|
||||
# now handled by doreah
|
||||
#measurement = 0
|
||||
#def clock(*args):
|
||||
# import time
|
||||
# global measurement
|
||||
# now = time.time()
|
||||
# if len(args) > 0:
|
||||
# print(args[0] + ": " + str(now - measurement))
|
||||
# measurement = now
|
||||
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>Maloja - KEY_ARTISTNAME</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<table class="top_info">
|
||||
<tr>
|
||||
@ -16,18 +16,18 @@
|
||||
<h1>KEY_ARTISTNAME</h1> <span class="rank"><a href="/topartists?max=100">KEY_POSITION</a></span><br/>
|
||||
<span>KEY_ASSOCIATED</span>
|
||||
<p class="stats"><a href="/scrobbles?artist=KEY_ENC_ARTISTNAME">KEY_SCROBBLES Scrobbles</a></p>
|
||||
|
||||
|
||||
<p class="desc">KEY_DESCRIPTION</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<h2><a href='/toptracks?artist=KEY_ENC_ARTISTNAME'>Top Tracks</a></h2>
|
||||
KEY_TRACKLIST
|
||||
|
||||
|
||||
|
||||
<h2><a href='/pulse?artist=KEY_ENC_ARTISTNAME&step=year&trail=1'>Pulse</a></h2>
|
||||
KEY_PULSE
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import urllib
|
||||
import database
|
||||
|
||||
|
||||
|
||||
def instructions(keys):
|
||||
from utilities import getArtistImage
|
||||
from htmlgenerators import artistLink, artistLinks, KeySplit
|
||||
@ -10,11 +10,11 @@ def instructions(keys):
|
||||
filterkeys, _, _, _ = KeySplit(keys,forceArtist=True)
|
||||
imgurl = getArtistImage(filterkeys["artist"],fast=True)
|
||||
pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []
|
||||
|
||||
|
||||
data = database.artistInfo(filterkeys["artist"])
|
||||
scrobbles = str(data["scrobbles"])
|
||||
pos = "#" + str(data["position"])
|
||||
|
||||
|
||||
credited = data.get("replace")
|
||||
includestr = " "
|
||||
if credited is not None:
|
||||
@ -24,11 +24,11 @@ def instructions(keys):
|
||||
if included is not None and included != []:
|
||||
includestr = "associated: "
|
||||
includestr += artistLinks(included)
|
||||
|
||||
|
||||
html_tracks, _ = module_trackcharts(**filterkeys,max_=15)
|
||||
|
||||
|
||||
html_tracks, _ = module_trackcharts(**filterkeys,max_=15)
|
||||
|
||||
|
||||
html_pulse = module_pulse(**filterkeys,step="year",stepn=1,trail=1)
|
||||
|
||||
replace = {"KEY_ARTISTNAME":keys["artist"],"KEY_ENC_ARTISTNAME":urllib.parse.quote(keys["artist"]),
|
||||
@ -36,5 +36,5 @@ def instructions(keys):
|
||||
"KEY_TRACKLIST":html_tracks,"KEY_PULSE":html_pulse,
|
||||
"KEY_SCROBBLES":scrobbles,"KEY_POSITION":pos,
|
||||
"KEY_ASSOCIATED":includestr}
|
||||
|
||||
|
||||
return (replace,pushresources)
|
||||
|
@ -3,10 +3,10 @@ import database
|
||||
from htmlgenerators import artistLink
|
||||
|
||||
def instructions(keys):
|
||||
|
||||
|
||||
db_data = database.issues()
|
||||
i = 0
|
||||
|
||||
|
||||
html = "<table class='list'>"
|
||||
if db_data["inconsistent"]:
|
||||
html += "<tr>"
|
||||
@ -38,7 +38,7 @@ def instructions(keys):
|
||||
html += """<td class='button' onclick="newrule(this,'replaceartist','""" + n[1] + """','""" + "␟".join(n[2] + [n[0]]) + """')"><div>Yes</div></td>"""
|
||||
html += "</tr>"
|
||||
i += 1
|
||||
|
||||
|
||||
html += "</table>"
|
||||
|
||||
return ({"KEY_ISSUESLIST":html,"KEY_ISSUES":str(i)},[])
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>Maloja - KEY_PULSEDETAILS Pulse</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<table class="top_info">
|
||||
<tr>
|
||||
@ -20,8 +20,8 @@
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
KEY_PULSE_TABLE
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,16 +1,16 @@
|
||||
import urllib
|
||||
import database
|
||||
|
||||
|
||||
|
||||
def instructions(keys):
|
||||
from utilities import getArtistImage, getTrackImage
|
||||
from htmlgenerators import artistLink, artistLinks, trackLink, scrobblesLink, keysToUrl, KeySplit
|
||||
from htmlmodules import module_pulse
|
||||
from htmlmodules import module_pulse
|
||||
from malojatime import range_desc, delimit_desc
|
||||
|
||||
|
||||
filterkeys, timekeys, delimitkeys, _ = KeySplit(keys)
|
||||
|
||||
|
||||
|
||||
|
||||
# describe the scope (and creating a key for the relevant artist or track)
|
||||
limitstring = ""
|
||||
#limitkey = {}
|
||||
@ -18,7 +18,7 @@ def instructions(keys):
|
||||
#limitkey["track"] = {"artists":keys.getall("artist"),"title":keys.get("title")}
|
||||
limitstring += "of " + trackLink(filterkeys["track"]) + " "
|
||||
limitstring += "by " + artistLinks(filterkeys["track"]["artists"])
|
||||
|
||||
|
||||
elif filterkeys.get("artist") is not None:
|
||||
#limitkey["artist"], limitkey["associated"] = keys.get("artist"), (keys.get("associated")!=None)
|
||||
limitstring += "of " + artistLink(filterkeys.get("artist"))
|
||||
@ -27,27 +27,26 @@ def instructions(keys):
|
||||
moreartists = data["associated"]
|
||||
if moreartists != []:
|
||||
limitstring += " <span class='extra'>including " + artistLinks(moreartists) + "</span>"
|
||||
|
||||
|
||||
limitstring += " " + range_desc(**timekeys)
|
||||
|
||||
|
||||
delimitstring = delimit_desc(**delimitkeys)
|
||||
|
||||
|
||||
# get image
|
||||
|
||||
|
||||
# get image
|
||||
if filterkeys.get("track") is not None:
|
||||
imgurl = getTrackImage(filterkeys.get("track")["artists"],filterkeys.get("track")["title"])
|
||||
elif filterkeys.get("artist") is not None:
|
||||
imgurl = getArtistImage(keys.get("artist"))
|
||||
else:
|
||||
imgurl = ""
|
||||
|
||||
pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []
|
||||
|
||||
|
||||
|
||||
pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []
|
||||
|
||||
|
||||
|
||||
html_pulse = module_pulse(**filterkeys,**timekeys,**delimitkeys)
|
||||
|
||||
|
||||
replace = {"KEY_PULSE_TABLE":html_pulse,"KEY_IMAGEURL":imgurl,"KEY_LIMITS":limitstring,"KEY_PULSEDETAILS":delimitstring}
|
||||
|
||||
|
||||
return (replace,pushresources)
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>Maloja - Scrobbles</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<table class="top_info">
|
||||
<tr>
|
||||
@ -20,8 +20,8 @@
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
KEY_SCROBBLELIST
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,22 +1,22 @@
|
||||
import urllib
|
||||
import database
|
||||
|
||||
|
||||
|
||||
def instructions(keys):
|
||||
from utilities import getArtistImage, getTrackImage
|
||||
from htmlgenerators import artistLink, artistLinks, trackLink, KeySplit
|
||||
from htmlmodules import module_scrobblelist
|
||||
from htmlmodules import module_scrobblelist
|
||||
from malojatime import range_desc
|
||||
|
||||
|
||||
|
||||
|
||||
filterkeys, timekeys, _, amountkeys = KeySplit(keys)
|
||||
|
||||
|
||||
# describe the scope
|
||||
limitstring = ""
|
||||
if filterkeys.get("track") is not None:
|
||||
limitstring += "of " + trackLink(filterkeys["track"]) + " "
|
||||
limitstring += "by " + artistLinks(filterkeys["track"]["artists"])
|
||||
|
||||
|
||||
elif filterkeys.get("artist") is not None:
|
||||
limitstring += "by " + artistLink(filterkeys.get("artist"))
|
||||
if filterkeys.get("associated"):
|
||||
@ -24,13 +24,13 @@ def instructions(keys):
|
||||
moreartists = data.get("associated")
|
||||
if moreartists != []:
|
||||
limitstring += " <span class='extra'>including " + artistLinks(moreartists) + "</span>"
|
||||
|
||||
|
||||
limitstring += " " + range_desc(**timekeys)
|
||||
|
||||
|
||||
|
||||
html, amount, rep = module_scrobblelist(**filterkeys,**timekeys,**amountkeys)
|
||||
|
||||
# get image
|
||||
|
||||
# get image
|
||||
if filterkeys.get("track") is not None:
|
||||
imgurl = getTrackImage(filterkeys.get("track")["artists"],filterkeys.get("track")["title"],fast=True)
|
||||
elif filterkeys.get("artist") is not None:
|
||||
@ -39,12 +39,11 @@ def instructions(keys):
|
||||
imgurl = getTrackImage(rep["artists"],rep["title"],fast=True)
|
||||
else:
|
||||
imgurl = ""
|
||||
|
||||
|
||||
|
||||
|
||||
pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []
|
||||
|
||||
|
||||
|
||||
replace = {"KEY_SCROBBLELIST":html,"KEY_SCROBBLES":str(amount),"KEY_IMAGEURL":imgurl,"KEY_LIMITS":limitstring}
|
||||
|
||||
|
||||
return (replace,pushresources)
|
||||
|
||||
|
@ -4,9 +4,9 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Maloja</title>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
function showRange(identifier,unit) {
|
||||
modules = document.getElementsByClassName("stat_module_" + identifier)
|
||||
@ -14,7 +14,7 @@
|
||||
modules[i].setAttribute("style","display:none;")
|
||||
}
|
||||
document.getElementById(identifier + "_" + unit).setAttribute("style","")
|
||||
|
||||
|
||||
selectors = document.getElementsByClassName("stat_selector_" + identifier)
|
||||
for (var i=0;i<selectors.length;i++) {
|
||||
selectors[i].setAttribute("style","")
|
||||
@ -23,55 +23,55 @@
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<!--<div class="header"><h1>Maloja</h1>
|
||||
</div>-->
|
||||
|
||||
|
||||
|
||||
|
||||
<h1><a href="/topartists?max=50">Top Artists</a></h1>
|
||||
<!--All Time | This Year | This Month | This Week-->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<span onclick="showRange('topartists','week')" class="stat_selector_topartists" id="selector_topartists_week">This Week</span>
|
||||
| <span onclick="showRange('topartists','month')" class="stat_selector_topartists" id="selector_topartists_month">This Month</span>
|
||||
| <span onclick="showRange('topartists','year')" class="stat_selector_topartists" id="selector_topartists_year">This Year</span>
|
||||
| <span onclick="showRange('topartists','year')" class="stat_selector_topartists" id="selector_topartists_year">This Year</span>
|
||||
| <span onclick="showRange('topartists','alltime')" class="stat_selector_topartists" id="selector_topartists_alltime" style="opacity:0.5;">All Time</span>
|
||||
|
||||
|
||||
<br/><br/>
|
||||
|
||||
|
||||
<span class="stat_module_topartists" id="topartists_week" style="display:none;">KEY_TOPARTISTS_WEEK</span>
|
||||
<span class="stat_module_topartists" id="topartists_month" style="display:none;">KEY_TOPARTISTS_MONTH</span>
|
||||
<span class="stat_module_topartists" id="topartists_year" style="display:none;">KEY_TOPARTISTS_YEAR</span>
|
||||
<span class="stat_module_topartists" id="topartists_alltime">KEY_TOPARTISTS_TOTAL</span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h1><a href="/toptracks?max=50">Top Tracks</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
<span onclick="showRange('toptracks','week')" class="stat_selector_toptracks" id="selector_toptracks_week">This Week</span>
|
||||
| <span onclick="showRange('toptracks','month')" class="stat_selector_toptracks" id="selector_toptracks_month">This Month</span>
|
||||
| <span onclick="showRange('toptracks','year')" class="stat_selector_toptracks" id="selector_toptracks_year">This Year</span>
|
||||
| <span onclick="showRange('toptracks','year')" class="stat_selector_toptracks" id="selector_toptracks_year">This Year</span>
|
||||
| <span onclick="showRange('toptracks','alltime')" class="stat_selector_toptracks" id="selector_toptracks_alltime" style="opacity:0.5;">All Time</span>
|
||||
|
||||
|
||||
<br/><br/>
|
||||
|
||||
|
||||
<span class="stat_module_toptracks" id="toptracks_week" style="display:none;">KEY_TOPTRACKS_WEEK</span>
|
||||
<span class="stat_module_toptracks" id="toptracks_month" style="display:none;">KEY_TOPTRACKS_MONTH</span>
|
||||
<span class="stat_module_toptracks" id="toptracks_year" style="display:none;">KEY_TOPTRACKS_YEAR</span>
|
||||
<span class="stat_module_toptracks" id="toptracks_alltime">KEY_TOPTRACKS_TOTAL</span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="sidelist">
|
||||
<h1><a href="/scrobbles?max=100">Last Scrobbles</a></h1>
|
||||
<span class="stats">Today</span> KEY_SCROBBLE_NUM_TODAY
|
||||
@ -79,34 +79,34 @@
|
||||
<span class="stats">This year</span> KEY_SCROBBLE_NUM_YEAR
|
||||
<span class="stats">All Time</span> KEY_SCROBBLE_NUM_TOTAL
|
||||
<br/><br/>
|
||||
|
||||
|
||||
<span class="stat_module">KEY_SCROBBLES</span>
|
||||
|
||||
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
<h1><a href="/pulse?step=month&trail=1">Pulse</a></h1>
|
||||
<!--
|
||||
<!--
|
||||
<a href="/pulse?step=day&trail=1">Days</a>
|
||||
<a href="/pulse?step=week&trail=1">Weeks</a>
|
||||
<a href="/pulse?step=month&trail=1">Months</a>
|
||||
<a href="/pulse?step=year&trail=1">Years</a>
|
||||
<a href="/pulse?step=week&trail=1">Weeks</a>
|
||||
<a href="/pulse?step=month&trail=1">Months</a>
|
||||
<a href="/pulse?step=year&trail=1">Years</a>
|
||||
-->
|
||||
|
||||
|
||||
<span onclick="showRange('pulse','days')" class="stat_selector_pulse" id="selector_pulse_days">7 days</span>
|
||||
| <span onclick="showRange('pulse','weeks')" class="stat_selector_pulse" id="selector_pulse_weeks">12 weeks</span>
|
||||
| <span onclick="showRange('pulse','months')" class="stat_selector_pulse" id="selector_pulse_months" style="opacity:0.5;">12 months</span>
|
||||
| <span onclick="showRange('pulse','months')" class="stat_selector_pulse" id="selector_pulse_months" style="opacity:0.5;">12 months</span>
|
||||
| <span onclick="showRange('pulse','years')" class="stat_selector_pulse" id="selector_pulse_years">10 years</span>
|
||||
<!--
|
||||
### this is for extra views of the current canonical week / month / year
|
||||
<br/>
|
||||
<span onclick="showRange('pulse','week')" class="stat_selector_pulse" id="selector_pulse_week">This Week</span>
|
||||
| <span onclick="showRange('pulse','month')" class="stat_selector_pulse" id="selector_pulse_month">This Month</span>
|
||||
| <span onclick="showRange('pulse','year')" class="stat_selector_pulse" id="selector_pulse_year"">This Year</span>
|
||||
| <span onclick="showRange('pulse','year')" class="stat_selector_pulse" id="selector_pulse_year"">This Year</span>
|
||||
-->
|
||||
<br/><br/>
|
||||
|
||||
|
||||
<span class="stat_module_pulse" id="pulse_months">KEY_PULSE_MONTHS</span>
|
||||
<span class="stat_module_pulse" id="pulse_days" style="display:none;">KEY_PULSE_DAYS</span>
|
||||
<span class="stat_module_pulse" id="pulse_years" style="display:none;">KEY_PULSE_YEARS</span>
|
||||
@ -117,9 +117,9 @@
|
||||
<span class="stat_module_pulse" id="pulse_year" style="display:none;">KEY_PULSE_YEAR</span>
|
||||
-->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
</html>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import urllib
|
||||
from datetime import datetime, timedelta
|
||||
import database
|
||||
from utilities import clock
|
||||
from doreah.timing import clock, clockp
|
||||
|
||||
from htmlmodules import module_scrobblelist, module_pulse, module_artistcharts_tiles, module_trackcharts_tiles
|
||||
|
||||
@ -24,7 +24,7 @@ def instructions(keys):
|
||||
topartists_month = module_artistcharts_tiles(since="month")
|
||||
topartists_week = module_artistcharts_tiles(since=weekstart)
|
||||
|
||||
clock("Artists")
|
||||
clockp("Artists")
|
||||
|
||||
# tracks
|
||||
|
||||
@ -34,13 +34,13 @@ def instructions(keys):
|
||||
toptracks_week = module_trackcharts_tiles(since=weekstart)
|
||||
|
||||
|
||||
clock("Tracks")
|
||||
clockp("Tracks")
|
||||
|
||||
|
||||
# scrobbles
|
||||
html_scrobbles, _, _ = module_scrobblelist(max_=15,shortTimeDesc=True,pictures=True,earlystop=True)
|
||||
|
||||
clock("Scrobbles")
|
||||
clockp("Scrobbles")
|
||||
|
||||
# stats
|
||||
|
||||
@ -61,7 +61,7 @@ def instructions(keys):
|
||||
amount_total = database.get_scrobbles_num()
|
||||
scrobbles_total = "<a href='/scrobbles'>" + str(amount_total) + "</a>"
|
||||
|
||||
clock("Amounts")
|
||||
clockp("Amounts")
|
||||
|
||||
# pulse
|
||||
dt = datetime.utcnow()
|
||||
@ -83,7 +83,7 @@ def instructions(keys):
|
||||
#html_pulse_month = module_pulse(max_=30,since=[dt.year,dt.month],step="day",trail=1)
|
||||
#html_pulse_year = module_pulse(max_=12,since=[dt.year],step="month",trail=1)
|
||||
|
||||
clock("Pulse")
|
||||
clockp("Pulse")
|
||||
|
||||
#pushresources = [{"file":img,"type":"image"} for img in artistimages + trackimages] #can't push scrobble images as we don't get them from the module function, need to think about that
|
||||
pushresources = []
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>Maloja - Top Artists</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<table class="top_info">
|
||||
<tr>
|
||||
@ -16,13 +16,13 @@
|
||||
<h1>Top Artists</h1><br/>
|
||||
<span>KEY_RANGE</span>
|
||||
<!--<p class="stats">KEY_SCROBBLES Scrobbles</p>-->
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
KEY_ARTISTLIST
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,28 +1,28 @@
|
||||
import urllib
|
||||
|
||||
|
||||
|
||||
def instructions(keys):
|
||||
from utilities import getArtistImage
|
||||
from htmlgenerators import KeySplit
|
||||
from htmlmodules import module_artistcharts
|
||||
from malojatime import range_desc
|
||||
|
||||
|
||||
|
||||
_, timekeys, _, amountkeys = KeySplit(keys)
|
||||
|
||||
|
||||
limitstring = range_desc(**timekeys)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
html_charts, rep = module_artistcharts(**amountkeys,**timekeys)
|
||||
|
||||
|
||||
if rep is not None:
|
||||
imgurl = getArtistImage(rep)
|
||||
else:
|
||||
imgurl = ""
|
||||
|
||||
|
||||
pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []
|
||||
|
||||
|
||||
|
||||
replace = {"KEY_TOPARTIST_IMAGEURL":imgurl,"KEY_ARTISTLIST":html_charts,"KEY_RANGE":limitstring}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>Maloja - Top Tracks</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<table class="top_info">
|
||||
<tr>
|
||||
@ -16,13 +16,13 @@
|
||||
<h1>Top Tracks</h1><br/>
|
||||
<span>KEY_LIMITS</span>
|
||||
<!--<p class="stats">KEY_SCROBBLES Scrobbles</p>-->
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
KEY_TRACKLIST
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,36 +1,35 @@
|
||||
import urllib
|
||||
|
||||
|
||||
|
||||
def instructions(keys):
|
||||
from utilities import getArtistImage, getTrackImage
|
||||
from htmlgenerators import artistLink, KeySplit
|
||||
from htmlmodules import module_trackcharts
|
||||
from htmlmodules import module_trackcharts
|
||||
from malojatime import range_desc
|
||||
|
||||
|
||||
filterkeys, timekeys, _, amountkeys = KeySplit(keys)
|
||||
|
||||
|
||||
|
||||
limitstring = ""
|
||||
|
||||
|
||||
|
||||
html_charts, rep = module_trackcharts(**amountkeys,**timekeys,**filterkeys)
|
||||
|
||||
|
||||
|
||||
|
||||
if filterkeys.get("artist") is not None:
|
||||
imgurl = getArtistImage(filterkeys.get("artist"))
|
||||
limitstring = "by " + artistLink(filterkeys.get("artist"))
|
||||
elif rep is not None:
|
||||
imgurl = getTrackImage(rep["artists"],rep["title"])
|
||||
imgurl = getTrackImage(rep["artists"],rep["title"])
|
||||
else:
|
||||
imgurl = ""
|
||||
|
||||
|
||||
limitstring += " " + range_desc(**timekeys)
|
||||
|
||||
|
||||
pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []
|
||||
|
||||
|
||||
|
||||
|
||||
replace = {"KEY_TOPARTIST_IMAGEURL":imgurl,"KEY_TRACKLIST":html_charts,"KEY_LIMITS":limitstring}
|
||||
|
||||
return (replace,pushresources)
|
||||
|
||||
return (replace,pushresources)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>Maloja - KEY_TRACKTITLE</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<table class="top_info">
|
||||
<tr>
|
||||
@ -15,22 +15,22 @@
|
||||
<td class="text">
|
||||
<span>KEY_ARTISTS</span><br/>
|
||||
<h1>KEY_TRACKTITLE</h1> <span class="rank"><a href="/toptracks?max=100">KEY_POSITION</a></span>
|
||||
|
||||
|
||||
<p class="stats"><a href="/scrobbles?KEY_SCROBBLELINK">KEY_SCROBBLES Scrobbles</a></p>
|
||||
|
||||
|
||||
<p class="desc"></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<h2><a href='/pulse?KEY_SCROBBLELINK&step=year&trail=1'>Pulse</a></h2>
|
||||
KEY_PULSE
|
||||
|
||||
|
||||
|
||||
|
||||
<h2><a href='/scrobbles?KEY_SCROBBLELINK'>Scrobbles</a></h2>
|
||||
KEY_SCROBBLELIST
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,32 +1,32 @@
|
||||
import urllib
|
||||
import database
|
||||
|
||||
|
||||
|
||||
def instructions(keys):
|
||||
from utilities import getArtistImage, getTrackImage
|
||||
from htmlgenerators import artistLinks, keysToUrl, KeySplit
|
||||
from htmlmodules import module_scrobblelist, module_pulse
|
||||
|
||||
|
||||
filterkeys, _, _, _ = KeySplit(keys,forceTrack=True)
|
||||
|
||||
|
||||
filterkeys, _, _, _ = KeySplit(keys,forceTrack=True)
|
||||
|
||||
track = filterkeys.get("track")
|
||||
imgurl = getTrackImage(track["artists"],track["title"],fast=True)
|
||||
pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []
|
||||
|
||||
|
||||
data = database.trackInfo(track["artists"],track["title"])
|
||||
|
||||
|
||||
scrobblesnum = str(data["scrobbles"])
|
||||
pos = "#" + str(data["position"])
|
||||
|
||||
|
||||
|
||||
html_scrobbles, _, _ = module_scrobblelist(track=track,max_=100,earlystop=True) # we have the number already from the trackinfo
|
||||
|
||||
|
||||
html_pulse = module_pulse(track=track,step="year",stepn=1,trail=1)
|
||||
|
||||
|
||||
replace = {"KEY_TRACKTITLE":track.get("title"),"KEY_ARTISTS":artistLinks(track.get("artists")),"KEY_SCROBBLES":scrobblesnum,"KEY_POSITION":pos,"KEY_IMAGEURL":imgurl,
|
||||
"KEY_SCROBBLELINK":keysToUrl(keys),
|
||||
"KEY_SCROBBLELIST":html_scrobbles,"KEY_PULSE":html_pulse}
|
||||
|
||||
|
||||
return (replace,pushresources)
|
||||
|
@ -5,27 +5,27 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>Maloja - Please wait</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<table class="top_info">
|
||||
<tr>
|
||||
|
||||
|
||||
<td class="text">
|
||||
<h1>Maloja</h1><br/>
|
||||
<span>Redbuilding the database</span>
|
||||
|
||||
|
||||
<p>Please wait...</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
<script>
|
||||
var pending = false;
|
||||
setInterval(probeServer,1500);
|
||||
|
||||
|
||||
function probeServer() {
|
||||
if (!pending) {
|
||||
console.log("Probing...");
|
||||
@ -34,11 +34,11 @@
|
||||
xhttp.open("GET","/db/test", true);
|
||||
xhttp.onreadystatechange = goback;
|
||||
xhttp.send();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function goback() {
|
||||
if ((this.readyState == 4) && (this.status == 205)) {
|
||||
console.log("Not ready yet!")
|
||||
@ -50,6 +50,6 @@
|
||||
window.location = "/issues";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user