Beispiel #1
0
    def tests_with_prefix(self):
        """
        Test the case that a line has a decorator.

        For example:
        ::

            127.0.0.1 google.com
        """

        for domain in self.domains:
            expected = domain

            data = "0.0.0.0 %s" % domain
            actual = Core._format_domain(data)

            self.assertEqual(expected, actual)

        for domain in self.domains:
            expected = domain

            data = "127.0.0.1 %s" % domain
            actual = Core._format_domain(data)

            self.assertEqual(expected, actual)
Beispiel #2
0
    def tests_reset_counters(self):
        """
        This method will test if the counter is reseted.
        """

        Core.reset_counters()

        for string in self.types:
            expected = 0
            actual = PyFunceble.CONFIGURATION["counter"]["number"][string]
            self.assertEqual(expected, actual)
Beispiel #3
0
    def tests_reset_counters(self):
        """
        Test if the counter is reseted.
        """

        Core.reset_counters()

        for string in self.types:
            expected = 0
            actual = PyFunceble.INTERN["counter"]["number"][string]

            self.assertEqual(expected, actual)
Beispiel #4
0
    def tests_quiet_colored_logo(self):
        """
        This method test if the logo is not printed when quiet is activated.
        """

        PyFunceble.CONFIGURATION["quiet"] = True

        Core.colored_logo()

        expected = ""
        actual = sys.stdout.getvalue()

        self.assertEqual(expected, actual)
Beispiel #5
0
    def tests_colored_logo_red(self):
        """
        This method test if the logo is red colored.
        """

        PyFunceble.CONFIGURATION["counter"]["percentage"]["up"] = 1

        Core.colored_logo()

        expected = self.logo_red
        actual = sys.stdout.getvalue()

        self.assertEqual(expected, actual)

        PyFunceble.CONFIGURATION["counter"]["percentage"]["up"] = 0
Beispiel #6
0
    def tests_colored_logo_green(self):
        """
        Test if the logo is green colored.
        """

        PyFunceble.CONFIGURATION["counter"]["percentage"]["up"] = 51

        Core.colorify_logo()

        expected = self.logo_green + "\n"
        actual = sys.stdout.getvalue()

        self.assertEqual(expected, actual)

        PyFunceble.CONFIGURATION["counter"]["percentage"]["up"] = 0
Beispiel #7
0
    def tests_colored_logo_red(self):
        """
        Test if the logo is red colored.
        """

        PyFunceble.INTERN["counter"]["percentage"]["up"] = 1

        Core.colorify_logo()

        expected = self.logo_red + "\n"
        actual = sys.stdout.getvalue()

        self.assertEqual(expected, actual)

        PyFunceble.INTERN["counter"]["percentage"]["up"] = 0
Beispiel #8
0
def test(domain):  # pragma: no cover
    """
    This function provide an access to the core while use PyFunceble as an imported module.
    """

    load_config()
    return Core(domain=domain, modulo_test=True).test()
Beispiel #9
0
def url_test(url, complete=False):  # pragma: no covere
    """
    Test the availability of the given URL.

    :param url: The URL to test.
    :type url: str

    :param complete:
        Activate the return of a dict with some significant data from
        the test.
    :type complete: bool

    :return: The status or the informations of the URL.
    :rtype: str|dict

    .. note::
        This function abstract and simplify for the access to the core for the
        end-user.
    """

    # We silently load the configuration.
    load_config(True)

    # And we return the status of the given URL.
    return Core(url_to_test=url, modulo_test=True).test(complete)
Beispiel #10
0
    def test_extracting_from_file(self, mock_isfile):
        """
        This method test the extraction.
        """

        mock_isfile.return_value = True

        actual = [
            "google.com # Leaked ?",
            "facebook.com # Was it a breach or not ?",
            "#This should be ignored",
        ]
        expected = [
            "google.com # Leaked ?", "facebook.com # Was it a breach or not ?"
        ]

        with mock.patch("builtins.open") as mock_open:
            mock_open.return_value.__enter__ = mock_open
            mock_open.return_value.__iter__ = mock.Mock(
                return_value=iter(actual))

            PyFunceble.CONFIGURATION["file_to_test"] = mock_open

            self.assertEqual(expected, Core._extract_domain_from_file())

        del PyFunceble.CONFIGURATION["file_to_test"]
Beispiel #11
0
    def test_adblock_decode(self):
        """
        This method test that the adblock decoding system is working proprely
        """

        actual = Core.adblock_decode(Core, self.lines)

        self.assertEqual(self.expected, actual)
