ó
vA¤\c           @  s	  d  d l  m Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l m	 Z	 m
 Z
 d  d l Z e j ƒ  Z d  d l Z d e e e j ƒ  ƒ ƒ d Z d e f d „  ƒ  YZ d e f d	 „  ƒ  YZ e a e a e j ƒ  Z d
 „  Z d „  Z d „  Z d S(   iÿÿÿÿ(   t   print_functionN(   t
   clear_slott   safe_renamet   .s   .tmpt   FileLocationc           B  s°   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   s=   
    A location that saves files to a directory on disk.
    c         C  sË   | |  _  y t j |  j  ƒ Wn n XyW t j j |  j  d ƒ } t | d ƒ  } | j d ƒ Wd  QXt j | ƒ t |  _	 Wn t
 |  _	 n Xi  |  _ t j j |  j  d ƒ |  _ d |  _ d  |  _ d  S(   Ns   text.txtt   ws   Test.t
   persistenti    (   t	   directoryt   ost   makedirst   patht   joint   opent   writet   unlinkt   Truet   activet   Falset   mtimesR   t   persistent_mtimet   Nonet   persistent_data(   t   selfR   t   fnt   f(    (    s   renpy/savelocation.pyt   __init__4   s"    			c         C  s)   t  j j |  j t j j | t j ƒ ƒ S(   s8   
        Given a slot name, returns a filename.
        (   R   R
   R   R   t   renpyt   exportst   fsencodet   savegame_suffix(   R   t   slotname(    (    s   renpy/savelocation.pyt   filenameV   s    c         C  s&   t  j r" d d l } | j ƒ  n  d S(   sJ   
        Called to indicate that the HOME filesystem was changed.
        iÿÿÿÿN(   R   t
   emscriptent   syncfs(   R   R    (    (    s   renpy/savelocation.pyt   sync]   s    	c   
   	   C  s¸  |  j  s d St Ÿ|  j } i  } t j } t | ƒ } xp t j |  j ƒ D]\ } | j	 | ƒ sf qK n  | |  } y, t j
 j t j
 j |  j | ƒ ƒ | | <WqK qK XqK W| |  _ x? | j ƒ  D]1 \ } } | j | d ƒ | k rÁ t | ƒ qÁ qÁ Wx' | D] } | | k rý t | ƒ qý qý Wx‹ |  j d |  j g D]s } t j
 j | ƒ r7t j
 j | ƒ } | |  j k rªt j j | ƒ }	 |	 d k	 r§| |  _ |	 |  _ Pq§qªq7q7WWd QXd S(   s;   
        Scan for files that are added or removed.
        Ns   .new(   R   t	   disk_lockR   R   R   t   lenR   t   listdirR   t   endswithR
   t   getmtimeR   t	   iteritemst   getR   R   R   t   existsR   t   loadR   (
   R   t
   old_mtimest
   new_mtimest   suffixt
   suffix_lenR   R   t   mtimet   pfnt   data(    (    s   renpy/savelocation.pyt   scanf   s>    			,			c         C  sA   |  j  | ƒ } t  | j | ƒ Wd QX|  j ƒ  |  j ƒ  d S(   s4   
        Saves the save record in slotname.
        N(   R   R#   t
   write_fileR"   R3   (   R   R   t   recordR   (    (    s   renpy/savelocation.pyt   save–   s
    
c         C  s   t  |  j ƒ S(   sa   
        Returns a list of all slots with savefiles in them, in arbitrary
        order.
        (   t   listR   (   R   (    (    s   renpy/savelocation.pyR7   £   s    c         C  s   |  j  j | d ƒ S(   s…   
        For a slot, returns the time the object was saved in that
        slot.

        Returns None if the slot is empty.
        N(   R   R)   R   (   R   R   (    (    s   renpy/savelocation.pyR0   «   s    c         C  s¸   t  ¬ y% |  j | ƒ } t j | d ƒ } Wn d SXzi y& | j d ƒ } t j | ƒ } | SWn n Xy' | j d ƒ j d ƒ } i | d 6SWn n Xi  SWd | j	 ƒ  XWd QXd S(   sa   
        Returns the JSON data for slotname.

        Returns None if the slot is empty.
        t   rt   jsont
   extra_infos   utf-8t
   _save_nameN(
   R#   R   t   zipfilet   ZipFileR   t   readR9   t   loadst   decodet   close(   R   R   R   t   zfR2   R:   (    (    s   renpy/savelocation.pyR9   µ   s(    c         C  sá   t  Õ |  j | ƒ } | d k r& d Sy% |  j | ƒ } t j | d ƒ } Wn d SXy t } | j d ƒ Wn t } | j d ƒ n X| j	 ƒ  | r¸ t
 j j j | d | ƒ } n t
 j j j | d | ƒ } | SWd QXd S(   s{   
        Returns a displayable that show the screenshot for this slot.

        Returns None if the slot is empty.
        R8   s   screenshot.tgas   screenshot.pngN(   R#   R0   R   R   R<   R=   R   t   getinfoR   RA   R   t   displayt   imt   ZipFileImage(   R   R   R0   R   RB   t   pngt
   screenshot(    (    s   renpy/savelocation.pyRH   Ø   s(    
c         C  sO   t  C |  j | ƒ } t j | d ƒ } | j d ƒ } | j ƒ  | SWd QXd S(   si   
        Returns the log component of the file found in `slotname`, so it
        can be loaded.
        R8   t   logN(   R#   R   R<   R=   R>   RA   (   R   R   R   RB   t   rv(    (    s   renpy/savelocation.pyR+   ü   s    
c         C  sV   t  J |  j | ƒ } t j j | ƒ r8 t j | ƒ n  |  j ƒ  |  j ƒ  Wd QXd S(   s/   
        Deletes the file in slotname.
        N(   R#   R   R   R
   R*   R   R"   R3   (   R   R   R   (    (    s   renpy/savelocation.pyR     s    
c         C  s‹   t   |  j | ƒ } |  j | ƒ } t j j | ƒ s; d St j j | ƒ r] t j | ƒ n  t j | | ƒ |  j ƒ  |  j ƒ  Wd QXd S(   s3   
        If old exists, renames it to new.
        N(	   R#   R   R   R
   R*   R   t   renameR"   R3   (   R   t   oldt   new(    (    s   renpy/savelocation.pyRK     s    
c         C  si   t  ] |  j | ƒ } |  j | ƒ } t j j | ƒ s; d St j | | ƒ |  j ƒ  |  j ƒ  Wd QXd S(   s9   
        Copies `old` to `new`, if `old` exists.
        N(	   R#   R   R   R
   R*   t   shutilt   copyfileR"   R3   (   R   RL   RM   (    (    s   renpy/savelocation.pyt   copy/  s    
c         C  s$   |  j  r |  j |  j  f g Sg  Sd S(   s½   
        Returns a list of (mtime, persistent) tuples loaded from the
        persistent file. This should return quickly, with the actual
        load occuring in the scan thread.
        N(   R   R   (   R   (    (    s   renpy/savelocation.pyt   load_persistent@  s    	c      
   C  s„   t  x |  j s d S|  j } | t } | d } t | d ƒ  } | j | ƒ Wd QXt | | ƒ t | | ƒ |  j ƒ  Wd QXd S(   sƒ   
        Saves `data` as the persistent data. Data is a binary string giving
        the persistent data in python format.
        Ns   .newt   wb(   R#   R   R   t   tmpR   R   R   R"   (   R   R2   R   t   fn_tmpt   fn_newR   (    (    s   renpy/savelocation.pyt   save_persistentL  s    		

c         C  s9   |  j  s d  Sy t j |  j ƒ |  j ƒ  Wn n Xd  S(   N(   R   R   R   R   R"   (   R   (    (    s   renpy/savelocation.pyt   unlink_persistentc  s    	c         C  s#   t  | t ƒ s t S|  j | j k S(   N(   t
   isinstanceR   R   R   (   R   t   other(    (    s   renpy/savelocation.pyt   __eq__o  s    c         C  s   |  | k S(   N(    (   R   RY   (    (    s   renpy/savelocation.pyt   __ne__u  s    (   t   __name__t
   __module__t   __doc__R   R   R"   R3   R6   R7   R0   R9   RH   R+   R   RK   RP   RQ   RV   RW   RZ   R[   (    (    (    s   renpy/savelocation.pyR   /   s&   	"				0			
	#	$								t   MultiLocationc           B  s¹   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   sš   
    A location that saves in multiple places. When loading or otherwise
    accessing a file, it loads the newest file found for the given slotname.
    c         C  s   g  |  _  d  S(   N(   t	   locations(   R   (    (    s   renpy/savelocation.pyR     s    c         C  s#   g  |  j  D] } | j r
 | ^ q
 S(   N(   R`   R   (   R   t   i(    (    s   renpy/savelocation.pyt   active_locations‚  s    c         C  s]   d } d } xJ |  j D]? } | j s+ q n  | j | ƒ } | | k r | } | } q q W| S(   s€   
        Returns the location containing the slotname with the newest
        mtime. Returns None of the slot is empty.
        iÿÿÿÿN(   R   R`   R   R0   (   R   R   R0   t   locationt   lt
   slot_mtime(    (    s   renpy/savelocation.pyt   newest…  s    	c         C  s'   | |  j  k r d S|  j  j | ƒ d S(   s&   
        Adds a new location.
        N(   R`   t   append(   R   Rc   (    (    s   renpy/savelocation.pyt   addš  s    c         C  sL   t  } x* |  j ƒ  D] } | j | | ƒ t } q W| sH t d ƒ ‚ n  d  S(   Ns$   Not saved - no valid save locations.(   R   Rb   R6   R   t	   Exception(   R   R   R5   t   savedRd   (    (    s   renpy/savelocation.pyR6   ¤  s    
c         C  s=   t  ƒ  } x' |  j ƒ  D] } | j | j ƒ  ƒ q Wt | ƒ S(   N(   t   setRb   t   updateR7   (   R   RJ   Rd   (    (    s   renpy/savelocation.pyR7   ¯  s    	c         C  s,   |  j  | ƒ } | d  k r d  S| j | ƒ S(   N(   Rf   R   R0   (   R   R   Rd   (    (    s   renpy/savelocation.pyR0   ·  s    c         C  s,   |  j  | ƒ } | d  k r d  S| j | ƒ S(   N(   Rf   R   R9   (   R   R   Rd   (    (    s   renpy/savelocation.pyR9   ¿  s    c         C  s,   |  j  | ƒ } | d  k r d  S| j | ƒ S(   N(   Rf   R   RH   (   R   R   Rd   (    (    s   renpy/savelocation.pyRH   Ç  s    c         C  s   |  j  | ƒ } | j | ƒ S(   N(   Rf   R+   (   R   R   Rd   (    (    s   renpy/savelocation.pyR+   Ï  s    c         C  s(   x! |  j  ƒ  D] } | j | ƒ q Wd  S(   N(   Rb   R   (   R   R   Rd   (    (    s   renpy/savelocation.pyR   Ó  s    c         C  s+   x$ |  j  ƒ  D] } | j | | ƒ q Wd  S(   N(   Rb   RK   (   R   RL   RM   Rd   (    (    s   renpy/savelocation.pyRK   ×  s    c         C  s+   x$ |  j  ƒ  D] } | j | | ƒ q Wd  S(   N(   Rb   RP   (   R   RL   RM   Rd   (    (    s   renpy/savelocation.pyRP   Û  s    c         C  s4   g  } x' |  j  ƒ  D] } | j | j ƒ  ƒ q W| S(   N(   Rb   t   extendRQ   (   R   RJ   Rd   (    (    s   renpy/savelocation.pyRQ   ß  s    c         C  s(   x! |  j  ƒ  D] } | j | ƒ q Wd  S(   N(   Rb   RV   (   R   R2   Rd   (    (    s   renpy/savelocation.pyRV   ç  s    c         C  s%   x |  j  ƒ  D] } | j ƒ  q Wd  S(   N(   Rb   RW   (   R   Rd   (    (    s   renpy/savelocation.pyRW   ì  s    c         C  s"   x |  j  D] } | j ƒ  q
 Wd  S(   N(   R`   R3   (   R   Rd   (    (    s   renpy/savelocation.pyR3   ñ  s    c         C  s#   t  | t ƒ s t S|  j | j k S(   N(   RX   R_   R   R`   (   R   RY   (    (    s   renpy/savelocation.pyRZ   ø  s    c         C  s   |  | k S(   N(    (   R   RY   (    (    s   renpy/savelocation.pyR[   þ  s    (   R\   R]   R^   R   Rb   Rf   Rh   R6   R7   R0   R9   RH   R+   R   RK   RP   RQ   RV   RW   R3   RZ   R[   (    (    (    s   renpy/savelocation.pyR_   y  s(   				
														c           C  sO   t  a xB t sJ y t j j j ƒ  Wn n Xt  t j d ƒ Wd  QXq	 Wd  S(   Ng      @(   R   t   quit_scan_threadR   t   loadsaveRc   R3   t   scan_thread_conditiont   wait(    (    (    s   renpy/savelocation.pyt   run_scan_thread  s    	c           C  s+   t   t a t  j ƒ  Wd  QXt j ƒ  d  S(   N(   Rp   R   Rn   t	   notifyAllt   scan_threadR   (    (    (    s   renpy/savelocation.pyt   quit  s    c          C  s   t  ƒ  }  |  j t t j j ƒ ƒ t j rg t j rg t j	 j
 t j j d ƒ } |  j t | ƒ ƒ n  |  j ƒ  |  t j _ t j d t ƒ a t j ƒ  d  S(   Nt   savest   target(   R_   Rh   R   R   t   configt   savedirt   mobilet   macappR   R
   R   t   gamedirR3   Ro   Rc   t	   threadingt   ThreadRr   Rt   t   start(   Rc   R
   (    (    s   renpy/savelocation.pyt   init'  s    	
(   t
   __future__R    R   R<   R9   t   renpy.displayR   R}   t   renpy.loadsaveR   R   RN   t   RLockR#   t   timet   strt   intRS   t   objectR   R_   R   Rt   R   Rn   t	   ConditionRp   Rr   Ru   R€   (    (    (    s   renpy/savelocation.pyt   <module>   s&    ÿ K‹		
