コード例 #1
0
ファイル: main.py プロジェクト: WangTing2/Moodle-Downloader-2
def run_init(storage_path, use_sso=False, skip_cert_verify=False):
    config = ConfigHelper(storage_path)

    if config.is_present():
        do_override_input = cutie.prompt_yes_or_no(
            'Do you want to override the existing config?')

        if not do_override_input:
            sys.exit(0)

    MailService(config).interactively_configure()

    do_sentry = cutie.prompt_yes_or_no(
        'Do you want to configure Error Reporting via Sentry?')
    if do_sentry:
        sentry_dsn = input('Please enter your Sentry DSN:   ')
        config.set_property('sentry_dsn', sentry_dsn)

    moodle = MoodleService(config, storage_path, skip_cert_verify)

    if (use_sso):
        moodle.interactively_acquire_sso_token()
    else:
        moodle.interactively_acquire_token()

    print('Configuration finished and saved!')

    if (storage_path == '.'):
        print(
            '  To set a cron-job for this program on your Unix-System:\n' +
            '    1. `crontab -e`\n' +
            '    2. Add `*/15 * * * * cd %s && python3 %smain.py`\n' % (
                os.getcwd(), os.path.join(os.path.dirname(
                    os.path.realpath(__file__)), '')) +
            '    3. Save and you\'re done!'
        )
    else:
        print(
            '  To set a cron-job for this program on your Unix-System:\n' +
            '    1. `crontab -e`\n' +
            '    2. Add `*/15 * * * *' +
            ' cd %s && python3 %smain.py --path %s`\n' % (
                os.getcwd(), os.path.join(os.path.dirname(
                    os.path.realpath(__file__)), ''), storage_path) +
            '    3. Save and you\'re done!'
        )

    print('')

    print('You can always do the additional configuration later' +
          ' with the --config option.')

    do_config = cutie.prompt_yes_or_no(
        'Do you want to make additional configurations now?')

    if do_config:
        run_configure(storage_path, skip_cert_verify)

    print('')
    print('All set and ready to go!')
コード例 #2
0
    def interactively_acquire_sso_token(self) -> str:
        """
        Walks the user through the receiving of a SSO token for the
        Moodle-System and saves it.
        @return: The Token for Moodle.
        """

        moodle_url = input('URL of Moodle:   ')

        moodle_uri = urlparse(moodle_url)

        moodle_domain, moodle_path = self._split_moodle_uri(moodle_uri)

        version = RequestHelper(moodle_domain, moodle_path, '',
                                self.skip_cert_verify
                                ).get_simple_moodle_version()

        if (version > 3.8):
            print('Between version 3.81 and 3.82 a change was added to' +
                  ' Moodle so that automatic copying of the SSO token' +
                  ' might not work. You can still try it, your version is: ' +
                  str(version))

        print(' If you want to copy the login-token manual,' +
              ' you will be guided through the manual copy process.')
        do_automatic = cutie.prompt_yes_or_no(
            'Do you want to try to receive the SSO token automatically?')

        print('Please log into Moodle on this computer and then visit' +
              ' the following address in your web browser: ')

        print('https://' + moodle_domain + moodle_path +
              'admin/tool/mobile/launch.php?service=' +
              'moodle_mobile_app&passport=12345&' +
              'urlscheme=http%3A%2F%2Flocalhost')

        if do_automatic:
            moodle_token = sso_token_receiver.receive_token()
        else:
            print('If you open the link in the browser, no web page should' +
                  ' load, instead an error will occur. Open the' +
                  ' developer console (press F12) and go to the Network Tab,' +
                  ' if there is no error, reload the web page.')

            print('Copy the link address of the website that could not be' +
                  ' loaded (right click, then click on Copy, then click' +
                  ' on copy link address).')

            token_address = input('Then insert the address here:   ')

            moodle_token = sso_token_receiver.extract_token(token_address)
            if(moodle_token is None):
                raise ValueError('Invalid URL!')

        # Saves the created token and the successful Moodle parameters.
        self.config_helper.set_property('token', moodle_token)
        self.config_helper.set_property('moodle_domain', moodle_domain)
        self.config_helper.set_property('moodle_path', moodle_path)

        return moodle_token
コード例 #3
0
    def _select_should_download_linked_files(self):
        """
        Asks the user if linked files should be downloaded
        """
        download_linked_files = self.config_helper.get_download_linked_files()

        print('')
        Log.info('In Moodle courses the teacher can also link to external' +
                 ' files. This can be audio, video, text or anything else.' +
                 ' In particular, the teacher can link to Youtube videos.')
        Log.debug('To download videos correctly you have to install ffmpeg. ')

        Log.error('These files can increase the download volume considerably.')

        Log.info('If you want to filter the external links by their domain,' +
                 ' you can manually set a whitelist and a blacklist' +
                 ' (https://github.com/C0D3D3V/Moodle-Downloader-2/' +
                 'wiki/Download-(external)-linked-files' +
                 ' for more details).')
        Log.warning(
            'Please note that the size of the external files is determined during the download, so the total size'
            + ' changes during the download.')
        print('')

        download_linked_files = cutie.prompt_yes_or_no(
            'Would you like to download linked files of the courses you have selected?',
            default_is_yes=download_linked_files,
        )

        self.config_helper.set_property('download_linked_files',
                                        download_linked_files)
