def register(config={}, **kwargs): bot = helpers.bot.instance() db.query(""" CREATE TABLE IF NOT EXISTS `chats` ( `chat_id` INTEGER, `settings` TEXT DEFAULT '{}', `date_added` TEXT DEFAULT CURRENT_TIMESTAMP, `deleted` INTEGER DEFAULT 0, PRIMARY KEY(`chat_id`) ); """) if "mode" in config and config["mode"] in ["force", "auto"]: _mode = config["mode"] else: _mode = "force" print("Gatekeeper is in", _mode, "mode.") @bot.channel_post_handler(func=lambda m: True, blocking=True, final=False, content_types=[ 'photo', 'audio', 'video', 'document', 'text', 'location', 'contact', 'sticker' ]) @bot.message_handler(func=lambda m: True, blocking=True, final=False, content_types=[ 'photo', 'audio', 'video', 'document', 'text', 'location', 'contact', 'sticker' ]) def whoru(msg): if _mode == "force": t = (msg.text or '').split('@')[0] if t in ['!start', '/start']: #do registration try: chat = register_chat(msg.chat.id) print("New chat:", msg.chat.id) except: bot.send_message( msg.chat.id, "Already registered. Use `!help` or /help for help.") else: chat = (get_chat(msg.chat.id)) if not chat: print("Unknown chat", msg.chat.id, "-- eating all.") else: msg.chat.gatekeeper_chat_data = chat return return -256 elif _mode == "auto": chat = get_chat(msg.chat.id) if not chat: print("Unknown chat", msg.chat.id, "-- registering chat.") chat = register_chat(msg.chat.id) msg.chat.gatekeeper_chat_data = chat
def create_poll(chat_id, poll_text, answers, ttl, is_multipoll=False): if not len(answers): return bot = helpers.bot.instance() poll_id = db.query("insert into polls(chat_id, text, answers, ttl, is_multi) VALUES (:chat_id, :text, :answers, :ttl, :is_multi)", {'chat_id':chat_id, 'text':poll_text, 'answers':json.dumps(answers), 'ttl':ttl * 60, 'is_multi':is_multipoll}, get_id=True) sent = bot.send_message(chat_id, compose_body(poll_text, answers), reply_markup=generate_markup(poll_id, answers), parse_mode="Markdown") db.query("update polls set message_id = ? where id = ?", [sent.message_id, poll_id]) return poll_id
def register(listen=True, ** kwargs): db.query(""" CREATE TABLE IF NOT EXISTS `reactions` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `chat_id` INTEGER, `trigger` TEXT, `reaction` TEXT, `added_by` INTEGER ); """) if listen: bot = helpers.bot.instance() @bot.message_handler(func=lambda m: True) @bot.channel_post_handler(func=lambda m: True) def react(msg): reactions = get_reactions(msg.chat.id, msg.text) reaction = ', '.join(reactions) if reaction: sent = bot.send_message(msg.chat.id, reaction) @bot.message_handler(regexp="^!reaction |^!react ") @bot.channel_post_handler(regexp="^!reaction |^!react ") @bot.message_handler(commands=['reaction', 'react']) @bot.channel_post_handler(commands=['reaction', 'react']) def handle_command(msg): segs = shlex.split(msg.text) segs.pop(0) if len(segs) >= 1: action = segs[0] reaction = None trigger = None if len(segs) >= 2: trigger = segs[1] if len(segs) >= 3: reaction = segs[2] if action == "add" and trigger and reaction: add_reaction(msg.chat.id, trigger, reaction) pass elif action == "del" and trigger and reaction: delete_trigger(msg.chat.id, trigger, reaction) pass elif action == "del" and trigger: #remove reaction completely reaction = trigger delete_reaction(msg.chat.id, reaction) elif action == "list": reactions = get_chat_reactions(msg.chat.id) result = "" if len(reactions): for reaction, trigger in reactions.items(): result += reaction + ":\n" for t in trigger.split('|'): result += " " + t + "\n" else: result = "No reactions for this channel." bot.send_message(msg.chat.id, result)
def add_reaction(chat_id, trigger, reaction): trigger = re.sub('[*./|\\\]', '', trigger) if not len(trigger): return r = db.query("select * from reactions where reaction = ? and chat_id = ?", [reaction, chat_id]) if len(r): r = dict(r[0]) r['trigger'] = r['trigger'].split("|") r['trigger'].append(trigger) db.query("update reactions set trigger = ? where chat_id = ? and reaction = ?", ['|'.join(r['trigger']), chat_id, reaction]) else: db.query("insert into reactions(chat_id, trigger, reaction) values(?,?,?)", [chat_id, trigger, reaction])
def delete_trigger(chat_id, trigger, reaction): trigger = re.sub('[*./|\\\]', '', trigger) if not len(trigger): return r = db.query("select * from reactions where reaction = ? and chat_id = ?", [reaction, chat_id]) if len(r): r = dict(r[0]) r['trigger'] = r['trigger'].split("|") r['trigger'].remove(trigger) print(reaction, trigger) if len(r['trigger']): db.query("update reactions set trigger = ? where chat_id = ? and reaction = ?", ['|'.join(r['trigger']), chat_id, reaction]) else: delete_reaction(chat_id, reaction)
def write_vote(poll_id, answer_id, user_id, username, is_multipoll=False): sql = "select id from poll_votes where poll_id = ? and user_id = ?" data = [poll_id, user_id] if is_multipoll: sql += " and answer_id = ?" data.append(answer_id) v = db.query(sql, data) updated = False if len(v): for item in v: item = dict(item) db.query("update poll_votes set answer_id = ? where id = ?", [answer_id, item['id']]) updated = True if not updated: db.query("insert into poll_votes(poll_id, answer_id, user_id, username) values (?,?,?,?)", [poll_id, answer_id, user_id, username])
def get_poll(poll_id, full=False): poll = db.query("select *, cast(strftime('%s', date_started) as integer) as date_started_unix from polls where id = ?", [poll_id]) if len(poll): poll = dict(poll[0]) if not full: return poll poll['_answers'] = json.loads(poll['answers']) poll['answers'] = [{"text":a, "votes":0, "voters":[]} for a in json.loads(poll['answers'])] else: return votes = db.query("select * from poll_votes where poll_id = ?", [poll_id]) for v in votes: v = dict(v) poll['answers'][v['answer_id']]['votes'] += 1 poll['answers'][v['answer_id']]['voters'].append(v['username']) return poll
def get_chat_reactions(chat_id): r = db.query("select * from reactions where chat_id = ?", [chat_id]) ret = {} for item in r: item = dict(item) ret[item['reaction']] = item['trigger'] return ret
def get_history_item(chat_id, item_id): r = db.query( "select * from translation_history where id = ? and chat_id = ?", [int(item_id), chat_id]) if len(r): return r[0] else: return False
def get_chat(chat_id): byid = db.query("select * from chats where chat_id = ?", [chat_id]) if len(byid): chat = dict(byid[0]) chat['id'] = chat['chat_id'] chat['settings'] = json.loads(chat['settings']) return chat else: return False
def register_chat(chat_id): db.query("insert into chats(chat_id) VALUES (?)", [chat_id]) #db.commit() return get_chat(chat_id)
def register(listen=True, ** kwargs): db.query(""" CREATE TABLE IF NOT EXISTS `polls` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `chat_id` INTEGER, `message_id` INTEGER, `text` TEXT, `answers` TEXT, `date_started` INTEGER DEFAULT CURRENT_TIMESTAMP, `ttl` INTEGER, `is_multi` INTEGER DEFAULT 0 ); """) db.query(""" CREATE TABLE IF NOT EXISTS `poll_votes` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `poll_id` INTEGER, `user_id` INTEGER, `username` TEXT, `answer_id` INTEGER ); """) if listen: bot = helpers.bot.instance() @bot.channel_post_handler(regexp="^!vote |^!poll ") @bot.message_handler(regexp="^!vote |^!poll ") @bot.message_handler(commands=['vote', 'poll']) @bot.channel_post_handler(commands=['vote', 'poll']) def start_vote(msg): is_multipoll = False _ = msg.text.split(' ') _.pop(0) if len(_): if _[0] == "end": #stop_vote pass else: txt = ' '.join(_) if '"' in txt: _test = StringIO(txt) """Documentation: `Note The reader is hard-coded to recognise either '\r' or '\n' as end-of-line, and ignores lineterminator. This behavior may change in the future.` Well, shit. """ _params = csv.reader(_test, delimiter="\n", quotechar='"', lineterminator="�") params = [] for pew in _params: params.append(list(filter(None, pew))[0]) else: params = txt.split("\n") voting_text = params.pop(0) try_ttl = params.pop(-1) try: ttl = int(try_ttl) except: params.append(try_ttl) ttl = 5 #minutes) if not create_poll(msg.chat.id, voting_text, params, ttl, is_multipoll): bot.send_message(msg.chat.id, "Cant start vote: not enough parameters.") @bot.callback_query_handler(func=lambda call: True) def callback_query(call): try: bot.answer_callback_query(call.id, "") except Exception as e: print(e) data = call.data poll_id = None answer_id = None if data: try: data = json.loads(data) poll_id = data['poll_id'] answer_id = data['answer_id'] except: print("This is not poll:", call.json) if poll_id and answer_id is not None: poll = get_poll(poll_id) if not poll: print("No such poll:", poll_id) return write_vote(poll_id, answer_id, call.from_user.id, call.from_user.username, poll['is_multi']) _p = update_poll(poll_id)
def ev_translate(msg): text = msg.text or msg.caption text = re.sub(commands, '', text) if text == '' and msg.reply_to_message: text = msg.reply_to_message.text or msg.reply_to_message.caption splitted = text.split(' ') dest = get_setting(msg.chat.id, 'default_to') or config['default_to'] #if user is trying to set target lang by hands if len(splitted[0]) == 2: #replacing commonly mistaken language codes _dest = replace_multiple( { "ua": "uk", "by": "be", "br": "be", "jp": "ja" }, splitted[0]) print(_dest) if _dest in google_languages: dest = _dest #deleting language code from text splitted.pop(0) text = ' '.join(splitted) local_detected = detect_lang(text) if local_detected == dest: dest = get_setting(msg.chat.id, 'default_to_if_from_is_to' ) or config['default_to_if_from_is_to'] try: translated = translate(text, dest, True) translated_text = translated['translatedText'] translated_src = translated['detectedSourceLanguage'] except Exception as e: print(msg.chat.id, 'Translation error:', e) bot.send_message(msg.chat.id, "Error: {}".format(e)) return hist_id = db.query( "insert into translation_history (chat_id, query, result, src_lang, target_lang) values (:chat_id, :query, :result, :src_lang, :target_lang)", { 'chat_id': msg.chat.id, 'query': text, 'result': translated_text, 'src_lang': translated_src, 'target_lang': dest }, get_id=True) markup = False if 'tts' in config and config['tts']: btns = [] if translated_src in google_tts_languages: btns.append( types.InlineKeyboardButton('Say [' + translated_src + ']', callback_data=json.dumps({ 'function': 'tts', 'what': 'src', 'id': hist_id }))) if dest in google_tts_languages: btns.append( types.InlineKeyboardButton('Say [' + dest + ']', callback_data=json.dumps({ 'function': 'tts', 'what': 'target', 'id': hist_id }))) if len(btns): markup = types.InlineKeyboardMarkup(row_width=2) markup.add(*btns) bot.send_message(msg.chat.id, translated_text, reply_to_message_id=msg.message_id, reply_markup=markup)
def register(listen=True, config={}, **kwargs): db.query(""" CREATE TABLE IF NOT EXISTS `translation_history` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `chat_id` INTEGER, `query` TEXT DEFAULT '', `result` TEXT DEFAULT '', `src_lang` TEXT DEFAULT 'auto', `target_lang` TEXT DEFAULT 'auto' ); """) if listen: bot = helpers.bot.instance() @bot.channel_post_handler(regexp=commands) @bot.message_handler( func=lambda msg: not (msg.text or msg.caption or '').startswith( '!tts') and not (msg.text or msg.caption or '').startswith( '!history') ) #any message in direct chat should trigger translation def ev_translate(msg): text = msg.text or msg.caption text = re.sub(commands, '', text) if text == '' and msg.reply_to_message: text = msg.reply_to_message.text or msg.reply_to_message.caption splitted = text.split(' ') dest = get_setting(msg.chat.id, 'default_to') or config['default_to'] #if user is trying to set target lang by hands if len(splitted[0]) == 2: #replacing commonly mistaken language codes _dest = replace_multiple( { "ua": "uk", "by": "be", "br": "be", "jp": "ja" }, splitted[0]) print(_dest) if _dest in google_languages: dest = _dest #deleting language code from text splitted.pop(0) text = ' '.join(splitted) local_detected = detect_lang(text) if local_detected == dest: dest = get_setting(msg.chat.id, 'default_to_if_from_is_to' ) or config['default_to_if_from_is_to'] try: translated = translate(text, dest, True) translated_text = translated['translatedText'] translated_src = translated['detectedSourceLanguage'] except Exception as e: print(msg.chat.id, 'Translation error:', e) bot.send_message(msg.chat.id, "Error: {}".format(e)) return hist_id = db.query( "insert into translation_history (chat_id, query, result, src_lang, target_lang) values (:chat_id, :query, :result, :src_lang, :target_lang)", { 'chat_id': msg.chat.id, 'query': text, 'result': translated_text, 'src_lang': translated_src, 'target_lang': dest }, get_id=True) markup = False if 'tts' in config and config['tts']: btns = [] if translated_src in google_tts_languages: btns.append( types.InlineKeyboardButton('Say [' + translated_src + ']', callback_data=json.dumps({ 'function': 'tts', 'what': 'src', 'id': hist_id }))) if dest in google_tts_languages: btns.append( types.InlineKeyboardButton('Say [' + dest + ']', callback_data=json.dumps({ 'function': 'tts', 'what': 'target', 'id': hist_id }))) if len(btns): markup = types.InlineKeyboardMarkup(row_width=2) markup.add(*btns) bot.send_message(msg.chat.id, translated_text, reply_to_message_id=msg.message_id, reply_markup=markup) @bot.channel_post_handler(regexp='^!languages') @bot.message_handler(regexp='^!languages') def langs(msg): bot.reply_to(msg, ', '.join(google_languages)) histregex = '^!history$|^!history ' @bot.channel_post_handler(regexp=histregex) @bot.message_handler(regexp=histregex) def history(msg): text = msg.text or msg.caption text = re.sub(histregex, '', text) send = '' markup = False if len(text): item = get_history_item(msg.chat.id, text) if not item: send = 'Cannot get item `{text}`. Type `!history` to get full history.'.format( {'text': text}) else: send = '`{query}` {src_lang}<->{target_lang} `{result}`'.format( **item) btns = [] if item['src_lang'] in google_tts_languages: btns.append( types.InlineKeyboardButton( 'Say [' + item['src_lang'] + ']', callback_data=json.dumps({ 'function': 'tts', 'what': 'src', 'id': item['id'] }))) if item['target_lang'] in google_tts_languages: btns.append( types.InlineKeyboardButton( 'Say [' + item['target_lang'] + ']', callback_data=json.dumps({ 'function': 'tts', 'what': 'target', 'id': item['id'] }))) if len(btns): markup = types.InlineKeyboardMarkup(row_width=2) markup.add(*btns) else: full = get_history(msg.chat.id) send = '' if not len(full): send = "History is empty." for item in full: send += '\n{id} `{query}` {src_lang}<->{target_lang} `{result}`'.format( **item) bot.reply_to(msg, send, reply_markup=markup, parse_mode="Markdown")
def get_history(chat_id): return db.query("select * from translation_history where chat_id = ?", [chat_id])
def set_chat(chat_id, settings): return db.query("update chats set settings = ? where chat_id = ?", [json.dumps(settings), chat_id])
def delete_reaction(chat_id, reaction): db.query("delete from reactions where reaction = ? and chat_id = ?", [reaction, chat_id])