def _select_sections_to_download(self, sections: [{}],
                                     excluded: [int]) -> [int]:
        """
        Asks the user for the sections that should be downloaded.
        @param sections: All available sections
        @param excluded sections currently excluded
        """

        choices = []
        defaults = []
        for i, section in enumerate(sections):
            section_id = section.get("id")
            choices.append(('%5i\t%s' % (section_id, section.get("name"))))

            if ResultsHandler.should_download_section(section_id, excluded):
                defaults.append(i)

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

        dont_download_section_ids = []
        for i, section in enumerate(sections):
            if i not in selected_sections:
                dont_download_section_ids.append(section.get("id"))

        return dont_download_section_ids
    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')
        return download_course_ids
    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()

        stored_files = MoodleService.filter_courses(stored_files,
                                                    self.config_helper)

        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.')

        course_options = []
        courses = []
        for course in stored_files:
            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 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()

        stored_files = MoodleService.filter_courses(stored_files, self.config_helper)

        if len(stored_files) <= 0:
            return

        course_options = []
        courses = []
        for course in stored_files:
            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(
            '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.'
        )

        Log.warning(
            'Only files that are missing locally but stored in the local'
            + ' database are displayed in this tool. If a file is not missing'
            + ' from a course, it will not be listed here at all.  Also, only'
            + ' courses that are selected for download are displayed.'
        )

        Log.critical(
            'For more complicated operations on the database a DB browser for SQLite'
            + ' is advantageous (https://sqlitebrowser.org/).'
        )

        if not courses:
            print('No files are missing locally but stored in the local database. Nothing to do.')
            return

        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 = []

        # Add the option to select all sections
        section_options.append(COLOR_SEQ % MAGENTA + '[All sections]' + RESET_SEQ)
        sections.append(None)  # Add None at index 0 to avoid index shifting

        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 == 0:
                selected_sections = sections[1:]
                break
            elif (selected_sections_id) < len(sections):
                selected_sections.append(sections[selected_sections_id])

        file_options = []
        files = []

        # Add the option to select all files
        file_options.append(COLOR_SEQ % CYAN + '[All files]' + RESET_SEQ)
        files.append(None)  # Add None at index 0 to avoid index shifting

        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 == 0:  # If all files is selected
                for file_to_delete in files[1:]:  # Ignore the first element of the array set as None
                    if isinstance(file_to_delete, File):
                        files_to_delete.append(file_to_delete)

                break

            elif 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 delete_old_files(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_old_files()

        if len(stored_files) <= 0:
            print('No old copies of files found. Nothing to do.')
            return

        print(
            'This management tool will navigate you through a menu to'
            + ' selectively remove old copies of files from the database '
            + ' and form the file system'
        )

        course_options = []
        for course in stored_files:
            course_options.append(COLOR_SEQ % BLUE + course.fullname + RESET_SEQ)

        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 = stored_files[selected_course_id]

        section_options = []
        sections = []

        # Add the option to select all sections
        section_options.append(COLOR_SEQ % MAGENTA + '[All sections]' + RESET_SEQ)
        sections.append(None)  # Add None at index 0 to avoid index shifting

        for course_file in selected_course.files:
            if 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 delete old 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 == 0:
                selected_sections = sections[1:]
                break
            elif (selected_sections_id) < len(sections):
                selected_sections.append(sections[selected_sections_id])

        file_options = []
        files = []

        # Add the option to select all files
        file_options.append(COLOR_SEQ % CYAN + '[All files]' + RESET_SEQ)
        files.append(None)  # Add None at index 0 to avoid index shifting

        for course_file in selected_course.files:
            if 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 deleted?')
        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 == 0:  # If all files is selected
                for file_to_delete in files[1:]:  # Ignore the first element of the array set as None
                    if isinstance(file_to_delete, File):
                        files_to_delete.append(file_to_delete)
                        if os.path.exists(file_to_delete.saved_to):
                            os.remove(file_to_delete.saved_to)

                break

            elif file_index < len(files) and isinstance(files[file_index], File):
                files_to_delete.append(files[file_index])
                if os.path.exists(files[file_index].saved_to):
                    os.remove(files[file_index].saved_to)

        self.state_recorder.batch_delete_files_from_db(files_to_delete)