o
    miFG                  
   @  s  d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	m
Z
mZmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZ ddlmZmZmZ ddlZ ddl!Z ddl"Z dd	l#m$Z$ erfdd
lm%Z% g dZ&ededZ'edZ(i ddddddddddddddddddddddddddddd dddZ)d!gd"gd#gd$gd%gd&d'gd(gd)gd*gd+	Z*d,gd-gd.gd/gd0Z+dd5d6Z,dd9d:Z-ddd@dAZ.ddDdEZ/	dddJdKZ0			dddQdRZ1ddTdUZ2ddWdXZ3ddd\d]Z4dddadbZ5	dddjdkZ6dldm dddnfddxdyZ7edd{d|Z8ed}d~ddd|Z8dd~ddd|Z8dZ9	 de9 d Z:	 e:d Z;	 e9d Z<	 e:d Z=	 dddZ>dS )z
Some utility functions.

Miscellaneous utilities

* list2set
* first
* uniq
* more_than

Term characterisation and generation

* to_term
* from_n3

Date/time utilities

* date_time
* parse_date_time

    )annotations)timegm)splitext)altzonegmtime	localtimetimetimezone)TYPE_CHECKINGAnyCallableDictHashableIterableIteratorListOptionalSetTupleTypeVarUnionoverload)quoteurlsplit
urlunsplitN)sign)Graph)list2setfirstuniq	more_thanto_termfrom_n3	date_timeparse_date_timeguess_format
find_rootsget_tree	_coalesce_iri2uri
_HashableT)bound_AnyTxmlZrdfowln3ttlturtlenttrixZxhtmlrdfahtmlsvgZnqnquadstrigjsonjson-ldjsonldzapplication/rdf+xmlztext/n3ztext/turtlezapplication/n-tripleszapplication/trixz	text/htmlzapplication/xhtml+xmlzapplication/n-quadszapplication/trigzapplication/ld+json)	r-   r/   r1   r2   r3   r4   r7   r8   r:   zapplication/sparql-results+xmlzapplication/sparql-results+jsonztext/csvztext/tab-separated-values)r-   r9   csvZtsvseqIterable[_HashableT]returnList[_HashableT]c                   s   t    fdd| D S )zX
    Return a new list without duplicates.
    Preserves the order, unlike set(seq)
    c                   s"   g | ]}| vr  |s|qS  )add).0xseenrA   E/home/kim/smarthome/.venv/lib/python3.10/site-packages/rdflib/util.py
<listcomp>}   s   " zlist2set.<locals>.<listcomp>set)r=   rA   rE   rG   r   v   s   r   Iterable[_AnyT]Optional[_AnyT]c                 C  s   | D ]}|  S dS )z_
    return the first element in a python sequence
    for graphs, use graph.value instead
    NrA   )r=   resultrA   rA   rG   r      s   r   sequenceIterable[str]stripintSet[str]c                 C  s   |rt dd | D S t | S )z,removes duplicate strings from the sequence.c                 s  s    | ]}|  V  qd S N)rP   )rC   srA   rA   rG   	<genexpr>   s    zuniq.<locals>.<genexpr>rI   )rN   rP   rA   rA   rG   r      s   r   Iterable[Any]numberc                 C  s(   d}| D ]}|d7 }||kr dS qdS )z>Returns 1 if sequence has more items than number and 0 if not.r      rA   )rN   rW   iitemrA   rA   rG   r       s   r    rT   Optional[str]default Optional[rdflib.term.Identifier]c                 C  s~   | s|S |  dr| drtj| dd S |  dr,| dr,tj| dd S |  dr7tj| S d|  }t|)ay  
    Creates and returns an Identifier of type corresponding
    to the pattern of the given positional argument string `s`:

    '' returns the `default` keyword argument value or `None`

    '<s>' returns `URIRef(s)` (i.e. without angle brackets)

    '"s"' returns `Literal(s)` (i.e. without doublequotes)

    '_s' returns `BNode(s)` (i.e. without leading underscore)

    <>rX   "_zUnrecognised term syntax: '%s')
