aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikkel Svagård <mikkel.svagard@gmail.com>2017-12-03 23:33:49 +0100
committerGitHub <noreply@github.com>2017-12-03 23:33:49 +0100
commit97ae43fa9538c6759367369e1344b82e6fb88baa (patch)
tree84bfd8c5cfada8b483e5d2d78bfea3a4fb5260f6
parentac7900cfd87452ea5ee6ee9a15b99256ff5e8166 (diff)
parentf0f05a19739123aa16cbd00620be8705e8348302 (diff)
downloadsaitama-97ae43fa9538c6759367369e1344b82e6fb88baa.tar.gz
Merge pull request #2 from kapteinstein/RemindMe
Add Remind Me functionality
-rw-r--r--FbClient.py132
-rw-r--r--Message_parser.py85
-rw-r--r--timeEventQueuer.py25
3 files changed, 238 insertions, 4 deletions
diff --git a/FbClient.py b/FbClient.py
new file mode 100644
index 0000000..4677f2d
--- /dev/null
+++ b/FbClient.py
@@ -0,0 +1,132 @@
+from fbchat import log, Client
+from fbchat.models import *
+from geeteventbus.subscriber import subscriber
+from geeteventbus.eventbus import eventbus
+from geeteventbus.event import event
+from timeEventQueuer import *
+from Message_parser import *
+
+import time
+import requests
+import threading
+import random
+import datetime
+
+#class types
+ID_TIMER = 0;
+ID_LISTENER = 1;
+EVENTID_CLIENT_SEND = "Topic Message Send"
+EVENTID_CLIENT_STOP = "Topic Stop Client"
+EVENTID_CLIENT_START = "Topic Start Client"
+
+_BASE_URL = 'http://spaghettiprojecti.no/saitama/'
+_THREAD_ID = '1434497743266652'
+
+# Subclass fbchat.Client and override required methods
+class Fb_client(threading.Thread,Client,subscriber):
+ def __init__(self,eventbus,parser):
+ with open('passwd.txt', 'r') as f:
+ passwd = [a.strip() for a in f.readlines()]
+ threading.Thread.__init__(self)
+ Client.__init__(self,passwd[0],passwd[1])
+ subscriber.__init__(self)
+
+ self.parser = parser
+ self.eb = eventbus
+ print("Registering Topics")
+ self.eb.register_consumer(self,EVENTID_CLIENT_SEND)
+ self.eb.register_consumer(self,EVENTID_CLIENT_STOP)
+ self.eb.register_consumer(self,EVENTID_CLIENT_START)
+ def run(self):
+ self.listen()
+
+ def onMessage(self, author_id, message_object, thread_id, thread_type, **kwargs):
+ self.markAsDelivered(author_id, thread_id)
+ self.markAsRead(author_id)
+
+ #log.info("{} from {} in {}".format(message_object, thread_id, thread_type.name))
+
+ # If Saitama-san is the author -> sayonara
+ if author_id == self.uid:
+ return
+
+ message_data = Message_data(message_object.text, thread_id, thread_type)
+ self.parser.parse(message_data)
+ print("Message parsed")
+
+ #Listens on the bus, subscribed to client send, stop and start
+ def process(self,new_event):
+ print("Event Recieved: {}".format(new_event.get_topic()))
+ if not isinstance(new_event,event):
+ print("Invalid event type passed")
+ return
+ if(new_event.get_topic()==EVENTID_CLIENT_SEND):
+ self.send_message(new_event)
+ elif(new_event.get_topic()==EVENTID_CLIENT_STOP):
+ self.stopClient()
+ elif(new_event.get_topic()==EVENTID_CLIENT_START):
+ self.startClient()
+
+ def startClient(self):
+ self.listen()
+ print("Exiting Client")
+
+ def stopClient(self):
+ print("Stop listneing and logging out")
+ self.stopListening()
+ self.logout()
+
+ def send_message(self,message_event):
+ message_data = message_event.get_data()
+ self.send(Message(text=message_data.get_text()),
+ thread_id=message_data.get_id(),
+ thread_type = message_data.get_type())
+
+ @staticmethod
+ def post_message_event(eb,message_data):
+ print("Posting event")
+ eb.post(event(EVENTID_CLIENT_SEND,message_data))
+
+class Message_data():
+ def __init__(self,text,thread_id,thread_type):
+ self.text = text
+ self.thread_id = thread_id
+ self.thread_type = thread_type
+
+ def get_text(self): return self.text
+ def set_text(self,text): self.text = text
+ def get_id(self,): return self.thread_id
+ def get_type(self,): return self.thread_type
+
+
+
+
+
+
+def main():
+ eb = eventbus()
+ parser = Message_parser(eb)
+
+ cv = threading.Condition() #conditional Variable
+ teq = Time_event_queuer(eb,cv)
+ teq.start()
+
+
+ client = Fb_client(eb,parser)
+ client.start()
+ #eb.post(event(EVENTID_CLIENT_START,""))
+ """
+ print("Joining")
+ while(client.isAlive()):
+ time.sleep(1)
+ client.join()
+ """
+ client.join()
+ print ("Exiting Main Thread")
+ eb.post(event(EVENTID_QUEUE_STOP,""))
+ teq.join()
+ eb.shutdown()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/Message_parser.py b/Message_parser.py
new file mode 100644
index 0000000..1adda5d
--- /dev/null
+++ b/Message_parser.py
@@ -0,0 +1,85 @@
+from FbClient import *
+from geeteventbus.event import event
+from datetime import datetime, timedelta
+
+TIME_KEYES = ['d','h','m','s']
+class Message_parser():
+ def __init__(self,event_bus):
+ self.eb = event_bus
+
+ def parse(self,message_data):
+ text = message_data.get_text()
+ print(text)
+ # echo if message start with @echo
+ if text.startswith('!echo'):
+ print("Echoing")
+ message_data.set_text(text[6::])
+ Fb_client.post_message_event(self.eb,message_data)
+ return
+
+ # send dad joke if message start with @dad
+ if '!dad' in text:
+ print("Dading")
+ joke = requests.get('https://icanhazdadjoke.com/',
+ headers={'Accept': 'text/plain'})
+ joke.encoding = 'utf-8'
+ message_data.set_text(joke.text)
+ Fb_client.post_message_event(self.eb,message_data)
+ return
+
+ if '!logout' in text:
+ print("Posting Stop event")
+ self.eb.post(event(EVENTID_CLIENT_STOP,""))
+
+ if text.startswith('!rm'):
+ self.parseRemindMe(message_data)
+
+ if text.startswith('!help'):
+ self.parseHelp(message_data)
+
+ def get_message_time(self,i,c):
+ if c == 's':
+ return timedelta(seconds = int(i))
+ elif c == 'm':
+ return timedelta(minutes = int(i))
+ elif c == 'h':
+ return timedelta(hours = int(i))
+ elif c == 'd':
+ return timedelta(days = int(i))
+
+ def parseRemindMe(self,message_data):
+ text = message_data.get_text().split()
+
+ text_time = text[1]
+ time_delta = timedelta(seconds=0)
+ number = ""
+ for c in text_time:
+ if(c.isdigit()):
+ number += c
+ if(c in TIME_KEYES):
+ time_delta += self.get_message_time(number,c)
+ number = ""
+
+ text_message = "REMINDER"
+ if(len(text) > 2):
+ text_message += ": " + ' '.join(text[2:])
+ message_data.set_text(text_message)
+ send_message_event = event(EVENTID_CLIENT_SEND,message_data)
+ Time_event_queuer.post_time_event(self.eb,send_message_event,time_delta)
+
+ if(time_delta>timedelta(seconds = 15)):
+ time_at = datetime.now() + time_delta
+ reciept_text = "Reminder set at {} in {}".format(
+ (':').join(str(time_at).split(':')[:-1]),
+ str(time_delta).split('.')[0])
+ reciept_data = Message_data(reciept_text,message_data.get_id(),
+ message_data.get_type())
+ Fb_client.post_message_event(self.eb,reciept_data)
+
+ def parseHelp(self,message_data):
+ message_data.set_text("Help is on the way")
+ Fb_client.post_message_event(self.eb,message_data)
+
+
+
+
diff --git a/timeEventQueuer.py b/timeEventQueuer.py
index aa08df6..d736f1c 100644
--- a/timeEventQueuer.py
+++ b/timeEventQueuer.py
@@ -24,8 +24,9 @@ Edit execute_event to fit execution process of event
The Queuer must be added as a subscriber to the event bus on the desired topics
"""
class Time_event_queuer(threading.Thread,subscriber):
- def __init__(self,cv):
+ def __init__(self,eb,cv):
super().__init__()
+ self.eb = eb #Event Bus
self.cv = cv #Conditional Variable, used for notifying on events
self.heap = []
self.execute_flag = False
@@ -34,6 +35,8 @@ class Time_event_queuer(threading.Thread,subscriber):
#Executes the event on top of heap. Must be popped
def execute_event(self):
e = heapq.heappop(self.heap)
+ if(isinstance(e[1],event)):
+ self.eb.post(e[1])
print("{} - Executing {}".format(datetime.now(),e[1]))
#Listens on the bus
@@ -48,6 +51,12 @@ class Time_event_queuer(threading.Thread,subscriber):
elif new_event.get_topic() == EVENTID_QUEUE_STOP:
self.stop_queue_loop()
+ def run(self):
+ self.eb.register_consumer(self,EVENTID_TIME)
+ self.eb.register_consumer(self,EVENTID_QUEUE_START)
+ self.eb.register_consumer(self,EVENTID_QUEUE_STOP)
+ self.start_queue_loop()
+
#Starts the queue loop on EVENTID_QUEUE_START event
def start_queue_loop(self):
self.execute_flag = True
@@ -159,11 +168,12 @@ def main():
cv = threading.Condition()
# Create new threads
- teq = Time_event_queuer(cv)
+ teq = Time_event_queuer(eb,cv)
+ teq.start()
th.add_thread(teq)
# Start new Threads
- th.start_threads()
+ #th.start_threads()
# Post Information
teq.post_time_event(eb,"post1",timedelta(seconds=3))
@@ -172,9 +182,16 @@ def main():
time.sleep(2)
teq.post_time_event(eb,"post3",timedelta(seconds=6))
time.sleep(1)
+ teq.post_time_event(eb,"post4",timedelta(seconds=1))
+ time.sleep(1)
+ teq.post_time_event(eb,"post5",timedelta(seconds=2))
+ time.sleep(1)
# Stopping threads
- th.join_threads()
+ #th.join_threads()
+ eb.post(event(EVENTID_QUEUE_STOP,""))
+ teq.join()
+
print ("Exiting Main Thread")