From ffa9955ce4cad7feab16aa328dbe1f07d684cfd0 Mon Sep 17 00:00:00 2001 From: Paul Walko Date: Sat, 29 Jul 2017 00:08:31 +0000 Subject: [PATCH 1/5] create bash module --- modules/bash.py | 281 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 modules/bash.py diff --git a/modules/bash.py b/modules/bash.py new file mode 100644 index 000000000..c6ff72ea3 --- /dev/null +++ b/modules/bash.py @@ -0,0 +1,281 @@ +#!/usr/bin/python3 +""" +bash.py - bash.org clone. Saves quotes from quote-logger module to a db +author: paulwalko +""" + +from threading import Thread +import os, sqlite3, time + +queue = [] + +def setup(self): + fn = self.nick + '-' + self.config.host + '.bash.db' + bash_quotes = 'bash_logs' + self.bash_quotes_path = os.path.join(os.path.expanduser('~/.phenny'), bash_quotes) + self.bash_db = os.path.join(os.path.expanduser('~/.phenny'), fn) + self.bash_conn = sqlite3.connect(self.bash_db) + + if not os.path.exists(self.bash_quotes_path): + os.makedirs(self.bash_quotes_path) + + c = self.bash_conn.cursor() + c.execute('''create table if not exists quotes ( + id integer primary key autoincrement, + channel varchar(255), + nick varchar(255), + quote text, + time timestamp default CURRENT_TIMESTAMP + );''') + + c.execute('''create table if not exists stats ( + id integer primary key autoincrement, + channel varchar(255), + nick varchar(255), + lines unsigned big int not null default 0, + unique (channel, nick) on conflict replace + );''') + c.close() + + """Start thread to check for new messages""" + Thread(target = insert_into_db_caller, args=(self,)).start() + +def bash(phenny, input): + """'.bash' - queries a quote selection to add""" + usage = "Usage: .bash <# msgs to start at> <# msgs to end at> (Specifies a range of messages)" + + input_all = input.group(2) + if not input_all: + phenny.say(usage) + return + + input_args = input_all.split() + if len(input_args) < 4: + phenny.say(usage) + return + + channel = input.sender + nick1 = input_args[0] + nick1_start_str = input_args[1] + nick2 = input_args[2] + nick2_end_str = input_args[3] + + """Check Input Type""" + if not nick1_start_str.isdigit() or not nick2_end_str.isdigit(): + phenny.say("Error: 2nd & 4th argument must be integers") + phenny.say(usage) + return + + nick1_start = int(nick1_start_str) + nick2_end = int(nick2_end_str) + + """Connect to db""" + fn = phenny.nick + '-' + phenny.config.host + '.bash.db' + bash_db = os.path.join(os.path.expanduser('~/.phenny'), fn) + bash_conn = sqlite3.connect(bash_db) + c = bash_conn.cursor() + + """Check input for validity""" + c.execute('''SELECT lines FROM stats WHERE (channel=? OR channel='NULL') AND nick=?''', (channel, nick1)) + rows = c.fetchall() + nick1_total = 0 + for row in rows: + nick1_total = nick1_total + row[0] + + c.execute('''SELECT lines FROM stats WHERE (channel=? OR channel='NULL') AND nick=?''', (channel, nick2)) + rows = c.fetchall() + nick2_total = 0 + for row in rows: + nick2_total = nick2_total + row[0] + + if nick1_total < nick1_start: + phenny.say("Error: %s has not done %s actions (EVERYTHING included EXCEPT {bot} replies)" % (nick1, nick1_start, self.phenny.nick)) + return + + if nick2_total < nick2_end: + phenny.say("Error: %s has not done %s actions (EVERYTHING included EXCEPT {bot} replies)" % (nick2, nick2_end, self.phenny.nick)) + return + + """Fetch quote ids""" + c.execute('''SELECT id, channel, nick FROM quotes WHERE (channel=? OR channel='ALL') AND nick=?''', (channel, nick1)) + rows = c.fetchall() + nick1_id = -1 + for row, i in zip(reversed(rows), range(nick1_start)): + if i == nick1_start - 1: + nick1_id = row[0] + + c.execute('''SELECT id, channel, nick FROM quotes WHERE (channel=? OR channel='ALL') AND nick=?''', (channel, nick2)) + rows = c.fetchall() + nick2_id = -1 + for row, i in zip(reversed(rows), range(nick2_end)): + if i == nick2_end - 1: + nick2_id = row[0] + + if nick2_id < nick1_id: + phenny.say("Error, try again. 2nd nick number (Newer) must come after 1st nick number") + phenny.say(usage) + return + + """Fetch quotes within range of ids""" + c.execute('''SELECT quote FROM quotes WHERE (channel=? OR channel='ALL') AND id >= ? AND id <= ?''', (channel, nick1_id, nick2_id)) + final_lines = [] + for line in c.fetchall(): + final_lines.append(line[0]) + final_lines = ''.join(final_lines) + + """Write quotes to file""" + files = os.listdir(phenny.bash_quotes_path) + files_num = [0] + new_file = '1.txt' + for f in files: + f = f.strip('.txt') + if f.isdigit(): + files_num.append(int(f)) + + new_file = str(max(files_num) + 1) + '.txt' + new_path = os.path.join(phenny.bash_quotes_path, new_file) + with open(new_path, 'w') as f: + f.write(final_lines) + f.close() + + phenny.say('%s: Check bash.walko.org to see your quote' % (input.nick)) + +def logger(phenny, input): + """logs EVERYTHING""" + + allowed_actions = ['PRIVMSG', 'JOIN', 'QUIT', 'PART', 'NICK', 'KICK', 'MODE'] + + if input.event not in allowed_actions: + return + + message="" + if input.event == 'PRIVMSG': + channel = input.sender + nick = input.nick + if input.group(1)[:8] == '\x01ACTION ': + quote = "* {nick} {msg}".format(nick=nick, msg=input.group(1)[8:-1]) + else: + quote = "<{nick}> {msg}".format(nick=nick, msg=input.group(1)) + elif input.event == 'JOIN': + channel = input.group(1) + nick = input.nick + quote = "--> {nick} has joined {channel}".format(nick=nick, channel=channel) + elif input.event == 'PART': + channel = input.sender + nick = input.nick + if input.group(1): + message = " ({message})".format(message=input.group(1)) + quote = "<-- {nick} has left {channel}{message}".format(nick=nick, channel=channel, message=message) + elif input.event == 'QUIT': + channel = 'ALL' + nick = input.nick + if input.group(1): + message = " ({message})".format(message=input.group(1)) + quote = "<-- {nick} has quit{message}".format(nick=nick, message=message) + elif input.event == 'KICK': + channel = input.sender + nick = input.nick + quote = "<-- {nick} has kicked {nick_kick} [{kick_msg}] from {channel}".format(nick=nick, nick_kick=input.args[1], kick_msg=input.group(1), channel=channel) + elif input.event == 'NICK': + channel = 'ALL' + nick = input.nick + quote = "-- {nick} is now known as {nick_new}".format(nick=nick, nick_new=input.group(1)) + elif len(input.args) > 0 and input.args[0].startswith('#'): + channel = input.sender + nick = input.nick + args = str(input.args[1:]).replace('(', '').replace(')', '').replace("'", '') + if args.endswith(','): + args = args.replace(',', '') + else: + args = args.replace(',', ' ') + quote = "-- Mode {channel} [{args}] by {nick}".format(channel=input.sender, args=args, nick=input.nick) + else: + return + + quote = "{quote}\n".format(quote=quote) + + sqlite_data = { + 'channel': channel, + 'nick': nick, + 'quote': quote + } + + # format action messages + + global queue + queue.append(sqlite_data) + +def insert_into_db_caller(phenny): + while True: + global queue + if len(queue) > 0: + insert_into_db(phenny, queue.pop(0)) + time.sleep(1) + +def insert_into_db(phenny, sqlite_data): + """inserts message to to temp db""" + + if not bash.conn: + bash.conn = sqlite3.connect(phenny.bash_db) + + c = bash.conn.cursor() + + c.execute('''insert into quotes + (channel, nick, quote, time) + values( + :channel, + :nick, + :quote, + CURRENT_TIMESTAMP + );''', sqlite_data) + + c.execute('''insert or replace into stats + (channel, nick, lines) + values( + :channel, + :nick, + coalesce((select lines from stats where channel=:channel and nick=:nick) + 1, 1) + );''', sqlite_data) + + + c.close() + bash.conn.commit() + + c = bash.conn.cursor() + + c.execute('''select id from quotes order by id desc limit 1''') + last_id = c.fetchall()[0][0] - 99 + + c.execute('''select channel, nick from quotes where id < ?''', (last_id,)) + rows = c.fetchall() + for row in rows: + channel = row[0] + nick = row[1] + + c.execute('''select lines from stats where channel=? and nick=?''', (channel, nick)) + lines = 0 + lines = c.fetchall()[0][0] + + if lines - 1 == 0: + c.execute('''delete from stats where channel=? and nick=?''', (channel, nick)) + else: + c.execute('''replace into stats + (channel, nick, lines) + values( + ?, + ?, + (select lines from stats where channel=? and nick=?) - 1 + );''', (channel, nick, channel, nick)) + + c.execute('''delete from quotes where id < ?''', (last_id,)) + + c.close() + bash.conn.commit() + +bash.conn = None +bash.rule = (['bash'], r'(.*)') +logger.event = '*' +logger.rule = r'(.*)' + +if __name__ == '__main__': + print(__doc__.strip()) From eebbe9ac22298d9398c5977acd519a2ee82c173b Mon Sep 17 00:00:00 2001 From: paulwalko Date: Wed, 2 Aug 2017 20:24:12 -0400 Subject: [PATCH 2/5] use actual bash --- modules/bash.py | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/modules/bash.py b/modules/bash.py index c6ff72ea3..e4d547ac9 100644 --- a/modules/bash.py +++ b/modules/bash.py @@ -5,7 +5,7 @@ """ from threading import Thread -import os, sqlite3, time +import os, sqlite3, time, web queue = [] @@ -123,22 +123,15 @@ def bash(phenny, input): final_lines.append(line[0]) final_lines = ''.join(final_lines) - """Write quotes to file""" - files = os.listdir(phenny.bash_quotes_path) - files_num = [0] - new_file = '1.txt' - for f in files: - f = f.strip('.txt') - if f.isdigit(): - files_num.append(int(f)) - - new_file = str(max(files_num) + 1) + '.txt' - new_path = os.path.join(phenny.bash_quotes_path, new_file) - with open(new_path, 'w') as f: - f.write(final_lines) - f.close() - - phenny.say('%s: Check bash.walko.org to see your quote' % (input.nick)) + + quote_json = { + 'body': final_lines, + 'tags': '', + 'key': "SUPERSECRETAPIKEY" + } + web.post('https://bash.vtluug.org/quotes', quote_json) + + phenny.say('Check https://bash.vtluug.org/quotes to see your quote!') def logger(phenny, input): """logs EVERYTHING""" From 211b84446f22dfd3c5a21895448c883b7b70fb71 Mon Sep 17 00:00:00 2001 From: Paul Walko Date: Wed, 2 Aug 2017 21:30:53 -0400 Subject: [PATCH 3/5] use vtbash --- modules/bash.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/bash.py b/modules/bash.py index e4d547ac9..7b886ffb4 100644 --- a/modules/bash.py +++ b/modules/bash.py @@ -126,10 +126,11 @@ def bash(phenny, input): quote_json = { 'body': final_lines, - 'tags': '', + 'tags': ','.join(['bone', nick1, nick2]), 'key': "SUPERSECRETAPIKEY" } - web.post('https://bash.vtluug.org/quotes', quote_json) + + web.post('https://bash.vtluug.org/quotes', {}, {}, True, json=quote_json) phenny.say('Check https://bash.vtluug.org/quotes to see your quote!') From 292c6e80b0cf3dcbc44694c8436cfd7a6713a4c3 Mon Sep 17 00:00:00 2001 From: Paul Walko Date: Sun, 23 Dec 2018 17:51:56 -0500 Subject: [PATCH 4/5] change 'self.phenny to phenny' + formatting --- modules/bash.py | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/modules/bash.py b/modules/bash.py index 7b886ffb4..d711d89d7 100644 --- a/modules/bash.py +++ b/modules/bash.py @@ -10,6 +10,8 @@ queue = [] def setup(self): + """Creates sqlite database to store quotes + """ fn = self.nick + '-' + self.config.host + '.bash.db' bash_quotes = 'bash_logs' self.bash_quotes_path = os.path.join(os.path.expanduser('~/.phenny'), bash_quotes) @@ -37,7 +39,7 @@ def setup(self): );''') c.close() - """Start thread to check for new messages""" + # Start thread to check for new messages Thread(target = insert_into_db_caller, args=(self,)).start() def bash(phenny, input): @@ -60,7 +62,7 @@ def bash(phenny, input): nick2 = input_args[2] nick2_end_str = input_args[3] - """Check Input Type""" + # Check Input Type if not nick1_start_str.isdigit() or not nick2_end_str.isdigit(): phenny.say("Error: 2nd & 4th argument must be integers") phenny.say(usage) @@ -69,13 +71,13 @@ def bash(phenny, input): nick1_start = int(nick1_start_str) nick2_end = int(nick2_end_str) - """Connect to db""" + # Connect to db fn = phenny.nick + '-' + phenny.config.host + '.bash.db' bash_db = os.path.join(os.path.expanduser('~/.phenny'), fn) bash_conn = sqlite3.connect(bash_db) c = bash_conn.cursor() - """Check input for validity""" + # Check input for validity c.execute('''SELECT lines FROM stats WHERE (channel=? OR channel='NULL') AND nick=?''', (channel, nick1)) rows = c.fetchall() nick1_total = 0 @@ -89,14 +91,16 @@ def bash(phenny, input): nick2_total = nick2_total + row[0] if nick1_total < nick1_start: - phenny.say("Error: %s has not done %s actions (EVERYTHING included EXCEPT {bot} replies)" % (nick1, nick1_start, self.phenny.nick)) + phenny.say("Error: {} has not done {} actions (EVERYTHING included EXCEPT {} replies)" \ + .format(nick1, nick1_start, phenny.nick)) return if nick2_total < nick2_end: - phenny.say("Error: %s has not done %s actions (EVERYTHING included EXCEPT {bot} replies)" % (nick2, nick2_end, self.phenny.nick)) + phenny.say("Error: {} has not done {} actions (EVERYTHING included EXCEPT {} replies)" \ + .format(nick2, nick2_end, phenny.nick)) return - """Fetch quote ids""" + # Fetch quote ids c.execute('''SELECT id, channel, nick FROM quotes WHERE (channel=? OR channel='ALL') AND nick=?''', (channel, nick1)) rows = c.fetchall() nick1_id = -1 @@ -116,7 +120,7 @@ def bash(phenny, input): phenny.say(usage) return - """Fetch quotes within range of ids""" + # Fetch quotes within range of ids c.execute('''SELECT quote FROM quotes WHERE (channel=? OR channel='ALL') AND id >= ? AND id <= ?''', (channel, nick1_id, nick2_id)) final_lines = [] for line in c.fetchall(): @@ -135,7 +139,8 @@ def bash(phenny, input): phenny.say('Check https://bash.vtluug.org/quotes to see your quote!') def logger(phenny, input): - """logs EVERYTHING""" + """logs everyting to specific format, except we only keep last 100 lines + """ allowed_actions = ['PRIVMSG', 'JOIN', 'QUIT', 'PART', 'NICK', 'KICK', 'MODE'] @@ -159,7 +164,8 @@ def logger(phenny, input): nick = input.nick if input.group(1): message = " ({message})".format(message=input.group(1)) - quote = "<-- {nick} has left {channel}{message}".format(nick=nick, channel=channel, message=message) + quote = "<-- {nick} has left {channel}{message}" \ + .format(nick=nick, channel=channel, message=message) elif input.event == 'QUIT': channel = 'ALL' nick = input.nick @@ -169,11 +175,13 @@ def logger(phenny, input): elif input.event == 'KICK': channel = input.sender nick = input.nick - quote = "<-- {nick} has kicked {nick_kick} [{kick_msg}] from {channel}".format(nick=nick, nick_kick=input.args[1], kick_msg=input.group(1), channel=channel) + quote = "<-- {nick} has kicked {nick_kick} [{kick_msg}] from {channel}" \ + .format(nick=nick, nick_kick=input.args[1], kick_msg=input.group(1), channel=channel) elif input.event == 'NICK': channel = 'ALL' nick = input.nick - quote = "-- {nick} is now known as {nick_new}".format(nick=nick, nick_new=input.group(1)) + quote = "-- {nick} is now known as {nick_new}" \ + .format(nick=nick, nick_new=input.group(1)) elif len(input.args) > 0 and input.args[0].startswith('#'): channel = input.sender nick = input.nick @@ -182,7 +190,8 @@ def logger(phenny, input): args = args.replace(',', '') else: args = args.replace(',', ' ') - quote = "-- Mode {channel} [{args}] by {nick}".format(channel=input.sender, args=args, nick=input.nick) + quote = "-- Mode {channel} [{args}] by {nick}" \ + .format(channel=input.sender, args=args, nick=input.nick) else: return @@ -194,8 +203,6 @@ def logger(phenny, input): 'quote': quote } - # format action messages - global queue queue.append(sqlite_data) @@ -267,7 +274,7 @@ def insert_into_db(phenny, sqlite_data): bash.conn.commit() bash.conn = None -bash.rule = (['bash'], r'(.*)') +bash.rule = (['bash', 'vtbash', 'quote'], r'(.*)') logger.event = '*' logger.rule = r'(.*)' From 2fbc6754e9c2fec6362ee9bb9ce766d7efde9138 Mon Sep 17 00:00:00 2001 From: Paul Walko Date: Sun, 23 Dec 2018 23:20:59 -0500 Subject: [PATCH 5/5] restructure bash + buxfixes --- modules/bash.py | 292 +++++++++++++++++++++++++----------------------- phenny | 6 +- 2 files changed, 158 insertions(+), 140 deletions(-) diff --git a/modules/bash.py b/modules/bash.py index d711d89d7..7a191883b 100644 --- a/modules/bash.py +++ b/modules/bash.py @@ -20,7 +20,7 @@ def setup(self): if not os.path.exists(self.bash_quotes_path): os.makedirs(self.bash_quotes_path) - + c = self.bash_conn.cursor() c.execute('''create table if not exists quotes ( id integer primary key autoincrement, @@ -42,112 +42,85 @@ def setup(self): # Start thread to check for new messages Thread(target = insert_into_db_caller, args=(self,)).start() -def bash(phenny, input): - """'.bash' - queries a quote selection to add""" - usage = "Usage: .bash <# msgs to start at> <# msgs to end at> (Specifies a range of messages)" - - input_all = input.group(2) - if not input_all: - phenny.say(usage) - return - - input_args = input_all.split() - if len(input_args) < 4: - phenny.say(usage) - return - - channel = input.sender - nick1 = input_args[0] - nick1_start_str = input_args[1] - nick2 = input_args[2] - nick2_end_str = input_args[3] +def insert_into_db(phenny, sqlite_data): + """inserts message to to temp db""" - # Check Input Type - if not nick1_start_str.isdigit() or not nick2_end_str.isdigit(): - phenny.say("Error: 2nd & 4th argument must be integers") - phenny.say(usage) - return + if not bash.conn: + bash.conn = sqlite3.connect(phenny.bash_db) - nick1_start = int(nick1_start_str) - nick2_end = int(nick2_end_str) + c = bash.conn.cursor() - # Connect to db - fn = phenny.nick + '-' + phenny.config.host + '.bash.db' - bash_db = os.path.join(os.path.expanduser('~/.phenny'), fn) - bash_conn = sqlite3.connect(bash_db) - c = bash_conn.cursor() + c.execute('''INSERT INTO quotes + (channel, nick, quote, time) + VALUES( + :channel, + :nick, + :quote, + CURRENT_TIMESTAMP + );''', sqlite_data) - # Check input for validity - c.execute('''SELECT lines FROM stats WHERE (channel=? OR channel='NULL') AND nick=?''', (channel, nick1)) - rows = c.fetchall() - nick1_total = 0 - for row in rows: - nick1_total = nick1_total + row[0] + c.execute('''INSERT OR REPLACE INTO stats + (channel, nick, lines) + VALUES( + :channel, + :nick, + COALESCE((SELECT lines FROM stats WHERE channel=:channel AND nick=:nick) + 1, 1) + );''', sqlite_data) - c.execute('''SELECT lines FROM stats WHERE (channel=? OR channel='NULL') AND nick=?''', (channel, nick2)) - rows = c.fetchall() - nick2_total = 0 - for row in rows: - nick2_total = nick2_total + row[0] - if nick1_total < nick1_start: - phenny.say("Error: {} has not done {} actions (EVERYTHING included EXCEPT {} replies)" \ - .format(nick1, nick1_start, phenny.nick)) - return - - if nick2_total < nick2_end: - phenny.say("Error: {} has not done {} actions (EVERYTHING included EXCEPT {} replies)" \ - .format(nick2, nick2_end, phenny.nick)) - return + c.close() + bash.conn.commit() - # Fetch quote ids - c.execute('''SELECT id, channel, nick FROM quotes WHERE (channel=? OR channel='ALL') AND nick=?''', (channel, nick1)) - rows = c.fetchall() - nick1_id = -1 - for row, i in zip(reversed(rows), range(nick1_start)): - if i == nick1_start - 1: - nick1_id = row[0] + c = bash.conn.cursor() - c.execute('''SELECT id, channel, nick FROM quotes WHERE (channel=? OR channel='ALL') AND nick=?''', (channel, nick2)) + c.execute('''SELECT id FROM quotes ORDER BY id DESC LIMIT 1''') + last_id = c.fetchall()[0][0] - 99 + + c.execute('''SELECT channel, nick FROM quotes WHERE id < ?''', (last_id,)) rows = c.fetchall() - nick2_id = -1 - for row, i in zip(reversed(rows), range(nick2_end)): - if i == nick2_end - 1: - nick2_id = row[0] + for row in rows: + channel = row[0] + nick = row[1] - if nick2_id < nick1_id: - phenny.say("Error, try again. 2nd nick number (Newer) must come after 1st nick number") - phenny.say(usage) - return + c.execute('''SELECT lines FROM stats WHERE channel=? AND nick=?''', (channel, nick)) + lines = 0 + lines = c.fetchall()[0][0] - # Fetch quotes within range of ids - c.execute('''SELECT quote FROM quotes WHERE (channel=? OR channel='ALL') AND id >= ? AND id <= ?''', (channel, nick1_id, nick2_id)) - final_lines = [] - for line in c.fetchall(): - final_lines.append(line[0]) - final_lines = ''.join(final_lines) + if lines - 1 == 0: + c.execute('''DELETE FROM stats WHERE channel=? AND nick=?''', (channel, nick)) + else: + c.execute('''REPLACE INTO stats + (channel, nick, lines) + VALUES( + ?, + ?, + (SELECT lines FROM stats WHERE channel=? AND nick=?) - 1 + );''', (channel, nick, channel, nick)) + c.execute('''DELETE FROM quotes WHERE id < ?''', (last_id,)) - quote_json = { - 'body': final_lines, - 'tags': ','.join(['bone', nick1, nick2]), - 'key': "SUPERSECRETAPIKEY" - } - - web.post('https://bash.vtluug.org/quotes', {}, {}, True, json=quote_json) + c.close() + bash.conn.commit() - phenny.say('Check https://bash.vtluug.org/quotes to see your quote!') +def insert_into_db_caller(phenny): + """Checks for a new quote once a second + """ + while True: + global queue + if len(queue) > 0: + insert_into_db(phenny, queue.pop(0)) + time.sleep(1) def logger(phenny, input): """logs everyting to specific format, except we only keep last 100 lines """ allowed_actions = ['PRIVMSG', 'JOIN', 'QUIT', 'PART', 'NICK', 'KICK', 'MODE'] - + if input.event not in allowed_actions: return - message="" + message='' if input.event == 'PRIVMSG': channel = input.sender nick = input.nick @@ -176,7 +149,8 @@ def logger(phenny, input): channel = input.sender nick = input.nick quote = "<-- {nick} has kicked {nick_kick} [{kick_msg}] from {channel}" \ - .format(nick=nick, nick_kick=input.args[1], kick_msg=input.group(1), channel=channel) + .format(nick=nick, nick_kick=input.args[1], + kick_msg=input.group(1), channel=channel) elif input.event == 'NICK': channel = 'ALL' nick = input.nick @@ -206,72 +180,112 @@ def logger(phenny, input): global queue queue.append(sqlite_data) -def insert_into_db_caller(phenny): - while True: - global queue - if len(queue) > 0: - insert_into_db(phenny, queue.pop(0)) - time.sleep(1) +def bash(phenny, input): + """'.bash' - queries a quote selection to add""" + usage = ('Usage: .bash <# msgs to start at> ' + ' <# msgs to end at> (Specifies a range of messages)') -def insert_into_db(phenny, sqlite_data): - """inserts message to to temp db""" + input_all = input.group(2) + if not input_all: + phenny.say(usage) + return - if not bash.conn: - bash.conn = sqlite3.connect(phenny.bash_db) - - c = bash.conn.cursor() + input_args = input_all.split() + if len(input_args) < 4: + phenny.say(usage) + return - c.execute('''insert into quotes - (channel, nick, quote, time) - values( - :channel, - :nick, - :quote, - CURRENT_TIMESTAMP - );''', sqlite_data) + channel = input.sender + nick1 = input_args[0] + nick1_start_str = input_args[1] + nick2 = input_args[2] + nick2_end_str = input_args[3] - c.execute('''insert or replace into stats - (channel, nick, lines) - values( - :channel, - :nick, - coalesce((select lines from stats where channel=:channel and nick=:nick) + 1, 1) - );''', sqlite_data) + # Check Input Type + if not nick1_start_str.isdigit() or not nick2_end_str.isdigit(): + phenny.say('Error: 2nd & 4th argument must be integers') + phenny.say(usage) + return + + nick1_start = int(nick1_start_str) + nick2_end = int(nick2_end_str) + # Connect to db + fn = phenny.nick + '-' + phenny.config.host + '.bash.db' + bash_db = os.path.join(os.path.expanduser('~/.phenny'), fn) + bash_conn = sqlite3.connect(bash_db) + c = bash_conn.cursor() - c.close() - bash.conn.commit() - - c = bash.conn.cursor() - - c.execute('''select id from quotes order by id desc limit 1''') - last_id = c.fetchall()[0][0] - 99 - - c.execute('''select channel, nick from quotes where id < ?''', (last_id,)) + # Check input for validity + c.execute('''SELECT lines FROM stats + WHERE (channel=? OR channel='NULL') + AND nick=?''', (channel, nick1)) rows = c.fetchall() + nick1_total = 0 for row in rows: - channel = row[0] - nick = row[1] + nick1_total = nick1_total + row[0] - c.execute('''select lines from stats where channel=? and nick=?''', (channel, nick)) - lines = 0 - lines = c.fetchall()[0][0] + c.execute('''SELECT lines FROM stats + WHERE (channel=? OR channel='NULL') + AND nick=?''', (channel, nick2)) + rows = c.fetchall() + nick2_total = 0 + for row in rows: + nick2_total = nick2_total + row[0] - if lines - 1 == 0: - c.execute('''delete from stats where channel=? and nick=?''', (channel, nick)) - else: - c.execute('''replace into stats - (channel, nick, lines) - values( - ?, - ?, - (select lines from stats where channel=? and nick=?) - 1 - );''', (channel, nick, channel, nick)) + if nick1_total < nick1_start: + phenny.say("Error: {} has not done {} actions ({} replies not included)" \ + .format(nick1, nick1_start, phenny.nick)) + return - c.execute('''delete from quotes where id < ?''', (last_id,)) + if nick2_total < nick2_end: + phenny.say("Error: {} has not done {} actions ({} replies not included)" \ + .format(nick2, nick2_end, phenny.nick)) + return - c.close() - bash.conn.commit() + # Fetch quote ids + c.execute('''SELECT id, channel, nick FROM quotes + WHERE (channel=? OR channel='ALL') + AND nick=?''', (channel, nick1)) + rows = c.fetchall() + nick1_id = -1 + for row, i in zip(reversed(rows), range(nick1_start)): + if i == nick1_start - 1: + nick1_id = row[0] + + c.execute('''SELECT id, channel, nick FROM quotes + WHERE (channel=? OR channel='ALL') + AND nick=?''', (channel, nick2)) + rows = c.fetchall() + nick2_id = -1 + for row, i in zip(reversed(rows), range(nick2_end)): + if i == nick2_end - 1: + nick2_id = row[0] + + if nick2_id < nick1_id: + phenny.say('Error, try again. 2nd message must occur after first message.') + phenny.say(usage) + return + + # Fetch quotes within range of ids + c.execute('''SELECT quote FROM quotes + WHERE (channel=? OR channel='ALL') + AND id >= ? AND id <= ?''', (channel, nick1_id, nick2_id)) + final_lines = [] + for line in c.fetchall(): + final_lines.append(line[0]) + final_lines = ''.join(final_lines) + + + quote_json = { + 'body': final_lines, + 'tags': ','.join([phenny.nick, nick1, nick2]), + 'key': phenny.config.bash_api_key + } + + web.post('https://bash.vtluug.org/quotes', {}, {}, True, json=quote_json) + + phenny.say('Check https://bash.vtluug.org/quotes to see your quote!') bash.conn = None bash.rule = (['bash', 'vtbash', 'quote'], r'(.*)') diff --git a/phenny b/phenny index 358d7fde0..cc38dc786 100755 --- a/phenny +++ b/phenny @@ -46,10 +46,14 @@ def create_default_config(fn): # leave the api key blank to not use them and be sure to add the 'linx' module to the ignore list. linx_api_key = "" + # bash-enabled features + # designed to be used with https://github.com/vtluug/pyqdb + bash_api_key = '' + # These are people who will be able to use admin.py's functions... admins = [owner, 'someoneyoutrust'] # But admin.py is disabled by default, as follows: - exclude = ['admin', 'linx', 'foodforus'] + exclude = ['admin', 'linx', 'foodforus', 'bash'] ignore = ['']