Ejemplo n.º 1
0
    def _get_structure(self):
        """
        This method return the structure we are goinng to work with.
        """

        structure_file = ""
        req = ""

        if path.isfile(self.structure):
            structure_file = self.structure
        elif path.isfile(self.base + "dir_structure_production.json"):
            structure_file = self.base + "dir_structure_production.json"
        else:
            if "dev" not in PyFunceble.VERSION:
                req = requests.get(PyFunceble.LINKS["dir_structure"])
            else:
                req = requests.get(PyFunceble.LINKS["dir_structure"].replace(
                    "master", "dev"))

        if structure_file.endswith("_production.json"):
            structure = Dict().from_json(File(structure_file).read())

            return self._update_structure_from_config(structure)

        elif structure_file.endswith(".json"):
            return Dict().from_json(File(structure_file).read())

        return self._update_structure_from_config(Dict().from_json(req.text))
Ejemplo n.º 2
0
    def test_merge_multilevel(self):
        """
        Test of Dict().merge() for the case that we have a multi level dict/list.
        """

        origin = {
            "hello": {"world": ["This is PyFunceble!", "Uhh!"]},
            "world": "Fun Ilrys",
            "hello_world": {"author": "funilrys", "name": "Fun"},
        }
        to_merge = {
            "hello": {"world": ["hello", "Uhh"]},
            "hello_world": {"author": "nobody", "surname": "body"},
        }

        expected = {
            "hello": {"world": ["hello", "Uhh"]},
            "world": "Fun Ilrys",
            "hello_world": {"author": "nobody", "name": "Fun", "surname": "body"},
        }
        actual = Dict(origin).merge(to_merge, strict=True)

        self.assertEqual(expected, actual)

        expected = {
            "hello": {"world": ["This is PyFunceble!", "Uhh!", "hello", "Uhh"]},
            "world": "Fun Ilrys",
            "hello_world": {"author": "nobody", "name": "Fun", "surname": "body"},
        }
        actual = Dict(origin).merge(to_merge, strict=False)

        self.assertEqual(expected, actual)
Ejemplo n.º 3
0
    def test_rename_key_single(self):
        """
        This method will test Dict().rename_key() for the case that we want to
        rename only one key.
        """

        # Test of the strict case
        expected = {
            "Hello": "world",
            "World": {"world", "hello"},
            "funilrys": ["Fun", "Ilrys"],
            "PyFunceble": "Funceble",
            "pyfunceble": ["funilrys"],
        }

        actual = Dict(self.to_test).rename_key({"Py": "PyFunceble"})

        self.assertEqual(expected, actual)

        # Test of the non-strict case
        expected = {
            "Hello": "world",
            "World": {"world", "hello"},
            "funilrys": ["Fun", "Ilrys"],
            "PyFunceble": "Funceble",
            "pyfunceble": ["funilrys"],
        }

        actual = Dict(self.to_test).rename_key({"fun": "nuf"}, strict=False)
Ejemplo n.º 4
0
    def test_to_yaml(self):
        """
        Test Dict().to_yaml.
        """

        file_to_read = "this_yaml_is_a_ghost.yaml"

        expected = False
        actual = PyFunceble.path.isfile(file_to_read)

        self.assertEqual(expected, actual)

        to_write = {"hello": ["This is PyFunceble!", "Uhh!"], "world": "Fun Ilrys"}

        expected = "{hello: [This is PyFunceble!, Uhh!], world: Fun Ilrys}\n"

        Dict(to_write).to_yaml(file_to_read, flow_style=True)

        expected = """hello:
- This is PyFunceble!
- Uhh!
world: Fun Ilrys
"""

        Dict(to_write).to_yaml(file_to_read, flow_style=False)

        actual = File(file_to_read).read()
        self.assertEqual(expected, actual)

        File(file_to_read).delete()

        expected = False
        actual = PyFunceble.path.isfile(file_to_read)

        self.assertEqual(expected, actual)
