From 1809da38e6b83e7822e617526c584d624bdcd663 Mon Sep 17 00:00:00 2001 From: Krateng Date: Sun, 3 Mar 2019 13:38:53 +0100 Subject: [PATCH] Added different pulses on start page --- malojatime.py | 186 +++++++++------------------------------------ website/maloja.css | 5 ++ website/start.html | 35 ++++++++- website/start.py | 25 ++++-- 4 files changed, 93 insertions(+), 158 deletions(-) diff --git a/malojatime.py b/malojatime.py index df9d233..42acd00 100644 --- a/malojatime.py +++ b/malojatime.py @@ -11,150 +11,7 @@ def register_scrobbletime(timestamp): FIRST_SCROBBLE = int(timestamp) -# This is meant to be a time object that is aware of its own precision -# now I know what you're saying -# "This is total overengineering, Jimmy!" -# "Just convert all user input into timestamps right at the entry into the database and only work with those" -# "You can get the range descriptions right at the start as well or even generate them from timestamps with a simple comparison" -# and you are absolutely correct -# but my name isn't Jimmy -# so we're doing objects -#class Time(): -# -# precision = 0 -# # 0 unused, no information at all, embrace eternity -# # 1 year -# # 2 month -# # 3 day -# # 4 specified by exact timestamp -# -# def __init__(self,*time): -# # time can be a int (timestamp), list or string (/-delimited list) -# -# if len(time) == 1: -# time = time[0] #otherwise we will already have a tuple and we can deal with that -# if isinstance(time,int) and time < 10000: time = [time] # if we have a low number, it's not a timestamp, but a year -# -# -# if isinstance(time,str): -# time = time.split("/") -# if isinstance(time,list) or isinstance(time,tuple): -# time = [int(x) for x in time][:3] -# self.precision = len(time) -# if len(time) > 0: self.YEAR = time[0] -# if len(time) > 1: self.MONTH = time[1] -# if len(time) > 2: self.DAY = time[2] -# elif isinstance(time,int): -# self.precision = 4 -# self.TIMESTAMP = time -# dt = datetime.datetime.utcfromtimestamp(time) -# self.YEAR, self.MONTH, self.DAY = dt.year, dt.month, dt.day -# -# -# def _array(self): -# if self.precision == 4: -# timeobject = datetime.datetime.utcfromtimestamp(self.TIMESTAMP) -# return [timeobject.year,timeobject.month,timeobject.day] -# if self.precision == 3: return [self.YEAR,self.MONTH,self.DAY] -# if self.precision == 2: return [self.YEAR,self.MONTH] -# if self.precision == 1: return [self.YEAR] -# -# -# def get(self): -# if self.precision == 4: return self.TIMESTAMP -# if self.precision == 3: return [self.YEAR,self.MONTH,self.DAY] -# if self.precision == 2: return [self.YEAR,self.MONTH] -# if self.precision == 1: return [self.YEAR] -# -# def getStartTimestamp(self): -# if self.precision == 4: return self.TIMESTAMP -# else: -# YEAR = self.YEAR if self.precision > 0 else 1970 -# MONTH = self.MONTH if self.precision > 1 else 1 -# DAY = self.DAY if self.precision > 2 else 1 -# return int(datetime.datetime(YEAR,MONTH,DAY,tzinfo=datetime.timezone.utc).timestamp()) -# -# def getEndTimestamp(self): -# if self.precision == 4: return self.TIMESTAMP -# else: return self.getNext().getStartTimestamp()-1 -# -# # get next time of the same precision, e.g. next month if month of this time was defined (even if it's 1 or 12) -# def getNext(self,obj=True): -# if self.precision == 4: result = self.TIMESTAMP + 1 -# else: result = _getNext(self._array()) -# -# if obj: return Time(result) -# else: return result -# -# -# def pad(self,precision=3): -# arrayA, arrayB = self._array(), self._array() -# if self.precision < min(2,precision): -# arrayA.append(1) -# arrayB.append(12) -# if self.precision+1 < min(3,precision): -# arrayA.append(1) -# arrayB.append(monthrange(*arrayB)[1]) -# -# return (arrayA,arrayB) -# -# def describe(self,short=False): -# if self.precision == 4: -# if short: -# now = datetime.datetime.now(tz=datetime.timezone.utc) -# difference = int(now.timestamp() - self.TIMESTAMP) -# -# if difference < 10: return "just now" -# if difference < 60: return str(difference) + " seconds ago" -# difference = int(difference/60) -# if difference < 60: return str(difference) + " minutes ago" if difference>1 else str(difference) + " minute ago" -# difference = int(difference/60) -# if difference < 24: return str(difference) + " hours ago" if difference>1 else str(difference) + " hour ago" -# difference = int(difference/24) -# timeobject = datetime.datetime.utcfromtimestamp(self.TIMESTAMP) -# if difference < 5: return timeobject.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") -# -# return timeobject.strftime("%d. %B %Y") -# else: -# timeobject = datetime.datetime.utcfromtimestamp(self.TIMESTAMP) -# return tim.strftime("%d. %b %Y %I:%M %p") -# -# else: -# YEAR = self.YEAR if self.precision > 0 else 2022 -# MONTH = self.MONTH if self.precision > 1 else 5 #else numbers dont matter, just needed to create the datetime object -# DAY = self.DAY if self.precision > 2 else 4 -# timeobject = datetime.datetime(YEAR,MONTH,DAY,tzinfo=datetime.timezone.utc) -# if self.precision == 3: return timeobject.strftime("%d. %B %Y") -# if self.precision == 2: return timeobject.strftime("%B %Y") -# if self.precision == 1: return timeobject.strftime("%Y") -# if self.precision == 0: return "Embrace Eternity" - - -#def getRange(timeA,timeB): -# return (timeA.getStartTimestamp(),timeB.getEndTimestamp()) -# -#def getRangeDesc(timeA,timeB): -# aA, aB = timeA.get(), timeB.get() -# if len(aA) != len(aB): -# prec = max(len(aA),len(aB)) -# aA, aB = timeA.pad(prec)[0], timeB.pad(prec)[1] -# if aA == aB: -# return Time(aA).describe() -# if aA[:-1] == aB[:-1]: -# return " ".join(Time(aA).describe().split(" ")[:-1]) + " to " + Time(aB).describe() #what -# - - -# alright forget everything I've just told you -# so how bout this: -# we completely ignore times -# all singular times (only used for scrobbles) are only ever expressed in timestamps anyway and remain simple ints -# ranges specified in any kind of list are completely separated from them -# even if you specify the pulse -# holy feck this is so much better + # converts strings and stuff to lists @@ -184,7 +41,7 @@ def time_pad(f,t): f,t = time_fix(f), time_fix(t) while len(f) < len(t): if len(f) == 1: f.append(1) - elif len(f) == 2: f.append(1) + elif len(f) == 2: f.append(1) while len(f) > len(t): if len(t) == 1: t.append(12) elif len(t) == 2: t.append(monthrange(*t)[1]) @@ -221,12 +78,31 @@ def time_desc(t,short=False): date = [1970,1,1] date[:len(t)] = t timeobject = datetime.datetime(date[0],date[1],date[2],tzinfo=datetime.timezone.utc) + + nowdate = [1970,1,1] + nowobject = datetime.datetime.now(tz=datetime.timezone.utc) + nowdate[:len(t)] = [nowobject.year, nowobject.month, nowobject.day][:len(t)] + nowobject = datetime.datetime(nowdate[0],nowdate[1],nowdate[2],tzinfo=datetime.timezone.utc) + if short: + if len(t) == 3: + diff = (nowobject - timeobject).days + if diff == 0: return "Today" + if diff == 1: return "Yesterday" + if diff < 7: return timeobject.strftime("%A") + #elif len(t) == 2: + + if len(t) == 3: return timeobject.strftime("%d. %B %Y") if len(t) == 2: return timeobject.strftime("%B %Y") if len(t) == 1: return timeobject.strftime("%Y") def range_desc(since=None,to=None,within=None,short=False): + # the 'short' var we pass down to some of the time_desc calls is a different one than the one here + # the function-wide one indicates whether we want the 'in' 'from' etc at the start + # the other one is if we want exact dates or weekdays etc + + if within is not None: since = within to = within @@ -257,10 +133,15 @@ def range_desc(since=None,to=None,within=None,short=False): since,to = time_pad(since,to) if since == to: if len(since) == 3: - sincestr = "on " + time_desc(since) + sincestr = "on " + time_desc(since,short=True) else: - sincestr = "in " + time_desc(since) - shortsincestr = time_desc(since) + sincestr = "in " + time_desc(since,short=True) + shortsincestr = time_desc(since,short=True) + tostr = "" + elif _week(since,to): + + sincestr = "in " + _week(since,to) + shortsincestr = _week(since,to) tostr = "" else: fparts = time_desc(since).split(" ") @@ -333,6 +214,15 @@ def delimit_desc(step="month",stepn=1,trail=1): return txt +def _week(since,to): + if len(since) != 3 or len(to) != 3: return False + dt_since, dt_to = datetime.datetime(*since,tzinfo=datetime.timezone.utc), datetime.datetime(*to,tzinfo=datetime.timezone.utc) + if (dt_to - dt_since).days != 6: return False + if dt_since.weekday() != 6: return False + + c = dt_to.isocalendar()[:2] + return str("Week " + str(c[1]) + " " + str(c[0])) + def _num(i): names = ["Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Eleven","Twelve"] if i < len(names): return names[i] diff --git a/website/maloja.css b/website/maloja.css index fb98b36..ab135d7 100644 --- a/website/maloja.css +++ b/website/maloja.css @@ -109,6 +109,11 @@ a { +span.stat_selector_pulse { + cursor:pointer; +} + + /* ** ** diff --git a/website/start.html b/website/start.html index c9fc7da..98c39b0 100644 --- a/website/start.html +++ b/website/start.html @@ -5,8 +5,27 @@ Maloja + + + + +

