Current File : //proc/self/root/lib/python3/dist-packages/certbot_apache/_internal/interfaces.py
"""ParserNode interface for interacting with configuration tree.

General description
-------------------

The ParserNode interfaces are designed to be able to contain all the parsing logic,
while allowing their users to interact with the configuration tree in a Pythonic
and well structured manner.

The structure allows easy traversal of the tree of ParserNodes. Each ParserNode
stores a reference to its ancestor and immediate children, allowing the user to
traverse the tree using built in interface methods as well as accessing the interface
properties directly.

ParserNode interface implementation should stand between the actual underlying
parser functionality and the business logic within Configurator code, interfacing
with both. The ParserNode tree is a result of configuration parsing action.

ParserNode tree will be in charge of maintaining the parser state and hence the
abstract syntax tree (AST). Interactions between ParserNode tree and underlying
parser should involve only parsing the configuration files to this structure, and
writing it back to the filesystem - while preserving the format including whitespaces.

For some implementations (Apache for example) it's important to keep track of and
to use state information while parsing conditional blocks and directives. This
allows the implementation to set a flag to parts of the parsed configuration
structure as not being in effect in a case of unmatched conditional block. It's
important to store these blocks in the tree as well in order to not to conduct
destructive actions (failing to write back parts of the configuration) while writing
the AST back to the filesystem.

The ParserNode tree is in charge of maintaining the its own structure while every
child node fetched with find - methods or by iterating its list of children can be
changed in place. When making changes the affected nodes should be flagged as "dirty"
in order for the parser implementation to figure out the parts of the configuration
that need to be written back to disk during the save() operation.


Metadata
--------

The metadata holds all the implementation specific attributes of the ParserNodes -
things like the positional information related to the AST, file paths, whitespacing,
and any other information relevant to the underlying parser engine.

Access to the metadata should be handled by implementation specific methods, allowing
the Configurator functionality to access the underlying information where needed.

For some implementations the node can be initialized using the information carried
in metadata alone. This is useful especially when populating the ParserNode tree
while parsing the configuration.


Apache implementation
---------------------

The Apache implementation of ParserNode interface requires some implementation
specific functionalities that are not described by the interface itself.

Initialization

When the user of a ParserNode class is creating these objects, they must specify
the parameters as described in the documentation for the __init__ methods below.
When these objects are created internally, however, some parameters may not be
needed because (possibly more detailed) information is included in the metadata
parameter. In this case, implementations can deviate from the required parameters
from __init__, however, they should still behave the same when metadata is not
provided.

For consistency internally, if an argument is provided directly in the ParserNode
initialization parameters as well as within metadata it's recommended to establish
clear behavior around this scenario within the implementation.

Conditional blocks

Apache configuration can have conditional blocks, for example: <IfModule ...>,
resulting the directives and subblocks within it being either enabled or disabled.
While find_* interface methods allow including the disabled parts of the configuration
tree in searches a special care needs to be taken while parsing the structure in
order to reflect the active state of configuration.

Whitespaces

Each ParserNode object is responsible of storing its prepending whitespace characters
in order to be able to write the AST back to filesystem like it was, preserving the
format, this applies for parameters of BlockNode and DirectiveNode as well.
When parameters of ParserNode are changed, the pre-existing whitespaces in the
parameter sequence are discarded, as the general reason for storing them is to
maintain the ability to write the configuration back to filesystem exactly like
it was. This loses its meaning when we have to change the directives or blocks
parameters for other reasons.

Searches and matching

Apache configuration is largely case insensitive, so the Apache implementation of
ParserNode interface needs to provide the user means to match block and directive
names and parameters in case insensitive manner. This does not apply to everything
however, for example the parameters of a conditional statement may be case sensitive.
For this reason the internal representation of data should not ignore the case.
"""
import abc
from typing import Any
from typing import Dict
from typing import List
from typing import Optional
from typing import Tuple
from typing import TypeVar

GenericParserNode = TypeVar("GenericParserNode", bound="ParserNode")


