3
d44                 @   s  d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm	Z	 ddlm
Z
 dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddddddddd d!d"d#d$d%d&d'd(gZd)d Z d*d Z!dNd+dZ"d,d Z#dOd.dZ$dPd/dZ%d0d  Z&d1d! Z'd2d" Z(d3d# Z)d4d$ Z*d5d% Z+dQd7dZ,d8d Z-d9d9d9d:d;d<d=d>d>d>d?d@dAZ.dRdBd&Z/dSdDdEZ0dTdFd'Z1dGdH d-d-dIfdJd(Z2dKdL Z3e4dMkre3  d-S )UaT  
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

Statement and component type checkers

* check_context
* check_subject
* check_predicate
* check_object
* check_statement
* check_pattern

    )absolute_import)division)print_function)timegm)altzone)gmtime)	localtime)time)timezone)splitext)ContextTypeError)ObjectTypeError)PredicateTypeError)SubjectTypeError)Graph)QuotedGraph)	Namespace)NamespaceManager)BNode)Literal)URIRef)signlist2setfirstuniq	more_thanto_termfrom_n3	date_timeparse_date_timecheck_contextcheck_subjectcheck_predicatecheck_objectcheck_statementcheck_patternguess_format
find_rootsget_treec                s   t    fdd| D S )zX
    Return a new list without duplicates.
    Preserves the order, unlike set(seq)
    c                s$   g | ]}| kr j | r|qS  )add).0x)seenr)   -/tmp/pip-build-7vycvbft/rdflib/rdflib/util.py
<listcomp>G   s    zlist2set.<locals>.<listcomp>)set)seqr)   )r-   r.   r   A   s    c             C   s   x| D ]}|S W dS )z_
    return the first element in a python sequence
    for graphs, use graph.value instead
    Nr)   )r1   resultr)   r)   r.   r   J   s    
c             C   s"   |rt dd | D S t | S dS )z,removes duplicate strings from the sequence.c             s   s   | ]}|j  V  qd S )N)strip)r+   sr)   r)   r.   	<genexpr>W   s    zuniq.<locals>.<genexpr>N)r0   )sequencer3   r)   r)   r.   r   T   s    c             C   s*   d}x | D ]}|d7 }||kr
dS q
W dS )z>Returns 1 if sequence has more items than number and 0 if not.r      r)   )r6   numberiitemr)   r)   r.   r   \   s    
Nc             C   sv   | s|S | j dr,| jdr,t| dd S | j drP| jdrPt| dd	 S | j drbt| S d|  }t|dS )
a  
    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)

    <>r7   "_zUnrecognised term syntax: '%s'Nr?   )
startswithendswithr   r   r   	Exception)r4   defaultmsgr)   r)   r.   r   f   s    
c             C   s  | s|S | j dr.t| dd jdjdS | j dr| j drHd}nd}| j|d\}}|t|d }d}d}|jd}	|	d	krt||	d
 d |||}n|j dr|dd }|jdd}|jdjd}t	|||S | dks| dk rt	| dkS | j
 rt	t| S | j dr:t| dd }
t||
S | j dr`t| dd }
t||
S | j dr|t| d
d S d| kr|dkrtt }| jdd\}}t|j | }t|| S t| S dS )a}  
    Creates the Identifier corresponding to the given n3 string.

        >>> 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(Graph())
        >>> nsm.bind('dbpedia', 'http://dbpedia.org/resource/')
        >>> berlin = URIRef('http://dbpedia.org/resource/Berlin')
        >>> from_n3('dbpedia:Berlin', nsm=nsm) == berlin
        True

    r;   r7   zraw-unicode-escapezunicode-escaper=   z"""Nz^^r      @z\"truefalse{[z_::r?   r?   r?   )r@   r   encodedecodersplitlenrfindr   replacer   isdigitintr   r   r   r   splitdict
namespacesr   )r4   rC   backendZnsmquotesvaluerestdatatypelanguageZdtoffset
identifierprefixZ	last_partnsr)   r)   r.   r      sN    










c             C   s,   t | tpt | ts(td| t| f d S )Nz%s:%s)
isinstancer   r   r   type)cr)   r)   r.   r       s    

c             C   s    t | tpt | tst| dS )z+ Test that s is a valid subject identifier.N)r`   r   r   r   )r4   r)   r)   r.   r!      s    c             C   s   t | tst| dS )z- Test that p is a valid predicate identifier.N)r`   r   r   )pr)   r)   r.   r"      s    
c             C   s*   t | tpt | tpt | ts&t| dS )z* Test that o is a valid object identifier.N)r`   r   r   r   r   )or)   r)   r.   r#      s    


