diff --git a/sukuinote/plugins/wikipedia.py b/sukuinote/plugins/wikipedia.py
new file mode 100644
index 0000000..6b6c43e
--- /dev/null
+++ b/sukuinote/plugins/wikipedia.py
@@ -0,0 +1,37 @@
+from pyrogram import Client, filters
+from pyrogram.errors.exceptions.forbidden_403 import Forbidden
+from .. import slave, config, help_dict, log_errors, public_log_errors
+
+@Client.on_message(~filters.sticker & ~filters.via_bot & ~filters.edited & filters.me & filters.command(['w', 'wiki', 'wikipedia'], prefixes=config['config']['prefixes']))
+@log_errors
+@public_log_errors
+async def wikipedia(client, message):
+ bot = await slave.get_me()
+ query = message.command
+ page = 1
+ query.pop(0)
+ if query and query[0].isnumeric():
+ page = int(query.pop(0))
+ page -= 1
+ if page < 0:
+ page = 0
+ elif page > 9:
+ page = 9
+ query = ' '.join(query)
+ if not query:
+ return
+ results = await client.get_inline_bot_results(bot.username or bot.id, 'w ' + query)
+ if not results.results:
+ await message.reply_text('There are no definitions')
+ return
+ try:
+ await message.reply_inline_bot_result(results.query_id, results.results[page].id)
+ except IndexError:
+ await message.reply_text(f'There are only {len(results.results)} definitions')
+ except Forbidden:
+ await message.reply_text({'message': results.results[page].send_message.message, 'entities': results.results[page].send_message.entities}, disable_web_page_preview=True, parse_mode='through')
+
+help_dict['wikipedia'] = ('Wikipedia',
+'''{prefix}wikipedia <query> - Searches for <query> on Wikipedia
+Aliases: {prefix}w, {prefix}wiki
+Can also be activated inline with: @{bot} wikipedia <query> or @{bot} wiki <query> or @{bot} w <query>''')
diff --git a/sukuinote/slave-plugins/wikipedia.py b/sukuinote/slave-plugins/wikipedia.py
new file mode 100644
index 0000000..3d31aa3
--- /dev/null
+++ b/sukuinote/slave-plugins/wikipedia.py
@@ -0,0 +1,108 @@
+import re
+import time
+import asyncio
+from urllib.parse import quote as urlencode
+from pyrogram import Client, filters
+from pyrogram.parser.html import HTML as pyrogram_html
+from pyrogram.types import InlineQueryResultArticle, InputTextMessageContent, InlineKeyboardMarkup, InlineKeyboardButton
+from .. import session, app_user_ids, log_errors
+
+all_results = dict()
+results_lock = asyncio.Lock()
+@Client.on_inline_query(filters.regex('^w(?:iki)?(?:pedia)?(.+)$'))
+@log_errors
+async def wikipedia(client, inline_query):
+ if inline_query.from_user.id not in app_user_ids:
+ await inline_query.answer([
+ InlineQueryResultArticle('...no', InputTextMessageContent('...no'))
+ ], cache_time=3600, is_personal=True)
+ return
+ query = inline_query.matches[0].group(1).strip().lower()
+ async with results_lock:
+ if query not in all_results:
+ async with session.get(f'https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&formatversion=2&srlimit=10&srprop=snippet&srenablerewrites=1&srsearch={urlencode(query)}') as resp:
+ all_results[query] = (await resp.json())['query']['search']
+ results = all_results[query]
+ answers = []
+ parser = pyrogram_html(client)
+ for a, result in enumerate(results):
+ full_snippet = None
+ text = f'{result["title"]}\n\n'
+ if result['snippet']:
+ full_snippet = snippet = (await parser.parse(result['snippet']))['message']
+ total_length = len((await parser.parse(text))['message'])
+ if len(snippet) > 1022 - total_length:
+ snippet = snippet[:1021-total_length] + '…'
+ text += snippet
+ buttons = [InlineKeyboardButton('Back', 'wikipedia_back'), InlineKeyboardButton(f'{a + 1}/{len(results)}', 'wikipedia_nop'), InlineKeyboardButton('Next', 'wikipedia_next')]
+ if not a:
+ buttons.pop(0)
+ if len(results) == a + 1:
+ buttons.pop()
+ answers.append(InlineQueryResultArticle(result['title'], InputTextMessageContent(text, disable_web_page_preview=True), reply_markup=InlineKeyboardMarkup([buttons]), id=f'wikipedia{a}-{time.time()}', description=full_snippet))
+ await inline_query.answer(answers, is_personal=True)
+
+@Client.on_callback_query(filters.regex('^wikipedia_nop$'))
+@log_errors
+async def wikipedia_nop(client, callback_query):
+ await callback_query.answer(cache_time=3600)
+
+message_info = dict()
+message_lock = asyncio.Lock()
+@Client.on_chosen_inline_result()
+@log_errors
+async def wikipedia_chosen(client, inline_result):
+ if inline_result.result_id.startswith('wikipedia'):
+ match = re.match('^w(?:iki)?(?:pedia)?(.*)$', inline_result.query)
+ if match:
+ query = match.group(1).strip().lower()
+ if query:
+ page = int(inline_result.result_id[9])
+ message_info[inline_result.inline_message_id] = query, page
+ async with results_lock:
+ if query not in all_results:
+ async with session.get(f'https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&formatversion=2&srlimit=10&srprop=snippet&srenablerewrites=1&srsearch={urlencode(query)}') as resp:
+ all_results[query] = (await resp.json())['query']['search']
+ return
+ inline_result.continue_propagation()
+
+@Client.on_callback_query(filters.regex('^wikipedia_(back|next)$'))
+@log_errors
+async def wikipedia_move(client, callback_query):
+ if callback_query.from_user.id not in app_user_ids:
+ await callback_query.answer('...no', cache_time=3600, show_alert=True)
+ return
+ async with message_lock:
+ if callback_query.inline_message_id not in message_info:
+ await callback_query.answer('This message is too old', cache_time=3600, show_alert=True)
+ return
+ query, page = message_info[callback_query.inline_message_id]
+ opage = page
+ if callback_query.matches[0].group(1) == 'back':
+ page -= 1
+ elif callback_query.matches[0].group(1) == 'next':
+ page += 1
+ if page < 0:
+ page = 0
+ elif page > 9:
+ page = 9
+ if page != opage:
+ async with results_lock:
+ results = all_results[query]
+ result = results[page]
+ text = f'{result["title"]}\n\n'
+ if result['snippet']:
+ parser = pyrogram_html(client)
+ snippet = (await parser.parse(result['snippet']))['message']
+ total_length = len((await parser.parse(text))['message'])
+ if len(snippet) > 1022 - total_length:
+ snippet = snippet[:1021-total_length] + '…'
+ text += snippet
+ buttons = [InlineKeyboardButton('Back', 'wikipedia_back'), InlineKeyboardButton(f'{page + 1}/{len(results)}', 'wikipedia_nop'), InlineKeyboardButton('Next', 'wikipedia_next')]
+ if not page:
+ buttons.pop(0)
+ if len(results) == page + 1:
+ buttons.pop()
+ await callback_query.edit_message_text(text, disable_web_page_preview=True, reply_markup=InlineKeyboardMarkup([buttons]))
+ message_info[callback_query.inline_message_id] = query, page
+ await callback_query.answer()