예제 #1
0
    def changes_to_notify(self) -> [Course]:
        changed_courses = []

        conn = sqlite3.connect(self.db_file)
        conn.row_factory = sqlite3.Row
        cursor = conn.cursor()

        cursor.execute(
            """SELECT course_id, course_fullname
            FROM files WHERE notified = 0 GROUP BY course_id;"""
        )

        curse_rows = cursor.fetchall()

        for course_row in curse_rows:
            course = Course(course_row['course_id'], course_row['course_fullname'])

            cursor.execute(
                """SELECT *
                FROM files WHERE notified = 0 AND course_id = ?;""",
                (course.id,),
            )

            file_rows = cursor.fetchall()

            course.files = []

            for file_row in file_rows:
                notify_file = File.fromRow(file_row)
                if notify_file.modified or notify_file.moved:
                    # add reference to new file

                    cursor.execute(
                        """SELECT *
                        FROM files
                        WHERE old_file_id = ?;""",
                        (notify_file.file_id,),
                    )

                    file_row = cursor.fetchone()
                    if file_row is not None:
                        notify_file.new_file = File.fromRow(file_row)

                course.files.append(notify_file)

            changed_courses.append(course)

        conn.close()
        return changed_courses
    def fetch_courses_info(self, course_ids: [int]) -> [Course]:
        """
        Queries the Moodle system for info about courses in a list.
        @param course_ids: A list of courses ids
        @return: A list of courses
        """
        # API is only available since version 3.2
        if len(course_ids) == 0 or self.version < 2016120500:
            return []

        data = {
            "field": "ids",
            "value": ",".join(list(map(str, course_ids))),
        }

        result = self.request_helper.post_REST(
            'core_course_get_courses_by_field', data)
        courses = result.get('courses', [])

        results = []
        for course in courses:
            results.append(
                Course(course.get('id', 0), course.get('fullname', '')))
            # We could also extract here the course summary and intro files
        return results
예제 #3
0
    def get_old_files(self) -> [Course]:
        # get all stored files (that are not yet deleted)
        conn = sqlite3.connect(self.db_file)
        conn.row_factory = sqlite3.Row
        cursor = conn.cursor()
        stored_courses = []

        cursor.execute("""SELECT DISTINCT course_id, course_fullname
            FROM files WHERE old_file_id IS NOT NULL""")

        course_rows = cursor.fetchall()
        for course_row in course_rows:
            course = Course(course_row['course_id'],
                            course_row['course_fullname'])

            cursor.execute(
                """SELECT *
                FROM files
                WHERE course_id = ?
                AND old_file_id IS NOT NULL""",
                (course.id, ),
            )

            updated_files = cursor.fetchall()

            course.files = []

            for updated_file in updated_files:
                cursor.execute(
                    """SELECT *
                    FROM files
                    WHERE file_id = ?""",
                    (updated_file['old_file_id'], ),
                )

                old_file = cursor.fetchone()

                notify_file = File.fromRow(old_file)
                course.files.append(notify_file)

            stored_courses.append(course)

        conn.close()
        return stored_courses
    def __get_new_files(self, changed_courses: [Course],
                        stored_courses: [Course],
                        current_courses: [Course]) -> [Course]:
        # check for new files
        for current_course in current_courses:
            # check if that file does not exist in stored

            same_course_in_stored = None

            for stored_course in stored_courses:
                if stored_course.id == current_course.id:
                    same_course_in_stored = stored_course
                    break

            if same_course_in_stored is None:
                # current_course is not saved yet

                changed_courses.append(current_course)
                # skip the next checks!
                continue

            # Does anyone know why it is necessary to give
            # a course an empty list of files O.o
            # if I don't do this then a course will be created
            # with the files of the previous course
            changed_course = Course(current_course.id, current_course.fullname,
                                    [])
            for current_file in current_course.files:
                matching_file = None

                for stored_file in same_course_in_stored.files:
                    # Try to find a matching file
                    if self.__files_have_same_path(
                            current_file,
                            stored_file) or self.__file_was_moved(
                                current_file, stored_file):
                        matching_file = current_file
                        break

                if matching_file is None:
                    # current_file is a new file
                    changed_course.files.append(current_file)

            if len(changed_course.files) > 0:
                matched_changed_course = None
                for ch_course in changed_courses:
                    if ch_course.id == changed_course.id:
                        matched_changed_course = ch_course
                        break
                if matched_changed_course is None:
                    changed_courses.append(changed_course)
                else:
                    matched_changed_course.files += changed_course.files
        return changed_courses
예제 #5
0
    def get_stored_files(self) -> [Course]:
        # get all stored files (that are not yet deleted)
        conn = sqlite3.connect(self.db_file)
        conn.row_factory = sqlite3.Row
        cursor = conn.cursor()
        stored_courses = []

        cursor.execute(
            """SELECT course_id, course_fullname
            FROM files WHERE deleted = 0 AND modified = 0 AND moved = 0
            GROUP BY course_id;"""
        )

        curse_rows = cursor.fetchall()

        for course_row in curse_rows:
            course = Course(course_row['course_id'], course_row['course_fullname'])

            cursor.execute(
                """SELECT *
                FROM files
                WHERE deleted = 0
                AND modified = 0
                AND moved = 0
                AND course_id = ?;""",
                (course.id,),
            )

            file_rows = cursor.fetchall()

            course.files = []

            for file_row in file_rows:
                notify_file = File.fromRow(file_row)
                course.files.append(notify_file)

            stored_courses.append(course)

        conn.close()
        return stored_courses
