Exemple #1
0
    def get_full_day_meetings(self):
        """ Retrieve all the full day meetings of this week. """
        self.full_day_meetings = Meeting.get_by_date(
            self.session, self.calendar, self.start_date, self.stop_date, full_day=True
        )

        for meeting in Meeting.get_active_regular_meeting(
            self.session, self.calendar, self.start_date, self.stop_date, full_day=True
        ):
            for delta in range(0, 7):
                day = self.start_date + timedelta(days=delta)
                if ((meeting.meeting_date - day).days % meeting.recursion_frequency) == 0:
                    if meeting not in self.full_day_meetings:
                        self.full_day_meetings.append(meeting)
Exemple #2
0
    def get_meetings(self):
        """ Retrieves the list of this week meeting from the database.
        """
        self.meetings = Meeting.get_by_date(self.session, self.calendar, self.start_date, self.stop_date)

        self.meetings.extend(
            Meeting.get_by_date(self.session, self.calendar, self.start_date, self.stop_date, full_day=True)
        )

        for meeting in Meeting.get_active_regular_meeting(self.session, self.calendar, self.start_date, self.stop_date):
            for delta in range(0, 7):
                day = self.start_date + timedelta(days=delta)
                if ((meeting.meeting_date - day).days % meeting.recursion_frequency) == 0:
                    if meeting not in self.meetings:
                        self.meetings.append(meeting)
Exemple #3
0
def update_attended_staff(meeting: Meeting, staff: Staff):
    """
    Updates the Database with staff members who have attended the meeting
    """
    if staff.id not in meeting.attended_staff:
        meeting.attended_staff.append(staff.id)
        db.update_meeting(meeting.id, meeting.to_json_dict())
Exemple #4
0
def test_parse_and_convert_modified_meeting():
    original_dict = db.get_all_meetings()[0]
    parsed_object = Meeting.parse(original_dict)  # Type: Meeting
    parsed_object.started = not parsed_object.started
    original_dict["started"] = not original_dict["started"]
    parsed_dict = parsed_object.to_json_dict()
    assert original_dict == parsed_dict
def load_meetings():
    """Load meetings from source CSV into database."""

    print "Importing meetings..."

    # Delete all rows in table, so if we need to run this a second time,
    # we won't be trying to add duplicate retailers
    Meeting.query.delete()

    # Read CSV file
    with open("seed_data/meetings.csv") as source_file:
        example_data = list(csv.reader(source_file))

    # skip header row for populating db
    for list_item in example_data[1:]:
        meeting = Meeting(meeting_title=list_item[1],
                          meeting_time=list_item[2],
                          attendees=list_item[3],
                          length=list_item[4],
                          topic_id=list_item[5])

        # Add the current retailer to the session
        db.session.add(meeting)

    # Commit the db.session changes to the database
    db.session.commit()
def test_get_role_none():
    meeting = Meeting.parse(db.get_meeting(mid))
    all_staff_ids = set([staff["_id"] for staff in db.get_all_staff()])
    non_participants = all_staff_ids.difference(set(meeting.staff))
    staff = Staff.parse(db.get_staff(non_participants.pop()))
    roles = get_role(staff, meeting)
    assert (len(roles) == 0)
