From 4df260317b8bd47ca65dca24b376b68b765a378f Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Wed, 19 Feb 2014 12:23:54 +0000 Subject: DropBox: - reorganization of projects and code - added access request at contact's menu - temporary disabled folders sending - added dropbox icon - version bump git-svn-id: http://svn.miranda-ng.org/main/trunk@8174 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/DropBox/DropBox_10.vcxproj | 18 +- plugins/DropBox/DropBox_10.vcxproj.filters | 39 ++- plugins/DropBox/DropBox_11.vcxproj | 37 ++- plugins/DropBox/DropBox_11.vcxproj.filters | 39 ++- plugins/DropBox/DropBox_12.vcxproj | 18 +- plugins/DropBox/DropBox_12.vcxproj.filters | 39 ++- plugins/DropBox/res/dropbox.ico | Bin 0 -> 6518 bytes plugins/DropBox/res/resource.rc | Bin 6948 -> 7492 bytes plugins/DropBox/src/common.h | 17 +- plugins/DropBox/src/dropBox_proto.cpp | 442 ----------------------------- plugins/DropBox/src/dropBox_proto.h | 73 ----- plugins/DropBox/src/dropbox.cpp | 128 +++++++++ plugins/DropBox/src/dropbox.h | 110 +++++++ plugins/DropBox/src/dropbox_dialogs.cpp | 62 ++++ plugins/DropBox/src/dropbox_events.cpp | 40 +++ plugins/DropBox/src/dropbox_icons.cpp | 33 +++ plugins/DropBox/src/dropbox_menus.cpp | 17 ++ plugins/DropBox/src/dropbox_services.cpp | 82 ++++++ plugins/DropBox/src/dropbox_transfers.cpp | 210 ++++++++++++++ plugins/DropBox/src/dropbox_utils.cpp | 26 ++ plugins/DropBox/src/http_request.h | 5 + plugins/DropBox/src/main.cpp | 21 +- plugins/DropBox/src/resource.h | Bin 1176 -> 1370 bytes plugins/DropBox/src/stdafx.cpp | 18 -- plugins/DropBox/src/version.h | 12 +- 25 files changed, 870 insertions(+), 616 deletions(-) create mode 100644 plugins/DropBox/res/dropbox.ico delete mode 100644 plugins/DropBox/src/dropBox_proto.cpp delete mode 100644 plugins/DropBox/src/dropBox_proto.h create mode 100644 plugins/DropBox/src/dropbox.cpp create mode 100644 plugins/DropBox/src/dropbox.h create mode 100644 plugins/DropBox/src/dropbox_dialogs.cpp create mode 100644 plugins/DropBox/src/dropbox_events.cpp create mode 100644 plugins/DropBox/src/dropbox_icons.cpp create mode 100644 plugins/DropBox/src/dropbox_menus.cpp create mode 100644 plugins/DropBox/src/dropbox_services.cpp create mode 100644 plugins/DropBox/src/dropbox_transfers.cpp create mode 100644 plugins/DropBox/src/dropbox_utils.cpp delete mode 100644 plugins/DropBox/src/stdafx.cpp (limited to 'plugins/DropBox') diff --git a/plugins/DropBox/DropBox_10.vcxproj b/plugins/DropBox/DropBox_10.vcxproj index 709f8deb02..f7d946da0e 100644 --- a/plugins/DropBox/DropBox_10.vcxproj +++ b/plugins/DropBox/DropBox_10.vcxproj @@ -20,7 +20,7 @@ {CBA58126-3E02-4159-9BD3-059AF9DBC84E} - DropBox + Dropbox @@ -83,15 +83,15 @@ true 4996;%(DisableSpecificWarnings) MultiThreadedDebugDLL + NotUsing common.h - Use Windows true $(ProfileDir)..\..\bin10\lib $(IntDir)$(TargetName).lib - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) false @@ -109,7 +109,7 @@ true 4996;%(DisableSpecificWarnings) MultiThreadedDebugDLL - Use + NotUsing common.h @@ -117,7 +117,7 @@ true $(ProfileDir)..\..\bin10\lib $(IntDir)$(TargetName).lib - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) false @@ -134,7 +134,7 @@ WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) ..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) 4996;%(DisableSpecificWarnings) - Use + NotUsing common.h Size @@ -144,7 +144,7 @@ true true false - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) $(ProfileDir)..\..\bin10\lib $(IntDir)$(TargetName).lib /PDBALTPATH:%_PDB% %(AdditionalOptions) @@ -163,7 +163,7 @@ NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) ..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) 4996;%(DisableSpecificWarnings) - Use + NotUsing common.h Size @@ -173,7 +173,7 @@ true true false - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) $(ProfileDir)..\..\bin10\lib $(IntDir)$(TargetName).lib /PDBALTPATH:%_PDB% %(AdditionalOptions) diff --git a/plugins/DropBox/DropBox_10.vcxproj.filters b/plugins/DropBox/DropBox_10.vcxproj.filters index 1d9e2a795d..d5d53e93d6 100644 --- a/plugins/DropBox/DropBox_10.vcxproj.filters +++ b/plugins/DropBox/DropBox_10.vcxproj.filters @@ -1,30 +1,48 @@  - + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + Source Files Source Files - + + Source Files + + Source Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files @@ -40,11 +58,16 @@ - + Resource Files Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/plugins/DropBox/DropBox_11.vcxproj b/plugins/DropBox/DropBox_11.vcxproj index 71d46e9c09..8f52177702 100644 --- a/plugins/DropBox/DropBox_11.vcxproj +++ b/plugins/DropBox/DropBox_11.vcxproj @@ -20,7 +20,7 @@ {CBA58126-3E02-4159-9BD3-059AF9DBC84E} - DropBox + Dropbox @@ -88,14 +88,14 @@ 4996;%(DisableSpecificWarnings) MultiThreadedDebugDLL common.h - Use + NotUsing Windows true $(ProfileDir)..\..\bin11\lib $(IntDir)$(TargetName).lib - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) false @@ -113,7 +113,7 @@ true 4996;%(DisableSpecificWarnings) MultiThreadedDebugDLL - Use + NotUsing common.h @@ -121,7 +121,7 @@ true $(ProfileDir)..\..\bin11\lib $(IntDir)$(TargetName).lib - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) false @@ -138,7 +138,7 @@ WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) ..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) 4996;%(DisableSpecificWarnings) - Use + NotUsing common.h Size @@ -148,7 +148,7 @@ true true false - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) $(ProfileDir)..\..\bin11\lib $(IntDir)$(TargetName).lib @@ -176,7 +176,7 @@ true true false - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) $(ProfileDir)..\..\bin11\lib $(IntDir)$(TargetName).lib @@ -186,23 +186,30 @@ - - + + + + + + + - - - Create - + + + - + + + + diff --git a/plugins/DropBox/DropBox_11.vcxproj.filters b/plugins/DropBox/DropBox_11.vcxproj.filters index 1d9e2a795d..d5d53e93d6 100644 --- a/plugins/DropBox/DropBox_11.vcxproj.filters +++ b/plugins/DropBox/DropBox_11.vcxproj.filters @@ -1,30 +1,48 @@  - + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + Source Files Source Files - + + Source Files + + Source Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files @@ -40,11 +58,16 @@ - + Resource Files Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/plugins/DropBox/DropBox_12.vcxproj b/plugins/DropBox/DropBox_12.vcxproj index 6142974e29..fe1fbb0686 100644 --- a/plugins/DropBox/DropBox_12.vcxproj +++ b/plugins/DropBox/DropBox_12.vcxproj @@ -20,7 +20,7 @@ {CBA58126-3E02-4159-9BD3-059AF9DBC84E} - DropBox + Dropbox @@ -87,15 +87,15 @@ true 4996;%(DisableSpecificWarnings) MultiThreadedDebugDLL + NotUsing common.h - Use Windows true $(ProfileDir)..\..\bin12\lib $(IntDir)$(TargetName).lib - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) false @@ -113,7 +113,7 @@ true 4996;%(DisableSpecificWarnings) MultiThreadedDebugDLL - Use + NotUsing common.h @@ -121,7 +121,7 @@ true $(ProfileDir)..\..\bin12\lib $(IntDir)$(TargetName).lib - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) false @@ -138,7 +138,7 @@ WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) ..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) 4996;%(DisableSpecificWarnings) - Use + NotUsing common.h Size @@ -148,7 +148,7 @@ true true false - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) $(ProfileDir)..\..\bin12\lib $(IntDir)$(TargetName).lib @@ -166,7 +166,7 @@ NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) ..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) 4996;%(DisableSpecificWarnings) - Use + NotUsing common.h Size @@ -176,7 +176,7 @@ true true false - comctl32.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;%(AdditionalDependencies) $(ProfileDir)..\..\bin12\lib $(IntDir)$(TargetName).lib diff --git a/plugins/DropBox/DropBox_12.vcxproj.filters b/plugins/DropBox/DropBox_12.vcxproj.filters index 1d9e2a795d..d5d53e93d6 100644 --- a/plugins/DropBox/DropBox_12.vcxproj.filters +++ b/plugins/DropBox/DropBox_12.vcxproj.filters @@ -1,30 +1,48 @@  - + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + Source Files Source Files - + + Source Files + + Source Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files @@ -40,11 +58,16 @@ - + Resource Files Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/plugins/DropBox/res/dropbox.ico b/plugins/DropBox/res/dropbox.ico new file mode 100644 index 0000000000..c5d1023f9a Binary files /dev/null and b/plugins/DropBox/res/dropbox.ico differ diff --git a/plugins/DropBox/res/resource.rc b/plugins/DropBox/res/resource.rc index b66b61e68c..52a1d26839 100644 Binary files a/plugins/DropBox/res/resource.rc and b/plugins/DropBox/res/resource.rc differ diff --git a/plugins/DropBox/src/common.h b/plugins/DropBox/src/common.h index c4d9c9c493..d3b14a3e15 100644 --- a/plugins/DropBox/src/common.h +++ b/plugins/DropBox/src/common.h @@ -1,14 +1,18 @@ #ifndef _COMMON_H_ #define _COMMON_H_ -//#include #include +#include #include #include #include #include +#include +#include +#include +#include #include #include @@ -20,13 +24,16 @@ #include #include -#include "dropBox_proto.h" #include "version.h" #include "resource.h" -#define MODULE "DropBox" +#define MODULE "Dropbox" -extern HINSTANCE g_hInstance; -extern HANDLE g_hNetlibUser; +class CDropbox; + +extern HINSTANCE g_hInstance; +extern CDropbox *g_dropbox; + +HANDLE CreateProtoServiceFunctionObj(const char *szModule, const char *szService, MIRANDASERVICEOBJ serviceProc, void* obj); #endif //_COMMON_H_ \ No newline at end of file diff --git a/plugins/DropBox/src/dropBox_proto.cpp b/plugins/DropBox/src/dropBox_proto.cpp deleted file mode 100644 index 969987776c..0000000000 --- a/plugins/DropBox/src/dropBox_proto.cpp +++ /dev/null @@ -1,442 +0,0 @@ -#include "common.h" - -HANDLE g_hNetlibUser; -ULONG g_fileId = 1; - -bool HasAccessToken() -{ - return db_get_sa(NULL, MODULE, "TokenSecret") != NULL; -} - -int OnModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - NETLIBUSER nlu = { sizeof(nlu) }; - nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; - nlu.szSettingsModule = MODULE; - nlu.szSettingsModule = MODULE; - nlu.ptszDescriptiveName = L"DropBox"; - - g_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); - - DropBoxLogIn(); - - return 0; -} - -int OnOptionsInit(WPARAM wParam, LPARAM lParam) -{ - OPTIONSDIALOGPAGE odp = { sizeof(odp) }; - odp.position = 100000000; - odp.hInstance = g_hInstance; - odp.flags = ODPF_BOLDGROUPS; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_MAIN); - odp.pszGroup = LPGEN("Network"); - odp.pszTitle = LPGEN("DropBox"); - odp.pfnDlgProc = MainOptionsProc; - - //Options_AddPage(wParam, &odp); - - return 0; -} - -INT_PTR DropBoxGetCaps(WPARAM wParam, LPARAM lParam) -{ - switch(wParam) - { - case PFLAGNUM_1: - return PF1_IM | PF1_FILESEND; - case PFLAGNUM_2: - return PF2_ONLINE; - case PFLAG_UNIQUEIDTEXT: - return (INT_PTR) "Dropbox ID"; - case PFLAG_UNIQUEIDSETTING: - return (DWORD_PTR)"uid"; - } - - return 0; -} - -HttpRequest *DropBoxCreateFileChunkedRequest(const char *data, int length) -{ - HttpRequest *request = new HttpRequest(g_hNetlibUser, REQUEST_PUT, DROPBOX_APICONTENT_URL "/chunked_upload"); - request->AddParameter("access_token", db_get_sa(NULL, MODULE, "TokenSecret")); - if (length > 0) - { - request->AddHeader("Content-Type", "application/octet-stream"); - request->dataLength = length; - request->pData = (char*)mir_alloc(sizeof(char) * (length + 1)); - memcpy(request->pData, data, length); - request->pData[length] = 0; - } - - return request; -} - -bool DropBoxSendFileChunkedStart(const char *data, int length, char *uploadId, int &offset) -{ - HttpRequest *request = DropBoxCreateFileChunkedRequest(data, length); - NETLIBHTTPREQUEST *response = request->Send(); - - delete request; - - if (response && response->resultCode == 200) - { - JSONNODE *root = json_parse(response->pData); - if (root != NULL) - { - JSONNODE *node = json_get(root, "upload_id"); - strcpy(uploadId, mir_u2a(json_as_string(node))); - - node = json_get(root, "offset"); - offset = json_as_int(node); - - return true; - } - } - - return 0; -} - -bool DropBoxSendFileChunkedNext(const char *data, int length, const char *uploadId, int &offset) -{ - HttpRequest *request = DropBoxCreateFileChunkedRequest(data, length); - request->AddParameter("upload_id", uploadId); - request->AddParameter("offset", offset); - - NETLIBHTTPREQUEST *response = request->Send(); - - delete request; - - if (response && response->resultCode == 200) - { - JSONNODE *root = json_parse(response->pData); - if (root != NULL) - { - JSONNODE *node = json_get(root, "offset"); - offset = json_as_int(node); - - return true; - } - } - - return false; -} - -bool DropBoxSendFileChunkedEnd(const char *fileName, const char *uploadId, MCONTACT hContact) -{ - char url[MAX_PATH]; - mir_snprintf( - url, - SIZEOF(url), - "%s/commit_chunked_upload/%s/%s", - DROPBOX_APICONTENT_URL, - DROPBOX_API_ROOT, - fileName); - - HttpRequest *request = new HttpRequest(g_hNetlibUser, REQUEST_POST, url); - request->AddParameter("upload_id", uploadId); - request->AddParameter("access_token", db_get_sa(NULL, MODULE, "TokenSecret")); - - NETLIBHTTPREQUEST *response = request->Send(); - - delete request; - - if (response && response->resultCode == 200) - { - mir_snprintf( - url, - SIZEOF(url), - "%s/shares/%s/%s", - DROPBOX_API_URL, - DROPBOX_API_ROOT, - fileName); - - request = new HttpRequest(g_hNetlibUser, REQUEST_POST, url); - request->AddParameter("access_token", db_get_sa(NULL, MODULE, "TokenSecret")); - - response = request->Send(); - - if (response && response->resultCode == 200) - { - JSONNODE *root = json_parse(response->pData); - if (root != NULL) - { - JSONNODE *node = json_get(root, "url"); - char message[1024]; - mir_snprintf( - message, - SIZEOF(message), - Translate("Link to download file \"%s\": %s"), - fileName, - mir_utf8encodeW(json_as_string(node))); - - DBEVENTINFO dbei = { sizeof(dbei) }; - dbei.szModule = MODULE; - dbei.timestamp = time(NULL); - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = strlen(message); - dbei.pBlob = (PBYTE)mir_strdup(message); - dbei.flags = DBEF_UTF; - ::db_event_add(hContact, &dbei); - } - } - - return true; - } - - return false; -} - -void DropBoxAsyncFileSend(void *arg) -{ - FileTransferParam *ftp = (FileTransferParam *)arg; - - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ftp->hProcess, 0); - - for (int i = 0; ftp->pfts.pszFiles[i]; i++) - { - FILE *file = fopen(ftp->pfts.pszFiles[i], "rb"); - if (file != NULL) - { - int offset = 0; - char *uploadId = new char[32]; - - const char *fileName = strrchr(ftp->pfts.pszFiles[i], '\\') + 1; - - fseek(file, 0, SEEK_END); - DWORD fileSize = ftell(file); - fseek(file, 0, SEEK_SET); - - ftp->pfts.currentFileNumber = i; - ftp->pfts.currentFileSize = fileSize; - ftp->pfts.currentFileProgress = 0; - ftp->pfts.szCurrentFile = strrchr(ftp->pfts.pszFiles[i], '\\') + 1; - - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftp->hProcess, (LPARAM)&ftp->pfts); - - while (!feof(file) && !ferror(file)) - { - int chunkSize = DROPBOX_FILE_CHUNK_SIZE; - if (fileSize < 1024*1024) - chunkSize = DROPBOX_FILE_CHUNK_SIZE / 5; - else if (fileSize > 20*1024*1024) - chunkSize = DROPBOX_FILE_CHUNK_SIZE * 4; - - char *data = new char[chunkSize + 1]; - size_t count = fread(data, sizeof(char), chunkSize, file); - - if (!offset) - DropBoxSendFileChunkedStart(data, count, uploadId, offset); - else - DropBoxSendFileChunkedNext(data, count, uploadId, offset); - - ftp->pfts.currentFileProgress += count; - ftp->pfts.totalProgress += count; - - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftp->hProcess, (LPARAM)&ftp->pfts); - } - - fclose(file); - - DropBoxSendFileChunkedEnd(fileName, uploadId, ftp->pfts.hContact); - ftp->pfts.currentFileProgress = ftp->pfts.currentFileSize; - - if (i < ftp->pfts.totalFiles - 1) - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ftp->hProcess, 0); - } - } - - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftp->hProcess, 0); - - delete ftp; -} - -INT_PTR DropBoxSendFile(WPARAM wParam, LPARAM lParam) -{ - CCSDATA *pccsd = (CCSDATA*)lParam; - - FileTransferParam *ftp = new FileTransferParam(); - ftp->pfts.flags = PFTS_SENDING | PFTS_UTF; - ftp->pfts.hContact = pccsd->hContact; - - char **files = (char**)pccsd->lParam; - - for (ftp->pfts.totalFiles = 0; files[ftp->pfts.totalFiles]; ftp->pfts.totalFiles++); - ftp->pfts.pszFiles = new char*[ftp->pfts.totalFiles + 1]; - ftp->pfts.pszFiles[ftp->pfts.totalFiles] = NULL; - for (int i = 0; i < ftp->pfts.totalFiles; i++) - { - ftp->pfts.pszFiles[i] = mir_strdup(files[i]); - - FILE *file = fopen(files[i], "rb"); - if (file != NULL) - { - fseek(file, 0, SEEK_END); - ftp->pfts.totalBytes += ftell(file); - fseek(file, 0, SEEK_SET); - fclose(file); - } - } - ULONG fileId = ::InterlockedIncrement(&g_fileId); - ftp->hProcess = (HANDLE)fileId; - - mir_forkthread(DropBoxAsyncFileSend, ftp); - - return fileId; -} - -INT_PTR DropBoxSendMessage(WPARAM wParam, LPARAM lParam) -{ - return 0; -} - -void SetContactStatus(MCONTACT hContact, int newStatus) -{ - if (db_get_w(hContact, MODULE, "Status", ID_STATUS_OFFLINE) != newStatus) - db_set_w(hContact, MODULE, "Status", newStatus); -} - -bool DropBoxLogIn() -{ - char *access_token = db_get_sa(NULL, MODULE, "TokenSecret"); - if (!access_token) - { - ShellExecuteA(NULL, "open", "https://www.dropbox.com/1/oauth2/authorize?response_type=code&client_id="DROPBOX_API_KEY, NULL, NULL, SW_SHOWDEFAULT); - - char request_token[128]; - request_token[0] = 0; - - if (DialogBoxParam( - g_hInstance, - MAKEINTRESOURCE(IDD_TOKEN_REQUEST), - NULL, - TokenRequestProc, - (LPARAM)&request_token) == IDOK) - { - HttpRequest *request = new HttpRequest(g_hNetlibUser, REQUEST_POST, DROPBOX_API_URL "/oauth2/token"); - request->AddParameter("grant_type", "authorization_code"); - request->AddParameter("code", request_token); - request->AddHeader("Content-Type", "application/x-www-form-urlencoded"); - char data[64]; - mir_snprintf( - data, - SIZEOF(data), - "client_id=%s&client_secret=%s", - DROPBOX_API_KEY, - DROPBOX_API_SECRET); - request->pData = mir_strdup(data); - request->dataLength = strlen(data); - - NETLIBHTTPREQUEST *response = request->Send(); - - if (response && response->resultCode == 200) - { - JSONNODE *root = json_parse(response->pData); - if (root != NULL) - { - JSONNODE *node = json_get(root, "access_token"); - access_token = mir_u2a(json_as_string(node)); - db_set_s(NULL, MODULE, "TokenSecret", access_token); - - MCONTACT hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0); - if (!CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)MODULE)) - { - node = json_get(root, "uid"); - wchar_t *uid = json_as_string(node); - db_set_ws(hContact, MODULE, "uid", uid); - - db_set_s(hContact, MODULE, "Nick", MODULE); - db_set_w(hContact, MODULE, "Status", ID_STATUS_ONLINE); - //SetContactStatus(hContact, ID_STATUS_ONLINE); - } - - delete node; - delete root; - delete request; - //delete access_token; - - return true; - } - } - - delete request; - } - } - /*else - { - for (MCONTACT hContact = db_find_first(MODULE); hContact; hContact = db_find_next(hContact, MODULE)) - SetContactStatus(hContact, ID_STATUS_ONLINE); - }*/ - - return false; -} - -//void LogOut() -//{ -// HttpRequest *request = new HttpRequest(this, REQUEST_POST, DROPBOX_API_URL "/disable_access_token"); -// //request->SendAsync(&CDropBoxProto::AsyncFunc); -// request->Send(); -// -// delete request; -//} - -INT_PTR CALLBACK TokenRequestProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char *token = reinterpret_cast(::GetWindowLongPtr(hwndDlg, GWLP_USERDATA)); - - switch (msg) - { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - token = (char*)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - { - //::SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)CSkypeProto::IconList[0].Handle); - //::SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)CSkypeProto::IconList[0].Handle); - - /*wchar_t title[MAX_PATH]; - ::mir_sntprintf( - title, - MAX_PATH, - ::TranslateT("Enter a password for %s:"), - param->login);*/ - //::SetDlgItemText(hwndDlg, IDC_INSTRUCTION, title); - - SendDlgItemMessage(hwndDlg, IDC_TOKEN, EM_LIMITTEXT, 128 - 1, 0); - } - break; - - case WM_CLOSE: - EndDialog(hwndDlg, 0); - break; - - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDOK: - { - char data[128]; - GetDlgItemTextA(hwndDlg, IDC_TOKEN, data, SIZEOF(data)); - strcpy(token, data); - - EndDialog(hwndDlg, IDOK); - } - break; - - case IDCANCEL: - EndDialog(hwndDlg, IDCANCEL); - break; - } - } - break; - } - - return FALSE; -} - -INT_PTR CALLBACK MainOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - return FALSE; -} \ No newline at end of file diff --git a/plugins/DropBox/src/dropBox_proto.h b/plugins/DropBox/src/dropBox_proto.h deleted file mode 100644 index b79f405fdc..0000000000 --- a/plugins/DropBox/src/dropBox_proto.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef _DROPBOX_PROTO_H_ -#define _DROPBOX_PROTO_H_ - -//#include "common.h" -#include "http_request.h" - -#define DROPBOX_API_VER "1" -#define DROPBOX_API_ROOT "sandbox" -#define DROPBOX_API_URL "https://api.dropbox.com/" DROPBOX_API_VER -#define DROPBOX_APICONTENT_URL "https://api-content.dropbox.com/" DROPBOX_API_VER - -#define DROPBOX_API_KEY "fa8du7gkf2q8xzg" -#include "..\..\DropBox\secret_key.h" - -#define DROPBOX_FILE_CHUNK_SIZE 1024 * 1024 //1 MB - -extern ULONG g_fileId; - -struct FileTransferParam -{ - HANDLE hProcess; - PROTOFILETRANSFERSTATUS pfts; - - FileTransferParam() - { - pfts.cbSize = sizeof(this->pfts); - pfts.flags = PFTS_UTF; - pfts.currentFileNumber = 0; - pfts.currentFileProgress = 0; - pfts.currentFileSize = 0; - pfts.currentFileTime = 0; - pfts.totalBytes = 0; - pfts.totalFiles = 0; - pfts.totalProgress = 0; - pfts.tszWorkingDir = NULL; - pfts.wszCurrentFile = NULL; - } - - ~FileTransferParam() - { - for (int i = 0; pfts.pszFiles[pfts.totalFiles]; i++) - { - delete pfts.pszFiles[i]; - } - delete pfts.pszFiles; - } -}; - -bool HasAccessToken(); - -void SetContactStatus(MCONTACT hContact, int newStatus); -bool DropBoxLogIn(); - -int OnOptionsInit(WPARAM wParam, LPARAM lParam); -int OnModulesLoaded(WPARAM wParam, LPARAM lParam); - -INT_PTR DropBoxGetCaps(WPARAM wParam, LPARAM lParam); - -INT_PTR DropBoxSendMessage(WPARAM wParam, LPARAM lParam); - -HttpRequest *DropBoxCreateFileChunkedRequest(const char *data, int length); -bool DropBoxSendFileChunkedStart(const char *data, int length, char *uploadId, int &offset); -bool DropBoxSendFileChunkedNext(const char *data, int length, const char *uploadId, int &offset); -bool DropBoxSendFileChunkedEnd(const char *fileName, const char *uploadId, MCONTACT hContact); - -void DropBoxAsyncFileSend(void *arg); - -INT_PTR DropBoxSendFile(WPARAM wParam, LPARAM lParam); - -INT_PTR CALLBACK MainOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK TokenRequestProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -#endif //_DROPBOX_PROTO_H_ \ No newline at end of file diff --git a/plugins/DropBox/src/dropbox.cpp b/plugins/DropBox/src/dropbox.cpp new file mode 100644 index 0000000000..35f9a7b832 --- /dev/null +++ b/plugins/DropBox/src/dropbox.cpp @@ -0,0 +1,128 @@ +#include "dropbox.h" + +CDropbox::CDropbox() +{ + PROTOCOLDESCRIPTOR pd = { PROTOCOLDESCRIPTOR_V3_SIZE }; + pd.szName = MODULE; + pd.type = PROTOTYPE_VIRTUAL; + CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); + + HookEvent(ME_OPT_INITIALISE, OnOptionsInit); + HookEvent(ME_SYSTEM_MODULESLOADED, CDropbox::OnModulesLoaded); + + CreateProtoServiceFunction(MODULE, PS_GETCAPS, CDropbox::GetCaps); + CreateProtoServiceFunction(MODULE, PSS_FILE, CDropbox::SendFile); + CreateProtoServiceFunction(MODULE, PSS_MESSAGE, CDropbox::SendMessage); + + InitIcons(); + InitMenus(); +} + +MCONTACT CDropbox::GetDefaultContact() +{ + return db_find_first(MODULE); +} + +bool CDropbox::HasAccessToken() +{ + return db_get_sa(NULL, MODULE, "TokenSecret") != NULL; +} + +void CDropbox::RequestAcceessToken() +{ + ShellExecuteA(NULL, "open", DROPBOX_WWW_URL "/" DROPBOX_API_VER "/oauth2/authorize?response_type=code&client_id=" DROPBOX_API_KEY, NULL, NULL, SW_SHOWDEFAULT); + + char request_token[128] = { 0 }; + //request_token[0] = 0; + + if (DialogBoxParam( + g_hInstance, + MAKEINTRESOURCE(IDD_TOKEN_REQUEST), + NULL, + CDropbox::TokenRequestProc, + (LPARAM)&request_token) == IDOK) + { + char data[64]; + mir_snprintf( + data, + SIZEOF(data), + "client_id=%s&client_secret=%s", + DROPBOX_API_KEY, + DROPBOX_API_SECRET); + + HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, DROPBOX_API_URL "/oauth2/token"); + request->AddParameter("grant_type", "authorization_code"); + request->AddParameter("code", request_token); + request->AddHeader("Content-Type", "application/x-www-form-urlencoded"); + request->pData = mir_strdup(data); + request->dataLength = strlen(data); + + NETLIBHTTPREQUEST *response = request->Send(); + + delete request; + + if (response) + { + if (response->resultCode == HttpStatus::OK) + { + JSONNODE *root = json_parse(response->pData); + if (root != NULL) + { + JSONNODE *node = json_get(root, "access_token"); + ptrA access_token = ptrA(mir_u2a(json_as_string(node))); + db_set_s(NULL, MODULE, "TokenSecret", access_token); + + MCONTACT hContact = GetDefaultContact(); + if (hContact) + { + node = json_get(root, "uid"); + wchar_t *uid = json_as_string(node); + db_set_ws(hContact, MODULE, "uid", uid); + if (db_get_w(hContact, MODULE, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE) + db_set_w(hContact, MODULE, "Status", ID_STATUS_ONLINE); + } + + CDropbox::ShowNotification(TranslateT("Access request"), TranslateT("Access granted"), MB_ICONINFORMATION); + + delete node; + delete root; + } + } + else + { + JSONNODE *root = json_parse(response->pData); + if (root != NULL) + { + JSONNODE *node = json_get(root, "error_description"); + wchar_t *error_description = json_as_string(node); + + CDropbox::ShowNotification(TranslateT("Access request"), error_description, MB_ICONERROR); + + delete node; + delete root; + } + } + + mir_free(response); + } + } +} + +void CDropbox::DestroyAcceessToken() +{ + + HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, DROPBOX_API_URL "/disable_access_token"); + //request->SendAsync(&CDropboxProto::AsyncFunc); + NETLIBHTTPREQUEST *response = request->Send(); + + delete request; + mir_free(response); + + db_unset(NULL, MODULE, "TokenSecret"); + MCONTACT hContact = GetDefaultContact(); + if (hContact) + { + if (db_get_w(hContact, MODULE, "Status", ID_STATUS_ONLINE) == ID_STATUS_ONLINE) + db_set_w(hContact, MODULE, "Status", ID_STATUS_OFFLINE); + } +} \ No newline at end of file diff --git a/plugins/DropBox/src/dropbox.h b/plugins/DropBox/src/dropbox.h new file mode 100644 index 0000000000..ba400d90d0 --- /dev/null +++ b/plugins/DropBox/src/dropbox.h @@ -0,0 +1,110 @@ +#ifndef _Dropbox_PROTO_H_ +#define _Dropbox_PROTO_H_ + +//#include "common.h" +#include "http_request.h" + +#define DROPBOX_API_VER "1" +#define DROPBOX_API_ROOT "sandbox" +#define DROPBOX_WWW_URL "https://www.dropbox.com/" +#define DROPBOX_API_URL "https://api.dropbox.com/" DROPBOX_API_VER +#define DROPBOX_APICONTENT_URL "https://api-content.dropbox.com/" DROPBOX_API_VER + +#define DROPBOX_API_KEY "fa8du7gkf2q8xzg" +#include "..\..\..\Dropbox\secret_key.h" + +#define DROPBOX_FILE_CHUNK_SIZE 1024 * 1024 //1 MB + +enum +{ + CMI_API_ACCESS_REQUERIED, + CMI_URL_OPEN_ROOT, + CMI_MAX // this item shall be the last one +}; + +struct FileTransferParam +{ + HANDLE hProcess; + PROTOFILETRANSFERSTATUS pfts; + + FileTransferParam() + { + pfts.cbSize = sizeof(this->pfts); + pfts.flags = PFTS_UTF; + pfts.currentFileNumber = 0; + pfts.currentFileProgress = 0; + pfts.currentFileSize = 0; + pfts.currentFileTime = 0; + pfts.totalBytes = 0; + pfts.totalFiles = 0; + pfts.totalProgress = 0; + pfts.tszWorkingDir = NULL; + pfts.wszCurrentFile = NULL; + } + + ~FileTransferParam() + { + for (int i = 0; pfts.pszFiles[pfts.totalFiles]; i++) + { + delete pfts.pszFiles[i]; + } + delete pfts.pszFiles; + } +}; + +class CDropbox +{ +public: + CDropbox(); + ~CDropbox() { } + +private: + HANDLE hNetlibUser; + ULONG hFileProcess; + + static HGENMENU ContactMenuItems[CMI_MAX]; + + // hooks + static int OnModulesLoaded(WPARAM wParam, LPARAM lParam); + static int OnOptionsInit(WPARAM wParam, LPARAM lParam); + + // services + static INT_PTR GetCaps(WPARAM wParam, LPARAM lParam); + static INT_PTR SendFile(WPARAM wParam, LPARAM lParam); + static INT_PTR SendMessage(WPARAM wParam, LPARAM lParam); + + static INT_PTR RequeriedApiAccess(WPARAM wParam, LPARAM lParam); + + // access token + static bool HasAccessToken(); + + void RequestAcceessToken(); + void DestroyAcceessToken(); + + // transrers + HttpRequest *CreateFileSendChunkedRequest(const char *data, int length); + void SendFileChunkedFirst(const char *data, int length, char *uploadId, int &offset); + void SendFileChunkedNext(const char *data, int length, const char *uploadId, int &offset); + void SendFileChunkedLast(const char *fileName, const char *uploadId, MCONTACT hContact); + + static void _cdecl SendFileAsync(void *arg); + + // contacts + static MCONTACT GetDefaultContact(); + + // icons + static void InitIcons(); + + // menus + static void InitMenus(); + + // dialogs + static INT_PTR CALLBACK TokenRequestProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK MainOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + + // utils + void ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, MCONTACT hContact = NULL); + void ShowNotification(const wchar_t *message, int flags = 0, MCONTACT hContact = NULL); +}; + +#endif //_Dropbox_PROTO_H_ \ No newline at end of file diff --git a/plugins/DropBox/src/dropbox_dialogs.cpp b/plugins/DropBox/src/dropbox_dialogs.cpp new file mode 100644 index 0000000000..1bbe8af20c --- /dev/null +++ b/plugins/DropBox/src/dropbox_dialogs.cpp @@ -0,0 +1,62 @@ +#include "dropbox.h" + +INT_PTR CALLBACK CDropbox::TokenRequestProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char *token = reinterpret_cast(::GetWindowLongPtr(hwndDlg, GWLP_USERDATA)); + + switch (msg) + { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + + token = (char*)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); + { + //::SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)CSkypeProto::IconList[0].Handle); + //::SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)CSkypeProto::IconList[0].Handle); + + /*wchar_t title[MAX_PATH]; + ::mir_sntprintf( + title, + MAX_PATH, + ::TranslateT("Enter a password for %s:"), + param->login);*/ + //::SetDlgItemText(hwndDlg, IDC_INSTRUCTION, title); + + SendDlgItemMessage(hwndDlg, IDC_TOKEN, EM_LIMITTEXT, 128 - 1, 0); + } + break; + + case WM_CLOSE: + EndDialog(hwndDlg, 0); + break; + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + { + char data[128]; + GetDlgItemTextA(hwndDlg, IDC_TOKEN, data, SIZEOF(data)); + strcpy(token, data); + + EndDialog(hwndDlg, IDOK); + } + break; + + case IDCANCEL: + EndDialog(hwndDlg, IDCANCEL); + break; + } + } + break; + } + + return FALSE; +} + +INT_PTR CALLBACK CDropbox::MainOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + return FALSE; +} \ No newline at end of file diff --git a/plugins/DropBox/src/dropbox_events.cpp b/plugins/DropBox/src/dropbox_events.cpp new file mode 100644 index 0000000000..83ee861712 --- /dev/null +++ b/plugins/DropBox/src/dropbox_events.cpp @@ -0,0 +1,40 @@ +#include "dropbox.h" + +int CDropbox::OnModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + NETLIBUSER nlu = { sizeof(nlu) }; + nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; + nlu.szSettingsModule = MODULE; + nlu.szSettingsModule = MODULE; + nlu.ptszDescriptiveName = L"Dropbox"; + + g_dropbox->hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); + + MCONTACT hContact = GetDefaultContact(); + if (!hContact) + { + hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0); + if (!CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)MODULE)) + { + db_set_s(hContact, MODULE, "Nick", MODULE); + } + } + + return 0; +} + +int CDropbox::OnOptionsInit(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.position = 100000000; + odp.hInstance = g_hInstance; + odp.flags = ODPF_BOLDGROUPS; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_MAIN); + odp.pszGroup = LPGEN("Network"); + odp.pszTitle = LPGEN("Dropbox"); + odp.pfnDlgProc = MainOptionsProc; + + //Options_AddPage(wParam, &odp); + + return 0; +} \ No newline at end of file diff --git a/plugins/DropBox/src/dropbox_icons.cpp b/plugins/DropBox/src/dropbox_icons.cpp new file mode 100644 index 0000000000..c781369f8e --- /dev/null +++ b/plugins/DropBox/src/dropbox_icons.cpp @@ -0,0 +1,33 @@ +#include "dropbox.h" + +void CDropbox::InitIcons() +{ + wchar_t filePath[MAX_PATH]; + GetModuleFileName(g_hInstance, filePath, MAX_PATH); + + wchar_t sectionName[100]; + mir_sntprintf( + sectionName, + SIZEOF(sectionName), + _T("%s/%s"), + LPGENT("Protocols"), + LPGENT(MODULE)); + + char settingName[100]; + mir_snprintf( + settingName, + SIZEOF(settingName), + "%s_%s", + MODULE, + "main"); + + SKINICONDESC sid = {0}; + sid.cbSize = sizeof(SKINICONDESC); + sid.flags = SIDF_ALL_TCHAR; + sid.ptszDefaultFile = filePath; + sid.pszName = settingName; + sid.ptszSection = sectionName; + sid.ptszDescription = LPGENT("Protocol icon"); + sid.iDefaultIndex = -IDI_DROPBOX; + /*HANDLE hIcon = */Skin_AddIcon(&sid); +} \ No newline at end of file diff --git a/plugins/DropBox/src/dropbox_menus.cpp b/plugins/DropBox/src/dropbox_menus.cpp new file mode 100644 index 0000000000..fe20bddf1d --- /dev/null +++ b/plugins/DropBox/src/dropbox_menus.cpp @@ -0,0 +1,17 @@ +#include "dropbox.h" + +HGENMENU CDropbox::ContactMenuItems[CMI_MAX]; + +void CDropbox::InitMenus() +{ + CLISTMENUITEM mi = { 0 }; + mi.cbSize = sizeof(CLISTMENUITEM); + mi.flags = CMIF_TCHAR; + + mi.pszService = MODULE"/RequeriedAccess"; + mi.ptszName = LPGENT("Requeried access"); + mi.position = -201001000 + CMI_API_ACCESS_REQUERIED; + mi.icolibItem = LoadSkinnedIconHandle(SKINICON_AUTH_REVOKE); + ContactMenuItems[CMI_API_ACCESS_REQUERIED] = Menu_AddContactMenuItem(&mi); + CreateServiceFunction(mi.pszService, RequeriedApiAccess); +} \ No newline at end of file diff --git a/plugins/DropBox/src/dropbox_services.cpp b/plugins/DropBox/src/dropbox_services.cpp new file mode 100644 index 0000000000..0524cff1c7 --- /dev/null +++ b/plugins/DropBox/src/dropbox_services.cpp @@ -0,0 +1,82 @@ +#include "dropbox.h" + +INT_PTR CDropbox::GetCaps(WPARAM wParam, LPARAM lParam) +{ + switch(wParam) + { + case PFLAGNUM_1: + return PF1_IM | PF1_FILESEND | PF1_AUTHREQ; + case PFLAGNUM_2: + return PF2_ONLINE; + case PFLAGNUM_4: + return PF4_FORCEAUTH; + case PFLAG_UNIQUEIDTEXT: + return (INT_PTR)MODULE " ID"; + case PFLAG_UNIQUEIDSETTING: + return (DWORD_PTR)"uid"; + } + + return 0; +} + +INT_PTR CDropbox::SendFile(WPARAM wParam, LPARAM lParam) +{ + CCSDATA *pccsd = (CCSDATA*)lParam; + + FileTransferParam *ftp = new FileTransferParam(); + ftp->pfts.flags = PFTS_SENDING | PFTS_UTF; + ftp->pfts.hContact = pccsd->hContact; + + char **files = (char**)pccsd->lParam; + + for (int i = 0; files[i]; i++) + { + if (PathIsDirectoryA(files[i])) + continue; + ftp->pfts.totalFiles++; + } + + ftp->pfts.pszFiles = new char*[ftp->pfts.totalFiles + 1]; + ftp->pfts.pszFiles[ftp->pfts.totalFiles] = NULL; + for (int i = 0, j = 0; files[i]; i++) + { + if (PathIsDirectoryA(files[i])) + continue; + + ftp->pfts.pszFiles[j] = mir_strdup(files[i]); + + FILE *file = fopen(files[j], "rb"); + if (file != NULL) + { + fseek(file, 0, SEEK_END); + ftp->pfts.totalBytes += ftell(file); + fseek(file, 0, SEEK_SET); + fclose(file); + } + + j++; + } + ULONG fileId = InterlockedIncrement(&g_dropbox->hFileProcess); + ftp->hProcess = (HANDLE)fileId; + + mir_forkthread(CDropbox::SendFileAsync, ftp); + + return fileId; +} + +INT_PTR CDropbox::SendMessage( WPARAM wParam, LPARAM lParam) +{ + return 0; +} + +INT_PTR CDropbox::RequeriedApiAccess(WPARAM wParam, LPARAM lParam) +{ + int result = MessageBox(NULL, TranslateT("Are you sure you want to requeried access?"), TranslateT("Requeried access"), MB_YESNO | MB_ICONQUESTION); + if (result == IDYES && g_dropbox->HasAccessToken()) + { + g_dropbox->DestroyAcceessToken(); + g_dropbox->RequestAcceessToken(); + } + + return 0; +} \ No newline at end of file diff --git a/plugins/DropBox/src/dropbox_transfers.cpp b/plugins/DropBox/src/dropbox_transfers.cpp new file mode 100644 index 0000000000..550e6b7e64 --- /dev/null +++ b/plugins/DropBox/src/dropbox_transfers.cpp @@ -0,0 +1,210 @@ +#include "dropbox.h" + +HttpRequest *CDropbox::CreateFileSendChunkedRequest(const char *data, int length) +{ + HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_PUT, DROPBOX_APICONTENT_URL "/chunked_upload"); + request->AddParameter("access_token", db_get_sa(NULL, MODULE, "TokenSecret")); + if (length > 0) + { + request->AddHeader("Content-Type", "application/octet-stream"); + request->dataLength = length; + request->pData = (char*)mir_alloc(sizeof(char) * (length + 1)); + memcpy(request->pData, data, length); + request->pData[length] = 0; + } + + return request; +} + +void CDropbox::SendFileChunkedFirst(const char *data, int length, char *uploadId, int &offset) +{ + HttpRequest *request = CreateFileSendChunkedRequest(data, length); + NETLIBHTTPREQUEST *response = request->Send(); + + delete request; + + if (response) + { + if (response->resultCode == HttpStatus::OK) + { + JSONNODE *root = json_parse(response->pData); + if (root != NULL) + { + JSONNODE *node = json_get(root, "upload_id"); + strcpy(uploadId, mir_u2a(json_as_string(node))); + + node = json_get(root, "offset"); + offset = json_as_int(node); + + delete node; + delete root; + } + } + + mir_free(response); + } +} + +void CDropbox::SendFileChunkedNext(const char *data, int length, const char *uploadId, int &offset) +{ + HttpRequest *request = CreateFileSendChunkedRequest(data, length); + request->AddParameter("upload_id", uploadId); + request->AddParameter("offset", offset); + + NETLIBHTTPREQUEST *response = request->Send(); + + delete request; + + if (response) + { + if (response->resultCode == HttpStatus::OK) + { + JSONNODE *root = json_parse(response->pData); + if (root != NULL) + { + JSONNODE *node = json_get(root, "offset"); + offset = json_as_int(node); + + delete node; + delete root; + } + } + + mir_free(response); + } +} + +void CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId, MCONTACT hContact) +{ + char url[MAX_PATH]; + mir_snprintf( + url, + SIZEOF(url), + "%s/commit_chunked_upload/%s/%s", + DROPBOX_APICONTENT_URL, + DROPBOX_API_ROOT, + fileName); + + HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, url); + request->AddParameter("upload_id", uploadId); + request->AddParameter("access_token", db_get_sa(NULL, MODULE, "TokenSecret")); + + NETLIBHTTPREQUEST *response = request->Send(); + + delete request; + + if (response && response->resultCode == HttpStatus::OK) + { + mir_snprintf( + url, + SIZEOF(url), + "%s/shares/%s/%s", + DROPBOX_API_URL, + DROPBOX_API_ROOT, + fileName); + + request = new HttpRequest(hNetlibUser, REQUEST_POST, url); + request->AddParameter("access_token", db_get_sa(NULL, MODULE, "TokenSecret")); + + mir_free(response); + + response = request->Send(); + + if (response) + { + if (response->resultCode == HttpStatus::OK) + { + JSONNODE *root = json_parse(response->pData); + if (root != NULL) + { + JSONNODE *node = json_get(root, "url"); + char message[1024]; + mir_snprintf( + message, + SIZEOF(message), + Translate("Link to download file \"%s\": %s"), + fileName, + mir_utf8encodeW(json_as_string(node))); + + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.szModule = MODULE; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = strlen(message); + dbei.pBlob = (PBYTE)mir_strdup(message); + dbei.flags = DBEF_UTF; + ::db_event_add(hContact, &dbei); + + delete node; + delete root; + } + } + + mir_free(response); + } + } +} + +void _cdecl CDropbox::SendFileAsync(void *arg) +{ + FileTransferParam *ftp = (FileTransferParam *)arg; + + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ftp->hProcess, 0); + + for (int i = 0; ftp->pfts.pszFiles[i]; i++) + { + FILE *file = fopen(ftp->pfts.pszFiles[i], "rb"); + if (file != NULL) + { + int offset = 0; + char *uploadId = new char[32]; + + const char *fileName = strrchr(ftp->pfts.pszFiles[i], '\\') + 1; + + fseek(file, 0, SEEK_END); + DWORD fileSize = ftell(file); + fseek(file, 0, SEEK_SET); + + ftp->pfts.currentFileNumber = i; + ftp->pfts.currentFileSize = fileSize; + ftp->pfts.currentFileProgress = 0; + ftp->pfts.szCurrentFile = strrchr(ftp->pfts.pszFiles[i], '\\') + 1; + + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftp->hProcess, (LPARAM)&ftp->pfts); + + while (!feof(file) && !ferror(file)) + { + int chunkSize = DROPBOX_FILE_CHUNK_SIZE; + if (fileSize < 1024*1024) + chunkSize = DROPBOX_FILE_CHUNK_SIZE / 5; + else if (fileSize > 20*1024*1024) + chunkSize = DROPBOX_FILE_CHUNK_SIZE * 4; + + char *data = new char[chunkSize + 1]; + size_t count = fread(data, sizeof(char), chunkSize, file); + + if (!offset) + g_dropbox->SendFileChunkedFirst(data, count, uploadId, offset); + else + g_dropbox->SendFileChunkedNext(data, count, uploadId, offset); + + ftp->pfts.currentFileProgress += count; + ftp->pfts.totalProgress += count; + + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftp->hProcess, (LPARAM)&ftp->pfts); + } + + fclose(file); + + g_dropbox->SendFileChunkedLast(fileName, uploadId, ftp->pfts.hContact); + ftp->pfts.currentFileProgress = ftp->pfts.currentFileSize; + + if (i < ftp->pfts.totalFiles - 1) + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ftp->hProcess, 0); + } + } + + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftp->hProcess, 0); + + delete ftp; +} \ No newline at end of file diff --git a/plugins/DropBox/src/dropbox_utils.cpp b/plugins/DropBox/src/dropbox_utils.cpp new file mode 100644 index 0000000000..caf4d9c980 --- /dev/null +++ b/plugins/DropBox/src/dropbox_utils.cpp @@ -0,0 +1,26 @@ +#include "dropbox.h" + +void CDropbox::ShowNotification(const wchar_t *caption, const wchar_t *message, int flags, MCONTACT hContact) +{ + if (Miranda_Terminated()) return; + + if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1)) + { + POPUPDATAW ppd = {0}; + ppd.lchContact = hContact; + wcsncpy(ppd.lpwzContactName, caption, MAX_CONTACTNAME); + wcsncpy(ppd.lpwzText, message, MAX_SECONDLINE); + ppd.lchIcon = Skin_GetIcon("Skype_main"); + + if (!PUAddPopupW(&ppd)) + return; + + } + + MessageBox(NULL, message, caption, MB_OK | flags); +} + +void CDropbox::ShowNotification(const wchar_t *message, int flags, MCONTACT hContact) +{ + ShowNotification(TranslateT(MODULE), message, flags, hContact); +} \ No newline at end of file diff --git a/plugins/DropBox/src/http_request.h b/plugins/DropBox/src/http_request.h index 582de2fa83..b17ef16b58 100644 --- a/plugins/DropBox/src/http_request.h +++ b/plugins/DropBox/src/http_request.h @@ -3,6 +3,11 @@ #include "common.h" +enum HttpStatus +{ + OK = 200 +}; + class HttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject { public: diff --git a/plugins/DropBox/src/main.cpp b/plugins/DropBox/src/main.cpp index 5c33cd74a1..da1ccca07f 100644 --- a/plugins/DropBox/src/main.cpp +++ b/plugins/DropBox/src/main.cpp @@ -1,7 +1,9 @@ -#include "common.h" +//#include "common.h" +#include "dropbox.h" int hLangpack; HINSTANCE g_hInstance; +CDropbox *g_dropbox; PLUGININFOEX pluginInfo = { @@ -37,25 +39,14 @@ extern "C" int __declspec(dllexport) Load(void) { mir_getLP(&pluginInfo); - HookEvent(ME_OPT_INITIALISE, OnOptionsInit); - HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); - - PROTOCOLDESCRIPTOR pd = { PROTOCOLDESCRIPTOR_V3_SIZE }; - pd.szName = MODULE; - pd.type = PROTOTYPE_VIRTUAL; - - CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); - - CreateProtoServiceFunction(MODULE, PS_GETCAPS, DropBoxGetCaps); - - CreateProtoServiceFunction(MODULE, PSS_FILE, DropBoxSendFile); - - CreateProtoServiceFunction(MODULE, PSS_MESSAGE, DropBoxSendMessage); + g_dropbox = new CDropbox(); return 0; } extern "C" int __declspec(dllexport) Unload(void) { + delete g_dropbox; + return 0; } \ No newline at end of file diff --git a/plugins/DropBox/src/resource.h b/plugins/DropBox/src/resource.h index 4b1586d386..50deccd319 100644 Binary files a/plugins/DropBox/src/resource.h and b/plugins/DropBox/src/resource.h differ diff --git a/plugins/DropBox/src/stdafx.cpp b/plugins/DropBox/src/stdafx.cpp deleted file mode 100644 index 2aa7ce281e..0000000000 --- a/plugins/DropBox/src/stdafx.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright (C) 2012-14 Miranda NG project (http://miranda-ng.org) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "common.h" \ No newline at end of file diff --git a/plugins/DropBox/src/version.h b/plugins/DropBox/src/version.h index 65107a26a2..178ef67ee7 100644 --- a/plugins/DropBox/src/version.h +++ b/plugins/DropBox/src/version.h @@ -1,15 +1,15 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 11 #define __RELEASE_NUM 0 -#define __BUILD_NUM 0 +#define __BUILD_NUM 1 #include -#define __PLUGIN_NAME "DropBox" -#define __INTERNAL_NAME "DropBox" -#define __FILENAME "DropBox.dll" -#define __DESCRIPTION "Provides ability to upload files on DropBox." +#define __PLUGIN_NAME "Dropbox" +#define __INTERNAL_NAME "Dropbox" +#define __FILENAME "Dropbox.dll" +#define __DESCRIPTION "Provides ability to upload files on Dropbox." #define __AUTHOR "unsane" #define __AUTHOREMAIL "" -#define __AUTHORWEB "http://miranda-ng.org/p/DropBox/" +#define __AUTHORWEB "http://miranda-ng.org/p/Dropbox/" #define __COPYRIGHT "© 2014 Miranda NG project" -- cgit v1.2.3