예제 #6
0
    def __get_new_files(self, changed_courses: [Course],
                        stored_courses: [Course],
                        current_courses: [Course]) -> [Course]:
        # check for new files
        for current_course in current_courses:
            # check if that file does not exist in stored

            same_course_in_stored = None

            for stored_course in stored_courses:
                if stored_course.id == current_course.id:
                    same_course_in_stored = stored_course
                    break

            if same_course_in_stored is None:
                # current_course is not saved yet

                changed_courses.append(current_course)
                # skip the next checks!
                continue

            changed_course = Course(current_course.id, current_course.fullname)
            for current_file in current_course.files:
                matching_file = None

                for stored_file in same_course_in_stored.files:
                    # Try to find a matching file
                    if self.__files_have_same_path(
                            current_file,
                            stored_file) or self.__file_was_moved(
                                current_file, stored_file):
                        matching_file = current_file
                        break

                if matching_file is None:
                    # current_file is a new file
                    changed_course.files.append(current_file)

            if len(changed_course.files) > 0:
                matched_changed_course = None
                for ch_course in changed_courses:
                    if ch_course.id == changed_course.id:
                        matched_changed_course = ch_course
                        break
                if matched_changed_course is None:
                    changed_courses.append(changed_course)
                else:
                    matched_changed_course.files += changed_course.files
        return changed_courses
예제 #7
0
    def fetch_courses(self, userid: str) -> [Course]:
        """
        Queries the Moodle system for all courses the user
        is enrolled in.
        @param userid: the user id
        @return: A list of courses
        """
        data = {'userid': userid}

        result = self.request_helper.post_REST('core_enrol_get_users_courses', data)

        results = []
        for course in result:
            results.append(Course(course.get('id', 0), course.get('fullname', '')))
        return results
    def fetch_all_visible_courses(self,
                                  log_all_courses_to: str = None) -> [Course]:
        """
        Queries the Moodle system for all courses available on the system and returns:
        @return: A list of all visible courses
        """
        # API is only available since version 3.2
        if self.version < 2016120500:
            return []

        result = self.request_helper.post_REST(
            'core_course_get_courses_by_field', timeout=1200)
        if log_all_courses_to is not None:
            with open(log_all_courses_to, 'w', encoding='utf-8') as log_file:
                log_file.write(json.dumps(result, indent=4,
                                          ensure_ascii=False))
        courses = result.get('courses', [])

        results = []
        for course in courses:
            if course.get('visible', 0) == 1:
                results.append(
                    Course(course.get('id', 0), course.get('fullname', '')))
        return results
    def __get_modified_files(self, stored_courses: [Course],
                             current_courses: [Course]) -> [Course]:
        # returns courses with modified and deleted files
        changed_courses = []

        for stored_course in stored_courses:

            same_course_in_current = None

            for current_course in current_courses:
                if current_course.id == stored_course.id:
                    same_course_in_current = current_course
                    break

            if same_course_in_current is None:
                # stroed_course does not exist anymore!

                # maybe it would be better
                # to not notify about this changes?
                for stored_file in stored_course.files:
                    stored_file.deleted = True
                    stored_file.notified = False
                changed_courses.append(stored_course)
                # skip the next checks!
                continue

            # there is the same course in the current set
            # so try to find removed files, that are still exist in storage
            # also find modified files
            changed_course = Course(stored_course.id, stored_course.fullname,
                                    [])
            for stored_file in stored_course.files:
                matching_file = None

                for current_file in same_course_in_current.files:
                    # Try to find a matching file with same path
                    if self.__files_have_same_path(current_file, stored_file):
                        matching_file = current_file
                        # file does still exist
                        break

                if matching_file is not None:
                    # An matching file was found
                    # Test for modification
                    if self.__files_are_diffrent(matching_file, stored_file):
                        # file is modified
                        matching_file.modified = True
                        matching_file.old_file = stored_file
                        changed_course.files.append(matching_file)

                    continue

                # No matching file was found --> file was deleted or moved
                # check for moved files

                for current_file in same_course_in_current.files:
                    # Try to find a matching file that was moved
                    if self.__file_was_moved(current_file, stored_file):
                        matching_file = current_file
                        # file does still exist
                        break

                if matching_file is None and not self.__ignore_deleted(
                        stored_file):
                    # No matching file was found --> file was deleted
                    stored_file.deleted = True
                    stored_file.notified = False
                    changed_course.files.append(stored_file)

                elif matching_file is not None:
                    matching_file.moved = True
                    matching_file.old_file = stored_file
                    changed_course.files.append(matching_file)

            if len(changed_course.files) > 0:
                changed_courses.append(changed_course)

        return changed_courses