settings.py 6.59 KB
Newer Older
1
2
3
4
"""Data Model and General Configuration of Eve.

Check out [the Eve docs for configuration](http://python-eve.org/config.html)
if you are unsure about some of the settings.
5

6
7
8
Our schema requires customized data validation. These validation rules are
implemented in `validation.py`.
Some validation rules are still missing, they are marked with TODO in the
9
schema directly.
10
"""
adietmue's avatar
adietmue committed
11

12
13
from os import environ

14
15
16
# CORS
X_DOMAINS = '*'
X_HEADERS = ['Authorization', 'If-Match', 'If-Modified-Since', 'Content-Type']
17

adietmue's avatar
adietmue committed
18
# AMIVAPI URL and Admin Group
19
20
AMIVAPI_URL = 'https://amiv-api.ethz.ch'
ADMIN_GROUP_NAME = 'PVK Admins'
21

22
# DB (can be set by env for easier CI tests)
23
MONGO_HOST = environ.get('MONGO_HOST', 'localhost')
24
25
26
27
MONGO_PORT = environ.get('MONGO_PORT', 27017)
MONGO_DBNAME = environ.get('MONGO_DBNAME', 'pvk')
MONGO_USERNAME = environ.get('MONGO_USERNAME', 'pvkuser')
MONGO_PASSWORD = environ.get('MONGO_PASSWORD', 'pvkpass')
28

29

30
31
32
# Only JSON, simplifies hooks
XML = False

adietmue's avatar
adietmue committed
33

34
RESOURCE_METHODS = ['GET', 'POST']
adietmue's avatar
adietmue committed
35
36
ITEM_METHODS = ['GET', 'PATCH', 'DELETE']

37

adietmue's avatar
adietmue committed
38
39
# ISO 8601 time format instead of rfc1123
DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
40

adietmue's avatar
adietmue committed
41

42
43
44
45
# More Feedback when creating something: Return all fields
BANDWIDTH_SAVER = False


46
# A schema for required start/end time tuple
47
TIMESPAN_SCHEMA = {
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
    'type': 'dict',
    'schema': {
        'start': {
            'type': 'datetime',
            'nullable': False,
            'required': True,
        },
        'end': {
            'type': 'datetime',
            'nullable': False,
            'required': True,
        },
    },
}


64
65
66
67
# Same as Eve, but include 403
STANDARD_ERRORS = [400, 401, 403, 404, 405, 406, 409, 410, 412, 422, 428]


68
69
70
# Resources
DOMAIN = {
    'lectures': {
71
72
73

        'user_methods': ['GET'],

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
        'schema': {
            'title': {
                'type': 'string',
                'maxlength': 100,
                'unique': True,
                'required': True,
                'nullable': False,
                'empty': False,
            },
            'department': {
                'type': 'string',
                'allowed': ['itet', 'mavt'],
                'required': True,
                'nullable': False,
            },
            'year': {
                'type': 'integer',
                'min': 1,
                'max': 3,
                'required': True
            },
95
96
97
98
99
100
101
102
            'assistants': {
                # List of nethz of assistants
                'type': 'list',
                'schema': {
                    'type': 'string',
                    'maxlength': 10,
                    'empty': False,
                    'nullable': False,
adietmue's avatar
adietmue committed
103
                },
104
                # TODO: Not the same nethz twice
105
                # TODO: Is nethz enough here?
106
            }
107
108
109
110
        },
    },

    'courses': {
111
112
113

        'user_methods': ['GET'],

114
115
116
117
118
119
120
121
        'schema': {
            'lecture': {
                'type': 'objectid',
                'data_relation': {
                    'resource': 'lectures',
                    'field': '_id',
                    'embeddable': True
                },
122
                'not_patchable': True,  # Course is tied to lecture
123
124
            },
            'assistant': {
adietmue's avatar
adietmue committed
125
                'type': 'string',
126
                # TODO: Assistant needs to exist for lecture
127
128
            },

129
            'signup': TIMESPAN_SCHEMA,
130
131
132

            'datetimes': {
                'type': 'list',
133
134
                'schema': TIMESPAN_SCHEMA,
                # TODO: Timeslots must not overlap
135
136
137
138
139
140
141
142
            },
            'room': {
                'type': 'string',
                'maxlength': 100,
                'unique': True,
                'required': True,
                'nullable': False,
                'empty': False,
143
                # TODO: Room must be empty for time slot
144
145
146
147
148
149
150
151
152
153
154
            },
            'spots': {
                'type': 'integer',
                'min': 1,
                'required': True,
                'nullable': False
            }
        },
    },

    'signups': {
155
156
        # Signup for a user to a course

157
158
        'user_methods': ['GET', 'POST', 'PATCH', 'DELETE'],

159
160
161
162
163
164
165
        'schema': {
            'nethz': {
                'type': 'string',
                'maxlength': 10,
                'empty': False,
                'nullable': False,
                'required': True,
adietmue's avatar
adietmue committed
166
                'only_own_nethz': True,
167
                'not_patchable': True,  # Signup is tied to user
168
169
170
171
172
173
174
175
            },
            'course': {
                'type': 'objectid',
                'data_relation': {
                    'resource': 'courses',
                    'field': '_id',
                    'embeddable': True
                },
adietmue's avatar
adietmue committed
176
                'unique_combination': ['nethz'],
177
                'required': True,
178
                # TODO: No overlapping courses
179
180
181
            },
            'status': {
                'type': 'string',
182
                'allowed': ['waiting', 'reserved', 'accepted'],
183
                'readonly': True,
184
                'default': 'waiting',
185
186
            },
        },
187
188
189
190
    },

    'selections': {
        # Easy way for users to safe their selections before signup is open
191
        # exactly like singups, but without status
192

193
194
        'user_methods': ['GET', 'POST', 'PATCH', 'DELETE'],

195
196
197
198
199
200
201
202
        'schema': {
            'nethz': {
                'type': 'string',
                'maxlength': 10,
                'empty': False,
                'nullable': False,
                'required': True,
                'only_own_nethz': True,
203
                'not_patchable': True,  # Signup is tied to user
204
            },
205
206
207
208
209
210
            'course': {
                'type': 'objectid',
                'data_relation': {
                    'resource': 'courses',
                    'field': '_id',
                    'embeddable': True
211
                },
212
213
214
                'unique_combination': ['nethz'],
                'required': True,
                # TODO: No overlapping courses
215
216
217
218
219
220
221
222
            },
        },
    },

    'payments': {
        # Dummy endpoint for payments.
        # TODO: Implement as soon as PSP is known.

223
224
225
        # Only admins can delete payments
        'user_methods': ['GET', 'POST', 'PATCH'],

226
227
228
229
230
231
232
233
234
235
236
        'schema': {
            'signups': {
                'type': 'list',
                'schema': {
                    'type': 'objectid',
                    'data_relation': {
                        'resource': 'signups',
                        'field': '_id',
                        'embeddable': True
                    },
                    # TODO: No duplicate entries
237
                    # TODO: No courses on waiting list
238
239
240
241
242
                },
                'required': True,
                'nullable': False,
            }
        }
243
244
    }
}