Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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)
Esempio n. 4
0
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])
Esempio n. 5
0
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)
Esempio n. 6
0
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])
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 10
0
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
Esempio n. 11
0
def register_chat(chat_id):
    db.query("insert into chats(chat_id) VALUES (?)", [chat_id])
    #db.commit()
    return get_chat(chat_id)
Esempio n. 12
0
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])
Esempio n. 16
0
def set_chat(chat_id, settings):
    return db.query("update chats set settings = ? where chat_id = ?",
                    [json.dumps(settings), chat_id])
Esempio n. 17
0
def delete_reaction(chat_id, reaction):
    db.query("delete from reactions where reaction = ? and chat_id = ?", [reaction, chat_id])