Example #1
0
def add_calendar():
    """ Add a calendar to the database.
    This function is only accessible to admin of the webapp.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for("index"))
    if not is_admin():
        flask.flash("You are not a fedocal admin, you are not allowed " "to add calendars.", "errors")
        return flask.redirect(flask.url_for("index"))

    form = forms.AddCalendarForm()
    # pylint: disable=E1101
    if form.validate_on_submit():
        calendarobj = Calendar(
            calendar_name=form.calendar_name.data,
            calendar_contact=form.calendar_contact.data,
            calendar_description=form.calendar_description.data,
            calendar_manager_group=form.calendar_manager_groups.data,
            calendar_admin_group=form.calendar_admin_groups.data,
            calendar_multiple_meetings=bool(form.calendar_multiple_meetings.data),
            calendar_regional_meetings=bool(form.calendar_regional_meetings.data),
        )
        try:
            calendarobj.save(SESSION)
            SESSION.commit()
        except SQLAlchemyError, err:
            SESSION.rollback()
            print "add_calendar:", err
            flask.flash("Could not add this calendar to the database", "errors")
            return flask.render_template("add_calendar.html", form=form)
        flask.flash("Calendar added")
        return flask.redirect(flask.url_for("index"))
Example #2
0
def add_meeting(calendar_name):
    """ Add a meeting to the database.
    This function is only available to CLA+1 member or members of the
    group administrating of the said calendar.

    :arg calendar_name, name of the calendar in which to add the meeting.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for("index"))
    calendarobj = Calendar.by_id(SESSION, calendar_name)
    if calendarobj.calendar_manager_group and not (
        is_calendar_manager(calendarobj) or is_calendar_admin(calendarobj) or is_admin()
    ):
        flask.flash(
            "You are not one of the manager of this calendar, "
            "or one of its admins, you are not allowed to add "
            "new meetings.",
            "errors",
        )
        return flask.redirect(flask.url_for("calendar", calendar_name=calendar_name))

    form = forms.AddMeetingForm()
    tzone = get_timezone()
    calendarobj = Calendar.by_id(SESSION, calendar_name)
    # pylint: disable=E1101
    if form.validate_on_submit():
        try:
            fedocallib.add_meeting(
                session=SESSION,
                calendarobj=calendarobj,
                fas_user=flask.g.fas_user,
                meeting_name=form.meeting_name.data,
                meeting_date=form.meeting_date.data,
                meeting_date_end=form.meeting_date_end.data,
                meeting_time_start=form.meeting_time_start.data,
                meeting_time_stop=form.meeting_time_stop.data,
                comanager=form.comanager.data,
                meeting_information=form.information.data,
                meeting_region=form.meeting_region.data,
                tzone=get_timezone(),
                frequency=form.frequency.data,
                end_repeats=form.end_repeats.data,
                remind_when=form.remind_when.data,
                remind_who=form.remind_who.data,
                full_day=form.full_day.data,
                admin=is_admin(),
            )
        except FedocalException, err:
            flask.flash(err, "warnings")
            return flask.render_template("add_meeting.html", calendar=calendarobj, form=form, tzone=tzone)
        except SQLAlchemyError, err:
            SESSION.rollback()
            print "add_meeting:", err
            flask.flash("Could not add this meeting to this calendar", "errors")
            return flask.render_template("add_meeting.html", calendar=calendarobj, form=form, tzone=tzone)
Example #3
0
def index():
    """ Displays the index page with containing the first calendar (by
    order of creation and if any) for the current week.
    """
    calendars_enabled = Calendar.by_status(SESSION, 'Enabled')
    calendars_disabled = Calendar.by_status(SESSION, 'Disabled')
    auth_form = forms.LoginForm()
    admin = is_admin()
    return flask.render_template(
        'index.html',
        calendars=calendars_enabled,
        calendars_table=chunks(calendars_enabled, 3),
        calendars_table2=chunks(calendars_disabled, 3),
        auth_form=auth_form,
        admin=admin)
