Exemplo n.º 1
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)
Exemplo n.º 2
0
Arquivo: api.py Projeto: 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)
    def test_delete_recurring_meeting(self):
        """ Test deleting a recurring meeting in the middle of the
        recursion.
        """
        # Setup info
        self.__setup_calendar()
        obj = model.Meeting(  # id:1
            meeting_name='test recurring',
            meeting_date=datetime(2014, 9, 1).date(),
            meeting_date_end=datetime(2014, 9, 1).date(),
            meeting_time_start=time(9, 0),
            meeting_time_stop=time(10, 0),
            meeting_information='This is a test meeting recurring',
            calendar_name='test_calendar',
            recursion_frequency=7,
            recursion_ends=datetime(2014, 10, 27).date(),
        )
        obj.add_manager(self.session, 'pingou')
        obj.save(self.session)
        self.session.commit()
        self.assertNotEqual(obj, None)

        # Before deletion
        calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
        meetings = fedocallib.get_by_date(self.session, calendarobj,
                                          datetime(2014, 9, 1).date(),
                                          datetime(2014, 10, 27).date())
        self.assertEqual(len(meetings), 9)
        ids = set([mtg.meeting_id for mtg in meetings])
        self.assertEqual(len(ids), 1)
        self.assertEqual(list(ids)[0], 1)
        dates = [str(mtg.meeting_date) for mtg in meetings]
        self.assertEqual(dates, [
            '2014-09-01',
            '2014-09-08',
            '2014-09-15',
            '2014-09-22',
            '2014-09-29',
            '2014-10-06',
            '2014-10-13',
            '2014-10-20',
            '2014-10-27',
        ])

        # Delete meeting in the middle
        meeting = model.Meeting.by_id(self.session, 1)
        fedocallib.delete_recursive_meeting(self.session,
                                            meeting=meeting,
                                            del_date=datetime(2014, 10,
                                                              20).date(),
                                            all_meetings=False)

        # After deletion
        meetings = fedocallib.get_by_date(self.session, calendarobj,
                                          datetime(2014, 9, 1).date(),
                                          datetime(2014, 10, 27).date())
        self.assertEqual(len(meetings), 8)
        self.assertEqual(len(ids), 1)
        self.assertEqual(list(ids)[0], 1)
        dates = [str(mtg.meeting_date) for mtg in meetings]
        self.assertEqual(dates, [
            '2014-09-01',
            '2014-09-08',
            '2014-09-15',
            '2014-09-22',
            '2014-09-29',
            '2014-10-06',
            '2014-10-13',
            '2014-10-27',
        ])

        # Delete meeting after the end of the recursion
        meeting = model.Meeting.by_id(self.session, 1)
        fedocallib.delete_recursive_meeting(self.session,
                                            meeting=meeting,
                                            del_date=datetime(2015, 10,
                                                              20).date(),
                                            all_meetings=False)

        # After deletion
        meetings = fedocallib.get_by_date(self.session, calendarobj,
                                          datetime(2014, 9, 1).date(),
                                          datetime(2015, 10, 27).date())
        self.assertEqual(len(meetings), 8)
        self.assertEqual(len(ids), 1)
        self.assertEqual(list(ids)[0], 1)
        dates = [str(mtg.meeting_date) for mtg in meetings]
        self.assertEqual(dates, [
            '2014-09-01',
            '2014-09-08',
            '2014-09-15',
            '2014-09-22',
            '2014-09-29',
            '2014-10-06',
            '2014-10-13',
            '2014-10-27',
        ])

        # Delete meeting before the start of the recursion
        # This will delete the first occurrence of the meeting as it is the
        # first one after the date specified.
        meeting = model.Meeting.by_id(self.session, 1)
        fedocallib.delete_recursive_meeting(self.session,
                                            meeting=meeting,
                                            del_date=datetime(2014, 8,
                                                              18).date(),
                                            all_meetings=False)

        # After deletion
        meetings = fedocallib.get_by_date(self.session, calendarobj,
                                          datetime(2014, 8, 1).date(),
                                          datetime(2015, 10, 27).date())
        self.assertEqual(len(meetings), 7)
        self.assertEqual(len(ids), 1)
        self.assertEqual(list(ids)[0], 1)
        dates = [str(mtg.meeting_date) for mtg in meetings]
        self.assertEqual(dates, [
            '2014-09-08',
            '2014-09-15',
            '2014-09-22',
            '2014-09-29',
            '2014-10-06',
            '2014-10-13',
            '2014-10-27',
        ])
    def test_editing_recurring_meeting_one_day_earlier(self):
        """ Test editing moving a meeting one day earlier in a recursion
        """
        # Setup info
        self.__setup_calendar()
        obj = model.Meeting(  # id:1
            meeting_name='test recurring',
            meeting_date=datetime(2014, 9, 1).date(),
            meeting_date_end=datetime(2014, 9, 1).date(),
            meeting_time_start=time(9, 0),
            meeting_time_stop=time(10, 0),
            meeting_information='This is a test meeting recurring',
            calendar_name='test_calendar',
            recursion_frequency=7,
            recursion_ends=datetime(2014, 10, 27).date(),
        )
        obj.add_manager(self.session, 'pingou')
        obj.save(self.session)
        self.session.commit()
        self.assertNotEqual(obj, None)

        # Before edition
        calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
        meetings = fedocallib.get_by_date(self.session, calendarobj,
                                          datetime(2014, 9, 1).date(),
                                          datetime(2014, 10, 27).date())
        self.assertEqual(len(meetings), 9)
        ids = set([mtg.meeting_id for mtg in meetings])
        self.assertEqual(list(ids)[0], 1)
        dates = [str(mtg.meeting_date) for mtg in meetings]
        self.assertEqual(dates, [
            '2014-09-01',
            '2014-09-08',
            '2014-09-15',
            '2014-09-22',
            '2014-09-29',
            '2014-10-06',
            '2014-10-13',
            '2014-10-20',
            '2014-10-27',
        ])

        # Edit meeting in the middle to move it by one day
        meeting = model.Meeting.by_id(self.session, 1)
        fedocallib.edit_meeting(
            session=self.session,
            meeting=meeting,
            calendarobj=calendarobj,
            fas_user=FakeUser(groups=['fi-apprentice'], username='******'),
            meeting_name='test recurring',
            meeting_date=datetime(2014, 9, 14).date(),
            meeting_date_end=datetime(2014, 9, 14).date(),
            meeting_time_start=time(9, 0),
            meeting_time_stop=time(10, 0),
            comanager='pingou',
            meeting_information='This is a test meeting recurring',
            meeting_location=None,
            tzone='UTC',
            recursion_frequency=7,
            recursion_ends=datetime(2014, 10, 27).date(),
            remind_when=None,
            reminder_from=None,
            remind_who=None,
            full_day=False,
            edit_all_meeting=False,
            admin=False)

        # After edition
        calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
        meetings = fedocallib.get_by_date(self.session, calendarobj,
                                          datetime(2014, 9, 1).date(),
                                          datetime(2014, 10, 27).date())
        #self.assertEqual(len(meetings), 9)
        ids = set([mtg.meeting_id for mtg in meetings])
        #self.assertEqual(list(ids), [1, 2, 3])
        dates = [str(mtg.meeting_date) for mtg in meetings]
        # One meeting moved by 1 day
        self.assertEqual(sorted(dates), [
            '2014-09-01',
            '2014-09-08',
            '2014-09-14',
            '2014-09-22',
            '2014-09-29',
            '2014-10-06',
            '2014-10-13',
            '2014-10-20',
            '2014-10-27',
        ])

        # Edit meeting in the middle to move it by 3 days (earlier)
        meeting = model.Meeting.by_id(self.session, 3)
        fedocallib.edit_meeting(
            session=self.session,
            meeting=meeting,
            calendarobj=calendarobj,
            fas_user=FakeUser(groups=['fi-apprentice'], username='******'),
            meeting_name='test recurring',
            meeting_date=datetime(2014, 9, 26).date(),
            meeting_date_end=datetime(2014, 9, 26).date(),
            meeting_time_start=time(9, 0),
            meeting_time_stop=time(10, 0),
            comanager='pingou',
            meeting_information='This is a test meeting recurring',
            meeting_location=None,
            tzone='UTC',
            recursion_frequency=7,
            recursion_ends=datetime(2014, 10, 27).date(),
            remind_when=None,
            reminder_from=None,
            remind_who=None,
            full_day=False,
            edit_all_meeting=False,
            admin=False)

        # After edition
        calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
        meetings = fedocallib.get_by_date(self.session, calendarobj,
                                          datetime(2014, 9, 1).date(),
                                          datetime(2014, 10, 27).date())
        self.assertEqual(len(meetings), 9)
        ids = set([mtg.meeting_id for mtg in meetings])
        self.assertEqual(list(ids), [1, 2, 3, 4, 5])
        dates = [str(mtg.meeting_date) for mtg in meetings]
        # One meeting moved by 3 day
        self.assertEqual(sorted(dates), [
            '2014-09-01',
            '2014-09-08',
            '2014-09-14',
            '2014-09-22',
            '2014-09-26',
            '2014-10-06',
            '2014-10-13',
            '2014-10-20',
            '2014-10-27',
        ])
