Compare commits

..

8 Commits

Author SHA1 Message Date
krateng
9e44cc3ce6
Merge pull request #416 from jessienab/patch-2
Update README.md
2025-05-18 14:08:34 +02:00
Jessie N.
c55ed87b52
Update README.md
Extremely simple change to remove redundant install instruction sections
2025-03-27 14:15:06 +00:00
krateng
3ba27ffc37
Merge pull request #407 from noirscape/dateutil
Add a new config option to use a ZoneInfo timezone.
2025-02-17 16:37:42 +01:00
noirscape
300e2c1ff7 fix and/or mistake 2025-02-15 01:27:26 +01:00
noirscape
5c343053d9 replace utcnow calls
the utcnow function was deprecated in python 3.12 in favor of passing a timezone object into now() instead.
2025-02-15 01:25:21 +01:00
noirscape
7dab61e420 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.
2025-02-15 01:09:42 +01:00
krateng
5296960d68
Merge pull request #404 from jackwilsdon/fix-local-permissions
Fix permissions after copying initial local files
2025-02-14 05:20:18 +01:00
Jack Wilsdon
e060241acb Fix permissions after copying initial local files 2025-02-13 19:16:24 +00:00
6 changed files with 20 additions and 12 deletions

View File

@ -14,10 +14,6 @@ You can check [my own Maloja page](https://maloja.krateng.ch) as an example inst
## Table of Contents ## Table of Contents
* [Features](#features) * [Features](#features)
* [How to install](#how-to-install) * [How to install](#how-to-install)
* [Requirements](#requirements)
* [Docker / Podman](#docker--podman)
* [PyPI](#pypi)
* [From Source](#from-source)
* [Extras](#extras) * [Extras](#extras)
* [How to use](#how-to-use) * [How to use](#how-to-use)
* [Basic control](#basic-control) * [Basic control](#basic-control)

View File

@ -50,6 +50,7 @@ def print_info():
print(col['lightblue']("Log Directory: "),conf.dir_settings['logs']) 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']("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']("Timezone: "),f"UTC{conf.malojaconfig['timezone']:+d}")
print(col['lightblue']("Location Timezone: "),conf.malojaconfig['location_timezone'])
print() print()
try: try:
from importlib.metadata import distribution from importlib.metadata import distribution

View File

@ -1,16 +1,18 @@
from datetime import timezone, timedelta, date, time, datetime from datetime import timezone, timedelta, date, time, datetime
from calendar import monthrange from calendar import monthrange
import math import math
import zoneinfo
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from .pkg_global.conf import malojaconfig from .pkg_global.conf import malojaconfig
OFFSET = malojaconfig["TIMEZONE"] OFFSET = malojaconfig["TIMEZONE"]
TIMEZONE = timezone(timedelta(hours=OFFSET)) LOCATION_TIMEZONE = malojaconfig["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 UTC = timezone.utc
FIRST_SCROBBLE = int(datetime.utcnow().replace(tzinfo=UTC).timestamp()) FIRST_SCROBBLE = int(datetime.now(UTC).timestamp())
def register_scrobbletime(timestamp): def register_scrobbletime(timestamp):
global FIRST_SCROBBLE global FIRST_SCROBBLE
@ -63,7 +65,7 @@ class MTRangeGeneric(ABC):
# whether we currently live or will ever again live in this range # whether we currently live or will ever again live in this range
def active(self): def active(self):
return (self.last_stamp() > datetime.utcnow().timestamp()) return (self.last_stamp() > datetime.now(timezone.utc).timestamp())
def __contains__(self,timestamp): def __contains__(self,timestamp):
return timestamp >= self.first_stamp() and timestamp <= self.last_stamp() return timestamp >= self.first_stamp() and timestamp <= self.last_stamp()
@ -111,7 +113,7 @@ class MTRangeGregorian(MTRangeSingular):
# whether we currently live or will ever again live in this range # whether we currently live or will ever again live in this range
# USE GENERIC SUPER METHOD INSTEAD # USE GENERIC SUPER METHOD INSTEAD
# def active(self): # def active(self):
# tod = datetime.datetime.utcnow().date() # tod = datetime.datetime.now(timezone.utc).date()
# if tod.year > self.year: return False # if tod.year > self.year: return False
# if self.precision == 1: return True # if self.precision == 1: return True
# if tod.year == self.year: # if tod.year == self.year:
@ -328,7 +330,7 @@ class MTRangeComposite(MTRangeGeneric):
if self.since is None: return FIRST_SCROBBLE if self.since is None: return FIRST_SCROBBLE
else: return self.since.first_stamp() else: return self.since.first_stamp()
def last_stamp(self): 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() if self.to is None: return today().last_stamp()
else: return self.to.last_stamp() else: return self.to.last_stamp()
@ -421,8 +423,8 @@ def get_last_instance(category,current,target,amount):
str_to_time_range = { str_to_time_range = {
**{s:callable for callable,strlist in currenttime_string_representations for s in strlist}, **{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(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.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(today,datetime.now(timezone.utc).isoweekday()+1%7,i,7)) for index,strlist in enumerate(weekday_string_representations,1) for s in strlist}
} }

View File

@ -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"), "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), "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"), "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":{ "Web Interface":{
"default_range_startpage":(tp.Choice({'alltime':'All Time','year':'Year','month':"Month",'week':'Week'}), "Default Range for Startpage Stats", "year"), "default_range_startpage":(tp.Choice({'alltime':'All Time','year':'Year','month':"Month",'week':'Week'}), "Default Range for Startpage Stats", "year"),

View File

@ -1,5 +1,6 @@
import os import os
import shutil import shutil
import stat
from importlib import resources from importlib import resources
from pathlib import PosixPath from pathlib import PosixPath
@ -34,6 +35,12 @@ def copy_initial_local_files():
dst = PosixPath(dir_settings[cat]) / subfolder dst = PosixPath(dir_settings[cat]) / subfolder
if os.path.isdir(src): if os.path.isdir(src):
shutil.copytree(src, dst, dirs_exist_ok=True) shutil.copytree(src, dst, dirs_exist_ok=True)
# fix permissions (u+w)
for dirpath, _, filenames in os.walk(dst):
os.chmod(dirpath, os.stat(dirpath).st_mode | stat.S_IWUSR)
for filename in filenames:
filepath = os.path.join(dirpath, filename)
os.chmod(filepath, os.stat(filepath).st_mode | stat.S_IWUSR)
charset = list(range(10)) + list("abcdefghijklmnopqrstuvwxyz") + list("ABCDEFGHIJKLMNOPQRSTUVWXYZ") charset = list(range(10)) + list("abcdefghijklmnopqrstuvwxyz") + list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")

View File

@ -68,6 +68,7 @@ Settings File | Environment Variable | Type | Description
`parse_remix_artists` | `MALOJA_PARSE_REMIX_ARTISTS` | Boolean | Parse Remix Artists `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 `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 `timezone` | `MALOJA_TIMEZONE` | Integer | UTC Offset
`location_timezone` | `MALOJA_LOCATION_TIMEZONE` | String | Location Timezone (overrides `timezone`)
**Web Interface** **Web Interface**
`default_range_startpage` | `MALOJA_DEFAULT_RANGE_STARTPAGE` | Choice | Default Range for Startpage Stats `default_range_startpage` | `MALOJA_DEFAULT_RANGE_STARTPAGE` | Choice | Default Range for Startpage Stats
`default_step_pulse` | `MALOJA_DEFAULT_STEP_PULSE` | Choice | Default Pulse Step `default_step_pulse` | `MALOJA_DEFAULT_STEP_PULSE` | Choice | Default Pulse Step