Example #4
0
def edit_calendar(calendar_name):
    """ Edit a specific calendar based on the calendar identifier.

    :arg calendar_name: the identifier of the calendar to edit.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for("index"))
    if not is_admin():
        flask.flash("You are not a fedocal admin, you are not allowed " "to edit the calendar.", "errors")
        return flask.redirect(flask.url_for("index"))

    calendarobj = Calendar.by_id(SESSION, calendar_name)
    form = forms.AddCalendarForm()
    # pylint: disable=E1101
    if form.validate_on_submit():
        try:
            calendarobj.calendar_name = form.calendar_name.data
            calendarobj.calendar_contact = form.calendar_contact.data
            calendarobj.calendar_description = form.calendar_description.data
            calendarobj.calendar_manager_group = form.calendar_manager_groups.data
            calendarobj.calendar_admin_group = form.calendar_admin_groups.data
            calendarobj.calendar_multiple_meetings = bool(form.calendar_multiple_meetings.data)
            calendarobj.calendar_regional_meetings = bool(form.calendar_regional_meetings.data)
            calendarobj.save(SESSION)
            SESSION.commit()
        except SQLAlchemyError, err:
            SESSION.rollback()
            print "edit_calendar:", err
            flask.flash("Could not update this calendar.", "errors")
            return flask.render_template("edit_calendar.html", form=form, calendar=calendarobj)

        flask.flash("Calendar updated")
        return flask.redirect(flask.url_for("calendar", calendar_name=calendarobj.calendar_name))
Example #5
0
def delete_calendar(calendar_name):
    """ Delete a specific calendar given its identifier.

    :arg calendar_name: the identifier of the calendar to delete.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for("index"))
    if not is_admin():
        flask.flash("You are not a fedocal admin, you are not allowed " "to delete the calendar.", "errors")
        return flask.redirect(flask.url_for("index"))

    calendarobj = Calendar.by_id(SESSION, calendar_name)
    deleteform = forms.DeleteCalendarForm()
    # pylint: disable=E1101
    if deleteform.validate_on_submit():
        if deleteform.confirm_delete.data:
            calendarobj.delete(SESSION)
            try:
                SESSION.commit()
            except SQLAlchemyError, err:
                SESSION.rollback()
                print "delete_calendar:", err
                flask.flash("Could not delete this calendar.", "errors")
        flask.flash("Calendar deleted")
        return flask.redirect(flask.url_for("index"))
Example #6
0
def delete_calendar(calendar_name):
    """ Delete a specific calendar given its identifier.

    :arg calendar_name: the identifier of the calendar to delete.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for('index'))
    if not is_admin():
        flask.flash('You are not a fedocal admin, you are not allowed '
                    'to delete the calendar.', 'errors')
        return flask.redirect(flask.url_for('index'))

    calendarobj = Calendar.by_id(SESSION, calendar_name)
    deleteform = forms.DeleteCalendarForm()
    # pylint: disable=E1101
    if deleteform.validate_on_submit():
        if deleteform.confirm_delete.data:
            calendarobj.delete(SESSION)
            try:
                SESSION.commit()
            except SQLAlchemyError, err:
                SESSION.rollback()
                print 'delete_calendar:', err
                flask.flash('Could not delete this calendar.', 'errors')
        flask.flash('Calendar deleted')
        fedmsg.publish(topic="calendar.delete", msg=dict(
            agent=flask.g.fas_user.username,
            calendar=calendarobj.to_json(),
        ))
        return flask.redirect(flask.url_for('index'))
Example #7
0
def delete_meeting(meeting_id):
    """ Delete a specific meeting given its identifier.

    :arg meeting_id: the identifier of the meeting to delete.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for("index"))
    meeting = Meeting.by_id(SESSION, meeting_id)
    if not (is_meeting_manager(meeting) or is_calendar_admin(meeting.calendar) or is_admin()):
        flask.flash(
            "You are not one of the manager of this meeting, " "or an admin, you are not allowed to delete it.",
            "errors",
        )
        return flask.redirect(flask.url_for("view_meeting", meeting_id=meeting_id))

    calendars = Calendar.get_all(SESSION)
    deleteform = forms.DeleteMeetingForm()
    # pylint: disable=E1101
    if deleteform.validate_on_submit():
        if deleteform.confirm_delete.data:
            if deleteform.confirm_futher_delete.data:
                fedocallib.delete_recursive_meeting(SESSION, meeting)
            else:
                meeting.delete(SESSION)
            try:
                SESSION.commit()
            except SQLAlchemyError, err:
                SESSION.rollback()
                print "edit_meeting:", err
                flask.flash("Could not update this meeting.", "error")
        flask.flash("Meeting deleted")
        return flask.redirect(flask.url_for("calendar", calendar_name=meeting.calendar_name))
Example #8
0
def inject_calendars():
    """ With this decorator we add the list of all the calendars
    available to all the function, so the variable calendars is available
    in all templates.
    """
    calendars = Calendar.get_all(SESSION)

    return dict(calendars=calendars)