Exemplo n.º 5
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)
Exemplo n.º 6
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'
    )
Exemplo n.º 7
0
    def test_delete_recurring_meeting(self):
        """ Test deleting a recurring meeting in the middle of the
        recursion.
        """
        # Setup info
        self.__setup_calendar()
        obj = model.Meeting(  # id:1
            meeting_name='test recurring',
            meeting_date=datetime(2014, 9, 1).date(),
            meeting_date_end=datetime(2014, 9, 1).date(),
            meeting_time_start=time(9, 0),
            meeting_time_stop=time(10, 0),
            meeting_information='This is a test meeting recurring',
            calendar_name='test_calendar',
            recursion_frequency=7,
            recursion_ends=datetime(2014, 10, 27).date(),
        )
        obj.add_manager(self.session, 'pingou')
        obj.save(self.session)
        self.session.commit()
        self.assertNotEqual(obj, None)

        # Before deletion
        calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
        meetings = fedocallib.get_by_date(
            self.session, calendarobj,
            datetime(2014, 9, 1).date(),
            datetime(2014, 10, 27).date()
        )
        self.assertEqual(len(meetings), 9)
        ids = set([mtg.meeting_id for mtg in meetings])
        self.assertEqual(len(ids), 1)
        self.assertEqual(list(ids)[0], 1)
        dates = [str(mtg.meeting_date) for mtg in meetings]
        self.assertEqual(
            dates,
            [
                '2014-09-01', '2014-09-08', '2014-09-15', '2014-09-22',
                '2014-09-29', '2014-10-06', '2014-10-13', '2014-10-20',
                '2014-10-27',
            ]
        )

        # Delete meeting in the middle
        meeting = model.Meeting.by_id(self.session, 1)
        fedocallib.delete_recursive_meeting(
            self.session,
            meeting=meeting,
            del_date=datetime(2014, 10, 20).date(),
            all_meetings=False)

        # After deletion
        meetings = fedocallib.get_by_date(
            self.session, calendarobj,
            datetime(2014, 9, 1).date(),
            datetime(2014, 10, 27).date()
        )
        self.assertEqual(len(meetings), 8)
        self.assertEqual(len(ids), 1)
        self.assertEqual(list(ids)[0], 1)
        dates = [str(mtg.meeting_date) for mtg in meetings]
        self.assertEqual(
            dates,
            [
                '2014-09-01', '2014-09-08', '2014-09-15', '2014-09-22',
                '2014-09-29', '2014-10-06', '2014-10-13',
                '2014-10-27',
            ]
        )

        # Delete meeting after the end of the recursion
        meeting = model.Meeting.by_id(self.session, 1)
        fedocallib.delete_recursive_meeting(
            self.session,
            meeting=meeting,
            del_date=datetime(2015, 10, 20).date(),
            all_meetings=False)

        # After deletion
        meetings = fedocallib.get_by_date(
            self.session, calendarobj,
            datetime(2014, 9, 1).date(),
            datetime(2015, 10, 27).date()
        )
        self.assertEqual(len(meetings), 8)
        self.assertEqual(len(ids), 1)
        self.assertEqual(list(ids)[0], 1)
        dates = [str(mtg.meeting_date) for mtg in meetings]
        self.assertEqual(
            dates,
            [
                '2014-09-01', '2014-09-08', '2014-09-15', '2014-09-22',
                '2014-09-29', '2014-10-06', '2014-10-13',
                '2014-10-27',
            ]
        )

        # Delete meeting before the start of the recursion
        # This will delete the first occurrence of the meeting as it is the
        # first one after the date specified.
        meeting = model.Meeting.by_id(self.session, 1)
        fedocallib.delete_recursive_meeting(
            self.session,
            meeting=meeting,
            del_date=datetime(2014, 8, 18).date(),
            all_meetings=False)

        # After deletion
        meetings = fedocallib.get_by_date(
            self.session, calendarobj,
            datetime(2014, 8, 1).date(),
            datetime(2015, 10, 27).date()
        )
        self.assertEqual(len(meetings), 7)
        self.assertEqual(len(ids), 1)
        self.assertEqual(list(ids)[0], 1)
        dates = [str(mtg.meeting_date) for mtg in meetings]
        self.assertEqual(
            dates,
            [
                '2014-09-08', '2014-09-15', '2014-09-22',
                '2014-09-29', '2014-10-06', '2014-10-13',
                '2014-10-27',
            ]
        )