Exemple #7
0
def agenda_is_free(
        session, calendarobj,
        meeting_date,
        meeting_date_end):
    """Check if there is already someting planned in this agenda at that
    time on that day.

    :arg session: the database session to use
    :arg calendar: the name of the calendar of interest.
    :arg meeting_date: the date of the meeting (as Datetime object)
    :arg meeting_date_end: the end date of the meeting (as Datetime
        object)
    :arg time_start: the time at which the meeting starts (as int)
    :arg time_stop: the time at which the meeting stops (as int)
    """
    meetings = Meeting.get_overlaping_meetings(
        session, calendarobj,
        meeting_date.date(),
        meeting_date_end.date())
    agenda_free = True

    for meeting in set(meetings):
        meeting_start_date_time = datetime(
            meeting.meeting_date.year,
            meeting.meeting_date.month,
            meeting.meeting_date.day,
            meeting.meeting_time_start.hour,
            meeting.meeting_time_start.minute,
            tzinfo=pytz.utc)

        meeting_stop_date_time = datetime(
            meeting.meeting_date_end.year,
            meeting.meeting_date_end.month,
            meeting.meeting_date_end.day,
            meeting.meeting_time_stop.hour,
            meeting.meeting_time_stop.minute,
            tzinfo=pytz.utc)

        if meeting_date <= meeting_start_date_time \
                and meeting_date_end > meeting_start_date_time:
            agenda_free = False
        elif meeting_date < meeting_stop_date_time \
                and meeting_date_end >= meeting_stop_date_time:
            agenda_free = False
        elif meeting_date < meeting_start_date_time \
                and meeting_date_end > meeting_stop_date_time:
            agenda_free = False
        elif meeting_date > meeting_start_date_time \
                and meeting_date_end < meeting_stop_date_time:
            agenda_free = False
        elif meeting_date == meeting_start_date_time \
                and meeting_date_end == meeting_stop_date_time:
            agenda_free = False

    return agenda_free
Exemple #8
0
def get_past_meeting_of_user(
        session, username, tzone='UTC', from_date=date.today()):
    """ Return all past meeting which specified username is among the
    managers.
    :arg session: the database session to use
    :arg username: the FAS user name that you would like to have the
        past meetings for.
    :kwarg tzone: the time-zone to which to convert the meetings.
        Defaults to 'UTC'.
    :kwarg from_date: the date from which the futur meetings should be
        retrieved. Defaults to today
    """
    meetings_tmp = Meeting.expand_regular_meetings(
        Meeting.get_past_meeting_of_user(session, username, from_date),
        end_date=from_date)
    meetings = []
    for meeting in meetings_tmp:
        meetings.append(convert_meeting_timezone(meeting, 'UTC', tzone))
    meetings.sort(key=operator.attrgetter('meeting_date'))
    return meetings
def test_meeting_contract_deployment():
    mch = MeetingContractHelper(c)
    meeting = Meeting.parse(db.get_all_meetings()[0])
    contract_addr = mch.new_meeting_contract(meeting)

    mdt_meeting = w3.eth.contract(
        address=contract_addr,
        abi=mch.contract_abi,
    )

    assert mdt_meeting.functions.getMeetingId().call() == meeting.id
Exemple #10
0
def get_by_date(session, calendarobj, start_date, end_date, tzone='UTC'):
    """ Returns all the meetings in a given time period.
    Recursive meetings are expanded as if each was a single meeting.

    :arg session: the database session to use
    :arg calendarobj: the calendar (object) of interest.
    :arg start_date: a Date object representing the beginning of the
        period
    :arg start_date: a Date object representing the ending of the period
    :kwarg tzone: the timezone in which the meetings should be displayed
        defaults to UTC.
    """
    meetings_utc = Meeting.get_by_date(session, calendarobj, start_date,
                                       end_date, no_recursive=True)
    meetings_utc.extend(Meeting.get_regular_meeting_by_date(session,
                        calendarobj, start_date, end_date))
    meetings = []
    for meeting in list(set(meetings_utc)):
        meetings.append(convert_meeting_timezone(
            meeting, 'UTC', tzone))
    meetings.sort(key=operator.attrgetter('meeting_date'))
    return meetings
Exemple #11
0
    def get_meetings(self):
        """ Retrieves the list of this week's meeting from the database.
        """
        self.meetings = Meeting.get_by_date(
            self.session, self.calendar, self.start_date, self.stop_date)

        for meeting in Meeting.get_active_regular_meeting(
                self.session, self.calendar,
                self.start_date, self.stop_date):
            for delta in range(0, 7):
                day = self.start_date + timedelta(days=delta)
                if ((meeting.meeting_date - day).days %
                        meeting.recursion_frequency) == 0:
                    if meeting not in self.meetings:
                        self.meetings.append(meeting)
        # Expand the regular meetings so that they appear as meeting
        self.meetings = Meeting.expand_regular_meetings(
            self.meetings, end_date=self.stop_date,
            start_date=self.start_date)
        # Sort the meetings by date, time_start and name
        self.meetings.sort(key=operator.attrgetter(
            'meeting_date', 'meeting_time_start', 'meeting_name'))