コード例 #4
0
    def _select_should_download_descriptions(self):
        """
        Asks the user if descriptions should be downloaded
        """
        download_descriptions = self.config_helper.get_download_descriptions()

        print('')
        Log.info(
            'In Moodle courses, descriptions can be added to all kinds' +
            ' of resources, such as files, tasks, assignments or simply' +
            ' free text. These descriptions are usually unnecessary to' +
            ' download because you have already read the information or' +
            ' know it from context. However, there are situations where' +
            ' it might be interesting to download these descriptions. The' +
            ' descriptions are created as Markdown files and can be' +
            ' deleted as desired.')
        Log.debug(
            'Creating the description files does not take extra time, but they can be annoying'
            + ' if they only contain unnecessary information.')

        print('')

        download_descriptions = cutie.prompt_yes_or_no(
            Log.special_str(
                'Would you like to download descriptions of the courses you have selected?'
            ),
            default_is_yes=download_descriptions,
        )

        self.config_helper.set_property('download_descriptions',
                                        download_descriptions)
コード例 #5
0
    def interactively_configure(self) -> None:
        """
        Guides the user through the configuration of the mail notification.
        """

        do_mail = cutie.prompt_yes_or_no(
            'Do you want to activate Notifications via mail?')

        if not do_mail:
            self.config_helper.remove_property('mail')
        else:
            print('[The following Inputs are not validated!]')

            config_valid = False
            while not config_valid:
                sender = input('E-Mail-Address of the Sender:   ')
                server_host = input('Host of the SMTP-Server:   ')
                server_port = input(
                    'Port of the SMTP-Server [STARTTLS, mostly 587]:   ')
                username = input('Username for the SMTP-Server:   ')
                password = getpass(
                    'Password for the SMTP-Server [no output]:   ')
                target = input('E-Mail-Address of the Target:   ')

                print('Testing Mail-Config...')
                welcome_content = create_full_welcome_mail()
                mail_shooter = MailShooter(sender, server_host,
                                           int(server_port), username,
                                           password)
                try:
                    mail_shooter.send(target, 'Hey!', welcome_content[0],
                                      welcome_content[1])
                except BaseException as e:
                    print('Error while sending the test mail: %s' % (str(e)))
                else:
                    input('Please check if you received the Welcome-Mail.' +
                          ' If yes, confirm with Return.\nIf not, exit' +
                          ' this program ([CTRL]+[C]) and try again later.')
                    config_valid = True

                raw_send_error_msg = ''
                while raw_send_error_msg not in ['y', 'n']:
                    raw_send_error_msg = input(
                        'Do you want to also get error reports sent by mail?' +
                        ' [y/n]   ')
                do_send_error_msg = raw_send_error_msg == 'y'

                mail_cfg = {
                    'sender': sender,
                    'server_host': server_host,
                    'server_port': server_port,
                    'username': username,
                    'password': password,
                    'target': target,
                    'send_error_msg': do_send_error_msg
                }

                self.config_helper.set_property('mail', mail_cfg)
コード例 #6
0
    def _change_settings_of(self, course: Course, options_of_courses: {}):
        """
        Ask for a new Name for the course.
        Then asks if a file structure should be created.
        """

        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,
            }

        changed = False

        # Ask for new name
        overwrite_name_with = input(
            Log.special_str(
                'Enter a new name for this Course [leave blank for "%s"]:   ' %
                (course.fullname, )))

        if overwrite_name_with == '':
            overwrite_name_with = None

        if (overwrite_name_with != course.fullname
                and current_course_settings.get('overwrite_name_with',
                                                None) != overwrite_name_with):
            current_course_settings.update(
                {'overwrite_name_with': overwrite_name_with})
            changed = True

        # Ask if a file structure should be created
        create_directory_structure = current_course_settings.get(
            'create_directory_structure', True)

        create_directory_structure = cutie.prompt_yes_or_no(
            Log.special_str(
                'Should a directory structure be created for this course?'),
            default_is_yes=create_directory_structure,
        )

        if create_directory_structure is not current_course_settings.get(
                'create_directory_structure', True):
            changed = True
            current_course_settings.update(
                {'create_directory_structure': create_directory_structure})

        if changed:
            options_of_courses.update(
                {str(course.id): current_course_settings})
            self.config_helper.set_property('options_of_courses',
                                            options_of_courses)
