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/src/dropbox_transfers.cpp | 210 ++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 plugins/DropBox/src/dropbox_transfers.cpp (limited to 'plugins/DropBox/src/dropbox_transfers.cpp') 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 -- cgit v1.2.3