This commit is contained in:
0xDEAD10CC 2017-07-25 18:35:28 -07:00
parent 586014ffe4
commit 68912fed15
5 changed files with 95 additions and 126 deletions

View file

@ -5,8 +5,10 @@ from gevent import Greenlet
class CoindroidAPITask(Greenlet): class CoindroidAPITask(Greenlet):
def __init__(self, **kwargs): def __init__(self, **kwargs):
Greenlet.__init__(self) Greenlet.__init__(self)
self.eventsEvent = kwargs.get("eventsEvent") self.eventTaskEvent = kwargs.get("eventTaskEvent")
self.eventsEvent.clear() self.droidControllerQueue = kwargs.get("droidControllerQueue")
if self.eventTaskEvent:
self.eventTaskEvent.clear()
self.logger = logging.getLogger(self.__class__.__name__) self.logger = logging.getLogger(self.__class__.__name__)
self.apiSession = requests.Session() self.apiSession = requests.Session()
self.lastTransaction = None self.lastTransaction = None

View file

@ -10,8 +10,8 @@ class CurrencyTask(CoindroidAPITask):
self.logger = logging.getLogger(self.__class__.__name__) self.logger = logging.getLogger(self.__class__.__name__)
self.currencyComparisonTuple = namedtuple("currencyComparison", self.currencyComparisonTuple = namedtuple("currencyComparison",
["added", "removed", "modified", "same"]) ["added", "removed", "modified", "same"])
self.eventTaskEvent.set()
self.updateCurrency() self.updateCurrency()
self.eventsEvent.set()
def dictCompare(self, d1, d2): def dictCompare(self, d1, d2):
d1_keys = set(d1.keys()) d1_keys = set(d1.keys())
@ -88,9 +88,11 @@ class CurrencyTask(CoindroidAPITask):
while True: while True:
update = self.compareCurrency() update = self.compareCurrency()
if update: if update:
self.eventsEvent.set() self.eventTaskEvent.set()
self.logger.debug("Sleeping...")
sleep(self.pause) sleep(self.pause)
else: else:
self.logger.debug("Sleeping...")
sleep(self.pause) sleep(self.pause)
self.logger.debug("Updating currency...") self.logger.debug("Updating currency...")
self.updateCurrency() self.updateCurrency()

View file

