From 8d08dc955158b3c9a4166df831d738c24e6f9dd6 Mon Sep 17 00:00:00 2001 From: Kendrick Chan Date: Tue, 24 Jul 2018 01:31:29 +0800 Subject: [PATCH 1/3] Add python utilities for redis / mqtt functionality #159 --- utils/mqtt_sender/mqtt_sender.py | 64 +++++++++++ .../rider_location_cache.py | 106 ++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 utils/mqtt_sender/mqtt_sender.py create mode 100644 utils/rider_location_cache/rider_location_cache.py diff --git a/utils/mqtt_sender/mqtt_sender.py b/utils/mqtt_sender/mqtt_sender.py new file mode 100644 index 00000000..e314b337 --- /dev/null +++ b/utils/mqtt_sender/mqtt_sender.py @@ -0,0 +1,64 @@ +import paho.mqtt.client as mqtt +import ssl +from threading import Thread +import redis +import time +import signal +import sys +import os + + + +def sigint_handler(signal, frame): + print 'Interrupted' + sys.exit(0) + os._exit(0) + + +def on_connect(client, userdata, flags, rc): + print("Connected with result code "+str(rc)) + client.subscribe("$SYS/#") + + + +def on_publish(client, userdata, mid): + pass + + + +def getRedis(i): + r = redis.StrictRedis(host='localhost', port=6379, db=0) + while 1: + time.sleep(0) + data = r.brpop("events", 10) + if data: + info = data[1].split('|') + print "Channel: " + info[0] + " message: " + info[1] + client.publish(info[0], info[1]) + + + +def sigint_handler(signal, frame): + print 'Interrupted' + sys.exit(0) + + + +client = mqtt.Client() +client.on_connect = on_connect +client.on_publish = on_publish + + + +client.tls_set( + "/etc/letsencrypt/live/resqaws.jankstudio.com/fullchain.pem", cert_reqs=ssl.CERT_NONE, + tls_version=ssl.PROTOCOL_TLSv1) + +client.connect("resqaws.jankstudio.com", 8883, 60) +t = Thread(target=getRedis, args=(1,)) + +t.start() + +signal.signal(signal.SIGINT, sigint_handler) +client.loop_forever() + diff --git a/utils/rider_location_cache/rider_location_cache.py b/utils/rider_location_cache/rider_location_cache.py new file mode 100644 index 00000000..441938e4 --- /dev/null +++ b/utils/rider_location_cache/rider_location_cache.py @@ -0,0 +1,106 @@ +import paho.mqtt.client as mqtt +import ssl +from threading import Thread +import redis +import time +import signal +import sys +import os +import mysql.connector +import json + +def mysql_connect(user, password, host, database): + conn = mysql.connector.connect(user=user, + password=password, + host=host, + database=database) + return conn + +def init_subscriptions(client, conn): + # given mysql connection, get all rider sessions + query = ("select id from rider_session") + cursor = conn.cursor() + cursor.execute(query) + for (id) in cursor: + print "subscribing to rider session %s" % id + client.subscribe('motorider_%s' % id) + cursor.close() + +def on_connect(client, userdata, flags, rc): + conn = mysql_connect('resq', 'Motolite456', '127.0.0.1', 'resq') + init_subscriptions(client, conn) + print("Connected with result code "+str(rc)) + client.subscribe("$SYS/#") + +def on_publish(client, userdata, mid): + pass + +def on_message(client, userdata, message): + print("message topic=",message.topic[0:10]) + + if message.topic[0:10] != 'motorider_': + return + #print repr(message) + + # check if json decodable + res = json.loads(message.payload) + + # get rider session id + sess_id = message.topic[10:] + + # check if it has event + if 'event' not in res: + return + + # check if event is driver_location + if res['event'] != 'driver_location': + return + + # update our redis key + key = 'location_%s' % sess_id + print "setting %s" % key + redis_conn.setex(key, 1600, message.payload) + + + +def getRedis(i): + r = redis.StrictRedis(host='localhost', port=6379, db=0) + while 1: + time.sleep(0) + data = r.brpop("events", 10) + if data: + info = data[1].split('|') + print "Channel: " + info[0] + " message: " + info[1] + client.publish(info[0], info[1]) + + +def sigint_handler(signal, frame): + print 'Interrupted' + sys.exit(0) + + + +client = mqtt.Client() +client.on_connect = on_connect +# client.on_publish = on_publish +client.on_message = on_message + +redis_conn = redis.StrictRedis(host='localhost', port=6379, db=0) + + +#client.tls_set( +# "/etc/letsencrypt/live/resqaws.jankstudio.com/fullchain.pem", cert_reqs=ssl.CERT_NONE, +# tls_version=ssl.PROTOCOL_TLSv1) +client.tls_set( + "/root/aws_ssl_keys/fullchain.pem", cert_reqs=ssl.CERT_NONE, + tls_version=ssl.PROTOCOL_TLSv1) +client.connect("resqaws.jankstudio.com", 8883, 60) + + +#t = Thread(target=getRedis, args=(1,)) + +#t.start() + +#signal.signal(signal.SIGINT, sigint_handler) +client.loop_forever() + From 098df6994907db4f0ccd91b5ce5deb9b2b2468de Mon Sep 17 00:00:00 2001 From: Kendrick Chan Date: Wed, 25 Jul 2018 23:03:32 +0800 Subject: [PATCH 2/3] Refactor cancel job order process #159 --- src/Controller/APIController.php | 4 ++++ src/Controller/JobOrderController.php | 4 ++++ src/Controller/RAPIController.php | 6 ++++-- src/Entity/JobOrder.php | 13 +++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Controller/APIController.php b/src/Controller/APIController.php index 67ee1db7..43c2bab5 100644 --- a/src/Controller/APIController.php +++ b/src/Controller/APIController.php @@ -1303,9 +1303,13 @@ class APIController extends Controller // TODO: check job order status, if it's cancellable $cancel_reason = $req->request->get('reason'); + + $jo->cancel($cancel_reason); + /* $jo->setStatus(JOStatus::CANCELLED) ->setDateCancel(new DateTime()) ->setCancelReason($cancel_reason); + */ $em->flush(); diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index 35ea2eab..8787432e 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -2133,6 +2133,7 @@ class JobOrderController extends BaseController if (empty($obj)) throw $this->createNotFoundException('The item does not exist'); + /* // cancel job order $obj->setStatus(JOStatus::CANCELLED) ->setDateCancel(new DateTime()) @@ -2142,6 +2143,9 @@ class JobOrderController extends BaseController $rider = $obj->getRider(); if ($rider != null) $rider->setAvailable(); + */ + + $obj->cancel($cancel_request); // the event $event = new JOEvent(); diff --git a/src/Controller/RAPIController.php b/src/Controller/RAPIController.php index ce1caf0b..229d5895 100644 --- a/src/Controller/RAPIController.php +++ b/src/Controller/RAPIController.php @@ -481,8 +481,7 @@ class RAPIController extends Controller if ($res->isError()) return $res->getReturnResponse(); - // TODO: refactor this into a jo handler class, so we don't have to repeat for control center - + /* // set jo status to cancelled // TODO: set reason $jo->setStatus(JOStatus::CANCELLED) @@ -490,6 +489,9 @@ class RAPIController extends Controller // make rider available $this->session->getRider()->setAvailable(true); + */ + + $jo->cancel("rider cancelled"); $em->flush(); diff --git a/src/Entity/JobOrder.php b/src/Entity/JobOrder.php index 1be9175b..02d8bdf6 100644 --- a/src/Entity/JobOrder.php +++ b/src/Entity/JobOrder.php @@ -653,4 +653,17 @@ class JobOrder { return $this->trade_in_type; } + + public function cancel($reason) + { + // set status to cancelled + $this->setStatus(JOStatus::CANCELLED) + ->setDateCancel(new DateTime()) + ->setCancelReason($reason); + + // set rider available + $rider = $obj->getRider(); + if ($rider != null) + $rider->setAvailable(); + } } From 5ed3a2e4470a6c010f1b87631742f8cbd8dc7f3f Mon Sep 17 00:00:00 2001 From: Kendrick Chan Date: Thu, 26 Jul 2018 02:58:19 +0800 Subject: [PATCH 3/3] Refactor fulfill jo to belong in entity #159 --- src/Controller/JobOrderController.php | 8 +++++--- src/Controller/RAPIController.php | 3 +++ src/Entity/JobOrder.php | 20 ++++++++++++++++---- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index 8787432e..f599368c 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -1326,12 +1326,12 @@ class JobOrderController extends BaseController ->setServiceType($req->request->get('service_type')) ->setWarrantyClass($req->request->get('warranty_class')) ->setSource($req->request->get('source')) - ->setStatus(JOStatus::FULFILLED) + // ->setStatus(JOStatus::FULFILLED) ->setDeliveryInstructions($req->request->get('delivery_instructions')) ->setTier1Notes($req->request->get('tier1_notes')) ->setTier2Notes($req->request->get('tier2_notes')) - ->setDeliveryAddress($req->request->get('delivery_address')) - ->setDateFulfill(new DateTime()); + ->setDeliveryAddress($req->request->get('delivery_address')); + // ->setDateFulfill(new DateTime()); // validate $errors = $validator->validate($obj); @@ -1342,6 +1342,8 @@ class JobOrderController extends BaseController } } + $obj->fulfill(); + // check if any errors were found if (!empty($error_array)) { // return validation failure response diff --git a/src/Controller/RAPIController.php b/src/Controller/RAPIController.php index 229d5895..0fa9f31d 100644 --- a/src/Controller/RAPIController.php +++ b/src/Controller/RAPIController.php @@ -554,8 +554,11 @@ class RAPIController extends Controller // set invoice to paid $jo->getInvoice()->setStatus(InvoiceStatus::PAID); + /* // set jo status to fulfilled $jo->setStatus(JOStatus::FULFILLED); + */ + $jo->fulfill(); $em->flush(); diff --git a/src/Entity/JobOrder.php b/src/Entity/JobOrder.php index 02d8bdf6..122df4df 100644 --- a/src/Entity/JobOrder.php +++ b/src/Entity/JobOrder.php @@ -654,6 +654,13 @@ class JobOrder return $this->trade_in_type; } + protected function makeRiderAvailable() + { + $rider = $this->getRider(); + if ($rider != null) + $rider->setAvailable(); + } + public function cancel($reason) { // set status to cancelled @@ -661,9 +668,14 @@ class JobOrder ->setDateCancel(new DateTime()) ->setCancelReason($reason); - // set rider available - $rider = $obj->getRider(); - if ($rider != null) - $rider->setAvailable(); + $this->makeRiderAvailable(); + } + + public function fulfill() + { + $this->setStatus(JOStatus::FULFILLED) + ->setDateFulfill(new DateTime()); + + $this->makeRiderAvailable(); } }