Ejemplo n.º 5
0
    def test_to_json(self):
        """
        Tests the method which let us get the JSON
        representation of the given dict.
        """

        expected = """{
    "Hello": "world",
    "Py": "Funceble",
    "World": {
        "world": "hello"
    },
    "funilrys": [
        "Fun",
        "Ilrys"
    ],
    "pyfunceble": [
        "funilrys"
    ]
}"""
        actual = Dict(self.test_subject.copy()).to_json()

        self.assertEqual(expected, actual)

        actual = Dict().from_json(expected)
        expected = self.test_subject.copy()

        self.assertEqual(expected, actual)
Ejemplo n.º 6
0
    def test_has_same_keys_as(self):
        """
        Tests the method which let us know if the keys of
        2 dicts are the same.
        """

        # This is a.
        origin = {"a": 1, "b": 1}

        # This is b.
        target = {"a": 1, "b": 2, "c": {"a": 1, "b": 3, "c": {"x": "x"}}}

        # We want to test that all keys of a are into b.
        self.assertEqual(True, Dict(target).has_same_keys_as(origin))
        # We want to test that all keys of b are into a.
        self.assertEqual(False, Dict(origin).has_same_keys_as(target))

        origin["c"] = {"a": 1, "b": 3, "c": {"x": "x"}}

        # We want to test that all keys of a are in b.
        self.assertEqual(True, Dict(target).has_same_keys_as(origin))
        # We want to test that all keys of b are in a.
        self.assertEqual(True, Dict(origin).has_same_keys_as(target))

        del origin["c"]["c"]
        # We want to test that all keys of b are in a.
        self.assertEqual(False, Dict(origin).has_same_keys_as(target))
Ejemplo n.º 7
0
    def _merge_values(self):
        """
        Simply merge the older into the new one.
        """

        to_remove = []

        self.new_config = Dict(
            Dict(self.upstream_config).merge(
                self.local_config)).remove_key(to_remove)
Ejemplo n.º 8
0
    def _merge_values(self):
        """
        Simply merge the older into the new one.
        """

        to_remove = []

        self.new_config = Dict(
            Dict(self.upstream_config).merge(
                PyFunceble.CONFIGURATION)).remove_key(to_remove)
Ejemplo n.º 9
0
    def _json_print(self):  # pragma: no cover
        """
        Management of the json template.
        """

        if self.output:
            # The given output is not empty.

            if PyFunceble.path.isfile(self.output):
                # The given output already exist.

                # We get the content of the output.
                content = Dict().from_json(self.file_output_instance.read())

                if isinstance(content, list):
                    # The content is a list.

                    # We extend the content with our data to print.
                    content.extend(self.data_to_print)

                    # We format our list.
                    content = List(content).custom_format(Sort.standard)

                    if PyFunceble.CONFIGURATION["hierarchical_sorting"]:
                        # The hierarchical sorting is activated.

                        # We format our content hierarchicaly
                        content = List(content).custom_format(
                            Sort.hierarchical)

                    # We finally save our content into the file.
                    Dict(content).to_json(self.output)
                else:
                    # The content is not a list.

                    # We raise an exception.
                    raise Exception("Output not correctly formatted.")
            else:
                # The given output does not already exist.

                # We save our data to print into the output.
                #
                # Note: We do not have to take care if self.data_to_print is a list
                # formatted or not because this method should not be called if it is
                # not the case.
                Dict(self.data_to_print).to_json(self.output)
        else:
            # The given output is empty.

            # We raise an exception.
            raise Exception("Empty output given.")
Ejemplo n.º 10
0
    def _get_current_version_yaml(cls):
        """
        Get and return the content of version.yaml
        """

        return Dict().from_yaml(
            File(PyFunceble.CURRENT_DIRECTORY + "version.yaml").read())
Ejemplo n.º 11
0
    def test_to_yaml_file_non_dict(self):
        """
        Tests the method which let us save a dict into a YAML file
        for the case that we don't given a dict.
        """

        output_file = "this_file_is_a_ghost"
        File(output_file).delete()

        self.assertRaises(TypeError, lambda: Dict(1).to_yaml_file(output_file))
        self.assertRaises(TypeError, lambda: Dict("100").to_yaml_file(output_file))
        self.assertRaises(
            TypeError, lambda: Dict("{'hello': 'world'}").to_yaml_file(output_file)
        )

        File(output_file).delete()
