From e03ce89a34434dcfe9f606bfab7e79f3a7ff4c11 Mon Sep 17 00:00:00 2001 From: gianricod Date: Fri, 23 Mar 2018 08:10:03 +0100 Subject: [PATCH] PushBullet IO implementation (#139) * pushbullet feature * Pushbullet h/cpp files * added pushbullet.cpp to CMakeLists.txt * pushbulletio added support for sending detection image * added code to save image to iopushbullet * Removing path from PB url in io.xml --- config/io.xml | 5 + include/kerberos/machinery/io/IoPushbullet.h | 56 +++++++ src/kerberos/CMakeLists.txt | 1 + src/kerberos/machinery/io/IoPushbullet.cpp | 159 +++++++++++++++++++ 4 files changed, 221 insertions(+) create mode 100755 include/kerberos/machinery/io/IoPushbullet.h create mode 100755 src/kerberos/machinery/io/IoPushbullet.cpp diff --git a/config/io.xml b/config/io.xml index 3200ae7..38efdd6 100755 --- a/config/io.xml +++ b/config/io.xml @@ -54,5 +54,10 @@ 0 + + https://api.pushbullet.com + o.mC5LPVCvPCphtSsEgWZQpFM86w9ciWQ3 + 10 + diff --git a/include/kerberos/machinery/io/IoPushbullet.h b/include/kerberos/machinery/io/IoPushbullet.h new file mode 100755 index 0000000..9ba2624 --- /dev/null +++ b/include/kerberos/machinery/io/IoPushbullet.h @@ -0,0 +1,56 @@ +// +// Class: IoPushbullet +// Description: A pushbullet class . +// Created: 13/11/2017 +// Author: Gianrico D'Angelis +// Mail: gianrico.dangelis@gmail.com +// +// +///////////////////////////////////////////////////// + +#ifndef __IoPushbullet_H_INCLUDED__ // if IoPushbullet.h hasn't been included yet... +#define __IoPushbullet_H_INCLUDED__ // #define this so the compiler knows it has been included + +#include "machinery/io/Io.h" +#include "document.h" +#include "writer.h" +#include "restclient-cpp/connection.h" +#include "restclient-cpp/restclient.h" +#include "Throttler.h" + +namespace kerberos +{ + char PushbulletName[] = "Pushbullet"; + class IoPushbullet : public IoCreator + { + private: + std::string m_url; + std::string m_instanceName; + std::string m_pbToken; + RestClient::Connection * pushbulletConnection; + Throttler throttle; + + public: + IoPushbullet(){}; + virtual ~IoPushbullet() + { + delete pushbulletConnection; + }; + void setup(const StringMap & settings); + void fire(JSON & data){}; + void disableCapture(){}; + + void setUrl(std::string url){m_url=url;}; + const char * getUrl(){return m_url.c_str();}; + void setToken(std::string token){m_pbToken=token;}; + const char * getToken(){return m_pbToken.c_str();}; + void setInstanceName(std::string instanceName){m_instanceName=instanceName;}; + std::string getInstanceName(){return m_instanceName;}; + + bool save(Image & image){ return true; }; + bool save(Image & image, JSON & data); + + bool pbUploadImage(std::string tmpFile, std::string upUrl); + }; +} +#endif diff --git a/src/kerberos/CMakeLists.txt b/src/kerberos/CMakeLists.txt index 90152bd..f8b4e39 100755 --- a/src/kerberos/CMakeLists.txt +++ b/src/kerberos/CMakeLists.txt @@ -48,6 +48,7 @@ machinery/io/IoWebhook.cpp machinery/io/IoScript.cpp machinery/io/IoMQTT.cpp + machinery/io/IoPushbullet.cpp ) set(KERBEROS_DEPENDENCIES ${KERBEROS_DEPENDENCIES} opencv restclient mosquitto) diff --git a/src/kerberos/machinery/io/IoPushbullet.cpp b/src/kerberos/machinery/io/IoPushbullet.cpp new file mode 100755 index 0000000..7bca509 --- /dev/null +++ b/src/kerberos/machinery/io/IoPushbullet.cpp @@ -0,0 +1,159 @@ +#include "machinery/io/IoPushbullet.h" + +namespace kerberos +{ + void IoPushbullet::setup(const StringMap & settings) + { + Io::setup(settings); + + // -------------------------- + // Get name from instance + + std::string instanceName = settings.at("name"); + setInstanceName(instanceName); + + // ------- + // Get url + + setUrl(settings.at("ios.Pushbullet.url").c_str()); + + //------ + //set pushbullet token + + setToken((settings.at("ios.Pushbullet.token").c_str())); + + // ------------- + // Set throttler + + throttle.setRate(std::stoi(settings.at("ios.Pushbullet.throttler"))); + + // ---------------------------- + // Initialize connection object + + pushbulletConnection = new RestClient::Connection(m_url); + pushbulletConnection->SetTimeout(5); // set connection timeout to 5s + RestClient::HeaderFields headers; + headers["Content-Type"] = "application/json"; + pushbulletConnection->SetHeaders(headers); + pushbulletConnection->AppendHeader("Access-Token",m_pbToken); + } + + bool IoPushbullet::save(Image & image, JSON & data) + { + if(throttle.canExecute()) + { + // --------------------------------------- + // Attach additional fields to JSON object + + JSON dataCopy,pbResp; + JSON::AllocatorType& allocator = dataCopy.GetAllocator(); + dataCopy.CopyFrom(data, allocator); + + JSONValue instanceName; + instanceName.SetString(getInstanceName().c_str(), allocator); + dataCopy.AddMember("instanceName", instanceName, allocator); + + // ----------------------------- + // Convert JSON object to string + + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + dataCopy.Accept(writer); + + + std::string upUrl ; + std::string fileUrl ; + RestClient::Response r; + + /* + * Step 1 : save file to tmp and provide path in a string var + */ + std::string tmpFile = "/tmp/detection.jpg"; + if(image.save(tmpFile)) + { + + /* + * Step 2 : create push for file + */ + + r = pushbulletConnection->post("/v2/upload-request", "{\"file_name\":\"detection.jpg\",\"file_type\":\"image/jpeg\"}"); + + if(r.code == 200){ + pbResp.Parse(r.body.c_str()); + upUrl = pbResp["upload_url"].GetString(); + fileUrl = pbResp["file_url"].GetString(); + BINFO << "IoPushbullet: response to upload request " + r.body; + + /* + * Step 3 : upload file to pushbullet + */ + if (pbUploadImage(tmpFile, upUrl)) { + + /* + * Step 4 : create text push for detection + */ + r = pushbulletConnection->post("/v2/pushes", "{\"type\":\"file\",\"file_url\":\""+ fileUrl +"\"}"); + if(r.code==200) + BINFO << "IoPushbullet: response to push file request " + r.body ; + } + + } + } + // ------------------- + // Send a message to pushbullet + + r = pushbulletConnection->post("/v2/pushes", "{\"body\":\"Motion detected\",\"title\":\"Kios\",\"type\":\"note\"}"); + + if(r.code == 200) + { + BINFO << "IoPushbullet: response to post to pushbullet " + r.body; + return true; + } + + return false; + } + return true; + } + + bool IoPushbullet::pbUploadImage(std::string tmpFile, std::string upUrl) { + + CURL *curl; + CURLcode res; + + struct curl_httppost *formpost = NULL; + struct curl_httppost *lastptr = NULL; + + curl_global_init(CURL_GLOBAL_ALL); + curl_formadd(&formpost, &lastptr, + CURLFORM_COPYNAME, "file", + CURLFORM_FILENAME, "detection.jpg", + CURLFORM_FILE, tmpFile.c_str(), + CURLFORM_CONTENTTYPE, "image/jpeg", + CURLFORM_END); + + curl = curl_easy_init(); + + if (curl) { + + curl_easy_setopt(curl, CURLOPT_URL, (upUrl).c_str()); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); + + res = curl_easy_perform(curl); + + curl_easy_cleanup(curl); + curl_formfree(formpost); + + if (res != CURLE_OK){ + fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res)); + return false; + } + } + else + return false; + + return true; + } + +}