U
    td@                     @   s   d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	 dd Z
d'd	d
Zd(ddZd)ddZd*ddZdd Zd+ddZd,ddZd-ddZd.ddZd/d!d"Zd0d#d$Zd1d%d&ZdS )2    N)copyfileobj)warn)	GraphBase)named_temporary_filec           	      C   sb  ddl }t| dr>t| dr>z
| j} W n tk
r<   Y dS X |j| \}}| }|dkr|j|\}}| }|dkrdS |dkrd	S |d
kr|dd S |dks|dkr^t| d}| }|dkrdS |	 
 }t|dkrZ| }|dkrdS |	 
 }t|dkrT| }|dkr2dS |	 
 }t|dkrPdS dS dS ndS dS )aV  _identify_format(filename)

    Tries to identify the format of the graph stored in the file with the
    given filename. It identifies most file formats based on the extension
    of the file (and not on syntactic evaluation). The only exception is
    the adjacency matrix format and the edge list format: the first few
    lines of the file are evaluated to decide between the two.

    @note: Internal function, should not be called directly.

    @param filename: the name of the file or a file object whose C{name}
      attribute is set.
    @return: the format of the file as a string.
    r   Nnamereadz.gz.pickleZpicklez.graphmlZgraphmlz)z.dimacsz.dlz.dotz.edgez.edgesz	.edgelistz.gmlr	   z	.graphmlzz.gwz.lglz.lgrz.ncolz.netz.pajekr   z.picklezz.svg   z.txtz.datredges   Z	adjacency)os.pathhasattrr   	Exceptionpathsplitextloweropenreadlinestripsplitlen)	filenameosrootext_Zext2flineparts r!   H/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/igraph/io/files.py_identify_format   sL    



r#   #c                 O   s   t |trt|}g d }}|D ]L}	|	 }	t|	dkr:q |	|rFq dd |	|D }
||
 |d7 }q |  |dkr| j	|f||}n | j
|f||\}}||j|< |S )a  Constructs a graph based on an adjacency matrix from the given file.

    Additional positional and keyword arguments not mentioned here are
    passed intact to L{Graph.Adjacency}.

    @param f: the name of the file to be read or a file object
    @param sep: the string that separates the matrix elements in a row.
      C{None} means an arbitrary sequence of whitespace characters.
    @param comment_char: lines starting with this string are treated
      as comments.
    @param attribute: an edge attribute name where the edge weights are
      stored in the case of a weighted adjacency matrix. If C{None},
      no weights are stored, values larger than 1 are considered as
      edge multiplicities.
    @return: the created graphr   c                 S   s   g | ]}t |qS r!   )float).0xr!   r!   r"   
<listcomp>   s     z8_construct_graph_from_adjacency_file.<locals>.<listcomp>r
   N)
isinstancestrr   r   r   
startswithr   appendcloseZ	AdjacencyZ_Weighted_Adjacencyes)clsr   sepZcomment_char	attributeargskwdsmatrixrir   rowgraphweightsr!   r!   r"   $_construct_graph_from_adjacency_filed   s$    





r9   Fc                 C   sD   ddl m} t|| ||\}}}}||jd< ||d< ||d< |S )a  Reads a graph from a file conforming to the DIMACS minimum-cost flow
    file format.

    For the exact definition of the format, see
    U{http://lpsolve.sourceforge.net/5.5/DIMACS.htm}.

    Restrictions compared to the official description of the format are
    as follows:

      - igraph's DIMACS reader requires only three fields in an arc
        definition, describing the edge's source and target node and
        its capacity.
      - Source vertices are identified by 's' in the FLOW field, target
        vertices are identified by 't'.
      - Node indices start from 1. Only a single source and target node
        is allowed.

    @param f: the name of the file or a Python file handle
    @param directed: whether the generated graph should be directed.
    @return: the generated graph. The indices of the source and target
      vertices are attached as graph attributes C{source} and C{target},
      the edge capacities are stored in the C{capacity} edge attribute.
    r   )Graphcapacitysourcetarget)Zigraphr:   superZRead_DIMACSr.   )r/   r   Zdirectedr:   r7   r<   r=   capr!   r!   r"   !_construct_graph_from_dimacs_file   s    
