From c95380f9b30137a01b776f0390438908f47cc848 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Fri, 28 Feb 2014 11:34:57 +0000 Subject: Dropbox: - fixed folders uploading - added commands (/content, /share, /delete) to Dropbox bot - fixed message after file sending to Dropbox bot git-svn-id: http://svn.miranda-ng.org/main/trunk@8325 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dropbox/Dropbox_10.vcxproj | 1 + plugins/Dropbox/Dropbox_10.vcxproj.filters | 30 ++++--- plugins/Dropbox/Dropbox_12.vcxproj | 5 +- plugins/Dropbox/Dropbox_12.vcxproj.filters | 6 ++ plugins/Dropbox/src/dropbox.cpp | 9 +- plugins/Dropbox/src/dropbox.h | 16 ++++ plugins/Dropbox/src/dropbox_commands.cpp | 130 +++++++++++++++++++++++++++++ plugins/Dropbox/src/dropbox_services.cpp | 59 +++++++++++-- plugins/Dropbox/src/dropbox_transfers.cpp | 48 +++++++---- 9 files changed, 268 insertions(+), 36 deletions(-) create mode 100644 plugins/Dropbox/src/dropbox_commands.cpp (limited to 'plugins/Dropbox') diff --git a/plugins/Dropbox/Dropbox_10.vcxproj b/plugins/Dropbox/Dropbox_10.vcxproj index f416a99f00..92a20d3522 100644 --- a/plugins/Dropbox/Dropbox_10.vcxproj +++ b/plugins/Dropbox/Dropbox_10.vcxproj @@ -193,6 +193,7 @@ + diff --git a/plugins/Dropbox/Dropbox_10.vcxproj.filters b/plugins/Dropbox/Dropbox_10.vcxproj.filters index 167c54d210..14fd674355 100644 --- a/plugins/Dropbox/Dropbox_10.vcxproj.filters +++ b/plugins/Dropbox/Dropbox_10.vcxproj.filters @@ -1,28 +1,28 @@  - + Source Files - + Source Files - + Source Files Source Files - + Source Files - + Source Files - + Source Files - + Source Files @@ -31,6 +31,9 @@ Source Files + + Source Files + @@ -39,16 +42,19 @@ Header Files + + Header Files + Header Files Header Files - + Header Files - + Header Files @@ -63,7 +69,7 @@ {badc339a-531c-4f2a-8a2e-e46bd5630044} - {10c16dab-11c5-44a6-a007-68a69a21d78e} + {bcf6c793-f4ae-4c61-be3c-1ad015244533} @@ -75,8 +81,8 @@ - + Resource Files\Icons - + \ No newline at end of file diff --git a/plugins/Dropbox/Dropbox_12.vcxproj b/plugins/Dropbox/Dropbox_12.vcxproj index b7549c55b7..80cf1ebf64 100644 --- a/plugins/Dropbox/Dropbox_12.vcxproj +++ b/plugins/Dropbox/Dropbox_12.vcxproj @@ -194,15 +194,16 @@ + + - - + Create diff --git a/plugins/Dropbox/Dropbox_12.vcxproj.filters b/plugins/Dropbox/Dropbox_12.vcxproj.filters index ad97939cf2..14fd674355 100644 --- a/plugins/Dropbox/Dropbox_12.vcxproj.filters +++ b/plugins/Dropbox/Dropbox_12.vcxproj.filters @@ -31,6 +31,9 @@ Source Files + + Source Files + @@ -51,6 +54,9 @@ Header Files + + Header Files + diff --git a/plugins/Dropbox/src/dropbox.cpp b/plugins/Dropbox/src/dropbox.cpp index ef6e29a36c..3e5cd0f5d1 100644 --- a/plugins/Dropbox/src/dropbox.cpp +++ b/plugins/Dropbox/src/dropbox.cpp @@ -1,6 +1,7 @@ #include "common.h" std::map CDropbox::dcftp; +std::map CDropbox::commands; HGENMENU CDropbox::ContactMenuItems[CMI_MAX]; void CDropbox::Init() @@ -18,11 +19,17 @@ void CDropbox::Init() CreateProtoServiceFunction(MODULE, PS_GETCAPS, CDropbox::ProtoGetCaps); CreateProtoServiceFunction(MODULE, PSS_FILE, CDropbox::ProtoSendFile); CreateProtoServiceFunction(MODULE, PSS_MESSAGE, CDropbox::ProtoSendMessage); + CreateProtoServiceFunction(MODULE, PSR_MESSAGE, CDropbox::ProtoReceiveMessage); InitIcons(); InitMenus(); - INSTANCE->hContactTransfer = 0; + commands["content"] = CDropbox::CommandContent; + commands["share"] = CDropbox::CommandShare; + commands["delete"] = CDropbox::CommandDelete; + + hContactTransfer = 0; + hFileProcess = hMessageProcess = 1; } MCONTACT CDropbox::hContactDefault = 0; diff --git a/plugins/Dropbox/src/dropbox.h b/plugins/Dropbox/src/dropbox.h index 8ffd4082f8..1b84aa786b 100644 --- a/plugins/Dropbox/src/dropbox.h +++ b/plugins/Dropbox/src/dropbox.h @@ -2,6 +2,7 @@ #define _DROPBOX_PROTO_H_ #include +#include #include "singleton.h" #include "http_request.h" #include "file_transfer.h" @@ -29,6 +30,13 @@ enum CMI_MAX // this item shall be the last one }; +struct MessageParam +{ + HANDLE hProcess; + MCONTACT hContact; + void *data; +}; + class CDropbox { public: @@ -38,10 +46,12 @@ public: private: HANDLE hNetlibUser; ULONG hFileProcess; + ULONG hMessageProcess; MCONTACT hContactTransfer; static MCONTACT hContactDefault; static std::map dcftp; + static std::map commands; static HGENMENU ContactMenuItems[CMI_MAX]; @@ -59,12 +69,18 @@ private: static INT_PTR ProtoGetCaps(WPARAM wParam, LPARAM lParam); static INT_PTR ProtoSendFile(WPARAM wParam, LPARAM lParam); static INT_PTR ProtoSendMessage(WPARAM wParam, LPARAM lParam); + static INT_PTR ProtoReceiveMessage(WPARAM wParam, LPARAM lParam); static INT_PTR RequestApiAuthorization(WPARAM wParam, LPARAM lParam); static INT_PTR RevokeApiAuthorization(WPARAM wParam, LPARAM lParam); static INT_PTR SendFilesToDropbox(WPARAM wParam, LPARAM lParam); + // commands + static void CommandContent(void *arg); + static void CommandShare(void *arg); + static void CommandDelete(void *arg); + // access token static bool HasAccessToken(); diff --git a/plugins/Dropbox/src/dropbox_commands.cpp b/plugins/Dropbox/src/dropbox_commands.cpp new file mode 100644 index 0000000000..10b20657d0 --- /dev/null +++ b/plugins/Dropbox/src/dropbox_commands.cpp @@ -0,0 +1,130 @@ +#include "common.h" + +void CDropbox::CommandContent(void *arg) +{ + MessageParam *param = (MessageParam*)arg; + + char *name = (char*)param->data; + + CMStringA url = DROPBOX_API_URL "/metadata/" DROPBOX_API_ROOT; + if (name) + url.AppendFormat("/%s", name); + + HttpRequest *request = new HttpRequest(INSTANCE->hNetlibUser, REQUEST_GET, url); + request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); + + mir_ptr response(request->Send()); + + delete request; + + if (response && response->resultCode == HTTP_STATUS::OK) + { + CMStringA message; + + JSONNODE *root = json_parse(response->pData); + if (root) + { + JSONNODE *node = json_get(root, "is_dir"); + bool isDir = json_as_bool(node); + if (!isDir) + message.AppendFormat("\"%s\" %s", name, Translate("is file")); + else + { + JSONNODE *content = json_as_array(json_get(root, "contents")); + for (int i = 0;; i++) + { + JSONNODE *item = json_at(content, i); + if (item == NULL) + { + if (i == 0) + message.AppendFormat("\"%s\" %s", name, Translate("is empty")); + break; + } + + ptrA subName(mir_u2a(json_as_string(json_get(item, "path")))); + message.AppendFormat("%s\n", (subName[0] == '/') ? &subName[1] : subName); + } + } + + ProtoBroadcastAck(MODULE, param->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, param->hProcess, 0); + CallContactService(INSTANCE->GetDefaultContact(), PSR_MESSAGE, 0, (LPARAM)message.GetBuffer()); + + return; + } + } + + ProtoBroadcastAck(MODULE, param->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, param->hProcess, 0); +} + +void CDropbox::CommandShare(void *arg) +{ + MessageParam *param = (MessageParam*)arg; + + char *name = (char*)param->data; + + CMStringA url = DROPBOX_API_URL "/shares/" DROPBOX_API_ROOT; + if (name) + url.AppendFormat("/%s", name); + + HttpRequest *request = new HttpRequest(INSTANCE->hNetlibUser, REQUEST_POST, url); + request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); + + mir_ptr response(request->Send()); + + delete request; + + if (response && response->resultCode == HTTP_STATUS::OK) + { + CMStringA link; + + JSONNODE *root = json_parse(response->pData); + if (root) + { + JSONNODE *node = json_get(root, "url"); + link = mir_u2a(json_as_string(node)); + ProtoBroadcastAck(MODULE, param->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, param->hProcess, 0); + CallContactService(INSTANCE->GetDefaultContact(), PSR_MESSAGE, 0, (LPARAM)link.GetBuffer()); + + return; + } + } + + ProtoBroadcastAck(MODULE, param->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, param->hProcess, 0); +} + +void CDropbox::CommandDelete(void *arg) +{ + MessageParam *param = (MessageParam*)arg; + + char *name = (char*)param->data; + + CMStringA pparam = CMStringA("root=" DROPBOX_API_ROOT "&path=") + name; + + HttpRequest *request = new HttpRequest(INSTANCE->hNetlibUser, REQUEST_POST, DROPBOX_API_URL "/fileops/delete"); + request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); + request->AddHeader("Content-Type", "application/x-www-form-urlencoded"); + request->pData = mir_strdup(pparam); + request->dataLength = pparam.GetLength(); + + mir_ptr response(request->Send()); + + delete request; + + if (response && response->resultCode == HTTP_STATUS::OK) + { + JSONNODE *root = json_parse(response->pData); + if (root) + { + JSONNODE *node = json_get(root, "is_deleted"); + bool isDeleted = json_as_bool(node); + CMStringA message; + message.AppendFormat("%s %s", name, !isDeleted ? Translate("is not deleted") : Translate("is deleted")); + ProtoBroadcastAck(MODULE, param->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, param->hProcess, 0); + CallContactService(INSTANCE->GetDefaultContact(), PSR_MESSAGE, 0, (LPARAM)message.GetBuffer()); + + return; + } + } + + ProtoBroadcastAck(MODULE, param->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, param->hProcess, 0); +} \ No newline at end of file diff --git a/plugins/Dropbox/src/dropbox_services.cpp b/plugins/Dropbox/src/dropbox_services.cpp index c298974166..ec556056ff 100644 --- a/plugins/Dropbox/src/dropbox_services.cpp +++ b/plugins/Dropbox/src/dropbox_services.cpp @@ -85,16 +85,61 @@ INT_PTR CDropbox::ProtoSendFile(WPARAM wParam, LPARAM lParam) return fileId; } -INT_PTR CDropbox::ProtoSendMessage(WPARAM wParam, LPARAM lParam) +INT_PTR CDropbox::ProtoSendMessage(WPARAM, LPARAM lParam) { - //CCSDATA *pccsd = (CCSDATA*)lParam; + CCSDATA *pccsd = (CCSDATA*)lParam; + + char *message = (char*)pccsd->lParam; + + if (message[0] && message[0] == '/') + { + // parse commands + char *sep = strchr(message, ' '); + int len = strlen(message) - (sep ? strlen(sep) : 0) - 1; + char *cmd = (char*)mir_alloc(len + 1); + strncpy(cmd, message + 1, len); + cmd[len] = 0; + if (INSTANCE->commands.find(cmd) != INSTANCE->commands.end()) + { + ULONG messageId = InterlockedIncrement(&INSTANCE->hMessageProcess); + + MessageParam *param = new MessageParam(); + param->hContact = pccsd->hContact; + param->hProcess = (HANDLE)messageId; + param->data = (sep ? sep + 1 : NULL); + + mir_forkthread(INSTANCE->commands[cmd], param); + + return messageId; + } + //mir_free(cmd); + } + + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.szModule = MODULE; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = strlen(message); + dbei.pBlob = (PBYTE)message; + dbei.flags = DBEF_SENT | DBEF_UTF; + db_event_add(pccsd->hContact, &dbei); + + return 0; +} + +INT_PTR CDropbox::ProtoReceiveMessage(WPARAM, LPARAM lParam) +{ + CCSDATA *pccsd = (CCSDATA*)lParam; - //char *message = (char*)pccsd->lParam; + char *message = (char*)pccsd->lParam; - //if (message[0] && message[0] == '/') - //{ - // // parse commands - //} + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.szModule = MODULE; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = strlen(message); + dbei.pBlob = (PBYTE)message; + db_event_add(pccsd->hContact, &dbei); return 0; } diff --git a/plugins/Dropbox/src/dropbox_transfers.cpp b/plugins/Dropbox/src/dropbox_transfers.cpp index 2978955de7..80f3474f56 100644 --- a/plugins/Dropbox/src/dropbox_transfers.cpp +++ b/plugins/Dropbox/src/dropbox_transfers.cpp @@ -138,12 +138,21 @@ int CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId, MC fileName, mir_u2a(json_as_string(node))); - int res = ACKRESULT_SUCCESS; - if (hContact != CDropbox::GetDefaultContact()) - res = CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)&message); - - if (res != ACKRESULT_FAILED) + { + if (CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)&message != ACKRESULT_FAILED)) + { + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.szModule = MODULE; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = strlen(message); + dbei.pBlob = (PBYTE)message; + dbei.flags = DBEF_SENT | DBEF_UTF; + db_event_add(hContact, &dbei); + } + } + else { DBEVENTINFO dbei = { sizeof(dbei) }; dbei.szModule = MODULE; @@ -151,7 +160,7 @@ int CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId, MC dbei.eventType = EVENTTYPE_MESSAGE; dbei.cbBlob = strlen(message); dbei.pBlob = (PBYTE)message; - dbei.flags = DBEF_SENT | DBEF_UTF; + dbei.flags = DBEF_UTF; db_event_add(hContact, &dbei); } @@ -182,7 +191,7 @@ int CDropbox::CreateFolder(const char *folderName, MCONTACT hContact) DROPBOX_API_ROOT, folder); - mir_ptr request(new HttpRequest(hNetlibUser, REQUEST_POST, DROPBOX_API_URL "/fileops/create_folder")); + HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, DROPBOX_API_URL "/fileops/create_folder"); request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); request->AddHeader("Content-Type", "application/x-www-form-urlencoded"); request->pData = mir_strdup(param); @@ -190,7 +199,9 @@ int CDropbox::CreateFolder(const char *folderName, MCONTACT hContact) mir_ptr response(request->Send()); - if (response && response->resultCode == HTTP_STATUS::OK) + delete request; + + if (response && (response->resultCode == HTTP_STATUS::OK || response->resultCode == HTTP_STATUS::FORBIDDEN)) { if (!strchr(folderName, '\\')) { @@ -220,12 +231,21 @@ int CDropbox::CreateFolder(const char *folderName, MCONTACT hContact) folderName, mir_u2a(json_as_string(node))); - int res = ACKRESULT_SUCCESS; - if (hContact != CDropbox::GetDefaultContact()) - res = CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)&message); - - if (res != ACKRESULT_FAILED) + { + if (CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)&message) != ACKRESULT_FAILED) + { + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.szModule = MODULE; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = strlen(message); + dbei.pBlob = (PBYTE)message; + dbei.flags = DBEF_SENT | DBEF_UTF; + db_event_add(hContact, &dbei); + } + } + else { DBEVENTINFO dbei = { sizeof(dbei) }; dbei.szModule = MODULE; @@ -233,7 +253,7 @@ int CDropbox::CreateFolder(const char *folderName, MCONTACT hContact) dbei.eventType = EVENTTYPE_MESSAGE; dbei.cbBlob = strlen(message); dbei.pBlob = (PBYTE)message; - dbei.flags = DBEF_SENT | DBEF_UTF; + dbei.flags = DBEF_UTF; db_event_add(hContact, &dbei); } -- cgit v1.2.3