U
    ¯ªh1  ã                
   @   sÄ   d dl Z d dlZd dlZddlmZ ddlmZ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 zd dlZdZW n. ek
r¦ Z zdZeeƒZW 5 dZ[X Y nX d	Zd
ZG dd„ deƒZdS )é    Né   )Útypesé   )ÚMemorySessionÚ_SentFileType)Úutils)ÚAuthKey)Ú
InputPhotoÚInputDocumentÚPeerUserÚPeerChatÚPeerChannelz.sessioné   c                       sþ   e Zd ZdZd4‡ fdd„	Zd5‡ fdd„	Zdd„ Zed	d
„ ƒZ‡ fdd„Z	e
jjdd„ ƒZe
jj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ed#d$„ ƒZd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd6d.d/„Zd0d1„ Zd2d3„ Z‡  Z S )7ÚSQLiteSessionaq  This session contains the required information to login into your
       Telegram account. NEVER give the saved session file to anyone, since
       they would gain instant access to all your messages and contacts.

       If you think the session has been compromised, close all the sessions
       through an official Telegram client to revoke the authorization.
    Nc                    s0  t d krt‚tƒ  ¡  d| _d| _|rF|| _| j t¡sF|  jt7  _d | _|  	¡ }| 
d¡ | ¡ rò| 
d¡ | ¡ d }|tk r°| j|d | 
d¡ | 
dtf¡ |  ¡  | 
d	¡ | ¡ }|rè|\| _| _| _}| _t|d
| _| ¡  n:|  |ddddd¡ | 
dtf¡ |  ¡  | ¡  |  ¡  d S )Nú:memory:TzDselect name from sqlite_master where type='table' and name='version'zselect version from versionr   )Úoldzdelete from versionzinsert into version values (?)zselect * from sessions©Údataz%version (version integer primary key)zàsessions (
                    dc_id integer primary key,
                    server_address text,
                    port integer,
                    auth_key blob,
                    takeout_id integer
                )zùentities (
                    id integer primary key,
                    hash integer not null,
                    username text,
                    phone integer,
                    name text,
                    date integer
                )a  sent_files (
                    md5_digest blob,
                    file_size integer,
                    type integer,
                    id integer,
                    hash integer,
                    primary key(md5_digest, file_size, type)
                )zÐupdate_state (
                    id integer primary key,
                    pts integer,
                    qts integer,
                    date integer,
                    seq integer
                ))Úsqlite3Úsqlite3_errÚsuperÚ__init__ÚfilenameÚsave_entitiesÚendswithÚ	EXTENSIONÚ_connÚ_cursorÚexecuteÚfetchoneÚCURRENT_VERSIONÚ_upgrade_databaseÚsaveÚ_dc_idÚ_server_addressÚ_portÚ_takeout_idr   Ú	_auth_keyÚcloseÚ_create_tableÚ_update_session_table)ÚselfZ
session_idÚcÚversionÚtuple_Úkey©Ú	__class__© ú</tmp/pip-unpacked-wheel-c81u5j2r/telethon/sessions/sqlite.pyr   !   sP    




ÿ
		â&zSQLiteSession.__init__c                    s   t ƒ  |¡}| j|_|S ©N)r   Úcloner   )r+   Zto_instanceZclonedr0   r2   r3   r5   r   s    zSQLiteSession.clonec                 C   s´   |   ¡ }|dkr|d7 }|dkr>|d7 }| d¡ |  |d¡ |dkrZ|d7 }|  |d¡ |dkrt|d7 }| d¡ |d	krŽ|d7 }| d
