settings.py 6.65 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
17
18
19
# prefix everything with /api
URL_PREFIX = 'api'

# CORS
X_DOMAINS = '*'
X_HEADERS = ['Authorization', 'If-Match', 'If-Modified-Since', 'Content-Type']
20

adietmue's avatar
adietmue committed
21
22
23
# AMIVAPI URL and Admin Group
AMIVAPI_URL = "https://amiv-api.ethz.ch"
ADMIN_GROUP_NAME = 'PVK Admins'
24
25

# DB
26
MONGO_HOST = environ.get('MONGO_HOST', 'localhost')
27
28
29
30
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')
31

32
33
34
# Only JSON, simplifies hooks
XML = False

adietmue's avatar
adietmue committed
35

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

39

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

adietmue's avatar
adietmue committed
43

44
45
46
47
# More Feedback when creating something: Return all fields
BANDWIDTH_SAVER = False


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


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


70
71
72
# Resources
DOMAIN = {
    'lectures': {
73
74
75

        'user_methods': ['GET'],

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
        '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
            },
97
98
99
100
101
102
103
104
            'assistants': {
                # List of nethz of assistants
                'type': 'list',
                'schema': {
                    'type': 'string',
                    'maxlength': 10,
                    'empty': False,
                    'nullable': False,
adietmue's avatar
adietmue committed
105
                },
106
                # TODO: Not the same nethz twice
107
                # TODO: Is nethz enough here?
108
            }
109
110
111
112
        },
    },

    'courses': {
113
114
115

        'user_methods': ['GET'],

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

131
            'signup': TIMESPAN_SCHEMA,
132
133
134

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

    'signups': {
157
158
        # Signup for a user to a course

159
160
        'user_methods': ['GET', 'POST', 'PATCH', 'DELETE'],

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

    'selections': {
        # Easy way for users to safe their selections before signup is open
        # List of selected courses per user

195
196
        'user_methods': ['GET', 'POST', 'PATCH', 'DELETE'],

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
        'schema': {
            'nethz': {
                'type': 'string',
                'maxlength': 10,
                'empty': False,
                'nullable': False,
                'required': True,
                'only_own_nethz': True,
                'unique': True,
            },
            'courses': {
                'type': 'list',
                'schema': {
                    'type': 'objectid',
                    'data_relation': {
                        'resource': 'courses',
                        'field': '_id',
                        'embeddable': True
                    },
                    # TODO: No duplicate entries
                    # TODO: No entries that are already reserved
                },
            },
        },
    },

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

227
228
229
        # Only admins can delete payments
        'user_methods': ['GET', 'POST', 'PATCH'],

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