This commit is contained in:
www
2020-12-27 19:12:27 +00:00
parent 35081dee68
commit 8735848ab7

View File

@@ -1,12 +1,16 @@
import yaml import yaml
from . import CHATFILE, TARGET, URL_HOSTNAME from . import CHATFILE, TARGET, URL_HOSTNAME
from pytgbot.bot.sync import SyncBot from pytgbot.bot.sync import SyncBot
from pytgbot.api_types.sendable.inline import InlineQueryResultArticle, InputTextMessageContent from pytgbot.api_types.sendable.inline import (
InlineQueryResultArticle,
InputTextMessageContent,
)
from pytgbot.api_types.receivable.inline import InlineQuery from pytgbot.api_types.receivable.inline import InlineQuery
from pytgbot.api_types.receivable.updates import Update from pytgbot.api_types.receivable.updates import Update
from .states import CreatePostWorkflow from .states import CreatePostWorkflow
from urllib.parse import urljoin from urllib.parse import urljoin
#from . import solr,reindex
# from . import solr,reindex
from solrfet2020 import SolrFet2020 from solrfet2020 import SolrFet2020
from . import fet, users from . import fet, users
from .users import User from .users import User
@@ -15,192 +19,227 @@ from key import API_KEY
import requests import requests
from .workflows import AuthWorkflow from .workflows import AuthWorkflow
import logging import logging
logger=logging.getLogger()
logger = logging.getLogger()
from misc import SaveFileMapping, SaveFileObject from misc import SaveFileMapping, SaveFileObject
from lxml.html.clean import clean_html, Cleaner from lxml.html.clean import clean_html, Cleaner
solr=SolrFet2020() solr = SolrFet2020()
def TelegramIntegrationException(Exception): def TelegramIntegrationException(Exception):
pass pass
def get_chat_id(update): def get_chat_id(update):
if update.message and update.message.chat: if update.message and update.message.chat:
return update.message.chat.id return update.message.chat.id
if update.callback_query: if update.callback_query:
return update.callback_query.message.chat.id return update.callback_query.message.chat.id
def get_message_id(update): def get_message_id(update):
if update.message: if update.message:
return update.message.message_id return update.message.message_id
def get_from_id(update): def get_from_id(update):
if update.message and update.message.to_array(): if update.message and update.message.to_array():
return str(update.message.to_array()["from"]["id"]) return str(update.message.to_array()["from"]["id"])
if update.callback_query and update.callback_query.to_array(): if update.callback_query and update.callback_query.to_array():
return str(update.callback_query.to_array()["from"]["id"]) return str(update.callback_query.to_array()["from"]["id"])
def get_from(update): def get_from(update):
if update.message and update.message.to_array(): if update.message and update.message.to_array():
return (update.message.to_array()["from"]) return update.message.to_array()["from"]
if update.callback_query and update.callback_query.to_array(): if update.callback_query and update.callback_query.to_array():
return (update.callback_query.to_array()["from"]) return update.callback_query.to_array()["from"]
def download_file(url): def download_file(url):
local_filename = url.split('/')[-1] local_filename = url.split("/")[-1]
# NOTE the stream=True parameter below # NOTE the stream=True parameter below
with requests.get(url, stream=True) as r: with requests.get(url, stream=True) as r:
r.raise_for_status() r.raise_for_status()
with open(local_filename, 'wb') as f: with open(local_filename, "wb") as f:
for chunk in r.iter_content(chunk_size=8192): for chunk in r.iter_content(chunk_size=8192):
# If you have chunk encoded response uncomment if # If you have chunk encoded response uncomment if
# and set chunk_size parameter to None. # and set chunk_size parameter to None.
#if chunk: # if chunk:
f.write(chunk) f.write(chunk)
return local_filename return local_filename
class BaseChat(SaveFileObject): class BaseChat(SaveFileObject):
"Basis für einen Telegram Chat" "Basis für einen Telegram Chat"
def __init__(self,id, bot):
self.id=id def __init__(self, id, bot):
#self.chat_id=chat_id self.id = id
self.bot=bot # self.chat_id=chat_id
self.workflows={} self.bot = bot
self.last_message_id=None self.workflows = {}
self.debug=False self.last_message_id = None
self.type="group" self.debug = False
self.mode ="" self.type = "group"
self.mode = ""
def to_dict(self): def to_dict(self):
return { return {
"id": self.id, "id": self.id,
"workflows": self.workflows, "workflows": self.workflows,
"debug": self.debug, "debug": self.debug,
"type": self.type, "type": self.type,
"mode": self.mode "mode": self.mode,
} }
@classmethod @classmethod
def from_dict(self, bot, d): def from_dict(self, bot, d):
c=Chat(d["id"],bot) c = Chat(d["id"], bot)
c.debug=d["debug"] c.debug = d["debug"]
c.type=d["type"] c.type = d["type"]
c.mode=d.get("mode","") c.mode = d.get("mode", "")
return c return c
def echo(self,update): def echo(self, update):
self.reply_msg(yaml.dump(update._raw)+"\nfrom"+str(get_from_id(update))) self.reply_msg(yaml.dump(update._raw) + "\nfrom" + str(get_from_id(update)))
def send_msg(self, text,**kwargs):
def send_msg(self, text, **kwargs):
self.bot.send_message(chat_id=self.id, text=text, **kwargs) self.bot.send_message(chat_id=self.id, text=text, **kwargs)
def reply_msg(self, text, **kwargs): def reply_msg(self, text, **kwargs):
self.bot.send_message(chat_id=self.id, text=text, reply_to_message_id=self.last_message_id,**kwargs) self.bot.send_message(
chat_id=self.id,
text=text,
reply_to_message_id=self.last_message_id,
**kwargs
)
def asdict(self): def asdict(self):
return self.to_dict() return self.to_dict()
def inline(self,query): def inline(self, query):
pass pass
def log_update(self, update): def log_update(self, update):
with open("chat_logs/%s.yaml" % self.id,"a+") as f: with open("chat_logs/%s.yaml" % self.id, "a+") as f:
f.write(yaml.safe_dump([update.to_array()])) f.write(yaml.safe_dump([update.to_array()]))
def process_update(self,update):
def process_update(self, update):
self.log_update(update) self.log_update(update)
if update.inline_query: if update.inline_query:
return self.inline(update.inline_query) return self.inline(update.inline_query)
self.last_message_id=get_message_id(update) self.last_message_id = get_message_id(update)
w=self.workflows.get(get_from_id(update),None) w = self.workflows.get(get_from_id(update), None)
if w: if w:
self.workflows[get_from_id(update)]=w self.workflows[get_from_id(update)] = w
if w and w.is_finished: if w and w.is_finished:
self.workflows[get_from_id(update)]=None self.workflows[get_from_id(update)] = None
w=None w = None
if self.debug: if self.debug:
self.echo(update) self.echo(update)
if update.message and w: if update.message and w:
w.process_message(update.message.text) w.process_message(update.message.text)
if update.callback_query: if update.callback_query:
self.send_msg("processing callback %s" % str(w)) self.send_msg("processing callback %s" % str(w))
if w: if w:
w.process_message(update.callback_query.data) w.process_message(update.callback_query.data)
self.bot.edit_message_text( self.bot.edit_message_text(
chat_id=update.callback_query.message.chat.id, chat_id=update.callback_query.message.chat.id,
message_id=update.callback_query.message.message_id, message_id=update.callback_query.message.message_id,
text=update.callback_query.message.text+": "+update.callback_query.data) text=update.callback_query.message.text
+ ": "
+ update.callback_query.data,
)
if update.message and update.message.photo: if update.message and update.message.photo:
ff=max(update.message.photo, key=lambda x: x.file_size) # Foto mit bester Auflösung ff = max(
fff = self.bot.get_file(ff.file_id) update.message.photo, key=lambda x: x.file_size
url=fff.get_download_url(API_KEY) ) # Foto mit bester Auflösung
fff = self.bot.get_file(ff.file_id)
url = fff.get_download_url(API_KEY)
r = requests.get(url) r = requests.get(url)
fn = url.split('/')[-1] fn = url.split("/")[-1]
media=(fn, BytesIO(r.content),r.headers["content-type"]) media = (fn, BytesIO(r.content), r.headers["content-type"])
if w: if w:
w.process_message(update.message.text, media=media) w.process_message(update.message.text, media=media)
if update.message and update.message.chat: if update.message and update.message.chat:
self.type=update.message.chat.type self.type = update.message.chat.type
u=users[update] u = users[update]
users.to_file() users.to_file()
class Chat(BaseChat): class Chat(BaseChat):
def inline(self, query): def inline(self, query):
#r=solr.search("text_txt: %s" % ,sort="date_dt desc").docs # r=solr.search("text_txt: %s" % ,sort="date_dt desc").docs
links,hits=solr.search(query.query) links, hits = solr.search(query.query)
r= links[0:6] r = links[0:6]
res=[ InlineQueryResultArticle( res = [
id=d["url"], InlineQueryResultArticle(
title=d["title"], id=d["url"],
url=urljoin(TARGET,d["url"]), title=d["title"],
thumb_url = urljoin(TARGET,d["image"]), url=urljoin(TARGET, d["url"]),
input_message_content = InputTextMessageContent(message_text=urljoin(TARGET,d["url"])) thumb_url=urljoin(TARGET, d["image"]),
) for d in r] input_message_content=InputTextMessageContent(
#links=[p["title"]+": "+"(%s) "% p["public_date"] + urljoin(TARGET,p["url"]) for p in r] message_text=urljoin(TARGET, d["url"])
self.bot.answer_inline_query(inline_query_id=query.id,results=res ) ),
)
for d in r
]
# links=[p["title"]+": "+"(%s) "% p["public_date"] + urljoin(TARGET,p["url"]) for p in r]
self.bot.answer_inline_query(inline_query_id=query.id, results=res)
return return
def process_command(self,cmd,txt,update): def process_command(self, cmd, txt, update):
self.last_message_id=get_message_id(update) self.last_message_id = get_message_id(update)
u=users[update] u = users[update]
# print("--\ndict: %s" % str(users.asdict())) # print("--\ndict: %s" % str(users.asdict()))
#users[get_from_id(update)]=u # users[get_from_id(update)]=u
if cmd == "/s" or cmd =="/search": if cmd == "/s" or cmd == "/search":
self.reply_msg("searching ...") self.reply_msg("searching ...")
links,hits=solr.search(txt) links, hits = solr.search(txt)
for d in links: for d in links:
self.send_msg(str(d["text"]), parse_mode="html") self.send_msg(str(d["text"]), parse_mode="html")
if hits==0: if hits == 0:
self.send_msg("Nichts gefunden sorry.") self.send_msg("Nichts gefunden sorry.")
return True return True
elif cmd =="/mode": elif cmd == "/mode":
self.mode=txt self.mode = txt
self.reply_msg("Mode: %s" % txt) self.reply_msg("Mode: %s" % txt)
return True return True
elif cmd == "/debug": elif cmd == "/debug":
if not u.fet_user: if not u.fet_user:
self.reply_msg("bitte vorher /auth ausführen wenn du ein FET Mitglied bist") self.reply_msg(
"bitte vorher /auth ausführen wenn du ein FET Mitglied bist"
)
return True return True
if self.debug: if self.debug:
self.debug = False self.debug = False
else: else:
self.debug = True #not self.debug self.debug = True # not self.debug
self.reply_msg("Debug: %s" % str(self.debug)) self.reply_msg("Debug: %s" % str(self.debug))
return True return True
elif cmd =="/post": elif cmd == "/post":
if not u.fet_user: if not u.fet_user:
self.reply_msg("bitte vorher /auth ausführen wenn du ein FET Mitglied bist") self.reply_msg(
"bitte vorher /auth ausführen wenn du ein FET Mitglied bist"
)
return True return True
self.workflows[get_from_id(update)]=CreatePostWorkflow(chat=self) self.workflows[get_from_id(update)] = CreatePostWorkflow(chat=self)
return True return True
elif cmd == "/reindex": elif cmd == "/reindex":
if not u.fet_user: if not u.fet_user:
self.reply_msg("bitte vorher /auth ausführen wenn du ein FET Mitglied bist") self.reply_msg(
"bitte vorher /auth ausführen wenn du ein FET Mitglied bist"
)
return True return True
self.reply_msg("Das kann ein bissl dauern...") self.reply_msg("Das kann ein bissl dauern...")
solr.reindex() solr.reindex()
@@ -208,7 +247,9 @@ class Chat(BaseChat):
return True return True
elif cmd == "/reindextest": elif cmd == "/reindextest":
if not u.fet_user: if not u.fet_user:
self.reply_msg("bitte vorher /auth ausführen wenn du ein FET Mitglied bist") self.reply_msg(
"bitte vorher /auth ausführen wenn du ein FET Mitglied bist"
)
return True return True
self.reply_msg("Das kann ein bissl dauern...") self.reply_msg("Das kann ein bissl dauern...")
solr.reindextest() solr.reindextest()
@@ -218,48 +259,61 @@ class Chat(BaseChat):
if u.fet_user: if u.fet_user:
self.reply_msg("Du bist schon authentifiziert...") self.reply_msg("Du bist schon authentifiziert...")
else: else:
u.token="afwerve" u.token = "afwerve"
u.a=1 u.a = 1
self.reply_msg(urljoin("https://"+URL_HOSTNAME, "/auth/%s/%s" %(u.id, u.token))) self.reply_msg(
self.send_msg(urljoin("https://",URL_HOSTNAME)) urljoin("https://" + URL_HOSTNAME, "/auth/%s/%s" % (u.id, u.token))
)
self.send_msg(urljoin("https://", URL_HOSTNAME))
users.to_file() users.to_file()
return True return True
else: return False else:
return False
return False return False
def get_command_from_update(update): def get_command_from_update(update):
"get the command and the text if there is one" "get the command and the text if there is one"
if update.message and update.message.entities and update.message.entities[0].type=="bot_command": if (
return update.message.text[update.message.entities[0].offset:update.message.entities[0].offset+update.message.entities[0].length], \ update.message
update.message.text[update.message.entities[0].offset+update.message.entities[0].length:].strip() and update.message.entities
and update.message.entities[0].type == "bot_command"
):
return (
update.message.text[
update.message.entities[0].offset : update.message.entities[0].offset
+ update.message.entities[0].length
],
update.message.text[
update.message.entities[0].offset + update.message.entities[0].length :
].strip(),
)
return None, None return None, None
class ChatManager(SaveFileMapping): class ChatManager(SaveFileMapping):
def __init__(self, bot):
def __init__(self,bot):
super().__init__(file=CHATFILE) super().__init__(file=CHATFILE)
if not type(bot) is SyncBot: if not type(bot) is SyncBot:
raise TelegramIntegrationException("This ChatManager needs a SyncBot from pytgbot as an argument") raise TelegramIntegrationException(
self.bot=bot "This ChatManager needs a SyncBot from pytgbot as an argument"
)
self.bot = bot
self.from_file() self.from_file()
def __getitem__(self,key):
def __getitem__(self, key):
if type(key) is Update: if type(key) is Update:
return self.__getitem__(get_chat_id(key)) return self.__getitem__(get_chat_id(key))
c=super().__getitem__(key) c = super().__getitem__(key)
if not c: if not c:
c=Chat(id=key,bot=self.bot) c = Chat(id=key, bot=self.bot)
self[key]=c self[key] = c
return c return c
def from_dict(self,dd): def from_dict(self, dd):
if type(dd) is dict: if type(dd) is dict:
self.data={dd[d]["id"]: Chat.from_dict(self.bot,dd[d]) for d in dd} self.data = {dd[d]["id"]: Chat.from_dict(self.bot, dd[d]) for d in dd}
elif dd is not None: elif dd is not None:
raise AttributeError("from_dict needs a dict got %s" % str(type(dd))) raise AttributeError("from_dict needs a dict got %s" % str(type(dd)))
@@ -269,11 +323,11 @@ class ChatManager(SaveFileMapping):
else: else:
logger.debug(yaml.dump(self.chats)) logger.debug(yaml.dump(self.chats))
def process_update(self,update): def process_update(self, update):
chat=self[update] chat = self[update]
cmd, txt = get_command_from_update(update) cmd, txt = get_command_from_update(update)
if cmd: if cmd:
if not chat.process_command(cmd,txt,update): if not chat.process_command(cmd, txt, update):
chat.reply_msg("Wrong command %s" % cmd) chat.reply_msg("Wrong command %s" % cmd)
else: else:
chat.process_update(update) chat.process_update(update)