diff options
-rw-r--r-- | src/tweet.cpp | 101 | ||||
-rw-r--r-- | src/tweet.h | 122 | ||||
-rw-r--r-- | src/user.cpp | 31 | ||||
-rw-r--r-- | src/user.h | 94 |
4 files changed, 138 insertions, 210 deletions
diff --git a/src/tweet.cpp b/src/tweet.cpp index 1003647..7f10a5c 100644 --- a/src/tweet.cpp +++ b/src/tweet.cpp | |||
@@ -7,83 +7,48 @@ | |||
7 | 7 | ||
8 | namespace twitter { | 8 | namespace twitter { |
9 | 9 | ||
10 | tweet::tweet(std::string data) try | 10 | tweet::tweet(std::string data) |
11 | : _valid(true) | ||
12 | { | 11 | { |
13 | auto json = nlohmann::json::parse(data); | 12 | try |
14 | _id = json["id"].get<tweet_id>(); | ||
15 | _text = json["text"].get<std::string>(); | ||
16 | _author = std::make_unique<user>(json["user"].dump()); | ||
17 | |||
18 | std::tm ctt = { 0 }; | ||
19 | std::stringstream createdAtStream; | ||
20 | createdAtStream << json["created_at"].get<std::string>(); | ||
21 | createdAtStream >> std::get_time(&ctt, "%a %b %d %H:%M:%S +0000 %Y"); | ||
22 | _created_at = twitter::timegm(&ctt); | ||
23 | |||
24 | if (!json["retweeted_status"].is_null()) | ||
25 | { | 13 | { |
26 | _is_retweet = true; | 14 | auto json = nlohmann::json::parse(data); |
15 | _id = json["id"].get<tweet_id>(); | ||
16 | _text = json["text"].get<std::string>(); | ||
17 | _author = new user(json["user"].dump()); | ||
18 | |||
19 | std::tm ctt = { 0 }; | ||
20 | std::stringstream createdAtStream; | ||
21 | createdAtStream << json["created_at"].get<std::string>(); | ||
22 | createdAtStream >> std::get_time(&ctt, "%a %b %d %H:%M:%S +0000 %Y"); | ||
23 | _created_at = twitter::timegm(&ctt); | ||
24 | |||
25 | if (!json["retweeted_status"].is_null()) | ||
26 | { | ||
27 | _is_retweet = true; | ||
27 | 28 | ||
28 | _retweeted_status = std::make_unique<tweet>(json["retweeted_status"].dump()); | 29 | _retweeted_status = new tweet(json["retweeted_status"].dump()); |
29 | } | 30 | } |
30 | 31 | ||
31 | if (!json["entities"].is_null()) | 32 | if (!json["entities"].is_null()) |
32 | { | ||
33 | auto entities = json["entities"]; | ||
34 | if (!entities["user_mentions"].is_null()) | ||
35 | { | 33 | { |
36 | for (auto mention : entities["user_mentions"]) | 34 | auto entities = json["entities"]; |
35 | if (!entities["user_mentions"].is_null()) | ||
37 | { | 36 | { |
38 | _mentions.push_back(std::make_pair(mention["id"].get<user_id>(), mention["screen_name"].get<std::string>())); | 37 | for (auto mention : entities["user_mentions"]) |
38 | { | ||
39 | _mentions.emplace_back( | ||
40 | mention["id"].get<user_id>(), | ||
41 | mention["screen_name"].get<std::string>()); | ||
42 | } | ||
39 | } | 43 | } |
40 | } | 44 | } |
41 | } | 45 | } catch (const std::invalid_argument& error) |
42 | } catch (const std::invalid_argument& error) | ||
43 | { | ||
44 | std::throw_with_nested(malformed_object("tweet", data)); | ||
45 | } catch (const std::domain_error& error) | ||
46 | { | ||
47 | std::throw_with_nested(malformed_object("tweet", data)); | ||
48 | } | ||
49 | |||
50 | tweet::tweet(const tweet& other) | ||
51 | { | ||
52 | _valid = other._valid; | ||
53 | _id = other._id; | ||
54 | _text = other._text; | ||
55 | _author = std::make_unique<user>(*other._author); | ||
56 | _is_retweet = other._is_retweet; | ||
57 | |||
58 | if (_is_retweet) | ||
59 | { | 46 | { |
60 | _retweeted_status = std::make_unique<tweet>(*other._retweeted_status); | 47 | std::throw_with_nested(malformed_object("tweet", data)); |
48 | } catch (const std::domain_error& error) | ||
49 | { | ||
50 | std::throw_with_nested(malformed_object("tweet", data)); | ||
61 | } | 51 | } |
62 | |||
63 | _mentions = other._mentions; | ||
64 | } | ||
65 | |||
66 | tweet::tweet(tweet&& other) : tweet() | ||
67 | { | ||
68 | swap(*this, other); | ||
69 | } | ||
70 | |||
71 | tweet& tweet::operator=(tweet other) | ||
72 | { | ||
73 | swap(*this, other); | ||
74 | |||
75 | return *this; | ||
76 | } | ||
77 | |||
78 | void swap(tweet& first, tweet& second) | ||
79 | { | ||
80 | std::swap(first._valid, second._valid); | ||
81 | std::swap(first._id, second._id); | ||
82 | std::swap(first._text, second._text); | ||
83 | std::swap(first._author, second._author); | ||
84 | std::swap(first._is_retweet, second._is_retweet); | ||
85 | std::swap(first._retweeted_status, second._retweeted_status); | ||
86 | std::swap(first._mentions, second._mentions); | ||
87 | } | 52 | } |
88 | 53 | ||
89 | std::string tweet::generateReplyPrefill(const user& me) const | 54 | std::string tweet::generateReplyPrefill(const user& me) const |
@@ -104,8 +69,6 @@ namespace twitter { | |||
104 | 69 | ||
105 | std::string tweet::getURL() const | 70 | std::string tweet::getURL() const |
106 | { | 71 | { |
107 | assert(_valid); | ||
108 | |||
109 | std::ostringstream urlstr; | 72 | std::ostringstream urlstr; |
110 | urlstr << "https://twitter.com/"; | 73 | urlstr << "https://twitter.com/"; |
111 | urlstr << _author->getScreenName(); | 74 | urlstr << _author->getScreenName(); |
diff --git a/src/tweet.h b/src/tweet.h index 71a27bd..23882e2 100644 --- a/src/tweet.h +++ b/src/tweet.h | |||
@@ -4,94 +4,72 @@ | |||
4 | #include <string> | 4 | #include <string> |
5 | #include <vector> | 5 | #include <vector> |
6 | #include <utility> | 6 | #include <utility> |
7 | #include <cassert> | ||
8 | #include <list> | ||
9 | #include <memory> | ||
10 | #include <ctime> | 7 | #include <ctime> |
8 | #include "../vendor/hkutil/hkutil/recptr.h" | ||
11 | #include "user.h" | 9 | #include "user.h" |
12 | 10 | ||
13 | namespace twitter { | 11 | namespace twitter { |
14 | 12 | ||
15 | class client; | ||
16 | |||
17 | typedef unsigned long long tweet_id; | 13 | typedef unsigned long long tweet_id; |
18 | 14 | ||
19 | class tweet { | 15 | class tweet { |
20 | public: | 16 | public: |
21 | 17 | ||
22 | tweet() {} | 18 | tweet(std::string data); |
23 | tweet(std::string data); | 19 | |
24 | 20 | tweet_id getID() const | |
25 | tweet(const tweet& other); | 21 | { |
26 | tweet(tweet&& other); | 22 | return _id; |
27 | 23 | } | |
28 | tweet& operator=(tweet other); | 24 | |
29 | 25 | std::string getText() const | |
30 | friend void swap(tweet& first, tweet& second); | 26 | { |
31 | 27 | return _text; | |
32 | tweet_id getID() const | 28 | } |
29 | |||
30 | const user& getAuthor() const | ||
31 | { | ||
32 | return *_author; | ||
33 | } | ||
34 | |||
35 | const std::time_t& getCreatedAt() const | ||
36 | { | ||
37 | return _created_at; | ||
38 | } | ||
39 | |||
40 | bool isRetweet() const | ||
41 | { | ||
42 | return _is_retweet; | ||
43 | } | ||
44 | |||
45 | const tweet& getRetweet() const | ||
46 | { | ||
47 | if (!_is_retweet) | ||
33 | { | 48 | { |
34 | assert(_valid); | 49 | throw std::logic_error("Tweet is not a retweet"); |
35 | |||
36 | return _id; | ||
37 | } | 50 | } |
38 | 51 | ||
39 | std::string getText() const | 52 | return *_retweeted_status; |
40 | { | 53 | } |
41 | assert(_valid); | ||
42 | 54 | ||
43 | return _text; | 55 | const std::vector<std::pair<user_id, std::string>>& getMentions() const |
44 | } | 56 | { |
45 | 57 | return _mentions; | |
46 | const user& getAuthor() const | 58 | } |
47 | { | ||
48 | assert(_valid); | ||
49 | |||
50 | return *_author; | ||
51 | } | ||
52 | |||
53 | const std::time_t& getCreatedAt() const | ||
54 | { | ||
55 | assert(_valid); | ||
56 | |||
57 | return _created_at; | ||
58 | } | ||
59 | |||
60 | bool isRetweet() const | ||
61 | { | ||
62 | assert(_valid); | ||
63 | |||
64 | return _is_retweet; | ||
65 | } | ||
66 | |||
67 | const tweet& getRetweet() const | ||
68 | { | ||
69 | assert(_valid && _is_retweet); | ||
70 | |||
71 | return *_retweeted_status; | ||
72 | } | ||
73 | |||
74 | const std::vector<std::pair<user_id, std::string>>& getMentions() const | ||
75 | { | ||
76 | assert(_valid); | ||
77 | |||
78 | return _mentions; | ||
79 | } | ||
80 | 59 | ||
81 | std::string generateReplyPrefill(const user& me) const; | 60 | std::string generateReplyPrefill(const user& me) const; |
82 | 61 | ||
83 | std::string getURL() const; | 62 | std::string getURL() const; |
84 | 63 | ||
85 | private: | 64 | private: |
86 | 65 | ||
87 | bool _valid = false; | 66 | tweet_id _id; |
88 | tweet_id _id; | 67 | std::string _text; |
89 | std::string _text; | 68 | hatkirby::recptr<user> _author; |
90 | std::unique_ptr<user> _author; | 69 | std::time_t _created_at; |
91 | std::time_t _created_at; | 70 | bool _is_retweet = false; |
92 | bool _is_retweet = false; | 71 | hatkirby::recptr<tweet> _retweeted_status; |
93 | std::unique_ptr<tweet> _retweeted_status; | 72 | std::vector<std::pair<user_id, std::string>> _mentions; |
94 | std::vector<std::pair<user_id, std::string>> _mentions; | ||
95 | }; | 73 | }; |
96 | 74 | ||
97 | }; | 75 | }; |
diff --git a/src/user.cpp b/src/user.cpp index d2fa592..8109123 100644 --- a/src/user.cpp +++ b/src/user.cpp | |||
@@ -1,24 +1,25 @@ | |||
1 | #include "user.h" | 1 | #include "user.h" |
2 | #include <json.hpp> | 2 | #include <json.hpp> |
3 | #include "codes.h" | 3 | #include "codes.h" |
4 | #include "client.h" | ||
5 | 4 | ||
6 | namespace twitter { | 5 | namespace twitter { |
7 | 6 | ||
8 | user::user(std::string data) try | 7 | user::user(std::string data) |
9 | : _valid(true) | ||
10 | { | 8 | { |
11 | auto json = nlohmann::json::parse(data); | 9 | try |
12 | _id = json["id"].get<user_id>(); | 10 | { |
13 | _screen_name = json["screen_name"].get<std::string>(); | 11 | auto json = nlohmann::json::parse(data); |
14 | _name = json["name"].get<std::string>(); | 12 | _id = json["id"].get<user_id>(); |
15 | _protected = json["protected"].get<bool>(); | 13 | _screen_name = json["screen_name"].get<std::string>(); |
16 | } catch (const std::invalid_argument& error) | 14 | _name = json["name"].get<std::string>(); |
17 | { | 15 | _protected = json["protected"].get<bool>(); |
18 | std::throw_with_nested(malformed_object("user", data)); | 16 | } catch (const std::invalid_argument& error) |
19 | } catch (const std::domain_error& error) | 17 | { |
20 | { | 18 | std::throw_with_nested(malformed_object("user", data)); |
21 | std::throw_with_nested(malformed_object("user", data)); | 19 | } catch (const std::domain_error& error) |
20 | { | ||
21 | std::throw_with_nested(malformed_object("user", data)); | ||
22 | } | ||
22 | } | 23 | } |
23 | 24 | ||
24 | }; | 25 | } |
diff --git a/src/user.h b/src/user.h index acd62d0..b743074 100644 --- a/src/user.h +++ b/src/user.h | |||
@@ -2,66 +2,52 @@ | |||
2 | #define USER_H_BF3AB38C | 2 | #define USER_H_BF3AB38C |
3 | 3 | ||
4 | #include <string> | 4 | #include <string> |
5 | #include <set> | ||
6 | #include <cassert> | ||
7 | 5 | ||
8 | namespace twitter { | 6 | namespace twitter { |
9 | 7 | ||
10 | class client; | ||
11 | |||
12 | typedef unsigned long long user_id; | 8 | typedef unsigned long long user_id; |
13 | 9 | ||
14 | class user { | 10 | class user { |
15 | public: | 11 | public: |
16 | 12 | ||
17 | user() {} | 13 | user(std::string data); |
18 | user(std::string data); | 14 | |
19 | 15 | user_id getID() const | |
20 | user_id getID() const | 16 | { |
21 | { | 17 | return _id; |
22 | assert(_valid); | 18 | } |
23 | 19 | ||
24 | return _id; | 20 | std::string getScreenName() const |
25 | } | 21 | { |
26 | 22 | return _screen_name; | |
27 | std::string getScreenName() const | 23 | } |
28 | { | 24 | |
29 | assert(_valid); | 25 | std::string getName() const |
30 | 26 | { | |
31 | return _screen_name; | 27 | return _name; |
32 | } | 28 | } |
33 | 29 | ||
34 | std::string getName() const | 30 | bool isProtected() const |
35 | { | 31 | { |
36 | assert(_valid); | 32 | return _protected; |
37 | 33 | } | |
38 | return _name; | 34 | |
39 | } | 35 | bool operator==(const user& other) const |
40 | 36 | { | |
41 | bool isProtected() const | 37 | return _id == other._id; |
42 | { | 38 | } |
43 | assert(_valid); | 39 | |
44 | 40 | bool operator!=(const user& other) const | |
45 | return _protected; | 41 | { |
46 | } | 42 | return _id != other._id; |
47 | 43 | } | |
48 | bool operator==(const user& other) const | 44 | |
49 | { | 45 | private: |
50 | return _id == other._id; | 46 | |
51 | } | 47 | user_id _id; |
52 | 48 | std::string _screen_name; | |
53 | bool operator!=(const user& other) const | 49 | std::string _name; |
54 | { | 50 | bool _protected = false; |
55 | return _id != other._id; | ||
56 | } | ||
57 | |||
58 | private: | ||
59 | |||
60 | bool _valid = false; | ||
61 | user_id _id; | ||
62 | std::string _screen_name; | ||
63 | std::string _name; | ||
64 | bool _protected = false; | ||
65 | }; | 51 | }; |
66 | 52 | ||
67 | }; | 53 | }; |