mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-12-01 22:03:46 +03:00
Use a different schema for file cache which actually persists
Caching the inputFile values would not persist accross several days so the cache was nearly unnecessary. Saving the id/hash of the actual inputMedia sent is a much better/persistent idea.
This commit is contained in:
parent
428abebed8
commit
55efb2b104
|
@ -633,13 +633,6 @@ class TelegramBareClient:
|
||||||
with open(file, 'rb') as stream:
|
with open(file, 'rb') as stream:
|
||||||
file = stream.read()
|
file = stream.read()
|
||||||
hash_md5 = md5(file)
|
hash_md5 = md5(file)
|
||||||
tuple_ = self.session.get_file(hash_md5.digest(), file_size)
|
|
||||||
if tuple_ and allow_cache:
|
|
||||||
__log__.info('File was already cached, not uploading again')
|
|
||||||
return InputFile(name=file_name,
|
|
||||||
md5_checksum=tuple_[0], id=tuple_[2], parts=tuple_[3])
|
|
||||||
elif tuple_ and not allow_cache:
|
|
||||||
self.session.clear_file(hash_md5.digest(), file_size)
|
|
||||||
else:
|
else:
|
||||||
hash_md5 = None
|
hash_md5 = None
|
||||||
|
|
||||||
|
@ -673,9 +666,6 @@ class TelegramBareClient:
|
||||||
if is_large:
|
if is_large:
|
||||||
return InputFileBig(file_id, part_count, file_name)
|
return InputFileBig(file_id, part_count, file_name)
|
||||||
else:
|
else:
|
||||||
self.session.cache_file(
|
|
||||||
hash_md5.digest(), file_size, file_id, part_count)
|
|
||||||
|
|
||||||
return InputFile(file_id, part_count, file_name,
|
return InputFile(file_id, part_count, file_name,
|
||||||
md5_checksum=hash_md5.hexdigest())
|
md5_checksum=hash_md5.hexdigest())
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import sqlite3
|
||||||
import struct
|
import struct
|
||||||
import time
|
import time
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
|
from enum import Enum
|
||||||
from os.path import isfile as file_exists
|
from os.path import isfile as file_exists
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
|
||||||
|
@ -12,11 +13,26 @@ from .. import utils
|
||||||
from ..tl import TLObject
|
from ..tl import TLObject
|
||||||
from ..tl.types import (
|
from ..tl.types import (
|
||||||
PeerUser, PeerChat, PeerChannel,
|
PeerUser, PeerChat, PeerChannel,
|
||||||
InputPeerUser, InputPeerChat, InputPeerChannel
|
InputPeerUser, InputPeerChat, InputPeerChannel,
|
||||||
|
InputPhoto, InputDocument
|
||||||
)
|
)
|
||||||
|
|
||||||
EXTENSION = '.session'
|
EXTENSION = '.session'
|
||||||
CURRENT_VERSION = 2 # database version
|
CURRENT_VERSION = 3 # database version
|
||||||
|
|
||||||
|
|
||||||
|
class _SentFileType(Enum):
|
||||||
|
DOCUMENT = 0
|
||||||
|
PHOTO = 1
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_type(cls):
|
||||||
|
if cls == InputDocument:
|
||||||
|
return _SentFileType.DOCUMENT
|
||||||
|
elif cls == InputPhoto:
|
||||||
|
return _SentFileType.PHOTO
|
||||||
|
else:
|
||||||
|
raise ValueError('The cls must be either InputDocument/InputPhoto')
|
||||||
|
|
||||||
|
|
||||||
class Session:
|
class Session:
|
||||||
|
@ -130,9 +146,10 @@ class Session:
|
||||||
"""sent_files (
|
"""sent_files (
|
||||||
md5_digest blob,
|
md5_digest blob,
|
||||||
file_size integer,
|
file_size integer,
|
||||||
file_id integer,
|
type integer,
|
||||||
part_count integer,
|
id integer,
|
||||||
primary key(md5_digest, file_size)
|
hash integer,
|
||||||
|
primary key(md5_digest, file_size, type)
|
||||||
)"""
|
)"""
|
||||||
)
|
)
|
||||||
c.execute("insert into version values (?)", (CURRENT_VERSION,))
|
c.execute("insert into version values (?)", (CURRENT_VERSION,))
|
||||||
|
@ -171,18 +188,22 @@ class Session:
|
||||||
|
|
||||||
def _upgrade_database(self, old):
|
def _upgrade_database(self, old):
|
||||||
c = self._conn.cursor()
|
c = self._conn.cursor()
|
||||||
if old == 1:
|
# old == 1 doesn't have the old sent_files so no need to drop
|
||||||
self._create_table(c,"""sent_files (
|
if old == 2:
|
||||||
md5_digest blob,
|
# Old cache from old sent_files lasts then a day anyway, drop
|
||||||
file_size integer,
|
c.execute('drop table sent_files')
|
||||||
file_id integer,
|
self._create_table(c, """sent_files (
|
||||||
part_count integer,
|
md5_digest blob,
|
||||||
primary key(md5_digest, file_size)
|
file_size integer,
|
||||||
)""")
|
type integer,
|
||||||
old = 2
|
id integer,
|
||||||
|
hash integer,
|
||||||
|
primary key(md5_digest, file_size, type)
|
||||||
|
)""")
|
||||||
c.close()
|
c.close()
|
||||||
|
|
||||||
def _create_table(self, c, *definitions):
|
@staticmethod
|
||||||
|
def _create_table(c, *definitions):
|
||||||
"""
|
"""
|
||||||
Creates a table given its definition 'name (columns).
|
Creates a table given its definition 'name (columns).
|
||||||
If the sqlite version is >= 3.8.2, it will use "without rowid".
|
If the sqlite version is >= 3.8.2, it will use "without rowid".
|
||||||
|
@ -420,24 +441,25 @@ class Session:
|
||||||
|
|
||||||
# File processing
|
# File processing
|
||||||
|
|
||||||
def get_file(self, md5_digest, file_size):
|
def get_file(self, md5_digest, file_size, cls):
|
||||||
return self._conn.execute(
|
tuple_ = self._conn.execute(
|
||||||
'select * from sent_files '
|
'select id, hash from sent_files '
|
||||||
'where md5_digest = ? and file_size = ?', (md5_digest, file_size)
|
'where md5_digest = ? and file_size = ? and type = ?',
|
||||||
|
(md5_digest, file_size, _SentFileType.from_type(cls))
|
||||||
).fetchone()
|
).fetchone()
|
||||||
|
if tuple_:
|
||||||
|
# Both allowed classes have (id, access_hash) as parameters
|
||||||
|
return cls(tuple_[0], tuple_[1])
|
||||||
|
|
||||||
|
def cache_file(self, md5_digest, file_size, instance):
|
||||||
|
if not isinstance(instance, (InputDocument, InputPhoto)):
|
||||||
|
raise TypeError('Cannot cache %s instance' % type(instance))
|
||||||
|
|
||||||
def cache_file(self, md5_digest, file_size, file_id, part_count):
|
|
||||||
with self._db_lock:
|
with self._db_lock:
|
||||||
self._conn.execute(
|
self._conn.execute(
|
||||||
'insert into sent_files values (?,?,?,?)',
|
'insert into sent_files values (?,?,?,?,?)', (
|
||||||
(md5_digest, file_size, file_id, part_count)
|
md5_digest, file_size,
|
||||||
)
|
_SentFileType.from_type(type(instance)),
|
||||||
self.save()
|
instance.id, instance.access_hash
|
||||||
|
))
|
||||||
def clear_file(self, md5_digest, file_size):
|
|
||||||
with self._db_lock:
|
|
||||||
self._conn.execute(
|
|
||||||
'delete from sent_files where '
|
|
||||||
'md5_digest = ? and file_size = ?', (md5_digest, file_size)
|
|
||||||
)
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user