Ejemplo n.º 12
0
    def test_to_test__path_exist_time_future(self):  # pylint: disable=invalid-name
        """
        Test Inactive.to_test() for the case that the path exist but
        the timestamp is in the future.
        """

        self.test_file_not_exist()

        PyFunceble.INTERN["inactive_db"] = {
            PyFunceble.INTERN["file_to_test"]: {
                self.time_future: ["hello.world", "world.hello"]
            }
        }

        expected = {
            PyFunceble.INTERN["file_to_test"]: {
                self.time_future: ["hello.world", "world.hello"],
                "to_test": [],
            }
        }

        Dict(PyFunceble.INTERN["inactive_db"]).to_json(self.file)
        Inactive().to_test()

        self.assertEqual(expected, PyFunceble.INTERN["inactive_db"])

        del PyFunceble.INTERN["inactive_db"]
        self.test_file_not_exist()
Ejemplo n.º 13
0
    def _timestamp(self):
        """
        Return the timestamp where we are going to save our current list.

        Returns: int or str
            The timestamp to append with the currently tested domains.
        """

        result = 0
        to_delete = []

        if self.file_path in PyFunceble.CONFIGURATION[
                "inactive_db"] and PyFunceble.CONFIGURATION["inactive_db"][
                    self.file_path]:
            for data in PyFunceble.CONFIGURATION["inactive_db"][
                    self.file_path]:
                if data != "to_test":
                    if self.current_time < int(data) + self.day_in_seconds:
                        result = int(data)
                    else:
                        result = self.current_time
                        to_delete.append(data)

            for element in to_delete:
                self._add_to_test(PyFunceble.CONFIGURATION["inactive_db"][
                    self.file_path][element])
            Dict(PyFunceble.CONFIGURATION["inactive_db"][
                self.file_path]).remove_key(to_delete)

            return result

        return self.current_time
Ejemplo n.º 14
0
    def update(self):
        """
        Update of the content of the :code:`public-suffix.json`.
        """

        if not PyFunceble.CONFIGURATION["quiet"]:
            # The quiet mode is not activated.

            # We print a message for the user on screen.
            print(
                "Update of %s" %
                PyFunceble.OUTPUTS["default_files"]["public_suffix"],
                end=" ",
            )

        # We loop through the line of the upstream file.
        list(map(self._extensions, self._data().split("\n")))

        # We save the content of our database in the final testination.
        Dict(self.public_suffix_db).to_json(self.destination)

        if not PyFunceble.CONFIGURATION["quiet"]:
            # The quiet mode is not activated.

            # We inform the user that everything goes right.
            print(PyFunceble.INTERN["done"])
Ejemplo n.º 15
0
    def test_backup(self):
        """
        Test AutoContinue().backup().
        """

        self.test_delete_file()
        PyFunceble.CONFIGURATION["auto_continue"] = True
        self.set_counter(to_set=25)

        AutoContinue().backup()

        expected = True
        actual = PyFunceble.path.isfile(self.file_to_work_with)

        self.assertEqual(expected, actual)

        expected = {
            PyFunceble.INTERN["file_to_test"]: {
                "up": 25,
                "down": 25,
                "invalid": 25,
                "tested": 25,
            }
        }
        actual = Dict().from_json(File(self.file_to_work_with).read())

        self.assertEqual(expected, actual)

        del PyFunceble.CONFIGURATION["auto_continue"]
        self.test_delete_file()
