def _filter_courses(changes: [Course],
                        download_course_ids: [int],
                        dont_download_course_ids: [int],
                        download_submissions: bool) -> [Course]:
        """
        Filters the changes course list from courses that
        should not get downloaded
        @param download_course_ids: list of course ids
                                         that should be downloaded
        @param dont_download_course_ids: list of course ids
                                         that should not be downloaded
        @param download_submissions: boolean if submissions
                                    should be downloaded
        @return: filtered changes course list
        """

        filtered_changes = []

        for course in changes:
            if (not download_submissions):
                course_files = []
                for file in course.files:
                    if (file.content_type != "submission_file"):
                        course_files.append(file)
                course.files = course_files

            if(ResultsHandler._should_download_course(
                course.id, download_course_ids,
                dont_download_course_ids) and
                    len(course.files) > 0):
                filtered_changes.append(course)

        return filtered_changes
    def interactively_acquire_config(self):
        """
        Guides the user through the process of configuring the downloader
        for the courses to be downloaded and in what way
        """

        token = self.get_token()
        moodle_domain = self.get_moodle_domain()
        moodle_path = self.get_moodle_path()

        request_helper = RequestHelper(moodle_domain, moodle_path, token)
        results_handler = ResultsHandler(request_helper)

        courses = []
        try:

            userid, version = results_handler.fetch_userid_and_version()
            results_handler.setVersion(version)

            courses = results_handler.fetch_courses(userid)

        except (RequestRejectedError, ValueError, RuntimeError) as error:
            raise RuntimeError(
                'Error while communicating with the Moodle System! (%s)' %
                (error))

        self._select_courses_to_download(courses)
        self._select_should_download_submissions()
示例#3
0
    def _select_courses_to_download(self, courses: [Course]):
        """
        Asks the user for the courses that should be downloaded.
        @param courses: All available courses
        """
        download_course_ids = self.config_helper.get_download_course_ids()
        dont_download_course_ids = self.config_helper.get_dont_download_course_ids(
        )

        print('')
        Log.info(
            'To avoid downloading all the Moodle courses you are enrolled in, you can select which ones you want'
            + ' to download here. ')
        print('')

        choices = []
        defaults = []
        for i, course in enumerate(courses):
            choices.append(('%5i\t%s' % (course.id, course.fullname)))

            if ResultsHandler._should_download_course(
                    course.id, download_course_ids, dont_download_course_ids):
                defaults.append(i)

        Log.special('Which of the courses should be downloaded?')
        Log.info(
            '[You can select with the space bar and confirm your selection with the enter key]'
        )
        print('')
        selected_courses = cutie.select_multiple(options=choices,
                                                 ticked_indices=defaults)

        download_course_ids = []
        for i, course in enumerate(courses):
            if i in selected_courses:
                download_course_ids.append(course.id)

        self.config_helper.set_property('download_course_ids',
                                        download_course_ids)

        self.config_helper.remove_property('dont_download_course_ids')
