diff options
author | aunsane <aunsane@gmail.com> | 2018-02-19 00:00:03 +0300 |
---|---|---|
committer | aunsane <aunsane@gmail.com> | 2018-02-19 00:00:20 +0300 |
commit | 46e398c0d295f3d33fe4c0450c36e1fc45a95616 (patch) | |
tree | 727617421cce4e6cc7f0863b4c4fcf367e135a10 /plugins/CloudFile/src/cloud_file.cpp | |
parent | 66c4ae72a70a6e155c4a2a6d14c91c532cdb3974 (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.cpp | 157 |
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; +} |