74 Commits

Author SHA1 Message Date
Keita.S 4f9b63372d Merge pull request #14 from milkcocoa0902/develop
merge branch develop into master
2022-04-29 01:52:34 +09:00
keita a0dfc7213a update README 2022-04-29 01:47:48 +09:00
Keita.S d47401470a Merge pull request #13 from milkcocoa0902/feature/oauth
merge branch feature/oauth into develop
2022-04-24 11:11:54 +09:00
keita 1644e4e624 format 2022-04-24 11:11:11 +09:00
keita 84ba888c3a access_tokenの再発行が出来るように 2022-04-24 11:06:37 +09:00
keita 8010a6b553 fix 2022-04-23 21:09:18 +09:00
keita 1a1ccdca27 format 2022-04-23 20:57:59 +09:00
keita 9f2c61b7e0 ベアラトークンのモデル作成。その他 2022-04-23 20:56:50 +09:00
keita 5eef4a64e6 %エンコードを解除するutil 2022-04-23 20:56:20 +09:00
keita 12d6061baf 追加したexceptionの登録 2022-04-23 20:55:51 +09:00
keita f1c05a5c38 exceptionの追加 2022-04-23 20:55:04 +09:00
keita bd7387eb90 include guard 2022-04-23 18:11:27 +09:00
keita cc1e136bf2 include guard 2022-04-23 18:09:12 +09:00
keita 611cfc2e31 code format 2022-04-23 18:04:03 +09:00
keita 136700d154 doc 2022-04-23 18:03:42 +09:00
keita d99ba765aa basic認証用のプロバイダとベアラトークンを取得するためのエンドポイントアクセスを有効に 2022-04-23 18:00:41 +09:00
keita 560fe707a6 access tokenが取得できるように 2022-04-23 04:55:43 +09:00
keita d43e04506b ? 2022-04-21 10:03:33 +09:00
keita 9dc7f35365 .gitignore 2021-10-08 19:38:30 +09:00
Keita.S 47df0803d9 Merge pull request #12 from milkcocoa0902/develop
merge brunch develop into master

. create user object
. add exception pattern
. can generate and use Bearer token access
2021-10-07 23:46:36 +09:00
keita 1c970995de doxygen 2021-10-07 23:43:58 +09:00
Keita.S 892d08c788 Merge pull request #11 from milkcocoa0902/feature/user_object
merge branch feature/user_object into develop

