def get_valid_extensions(self):
        """
        Get the list of valid extensions based on the result of self.download().
        """

        result = {}
        regex_valid_extension = r'(/domains/root/db/)(.*)(\.html)'

        for readed in open(self.download_destination):
            readed = readed.rstrip('\n').strip()

            matched = Helpers.Regex(readed,
                                    regex_valid_extension,
                                    return_data=True,
                                    rematch=True).match()

            if not matched:
                continue
            else:
                ext_with_referer = {matched[1]: self.referer(matched[1])}
                result.update(ext_with_referer)

        Helpers.File(self.download_destination).delete()
        Helpers.File(self.destination).delete()
        return result
    def restore(self):
        """
        Restore the 'output/' directory structure based on the `dir_structure.json` file.
        """

        if not Settings.quiet:
            print('Creation of non existant files and directories', end=" ")

        structure = Helpers.Dict().from_json(
            Helpers.File(self.structure).read())

        structure = structure['output']
        replace = self.restore_replace()

        for directory in structure:
            if not path.isdir(self.base + self.path + directory):
                self.travis_permissions()
                mkdir(self.base + self.path + directory)
                self.travis_permissions()

            for file in structure[directory]:
                file_path = self.path + directory + directory_separator + file

                content_to_write = structure[directory][file]['content']
                online_sha = structure[directory][file]['sha512']
                content_to_write = Helpers.Regex(content_to_write,
                                                 '@@@',
                                                 escape=True,
                                                 replace_with='\\n').replace()

                git_to_keep = file_path.replace('gitignore', 'keep')
                keep_to_git = file_path.replace('keep', 'gitignore')

                if replace:
                    if path.isfile(file_path) and Hash(
                            file_path, 'sha512', True).get() == online_sha:
                        rename(file_path, git_to_keep)
                        write = False
                    else:
                        Helpers.File(file_path).delete()
                        file_path = git_to_keep
                        write = True
                else:
                    if path.isfile(keep_to_git) and Hash(
                            file_path, 'sha512', True).get() == online_sha:
                        rename(file_path, keep_to_git)
                        write = False
                    else:
                        Helpers.File(keep_to_git).delete()
                        file_path = keep_to_git
                        write = True

                if write:
                    Helpers.File(file_path).write(content_to_write + '\n',
                                                  True)

        if not Settings.quiet:
            print(Settings.done)
    def them_all(self):
        """
        Delete all discovered files.
        """

        to_delete = self.file_to_delete()

        for file in to_delete:
            Helpers.File(file).delete()
    def __init__(self):
        self.current_path = getcwd()

        self.destination = self.current_path + \
            directory_separator + Settings.funilrys + '.'

        self.files = {
            'script': 'PyFunceble.py',
            'tool': 'tool.py',
            'iana': 'iana-domains-db.json',
            'dir_structure': 'dir_structure.json'
        }

        if path.isdir(self.current_path + directory_separator +
                      '.git') and Settings.script in Helpers.Command(
                          'git remote show origin').execute():
            self.git()
        else:
            if not self.same_version(True):
                for data in self.files:
                    Helpers.File(self.current_path + directory_separator +
                                 self.files[data]).delete()
                    rename(
                        self.destination + self.files[data],
                        self.current_path + directory_separator +
                        self.files[data])

                if not Settings.quiet:
                    print('Checking version', end=' ')
                if self.same_version() and not Settings.quiet:
                    print(Settings.done +
                          '\n\nThe update was successfully completed!')
                else:
                    if not Settings.quiet:
                        print(
                            Settings.error +
                            '\nImpossible to update PyFunceble. Please report issue.'
                        )
            else:
                if not Settings.quiet:
                    print('No need to update.\n')

                for data in self.files:
                    Helpers.File(self.destination + self.files[data]).delete()
    def execute(self):
        """
        Execute the installation or production logic.
        """

        replacement_production = {
            'to_replace': [
                'official_status_index', 'official_down_status',
                'official_up_status', 'auto_continue', 'command_before_end',
                'custom_ip', 'days_between_db_retest', 'debug', 'domain',
                'generate_hosts', 'header_printed', 'to_filter', 'less',
                'logs', 'plain_list_domain', 'quiet', 'referer',
                'seconds_before_http_timeout', 'share_logs',
                'show_execution_time', 'show_percentage', 'split_files',
                'travis', 'travis_autosave_minutes', 'travis_autosave_commit',
                'travis_autosave_final_commit', 'unified_file', 'link_to_repo',
                'iana_server', 'current_datetime', 'number_of_tested',
                'number_of_up', 'number_of_down', 'number_of_invalid',
                'http_code_status', 'http_code', 'cleaned_done', 'current_dir'
            ]
        }

        replacement_installation = {
            'current_dir': r"current_dir = '%%current_dir%%'"
        }

        replacement_list = {}

        if self.production:
            replacement_list = replacement_production
        else:
            replacement_list = replacement_installation

            if self.data_to_install is not None:
                replacement_list.update(self.data_to_install)

        script = Helpers.File(self.file_to_install).read()

        for to_replace in replacement_list:
            if to_replace == 'to_replace' or to_replace == 'to_install':
                for variable in replacement_list[to_replace]:

                    if to_replace == 'to_install':
                        replacement = variable + ' = ' + \
                            str(replacement_list[to_replace][variable])
                    else:
                        replacement = variable + ' = ' + \
                            self.default_values()[variable]

                    script = Helpers.Regex(script,
                                           variable + ' = .*',
                                           replace_with=replacement,
                                           occurences=1).replace()
            else:
                replacement = to_replace + ' = ' + \
                    self.default_values()[to_replace]

                script = Helpers.Regex(script,
                                       replacement_list[to_replace],
                                       replace_with=replacement,
                                       occurences=1).replace()

        Helpers.File(self.file_to_install).write(script, True)

        if not Settings.quiet:
            print(Settings.done)