Example #9
0
def add_calendar():
    """ Add a calendar to the database.
    This function is only accessible to admin of the webapp.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for('index'))
    if not is_admin():
        flask.flash('You are not a fedocal admin, you are not allowed '
                    'to add calendars.', 'errors')
        return flask.redirect(flask.url_for('index'))

    status = fedocallib.get_calendar_statuses(SESSION)

    form = forms.AddCalendarForm(status=status)
    # pylint: disable=E1101
    if form.validate_on_submit():
        calendarobj = Calendar(
            calendar_name=form.calendar_name.data,
            calendar_contact=form.calendar_contact.data,
            calendar_description=form.calendar_description.data,
            calendar_editor_group=form.calendar_editor_groups.data,
            calendar_admin_group=form.calendar_admin_groups.data,
            calendar_multiple_meetings=bool(
                form.calendar_multiple_meetings.data),
            calendar_regional_meetings=bool(
                form.calendar_regional_meetings.data),
            calendar_status=form.calendar_status.data
        )
        try:
            calendarobj.save(SESSION)
            SESSION.commit()
        except SQLAlchemyError, err:
            SESSION.rollback()
            print 'add_calendar:', err
            flask.flash('Could not add this calendar to the database',
                        'errors')
            return flask.render_template('add_calendar.html',
                                         form=form)

        flask.flash('Calendar added')
        fedmsg.publish(topic="calendar.new", msg=dict(
            agent=flask.g.fas_user.username,
            calendar=calendarobj.to_json(),
        ))
        return flask.redirect(flask.url_for('index'))
Example #10
0
def index():
    """ Displays the index page with containing the first calendar (by
    order of creation and if any) for the current week.
    """
    calendars = Calendar.get_all(SESSION)
    auth_form = forms.LoginForm()
    admin = is_admin()
    return flask.render_template(
        "index.html", calendars=calendars, calendars_table=chunks(calendars, 3), auth_form=auth_form, admin=admin
    )
Example #11
0
def is_user_managing_in_calendar(session, calendar_name, fas_user):
    """ Returns True if the user is in a group set as editor of the
    calendar and False otherwise. It will also return True if there are
    no groups set as editor the calendar.

    :arg session: the database session to use
    :arg calendar_name: the name of the calendar of interest.
    :arg fas_user: a FAS user object with all the info.
    """
    editor_groups = Calendar.get_editor_groups(session, calendar_name)
    admin_groups = Calendar.get_admin_groups(session, calendar_name)
    if not editor_groups:
        return True
    else:
        return len(
            set(editor_groups).intersection(set(fas_user.groups))
        ) >= 1 or len(
            set(admin_groups).intersection(set(fas_user.groups))
        ) >= 1
Example #12
0
def edit_meeting(meeting_id):
    """ Edit a specific meeting based on the meeting identifier.

    :arg meeting_id: the identifier of the meeting to edit.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for("index"))
    meeting = Meeting.by_id(SESSION, meeting_id)
    calendarobj = Calendar.by_id(SESSION, meeting.calendar_name)
    if not (is_meeting_manager(meeting) or is_calendar_admin(meeting.calendarobj) or is_admin()):
        flask.flash(
            "You are not one of the manager of this meeting, " "or an admin, you are not allowed to edit it.", "errors"
        )
        return flask.redirect(flask.url_for("view_meeting", meeting_id=meeting_id))

    tzone = get_timezone()
    form = forms.AddMeetingForm()
    # pylint: disable=E1101
    if form.validate_on_submit():
        try:
            fedocallib.edit_meeting(
                session=SESSION,
                meeting=meeting,
                calendarobj=calendarobj,
                fas_user=flask.g.fas_user,
                meeting_name=form.meeting_name.data,
                meeting_date=form.meeting_date.data,
                meeting_date_end=None,
                meeting_time_start=form.meeting_time_start.data,
                meeting_time_stop=form.meeting_time_stop.data,
                comanager=form.comanager.data,
                meeting_information=form.information.data,
                meeting_region=form.meeting_region.data,
                tzone=get_timezone(),
                recursion_frequency=form.frequency.data,
                recursion_ends=form.end_repeats.data,
                remind_when=form.remind_when.data,
                remind_who=form.remind_who.data,
                full_day=form.full_day.data,
                edit_all_meeting=form.recursive_edit.data,
                admin=is_admin(),
            )
        except FedocalException, err:
            flask.flash(err, "warnings")
            return flask.render_template(
                "edit_meeting.html", meeting=meeting, calendar=calendarobj, form=form, tzone=tzone
            )
        except SQLAlchemyError, err:
            SESSION.rollback()
            print "edit_meeting:", err
            flask.flash("Could not update this meeting.", "errors")
            return flask.render_template(
                "edit_meeting.html", meeting=meeting, calendar=calendarobj, form=form, tzone=tzone
            )
Example #13
0
def ical_all():
    """ Returns a iCal feed of all calendars from today - 1 month to
    today + 6 month.
    """
    startd = datetime.date.today() - datetime.timedelta(days=30)
    endd = datetime.date.today() + datetime.timedelta(days=180)
    ical = vobject.iCalendar()
    meetings = []
    for calendar in Calendar.get_all(SESSION):
        meetings.extend(fedocallib.get_meetings_by_date(SESSION, calendar.calendar_name, startd, endd))
    fedocallib.add_meetings_to_vcal(ical, meetings)
    return flask.Response(ical.serialize(), mimetype="text/calendar")
Example #14
0
def calendar_list(calendar_name, year, month, day):
    """ Display in a list form all the meetings of a given calendar.
    By default it displays all the meetings of the current year but this
    can be more restricted to a month or even a day.

    :arg calendar_name: the name of the calendar that one would like to
        consult.
    :arg year: the year of the date one would like to consult.
    :arg month: the month of the date one would like to consult.
    :arg day: the day of the date one would like to consult.
    """
    inyear = year
    if not year:
        inyear = datetime.date.today().year
    inmonth = month
    if not month:
        inmonth = 1
    inday = day
    if not day:
        inday = 1
    start_date = datetime.date(inyear, inmonth, inday)
    if not month and not day:
        end_date = start_date + relativedelta(years=+1)
    elif not day:
        end_date = start_date + relativedelta(months=+1)
    else:
        end_date = start_date + relativedelta(days=+1)

    calendarobj = Calendar.by_id(SESSION, calendar_name)
    tzone = get_timezone()
    meetings = fedocallib.get_by_date(
        SESSION, calendarobj, start_date, end_date, tzone)

    month_name = datetime.date.today().strftime('%B')
    auth_form = forms.LoginForm()
    admin = is_admin()

    curmonth_cal = fedocallib.get_html_monthly_cal(
        year=year, month=month, day=day, calendar_name=calendar_name)
    return flask.render_template(
        'meeting_list.html',
        calendar=calendarobj,
        month=month_name,
        meetings=meetings,
        tzone=tzone,
        year=inyear,
        auth_form=auth_form,
        curmonth_cal=curmonth_cal,
        admin=admin)
