1
0
mirror of https://github.com/krateng/maloja.git synced 2023-08-10 21:12:55 +03:00

Merge branch 'master' into pyhp

This commit is contained in:
Krateng
2019-10-24 15:52:06 +02:00
57 changed files with 1339 additions and 399 deletions

View File

@@ -4,7 +4,8 @@
<head>
<meta charset="UTF-8" />
<title>Maloja - KEY_ARTISTNAME</title>
<script src="javascript/rangeselect.js" async></script>
<script src="javascript/cookies.js"></script>
<script src="javascript/rangeselect.js"></script>
</head>
<body>
@@ -15,13 +16,13 @@
</td>
<td class="text">
<h1>KEY_ARTISTNAME</h1>
<span class="rank"><a href="/charts_artists?max=100">KEY_POSITION</a></span>
<span class="rank"><a href="/charts_artists">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>
<span>KEY_MEDALS</span>
<span>KEY_MEDALS</span> <span>KEY_TOPWEEKS</span> <span>KEY_CERTS</span>
</td>
</tr>
</table>
@@ -32,35 +33,35 @@
<table class="twopart">
<tr>
<td>
<h2><a href='/pulse?artist=KEY_ENC_ARTISTNAME&step=year&trail=1'>Pulse</a></h2>
<h2><a class="stat_link_pulse" href='/pulse?artist=KEY_ENC_ARTISTNAME&trail=1&step=month'>Pulse</a></h2>
<span onclick="showRange('pulse','days')" class="stat_selector_pulse selector_pulse_days">7 days</span>
| <span onclick="showRange('pulse','weeks')" class="stat_selector_pulse selector_pulse_weeks">12 weeks</span>
| <span onclick="showRange('pulse','months')" class="stat_selector_pulse selector_pulse_months" style="opacity:0.5;">12 months</span>
| <span onclick="showRange('pulse','years')" class="stat_selector_pulse selector_pulse_years">10 years</span>
<span onclick="showRangeManual('pulse','day')" class="stat_selector_pulse selector_pulse_day">7 days</span>
| <span onclick="showRangeManual('pulse','week')" class="stat_selector_pulse selector_pulse_week">12 weeks</span>
| <span onclick="showRangeManual('pulse','month')" class="stat_selector_pulse selector_pulse_month" style="opacity:0.5;">12 months</span>
| <span onclick="showRangeManual('pulse','year')" class="stat_selector_pulse selector_pulse_year">10 years</span>
<br/><br/>
<span class="stat_module_pulse pulse_months">KEY_PULSE_MONTHS</span>
<span class="stat_module_pulse pulse_days" style="display:none;">KEY_PULSE_DAYS</span>
<span class="stat_module_pulse pulse_years" style="display:none;">KEY_PULSE_YEARS</span>
<span class="stat_module_pulse pulse_weeks" style="display:none;">KEY_PULSE_WEEKS</span>
<span class="stat_module_pulse pulse_month">KEY_PULSE_MONTHS</span>
<span class="stat_module_pulse pulse_day" style="display:none;">KEY_PULSE_DAYS</span>
<span class="stat_module_pulse pulse_year" style="display:none;">KEY_PULSE_YEARS</span>
<span class="stat_module_pulse pulse_week" style="display:none;">KEY_PULSE_WEEKS</span>
</td>
<td>
<!-- We use the same classes / function calls here because we want it to switch together with pulse -->
<h2><a href='/performance?artist=KEY_ENC_CREDITEDARTISTNAME&step=year&trail=1'>Performance</a></h2>
<span onclick="showRange('pulse','days')" class="stat_selector_pulse selector_pulse_days">7 days</span>
| <span onclick="showRange('pulse','weeks')" class="stat_selector_pulse selector_pulse_weeks">12 weeks</span>
| <span onclick="showRange('pulse','months')" class="stat_selector_pulse selector_pulse_months" style="opacity:0.5;">12 months</span>
| <span onclick="showRange('pulse','years')" class="stat_selector_pulse selector_pulse_years">10 years</span>
<h2><a class="stat_link_pulse" href='/performance?artist=KEY_ENC_CREDITEDARTISTNAME&trail=1&step=month'>Performance</a></h2>
<span onclick="showRangeManual('pulse','day')" class="stat_selector_pulse selector_pulse_day">7 days</span>
| <span onclick="showRangeManual('pulse','week')" class="stat_selector_pulse selector_pulse_week">12 weeks</span>
| <span onclick="showRangeManual('pulse','month')" class="stat_selector_pulse selector_pulse_month" style="opacity:0.5;">12 months</span>
| <span onclick="showRangeManual('pulse','year')" class="stat_selector_pulse selector_pulse_year">10 years</span>
<br/><br/>
<span class="stat_module_pulse pulse_months">KEY_PERFORMANCE_MONTHS</span>
<span class="stat_module_pulse pulse_days" style="display:none;">KEY_PERFORMANCE_DAYS</span>
<span class="stat_module_pulse pulse_years" style="display:none;">KEY_PERFORMANCE_YEARS</span>
<span class="stat_module_pulse pulse_weeks" style="display:none;">KEY_PERFORMANCE_WEEKS</span>
<span class="stat_module_pulse pulse_month">KEY_PERFORMANCE_MONTHS</span>
<span class="stat_module_pulse pulse_day" style="display:none;">KEY_PERFORMANCE_DAYS</span>
<span class="stat_module_pulse pulse_year" style="display:none;">KEY_PERFORMANCE_YEARS</span>
<span class="stat_module_pulse pulse_week" style="display:none;">KEY_PERFORMANCE_WEEKS</span>
</td>
</tr>
</table>

View File