Top Artists

@@ -117,7 +136,7 @@ All Time KEY_SCROBBLES_TOTAL

- KEY_SCROBBLES + KEY_SCROBBLES
@@ -130,10 +149,18 @@ MonthsYears --> + + 7 days + | 12 weeks + | 12 months + | 10 years +

- KEY_PULSE - + KEY_PULSE_MONTHS + + + @@ -142,4 +169,6 @@ + + diff --git a/website/start.py b/website/start.py index b96e6a0..cff4e76 100644 --- a/website/start.py +++ b/website/start.py @@ -1,5 +1,5 @@ import urllib -from datetime import datetime +from datetime import datetime, timedelta import database from htmlmodules import module_scrobblelist, module_pulse @@ -49,14 +49,25 @@ def instructions(keys): # get pulse dt = datetime.utcnow() - dtl = [dt.year-1,dt.month+1] - if dtl[1] > 12: dtl = [dtl[0]+1,dtl[1]-12] - dts = "/".join([str(e) for e in dtl]) + first_month = [dt.year-1,dt.month+1] + dt_firstweek = dt - timedelta(11*7) - timedelta((6-dt.weekday())) + first_week = [dt_firstweek.year,dt_firstweek.month,dt_firstweek.day] + dt_firstday = dt - timedelta(6) + first_day = [dt_firstday.year,dt_firstday.month,dt_firstday.day] + first_year = [dt.year - 9] + + if first_month[1] > 12: first_month = [first_month[0]+1,first_month[1]-12] + #while first_week[2] + + + #first_month = "/".join([str(e) for e in first_month]) # this is literally the ugliest piece of code i have written in my entire feckin life # good lord - html_pulse = module_pulse(max_=12,since=dts,step="month",trail=1) - + html_pulse_days = module_pulse(max_=7,since=first_day,step="day",trail=1) + html_pulse_weeks = module_pulse(max_=12,since=first_week,step="week",trail=1) + html_pulse_months = module_pulse(max_=12,since=first_month,step="month",trail=1) + html_pulse_years = module_pulse(max_=10,since=first_year,step="year",trail=1) 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 @@ -66,7 +77,7 @@ def instructions(keys): #"KEY_SCROBBLE_TIME":scrobbletimes,"KEY_SCROBBLE_ARTISTS":scrobbleartists,"KEY_SCROBBLE_TITLE":scrobbletracklinks,"KEY_SCROBBLE_IMAGE":scrobbleimages, "KEY_SCROBBLES":html_scrobbles, #"KEY_PULSE_TERM":pulse_rangedescs,"KEY_PULSE_AMOUNT":pulse_amounts,"KEY_PULSE_BAR":pulse_bars - "KEY_PULSE":html_pulse + "KEY_PULSE_MONTHS":html_pulse_months,"KEY_PULSE_YEARS":html_pulse_years,"KEY_PULSE_DAYS":html_pulse_days,"KEY_PULSE_WEEKS":html_pulse_weeks } return (replace,pushresources)