Ejemplo n.º 16
0
    def _load_config_file(self):
        """
        Load .PyFunceble.yaml into the system.
        """

        try:
            # We try to load the configuration file.

            PyFunceble.CONFIGURATION.update(
                Dict.from_yaml(File(self.path_to_config).read()))

            # We install the latest iana configuration file.
            self._install_iana_config()

            # We install the latest public suffix configuration file.
            self._install_psl_config()

            # We install the latest directory structure file.
            self._install_directory_structure_file()
        except FileNotFoundError as exception:
            # But if the configuration file is not found.

            if PyFunceble.path.isfile(self.path_to_default_config):
                # The `DEFAULT_CONFIGURATION_FILENAME` file exists.

                # We copy it as the configuration file.
                File(self.path_to_default_config).copy(self.path_to_config)

                # And we load the configuration file as it does exist (yet).
                self._load_config_file()
            else:
                # The `DEFAULT_CONFIGURATION_FILENAME` file does not exists.

                # We raise the exception we were handling.
                raise exception
Ejemplo n.º 17
0
    def test_save(self):
        """
        Test the saving system.
        """

        File(self.file).delete()

        expected = False
        actual = PyFunceble.path.isfile(self.file)

        self.assertEqual(expected, actual)

        self.mining.database = self.excepted_content
        self.mining.save()

        expected = True
        actual = PyFunceble.path.isfile(self.file)

        self.assertEqual(
            self.excepted_content, Dict().from_json(File(self.file).read())
        )

        File(self.file).delete()

        actual = PyFunceble.path.isfile(self.file)
        expected = False

        self.assertEqual(expected, actual)
Ejemplo n.º 18
0
    def load_config_file(self):
        """
        This method will load .PyFunceble.yaml.
        """

        PyFunceble.CONFIGURATION.update(
            Dict.from_yaml(File(self.path_to_config).read()))
Ejemplo n.º 19
0
    def to_test(self):
        """
        Get the list to test for the next session.
        """

        result = []
        to_delete = []

        self._retrieve()

        if self.file_path in PyFunceble.CONFIGURATION["inactive_db"]:
            for data in PyFunceble.CONFIGURATION["inactive_db"][
                    self.file_path]:
                if data != "to_test":
                    if self.current_time > int(data) + self.day_in_seconds:
                        result.extend(PyFunceble.CONFIGURATION["inactive_db"][
                            self.file_path][data])
                        to_delete.append(data)

            Dict(PyFunceble.CONFIGURATION["inactive_db"][
                self.file_path]).remove_key(to_delete)

            self._add_to_test(result)
        else:
            PyFunceble.CONFIGURATION["inactive_db"].update(
                {self.file_path: {}})

        self._backup()
Ejemplo n.º 20
0
    def update(self):
        """
        Update the content of the `iana-domains-db` file.
        """

        if not PyFunceble.CONFIGURATION["quiet"]:
            # * The quiet mode is not activated.

            # We print on screen what we are doing.
            print("Update of iana-domains-db", end=" ")

        # We loop through the line of the iana website.
        for extension, referer in self._extensions():

            if extension not in self.iana_db or self.iana_db[
                    extension] != referer:
                # We add the extension to the databae.
                self.iana_db[extension] = referer

                # We save the content of the constructed database.
                Dict(self.iana_db).to_json(self.destination)

        if not PyFunceble.CONFIGURATION["quiet"]:
            # The quiet mode is not activated.

            # We indicate that the work is done without any issue.
            print(PyFunceble.INTERN["done"])
Ejemplo n.º 21
0
    def _retrieve(self):
        """
        Retrieve the mining informations.
        """

        if PyFunceble.CONFIGURATION["mining"]:
            # The mining is activated.

            if "mined" not in PyFunceble.INTERN:
                PyFunceble.INTERN["mined"] = {}

            if PyFunceble.path.isfile(self.file):
                # Our backup file exist.

                # We return the information from our backup.
                data = Dict().from_json(File(self.file).read())

                # We clean the empty elements.
                for file_path in data:
                    PyFunceble.INTERN["mined"][file_path] = {}

                    for element in data[file_path]:
                        if data[file_path][element]:
                            PyFunceble.INTERN["mined"][file_path][
                                element] = data[file_path][element]

                return
        # * The mining is not activated.
        # or
        # * Our backup file does not exist.

        # We return nothing.
        PyFunceble.INTERN["mined"] = {}

        return