Example #15
0
def delete_meeting(meeting_id):
    """ Delete a specific meeting given its identifier.

    :arg meeting_id: the identifier of the meeting to delete.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for('index'))
    meeting = Meeting.by_id(SESSION, meeting_id)

    if meeting.calendar.calendar_status != 'Enabled':
        flask.flash('This calendar is "%s", you are not allowed to delete '
                    'its meetings anymore.' % calendarobj.calendar_status,
                    'errors')
        return flask.redirect(flask.url_for('calendar',
                              calendar_name=calendar_name))

    if not (is_meeting_manager(meeting)
            or is_calendar_admin(meeting.calendar)
            or is_admin()):
        flask.flash('You are not one of the manager of this meeting, '
                    'or an admin, you are not allowed to delete it.',
                    'errors')
        return flask.redirect(flask.url_for('view_meeting',
                                            meeting_id=meeting_id))

    calendars = Calendar.get_all(SESSION)
    deleteform = forms.DeleteMeetingForm()
    # pylint: disable=E1101
    if deleteform.validate_on_submit():
        if deleteform.confirm_delete.data:
            if deleteform.confirm_futher_delete.data:
                fedocallib.delete_recursive_meeting(SESSION, meeting)
            else:
                meeting.delete(SESSION)
            try:
                SESSION.commit()
            except SQLAlchemyError, err:
                SESSION.rollback()
                print 'edit_meeting:', err
                flask.flash('Could not update this meeting.', 'error')
        flask.flash('Meeting deleted')
        fedmsg.publish(topic="meeting.delete", msg=dict(
            agent=flask.g.fas_user.username,
            meeting=meeting.to_json(),
            calendar=meeting.calendar.to_json(),
        ))
        return flask.redirect(flask.url_for(
            'calendar', calendar_name=meeting.calendar_name))
Example #16
0
def get_meetings_by_date_and_location(
        session, calendar, start_date, end_date, location):
    """ Return a list of meetings which have or will occur in between
    the two provided dates.

    :arg session: the database session to use
    :arg calendar: the name of the calendar of interest.
    :arg start_date: the date from which we would like to retrieve the
        meetings (this day is included in the selection).
    :arg start_date: the date until which we would like to retrieve the
        meetings (this day is excluded from the selection).
    :arg location: the location in which the meetings occurs.
    """
    calendar = Calendar.by_id(session, calendar)
    return Meeting.get_by_date_and_location(session, calendar, start_date,
                                            end_date, location)
Example #17
0
def edit_calendar(calendar_name):
    """ Edit a specific calendar based on the calendar identifier.

    :arg calendar_name: the identifier of the calendar to edit.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for('index'))
    if not is_admin():
        flask.flash('You are not a fedocal admin, you are not allowed '
                    'to edit the calendar.', 'errors')
        return flask.redirect(flask.url_for('index'))

    calendarobj = Calendar.by_id(SESSION, calendar_name)
    status = fedocallib.get_calendar_statuses(SESSION)
    form = forms.AddCalendarForm(status=status)
    # pylint: disable=E1101
    if form.validate_on_submit():
        try:
            calendarobj.calendar_name = form.calendar_name.data
            calendarobj.calendar_contact = form.calendar_contact.data
            calendarobj.calendar_description = form.calendar_description.data
            calendarobj.calendar_editor_group = \
                form.calendar_editor_groups.data
            calendarobj.calendar_admin_group = \
                form.calendar_admin_groups.data
            calendarobj.calendar_multiple_meetings = bool(
                form.calendar_multiple_meetings.data)
            calendarobj.calendar_regional_meetings = bool(
                form.calendar_regional_meetings.data)
            calendarobj.calendar_status = form.calendar_status.data
            calendarobj.save(SESSION)
            SESSION.commit()
        except SQLAlchemyError, err:
            SESSION.rollback()
            print 'edit_calendar:', err
            flask.flash('Could not update this calendar.', 'errors')
            return flask.render_template(
                'edit_calendar.html', form=form, calendar=calendarobj)

        flask.flash('Calendar updated')
        fedmsg.publish(topic="calendar.update", msg=dict(
            agent=flask.g.fas_user.username,
            calendar=calendarobj.to_json(),
        ))
        return flask.redirect(flask.url_for(
            'calendar', calendar_name=calendarobj.calendar_name))
