@ -80,7 +80,7 @@ class LogArchiver:
 | 
			
		||||
    def load_file(self, path):
 | 
			
		||||
        with gzip.open(path, "rb") as archive:
 | 
			
		||||
            data = archive.read()
 | 
			
		||||
            logs = yaml.load(data)
 | 
			
		||||
            logs = yaml.safe_load(data)
 | 
			
		||||
 | 
			
		||||
            # we need to preload diffusions, sounds and tracks
 | 
			
		||||
            rels = {
 | 
			
		||||
 | 
			
		||||
@ -84,7 +84,6 @@ class SoundStats:
 | 
			
		||||
        self.stats = [SoxStats(self.path)]
 | 
			
		||||
        position = 0
 | 
			
		||||
        length = self.stats[0].get("length")
 | 
			
		||||
        print(self.stats, "-----")
 | 
			
		||||
        if not self.sample_length:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
import pytz
 | 
			
		||||
from zoneinfo import ZoneInfo
 | 
			
		||||
 | 
			
		||||
from django.db.models import Q
 | 
			
		||||
from django.utils import timezone as tz
 | 
			
		||||
 | 
			
		||||
@ -11,38 +12,36 @@ __all__ = ("AircoxMiddleware",)
 | 
			
		||||
class AircoxMiddleware(object):
 | 
			
		||||
    """Middleware used to get default info for the given website.
 | 
			
		||||
 | 
			
		||||
    Theses
 | 
			
		||||
    It provide following request attributes:
 | 
			
		||||
    - ``station``: current Station
 | 
			
		||||
 | 
			
		||||
    This middleware must be set after the middleware
 | 
			
		||||
        'django.contrib.auth.middleware.AuthenticationMiddleware',
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    timezone_session_key = "aircox.timezone"
 | 
			
		||||
 | 
			
		||||
    def __init__(self, get_response):
 | 
			
		||||
        self.get_response = get_response
 | 
			
		||||
 | 
			
		||||
    def get_station(self, request):
 | 
			
		||||
        """Return station for the provided request."""
 | 
			
		||||
        expr = Q(default=True) | Q(hosts__contains=request.get_host())
 | 
			
		||||
        # case = Case(When(hosts__contains=request.get_host(), then=Value(0)),
 | 
			
		||||
        #            When(default=True, then=Value(32)))
 | 
			
		||||
        host = request.get_host()
 | 
			
		||||
        expr = Q(default=True) | Q(hosts=host) | Q(hosts__contains=host + "\n")
 | 
			
		||||
        return Station.objects.filter(expr).order_by("default").first()
 | 
			
		||||
        #              .annotate(resolve_priority=case) \
 | 
			
		||||
        # .order_by('resolve_priority').first()
 | 
			
		||||
 | 
			
		||||
    def init_timezone(self, request):
 | 
			
		||||
        # note: later we can use http://freegeoip.net/ on user side if
 | 
			
		||||
        # required
 | 
			
		||||
        timezone = None
 | 
			
		||||
        try:
 | 
			
		||||
            timezone = request.session.get("aircox.timezone")
 | 
			
		||||
            timezone = request.session.get(self.timezone_session_key)
 | 
			
		||||
            if timezone:
 | 
			
		||||
                timezone = pytz.timezone(timezone)
 | 
			
		||||
                timezone = ZoneInfo(timezone)
 | 
			
		||||
                tz.activate(timezone)
 | 
			
		||||
        except Exception:
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        if not timezone:
 | 
			
		||||
            timezone = tz.get_current_timezone()
 | 
			
		||||
            tz.activate(timezone)
 | 
			
		||||
 | 
			
		||||
    def __call__(self, request):
 | 
			
		||||
        self.init_timezone(request)
 | 
			
		||||
        request.station = self.get_station(request)
 | 
			
		||||
 | 
			
		||||
@ -39,8 +39,10 @@ class DiffusionQuerySet(RerunQuerySet):
 | 
			
		||||
    def date(self, date=None, order=True):
 | 
			
		||||
        """Diffusions occuring date."""
 | 
			
		||||
        date = date or datetime.date.today()
 | 
			
		||||
        start = tz.datetime.combine(date, datetime.time())
 | 
			
		||||
        end = tz.datetime.combine(date, datetime.time(23, 59, 59, 999))
 | 
			
		||||
        start = tz.make_aware(tz.datetime.combine(date, datetime.time()))
 | 
			
		||||
        end = tz.make_aware(
 | 
			
		||||
            tz.datetime.combine(date, datetime.time(23, 59, 59, 999))
 | 
			
		||||
        )
 | 
			
		||||
        # start = tz.get_current_timezone().localize(start)
 | 
			
		||||
        # end = tz.get_current_timezone().localize(end)
 | 
			
		||||
        qs = self.filter(start__range=(start, end))
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import calendar
 | 
			
		||||
import zoneinfo
 | 
			
		||||
 | 
			
		||||
import pytz
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.utils import timezone as tz
 | 
			
		||||
from django.utils.functional import cached_property
 | 
			
		||||
@ -49,9 +49,9 @@ class Schedule(Rerun):
 | 
			
		||||
    )
 | 
			
		||||
    timezone = models.CharField(
 | 
			
		||||
        _("timezone"),
 | 
			
		||||
        default=lambda: tz.get_current_timezone().zone,
 | 
			
		||||
        default=lambda: tz.get_current_timezone().key,
 | 
			
		||||
        max_length=100,
 | 
			
		||||
        choices=[(x, x) for x in pytz.all_timezones],
 | 
			
		||||
        choices=[(x, x) for x in zoneinfo.available_timezones()],
 | 
			
		||||
        help_text=_("timezone used for the date"),
 | 
			
		||||
    )
 | 
			
		||||
    duration = models.TimeField(
 | 
			
		||||
@ -82,9 +82,7 @@ class Schedule(Rerun):
 | 
			
		||||
    @cached_property
 | 
			
		||||
    def tz(self):
 | 
			
		||||
        """Pytz timezone of the schedule."""
 | 
			
		||||
        import pytz
 | 
			
		||||
 | 
			
		||||
        return pytz.timezone(self.timezone)
 | 
			
		||||
        return zoneinfo.ZoneInfo(self.timezone)
 | 
			
		||||
 | 
			
		||||
    @cached_property
 | 
			
		||||
    def start(self):
 | 
			
		||||
@ -110,7 +108,7 @@ class Schedule(Rerun):
 | 
			
		||||
        """Return a datetime set to schedule's time for the provided date,
 | 
			
		||||
        handling timezone (based on schedule's timezone)."""
 | 
			
		||||
        date = tz.datetime.combine(date, self.time)
 | 
			
		||||
        return self.tz.normalize(self.tz.localize(date))
 | 
			
		||||
        return date.replace(tzinfo=self.tz)
 | 
			
		||||
 | 
			
		||||
    def dates_of_month(self, date):
 | 
			
		||||
        """Return normalized diffusion dates of provided date's month."""
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,7 @@ class Station(models.Model):
 | 
			
		||||
        max_length=512,
 | 
			
		||||
        null=True,
 | 
			
		||||
        blank=True,
 | 
			
		||||
        help_text=_("specify one url per line"),
 | 
			
		||||
        help_text=_("specify one domain per line, without 'http://' prefix"),
 | 
			
		||||
    )
 | 
			
		||||
    audio_streams = models.TextField(
 | 
			
		||||
        _("audio streams"),
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@ from datetime import time, timedelta
 | 
			
		||||
import itertools
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.contrib.auth.models import User
 | 
			
		||||
from django.test import RequestFactory
 | 
			
		||||
 | 
			
		||||
@ -16,6 +17,12 @@ req_factory = RequestFactory()
 | 
			
		||||
"""Request Factory used among different tests."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
settings.ALLOWED_HOSTS = list(settings.ALLOWED_HOSTS) + [
 | 
			
		||||
    "sub.server.org",
 | 
			
		||||
    "server.org",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def staff_user():
 | 
			
		||||
    return baker.make(User, is_active=True, is_staff=True)
 | 
			
		||||
@ -31,12 +38,23 @@ def logger():
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def station():
 | 
			
		||||
    return baker.make(models.Station, audio_streams="stream 1\nstream 2")
 | 
			
		||||
    return baker.make(
 | 
			
		||||
        models.Station,
 | 
			
		||||
        hosts="server.org",
 | 
			
		||||
        audio_streams="stream 1\nstream 2",
 | 
			
		||||
        default=True,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def stations(station):
 | 
			
		||||
    return [station, baker.make(models.Station)]
 | 
			
		||||
def sub_station():
 | 
			
		||||
    """Non-default station."""
 | 
			
		||||
    return baker.make(models.Station, hosts="sub.server.org", default=False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def stations(station, sub_station):
 | 
			
		||||
    return [station, sub_station]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ class TestSchedule:
 | 
			
		||||
    @pytest.mark.django_db
 | 
			
		||||
    def test_tz(self, schedules):
 | 
			
		||||
        for schedule in schedules:
 | 
			
		||||
            assert schedule.timezone == schedule.tz.zone
 | 
			
		||||
            assert schedule.timezone == schedule.tz.key
 | 
			
		||||
 | 
			
		||||
    @pytest.mark.django_db
 | 
			
		||||
    def test_start(self, schedules):
 | 
			
		||||
@ -45,7 +45,7 @@ class TestSchedule:
 | 
			
		||||
    def test_normalize(self, schedules):
 | 
			
		||||
        for schedule in schedules:
 | 
			
		||||
            dt = datetime.combine(schedule.date, schedule.time)
 | 
			
		||||
            assert schedule.normalize(dt).tzinfo.zone == schedule.timezone
 | 
			
		||||
            assert schedule.normalize(dt).tzinfo.key == schedule.timezone
 | 
			
		||||
 | 
			
		||||
    @pytest.mark.django_db
 | 
			
		||||
    def test_dates_of_month_ponctual(self):
 | 
			
		||||
@ -117,7 +117,7 @@ class TestSchedule:
 | 
			
		||||
        assert dt.month == at.month
 | 
			
		||||
        assert dt.weekday() == schedule.date.weekday()
 | 
			
		||||
        assert dt.time() == schedule.time
 | 
			
		||||
        assert dt.tzinfo.zone == schedule.timezone
 | 
			
		||||
        assert dt.tzinfo.key == schedule.timezone
 | 
			
		||||
 | 
			
		||||
    @pytest.mark.django_db
 | 
			
		||||
    def test_diffusions_of_month(self, sched_initials):
 | 
			
		||||
 | 
			
		||||
@ -6,11 +6,11 @@ to:
 | 
			
		||||
- cancels Diffusions that have an archive but could not have been played;
 | 
			
		||||
- run Liquidsoap
 | 
			
		||||
"""
 | 
			
		||||
from datetime import timezone
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
from argparse import RawTextHelpFormatter
 | 
			
		||||
 | 
			
		||||
import pytz
 | 
			
		||||
from django.core.management.base import BaseCommand
 | 
			
		||||
from django.utils import timezone as tz
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ from aircox_streamer.controllers import Monitor, Streamer
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# force using UTC
 | 
			
		||||
tz.activate(pytz.UTC)
 | 
			
		||||
tz.activate(timezone.UTC)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Command(BaseCommand):
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
from zoneinfo import ZoneInfo
 | 
			
		||||
 | 
			
		||||
import pytz
 | 
			
		||||
from django.utils import timezone
 | 
			
		||||
 | 
			
		||||
sys.path.insert(1, os.path.dirname(os.path.realpath(__file__)))
 | 
			
		||||
@ -65,7 +65,7 @@ USE_I18N = True
 | 
			
		||||
USE_L10N = True
 | 
			
		||||
USE_TZ = True
 | 
			
		||||
 | 
			
		||||
timezone.activate(pytz.timezone(TIME_ZONE))
 | 
			
		||||
timezone.activate(ZoneInfo(TIME_ZONE))
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
    import locale
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ For Django settings see:
 | 
			
		||||
    https://docs.djangoproject.com/en/3.1/topics/settings/
 | 
			
		||||
    https://docs.djangoproject.com/en/3.1/ref/settings/
 | 
			
		||||
"""
 | 
			
		||||
from zoneinfo import ZoneInfo
 | 
			
		||||
from .prod import *
 | 
			
		||||
 | 
			
		||||
# FOR dev: from .dev import *
 | 
			
		||||
@ -20,7 +21,7 @@ LANGUAGE_CODE = "fr-BE"
 | 
			
		||||
LC_LOCALE = "fr_BE.UTF-8"
 | 
			
		||||
TIME_ZONE = "Europe/Brussels"
 | 
			
		||||
 | 
			
		||||
timezone.activate(pytz.timezone(TIME_ZONE))
 | 
			
		||||
timezone.activate(ZoneInfo(TIME_ZONE))
 | 
			
		||||
 | 
			
		||||
# Secret key: you MUST put a consistent secret key. You can generate one
 | 
			
		||||
# at https://djecrety.ir/
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user