Beispiel #12
0
    def __init__(self, list_to_test, clean_all=False):
        if list_to_test:
            # The list to test is not empty.

            try:
                # We try to see if we have to reset counters and clean the output directory.

                # We get the number of tested.
                number_of_tested = PyFunceble.CONFIGURATION["counter"]["number"][
                    "tested"
                ]

                if (
                    number_of_tested == 0
                    or list_to_test[number_of_tested - 1] == list_to_test[-1]
                    or number_of_tested >= len(list_to_test)
                ):
                    # * If the number of tested is null,
                    # or
                    # * the last tested element is the same as the last element in the
                    #   sequence,
                    # or
                    # * The number of tested is equal to the number of elements in the
                    #   sequence,

                    # We reset the counters.
                    Core.reset_counters()

                    # We clean the output directory.
                    self.almost_everything(clean_all)
            except IndexError:
                # But if at any time in the conditionnal an Index Error occurs,

                # We reset the counters.
                Core.reset_counters()

                # We clean the output directory.
                self.almost_everything(clean_all)
        else:
            # The list to test is empty.

            # We clean the output directory.
            self.almost_everything(clean_all)
Beispiel #13
0
    def tests_simple_line(self):
        """
        Test the case that we encouter a simple line without decorator.
        """

        for domain in self.domains:
            expected = domain
            actual = Core._format_domain(domain)

            self.assertEqual(expected, actual)
Beispiel #14
0
    def tests_with_multiple_tabs(self):
        """
        Test the case that we have multiple tabs as sparator between
        our domain end its prefix.
        """

        for domain in self.domains:
            expected = domain

            data = "0.0.0.0\t\t\t\t\t\t\t\t\t\t%s" % domain
            actual = Core._format_domain(data)

            self.assertEqual(expected, actual)

        for domain in self.domains:
            expected = domain

            data = "127.0.0.1\t\t\t\t\t\t\t\t\t\t\t%s" % domain
            actual = Core._format_domain(data)

            self.assertEqual(expected, actual)
Beispiel #15
0
    def tests_ends_with_comment(self):
        """
        Test the case that a line has a comment at the end of its line.
        """

        for domain in self.domains:
            expected = domain

            data = "%s # hello world" % domain
            actual = Core._format_domain(data)

            self.assertEqual(expected, actual)
Beispiel #16
0
    def tests_comment(self):
        """
        Test the case that we encouter a commented line.
        """

        for domain in self.domains:
            expected = ""

            data = "# %s" % domain
            actual = Core._format_domain(data)

            self.assertEqual(expected, actual)
Beispiel #17
0
    def tests_multiple_spaces(self):
        """
        This method test the case that we have multiple space as sparator between
        our domain end its prefix.
        """

        for domain in self.domains:
            expected = domain

            data = "0.0.0.0                %s" % domain
            actual = Core._format_domain(data)

            self.assertEqual(expected, actual)

        for domain in self.domains:
            expected = domain

            data = "127.0.0.1                %s" % domain
            actual = Core._format_domain(data)

            self.assertEqual(expected, actual)
Beispiel #18
0
    def test_index_not_exist(self):
        """
        Test the case that the switched data does not exist into
        the configuration system.
        """

        to_switch = "helloworld"

        self.assertRaisesRegex(
            Exception,
            self.exception_message % repr(to_switch),
            lambda: Core.switch(to_switch),
        )
Beispiel #19
0
    def test_switch_false(self):
        """
        Test the case that we want to switch a switch which is set
        to False.
        """

        PyFunceble.CONFIGURATION["helloworld"] = False

        expected = True
        actual = Core.switch("helloworld")

        self.assertEqual(expected, actual)

        del PyFunceble.CONFIGURATION["helloworld"]
Beispiel #20
0
def url_test(url, complete=False, config=None):  # pragma: no covere
    """
    Test the availability of the given URL.

    :param url: The URL to test.
    :type url: str

    :param complete:
        Activate the return of a dict with some significant data from
        the test.
    :type complete: bool

    :param config:
        A dict with the configuration index (from .PyFunceble.yaml) to update.
    :type config: dict

    :return: The status or the informations of the URL.
    :rtype: str|dict

    .. warning::
        If an empty or a non-string :code:`url` is given, we return :code:`None`.

    .. warning::
        If :code:`config` is given, the given :code:`dict` overwrite
        the last value of the given indexes.

    """

    if url and isinstance(url, str):
        # The given URL is not empty nor None.
        # and
        # * The given URL is a string.

        # We silently load the configuration.
        load_config(True)

        if config and isinstance(config, dict):
            # The given configuration is not None or empty.
            # and
            # It is a dict.

            # We update the configuration index.
            CONFIGURATION.update(config)

        # And we return the status of the given URL.
        return Core(url_to_test=url, modulo_test=True).test(complete)

    # We return None, there is nothing to test.
    return None
