summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Lantsev <aunsane@gmail.com>2014-02-24 17:38:35 +0000
committerAlexander Lantsev <aunsane@gmail.com>2014-02-24 17:38:35 +0000
commite62bc2a6f28f6a7b7fcb3996e9fab86fae3239f7 (patch)
tree6fc970809eb2fbbbf383c1639f83c93a2edf406b
parent994443d6cdca5a5a1204575a0cea2a198c9d01bb (diff)
Dropbox:
- added ability to send files to contacts of other protocols - many other little improvements git-svn-id: http://svn.miranda-ng.org/main/trunk@8263 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--plugins/Dropbox/Dropbox_11.vcxproj1
-rw-r--r--plugins/Dropbox/Dropbox_11.vcxproj.filters3
-rw-r--r--plugins/Dropbox/src/common.h10
-rw-r--r--plugins/Dropbox/src/dropbox.cpp31
-rw-r--r--plugins/Dropbox/src/dropbox.h70
-rw-r--r--plugins/Dropbox/src/dropbox_events.cpp65
-rw-r--r--plugins/Dropbox/src/dropbox_menus.cpp39
-rw-r--r--plugins/Dropbox/src/dropbox_services.cpp100
-rw-r--r--plugins/Dropbox/src/dropbox_transfers.cpp102
-rw-r--r--plugins/Dropbox/src/dropbox_utils.cpp31
-rw-r--r--plugins/Dropbox/src/file_transfer.h57
-rw-r--r--plugins/Dropbox/src/http_request.h16
12 files changed, 336 insertions, 189 deletions
diff --git a/plugins/Dropbox/Dropbox_11.vcxproj b/plugins/Dropbox/Dropbox_11.vcxproj
index cdd3d7aae4..16db020481 100644
--- a/plugins/Dropbox/Dropbox_11.vcxproj
+++ b/plugins/Dropbox/Dropbox_11.vcxproj
@@ -188,6 +188,7 @@
<ItemGroup>
<ClInclude Include="src\common.h" />
<ClInclude Include="src\dropbox.h" />
+ <ClInclude Include="src\file_transfer.h" />
<ClInclude Include="src\http_request.h" />
<ClInclude Include="src\resource.h" />
<ClInclude Include="src\singleton.h" />
diff --git a/plugins/Dropbox/Dropbox_11.vcxproj.filters b/plugins/Dropbox/Dropbox_11.vcxproj.filters
index ad97939cf2..6f2103fb99 100644
--- a/plugins/Dropbox/Dropbox_11.vcxproj.filters
+++ b/plugins/Dropbox/Dropbox_11.vcxproj.filters
@@ -51,6 +51,9 @@
<ClInclude Include="src\singleton.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\file_transfer.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
diff --git a/plugins/Dropbox/src/common.h b/plugins/Dropbox/src/common.h
index d30863a33b..faa1e30302 100644
--- a/plugins/Dropbox/src/common.h
+++ b/plugins/Dropbox/src/common.h
@@ -13,6 +13,12 @@
#include <m_skin.h>
#include <m_icolib.h>
#include <m_popup.h>
+#include <m_file.h>
+#include <m_json.h>
+#include <m_langpack.h>
+#include <m_message.h>
+#include <m_string.h>
+#include <m_msg_buttonsbar.h>
#include <m_protoint.h>
#include <m_protomod.h>
@@ -20,10 +26,6 @@
#include <m_netlib.h>
-#include <m_json.h>
-#include <m_langpack.h>
-#include <m_string.h>
-
#include "version.h"
#include "resource.h"
#include "dropbox.h"
diff --git a/plugins/Dropbox/src/dropbox.cpp b/plugins/Dropbox/src/dropbox.cpp
index 9bbee6b9f5..41c53d22a4 100644
--- a/plugins/Dropbox/src/dropbox.cpp
+++ b/plugins/Dropbox/src/dropbox.cpp
@@ -9,6 +9,8 @@ void CDropbox::Init()
HookEvent(ME_OPT_INITIALISE, OnOptionsInit);
HookEvent(ME_SYSTEM_MODULESLOADED, CDropbox::OnModulesLoaded);
+ HookEvent(ME_DB_CONTACT_DELETED, CDropbox::OnContactDeleted);
+ HookEvent(ME_CLIST_PREBUILDCONTACTMENU, CDropbox::OnPrebuildContactMenu);
CreateProtoServiceFunction(MODULE, PS_GETCAPS, CDropbox::ProtoGetCaps);
CreateProtoServiceFunction(MODULE, PSS_FILE, CDropbox::ProtoSendFile);
@@ -16,11 +18,18 @@ void CDropbox::Init()
InitIcons();
InitMenus();
+
+ INSTANCE->hContactTransfer = 0;
}
+MCONTACT CDropbox::hContactDefault = 0;
+
MCONTACT CDropbox::GetDefaultContact()
{
- return db_find_first(MODULE);
+ if (!hContactDefault)
+ hContactDefault = db_find_first(MODULE);
+
+ return hContactDefault;
}
bool CDropbox::HasAccessToken()
@@ -41,9 +50,17 @@ void CDropbox::RequestAcceessToken(MCONTACT hContact)
CDropbox::TokenRequestProc,
(LPARAM)&request_token) == IDOK)
{
+ char data[1024];
+ mir_snprintf(
+ data,
+ SIZEOF(data),
+ Translate("grant_type=authorization_code&code=%s"),
+ request_token);
+
HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, DROPBOX_API_URL "/oauth2/token");
- request->AddParameter("grant_type", "authorization_code");
- request->AddParameter("code", request_token);
+ request->pData = mir_strdup(data);
+ request->dataLength = strlen(data);
+ request->AddHeader("Content-Type", "application/x-www-form-urlencoded");
request->AddBasicAuthHeader(DROPBOX_API_KEY, DROPBOX_API_SECRET);
NETLIBHTTPREQUEST *response = request->Send();
@@ -52,7 +69,7 @@ void CDropbox::RequestAcceessToken(MCONTACT hContact)
if (response)
{
- if (response->resultCode == HttpStatus::OK)
+ if (response->resultCode == HTTP_STATUS::OK)
{
JSONNODE *root = json_parse(response->pData);
if (root != NULL)
@@ -122,9 +139,9 @@ void CDropbox::RequestApiAuthorizationAsync(void *arg)
TranslateT("Request athorization"),
MB_YESNO | MB_ICONQUESTION) == IDYES)
{
- Singleton<CDropbox>::GetInstance()->DestroyAcceessToken(hContact);
- Singleton<CDropbox>::GetInstance()->RequestAcceessToken(hContact);
+ INSTANCE->DestroyAcceessToken(hContact);
+ INSTANCE->RequestAcceessToken(hContact);
}
else
- Singleton<CDropbox>::GetInstance()->RequestAcceessToken(hContact);
+ INSTANCE->RequestAcceessToken(hContact);
} \ No newline at end of file
diff --git a/plugins/Dropbox/src/dropbox.h b/plugins/Dropbox/src/dropbox.h
index 09f162302f..72af0114ee 100644
--- a/plugins/Dropbox/src/dropbox.h
+++ b/plugins/Dropbox/src/dropbox.h
@@ -1,8 +1,10 @@
#ifndef _DROPBOX_PROTO_H_
#define _DROPBOX_PROTO_H_
+#include <map>
#include "singleton.h"
#include "http_request.h"
+#include "file_transfer.h"
#define DROPBOX_API_VER "1"
#define DROPBOX_API_ROOT "sandbox"
@@ -15,6 +17,10 @@
#define DROPBOX_FILE_CHUNK_SIZE 1024 * 1024 //1 MB
+#define BBB_ID_FILE_SEND 10001
+
+#define INSTANCE Singleton<CDropbox>::GetInstance()
+
enum
{
CMI_API_REQUEST_AUTH,
@@ -22,56 +28,6 @@ enum
CMI_MAX // this item shall be the last one
};
-struct FileTransferParam
-{
- HANDLE hProcess;
- PROTOFILETRANSFERSTATUS pfts;
-
- int totalFolders;
- char **pszFolders;
- int relativePathStart;
-
- FileTransferParam()
- {
- totalFolders = 0;
- pszFolders = NULL;
- relativePathStart = 0;
-
- pfts.cbSize = sizeof(this->pfts);
- pfts.flags = PFTS_UTF;
- pfts.currentFileNumber = 0;
- pfts.currentFileProgress = 0;
- pfts.currentFileSize = 0;
- pfts.totalBytes = 0;
- pfts.totalFiles = 0;
- pfts.totalProgress = 0;
- pfts.pszFiles = NULL;
- pfts.tszWorkingDir = NULL;
- pfts.wszCurrentFile = NULL;
- }
-
- ~FileTransferParam()
- {
- if (pfts.pszFiles)
- {
- for (int i = 0; pfts.pszFiles[i]; i++)
- {
- if (pfts.pszFiles[i]) mir_free(pfts.pszFiles[i]);
- }
- delete pfts.pszFiles;
- }
-
- if (pszFolders)
- {
- for (int i = 0; pszFolders[i]; i++)
- {
- if (pszFolders[i]) mir_free(pszFolders[i]);
- }
- delete pszFolders;
- }
- }
-};
-
class CDropbox
{
public:
@@ -81,12 +37,22 @@ public:
private:
HANDLE hNetlibUser;
ULONG hFileProcess;
+ MCONTACT hContactTransfer;
+
+ static MCONTACT hContactDefault;
+ static std::map<HWND, MCONTACT> dcftp;
static HGENMENU ContactMenuItems[CMI_MAX];
// hooks
static int OnModulesLoaded(WPARAM wParam, LPARAM lParam);
static int OnOptionsInit(WPARAM wParam, LPARAM lParam);
+ static int OnContactDeleted(WPARAM wParam, LPARAM lParam);
+ static int OnPrebuildContactMenu(WPARAM wParam, LPARAM);
+ static int OnSrmmWindowOpened(WPARAM wParam, LPARAM);
+ static int OnSrmmButtonPressed(WPARAM wParam, LPARAM);
+ static int OnFileDoalogCancelled(WPARAM wParam, LPARAM);
+ static int OnFileDoalogSuccessed(WPARAM wParam, LPARAM);
// services
static INT_PTR ProtoGetCaps(WPARAM wParam, LPARAM lParam);
@@ -106,7 +72,6 @@ private:
static void RequestApiAuthorizationAsync(void *arg);
// 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);
@@ -123,12 +88,15 @@ private:
// menus
static void InitMenus();
+ static void Menu_DisableItem(HGENMENU hMenuItem, BOOL bDisable);
// 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
+ static wchar_t *HttpStatusToText(HTTP_STATUS status);
+
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);
};
diff --git a/plugins/Dropbox/src/dropbox_events.cpp b/plugins/Dropbox/src/dropbox_events.cpp
index 02e2a788bd..b670370ae2 100644
--- a/plugins/Dropbox/src/dropbox_events.cpp
+++ b/plugins/Dropbox/src/dropbox_events.cpp
@@ -2,13 +2,16 @@
int CDropbox::OnModulesLoaded(WPARAM wParam, LPARAM lParam)
{
+ HookEvent(ME_FILEDLG_CANCELED, CDropbox::OnFileDoalogCancelled);
+ HookEvent(ME_FILEDLG_SUCCEEDED, CDropbox::OnFileDoalogSuccessed);
+
NETLIBUSER nlu = { sizeof(nlu) };
nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR;
nlu.szSettingsModule = MODULE;
nlu.szSettingsModule = MODULE;
nlu.ptszDescriptiveName = L"Dropbox";
- Singleton<CDropbox>::GetInstance()->hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
+ INSTANCE->hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
MCONTACT hContact = GetDefaultContact();
if (!hContact)
@@ -20,6 +23,22 @@ int CDropbox::OnModulesLoaded(WPARAM wParam, LPARAM lParam)
}
}
+ if (ServiceExists(MS_BB_ADDBUTTON))
+ {
+ BBButton bbd = { sizeof(bbd) };
+ bbd.pszModuleName = MODULE;
+
+ bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISRSIDEBUTTON;
+ bbd.ptszTooltip = TranslateT("Send files to Dropbox");
+ bbd.hIcon = LoadSkinnedIconHandle(SKINICON_EVENT_FILE);
+ bbd.dwButtonID = BBB_ID_FILE_SEND;
+ bbd.dwDefPos = 100 + bbd.dwButtonID;
+ CallService(MS_BB_ADDBUTTON, 0, (LPARAM)&bbd);
+
+ HookEvent(ME_MSG_WINDOWEVENT, CDropbox::OnSrmmWindowOpened);
+ HookEvent(ME_MSG_BUTTONPRESSED, CDropbox::OnSrmmButtonPressed);
+ }
+
return 0;
}
@@ -37,4 +56,48 @@ int CDropbox::OnOptionsInit(WPARAM wParam, LPARAM lParam)
//Options_AddPage(wParam, &odp);
return 0;
+}
+
+int CDropbox::OnContactDeleted(WPARAM hContact, LPARAM lParam)
+{
+ if (lstrcmpiA(GetContactProto(hContact), MODULE) == 0)
+ {
+ if (INSTANCE->HasAccessToken())
+ INSTANCE->DestroyAcceessToken(hContact);
+ }
+
+ return 0;
+}
+
+int CDropbox::OnSrmmWindowOpened(WPARAM hContact, LPARAM lParam)
+{
+ MessageWindowEventData *ev = (MessageWindowEventData*)lParam;
+ if (ev->uType == MSG_WINDOW_EVT_OPENING && ev->hContact)
+ {
+ WORD status = CallContactService(hContact, PS_GETSTATUS, 0, 0);
+
+ BBButton bbd = { sizeof(bbd) };
+ bbd.pszModuleName = MODULE;
+ bbd.bbbFlags = (ev->hContact != INSTANCE->GetDefaultContact() || status == ID_STATUS_OFFLINE) ? 0 : BBSF_HIDDEN | BBSF_DISABLED;
+
+ bbd.dwButtonID = BBB_ID_FILE_SEND;
+ CallService(MS_BB_SETBUTTONSTATE, (WPARAM)ev->hContact, (LPARAM)&bbd);
+ }
+
+ return 0;
+}
+
+int CDropbox::OnSrmmButtonPressed(WPARAM hContact, LPARAM lParam)
+{
+ CustomButtonClickData *cbc = (CustomButtonClickData *)lParam;
+ if (!strcmp(cbc->pszModule, MODULE) && cbc->dwButtonId == BBB_ID_FILE_SEND && hContact)
+ {
+ INSTANCE->hContactTransfer = hContact;
+
+ HWND hwnd = (HWND)CallService(MS_FILE_SENDFILE, INSTANCE->GetDefaultContact(), 0);
+
+ dcftp[hwnd] = hContact;
+ }
+
+ return 0;
} \ No newline at end of file
diff --git a/plugins/Dropbox/src/dropbox_menus.cpp b/plugins/Dropbox/src/dropbox_menus.cpp
index aff00f4187..f510858240 100644
--- a/plugins/Dropbox/src/dropbox_menus.cpp
+++ b/plugins/Dropbox/src/dropbox_menus.cpp
@@ -8,12 +8,12 @@ void CDropbox::InitMenus()
mi.cbSize = sizeof(CLISTMENUITEM);
mi.flags = CMIF_TCHAR;
- /*mi.pszService = MODULE"/SendFilesToDropbox";
+ mi.pszService = MODULE"/SendFilesToDropbox";
mi.ptszName = LPGENT("Send files to Dropbox");
- mi.position = -201000000 + CMI_SEND_FILES;
+ mi.position = -201002000 + CMI_SEND_FILES;
mi.icolibItem = LoadSkinnedIconHandle(SKINICON_EVENT_FILE);
ContactMenuItems[CMI_SEND_FILES] = Menu_AddContactMenuItem(&mi);
- CreateServiceFunction(mi.pszService, SendFilesToDropbox);*/
+ CreateServiceFunction(mi.pszService, SendFilesToDropbox);
mi.pszService = MODULE"/RequestAuthorization";
mi.ptszName = LPGENT("Request Authorization");
@@ -21,4 +21,37 @@ void CDropbox::InitMenus()
mi.icolibItem = LoadSkinnedIconHandle(SKINICON_AUTH_REQUEST);
ContactMenuItems[CMI_API_REQUEST_AUTH] = Menu_AddContactMenuItem(&mi);
CreateServiceFunction(mi.pszService, RequestApiAuthorization);
+}
+
+void CDropbox::Menu_DisableItem(HGENMENU hMenuItem, BOOL bDisable)
+{
+ CLISTMENUITEM clmi = { sizeof(clmi) };
+ clmi.cbSize = sizeof(CLISTMENUITEM);
+ clmi.flags = CMIM_FLAGS;
+ if (bDisable)
+ clmi.flags |= CMIF_GRAYED;
+
+ Menu_ModifyItem(hMenuItem, &clmi);
+}
+
+int CDropbox::OnPrebuildContactMenu(WPARAM hContact, LPARAM lParam)
+{
+ if ( !hContact)
+ return 0;
+
+ //bool ctrlPressed = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ WORD status = CallContactService(hContact, PS_GETSTATUS, 0, 0);
+
+ if (hContact == INSTANCE->GetDefaultContact() || status == ID_STATUS_OFFLINE)
+ Menu_ShowItem(INSTANCE->ContactMenuItems[CMI_SEND_FILES], FALSE);
+ else
+ {
+ Menu_DisableItem(INSTANCE->ContactMenuItems[CMI_SEND_FILES], INSTANCE->hContactTransfer);
+ if (strcmp(GetContactProto(hContact), MODULE))
+ {
+ Menu_ShowItem(INSTANCE->ContactMenuItems[CMI_API_REQUEST_AUTH], FALSE);
+ }
+ }
+
+ return 0;
} \ No newline at end of file
diff --git a/plugins/Dropbox/src/dropbox_services.cpp b/plugins/Dropbox/src/dropbox_services.cpp
index c485779737..1ce493c25a 100644
--- a/plugins/Dropbox/src/dropbox_services.cpp
+++ b/plugins/Dropbox/src/dropbox_services.cpp
@@ -23,9 +23,11 @@ INT_PTR CDropbox::ProtoSendFile(WPARAM wParam, LPARAM lParam)
{
CCSDATA *pccsd = (CCSDATA*)lParam;
- FileTransferParam *ftp = new FileTransferParam();
+ FileTransfer *ftp = new FileTransfer();
ftp->pfts.flags = PFTS_SENDING | PFTS_UTF;
ftp->pfts.hContact = pccsd->hContact;
+ ftp->hContact = (INSTANCE->hContactTransfer) ? INSTANCE->hContactTransfer : pccsd->hContact;
+ INSTANCE->hContactTransfer = 0;
char **files = (char**)pccsd->lParam;
@@ -73,7 +75,8 @@ INT_PTR CDropbox::ProtoSendFile(WPARAM wParam, LPARAM lParam)
k++;
}
}
- ULONG fileId = InterlockedIncrement(&Singleton<CDropbox>::GetInstance()->hFileProcess);
+
+ ULONG fileId = InterlockedIncrement(&INSTANCE->hFileProcess);
ftp->hProcess = (HANDLE)fileId;
mir_forkthread(CDropbox::SendFileAsync, ftp);
@@ -83,6 +86,19 @@ INT_PTR CDropbox::ProtoSendFile(WPARAM wParam, LPARAM lParam)
INT_PTR CDropbox::ProtoSendMessage( WPARAM wParam, LPARAM lParam)
{
+ CCSDATA *pccsd = (CCSDATA*)lParam;
+
+ char *message = (char*)pccsd->lParam;
+
+ 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(pccsd->hContact, &dbei);
+
return 0;
}
@@ -93,73 +109,33 @@ INT_PTR CDropbox::RequestApiAuthorization(WPARAM wParam, LPARAM lParam)
return 0;
}
-INT_PTR CDropbox::SendFilesToDropbox(WPARAM wParam, LPARAM lParam)
-{
- TCHAR filter[128], *pfilter;
- wchar_t buffer[4096] = {0};
-
- OPENFILENAME ofn = {0};
- ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
- //ofn.hwndOwner = hwndDlg;
- lstrcpy(filter, TranslateT("All files"));
- lstrcat(filter, _T(" (*)"));
- pfilter = filter + lstrlen(filter)+1;
- lstrcpy(pfilter, _T("*"));
- pfilter = filter + lstrlen(filter)+1;
- pfilter[ 0 ] = '\0';
- ofn.lpstrFilter = filter;
- ofn.lpstrFile = buffer;
- ofn.nMaxFile = 4096;
- ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_DONTADDTORECENT;
- if (GetOpenFileName(&ofn))
- {
- wchar_t **files = NULL;
+std::map<HWND, MCONTACT> CDropbox::dcftp;
- if (buffer[ofn.nFileOffset - 1] != '\0')
- {
- // Single-Select
- files = (wchar_t**)mir_alloc(sizeof(wchar_t*) * 2);
+INT_PTR CDropbox::SendFilesToDropbox(WPARAM hContact, LPARAM lParam)
+{
+ INSTANCE->hContactTransfer = hContact;
- files[0] = mir_wstrdup(buffer);
- files[1] = NULL;
- }
- else
- {
- // Multi-Select
- int i = 0;
- wchar_t *p = buffer;
+ HWND hwnd = (HWND)CallService(MS_FILE_SENDFILE, INSTANCE->GetDefaultContact(), 0);
- while (*p)
- {
- p += lstrlen(p) + 1;
- i++;
- }
+ dcftp[hwnd] = hContact;
- files = (wchar_t**)mir_alloc(sizeof(wchar_t*) * i);
- p = buffer; i = 0;
+ return 0;
+}
- while (*p)
- {
- p += lstrlen(p) + 1;
- if (lstrlen(p) > 0)
- {
- int len = lstrlen(buffer) + lstrlen(p) + 1;
- files[i] = (wchar_t*)mir_alloc(sizeof(wchar_t) * len);
- lstrcpy(files[i], buffer);
- lstrcat(files[i], L"\\");
- lstrcat(files[i], p);
- files[i++][len] = '\0';
- }
- }
- files[i] = NULL;
- }
+int CDropbox::OnFileDoalogCancelled(WPARAM hContact, LPARAM lParam)
+{
+ HWND hwnd = (HWND)lParam;
+ if (INSTANCE->hContactTransfer == dcftp[hwnd])
+ dcftp.erase((HWND)lParam);
- /*char *cHandle = (char*)wParam;
- char hHandle[16]= { 0 };
- strcat(&hHandle[1], cHandle);*/
+ return 0;
+}
- CallContactService(wParam, PSS_FILET, wParam, (LPARAM)files);
- }
+int CDropbox::OnFileDoalogSuccessed(WPARAM hContact, LPARAM lParam)
+{
+ HWND hwnd = (HWND)lParam;
+ if (INSTANCE->hContactTransfer == dcftp[hwnd])
+ dcftp.erase((HWND)lParam);
return 0;
} \ No newline at end of file
diff --git a/plugins/Dropbox/src/dropbox_transfers.cpp b/plugins/Dropbox/src/dropbox_transfers.cpp
index 4d5dd7c2e6..c87d06fe15 100644
--- a/plugins/Dropbox/src/dropbox_transfers.cpp
+++ b/plugins/Dropbox/src/dropbox_transfers.cpp
@@ -1,31 +1,21 @@
#include "common.h"
-HttpRequest *CDropbox::CreateFileSendChunkedRequest(const char *data, int length)
+void CDropbox::SendFileChunkedFirst(const char *data, int length, char *uploadId, int &offset)
{
HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_PUT, DROPBOX_APICONTENT_URL "/chunked_upload");
request->AddBearerAuthHeader(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;
- }
+ request->AddHeader("Content-Type", "application/octet-stream");
+ request->pData = (char*)mir_alloc(sizeof(char) * length );
+ memcpy(request->pData, data, length);
+ request->dataLength = length;
- 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)
+ if (response->resultCode == HTTP_STATUS::OK)
{
JSONNODE *root = json_parse(response->pData);
if (root != NULL)
@@ -47,9 +37,15 @@ void CDropbox::SendFileChunkedFirst(const char *data, int length, char *uploadId
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);
+ CMStringA url = DROPBOX_APICONTENT_URL "/chunked_upload";
+ url.AppendFormat("?upload_id=%s&offset=%i", uploadId, offset);
+
+ HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_PUT, url);
+ request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret"));
+ request->AddHeader("Content-Type", "application/octet-stream");
+ request->pData = (char*)mir_alloc(sizeof(char) * length);
+ memcpy(request->pData, data, length);
+ request->dataLength = length;
NETLIBHTTPREQUEST *response = request->Send();
@@ -57,7 +53,7 @@ void CDropbox::SendFileChunkedNext(const char *data, int length, const char *upl
if (response)
{
- if (response->resultCode == HttpStatus::OK)
+ if (response->resultCode == HTTP_STATUS::OK)
{
JSONNODE *root = json_parse(response->pData);
if (root != NULL)
@@ -84,9 +80,13 @@ void CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId, M
fileName);
url.Replace('\\', '/');
+ CMStringA param = CMStringA("upload_id=") + uploadId;
+
HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, url);
- request->AddParameter("upload_id", uploadId);
request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret"));
+ request->AddHeader("Content-Type", "application/x-www-form-urlencoded");
+ request->pData = mir_strdup(param);
+ request->dataLength = param.GetLength();
NETLIBHTTPREQUEST *response = request->Send();
@@ -94,7 +94,7 @@ void CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId, M
if (response)
{
- if (response->resultCode == HttpStatus::OK && !strchr(fileName, '\\'))
+ if (response->resultCode == HTTP_STATUS::OK && !strchr(fileName, '\\'))
{
url.Replace(DROPBOX_APICONTENT_URL, DROPBOX_API_URL);
url.Replace("commit_chunked_upload", "shares");
@@ -108,12 +108,13 @@ void CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId, M
if (response)
{
- if (response->resultCode == HttpStatus::OK)
+ if (response->resultCode == HTTP_STATUS::OK)
{
JSONNODE *root = json_parse(response->pData);
if (root != NULL)
{
JSONNODE *node = json_get(root, "url");
+
char message[1024];
mir_snprintf(
message,
@@ -122,14 +123,7 @@ void CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId, M
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);
+ CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)&message);
delete node;
delete root;
@@ -149,10 +143,16 @@ void CDropbox::CreateFolder(const char *folderName, MCONTACT hContact)
CMStringA folder = folderName;
folder.Replace('\\', '/');
+ CMStringA param;
+ param.AppendFormat("root=%s&path=%s",
+ DROPBOX_API_ROOT,
+ folder);
+
HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, DROPBOX_API_URL "/fileops/create_folder");
- request->AddParameter("root", DROPBOX_API_ROOT);
- request->AddParameter("path", folderName);
request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret"));
+ request->AddHeader("Content-Type", "application/x-www-form-urlencoded");
+ request->pData = mir_strdup(param);
+ request->dataLength = param.GetLength();
NETLIBHTTPREQUEST *response = request->Send();
@@ -160,16 +160,12 @@ void CDropbox::CreateFolder(const char *folderName, MCONTACT hContact)
if (response)
{
- if (response->resultCode == HttpStatus::OK && !strchr(folderName, '\\'))
+ if (response->resultCode == HTTP_STATUS::OK && !strchr(folderName, '\\'))
{
- char url[MAX_PATH];
- mir_snprintf(
- url,
- SIZEOF(url),
- "%s/shares/%s/%s",
- DROPBOX_API_URL,
+ CMStringA url = DROPBOX_API_URL;
+ url.AppendFormat("/shares/%s/%s",
DROPBOX_API_ROOT,
- folder.GetBuffer());
+ folder);
request = new HttpRequest(hNetlibUser, REQUEST_POST, url);
request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret"));
@@ -180,7 +176,7 @@ void CDropbox::CreateFolder(const char *folderName, MCONTACT hContact)
if (response)
{
- if (response->resultCode == HttpStatus::OK)
+ if (response->resultCode == HTTP_STATUS::OK)
{
JSONNODE *root = json_parse(response->pData);
if (root != NULL)
@@ -194,14 +190,7 @@ void CDropbox::CreateFolder(const char *folderName, MCONTACT hContact)
folderName,
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);
+ CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)&message);
delete node;
delete root;
@@ -218,12 +207,12 @@ void CDropbox::CreateFolder(const char *folderName, MCONTACT hContact)
void _cdecl CDropbox::SendFileAsync(void *arg)
{
- FileTransferParam *ftp = (FileTransferParam *)arg;
+ FileTransfer *ftp = (FileTransfer*)arg;
ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ftp->hProcess, 0);
for (int i = 0; ftp->pszFolders[i]; i++)
- Singleton<CDropbox>::GetInstance()->CreateFolder(ftp->pszFolders[i], ftp->pfts.hContact);
+ INSTANCE->CreateFolder(ftp->pszFolders[i], ftp->hContact);
for (int i = 0; ftp->pfts.pszFiles[i]; i++)
{
@@ -262,9 +251,9 @@ void _cdecl CDropbox::SendFileAsync(void *arg)
int count = fread(data, sizeof(char), chunkSize, file);
if (!offset)
- Singleton<CDropbox>::GetInstance()->SendFileChunkedFirst(data, count, uploadId, offset);
+ INSTANCE->SendFileChunkedFirst(data, count, uploadId, offset);
else
- Singleton<CDropbox>::GetInstance()->SendFileChunkedNext(data, count, uploadId, offset);
+ INSTANCE->SendFileChunkedNext(data, count, uploadId, offset);
ftp->pfts.currentFileProgress += count;
ftp->pfts.totalProgress += count;
@@ -274,7 +263,7 @@ void _cdecl CDropbox::SendFileAsync(void *arg)
fclose(file);
- Singleton<CDropbox>::GetInstance()->SendFileChunkedLast(fileName, uploadId, ftp->pfts.hContact);
+ INSTANCE->SendFileChunkedLast(fileName, uploadId, ftp->hContact);
ftp->pfts.currentFileProgress = ftp->pfts.currentFileSize;
if (i < ftp->pfts.totalFiles - 1)
@@ -282,6 +271,9 @@ void _cdecl CDropbox::SendFileAsync(void *arg)
}
}
+ if (INSTANCE->hContactTransfer)
+ INSTANCE->hContactTransfer = 0;
+
ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftp->hProcess, 0);
delete ftp;
diff --git a/plugins/Dropbox/src/dropbox_utils.cpp b/plugins/Dropbox/src/dropbox_utils.cpp
index eaed860e19..cba5442ba9 100644
--- a/plugins/Dropbox/src/dropbox_utils.cpp
+++ b/plugins/Dropbox/src/dropbox_utils.cpp
@@ -1,5 +1,32 @@
#include "common.h"
+wchar_t *CDropbox::HttpStatusToText(HTTP_STATUS status)
+{
+ switch (status)
+ {
+ case OK:
+ return TranslateT("Ok");
+ case BAD_REQUEST:
+ return TranslateT("Bad input parameter. Error message should indicate which one and why");
+ case UNAUTHORIZED:
+ return TranslateT("Bad or expired token. This can happen if the user or Dropbox revoked or expired an access token. To fix, you should re-authenticate the user");
+ case FORBIDDEN:
+ return TranslateT("Bad OAuth request (wrong consumer key, bad nonce, expired timestamp...). Unfortunately, re-authenticating the user won't help here");
+ case NOT_FOUND:
+ return TranslateT("File or folder not found at the specified path");
+ case METHOD_NOT_ALLOWED:
+ return TranslateT("Request method not expected (generally should be GET or POST)");
+ case TOO_MANY_REQUESTS:
+ return TranslateT("Your app is making too many requests and is being rate limited. 429s can trigger on a per-app or per-user basis");
+ case SERVICE_UNAVAILABLE:
+ return TranslateT("If the response includes the Retry-After header, this means your OAuth 1.0 app is being rate limited. Otherwise, this indicates a transient server error, and your app should retry its request.");
+ case INSUFICIENTE_STORAGE:
+ return TranslateT("User is over Dropbox storage quota");
+ }
+
+ return TranslateT("Unknown");
+}
+
void CDropbox::ShowNotification(const wchar_t *caption, const wchar_t *message, int flags, MCONTACT hContact)
{
if (Miranda_Terminated()) return;
@@ -14,9 +41,9 @@ void CDropbox::ShowNotification(const wchar_t *caption, const wchar_t *message,
if (!PUAddPopupW(&ppd))
return;
-
+
}
-
+
MessageBox(NULL, message, caption, MB_OK | flags);
}
diff --git a/plugins/Dropbox/src/file_transfer.h b/plugins/Dropbox/src/file_transfer.h
new file mode 100644
index 0000000000..1c0a511e47
--- /dev/null
+++ b/plugins/Dropbox/src/file_transfer.h
@@ -0,0 +1,57 @@
+#ifndef _FILE_TRANSFER_H_
+#define _FILE_TRANSFER_H_
+
+#include "common.h"
+
+struct FileTransfer
+{
+ HANDLE hProcess;
+ MCONTACT hContact;
+ PROTOFILETRANSFERSTATUS pfts;
+
+ int totalFolders;
+ char **pszFolders;
+ int relativePathStart;
+
+ FileTransfer()
+ {
+ totalFolders = 0;
+ pszFolders = NULL;
+ relativePathStart = 0;
+
+ pfts.cbSize = sizeof(this->pfts);
+ pfts.flags = PFTS_UTF;
+ pfts.currentFileNumber = 0;
+ pfts.currentFileProgress = 0;
+ pfts.currentFileSize = 0;
+ pfts.totalBytes = 0;
+ pfts.totalFiles = 0;
+ pfts.totalProgress = 0;
+ pfts.pszFiles = NULL;
+ pfts.tszWorkingDir = NULL;
+ pfts.wszCurrentFile = NULL;
+ }
+
+ ~FileTransfer()
+ {
+ if (pfts.pszFiles)
+ {
+ for (int i = 0; pfts.pszFiles[i]; i++)
+ {
+ if (pfts.pszFiles[i]) mir_free(pfts.pszFiles[i]);
+ }
+ delete pfts.pszFiles;
+ }
+
+ if (pszFolders)
+ {
+ for (int i = 0; pszFolders[i]; i++)
+ {
+ if (pszFolders[i]) mir_free(pszFolders[i]);
+ }
+ delete pszFolders;
+ }
+ }
+};
+
+#endif //_FILE_TRANSFER_H_ \ No newline at end of file
diff --git a/plugins/Dropbox/src/http_request.h b/plugins/Dropbox/src/http_request.h
index 81a6dcd99d..79882053e3 100644
--- a/plugins/Dropbox/src/http_request.h
+++ b/plugins/Dropbox/src/http_request.h
@@ -3,9 +3,17 @@
#include "common.h"
-enum HttpStatus
+enum HTTP_STATUS
{
- OK = 200
+ OK = 200,
+ BAD_REQUEST = 400,
+ UNAUTHORIZED = 401,
+ FORBIDDEN = 403,
+ NOT_FOUND = 404,
+ METHOD_NOT_ALLOWED = 405,
+ TOO_MANY_REQUESTS = 429,
+ SERVICE_UNAVAILABLE = 503,
+ INSUFICIENTE_STORAGE = 507
};
class HttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject
@@ -83,7 +91,7 @@ public:
headersCount++;
}
- void AddParameter(LPCSTR szName, LPCSTR szValue)
+ /*void AddParameter(LPCSTR szName, LPCSTR szValue)
{
if (m_szUrl.Find('?') == -1)
m_szUrl.AppendFormat("?%s=%s", szName, szValue);
@@ -97,7 +105,7 @@ public:
m_szUrl.AppendFormat("?%s=%i", szName, value);
else
m_szUrl.AppendFormat("&%s=%i", szName, value);
- }
+ }*/
NETLIBHTTPREQUEST *Send()
{