r@   c              
   C   sT   t  D}t|d}tt|d| W 5 Q R X | j||dW  5 Q R  S Q R X dS )aD  Reads a graph from a zipped GraphML file.

    @param f: the name of the file
    @param index: if the GraphML file contains multiple graphs,
      specified the one that should be loaded. Graph indices
      start from zero, so if you want to load the first graph,
      specify 0 here.
    @return: the loaded graph objectwbrb)indexN)r   r   r   gzipGzipFileZRead_GraphML)r/   r   rC   tmpfileoutfr!   r!   r"   #_construct_graph_from_graphmlz_file   s    	rH   c                 C   s   ddl }t|dr||}nzt|d}W n~ tk
rl   z||}W n tk
rf   tdY nX Y nR tk
r   z||}W n tk
r   tdY nX Y nX ||}|  t	|| std| j
 |S )zReads a graph from Python pickled format

    @param fname: the name of the file, a stream to read from, or
      a string containing the pickled data.
    @return: the created graph object.
    r   Nr   rB   zJCannot load file. If fname is a file name, that filename may be incorrect.unpickled object is not a %s)pickler   loadr   UnicodeDecodeErrorloads	TypeErrorIOErrorr-   r)   __name__)r/   fnamerJ   resultfpr!   r!   r"   !_construct_graph_from_pickle_file   s0    


rT   c                 C   sn   ddl }t|dr@t|tjr*||}qR|tjd|d}n|t|d}t|| sjtd| j |S )zReads a graph from compressed Python pickled format, uncompressing
    it on-the-fly.

    @param fname: the name of the file or a stream to read from.
    @return: the created graph object.
    r   Nr   rB   modefileobjrI   )	rJ   r   r)   rD   rE   rK   r   rN   rP   )r/   rQ   rJ   rR   r!   r!   r"   "_construct_graph_from_picklez_file   s    

rX   c              	   O   s   t |tjrt|}|dkr$t|}z| j| d }W n( ttfk
r^   tdt| Y nX |dkrxtdt| t	| |}||f||S )a  Unified reading function for graphs.

    This method tries to identify the format of the graph given in
    the first parameter and calls the corresponding reader method.

    The remaining arguments are passed to the reader method without
    any changes.

    @param f: the file containing the graph to be loaded
    @param format: the format of the file (if known in advance).
      C{None} means auto-detection. Possible values are: C{"ncol"}
      (NCOL format), C{"lgl"} (LGL format), C{"graphdb"} (GraphDB
      format), C{"graphml"}, C{"graphmlz"} (GraphML and gzipped
      GraphML format), C{"gml"} (GML format), C{"net"}, C{"pajek"}
      (Pajek format), C{"dimacs"} (DIMACS format), C{"edgelist"},
      C{"edges"} or C{"edge"} (edge list), C{"adjacency"}
      (adjacency matrix), C{"dl"} (DL format used by UCINET),
      C{"pickle"} (Python pickled format),
      C{"picklez"} (gzipped Python pickled format)
    @raises IOError: if the file format can't be identified and
      none was given.
    Nr   unknown file format: %sz$no reader method for file format: %s
r)   r   PathLiker*   r#   Z_format_mappingKeyError
IndexErrorrO   getattr)r/   r   formatr2   r3   readerr!   r!   r"   _construct_graph_from_file  s    
ra    
c                 O   sV   t |trt|d}| j||}|D ]$}||tt| || q$|  dS )a  Writes the adjacency matrix of the graph to the given file

    All the remaining arguments not mentioned here are passed intact
    to L{Graph.get_adjacency}.

    @param f: the name of the file to be written.
    @param sep: the string that separates the matrix elements in a row
    @param eol: the string that separates the rows of the matrix. Please
      note that igraph is able to read back the written adjacency matrix
      if and only if this is a single newline character
    wN)r)   r*   r   Zget_adjacencywritejoinmapr-   )r7   r   r0   eolr2   r3   r4   r6   r!   r!   r"   _write_graph_to_adjacency_file*  s    

ri   r;   c                 C   s   |dkr2z| d }W n t k
r0   tdY nX |dkrdz| d }W n t k
rb   tdY nX t|tr||  krtd|  dg|   }t| ||||S )aG  Writes the graph in DIMACS format to the given file.

    @param f: the name of the file to be written or a Python file handle.
    @param source: the source vertex ID. If C{None}, igraph will try to
      infer it from the C{source} graph attribute.
    @param target: the target vertex ID. If C{None}, igraph will try to
      infer it from the C{target} graph attribute.
    @param capacity: the capacities of the edges in a list or the name of
      an edge attribute that holds the capacities. If there is no such
      edge attribute, every edge will have a capacity of 1.
    Nr<   zlsource vertex must be provided in the 'source' graph attribute or in the 'source' argument of write_dimacs()r=   zltarget vertex must be provided in the 'target' graph attribute or in the 'target' argument of write_dimacs()z"'%s' edge attribute does not existr
   )	r\   
