summaryrefslogtreecommitdiff
path: root/plugins/CloudFile/src/cloud_file.cpp
diff options
context:
space:
mode:
authoraunsane <aunsane@gmail.com>2018-02-19 00:00:03 +0300
committeraunsane <aunsane@gmail.com>2018-02-19 00:00:20 +0300
commit46e398c0d295f3d33fe4c0450c36e1fc45a95616 (patch)
tree727617421cce4e6cc7f0863b4c4fcf367e135a10 /plugins/CloudFile/src/cloud_file.cpp
parent66c4ae72a70a6e155c4a2a6d14c91c532cdb3974 (diff)
CloudFile: added support for the usual accounts system(#1144)
Diffstat (limited to 'plugins/CloudFile/src/cloud_file.cpp')
-rw-r--r--plugins/CloudFile/src/cloud_file.cpp157
1 files changed, 157 insertions, 0 deletions
diff --git a/plugins/CloudFile/src/cloud_file.cpp b/plugins/CloudFile/src/cloud_file.cpp
new file mode 100644
index 0000000000..ce1392f9d3
--- /dev/null
+++ b/plugins/CloudFile/src/cloud_file.cpp
@@ -0,0 +1,157 @@
+#include "stdafx.h"
+
+static int CompareServices(const CCloudService *p1, const CCloudService *p2)
+{
+ return mir_strcmp(p1->GetAccountName(), p2->GetAccountName());
+}
+
+LIST<CCloudService> Services(10, CompareServices);
+
+void InitServices()
+{
+ PROTOCOLDESCRIPTOR pd = { sizeof(pd) };
+ pd.type = PROTOTYPE_PROTOCOL;
+
+ pd.szName = MODULE "/Dropbox";
+ pd.fnInit = (pfnInitProto)CDropboxService::Init;
+ pd.fnUninit = (pfnUninitProto)CDropboxService::UnInit;
+ Proto_RegisterModule(&pd);
+
+ pd.szName = MODULE "/GDrive";
+ pd.fnInit = (pfnInitProto)CGDriveService::Init;
+ pd.fnUninit = (pfnUninitProto)CGDriveService::UnInit;
+ Proto_RegisterModule(&pd);
+
+ pd.szName = MODULE "/OneDrivre";
+ pd.fnInit = (pfnInitProto)COneDriveService::Init;
+ pd.fnUninit = (pfnUninitProto)COneDriveService::UnInit;
+ Proto_RegisterModule(&pd);
+
+ pd.szName = MODULE "/YandexDisk";
+ pd.fnInit = (pfnInitProto)CYandexService::Init;
+ pd.fnUninit = (pfnUninitProto)CYandexService::UnInit;
+ Proto_RegisterModule(&pd);
+
+ pd.szName = MODULE;
+ pd.type = PROTOTYPE_FILTER;
+ Proto_RegisterModule(&pd);
+
+ CreateServiceFunction(MODULE PSS_FILE, &CCloudService::SendFileInterceptor);
+}
+
+CCloudService::CCloudService(const char *protoName, const wchar_t *userName)
+ : PROTO<CCloudService>(protoName, userName)
+{
+ NETLIBUSER nlu = {};
+ nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_UNICODE;
+ nlu.szSettingsModule = (char*)protoName;
+ nlu.szDescriptiveName.w = (wchar_t*)userName;
+ hConnection = Netlib_RegisterUser(&nlu);
+}
+
+CCloudService::~CCloudService()
+{
+ Netlib_CloseHandle(hConnection);
+ hConnection = nullptr;
+}
+
+const char* CCloudService::GetAccountName() const
+{
+ return m_szModuleName;
+}
+
+const wchar_t* CCloudService::GetUserName() const
+{
+ return m_tszUserName;
+}
+
+DWORD_PTR CCloudService::GetCaps(int type, MCONTACT)
+{
+ switch (type) {
+ case PFLAGNUM_1:
+ return PF1_FILESEND;
+ default:
+ return 0;
+ }
+}
+
+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 == nullptr)
+ 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::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::HttpResponseToError(NETLIBHTTPREQUEST *response)
+{
+ if (response->dataLength)
+ throw Exception(response->pData);
+ throw Exception(HttpStatusToError(response->resultCode));
+}
+
+void CCloudService::HandleHttpError(NETLIBHTTPREQUEST *response)
+{
+ if (response == nullptr)
+ throw Exception(HttpStatusToError());
+
+ if (!HTTP_CODE_SUCCESS(response->resultCode))
+ HttpResponseToError(response);
+}
+
+JSONNode CCloudService::GetJsonResponse(NETLIBHTTPREQUEST *response)
+{
+ HandleHttpError(response);
+
+ JSONNode root = JSONNode::parse(response->pData);
+ if (root.isnull())
+ throw Exception(HttpStatusToError());
+
+ HandleJsonError(root);
+
+ return root;
+}