Example #18
0
def calendar(calendar_name, year, month, day):
    """ Display the week of a specific date for a specified calendar.

    :arg calendar_name: the name of the calendar that one would like to
        consult.
    :arg year: the year of the date one would like to consult.
    :arg month: the month of the date one would like to consult.
    :arg day: the day of the date one would like to consult.
    """
    calendarobj = Calendar.by_id(SESSION, calendar_name)
    week_start = fedocallib.get_start_week(year, month, day)
    weekdays = fedocallib.get_week_days(year, month, day)
    tzone = get_timezone()
    meetings = fedocallib.get_meetings(
        SESSION, calendarobj, year, month, day, tzone=tzone)
    next_week = fedocallib.get_next_week(
        week_start.year, week_start.month, week_start.day)
    prev_week = fedocallib.get_previous_week(
        week_start.year, week_start.month, week_start.day)
    auth_form = forms.LoginForm()
    admin = is_admin()
    month_name = week_start.strftime('%B')

    day_index = None
    today = datetime.date.today()
    if today > week_start and today < week_start + datetime.timedelta(days=7):
        day_index = fedocallib.get_week_day_index(
            today.year, today.month, today.day)

    curmonth_cal = fedocallib.get_html_monthly_cal(
        year=year, month=month, day=day, calendar_name=calendar_name)
    return flask.render_template(
        'agenda.html',
        calendar=calendarobj,
        month=month_name,
        weekdays=weekdays,
        day_index=day_index,
        meetings=meetings,
        tzone=tzone,
        next_week=next_week,
        prev_week=prev_week,
        auth_form=auth_form,
        curmonth_cal=curmonth_cal,
        admin=admin)
Example #19
0
File: api.py Project: tyll/fedocal
def api_meetings():
    """
Retrieve meetings
=================

The ``/api/meetings/`` endpoint returns the meetings meeting the
provided criteria.

Response format
----------------

Sample response:

.. code-block:: javascript

    {
        "meetings": [
            {
                "meeting_time_start": "23:00:00",
                "meeting_information": "",
                "meeting_time_stop": "23:00:00",
                "calendar_name": "test",
                "meeting_date_end": "2013-05-27",
                "meeting_manager": "pingou2,",
                "meeting_date": "2013-05-27",
                "meeting_name": "test1.5",
                "meeting_location": "None"
            },
            {
                "meeting_time_start": "06:00:00",
                "meeting_information": "",
                "meeting_time_stop": "07:00:00",
                "calendar_name": "test",
                "meeting_date_end": "2013-05-28",
                "meeting_manager": "pingou,",
                "meeting_date": "2013-05-28",
                "meeting_name": "test3",
                "meeting_location": null
            }
        ],
        "arguments": {
            "start": "2013-05-04",
            "calendar": "test",
            "end": "2013-11-30",
            "region": null
        }
    }


The ``arguments`` item in the root dictionary contains all possible
arguments, and displays the value used (the default if the argument
was not provided).

Time arguments
--------------

Below is a table describing what timeframe messages are received from
depending on what combination of time options you provide.

========= ======= =================
``start`` ``end`` Message timeframe
========= ======= =================
no        no      the last 30 days and the coming 180 days
**yes**   no      from ``start`` until the coming 180 days
no        **yes** the last 30 days until ``end``
**yes**   **yes** between ``start`` and ``end``
========= ======= =================

``start``
  Return results starting at date ``start`` (prefered format is
  "+%Y-%m-%d" see ``date "+%Y-%m-%d"``).

  Default: 30 days ago ``date "+%Y-%m-%d" -d "30 days ago"``

``end``
  Return results ending at date ``end`` (prefered format is
  "+%Y-%m-%d" see ``date "+%Y-%m-%d"``).

  Default: coming 180 days ``date "+%Y-%m-%d" -d "180 days"``

Filter arguments
----------------

``calendar``
  Restrict the meetings to a specific calendar.

  Default: all calendars

``region``
  Restrict the meeting to a specific region.

  If the calendar does not have support for regions enabled, no
  meetings will be found matching this criteria and no meetings will
  be returned.

  Default: all regions

    """
    @flask.after_this_request
    def callback(response):
        """ Handle case the query was an JQuery ajax call. """
        return check_callback(response)

    startd = flask.request.args.get('start', None)
    if startd is None:
        startd = datetime.date.today() - datetime.timedelta(days=30)
    else:
        try:
            startd = parser.parse(startd).date()
        except ValueError:
            output = {"meetings": [],
                      "error": "Invalid start date format: %s" % startd}
            return flask.Response(
                response=json.dumps(output),
                status=400,
                mimetype='application/json')

    endd = flask.request.args.get('end', None)
    if endd is None:
        endd = datetime.date.today() + datetime.timedelta(days=180)
    else:
        try:
            endd = parser.parse(endd).date()
        except ValueError:
            output = {"meetings": [],
                      "error": "Invalid end date format: %s" % endd}
            return flask.Response(
                response=json.dumps(output),
                status=400,
                mimetype='application/json')

    calendar_name = flask.request.args.get('calendar', None)
    location = flask.request.args.get('location', None)
    region = flask.request.args.get('region', None)
    location = location or region

    if calendar_name:
        calendarobj = Calendar.by_id(SESSION, calendar_name)

        if not calendarobj:
            output = {"meetings": [],
                      "error": "Invalid calendar provided: %s" %
                      calendar_name}
            return flask.Response(
                response=json.dumps(output),
                status=400,
                mimetype='application/json')

    status = 200
    meetings = []
    try:
        if calendar_name:
            if location:
                #print "calendar and region"
                meetings = fedocallib.get_meetings_by_date_and_location(
                    SESSION, calendar_name, startd, endd, location)
            else:
                #print "calendar and no region"
                meetings = fedocallib.get_by_date(
                    SESSION, calendarobj, startd, endd)
        else:
            meetings = []
            if location:
                #print "no calendar and region"
                meetings.extend(
                    fedocallib.get_by_date_at_location(
                        SESSION, location, startd, endd)
                )
            else:
                #print "no calendar and no region"
                for calendar in fedocallib.get_calendars(SESSION):
                    meetings.extend(fedocallib.get_by_date(
                        SESSION, calendar, startd, endd))
    except SQLAlchemyError, err:  # pragma: no cover
        status = 500
        LOG.debug('Error in api_meetings')
        LOG.exception(err)
