Skip to content

Commit

Permalink
User data now stored in SQLite database. Access is through Storm ORM
Browse files Browse the repository at this point in the history
so the actual database implementation can be swapped out
  • Loading branch information
michel-slm committed Sep 29, 2009
1 parent 6db23f3 commit 1adb32a
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 35 deletions.
39 changes: 26 additions & 13 deletions bot.py
Expand Up @@ -21,19 +21,32 @@

from plugins import twitter
import os, sys, time
import msg_eval
from msg_eval import MsgEval
import datamodel

t = twitter.Twitter()

while True:
# check if there is a request
for m in t.get_messages():
print m['sender_screen_name'], m['text']
try:
result = msg_eval.eval(m)
except Exception as e:
result = str(type(e)) + ": " + str(e)
t.send_message(m['sender_screen_name'], result)

time.sleep(30)
msg_eval = MsgEval(t)

try:
while True:
# check if there is a request
# reverse the list, due to reverse chronological order
# to make sure later commands overwrite earlier ones
for m in t.get_messages()[::-1]:
sys.stdout.write(m['sender_screen_name'] + ": " + m['text'] + "\n")
try:
result = msg_eval.eval(m)
except Exception as e:
result = str(type(e)) + ": " + str(e)
if result:
print result
t.send_message(m['sender_screen_name'], result)
else:
sys.stdout.write("Message processed silently.\n")

time.sleep(30)

except KeyboardInterrupt as e:
sys.stdout.write("Quitting\n")
msg_eval.quit()

67 changes: 67 additions & 0 deletions datamodel.py
@@ -0,0 +1,67 @@
"""
Copyright (C) 2009 Michel Alexandre Sailm. All rights reserved.
This file is part of Hircus ConnectBot.
Hircus ConnectBot is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
Hircus ConnectBot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with Hircus ConnectBot. If not, see
<http://www.gnu.org/licenses/>.
"""

from storm.locals import *
import os

DB_BACKEND = 'sqlite:'
DB_FILE = os.path.join(os.getenv("HOME"),
".config",
"hircus_contactbot",
"contacts.db")

DB_INITSQL = \
"""
CREATE TABLE person
(id INTEGER PRIMARY KEY,
screen_name VARCHAR,
phone VARCHAR,
location VARCHAR)
"""

class Person(object):
__storm_table__ = "person"
id = Int(primary=True)
screen_name = Unicode()
phone = Unicode()
location = Unicode()

class MsgDB(object):
def __init__(self, db_backend=DB_BACKEND, db_file=DB_FILE):
db_exists = db_file and os.path.exists(db_file)
self.db = create_database(db_backend+db_file)
self.store = Store(self.db)
if not db_exists:
# new database, needs initializing
print "Initializing DB"
self.store.execute(DB_INITSQL)
print "DB initialized"
self.store.flush()
self.store.commit()

def find_person(self, name):
person = self.store.find(Person, \
Person.screen_name == name).one()
if not person:
person = Person()
person.screen_name = name
self.store.add(person)

return person
85 changes: 63 additions & 22 deletions msg_eval.py
Expand Up @@ -18,39 +18,80 @@
<http://www.gnu.org/licenses/>.
"""

import datamodel

class MsgError(Exception):
def __init__(self, value):
self.value = value

def __str__(self):
return repr(self.value)

def eval(msg):
sender = msg['sender_screen_name']
cmdtext = msg['text']
cmds = cmdtext.split()
class MsgEval(object):
def __init__(self, agent):
self.__msg_db = datamodel.MsgDB()
self.__agent = agent

if len(cmds) < 2:
raise MsgError("Insufficient arguments")
def eval(self, msg):
sender = unicode(msg['sender_screen_name'])
cmdtext = msg['text']
cmds = cmdtext.split()

if cmds[0] == "set":
cmds = cmds[1:]
if len(cmds) < 2:
raise MsgError("Invalid arguments: " + cmds)
if cmds[0] == "phone":
return "new phone number for " + sender + " is " + cmds[1]
elif cmds[0] == "location":
return "new location for " + sender + " is " + \
cmdtext[cmdtext.index(cmds[1]):]
raise MsgError("Insufficient arguments")

if cmds[0] == "set":
cmds = cmds[1:]
if len(cmds) < 2:
raise MsgError("Invalid arguments: " + cmds)
if cmds[0] == "phone":
phone = unicode(cmds[1])
person = self.__msg_db.find_person(sender)
person.phone = phone
self.__msg_db.store.flush()
#return "new phone number for " + sender + " is " + cmds[1]
return None
elif cmds[0] == "location":
location = unicode(cmdtext[cmdtext.index(cmds[1]):])
person = self.__msg_db.find_person(sender)
person.location = location
self.__msg_db.store.flush()
#return "new location for " + sender + " is " + location
return None

else:
raise KeyError(cmds[0])
elif cmds[0] == "phone":
target = unicode(cmds[1])
if sender==target or self.__agent.friends_p(target, sender):
target_person = self.__msg_db.find_person(target)
if target_person.phone:
return "%s can be reached at %s." \
% (target, target_person.phone)
else:
return "%s has not left a number." \
% (target,)
else:
return "%s's phone number is on a need-to-know basis." \
% (target,)

elif cmds[0] == "location":
print "Got a location request!"
target = unicode(cmds[1])
if sender==target or self.__agent.friends_p(target, sender):
target_person = self.__msg_db.find_person(target)
if target_person.location:
return "%s is currently in %s." \
% (target, target_person.location)
else:
return "%s's whereabout is unknown." \
% (target,)
else:
return "%s's whereabout is on a need-to-know basis." \
% (target,)
else:
raise KeyError(cmds[0])
elif cmds[0] == "phone":
raise NotImplementedError()
elif cmds[0] == "location":
raise NotImplementedError()
else:
raise KeyError(cmds[0])



def quit(self):
# commit remaining changes
self.__msg_db.store.commit()

0 comments on commit 1adb32a

Please sign in to comment.