class ParserNode(metaclass=abc.ABCMeta):
    """
    ParserNode is the basic building block of the tree of such nodes,
    representing the structure of the configuration. It is largely meant to keep
    the structure information intact and idiomatically accessible.

    The root node as well as the child nodes of it should be instances of ParserNode.
    Nodes keep track of their differences to on-disk representation of configuration
    by marking modified ParserNodes as dirty to enable partial write-to-disk for
    different files in the configuration structure.

    While for the most parts the usage and the child types are obvious, "include"-
    and similar directives are an exception to this rule. This is because of the
    nature of include directives - which unroll the contents of another file or
    configuration block to their place. While we could unroll the included nodes
    to the parent tree, it remains important to keep the context of include nodes
    separate in order to write back the original configuration as it was.

    For parsers that require the implementation to keep track of the whitespacing,
    it's responsibility of each ParserNode object itself to store its prepending
    whitespaces in order to be able to reconstruct the complete configuration file
    as it was when originally read from the disk.

    ParserNode objects should have the following attributes:

    # Reference to ancestor node, or None if the node is the root node of the
    # configuration tree.
    ancestor: Optional[ParserNode]

    # True if this node has been modified since last save.
    dirty: bool

    # Filepath of the file where the configuration element for this ParserNode
    # object resides. For root node, the value for filepath is the httpd root
    # configuration file. Filepath can be None if a configuration directive is
    # defined in for example the httpd command line.
    filepath: Optional[str]

    # Metadata dictionary holds all the implementation specific key-value pairs
    # for the ParserNode instance.
    metadata: Dict[str, Any]
    """
    ancestor: Optional["ParserNode"]
    dirty: bool
    filepath: Optional[str]
    metadata: Dict[str, Any]

    @abc.abstractmethod
    def __init__(self, **kwargs: Any) -> None:
        """
        Initializes the ParserNode instance, and sets the ParserNode specific
        instance variables. This is not meant to be used directly, but through
        specific classes implementing ParserNode interface.

        :param ancestor: BlockNode ancestor for this CommentNode. Required.
        :type ancestor: BlockNode or None

        :param filepath: Filesystem path for the file where this CommentNode
            does or should exist in the filesystem. Required.
        :type filepath: str or None

        :param dirty: Boolean flag for denoting if this CommentNode has been
            created or changed after the last save. Default: False.
        :type dirty: bool

        :param metadata: Dictionary of metadata values for this ParserNode object.
            Metadata information should be used only internally in the implementation.
            Default: {}
        :type metadata: dict
        """

    @abc.abstractmethod
    def save(self, msg: str) -> None:
        """
        Save traverses the children, and attempts to write the AST to disk for
        all the objects that are marked dirty. The actual operation of course
        depends on the underlying implementation. save() shouldn't be called
        from the Configurator outside of its designated save() method in order
        to ensure that the Reverter checkpoints are created properly.

        Note: this approach of keeping internal structure of the configuration
        within the ParserNode tree does not represent the file inclusion structure
        of actual configuration files that reside in the filesystem. To handle
        file writes properly, the file specific temporary trees should be extracted
        from the full ParserNode tree where necessary when writing to disk.

        :param str msg: Message describing the reason for the save.

        """

    @abc.abstractmethod
    def find_ancestors(self: GenericParserNode, name: str) -> List[GenericParserNode]:
        """
        Traverses the ancestor tree up, searching for BlockNodes with a specific
        name.

        :param str name: Name of the ancestor BlockNode to search for

        :returns: A list of ancestor BlockNodes that match the name
        :rtype: list of BlockNode
        """


class CommentNode(ParserNode, metaclass=abc.ABCMeta):
    """
    CommentNode class is used for representation of comments within the parsed
    configuration structure. Because of the nature of comments, it is not able
    to have child nodes and hence it is always treated as a leaf node.

    CommentNode stores its contents in class variable 'comment' and does not
    have a specific name.

    CommentNode objects should have the following attributes in addition to
    the ones described in ParserNode:

    # Contains the contents of the comment without the directive notation
    # (typically # or /* ... */).
    comment: str

    """
    comment: str

    @abc.abstractmethod
    def __init__(self, **kwargs: Any) -> None:
        """
        Initializes the CommentNode instance and sets its instance variables.

        :param comment: Contents of the comment. Required.
        :type comment: str

        :param ancestor: BlockNode ancestor for this CommentNode. Required.
        :type ancestor: BlockNode or None

        :param filepath: Filesystem path for the file where this CommentNode
            does or should exist in the filesystem. Required.
        :type filepath: str or None

        :param dirty: Boolean flag for denoting if this CommentNode has been
            created or changed after the last save. Default: False.
        :type dirty: bool
        """
        super().__init__(  # pragma: no cover
            ancestor=kwargs['ancestor'],
            dirty=kwargs.get('dirty', False),
            filepath=kwargs['filepath'],
            metadata=kwargs.get('metadata', {}),
        )