Example #20
0
def api_user_shield(username, calendar_name):
    """
User shield
===========

Provides a small image (a shield) displaying the status of the specified
user on the specified calendar if the user is currently managing a meeting.

Filter arguments
----------------

``connector``
  Changes the 'connector' text used in the image.

  Default: 'in'

``status``
  Changes the 'status' text used in the image.

  Default: the name of the calendar checked

``always``
  Booleans to specify whether to return an image if no meeting is found for
  the specified user on the specified calendar.

  Default: True
  Can be:  False, 0, f

If the user is not managing a meeting, instead of returning the image the
endpoint raises a 404.

    """
    connector = flask.request.args.get('connector', 'in')
    status = flask.request.args.get('status', calendar_name)
    always = flask.request.args.get('always', True)

    if str(always).lower() in ['0', 'false', 'f']:
        always = False
    else:
        always = True

    calendarobj = Calendar.by_id(SESSION, calendar_name)
    if not calendarobj:
        flask.abort(400, 'Invalid calendar provided')

    start_date = datetime.datetime.utcnow().date()
    end_date = start_date + datetime.timedelta(days=1)

    meetings = fedocallib.get_by_date(
        SESSION, calendarobj, start_date, end_date, tzone='UTC')

    green, red = 'brightgreen', 'red'

    template = 'https://img.shields.io/badge/%s-%s_%s-%s.png'

    output = None
    for meeting in meetings:
        usernames = [user.username for user in meeting.meeting_manager_user]
        if username in usernames:
            output = template % (username, connector, status, green)
            break

    if output:
        return flask.redirect(output)
    elif always:
        output = template % (username, "not " + connector, status, red)
        return flask.redirect(output)
    else:
        flask.abort(404)