@ -1,92 +1,85 @@
import logging import logging
from CoindroidAPI import CoindroidAPITask from CoindroidAPI import CoindroidAPITask
from gevent import sleep from gevent import sleep
from collections import namedtuple
from twilio.rest import Client as TwilioClient
# todo Flesh out getting events to Droids and having them act accordingly
class DroidTask(CoindroidAPITask): class DroidControllerTask(CoindroidAPITask):
def __init__(self, **kwargs): def __init__(self, **kwargs):
""" super(DroidControllerTask, self).__init__(**kwargs)
This is a DroidTask self.logger = logging.getLogger(self.__class__.__name__)
It performs actions on events received from:w self.droidTuple = namedtuple("droidTuple",
["block_height", "action_id", "action_type", "player_id", "player_username",
"droid_id", "droid_name", "targetID", "targetName", "healthChangedFrom",
"healthChangedTo", "netDamageTaken", "experienceEarned", "grossDamagePerformed",
"experienceChangedFrom", "experienceChangedTo",
])
twilioAccount = "ACdfcd2b529db83954e8a0041796072960"
twilioToken = "ab9b98a0b3da8a728d14774192773af2"
self.twilioClient = TwilioClient(twilioAccount, twilioToken)
:param \**kwargs: def getDroidStats(self, event):
See below return {
:Keyword Arguments: "block_height" : event.get("block_height"),
* *apiUrl* (``str``) -- "action_id" : event.get("action_id"),
Coindroids API URL. "action_type" : event.get("action_type"),
Default is ``https://api.coindroids.com/`` "player_id" : event.get("player_id"),
* *pause* (``int``) -- "player_username" : event.get("player_username"),
Time to wait between requests "droid_id" : event.get("droid_id"),
""" "droid_name" : event.get("droid_name"),
super(EventTask, self).__init__(**kwargs) "targetID" : event.get("target").get("id"),
self.logger = logging.getLogger(__name__) "targetName" : event.get("target").get("name"),
self.updateEvents() "healthChangedFrom" : next(
(x.get("value_from") for x in event.get("outcomes") if x.get("outcome_type") == "Health changed"),
None),
"healthChangedTo" : next(
(x.get("value_to") for x in event.get("outcomes") if x.get("outcome_type") == "Health changed"),
None),
"netDamageTaken" : next(
(x.get("value_to") for x in event.get("outcomes") if x.get("outcome_type") == "Net damage taken"),
None),
"experienceEarned" : next(
(x.get("value_to") for x in event.get("outcomes") if x.get("outcome_type") == "Experience earned"),
None),
"grossDamagePerformed" : next((x.get("value_to") for x in event.get("outcomes") if
x.get("outcome_type") == "Gross damage performed"), None),
"experienceChangedFrom": next((x.get("value_from") for x in event.get("outcomes") if
x.get("outcome_type") == "Experience changed"), None),
"experienceChangedTo" : next(
(x.get("value_to") for x in event.get("outcomes") if x.get("outcome_type") == "Experience changed"),
None)
}
def updateEvents(self): def sendSMS(self, from_="+14159037708", **kwargs):
while True:
try: try:
request = self.apiSession.get(self.apiUrl + "event", self.twilioClient.messages.create(from_=from_, **kwargs)
params={"order" : "block_height.desc",
"currency_id": "eq.2"})
# "involved_droids": ""}).json()
except: except:
self.logger.exception("Unable to get events!") self.logger.exception("Unable to send SMS!!")
self.logger.error("Waiting for update...") pass
sleep(self.pause)
continue
self.currentTransaction = request.json()
self.logger.info("Retrieved events from Coindroids...")
self.logger.debug("{} events found...".format(len(self.currentTransaction)))
if not self.lastTransaction:
self.logger.info("No previous events available... Waiting for update...")
self.lastTransaction = self.currentTransaction.copy()
self.currentTransaction = None
sleep(self.pause)
continue
break
def compareEvents(self):
"""
Compares old events to new events
:return: list of events
"""
setLastEventsIDs = set([x.get("action_id") for x in self.lastTransaction])
setEventsIDs = set([x.get("action_id") for x in self.currentTransaction])
setRemovedEvents = setLastEventsIDs - setEventsIDs
setAddedEvents = setEventsIDs - setLastEventsIDs
ret = []
if setRemovedEvents:
self.logger.debug("Events removed from this update: {}".format(setRemovedEvents))
if setAddedEvents:
self.logger.debug("Added events:")
for event_id in setAddedEvents:
for event in self.currentTransaction:
if event:
if event["action_id"] == event_id:
ret.append(event)
self.logger.debug("At block_height {}, action_id {} - {}({}):{}({}) did {} on {}".format(
*(event.get(i) for i in ("block_height",
"action_id", "player_username", "player_id",
"droid_name", "droidID", "action_type",
"target"))))
else:
self.logger.error("Found empty event!")
return ret
def _run(self): def _run(self):
self.logger.info("Running {}".format(self.__class__.__name__)) self.logger.info("Running {}".format(self.__class__.__name__))
while True: while True:
if self.eventsEvent.ready(): if not self.droidControllerQueue.empty():
self.logger.debug("{} woken up...".format(self.__class__.__name__)) self.logger.debug("{} woken up...".format(self.__class__.__name__))
for _ in range(5): events = self.droidControllerQueue.get()
self.logger.debug("Trying to get updated events ({}/5)".format(_)) for event in events:
update = self.compareEvents() stats = self.getDroidStats(event)
if update: message = "At block_height {block_height}, action_id {action_id} - " \
self.logger.debug("TODO: Send events to queue for worker threads") "{player_username}({player_id}):{droid_name}({droid_id}) did {action_type} on " \
break "{targetName}({targetID}). Health changed from {healthChangedFrom} to " \
"{healthChangedTo}.".format(**stats)
self.logger.info(message)
if stats["targetID"] or stats["targetName"]:
if (stats["targetID"] == 160) or (stats["targetName"] == "bob"):
self.logger.debug("bob's got an action!!! sending sms!!")
self.sendSMS(to="+14088963912", body=message)
if (stats["targetID"] == 165) or (stats["targetName"] == "Mabuhay"):
self.logger.debug("bob's got an action!!! sending sms!!")
self.sendSMS(to="+14088963912", body=message)
else: else:
self.logger.debug("No events detected") self.logger.warning("Event has no target!")
sleep(5) else:
self.logger.debug("Queue is empty... No action to take...")
sleep(self.pause) sleep(self.pause)
continue

View file

