Skip to content
Snippets Groups Projects
utils.py 4.59 KiB
Newer Older
  • Learn to ignore specific revisions
  • #
    # steering, Programme/schedule management for AURA
    #
    # Copyright (C) 2011-2017, 2020, Ernesto Rico Schmidt
    # Copyright (C) 2017-2019, Ingo Leindecker
    #
    # This program is free software: you can redistribute it and/or modify it under
    # the terms of the GNU Affero General Public License as published by the Free
    # Software Foundation, either version 3 of the License, or (at your option) any
    # later version.
    #
    # This program is distributed in the hope that it will be useful, but WITHOUT
    # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    # FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
    # details.
    #
    # You should have received a copy of the GNU Affero General Public License
    # along with this program.  If not, see <http://www.gnu.org/licenses/>.
    #
    
    import typing
    
    Ernesto Rico Schmidt's avatar
    Ernesto Rico Schmidt committed
    from datetime import date, datetime, time
    
    from typing import Dict, Optional, Tuple, TypedDict, Union
    
    from django.conf import settings
    
    Ernesto Rico Schmidt's avatar
    Ernesto Rico Schmidt committed
    from django.utils import timezone
    
    if typing.TYPE_CHECKING:
    
        from program.models import Host, HostLink, Note, NoteLink, Show, ShowLink
    
    
    class Link(TypedDict):
        type_id: int
        url: str
    
    def parse_datetime(date_string: str | None) -> datetime | None:
    
        parse a datetime string and return a timezone aware datetime object.
    
        Returns `None` if no datetime string is given.
    
    
        if date_string is None:
            return None
    
    
    Ernesto Rico Schmidt's avatar
    Ernesto Rico Schmidt committed
            parsed_datetime = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")
    
        except ValueError:
            parsed_datetime = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S%z")
    
    
        return (
            timezone.make_aware(parsed_datetime)
            if timezone.is_naive(parsed_datetime)
            else parsed_datetime
        )
    
    def parse_date(date_string: str | None) -> date | None:
    
        parse a date string and return a date object.
    
        Returns `None` if no date string is given.
    
    
        if date_string is None:
            return None
    
    
        return datetime.strptime(date_string, "%Y-%m-%d").date()
    
    
    
    def parse_time(date_string: str | None) -> time | None:
    
        parse a time string and return a time object.
    
        Returns `None` if no time string is given.
    
        if date_string is None:
            return None
    
    
        if len(date_string) == 5:
            return datetime.strptime(date_string, "%H:%M").time()
        else:
            return datetime.strptime(date_string, "%H:%M:%S").time()
    
    def get_audio_url(cba_id: Optional[int]) -> str:
    
        """
        Retrieve the direct URL to the mp3 in CBA
        In order to retrieve the URL, stations need
           - to be whitelisted by CBA
           - an API Key
    
        For these contact cba@fro.at
        """
    
    
        if not cba_id or settings.CBA_API_KEY == "":
    
            if settings.DEBUG:
    
                url = (
                    "https://cba.fro.at/wp-content/plugins/cba/ajax/cba-get-filename.php?post_id="
                    + str(cba_id)
                    + "&c=Ml3fASkfwR8"
                )
    
                    settings.CBA_AJAX_URL
    
                    + "?action=cba_ajax_get_filename&post_id="
                    + str(cba_id)
                    + "&api_key="
    
                    + settings.CBA_API_KEY
    
            try:
                return requests.get(url).json()
            except (requests.RequestException, json.JSONDecodeError):
                # TODO: we might want to add some logging
                return ""
    
    def get_values(
        kwargs: Dict[str, str], *keys: str
    ) -> Union[Tuple[Union[int, str, None], ...], int, str, None]:
    
        """Get the values of the keys from the kwargs."""
    
        def int_if_digit(value: Optional[str]) -> Optional[Union[int, str]]:
            return int(value) if value and value.isdigit() else value
    
        values = [kwargs.get(key) for key in keys]
    
        if len(values) > 1:
            return tuple(int_if_digit(value) for value in values)
        else:
            return int_if_digit(values[0])
    
    
    
    def update_links(
        instance: Union["Host", "Note", "Show"], links: list[Link]
    ) -> Union["Host", "Note", "Show"]:
        """Update the links associated with the instance"""
    
        # delete the links associated with the instance
    
        if instance.links.count() > 0:
            for link in instance.links.all():
                link.delete(keep_parents=True)
    
    
        match type(instance):
            case "Host":
                for link_data in links:
                    HostLink.objects.create(host=instance, **link_data)
            case "Note":
                for link_data in links:
                    NoteLink.objects.create(note=instance, **link_data)
            case "Show":
                for link_data in links:
                    ShowLink.objects.create(show=instance, **link_data)
    
    
        return instance