Exemple #12
0
def load_meetings():
    """Load meetings into db"""

    print("Meetings")

    #Delete row to avoid duplicates
    Meeting.query.delete()

    meeting_rows = csv.DictReader(open('data/meetings.csv'))

    for meeting in meeting_rows:
        new_meeting = Meeting(month=meeting["month"], year=meeting["year"])
        db.session.add(new_meeting)
    db.session.commit()
def test_meeting_contract_set_hash():
    mch = MeetingContractHelper(c)
    meeting = Meeting.parse(db.get_all_meetings()[0])
    contract_addr = mch.new_meeting_contract(meeting)
    meeting.contract_id = contract_addr
    mch.set_event_hash(meeting, "start_event", "end_event")

    mdt_meeting = w3.eth.contract(
        address=contract_addr,
        abi=mch.contract_abi,
    )

    assert mdt_meeting.functions.getEvents().call() == [
        "start_event", "end_event"
    ]
Exemple #14
0
def get_meetings_by_date_and_region(
        session, calendar, start_date, end_date, region):
    """ 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 region: the region in which the meetings should occur.
    """
    calendar = Calendar.by_id(session, calendar)
    return Meeting.get_by_date_and_region(session, calendar, start_date,
                                          end_date, region)
Exemple #15
0
def get_future_regular_meeting_of_user(
        session, username, tzone='UTC', from_date=date.today()):
    """ Return all future recursive meeting which specified username is
    among the managers.

    :arg session: the database session to use.
    :arg username: the FAS user name that you would like to have the
        past meetings for.
    :kwarg tzone: the time-zone to which to convert the meetings.
        Defaults to 'UTC'.
    :kwarg from_date: the date from which the futur meetings should be
        retrieved. Defaults to today.
    """
    meetings_tmp = Meeting.get_future_regular_meeting_of_user(
        session, username, from_date)
    meetings = []
    for meeting in meetings_tmp:
        meetings.append(convert_meeting_timezone(meeting, 'UTC', tzone))
    return meetings
Exemple #16
0
def retrieve_meeting_to_remind(session, offset=30):
    """ Retrieve all the meetings for which we have to send a reminder.

    :arg session: the database session to use.
    :kwarg offset: the frequency at which the cron job is ran in order
        to avoid sending twice the same reminder.
    """
    today = datetime.utcnow()
    meetings = []

    for reminder_time in [12, 24, 48, 168]:
    # Retrieve meeting planned in less than X hours
        new_date = _generate_date_rounded_to_the_hour(today,
                                                      reminder_time)
        end_date = new_date + timedelta(minutes=offset)
        meetings.extend(Meeting.get_meeting_with_reminder(
            session, new_date.date(), new_date.time(), end_date.time(),
            'H-%s' % reminder_time))

    return meetings