@ -1,16 +1,12 @@
import logging import logging
from CoindroidAPI import CoindroidAPITask from CoindroidAPI import CoindroidAPITask
from gevent import sleep from gevent import sleep
from twilio.rest import Client as TwilioClient
class EventTask(CoindroidAPITask): class EventTask(CoindroidAPITask):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super(EventTask, self).__init__(**kwargs) super(EventTask, self).__init__(**kwargs)
self.logger = logging.getLogger(self.__class__.__name__) self.logger = logging.getLogger(self.__class__.__name__)
twilioAccount = "ACdfcd2b529db83954e8a0041796072960"
twilioToken = "ab9b98a0b3da8a728d14774192773af2"
self.twilioClient = TwilioClient(twilioAccount, twilioToken)
self.updateEvents() self.updateEvents()
def updateEvents(self, updateLast=True): def updateEvents(self, updateLast=True):
@ -47,45 +43,12 @@ class EventTask(CoindroidAPITask):
setAddedEvents = setEventsIDs - setLastEventsIDs setAddedEvents = setEventsIDs - setLastEventsIDs
ret = [] ret = []
if setAddedEvents: if setAddedEvents:
self.logger.debug("Added events:") self.logger.debug("Events have been added...")
for event_id in setAddedEvents: for event_id in setAddedEvents:
for event in self.currentTransaction: for event in self.currentTransaction:
if event: if event:
if event["action_id"] == event_id: if event["action_id"] == event_id:
ret.append(event) ret.append(event)
keys = ["block_height", "action_id", "player_username", "player_id", "droid_name",
"droid_id", "action_type"]
message_args = [event.get(i) for i in keys]
if event.get("target"):
message_args.extend([event["target"].get("name"), event["target"].get("id")])
if (event["target"].get("name") == "bob") or (event["target"].get("id") == 160):
self.logger.debug("TEMP - bob's got an action!!! sending sms!!")
try:
self.twilioClient.messages.create(
to="+14088963912",
from_="+14159037708",
body="At block_height {}, action_id {} - {}({}):{}({}) did {} on {}({})".format(
*message_args)
)
except:
self.logger.exception("Unable to send SMS!!")
if (event["target"].get("name") == "Mabuhay") or (event["target"].get("id") == 165):
self.logger.debug("TEMP - Mabuhay's got an action!!! sending sms!!")
try:
self.twilioClient.messages.create(
to="+14086342295",
from_="+14159037708",
body="At block_height {}, action_id {} - {}({}):{}({}) did {} on {}({})".format(
*message_args)
)
except:
self.logger.exception("Unable to send SMS!!")
else:
self.logger.warning("Event has no target!")
message_args.extend([None, None])
self.logger.debug(
"At block_height {}, action_id {} - {}({}):{}({}) did {} on {}({})".format(
*message_args))
else: else:
self.logger.error("Found empty event!") self.logger.error("Found empty event!")
return ret return ret
@ -93,22 +56,26 @@ class EventTask(CoindroidAPITask):
def _run(self): def _run(self):
self.logger.info("Running {}".format(self.__class__.__name__)) self.logger.info("Running {}".format(self.__class__.__name__))
while True: while True:
if self.eventsEvent.ready(): if self.eventTaskEvent.ready():
self.logger.debug("{} woken up...".format(self.__class__.__name__)) self.logger.debug("{} woken up...".format(self.__class__.__name__))
for _ in range(5): for _ in range(5):
self.logger.debug("Trying to get updated events ({}/5)".format(_)) self.logger.debug("Trying to get updated events ({}/5)".format(_))
self.updateEvents(updateLast=False) self.updateEvents(updateLast=False)
update = self.compareEvents() update = self.compareEvents()
if update: if update:
self.eventsEvent.clear() self.eventTaskEvent.clear()
self.logger.debug("TODO: Send events to queue for worker threads")
self.updateEvents() self.updateEvents()
self.logger.debug("Sending events to queue for DroidTasks")
self.droidControllerQueue.put(update)
break break
else: else:
self.logger.debug("No events detected") self.logger.debug("No events detected")
self.logger.debug("Sleeping...")
sleep(5) sleep(5)
self.updateEvents(updateLast=False) self.updateEvents(updateLast=False)
else: else:
self.logger.error("No events detected after 5 rounds!") self.logger.error("No events detected after 5 rounds!")
self.eventTaskEvent.clear()
self.logger.debug("Sleeping...")
sleep(self.pause) sleep(self.pause)
continue continue

View file

@ -4,8 +4,10 @@
import gevent, logging import gevent, logging
from gevent.event import Event from gevent.event import Event
from gevent.queue import Queue
from Currency import CurrencyTask from Currency import CurrencyTask
from Event import EventTask from Event import EventTask
from Droid import DroidControllerTask
formatter = logging.Formatter('%(asctime)s - %(name)s %(funcName)s():%(lineno)d - %(levelname)s - %(message)s') formatter = logging.Formatter('%(asctime)s - %(name)s %(funcName)s():%(lineno)d - %(levelname)s - %(message)s')
logger = logging.getLogger() logger = logging.getLogger()
@ -20,11 +22,14 @@ def main():
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
while True: while True:
logger.info("Starting main loop...") logger.info("Starting main loop...")
eventsEvent = Event() eventTaskEvent = Event()
currencyTask = CurrencyTask.spawn(eventsEvent=eventsEvent) droidControllerQueue = Queue()
eventTask = EventTask.spawn(eventsEvent=eventsEvent) currencyTask = CurrencyTask.spawn(eventTaskEvent=eventTaskEvent)
gevent.joinall([currencyTask, eventsEvent]) eventTask = EventTask.spawn(eventTaskEvent=eventTaskEvent, droidControllerQueue=droidControllerQueue)
droidController = DroidControllerTask.spawn(droidControllerQueue=droidControllerQueue)
gevent.joinall([currencyTask, eventTask, droidController])
logger.error("Main loop ended... This shouldn't happen?") logger.error("Main loop ended... This shouldn't happen?")
if __name__ == "__main__": if __name__ == "__main__":
main() main()