class DirectiveNode(ParserNode, metaclass=abc.ABCMeta):
    """
    DirectiveNode class represents a configuration directive within the configuration.
    It can have zero or more parameters attached to it. Because of the nature of
    single directives, it is not able to have child nodes and hence it is always
    treated as a leaf node.

    If a this directive was defined on the httpd command line, the ancestor instance
    variable for this DirectiveNode should be None, and it should be inserted to the
    beginning of root BlockNode children sequence.

    DirectiveNode objects should have the following attributes in addition to
    the ones described in ParserNode:

    # True if this DirectiveNode is enabled and False if it is inside of an
    # inactive conditional block.
    enabled: bool

    # Name, or key of the configuration directive. If BlockNode subclass of
    # DirectiveNode is the root configuration node, the name should be None.
    name: Optional[str]

    # Tuple of parameters of this ParserNode object, excluding whitespaces.
    parameters: Tuple[str, ...]

    """
    enabled: bool
    name: Optional[str]
    parameters: Tuple[str, ...]

    @abc.abstractmethod
    def __init__(self, **kwargs: Any) -> None:
        """
        Initializes the DirectiveNode instance and sets its instance variables.

        :param name: Name or key of the DirectiveNode object. Required.
        :type name: str or None

        :param tuple parameters: Tuple of str parameters for this DirectiveNode.
            Default: ().
        :type parameters: tuple

        :param ancestor: BlockNode ancestor for this DirectiveNode, or None for
            root configuration node. Required.
        :type ancestor: BlockNode or None

        :param filepath: Filesystem path for the file where this DirectiveNode
            does or should exist in the filesystem, or None for directives introduced
            in the httpd command line. Required.
        :type filepath: str or None

        :param dirty: Boolean flag for denoting if this DirectiveNode has been
            created or changed after the last save. Default: False.
        :type dirty: bool

        :param enabled: True if this DirectiveNode object is parsed in the active
            configuration of the httpd. False if the DirectiveNode exists within a
            unmatched conditional configuration block. Default: True.
        :type enabled: bool

        """
        super().__init__(  # pragma: no cover
            ancestor=kwargs['ancestor'],
            dirty=kwargs.get('dirty', False),
            filepath=kwargs['filepath'],
            metadata=kwargs.get('metadata', {}),
        )

    @abc.abstractmethod
    def set_parameters(self, parameters: List[str]) -> None:
        """
        Sets the sequence of parameters for this ParserNode object without
        whitespaces. While the whitespaces for parameters are discarded when using
        this method, the whitespacing preceding the ParserNode itself should be
        kept intact.

        :param list parameters: sequence of parameters
        """