示例#4
0
    def interactively_manage_database(self):
        RESET_SEQ = "\033[0m"
        COLOR_SEQ = "\033[1;%dm"

        BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(30, 38)

        stored_files = self.state_recorder.get_stored_files()

        if(len(stored_files) <= 0):
            return

        print("This management tool will navigate you through a menu to" +
              " selectively remove file entries from the database so" +
              " that these files can be downloaded again.")

        download_course_ids = self.config_helper.get_download_course_ids()
        dont_download_course_ids = self.config_helper\
            .get_dont_download_course_ids()

        course_options = []
        courses = []
        for course in stored_files:
            if (not ResultsHandler._should_download_course(
                    course.id, download_course_ids, dont_download_course_ids)):
                continue

            for course_file in course.files:
                if(not os.path.exists(course_file.saved_to)):
                    course_options.append(COLOR_SEQ %
                                          BLUE + course.fullname + RESET_SEQ)
                    courses.append(course)
                    break

        print('Choose one of the courses:')
        print('[Confirm your selection with the Enter key]')
        print('')
        selected_course_id = cutie.select(options=course_options)

        selected_course = courses[selected_course_id]

        section_options = []
        sections = []
        for course_file in selected_course.files:
            if (not os.path.exists(course_file.saved_to)
                    and (course_file.section_name not in sections)):
                section_options.append(
                    COLOR_SEQ % MAGENTA + course_file.section_name + RESET_SEQ)
                sections.append(course_file.section_name)

        print('From which sections you want to select files.')
        print('[You can select with the space bar and confirm' +
              ' your selection with the enter key]')
        print('')

        selected_sections_ids = cutie.select_multiple(
            options=section_options, minimal_count=1)
        selected_sections = []
        for selected_sections_id in selected_sections_ids:
            if(selected_sections_id < len(sections)):
                selected_sections.append(sections[selected_sections_id])

        file_options = []
        files = []
        for course_file in selected_course.files:
            if (not os.path.exists(course_file.saved_to)
                    and (course_file.section_name in selected_sections)):
                file_options.append(COLOR_SEQ % CYAN +
                                    course_file.content_filename + RESET_SEQ)
                files.append(course_file)

        print('Which of the files should be removed form the database,' +
              ' so that they will be redownloaded?')
        print('[You can select with the space bar and confirm' +
              ' your selection with the enter key]')
        print('')
        selected_files = cutie.select_multiple(options=file_options)

        files_to_delete = []
        for file_index in selected_files:
            if(file_index < len(files)
               and isinstance(files[file_index], File)):
                files_to_delete.append(files[file_index])

        self.state_recorder.batch_delete_files_from_db(files_to_delete)
    def fetch_state(self) -> [Course]:
        """
        Gets the current status of the configured Moodle account and compares
        it with the last known status for changes. It does not change the
        known state, nor does it download the files.
        @return: List with detected changes
        """
        logging.debug('Fetching current Moodle State...')

        token = self.config_helper.get_token()
        moodle_domain = self.config_helper.get_moodle_domain()
        moodle_path = self.config_helper.get_moodle_path()

        request_helper = RequestHelper(moodle_domain, moodle_path, token,
                                       self.skip_cert_verify)
        results_handler = ResultsHandler(request_helper)

        download_course_ids = self.config_helper.get_download_course_ids()
        dont_download_course_ids = self.config_helper\
            .get_dont_download_course_ids()
        download_submissions = self.config_helper.get_download_submissions()
        download_descriptions = self.config_helper.get_download_descriptions()

        courses = []
        filtered_courses = []
        try:

            sys.stdout.write('\rDownload account information')
            sys.stdout.flush()

            userid, version = results_handler.fetch_userid_and_version()
            results_handler.setVersion(version)

            courses_list = results_handler.fetch_courses(userid)
            courses = []
            # Filter unselected courses
            for course in courses_list:
                if (ResultsHandler._should_download_course(
                    course.id, download_course_ids,
                        dont_download_course_ids)):
                    courses.append(course)

            assignments = results_handler.fetch_assignments(courses)

            if(download_submissions):
                assignments = results_handler.fetch_submissions(
                    userid, assignments, download_course_ids,
                    dont_download_course_ids)

            index = 0
            for course in courses:
                index += 1

                # to limit the output to one line
                limits = shutil.get_terminal_size()

                shorted_course_name = course.fullname
                if (len(course.fullname) > 17):
                    shorted_course_name = course.fullname[:15] + '..'

                into = '\rDownload course information'

                status_message = (into + ' %3d/%3d [%17s|%6s]'
                                  % (index, len(courses),
                                      shorted_course_name,
                                      course.id))

                if (len(status_message) > limits.columns):
                    status_message = status_message[0:limits.columns]

                sys.stdout.write(status_message)
                sys.stdout.flush()

                course_assignments = assignments.get(course.id, [])
                course.files = results_handler.fetch_files(
                    course.id, course_assignments, download_descriptions)

                filtered_courses.append(course)
            print("")

        except (RequestRejectedError, ValueError, RuntimeError) as error:
            raise RuntimeError(
                'Error while communicating with the Moodle System! (%s)' % (
                    error))

        logging.debug('Checking for changes...')
        changes = self.recorder.changes_of_new_version(filtered_courses)

        # Filter changes
        changes = self._filter_courses(changes, download_course_ids,
                                       dont_download_course_ids,
                                       download_submissions,
                                       download_descriptions)

        changes = self.add_options_to_courses(changes)

        return changes
示例#6
0
    def _set_options_of_courses(self, courses: [Course]):
        """
        Let the user set special options for every single course
        """
        download_course_ids = self.config_helper.get_download_course_ids()
        dont_download_course_ids = self.config_helper.get_dont_download_course_ids()

        print('')
        print('You can set special settings for every single course.' +
              ' You can set these options:\n' +
              '- A different name for the course\n' +
              '- If a directory structure should be created for the course' +
              ' [create_directory_structure (cfs)].')
        print('')

        while(True):

            choices = []
            choices_courses = []

            options_of_courses = self.config_helper.get_options_of_courses()

            choices.append('None')

            for course in courses:
                if(ResultsHandler._should_download_course(
                        course.id, download_course_ids,
                        dont_download_course_ids)):

                    current_course_settings = options_of_courses.get(
                        str(course.id), None)

                    # create default settings
                    if current_course_settings is None:
                        current_course_settings = {
                            'original_name': course.fullname,
                            'overwrite_name_with': None,
                            'create_directory_structure': True
                        }

                    # create list of options
                    overwrite_name_with = current_course_settings.get(
                        'overwrite_name_with', None)

                    create_directory_structure = current_course_settings.get(
                        'create_directory_structure', True)

                    if(overwrite_name_with is not None and
                            overwrite_name_with != course.fullname):
                        choices.append(('%5i\t%s (%s) cfs=%s' %
                                        (course.id, overwrite_name_with,
                                            course.fullname,
                                            create_directory_structure)))

                    else:
                        choices.append(('%5i\t%s  cfs=%s' %
                                        (course.id, course.fullname,
                                            create_directory_structure)))

                    choices_courses.append(course)

            print('')
            print('For which of the following course do you want to change' +
                  ' the settings?')
            print('[Confirm your selection with the Enter key]')
            print('')

            selected_course = cutie.select(options=choices)
            if(selected_course == 0):
                break
            else:
                self._change_settings_of(choices_courses[selected_course - 1],
                                         options_of_courses)