Beispiel #21
0
    def test_switch_value_is_not_bool(self):
        """
        Test the case that we want to switch a switch which is not
        in bool format.
        """
        PyFunceble.CONFIGURATION["helloworld"] = "Hello, World!"

        to_switch = "helloworld"

        self.assertRaisesRegex(
            Exception,
            self.exception_message % repr(to_switch),
            lambda: Core.switch(to_switch),
        )

        del PyFunceble.CONFIGURATION["helloworld"]
Beispiel #22
0
def test(domain, complete=False, config=None):  # pragma: no cover
    """
    Test the availability of the given domain or IP.

    :param domain: The domain or IP to test.
    :type domain: str

    :param complete:
        Activate the return of a dict with some significant data from
        the test.
    :type complete: bool

    :param config:
        A dict with the configuration index (from .PyFunceble.yaml) to update.
    :type config: dict

    :return: The status or the informations of the domain.
    :rtype: str|dict

    .. warning::
        If an empty or a non-string :code:`domain` is given, we return :code:`None`.

    .. warning::
        If :code:`config` is given, the given :code:`dict` overwrite
        the last value of the given indexes.

    .. note::
        If :code:`complete` is set to :code:`True`, we return the following indexes.

        ::

            {
                "_status_source": None,
                "_status": None,
                "domain_syntax_validation": None,
                "expiration_date": None,
                "http_status_code": None,
                "ip4_syntax_validation": None,
                "nslookup": [],
                "status_source": None,
                "status": None,
                "tested": None,
                "url_syntax_validation": None,
                "whois_record": None,
                "whois_server": None,
            }
    """

    if domain and isinstance(domain, str):
        # * The given domain is not empty nor None.
        # and
        # * The given domain is a string.

        # We silently load the configuration.
        load_config(True)

        if config and isinstance(config, dict):
            # The given configuration is not None or empty.
            # and
            # It is a dict.

            # We update the configuration index.
            CONFIGURATION.update(config)

        # And we return the status of the given domain.
        return Core(domain_or_ip_to_test=domain, modulo_test=True).test(complete)

    # We return None, there is nothing to test.
    return None
