Markov: allow for auto-context insertion
this should result in no chains having a null context --- if no pre-existing context is created, one is created for the channel/nick and used. this makes, for example, arbitrary queries "private" to that nick (again unless that has been overridden). shouldn't affect much of anything, but adding this made the context-less learning code obsolete, which is fine since it was never used anyway
This commit is contained in:
parent
ce93480e9b
commit
7d41564d02
|
@ -54,11 +54,9 @@ class Markov(Module):
|
|||
self.stop = '__stop'
|
||||
|
||||
# set up regexes, for replying to specific stuff
|
||||
trainpattern = '^!markov\s+train\s+(.*)$'
|
||||
learnpattern = '^!markov\s+learn\s+(.*)$'
|
||||
replypattern = '^!markov\s+reply(\s+min=(\d+))?(\s+max=(\d+))?(\s+(.*)$|$)'
|
||||
|
||||
self.trainre = re.compile(trainpattern)
|
||||
self.learnre = re.compile(learnpattern)
|
||||
self.replyre = re.compile(replypattern)
|
||||
|
||||
|
@ -163,11 +161,14 @@ class Markov(Module):
|
|||
target = event.target()
|
||||
nick = irclib.nm_to_n(event.source())
|
||||
|
||||
if not irclib.is_channel(target):
|
||||
target = nick
|
||||
|
||||
self.lines_seen.append((nick, datetime.now()))
|
||||
self.connection = connection
|
||||
|
||||
# don't learn from commands
|
||||
if self.trainre.search(what) or self.learnre.search(what) or self.replyre.search(what):
|
||||
if self.learnre.search(what) or self.replyre.search(what):
|
||||
return
|
||||
|
||||
self._learn_line(what, target)
|
||||
|
@ -177,10 +178,7 @@ class Markov(Module):
|
|||
|
||||
target = event.target()
|
||||
|
||||
if self.trainre.search(what):
|
||||
return self.reply(connection, event, self.markov_train(connection, event, nick,
|
||||
userhost, what, admin_unlocked))
|
||||
elif self.learnre.search(what):
|
||||
if self.learnre.search(what):
|
||||
return self.reply(connection, event, self.markov_learn(connection, event, nick,
|
||||
userhost, what, admin_unlocked))
|
||||
elif self.replyre.search(what) and not self.shut_up:
|
||||
|
@ -202,21 +200,6 @@ class Markov(Module):
|
|||
self.lines_seen.append(('.self.said.', datetime.now()))
|
||||
return self.reply(connection, event, '{0:s}'.format(self._generate_line(target, line=what)))
|
||||
|
||||
def markov_train(self, connection, event, nick, userhost, what, admin_unlocked):
|
||||
"""Learn lines from a file. Good for initializing a brain."""
|
||||
|
||||
match = self.trainre.search(what)
|
||||
if match and admin_unlocked:
|
||||
filename = match.group(1)
|
||||
|
||||
try:
|
||||
for line in open(filename, 'r'):
|
||||
self._learn_line(line)
|
||||
|
||||
return 'Learned from \'{0:s}\'.'.format(filename)
|
||||
except IOError:
|
||||
return 'No such file \'{0:s}\'.'.format(filename)
|
||||
|
||||
def markov_learn(self, connection, event, nick, userhost, what, admin_unlocked):
|
||||
"""Learn one line, as provided to the command."""
|
||||
|
||||
|
@ -431,10 +414,10 @@ class Markov(Module):
|
|||
max_id = self._get_max_chain_id()
|
||||
rand_id = random.randint(1,max_id)
|
||||
query = ('SELECT v FROM markov_chain WHERE k1 = ? AND k2 = ? AND '
|
||||
'(context_id = ? OR context_id IS NULL) AND id >= {0:d} LIMIT 1'.format(rand_id))
|
||||
'(context_id = ?) AND id >= {0:d} LIMIT 1'.format(rand_id))
|
||||
else:
|
||||
query = ('SELECT v FROM markov_chain WHERE k1 = ? AND k2 = ? AND '
|
||||
'(context_id = ? OR context_id IS NULL)')
|
||||
'(context_id = ?)')
|
||||
cursor = db.execute(query, (k1,k2,context_id))
|
||||
results = cursor.fetchall()
|
||||
|
||||
|
@ -454,7 +437,7 @@ class Markov(Module):
|
|||
values = []
|
||||
try:
|
||||
db = self.get_db()
|
||||
query = 'SELECT k2 FROM markov_chain WHERE v = ? AND (context_id = ? OR context_id IS NULL)'
|
||||
query = 'SELECT k2 FROM markov_chain WHERE v = ? AND (context_id = ?)'
|
||||
cursor = db.execute(query, (v,context_id))
|
||||
results = cursor.fetchall()
|
||||
|
||||
|
@ -529,7 +512,52 @@ class Markov(Module):
|
|||
if result:
|
||||
return result['id']
|
||||
else:
|
||||
return None
|
||||
# auto-generate a context to keep things private
|
||||
self._add_context_for_target(target)
|
||||
return self._get_context_id_for_target(target)
|
||||
except sqlite3.Error as e:
|
||||
db.close()
|
||||
print('sqlite error in Markov._get_context_id_for_target: ' + str(e))
|
||||
raise
|
||||
|
||||
def _add_context_for_target(self, target):
|
||||
|
||||
"""Create a new context for the desired/input target."""
|
||||
|
||||
try:
|
||||
db = self.get_db()
|
||||
cur = db.cursor()
|
||||
statement = 'INSERT INTO markov_context (context) VALUES (?)'
|
||||
cur.execute(statement, (target,))
|
||||
statement = '''
|
||||
INSERT INTO markov_target_to_context_map (target, context_id)
|
||||
VALUES (?, (SELECT id FROM markov_context WHERE context = ?))
|
||||
'''
|
||||
cur.execute(statement, (target,target))
|
||||
db.commit()
|
||||
db.close()
|
||||
except sqlite3.Error as e:
|
||||
db.rollback()
|
||||
db.close()
|
||||
print("sqlite error in Markov._add_context_for_target: " + str(e))
|
||||
raise
|
||||
try:
|
||||
db = self.get_db()
|
||||
query = '''
|
||||
SELECT mc.id FROM markov_context mc
|
||||
INNER JOIN markov_target_to_context_map mt
|
||||
ON mt.context_id = mc.id
|
||||
WHERE mt.target = ?
|
||||
'''
|
||||
cursor = db.execute(query, (target,))
|
||||
result = cursor.fetchone()
|
||||
db.close()
|
||||
if result:
|
||||
return result['id']
|
||||
else:
|
||||
# auto-generate a context to keep things private
|
||||
self._add_context_for_target(target)
|
||||
return self._get_context_id_for_target(target)
|
||||
except sqlite3.Error as e:
|
||||
db.close()
|
||||
print('sqlite error in Markov._get_context_id_for_target: ' + str(e))
|
||||
|
|
Loading…
Reference in New Issue