From 7dab61e42033854f3aa1e0a52dea36a15f9f817b Mon Sep 17 00:00:00 2001 From: noirscape Date: Sat, 15 Feb 2025 01:09:42 +0100 Subject: [PATCH 1/3] Add a new config option to use a ZoneInfo timezone. The ZoneInfo class was added in python version 3.9, and the Alpine timezone package is already installed in the Containerfile as part of the runtime dependencies. zoneinfo provides instances of the same timezone class already used for the existing OFFSET timezones (making it a drop-in accessible option), but implements them using an IANA timezone database (making it historically accurate, and hopefully, future accurate on new builds as well). The implementation in this commit by default only overrides if LOCATION_TIMEZONE both hasn't been set and is in the installed tzdata package, making it fully backwards compatible with existing options. --- maloja/__main__.py | 1 + maloja/malojatime.py | 4 +++- maloja/pkg_global/conf.py | 3 ++- settings.md | 1 + 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/maloja/__main__.py b/maloja/__main__.py index 67b010b..1da4752 100644 --- a/maloja/__main__.py +++ b/maloja/__main__.py @@ -50,6 +50,7 @@ def print_info(): print(col['lightblue']("Log Directory: "),conf.dir_settings['logs']) print(col['lightblue']("Network: "),f"Dual Stack, Port {conf.malojaconfig['port']}" if conf.malojaconfig['host'] == "*" else f"IPv{ip_address(conf.malojaconfig['host']).version}, Port {conf.malojaconfig['port']}") print(col['lightblue']("Timezone: "),f"UTC{conf.malojaconfig['timezone']:+d}") + print(col['lightblue']("Location Timezone: "),conf.malojaconfig['location_timezone']) print() try: from importlib.metadata import distribution diff --git a/maloja/malojatime.py b/maloja/malojatime.py index 1af046d..bce6bdf 100644 --- a/maloja/malojatime.py +++ b/maloja/malojatime.py @@ -1,13 +1,15 @@ from datetime import timezone, timedelta, date, time, datetime from calendar import monthrange import math +import zoneinfo from abc import ABC, abstractmethod from .pkg_global.conf import malojaconfig OFFSET = malojaconfig["TIMEZONE"] -TIMEZONE = timezone(timedelta(hours=OFFSET)) +LOCATION_TIMEZONE = malojaconfig["LOCATION_TIMEZONE"] +TIMEZONE = timezone(timedelta(hours=OFFSET)) if not LOCATION_TIMEZONE and LOCATION_TIMEZONE in zoneinfo.available_timezones() else zoneinfo.ZoneInfo(LOCATION_TIMEZONE) UTC = timezone.utc FIRST_SCROBBLE = int(datetime.utcnow().replace(tzinfo=UTC).timestamp()) diff --git a/maloja/pkg_global/conf.py b/maloja/pkg_global/conf.py index 64a6ed8..4efbcba 100644 --- a/maloja/pkg_global/conf.py +++ b/maloja/pkg_global/conf.py @@ -207,7 +207,8 @@ malojaconfig = Configuration( "filters_remix":(tp.Set(tp.String()), "Remix Filters", ["Remix", "Remix Edit", "Short Mix", "Extended Mix", "Soundtrack Version"], "Filters used to recognize the remix artists in the title"), "parse_remix_artists":(tp.Boolean(), "Parse Remix Artists", False), "week_offset":(tp.Integer(), "Week Begin Offset", 0, "Start of the week for the purpose of weekly statistics. 0 = Sunday, 6 = Saturday"), - "timezone":(tp.Integer(), "UTC Offset", 0) + "timezone":(tp.Integer(), "UTC Offset", 0), + "location_timezone":(tp.String(), "Location Timezone", None) }, "Web Interface":{ "default_range_startpage":(tp.Choice({'alltime':'All Time','year':'Year','month':"Month",'week':'Week'}), "Default Range for Startpage Stats", "year"), diff --git a/settings.md b/settings.md index 425001b..9f3b317 100644 --- a/settings.md +++ b/settings.md @@ -68,6 +68,7 @@ Settings File | Environment Variable | Type | Description `parse_remix_artists` | `MALOJA_PARSE_REMIX_ARTISTS` | Boolean | Parse Remix Artists `week_offset` | `MALOJA_WEEK_OFFSET` | Integer | Start of the week for the purpose of weekly statistics. 0 = Sunday, 6 = Saturday `timezone` | `MALOJA_TIMEZONE` | Integer | UTC Offset +`location_timezone` | `MALOJA_LOCATION_TIMEZONE` | String | Location Timezone (overrides `timezone`) **Web Interface** `default_range_startpage` | `MALOJA_DEFAULT_RANGE_STARTPAGE` | Choice | Default Range for Startpage Stats `default_step_pulse` | `MALOJA_DEFAULT_STEP_PULSE` | Choice | Default Pulse Step From 5c343053d915909079af80c73e11f7e956aed0b7 Mon Sep 17 00:00:00 2001 From: noirscape Date: Sat, 15 Feb 2025 01:25:21 +0100 Subject: [PATCH 2/3] replace utcnow calls the utcnow function was deprecated in python 3.12 in favor of passing a timezone object into now() instead. --- maloja/malojatime.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/maloja/malojatime.py b/maloja/malojatime.py index bce6bdf..d39e1ea 100644 --- a/maloja/malojatime.py +++ b/maloja/malojatime.py @@ -12,7 +12,7 @@ LOCATION_TIMEZONE = malojaconfig["LOCATION_TIMEZONE"] TIMEZONE = timezone(timedelta(hours=OFFSET)) if not LOCATION_TIMEZONE and LOCATION_TIMEZONE in zoneinfo.available_timezones() else zoneinfo.ZoneInfo(LOCATION_TIMEZONE) UTC = timezone.utc -FIRST_SCROBBLE = int(datetime.utcnow().replace(tzinfo=UTC).timestamp()) +FIRST_SCROBBLE = int(datetime.now(UTC).timestamp()) def register_scrobbletime(timestamp): global FIRST_SCROBBLE @@ -65,7 +65,7 @@ class MTRangeGeneric(ABC): # whether we currently live or will ever again live in this range def active(self): - return (self.last_stamp() > datetime.utcnow().timestamp()) + return (self.last_stamp() > datetime.now(timezone.utc).timestamp()) def __contains__(self,timestamp): return timestamp >= self.first_stamp() and timestamp <= self.last_stamp() @@ -113,7 +113,7 @@ class MTRangeGregorian(MTRangeSingular): # whether we currently live or will ever again live in this range # USE GENERIC SUPER METHOD INSTEAD # def active(self): -# tod = datetime.datetime.utcnow().date() +# tod = datetime.datetime.now(timezone.utc).date() # if tod.year > self.year: return False # if self.precision == 1: return True # if tod.year == self.year: @@ -330,7 +330,7 @@ class MTRangeComposite(MTRangeGeneric): if self.since is None: return FIRST_SCROBBLE else: return self.since.first_stamp() def last_stamp(self): - #if self.to is None: return int(datetime.utcnow().replace(tzinfo=timezone.utc).timestamp()) + #if self.to is None: return int(datetime.now(timezone.utc).timestamp()) if self.to is None: return today().last_stamp() else: return self.to.last_stamp() @@ -423,8 +423,8 @@ def get_last_instance(category,current,target,amount): str_to_time_range = { **{s:callable for callable,strlist in currenttime_string_representations for s in strlist}, - **{s:(lambda i=index:get_last_instance(thismonth,datetime.utcnow().month,i,12)) for index,strlist in enumerate(month_string_representations,1) for s in strlist}, - **{s:(lambda i=index:get_last_instance(today,datetime.utcnow().isoweekday()+1%7,i,7)) for index,strlist in enumerate(weekday_string_representations,1) for s in strlist} + **{s:(lambda i=index:get_last_instance(thismonth,datetime.now(timezone.utc).month,i,12)) for index,strlist in enumerate(month_string_representations,1) for s in strlist}, + **{s:(lambda i=index:get_last_instance(today,datetime.now(timezone.utc).isoweekday()+1%7,i,7)) for index,strlist in enumerate(weekday_string_representations,1) for s in strlist} } From 300e2c1ff723e06bf9e058bbb4aba7bd9e4c1bb9 Mon Sep 17 00:00:00 2001 From: noirscape Date: Sat, 15 Feb 2025 01:27:26 +0100 Subject: [PATCH 3/3] fix and/or mistake --- maloja/malojatime.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maloja/malojatime.py b/maloja/malojatime.py index d39e1ea..76bb359 100644 --- a/maloja/malojatime.py +++ b/maloja/malojatime.py @@ -9,7 +9,7 @@ from .pkg_global.conf import malojaconfig OFFSET = malojaconfig["TIMEZONE"] LOCATION_TIMEZONE = malojaconfig["LOCATION_TIMEZONE"] -TIMEZONE = timezone(timedelta(hours=OFFSET)) if not LOCATION_TIMEZONE and LOCATION_TIMEZONE in zoneinfo.available_timezones() else zoneinfo.ZoneInfo(LOCATION_TIMEZONE) +TIMEZONE = timezone(timedelta(hours=OFFSET)) if not LOCATION_TIMEZONE or LOCATION_TIMEZONE not in zoneinfo.available_timezones() else zoneinfo.ZoneInfo(LOCATION_TIMEZONE) UTC = timezone.utc FIRST_SCROBBLE = int(datetime.now(UTC).timestamp())