コード例 #7
0
    def interactively_configure(self) -> None:
        """
        Guides the user through the configuration of the telegram notification.
        """

        do_telegram = cutie.prompt_yes_or_no(
            'Do you want to activate Notifications via Telegram?')

        if not do_telegram:
            self.config_helper.remove_property('telegram')
        else:
            print('[The following Inputs are not validated!]')

            config_valid = False
            while not config_valid:
                telegram_token = input('Telegram Token:    ')
                telegram_chatID = input('Telegram Chat ID:   ')

                print('Testing Telegram-Config...')

                try:
                    telegram_shooter = TelegramShooter(telegram_token,
                                                       telegram_chatID)
                    telegram_shooter.send(
                        "This is a Testmessage from Moodle Downloader!")
                except BaseException as e:
                    print('Error while sending the test message: %s' %
                          (str(e)))

                else:
                    input('Please check if you received the Testmessage.' +
                          ' If yes, confirm with Return.\nIf not, exit' +
                          ' this program ([CTRL]+[C]) and try again later.')
                    config_valid = True

                raw_send_error_msg = ''
                while raw_send_error_msg not in ['y', 'n']:
                    raw_send_error_msg = input(
                        'Do you want to also get error reports sent in' +
                        '  telegram? [y/n]   ')

                do_send_error_msg = raw_send_error_msg == 'y'

                telegram_cfg = {
                    'token': telegram_token,
                    'chat_id': telegram_chatID,
                    'send_error_msg': do_send_error_msg
                }

                self.config_helper.set_property('telegram', telegram_cfg)
コード例 #8
0
    def _select_should_download_submissions(self):
        """
        Asks the user if submissions should be downloaded
        """
        download_submissions = self.config_helper.get_download_submissions()

        print('')
        print('Submissions are files that you or a teacher have uploaded' +
              ' to your assignments. Moodle does not provide an' +
              ' interface for downloading information from all' +
              ' submissions to a course at once. Therefore, it' +
              ' may be slow to monitor changes to submissions.')
        print('')

        download_submissions = cutie.prompt_yes_or_no(
            'Do you want to download submissions of your assignments?',
            default_is_yes=download_submissions)

        self.config_helper.set_property('download_submissions',
                                        download_submissions)
コード例 #9
0
    def _select_should_download_databases(self):
        """
        Asks the user if databases should be downloaded
        """
        download_databases = self.config_helper.get_download_databases()

        print('')
        Log.info('In the database module of Moodle data can be stored' +
                 ' structured with information. Often it is also' +
                 ' possible for students to upload data there.  Because' +
                 ' the implementation of the downloader has not yet been' +
                 ' optimized at this point, it is optional to download the' +
                 ' databases. Currently only files are downloaded, thumbails' +
                 ' are ignored.')
        print('')

        download_databases = cutie.prompt_yes_or_no(
            Log.special_str(
                'Do you want to download databases of your courses?'),
            default_is_yes=download_databases)

        self.config_helper.set_property('download_databases',
                                        download_databases)
コード例 #10
0
ファイル: main.py プロジェクト: RaR0CH/Moodle-Downloader-2
def run_init(storage_path, use_sso=False, skip_cert_verify=False):
    config = ConfigHelper(storage_path)

    if config.is_present():
        do_override_input = cutie.prompt_yes_or_no(
            Log.error_str('Do you want to override the existing config?'))

        if not do_override_input:
            sys.exit(0)

    MailService(config).interactively_configure()
    TelegramService(config).interactively_configure()

    do_sentry = cutie.prompt_yes_or_no(
        'Do you want to configure Error Reporting via Sentry?')
    if do_sentry:
        sentry_dsn = input('Please enter your Sentry DSN:   ')
        config.set_property('sentry_dsn', sentry_dsn)

    moodle = MoodleService(config, storage_path, skip_cert_verify)

    if use_sso:
        moodle.interactively_acquire_sso_token()
    else:
        moodle.interactively_acquire_token()

    if os.name != 'nt':
        Log.info(
            'On Windows many characters are forbidden in filenames and paths, if you want, these characters can be'
            + ' automatically removed from filenames.')

        Log.warning(
            'If you want to view the downloaded files on Windows this is important!'
        )

        default_windows_map = cutie.prompt_yes_or_no(
            'Do you want to load the default filename character map for windows?'
        )
        if default_windows_map:
            config.set_default_filename_character_map(True)
        else:
            config.set_default_filename_character_map(False)
    else:
        config.set_default_filename_character_map(True)

    Log.success('Configuration finished and saved!')

    if os.name != 'nt':
        if storage_path == '.':
            Log.info(
                '  To set a cron-job for this program on your Unix-System:\n' +
                '    1. `crontab -e`\n' +
                '    2. Add `*/15 * * * * cd %s && python3 %smain.py`\n' %
                (os.getcwd(),
                 os.path.join(os.path.dirname(os.path.realpath(__file__)), ''))
                + '    3. Save and you\'re done!')
        else:
            Log.info(
                '  To set a cron-job for this program on your Unix-System:\n' +
                '    1. `crontab -e`\n' + '    2. Add `*/15 * * * *' +
                ' cd %s && python3 %smain.py --path %s`\n' %
                (os.getcwd(),
                 os.path.join(os.path.dirname(os.path.realpath(__file__)), ''),
                 storage_path) + '    3. Save and you\'re done!')

    print('')

    Log.info(
        'You can always do the additional configuration later with the --config option.'
    )

    do_config = cutie.prompt_yes_or_no(
        'Do you want to make additional configurations now?')

    if do_config:
        run_configure(storage_path, skip_cert_verify)

    print('')
    Log.success('All set and ready to go!')