Exemple #17
0
def room_message(event_string):
    """
    Main function that handles all events that enter through the web socket
    """
    # Parse json as dict
    try:
        event_json = json.loads(event_string)
    except ValueError as ve:
        log.error("Error Parsing room-message as JSON!")
        log.error(ve)
        traceback.print_tb(ve.__traceback__)
        return json.dumps(
            sign(
                get_error_ack(
                    "unknown",
                    "unknown",
                    content=AckErrorContent(
                        error_code=EventError.MALFORMED_EVENT,
                        details='Cant parse message as JSON'))).to_json_dict())

    # Validate JSON dict using schema
    ok, err_event = validate_schema(event_json)
    if not ok:
        log.error("Sending error msg")
        errormsg = json.dumps(sign(err_event).to_json_dict())
        log.error("======== error_msg: " + errormsg)
        return errormsg

    # Parse dict as event object
    try:
        event = Event.parse(event_json)
    except KeyError as ve:
        log.error("Error Parsing room-message!")
        log.error(ve)
        traceback.print_tb(ve.__traceback__)
        return json.dumps(
            sign(
                get_error_ack("unknown",
                              "unknown",
                              content=AckErrorContent(
                                  error_code=EventError.MALFORMED_EVENT,
                                  details='Cant parse message as Event'))).
            to_json_dict())

    # Check timestamp
    ok, err_event = validate_timestamp(event)
    if not ok:
        return json.dumps(sign(err_event).to_json_dict())

    # Get the staff
    try:
        staff = Staff.parse(db.get_staff(event.by))
    except KeyError as ke:
        log.error(ke)
        traceback.print_tb(ke.__traceback__)
        return json.dumps(
            sign(
                get_error_ack(event.id,
                              event.meeting_id,
                              content=AckErrorContent(
                                  error_code=EventError.STAFF_NOT_FOUND,
                                  details=''))).to_json_dict())
    except TypeError as te:
        log.error(te)
        traceback.print_tb(te.__traceback__)
        return json.dumps(
            sign(
                get_error_ack(event.id,
                              event.meeting_id,
                              content=AckErrorContent(
                                  error_code=EventError.STAFF_NOT_FOUND,
                                  details=''))).to_json_dict())

    # Get the meeting
    try:
        meeting = Meeting.parse(db.get_meeting(event.meeting_id))
    except KeyError as ke:
        log.error(ke)
        traceback.print_tb(ke.__traceback__)
        return json.dumps(
            sign(
                get_error_ack(event.id,
                              event.meeting_id,
                              content=AckErrorContent(
                                  error_code=EventError.MEETING_NOT_FOUND,
                                  details=''))).to_json_dict())

    except TypeError as te:
        log.error(te)
        traceback.print_tb(te.__traceback__)
        return json.dumps(
            sign(
                get_error_ack(event.id,
                              event.meeting_id,
                              content=AckErrorContent(
                                  error_code=EventError.MEETING_NOT_FOUND,
                                  details=''))).to_json_dict())

    # Check signature, before trusting anything it says

    if event.type in [MeetingEventType.JOIN, MeetingEventType.START
                      ]:  # We check contract for join and start
        ok, err_event = validate_signature(event,
                                           staff,
                                           meeting,
                                           check_contract=True)
        if not ok:
            return json.dumps(sign(err_event).to_json_dict())
    else:
        ok, err_event = validate_signature(event, staff, meeting)
        if not ok:
            return json.dumps(sign(err_event).to_json_dict())

    # Get the roles
    roles = get_role(staff, meeting)

    # A preliminary authority check to see if the user can make any statements about the meeting
    ok, err_event = validate_preliminary_authority(event, roles)
    if not ok:
        return json.dumps(sign(err_event).to_json_dict())

    # Get the event type
    event_type = MeetingEventType(event.type)
    ack_event = None
    ok = False
    end_meeting = False
    send_privately = False

    if event_type == MeetingEventType.START:
        ok, ack_event = start(event, staff, meeting, roles)

    if event_type == MeetingEventType.JOIN:
        ok, ack_event = join(event, staff, meeting, roles)

    if event_type == MeetingEventType.LEAVE:
        ok, ack_event = leave(event, staff, meeting)

    if event_type == MeetingEventType.POLL:
        ok, ack_event = poll(event, staff, meeting, roles)

    if event_type == MeetingEventType.VOTE:
        ok, ack_event = vote(event, staff, meeting, roles)

    if event_type == MeetingEventType.POLL_END:
        ok, ack_event = end_poll(event, staff, meeting, roles)

    if event_type == MeetingEventType.COMMENT or event_type == MeetingEventType.REPLY or event_type == MeetingEventType.DISAGREEMENT:
        ok, ack_event = comment_reply_disagreement(event, staff, meeting,
                                                   roles)

    if event_type == MeetingEventType.DISCUSSION:
        ok, ack_event = discussion(event, staff, meeting, roles)

    if event_type == MeetingEventType.PATIENT_DATA_CHANGE:
        ok, ack_event = patient_data_change(event, staff, meeting, roles)

    if event_type == MeetingEventType.END:
        ok, ack_event = end(event, staff, meeting, roles)
        if ok:
            end_meeting = True

    if not ok:  # If not ok we send the error ack event privately
        return json.dumps(sign(ack_event).to_json_dict())
    else:
        # If an event has been referenced
        check_and_remove_ref_event(meeting, event.ref_event)

        # Add ack and event to unreferenced events
        add_event_as_unref(meeting, event)
        add_event_as_unref(meeting, ack_event)

        # Sign the ack
        signed_ack_event = sign(ack_event)

        if not send_privately:  # Only Broadcast if the send_privately is set to False
            # Broadcast event
            send(json.dumps(event.to_json_dict()), broadcast_room=meeting.id)
            send(json.dumps(signed_ack_event.to_json_dict()),
                 broadcast_room=meeting.id)

        record(event, meeting)
        record(signed_ack_event, meeting)

        if end_meeting:
            end_meeting_session(meeting, event, signed_ack_event)

        # Send the ack event to the user privately as well
        return json.dumps(signed_ack_event.to_json_dict())
