generated from exteraGramPlugins/pluginBase
Message Logger: show logged edits and deletions from telegram-panel [no bump]
Publish plugin / publish (push) Successful in 4s
Publish plugin / publish (push) Successful in 4s
Keeps deleted messages (75% opacity, red icon-pack trash icon), restores logged messages deleted while away, reports deletions, and shows edit history as a mock chat (Edit history in the message menu, Open topic). Message links and history open as any signed-in account with access. Per-master API tokens; chat state synced per checked range with an hour's validity, cached in SQLite with a configurable lifetime. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
80f1d5e55c
commit
9b2f26a845
26 files changed
+2928
-112
No files matched your search
@@ -0,0 +1,128 @@
|
||||
"""Telegram requests through the client's own session.
|
||||
|
||||
Sent with ConnectionsManager.sendRequest and a Java RequestDelegate proxy,
|
||||
kept strongly referenced until it fires: on 12.10.6 the SDK's send_request
|
||||
never invoked the callback for these requests.
|
||||
"""
|
||||
|
||||
import threading
|
||||
|
||||
import diag
|
||||
from jutil import java_list
|
||||
|
||||
_pending = set()
|
||||
_lock = threading.Lock()
|
||||
|
||||
|
||||
_Delegate = None
|
||||
|
||||
|
||||
def _delegate_class():
|
||||
"""A Java RequestDelegate calling a Python function (created once)."""
|
||||
global _Delegate
|
||||
if _Delegate is None:
|
||||
from java import dynamic_proxy
|
||||
from org.telegram.tgnet import RequestDelegate
|
||||
|
||||
class Delegate(dynamic_proxy(RequestDelegate)):
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self.fn = fn
|
||||
|
||||
def run(self, response, error):
|
||||
self.fn(response, error)
|
||||
|
||||
_Delegate = Delegate
|
||||
return _Delegate
|
||||
|
||||
|
||||
def _send(account, request, callback):
|
||||
from org.telegram.tgnet import ConnectionsManager
|
||||
|
||||
box = []
|
||||
|
||||
def done(response, error):
|
||||
with _lock:
|
||||
for proxy in box:
|
||||
_pending.discard(proxy)
|
||||
try:
|
||||
callback(response, error)
|
||||
except Exception as exc:
|
||||
diag.error("tg callback", exc)
|
||||
|
||||
delegate = _delegate_class()(done)
|
||||
box.append(delegate)
|
||||
with _lock:
|
||||
_pending.add(delegate)
|
||||
ConnectionsManager.getInstance(account).sendRequest(request, delegate)
|
||||
|
||||
|
||||
def _message_ids(ids):
|
||||
"""getMessages ids: ArrayList<Integer>. `jint` forces Integer boxing;
|
||||
a plain Python int (even from Integer.valueOf) is boxed as Long, which
|
||||
fails serialization on the network thread without any callback."""
|
||||
from java import jint
|
||||
from java.util import ArrayList
|
||||
|
||||
items = ArrayList()
|
||||
for i in ids:
|
||||
items.add(jint(int(i)))
|
||||
return items
|
||||
|
||||
|
||||
def channel_chat(account, channel_id):
|
||||
"""The cached TLRPC.Chat of a channel, loading it from storage if needed."""
|
||||
from org.telegram.messenger import MessagesController, MessagesStorage
|
||||
|
||||
controller = MessagesController.getInstance(account)
|
||||
chat = controller.getChat(int(channel_id))
|
||||
if chat is None:
|
||||
try:
|
||||
chat = MessagesStorage.getInstance(account).getChatSync(int(channel_id))
|
||||
if chat is not None:
|
||||
controller.putChat(chat, True)
|
||||
except Exception as exc:
|
||||
diag.error("tg.channel_chat", exc)
|
||||
return chat
|
||||
|
||||
|
||||
def get_messages(account, dialog_id, ids, callback):
|
||||
"""Fetches `ids` of a dialog (a channel when `dialog_id` is one).
|
||||
|
||||
`callback(messages, error_text)`: messages by id (TL_messageEmpty for
|
||||
deleted ones), or None and an error.
|
||||
"""
|
||||
from org.telegram.messenger import ChatObject, MessagesController
|
||||
from org.telegram.tgnet import TLRPC
|
||||
|
||||
controller = MessagesController.getInstance(account)
|
||||
dialog_id = int(dialog_id)
|
||||
chat = channel_chat(account, -dialog_id) if dialog_id < 0 else None
|
||||
if chat is not None and ChatObject.isChannel(chat):
|
||||
request = TLRPC.TL_channels_getMessages()
|
||||
request.channel = controller.getInputChannel(chat)
|
||||
if request.channel is None or getattr(request.channel, "access_hash", 0) == 0:
|
||||
callback(None, "not a member of that chat")
|
||||
return
|
||||
elif dialog_id < 0 and chat is None:
|
||||
callback(None, "chat not found (not a member?)")
|
||||
return
|
||||
else:
|
||||
request = TLRPC.TL_messages_getMessages()
|
||||
request.id = _message_ids(ids)
|
||||
|
||||
def done(response, error):
|
||||
if error is not None or response is None:
|
||||
callback(None, getattr(error, "text", None) or "request failed")
|
||||
return
|
||||
try:
|
||||
controller.putUsers(response.users, False)
|
||||
controller.putChats(response.chats, False)
|
||||
except Exception:
|
||||
pass
|
||||
found = {}
|
||||
for message in java_list(response.messages):
|
||||
found[int(message.id)] = message
|
||||
callback(found, None)
|
||||
|
||||
_send(account, request, done)
|
||||
Reference in new issue
Block a user