@@ -5,7 +5,7 @@ from malojatime import today,thisweek,thismonth,thisyear
def instructions(keys):
from utilities import getArtistImage
from htmlgenerators import artistLink, artistLinks
from htmlgenerators import artistLink, artistLinks, link_address
from urihandler import compose_querystring, uri_to_internal
from htmlmodules import module_pulse, module_performance, module_trackcharts, module_scrobblelist
@@ -22,13 +22,31 @@ def instructions(keys):
if "medals" in data and data["medals"] is not None:
if "gold" in data["medals"]:
for y in data["medals"]["gold"]:
html_medals += "<a title='Best Artist in " + str(y) + "' class='hidelink medal shiny gold' href='/charts_artists?max=50&in=" + str(y) + "'><span>" + str(y) + "</span></a>"
html_medals += "<a title='Best Artist in " + str(y) + "' class='hidelink medal shiny gold' href='/charts_artists?in=" + str(y) + "'><span>" + str(y) + "</span></a>"
if "silver" in data["medals"]:
for y in data["medals"]["silver"]:
html_medals += "<a title='Second Best Artist in " + str(y) + "' class='hidelink medal shiny silver' href='/charts_artists?max=50&in=" + str(y) + "'><span>" + str(y) + "</span></a>"
html_medals += "<a title='Second Best Artist in " + str(y) + "' class='hidelink medal shiny silver' href='/charts_artists?in=" + str(y) + "'><span>" + str(y) + "</span></a>"
if "bronze" in data["medals"]:
for y in data["medals"]["bronze"]:
html_medals += "<a title='Third Best Artist in " + str(y) + "' class='hidelink medal shiny bronze' href='/charts_artists?max=50&in=" + str(y) + "'><span>" + str(y) + "</span></a>"
html_medals += "<a title='Third Best Artist in " + str(y) + "' class='hidelink medal shiny bronze' href='/charts_artists?in=" + str(y) + "'><span>" + str(y) + "</span></a>"
html_cert = ""
for track in database.get_tracks(artist=artist):
info = database.trackInfo(track)
if info.get("certification") is not None:
img = "/media/record_{cert}.png".format(cert=info["certification"])
trackname = track["title"].replace("'","&#39;")
tracklink = link_address(track)
tooltip = "{title} has reached {cert} status".format(title=trackname,cert=info["certification"].capitalize())
html_cert += "<a href='{link}'><img class='certrecord_small' src='{img}' title='{tooltip}' /></a>".format(tooltip=tooltip,img=img,link=tracklink)
html_topweeks = ""
if data.get("topweeks") not in [0,None]:
link = "/performance?artist=" + urllib.parse.quote(keys["artist"]) + "&trail=1&step=week"
title = str(data["topweeks"]) + " weeks on #1"
html_topweeks = "<a title='" + title + "' href='" + link + "'><img class='star' src='/media/star.png' />" + str(data["topweeks"]) + "</a>"
credited = data.get("replace")
includestr = " "
@@ -69,6 +87,8 @@ def instructions(keys):
"KEY_POSITION":pos,
"KEY_ASSOCIATED":includestr,
"KEY_MEDALS":html_medals,
"KEY_CERTS":html_cert,
"KEY_TOPWEEKS":html_topweeks,
# tracks
"KEY_TRACKLIST":html_tracks,
# pulse

View File

@@ -11,7 +11,7 @@
<table class="top_info">
<tr>
<td class="image">
<div style="background-image:url('KEY_TOPARTIST_IMAGEURL')"></div>
KEY_TOPARTIST_IMAGEDIV
</td>
<td class="text">
<h1>Artist Charts</h1><a href="/top_artists"><span>View #1 Artists</span></a><br/>
@@ -24,6 +24,9 @@
</tr>
</table>
<span class="stat_module_topartists">
KEY_ARTISTCHART
</span>
KEY_ARTISTLIST

View File

@@ -4,8 +4,9 @@ import urllib
def instructions(keys):
from utilities import getArtistImage
from urihandler import compose_querystring, uri_to_internal
from htmlmodules import module_artistcharts, module_filterselection
from htmlmodules import module_artistcharts, module_filterselection, module_artistcharts_tiles
from malojatime import range_desc
from doreah.settings import get_settings
_, timekeys, _, amountkeys = uri_to_internal(keys)
@@ -16,6 +17,7 @@ def instructions(keys):
html_charts, rep = module_artistcharts(**amountkeys,**timekeys)
if rep is not None:
@@ -23,12 +25,23 @@ def instructions(keys):
else:
imgurl = ""
html_tiles = ""
if get_settings("CHARTS_DISPLAY_TILES"):
html_tiles = module_artistcharts_tiles(timerange=timekeys["timerange"])
imgurl = "favicon.png"
imgdiv = '<div style="background-image:url('+imgurl+')"></div>'
pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []
replace = {"KEY_TOPARTIST_IMAGEURL":imgurl,
"KEY_ARTISTLIST":html_charts,
"KEY_RANGE":limitstring,
"KEY_FILTERSELECTOR":html_filterselector}
replace = {
"KEY_TOPARTIST_IMAGEDIV":imgdiv,
"KEY_ARTISTCHART":html_tiles,
"KEY_ARTISTLIST":html_charts,
"KEY_RANGE":limitstring,
"KEY_FILTERSELECTOR":html_filterselector
}
return (replace,pushresources)

View File

@@ -10,7 +10,7 @@
<table class="top_info">
<tr>
<td class="image">
<div style="background-image:url('KEY_TOPARTIST_IMAGEURL')"></div>
KEY_TOPARTIST_IMAGEDIV
</td>
<td class="text">
<h1>Track Charts</h1>TOP_TRACKS_LINK<br/>
@@ -22,6 +22,9 @@
</tr>
</table>
<span class="stat_module_topartists">
KEY_TRACKCHART
</span>
KEY_TRACKLIST

View File