c             C   sb   | \}}}t |tpt |ts&t|t |ts8t|t |tpTt |tpTt |ts^t|d S )N)r`   r   r   r   r   r   r   )tripler4   rc   rd   r)   r)   r.   r$      s    




c             C   st   | \}}}|r,t |tp t |t r,t||rDt |t rDt||rpt |tpdt |tpdt |t rpt|d S )N)r`   r   r   r   r   r   r   )re   r4   rc   rd   r)   r)   r.   r%      s    

Fc          	   C   s   | dkrt  } |rJt| }|d r,td }ntd }d|d |d f }nt| }d}|\	}}}}}	}
}}}d|||||	|
|f }|S )ah  http://www.w3.org/TR/NOTE-datetime ex: 1997-07-16T19:20:30Z

    >>> 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_zoneZ
time_tupleZtz_minsZtzdyearmonthdayhhmmsswdyzr4   r)   r)   r.   r   
  s    
c          
   C   s   d| kr| d7 } | j d\}}|dd |dd  }}| sF|dkrX|dd }d}n>t|dd }t|d	d
 }t|| |d  d }| }|j d\}	}
}|j d\}}}tt|	t|
t|t|t|t|dddf	}|| }|S )a  always returns seconds in UTC

    # 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   rf   Nrh   r7            rg   -rK   r?   )rT   rS   r   r   )valZymdr	   ZhmsZtz_strZ	tz_offsetZ
signed_hrsZminsZsecsrj   rk   rl   hourminutesecondri   r)   r)   r.   r   .  s"    xmln3ZturtlenttrixZrdfaZnquadstrig)rdfZrdfsZowlr}   Zttlr~   r   ZxhtmlhtmlsvgZnqr   c             C   s$   |pt }|jt| p"|j| j S )a  
    Guess RDF serialization based on file suffix. Uses
    ``SUFFIX_FORMAT_MAP`` unless ``fmap`` is provided. Examples:

        >>> 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.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::

        >>> guess_format('.rdf')
        'xml'
        >>> guess_format('rdf')
        'xml'
        >>> guess_format('RDF')
        'xml'
    )SUFFIX_FORMAT_MAPget_get_extlower)fpathZfmapr)   r)   r.   r&   i  s    Tc             C   sH   t | d }|dkr"| jdr"| }|r.|j }|jdrD|dd }|S )a)  
    Gets the file extension from a file(path); stripped of leading '.' and in
    lower case. Examples:

        >>> _get_ext("path/to/file.txt")
        'txt'
        >>> _get_ext("OTHER.PDF")
        'pdf'
        >>> _get_ext("noext")
        ''
        >>> _get_ext(".rdf")
        'rdf'
    r7    .Nr?   )r   r@   r   )r   r   extr)   r)   r.   r     s    
r   c             C   s^   t  }|dkrt  }xD| j|D ]6\}}|j| ||krD|j| ||kr |j| q W |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)r0   Zsubject_objectsr*   remove)graphproprootsZ	non_rootsr,   rq   r)   r)   r.   r'     s    

c             C   s   | S )Nr)   )r,   r)   r)   r.   <lambda>  s    r   downc          	   C   s   |dkrt  }||krdS |j| g }|dkr>| j||}n| j||}x.|D ]&}	t| |	|||||}
|
rP|j|
 qPW ||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.

    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)r0   r*   Zsubjectsobjectsr(   appendsorted)r   rootr   ZmapperZsortkeydonedirtreeZbranchesbranchri   r)   r)   r.   r(     s    

c              C   s   dd l } | j  d S )Nr   )doctesttestmod)r   r)   r)   r.   test  s    r   __main__)r   )N)NNN)NF)N)T)N)5__doc__
__future__r   r   r   calendarr   r	   r   r   r   r
   os.pathr   Zrdflib.exceptionsr   r   r   r   Zrdflib.graphr   r   Zrdflib.namespacer   r   Zrdflib.termr   r   r   Zrdflib.compatr   __all__r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r   r   r   r&   r   r'   r(   r   __name__r)   r)   r)   r.   <module>   s|   
	




S
$,
 

'
