a
    F­^i"9  ã                   @   s  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 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 ¡ Zd dlZdeee ¡ ƒƒ d Z G dd„ de!ƒZ"G d	d
„ d
e!ƒZ#da$da%e &¡ Z'dd„ Z(dd„ Z)dd„ Z*dS )é    )ÚdivisionÚabsolute_importÚwith_statementÚprint_functionÚunicode_literals)ÚPY2Ú
basestringÚbchrÚbordÚchrÚopenÚpystrÚrangeÚroundÚstrÚtobytesÚunicodeN)Ú
clear_slotÚsafe_renameÚ.z.tmpc                   @   s    e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&S )'ÚFileLocationz=
    A location that saves files to a directory on disk.
    c                 C   sÒ   || _ zt | j ¡ W n ty(   Y n0 tj | j ¡ zXtj | j d¡}t	|dƒ}| 
d¡ W d   ƒ n1 st0    Y  t |¡ d| _W n ty¨   d| _Y n0 i | _tj | j d¡| _d| _d | _d S )Nztext.txtÚwzTest.TFÚ
persistentr   )Ú	directoryÚosÚmakedirsÚ	ExceptionÚrenpyÚutilZexpose_directoryÚpathÚjoinr   ÚwriteÚunlinkÚactiveÚmtimesr   Úpersistent_mtimeÚpersistent_data)Úselfr   ÚfnÚf© r*   úVC:\Program Files (x86)\Steam\steamapps\common\Selene ~Apoptosis~\renpy\savelocation.pyÚ__init__7   s$    (

zFileLocation.__init__c                 C   s   t j | jtj |tj ¡¡S )z8
        Given a slot name, returns a filename.
        )r   r   r    r   r   ÚexportsÚfsencodeÚsavegame_suffix©r'   Úslotnamer*   r*   r+   Úfilename[   s    zFileLocation.filenamec                 C   s   t jrddl}| ¡  dS )zJ
        Called to indicate that the HOME filesystem was changed.
        r   N)r   Ú
emscriptenÚsyncfs)r'   r3   r*   r*   r+   Úsyncb   s    zFileLocation.syncc           
   
   C   sV  | j s
dS t0 | j}i }tj}t|ƒ}t | j¡D ]R}| 	|¡sFq6|d| … }z tj
 tj
 | j|¡¡||< W q6 ty†   Y q60 q6|| _| ¡ D ] \}}| |d¡|kr˜t|ƒ q˜|D ]}||vr¾t|ƒ q¾| jd | jfD ]L}tj
 |¡rätj
 |¡}|| jkrätj |¡}	|	durä|| _|	| _ q2qäW d  ƒ n1 sH0    Y  dS )z;
        Scan for files that are added or removed.
        Nú.new)r#   Ú	disk_lockr$   r   r/   Úlenr   Úlistdirr   Úendswithr   Úgetmtimer    r   ÚitemsÚgetr   r   Úexistsr%   Úloadr&   )
r'   Z
old_mtimesZ
new_mtimesÚsuffixZ
suffix_lenr(   r1   ÚmtimeZpfnÚdatar*   r*   r+   Úscank   s>    
 


zFileLocation.scanc                 C   sX   |   |¡}t | |¡ W d  ƒ n1 s.0    Y  tj |¡ |  ¡  |  ¡  dS )z4
        Saves the save record in slotname.
        N)r2   r7   Ú
write_filer   r   Úexpose_filer5   rC   )r'   r1   Úrecordr2   r*   r*   r+   Úsave›   s    
(zFileLocation.savec                 C   s
   t | jƒS )za
        Returns a list of all slots with savefiles in them, in arbitrary
        order.
        )Úlistr$   ©r'   r*   r*   r+   rH   ª   s    zFileLocation.listc                 C   s   | j  |d¡S )z…
        For a slot, returns the time the object was saved in that
        slot.

        Returns None if the slot is empty.
        N)r$   r=   r0   r*   r*   r+   rA   ²   s    zFileLocation.mtimec              
   C   s6  t  zæ|  |¡}t |d¡¼}z8| d¡}t |¡}|W W  d  ƒ W W  d  ƒ S  tyl   Y n0 z8| d¡ d¡}d|iW W  d  ƒ W W  d  ƒ S  ty¸   Y n0 i W  d  ƒ W W  d  ƒ S 1 sâ0    Y  W n" ty   Y W d  ƒ dS 0 W d  ƒ n1 s(0    Y  dS )za
        Returns the JSON data for slotname.

        Returns None if the slot is empty.
        ÚrÚjsonNÚ
extra_infozutf-8Ú
_save_name)	r7   r2   ÚzipfileÚZipFileÚreadrK   Úloadsr   Údecode)r'   r1   r2   ÚzfrB   rL   r*   r*   r+   rK   ¼   s$    