startswithendswithrdflibtermURIRefLiteralBNode	Exception)rT   r\   msgrA   rA   rG   r!      s   
r!   strbackendnsm+Optional[rdflib.namespace.NamespaceManager]&Optional[Union[rdflib.term.Node, str]]c                 C  sn  | s|S |  drtj| dd ddS |  drz|  dr&d}nd}| |d\}}|t|d }d}d}|d	}	|	d
krSt	||	d d |||}n| dr^|dd }|
dd}|
dd}|dd}tj|||S | dks| dkrtj| dkS |  
ddd
ddd
ddd rd|  v rtjj| tjjjdS d| v rtjjt| tjjjdS tjjt| tjjjdS |  drt	| dd }
tj||
S |  drt	| dd }
tj||
S |  drtj| dd S d| v r1|du rtjtj }| dd\}}t| | }tj|| S tj| S )a  Creates the Identifier corresponding to the given n3 string.

    ```python
    >>> from rdflib.term import URIRef, Literal
    >>> from rdflib.namespace import NamespaceManager
    >>> from_n3('<http://ex.com/foo>') == URIRef('http://ex.com/foo')
    True
    >>> from_n3('"foo"@de') == Literal('foo', lang='de')
    True
    >>> from_n3('"""multi\nline\nstring"""@en') == Literal(
    ...     'multi\nline\nstring', lang='en')
    True
    >>> from_n3('42') == Literal(42)
    True
    >>> from_n3(Literal(42).n3()) == Literal(42)
    True
    >>> from_n3('"42"^^xsd:integer') == Literal(42)
    True
    >>> from rdflib import RDFS
    >>> from_n3('rdfs:label') == RDFS['label']
    True
    >>> nsm = NamespaceManager(rdflib.graph.Graph())
    >>> nsm.bind('dbpedia', 'http://dbpedia.org/resource/')
    >>> berlin = URIRef('http://dbpedia.org/resource/Berlin')
    >>> from_n3('dbpedia:Berlin', nsm=nsm) == berlin
    True

    ```
    r^   rX   r`   zraw-unicode-escapezunicode-escapera   z"""Nz^^r      @z\"z\xz\\xtruefalse. -e)datatype{[z_::)rc   re   rf   rg   encodedecodersplitlenrfindr"   replacerh   lower	isnumeric	namespaceZXSDdoublefloatdecimalrQ   integergraphZQuotedGraphr   ri   ZNamespaceManagersplitdict
namespaces	Namespace)rT   r\   rm   rn   quotesvaluerestry   languageZdtoffset
identifierprefixZ	last_partnsrA   rA   rG   r"      sf   #











r"   Fc              	   C  s   | du rt  } |r%t| }|d rtd }ntd }d|d |d f }nt| }d}|\	}}}}}	}
}}}d|||||	|
|f }|S )a  http://www.w3.org/TR/NOTE-datetime ex: 1997-07-16T19:20:30Z

    ```python
    >>> date_time(1126482850)
    '2005-09-11T23:54:10Z'

    @@ this will change depending on where it is run
    #>>> date_time(1126482850, local_time_zone=True)
    #'2005-09-11T19:54:10-04:00'

    >>> date_time(1)
    '1970-01-01T00:00:01Z'

    >>> date_time(0)
    '1970-01-01T00:00:00Z'

    ```
    N   <   z
-%02d:%02dZz!%0004d-%02d-%02dT%02d:%02d:%02d%s)r   r   r   r	   r   )tZlocal_time_zone
time_tupleZtz_minsZtzdyearmonthdayhhmmsswdyzrT   rA   rA   rG   r#   )  s   
r#   valc              
   C  s   d| vr| d7 } |  d\}}|dd |dd }}|r"|dkr+|dd }d}nt|dd }t|d	d
 }t|| |d  d }| }| d\}	}
}| d\}}}tt|	t|
t|t|t|t|dddf	}|| }|S )a  always returns seconds in UTC

    ```python
    # tests are written like this to make any errors easier to understand
    >>> parse_date_time('2005-09-11T23:54:10Z') - 1126482850.0
    0.0

    >>> parse_date_time('2005-09-11T16:54:10-07:00') - 1126482850.0
    0.0

    >>> parse_date_time('1970-01-01T00:00:01Z') - 1.0
    0.0

    >>> parse_date_time('1970-01-01T00:00:00Z') - 0.0
    0.0
    >>> parse_date_time("2005-09-05T10:42:00") - 1125916920.0
    0.0

    ```
    Tz
T00:00:00Zr   r   Nr   r`            r   rw   r|   )r   rQ   r   r   )r   Zymdr   ZhmsZtz_strZ	tz_offsetZ
signed_hrsZminsZsecsr   r   r   hourminutesecondr   rA   rA   rG   r$   O  s$   ,r$   fpathfmapOptional[Dict[str, str]]c                 C  s$   |pt }|t| p||  S )a}  
    Guess RDF serialization based on file suffix. Uses
    `SUFFIX_FORMAT_MAP` unless `fmap` is provided.

    Example:
        ```python
        >>> guess_format('path/to/file.rdf')
        'xml'
        >>> guess_format('path/to/file.owl')
        'xml'
        >>> guess_format('path/to/file.ttl')
        'turtle'
        >>> guess_format('path/to/file.json')
        'json-ld'
        >>> guess_format('path/to/file.xhtml')
        'rdfa'
        >>> guess_format('path/to/file.svg')
        'rdfa'
        >>> guess_format('path/to/file.xhtml', {'xhtml': 'grddl'})
        'grddl'

        ```

        This also works with just the suffixes, with or without leading dot, and
        regardless of letter case:

        ```python
        >>> guess_format('.rdf')
        'xml'
        >>> guess_format('rdf')
        'xml'
        >>> guess_format('RDF')
        'xml'

        ```
    )SUFFIX_FORMAT_MAPget_get_extr   )r   r   rA   rA   rG   r%   ~  s   %r%   Tr   boolc                 C  sH   t | d }|dkr| dr| }|r| }|dr"|dd }|S )aK  
    Gets the file extension from a file(path); stripped of leading '.' and in
    lower case.

    Example:
        ```python
        >>> _get_ext("path/to/file.txt")
        'txt'
        >>> _get_ext("OTHER.PDF")
        'pdf'
        >>> _get_ext("noext")
        ''
        >>> _get_ext(".rdf")
        'rdf'

        ```
    r`   rv   ru   rX   N)r   rc   r   )r   r   extrA   rA   rG   r     s   
r   r   r   proprdflib.term.URIRefrootsOptional[Set[rdflib.term.Node]]Set[rdflib.term.Node]c                 C  sZ   t  }|du r
t  }| |D ]\}}|| ||v r!|| ||vr*|| q|S )a  Find the roots in some sort of transitive hierarchy.

    find_roots(graph, rdflib.RDFS.subClassOf)
    will return a set of all roots of the sub-class hierarchy

    Assumes triple of the form (child, prop, parent), i.e. the direction of
    `RDFS.subClassOf` or `SKOS.broader`
    N)rJ   Zsubject_objectsrB   remove)r   r   r   Z	non_rootsrD   r   rA   rA   rG   r&     s   


r&   c                 C  s   | S rS   rA   )rD   rA   rA   rG   <lambda>  s    r   downrootrdflib.term.Nodemapper.Callable[[rdflib.term.Node], rdflib.term.Node]sortkeyOptional[Callable[[Any], Any]]donedir,Optional[Tuple[rdflib.term.Node, List[Any]]]c              	   C  s   |du rt  }||v rdS || g }|dkr| ||}n| ||}|D ]}	t| |	|||||}
|
r:||
 q'||t||dfS )a  
    Return a nested list/tuple structure representing the tree
    built by the transitive property given, starting from the root given

    i.e.

    ```python
    get_tree(
        graph,
        rdflib.URIRef("http://xmlns.com/foaf/0.1/Person"),
        rdflib.RDFS.subClassOf,
    )
    ```

    will return the structure for the subClassTree below person.

    dir='down' assumes triple of the form (child, prop, parent),
    i.e. the direction of RDFS.subClassOf or SKOS.broader
    Any other dir traverses in the other direction
    Nr   )key)rJ   rB   Zsubjectsobjectsr'   appendsorted)r   r   r   r   r   r   r   treeZbranchesbranchr   rA   rA   rG   r'     s   

r'   argsc                 G     d S rS   rA   r\   r   rA   rA   rG   r(     s   r(   .)r\   c                 G  r   rS   rA   r   rA   rA   rG   r(     s   c                 G  s   |D ]
}|dur|  S q| S )a  
    This is a null coalescing function, it will return the first non-`None`
    argument passed to it, otherwise it will return `default` which is `None`
    by default.

    For more info regarding the rationale of this function see deferred
    [PEP 505](https://peps.python.org/pep-0505/).

    Args:
        *args: Values to consider as candidates to return, the first arg that
            is not `None` will be returned. If no argument is passed this function
            will return None.
        default: The default value to return if none of the args are not `None`.

    Returns:
        The first `args` that is not `None`, otherwise the value of
            `default` if there are no `args` or if all `args` are `None`.
    NrA   )r\   r   argrA   rA   rG   r(     s
   z!$&'()*+,;=%z:@z/?/iric           
      C  s  t | }|\}}}}}|dvr| S t|td}t|td}t|td}|jr0|jdd}nd}d|v r<d| d}|jrG| d|j }|jrit|jt	d}|j
rbt|j
t	d}| d| }| d	| }t|||||f}	| d
r|	d
s|	d
7 }	|	S )u*  
    Prior art:

    - [iri_to_uri from Werkzeug](https://github.com/pallets/werkzeug/blob/92c6380248c7272ee668e1f8bbd80447027ccce2/src/werkzeug/urls.py#L926-L931)

    ```python
    >>> _iri2uri("https://dbpedia.org/resource/Almería")
    'https://dbpedia.org/resource/Almer%C3%ADa'

    ```
    )httphttps)safeidnaasciirv   r|   r{   ]rr   #)r   r   _PATH_SAFE_CHARS_QUERY_SAFE_CHARShostnamer}   r~   portusername_USERNAME_SAFE_CHARSpasswordr   rd   )
r   partsschemenetlocpathqueryfragmentauthZpass_quotedurirA   rA   rG   r)   a  s0   r)   )r=   r>   r?   r@   )r=   rK   r?   rL   )r   )rN   rO   rP   rQ   r?   rR   )rN   rV   rW   rQ   r?   rQ   rS   )rT   r[   r\   r]   r?   r]   )NNN)
rT   rl   r\   r[   rm   r[   rn   ro   r?   rp   )NF)r   rl   r?   rQ   )r   rl   r   r   r?   r[   )T)r   rl   r   r   r?   rl   )r   r   r   r   r   r   r?   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   rl   r?   r   )r   rL   r\   r,   r?   r,   )r   rL   r\   rL   r?   rL   )r   rl   r?   rl   )?__doc__
__future__r   calendarr   Zos.pathr   r   r   r   r   r	   typingr
   r   r   r   r   r   r   r   r   r   r   r   r   r   urllib.parser   r   r   Zrdflib.graphre   Zrdflib.namespaceZrdflib.termZrdflib.compatr   r   __all__r*   r,   r   ZFORMAT_MIMETYPE_MAPZ"RESPONSE_TABLE_FORMAT_MIMETYPE_MAPr   r   r   r    r!   r"   r#   r$   r%   r   r&   r'   r(   Z_RFC3986_SUBDELIMSZ_RFC3986_PCHAR_NUr   r   r   r)   rA   rA   rA   rG   <module>   s    @	






p
&/)4
