about summary refs log tree commit diff stats
path: root/src/tweet.cpp
blob: 864bcd84d7068141a1af64c6971529a603598523 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include "tweet.h"
#include <json.hpp>
#include "util.h"
#include "codes.h"
#include "client.h"

namespace twitter {
  
  tweet::tweet(std::string data) try
    : _valid(true)
  {
    auto json = nlohmann::json::parse(data);
    _id = json["id"].get<tweet_id>();
    _text = json["text"].get<std::string>();
    _author = make_unique<user>(json["user"].dump());
    
    if (!json["retweeted_status"].is_null())
    {
      _is_retweet = true;
      
      _retweeted_status = make_unique<tweet>(json["retweeted_status"].dump());
    }
    
    if (!json["entities"].is_null())
    {
      auto entities = json["entities"];
      if (!entities["user_mentions"].is_null())
      {
        for (auto mention : entities["user_mentions"])
        {
          _mentions.push_back(std::make_pair(mention["id"].get<user_id>(), mention["screen_name"].get<std::string>()));
        }
      }
    }
  } catch (const std::invalid_argument& error)
  {
    std::throw_with_nested(malformed_object("tweet", data));
  } catch (const std::domain_error& error)
  {
    std::throw_with_nested(malformed_object("tweet", data));
  }
  
  tweet::tweet(const tweet& other)
  {
    _valid = other._valid;
    _id = other._id;
    _text = other._text;
    _author = make_unique<user>(*other._author);
    _is_retweet = other._is_retweet;
    
    if (_is_retweet)
    {
      _retweeted_status = make_unique<tweet>(*other._retweeted_status);
    }
    
    _mentions = other._mentions;
  }
  
  tweet::tweet(tweet&& other) : tweet()
  {
    swap(*this, other);
  }
  
  tweet& tweet::operator=(tweet other)
  {
    swap(*this, other);
    
    return *this;
  }
  
  void swap(tweet& first, tweet& second)
  {
    std::swap(first._valid, second._valid);
    std::swap(first._id, second._id);
    std::swap(first._text, second._text);
    std::swap(first._author, second._author);
    std::swap(first._is_retweet, second._is_retweet);
    std::swap(first._retweeted_status, second._retweeted_status);
    std::swap(first._mentions, second._mentions);
  }
  
  std::string tweet::generateReplyPrefill(const user& me) const
  {
    std::ostringstream output;
    output << "@" << _author->getScreenName() << " ";
    
    for (auto mention : _mentions)
    {
      if ((mention.first != _author->getID()) && (mention.first != me.getID()))
      {
        output << "@" << mention.second << " ";
      }
    }
    
    return output.str();
  }
  
  std::string tweet::getURL() const
  {
    assert(_valid);
    
    std::ostringstream urlstr;
    urlstr << "https://twitter.com/";
    urlstr << _author->getScreenName();
    urlstr << "/statuses/";
    urlstr << _id;
    
    return urlstr.str();
  }
  
};