$(6zFileLocation.jsonc              
   C   s  t  ð |  |¡}|du r*W d  ƒ dS zn|  |¡}t |d¡D}zd}| d¡ W n  tyv   d}| d¡ Y n0 W d  ƒ n1 sŒ0    Y  W n  ty¸   Y W d  ƒ dS 0 |rÒtjj	 
|d|¡}ntjj	 
|d|¡}|W  d  ƒ S 1  sþ0    Y  dS )z{
        Returns a displayable that show the screenshot for this slot.

        Returns None if the slot is empty.
        NrJ   Fzscreenshot.tgaTzscreenshot.png)r7   rA   r2   rN   rO   Úgetinfor   r   ÚdisplayÚimZZipFileImage)r'   r1   rA   r2   rS   ZpngÚ
screenshotr*   r*   r+   rW   Ù   s&    

2zFileLocation.screenshotc              	   C   sl   t T |  |¡}t |d¡}| d¡}W d  ƒ n1 s<0    Y  |W  d  ƒ S 1 s^0    Y  dS )zi
        Returns the log component of the file found in `slotname`, so it
        can be loaded.
        rJ   ÚlogN)r7   r2   rN   rO   rP   )r'   r1   r2   rS   Úrvr*   r*   r+   r?   ú   s
    
(zFileLocation.loadc                 C   sX   t @ |  |¡}tj |¡r&t |¡ |  ¡  |  ¡  W d  ƒ n1 sJ0    Y  dS )z/
        Deletes the file in slotname.
        N)r7   r2   r   r   r>   r"   r5   rC   )r'   r1   r2   r*   r*   r+   r"   	  s    

zFileLocation.unlinkc                 C   s   t x |  |¡}|  |¡}tj |¡s6W d  ƒ dS |t }t||ƒ t||ƒ tj 	|¡ |  
¡  |  ¡  W d  ƒ n1 s‚0    Y  dS )z3
        If old exists, renames it to new.
        N)r7   r2   r   r   r>   Útmpr   r   r   rE   r5   rC   )r'   ÚoldÚnewZold_tmpr*   r*   r+   Úrename  s    



zFileLocation.renamec                 C   s€   t h |  |¡}|  |¡}tj |¡s6W d  ƒ dS t ||¡ tj 	|¡ |  
¡  |  ¡  W d  ƒ n1 sr0    Y  dS )z9
        Copies `old` to `new`, if `old` exists.
        N)r7   r2   r   r   r>   ÚshutilÚcopyfiler   r   rE   r5   rC   )r'   r[   r\   r*   r*   r+   Úcopy,  s    

zFileLocation.copyc                 C   s   | j r| j| j fgS g S dS )z½
        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%   rI   r*   r*   r+   Úload_persistent>  s    zFileLocation.load_persistentc              	   C   s¾   t ¦ | jsW d  ƒ dS | j}|t }|d }t|dƒ}| |¡ W d  ƒ n1 s\0    Y  t||ƒ t||ƒ tj 	|¡| _
tj |¡ |  ¡  W d  ƒ n1 s°0    Y  dS )zƒ
        Saves `data` as the persistent data. Data is a binary string giving
        the persistent data in python format.
        Nr6   Úwb)r7   r#   r   rZ   r   r!   r   r   r   r;   r%   r   r   rE   r5   )r'   rB   r(   Zfn_tmpZfn_newr)   r*   r*   r+   Úsave_persistentJ  s    (

zFileLocation.save_persistentc                 C   s:   | j s
d S zt | j¡ |  ¡  W n ty4   Y n0 d S ©N)r#   r   r"   r   r5   r   rI   r*   r*   r+   Úunlink_persistentf  s    zFileLocation.unlink_persistentc                 C   s   t |tƒsdS | j|jkS ©NF)Ú
isinstancer   r   ©r'   Úotherr*   r*   r+   Ú__eq__r  s    
zFileLocation.__eq__c                 C   s
   | |k S rd   r*   rh   r*   r*   r+   Ú__ne__x  s    zFileLocation.__ne__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r,   r2   r5   rC   rG   rH   rA   rK   rW   r?   r"   r]   r`   ra   rc   re   rj   rk   r*   r*   r*   r+   r   2   s&   $	0
!r   c                   @   s¨   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(S ))ÚMultiLocationzš
    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 rd   ©Ú	locationsrI   r*   r*   r+   r,   ‚  s    zMultiLocation.__init__c                 C   s   dd„ | j D ƒS )Nc                 S   s   g | ]}|j r|‘qS r*   )r#   )Ú.0Úir*   r*   r+   Ú
<listcomp>†  ó    z2MultiLocation.active_locations.<locals>.<listcomp>rq   rI   r*   r*   r+   Úactive_locations…  s    zMultiLocation.active_locationsc                 C   sB   d}d}| j D ].}|jsq| |¡}|dur||kr|}|}q|S )z€
        Returns the location containing the slotname with the newest
        mtime. Returns None if the slot is empty.
        éÿÿÿÿN)rr   r#   rA   )r'   r1   rA   ÚlocationÚlÚ