def test_get_role_host():
    meeting = Meeting.parse(db.get_meeting(mid))
    staff = Staff.parse(db.get_staff(meeting.host))
    roles = get_role(staff, meeting)
    assert (Role.HOST in roles) and (Role.PARTICIPANT in roles)
def test_get_role_participant():
    meeting = Meeting.parse(db.get_meeting(mid))
    staff = Staff.parse(db.get_staff(meeting.staff[1]))
    roles = get_role(staff, meeting)
    assert (Role.PARTICIPANT in roles)
Exemple #20
0
def edit_meeting(
        session, meeting, calendarobj, fas_user,
        meeting_name, meeting_date, meeting_date_end,
        meeting_time_start, meeting_time_stop, comanager,
        meeting_information,
        meeting_region, tzone,
        recursion_frequency, recursion_ends,
        remind_when, remind_who,
        full_day,
        edit_all_meeting=True,
        admin=False):
    """ When a user wants to edit a meeting to the database, we need to
    perform a number of test first checking that the input is valid
    and then edit the desired meeting.
    """
    if not is_user_managing_in_calendar(
            session, calendarobj.calendar_name, fas_user) and not admin:
        raise UserNotAllowed(
            'You are not allowed to add a meeting to this calendar')

    if not meeting_date_end:
        meeting_date_end = meeting_date

    if full_day:
        meeting_time_start = time(0, 0)
        meeting_time_stop = time(0, 0)
        tzone = 'UTC'

    meeting_time_start = convert_time(
        datetime(meeting_date.year, meeting_date.month, meeting_date.day,
                 meeting_time_start.hour,
                 meeting_time_start.minute),
        tzone, 'UTC')
    meeting_time_stop = convert_time(
        datetime(meeting_date_end.year, meeting_date_end.month,
                 meeting_date_end.day,
                 meeting_time_stop.hour,
                 meeting_time_stop.minute),
        tzone, 'UTC')

    if not is_date_in_future(meeting_date, meeting_time_start):
        raise InvalidMeeting('The date you entered is in the past')

    if meeting_time_start.date() > meeting_time_stop.date():
        raise InvalidMeeting(
            'The start date of your meeting is later than the stop date.')

    if meeting_time_start > meeting_time_stop:
        raise InvalidMeeting(
            'The start time of your meeting is later than the stop time.')

    if full_day:
        meeting_time_stop = meeting_time_stop + timedelta(days=1)

    if recursion_frequency and recursion_ends:
        agenda_free = agenda_is_free_in_future(
            session, calendarobj,
            meeting_time_start.date(), meeting_time_stop.date(),
            recursion_ends,
            meeting_time_start.time(), meeting_time_stop.time(),
            meeting_id = meeting.meeting_id)

        if not bool(calendarobj.calendar_multiple_meetings) and \
                not agenda_free:
            raise InvalidMeeting(
                'The start or end time you have entered is already '
                'occupied in the future.')

    ## The information are correct
    ## What we do now:
    # a) the meeting is not recursive -> edit the information as provided
    # b) the meeting is recursive and we update all the meetings
    #     -> recursion_end = today
    #     -> copy meeting to new object
    #     -> update new object
    # c) the meeting is recursive and the update only one meeting
    #     -> recursion_end = today
    #     -> copy meeting to new object w/o recursion
    #     -> update new object
    #     -> copy meeting to new object w/ recursion and date = date + offset

    remove_recursion = False
    if meeting.recursion_frequency:
        old_meeting = Meeting.copy(meeting)
        old_meeting.recursion_ends = meeting_date - timedelta(days=1)
        if old_meeting.recursion_ends > old_meeting.meeting_date:
            old_meeting.save(session)
        if not edit_all_meeting:
            remove_recursion = True
            new_meeting = Meeting.copy(meeting)
            new_meeting.meeting_date = meeting_date + timedelta(
                days=meeting.recursion_frequency)

            dt_start = datetime(
                new_meeting.meeting_date.year,
                new_meeting.meeting_date.month,
                new_meeting.meeting_date.day,
                new_meeting.meeting_time_start.hour,
                new_meeting.meeting_time_start.minute,
                tzinfo=pytz.utc)
            dt_stop = datetime(
                new_meeting.meeting_date_end.year,
                new_meeting.meeting_date_end.month,
                new_meeting.meeting_date_end.day,
                new_meeting.meeting_time_start.hour,
                new_meeting.meeting_time_start.minute,
                tzinfo=pytz.utc)

            free_time = agenda_is_free(
                session, calendarobj,
                dt_start, dt_stop)

            if not bool(calendarobj.calendar_multiple_meetings) and \
                    bool(free_time):
                new_meeting.save(session)

    meeting.meeting_name = meeting_name
    meeting.meeting_manager = '%s,' % fas_user.username
    if comanager:
        meeting.meeting_manager = '%s%s,' % (meeting.meeting_manager,
                                             comanager)

    meeting.meeting_date = meeting_time_start.date()
    meeting.meeting_date_end = meeting_time_stop.date()
    meeting.meeting_time_start = meeting_time_start.time()
    meeting.meeting_time_stop = meeting_time_stop.time()
    meeting.meeting_information = meeting_information

    region = meeting_region
    if not region:
        region = None
    meeting.meeting_region = region

    recursion_frequency = recursion_frequency
    if not recursion_frequency:
        recursion_frequency = None
    meeting.recursion_frequency = recursion_frequency

    if not recursion_ends:
        recursion_ends = date(2025, 12, 31)
    meeting.recursion_ends = recursion_ends

    if remind_when and remind_who:
        if meeting.reminder_id:
            meeting.reminder.reminder_offset = remind_when
            meeting.reminder.reminder_to = remind_who
            meeting.reminder.save(session)
        else:
            reminder = Reminder(remind_when,
                                remind_who,
                                None)
            reminder.save(session)
            session.flush()
            meeting.reminder = reminder
            session.flush()
    elif meeting.reminder_id:
        meeting.reminder.delete(session)
        meeting.reminder_id = None

    if remove_recursion:
        meeting.recursion_frequency = None
        meeting.recursion_ends = None

    meeting.save(session)
    session.commit()
Exemple #21
0
def test_parse_and_convert_bad_event():
    original_dict = copy.deepcopy(general_event_dict)
    print(original_dict)
    original_dict.pop("meetingId")
    with pytest.raises(KeyError) as e:
        parsed_dict = Meeting.parse(original_dict)
Exemple #22
0
def test_parse_and_convert_meeting():
    original_dict = db.get_all_meetings()[0]
    parsed_object = Meeting.parse(original_dict)
    generated_dict = parsed_object.to_json_dict()
    assert original_dict == generated_dict
Exemple #23
0
def test_parse_and_convert_bad_staff():
    original_dict = db.get_all_staff()[0]
    print(original_dict)
    original_dict.pop("name")
    with pytest.raises(KeyError) as e:
        parsed_dict = Meeting.parse(original_dict)