-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmtgDEbot.py
171 lines (138 loc) · 5.88 KB
/
mtgDEbot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import sys
import asyncio
import telepot
import requests
import json
from pprint import pprint
from telepot.aio.helper import InlineUserHandler, AnswererMixin, ChatHandler
from telepot.aio.delegate import pave_event_space, per_chat_id, create_open, per_inline_from_id
from telepot.namedtuple import *
"""
(vorher mit pip3.5 installieren: telepot, requests, beautifulsoup4)
$ python3.5 mtgDEbot.py <token>
Telegram Bot, der Magickarten von http://magiccards.info inline sucht.
Die Suche wurde auf deutsche Karten eingeschränkt.
So lange nichts eingegeben wurde, wird eine zufällige Karte angezeigt.
Verwendung des Bots inline: @mtgDEbot <Kartenname> [.,/| <Edition>]
Die Angabe der Edition ist optional, es gibt verschiedene Trenner,
hinter dem Trenner kann ein Leerzeichen sein, muss aber nicht.
Der ganze Code basiert auf Codebeispielen und Tutorials, die hier zu finden sind:
https://github.com/nickoala/telepot
Danke!
"""
"""
Wird der Bot direkt angesprochen, antwortet er mit einer kleinen Anleitung.
Bisher keine expliziten Befehle wie /help oder so
"""
class ChatBot(ChatHandler):
def __init__(self, *args, **kwargs):
super(ChatBot, self).__init__(*args, **kwargs)
async def on_chat_message(self, msg):
content_type, chat_type, chat_id = telepot.glance(msg)
# print(content_type, chat_type, chat_id)
if content_type == 'text':
# answer = msg['text']
answer = ("Hier gibt es nicht viel zu erreichen, verwende den Bot in einem anderem (Gruppen-)Chat: " +
"\"@mtgDEbot Kartenname / Edition\". " +
"Als Trenner dürfen . , / | verwendet werden.")
# print(answer)
await self.sender.sendMessage(answer)
"""
Hier handelt der Bot inline in Chats und erfüllt seine eigentliche Aufgabe
"""
class InlineHandler(InlineUserHandler, AnswererMixin):
def __init__(self, *args, **kwargs):
super(InlineHandler, self).__init__(*args, **kwargs)
def on_inline_query(self, msg):
def compute_answer():
api_url = 'https://api.scryfall.com/cards'
api_search = api_url + '/search'
api_random = api_url + '/random'
search_lang = '?include_multilingual=true&lang%3Ade&lang%3Aen&q='
trenner = tuple(["|", "/", ".", ","])
search_string = []
edition_string = ''
nextisedition = False
articles = []
query_id, from_id, query_string = telepot.glance(msg, flavor='inline_query')
print(self.id, ':', 'Inline Query:', query_id, from_id, query_string)
"""
Suchbegriff in Einzelteile zerlegen und hinten die Edition extrahieren
"""
words = query_string.split()
for word in words:
if word.startswith(trenner) and len(word) >= 3:
edition_string = word[1:]
break
elif word.startswith(trenner) and len(word) == 1:
nextisedition = True
elif nextisedition:
edition_string = word
break
else:
search_string.append(word)
"""
Suchstring erzeugen, falls noch nicht eingegeben wurde, wird eine zufällige Karte ausgegeben
"""
search_string = api_search + search_lang + "+".join(search_string)
if edition_string:
# print(edition_string)
edition_string = "+edition%3A" + edition_string
search_string += edition_string
if not query_string:
search_string = api_random
print(search_string)
response = requests.get(search_string)
"""
Bilder extrahieren
"""
cards = json.loads(response.text)
if cards['object'] == 'list':
for card in cards['data']:
curr_img = InlineQueryResultPhoto(
id=card['id'],
photo_url=card['image_uris']['large'],
thumb_url=card['image_uris']['normal'],
title=card['name'],
caption=card['name'],
description=card['type_line'],
# photo_width=100, photo_height=140
)
if len(articles) > 14:
break
articles.append(curr_img)
elif cards['object'] == 'card':
curr_img = InlineQueryResultPhoto(
id=cards['id'],
photo_url=cards['image_uris']['large'],
thumb_url=cards['image_uris']['normal'],
title=cards['name'],
caption=cards['name'],
description=cards['type_line'],
# photo_width=100, photo_height=140
)
articles.append(curr_img)
# articles = [{'type': 'article', 'id': 'abc', 'title': query_string, 'message_text': query_string}]
return articles
self.answerer.answer(msg, compute_answer)
"""
Nach Auswahl einer Karte wird hier das Ergebnis verschickt
"""
def on_chosen_inline_result(self, msg):
pprint(msg)
result_id, from_id, query_string = telepot.glance(msg, flavor='chosen_inline_result')
print(self.id, ':', 'Chosen Inline Result:', result_id, from_id, query_string)
"""
Die eigentliche ausführung des Bots
"""
TOKEN = sys.argv[1] # get token from command-line
bot = telepot.aio.DelegatorBot(TOKEN, [
pave_event_space()(
per_chat_id(), create_open, ChatBot, timeout=10),
pave_event_space()(
per_inline_from_id(), create_open, InlineHandler, timeout=10),
])
loop = asyncio.get_event_loop()
loop.create_task(bot.message_loop())
print('Listening ...')
loop.run_forever()