INT_PTR CDropbox::SendFileToDropbox(void *obj, WPARAM hContact, LPARAM lParam) { CDropbox *instance = (CDropbox*)obj; if (!instance->HasAccessToken()) return 0; if (hContact == NULL) hContact = instance->GetDefaultContact(); wchar_t *filePath = (wchar_t*)lParam; FileTransferParam *ftp = new FileTransferParam(); ftp->pfts.flags |= PFTS_SENDING; ftp->pfts.hContact = hContact; ftp->pfts.totalFiles = 1; ftp->hContact = (instance->hTransferContact) ? instance->hTransferContact : hContact; instance->hTransferContact = 0; int length = wcsrchr(filePath, '\\') - filePath; ftp->pfts.wszWorkingDir = (wchar_t*)mir_alloc(sizeof(wchar_t) * (length + 1)); lstrcpyn(ftp->pfts.wszWorkingDir, filePath, length + 1); ftp->pfts.wszWorkingDir[length] = '\0'; ftp->pfts.pwszFiles = (wchar_t**)mir_alloc(sizeof(wchar_t*) * (ftp->pfts.totalFiles + 1)); ftp->pfts.pwszFiles[0] = mir_wstrdup(filePath); ftp->pfts.pwszFiles[ftp->pfts.totalFiles] = NULL; ULONG fileId = InterlockedIncrement(&instance->hFileProcess); ftp->hProcess = (HANDLE)fileId; mir_forkthreadowner(CDropbox::SendFilesAndEventAsync, obj, ftp, 0); return fileId; }
void CDropbox::RequestAccountInfo(void *p) { CDropbox *self = (CDropbox*)p; MCONTACT hContact = self->GetDefaultContact(); ptrA token(db_get_sa(NULL, MODULE, "TokenSecret")); GetCurrentAccountRequest request(token); NLHR_PTR response(request.Send(self->hNetlibConnection)); HandleJsonResponseError(response); JSONNode root = JSONNode::parse(response->pData); if (root.empty()) return; JSONNode referral_link = root.at("referral_link"); if (!referral_link.empty()) db_set_s(hContact, MODULE, "Homepage", referral_link.as_string().c_str()); JSONNode email = root.at("email"); if (!email.empty()) db_set_s(hContact, MODULE, "e-mail", email.as_string().c_str()); JSONNode name = root.at("name"); if (!name.empty()) { db_set_utf(hContact, MODULE, "FirstName", name.at("given_name").as_string().c_str()); db_set_utf(hContact, MODULE, "LastName", name.at("surname").as_string().c_str()); } JSONNode country = root.at("country"); if (!country.empty()) { std::string isocode = country.as_string(); if (isocode.empty()) db_unset(hContact, MODULE, "Country"); else { char *szCountry = (char *)CallService(MS_UTILS_GETCOUNTRYBYISOCODE, (WPARAM)isocode.c_str(), 0); db_set_s(hContact, MODULE, "Country", szCountry); } } /*JSONNode quota_info = root.at("quota_info"); if (!quota_info.empty()) { ULONG lTotalQuota = quota_info.at("quota").as_int(); ULONG lNormalQuota = quota_info.at("normal").as_int(); ULONG lSharedQuota = quota_info.at("shared").as_int(); db_set_dw(hContact, MODULE, "SharedQuota", lSharedQuota); db_set_dw(hContact, MODULE, "NormalQuota", lNormalQuota); db_set_dw(hContact, MODULE, "TotalQuota", lTotalQuota); db_set_s(hContact, "CList", "StatusMsg", CMStringA(FORMAT, Translate("Free %ld of %ld MB"), (lTotalQuota - lNormalQuota) / (1024 * 1024), lTotalQuota / (1024 * 1024))); }*/ }
int CDropbox::OnPrebuildContactMenu(void *obj, WPARAM hContact, LPARAM lParam) { CDropbox *instance = (CDropbox*)obj; if (!hContact) return 0; Menu_ShowItem(instance->contactMenuItems[CMI_SEND_FILES], FALSE); if (!instance->HasAccessToken()) return 0; char *proto = GetContactProto(hContact); bool isProtoOnline = CallProtoService(proto, PS_GETSTATUS, 0, 0) > ID_STATUS_OFFLINE; WORD status = db_get_w(hContact, proto, "Status", ID_STATUS_OFFLINE); bool canSendOffline = (CallProtoService(proto, PS_GETCAPS, PFLAGNUM_4, 0) & PF4_IMSENDOFFLINE) > 0; if (hContact != instance->GetDefaultContact() && isProtoOnline && (status != ID_STATUS_OFFLINE || canSendOffline) && instance->HasAccessToken() && !instance->hTransferContact) Menu_ShowItem(instance->contactMenuItems[CMI_SEND_FILES], TRUE); return 0; }
UINT CDropbox::RequestAcceessTokenAsync(void *owner, void* param) { HWND hwndDlg = (HWND)param; CDropbox *instance = (CDropbox*)owner; EnableWindow(GetDlgItem(hwndDlg, IDC_AUTHORIZE), FALSE); SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("in process...")); if (instance->HasAccessToken()) instance->DestroyAcceessToken(); char requestToken[128]; GetDlgItemTextA(hwndDlg, IDC_REQUEST_CODE, requestToken, SIZEOF(requestToken)); char data[1024]; mir_snprintf( data, SIZEOF(data), "grant_type=authorization_code&code=%s", requestToken); HttpRequest *request = new HttpRequest(instance->hNetlibUser, REQUEST_POST, DROPBOX_API_URL "/oauth2/token"); request->AddBasicAuthHeader(DROPBOX_API_KEY, DROPBOX_API_SECRET); request->AddHeader("Content-Type", "application/x-www-form-urlencoded"); request->pData = mir_strdup(data); request->dataLength = (int)strlen(data); mir_ptr<NETLIBHTTPREQUEST> response(request->Send()); delete request; MCONTACT hContact = instance->GetDefaultContact(); if (response) { JSONROOT root(response->pData); if (root) { if (response->resultCode == HTTP_STATUS_OK) { JSONNODE *node = json_get(root, "access_token"); ptrA access_token = ptrA(mir_u2a(json_as_string(node))); db_set_s(NULL, MODULE, "TokenSecret", access_token); if (hContact) { if (db_get_w(hContact, MODULE, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE) db_set_w(hContact, MODULE, "Status", ID_STATUS_ONLINE); } instance->RequestAccountInfo(); if (hwndDlg) SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("you have been authorized")); /*else ShowNotification(TranslateT("you have been authorized"), MB_ICONINFORMATION);*/ } else { JSONNODE *node = json_get(root, "error_description"); ptrW error_description(json_as_string(node)); if (hwndDlg) SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, error_description); /*else ShowNotification((wchar_t*)error_description, MB_ICONERROR);*/ } } } else { if (hwndDlg) SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("server does not respond")); HandleHttpResponseError(instance->hNetlibUser, response); } SetDlgItemTextA(hwndDlg, IDC_REQUEST_CODE, ""); return 0; }
UINT CDropbox::RequestAccessTokenAsync(void *owner, void *param) { HWND hwndDlg = (HWND)param; CDropbox *instance = (CDropbox*)owner; EnableWindow(GetDlgItem(hwndDlg, IDC_AUTHORIZE), FALSE); SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("in process...")); if (instance->HasAccessToken()) instance->DestroyAccessToken(); char requestToken[128]; GetDlgItemTextA(hwndDlg, IDC_REQUEST_CODE, requestToken, _countof(requestToken)); GetAccessTokenRequest request(requestToken); NLHR_PTR response(request.Send(instance->hNetlibConnection)); if (response == NULL || response->resultCode != HTTP_STATUS_OK) { Netlib_Logf(instance->hNetlibConnection, "%s: %s", MODULE, HttpStatusToText(HTTP_STATUS_ERROR)); if (hwndDlg) SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("server does not respond")); /*else ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);*/ return 0; } JSONNode root = JSONNode::parse(response->pData); if (root.empty()) { Netlib_Logf(instance->hNetlibConnection, "%s: %s", MODULE, HttpStatusToText((HTTP_STATUS)response->resultCode)); if (hwndDlg) SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("server does not respond")); /*else ShowNotification((TCHAR*)error_description, MB_ICONERROR);*/ return 0; } JSONNode node = root.at("error_description"); if (node != JSONNULL) { ptrT error_description(mir_a2t_cp(node.as_string().c_str(), CP_UTF8)); Netlib_Logf(instance->hNetlibConnection, "%s: %s", MODULE, HttpStatusToText((HTTP_STATUS)response->resultCode)); if (hwndDlg) SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, error_description); /*else ShowNotification((TCHAR*)error_description, MB_ICONERROR);*/ return 0; } node = root.at("access_token"); db_set_s(NULL, MODULE, "TokenSecret", node.as_string().c_str()); ProtoBroadcastAck(MODULE, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_OFFLINE, (WPARAM)ID_STATUS_ONLINE); MCONTACT hContact = instance->GetDefaultContact(); if (hContact) { if (db_get_w(hContact, MODULE, "Status", ID_STATUS_OFFLINE) != ID_STATUS_ONLINE) db_set_w(hContact, MODULE, "Status", ID_STATUS_ONLINE); } try { RequestAccountInfo(instance); } catch (DropboxException &ex) { Netlib_Logf(instance->hNetlibConnection, "%s: %s", MODULE, ex.what()); return 0; } if (hwndDlg) SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("you have been authorized")); /*else ShowNotification(TranslateT("you have been authorized"), MB_ICONINFORMATION);*/ SetDlgItemTextA(hwndDlg, IDC_REQUEST_CODE, ""); return 0; }
INT_PTR CDropbox::ProtoSendFile(void *obj, WPARAM, LPARAM lParam) { CDropbox *instance = (CDropbox*)obj; if (!instance->HasAccessToken()) return ACKRESULT_FAILED; CCSDATA *pccsd = (CCSDATA*)lParam; FileTransferParam *ftp = new FileTransferParam(); ftp->pfts.flags |= PFTS_SENDING; ftp->pfts.hContact = pccsd->hContact; ftp->hContact = (instance->hTransferContact) ? instance->hTransferContact : pccsd->hContact; instance->hTransferContact = 0; wchar_t **paths = (wchar_t**)pccsd->lParam; for (int i = 0; paths[i]; i++) { if (PathIsDirectory(paths[i])) ftp->totalFolders++; else ftp->pfts.totalFiles++; } ftp->pwszFolders = (wchar_t**)mir_alloc(sizeof(wchar_t*) * (ftp->totalFolders + 1)); ftp->pwszFolders[ftp->totalFolders] = NULL; ftp->pfts.pwszFiles = (wchar_t**)mir_alloc(sizeof(wchar_t*) * (ftp->pfts.totalFiles + 1)); ftp->pfts.pwszFiles[ftp->pfts.totalFiles] = NULL; for (int i = 0, j = 0, k = 0; paths[i]; i++) { if (PathIsDirectory(paths[i])) { if (!ftp->relativePathStart) { wchar_t *rootFolder = paths[j]; wchar_t *relativePath = wcsrchr(rootFolder, '\\') + 1; ftp->relativePathStart = relativePath - rootFolder; } ftp->pwszFolders[j] = mir_wstrdup(&paths[i][ftp->relativePathStart]); j++; } else { if (!ftp->pfts.wszWorkingDir) { wchar_t *path = paths[j]; int length = wcsrchr(path, '\\') - path; ftp->pfts.wszWorkingDir = (wchar_t*)mir_alloc(sizeof(wchar_t) * (length + 1)); lstrcpyn(ftp->pfts.wszWorkingDir, paths[j], length + 1); ftp->pfts.wszWorkingDir[length] = '\0'; } ftp->pfts.pwszFiles[k] = mir_wstrdup(paths[i]); FILE *file = _wfopen(paths[i], L"rb"); if (file != NULL) { fseek(file, 0, SEEK_END); ftp->pfts.totalBytes += ftell(file); fseek(file, 0, SEEK_SET); fclose(file); } k++; } } ULONG fileId = InterlockedIncrement(&instance->hFileProcess); ftp->hProcess = (HANDLE)fileId; mir_forkthreadowner(CDropbox::SendFilesAndReportAsync, obj, ftp, 0); return fileId; }
INT_PTR CDropbox::ProtoSendMessage(void *obj, WPARAM, LPARAM lParam) { CDropbox *instance = (CDropbox*)obj; if (!instance->HasAccessToken()) return ACKRESULT_FAILED; 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)message; dbei.flags = DBEF_SENT | DBEF_READ | DBEF_UTF; db_event_add(pccsd->hContact, &dbei); char help[1024]; if (message[0] && message[0] == '/') { // parse commands char *sep = strchr(message, ' '); int len = strlen(message) - (sep ? strlen(sep) : 0) - 1; ptrA cmd((char*)mir_alloc(len + 1)); strncpy(cmd, message + 1, len); cmd[len] = 0; if (instance->commands.find((char*)cmd) != instance->commands.end()) { ULONG messageId = InterlockedIncrement(&instance->hMessageProcess); CommandParam *param = new CommandParam(); param->instance = instance; param->hContact = pccsd->hContact; param->hProcess = (HANDLE)messageId; param->data = (sep ? sep + 1 : NULL); mir_forkthread(instance->commands[(char*)cmd], param); return messageId; } else { mir_snprintf( help, SIZEOF(help), Translate("Unknown command \"%s\".\nUse \"/help\" for more info."), message); CallContactService(instance->GetDefaultContact(), PSR_MESSAGE, 0, (LPARAM)help); return 0; } } mir_snprintf( help, SIZEOF(help), Translate("\"%s\" is not valid.\nUse \"/help\" for more info."), message); CallContactService(instance->GetDefaultContact(), PSR_MESSAGE, 0, (LPARAM)help); return 0; }