¡ |dkr¨|d7 }| d¡ | ¡  d S )Nr   r   zdrop table sent_fileszïsent_files (
                md5_digest blob,
                file_size integer,
                type integer,
                id integer,
                hash integer,
                primary key(md5_digest, file_size, type)
            )é   z¸update_state (
                id integer primary key,
                pts integer,
                qts integer,
                date integer,
                seq integer
            )é   z2alter table sessions add column takeout_id integeré   zdelete from entitiesé   z,alter table entities add column date integer)r   r   r)   r(   )r+   r   r,   r2   r2   r3   r!   w   s(    



zSQLiteSession._upgrade_databasec                 G   s   |D ]}|   d |¡¡ qd S )Nzcreate table {})r   Úformat)r,   ZdefinitionsZ
definitionr2   r2   r3   r)   Ÿ   s    zSQLiteSession._create_tablec                    sJ   t ƒ  |||¡ |  ¡  |  d¡}|r@|d r@t|d d| _nd | _d S )Nzselect auth_key from sessionsr   r   )r   Úset_dcr*   Ú_executer   r'   )r+   Zdc_idÚserver_addressÚportÚrowr0   r2   r3   r;   ¦   s    
zSQLiteSession.set_dcc                 C   s   || _ |  ¡  d S r4   )r'   r*   ©r+   Úvaluer2   r2   r3   Úauth_key±   s    zSQLiteSession.auth_keyc                 C   s   || _ |  ¡  d S r4   )r&   r*   r@   r2   r2   r3   Ú
takeout_id¶   s    zSQLiteSession.takeout_idc                 C   sJ   |   ¡ }| d¡ | d| j| j| j| jr2| jjnd| jf¡ | ¡  d S )Nzdelete from sessionsz2insert or replace into sessions values (?,?,?,?,?)ó    )	r   r   r#   r$   r%   r'   r/   r&   r(   )r+   r,   r2   r2   r3   r*   »   s    
ûz#SQLiteSession._update_session_tablec                 C   sJ   |   d|¡}|rF|\}}}}tjj|tjjd}tjj||||ddS d S )Nz9select pts, qts, date, seq from update_state where id = ?©Útzr   )Úunread_count)r<   ÚdatetimeÚfromtimestampÚtimezoneÚutcr   ÚupdatesÚState)r+   Ú	entity_idr?   ÚptsÚqtsÚdateÚseqr2   r2   r3   Úget_update_stateÌ   s    ÿ ÿzSQLiteSession.get_update_statec                 C   s$   |   d||j|j|j ¡ |j¡ d S )Nz6insert or replace into update_state values (?,?,?,?,?))r<   rO   rP   rQ   Ú	timestamprR   )r+   rN   Ústater2   r2   r3   Úset_update_stateÕ   s       þzSQLiteSession.set_update_statec                 C   s8   |   ¡ }z | d¡ ¡ }dd„ |D ƒW ¢S | ¡  X d S )Nz0select id, pts, qts, date, seq from update_statec              	   s   sL   | ]D}|d  t jj|d |d tjj|d tjjd|d d dfV  qdS )r   r   r   r6   rE   r7   )rO   rP   rQ   rR   rG   N)r   rL   rM   rH   rI   rJ   rK   ©Ú.0r?   r2   r2   r3   Ú	<genexpr>Þ   s   úûz2SQLiteSession.get_update_states.<locals>.<genexpr>)r   r(   r   Úfetchall)r+   r,   Úrowsr2   r2   r3   Úget_update_statesÚ   s    ú
zSQLiteSession.get_update_statesc                 C   s   | j dk	r| j  ¡  dS )z;Saves the current session object as session_user_id.sessionN)r   Úcommit©r+   r2   r2   r3   r"   è   s    
zSQLiteSession.savec                 C   s&   | j dkrtj| jdd| _ | j  ¡ S )z8Asserts that the connection is open and returns a cursorNF)Zcheck_same_thread)r   r   Úconnectr   Úcursorr^   r2   r2   r3   r   ï   s
    
ÿzSQLiteSession._cursorc                 G   s,   |   ¡ }z| ||¡ ¡ W ¢S | ¡  X dS )z…
        Gets a cursor, executes `stmt` and closes the cursor,
        fetching one row afterwards and returning its result.
        N)r   r(   r   r   )r+   ZstmtÚvaluesr,   r2   r2   r3   r<   ö   s    zSQLiteSession._executec                 C   s2   | j dkr.| jdk	r.| j ¡  | j ¡  d| _dS )z4Closes the connection unless we're working in-memoryr   N)r   r   r]   r(   r^   r2   r2   r3   r(     s
    



zSQLiteSession.closec                 C   s<   | j dkrdS zt | j ¡ W dS  tk
r6   Y dS X dS )z Deletes the current session filer   TFN)r   ÚosÚremoveÚOSErrorr^   r2   r2   r3   Údelete	  s    
zSQLiteSession.deletec                 C   s   dd„ t  d¡D ƒS )zvLists all the sessions of the users who have ever connected
           using this client and never logged out
        c                 S   s.   g | ]&}|  t¡rtj tj |¡¡d  ‘qS ©r   )r   r   rb   ÚpathÚsplitextÚbasename)rX   Úfr2   r2   r3   Ú