Ejemplo n.º 22
0
    def clean(self):
        """
        Clean the database.
        """

        if self.authorized:
            # We are authorized to operate.

            if PyFunceble.CONFIGURATION["db_type"] == "json":
                # We empty the database.
                self.database[self.filename] = {}

                # And we save the current database state.
                Dict(self.database).to_json(self.database_file)
            elif PyFunceble.CONFIGURATION["db_type"] == "sqlite":
                # We construct the query we are going to execute.
                query = "DELETE FROM {0} WHERE file_path = :file".format(
                    self.table_name)
                # We execute it.
                self.sqlite_db.cursor.execute(query, {"file": self.filename})
                # We commit everything.
                self.sqlite_db.connection.commit()
            elif PyFunceble.CONFIGURATION["db_type"] in ["mariadb", "mysql"]:
                # We construct the query we are going to execute.
                query = "DELETE FROM {0} WHERE file_path = %(file)s".format(
                    self.table_name)

                with self.mysql_db.get_connection() as cursor:
                    cursor.execute(query, {"file": self.filename})
Ejemplo n.º 23
0
    def test_retrieve_file_exist(self):
        """
        Test the case that we want to retrieve a file that exist.
        """

        File(self.file).delete()

        expected = False
        actual = PyFunceble.path.isfile(self.file)

        self.assertEqual(expected, actual)

        PyFunceble.INTERN["to_test_type"] = "domain"

        Dict(self.excepted_content).to_json(self.file)
        Mining()._retrieve()

        self.assertEqual(self.excepted_content, PyFunceble.INTERN["mined"])

        del PyFunceble.INTERN["mined"]
        del PyFunceble.INTERN["to_test_type"]

        File(self.file).delete()

        expected = False
        actual = PyFunceble.path.isfile(self.file)

        self.assertEqual(expected, actual)
Ejemplo n.º 24
0
    def test_backup(self):
        """
        This function test AutoContinue().backup().
        """

        PyFunceble.CONFIGURATION["auto_continue"] = True

        File(self.file).delete()

        expected = False
        actual = PyFunceble.path.isfile(self.file)

        self.assertEqual(expected, actual)
        self.set_counter(to_set=25)

        AutoContinue().backup()

        expected = True
        actual = PyFunceble.path.isfile(self.file)

        self.assertEqual(expected, actual)

        expected = {
            PyFunceble.CONFIGURATION["file_to_test"]: {
                "up": 25, "down": 25, "invalid": 25, "tested": 25
            }
        }
        actual = Dict().from_json(File(self.file).read())

        self.assertEqual(expected, actual)
        PyFunceble.CONFIGURATION["auto_continue"] = False
        File(self.file).delete()
Ejemplo n.º 25
0
    def test_add_file_path_not_present(self):  # pylint: disable=invalid-name
        """
        Test Inactive.add() for the case that the path is not
        present into the Inactive.
        """

        self.test_file_not_exist()

        timestamp = str(Inactive()._timestamp())
        PyFunceble.INTERN["to_test"] = "hello.world"
        expected = {
            PyFunceble.INTERN["file_to_test"]: {
                timestamp: ["hello.world"]
            }
        }

        Inactive().add()
        actual = Dict().from_json(File(self.file).read())

        self.assertEqual(expected, actual)

        del PyFunceble.INTERN["to_test"]
        del PyFunceble.INTERN["inactive_db"]

        self.test_file_not_exist()
Ejemplo n.º 26
0
    def backup(cls):
        """
        Backup the developer state of `output/` in order to make it restorable
            and portable for user.
        """

        output_path = PyFunceble.CURRENT_DIRECTORY + PyFunceble.OUTPUTS[
            "parent_directory"]
        result = {PyFunceble.OUTPUTS["parent_directory"]: {}}

        for root, _, files in walk(output_path):
            directories = root.split(output_path)[1]

            local_result = result[PyFunceble.OUTPUTS["parent_directory"]]

            for file in files:
                file_path = root + directory_separator + file
                file_hash = Hash(file_path, "sha512", True).get()

                lines_in_list = [line.rstrip("\n") for line in open(file_path)]

                formated_content = "@@@".join(lines_in_list)

                local_result = local_result.setdefault(
                    directories,
                    {file: {
                        "sha512": file_hash,
                        "content": formated_content
                    }},
                )

        Dict(result).to_json(PyFunceble.CURRENT_DIRECTORY +
                             "dir_structure_production.json")