Beispiel #23
0
def command_line():  # pragma: no cover  # pylint: disable=too-many-branches,too-many-statements
    """
    This function provide the command line arguments of PyFunceble.
    """

    if __name__ == "PyFunceble":
        load_config()

        initiate(autoreset=True)

        PARSER = argparse.ArgumentParser(
            description='A tool to check domains or IP availability \
            (ACTIVE, INACTIVE, INVALID). Also described as "[an] excellent \
            script for checking ACTIVE and INACTIVE domain names"',
            epilog="Crafted with %s by %s" % (
                Fore.RED + "♥" + Fore.RESET,
                Style.BRIGHT + Fore.CYAN + "Nissar Chababy (Funilrys) " +
                Style.RESET_ALL + "with the help of " + Style.BRIGHT +
                Fore.GREEN + "https://git.io/vND4m " + Style.RESET_ALL +
                "&& " + Style.BRIGHT + Fore.GREEN + "https://git.io/vND4a",
            ),
            add_help=False,
        )

        CURRENT_VALUE_FORMAT = Fore.YELLOW + Style.BRIGHT + "Installed value: " + Fore.BLUE

        PARSER.add_argument(
            "-ad",
            "--adblock",
            action="store_true",
            help="Switch the decoding of the adblock format. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["adblock"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "-a",
            "--all",
            action="store_false",
            help="Output all available informations on screen. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["less"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--cmd-before-end",
            type=str,
            help="Pass a command before the results (final) commit of travis \
            mode. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["command_before_end"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "-c",
            "--auto-continue",
            "--continue",
            action="store_true",
            help="Switch the value of the auto continue mode. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["auto_continue"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--autosave-minutes",
            type=int,
            help="Update the minimum of minutes before we start commiting \
                to upstream under Travis CI. %s" %
            (CURRENT_VALUE_FORMAT +
             repr(CONFIGURATION["travis_autosave_minutes"]) + Style.RESET_ALL),
        )
        PARSER.add_argument("--clean",
                            action="store_true",
                            help="Clean all files under output.")
        PARSER.add_argument(
            "--commit-autosave-message",
            type=str,
            help="Replace the default autosave commit message. %s" %
            (CURRENT_VALUE_FORMAT +
             repr(CONFIGURATION["travis_autosave_commit"]) + Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--commit-results-message",
            type=str,
            help="Replace the default results (final) commit message. %s" %
            (CURRENT_VALUE_FORMAT +
             repr(CONFIGURATION["travis_autosave_final_commit"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument("-d",
                            "--domain",
                            type=str,
                            help="Analyze the given domain.")
        PARSER.add_argument(
            "-db",
            "--database",
            action="store_true",
            help="Switch the value of the usage of a database to store \
                inactive domains of the currently tested list. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["inactive_database"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "-dbr",
            "--days-between-db-retest",
            type=int,
            help=
            "Set the numbers of day(s) between each retest of domains present \
            into inactive-db.json. %s" %
            (CURRENT_VALUE_FORMAT +
             repr(CONFIGURATION["days_between_db_retest"]) + Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--debug",
            action="store_true",
            help="Switch the value of the debug mode. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["debug"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--directory-structure",
            action="store_true",
            help=
            "Generate the directory and files that are needed and which does \
                not exist in the current directory.",
        )
        PARSER.add_argument("-f",
                            "--file",
                            type=str,
                            help="Test a file with a list of domains.")
        PARSER.add_argument("--filter", type=str, help="Domain to filter.")
        PARSER.add_argument(
            "-ex",
            "--execution",
            action="store_true",
            help="Switch the dafault value of the execution time showing. %s" %
            (CURRENT_VALUE_FORMAT +
             repr(CONFIGURATION["show_execution_time"]) + Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--help",
            action="help",
            default=argparse.SUPPRESS,
            help="Show this help message and exit.",
        )
        PARSER.add_argument(
            "-h",
            "--host",
            action="store_true",
            help="Switch the value of the generation of hosts file. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["generate_hosts"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--http",
            action="store_true",
            help="Switch the value of the usage of HTTP code. %s" %
            (CURRENT_VALUE_FORMAT + repr(HTTP_CODE["active"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument("--iana",
                            action="store_true",
                            help="Update `iana-domains-db.json`.")
        PARSER.add_argument(
            "-ip",
            type=str,
            help="Change the ip to print in host file. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["custom_ip"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--less",
            action="store_true",
            help="Output less informations on screen. %s" %
            (CURRENT_VALUE_FORMAT + repr(Core.switch("less")) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "-n",
            "--no-files",
            action="store_true",
            help="Switch the value the production of output files. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["no_files"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "-nl",
            "--no-logs",
            action="store_true",
            help="Switch the value of the production of logs files in case we \
            encounter some errors. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["logs"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "-nu",
            "--no-unified",
            action="store_true",
            help=
            "Switch the value of the production of result.txt as unified result \
                under the output directory. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["unified"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "-nw",
            "--no-whois",
            action="store_true",
            help=
            "Switch the value the usage of whois to test domain's status. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["no_whois"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "-p",
            "--percentage",
            action="store_true",
            help="Switch the value of the percentage output mode. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["show_percentage"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--plain",
            action="store_true",
            help="Switch the value of the generation \
                of the plain list of domain. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["plain_list_domain"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--production",
            action="store_true",
            help="Prepare the repository for production.",
        )
        PARSER.add_argument(
            "-q",
            "--quiet",
            action="store_true",
            help="Run the script in quiet mode. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["quiet"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--share-logs",
            action="store_true",
            help=
            "Activate the sharing of logs to an API which helps manage logs in \
                order to make PyFunceble a better script. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["share_logs"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "-s",
            "--simple",
            action="store_true",
            help="Switch the value of the simple output mode. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["simple"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--split",
            action="store_true",
            help=
            "Switch the valur of the split of the generated output files. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["inactive_database"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "-t",
            "--timeout",
            type=int,
            default=3,
            help="Switch the value of the timeout. %s" %
            (CURRENT_VALUE_FORMAT +
             repr(CONFIGURATION["seconds_before_http_timeout"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--travis",
            action="store_true",
            help="Activate the travis mode. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["travis"]) +
             Style.RESET_ALL),
        )
        PARSER.add_argument(
            "--travis-branch",
            type=str,
            default="master",
            help="Switch the branch name where we are going to push. %s" %
            (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["travis_branch"]) +
             Style.RESET_ALL),
        )

        PARSER.add_argument("-u",
                            "--url",
                            type=str,
                            help="Analyze the given url.")

        PARSER.add_argument("-uf",
                            "--url-file",
                            type=str,
                            help="Test a file with a list of URL.")

        PARSER.add_argument("-v",
                            "--version",
                            action="version",
                            version="%(prog)s " + VERSION)

        ARGS = PARSER.parse_args()

        if ARGS.less:
            CONFIGURATION.update({"less": ARGS.less})

        if ARGS.adblock:
            CONFIGURATION.update({"adblock": Core.switch("adblock")})

        if ARGS.auto_continue:
            CONFIGURATION.update(
                {"auto_continue": Core.switch("auto_continue")})

        if ARGS.autosave_minutes:
            CONFIGURATION.update(
                {"travis_autosave_minutes": ARGS.autosave_minutes})

        if ARGS.clean:
            Clean(None)

        if ARGS.cmd_before_end:
            CONFIGURATION.update({"command_before_end": ARGS.cmd_before_end})

        if ARGS.commit_autosave_message:
            CONFIGURATION.update(
                {"travis_autosave_commit": ARGS.commit_autosave_message})

        if ARGS.commit_results_message:
            CONFIGURATION.update(
                {"travis_autosave_final_commit": ARGS.commit_results_message})

        if ARGS.database:
            CONFIGURATION.update(
                {"inactive_database": Core.switch("inactive_database")})

        if ARGS.days_between_db_retest:
            CONFIGURATION.update(
                {"days_between_db_retest": ARGS.days_between_db_retest})

        if ARGS.debug:
            CONFIGURATION.update({"debug": Core.switch("debug")})

        if ARGS.directory_structure:
            DirectoryStructure()

        if ARGS.execution:
            CONFIGURATION.update(
                {"show_execution_time": Core.switch("show_execution_time")})

        if ARGS.filter:
            CONFIGURATION.update({"to_filter": ARGS.filter})

        if ARGS.host:
            CONFIGURATION.update(
                {"generate_hosts": Core.switch("generate_hosts")})

        if ARGS.http:
            HTTP_CODE.update(
                {"active": Core.switch(HTTP_CODE["active"], True)})

        if ARGS.iana:
            IANA()

        if ARGS.ip:
            CONFIGURATION.update({"custom_ip": ARGS.ip})

        if ARGS.no_files:
            CONFIGURATION.update({"no_files": Core.switch("no_files")})

        if ARGS.no_logs:
            CONFIGURATION.update({"logs": Core.switch("logs")})

        if ARGS.no_unified:
            CONFIGURATION.update({"unified": Core.switch("unified")})

        if ARGS.no_whois:
            CONFIGURATION.update({"no_whois": Core.switch("no_whois")})

        if ARGS.percentage:
            CONFIGURATION.update(
                {"show_percentage": Core.switch("show_percentage")})

        if ARGS.plain:
            CONFIGURATION.update(
                {"plain_list_domain": Core.switch("plain_list_domain")})

        if ARGS.production:
            Production()

        if ARGS.quiet:
            CONFIGURATION.update({"quiet": Core.switch("quiet")})

        if ARGS.share_logs:
            CONFIGURATION.update({"share_logs": Core.switch("share_logs")})

        if ARGS.simple:
            CONFIGURATION.update({
                "simple": Core.switch("simple"),
                "quiet": Core.switch("quiet")
            })

        if ARGS.split:
            CONFIGURATION.update({"split": Core.switch("split")})

        if ARGS.timeout:
            if ARGS.timeout % 3 == 0:
                CONFIGURATION.update(
                    {"seconds_before_http_timeout": ARGS.timeout})

        if ARGS.travis:
            CONFIGURATION.update({"travis": Core.switch("travis")})

        if ARGS.travis_branch:
            CONFIGURATION.update({"travis_branch": ARGS.travis_branch})

        if not CONFIGURATION["quiet"]:
            print(Fore.YELLOW + ASCII_PYFUNCEBLE + Fore.RESET)

        Version().compare()
        Core(
            domain=ARGS.domain,
            file_path=ARGS.file,
            url_to_test=ARGS.url,
            url_file=ARGS.url_file,
        )
Beispiel #24
0
def _command_line():  # pragma: no cover pylint: disable=too-many-branches,too-many-statements
    """
    Provide the command line interface.
    """

    if __name__ == "PyFunceble":
        # We initiate the end of the coloration at the end of each line.
        initiate(autoreset=True)

        # We load the configuration and the directory structure.
        load_config(True)
        try:
            # The following handle the command line argument.

            try:
                PARSER = argparse.ArgumentParser(
                    epilog="Crafted with %s by %s" % (
                        Fore.RED + "♥" + Fore.RESET,
                        Style.BRIGHT + Fore.CYAN +
                        "Nissar Chababy (Funilrys) " + Style.RESET_ALL +
                        "with the help of " + Style.BRIGHT + Fore.GREEN +
                        "https://pyfunceble.rtfd.io/en/master/contributors.html "
                        + Style.RESET_ALL + "&& " + Style.BRIGHT + Fore.GREEN +
                        "https://pyfunceble.rtfd.io/en/master/special-thanks.html",
                    ),
                    add_help=False,
                )

                CURRENT_VALUE_FORMAT = (Fore.YELLOW + Style.BRIGHT +
                                        "Configured value: " + Fore.BLUE)

                PARSER.add_argument(
                    "-ad",
                    "--adblock",
                    action="store_true",
                    help="Switch the decoding of the adblock format. %s" %
                    (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["adblock"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-a",
                    "--all",
                    action="store_false",
                    help="Output all available information on the screen. %s" %
                    (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["less"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    ""
                    "-c",
                    "--auto-continue",
                    "--continue",
                    action="store_true",
                    help="Switch the value of the auto continue mode. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["auto_continue"]) + Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--autosave-minutes",
                    type=int,
                    help="Update the minimum of minutes before we start "
                    "committing to upstream under Travis CI. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["travis_autosave_minutes"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument("--clean",
                                    action="store_true",
                                    help="Clean all files under output.")

                PARSER.add_argument(
                    "--clean-all",
                    action="store_true",
                    help=
                    "Clean all files under output and all file generated by PyFunceble.",
                )

                PARSER.add_argument(
                    "--cmd",
                    type=str,
                    help="Pass a command to run before each commit "
                    "(except the final one) under the Travis mode. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["command_before_end"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--cmd-before-end",
                    type=str,
                    help="Pass a command to run before the results "
                    "(final) commit under the Travis mode. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["command_before_end"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--commit-autosave-message",
                    type=str,
                    help="Replace the default autosave commit message. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["travis_autosave_commit"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--commit-results-message",
                    type=str,
                    help=
                    "Replace the default results (final) commit message. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["travis_autosave_final_commit"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument("-d",
                                    "--domain",
                                    type=str,
                                    help="Set and test the given domain.")

                PARSER.add_argument(
                    "-db",
                    "--database",
                    action="store_true",
                    help="Switch the value of the usage of a database to store "
                    "inactive domains of the currently tested list. %s" %
                    (CURRENT_VALUE_FORMAT + repr(
                        CONFIGURATION["inactive_database"]) + Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-dbr",
                    "--days-between-db-retest",
                    type=int,
                    help=
                    "Set the numbers of days between each retest of domains present "
                    "into inactive-db.json. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["days_between_db_retest"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--debug",
                    action="store_true",
                    help="Switch the value of the debug mode. %s" %
                    (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["debug"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--directory-structure",
                    action="store_true",
                    help=
                    "Generate the directory and files that are needed and which does "
                    "not exist in the current directory.",
                )

                PARSER.add_argument(
                    "-ex",
                    "--execution",
                    action="store_true",
                    help=
                    "Switch the default value of the execution time showing. %s"
                    % (CURRENT_VALUE_FORMAT +
                       repr(CONFIGURATION["show_execution_time"]) +
                       Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-f",
                    "--file",
                    type=str,
                    help="Read the given file and test all domains inside it. "
                    "If a URL is given we download and test the content of the given URL.",  # pylint: disable=line-too-long
                )

                PARSER.add_argument("--filter",
                                    type=str,
                                    help="Domain to filter (regex).")

                PARSER.add_argument(
                    "--help",
                    action="help",
                    default=argparse.SUPPRESS,
                    help="Show this help message and exit.",
                )

                PARSER.add_argument(
                    "--hierarchical",
                    action="store_true",
                    help=
                    "Switch the value of the hierarchical sorting of the tested file. %s"
                    % (CURRENT_VALUE_FORMAT +
                       repr(CONFIGURATION["hierarchical_sorting"]) +
                       Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-h",
                    "--host",
                    action="store_true",
                    help="Switch the value of the generation of hosts file. %s"
                    %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["generate_hosts"]) + Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--http",
                    action="store_true",
                    help="Switch the value of the usage of HTTP code. %s" %
                    (CURRENT_VALUE_FORMAT + repr(HTTP_CODE["active"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--iana",
                    action="store_true",
                    help="Update/Generate `iana-domains-db.json`.",
                )

                PARSER.add_argument(
                    "--idna",
                    action="store_true",
                    help="Switch the value of the IDNA conversion. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["idna_conversion"]) + Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-ip",
                    type=str,
                    help=
                    "Change the IP to print in the hosts files with the given one. %s"
                    % (CURRENT_VALUE_FORMAT +
                       repr(CONFIGURATION["custom_ip"]) + Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--json",
                    action="store_true",
                    help="Switch the value of the generation "
                    "of the JSON formatted list of domains. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["generate_json"]) + Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--less",
                    action="store_true",
                    help="Output less informations on screen. %s" %
                    (CURRENT_VALUE_FORMAT + repr(Core.switch("less")) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--local",
                    action="store_true",
                    help="Switch the value of the local network testing. %s" %
                    (CURRENT_VALUE_FORMAT + repr(Core.switch("local")) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument("--link",
                                    type=str,
                                    help="Download and test the given file.")

                PARSER.add_argument(
                    "-m",
                    "--mining",
                    action="store_true",
                    help="Switch the value of the mining subsystem usage. %s" %
                    (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["mining"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-n",
                    "--no-files",
                    action="store_true",
                    help=
                    "Switch the value of the production of output files. %s" %
                    (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["no_files"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-nl",
                    "--no-logs",
                    action="store_true",
                    help="Switch the value of the production of logs files "
                    "in the case we encounter some errors. %s" %
                    (CURRENT_VALUE_FORMAT + repr(not CONFIGURATION["logs"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-nu",
                    "--no-unified",
                    action="store_true",
                    help="Switch the value of the production unified logs "
                    "under the output directory. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(not CONFIGURATION["unified"]) + Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-nw",
                    "--no-whois",
                    action="store_true",
                    help=
                    "Switch the value the usage of whois to test domain's status. %s"
                    % (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["no_whois"]) +
                       Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-p",
                    "--percentage",
                    action="store_true",
                    help="Switch the value of the percentage output mode. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["show_percentage"]) + Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--plain",
                    action="store_true",
                    help="Switch the value of the generation "
                    "of the plain list of domains. %s" %
                    (CURRENT_VALUE_FORMAT + repr(
                        CONFIGURATION["plain_list_domain"]) + Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--production",
                    action="store_true",
                    help="Prepare the repository for production.",
                )

                PARSER.add_argument(
                    "-psl",
                    "--public-suffix",
                    action="store_true",
                    help="Update/Generate `public-suffix.json`.",
                )

                PARSER.add_argument(
                    "-q",
                    "--quiet",
                    action="store_true",
                    help="Run the script in quiet mode. %s" %
                    (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["quiet"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--share-logs",
                    action="store_true",
                    help="Switch the value of the sharing of logs. %s" %
                    (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["share_logs"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-s",
                    "--simple",
                    action="store_true",
                    help="Switch the value of the simple output mode. %s" %
                    (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["simple"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--split",
                    action="store_true",
                    help=
                    "Switch the value of the split of the generated output files. %s"
                    % (CURRENT_VALUE_FORMAT + repr(
                        CONFIGURATION["inactive_database"]) + Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--syntax",
                    action="store_true",
                    help="Switch the value of the syntax test mode. %s" %
                    (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["syntax"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-t",
                    "--timeout",
                    type=int,
                    default=3,
                    help="Switch the value of the timeout. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["seconds_before_http_timeout"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--travis",
                    action="store_true",
                    help="Switch the value of the Travis mode. %s" %
                    (CURRENT_VALUE_FORMAT + repr(CONFIGURATION["travis"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "--travis-branch",
                    type=str,
                    default="master",
                    help="Switch the branch name where we are going to push. %s"
                    % (CURRENT_VALUE_FORMAT +
                       repr(CONFIGURATION["travis_branch"]) + Style.RESET_ALL),
                )

                PARSER.add_argument("-u",
                                    "--url",
                                    type=str,
                                    help="Analyze the given URL.")

                PARSER.add_argument(
                    "-uf",
                    "--url-file",
                    type=str,
                    help="Read and test the list of URL of the given file. "
                    "If a URL is given we download and test the content of the given URL.",  # pylint: disable=line-too-long
                )

                PARSER.add_argument(
                    "-ua",
                    "--user-agent",
                    type=str,
                    help="Set the user-agent to use and set every time we "
                    "interact with everything which is not our logs sharing system.",  # pylint: disable=line-too-long
                )

                PARSER.add_argument(
                    "-v",
                    "--version",
                    help="Show the version of PyFunceble and exit.",
                    action="version",
                    version="%(prog)s " + VERSION,
                )

                PARSER.add_argument(
                    "-vsc",
                    "--verify-ssl-certificate",
                    action="store_true",
                    help="Switch the value of the verification of the "
                    "SSL/TLS certificate when testing for URL. %s" %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["verify_ssl_certificate"]) +
                     Style.RESET_ALL),
                )

                PARSER.add_argument(
                    "-wdb",
                    "--whois-database",
                    action="store_true",
                    help="Switch the value of the usage of a database to store "
                    "whois data in order to avoid whois servers rate limit. %s"
                    %
                    (CURRENT_VALUE_FORMAT +
                     repr(CONFIGURATION["whois_database"]) + Style.RESET_ALL),
                )

                ARGS = PARSER.parse_args()

                if ARGS.less:
                    CONFIGURATION.update({"less": ARGS.less})
                elif not ARGS.all:
                    CONFIGURATION.update({"less": ARGS.all})

                if ARGS.adblock:
                    CONFIGURATION.update({"adblock": Core.switch("adblock")})

                if ARGS.auto_continue:
                    CONFIGURATION.update(
                        {"auto_continue": Core.switch("auto_continue")})

                if ARGS.autosave_minutes:
                    CONFIGURATION.update(
                        {"travis_autosave_minutes": ARGS.autosave_minutes})

                if ARGS.clean:
                    Clean(None)

                if ARGS.clean_all:
                    Clean(None, ARGS.clean_all)

                if ARGS.cmd:
                    CONFIGURATION.update({"command": ARGS.cmd})

                if ARGS.cmd_before_end:
                    CONFIGURATION.update(
                        {"command_before_end": ARGS.cmd_before_end})

                if ARGS.commit_autosave_message:
                    CONFIGURATION.update({
                        "travis_autosave_commit":
                        ARGS.commit_autosave_message
                    })

                if ARGS.commit_results_message:
                    CONFIGURATION.update({
                        "travis_autosave_final_commit":
                        ARGS.commit_results_message
                    })

                if ARGS.database:
                    CONFIGURATION.update({
                        "inactive_database":
                        Core.switch("inactive_database")
                    })

                if ARGS.days_between_db_retest:
                    CONFIGURATION.update({
                        "days_between_db_retest":
                        ARGS.days_between_db_retest
                    })

                if ARGS.debug:
                    CONFIGURATION.update({"debug": Core.switch("debug")})

                if ARGS.directory_structure:
                    DirectoryStructure()

                if ARGS.execution:
                    CONFIGURATION.update({
                        "show_execution_time":
                        Core.switch("show_execution_time")
                    })

                if ARGS.filter:
                    CONFIGURATION.update({"filter": ARGS.filter})

                if ARGS.hierarchical:
                    CONFIGURATION.update({
                        "hierarchical_sorting":
                        Core.switch("hierarchical_sorting")
                    })

                if ARGS.host:
                    CONFIGURATION.update(
                        {"generate_hosts": Core.switch("generate_hosts")})

                if ARGS.http:
                    HTTP_CODE.update(
                        {"active": Core.switch(HTTP_CODE["active"], True)})

                if ARGS.iana:
                    IANA().update()

                if ARGS.idna:
                    CONFIGURATION.update(
                        {"idna_conversion": Core.switch("idna_conversion")})

                if ARGS.ip:
                    CONFIGURATION.update({"custom_ip": ARGS.ip})

                if ARGS.json:
                    CONFIGURATION.update(
                        {"generate_json": Core.switch("generate_json")})

                if ARGS.local:
                    CONFIGURATION.update({"local": Core.switch("local")})

                if ARGS.mining:
                    CONFIGURATION.update({"mining": Core.switch("mining")})

                if ARGS.no_files:
                    CONFIGURATION.update({"no_files": Core.switch("no_files")})

                if ARGS.no_logs:
                    CONFIGURATION.update({"logs": Core.switch("logs")})

                if ARGS.no_unified:
                    CONFIGURATION.update({"unified": Core.switch("unified")})

                if ARGS.no_whois:
                    CONFIGURATION.update({"no_whois": Core.switch("no_whois")})

                if ARGS.percentage:
                    CONFIGURATION.update(
                        {"show_percentage": Core.switch("show_percentage")})

                if ARGS.plain:
                    CONFIGURATION.update({
                        "plain_list_domain":
                        Core.switch("plain_list_domain")
                    })

                if ARGS.production:
                    Production()

                if ARGS.public_suffix:
                    PublicSuffix().update()

                if ARGS.quiet:
                    CONFIGURATION.update({"quiet": Core.switch("quiet")})

                if ARGS.share_logs:
                    CONFIGURATION.update(
                        {"share_logs": Core.switch("share_logs")})

                if ARGS.simple:
                    CONFIGURATION.update({
                        "simple": Core.switch("simple"),
                        "quiet": Core.switch("quiet")
                    })

                if ARGS.split:
                    CONFIGURATION.update({"split": Core.switch("split")})

                if ARGS.syntax:
                    CONFIGURATION.update({"syntax": Core.switch("syntax")})

                if ARGS.timeout and ARGS.timeout % 3 == 0:
                    CONFIGURATION.update(
                        {"seconds_before_http_timeout": ARGS.timeout})

                if ARGS.travis:
                    CONFIGURATION.update({"travis": Core.switch("travis")})

                if ARGS.travis_branch:
                    CONFIGURATION.update({"travis_branch": ARGS.travis_branch})

                if ARGS.user_agent:
                    CONFIGURATION.update({"user_agent": ARGS.user_agent})

                if ARGS.verify_ssl_certificate:
                    CONFIGURATION.update({
                        "verify_ssl_certificate":
                        ARGS.verify_ssl_certificate
                    })

                if ARGS.whois_database:
                    CONFIGURATION.update(
                        {"whois_database": Core.switch("whois_database")})

                if not CONFIGURATION["quiet"]:
                    Core.colorify_logo(home=True)

                # We compare the versions (upstream and local) and in between.
                Version().compare()

                # We call our Core which will handle all case depending of the configuration or
                # the used command line arguments.
                Core(
                    domain_or_ip_to_test=ARGS.domain,
                    file_path=ARGS.file,
                    url_to_test=ARGS.url,
                    url_file=ARGS.url_file,
                    link_to_test=ARGS.link,
                )
            except KeyError as e:
                if not Version(True).is_cloned():
                    # We are not into the cloned version.

                    # We merge the local with the upstream configuration.
                    Merge(CURRENT_DIRECTORY)
                else:
                    # We are in the cloned version.

                    # We raise the exception.
                    #
                    # Note: The purpose of this is to avoid having
                    # to search for a mistake while developing.
                    raise e
        except KeyboardInterrupt:
            stay_safe()