def deleteTopic(self, agenda_id, section_position, topic_position):
     """
     Deletes a topic from agenda
     :param agenda_id:
     :param section_position:
     :param topic_position:
     :return: ResponseWrapper
     """
     if type(agenda_id) is not str:
         raise TypeError('agenda_id must be of type str')
     if type(section_position) is not int:
         raise TypeError('section_position must be of type int')
     if type(topic_position) is not int:
         raise TypeError('topic_position must be of type int')
     try:
         objectAgenda = self.getAgendaById(agenda_id).object
         done = objectAgenda.deleteTopic(section_position, topic_position)
         returned = self.db.agendas.update_one(
             {'_id': ObjectId(agenda_id)},
             {'$set': objectAgenda.makeJson()})
         responseWrapper: ResponseWrapper = ResponseWrapper(
             objectAgenda,
             found=True,
             operationDone=bool(returned.matched_count) and done)
         return responseWrapper
     except:
         return ResponseWrapper(None)
 def createNewAgenda(self, json_agenda) -> ResponseWrapper:
     """
     Adds a new agenda to database
     :param json_agenda
     :return: ResponseWrapper
     """
     if type(json_agenda) is not dict:
         raise TypeError('json_agenda must be of type dict')
     if 'date' not in json_agenda:
         raise ValueError('json_agenda doesnt contain date field')
     if 'lc' not in json_agenda:
         raise ValueError('json_agenda doesnt contain lc field')
     if type(json_agenda['date']) is not str:
         raise TypeError('date must be of type str')
     if not bool(
             re.search(
                 "^([1-9]|0?[1-9]|1[0-9]|2[0-9]|3[0-1])(/|.|-|\|)([1-9]|0?[1-9]|1[0-2])(/|.|-|\|)20[0-9][0-9]$",
                 json_agenda['date'])):
         raise ValueError(
             'date must be of format dd/mm/yyyy or dd-mm-yyyy or dd.mm.yyyy or dd\\mm\\yyyy'
         )
     if type(json_agenda['lc']) is not str:
         raise TypeError('lc must be of type str')
     try:
         objectAgenda = Agenda(json_agenda.get("date"),
                               json_agenda.get("lc"))
         agenda_id = str(
             self.db.agendas.insert_one(
                 objectAgenda.makeJson()).inserted_id)
         object = Agenda(json_agenda.get("date"), json_agenda.get("lc"),
                         agenda_id)
         return ResponseWrapper(object, found=True, operationDone=True)
     except:
         return ResponseWrapper(None)
 def createNewSectionInPosition(self, agenda_id, section_name, position):
     """
     Adds new session to existing agenda in requested position
     :param agenda_id:
     :param section_name:
     :param position:
     :return: ResponseWrapper
     """
     if type(agenda_id) is not str:
         raise TypeError('agenda_id must be of type str')
     if type(section_name) is not str:
         raise TypeError('section_name must be of type str')
     if type(position) is not int:
         raise TypeError('position must be of type int')
     try:
         objectAgenda = self.getAgendaById(agenda_id).object
         objectAgenda.addSectionInPosition(section_name, position)
         returned = self.db.agendas.update_one(
             {'_id': ObjectId(agenda_id)},
             {'$set': objectAgenda.makeJson()})
         responseWrapper: ResponseWrapper = ResponseWrapper(
             objectAgenda,
             found=True,
             operationDone=bool(returned.matched_count))
         return responseWrapper
     except:
         return ResponseWrapper(None)
 def updateSection(self, agenda_id, section_position,
                   section_json) -> Optional[ResponseWrapper]:
     """
     Replaces a section in an existing agenda with agenda_id, with section_json
     :param agenda_id:
     :param section_position:
     :param section_json:
     :return: ResponseWrapper
     """
     if type(agenda_id) is not str:
         raise TypeError('agenda_id must be of type str')
     if type(section_position) is not int:
         raise TypeError('section_position must be of type int')
     if type(section_json) is not dict:
         raise TypeError('section_json must be of type dict')
     if 'section_name' not in section_json:
         raise ValueError('section_json doesnt contain sections field')
     if type(section_json['section_name']) is not str:
         raise TypeError('section_name must be of type str')
     try:
         objectAgenda = self.getAgendaById(agenda_id).object
         objectAgenda.setSection(section_position,
                                 getSectionFromJson(section_json))
         returned = self.db.agendas.update_one(
             {'_id': ObjectId(agenda_id)},
             {'$set': objectAgenda.makeJson()})
         responseWrapper: ResponseWrapper = ResponseWrapper(
             objectAgenda,
             found=True,
             operationDone=bool(returned.matched_count))
         return responseWrapper
     except:
         return ResponseWrapper(None)
 def deleteAgenda(self, agenda_id):
     """
     Deletes an agenda with agenda_id from the database
     :param agenda_id:
     :return: ResponseWrapper
     """
     if type(agenda_id) is not str:
         raise TypeError('agenda_id must be of type str')
     try:
         agendaWrapper = self.getAgendaById(agenda_id)
         returned = self.db.agendas.delete_many(
             {'_id': ObjectId(agenda_id)})
         return ResponseWrapper(agendaWrapper.object,
                                found=agendaWrapper.found,
                                operationDone=bool(returned.deleted_count))
     except:
         return ResponseWrapper(None)
 def getAgendaById(self, agenda_id) -> ResponseWrapper:
     """
     Returns an agenda based on requested id
     :param agenda_id:
     :return: ResponseWrapper
     """
     if type(agenda_id) is not str:
         raise TypeError('agenda_id must be of type str')
     try:
         jsonReturned = self.db.agendas.find_one(
             {'_id': ObjectId(agenda_id)})
         if jsonReturned is None:
             return ResponseWrapper(None)
         object = getAgendaFromJson(jsonReturned)
         object.id = agenda_id
         return ResponseWrapper(object, found=True, operationDone=True)
     except:
         return ResponseWrapper(None)
    def updateTopic(self, agenda_id, section_position, topic_position,
                    topic_json) -> Optional[ResponseWrapper]:
        """
        Replaces a topic in an existing agenda with agenda_id, with topic_json
        :param agenda_id:
        :param section_position:
        :param topic_position:
        :param topic_json:
        :return: ResponseWrapper
        """
        if type(agenda_id) is not str:
            raise TypeError('agenda_id must be of type str')
        if type(section_position) is not int:
            raise TypeError('section_position must be of type int')
        if type(topic_position) is not int:
            raise TypeError('topic_position must be of type int')
        if type(topic_json) is not dict:
            raise TypeError('topic_json must be of type dict')
        if 'topic_name' not in topic_json:
            raise ValueError('topic_json does not contain topic_name field')
        if 'votable' not in topic_json:
            raise ValueError('topic_json does not contain votable field')
        if type(topic_json["topic_name"]) is not str:
            raise TypeError('topic_name must be of type str')
        if type(topic_json["votable"]) is not bool:
            raise TypeError('votable must be of type bool')

        try:
            objectAgenda = self.getAgendaById(agenda_id).object
            done = objectAgenda.setTopic(section_position, topic_position,
                                         getTopicFromJson(topic_json))
            if done:
                returned = self.db.agendas.update_one(
                    {'_id': ObjectId(agenda_id)},
                    {'$set': objectAgenda.makeJson()})
                operationDone = bool(returned.matched_count)
            else:
                operationDone = False
            responseWrapper: ResponseWrapper = ResponseWrapper(
                objectAgenda, found=True, operationDone=operationDone)
            return responseWrapper
        except:
            return ResponseWrapper(None)
    def createNewTopic(self, agenda_id, section_position, topic_position,
                       topic_json):
        """
        Adds a new topic to existing agenda in requested position
        :param agenda_id:
        :param section_position:
        :param topic_position:
        :param topic_json:
        :return: ResponseWrapper
        """
        if type(agenda_id) is not str:
            raise TypeError('agenda_id must be of type str')
        if type(section_position) is not int:
            raise TypeError('section_position must be of type int')
        if type(topic_position) is not int:
            raise TypeError('topic_position must be of type int')
        if type(topic_json) is not dict:
            raise TypeError('topic_json must be of type dict')
        if 'topic_name' not in topic_json:
            raise ValueError('topic_json does not contain topic_name field')
        if 'votable' not in topic_json:
            raise ValueError('topic_json does not contain votable field')
        if type(topic_json["topic_name"]) is not str:
            raise TypeError('topic_name must be of type str')
        if type(topic_json["votable"]) is not bool:
            raise TypeError('votable must be of type bool')

        try:
            objectAgenda = self.getAgendaById(agenda_id).object
            objectAgenda.addTopicInPosition(section_position,
                                            getTopicFromJson(topic_json),
                                            topic_position)
            returned = self.db.agendas.update_one(
                {'_id': ObjectId(agenda_id)},
                {'$set': objectAgenda.makeJson()})
            responseWrapper: ResponseWrapper = ResponseWrapper(
                objectAgenda,
                found=True,
                operationDone=bool(returned.matched_count))
            return responseWrapper
        except:
            return ResponseWrapper(None)
 def updateAgenda(self, agenda_id, new_agenda) -> Optional[ResponseWrapper]:
     """
     Replaces an agenda with agenda_id, with new_agenda
     :param agenda_id:
     :param new_agenda:
     :return: ResponseWrapper
     """
     if type(agenda_id) is not str:
         raise TypeError('agenda_id must be of type str')
     if type(new_agenda) is not dict:
         raise TypeError('new_agenda must be of type dict')
     if 'date' not in new_agenda:
         raise ValueError('new_agenda doesnt contain date field')
     if 'lc' not in new_agenda:
         raise ValueError('new_agenda doesnt contain lc field')
     if 'sections' not in new_agenda:
         raise ValueError('new_agenda doesnt contain sections field')
     if type(new_agenda['date']) is not str:
         raise TypeError('date must be of type str')
     if not bool(
             re.search(
                 "^([1-9]|0?[1-9]|1[0-9]|2[0-9]|3[0-1])(/|.|-|)([1-9]|0?[1-9]|1[0-2])(/|.|-|)20[0-9][0-9]$",
                 new_agenda['date'])):
         raise ValueError(
             'date must be of format dd/mm/yyyy or dd.mm.yyyy dd\\mm\\yyyy')
     if type(new_agenda['lc']) is not str:
         raise TypeError('lc must be of type str')
     if type(new_agenda['sections']) is not list:
         raise TypeError('sections must be of type dict')
     try:
         returned = self.db.agendas.update_one({'_id': ObjectId(agenda_id)},
                                               {'$set': new_agenda})
         return ResponseWrapper(self.getAgendaById(agenda_id).object,
                                found=True,
                                operationDone=bool(returned.matched_count))
     except:
         return ResponseWrapper(None)