ValueErrorr)   r*   Zedge_attributesr   Zecountr   Zwrite_dimacs)r7   r   r<   r=   r;   r!   r!   r"   _write_graph_to_dimacs_file?  s$    

rk   	   c              	   C   sF   t  6}| | t|d|}tt|d| |  W 5 Q R X dS )av  Writes the graph to a zipped GraphML file.

    The library uses the gzip compression algorithm, so the resulting
    file can be unzipped with regular gzip uncompression (like
    C{gunzip} or C{zcat} from Unix command line) or the Python C{gzip}
    module.

    Uses a temporary file to store intermediate GraphML data, so
    make sure you have enough free space to store the unzipped
    GraphML file as well.

    @param f: the name of the file to be written.
    @param compresslevel: the level of compression. 1 is fastest and
      produces the least compression, and 9 is slowest and produces
      the most compression.rA   rB   N)r   Zwrite_graphmlrD   rE   r   r   r-   )r7   r   compresslevelrF   rG   r!   r!   r"   _write_graph_to_graphmlz_filef  s
    
rn   c                 C   sX   ddl }|dkr|| |S t|ds6d}t|d}nd}|| ||}|rT|  |S )a  Saves the graph in Python pickled format

    @param fname: the name of the file or a stream to save to. If
      C{None}, saves the graph to a string and returns the string.
    @param version: pickle protocol version to be used. If -1, uses
      the highest protocol available
    @return: C{None} if the graph was saved successfully to the
      given file, or a string if C{fname} was C{None}.
    r   Nre   TrA   F)rJ   dumpsr   r   dumpr-   r7   rQ   versionrJ   Zfile_was_openedrR   r!   r!   r"   _write_graph_to_pickle_file}  s    

rt   c                 C   sd   ddl }d}t|ds(d}t|d}nt|tjsFd}tjd|d}|| ||}|r`|  |S )a  Saves the graph in Python pickled format, compressed with
    gzip.

    Saving in this format is a bit slower than saving in a Python pickle
    without compression, but the final file takes up much less space on
    the hard drive.

    @param fname: the name of the file or a stream to save to.
    @param version: pickle protocol version to be used. If -1, uses
      the highest protocol available
    @return: C{None} if the graph was saved successfully to the
      given file.
    r   NFre   TrA   rU   )rJ   r   rD   r   r)   rE   rq   r-   rr   r!   r!   r"   _write_graph_to_picklez_file  s    
ru   c              	   O   s   t |tjrt|}|dkr$t|}z| j| d }W n( ttfk
r^   tdt| Y nX |dkrxtdt| t	| |}||f||S )a  Unified writing function for graphs.

    This method tries to identify the format of the graph given in
    the first parameter (based on extension) and calls the corresponding
    writer method.

    The remaining arguments are passed to the writer method without
    any changes.

    @param f: the file containing the graph to be saved
    @param format: the format of the file (if one wants to override the
      format determined from the filename extension, or the filename itself
      is a stream). C{None} means auto-detection. Possible values are:

        - C{"adjacency"}: adjacency matrix format

        - C{"dimacs"}: DIMACS format

        - C{"dot"}, C{"graphviz"}: GraphViz DOT format

        - C{"edgelist"}, C{"edges"} or C{"edge"}: numeric edge list format

        - C{"gml"}: GML format

        - C{"graphml"} and C{"graphmlz"}: standard and gzipped GraphML
          format

        - C{"gw"}, C{"leda"}, C{"lgr"}: LEDA native format

        - C{"lgl"}: LGL format

        - C{"ncol"}: NCOL format

        - C{"net"}, C{"pajek"}: Pajek format

        - C{"pickle"}, C{"picklez"}: standard and gzipped Python pickled
          format

        - C{"svg"}: SVG format

    @raises IOError: if the file format can't be identified and
      none was given.
    Nr
   rY   z$no writer method for file format: %srZ   )r7   r   r_   r2   r3   writerr!   r!   r"   _write_graph_to_file  s    ,
rw   )Nr$   N)F)r   )N)N)rb   rc   )NNr;   )rl   )Nro   )Nro   )N)rD   r   shutilr   warningsr   Zigraph._igraphr   Zigraph.utilsr   r#   r9   r@   rH   rT   rX   ra   ri   rk   rn   rt   ru   rw   r!   r!   r!   r"   <module>   s0   X     
+
"

-
%
     
'


!