class BlockNode(DirectiveNode, metaclass=abc.ABCMeta):
    """
    BlockNode class represents a block of nested configuration directives, comments
    and other blocks as its children. A BlockNode can have zero or more parameters
    attached to it.

    Configuration blocks typically consist of one or more child nodes of all possible
    types. Because of this, the BlockNode class has various discovery and structure
    management methods.

    Lists of parameters used as an optional argument for some of the methods should
    be lists of strings that are applicable parameters for each specific BlockNode
    or DirectiveNode type. As an example, for a following configuration example:

        <VirtualHost *:80>
           ...
        </VirtualHost>

    The node type would be BlockNode, name would be 'VirtualHost' and its parameters
    would be: ['*:80'].

    While for the following example:

        LoadModule alias_module /usr/lib/apache2/modules/mod_alias.so

    The node type would be DirectiveNode, name would be 'LoadModule' and its
    parameters would be: ['alias_module', '/usr/lib/apache2/modules/mod_alias.so']

    The applicable parameters are dependent on the underlying configuration language
    and its grammar.

    BlockNode objects should have the following attributes in addition to
    the ones described in DirectiveNode:

    # Tuple of direct children of this BlockNode object. The order of children
    # in this tuple retain the order of elements in the parsed configuration
    # block.
    children: Tuple[ParserNode, ...]

    """
    children: Tuple[ParserNode, ...]

    @abc.abstractmethod
    def add_child_block(self, name: str, parameters: Optional[List[str]] = None,
                        position: Optional[int] = None) -> "BlockNode":
        """
        Adds a new BlockNode child node with provided values and marks the callee
        BlockNode dirty. This is used to add new children to the AST. The preceding
        whitespaces should not be added based on the ancestor or siblings for the
        newly created object. This is to match the current behavior of the legacy
        parser implementation.

        :param str name: The name of the child node to add
        :param list parameters: list of parameters for the node
        :param int position: Position in the list of children to add the new child
            node to. Defaults to None, which appends the newly created node to the list.
            If an integer is given, the child is inserted before that index in the
            list similar to list().insert.

        :returns: BlockNode instance of the created child block

        """

    @abc.abstractmethod
    def add_child_directive(self, name: str, parameters: Optional[List[str]] = None,
                            position: Optional[int] = None) -> DirectiveNode:
        """
        Adds a new DirectiveNode child node with provided values and marks the
        callee BlockNode dirty. This is used to add new children to the AST. The
        preceding whitespaces should not be added based on the ancestor or siblings
        for the newly created object. This is to match the current behavior of the
        legacy parser implementation.


        :param str name: The name of the child node to add
        :param list parameters: list of parameters for the node
        :param int position: Position in the list of children to add the new child
            node to. Defaults to None, which appends the newly created node to the list.
            If an integer is given, the child is inserted before that index in the
            list similar to list().insert.

        :returns: DirectiveNode instance of the created child directive

        """

    @abc.abstractmethod
    def add_child_comment(self, comment: str = "", position: Optional[int] = None) -> CommentNode:
        """
        Adds a new CommentNode child node with provided value and marks the
        callee BlockNode dirty. This is used to add new children to the AST. The
        preceding whitespaces should not be added based on the ancestor or siblings
        for the newly created object. This is to match the current behavior of the
        legacy parser implementation.


        :param str comment: Comment contents
        :param int position: Position in the list of children to add the new child
            node to. Defaults to None, which appends the newly created node to the list.
            If an integer is given, the child is inserted before that index in the
            list similar to list().insert.

        :returns: CommentNode instance of the created child comment

        """

    @abc.abstractmethod
    def find_blocks(self, name: str, exclude: bool = True) -> List["BlockNode"]:
        """
        Find a configuration block by name. This method walks the child tree of
        ParserNodes under the instance it was called from. This way it is possible
        to search for the whole configuration tree, when starting from root node or
        to do a partial search when starting from a specified branch. The lookup
        should be case insensitive.

        :param str name: The name of the directive to search for
        :param bool exclude: If the search results should exclude the contents of
            ParserNode objects that reside within conditional blocks and because
            of current state are not enabled.

        :returns: A list of found BlockNode objects.
        """

    @abc.abstractmethod
    def find_directives(self, name: str, exclude: bool = True) -> List[DirectiveNode]:
        """
        Find a directive by name. This method walks the child tree of ParserNodes
        under the instance it was called from. This way it is possible to search
        for the whole configuration tree, when starting from root node, or to do
        a partial search when starting from a specified branch. The lookup should
        be case insensitive.

        :param str name: The name of the directive to search for
        :param bool exclude: If the search results should exclude the contents of
            ParserNode objects that reside within conditional blocks and because
            of current state are not enabled.

        :returns: A list of found DirectiveNode objects.

        """

    @abc.abstractmethod
    def find_comments(self, comment: str) -> List[CommentNode]:
        """
        Find comments with value containing the search term.

        This method walks the child tree of ParserNodes under the instance it was
        called from. This way it is possible to search for the whole configuration
        tree, when starting from root node, or to do a partial search when starting
        from a specified branch. The lookup should be case sensitive.

        :param str comment: The content of comment to search for

        :returns: A list of found CommentNode objects.

        """

    @abc.abstractmethod
    def delete_child(self, child: ParserNode) -> None:
        """
        Remove a specified child node from the list of children of the called
        BlockNode object.

        :param ParserNode child: Child ParserNode object to remove from the list
            of children of the callee.
        """

    @abc.abstractmethod
    def unsaved_files(self) -> List[str]:
        """
        Returns a list of file paths that have been changed since the last save
        (or the initial configuration parse). The intended use for this method
        is to tell the Reverter which files need to be included in a checkpoint.

        This is typically called for the root of the ParserNode tree.

        :returns: list of file paths of files that have been changed but not yet
            saved to disk.
        """

    @abc.abstractmethod
    def parsed_paths(self) -> List[str]:
        """
        Returns a list of file paths that have currently been parsed into the parser
        tree. The returned list may include paths with wildcard characters, for
        example: ['/etc/apache2/conf.d/*.load']

        This is typically called on the root node of the ParserNode tree.

        :returns: list of file paths of files that have been parsed
        """
