Better time window specifications (since, to and in)

This commit is contained in:
Krateng 2019-02-15 15:41:58 +01:00
parent 3a06123255
commit 4faf9a9490
5 changed files with 54 additions and 31 deletions

View File

@ -28,15 +28,15 @@ The software works fairly well and has a few web views, but there is only one sc
## How to install
I wouldn't recommend it yet. But if you want to test Maloja, it's fairly easy:
Installing Maloja is fairly easy on a Linux machine. Don't ask me how to do it on Windows, I have no clue.
1) Install the requirements:
* [bottle.py](https://github.com/bottlepy/bottle)
* [waitress](https://github.com/Pylons/waitress)
2) Put the Maloja folder anywhere and start server.py.
2) Put it anywhere and start server.py
3) (Recommended) Put your server behind a reverse proxy for SSL encryption. Configure that proxy to rewrite /db/ requests to the database port. In nginx this would look as follows:
location / {
@ -47,5 +47,7 @@ I wouldn't recommend it yet. But if you want to test Maloja, it's fairly easy:
rewrite ^/db(.*)$ $1 break;
proxy_pass http://yoururl:42011;
}
If you would like to import all your previous last.fm scrobbles, use [benfoxall's website](https://benjaminbenben.com/lastfm-to-csv/) ([GitHub page](https://github.com/benfoxall/lastfm-to-csv)). Use the python script lastfmconverter.py with two arguments - the downloaded csv file and your new tsv file - to convert your data. Place the tsv file in scrobbles/ and the server will recognize it on startup.
4) In order to scrobble your music from Plex Web, install the included Chrome extension. Make sure to generate a random key and enter that key in the extension as well as the file autenticated_machines.tsv in the clients folder.
5) If you would like to import all your previous last.fm scrobbles, use [benfoxall's website](https://benjaminbenben.com/lastfm-to-csv/) ([GitHub page](https://github.com/benfoxall/lastfm-to-csv)). Use the python script lastfmconverter.py with two arguments - the downloaded csv file and your new tsv file - to convert your data. Place the tsv file in scrobbles/ and the server will recognize it on startup.

View File

@ -141,7 +141,7 @@ def test_server():
def get_scrobbles():
keys = FormsDict.decode(request.query)
r = db_query(artists=keys.getall("artist"),title=keys.get("title"),since=keys.get("since"),to=keys.get("to"),associated=(keys.get("associated")!=None))
r = db_query(artists=keys.getall("artist"),title=keys.get("title"),since=keys.get("since"),to=keys.get("to"),within=keys.get("in"),associated=(keys.get("associated")!=None))
r.reverse()
if keys.get("max") is not None:
@ -153,7 +153,7 @@ def get_scrobbles():
def get_scrobbles():
keys = FormsDict.decode(request.query)
r = db_query(artists=keys.getall("artist"),title=keys.get("title"),since=keys.get("since"),to=keys.get("to"),associated=(keys.get("associated")!=None))
r = db_query(artists=keys.getall("artist"),title=keys.get("title"),since=keys.get("since"),to=keys.get("to"),within=keys.get("in"),associated=(keys.get("associated")!=None))
r.reverse()
return {"amount":len(r)}
@ -189,30 +189,34 @@ def get_amounts():
def get_charts_artists():
since = request.query.get("since")
to = request.query.get("to")
within=request.query.get("in")
return {"list":db_aggregate(by="ARTIST",since=since,to=to)}
return {"list":db_aggregate(by="ARTIST",since=since,to=to,within=within)}
@dbserver.route("/charts/tracks")
def get_charts_tracks():
keys = FormsDict.decode(request.query)
since = keys.get("since")
to = keys.get("to")
within=request.query.get("in")
artist = keys.get("artist")
return {"list":db_aggregate(by="TRACK",since=since,to=to,artist=artist)}
return {"list":db_aggregate(by="TRACK",since=since,to=to,within=within,artist=artist)}
@dbserver.route("/charts")
def get_charts():
since = request.query.get("since")
to = request.query.get("to")
within=request.query.get("in")
return {"number":db_aggregate(since=since,to=to)}
return {"number":db_aggregate(since=since,to=to,within=within)}
@dbserver.route("/pulse")
def get_pulse():
since = request.query.get("since")
to = request.query.get("to")
(ts_start,ts_end) = getTimestamps(since,to)
within=request.query.get("in")
(ts_start,ts_end) = getTimestamps(since,to,within)
step = request.query.get("step","month")
trail = int(request.query.get("trail",3))
@ -244,7 +248,8 @@ def get_pulse():
def get_top_artists():
since = request.query.get("since")
to = request.query.get("to")
(ts_start,ts_end) = getTimestamps(since,to)
within=request.query.get("in")
(ts_start,ts_end) = getTimestamps(since,to,within)
step = request.query.get("step","month")
trail = int(request.query.get("trail",3))
@ -278,7 +283,8 @@ def get_top_artists():
def get_top_tracks():
since = request.query.get("since")
to = request.query.get("to")
(ts_start,ts_end) = getTimestamps(since,to)
within=request.query.get("in")
(ts_start,ts_end) = getTimestamps(since,to,within)
step = request.query.get("step","month")
trail = int(request.query.get("trail",3))
@ -323,7 +329,13 @@ def getStartOf(timestamp,unit):
newdate = date - d
return [newdate.year,newdate.month,newdate.day]
def getNext(time,unit,step=1):
def getNext(time,unit="auto",step=1):
if unit == "auto":
# see how long the list is, increment by the last specified unit
unit = [None,"year","month","day"][len(time)]
while len(time) < 3:
time.append(1)
if unit == "year":
return [time[0] + step,time[1],time[2]]
elif unit == "month":
@ -653,8 +665,8 @@ def sync():
# Queries the database
def db_query(artists=None,title=None,track=None,since=None,to=None,associated=False):
(since, to) = getTimestamps(since,to)
def db_query(artists=None,title=None,track=None,since=None,to=None,within=None,associated=False):
(since, to) = getTimestamps(since,to,within)
# this is not meant as a search function. we *can* query the db with a string, but it only works if it matches exactly
# if a title is specified, we assume that a specific track (with the exact artist combination) is requested
@ -686,8 +698,8 @@ def db_query(artists=None,title=None,track=None,since=None,to=None,associated=Fa
# Queries that... well... aggregate
def db_aggregate(by=None,since=None,to=None,artist=None):
(since, to) = getTimestamps(since,to)
def db_aggregate(by=None,since=None,to=None,withinin=None,artist=None):
(since, to) = getTimestamps(since,to,within)
if isinstance(artist, str):
artist = ARTISTS.index(artist)
@ -746,9 +758,14 @@ def db_search(query,type=None):
####
# Takes user inputs like YYYY/MM and returns the timestamps. Returns timestamp if timestamp was already given.
def getTimestamps(f,t):
#(f,t) = inp
# Takes user inputs like YYYY/MM and returns the timestamps. Returns timestamp if timestamp was already given.
# to dates are interpreted differently (from 2010 and to 2010 both include all of 2010)
def getTimestamps(f=None,t=None,i=None):
if i is not None:
f = i
t = i
if isinstance(f, str) and f.lower() == "today":
tod = datetime.datetime.utcnow()
f = [tod.year,tod.month,tod.day]
@ -782,15 +799,18 @@ def getTimestamps(f,t):
# this step is done if either the input is a list or the first step was done (which creates a list)
if isinstance(f, list):
date = [1970,1,1,0,0]
date[:len(f)] = f
f = int(datetime.datetime(date[0],date[1],date[2],date[3],date[4],tzinfo=datetime.timezone.utc).timestamp())
#date = [1970,1,1,0,0]
#date[:len(f)] = f
while len(f) < 3: f.append(1) # padding month and day
#f = int(datetime.datetime(date[0],date[1],date[2],date[3],date[4],tzinfo=datetime.timezone.utc).timestamp())
f = int(datetime.datetime(f[0],f[1],f[2],tzinfo=datetime.timezone.utc).timestamp())
if isinstance(t, list):
date = [1970,1,1,0,0]
date[:len(t)] = t
t = int(datetime.datetime(date[0],date[1],date[2],date[3],date[4],tzinfo=datetime.timezone.utc).timestamp())
t = getNext(t) # going on step forward automatically pads month and day
#date = [1970,1,1,0,0]
#date[:len(t)] = t
#t = int(datetime.datetime(date[0],date[1],date[2],date[3],date[4],tzinfo=datetime.timezone.utc).timestamp())
t = int(datetime.datetime(t[0],t[1],t[2],tzinfo=datetime.timezone.utc).timestamp())
if (f==None):
f = min(timestamps)
@ -801,6 +821,8 @@ def getTimestamps(f,t):
def getArtistId(nameorid):
if isinstance(nameorid,int):
return nameorid

View File

@ -74,7 +74,7 @@ def getTimeDesc(timestamp,short=False):
difference = int(difference/60)
if difference < 24: return str(difference) + " hours ago" if difference>1 else str(difference) + " hour ago"
difference = int(difference/24)
if difference < 7: return tim.strftime("%A")
if difference < 5: return tim.strftime("%A")
if difference < 31: return str(difference) + " days ago" if difference>1 else str(difference) + " day ago"
#if difference < 300 and tim.year == now.year: return tim.strftime("%B")
#if difference < 300: return tim.strftime("%B %Y")

View File

@ -3,7 +3,7 @@
"version": "0.1",
"description": "Scrobbles tracks from Plex Web to your Maloja server",
"manifest_version": 2,
"permissions": ["activeTab", "declarativeContent","tabs","storage","http://app.plex.tv/*","https://app.plex.tv/*"],
"permissions": ["activeTab", "declarativeContent","tabs","storage","http://app.plex.tv/*","https://app.plex.tv/*","<all_urls>"],
"background":
{
"scripts":

View File

@ -26,7 +26,6 @@ def replacedict(keys,dbport):
# get chart data
# artists
print("REQUESTING " + "http://[::1]:" + str(dbport) + "/charts/artists")
response = urllib.request.urlopen("http://[::1]:" + str(dbport) + "/charts/artists")
db_data = json.loads(response.read())
charts = db_data["list"][:max_show]