config.py 5.01 KB
Newer Older
1
#
David Trattnig's avatar
David Trattnig committed
2
3
4
# Aura Engine (https://gitlab.servus.at/aura/engine)
#
# Copyright (C) 2017-2020 - The Aura Engine Team.
5
#
6
7
8
9
# 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.
David Trattnig's avatar
David Trattnig committed
10
#
11
12
13
14
# 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.
David Trattnig's avatar
David Trattnig committed
15
#
16
17
# 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/>.
18

David Trattnig's avatar
David Trattnig committed
19

20
import os
21
import os.path
22
23
24
import sys
import logging

25
from pathlib import Path
26
from configparser import ConfigParser
27
28
29


class AuraConfig:
30
    """
31
    AuraConfig Class
32

33
    Holds the Engine Configuration as in the file `engine.ini`.
34
    """
35
    instance = None
36
37
38
    ini_path = ""
    logger = None

39

40
    def __init__(self, ini_path="/etc/aura/engine.ini"):
41
42
        """
        Initializes the configuration, defaults to `/etc/aura/engine.ini`.
43
        If this file doesn't exist it uses `./config/engine.ini` from
44
45
46
47
48
        the project directory.

        Args:
            ini_path(String):      The path to the configuration file `engine.ini`
        """
49
        self.logger = logging.getLogger("AuraEngine")
50
51
        config_file = Path(ini_path)
        if not config_file.is_file():
52
            ini_path = "%s/config/engine.ini" % Path(__file__).parent.parent.parent.absolute()
53

54
55
        self.ini_path = ini_path
        self.load_config()
56
        AuraConfig.instance = self
57

David Trattnig's avatar
David Trattnig committed
58
        # Defaults
59
        self.set("config_dir", os.path.dirname(ini_path))
David Trattnig's avatar
David Trattnig committed
60
61
        self.set("install_dir", os.path.realpath(__file__ + "../../../.."))

62
63


64
65
66
67
68
69
70
71
72
    @staticmethod
    def config():
        """
        Retrieves the global instances of the configuration.
        """
        return AuraConfig.instance



73
74
    def set(self, key, value):
        """
David Trattnig's avatar
David Trattnig committed
75
76
77
78
79
        Setter for some specific config property.

        Args:
            key (String):   key
            default (*):    value
80
81
82
83
84
85
        """
        try:
            self.__dict__[key] = int(value)
        except:
            self.__dict__[key] = str(value)

David Trattnig's avatar
David Trattnig committed
86
87


88
89
    def get(self, key, default=None):
        """
David Trattnig's avatar
David Trattnig committed
90
        Getter for some specific config property.
91

David Trattnig's avatar
David Trattnig committed
92
93
94
95
        Args:
            key (String):   key
            default (*):    value
        """
96
97
98
99
100
101
        if key not in self.__dict__:
            if default:
                self.set(key, default)
            else:
                self.logger.warning("Key " + key + " not found in configfile " + self.ini_path + "!")
                return None
102

103
104
        return self.__dict__[key]

David Trattnig's avatar
David Trattnig committed
105

106
107
108
109
    def get_database_uri(self):
        """
        Retrieves the database connection string.
        """
David Trattnig's avatar
David Trattnig committed
110
111
        db_name = str(self.get("db_name"))
        db_user = str(self.get("db_user"))
112
        db_pass = str(self.get("db_pass"))
David Trattnig's avatar
David Trattnig committed
113
114
        db_host = str(self.get("db_host"))
        db_type = str(self.get("db_type"))
115
        db_charset = self.get("db_charset", "utf8")
David Trattnig's avatar
David Trattnig committed
116
117
118
119
120
121
        if db_type == "mysql":
            return "mysql://" + db_user + ":" + db_pass + "@" + db_host + "/" + db_name + "?charset=" + db_charset
        elif db_type == "postgresql":
            return f"postgresql+psycopg2://{db_user}:{db_pass}@{db_host}/{db_name}?client_encoding={db_charset}"
        else:
            return f"Error: invalid database type '{db_type}'"
122
123


124
    def load_config(self):
125
        """
126
        Set config defaults and load settings from file
127
        """
128
129
130
131
        if not os.path.isfile(self.ini_path):
            self.logger.critical(self.ini_path + " not found  :(")
            sys.exit(1)

David Trattnig's avatar
David Trattnig committed
132
        # Read the file
133
134
135
136
        f = open(self.ini_path, 'r')
        ini_str = f.read()
        f.close()

David Trattnig's avatar
David Trattnig committed
137
        # Parse the values
138
139
140
141
142
143
144
145
146
147
148
149
        config_parser = ConfigParser()
        try:
            config_parser.read_string(ini_str)
        except Exception as e:
            self.logger.critical("Cannot read " + self.ini_path + "! Reason: " + str(e))
            sys.exit(0)

        for section in config_parser.sections():
            for key, value in config_parser.items(section):
                v = config_parser.get(section, key).replace('"', '').strip()
                self.set(key, v)

David Trattnig's avatar
David Trattnig committed
150

151
152
153
154
155
156
157
158
    def to_abs_path(self, path):
        """
        Transforms any given (relative) path to an absolute paths
        derived from the project root.
        """
        if path.startswith("/"):
            return path
        else:
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
            return self.get("install_dir") + "/" + path


    def abs_audio_store_path(self):
        """
        Returns the absolute path to the audio store, based on the `audio_source_folder` setting.
        """
        return self.to_abs_path(self.get("audio_source_folder"))


    def abs_playlist_path(self):
        """
        Returns the absolute path to the playlist folder
        """
        return self.to_abs_path(self.get("audio_playlist_folder"))