def post(self): """Create a new label""" received_data = request_to_dict(request) logging.debug("Received POST data: %s", received_data) new_label = db.Label(**received_data) new_label.save() return new_label, 201
def get(self, subscription_id: str): """ Returns an ICS feed when requested. Takes all search parameters that are accepted """ req_dict = request_to_dict(request) sub = db.Subscription.objects( sid=subscription_id).first() # type: Subscription if not sub: return "Subscription not found with identifier '{}'".format( subscription_id), 404 if 'labels' in req_dict: logging.warning( 'ICS feed requested with manually-specified labels %s. ' 'They have been ignored in favor of the stored labels %s', req_dict['labels'], sub.labels) req_dict['labels'] = sub.labels query = event_query(get_to_event_search(req_dict)) results = db.Event.objects(__raw__=query) # converts mongoDB objects to an ICS format response = mongo_to_ics(results, sub=sub) logging.debug("ics feed created for Subscription %s", sub.id) cd = "attachment;filename=abe.ics" return Response(response, mimetype="text/calendar", headers={"Content-Disposition": cd})
def put(self, client_id): """Update an app""" data = request_to_dict(request) if 'client_id' in data: abort(400) result = db.App.objects(client_id=client_id).first() if not result: return "App not found with identifier '{}'".format(client_id), 404 result.modify(**data) return result
def post(self): """Create an app. The API server creates the `client_id`. Use it in the [authentication flow](https://github.com/olin-build/ABE/wiki/User-Authentication). """ data = request_to_dict(request) if 'client_id' in data: abort(400) data['client_id'] = uuid4().hex app = db.App(**data) app.save() return app, 201
def post(self): """ Converts an ICS feed input to MongoDB objects. """ # reads outside ics feed url = request_to_dict(request) data = requests.get(url['url'].strip()).content.decode('utf-8') cal = Calendar.from_ical(data) if 'labels' in url: labels = url['labels'] else: labels = ['unlabeled'] extract_ics(cal, url['url'], labels)
def delete(self, id): """Delete a label""" logging.debug('Label requested: %s', id) search_fields = ['name', 'id'] result = multi_search(db.Label, id, search_fields) if not result: return "Label not found with identifier '{}'".format(id), 404 received_data = request_to_dict(request) logging.debug("Received DELETE data: %s", received_data) result.delete() # TODO: this should also remove the label from tagged events # TODO: should this operation fail if it would leave events untagged? return result
def post(self): """ Create new event with parameters passed in through args or form """ received_data = request_to_dict(request) logging.debug("Received POST data: %s", received_data) # combines args and form new_event = db.Event(**received_data) if not request_has_scope(request, 'create:protected_events'): check_protected_labels(new_event.labels) if 'recurrence' in new_event: # if this is a recurring event if not new_event.recurrence.forever: # if it doesn't recur forever # find the end of the recurrence new_event.recurrence_end = find_recurrence_end(new_event) new_event.save() return mongo_to_dict(new_event), 201
def get_to_event_search(request): """Build search dictionary based on get parameters""" if isinstance(request, dict): req_dict = request else: req_dict = request_to_dict(request) visibilities = { 'public': ['public'], 'olin': ['public', 'olin'], 'students': ['public', 'olin', 'students'], } def split_into_list(a): return a if isinstance(a, list) else a.split(',') def ensure_date_time(a): return dateutil.parser.parse(a) if not isinstance(a, datetime) else a preprocessing = { 'labels': split_into_list, # split labels on commas if not already list 'labels_and': split_into_list, 'labels_not': split_into_list, 'visibility': lambda a: visibilities.get(a, None), # search based on list 'start': ensure_date_time, 'end': ensure_date_time, } search_dict = req_dict for key, process in preprocessing.items(): if key in search_dict.keys(): search_dict[key] = process(search_dict[key]) # create a default date range if none is given now = datetime.now() if 'start' not in search_dict: search_dict['start'] = now + relativedelta(months=-1) if 'end' not in search_dict: search_dict['end'] = now + relativedelta(months=+2) return search_dict
def put(self, subscription_id: str): """Modify an existing subscription""" data = request_to_dict(request) logging.debug("Received Subscription PUT data: %s", data) subscription = db.Subscription.objects(sid=subscription_id).first() if not subscription: return "Subscription not found with identifier '{}'".format( subscription_id), 404 if isinstance(data['labels'], list): subscription.labels = data['labels'] elif isinstance(data['labels'], str): subscription.labels = data['labels'].split(',') subscription.save() return subscription_to_dict(subscription)
def put(self, id): """Modify a label's properties""" received_data = request_to_dict(request) logging.debug("Received PUT data: %s", received_data) search_fields = ['name', 'id'] result = multi_search(db.Label, id, search_fields) if not result: return "Label not found with identifier '{}'".format(id), 404 previous_name = result['name'] new_name = received_data.get('name', previous_name) result.update(**received_data) # TODO: do this inside the same transaction as the update above, on update to mnogo 4.0 if previous_name != new_name: db.Event.objects(labels=previous_name).update(labels__S=new_name) db.ICS.objects(labels=previous_name).update(labels__S=new_name) db.Subscription.objects(labels=previous_name).update( labels__S=new_name) return result
def post(self, subscription_id: str = ''): """ Creates a subscription object with a list of labels, returning it with an ID """ d = request_to_dict(request) subscription = Subscription.new( ) # Creates a subscription with a random ID if subscription_id: subscription.sid = subscription_id if isinstance(d['labels'], list): subscription.labels = d['labels'] elif isinstance(d['labels'], str): subscription.labels = d['labels'].split(',') else: raise ValueError('labels must be a list or comma-separated string') subscription.save() logging.debug("Subscription %s saved to the database", subscription.sid) return subscription_to_dict(subscription)
def delete(self, event_id, rec_id=None): """ Delete individual event event_id the id of the event to be deleted rec_id the rec_id of a sub_event to be deleted """ # TODO: call check_protected_labels(result.labels) # if not request_has_scope(request, 'delete:protected_events') logging.debug('Event requested: %s', event_id) result = db.Event.objects(id=event_id).first() if not result: # if no event is found with the id given # try finding a sub_event with that id cur_parent_event = db.Event.objects( __raw__={ 'sub_events._id': objectid.ObjectId(event_id) }).first() if cur_parent_event: # if found update the deleted field of the sub_event received_data = {'deleted': True} result = update_sub_event(received_data, cur_parent_event, objectid.ObjectId(event_id)) logging.debug("Edited sub_event deleted") else: abort(404) elif rec_id: # if this is a sub_event of a recurring event that has not been created yet sub_event_dummy = placeholder_recurring_creation( rec_id, [], result, True) sub_event_dummy['deleted'] = True # create a sub_event with the deleted field set to true create_sub_event(sub_event_dummy, result) logging.debug("Deleted sub_event for the first time") else: # if a normal event is to be deleted received_data = request_to_dict(request) logging.debug("Received DELETE data: %s", received_data) result.delete() return mongo_to_dict(result)
def put(self, event_id): """ Modify individual event event_id id of the event to modify """ received_data = request_to_dict(request) logging.debug("Received PUT data: %s", received_data) result = db.Event.objects(id=event_id).first() if not result: # if no event was found # try finding a sub_event with the id and save the parent event it is stored under cur_parent_event = db.Event.objects( __raw__={ 'sub_events._id': objectid.ObjectId(event_id) }).first() if cur_parent_event: # if a sub_event was found, updated it with the received_data result = update_sub_event(received_data, cur_parent_event, objectid.ObjectId(event_id)) else: abort(404) else: # if event was found if not request_has_scope(request, 'edit:protected_events'): check_protected_labels(result.labels) # TODO: also check the new labels # if the received data is a new sub_event if 'sid' in received_data and received_data['sid'] is not None: # create a new sub_event document if 'rec_id' in received_data and received_data[ 'rec_id'] is not None: received_data['rec_id'] = dateutil.parser.parse( str(received_data['rec_id'])) result = create_sub_event(received_data, result) else: # if this a normal event to be updated result.update(**received_data) result.reload() return mongo_to_dict(result)