@@ -5,8 +5,9 @@ def instructions(keys):
from utilities import getArtistImage, getTrackImage
from htmlgenerators import artistLink
from urihandler import compose_querystring, uri_to_internal
from htmlmodules import module_trackcharts, module_filterselection
from htmlmodules import module_trackcharts, module_filterselection, module_trackcharts_tiles
from malojatime import range_desc
from doreah.settings import get_settings
filterkeys, timekeys, _, amountkeys = uri_to_internal(keys)
@@ -23,6 +24,9 @@ def instructions(keys):
html_charts, rep = module_trackcharts(**amountkeys,**timekeys,**filterkeys)
html_tiles = ""
if filterkeys.get("artist") is not None:
imgurl = getArtistImage(filterkeys.get("artist"))
limitstring = "by " + artistLink(filterkeys.get("artist"))
@@ -31,6 +35,15 @@ def instructions(keys):
else:
imgurl = ""
html_tiles = ""
if get_settings("CHARTS_DISPLAY_TILES"):
html_tiles = module_trackcharts_tiles(timerange=timekeys["timerange"])
imgurl = "favicon.png"
imgdiv = '<div style="background-image:url('+imgurl+')"></div>'
limitstring += " " + timekeys["timerange"].desc(prefix=True)
pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []
@@ -38,7 +51,8 @@ def instructions(keys):
replace = {
"KEY_TOPARTIST_IMAGEURL":imgurl,
"KEY_TOPARTIST_IMAGEDIV":imgdiv,
"KEY_TRACKCHART":html_tiles,
"KEY_TRACKLIST":html_charts,
"KEY_LIMITS":limitstring,
"KEY_FILTERSELECTOR":html_filterselector,

View File

@@ -1,3 +1,9 @@
<meta name="description" content='Maloja is a self-hosted music scrobble server.' />
<!--<link rel="stylesheet/less" href="/less/maloja.less" />
<link rel="stylesheet/less" href="/less/grisons.less" />
<link rel="stylesheet" href="/css/maloja.css" />
<script src="/javascript/search.js" async="yes"></script>
<link rel="stylesheet" href="/css/grisons.css" />
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.9.0/less.min.js" ></script> -->
<link rel="stylesheet" href="/css/style.css" />
<script src="/javascript/search.js" async></script>

78
website/compare.html Normal file
View File

@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Maloja - Compare</title>
<style>
.comparecircle {
height:500px;
width:500px;
border-radius:250px;
border: 1px solid rgba(245,245,220,0.3);
margin:auto;
margin-top:100px;
text-align:center;
line-height:500px;
font-size:60px;
color:black;
/* background-image: linear-gradient(to right,KEY_CIRCLE_CSS); */
background-image: radial-gradient(#KEY_CICLE_COLOR KEY_FULLMATCHpx, transparent KEY_PARTIALMATCHpx);
}
table tr td:first-child {
text-align: left;
padding:10px;
width:33%;
}
table tr td {
text-align: center;
padding:10px;
}
table tr td:last-child {
text-align: right;
padding:10px;
width:33%;
}
</style>
</head>
<body>
<table style="width:99%;">
<tr>
<td><h1>KEY_NAME_SELF</h1></td>
<td>
<div class="comparecircle">
KEY_MATCH%
</div>
</td>
<td><h1>KEY_NAME_OTHER</h1></td>
</tr>
<tr>
<td></td>
<td style="font-size:70%;color:grey;">
The size of the circle shows matching music taste.
The fuzziness of its border indicates differences in quantity.
</td>
<td></td>
</tr>
<tr>
<td></td>
<td>
<span>Common Favorite</span>
<h2 style="margin:7px;">KEY_BESTARTIST_LINK</h2>
<img src="KEY_BESTARTIST_IMAGE" style="width:80px;" />
</td>
<td></td>
</tr>
</table>
</body>
</html>

88
website/compare.py Normal file
View File

@@ -0,0 +1,88 @@
import urllib
import database
import json
from htmlgenerators import artistLink
from utilities import getArtistImage
def instructions(keys):
compareto = keys.get("to")
compareurl = compareto + "/api/info"
response = urllib.request.urlopen(compareurl)
strangerinfo = json.loads(response.read())
owninfo = database.info()
artists = {}
for a in owninfo["artists"]:
artists[a.lower()] = {"name":a,"self":int(owninfo["artists"][a]*1000),"other":0}
for a in strangerinfo["artists"]:
artists[a.lower()] = artists.setdefault(a.lower(),{"name":a,"self":0})
artists[a.lower()]["other"] = int(strangerinfo["artists"][a]*1000)
for a in artists:
common = min(artists[a]["self"],artists[a]["other"])
artists[a]["self"] -= common
artists[a]["other"] -= common
artists[a]["common"] = common
best = sorted((artists[a]["name"] for a in artists),key=lambda x: artists[x.lower()]["common"],reverse=True)
result = {
"unique_self":sum(artists[a]["self"] for a in artists if artists[a]["common"] == 0),
"more_self":sum(artists[a]["self"] for a in artists if artists[a]["common"] != 0),
# "common":{
# **{
# artists[a]["name"]:artists[a]["common"]
# for a in best[:3]},
# None: sum(artists[a]["common"] for a in artists if a not in best[:3])
# },
"common":sum(artists[a]["common"] for a in artists),
"more_other":sum(artists[a]["other"] for a in artists if artists[a]["common"] != 0),
"unique_other":sum(artists[a]["other"] for a in artists if artists[a]["common"] == 0)
}
total = sum(result[c] for c in result)
percentages = {c:result[c]*100/total for c in result}
css = []
cumulative = 0
for color,category in [
("rgba(255,255,255,0.2)","unique_self"),
("rgba(255,255,255,0.5)","more_self"),
("white","common"),
("rgba(255,255,255,0.5)","more_other"),
("rgba(255,255,255,0.2)","unique_other")]:
cumulative += percentages[category]
css.append(color + " " + str(cumulative) + "%")
fullmatch = percentages["common"]
partialmatch = percentages["more_self"] + percentages["more_other"]
match = fullmatch + (partialmatch)/2
pixel_fullmatch = fullmatch * 2.5
pixel_partialmatch = (fullmatch+partialmatch) * 2.5
match = min(match,100)
matchcolor = format(int(min(1,match/50)*255),"02x") * 2 + format(int(max(0,match/50-1)*255),"02x")
return {
"KEY_CIRCLE_CSS":",".join(css),
"KEY_CICLE_COLOR":matchcolor,
"KEY_MATCH":str(round(match,2)),
"KEY_FULLMATCH":str(int(pixel_fullmatch)),
"KEY_PARTIALMATCH":str(int(pixel_partialmatch)),
"KEY_NAME_SELF":owninfo["name"],
"KEY_NAME_OTHER":strangerinfo["name"],
"KEY_BESTARTIST_LINK":artistLink(best[0]),
"KEY_BESTARTIST_IMAGE":getArtistImage(best[0])
},[]

View File

@@ -7,7 +7,7 @@
<script src="javascript/cookies.js"></script>
</head>
<body onload="insertAPIKeyFromCookie()">
<body>
<table class="top_info">
<tr>
<td class="image">

View File

@@ -1,32 +1,81 @@
apikeycorrect = false;
function insertAPIKeyFromCookie() {
cookies = decodeURIComponent(document.cookie).split(';');
for(var i = 0; i <cookies.length; i++) {
cookies[i] = cookies[i].trim()
if (cookies[i].startsWith("apikey=")) {
document.getElementById("apikey").value = cookies[i].replace("apikey=","")
checkAPIkey()
}
var cookies = {};
function getCookies() {
cookiestrings = decodeURIComponent(document.cookie).split(';');
for(var i = 0; i <cookiestrings.length; i++) {
cookiestrings[i] = cookiestrings[i].trim();
[key,value] = cookiestrings[i].split("=");
cookies[key] = value;
}
}
// always on document load, but call specifically when needed early
document.addEventListener("load",getCookies);
function setCookie(key,val,session=true) {
cookies[key] = val;
if (!session) {
var d = new Date();
d.setTime(d.getTime() + (500*24*60*60*1000));
expirestr = "expires=" + d.toUTCString();
}
else {
expirestr = ""
}
document.cookie = encodeURIComponent(key) + "=" + encodeURIComponent(val) + ";" + expirestr;
}
function saveCookies() {
for (var c in cookies) {
document.cookie = encodeURIComponent(c) + "=" + encodeURIComponent(cookies[c]);
}
}
/// RANGE SELECTORS
// in rangeselect.js
/// API KEY
function insertAPIKeyFromCookie() {
element = document.getElementById("apikey")
if (element != null && element != undefined) {
getCookies();
key = cookies["apikey"];
if (key != null && key != undefined) {
element.value = key;
checkAPIkey();
}
}
}
window.addEventListener("load",insertAPIKeyFromCookie);
function saveAPIkey() {
key = document.getElementById("apikey").value
document.cookie = "apikey=" + encodeURIComponent(key)
key = APIkey();
setCookie("apikey",key,false);
}
function checkAPIkey() {
saveAPIkey()
url = "/api/test?key=" + document.getElementById("apikey").value
url = "/api/test?key=" + APIkey()
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && (this.status == 204 || this.status == 205)) {
document.getElementById("apikey").style.backgroundColor = "lawngreen"
apikeycorrect = true
saveAPIkey();
}
else {
document.getElementById("apikey").style.backgroundColor = "red"

View File

@@ -1,28 +1,53 @@
function showRange(identifier,unit) {
// Make all modules disappear
modules = document.getElementsByClassName("stat_module_" + identifier)
modules = document.getElementsByClassName("stat_module_" + identifier);
for (var i=0;i<modules.length;i++) {
//modules[i].setAttribute("style","width:0px;overflow:hidden;")
// cheesy trick to make the allocated space always whatever the biggest module needs
// somehow that messes up pulse on the start page tho
modules[i].setAttribute("style","display:none;")
modules[i].setAttribute("style","display:none;");
}
// Make requested module appear
reactivate = document.getElementsByClassName(identifier + "_" + unit)
reactivate = document.getElementsByClassName(identifier + "_" + unit);
for (var i=0;i<reactivate.length;i++) {
reactivate[i].setAttribute("style","")
reactivate[i].setAttribute("style","");
}
// Set all selectors to unselected
selectors = document.getElementsByClassName("stat_selector_" + identifier)
selectors = document.getElementsByClassName("stat_selector_" + identifier);
for (var i=0;i<selectors.length;i++) {
selectors[i].setAttribute("style","")
selectors[i].setAttribute("style","");
}
// Set the active selector to selected
reactivate = document.getElementsByClassName("selector_" + identifier + "_" + unit)
reactivate = document.getElementsByClassName("selector_" + identifier + "_" + unit);
for (var i=0;i<reactivate.length;i++) {
reactivate[i].setAttribute("style","opacity:0.5;")
reactivate[i].setAttribute("style","opacity:0.5;");
}
links = document.getElementsByClassName("stat_link_" + identifier);
for (let l of links) {
var a = l.href.split("=");
a.splice(-1);
a.push(unit);
l.href = a.join("=");
}
}
function showRangeManual(identifier,unit) {
showRange(identifier,unit);
setCookie("rangeselect_" + identifier,unit);
}
document.addEventListener('DOMContentLoaded',function() {
getCookies();
for (c in cookies) {
if (c.startsWith("rangeselect_")) {
showRange(c.slice(12),cookies[c]);
}
}
})

134
website/less/grisons.less Normal file
View File

@@ -0,0 +1,134 @@
/**
COMMON STYLES FOR MALOJA, ALBULA AND POSSIBLY OTHERS
**/
@BASE_COLOR: #333337;
@BASE_COLOR_DARK: #0a0a0a;
@BASE_COLOR_LIGHT: #444447;
@TEXT_COLOR: beige;
@TEXT_COLOR_SELECTED: fadeout(@TEXT_COLOR,40%);
@TEXT_COLOR_SECONDARY: #bbb;
@TEXT_COLOR_TERTIARY: grey;
@FOCUS_COLOR: yellow;
@CONTROL_ELEMENT_BG_COLOR: rgba(0,255,255,0.1);
@CONTROL_ELEMENT_FG_COLOR: rgba(103,85,0,0.7);
@CONTROL_ELEMENT_FOCUS_COLOR: gold;
@BUTTON_BG_COLOR: @TEXT_COLOR;
@BUTTON_FOCUS_BG_COLOR: @FOCUS_COLOR;
@BUTTON_FG_COLOR: @BASE_COLOR;
@BUTTON_FOCUS_FG_COLOR: @BASE_COLOR;
//@import url('https://fonts.googleapis.com/css?family=Ubuntu');
body {
background-color: @BASE_COLOR;
color: @TEXT_COLOR;
font-family:"Ubuntu";
}
/* TOP INFO TABLE */
table.top_info td.image div {
margin-right:20px;
margin-bottom:20px;
background-size:cover;
background-position:center;
height:174px;
width:174px
}
table.top_info td.text {
vertical-align: top;
}
table.top_info td.text h1 {
display:inline;
padding-right:5px;
}
table.top_info td.text table.image_row td {
height:50px;
width:50px;
background-size:cover;
background-position:center;
background-repeat: no-repeat;
opacity:0.5;
filter: grayscale(80%);
}
table.top_info td.text table.image_row td:hover {
opacity:1;
filter: grayscale(0%);
}
/** SCROLLBAR **/
::-webkit-scrollbar {
width: 8px;
cursor: pointer;
}
::-webkit-scrollbar-track {
background: grey;
background-color: @CONTROL_ELEMENT_BG_COLOR;
}
::-webkit-scrollbar-thumb {
background-color: @CONTROL_ELEMENT_FG_COLOR;
}
::-webkit-scrollbar-thumb:hover {
background: @CONTROL_ELEMENT_FOCUS_COLOR;
}
[onclick]:hover, a:hover {
cursor: pointer;
}
/** HOVERABLE LOAD/PROGRESS BAR **/
div.grisons_bar {
background-color: @CONTROL_ELEMENT_BG_COLOR;
}
div.grisons_bar>div {
height:100%;
background-color: @CONTROL_ELEMENT_FG_COLOR;
}
div.grisons_bar:hover>div {
background-color: @CONTROL_ELEMENT_FOCUS_COLOR;
}
/** LINKS **/
a {
color:inherit;
text-decoration:none;
}
// for links in running text
a.textlink {
color:@FOCUS_COLOR;
}
a.hidelink:hover {
text-decoration:none;
}
a:hover {
text-decoration:underline;
}

View File

@@ -0,0 +1,45 @@
/* cyrillic-ext */
@font-face {
font-family: 'Ubuntu';
font-style: normal;
font-weight: 400;
src: local('Ubuntu Regular'), local('Ubuntu-Regular'), url(https://fonts.gstatic.com/s/ubuntu/v14/4iCs6KVjbNBYlgoKcg72j00.woff2) format('woff2');
}
/* cyrillic */
@font-face {
font-family: 'Ubuntu';
font-style: normal;
font-weight: 400;
src: local('Ubuntu Regular'), local('Ubuntu-Regular'), url(https://fonts.gstatic.com/s/ubuntu/v14/4iCs6KVjbNBYlgoKew72j00.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Ubuntu';
font-style: normal;
font-weight: 400;
src: local('Ubuntu Regular'), local('Ubuntu-Regular'), url(https://fonts.gstatic.com/s/ubuntu/v14/4iCs6KVjbNBYlgoKcw72j00.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Ubuntu';
font-style: normal;
font-weight: 400;
src: local('Ubuntu Regular'), local('Ubuntu-Regular'), url(https://fonts.gstatic.com/s/ubuntu/v14/4iCs6KVjbNBYlgoKfA72j00.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* latin-ext */
@font-face {
font-family: 'Ubuntu';
font-style: normal;
font-weight: 400;
src: local('Ubuntu Regular'), local('Ubuntu-Regular'), url(https://fonts.gstatic.com/s/ubuntu/v14/4iCs6KVjbNBYlgoKcQ72j00.woff2) format('woff2');
}
/* latin */
@font-face {
font-family: 'Ubuntu';
font-style: normal;
font-weight: 400;
src: local('Ubuntu Regular'), local('Ubuntu-Regular'), url(https://fonts.gstatic.com/s/ubuntu/v14/4iCs6KVjbNBYlgoKfw72.woff2) format('woff2');
}

View File

@@ -1,9 +1,6 @@
@import url('https://fonts.googleapis.com/css?family=Ubuntu');
@import "website/less/grisons";
body {
background-color:#333337;
color:beige;
font-family:"Ubuntu";
padding:15px;
padding-bottom:35px;
/**
@@ -15,21 +12,6 @@ body {
*/
}
a {
color:inherit;
text-decoration:none;
}
a.textlink {
color:gold;
}
a.hidelink:hover {
text-decoration:none;
}
a:hover {
text-decoration:underline;
}
input[type="date"] {
@@ -42,6 +24,9 @@ input[type="date"] {
}
/**
Header (unused)
**/
@@ -76,7 +61,7 @@ div.footer {
position:fixed;
height:20px;
/**width:100%;**/
background-color:rgba(10,10,10,0.9);
background-color:@BASE_COLOR_DARK;
bottom:0px;
left:0px;
right:0px;
@@ -185,7 +170,7 @@ div.searchresults table.searchresults_tracks td span:nth-child(1) {
position:fixed;
/*height:30px;*/
/**width:100%;**/
background-color:rgba(10,10,10,0.9);
background-color:@BASE_COLOR_DARK;
bottom:0px;
left:0px;
right:0px;
@@ -218,36 +203,6 @@ div.searchresults table.searchresults_tracks td span:nth-child(1) {
/*
**
**
** TOP INFO TABLE
**
**
*/
table.top_info td.image {
padding:20px;
padding-left:0px;
padding-top:0px;
}
table.top_info td.image div {
background-size:cover;
background-position:center;
height:174px;
width:174px
}
table.top_info td.text {
vertical-align: top;
padding-left: 30px;
}
table.top_info td.text h1 {
display:inline;
padding-right:5px;
}
p.desc a {
padding-left:20px;
@@ -257,7 +212,10 @@ p.desc a {
background-image:url("https://www.last.fm/static/images/lastfm_avatar_twitter.66cd2c48ce03.png");
}
table.top_info + .stat_module_topartists table,
table.top_info + .stat_module_toptracks table {
margin:15px 0;
}
/*
**
@@ -268,17 +226,22 @@ p.desc a {
*/
.paginate {
text-align: center;
padding:30px;
}
.stats {
color:grey;
color:@TEXT_COLOR_TERTIARY;
}
.rank {
text-align:right;
color:grey;
color:@TEXT_COLOR_TERTIARY;
}
.extra {
color:gray; /*sue me*/
color:@TEXT_COLOR_TERTIARY;
font-size:80%;
}
@@ -292,14 +255,14 @@ input#apikey {
input.simpleinput {
font-family:'Ubuntu';
color:beige;
color:@TEXT_COLOR;
outline:none;
border-top: 0px solid;
border-left: 0px solid;
border-right: 0px solid;
padding:2px;
background-color:inherit;
border-bottom: 1px solid beige;
border-bottom: 1px solid @TEXT_COLOR;
}
@@ -379,6 +342,15 @@ img.certrecord {
height:30px;
vertical-align: text-bottom;
}
img.certrecord_small {
height:20px;
vertical-align: text-bottom;
}
img.star {
height:20px;
vertical-align: text-bottom;
}
/*
@@ -430,7 +402,7 @@ table.list tr:hover {
table.list td.time {
width:11%;
color:gray;
color:@TEXT_COLOR_TERTIARY;
}
@@ -476,10 +448,13 @@ table.list td.artists,td.artist,td.title,td.track {
}
table.list td.track span.artist_in_trackcolumn {
color:#bbb;
color:@TEXT_COLOR_SECONDARY;
}
table.list td.track a.trackProviderSearch {
margin-right: 5px;
padding: 0 10px;
}
@@ -519,23 +494,23 @@ table.list td.amount {
}
table.list td.bar {
width:500px;
background-color:#333337;
background-color:@BASE_COLOR;
/* Remove 5er separators for bars */
/*border-color:rgba(0,0,0,0)!important;*/
}
table.list td.bar div {
background-color:beige;
background-color:@TEXT_COLOR;
height:20px; /* can only do this absolute apparently */
position:relative;
}
table.list tr:hover td.bar div {
background-color:yellow;
background-color:@FOCUS_COLOR;
cursor:pointer;
}
table.list td.chart {
width:500px;
background-color:#333337;
background-color:@BASE_COLOR;
/* Remove 5er separators for bars */
/*border-color:rgba(0,0,0,0)!important;*/
}
@@ -581,8 +556,14 @@ table.list tr td.button {
table.list td.button div {
background-color:yellow;
color:#333337;
background-color:@BUTTON_BG_COLOR;
color:@BUTTON_FG_COLOR;
padding:3px;
border-radius:4px;
}
table.list td.button div:hover {
background-color:@BUTTON_FOCUS_BG_COLOR;
color:@BUTTON_FOCUS_FG_COLOR;
padding:3px;
border-radius:4px;
}

View File

@@ -154,7 +154,7 @@
<body onload="insertAPIKeyFromCookie()">
<body>
<table class="top_info">
<tr>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
website/media/star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

BIN
website/media/star_alt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -9,10 +9,10 @@ def instructions(keys):
from htmlmodules import module_performance, module_filterselection
from malojatime import range_desc, delimit_desc
filterkeys, timekeys, delimitkeys, _ = uri_to_internal(keys)
filterkeys, timekeys, delimitkeys, paginatekeys = uri_to_internal(keys)
#equivalent pulse chart
pulselink_keys = internal_to_uri({**filterkeys,**timekeys,**delimitkeys})
pulselink_keys = internal_to_uri({**filterkeys,**timekeys,**delimitkeys,**paginatekeys})
pulselink = "/pulse?" + compose_querystring(pulselink_keys)
pulselink = "<a href=\"" + pulselink + "\"><span>View Pulse</span></a>"
@@ -54,7 +54,7 @@ def instructions(keys):
html_performance = module_performance(**filterkeys,**timekeys,**delimitkeys)
html_performance = module_performance(**filterkeys,**timekeys,**delimitkeys,**paginatekeys)
replace = {
"KEY_PULSE_LINK":pulselink,

46
website/proxy.html Normal file
View File

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Maloja - Proxyscrobble</title>
<script src="javascript/cookies.js"></script>
<script>
window.addEventListener("load",function(){
try {
document.getElementById("lastfmlink").href += window.location.href;
}
catch (e) {
}
});
</script>
</head>
<body>
<table class="top_info">
<tr>
<td class="image">
<div style="background-image:url('/favicon.png')"></div>
</td>
<td class="text">
<h1>Proxyscrobble</h1>
<p class="desc">Duplicate your scrobbles to another service.
Your API key is required to make any changes to the server: <input id='apikey' onchange='checkAPIkey()' style='width:300px;'/></p>
</td>
</tr>
</table>
<table class="list">
<tr>
<td>Last.fm</td>
KEY_STATUS_LASTFM
</tr>
</table>
</body>
</html>

53
website/proxy.py Normal file
View File

@@ -0,0 +1,53 @@
from doreah.settings import get_settings, update_settings
import urllib.request
import hashlib
import xml.etree.ElementTree as ET
from bottle import redirect, request
from database import checkAPIkey
from external import lfmbuild
def instructions(keys):
authenticated = False
if "Cookie" in request.headers:
cookies = request.headers["Cookie"].split(";")
for c in cookies:
if c.strip().startswith("apikey="):
authenticated = checkAPIkey(c.strip()[7:])
if "token" in keys and authenticated:
token = keys.get("token")
parameters = {
"method":"auth.getSession",
"token":token,
"api_key":get_settings("LASTFM_API_KEY")
}
response = urllib.request.urlopen("http://ws.audioscrobbler.com/2.0/?" + lfmbuild(parameters))
xml = response.read()
data = ET.fromstring(xml)
if data.attrib.get("status") == "ok":
username = data.find("session").find("name").text
sessionkey = data.find("session").find("key").text
update_settings("settings/settings.ini",{"LASTFM_API_SK":sessionkey,"LASTFM_USERNAME":username},create_new=True)
return "/proxy"
else:
key,secret,sessionkey,name = get_settings("LASTFM_API_KEY","LASTFM_API_SECRET","LASTFM_API_SK","LASTFM_USERNAME")
if key is None:
lastfm = "<td>No Last.fm key provided</td>"
elif secret is None:
lastfm = "<td>No Last.fm secret provided</td>"
elif sessionkey is None and authenticated:
url = "http://www.last.fm/api/auth/?api_key=" + key + "&cb="
lastfm = "<td class='button'><a id='lastfmlink' href='" + url + "'><div>Connect</div></a></td>"
elif sessionkey is None:
lastfm = "<td>Not active</td>"
else:
lastfm = "<td>Account: " + name + "</td>"
return {"KEY_STATUS_LASTFM":lastfm},[]

View File

@@ -9,11 +9,11 @@ def instructions(keys):
from htmlmodules import module_pulse, module_filterselection
from malojatime import range_desc, delimit_desc
filterkeys, timekeys, delimitkeys, _ = uri_to_internal(keys)
filterkeys, timekeys, delimitkeys, paginatekeys = uri_to_internal(keys)
#equivalent performance chart if we're not looking at the overall pulse
if len(filterkeys) != 0:
performancelink_keys = internal_to_uri({**filterkeys,**timekeys,**delimitkeys})
performancelink_keys = internal_to_uri({**filterkeys,**timekeys,**delimitkeys,**paginatekeys})
performancelink = "/performance?" + compose_querystring(performancelink_keys)
performancelink = "<a href=\"" + performancelink + "\"><span>View Rankings</span></a>"
@@ -57,7 +57,7 @@ def instructions(keys):
html_pulse = module_pulse(**filterkeys,**timekeys,**delimitkeys)
html_pulse = module_pulse(**filterkeys,**timekeys,**delimitkeys,**paginatekeys)
replace = {
"KEY_RANKINGS_LINK":performancelink,

View File

@@ -58,7 +58,7 @@
</head>
<body onload="replace();insertAPIKeyFromCookie()">
<body onload="replace()">
<table class="top_info">
<tr>
<td class="image">

View File

@@ -4,10 +4,12 @@
<head>
<meta charset="UTF-8" />
<title>Maloja</title>
<script src="javascript/rangeselect.js"></script>
<script>document.addEventListener('DOMContentLoaded',function() {
KEY_JS_INIT_RANGES
})</script>
<script src="javascript/cookies.js"></script>
<script src="javascript/rangeselect.js"></script>
</head>
@@ -18,15 +20,15 @@
</div>-->
<h1><a href="/charts_artists?max=50">Top Artists</a></h1>
<h1><a class="stat_link_topartists" href="/charts_artists?in=alltime">Top Artists</a></h1>
<!--All Time | This Year | This Month | This Week-->
<span onclick="showRange('topartists','week')" class="stat_selector_topartists selector_topartists_week">This Week</span>
| <span onclick="showRange('topartists','month')" class="stat_selector_topartists selector_topartists_month">This Month</span>
| <span onclick="showRange('topartists','year')" class="stat_selector_topartists selector_topartists_year">This Year</span>
| <span onclick="showRange('topartists','alltime')" class="stat_selector_topartists selector_topartists_alltime" style="opacity:0.5;">All Time</span>
<span onclick="showRangeManual('topartists','week')" class="stat_selector_topartists selector_topartists_week">This Week</span>
| <span onclick="showRangeManual('topartists','month')" class="stat_selector_topartists selector_topartists_month">This Month</span>
| <span onclick="showRangeManual('topartists','year')" class="stat_selector_topartists selector_topartists_year">This Year</span>
| <span onclick="showRangeManual('topartists','alltime')" class="stat_selector_topartists selector_topartists_alltime" style="opacity:0.5;">All Time</span>
<br/><br/>
@@ -38,13 +40,13 @@
<h1><a href="/charts_tracks?max=50">Top Tracks</a></h1>
<h1><a class="stat_link_toptracks" href="/charts_tracks?in=alltime">Top Tracks</a></h1>
<span onclick="showRange('toptracks','week')" class="stat_selector_toptracks selector_toptracks_week">This Week</span>
| <span onclick="showRange('toptracks','month')" class="stat_selector_toptracks selector_toptracks_month">This Month</span>
| <span onclick="showRange('toptracks','year')" class="stat_selector_toptracks selector_toptracks_year">This Year</span>
| <span onclick="showRange('toptracks','alltime')" class="stat_selector_toptracks selector_toptracks_alltime" style="opacity:0.5;">All Time</span>
| <span onclick="showRangeManual('toptracks','month')" class="stat_selector_toptracks selector_toptracks_month">This Month</span>
| <span onclick="showRangeManual('toptracks','year')" class="stat_selector_toptracks selector_toptracks_year">This Year</span>
| <span onclick="showRangeManual('toptracks','alltime')" class="stat_selector_toptracks selector_toptracks_alltime" style="opacity:0.5;">All Time</span>
<br/><br/>
@@ -59,7 +61,7 @@
<div class="sidelist">
<h1><a href="/scrobbles?max=100">Last Scrobbles</a></h1>
<h1><a href="/scrobbles">Last Scrobbles</a></h1>
<span class="stats">Today</span> KEY_SCROBBLE_NUM_TODAY
<span class="stats">This Week</span> KEY_SCROBBLE_NUM_WEEK
<span class="stats">This Month</span> KEY_SCROBBLE_NUM_MONTH
@@ -73,7 +75,7 @@
<br/>
<h1><a href="/pulse?step=month&trail=1">Pulse</a></h1>
<h1><a class="stat_link_pulse" href="/pulse?trail=1&step=month">Pulse</a></h1>
<!--
<a href="/pulse?step=day&trail=1">Days</a>
<a href="/pulse?step=week&trail=1">Weeks</a>
@@ -81,10 +83,10 @@
<a href="/pulse?step=year&trail=1">Years</a>
-->
<span onclick="showRange('pulse','days')" class="stat_selector_pulse selector_pulse_days">7 days</span>
| <span onclick="showRange('pulse','weeks')" class="stat_selector_pulse selector_pulse_weeks">12 weeks</span>
| <span onclick="showRange('pulse','months')" class="stat_selector_pulse selector_pulse_months" style="opacity:0.5;">12 months</span>
| <span onclick="showRange('pulse','years')" class="stat_selector_pulse selector_pulse_years">10 years</span>
<span onclick="showRangeManual('pulse','day')" class="stat_selector_pulse selector_pulse_day">7 days</span>
| <span onclick="showRangeManual('pulse','week')" class="stat_selector_pulse selector_pulse_week">12 weeks</span>
| <span onclick="showRangeManual('pulse','month')" class="stat_selector_pulse selector_pulse_month" style="opacity:0.5;">12 months</span>
| <span onclick="showRangeManual('pulse','year')" class="stat_selector_pulse selector_pulse_year">10 years</span>
<!--
### this is for extra views of the current canonical week / month / year
<br/>
@@ -94,10 +96,10 @@
-->
<br/><br/>
<span class="stat_module_pulse pulse_months">KEY_PULSE_MONTHS</span>
<span class="stat_module_pulse pulse_days" style="display:none;">KEY_PULSE_DAYS</span>
<span class="stat_module_pulse pulse_years" style="display:none;">KEY_PULSE_YEARS</span>
<span class="stat_module_pulse pulse_weeks" style="display:none;">KEY_PULSE_WEEKS</span>
<span class="stat_module_pulse pulse_month">KEY_PULSE_MONTHS</span>
<span class="stat_module_pulse pulse_day" style="display:none;">KEY_PULSE_DAYS</span>
<span class="stat_module_pulse pulse_year" style="display:none;">KEY_PULSE_YEARS</span>
<span class="stat_module_pulse pulse_week" style="display:none;">KEY_PULSE_WEEKS</span>
<!--
<span class="stat_module_pulse pulse_week" style="display:none;">KEY_PULSE_WEEK</span>
<span class="stat_module_pulse pulse_month" style="display:none;">KEY_PULSE_MONTH</span>

View File

@@ -12,7 +12,7 @@ def instructions(keys):
# commands to execute on load for default ranges
js_command = "showRange('topartists','" + get_settings("DEFAULT_RANGE_CHARTS_ARTISTS") + "');"
js_command += "showRange('toptracks','" + get_settings("DEFAULT_RANGE_CHARTS_TRACKS") + "');"
js_command += "showRange('pulse','" + get_settings("DEFAULT_RANGE_PULSE") + "');"
js_command += "showRange('pulse','" + get_settings("DEFAULT_STEP_PULSE") + "');"
clock()

View File

@@ -4,7 +4,8 @@
<head>
<meta charset="UTF-8" />
<title>Maloja - KEY_TRACKTITLE</title>
<script src="javascript/rangeselect.js" async></script>
<script src="javascript/cookies.js" ></script>
<script src="javascript/rangeselect.js"></script>
</head>
<body>
@@ -15,12 +16,12 @@
</td>
<td class="text">
<span>KEY_ARTISTS</span><br/>
<h1>KEY_TRACKTITLE</h1> KEY_CERTS <span class="rank"><a href="/charts_tracks?max=100">KEY_POSITION</a></span>
<h1>KEY_TRACKTITLE</h1> KEY_CERTS <span class="rank"><a href="/charts_tracks">KEY_POSITION</a></span>
<p class="stats"><a href="/scrobbles?KEY_SCROBBLELINK">KEY_SCROBBLES Scrobbles</a></p>
<p class="desc"></p>
<span>KEY_MEDALS</span>
<span>KEY_MEDALS</span> <span>KEY_TOPWEEKS</span>
</td>
</tr>
</table>
@@ -29,32 +30,32 @@
<table class="twopart">
<tr>
<td>
<h2><a href='/pulse?KEY_SCROBBLELINK&step=year&trail=1'>Pulse</a></h2>
<span onclick="showRange('pulse','days')" class="stat_selector_pulse selector_pulse_days">7 days</span>
| <span onclick="showRange('pulse','weeks')" class="stat_selector_pulse selector_pulse_weeks">12 weeks</span>
| <span onclick="showRange('pulse','months')" class="stat_selector_pulse selector_pulse_months" style="opacity:0.5;">12 months</span>
| <span onclick="showRange('pulse','years')" class="stat_selector_pulse selector_pulse_years">10 years</span>
<h2><a class="stat_link_pulse" href='/pulse?KEY_SCROBBLELINK&trail=1&step=month'>Pulse</a></h2>
<span onclick="showRangeManual('pulse','day')" class="stat_selector_pulse selector_pulse_day">7 days</span>
| <span onclick="showRangeManual('pulse','week')" class="stat_selector_pulse selector_pulse_week">12 weeks</span>
| <span onclick="showRangeManual('pulse','month')" class="stat_selector_pulse selector_pulse_month" style="opacity:0.5;">12 months</span>
| <span onclick="showRangeManual('pulse','year')" class="stat_selector_pulse selector_pulse_year">10 years</span>
<br/><br/>
<span class="stat_module_pulse pulse_months">KEY_PULSE_MONTHS</span>
<span class="stat_module_pulse pulse_days" style="display:none;">KEY_PULSE_DAYS</span>
<span class="stat_module_pulse pulse_years" style="display:none;">KEY_PULSE_YEARS</span>
<span class="stat_module_pulse pulse_weeks" style="display:none;">KEY_PULSE_WEEKS</span>
<span class="stat_module_pulse pulse_month">KEY_PULSE_MONTHS</span>
<span class="stat_module_pulse pulse_day" style="display:none;">KEY_PULSE_DAYS</span>
<span class="stat_module_pulse pulse_year" style="display:none;">KEY_PULSE_YEARS</span>
<span class="stat_module_pulse pulse_week" style="display:none;">KEY_PULSE_WEEKS</span>
</td>
<td>
<h2><a href='/performance?KEY_SCROBBLELINK&step=year&trail=1'>Performance</a></h2>
<span onclick="showRange('pulse','days')" class="stat_selector_pulse selector_pulse_days">7 days</span>
| <span onclick="showRange('pulse','weeks')" class="stat_selector_pulse selector_pulse_weeks">12 weeks</span>
| <span onclick="showRange('pulse','months')" class="stat_selector_pulse selector_pulse_months" style="opacity:0.5;">12 months</span>
| <span onclick="showRange('pulse','years')" class="stat_selector_pulse selector_pulse_years">10 years</span>
<h2><a class="stat_link_pulse" href='/performance?KEY_SCROBBLELINK&trail=1&step=month'>Performance</a></h2>
<span onclick="showRangeManual('pulse','day')" class="stat_selector_pulse selector_pulse_day">7 days</span>
| <span onclick="showRangeManual('pulse','week')" class="stat_selector_pulse selector_pulse_week">12 weeks</span>
| <span onclick="showRangeManual('pulse','month')" class="stat_selector_pulse selector_pulse_month" style="opacity:0.5;">12 months</span>
| <span onclick="showRangeManual('pulse','year')" class="stat_selector_pulse selector_pulse_year">10 years</span>
<br/><br/>
<span class="stat_module_pulse pulse_months">KEY_PERFORMANCE_MONTHS</span>
<span class="stat_module_pulse pulse_days" style="display:none;">KEY_PERFORMANCE_DAYS</span>
<span class="stat_module_pulse pulse_years" style="display:none;">KEY_PERFORMANCE_YEARS</span>
<span class="stat_module_pulse pulse_weeks" style="display:none;">KEY_PERFORMANCE_WEEKS</span>
<span class="stat_module_pulse pulse_month">KEY_PERFORMANCE_MONTHS</span>
<span class="stat_module_pulse pulse_day" style="display:none;">KEY_PERFORMANCE_DAYS</span>
<span class="stat_module_pulse pulse_year" style="display:none;">KEY_PERFORMANCE_YEARS</span>
<span class="stat_module_pulse pulse_week" style="display:none;">KEY_PERFORMANCE_WEEKS</span>
</td>
</tr>
</table>

View File

@@ -29,13 +29,19 @@ def instructions(keys):
if "medals" in data and data["medals"] is not None:
if "gold" in data["medals"]:
for y in data["medals"]["gold"]:
html_medals += "<a title='Best Track in " + str(y) + "' class='hidelink medal shiny gold' href='/charts_tracks?max=50&in=" + str(y) + "'><span>" + str(y) + "</span></a>"
html_medals += "<a title='Best Track in " + str(y) + "' class='hidelink medal shiny gold' href='/charts_tracks?in=" + str(y) + "'><span>" + str(y) + "</span></a>"
if "silver" in data["medals"]:
for y in data["medals"]["silver"]:
html_medals += "<a title='Second Best Track in " + str(y) + "' class='hidelink medal shiny silver' href='/charts_tracks?max=50&in=" + str(y) + "'><span>" + str(y) + "</span></a>"
html_medals += "<a title='Second Best Track in " + str(y) + "' class='hidelink medal shiny silver' href='/charts_tracks?in=" + str(y) + "'><span>" + str(y) + "</span></a>"
if "bronze" in data["medals"]:
for y in data["medals"]["bronze"]:
html_medals += "<a title='Third Best Track in " + str(y) + "' class='hidelink medal shiny bronze' href='/charts_tracks?max=50&in=" + str(y) + "'><span>" + str(y) + "</span></a>"
html_medals += "<a title='Third Best Track in " + str(y) + "' class='hidelink medal shiny bronze' href='/charts_tracks?in=" + str(y) + "'><span>" + str(y) + "</span></a>"
html_topweeks = ""
if data.get("topweeks") not in [0,None]:
link = "/performance?" + compose_querystring(keys) + "&trail=1&step=week"
title = str(data["topweeks"]) + " weeks on #1"
html_topweeks = "<a title='" + title + "' href='" + link + "'><img class='star' src='/media/star.png' />" + str(data["topweeks"]) + "</a>"
@@ -65,6 +71,7 @@ def instructions(keys):
"KEY_SCROBBLELINK":compose_querystring(keys),
"KEY_MEDALS":html_medals,
"KEY_CERTS":html_cert,
"KEY_TOPWEEKS":html_topweeks,
"KEY_SCROBBLELIST":html_scrobbles,
# pulse
"KEY_PULSE_MONTHS":html_pulse_months,