Exemplo n.º 8
0
    def test_editing_recurring_meeting_one_day_earlier(self):
        """ Test editing moving a meeting one day earlier in a recursion
        """
        # Setup info
        self.__setup_calendar()
        obj = model.Meeting(  # id:1
            meeting_name='test recurring',
            meeting_date=datetime(2014, 9, 1).date(),
            meeting_date_end=datetime(2014, 9, 1).date(),
            meeting_time_start=time(9, 0),
            meeting_time_stop=time(10, 0),
            meeting_information='This is a test meeting recurring',
            calendar_name='test_calendar',
            recursion_frequency=7,
            recursion_ends=datetime(2014, 10, 27).date(),
        )
        obj.add_manager(self.session, 'pingou')
        obj.save(self.session)
        self.session.commit()
        self.assertNotEqual(obj, None)

        # Before edition
        calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
        meetings = fedocallib.get_by_date(
            self.session, calendarobj,
            datetime(2014, 9, 1).date(),
            datetime(2014, 10, 27).date()
        )
        self.assertEqual(len(meetings), 9)
        ids = set([mtg.meeting_id for mtg in meetings])
        self.assertEqual(list(ids)[0], 1)
        dates = [str(mtg.meeting_date) for mtg in meetings]
        self.assertEqual(
            dates,
            [
                '2014-09-01', '2014-09-08', '2014-09-15', '2014-09-22',
                '2014-09-29', '2014-10-06', '2014-10-13', '2014-10-20',
                '2014-10-27',
            ]
        )

        # Edit meeting in the middle to move it by one day
        meeting = model.Meeting.by_id(self.session, 1)
        fedocallib.edit_meeting(
            session=self.session,
            meeting=meeting,
            calendarobj=calendarobj,
            fas_user=FakeUser(groups=['fi-apprentice'], username='******'),
            meeting_name='test recurring',
            meeting_date=datetime(2014, 9, 14).date(),
            meeting_date_end=datetime(2014, 9, 14).date(),
            meeting_time_start=time(9, 0),
            meeting_time_stop=time(10, 0),
            comanager='pingou',
            meeting_information='This is a test meeting recurring',
            meeting_location=None,
            tzone='UTC',
            recursion_frequency=7,
            recursion_ends=datetime(2014, 10, 27).date(),
            remind_when=None,
            reminder_from=None,
            remind_who=None,
            full_day=False,
            edit_all_meeting=False,
            admin=False
        )

        # After edition
        calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
        meetings = fedocallib.get_by_date(
            self.session, calendarobj,
            datetime(2014, 9, 1).date(),
            datetime(2014, 10, 27).date()
        )
        #self.assertEqual(len(meetings), 9)
        ids = set([mtg.meeting_id for mtg in meetings])
        #self.assertEqual(list(ids), [1, 2, 3])
        dates = [str(mtg.meeting_date) for mtg in meetings]
        # One meeting moved by 1 day
        self.assertEqual(
            sorted(dates),
            [
                '2014-09-01', '2014-09-08', '2014-09-14', '2014-09-22',
                '2014-09-29', '2014-10-06', '2014-10-13', '2014-10-20',
                '2014-10-27',
            ]
        )

        # Edit meeting in the middle to move it by 3 days (earlier)
        meeting = model.Meeting.by_id(self.session, 3)
        fedocallib.edit_meeting(
            session=self.session,
            meeting=meeting,
            calendarobj=calendarobj,
            fas_user=FakeUser(groups=['fi-apprentice'], username='******'),
            meeting_name='test recurring',
            meeting_date=datetime(2014, 9, 26).date(),
            meeting_date_end=datetime(2014, 9, 26).date(),
            meeting_time_start=time(9, 0),
            meeting_time_stop=time(10, 0),
            comanager='pingou',
            meeting_information='This is a test meeting recurring',
            meeting_location=None,
            tzone='UTC',
            recursion_frequency=7,
            recursion_ends=datetime(2014, 10, 27).date(),
            remind_when=None,
            reminder_from=None,
            remind_who=None,
            full_day=False,
            edit_all_meeting=False,
            admin=False
        )

        # After edition
        calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
        meetings = fedocallib.get_by_date(
            self.session, calendarobj,
            datetime(2014, 9, 1).date(),
            datetime(2014, 10, 27).date()
        )
        self.assertEqual(len(meetings), 9)
        ids = set([mtg.meeting_id for mtg in meetings])
        self.assertEqual(list(ids), [1, 2, 3, 4, 5])
        dates = [str(mtg.meeting_date) for mtg in meetings]
        # One meeting moved by 3 day
        self.assertEqual(
            sorted(dates),
            [
                '2014-09-01', '2014-09-08', '2014-09-14', '2014-09-22',
                '2014-09-26', '2014-10-06', '2014-10-13', '2014-10-20',
                '2014-10-27',
            ]
        )
Exemplo n.º 9
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)