From b84628e01d25200da4174c69687b77258e4293fd Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 13 Apr 2018 15:20:47 +0200 Subject: [PATCH] Add syncer module --- pyrogram/client/syncer.py | 107 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 pyrogram/client/syncer.py diff --git a/pyrogram/client/syncer.py b/pyrogram/client/syncer.py new file mode 100644 index 00000000..2fa464be --- /dev/null +++ b/pyrogram/client/syncer.py @@ -0,0 +1,107 @@ +import base64 +import json +import logging +import os +import shutil +import time +from threading import Thread, Event, Lock +from . import utils + +log = logging.getLogger(__name__) + + +class Syncer: + INTERVAL = 2 + + clients = {} + thread = None + event = Event() + lock = Lock() + + @classmethod + def add(cls, client): + with cls.lock: + cls.sync(client) + + cls.clients[id(client)] = client + + if len(cls.clients) == 1: + cls.start() + + @classmethod + def remove(cls, client): + with cls.lock: + cls.sync(client) + + del cls.clients[id(client)] + + if len(cls.clients) == 0: + cls.stop() + + @classmethod + def start(cls): + cls.event.clear() + cls.thread = Thread(target=cls.worker, name=cls.__name__) + cls.thread.start() + + @classmethod + def stop(cls): + cls.event.set() + + @classmethod + def worker(cls): + while True: + cls.event.wait(cls.INTERVAL) + + if cls.event.is_set(): + break + + with cls.lock: + for client in cls.clients.values(): + cls.sync(client) + + @classmethod + def sync(cls, client): + try: + auth_key = base64.b64encode(client.auth_key).decode() + auth_key = [auth_key[i: i + 43] for i in range(0, len(auth_key), 43)] + + data = dict( + dc_id=client.dc_id, + test_mode=client.test_mode, + auth_key=auth_key, + user_id=client.user_id, + date=int(time.time()), + peers_by_id={ + k: getattr(v, "access_hash", None) + for k, v in client.peers_by_id.items() + }, + peers_by_username={ + k: utils.get_peer_id(v) + for k, v in client.peers_by_username.items() + }, + peers_by_phone={ + k: utils.get_peer_id(v) + for k, v in client.peers_by_phone.items() + } + ) + + with open("{}.sync".format(client.session_name), "w", encoding="utf-8") as f: + json.dump(data, f, indent=4) + + f.flush() + os.fsync(f.fileno()) + except Exception as e: + log.critical(e, exc_info=True) + else: + shutil.move( + "{}.sync".format(client.session_name), + "{}.session".format(client.session_name) + ) + + log.info("Synced {}".format(client.session_name)) + finally: + try: + os.remove("{}.sync".format(client.session_name)) + except OSError: + pass