Esempio n. 1
0
 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
Esempio n. 2
0
    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})
Esempio n. 3
0
 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
Esempio n. 4
0
    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
Esempio n. 5
0
    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)
Esempio n. 6
0
    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
Esempio n. 7
0
 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
Esempio n. 8
0
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
Esempio n. 9
0
    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)
Esempio n. 10
0
    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
Esempio n. 11
0
    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)
Esempio n. 12
0
    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)
Esempio n. 13
0
    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)