slot_mtimer*   r*   r+   Únewestˆ  s    

zMultiLocation.newestc                 C   s   || j v rdS | j  |¡ dS )z&
        Adds a new location.
        N)rr   Úappend)r'   ry   r*   r*   r+   Úaddž  s    
zMultiLocation.addc                 C   s2   d}|   ¡ D ]}| ||¡ d}q|s.tdƒ‚d S )NFTz$Not saved - no valid save locations.)rw   rG   r   )r'   r1   rF   Zsavedrz   r*   r*   r+   rG   ¨  s    zMultiLocation.savec                 C   s*   t ƒ }|  ¡ D ]}| | ¡ ¡ qt|ƒS rd   )Úsetrw   ÚupdaterH   ©r'   rY   rz   r*   r*   r+   rH   ³  s    zMultiLocation.listc                 C   s    |   |¡}|d u rd S | |¡S rd   )r|   rA   ©r'   r1   rz   r*   r*   r+   rA   »  s    
zMultiLocation.mtimec                 C   s    |   |¡}|d u rd S | |¡S rd   )r|   rK   r‚   r*   r*   r+   rK   Ã  s    
zMultiLocation.jsonc                 C   s    |   |¡}|d u rd S | |¡S rd   )r|   rW   r‚   r*   r*   r+   rW   Ë  s    
zMultiLocation.screenshotc                 C   s   |   |¡}| |¡S rd   )r|   r?   r‚   r*   r*   r+   r?   Ó  s    
zMultiLocation.loadc                 C   s   |   ¡ D ]}| |¡ qd S rd   )rw   r"   r‚   r*   r*   r+   r"   ×  s    zMultiLocation.unlinkc                 C   s   |   ¡ D ]}| ||¡ qd S rd   )rw   r]   ©r'   r[   r\   rz   r*   r*   r+   r]   Û  s    zMultiLocation.renamec                 C   s   |   ¡ D ]}| ||¡ qd S rd   )rw   r`   rƒ   r*   r*   r+   r`   ß  s    zMultiLocation.copyc                 C   s$   g }|   ¡ D ]}| | ¡ ¡ q|S rd   )rw   Úextendra   r   r*   r*   r+   ra   ã  s    zMultiLocation.load_persistentc                 C   s   |   ¡ D ]}| |¡ qd S rd   )rw   rc   )r'   rB   rz   r*   r*   r+   rc   ë  s    zMultiLocation.save_persistentc                 C   s   |   ¡ D ]}| ¡  qd S rd   )rw   re   ©r'   rz   r*   r*   r+   re   ð  s    zMultiLocation.unlink_persistentc                 C   s   | j D ]}| ¡  qd S rd   )rr   rC   r…   r*   r*   r+   rC   õ  s    
zMultiLocation.scanc                 C   s   t |tƒsdS | j|jkS rf   )rg   rp   rr   rh   r*   r*   r+   rj   ü  s    
zMultiLocation.__eq__c                 C   s
   | |k S rd   r*   rh   r*   r*   r+   rk     s    zMultiLocation.__ne__N)rl   rm   rn   ro   r,   rw   r|   r~   rG   rH   rA   rK   rW   r?   r"   r]   r`   ra   rc   re   rC   rj   rk   r*   r*   r*   r+   rp   |  s(   
rp   Fc                   C   s`   da t s\ztjj ¡  W n ty*   Y n0 t t d¡ W d   ƒ q1 sP0    Y  qd S )NFg      @)Úquit_scan_threadr   Úloadsavery   rC   r   Úscan_thread_conditionÚwaitr*   r*   r*   r+   Úrun_scan_thread  s    rŠ   c                   C   sD   t  dat  ¡  W d   ƒ n1 s&0    Y  td ur@t ¡  d S )NT)rˆ   r†   Ú
notify_allÚscan_threadr    r*   r*   r*   r+   Úquit   s
    &r   c                  C   sl   t ƒ } |  ttjjƒ¡ tjsDtjsDtj	 
tjjd¡}|  t|ƒ¡ |  ¡  | tj_tjtdat ¡  d S )NÚsaves)Útarget)rp   r~   r   r   ÚconfigÚsavedirÚmobileÚmacappr   r   r    ÚgamedirrC   r‡   ry   Ú	threadingÚThreadrŠ   rŒ   Ústart)ry   r   r*   r*   r+   Úinit+  s    r˜   )+Ú
__future__r   r   r   r   r   Úrenpy.compatr   r   r	   r
   r   r   r   r   r   r   r   r   r   rN   rK   r   r•   Úrenpy.loadsaver   r   r^   ÚRLockr7   ÚtimeÚintrZ   Úobjectr   rp   rŒ   r†   Ú	Conditionrˆ   rŠ   r   r˜   r*   r*   r*   r+   Ú<module>   s,   8  L 