. create user object
. add exception pattern
. can generate and use Bearer token access
2021-10-07 23:40:24 +09:00
keita 9551f7280b fix cmake config 2021-10-07 23:37:31 +09:00
keita 5aed635d54 fix include guard format 2021-10-07 22:04:11 +09:00
keita e7c0df8e99 README 2021-10-07 21:50:46 +09:00
keita d3d0dc96fd ユーザオブジェクト 2021-10-07 21:26:24 +09:00
keita 98ed362e12 format 2021-10-07 20:55:23 +09:00
keita 5d32261b9e OAuth2が出来るようになったよ。ブランチの目的からめちゃくちゃズレてるね 2021-10-07 20:53:25 +09:00
keita a4fd0d9830 smallCamelCaseに変更 2021-04-03 23:31:27 +09:00
Keita.S 3bd3adfe75 Merge pull request #10 from milkcocoa0902/develop
merge branch develop into master
2021-04-01 22:00:14 +09:00
keita f97deb5c36 format 2021-04-01 21:56:56 +09:00
keita 1e31c756ce manage README 2021-04-01 21:56:11 +09:00
keita ea68ad22c1 APIのエントリーポイントにdmを載せた 2021-04-01 21:52:09 +09:00
keita 1482347c48 dm用のエントリーポイント 2021-04-01 21:51:45 +09:00
keita b9d40e25c3 dmを送信するためにはapplication/jsonをpostしないといけないためhttp/postのinterfaceにて対応 2021-04-01 21:51:20 +09:00
keita 227742748d direct_maggages/event/newをたたくやつ 2021-04-01 21:50:28 +09:00
Keita.S 0d4d1c30b9 Merge pull request #9 from milkcocoa0902/develop
merge branch develop into master
2021-03-20 10:41:57 +09:00
keita 095b95a302 add LICENSE 2021-03-20 10:36:00 +09:00
keita 783f0a4087 manage README 2021-03-20 10:29:12 +09:00
keita 6266d0f67c 整形 2021-03-20 10:27:19 +09:00
keita fc886b70b8 statuses/unretweet/:idを叩くやつをエントリーポイントにのせた 2021-03-20 10:26:53 +09:00
keita 81d248151a statuses/unretweet/:idを叩くやつ 2021-03-20 10:26:31 +09:00
keita 576a4a5ea3 manage comment 2021-03-19 23:13:13 +09:00
keita 561f255a76 manage README 2021-03-19 23:08:02 +09:00
keita e32356eca3 Status::UserTimelineでstd::coutへのダンプを消した(#66) 2021-03-19 23:05:08 +09:00
keita f8b7480737 存在しなくなったパスをテストから消した 2021-03-19 23:03:40 +09:00
keita 9413cd8ce2 Model::TweetからHttpPostにエラーハンドリングを移動した(#67) 2021-03-19 22:55:34 +09:00
keita 73e0b9f902 status/user_timelineを叩くやつの追加(#66) 2021-03-19 22:28:06 +09:00
keita 4d2eecc47d statuses_usertimelineを叩くやつの実装(#66) 2021-03-19 22:20:12 +09:00
keita 38e8795e06 HTTP/GETの実装(#66) 2021-03-19 22:18:39 +09:00
Keita.S 1e38d518b8 Merge pull request #8 from milkcocoa0902/develop
merge branch develop into master
2021-03-14 23:21:12 +09:00
keita bafa269c4e manage README 2021-03-14 23:18:17 +09:00
keita 8a06e436ab RTを叩くやつをstatusグループに統合(#65) 2021-03-14 23:17:59 +09:00
keita 33cb1f3e18 RTを叩くやつ(#65) 2021-03-14 23:17:42 +09:00
keita f35598c8ae add unsupportedMediaTypeException 2021-03-14 00:58:29 +09:00
keita bc1debe5fe include guard 2021-03-14 00:18:12 +09:00
keita ef378fb4c6 manage README 2021-03-11 21:43:00 +09:00
keita dd3c7e4024 Doxyfileからtestフォルダを除外した 2021-03-11 21:40:36 +09:00
keita d2425d009d コメント書いたり 2021-03-11 21:40:10 +09:00
keita 16daa46810 manage README 2021-03-11 21:13:17 +09:00
keita 7aa9a060c0 パーセントエンコードが二重になってたので修正 2021-03-11 20:38:37 +09:00
keita cb2d284e54 statuses/updateのエンドポイントのオプションを書いた 2021-03-11 20:33:08 +09:00
keita a8aa3173bd mime-typeを検出するようにしてみた(#56) 2021-03-11 14:32:25 +09:00
keita 9d90f01c9f 整形 2021-03-11 13:43:33 +09:00
keita a8614c3b7e media/uploadを今度こそエントリーポイントに乗せた(#56) 2021-03-11 13:43:11 +09:00
keita e0c78cacbd media/uploadをエントリーポイントに乗せた(#56) 2021-03-11 13:42:10 +09:00
keita bf285508ee statuses/updateをmediaと一緒に叩くやつ(#56) 2021-03-11 00:03:06 +09:00
keita 852a6bb1b3 media/uploadを叩くやつ(#56) 2021-03-10 23:59:01 +09:00
keita a58903e9c0 multipart/form-dataに対応(#56) 2021-03-10 23:57:52 +09:00
keita 3c99ccab3e 署名時にurlEncode 2021-03-10 22:35:04 +09:00
keita 00a568c016 HttpGetの実装に向けてHttpBaseの実装 2021-03-10 22:34:20 +09:00
keita ccdb26b18d Merge branch 'develop' of http://gitbucket.milkcocoa.info/git/milkcocoa0902/CocoaTweet into develop 2021-03-06 20:44:51 +09:00
Keita.S 3c30e99020 Merge pull request #7 from milkcocoa0902/feature/build__on_macOS
Feature/build  on macOS
2021-03-06 20:30:58 +09:00
keita 4efd7777c4 fix typo 2021-03-05 16:11:16 +09:00
105 changed files with 2787 additions and 307 deletions
+3
View File
@@ -1,3 +1,6 @@
build/ build/
*.swp *.swp
src/main.cc src/main.cc
help/
Testing/
**/api_key.json
+3 -2
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.05)
project(CocoaTweet CXX C) project(CocoaTweet CXX C)
@@ -60,7 +60,8 @@ if(ENABLE_TEST)
if(NOT (UNIX OR APPLE)) if(NOT (UNIX OR APPLE))
message(FAITAL_ERROR "unit test is NOT supported on Windows") message(FAITAL_ERROR "unit test is NOT supported on Windows")
endif() endif()
find_package(Boost 1.71.0 COMPONENTS unit_test_framework REQUIRED) set(Boost_NO_BOOST_CMAKE TRUE)
find_package(Boost 1.67 COMPONENTS unit_test_framework REQUIRED)
# Enable CTest # Enable CTest
enable_testing() enable_testing()
add_subdirectory(test) add_subdirectory(test)
+1
View File
@@ -935,6 +935,7 @@ EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = */third/* EXCLUDE_PATTERNS = */third/*
EXCLUDE_PATTERNS += */build/* EXCLUDE_PATTERNS += */build/*
EXCLUDE_PATTERNS += */test/*
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the # (namespaces, classes, functions, etc.) that should be excluded from the
+7
View File
@@ -0,0 +1,7 @@
Copyright 2021 Keita.S(@milkcocoa0902)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+85 -9
View File
@@ -2,6 +2,7 @@
![](http://jenkins.milkcocoa.info/job/CocoaTweet/job/master/badge/icon?style=plastic&config=unittest) ![](http://jenkins.milkcocoa.info/job/CocoaTweet/job/master/badge/icon?style=plastic&config=unittest)
![](https://img.shields.io/badge/libcurl-libcurl4--openssl-blue) ![](https://img.shields.io/badge/libcurl-libcurl4--openssl-blue)
![](https://img.shields.io/badge/libssl-1.1.1f-blue) ![](https://img.shields.io/badge/libssl-1.1.1f-blue)
![](https://img.shields.io/badge/license-MIT-orange)
# CocoaTweet # CocoaTweet
This is a library for using Twitter API from C++ This is a library for using Twitter API from C++
@@ -10,8 +11,20 @@ This is a library for using Twitter API from C++
you can use these endpoint you can use these endpoint
- statuses/update - statuses/update
- statuses/destroy/:id - statuses/destroy/:id
- statuses/retweet/:id
- statuses/unretweet/:id
- statuses/user_timeline
- favorites/create - favorites/create
- favorites/destroy - favorites/destroy
- users/show
- media/upload(support: jpg, jpeg, png, gif, mp4)
- direct_messages/events/new (message_create)
- oauth/access_token
- oauth/authorize
- oauth/invalidate_token
- oauth/request_token
- oauth2/token
- oauth2/invalidate_token
# Dependency # Dependency
- libcurl(openssl version) - libcurl(openssl version)
@@ -20,7 +33,7 @@ you can use these endpoint
# Installation # Installation
## Ubuntu ## Ubuntu
``` ```
# apt install clang cmake git libboost-dev libboost-test-dev libcurl4-openssl-dev libssl-dev nunja-build # apt install clang cmake git libboost-dev libcurl4-openssl-dev libssl-dev ninja-build
$ git clone https://github.com/koron0902/CocoaTweet $ git clone https://github.com/koron0902/CocoaTweet
$ cd CocoaTweet $ cd CocoaTweet
$ mkdir build $ mkdir build
@@ -65,17 +78,19 @@ $ mingw32-make
# How # How
## API Key Registration ## API Key Registration
there're 4 ways to register API key
### 1.Write Key into code ### 1.Write Key into code
write api key into code and create Key object use it. write api key into code and create Key object use it.
``` ```
#include "cocoatweet/oauth/key.h" #include "cocoatweet/authentication/key.h"
auto consumerKey = "your consumer key"; auto consumerKey = "your consumer key";
auto consumerSecret = "your consumer secret"; auto consumerSecret = "your consumer secret";
auto accessToken = "your access token"; auto accessToken = "your access token";
auto accessTokenSecret = "your access token secret"; auto accessTokenSecret = "your access token secret";
CocoaTweet::OAuth::Key key(consumerKey, consumerSecret, accessToken, accessTokenSecret); CocoaTweet::Authentication::Key key(consumerKey, consumerSecret, accessToken, accessTokenSecret);
``` ```
@@ -93,11 +108,45 @@ prepare file which written 'api-key' with json format.
then you can load api key from json file. then you can load api key from json file.
``` ```
#include "cocoatweet/oauth/key.h" #include "cocoatweet/authentication/key.h"
CocoaTweet::OAuth::Key key = CocoaTweet::OAuth::Key::fromJsonFile("api_key.json"); CocoaTweet::Authentication::Key key = CocoaTweet::Authentication::Key::fromJsonFile("api_key.json");
``` ```
### 3. Authenticate with API call
※ consumer key, consumer secret are needed. in this case, get access token with api call.
```
CocoaTweet::API::API api(key);
auto oAuthToken = api.oauth1().requestToken("oob");
const auto signInUrl = api.oauth1().authorize(oAuthToken);
std::cout << "signin : " << signInUrl << std::endl;
std::string pin = "";
std::cout << "pincode : ";
std::cin >> pin;
const auto validOAuthToken = api.oauth1().accessToken(oAuthToken, pin);
key.accessToken(validOAuthToken.oauthToken());
key.accessTokenSecret(validOAuthToken.oauthTokenSecret());
api.swapKey(key);
```
### 4. Get BearerToken with API call
if you want to call Twitter API using Bearer Token; OAuth2, you can do.
also need consumer key and secret
```
CocoaTweet::API::API api(key);
auto bearerToken = api.oauth2().token();
key.bearerToken(bearerToken);
key.authType(CocoaTweet::Authentication::Key::AUTH_TYPE::OAUTH2);
api.swapKey(key);
```
After call it, always use Bearer Token to access API which kinds of GET method.
no affect to POST method.
then, if you use this, and ONLY use kind of GET API, you DO NOT need acess token.
## Generate API object ## Generate API object
generating API object with Key. generating API object with Key.
this object is API entry point. this object is API entry point.
@@ -109,17 +158,44 @@ CocoaTweet::API::API api(key);
``` ```
## Use API ## Use API
``` ```
// Post a tweet // Post a tweet
api.status().Update("Hello, World!!\nTweet from Cocoa Twitter Library"); api.status().update("Hello, World!!\nTweet from Cocoa Twitter Library");
// Upload a media
auto media1 = api.media().Upload("path/to/file/image.jpeg");
auto media2 = api.media().Upload("path/to/file/image2.png");
api.status().update("Upload media from Cocoa Twitter Library", std::vector<std::string>{media1.id(), media2.id()});
// Retweet a tweet
api.status().retweet("tweet id");
// un RT a tweet
api.status().unretweet("tweet id")
// Delete a tweet // Delete a tweet
api.status().Destroy("tweet id"); api.status().destroy("tweet id");
// Fav. a tweet // Fav. a tweet
api.favorite().Create("tweet id"); api.favorite().create("tweet id");
// un Fav. a tweet // un Fav. a tweet
api.favorite().Destroy("tweet id"); api.favorite().destroy("tweet id");
// get a timeline with screen name
auto timeline = api.status().userTimeline("milkcocoa0902");
auto user = api.user().show("milkcocoa0902");
// send a direct message
// you cau get recipient_id using user.show()
api.directMessage().messageCreate("<recipient_id>", "Sent message using Cocoa Twitter Library");
``` ```
# More Information
See [API Document](https://cocoatweet.milkcocoa.info)
donate by BitCoin : bc1qhpm8tmq72scqpl2ccemcf0ktfjg4rsu73e99tz
+6
View File
@@ -0,0 +1,6 @@
{
"consumer_key" : "wcSkGjuvoQ7gGjB0rR5XSJiWI",
"consumer_secret" : "Qo9fiQaimj7QwqB8dXOONVI9QL2quJyxh3ZXo2REgvcrpCC3gE",
"access_token" : "1427931990792146949-nmcoAzhLSq0j0vwv8ati9F5oQN3Gb7",
"access_token_secret" : "bzWd71ARfczBMuYLcsHdlXotdNVHY3nX7WMOSrLCuHXHa"
}
+42 -4
View File
@@ -1,10 +1,34 @@
#include <cocoatweet/api/api.h> #include <cocoatweet/api/api.h>
#include <cocoatweet/authentication/oauth.h>
#include <cocoatweet/authentication/bearer.h>
#include <cocoatweet/authentication/plain.h>
namespace CocoaTweet::API { namespace CocoaTweet::API {
API::API(CocoaTweet::OAuth::Key _key) { API::API(CocoaTweet::Authentication::Key _key) {
oauth_ = std::make_shared<CocoaTweet::OAuth::OAuth1>(_key); swapKey(_key);
status_ = Statuses::Status(oauth_); }
favorite_ = Favorites::Favorite(oauth_);
void API::swapKey(const CocoaTweet::Authentication::Key _key) {
if (_key.authType() == CocoaTweet::Authentication::Key::OAUTH10A) {
oauth_ = std::make_shared<CocoaTweet::Authentication::OAuth1>(_key);
} else if (_key.authType() == CocoaTweet::Authentication::Key::OAUTH2) {
oauth_ = std::make_shared<CocoaTweet::Authentication::Bearer>(_key);
}
user_ = Users::User(oauth_);
status_ = Statuses::Status(oauth_);
favorite_ = Favorites::Favorite(oauth_);
media_ = Medias::Media(oauth_);
directMessage_ = DirectMessages::DirectMessage(oauth_);
oauth1_ = OAuth1::OAuth(oauth_);
oauth2_ = OAuth2::OAuth2(oauth_);
}
// const std::string& API::generateBearerToken() const {
// return oauth_->generateBearerToken();
// }
Users::User API::user() const {
return user_;
} }
Statuses::Status API::status() const { Statuses::Status API::status() const {
@@ -14,4 +38,18 @@ Statuses::Status API::status() const {
Favorites::Favorite API::favorite() const { Favorites::Favorite API::favorite() const {
return favorite_; return favorite_;
} }
Medias::Media API::media() const {
return media_;
}
DirectMessages::DirectMessage API::directMessage() const {
return directMessage_;
}
OAuth1::OAuth API::oauth1() const {
return oauth1_;
}
OAuth2::OAuth2 API::oauth2() const {
return oauth2_;
}
} // namespace CocoaTweet::API } // namespace CocoaTweet::API
+26 -4
View File
@@ -1,17 +1,24 @@
#ifndef COCOATWEET_API_API_H_ #ifndef COCOATWEET_API_API_H_
#define COCOATWEET_API_API_H_ #define COCOATWEET_API_API_H_
#include <cocoatweet/api/user/user.h>
#include <cocoatweet/api/status/status.h> #include <cocoatweet/api/status/status.h>
#include <cocoatweet/api/favorite/favorite.h> #include <cocoatweet/api/favorite/favorite.h>
#include <cocoatweet/oauth/oauth.h> #include <cocoatweet/api/media/media.h>
#include <cocoatweet/api/directMessage/directMessage.h>
#include <cocoatweet/authentication/authenticator.h>
#include <cocoatweet/api/oauth1/oauth.h>
#include <cocoatweet/api/oauth2/oauth2.h>
namespace CocoaTweet::API { namespace CocoaTweet::API {
/// @brief Twitter API Entry Point /// @brief Twitter API Entry Point
class API { class API {
public: public:
/// @brief primary constructor /// @brief primary constructor
/// @param[in] _key Twitter API Key typed CocoaTweet::OAuth::Key /// @param[in] _key Twitter API Key typed CocoaTweet::Authentication::Key
API(CocoaTweet::OAuth::Key _key); API(CocoaTweet::Authentication::Key _key);
Users::User user() const;
/// @brief Getter for Grouped by Statuses/* /// @brief Getter for Grouped by Statuses/*
/// @param[out] Status object typed CocoaTweet::API::Statuses::Status /// @param[out] Status object typed CocoaTweet::API::Statuses::Status
@@ -21,10 +28,25 @@ public:
/// @param[out] Favorite object typed CococaTweet::API::Favorites::Favorite /// @param[out] Favorite object typed CococaTweet::API::Favorites::Favorite
Favorites::Favorite favorite() const; Favorites::Favorite favorite() const;
Medias::Media media() const;
DirectMessages::DirectMessage directMessage() const;
OAuth1::OAuth oauth1() const;
OAuth2::OAuth2 oauth2() const;
const std::string& generateBearerToken() const;
void swapKey(const CocoaTweet::Authentication::Key _key);
private: private:
Users::User user_;
Statuses::Status status_; Statuses::Status status_;
Favorites::Favorite favorite_; Favorites::Favorite favorite_;
std::shared_ptr<CocoaTweet::OAuth::OAuth1> oauth_; Medias::Media media_;
DirectMessages::DirectMessage directMessage_;
OAuth1::OAuth oauth1_;
OAuth2::OAuth2 oauth2_;
std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> oauth_;
}; };
} // namespace CocoaTweet::API } // namespace CocoaTweet::API
@@ -0,0 +1,16 @@
#include <cocoatweet/api/directMessage/directMessage.h>
#include <cocoatweet/api/directMessage/new.h>
namespace CocoaTweet::API::DirectMessages {
DirectMessage::DirectMessage(
std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
oauth_ = _oauth;
}
void DirectMessage::messageCreate(const std::string& _recipient, const std::string& _message) {
CocoaTweet::API::DirectMessages::New dm;
dm.recipient(_recipient);
dm.message(_message);
dm.process(oauth_);
}
} // namespace CocoaTweet::API::DirectMessages
@@ -0,0 +1,28 @@
#ifndef COCOATWEET_API_DIRECTMESSAGE_DIRECTMESSAGE_H_
#define COCOATWEET_API_DIRECTMESSAGE_DIRECTMESSAGE_H_
#include "cocoatweet/api/interface/groupInterface.h"
#include "cocoatweet/authentication/authenticator.h"
#include <cocoatweet/api/model/tweet.h>
#include <vector>
#include <utility>
namespace CocoaTweet::API::DirectMessages {
/// @brief Entory point for statuses/*
class DirectMessage : public groupInterface {
public:
DirectMessage() = default;
/// @brief constructor which finally should to be called.
/// @param[in] std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> : pointer to
/// OAuth object
DirectMessage(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
void messageCreate(const std::string& _recipient, const std::string& _message);
private:
};
} // namespace CocoaTweet::API::DirectMessages
#endif
+30
View File
@@ -0,0 +1,30 @@
#include <cocoatweet/api/directMessage/new.h>
#include <cocoatweet/util/util.h>
#include <string>
namespace CocoaTweet::API::DirectMessages {
New::New() {
url_ = "https://api.twitter.com/1.1/direct_messages/events/new.json";
contentType_ = "application/json";
nlohmann::json tmp;
tmp["type"] = "message_create";
tmp["message_create"] = nlohmann::json::object();
tmp["message_create"]["target"] = nlohmann::json::object();
tmp["message_create"]["message_data"] = nlohmann::json::object();
json_["event"] = tmp;
}
void New::recipient(const std::string& _id) {
json_["event"]["message_create"]["target"]["recipient_id"] = std::stol(_id);
}
void New::message(const std::string& _message) {
json_["event"]["message_create"]["message_data"]["text"] = _message;
}
void New::process(std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
bodyParam_.insert_or_assign("data", json_.dump());
HttpPost::process(_oauth, [](const std::string& _rcv) {});
}
} // namespace CocoaTweet::API::DirectMessages
+31
View File
@@ -0,0 +1,31 @@
#ifndef COCOATWEET_API_DIRECTMESSAGE_NEW_H_
#define COCOATWEET_API_DIRECTMESSAGE_NEW_H_
#include <cocoatweet/api/interface/httpPost.h>
#include <cocoatweet/api/model/tweet.h>
#include <vector>
#include <utility>
#include <memory>
#include "nlohmann/json.hpp"
namespace CocoaTweet::API::DirectMessages {
/// @brief class for using statuses/update endpoint
class New : public CocoaTweet::API::Interface::HttpPost {
public:
New();
void recipient(const std::string& _id);
void message(const std::string& _message);
/// @brief process request for endpoint
/// @param[in] std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth : pointer
/// to oauth object
/// @param[out] CocoaTweet::API::Model::Tweet : request result
void process(std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
private:
std::string status_;
nlohmann::json json_;
};
} // namespace CocoaTweet::API::DirectMessages
#endif
+5 -5
View File
@@ -11,12 +11,12 @@ void Create::id(const std::string& _id) {
bodyParam_.insert_or_assign("id", _id); bodyParam_.insert_or_assign("id", _id);
} }
CocoaTweet::API::Model::Tweet Create::process(std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth) { CocoaTweet::API::Model::Tweet Create::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
CocoaTweet::API::Model::Tweet tweet; CocoaTweet::API::Model::Tweet tweet;
HttpPost::process(_oauth, HttpPost::process(_oauth, [&tweet](const std::string& _rcv) {
[&tweet](const unsigned int _responseCode, const std::string& _rcv) { tweet = CocoaTweet::API::Model::Tweet(_rcv);
tweet = CocoaTweet::API::Model::Tweet(_responseCode, _rcv); });
});
return tweet; return tweet;
} }
+2 -1
View File
@@ -9,7 +9,8 @@ class Create : public CocoaTweet::API::Interface::HttpPost {
public: public:
Create(); Create();
void id(const std::string& _id); void id(const std::string& _id);
CocoaTweet::API::Model::Tweet process(std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth); CocoaTweet::API::Model::Tweet process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
private: private:
}; };
+4 -5
View File
@@ -12,12 +12,11 @@ void Destroy::id(const std::string& _id) {
} }
CocoaTweet::API::Model::Tweet Destroy::process( CocoaTweet::API::Model::Tweet Destroy::process(
std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth) { std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
CocoaTweet::API::Model::Tweet tweet; CocoaTweet::API::Model::Tweet tweet;
HttpPost::process(_oauth, HttpPost::process(_oauth, [&tweet](const std::string& _rcv) {
[&tweet](const unsigned int _responseCode, const std::string& _rcv) { tweet = CocoaTweet::API::Model::Tweet(_rcv);
tweet = CocoaTweet::API::Model::Tweet(_responseCode, _rcv); });
});
return tweet; return tweet;
} }
+2 -1
View File
@@ -9,7 +9,8 @@ class Destroy : public CocoaTweet::API::Interface::HttpPost {
public: public:
Destroy(); Destroy();
void id(const std::string& _id); void id(const std::string& _id);
CocoaTweet::API::Model::Tweet process(std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth); CocoaTweet::API::Model::Tweet process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
private: private:
}; };
+3 -3
View File
@@ -3,17 +3,17 @@
#include "cocoatweet/api/favorite/destroy.h" #include "cocoatweet/api/favorite/destroy.h"
namespace CocoaTweet::API::Favorites { namespace CocoaTweet::API::Favorites {
Favorite::Favorite(std::shared_ptr<CocoaTweet::OAuth::OAuth1> _oauth) { Favorite::Favorite(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
oauth_ = _oauth; oauth_ = _oauth;
} }
CocoaTweet::API::Model::Tweet Favorite::Create(const std::string& _id) const { CocoaTweet::API::Model::Tweet Favorite::create(const std::string& _id) const {
CocoaTweet::API::Favorites::Create create; CocoaTweet::API::Favorites::Create create;
create.id(_id); create.id(_id);
return create.process(oauth_); return create.process(oauth_);
} }
CocoaTweet::API::Model::Tweet Favorite::Destroy(const std::string& _id) const { CocoaTweet::API::Model::Tweet Favorite::destroy(const std::string& _id) const {
CocoaTweet::API::Favorites::Destroy destroy; CocoaTweet::API::Favorites::Destroy destroy;
destroy.id(_id); destroy.id(_id);
return destroy.process(oauth_); return destroy.process(oauth_);
+4 -4
View File
@@ -2,16 +2,16 @@
#define COCOATWEET_API_FAVORITE_FAVORITE_H_ #define COCOATWEET_API_FAVORITE_FAVORITE_H_
#include "cocoatweet/api/interface/groupInterface.h" #include "cocoatweet/api/interface/groupInterface.h"
#include "cocoatweet/oauth/oauth.h" #include "cocoatweet/authentication/authenticator.h"
#include <cocoatweet/api/model/tweet.h> #include <cocoatweet/api/model/tweet.h>
namespace CocoaTweet::API::Favorites { namespace CocoaTweet::API::Favorites {
class Favorite : public groupInterface { class Favorite : public groupInterface {
public: public:
Favorite() = default; Favorite() = default;
Favorite(std::shared_ptr<CocoaTweet::OAuth::OAuth1> _oauth); Favorite(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
CocoaTweet::API::Model::Tweet Create(const std::string& _id) const; CocoaTweet::API::Model::Tweet create(const std::string& _id) const;
CocoaTweet::API::Model::Tweet Destroy(const std::string& _id) const; CocoaTweet::API::Model::Tweet destroy(const std::string& _id) const;
}; };
} // namespace CocoaTweet::API::Favorites } // namespace CocoaTweet::API::Favorites
@@ -2,12 +2,12 @@
#define COCOATWEET_API_INTERFACE_GROUPINTERFACE_H_ #define COCOATWEET_API_INTERFACE_GROUPINTERFACE_H_
#include <memory> #include <memory>
#include "cocoatweet/oauth/oauth.h" #include "cocoatweet/authentication/authenticator.h"
namespace CocoaTweet::API { namespace CocoaTweet::API {
class groupInterface { class groupInterface {
protected: protected:
std::weak_ptr<CocoaTweet::OAuth::OAuth1> oauth_; std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> oauth_;
}; };
} // namespace CocoaTweet::API } // namespace CocoaTweet::API
+26
View File
@@ -0,0 +1,26 @@
#ifndef COCOATWEET_API_INTERFACE_HTTPBASE_H_
#define COCOATWEET_API_INTERFACE_HTTPBASE_H_
#include <functional>
#include <memory>
#include "cocoatweet/authentication/authenticator.h"
namespace CocoaTweet::API::Interface {
class HttpBase {
public:
protected:
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> oauth_;
std::map<std::string, std::string> bodyParam_;
std::string url_;
std::string contentType_;
virtual void process(std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth,
std::function<void(const std::string&)> _callback) = 0;
static size_t curlCallback_(char* _ptr, size_t _size, size_t _nmemb, std::string* _stream) {
int realsize = _size * _nmemb;
_stream->append(_ptr, realsize);
return realsize;
}
};
} // namespace CocoaTweet::API::Interface
#endif
+154
View File
@@ -0,0 +1,154 @@
#include <cocoatweet/api/interface/httpGet.h>
#include "cocoatweet/util/util.h"
#include <cocoatweet/exception/tweetNotFoundException.h>
#include <cocoatweet/exception/authenticateException.h>
#include <cocoatweet/exception/tweetDuplicateException.h>
#include <cocoatweet/exception/tweetTooLongException.h>
#include <cocoatweet/exception/rateLimitException.h>
#include <cocoatweet/exception/tokenInvalidException.h>
#include <cocoatweet/exception/missingRequiredParamException.h>
#include <cocoatweet/exception/credentialNotAllowedException.h>
#include <cocoatweet/exception/credentialNotVerifiedException.h>
#include <cocoatweet/exception/invalidateTokenException.h>
#include "nlohmann/json.hpp"
#include <iterator>
#include <memory>
#include <vector>
#include <sstream>
#include <stdexcept>
extern "C" {
#include <curl/curl.h>
}
#ifndef NDEBUG
#include <iostream>
#endif
namespace CocoaTweet::API::Interface {
void HttpGet::process(std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth,
std::function<void(const std::string&)> _callback) {
auto url = url_;
// エンドポイントへのパラメータにOAuthパラメータを付加して署名作成
auto oauth = _oauth.lock();
// auto oauthParam = oauth->oauthParam();
// auto sigingParam = oauthParam;
// if (contentType_ == "application/x-www-form-urlencoded") {
// for (const auto [k, v] : bodyParam_) {
// sigingParam.insert_or_assign(k, v);
// }
// }
// auto signature = oauth->signature(sigingParam, "GET", url_);
// // 作成した署名をエンドポイントへのパラメータ及びOAuthパラメータに登録
// oauthParam.merge(signature);
// // ヘッダの構築
// std::string oauthHeader = "authorization: OAuth ";
// {
// std::vector<std::string> tmp;
// for (const auto& [key, value] : oauthParam) {
// tmp.push_back(key + "=" + CocoaTweet::Util::urlEncode(value));
// }
// oauthHeader += CocoaTweet::Util::join(tmp, ",");
// }
auto oauthHeader = std::string();
if (contentType_ == "application/x-www-form-urlencoded") {
oauthHeader = oauth->calculateAuthHeader(bodyParam_, "GET", url_);
} else {
oauthHeader = oauth->calculateAuthHeader({}, "GET", url_);
}
// URLの構築
{
std::vector<std::string> tmp;
for (const auto& [key, value] : bodyParam_) {
tmp.push_back(key + "=" + value);
}
url_ += std::string("?" + CocoaTweet::Util::join(tmp, "&"));
}
// do post
CURL* curl;
CURLcode res;
std::string rcv;
long responseCode;
curl = curl_easy_init();
url_ = url_;
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, url_.c_str());
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallback_);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (std::string*)&rcv);
#ifndef NDEBUG
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
#endif
// Headerを保持するcurl_slist*を初期化
struct curl_slist* headers = NULL;
// Authorizationをヘッダに追加
headers = curl_slist_append(headers, oauthHeader.c_str());
std::string contentType = "";
if (contentType_ == "application/x-www-form-urlencoded") {
contentType = contentType_;
} else if (contentType_ == "multipart/form-data") {
contentType = contentType_ + "; boundary=milkcocoa0902";
}
headers = curl_slist_append(headers, ("Content-Type: " + contentType).c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
curl_easy_cleanup(curl);
}
if (res != CURLE_OK) {
throw std::runtime_error(std::string("INTERNAL ERROR : curl(") + std::to_string(res) + ")");
exit(1);
}
#ifndef NDEBUG
std::cout << rcv << std::endl;
#endif
if ((responseCode / 100) == 4) {
auto j = nlohmann::json::parse(rcv);
if (j.count("error") != 0) {
// この形式はエラーコードを持たないのでエラー種別が特定できない
throw new CocoaTweet::Exception::Exception(j["error"]);
}
auto error = j["errors"][0]["code"];
auto message = j["errors"][0]["message"];
if (error.get<int>() == 144) {
throw CocoaTweet::Exception::TweetNotFoundException(message.get<std::string>().c_str());
} else if (error.get<int>() == 32) {
throw CocoaTweet::Exception::AuthenticateException(message.get<std::string>().c_str());
} else if (error.get<int>() == 89) {
throw CocoaTweet::Exception::TokenInvalidException(message.get<std::string>().c_str());
} else if (error.get<int>() == 187) {
throw CocoaTweet::Exception::TweetDuplicateException(message.get<std::string>().c_str());
} else if (error.get<int>() == 88 || error.get<int>() == 185) {
throw CocoaTweet::Exception::RateLimitException(message.get<std::string>().c_str());
} else if (error.get<int>() == 186) {
throw CocoaTweet::Exception::TweetTooLongException(message.get<std::string>().c_str());
} else if (error.get<int>() == 170) {
throw CocoaTweet::Exception::MissingRequiredParamException(
message.get<std::string>().c_str());
} else if (error.get<int>() == 220) {
throw CocoaTweet::Exception::CredentialNotAllowedException(
message.get<std::string>().c_str());
} else if (error.get<int>() == 99) {
throw CocoaTweet::Exception::CredentialNotVerifiedException(
message.get<std::string>().c_str());
} else if (error.get<int>() == 348) {
throw CocoaTweet::Exception::InvalidateTokenException(message.get<std::string>().c_str());
} else {
}
}
if (_callback) {
_callback(rcv);
}
}
} // namespace CocoaTweet::API::Interface
+23
View File
@@ -0,0 +1,23 @@
#ifndef COCOATWEET_API_INTERFACE_HTTPGET_H_
#define COCOATWEET_API_INTERFACE_HTTPGET_H_
#include <functional>
#include "cocoatweet/authentication/authenticator.h"
#include <cocoatweet/api/interface/httpBase.h>
namespace CocoaTweet::API::Interface {
/// @brief class for Send request with POST method
class HttpGet : public virtual HttpBase {
public:
protected:
/// @brief Send HTTP/POST using OAuth object
/// @param[in] std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth : pointer
/// to OAuth object to authenticate
/// @param[in] std::function<void(const unsigned int, const std::string&)> _callback :
/// callback method for processing to response
void process(std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth,
std::function<void(const std::string&)> _callback);
};
} // namespace CocoaTweet::API::Interface
#endif
+107 -30
View File
@@ -1,5 +1,16 @@
#include <cocoatweet/api/interface/httpPost.h> #include <cocoatweet/api/interface/httpPost.h>
#include "cocoatweet/util/util.h" #include "cocoatweet/util/util.h"
#include <cocoatweet/exception/tweetNotFoundException.h>
#include <cocoatweet/exception/authenticateException.h>
#include <cocoatweet/exception/tweetDuplicateException.h>
#include <cocoatweet/exception/tweetTooLongException.h>
#include <cocoatweet/exception/rateLimitException.h>
#include <cocoatweet/exception/tokenInvalidException.h>
#include <cocoatweet/exception/missingRequiredParamException.h>
#include <cocoatweet/exception/credentialNotAllowedException.h>
#include <cocoatweet/exception/credentialNotVerifiedException.h>
#include <cocoatweet/exception/invalidateTokenException.h>
#include "nlohmann/json.hpp"
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <vector> #include <vector>
@@ -9,48 +20,64 @@ extern "C" {
#include <curl/curl.h> #include <curl/curl.h>
} }
#ifndef NDEBUG
#include <iostream>
#endif
namespace CocoaTweet::API::Interface { namespace CocoaTweet::API::Interface {
size_t HttpPost::curlCallback_(char* _ptr, size_t _size, size_t _nmemb, std::string* _stream) { void HttpPost::process(std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth,
int realsize = _size * _nmemb; std::function<void(const std::string&)> _callback) {
_stream->append(_ptr, realsize);
return realsize;
}
void HttpPost::process(std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth,
std::function<void(const unsigned int, const std::string&)> _callback) {
// エンドポイントへのパラメータにOAuthパラメータを付加して署名作成 // エンドポイントへのパラメータにOAuthパラメータを付加して署名作成
auto oauth = _oauth.lock(); auto oauth = _oauth.lock();
auto oauthParam = oauth->oauthParam(); // auto oauthParam = oauth->oauthParam();
auto sigingParam = oauthParam; // auto sigingParam = oauthParam;
if (contentType_ == "application/x-www-form-urlencoded") { // if (contentType_ == "application/x-www-form-urlencoded") {
for (const auto [k, v] : bodyParam_) { // for (const auto [k, v] : bodyParam_) {
sigingParam.insert_or_assign(k, v); // sigingParam.insert_or_assign(k, v);
} // }
} // }
auto signature = oauth->signature(sigingParam, "POST", url_); // auto signature = oauth->signature(sigingParam, "POST", url_);
// 作成した署名をエンドポイントへのパラメータ及びOAuthパラメータに登録 // 作成した署名をエンドポイントへのパラメータ及びOAuthパラメータに登録
oauthParam.merge(signature); // oauthParam.merge(signature);
// リクエストボディの構築 // リクエストボディの構築
std::string requestBody = ""; std::string requestBody = "";
{ {
std::vector<std::string> tmp; if (contentType_ == "application/x-www-form-urlencoded") {
for (const auto& [key, value] : bodyParam_) { std::vector<std::string> tmp;
tmp.push_back(key + "=" + value); for (const auto& [key, value] : bodyParam_) {
tmp.push_back(key + "=" + value);
requestBody = CocoaTweet::Util::join(tmp, "&");
}
} else if (contentType_ == "multipart/form-data") {
for (const auto& [key, value] : bodyParam_) {
requestBody += (std::string("--") + "milkcocoa0902" + "\r\n");
requestBody +=
("Content-Disposition: form-data; name=\"" + key + "\";\r\n\r\n" + value + "\r\n");
}
requestBody += (std::string("--") + "milkcocoa0902" + "--" + "\r\n");
} else if (contentType_ == "application/json") {
requestBody = bodyParam_["data"];
} }
requestBody = CocoaTweet::Util::join(tmp, "&");
} }
// ヘッダの構築 // ヘッダの構築
std::string oauthHeader = "authorization: OAuth "; // std::string oauthHeader = "authorization: OAuth ";
{ // {
std::vector<std::string> tmp; // std::vector<std::string> tmp;
for (const auto& [key, value] : oauthParam) { // for (const auto& [key, value] : oauthParam) {
tmp.push_back(key + "=" + CocoaTweet::Util::urlEncode(value)); // tmp.push_back(key + "=" + CocoaTweet::Util::urlEncode(value));
} // }
oauthHeader += CocoaTweet::Util::join(tmp, ","); // oauthHeader += CocoaTweet::Util::join(tmp, ",");
// }
auto oauthHeader = std::string();
if (contentType_ == "application/x-www-form-urlencoded") {
oauthHeader = oauth->calculateAuthHeader(bodyParam_, "POST", url_);
} else {
oauthHeader = oauth->calculateAuthHeader({}, "POST", url_);
} }
// do post // do post
@@ -69,12 +96,24 @@ void HttpPost::process(std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth,
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallback_); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallback_);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (std::string*)&rcv); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (std::string*)&rcv);
#ifndef NDEBUG #ifndef NDEBUG
std::cout << "requestBody : " << requestBody << std::endl;
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
#endif #endif
// Headerを保持するcurl_slist*を初期化 // Headerを保持するcurl_slist*を初期化
struct curl_slist* headers = NULL; struct curl_slist* headers = NULL;
// Authorizationをヘッダに追加 // Authorizationをヘッダに追加
headers = curl_slist_append(headers, oauthHeader.c_str()); headers = curl_slist_append(headers, oauthHeader.c_str());
std::string contentType = "";
if (contentType_ == "application/x-www-form-urlencoded") {
contentType = contentType_;
} else if (contentType_ == "multipart/form-data") {
contentType = contentType_ + "; boundary=milkcocoa0902";
} else if (contentType_ == "application/json") {
contentType_ = "application/json";
}
headers = curl_slist_append(headers, ("Content-Type: " + contentType).c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
@@ -86,8 +125,46 @@ void HttpPost::process(std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth,
exit(1); exit(1);
} }
#ifndef NDEBUG
std::cout << rcv << std::endl;
#endif
if ((responseCode / 100) == 4) {
auto j = nlohmann::json::parse(rcv);
if (j.count("error") != 0) {
// この形式はエラーコードを持たないのでエラー種別が特定できない
throw new CocoaTweet::Exception::Exception(j["error"]);
}
auto error = j["errors"][0]["code"];
auto message = j["errors"][0]["message"];
if (error.get<int>() == 144) {
throw CocoaTweet::Exception::TweetNotFoundException(message.get<std::string>().c_str());
} else if (error.get<int>() == 32) {
throw CocoaTweet::Exception::AuthenticateException(message.get<std::string>().c_str());
} else if (error.get<int>() == 89) {
throw CocoaTweet::Exception::TokenInvalidException(message.get<std::string>().c_str());
} else if (error.get<int>() == 187) {
throw CocoaTweet::Exception::TweetDuplicateException(message.get<std::string>().c_str());
} else if (error.get<int>() == 88 || error.get<int>() == 185) {
throw CocoaTweet::Exception::RateLimitException(message.get<std::string>().c_str());
} else if (error.get<int>() == 186) {
throw CocoaTweet::Exception::TweetTooLongException(message.get<std::string>().c_str());
} else if (error.get<int>() == 170) {
throw CocoaTweet::Exception::MissingRequiredParamException(
message.get<std::string>().c_str());
} else if (error.get<int>() == 220) {
throw CocoaTweet::Exception::CredentialNotAllowedException(
message.get<std::string>().c_str());
} else if (error.get<int>() == 99) {
throw CocoaTweet::Exception::CredentialNotVerifiedException(
message.get<std::string>().c_str());
} else if (error.get<int>() == 348) {
throw CocoaTweet::Exception::InvalidateTokenException(message.get<std::string>().c_str());
}
}
if (_callback) { if (_callback) {
_callback(responseCode, rcv); _callback(rcv);
} }
} }
} // namespace CocoaTweet::API::Interface } // namespace CocoaTweet::API::Interface
+11 -9
View File
@@ -2,19 +2,21 @@
#define COCOATWEET_API_INTERFACE_HTTPPOST_H_ #define COCOATWEET_API_INTERFACE_HTTPPOST_H_
#include <functional> #include <functional>
#include "cocoatweet/oauth/oauth.h" #include "cocoatweet/authentication/authenticator.h"
#include <cocoatweet/api/interface/httpBase.h>
namespace CocoaTweet::API::Interface { namespace CocoaTweet::API::Interface {
class HttpPost { /// @brief class for Send request with POST method
class HttpPost : public HttpBase {
public: public:
protected: protected:
std::weak_ptr<CocoaTweet::OAuth::OAuth1> oauth_; /// @brief Send HTTP/POST using OAuth object
std::map<std::string, std::string> bodyParam_; /// @param[in] std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth : pointer
std::string url_; /// to OAuth object to authenticate
std::string contentType_; /// @param[in] std::function<void(const unsigned int, const std::string&)> _callback :
void process(std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth, /// callback method for processing to response
std::function<void(const unsigned int, const std::string&)> _callback); void process(std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth,
static size_t curlCallback_(char* _ptr, size_t _size, size_t _nmemb, std::string* _stream); std::function<void(const std::string&)> _callback);
}; };
} // namespace CocoaTweet::API::Interface } // namespace CocoaTweet::API::Interface
+13
View File
@@ -0,0 +1,13 @@
#include "cocoatweet/api/media/media.h"
namespace CocoaTweet::API::Medias {
Media::Media(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
oauth_ = _oauth;
}
CocoaTweet::API::Model::MediaStore Media::upload(const std::string& _media) const {
CocoaTweet::API::Medias::Upload upload;
upload.media(_media);
return upload.process(oauth_);
}
} // namespace CocoaTweet::API::Medias
+29
View File
@@ -0,0 +1,29 @@
#ifndef COCOATWEET_API_MEDIA_MEDIA_H_
#define COCOATWEET_API_MEDIA_MEDIA_H_
#include "cocoatweet/api/interface/groupInterface.h"
#include "cocoatweet/authentication/authenticator.h"
#include <cocoatweet/api/model/mediaStore.h>
#include <cocoatweet/api/media/upload.h>
#include <vector>
namespace CocoaTweet::API::Medias {
/// @brief Entory point for statuses/*
class Media : public groupInterface {
public:
/// @brief primary constructor to allow for create NON-INITIALIZED object
Media() = default;
/// @brief constructor which finally should to be called.
/// @param[in] std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> : pointer to
/// OAuth object
Media(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
CocoaTweet::API::Model::MediaStore upload(const std::string& _file) const;
private:
};
} // namespace CocoaTweet::API::Medias
#endif
+88
View File
@@ -0,0 +1,88 @@
#include <cocoatweet/api/media/upload.h>
#include <cocoatweet/api/model/mediaStore.h>
#include <cocoatweet/exception/unsupportedMediaTypeException.h>
#include <fstream>
namespace CocoaTweet::API::Medias {
const std::map<std::string, std::string> Upload::mimeType = {{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".png", "image/png"},
{".gif", "image/gif"},
{".mp4", "video/mp4"}};
Upload::Upload() {
url_ = "https://upload.twitter.com/1.1/media/upload.json";
}
void Upload::media(const std::string& _media) {
media_ = _media;
}
void Upload::mediaId(const std::string& _mediaId) {}
CocoaTweet::API::Model::MediaStore Upload::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
auto extension = std::filesystem::path(media_).extension().string<char>();
if (mimeType.count(extension) == 0) {
throw new CocoaTweet::Exception::UnsupportedMediaTypeException(
std::string("media type \"" + extension + "\" is not supported media type"));
}
auto backup = bodyParam_;
CocoaTweet::API::Model::MediaStore media;
std::ifstream ifs(media_, std::ios::binary);
std::string data((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
ifs.close();
bodyParam_.insert_or_assign("total_bytes", std::to_string(data.size()));
// INIT
{
contentType_ = "application/x-www-form-urlencoded";
bodyParam_.insert_or_assign("command", "INIT");
bodyParam_.insert_or_assign(
"media_type", mimeType.at(std::filesystem::path(media_).extension().string<char>()));
HttpPost::process(_oauth, [&media](const std::string& _rcv) {
media = CocoaTweet::API::Model::MediaStore::parse(_rcv);
});
bodyParam_.insert_or_assign("media_id", media.id());
}
// APPEND
{
contentType_ = "multipart/form-data";
bodyParam_.erase("media_type");
bodyParam_.erase("total_bytes");
unsigned int segment = 0;
const unsigned long long chunk = 1024 * 512;
while (segment * chunk < data.size()) {
bodyParam_.insert_or_assign("command", "APPEND");
bodyParam_.insert_or_assign("segment_index", std::to_string(segment));
bodyParam_.insert_or_assign("media", data.substr(segment * chunk, chunk));
HttpPost::process(_oauth, [](const std::string& _rsv) {
// std::cout << _responseCode << std::endl << _rsv<< std::endl;
});
segment++;
}
}
// FINALIZE
{
contentType_ = "application/x-www-form-urlencoded";
bodyParam_.insert_or_assign("command", "FINALIZE");
bodyParam_.erase("segment_index");
bodyParam_.erase("media");
HttpPost::process(_oauth, [&media](const std::string& _rcv) {
media = CocoaTweet::API::Model::MediaStore::parse(_rcv);
});
}
// STATUS if needed
{}
bodyParam_ = backup;
return media;
}
} // namespace CocoaTweet::API::Medias
+29 -13
View File
@@ -1,22 +1,38 @@
#ifndef COCOATWEET_API_MEDIA_UPLOAD_H_ #ifndef COCOATWEET_API_MEDIA_UPLOAD_H_
#define COCOATWEET_API_MEDIA_UPLOAD_H_ #define COCOATWEET_API_MEDIA_UPLOAD_H_
#include <cocoatweet/api/interface/postInterface.h> #include <cocoatweet/api/interface/httpPost.h>
#include <cocoatweet/api/model/mediaStore.h>
#include <string>
#include <filesystem>
namespace CocoaTweet::API::Medias { namespace CocoaTweet::API::Medias {
class Upload : public postInterface { /// @brief entry point for using media/upload endpoint
public: class Upload : public CocoaTweet::API::Interface::HttpPost {
enum Command : class st::string { private:
INIT = "INIT", std::string media_;
APPEND = "APPEND", static const std::map<std::string, std::string> mimeType;
FINALIZE = "FINALIZE",
};
Upload::Upload(); public:
/// @brief default constructor
Upload();
/// @brief set media file with absolute path
/// @param[in] const std::string& _media : absolute path to media should be uploaded
/// @param[out] none
void media(const std::string& _media); void media(const std::string& _media);
void mediaId(const std::string _mediaId);
void process(std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth, Command _command); /// @brief set media id(no affect to process. will be obsoleted)
} void mediaId(const std::string& _mediaId);
/// @brief upload media
/// @param[in] std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth : pointer
/// to OAuth object for authenticate
/// @param[out] CocoaTweet::API::Model::MediaStore : media upload result. use id() for post
/// tweet.
CocoaTweet::API::Model::MediaStore process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
};
} // namespace CocoaTweet::API::Medias } // namespace CocoaTweet::API::Medias
#endif #endif
+13
View File
@@ -0,0 +1,13 @@
#include "bearerToken.h"
namespace CocoaTweet::API::Model {
BearerToken::BearerToken() : token_("") {}
BearerToken::BearerToken(const std::string _token) : token_(_token) {}
const std::string& BearerToken::token() const {
return token_;
}
void BearerToken::token(const std::string& _token) {
token_ = _token;
}
} // namespace CocoaTweet::API::Model
+17
View File
@@ -0,0 +1,17 @@
#ifndef COCOATWEET_API_MODEL_BEARERTOKEN_H_
#define COCOATWEET_API_MODEL_BEARERTOKEN_H_
#include <string>
namespace CocoaTweet::API::Model {
class BearerToken {
std::string token_;
public:
BearerToken();
BearerToken(const std::string _token);
const std::string& token() const;
void token(const std::string& _token);
};
} // namespace CocoaTweet::API::Model
#endif
+67
View File
@@ -0,0 +1,67 @@
#include <cocoatweet/api/model/mediaStore.h>
#include <cocoatweet/exception/exception.h>
#include "nlohmann/json.hpp"
namespace CocoaTweet::API::Model {
MediaStore MediaStore::parse(const std::string& _json) {
auto j = nlohmann::json::parse(_json);
MediaStore media;
if (j.count("media_id_string") != 0) {
media.id(j["media_id_string"]);
}
if (j.count("size") != 0) {
media.size(j["size"]);
}
if (j.count("expires_after_secs") != 0) {
media.expires(j["expires_after_secs"]);
}
if (j.count("processing_info") == 0) {
media.state("succeeded");
} else {
media.state(j["processing_info"]["state"]);
media.remain(j["processing_info"]["check_after_secs"].get<unsigned int>());
}
return media;
}
void MediaStore::id(const std::string _id) {
id_ = _id;
}
void MediaStore::size(const unsigned int _size) {
size_ = _size;
}
void MediaStore::expires(const unsigned int _ex) {
expires_ = _ex;
}
void MediaStore::state(const std::string _state) {
state_ = _state;
}
void MediaStore::remain(const unsigned int _remain) {
remain_ = _remain;
}
const std::string MediaStore::id() const {
return id_;
}
const unsigned int MediaStore::size() const {
return size_;
}
const unsigned int MediaStore::expire() const {
return expires_;
}
const std::string MediaStore::state() const {
return state_;
}
const unsigned int MediaStore::remain() const {
return remain_;
}
} // namespace CocoaTweet::API::Model
+85
View File
@@ -0,0 +1,85 @@
#ifndef COCOATWEET_API_MODEL_MEDIASTORE_H_
#define COCOATWEET_API_MODEL_MEDIASTORE_H_
#include <string>
namespace CocoaTweet::API::Model {
/// @brief data class for tweet object
class MediaStore final {
public:
/// @brief constructor
MediaStore() = default;
/// @brief copy constructor
MediaStore(const MediaStore&) = default;
/// @brief constructor for create object from json response
/// @param[in] const std::string& _json : received content from twitter endpoint
MediaStore(const std::string& _json) : MediaStore(MediaStore::parse(_json)) {}
/// @brief response parser for MediaStore object
/// @param[in] const std::string& _json : received content from twitter endpoint
/// @param[out] CocoaTweet::API::Model::MediaStore
static MediaStore parse(const std::string& _json);
/// @brief set id of tweet
/// @param[in] const std::string _id : media id to set
/// @param[out] none
void id(const std::string _id);
/// @brief set media size in byte
/// @param[in] const unsigned int _size : media size in byte
/// @param[out] none
void size(const unsigned int _size);
/// @brief set remaining time to expire the media
/// @param[in] const unsigned int : remaining time to expire the media ib sec
/// @param[out] none
void expires(const unsigned int _ex);
/// @brief set media processing status
/// @param[in] const std::string _state : media processed status
/// @param[out] none
void state(const std::string _state);
/// @brief set how second need for upload complete
/// @param[in] needed time to upload complete on server in second
/// @param[out] none
void remain(const unsigned int _remain);
/// @brief get media id
/// @param[in] none
/// @param[out] const std::string : media id
const std::string id() const;
/// @brief get media size
/// @param[in] none
/// @param[out] const unsigned int : media size in byte
const unsigned int size() const;
/// @brief get remaining time to expire the media
/// @param[in] none
/// @param[out] const unsigned int : remaining time to expire the media ib sec
const unsigned int expire() const;
/// @brief get media processing status
/// @param[in] none
/// @param[out] const std::string _state : media processed status
const std::string state() const;
/// @brief set how second need for upload complete
/// @param[in] none
/// @param[out] needed time to upload complete on server in second
const unsigned int remain() const;
private:
std::string id_;
unsigned long long size_;
unsigned long long expires_;
std::string state_;
unsigned long long remain_;
};
} // namespace CocoaTweet::API::Model
#endif
+20
View File
@@ -0,0 +1,20 @@
#include "oauthToken.h"
namespace CocoaTweet::API::Model {
OAuthToken::OAuthToken() : oauthToken_(""), oauthTokenSecret_("") {}
OAuthToken::OAuthToken(const std::string _oauthToken, const std::string& _oauthTokenSecret)
: oauthToken_(_oauthToken), oauthTokenSecret_(_oauthTokenSecret) {}
const std::string& OAuthToken::oauthToken() const {
return oauthToken_;
}
const std::string& OAuthToken::oauthTokenSecret() const {
return oauthTokenSecret_;
}
void OAuthToken::oauthToken(const std::string& _oauthToken) {
oauthToken_ = _oauthToken;
}
void OAuthToken::oauthTokenSecret(const std::string& _oauthTokenSecret) {
oauthTokenSecret_ = _oauthTokenSecret;
}
} // namespace CocoaTweet::API::Model
+20
View File
@@ -0,0 +1,20 @@
#ifndef COCOATWEET_API_MODEL_OAUTHTOKEN_H_
#define COCOATWEET_API_MODEL_OAUTHTOKEN_H_
#include <string>
namespace CocoaTweet::API::Model {
class OAuthToken {
std::string oauthToken_;
std::string oauthTokenSecret_;
public:
OAuthToken();
OAuthToken(const std::string _oauthToken, const std::string& _oauthTokenSecret);
const std::string& oauthToken() const;
const std::string& oauthTokenSecret() const;
void oauthToken(const std::string& _oauthToken);
void oauthTokenSecret(const std::string& _oauthTokenSecret);
};
} // namespace CocoaTweet::API::Model
#endif
+18 -25
View File
@@ -1,35 +1,17 @@
#include <cocoatweet/api/model/tweet.h> #include <cocoatweet/api/model/tweet.h>
#include <cocoatweet/exception/tweetNotFoundException.h>
#include <cocoatweet/exception/authenticateException.h>
#include <cocoatweet/exception/tweetDuplicateException.h>
#include <cocoatweet/exception/tweetTooLongException.h>
#include <cocoatweet/exception/rateLimitException.h>
#include "nlohmann/json.hpp" #include "nlohmann/json.hpp"
namespace CocoaTweet::API::Model { namespace CocoaTweet::API::Model {
Tweet Tweet::parse(const unsigned int _responseCode, const std::string& _json) { Tweet Tweet::parse(const std::string& _json) {
auto j = nlohmann::json::parse(_json); auto j = nlohmann::json::parse(_json);
Tweet tweet; Tweet tweet;
if (_responseCode == 200) { tweet.id(j["id_str"]);
tweet.id(j["id_str"]); tweet.createdAt(j["created_at"]);
tweet.createdAt(j["created_at"]); tweet.text(j["text"]);
tweet.text(j["text"]); tweet.source(j["source"]);
tweet.source(j["source"]); if (j.contains("user")) {
} else { tweet.user(CocoaTweet::API::Model::User(j["user"].dump()));
auto error = j["errors"][0]["code"];
auto message = j["errors"][0]["message"];
if (error.get<int>() == 144) {
throw CocoaTweet::Exception::TweetNotFoundException(message.get<std::string>().c_str());
} else if (error.get<int>() == 32) {
throw CocoaTweet::Exception::AuthenticateException(message.get<std::string>().c_str());
} else if (error.get<int>() == 187) {
throw CocoaTweet::Exception::TweetDuplicateException(message.get<std::string>().c_str());
} else if (error.get<int>() == 88 || error.get<int>() == 185) {
throw CocoaTweet::Exception::RateLimitException(message.get<std::string>().c_str());
} else if (error.get<int>() == 186) {
throw CocoaTweet::Exception::TweetTooLongException(message.get<std::string>().c_str());
}
} }
return tweet; return tweet;
@@ -50,16 +32,27 @@ void Tweet::source(const std::string _source) {
source_ = _source; source_ = _source;
} }
void Tweet::user(const CocoaTweet::API::Model::User _user) {
user_ = _user;
}
const std::string Tweet::id() const { const std::string Tweet::id() const {
return id_; return id_;
} }
const std::string Tweet::createdAt() const { const std::string Tweet::createdAt() const {
return createdAt_; return createdAt_;
} }
const std::string Tweet::text() const { const std::string Tweet::text() const {
return text_; return text_;
} }
const std::string Tweet::source() const { const std::string Tweet::source() const {
return source_; return source_;
} }
const CocoaTweet::API::Model::User Tweet::user() const {
return user_;
}
} // namespace CocoaTweet::API::Model } // namespace CocoaTweet::API::Model
+53 -4
View File
@@ -1,30 +1,79 @@
#ifndef COCOATWEET_API_MODEL_TWEET_H_ #ifndef COCOATWEET_API_MODEL_TWEET_H_
#define COCOATWEET_API_MODEL_TWEET_H_ #define COCOATWEET_API_MODEL_TWEET_H_
#include <cocoatweet/api/model/user.h>
#include <string> #include <string>
namespace CocoaTweet::API::Model { namespace CocoaTweet::API::Model {
/// @brief data class for tweet object
class Tweet final { class Tweet final {
public: public:
Tweet() = default; /// @brief constructor
Tweet() = default;
/// @brief copy constructor
Tweet(const Tweet&) = default; Tweet(const Tweet&) = default;
Tweet(const unsigned int _responseCode, const std::string& _json)
: Tweet(Tweet::parse(_responseCode, _json)) {} /// @brief constructor for create object from json response
static Tweet parse(const unsigned int _responseCode, const std::string& _json); /// @param[in] const std::string& _json : received content from twitter endpoint
Tweet(const std::string& _json) : Tweet(Tweet::parse(_json)) {}
/// @brief response parser for tweet object
/// @param[in] const std::string& _json : received content from twitter endpoint
/// @param[out] CocoaTweet::API::Model::Tweet
static Tweet parse(const std::string& _json);
/// @brief set id of tweet
/// @param[in] const std::string _id : tweet id to set
/// @param[out] none
void id(const std::string _id); void id(const std::string _id);
/// @brief set created time of tweet
/// @param[in] const std::string _at : tweet created time to set
/// @param[out] none
void createdAt(const std::string _at); void createdAt(const std::string _at);
/// @brief set tweet text
/// @param[in] const std::string _text : text of tweet to set
/// @param[out] none
void text(const std::string _text); void text(const std::string _text);
/// @brief set tweet source
/// @param[in] const std::string _source : source information to set
/// @param[out] none
void source(const std::string _source); void source(const std::string _source);
void user(const CocoaTweet::API::Model::User _user);
/// @brief get tweet id
/// @param[in] none
/// @param[out] const std::string : tweet id
const std::string id() const; const std::string id() const;
/// @brief get tweet create time
/// @param[in] none
/// @param[out] const std::string : time of tweet created time
const std::string createdAt() const; const std::string createdAt() const;
/// @brief get tweet text
/// @param[in] none
/// @param[out] const std::string : tweet text
const std::string text() const; const std::string text() const;
/// @brief get tweet source information
/// @param[in] none
/// @param[out] const std::string : source information
const std::string source() const; const std::string source() const;
const CocoaTweet::API::Model::User user() const;
private: private:
std::string id_; std::string id_;
std::string createdAt_; std::string createdAt_;
std::string text_; std::string text_;
std::string source_; std::string source_;
CocoaTweet::API::Model::User user_;
}; };
} // namespace CocoaTweet::API::Model } // namespace CocoaTweet::API::Model
+130
View File
@@ -0,0 +1,130 @@
#include <cocoatweet/api/model/user.h>
#include "nlohmann/json.hpp"
namespace CocoaTweet::API::Model {
CocoaTweet::API::Model::User User::parse(const std::string& _json) {
auto j = nlohmann::json::parse(_json);
User user;
user.id(j["id_str"]);
user.name(j["name"]);
user.screenName(j["screen_name"]);
if (j["location"].is_null() == false) {
user.location(j["location"]);
}
if (j["url"].is_null() == false) {
user.location(j["url"]);
}
if (j["description"].is_null() == false) {
user.location(j["description"]);
}
user.protectedUser(j["protected"]);
user.follower(j["followers_count"]);
user.follow(j["friends_count"]);
user.listed(j["listed_count"]);
user.favorite(j["favourites_count"]);
if (j["profile_banner_url"].is_null() == false) {
user.bannerUrl(j["profile_banner_url"]);
}
if (j["profile_image_url_https"].is_null() == false) {
user.iconUrl(j["profile_image_url_https"]);
}
return user;
}
void User::id(const std::string& _id) {
id_ = _id;
}
void User::name(const std::string& _name) {
name_ = _name;
}
void User::screenName(const std::string& _screen) {
screenName_ = _screen;
}
void User::location(const std::string& _location) {
location_ = _location;
}
void User::url(const std::string& _url) {
url_ = _url;
}
void User::description(const std::string& _description) {
description_ = _description;
}
void User::protectedUser(const bool _protected) {
protectedUser_ = _protected;
}
void User::follower(const long _follower) {
follower_ = _follower;
}
void User::follow(const long _follow) {
follow_ = _follow;
}
void User::listed(const long _listed) {
listed_ = _listed;
}
void User::favorite(const long _favorite) {
favorite_ = _favorite;
}
void User::createdAt(const std::string& _created) {
createdAt_ = _created;
}
void User::bannerUrl(const std::string& _banner) {
bannerUrl_ = _banner;
}
void User::iconUrl(const std::string& _icon) {
iconUrl_ = _icon;
}
const std::string& User::id() const {
return id_;
}
const std::string& User::name() const {
return name_;
}
const std::string& User::screenName() const {
return screenName_;
}
const std::string& User::location() const {
return location_;
}
const std::string& User::url() const {
return url_;
}
const std::string& User::description() const {
return description_;
}
bool User::protectedUser() const {
return protectedUser_;
}
long User::follower() const {
return follower_;
}
long User::follow() const {
return follow_;
}
long User::listed() const {
return listed_;
}
long User::favorite() const {
return favorite_;
}
const std::string& User::created() const {
return createdAt_;
}
const std::string& User::bannerUrl() const {
return bannerUrl_;
}
const std::string& User::icon() const {
return iconUrl_;
}
} // namespace CocoaTweet::API::Model
+74
View File
@@ -0,0 +1,74 @@
#ifndef COCOATWEET_API_MODEL_USER_H_
#define COCOATWEET_API_MODEL_USER_H_
#include <string>
namespace CocoaTweet::API::Model {
/// @brief data class for tweet object
class User final {
public:
/// @brief constructor
User() = default;
/// @brief copy constructor
User(const User&) = default;
/// @brief constructor for create object from json response
/// @param[in] const std::string& _json : received content from twitter endpoint
User(const std::string& _json) : User(User::parse(_json)) {}
/// @brief response parser for user object
/// @param[in] const std::string& _json : received content from twitter endpoint
/// @param[out] CocoaTweet::API::Model::User
static User parse(const std::string& _json);
void id(const std::string& _id);
void name(const std::string& _name);
void screenName(const std::string& _screen);
void location(const std::string& _location);
void url(const std::string& _url);
void description(const std::string& _description);
void protectedUser(const bool _protected);
void follower(const long _follower);
void follow(const long _follow);
void listed(const long _listed);
void favorite(const long _favorite);
void createdAt(const std::string& _created);
void bannerUrl(const std::string& _banner);
void iconUrl(const std::string& _icon);
const std::string& id() const;
const std::string& name() const;
const std::string& screenName() const;
const std::string& location() const;
const std::string& url() const;
const std::string& description() const;
bool protectedUser() const;
long follower() const;
long follow() const;
long listed() const;
long favorite() const;
const std::string& created() const;
const std::string& bannerUrl() const;
const std::string& icon() const;
private:
std::string id_;
std::string name_;
std::string screenName_;
std::string location_;
std::string url_;
std::string description_;
bool protectedUser_;
long follower_;
long follow_;
long listed_;
long favorite_;
std::string createdAt_;
std::string bannerUrl_;
std::string iconUrl_;
};
} // namespace CocoaTweet::API::Model
#endif
+40
View File
@@ -0,0 +1,40 @@
#include <cocoatweet/api/oauth1/accessToken.h>
#include <cocoatweet/util/util.h>
#include <cocoatweet/authentication/oauth.h>
namespace CocoaTweet::API::OAuth1 {
AccessToken::AccessToken() {
contentType_ = "application/x-www-form-urlencoded";
url_ = "https://api.twitter.com/oauth/access_token";
}
void AccessToken::oauthVerifier(const std::string& _verifier) {
bodyParam_.insert_or_assign("oauth_verifier", _verifier);
}
void AccessToken::oauthToken(const CocoaTweet::API::Model::OAuthToken _token) {
oauthToken_ = _token;
}
const CocoaTweet::API::Model::OAuthToken AccessToken::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
auto key = _oauth.lock()->key();
key.authType(CocoaTweet::Authentication::Key::AUTH_TYPE::OAUTH10A);
key.accessToken(oauthToken_.oauthToken());
key.accessTokenSecret(oauthToken_.oauthTokenSecret());
auto oauth = std::make_shared<CocoaTweet::Authentication::OAuth1>(key);
CocoaTweet::API::Model::OAuthToken oauthToken;
HttpPost::process(oauth, [&oauthToken](const std::string& _rcv) {
auto mp = CocoaTweet::Util::parse(_rcv, '&', '=');
if (mp.count("oauth_token")) {
oauthToken.oauthToken(mp.at("oauth_token"));
}
if (mp.count("oauth_token_secret")) {
oauthToken.oauthTokenSecret(mp.at("oauth_token_secret"));
}
});
return oauthToken;
}
} // namespace CocoaTweet::API::OAuth1
+22
View File
@@ -0,0 +1,22 @@
#ifndef COCOATWEET_API_OAUTH1_ACCESSTOKEN_H_
#define COCOATWEET_API_OAUTH1_ACCESSTOKEN_H_
#include <cocoatweet/api/interface/httpPost.h>
#include <cocoatweet/api/model/oauthToken.h>
namespace CocoaTweet::API::OAuth1 {
class AccessToken : public CocoaTweet::API::Interface::HttpPost {
private:
CocoaTweet::API::Model::OAuthToken oauthToken_;
public:
AccessToken();
void oauthVerifier(const std::string& _verifier);
void oauthToken(const CocoaTweet::API::Model::OAuthToken _token);
const CocoaTweet::API::Model::OAuthToken process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
};
} // namespace CocoaTweet::API::OAuth1
#endif
+4
View File
@@ -0,0 +1,4 @@
#ifndef COCOATWEET_API_OAUTH1_AUTHENTICATE_H_
#define COCOATWEET_API_OAUTH1_AUTHENTICATE_H_
#endif
+35
View File
@@ -0,0 +1,35 @@
#include <string>
#include <cocoatweet/api/oauth1/authorize.h>
#include <iostream>
#include <cocoatweet/util/util.h>
namespace CocoaTweet::API::OAuth1 {
Authorize::Authorize() {
contentType_ = "application/x-www-form-urlencoded";
url_ = "https://api.twitter.com/oauth/authorize";
}
void Authorize::oauthToken(const std::string& _oauthToken) {
bodyParam_.insert_or_assign("oauth_token", _oauthToken);
}
void Authorize::forceLogin(const bool _forceLogin) {
bodyParam_.insert_or_assign("force_login", std::to_string(static_cast<int>(_forceLogin)));
}
void Authorize::screenName(const std::string& _screenName) {
bodyParam_.insert_or_assign("screen_name", _screenName);
}
const std::string Authorize::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> __unused__) {
std::vector<std::string> tmp;
std::string query = "";
for (const auto& [key, value] : bodyParam_) {
tmp.push_back(key + "=" + value);
query = CocoaTweet::Util::join(tmp, "&");
}
return url_ + "?" + query;
;
}
} // namespace CocoaTweet::API::OAuth1
+21
View File
@@ -0,0 +1,21 @@
#ifndef COCOATWEET_API_OAUTH1_AUTHORIZE_H_
#define COCOATWEET_API_OAUTH1_AUTHORIZE_H_
#include <cocoatweet/api/interface/httpPost.h>
namespace CocoaTweet::API::OAuth1 {
class Authorize : public CocoaTweet::API::Interface::HttpPost {
public:
Authorize();
void oauthToken(const std::string& _oauthToken);
void forceLogin(const bool _forceLogin);
void screenName(const std::string& _screenName);
const std::string process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> __unused__);
};
} // namespace CocoaTweet::API::OAuth1
#endif
@@ -0,0 +1,27 @@
#include <cocoatweet/api/oauth1/invalidateToken.h>
#include <cocoatweet/util/util.h>
#include "nlohmann/json.hpp"
#include <cocoatweet/authentication/oauth.h>
#include <iostream>
namespace CocoaTweet::API::OAuth1 {
InvalidateToken::InvalidateToken() {
contentType_ = "application/x-www-form-urlencoded";
url_ = "https://api.twitter.com/1.1/oauth/invalidate_token";
}
const CocoaTweet::API::Model::OAuthToken InvalidateToken::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
auto key = _oauth.lock()->key();
key.authType(CocoaTweet::Authentication::Key::AUTH_TYPE::OAUTH10A);
auto oauth = std::make_shared<CocoaTweet::Authentication::OAuth1>(key);
CocoaTweet::API::Model::OAuthToken oauthToken;
HttpPost::process(oauth, [&oauthToken](const std::string& _rcv) {
std::cout << _rcv << std::endl;
auto j = nlohmann::json::parse(_rcv);
oauthToken.oauthToken(j["access_token"]);
});
return oauthToken;
}
} // namespace CocoaTweet::API::OAuth1
@@ -0,0 +1,17 @@
#ifndef COCOATWEET_API_OAUTH1_INVALIDATETOKEN_H_
#define COCOATWEET_API_OAUTH1_INVALIDATETOKEN_H_
#include <cocoatweet/api/interface/httpPost.h>
#include <cocoatweet/api/model/oauthToken.h>
namespace CocoaTweet::API::OAuth1 {
class InvalidateToken : public CocoaTweet::API::Interface::HttpPost {
private:
public:
InvalidateToken();
const CocoaTweet::API::Model::OAuthToken process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
};
} // namespace CocoaTweet::API::OAuth1
#endif
+45
View File
@@ -0,0 +1,45 @@
#include <cocoatweet/api/oauth1/oauth.h>
#include <cocoatweet/authentication/oauth.h>
namespace CocoaTweet::API::OAuth1 {
OAuth::OAuth(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
oauth_ = _oauth;
}
CocoaTweet::API::Model::OAuthToken OAuth::requestToken(
const std::string& _oauthCallback) const {
// auto key = oauth_.lock()->key();
// key.authType(CocoaTweet::Authentication::Key::AUTH_TYPE::OAUTH10A);
// auto oauth = std::make_shared<CocoaTweet::Authentication::OAuth1>(key);
CocoaTweet::API::OAuth1::RequestToken requestToken;
requestToken.oauthCallback(_oauthCallback);
return requestToken.process(oauth_);
}
const std::string OAuth::authorize(const CocoaTweet::API::Model::OAuthToken _oauthToken) const {
CocoaTweet::API::OAuth1::Authorize authorize;
authorize.oauthToken(_oauthToken.oauthToken());
return authorize.process(oauth_);
}
const CocoaTweet::API::Model::OAuthToken OAuth::accessToken(
const CocoaTweet::API::Model::OAuthToken _oauthToken, const std::string _verifier) const {
// auto key = oauth_.lock()->key();
// key.authType(CocoaTweet::Authentication::Key::AUTH_TYPE::OAUTH10A);
// key.accessToken(_oauthToken.oauthToken());
// key.accessTokenSecret(_oauthToken.oauthTokenSecret());
// auto oauth = std::make_shared<CocoaTweet::Authentication::OAuth1>(key);
CocoaTweet::API::OAuth1::AccessToken accessToken;
accessToken.oauthVerifier(_verifier);
return accessToken.process(oauth_);
}
const CocoaTweet::API::Model::OAuthToken OAuth::invalidateToken() const {
// auto key = oauth_.lock()->key();
// key.authType(CocoaTweet::Authentication::Key::AUTH_TYPE::OAUTH10A);
// auto oauth = std::make_shared<CocoaTweet::Authentication::OAuth1>(key);
CocoaTweet::API::OAuth1::InvalidateToken invalidateToken;
return invalidateToken.process(oauth_);
}
} // namespace CocoaTweet::API::OAuth1
+33
View File
@@ -0,0 +1,33 @@
#ifndef COCOATWEET_API_OAUTH1_OAUTH_H_
#define COCOATWEET_API_OAUTH1_OAUTH_H_
#include "cocoatweet/api/interface/groupInterface.h"
#include <cocoatweet/api/oauth1/accessToken.h>
#include <cocoatweet/api/oauth1/requestToken.h>
#include <cocoatweet/api/oauth1/authorize.h>
#include <cocoatweet/api/oauth1/invalidateToken.h>
#include <cocoatweet/api/model/oauthToken.h>
#include <vector>
#include <utility>
namespace CocoaTweet::API::OAuth1 {
/// @brief class for using users/show endpoint
class OAuth : public groupInterface {
public:
/// @brief primary constructor
OAuth() = default;
/// @brief constructor which finally should to be called.
/// @param[in] std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> : pointer to
/// OAuth object
OAuth(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
CocoaTweet::API::Model::OAuthToken requestToken(const std::string& _oauthCallback) const;
const std::string authorize(const CocoaTweet::API::Model::OAuthToken _oauthToken) const;
const CocoaTweet::API::Model::OAuthToken accessToken(
const CocoaTweet::API::Model::OAuthToken _oauthToken, const std::string _verifier) const;
const CocoaTweet::API::Model::OAuthToken invalidateToken() const;
};
} // namespace CocoaTweet::API::OAuth1
#endif
+33
View File
@@ -0,0 +1,33 @@
#include <cocoatweet/api/oauth1/requestToken.h>
#include <cocoatweet/util/util.h>
#include <cocoatweet/authentication/oauth.h>
namespace CocoaTweet::API::OAuth1 {
RequestToken::RequestToken() {
contentType_ = "application/x-www-form-urlencoded";
url_ = "https://api.twitter.com/oauth/request_token";
}
void RequestToken::oauthCallback(const std::string& _oauthCallback) {
bodyParam_.insert_or_assign("oauth_callback", _oauthCallback);
}
CocoaTweet::API::Model::OAuthToken RequestToken::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
auto key = _oauth.lock()->key();
key.authType(CocoaTweet::Authentication::Key::AUTH_TYPE::OAUTH10A);
auto oauth = std::make_shared<CocoaTweet::Authentication::OAuth1>(key);
CocoaTweet::API::Model::OAuthToken oauthToken;
HttpPost::process(oauth, [&oauthToken](const std::string& _rcv) {
auto mp = CocoaTweet::Util::parse(_rcv, '&', '=');
if (mp.count("oauth_token")) {
oauthToken.oauthToken(mp.at("oauth_token"));
}
if (mp.count("oauth_token_secret")) {
oauthToken.oauthTokenSecret(mp.at("oauth_token_secret"));
}
});
return oauthToken;
}
} // namespace CocoaTweet::API::OAuth1
+18
View File
@@ -0,0 +1,18 @@
#ifndef COCOATWEET_API_OAUTH1_REQUESTTOKEN_H_
#define COCOATWEET_API_OAUTH1_REQUESTTOKEN_H_
#include <cocoatweet/api/interface/httpPost.h>
#include <cocoatweet/api/model/oauthToken.h>
namespace CocoaTweet::API::OAuth1 {
class RequestToken : public CocoaTweet::API::Interface::HttpPost {
public:
RequestToken();
void oauthCallback(const std::string& _oauthCallback);
CocoaTweet::API::Model::OAuthToken process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
};
} // namespace CocoaTweet::API::OAuth1
#endif
@@ -0,0 +1,30 @@
#include <cocoatweet/api/oauth2/invalidateToken.h>
#include "nlohmann/json.hpp"
namespace CocoaTweet::API::OAuth2 {
InvalidateToken::InvalidateToken() {
contentType_ = "application/x-www-form-urlencoded";
url_ = "https://api.twitter.com/oauth2/invalidate_token";
}
void InvalidateToken::accessToken(const std::string _bearer) {
// bodyParam_.insert_or_assign("access_token", _bearer);
bearer_ = _bearer;
}
const CocoaTweet::API::Model::BearerToken InvalidateToken::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
auto org = url_;
auto url = url_ + "?access_token=" + bearer_;
url_ = url;
auto basic = std::make_shared<CocoaTweet::Authentication::Basic>(_oauth.lock()->key());
CocoaTweet::API::Model::BearerToken bearer;
HttpPost::process(basic, [&bearer](const std::string& _rcv) {
auto j = nlohmann::json::parse(_rcv);
bearer.token(j["access_token"]);
});
url_ = org;
return bearer;
}
} // namespace CocoaTweet::API::OAuth2
@@ -0,0 +1,21 @@
#ifndef COCOATWEET_API_OAUTH2_INVALIDATETOKEN_H_
#define COCOATWEET_API_OAUTH2_INVALIDATETOKEN_H_
#include <cocoatweet/api/model/bearerToken.h>
#include <cocoatweet/api/interface/httpPost.h>
#include <cocoatweet/authentication/basic.h>
namespace CocoaTweet::API::OAuth2 {
class InvalidateToken : public CocoaTweet::API::Interface::HttpPost {
public:
InvalidateToken();
void accessToken(const std::string _bearer);
const CocoaTweet::API::Model::BearerToken process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
private:
std::string bearer_;
};
} // namespace CocoaTweet::API::OAuth2
#endif
+26
View File
@@ -0,0 +1,26 @@
#include <cocoatweet/api/oauth2/oauth2.h>
#include <cocoatweet/authentication/basic.h>
namespace CocoaTweet::API::OAuth2 {
OAuth2::OAuth2(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
oauth_ = _oauth;
}
const std::string OAuth2::token() const {
// auto key = oauth_.lock()->key();
// auto oauth = std::make_shared<CocoaTweet::Authentication::Basic>(key);
CocoaTweet::API::OAuth2::Token token;
return token.process(oauth_);
}
const CocoaTweet::API::Model::BearerToken OAuth2::invalidateToken(
const std::string& _bearer) const {
// auto key = oauth_.lock()->key();
// auto oauth = std::make_shared<CocoaTweet::Authentication::Basic>(key);
CocoaTweet::API::OAuth2::InvalidateToken invalidateToken;
invalidateToken.accessToken(_bearer);
return invalidateToken.process(oauth_);
}
} // namespace CocoaTweet::API::OAuth2
+30
View File
@@ -0,0 +1,30 @@
#ifndef COCOATWEET_API_OAUTH2_OAUTH2_H_
#define COCOATWEET_API_OAUTH2_OAUTH2_H_
#include "cocoatweet/api/interface/groupInterface.h"
#include <cocoatweet/api/oauth2/invalidateToken.h>
#include <cocoatweet/api/oauth2/token.h>
#include <cocoatweet/api/model/oauthToken.h>
#include <cocoatweet/api/model/bearerToken.h>
#include <vector>
#include <utility>
namespace CocoaTweet::API::OAuth2 {
/// @brief class for using users/show endpoint
class OAuth2 : public groupInterface {
public:
/// @brief primary constructor
OAuth2() = default;
/// @brief constructor which finally should to be called.
/// @param[in] std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> : pointer to
/// OAuth object
OAuth2(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
const std::string token() const;
const CocoaTweet::API::Model::BearerToken invalidateToken(const std::string& _bearer) const;
};
} // namespace CocoaTweet::API::OAuth2
#endif
+23
View File
@@ -0,0 +1,23 @@
#include <cocoatweet/api/oauth2/token.h>
#include "nlohmann/json.hpp"
namespace CocoaTweet::API::OAuth2 {
Token::Token() {
contentType_ = "application/x-www-form-urlencoded";
url_ = "https://api.twitter.com/oauth2/token";
bodyParam_.insert_or_assign("grant_type", "client_credentials");
}
const std::string Token::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
auto basic = std::make_shared<CocoaTweet::Authentication::Basic>(_oauth.lock()->key());
std::string bearer = "";
HttpPost::process(basic, [&bearer](const std::string& _rcv) {
auto j = nlohmann::json::parse(_rcv);
bearer = j["access_token"];
});
return bearer;
}
} // namespace CocoaTweet::API::OAuth2
+16
View File
@@ -0,0 +1,16 @@
#ifndef COCOATWEET_API_OAUTH2_TOKEN_H_
#define COCOATWEET_API_OAUTH2_TOKEN_H_
#include <cocoatweet/api/interface/httpPost.h>
#include <cocoatweet/authentication/basic.h>
namespace CocoaTweet::API::OAuth2 {
class Token : public CocoaTweet::API::Interface::HttpPost {
public:
Token();
const std::string process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
};
} // namespace CocoaTweet::API::OAuth2
#endif
+4 -5
View File
@@ -9,12 +9,11 @@ void Destroy::id(const std::string _id) {
} }
CocoaTweet::API::Model::Tweet Destroy::process( CocoaTweet::API::Model::Tweet Destroy::process(
std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth) { std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
CocoaTweet::API::Model::Tweet tweet; CocoaTweet::API::Model::Tweet tweet;
HttpPost::process(_oauth, HttpPost::process(_oauth, [&tweet](const std::string& _rcv) {
[&tweet](const unsigned int _responseCode, const std::string& _rsv) { tweet = CocoaTweet::API::Model::Tweet::parse(_rcv);
tweet = CocoaTweet::API::Model::Tweet::parse(_responseCode, _rsv); });
});
return tweet; return tweet;
} }
+5 -3
View File
@@ -18,9 +18,11 @@ public:
void id(const std::string _id); void id(const std::string _id);
/// @brief process request for endpoint /// @brief process request for endpoint
/// @param[in] std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth : pointer to oauth object /// @param[in] std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth : pointer
/// @param[out] none /// to oauth object
CocoaTweet::API::Model::Tweet process(std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth); /// @param[out] CocoaTweet::API::Model::Tweet : request result
CocoaTweet::API::Model::Tweet process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
}; };
} // namespace CocoaTweet::API::Statuses } // namespace CocoaTweet::API::Statuses
+20
View File
@@ -0,0 +1,20 @@
#include <cocoatweet/api/status/retweet.h>
namespace CocoaTweet::API::Statuses {
Retweet::Retweet() {}
void Retweet::id(const std::string& _id) {
contentType_ = "application/x-www-form-urlencoded";
url_ = "https://api.twitter.com/1.1/statuses/retweet/" + _id + ".json";
}
CocoaTweet::API::Model::Tweet Retweet::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
CocoaTweet::API::Model::Tweet tweet;
HttpPost::process(_oauth, [&tweet](const std::string& _rcv) {
tweet = CocoaTweet::API::Model::Tweet(_rcv);
});
return tweet;
}
} // namespace CocoaTweet::API::Statuses
+19
View File
@@ -0,0 +1,19 @@
#ifndef COCOATWEET_API_STATUS_RETWEET_H_
#define COCOATWEET_API_STATUS_RETWEET_H_
#include <cocoatweet/api/interface/httpPost.h>
#include <cocoatweet/api/model/tweet.h>
namespace CocoaTweet::API::Statuses {
class Retweet : public CocoaTweet::API::Interface::HttpPost {
public:
Retweet();
void id(const std::string& _id);
CocoaTweet::API::Model::Tweet process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
};
} // namespace CocoaTweet::API::Statuses
#endif
+77 -3
View File
@@ -1,21 +1,95 @@
#include "cocoatweet/api/status/status.h" #include "cocoatweet/api/status/status.h"
#include "cocoatweet/api/status/update.h" #include "cocoatweet/api/status/update.h"
#include "cocoatweet/api/status/destroy.h" #include "cocoatweet/api/status/destroy.h"
#include "cocoatweet/api/status/retweet.h"
#include "cocoatweet/api/status/unretweet.h"
#include "cocoatweet/api/status/userTimeline.h"
namespace CocoaTweet::API::Statuses { namespace CocoaTweet::API::Statuses {
Status::Status(std::shared_ptr<CocoaTweet::OAuth::OAuth1> _oauth) { Status::Status(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
oauth_ = _oauth; oauth_ = _oauth;
} }
CocoaTweet::API::Model::Tweet Status::Update(const std::string& _status) const { CocoaTweet::API::Model::Tweet Status::update(const std::string& _status) const {
CocoaTweet::API::Statuses::Update update; CocoaTweet::API::Statuses::Update update;
update.status(_status); update.status(_status);
return update.process(oauth_); return update.process(oauth_);
} }
CocoaTweet::API::Model::Tweet Status::Destroy(const std::string& _id) const { CocoaTweet::API::Model::Tweet Status::update(const std::string& _status,
const Options _options) const {
CocoaTweet::API::Statuses::Update update;
update.status(_status);
if (_options.replyToStatusId != defaultOpt_.replyToStatusId) {
update.replyToStatusId(_options.replyToStatusId);
}
if (_options.autoPopulateReplyMetaData != defaultOpt_.autoPopulateReplyMetaData) {
update.autoPopulateReplyMetaData(_options.autoPopulateReplyMetaData);
}
if (_options.excludeReplyUserId != defaultOpt_.excludeReplyUserId) {
update.excludeReplyUserId(_options.excludeReplyUserId);
}
if (_options.attachmentUrl != defaultOpt_.attachmentUrl) {
update.attachmentUrl(_options.attachmentUrl);
}
if (_options.coord != defaultOpt_.coord) {
update.coord(_options.coord);
}
if (_options.displayCoord != defaultOpt_.displayCoord) {
update.displayCoord(_options.displayCoord);
}
if (_options.trimUser != defaultOpt_.trimUser) {
update.trimUser(_options.trimUser);
}
if (_options.enableDMCommands != defaultOpt_.enableDMCommands) {
update.enableDMCommands(_options.enableDMCommands);
}
if (_options.failDMCommands != defaultOpt_.failDMCommands) {
update.failDMCommands(_options.failDMCommands);
}
return update.process(oauth_);
}
CocoaTweet::API::Model::Tweet Status::update(const std::string& _status,
std::vector<std::string> _mediaId) const {
CocoaTweet::API::Statuses::Update update;
update.status(_status);
update.mediaId(_mediaId);
return update.process(oauth_);
}
CocoaTweet::API::Model::Tweet Status::destroy(const std::string& _id) const {
CocoaTweet::API::Statuses::Destroy destroy; CocoaTweet::API::Statuses::Destroy destroy;
destroy.id(_id); destroy.id(_id);
return destroy.process(oauth_); return destroy.process(oauth_);
} }
CocoaTweet::API::Model::Tweet Status::retweet(const std::string& _id) const {
CocoaTweet::API::Statuses::Retweet retweet;
retweet.id(_id);
return retweet.process(oauth_);
}
CocoaTweet::API::Model::Tweet Status::unretweet(const std::string& _id) const {
CocoaTweet::API::Statuses::Unretweet unretweet;
unretweet.id(_id);
return unretweet.process(oauth_);
}
std::vector<CocoaTweet::API::Model::Tweet> Status::userTimeline(
const std::string& _screenName) const {
CocoaTweet::API::Statuses::UserTimeline userTimeline;
userTimeline.screenName(_screenName);
return userTimeline.process(oauth_);
}
} // namespace CocoaTweet::API::Statuses } // namespace CocoaTweet::API::Statuses
+58 -4
View File
@@ -2,18 +2,72 @@
#define COCOATWEET_API_STATUS_STATUS_H_ #define COCOATWEET_API_STATUS_STATUS_H_
#include "cocoatweet/api/interface/groupInterface.h" #include "cocoatweet/api/interface/groupInterface.h"
#include "cocoatweet/oauth/oauth.h" #include "cocoatweet/authentication/authenticator.h"
#include <cocoatweet/api/model/tweet.h> #include <cocoatweet/api/model/tweet.h>
#include <vector>
#include <utility>
namespace CocoaTweet::API::Statuses { namespace CocoaTweet::API::Statuses {
/// @brief Entory point for statuses/*
class Status : public groupInterface { class Status : public groupInterface {
public: public:
struct Options {
std::string replyToStatusId;
bool autoPopulateReplyMetaData = false;
std::vector<std::string> excludeReplyUserId;
std::string attachmentUrl;
std::pair<std::string, std::string> coord;
bool displayCoord = false;
bool trimUser = false;
bool enableDMCommands = false;
bool failDMCommands = true;
};
/// @brief primary constructor to allow for create NON-INITIALIZED object
Status() = default; Status() = default;
Status(std::shared_ptr<CocoaTweet::OAuth::OAuth1> _oauth);
CocoaTweet::API::Model::Tweet Update(const std::string& _status) const; /// @brief constructor which finally should to be called.
CocoaTweet::API::Model::Tweet Destroy(const std::string& _id) const; /// @param[in] std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> : pointer to
/// OAuth object
Status(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
/// @brief send request to statuses/update with specified status
/// @details this function throws CocoaTweet::Exception::* if something happen
/// @param[in] const std::string& : tweet text
/// @param[out] CocoaTweet::API::Model::Tweet : Tweet result
CocoaTweet::API::Model::Tweet update(const std::string& _status) const;
/// @brief send request to statuses/update with specified status
/// @details this function throws CocoaTweet::Exception::* if something happen
/// @param[in] const std::string& : tweet text
/// @param[in] const CocoaTweet::API::Statuses::Status::Options option : status update options
/// for more parameters
/// @param[out] CocoaTweet::API::Model::Tweet : Tweet result
CocoaTweet::API::Model::Tweet update(const std::string& _status,
const Options _options) const;
/// @brief send request to statuses/update with specified status
/// @details this function throws CocoaTweet::Exception::* if something happen
/// @param[in] const std::string& : tweet text
/// @param[in] std::vector<std::string> _mediaId : media id which posted with tweet
/// @param[out] CocoaTweet::API::Model::Tweet : Tweet result
CocoaTweet::API::Model::Tweet update(const std::string& _status,
std::vector<std::string> _mediaId) const;
/// @brief send request to statuses/destroy with specified id
/// @details this function throws CocoaTweet::Exception::* if something happen
/// @param[in] const std::string& : tweet id which should be delete
/// @param[out] CocoaTweet::API::Model::Tweet : Destroy result
CocoaTweet::API::Model::Tweet destroy(const std::string& _id) const;
CocoaTweet::API::Model::Tweet retweet(const std::string& _id) const;
CocoaTweet::API::Model::Tweet unretweet(const std::string& _id) const;
std::vector<CocoaTweet::API::Model::Tweet> userTimeline(const std::string& _screenName) const;
private: private:
Options defaultOpt_;
}; };
} // namespace CocoaTweet::API::Statuses } // namespace CocoaTweet::API::Statuses
+20
View File
@@ -0,0 +1,20 @@
#include <cocoatweet/api/status/unretweet.h>
namespace CocoaTweet::API::Statuses {
Unretweet::Unretweet() {}
void Unretweet::id(const std::string& _id) {
contentType_ = "application/x-www-form-urlencoded";
url_ = "https://api.twitter.com/1.1/statuses/unretweet/" + _id + ".json";
}
CocoaTweet::API::Model::Tweet Unretweet::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
CocoaTweet::API::Model::Tweet tweet;
HttpPost::process(_oauth, [&tweet](const std::string& _rcv) {
tweet = CocoaTweet::API::Model::Tweet(_rcv);
});
return tweet;
}
} // namespace CocoaTweet::API::Statuses
+19
View File
@@ -0,0 +1,19 @@
#ifndef COCOATWEET_API_STATUS_UNRETWEET_H_
#define COCOATWEET_API_STATUS_UNRETWEET_H_
#include <cocoatweet/api/interface/httpPost.h>
#include <cocoatweet/api/model/tweet.h>
namespace CocoaTweet::API::Statuses {
class Unretweet : public CocoaTweet::API::Interface::HttpPost {
public:
Unretweet();
void id(const std::string& _id);
CocoaTweet::API::Model::Tweet process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
};
} // namespace CocoaTweet::API::Statuses
#endif
+47 -5
View File
@@ -1,4 +1,5 @@
#include "cocoatweet/api/status/update.h" #include "cocoatweet/api/status/update.h"
#include <cocoatweet/util/util.h>
namespace CocoaTweet::API::Statuses { namespace CocoaTweet::API::Statuses {
Update::Update() { Update::Update() {
@@ -11,12 +12,53 @@ void Update::status(const std::string _status) {
bodyParam_.insert_or_assign("status", status_); bodyParam_.insert_or_assign("status", status_);
} }
CocoaTweet::API::Model::Tweet Update::process(std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth) { void Update::mediaId(const std::vector<std::string> _media) {
bodyParam_.insert_or_assign("media_ids", CocoaTweet::Util::join(_media, ","));
}
void Update::replyToStatusId(const std::string _reply) {
bodyParam_.insert_or_assign("in_reply_to_status_id", _reply);
}
void Update::autoPopulateReplyMetaData(bool _meta) {
bodyParam_.insert_or_assign("auto_populate_reply_metadata", std::to_string(_meta));
}
void Update::excludeReplyUserId(const std::vector<std::string> _ex) {
bodyParam_.insert_or_assign("exclude_reply_user_ids", CocoaTweet::Util::join(_ex, ","));
}
void Update::attachmentUrl(const std::string _url) {
bodyParam_.insert_or_assign("attachment_url", _url);
}
void Update::coord(std::pair<std::string, std::string> _coord) {
bodyParam_.insert_or_assign("lat", _coord.first);
bodyParam_.insert_or_assign("long", _coord.second);
}
void Update::displayCoord(bool _disp) {
bodyParam_.insert_or_assign("display_coordinates", std::to_string(_disp));
}
void Update::trimUser(bool _trim) {
bodyParam_.insert_or_assign("trim_user", std::to_string(_trim));
}
void Update::enableDMCommands(bool _enable) {
bodyParam_.insert_or_assign("enable_dmcommands", std::to_string(_enable));
}
void Update::failDMCommands(bool _fail) {
bodyParam_.insert_or_assign("fail_dmcommands", std::to_string(_fail));
}
CocoaTweet::API::Model::Tweet Update::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
CocoaTweet::API::Model::Tweet tweet; CocoaTweet::API::Model::Tweet tweet;
HttpPost::process(_oauth, HttpPost::process(_oauth, [&tweet](const std::string& _rcv) {
[&tweet](const unsigned int _responseCode, const std::string& _rsv) { tweet = CocoaTweet::API::Model::Tweet::parse(_rcv);
tweet = CocoaTweet::API::Model::Tweet::parse(_responseCode, _rsv); });
});
return tweet; return tweet;
} }
+36 -2
View File
@@ -1,16 +1,50 @@
#ifndef COCOATWEET_API_STATUS_UPDATE_H_ #ifndef COCOATWEET_API_STATUS_UPDATE_H_
#define COCOATWEET_API_STATUS_UPDATE_H_ #define COCOATWEET_API_STATUS_UPDATE_H_
#include <memory>
#include <cocoatweet/api/interface/httpPost.h> #include <cocoatweet/api/interface/httpPost.h>
#include <cocoatweet/api/model/tweet.h> #include <cocoatweet/api/model/tweet.h>
#include <vector>
#include <utility>
#include <memory>
namespace CocoaTweet::API::Statuses { namespace CocoaTweet::API::Statuses {
/// @brief class for using statuses/update endpoint
class Update : public CocoaTweet::API::Interface::HttpPost { class Update : public CocoaTweet::API::Interface::HttpPost {
public: public:
/// @brief primary constructor
Update(); Update();
/// @brief set tweet text for sending request to statuses/update
/// @param[in] const std::string _status : tweet text
/// @param[out] none
void status(const std::string _status); void status(const std::string _status);
CocoaTweet::API::Model::Tweet process(std::weak_ptr<CocoaTweet::OAuth::OAuth1> _oauth);
void mediaId(const std::vector<std::string> _media);
void replyToStatusId(const std::string _reply);
void autoPopulateReplyMetaData(bool _meta);
void excludeReplyUserId(const std::vector<std::string> _ex);
void attachmentUrl(const std::string _url);
void coord(std::pair<std::string, std::string> _coord);
void displayCoord(bool _disp);
void trimUser(bool _trim);
void enableDMCommands(bool _enable);
void failDMCommands(bool _fail);
/// @brief process request for endpoint
/// @param[in] std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth : pointer
/// to oauth object
/// @param[out] CocoaTweet::API::Model::Tweet : request result
CocoaTweet::API::Model::Tweet process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
private: private:
std::string status_; std::string status_;
+27
View File
@@ -0,0 +1,27 @@
#include "cocoatweet/api/status/userTimeline.h"
#include <cocoatweet/util/util.h>
#include "nlohmann/json.hpp"
namespace CocoaTweet::API::Statuses {
UserTimeline::UserTimeline() {
contentType_ = "application/x-www-form-urlencoded";
url_ = "https://api.twitter.com/1.1/statuses/user_timeline.json";
}
void UserTimeline::screenName(const std::string& _screenName) {
bodyParam_.insert_or_assign("screen_name", _screenName);
}
std::vector<CocoaTweet::API::Model::Tweet> UserTimeline::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
std::vector<CocoaTweet::API::Model::Tweet> tweet;
HttpGet::process(_oauth, [&tweet](const std::string& _rcv) {
auto json = nlohmann::json::parse(_rcv);
for (auto j : json) {
tweet.push_back(CocoaTweet::API::Model::Tweet::parse(j.dump()));
}
});
return tweet;
}
} // namespace CocoaTweet::API::Statuses
+33
View File
@@ -0,0 +1,33 @@
#ifndef COCOATWEET_API_STATUS_USERTIMELINE_H_
#define COCOATWEET_API_STATUS_USERTIMELINE_H_
#include <cocoatweet/api/interface/httpGet.h>
#include <cocoatweet/api/model/tweet.h>
#include <vector>
#include <utility>
#include <memory>
namespace CocoaTweet::API::Statuses {
/// @brief class for using statuses/user_timeline endpoint
class UserTimeline : public CocoaTweet::API::Interface::HttpGet {
public:
/// @brief primary constructor
UserTimeline();
/// @brief set screen name to get timeline
/// @param[in] const std::string& _screenName : screen name for getting tweet
void screenName(const std::string& _screenName);
/// @brief process request for endpoint
/// @param[in] std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth : pointer
/// to oauth object
/// @param[out] std::vector<CocoaTweet::API::Model::Tweet> : request result
std::vector<CocoaTweet::API::Model::Tweet> process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
private:
std::string status_;
};
} // namespace CocoaTweet::API::Statuses
#endif
+34
View File
@@ -0,0 +1,34 @@
#include "cocoatweet/api/user/show.h"
#include <cocoatweet/util/util.h>
#include "nlohmann/json.hpp"
namespace CocoaTweet::API::Users {
Show::Show() {
contentType_ = "application/x-www-form-urlencoded";
url_ = "https://api.twitter.com/1.1/users/show.json";
}
void Show::screenName(const std::string& _screenName) {
if (bodyParam_.count("user_id") > 0) {
bodyParam_.erase("user_id");
}
bodyParam_.insert_or_assign("screen_name", _screenName);
}
void Show::id(const std::string& _id) {
if (bodyParam_.count("screen_name") > 0) {
bodyParam_.erase("screen_name");
}
bodyParam_.insert_or_assign("id", _id);
}
CocoaTweet::API::Model::User Show::process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
CocoaTweet::API::Model::User user;
HttpGet::process(_oauth, [&user](const std::string& _rcv) {
user = CocoaTweet::API::Model::User::parse(_rcv);
});
return user;
}
} // namespace CocoaTweet::API::Users
+37
View File
@@ -0,0 +1,37 @@
#ifndef COCOATWEET_API_USER_SHOW_H_
#define COCOATWEET_API_USER_SHOW_H_
#include <cocoatweet/api/interface/httpGet.h>
#include <cocoatweet/api/model/user.h>
#include <vector>
#include <utility>
#include <memory>
namespace CocoaTweet::API::Users {
/// @brief class for using users/show endpoint
class Show : public CocoaTweet::API::Interface::HttpGet {
public:
/// @brief primary constructor
Show();
/// @brief set screen name to get user information
/// @param[in] const std::string& _id : screen name for getting information
void id(const std::string& _id);
/// @brief set screen name to get user information
/// @param[in] const std::string& _screenName : screen name for getting information
void screenName(const std::string& _screenName);
/// @brief process request for endpoint
/// @param[in] std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth : pointer
/// to oauth object
/// @param[out] CocoaTweet::API::Model::User : request result
CocoaTweet::API::Model::User process(
std::weak_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
private:
std::string status_;
};
} // namespace CocoaTweet::API::Users
#endif
+14
View File
@@ -0,0 +1,14 @@
#include <cocoatweet/api/user/user.h>
#include <cocoatweet/api/user/show.h>
namespace CocoaTweet::API::Users {
User::User(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth) {
oauth_ = _oauth;
}
CocoaTweet::API::Model::User User::show(const std::string& _screenName) const {
CocoaTweet::API::Users::Show show;
show.screenName(_screenName);
return show.process(oauth_);
}
} // namespace CocoaTweet::API::Users
+26
View File
@@ -0,0 +1,26 @@
#ifndef COCOATWEET_API_USER_USER_H_
#define COCOATWEET_API_USER_USER_H_
#include "cocoatweet/api/interface/groupInterface.h"
#include "cocoatweet/authentication/authenticator.h"
#include <cocoatweet/api/model/user.h>
#include <vector>
#include <utility>
namespace CocoaTweet::API::Users {
/// @brief class for using users/show endpoint
class User : public groupInterface {
public:
/// @brief primary constructor
User() = default;
/// @brief constructor which finally should to be called.
/// @param[in] std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> : pointer to
/// OAuth object
User(std::shared_ptr<CocoaTweet::Authentication::AuthenticatorBase> _oauth);
CocoaTweet::API::Model::User show(const std::string& _screenName) const;
};
} // namespace CocoaTweet::API::Users
#endif
@@ -0,0 +1,29 @@
#ifndef COCOATWEET_AUTHENTICATION_AUTHENTICATOR_H_
#define COCOATWEET_AUTHENTICATION_AUTHENTICATOR_H_
#include <cocoatweet/authentication/key.h>
namespace CocoaTweet::Authentication {
class AuthenticatorBase {
public:
enum class AuthenticationMethod { OAUTH10A, OAUTH2, BASIC, PLAIN, NONE };
virtual const std::string calculateAuthHeader(std::map<std::string, std::string> _bodyParam,
const std::string& _method,
const std::string& _url) = 0;
const Key key() const {
return key_;
}
protected:
AuthenticationMethod method_;
Key key_;
static size_t curlCallback_(char* _ptr, size_t _size, size_t _nmemb, std::string* _stream) {
int realsize = _size * _nmemb;
_stream->append(_ptr, realsize);
return realsize;
}
};
} // namespace CocoaTweet::Authentication
#endif
+74
View File
@@ -0,0 +1,74 @@
#include "basic.h"
#include "cocoatweet/util/util.h"
#include <random>
#include <ctime>
#include <bitset>
#include <sstream>
#include <string>
#include <cstring>
#include <iterator>
#include <nlohmann/json.hpp>
#include <cocoatweet/exception/invalidParameterException.h>
extern "C" {
#include <openssl/hmac.h>
#include <openssl/sha.h>
#include <openssl/buffer.h>
#include <curl/curl.h>
}
#ifndef NDEBUG
#include <iostream>
#endif
namespace CocoaTweet::Authentication {
Basic::Basic() {
method_ = AuthenticationMethod::BASIC;
}
Basic::Basic(const Key _key) {
key_ = _key;
method_ = AuthenticationMethod::BASIC;
}
const std::string Basic::calculateAuthHeader(std::map<std::string, std::string> _bodyParam,
const std::string& _method,
const std::string& _url) {
auto signature = key_.consumerKey() + ":" + key_.consumerSecret();
auto k64Signature = base64(signature);
auto authHeader = std::string("Authorization: Basic ") + k64Signature;
return authHeader;
}
const std::string Basic::base64(const std::string& _raw) {
auto base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::stringstream ss;
for (auto r : _raw) {
ss << std::bitset<8>(r);
}
if (_raw.length() % 3 == 1) {
ss << "0000";
} else if (_raw.length() % 3 == 2) {
ss << "00";
}
auto bin = ss.str();
std::string base64 = "";
for (auto i = 0; i < bin.length() / 6; i++) {
base64 += base64Table[std::stoi(bin.substr(i * 6, 6), nullptr, 2)];
}
if (base64.length() % 4 == 3) {
base64 += "=";
} else if (base64.length() % 4 == 2) {
base64 += "==";
} else if (base64.length() % 4 == 1) {
base64 += "===";
}
return base64;
}
} // namespace CocoaTweet::Authentication
+24
View File
@@ -0,0 +1,24 @@
#ifndef COCOATWEET_AUTHENTICATION_BASIC_H_
#define COCOATWEET_AUTHENTICATION_BASIC_H_
#include <string>
#include <map>
#include <memory>
#include "key.h"
#include <cocoatweet/authentication/authenticator.h>
namespace CocoaTweet::Authentication {
class Basic : public AuthenticatorBase {
public:
Basic();
Basic(const Key _key);
// const std::string& generateBearerToken();
const std::string calculateAuthHeader(std::map<std::string, std::string> _bodyParam,
const std::string& _method, const std::string& _url);
const std::string base64(const std::string& _raw);
};
} // namespace CocoaTweet::Authentication
#endif
+42
View File
@@ -0,0 +1,42 @@
#include "bearer.h"
#include "cocoatweet/util/util.h"
#include <random>
#include <ctime>
#include <bitset>
#include <sstream>
#include <string>
#include <cstring>
#include <iterator>
#include <nlohmann/json.hpp>
#include <cocoatweet/exception/invalidParameterException.h>
extern "C" {
#include <openssl/hmac.h>
#include <openssl/sha.h>
#include <openssl/buffer.h>
#include <curl/curl.h>
}
#ifndef NDEBUG
#include <iostream>
#endif
namespace CocoaTweet::Authentication {
Bearer::Bearer() {
method_ = AuthenticationMethod::OAUTH2;
}
Bearer::Bearer(const Key _key) {
key_ = _key;
method_ = AuthenticationMethod::OAUTH2;
}
const std::string Bearer::calculateAuthHeader(std::map<std::string, std::string> _bodyParam,
const std::string& _method,
const std::string& _url) {
auto authHeader = std::string("Authorization: Bearer ") + key_.bearerToken();
return authHeader;
}
} // namespace CocoaTweet::Authentication
+21
View File
@@ -0,0 +1,21 @@
#ifndef COCOATWEET_AUTHENTICATION_BEARER_H_
#define COCOATWEET_AUTHENTICATION_BEARER_H_
#include <string>
#include <map>
#include <memory>
#include "key.h"
#include <cocoatweet/authentication/authenticator.h>
namespace CocoaTweet::Authentication {
class Bearer : public AuthenticatorBase {
public:
Bearer();
Bearer(const Key _key);
const std::string calculateAuthHeader(std::map<std::string, std::string> _bodyParam,
const std::string& _method, const std::string& _url);
};
} // namespace CocoaTweet::Authentication
#endif
+35
View File
@@ -0,0 +1,35 @@
#include "cocoatweet/authentication/key.h"
#include "nlohmann/json.hpp"
#include <fstream>
#include <string>
#include <typeinfo>
namespace CocoaTweet::Authentication {
Key Key::fromJsonFile(const std::string _jsonFile) {
std::ifstream ifs(_jsonFile);
std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
auto j = nlohmann::json::parse(str);
Key key;
key.authType(Key::AUTH_TYPE::OAUTH10A);
if (j.contains("consumer_key")) {
key.consumerKey(j["consumer_key"].get<std::string>());
}
if (j.contains("consumer_secret")) {
key.consumerSecret(j["consumer_secret"].get<std::string>());
}
if (j.contains("access_token")) {
key.accessToken(j["access_token"].get<std::string>());
}
if (j.contains("access_token_secret")) {
key.accessTokenSecret(j["access_token_secret"].get<std::string>());
}
return key;
}
} // namespace CocoaTweet::Authentication
+91
View File
@@ -0,0 +1,91 @@
#ifndef COCOATWEET_AUTHENTICATION_KEY_H_
#define COCOATWEET_AUTHENTICATION_KEY_H_
#include <string>
#include <map>
namespace CocoaTweet::Authentication {
class Key {
public:
enum AUTH_TYPE { OAUTH10A, OAUTH2 };
private:
std::string consumerKey_;
std::string consumerSecret_;
std::string accessToken_;
std::string accessTokenSecret_;
std::string bearerToken_;
AUTH_TYPE authType_;
public:
Key() : consumerKey_(""), consumerSecret_(""), accessToken_(""), accessTokenSecret_("") {}
Key(const std::string& _consumerKey, const std::string& _consumerSecret,
const std::string& _accessToken, const std::string& _accessTokenSecret,
const AUTH_TYPE _authType = AUTH_TYPE::OAUTH10A)
: consumerKey_(_consumerKey),
consumerSecret_(_consumerSecret),
accessToken_(_accessToken),
accessTokenSecret_(_accessTokenSecret),
authType_(_authType) {}
Key(const std::string& _consumerKey, const std::string& _consumerSecret,
const AUTH_TYPE _authType = AUTH_TYPE::OAUTH2)
: consumerKey_(_consumerKey), consumerSecret_(_consumerSecret), authType_(_authType) {}
void consumerKey(const std::string& _consumerKey) {
consumerKey_ = _consumerKey;
}
void consumerSecret(const std::string& _consumerSecret) {
consumerSecret_ = _consumerSecret;
}
void accessToken(const std::string& _accessToken) {
accessToken_ = _accessToken;
}
void accessTokenSecret(const std::string& _accessTokenSecret) {
accessTokenSecret_ = _accessTokenSecret;
}
void bearerToken(const std::string& _bearer) {
bearerToken_ = _bearer;
}
const std::string& consumerKey() const {
return consumerKey_;
}
const std::string& consumerSecret() const {
return consumerSecret_;
}
const std::string& accessToken() const {
return accessToken_;
}
const std::string& accessTokenSecret() const {
return accessTokenSecret_;
}
const std::string& bearerToken() const {
return bearerToken_;
}
const AUTH_TYPE authType() const {
return authType_;
}
void authType(AUTH_TYPE _authType) {
authType_ = _authType;
}
std::map<std::string, std::string> noSecret() const {
return std::map<std::string, std::string>{{"oauth_consumer_key", consumerKey_},
{"oauth_token", accessToken_}};
}
const std::map<std::string, std::string> secret() const {
return std::map<std::string, std::string>{{"oauth_consumer_key", consumerSecret_},
{"oauth_token", accessTokenSecret_}};
}
static Key fromJsonFile(const std::string _jsonFile);
};
} // namespace CocoaTweet::Authentication
#endif
@@ -7,17 +7,30 @@
#include <string> #include <string>
#include <cstring> #include <cstring>
#include <iterator> #include <iterator>
#include <nlohmann/json.hpp>
#include <cocoatweet/exception/invalidParameterException.h>
extern "C" { extern "C" {
#include <openssl/hmac.h> #include <openssl/hmac.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/buffer.h> #include <openssl/buffer.h>
#include <curl/curl.h>
} }
namespace CocoaTweet::OAuth { #ifndef NDEBUG
OAuth1::OAuth1() {} #include <iostream>
#endif
OAuth1::OAuth1(const Key _key) : key_(_key) {} namespace CocoaTweet::Authentication {
OAuth1::OAuth1() {
method_ = AuthenticationMethod::OAUTH10A;
}
OAuth1::OAuth1(const Key _key) {
key_ = _key;
method_ = AuthenticationMethod::OAUTH10A;
}
std::map<std::string, std::string> OAuth1::signature( std::map<std::string, std::string> OAuth1::signature(
const std::map<std::string, std::string>& _param, const std::string& _method, const std::map<std::string, std::string>& _param, const std::string& _method,
@@ -38,6 +51,33 @@ std::map<std::string, std::string> OAuth1::signature(
return ret; return ret;
} }
const std::string OAuth1::calculateAuthHeader(std::map<std::string, std::string> _bodyParam,
const std::string& _method,
const std::string& _url) {
auto authParam = oauthParam();
auto sigingParam = authParam;
if (!_bodyParam.empty()) {
for (const auto [k, v] : _bodyParam) {
sigingParam.insert_or_assign(k, v);
}
}
auto sign = signature(sigingParam, _method, _url);
authParam.merge(sign);
// ヘッダの構築
std::string oauthHeader = "authorization: OAuth ";
{
std::vector<std::string> tmp;
for (const auto& [key, value] : authParam) {
tmp.push_back(key + "=" + CocoaTweet::Util::urlEncode(value));
}
oauthHeader += CocoaTweet::Util::join(tmp, ",");
}
return oauthHeader;
}
const std::string OAuth1::nonce() const { const std::string OAuth1::nonce() const {
std::random_device engine; std::random_device engine;
std::string nonceTable = "abcdefghijklmnopqrstuvwxyz0123456789"; std::string nonceTable = "abcdefghijklmnopqrstuvwxyz0123456789";
@@ -56,15 +96,11 @@ const std::string OAuth1::timestamp() const {
} }
const std::string OAuth1::method() const { const std::string OAuth1::method() const {
return SIGNATURE_METHOD_; return "HMAC-SHA1";
} }
const std::string OAuth1::version() const { const std::string OAuth1::version() const {
return OAUTH_VERSION_; return "1.0";
}
const Key OAuth1::key() const {
return key_;
} }
std::map<std::string, std::string> OAuth1::oauthParam() const { std::map<std::string, std::string> OAuth1::oauthParam() const {
@@ -135,4 +171,4 @@ std::string OAuth1::hmacSha1(std::string _key, std::string _data) {
return static_cast<std::string>(k64); return static_cast<std::string>(k64);
} }
} // namespace CocoaTweet::OAuth } // namespace CocoaTweet::Authentication
@@ -1,33 +1,34 @@
#ifndef COCOATWEET_OAUTH_OAUTH_H_ #ifndef COCOATWEET_AUTHENTICATION_OAUTH_H_
#define COCOATWEET_OAUTH_OAUTH_H_ #define COCOATWEET_AUTHENTICATION_OAUTH_H_
#include <string> #include <string>
#include <map> #include <map>
#include <memory> #include <memory>
#include "key.h" #include "key.h"
#include <cocoatweet/authentication/authenticator.h>
namespace CocoaTweet::OAuth { namespace CocoaTweet::Authentication {
class OAuth1 { class OAuth1 : public AuthenticatorBase {
public: public:
OAuth1(); OAuth1();
OAuth1(const Key _key); OAuth1(const Key _key);
std::map<std::string, std::string> signature(const std::map<std::string, std::string>& _param, std::map<std::string, std::string> signature(const std::map<std::string, std::string>& _param,
const std::string& _method, const std::string& _method,
const std::string& _url); const std::string& _url);
// const std::string& generateBearerToken();
const std::string calculateAuthHeader(std::map<std::string, std::string> _bodyParam,
const std::string& _method, const std::string& _url);
const std::string nonce() const; const std::string nonce() const;
const std::string timestamp() const; const std::string timestamp() const;
const std::string method() const; const std::string method() const;
const std::string version() const; const std::string version() const;
const Key key() const;
std::map<std::string, std::string> oauthParam() const; std::map<std::string, std::string> oauthParam() const;
std::string hmacSha1(std::string _key, std::string _data); std::string hmacSha1(std::string _key, std::string _data);
const std::string base64(const std::string& _raw); const std::string base64(const std::string& _raw);
private:
Key key_;
const std::string SIGNATURE_METHOD_ = "HMAC-SHA1";
const std::string OAUTH_VERSION_ = "1.0";
}; };
} // namespace CocoaTweet::OAuth } // namespace CocoaTweet::Authentication
#endif #endif
+10
View File
@@ -0,0 +1,10 @@
#ifndef COCOATWEET_AUTHENTICATION_PLAIN_H_
#define COCOATWEET_AUTHENTICATION_PLAIN_H_
#include <cocoatweet/authentication/authenticator.h>
namespace CocoaTweet::Authentication {
class Plain : public AuthenticatorBase {};
} // namespace CocoaTweet::Authentication
#endif
@@ -4,7 +4,7 @@
#include <cocoatweet/exception/exception.h> #include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception { namespace CocoaTweet::Exception {
class AuthenticateException final : Exception { class AuthenticateException final : public Exception {
using Exception::Exception; using Exception::Exception;
}; };
} // namespace CocoaTweet::Exception } // namespace CocoaTweet::Exception
@@ -0,0 +1,12 @@
#ifndef COCOATWEET_EXCEPTION_CREDENTIALNOTALLOWEDEXCEPTION_H_
#define COCOATWEET_EXCEPTION_CREDENTIALNOTALLOWEDEXCEPTION_H_
#include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception {
class CredentialNotAllowedException final : public Exception {
using Exception::Exception;
};
} // namespace CocoaTweet::Exception
#endif
@@ -0,0 +1,12 @@
#ifndef COCOATWEET_EXCEPTION_CREDENTIALNOTVERIFIEDEXCEPTION_H_
#define COCOATWEET_EXCEPTION_CREDENTIALNOTVERIFIEDEXCEPTION_H_
#include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception {
class CredentialNotVerifiedException final : public Exception {
using Exception::Exception;
};
} // namespace CocoaTweet::Exception
#endif
+1
View File
@@ -8,6 +8,7 @@ namespace CocoaTweet::Exception {
class Exception : public std::exception { class Exception : public std::exception {
public: public:
Exception(const char* _msg) : msg_(std::string(_msg)) {} Exception(const char* _msg) : msg_(std::string(_msg)) {}
Exception(const std::string& _msg) : msg_(std::string(_msg)) {}
const std::string& what() { const std::string& what() {
return msg_; return msg_;
} }
@@ -0,0 +1,12 @@
#ifndef COCOATWEET_EXCEPTION_INVALIDPARAMETEREXCEPTION_H_
#define COCOATWEET_EXCEPTION_INVALIDPARAMETEREXCEPTION_H_
#include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception {
class InvalidParameterException final : public Exception {
using Exception::Exception;
};
} // namespace CocoaTweet::Exception
#endif
@@ -0,0 +1,12 @@
#ifndef COCOATWEET_EXCEPTION_INVALIDATETOKENEXCEPTION_H_
#define COCOATWEET_EXCEPTION_INVALIDATETOKENEXCEPTION_H_
#include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception {
class InvalidateTokenException final : public Exception {
using Exception::Exception;
};
} // namespace CocoaTweet::Exception
#endif
@@ -0,0 +1,12 @@
#ifndef COCOATWEET_EXCEPTION_MISSINGREQUIREDPARAMEXCEPTION_H_
#define COCOATWEET_EXCEPTION_MISSINGREQUIREDPARAMEXCEPTION_H_
#include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception {
class MissingRequiredParamException final : public Exception {
using Exception::Exception;
};
} // namespace CocoaTweet::Exception
#endif
@@ -4,7 +4,7 @@
#include <cocoatweet/exception/exception.h> #include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception { namespace CocoaTweet::Exception {
class RateLimitException final : Exception { class RateLimitException final : public Exception {
using Exception::Exception; using Exception::Exception;
}; };
} // namespace CocoaTweet::Exception } // namespace CocoaTweet::Exception
@@ -0,0 +1,12 @@
#ifndef COCOATWEET_EXCEPTION_TOKENINVALIDEXCEPTION_H_
#define COCOATWEET_EXCEPTION_TOKENINVALIDEXCEPTION_H_
#include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception {
class TokenInvalidException final : public Exception {
using Exception::Exception;
};
} // namespace CocoaTweet::Exception
#endif
@@ -4,7 +4,7 @@
#include <cocoatweet/exception/exception.h> #include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception { namespace CocoaTweet::Exception {
class TweetDuplicateException final : Exception { class TweetDuplicateException final : public Exception {
using Exception::Exception; using Exception::Exception;
}; };
} // namespace CocoaTweet::Exception } // namespace CocoaTweet::Exception
@@ -4,7 +4,7 @@
#include <cocoatweet/exception/exception.h> #include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception { namespace CocoaTweet::Exception {
class TweetNotFoundException final : Exception { class TweetNotFoundException final : public Exception {
using Exception::Exception; using Exception::Exception;
}; };
} // namespace CocoaTweet::Exception } // namespace CocoaTweet::Exception
@@ -4,7 +4,7 @@
#include <cocoatweet/exception/exception.h> #include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception { namespace CocoaTweet::Exception {
class TweetTooLongException final : Exception { class TweetTooLongException final : public Exception {
using Exception::Exception; using Exception::Exception;
}; };
} // namespace CocoaTweet::Exception } // namespace CocoaTweet::Exception
@@ -0,0 +1,12 @@
#ifndef COCOATWEET_EXCEPTION_UNSUPPORTEDMEDIATYPEEXCEPTION_H_
#define COCOATWEET_EXCEPTION_UNSUPPORTEDMEDIATYPEEXCEPTION_H_
#include <cocoatweet/exception/exception.h>
namespace CocoaTweet::Exception {
class UnsupportedMediaTypeException final : public Exception {
using Exception::Exception;
};
} // namespace CocoaTweet::Exception
#endif
+22
View File
@@ -0,0 +1,22 @@
#ifndef COCOATWEET_OAUTH_AUTHORIZE_H_
#define COCOATWEET_OAUTH_AUTHORIZE_H_
#include "cocoatweet/api/interface/groupInterface.h"
#include <vector>
#include <utility>
namespace CocoaTweet::Authentication {
class Auth : public groupInterface {
public:
enum AuthType { OAuth, Bearer };
Auth();
Auth(Key _key);
authorize(const bool app_only);
private:
Key key_;
}
} // namespace CocoaTweet::Authentication
#endif
-15
View File
@@ -1,15 +0,0 @@
#include "cocoatweet/oauth/key.h"
#include "nlohmann/json.hpp"
#include <fstream>
#include <string>
namespace CocoaTweet::OAuth {
Key Key::fromJsonFile(const std::string _jsonFile) {
std::ifstream ifs(_jsonFile);
std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
auto j = nlohmann::json::parse(str);
return Key(j["consumer_key"], j["consumer_secret"], j["access_token"],
j["access_token_secret"]);
}
} // namespace CocoaTweet::OAuth
-47
View File
@@ -1,47 +0,0 @@
#ifndef COCOATWEET_OAUTH_KEY_H_
#define COCOATWEET_OAUTH_KEY_H_
#include <string>
#include <map>
namespace CocoaTweet::OAuth {
class Key {
const std::string consumerKey_;
const std::string consumerSecret_;
const std::string accessToken_;
const std::string accessTokenSecret_;
public:
Key() : consumerKey_(""), consumerSecret_(""), accessToken_(""), accessTokenSecret_("") {}
Key(const std::string& _consumerKey, const std::string& _consumerSecret,
const std::string& _accessToken, const std::string& _accessTokenSecret)
: consumerKey_(_consumerKey),
consumerSecret_(_consumerSecret),
accessToken_(_accessToken),
accessTokenSecret_(_accessTokenSecret) {}
const std::string& consumerKey() const {
return consumerKey_;
}
const std::string& consumerSecret() const {
return consumerSecret_;
}
const std::string& accessToken() const {
return accessToken_;
}
const std::string& accessTokenSecret() const {
return accessTokenSecret_;
}
std::map<std::string, std::string> noSecret() const {
return std::map<std::string, std::string>{{"oauth_consumer_key", consumerKey_},
{"oauth_token", accessToken_}};
}
const std::map<std::string, std::string> secret() const {
return std::map<std::string, std::string>{{"oauth_consumer_key", consumerSecret_},
{"oauth_token", accessTokenSecret_}};
}
static Key fromJsonFile(const std::string _jsonFile);
};
} // namespace CocoaTweet::OAuth
#endif

Some files were not shown because too many files have changed in this diff Show More