¿Qué es la limpieza dental de perros? - Clínica veterinaria


Es la eliminación del sarro y la placa adherida a la superficie de los dientes mediante un equipo de ultrasonidos que garantiza la integridad de las piezas dentales a la vez que elimina en profundidad cualquier resto de suciedad.

A continuación se procede al pulido de los dientes mediante una fresa especial que elimina la placa bacteriana y devuelve a los dientes el aspecto sano que deben tener.

Una vez terminado todo el proceso, se mantiene al perro en observación hasta que se despierta de la anestesia, bajo la atenta supervisión de un veterinario.

¿Cada cuánto tiempo tengo que hacerle una limpieza dental a mi perro?

A partir de cierta edad, los perros pueden necesitar una limpieza dental anual o bianual. Depende de cada caso. En líneas generales, puede decirse que los perros de razas pequeñas suelen acumular más sarro y suelen necesitar una atención mayor en cuanto a higiene dental.


Riesgos de una mala higiene


Los riesgos más evidentes de una mala higiene dental en los perros son los siguientes:

  • Cuando la acumulación de sarro no se trata, se puede producir una inflamación y retracción de las encías que puede descalzar el diente y provocar caídas.
  • Mal aliento (halitosis).
  • Sarro perros
  • Puede ir a más
  • Las bacterias de la placa pueden trasladarse a través del torrente circulatorio a órganos vitales como el corazón ocasionando problemas de endocarditis en las válvulas. Las bacterias pueden incluso acantonarse en huesos (La osteomielitis es la infección ósea, tanto cortical como medular) provocando mucho dolor y una artritis séptica).

¿Cómo se forma el sarro?

El sarro es la calcificación de la placa dental. Los restos de alimentos, junto con las bacterias presentes en la boca, van a formar la placa bacteriana o placa dental. Si la placa no se retira, al mezclarse con la saliva y los minerales presentes en ella, reaccionará formando una costra. La placa se calcifica y se forma el sarro.

El sarro, cuando se forma, es de color blanquecino pero a medida que pasa el tiempo se va poniendo amarillo y luego marrón.

Síntomas de una pobre higiene dental
La señal más obvia de una mala salud dental canina es el mal aliento.

Sin embargo, a veces no es tan fácil de detectar
Y hay perros que no se dejan abrir la boca por su dueño. Por ejemplo…

Recientemente nos trajeron a la clínica a un perro que parpadeaba de un ojo y decía su dueño que le picaba un lado de la cara. Tenía molestias y dificultad para comer, lo que había llevado a sus dueños a comprarle comida blanda (que suele ser un poco más cara y llevar más contenido en grasa) durante medio año. Después de una exploración oftalmológica, nos dimos cuenta de que el ojo tenía una úlcera en la córnea probablemente de rascarse . Además, el canto lateral del ojo estaba inflamado. Tenía lo que en humanos llamamos flemón pero como era un perro de pelo largo, no se le notaba a simple vista. Al abrirle la boca nos llamó la atención el ver una muela llena de sarro. Le realizamos una radiografía y encontramos una fístula que llegaba hasta la parte inferior del ojo.