Example #21
0
def api_meetings():
    """
Retrieve meetings
=================

The ``/api/meetings/`` endpoint returns the meetings meeting the
provided criteria.

Response format
----------------

Sample response:

.. code-block:: javascript

    {
        "meetings": [
            {
                "meeting_time_start": "23:00:00",
                "meeting_information": "",
                "meeting_time_stop": "23:00:00",
                "calendar_name": "test",
                "meeting_date_end": "2013-05-27",
                "meeting_manager": [ "pingou2" ],
                "meeting_date": "2013-05-27",
                "meeting_name": "test1.5",
                "meeting_location": "None",
                "meeting_timezone": "UTC"
            },
            {
                "meeting_time_start": "06:00:00",
                "meeting_information": "",
                "meeting_time_stop": "07:00:00",
                "calendar_name": "test",
                "meeting_date_end": "2013-05-28",
                "meeting_manager": [ "pingou" ],
                "meeting_date": "2013-05-28",
                "meeting_name": "test3",
                "meeting_location": null,
                "meeting_timezone": "UTC"
            }
        ],
        "arguments": {
            "start": "2013-05-04",
            "calendar": "test",
            "end": "2013-11-30",
            "region": null
        }
    }

The ``meeting_time_start``, ``meeting_time_end``, ``meeting_date`` and
``meeting_date_end`` contain time in "UTC". The ``meeting_timezone`` indicates
the timezone the meeting is registered with. If the ``meeting_timezone`` is not
"UTC", the meeting time will change according to DST rules of the specified
timezone.

The ``arguments`` item in the root dictionary contains all possible
arguments, and displays the value used (the default if the argument
was not provided).

Time arguments
--------------

Below is a table describing what timeframe messages are received from
depending on what combination of time options you provide.

========= ======= =================
``start`` ``end`` Message timeframe
========= ======= =================
no        no      the last 30 days and the coming 180 days
**yes**   no      from ``start`` until the coming 180 days
no        **yes** the last 30 days until ``end``
**yes**   **yes** between ``start`` and ``end``
========= ======= =================

``start``
  Return results starting at date ``start`` (prefered format is
  "+%Y-%m-%d" see ``date "+%Y-%m-%d"``).

  Default: 30 days ago ``date "+%Y-%m-%d" -d "30 days ago"``

``end``
  Return results ending at date ``end`` (prefered format is
  "+%Y-%m-%d" see ``date "+%Y-%m-%d"``).

  Default: coming 180 days ``date "+%Y-%m-%d" -d "180 days"``

Filter arguments
----------------

``calendar``
  Restrict the meetings to a specific calendar.

  Default: all calendars

``region``
  Restrict the meeting to a specific region.

  If the calendar does not have support for regions enabled, no
  meetings will be found matching this criteria and no meetings will
  be returned.

  Default: all regions

    """
    @flask.after_this_request
    def callback(response):
        """ Handle case the query was an JQuery ajax call. """
        return check_callback(response)

    startd = flask.request.args.get('start', None)
    if startd is None:
        startd = datetime.date.today() - datetime.timedelta(days=30)
    else:
        try:
            startd = parser.parse(startd).date()
        except (ValueError, TypeError):
            output = {"meetings": [],
                      "error": "Invalid start date format: %s" % startd}
            return flask.Response(
                response=json.dumps(output),
                status=400,
                mimetype='application/json')

    endd = flask.request.args.get('end', None)
    if endd is None:
        endd = datetime.date.today() + datetime.timedelta(days=180)
    else:
        try:
            endd = parser.parse(endd).date()
        except (ValueError, TypeError):
            output = {"meetings": [],
                      "error": "Invalid end date format: %s" % endd}
            return flask.Response(
                response=json.dumps(output),
                status=400,
                mimetype='application/json')

    calendar_name = flask.request.args.get('calendar', None)
    location = flask.request.args.get('location', None)
    region = flask.request.args.get('region', None)
    location = location or region

    if calendar_name:
        calendarobj = Calendar.by_id(SESSION, calendar_name)

        if not calendarobj:
            output = {
                "meetings": [],
                "error": "Invalid calendar provided: %s" % calendar_name}
            return flask.Response(
                response=json.dumps(output),
                status=400,
                mimetype='application/json')

    status = 200
    meetings = []
    try:
        if calendar_name:
            if location:
                # print "calendar and region"
                meetings = fedocallib.get_meetings_by_date_and_location(
                    SESSION, calendar_name, startd, endd, location)
            else:
                # print "calendar and no region"
                meetings = fedocallib.get_by_date(
                    SESSION, calendarobj, startd, endd)
        else:
            meetings = []
            if location:
                # print "no calendar and region"
                meetings.extend(
                    fedocallib.get_by_date_at_location(
                        SESSION, location, startd, endd)
                )
            else:
                # print "no calendar and no region"
                for calendar in fedocallib.get_calendars(SESSION):
                    meetings.extend(fedocallib.get_by_date(
                        SESSION, calendar, startd, endd))
    except SQLAlchemyError as err:  # pragma: no cover
        status = 500
        LOG.debug('Error in api_meetings')
        LOG.exception(err)

    output = {}
    output['arguments'] = {
        'start': startd.strftime('%Y-%m-%d'),
        'end': endd.strftime('%Y-%m-%d'),
        'calendar': calendar_name,
        'location': location,
    }

    meetings_json = []
    for meeting in meetings:
        meetings_json.append(meeting.to_json())
    output['meetings'] = meetings_json

    return flask.Response(
        response=json.dumps(output),
        status=status,
        mimetype='application/json'
    )
Example #22
0
def edit_meeting(meeting_id):
    """ Edit a specific meeting based on the meeting identifier.

    :arg meeting_id: the identifier of the meeting to edit.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for('index'))
    meeting = Meeting.by_id(SESSION, meeting_id)
    calendarobj = Calendar.by_id(SESSION, meeting.calendar_name)

    if calendarobj.calendar_status != 'Enabled':
        flask.flash('This calendar is "%s", you are not allowed to edit its '
                    'meetings anymore.' % calendarobj.calendar_status,
                    'errors')
        return flask.redirect(flask.url_for('calendar',
                              calendar_name=calendar_name))

    if not (is_meeting_manager(meeting)
            or is_calendar_admin(calendarobj)
            or is_admin()):
        flask.flash('You are not one of the manager of this meeting, '
                    'or an admin, you are not allowed to edit it.',
                    'errors')
        return flask.redirect(flask.url_for('view_meeting',
                                            meeting_id=meeting_id))

    tzone = get_timezone()
    form = forms.AddMeetingForm(timezone=tzone)
    # pylint: disable=E1101
    if form.validate_on_submit():
        tzone = form.meeting_timezone.data or tzone
        try:
            fedocallib.edit_meeting(
                session=SESSION,
                meeting=meeting,
                calendarobj=calendarobj,
                fas_user=flask.g.fas_user,
                meeting_name=form.meeting_name.data,
                meeting_date=form.meeting_date.data,
                meeting_date_end=None,
                meeting_time_start=form.meeting_time_start.data,
                meeting_time_stop=form.meeting_time_stop.data,
                comanager=form.comanager.data,
                meeting_information=form.information.data,
                meeting_region=form.meeting_region.data,
                tzone=tzone,
                recursion_frequency=form.frequency.data,
                recursion_ends=form.end_repeats.data,
                remind_when=form.remind_when.data,
                remind_who=form.remind_who.data,
                full_day=form.full_day.data,
                edit_all_meeting=form.recursive_edit.data,
                admin=is_admin())
        except FedocalException, err:
            flask.flash(err, 'warnings')
            return flask.render_template(
                'edit_meeting.html', meeting=meeting, calendar=calendarobj,
                form=form, tzone=tzone)
        except SQLAlchemyError, err:
            SESSION.rollback()
            print 'edit_meeting:', err
            flask.flash('Could not update this meeting.', 'errors')
            return flask.render_template(
                'edit_meeting.html', meeting=meeting,
                calendar=calendarobj, form=form, tzone=tzone)
Example #23
0
def get_calendars(session):
    """ Retrieve the list of Calendar from the database. """
    return Calendar.get_all(session)
Example #24
0
def api_user_shield(username, calendar_name):
    """
