aboutsummaryrefslogtreecommitdiffhomepage
path: root/libs/ga4mp/store.py
blob: d85bc0c2a057cb31eaa603ad9efce598e03e607b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import json
import logging
from pathlib import Path

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

class BaseStore(dict):
    def __init__(self):
        self.update([("user_properties", {}),("session_parameters", {})])

    def save(self):
        raise NotImplementedError("Subclass should be using this function, but it was called through the base class instead.")

    def _check_exists(self, key):
        # Helper function to make sure a key exists before trying to work with values within it.
        if key not in self.keys():
            self[key] = {}

    def _set(self, param_type, name, value):
        # Helper function to set a single parameter (user or session or other).
        self._check_exists(key=param_type)
        self[param_type][name] = value

    def _get_one(self, param_type, name):
        # Helper function to get a single parameter value (user or session).
        self._check_exists(key=param_type)
        return self[param_type].get(name, None)

    def _get_all(self, param_type=None):
        # Helper function to get all user or session parameters - or the entire dictionary if not specified.
        if param_type is not None:
            return self[param_type]
        else:
            return self

    # While redundant, the following make sure the distinction between session and user items is easier for the end user.
    def set_user_property(self, name, value):
        self._set(param_type="user_properties", name=name, value=value)

    def get_user_property(self, name):
        return self._get_one(param_type="user_properties", name=name)

    def get_all_user_properties(self):
        return self._get_all(param_type="user_properties")

    def clear_user_properties(self):
        self["user_properties"] = {}

    def set_session_parameter(self, name, value):
        self._set(param_type="session_parameters", name=name, value=value)

    def get_session_parameter(self, name):
        return self._get_one(param_type="session_parameters", name=name)

    def get_all_session_parameters(self):
        return self._get_all(param_type="session_parameters")

    def clear_session_parameters(self):
        self["session_parameters"] = {}

    # Similar functions for other items the user wants to store that don't fit the other two categories.
    def set_other_parameter(self, name, value):
        self._set(param_type="other", name=name, value=value)

    def get_other_parameter(self, name):
        return self._get_one(param_type="other", name=name)

    def get_all_other_parameters(self):
        return self._get_all(param_type="other")

    def clear_other_parameters(self):
        self["other"] = {}

class DictStore(BaseStore):
    # Class for working with dictionaries that persist for the life of the class.
    def __init__(self, data: dict = None):
        super().__init__()
        if data:
            self.update(data)

    def save(self):
        # Give the user back what's in the dictionary so they can decide how to save it.
        self._get_all()

class FileStore(BaseStore):
    # Class for working with dictionaries that get saved to a JSON file.
    def __init__(self, data_location: str = None):
        super().__init__()
        self.data_location = data_location
        try:
            self._load_file(data_location)
        except:
            logger.info(f"Failed to find file at location: {data_location}")

    def _load_file(self):
        # Function to get data from the object's initialized location.
        # If the provided or stored data_location exists, read the file and overwrite the object's contents.
        if Path(self.data_location).exists():
            with open(self.data_location, "r") as json_file:
                self = json.load(json_file)
        # If the data_location doesn't exist, try to create a new starter JSON file at the location given.
        else:
            starter_dict = '{"user_properties":{}, "session_parameters":{}}'
            starter_json = json.loads(starter_dict)
            Path(self.data_location).touch()
            with open(self.data_location, "w") as json_file:
                json.dumps(starter_json, json_file)

    def save(self):
        # Function to save the current dictionary to a JSON file at the object's initialized location.
        try:
            with open(self.data_location, "w") as outfile:
                json.dump(self, outfile)
        except:
            logger.info(f"Failed to save file at location: {self.data_location}")