settings.py 6.61 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 = environ.get('AMIVAPI_URL', 'https://amiv-api.ethz.ch')
ADMIN_GROUP_NAME = environ.get('AMIVAPI_GROUP', 'PVK Admins')
21
22

# DB
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
# Only JSON, simplifies hooks
XML = False

adietmue's avatar
adietmue committed
32

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

36

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

adietmue's avatar
adietmue committed
40

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


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


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


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

        'user_methods': ['GET'],

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

    'courses': {
110
111
112

        'user_methods': ['GET'],

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

128
            'signup': TIMESPAN_SCHEMA,
129
130
131

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

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

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

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

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

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

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

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

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

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