o
    
iFG                  
   @  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xmlrdfowln3ttlturtlenttrixxhtmlrdfahtmlsvg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-   r0   r2   r3   r4   r6   r:   r;   r=   zapplication/sparql-results+xmlzapplication/sparql-results+jsonztext/csvztext/tab-separated-values)r-   r<   csv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seenrE   ?/home/ubuntu/.local/lib/python3.10/site-packages/rdflib/util.py
<listcomp>}   s   " zlist2set.<locals>.<listcomp>set)rA   rE   rI   rK   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
    NrE   )rA   resultrE   rE   rK   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)rT   )rG   srE   rE   rK   	<genexpr>   s    zuniq.<locals>.<genexpr>rM   )rR   rT   rE   rE   rK   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      rE   )rR   r[   iitemrE   rE   rK   r       s   r    rX   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)

    <>r\   "_zUnrecognised term syntax: '%s')
startswithendswithrdflibtermURIRefLiteralBNode	Exception)rX   r`   msgrE   rE   rK   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

    ```
    rb   r\   rd   zraw-unicode-escapezunicode-escapere   z"""Nz^^r      @z\"z\xz\\xtruefalse. -e)datatype{[z_::)rg   ri   rj   rk   encodedecodersplitlenrfindr"   replacerl   lower	isnumeric	namespaceXSDdoublefloatdecimalrU   integergraphQuotedGraphr   rm   NamespaceManagersplitdict
namespaces	Namespace)rX   r`   rq   rr   quotesvaluerestr}   languagedtoffset
identifierprefix	last_partnsrE   rE   rK   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   )tlocal_time_zone
time_tupletz_minstzdyearmonthdayhhmmsswdyzrX   rE   rE   rK   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   rd            r   r{   r   )r   rU   r   r   )r   ymdr   hmstz_str	tz_offset
signed_hrsminssecsr   r   r   hourminutesecondr   rE   rE   rK   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   rE   rE   rK   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'

        ```
    rd   rz   ry   r\   N)r   rg   r   )r   r   extrE   rE   rK   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)rN   subject_objectsrF   remove)r   r   r   	non_rootsrH   r   rE   rE   rK   r&     s   


r&   c                 C  s   | S rW   rE   )rH   rE   rE   rK   <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)rN   rF   subjectsobjectsr'   appendsorted)r   r   r   r   r   r   r   treebranchesbranchr   rE   rE   rK   r'     s   

r'   argsc                 G     d S rW   rE   r`   r   rE   rE   rK   r(     s   r(   .)r`   c                 G  r   rW   rE   r   rE   rE   rK   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`.
    NrE   )r`   r   argrE   rE   rK   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asciirz   r   r   ]rv   #)r   r   _PATH_SAFE_CHARS_QUERY_SAFE_CHARShostnamer   r   portusername_USERNAME_SAFE_CHARSpasswordr   rh   )
r   partsschemenetlocpathqueryfragmentauthpass_quotedurirE   rE   rK   r)   a  s0   r)   )rA   rB   rC   rD   )rA   rO   rC   rP   )r   )rR   rS   rT   rU   rC   rV   )rR   rZ   r[   rU   rC   rU   rW   )rX   r_   r`   ra   rC   ra   )NNN)
rX   rp   r`   r_   rq   r_   rr   rs   rC   rt   )NF)r   rp   rC   rU   )r   rp   r   r   rC   r_   )T)r   rp   r   r   rC   rp   )r   r   r   r   r   r   rC   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   rp   rC   r   )r   rP   r`   r,   rC   r,   )r   rP   r`   rP   rC   rP   )r   rp   rC   rp   )?__doc__
__future__r   calendarr   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   rdflib.graphri   rdflib.namespacerdflib.termrdflib.compatr   r   __all__r*   r,   r   FORMAT_MIMETYPE_MAP"RESPONSE_TABLE_FORMAT_MIMETYPE_MAPr   r   r   r    r!   r"   r#   r$   r%   r   r&   r'   r(   _RFC3986_SUBDELIMS_RFC3986_PCHAR_NUr   r   r   r)   rE   rE   rE   rK   <module>   s    @	





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