Ejemplo n.º 27
0
    def test_backup(self):
        """
        Test the backup system.
        """

        File(self.file).delete()

        expected = False
        actual = PyFunceble.path.isfile(self.file)

        self.assertEqual(expected, actual)

        PyFunceble.INTERN["mined"] = self.excepted_content
        Mining()._backup()

        expected = True
        actual = PyFunceble.path.isfile(self.file)

        self.assertEqual(self.excepted_content,
                         Dict().from_json(File(self.file).read()))

        del PyFunceble.INTERN["mined"]

        File(self.file).delete()

        actual = PyFunceble.path.isfile(self.file)
        expected = False

        self.assertEqual(expected, actual)
Ejemplo n.º 28
0
    def __init__(self, configuration_path):
        config_link = Version(True).right_url_from_version(
            "https://raw.githubusercontent.com/funilrys/PyFunceble/master/.PyFunceble_production.yaml"  # pylint: disable=line-too-long
        )

        self.path_to_config = configuration_path

        if not self.path_to_config.endswith(PyFunceble.directory_separator):
            self.path_to_config += PyFunceble.directory_separator

        self.path_to_config += PyFunceble.CONFIGURATION_FILENAME

        dict_instance = Dict()

        self.local_config = dict_instance.from_yaml(
            File(self.path_to_config).read())
        self.upstream_config = dict_instance.from_yaml(
            Download(config_link, return_data=True).text())

        if self.upstream_config["links"]["config"] != config_link:
            self.upstream_config = dict_instance.from_yaml(
                Download(self.upstream_config["links"]["config"],
                         return_data=True).text())

        self.new_config = {}

        self._load()
Ejemplo n.º 29
0
    def test_restore_old_system(self):
        """
        This method test AutoContinue().restore() for the case that we run the
        most recent version but with data from the old system.
        """

        PyFunceble.CONFIGURATION["auto_continue"] = True
        File(self.file).delete()

        old_system = {
            PyFunceble.CONFIGURATION["file_to_test"]: {
                "number_of_up": 15,
                "number_of_down": 18,
                "number_of_invalid": 5,
                "number_of_tested": 38,
            }
        }

        Dict(old_system).to_json(self.file)
        AutoContinue().restore()

        expected = {"up": 15, "down": 18, "invalid": 5, "tested": 38}
        actual = PyFunceble.CONFIGURATION["counter"]["number"]

        self.assertEqual(expected, actual)

        self.set_counter(0)

        expected = {"up": 0, "down": 0, "invalid": 0, "tested": 0}
        actual = PyFunceble.CONFIGURATION["counter"]["number"]

        self.assertEqual(expected, actual)
        PyFunceble.CONFIGURATION["auto_continue"] = False
        File(self.file).delete()
Ejemplo n.º 30
0
    def __init__(self):
        if (PyFunceble.CONFIGURATION["auto_continue"]
                and not PyFunceble.CONFIGURATION["no_files"]):
            # * The auto_continue subsystem is activated.
            # and
            # * We are authorized to generate files.

            # We set the log file location.
            self.autocontinue_log_file = (
                PyFunceble.OUTPUT_DIRECTORY +
                PyFunceble.OUTPUTS["parent_directory"] +
                PyFunceble.OUTPUTS["logs"]["filenames"]["auto_continue"])

            if PyFunceble.path.isfile(self.autocontinue_log_file):
                # The log file already exist.

                # We get its content and save it inside backup_content.
                self.backup_content = Dict().from_json(
                    File(self.autocontinue_log_file).read())
            else:
                # The log file does not exist.

                # We initiate the backup content.
                self.backup_content = {}
                # And we save our empty backup_content to the log file.
                File(self.autocontinue_log_file).write(str(
                    self.backup_content))