diff -aurN ./gyamblr/gyazowin/gyazowin.cpp.orig ./gyamblr/gyazowin/gyazowin.cpp --- ./gyamblr/gyazowin/gyazowin.cpp.orig 2008-02-12 20:13:55.000000000 +0900 +++ ./gyamblr/gyazowin/gyazowin.cpp 2008-04-27 09:17:35.000000000 +0900 @@ -1,6 +1,7 @@ // gyazowin.cpp : アプリケーションのエントリ ポイントを定義します。 // +#include #include "stdafx.h" #include "gyazowin.h" #include "string.h" @@ -623,7 +624,7 @@ } // ID を生成・ロードする -BOOL getId(std::string& account,std::string& email,std::string& passwd) +BOOL getId(std::string& account,std::string& email,std::string& passwd, std::string& is_private) { const char* idFile = "account.txt"; @@ -643,6 +644,8 @@ ifs >> email; } else if ( !s.compare("password") ) { ifs >> passwd; + } else if ( !s.compare("private") ) { + ifs >> is_private; } p = s.c_str(); @@ -654,7 +657,6 @@ return FALSE; } - #define BOUNDARY "----BOUNDARYBOUNDARY----" #define CRLF "\x0d\x0a" @@ -673,6 +675,27 @@ return toUTF8((const char*)title, (int)_tcslen(title) * sizeof(TCHAR), true ); } +std::string encode_value(const char *value) { + char *buf = (char *)malloc(strlen(value) * 2); + const char *p = value; + char *q = buf; + + while (*p) { + if (*p == '@') { + *q++ = '%'; + *q++ = '4'; + *q++ = '0'; + *p++; + } else { + *q++ = *p++; + } + } + *q = '\0'; + + return std::string(buf); +} + +BOOL scrape_from_dashboard(HWND hwnd, const char *baseurl, const char *authinfo); // PNG ファイルをアップロードする. BOOL uploadFile(HWND hwnd, LPCTSTR fileName, int type) @@ -689,12 +712,22 @@ std::string account; std::string email; std::string passwd; + std::string str_is_private; + BOOL is_private = FALSE; + std::string auth_query; // ID を取得 - BOOL b = getId(account, email, passwd); + BOOL b = getId(account, email, passwd, str_is_private); if ( !b ) { return FALSE; } + if (strlen(str_is_private.c_str()) && atoi(str_is_private.c_str())) { + is_private = 1; + auth_query = "email="; + auth_query += encode_value(email.data()); + auth_query += "&password="; + auth_query += encode_value(passwd.data()); + } // メッセージの構成 @@ -702,6 +735,9 @@ injectParam(buf, "password", passwd); injectParam(buf, "generator", "gyazowin.tumblr"); + if (is_private) { + injectParam(buf, "private", "1"); + } const char* paramname = NULL; @@ -709,7 +745,7 @@ switch( type ) { case POSTTYPE_CAPTURE: injectParam(buf, "type", "photo"); - injectParam(buf, "caption", "captured with Gyamblr for Windows. based on Gyazowin."); + injectParam(buf, "caption", "captured with Gyamblr for Windows. modded by woremacx. based on Gyazowin."); paramname = ("data"); break; case POSTTYPE_PHOTO: @@ -824,7 +860,8 @@ // upload 成功,結果 (URL) を読取る DWORD len; char resbuf[1024]; - std::string result = "http://" + account + ".tumblr.com/post/"; + std::string result = "http://" + account + ".tumblr.com/"; + result += is_private ? "private/" : "post/"; // そんなに長いことはないけどまあ一応 while(InternetReadFile(hRequest, (LPVOID) resbuf, 1024, &len) @@ -837,11 +874,15 @@ result += '\0'; // クリップボードに URL をコピー - setClipBoardText(result.c_str()); // URL を起動 - execUrl(result.c_str()); - + if (is_private) { + // execUrl("http://www.tumblr.com/dashboard"); + scrape_from_dashboard(hwnd, result.c_str(), auth_query.c_str()); + } else { + setClipBoardText(result.c_str()); + execUrl(result.c_str()); + } return TRUE; } } else { @@ -852,3 +893,117 @@ return FALSE; } + +BOOL scrape_from_dashboard(HWND hwnd, const char *baseurl, const char *authinfo) { + const TCHAR* UPLOAD_SERVER = _T("www.tumblr.com"); + const TCHAR* LOGIN_PATH = _T("/login"); + const TCHAR* DASHBOARD_PATH = _T("/dashboard"); + + const TCHAR* szHeader = + _T( "Content-Type: application/x-www-form-urlencoded" ); + + HINTERNET hSession = InternetOpen(szTitle, + INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + if(NULL == hSession) { + MessageBox(hwnd, _T("cannot configure wininet"), + _T("Error"), MB_ICONERROR | MB_OK); + return FALSE; + } + + HINTERNET hConnection = InternetConnect(hSession, + UPLOAD_SERVER, INTERNET_DEFAULT_HTTP_PORT, + NULL, NULL, INTERNET_SERVICE_HTTP, 0, NULL); + if(NULL == hSession) { + MessageBox(hwnd, _T("cannot initiate connection"), + _T("Error"), MB_ICONERROR | MB_OK); + return FALSE; + } + + // 要求先の設定 + HINTERNET hRequest = HttpOpenRequest(hConnection, + _T("POST"), LOGIN_PATH, NULL, + NULL, NULL, INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD, NULL); + if(NULL == hSession) { + MessageBox(hwnd, _T("cannot compose post request"), + _T("Error"), MB_ICONERROR | MB_OK); + return FALSE; + } + + // 要求を送信 + if (HttpSendRequest(hRequest, + szHeader, + lstrlen(szHeader), + (LPVOID)authinfo, + (DWORD)strlen(authinfo))) + { + // 要求は成功 + + DWORD resLen = 8; + TCHAR resCode[8]; + + // status code を取得 + HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE, resCode, &resLen, 0); + if( (_ttoi(resCode) / 100) != 2 ) { + // upload 失敗 (status error) + MessageBox(hwnd, _T("failed to upload (unexpected result code, under maintainance?)"), + _T("Error"), MB_ICONERROR | MB_OK); + } + } + + hRequest = HttpOpenRequest(hConnection, + _T("GET"), DASHBOARD_PATH, NULL, + NULL, NULL, INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD, NULL); + if(NULL == hSession) { + MessageBox(hwnd, _T("cannot compose post request"), + _T("Error"), MB_ICONERROR | MB_OK); + return FALSE; + } + + // 要求を送信 + if (HttpSendRequest(hRequest, NULL, 0, NULL, 0)) + { + // 要求は成功 + + DWORD resLen = 8; + TCHAR resCode[8]; + + // status code を取得 + HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE, resCode, &resLen, 0); + if( (_ttoi(resCode) / 100) != 2 ) { + // upload 失敗 (status error) + MessageBox(hwnd, _T("failed to upload (unexpected result code, under maintainance?)"), + _T("Error"), MB_ICONERROR | MB_OK); + } else { + // upload 成功,結果 (URL) を読取る + DWORD len; + char resbuf[1024]; + std::string result; + + while(InternetReadFile(hRequest, (LPVOID) resbuf, 1024, &len) + && len != 0) + { + result.append(resbuf, len); + } + + result += '\0'; + + // クリップボードに URL をコピー + const char *res = result.c_str(); + char *p, *q; + if ((p = strstr((char *)res, baseurl)) != NULL) { + if ((q = strchr(p, '\"')) != NULL) { + char *url = (char *)malloc((q - p) *2); + memcpy(url, p, (size_t)(q - p)); + *(url + (q - p)) = '\0'; + setClipBoardText(url); + execUrl(url); + } + } + return TRUE; + } + } else { + // アップロード失敗... + MessageBox(hwnd, _T("oh, failed to login"), _T("Error"), MB_ICONERROR | MB_OK); + } +} +