Le tuvimos que extraer la muela. Tras esto, el ojo se curó completamente con unos colirios y una lentilla protectora de úlcera. Afortunadamente, la úlcera no profundizó y no perforó el ojo. Ahora el perro come perfectamente a pesar de haber perdido una muela.

¿Cómo mantener la higiene dental de tu perro?
Hay varias maneras de prevenir problemas derivados de la salud dental de tu perro.

Limpiezas de dientes en casa
Es recomendable limpiar los dientes de tu perro semanal o diariamente si se puede. Existe una gran variedad de productos que se pueden utilizar:

Pastas de dientes.
Cepillos de dientes o dedales para el dedo índice, que hacen más fácil la limpieza.
Colutorios para echar en agua de bebida o directamente sobre el diente en líquido o en spray.

En la Clínica Tus Veterinarios enseñamos a nuestros clientes a tomar el hábito de limpiar los dientes de sus perros desde que son cachorros. Esto responde a nuestro compromiso con la prevención de enfermedades caninas.

Hoy en día tenemos muchos clientes que limpian los dientes todos los días a su mascota, y como resultado, se ahorran el dinero de hacer limpiezas dentales profesionales y consiguen una mejor salud de su perro.


Limpiezas dentales profesionales de perros y gatos

Recomendamos hacer una limpieza dental especializada anualmente. La realizamos con un aparato de ultrasonidos que utiliza agua para quitar el sarro. Después, procedemos a pulir los dientes con un cepillo de alta velocidad y una pasta especial. Hacemos esto para proteger el esmalte.

La frecuencia de limpiezas dentales necesaria varía mucho entre razas. En general, las razas grandes tienen buena calidad de esmalte, por lo que no necesitan hacerlo tan a menudo e incluso pueden pasarse la vida sin requerir una limpieza. Sin embargo, razas pequeñas como el Yorkshire o el Maltés, deben hacérselas todos los años desde cachorros si se quiere conservar sus piezas dentales.

Otro factor fundamental es la calidad del pienso. Algunas marcas han diseñado croquetas que limpian la superficie del diente y de la muela al masticarse.

Ultrasonido para perros

¿Se necesita anestesia para las limpiezas dentales de perros y gatos?

La limpieza dental en perros no es una técnica que pueda practicarse sin anestesia general , aunque hay veces que los propietarios no quieren anestesiar y si tiene poco sarro y el perro es muy bueno se puede intentar…… , pero no se va a poder pulir ni acceder a todas la zona de la boca …. Además los limpiadores dentales van a irrigar agua y hay riesgo de aspiración a vías respiratorias si no se realiza una anestesia correcta con intubación traqueal . En resumen , sin anestesia no se va hacer una correcta limpieza dental.

Tampoco sirve la sedación ya que necesitamos que el animal esté totalmente quieto, y el veterinario tenga un acceso completo a todas sus piezas dentales y encías.

Alimentos para la limpieza dental

Hay que tener cierto cuidado a la hora de comprar determinados alimentos porque no todos son saludables. Algunos tienen demasiado contenido graso, que en exceso puede causar problemas cardiovasculares y obesidad.

Los mejores alimentos para los dientes son aquellos que están elaborados por empresas farmacéuticas y llevan componentes químicos con tratamientos específicos para el diente del perro. Esto implica no solo limpieza a través de la acción mecánica de morder sino también un tratamiento antibacteriano para prevenir el sarro.

Conclusión

Si eres como la mayoría de dueños, por falta de tiempo , es probable que no estés prestando la suficiente atención a la limpieza dental de tu perro. Por eso te animamos a que comiences a limpiar los dientes de tu perro y consideres atender a su higiene bucal con frecuencia.

Estas simples medidas pueden conllevar a que tu perro tenga una vida más larga y mucho más saludable.

Si te resulta imposible introducir un cepillo de dientes a tu perro en la boca, pásate con él por clínica Tus Veterinarios y te explicamos cómo hacerlo.

Necesitas hacer una limpieza dental profesional a tu mascota?
Llámanos al 622575274 o contacta con nosotros

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

¡Hola!