User shield
===========

Provides a small image (a shield) displaying the status of the specified
user on the specified calendar if the user is currently managing a meeting.

Filter arguments
----------------

``connector``
  Changes the 'connector' text used in the image.

  Default: 'in'

``status``
  Changes the 'status' text used in the image.

  Default: the name of the calendar checked

``always``
  Booleans to specify whether to return an image if no meeting is found for
  the specified user on the specified calendar.

  Default: True
  Can be:  False, 0, f

If the user is not managing a meeting, instead of returning the image the
endpoint raises a 404.

    """
    connector = flask.request.args.get('connector', 'in')
    status = flask.request.args.get('status', calendar_name)
    always = flask.request.args.get('always', True)

    if str(always).lower() in ['0', 'false', 'f']:
        always = False
    else:
        always = True

    calendarobj = Calendar.by_id(SESSION, calendar_name)
    if not calendarobj:
        flask.abort(400, 'Invalid calendar provided')

    start_date = datetime.datetime.utcnow().date()
    end_date = start_date + datetime.timedelta(days=1)

    meetings = fedocallib.get_by_date(
        SESSION, calendarobj, start_date, end_date, tzone='UTC')

    green, red = 'brightgreen', 'red'

    ## We *would* use the canonical b.repl.ca url, but it doesn't support SSL
    ## the way that we need currently.  So, instead we'll use the backend name
    ## to get around that.
    #template = 'http://b.repl.ca/v1/%s-%s_%s-%s.png'
    template = 'https://buckler-bowes.rhcloud.com/v1/%s-%s_%s-%s.png'

    output = None
    for meeting in meetings:
        usernames = [user.username for user in meeting.meeting_manager_user]
        if username in usernames:
            output = template % (username, connector, status, green)
            break

    if output:
        return flask.redirect(output)
    elif always:
        output = template % (username, "not " + connector, status, red)
        return flask.redirect(output)
    else:
        flask.abort(404)
Example #25
0
def add_meeting(calendar_name):
    """ Add a meeting to the database.
    This function is only available to CLA+1 member or members of the
    group administrating of the said calendar.

    :arg calendar_name, name of the calendar in which to add the meeting.
    """
    if not flask.g.fas_user:
        return flask.redirect(flask.url_for('index'))
    calendarobj = Calendar.by_id(SESSION, calendar_name)

    if calendarobj.calendar_status != 'Enabled':
        flask.flash('This calendar is "%s", you are not allowed to add '
                    'meetings anymore.' % calendarobj.calendar_status,
                    'errors')
        return flask.redirect(flask.url_for('calendar',
                              calendar_name=calendar_name))

    if calendarobj.calendar_editor_group and \
       not (is_calendar_manager(calendarobj)
            or is_calendar_admin(calendarobj)
            or is_admin()):
        flask.flash('You are not one of the editors of this calendar, '
                    'or one of its admins, you are not allowed to add '
                    'new meetings.', 'errors')
        return flask.redirect(flask.url_for('calendar',
                                            calendar_name=calendar_name))

    tzone = get_timezone()
    form = forms.AddMeetingForm(timezone=tzone)
    calendarobj = Calendar.by_id(SESSION, calendar_name)
    # pylint: disable=E1101
    if form.validate_on_submit():
        tzone = form.meeting_timezone.data or tzone
        try:
            meeting = fedocallib.add_meeting(
                session=SESSION,
                calendarobj=calendarobj,
                fas_user=flask.g.fas_user,
                meeting_name=form.meeting_name.data,
                meeting_date=form.meeting_date.data,
                meeting_date_end=form.meeting_date_end.data,
                meeting_time_start=form.meeting_time_start.data,
                meeting_time_stop=form.meeting_time_stop.data,
                comanager=form.comanager.data,
                meeting_information=form.information.data,
                meeting_region=form.meeting_region.data,
                tzone=tzone,
                frequency=form.frequency.data,
                end_repeats=form.end_repeats.data,
                remind_when=form.remind_when.data,
                remind_who=form.remind_who.data,
                full_day=form.full_day.data,
                admin=is_admin())
        except FedocalException, err:
            flask.flash(err, 'warnings')
            return flask.render_template(
                'add_meeting.html', calendar=calendarobj, form=form,
                tzone=tzone)
        except SQLAlchemyError, err:
            SESSION.rollback()
            print 'add_meeting:', err
            flask.flash('Could not add this meeting to this calendar',
                        'errors')
            return flask.render_template(
                'add_meeting.html', calendar=calendarobj, form=form,
                tzone=tzone)