<listcomp>  s    
ÿz/SQLiteSession.list_sessions.<locals>.<listcomp>Ú.)rb   Úlistdir)Úclsr2   r2   r3   Úlist_sessions  s    ÿzSQLiteSession.list_sessionsc                    sd   | j s
dS |  |¡}|sdS |  ¡ }z0tt ¡ ƒf‰ ‡ fdd„|D ƒ}| d|¡ W 5 | ¡  X dS )zq
        Processes all the found entities on the given TLObject,
        unless .save_entities is False.
        Nc                    s   g | ]}|ˆ  ‘qS r2   r2   rW   ©Znow_tupr2   r3   rk   ,  s     z2SQLiteSession.process_entities.<locals>.<listcomp>z4insert or replace into entities values (?,?,?,?,?,?))r   Z_entities_to_rowsr   r(   ÚintÚtimeÚexecutemany)r+   Ztlor[   r,   r2   rp   r3   Úprocess_entities  s    
 ÿzSQLiteSession.process_entitiesc                 C   s   |   d|¡S )Nz-select id, hash from entities where phone = ?©r<   )r+   Zphoner2   r2   r3   Úget_entity_rows_by_phone2  s     ÿz&SQLiteSession.get_entity_rows_by_phonec                 C   sŒ   |   ¡ }zt| d|f¡ ¡ }|s(W ¢Zd S t|ƒdkrb|jdd„ d | ddd„ |d d	… D ƒ¡ |d	 d
 |d	 d fW ¢S | ¡  X d S )Nz6select id, hash, date from entities where username = ?r   c                 S   s   | d p
dS )Nr   r   r2   )Útr2   r2   r3   Ú<lambda>C  rD   z;SQLiteSession.get_entity_rows_by_username.<locals>.<lambda>)r/   z0update entities set username = null where id = ?c                 S   s   g | ]}|d  f‘qS rf   r2   )rX   rw   r2   r2   r3   rk   E  s     z=SQLiteSession.get_entity_rows_by_username.<locals>.<listcomp>éÿÿÿÿr   )r   r(   r   rZ   ÚlenÚsortrs   )r+   Úusernamer,   Úresultsr2   r2   r3   Úget_entity_rows_by_username6  s    þÿz)SQLiteSession.get_entity_rows_by_usernamec                 C   s   |   d|¡S )Nz,select id, hash from entities where name = ?ru   )r+   Únamer2   r2   r3   Úget_entity_rows_by_nameK  s     ÿz%SQLiteSession.get_entity_rows_by_nameTc              	   C   sB   |r|   d|¡S |   dt t|ƒ¡t t|ƒ¡t t|ƒ¡¡S d S )Nz*select id, hash from entities where id = ?z1select id, hash from entities where id in (?,?,?))r<   r   Zget_peer_idr   r   r   )r+   ÚidÚexactr2   r2   r3   Úget_entity_rows_by_idO  s     ÿüz#SQLiteSession.get_entity_rows_by_idc                 C   s2   |   d||t |¡j¡}|r.||d |d ƒS d S )NzSselect id, hash from sent_files where md5_digest = ? and file_size = ? and type = ?r   r   )r<   r   Ú	from_typerA   )r+   Ú
md5_digestÚ	file_sizern   r?   r2   r2   r3   Úget_file]  s      
ýzSQLiteSession.get_filec              	   C   sF   t |ttfƒstdt|ƒ ƒ‚|  d||t t|ƒ¡j|j	|j
¡ d S )NzCannot cache %s instancez4insert or replace into sent_files values (?,?,?,?,?))Ú
isinstancer
   r	   Ú	TypeErrorÚtyper<   r   r„   rA   r   Zaccess_hash)r+   r…   r†   Úinstancer2   r2   r3   Ú
cache_fileg  s      üzSQLiteSession.cache_file)N)N)T)!Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r5   r!   Ústaticmethodr)   r;   r   rB   ÚsetterrC   r*   rS   rV   r\   r"   r   r<   r(   re   Úclassmethodro   rt   rv   r~   r€   rƒ   r‡   rŒ   Ú__classcell__r2   r2   r0   r3   r      s:   Q(


	

	

r   )rH   rb   rr   Útlr   Zmemoryr   r   Ú r   Zcryptor   Ztl.typesr	   r
   r   r   r   r   r   ÚImportErrorÚerŠ   r   r    r   r2   r2   r2   r3   Ú<module>   s    