summaryrefslogtreecommitdiff
path: root/plugins/CloudFile/src/cloud_service.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/CloudFile/src/cloud_service.cpp')
-rw-r--r--plugins/CloudFile/src/cloud_service.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/plugins/CloudFile/src/cloud_service.cpp b/plugins/CloudFile/src/cloud_service.cpp
new file mode 100644
index 0000000000..9e57dc14aa
--- /dev/null
+++ b/plugins/CloudFile/src/cloud_service.cpp
@@ -0,0 +1,164 @@
+#include "stdafx.h"
+
+static int CompareServices(const CCloudService *p1, const CCloudService *p2)
+{
+ return mir_strcmp(p1->GetModule(), p2->GetModule());
+}
+
+LIST<CCloudService> Services(10, CompareServices);
+
+void InitServices()
+{
+ Services.insert(new CDropboxService(hNetlibConnection));
+ //Services.insert(new CGDriveService(hNetlibConnection));
+ Services.insert(new CYandexService(hNetlibConnection));
+
+ PROTOCOLDESCRIPTOR pd = { sizeof(pd) };
+
+ size_t count = Services.getCount();
+ for (size_t i = 0; i < count; i++) {
+ CCloudService *service = Services[i];
+
+ CMStringA moduleName(CMStringDataFormat::FORMAT, "%s/%s", MODULE, service->GetModule());
+ pd.type = PROTOTYPE_VIRTUAL;
+ pd.szName = moduleName.GetBuffer();
+ Proto_RegisterModule(&pd);
+
+ CMStringA serviceName(CMStringDataFormat::FORMAT, "%s%s", moduleName, PSS_FILE);
+ CreateServiceFunctionObj(serviceName, ProtoSendFile, service);
+
+ moduleName = CMStringA(CMStringDataFormat::FORMAT, "%s/%s/Interceptor", MODULE, service->GetModule());
+ pd.szName = moduleName.GetBuffer();
+ pd.type = PROTOTYPE_FILTER;
+ Proto_RegisterModule(&pd);
+
+ serviceName = CMStringA(CMStringDataFormat::FORMAT, "%s%s", moduleName, PSS_FILE);
+ CreateServiceFunctionObj(serviceName, ProtoSendFileInterceptor, service);
+ }
+}
+
+CCloudService::CCloudService(HNETLIBUSER hConnection)
+ : hConnection(hConnection)
+{
+}
+
+void CCloudService::SendToContact(MCONTACT hContact, const wchar_t *data)
+{
+ const char *szProto = GetContactProto(hContact);
+ if (db_get_b(hContact, szProto, "ChatRoom", 0) == TRUE) {
+ ptrW tszChatRoom(db_get_wsa(hContact, szProto, "ChatRoomID"));
+ Chat_SendUserMessage(szProto, tszChatRoom, data);
+ return;
+ }
+
+ char *message = mir_utf8encodeW(data);
+ if (ProtoChainSend(hContact, PSS_MESSAGE, 0, (LPARAM)message) != ACKRESULT_FAILED)
+ AddEventToDb(hContact, EVENTTYPE_MESSAGE, DBEF_UTF | DBEF_SENT, (DWORD)mir_strlen(message), (PBYTE)message);
+}
+
+void CCloudService::PasteToInputArea(MCONTACT hContact, const wchar_t *data)
+{
+ CallService(MS_MSG_SENDMESSAGEW, hContact, (LPARAM)data);
+}
+
+void CCloudService::PasteToClipboard(const wchar_t *data)
+{
+ if (OpenClipboard(NULL)) {
+ EmptyClipboard();
+
+ size_t size = sizeof(wchar_t) * (mir_wstrlen(data) + 1);
+ HGLOBAL hClipboardData = GlobalAlloc(NULL, size);
+ if (hClipboardData) {
+ wchar_t *pchData = (wchar_t*)GlobalLock(hClipboardData);
+ if (pchData) {
+ memcpy(pchData, (wchar_t*)data, size);
+ GlobalUnlock(hClipboardData);
+ SetClipboardData(CF_UNICODETEXT, hClipboardData);
+ }
+ }
+ CloseClipboard();
+ }
+}
+
+void CCloudService::Report(MCONTACT hContact, const wchar_t *data)
+{
+ if (db_get_b(NULL, MODULE, "UrlAutoSend", 1))
+ SendToContact(hContact, data);
+
+ if (db_get_b(NULL, MODULE, "UrlPasteToMessageInputArea", 0))
+ PasteToInputArea(hContact, data);
+
+ if (db_get_b(NULL, MODULE, "UrlCopyToClipboard", 0))
+ PasteToClipboard(data);
+}
+
+char* CCloudService::PreparePath(const char *oldPath, char *newPath)
+{
+ if (oldPath == NULL)
+ mir_strcpy(newPath, "");
+ else if (*oldPath != '/')
+ {
+ CMStringA result("/");
+ result.Append(oldPath);
+ result.Replace("\\", "/");
+ mir_strcpy(newPath, result);
+ }
+ else
+ mir_strcpy(newPath, oldPath);
+ return newPath;
+}
+
+char* CCloudService::PreparePath(const wchar_t *oldPath, char *newPath)
+{
+ return PreparePath(ptrA(mir_utf8encodeW(oldPath)), newPath);
+}
+
+char* CCloudService::HttpStatusToError(int status)
+{
+ switch (status) {
+ case HTTP_CODE_OK:
+ return "OK";
+ case HTTP_CODE_BAD_REQUEST:
+ return "Bad input parameter. Error message should indicate which one and why";
+ case HTTP_CODE_UNAUTHORIZED:
+ return "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 HTTP_CODE_FORBIDDEN:
+ return "Bad OAuth request (wrong consumer key, bad nonce, expired timestamp...). Unfortunately, re-authenticating the user won't help here";
+ case HTTP_CODE_NOT_FOUND:
+ return "File or folder not found at the specified path";
+ case HTTP_CODE_METHOD_NOT_ALLOWED:
+ return "Request method not expected (generally should be GET or POST)";
+ case HTTP_CODE_TOO_MANY_REQUESTS:
+ return "Your app is making too many requests and is being rate limited. 429s can trigger on a per-app or per-user basis";
+ case HTTP_CODE_SERVICE_UNAVAILABLE:
+ return "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.";
+ }
+
+ return "Unknown error";
+}
+
+void CCloudService::HandleHttpError(NETLIBHTTPREQUEST *response)
+{
+ if (response == NULL)
+ throw Exception(HttpStatusToError());
+
+ if (response->resultCode != HTTP_CODE_OK &&
+ response->resultCode != HTTP_CODE_CONFLICT) {
+ if (response->dataLength)
+ throw Exception(response->pData);
+ throw Exception(HttpStatusToError(response->resultCode));
+ }
+}
+
+JSONNode CCloudService::GetJsonResponse(NETLIBHTTPREQUEST *response)
+{
+ HandleHttpError(response);
+
+ JSONNode root = JSONNode::parse(response->pData);
+ if (root.isnull())
+ throw Exception(HttpStatusToError());
+
+ HandleJsonError(root);
+
+ return root;
+} \ No newline at end of file