1 /** 2 * Copyright © The Bot Blog 2019 3 * License: MIT (https://github.com/TheBotBlog/thebotbloglib/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 */ 6 module thebotbloglib.facebookcomment; 7 8 import std.string : strip, toLower; 9 import std.array : split; 10 import std.algorithm : count; 11 12 import thebotbloglib.webmanager; 13 import thebotbloglib.facebookservice; 14 import thebotbloglib.graphapi; 15 import thebotbloglib.facebookreact; 16 17 /// A Facebook comment. 18 final class FacebookComment 19 { 20 private: 21 /// The facebook service. 22 FacebookService _service; 23 /// The comment id. 24 string _commentId; 25 /// The id. 26 string _id; 27 /// The time the comment was created. 28 string _createdTime; 29 /// The comment's message. 30 string _message; 31 /// The author's name. 32 string _authorName; 33 /// The author's id. 34 string _authorId; 35 36 /// All the like reactions. 37 FacebookReact[] _likeReacts; 38 /// All the love reactions. 39 FacebookReact[] _loveReacts; 40 /// All the wow reactions. 41 FacebookReact[] _wowReacts; 42 /// All the haha reactions. 43 FacebookReact[] _hahaReacts; 44 /// All the sad reactions. 45 FacebookReact[] _sadReacts; 46 /// All the angry reactions. 47 FacebookReact[] _angryReacts; 48 49 /// The total amount of reactions. 50 size_t _totalReacts; 51 /// The total amount of positive reactions. 52 size_t _totalPositiveReacts; 53 /// The total amount of inclusive positive reactions. 54 size_t _totalInclusivePositiveReacts; 55 /// The total amount of negative reactions. 56 size_t _totalNegativeReacts; 57 /// The total reaction rate. 58 ptrdiff_t _totalReactionRate; 59 60 package(thebotbloglib) 61 { 62 final: 63 /** 64 * Creates a new Facebook comment. 65 * Params: 66 * service = The Facebook service to associate the comment with. 67 */ 68 this(FacebookService service) 69 { 70 _service = service; 71 } 72 73 @property 74 { 75 /// Sets the id of the comment. 76 void id(string newId) 77 { 78 _id = newId; 79 } 80 81 /// Sets the created time of the comment. 82 void createdTime(string newCreatedTime) 83 { 84 _createdTime = newCreatedTime; 85 } 86 87 /// Sets the message of the comment. 88 void message(string newMessage) 89 { 90 _message = newMessage; 91 } 92 93 /// Sets the author's name. 94 void authorName(string newAuthorName) 95 { 96 _authorName = newAuthorName; 97 } 98 99 /// Sets the author's id. 100 void authorId(string authorId) 101 { 102 _authorId = authorId; 103 } 104 } 105 } 106 107 public: 108 final: 109 @property 110 { 111 /// Gets the id. 112 string id() { return _id; } 113 114 /// Gets the time the comment was created. 115 string createdTime() { return _createdTime; } 116 117 /// Gets the message. 118 string message() { return _message; } 119 120 /// Gets the author's name. 121 string authorName() { return _authorName; } 122 123 /// Gets the author's id. 124 string authorId() { return _authorId; } 125 126 /// Gets the comment id. 127 string commentId() 128 { 129 if (id && id.strip.length && (!_commentId || !_commentId.strip.length)) 130 { 131 auto idData = id.split("_"); 132 133 if (idData.length > 1) 134 { 135 _commentId = idData[1]; 136 } 137 } 138 139 return _commentId; 140 } 141 142 /// Gets the like reactions. 143 FacebookReact[] likeReacts() { return _likeReacts; } 144 145 /// Gets the love reactions. 146 FacebookReact[] loveReacts() { return _loveReacts; } 147 148 /// Gets the wow reactions. 149 FacebookReact[] wowReacts() { return _wowReacts; } 150 151 /// Gets the haha reactions. 152 FacebookReact[] hahaReacts() { return _hahaReacts; } 153 154 /// Gets sad reactions. 155 FacebookReact[] sadReacts() { return _sadReacts; } 156 157 /// Gets the angry reactions. 158 FacebookReact[] angryReacts() { return _angryReacts; } 159 160 /// Gets the total reactions. 161 size_t totalReacts() { return _totalReacts; } 162 163 /// Gets the total positive reactions. 164 size_t totalPositiveReacts() { return _totalPositiveReacts; } 165 166 /// Gets the total inclusive positive reactions. 167 size_t totalInclusivePositiveReacts() { return _totalInclusivePositiveReacts; } 168 169 /// Gets the total negative reactions. 170 size_t totalNegativeReacts() { return _totalNegativeReacts; } 171 172 /// Gets the totoal reaction rate. 173 ptrdiff_t totalReactionRate() { return _totalReactionRate; } 174 } 175 176 /// Updates the reaactions. 177 void updateReacts() 178 { 179 FacebookReact[] reacts = []; 180 181 auto web = new WebManager(_service); 182 183 string[string] data; 184 185 auto resp = web.getRequest!GraphAPIObjectReactions(id, "reactions", data); 186 187 auto nextUrl = fillReacts(resp, reacts); 188 189 while (nextUrl && nextUrl.strip.length) 190 { 191 resp = web.getRequestRaw!GraphAPIObjectReactions(nextUrl); 192 193 nextUrl = fillReacts(resp, reacts); 194 } 195 196 _totalReacts = reacts.count!(r => r.reactionType != "none"); 197 198 _likeReacts = []; 199 _loveReacts = []; 200 _wowReacts = []; 201 _hahaReacts = []; 202 _sadReacts = []; 203 _angryReacts = []; 204 205 foreach (react; reacts) 206 { 207 switch (react.reactionType) 208 { 209 case "like": _likeReacts ~= react; break; 210 case "love": _loveReacts ~= react; break; 211 case "wow": _wowReacts ~= react; break; 212 case "haha": _hahaReacts ~= react; break; 213 case "sad": _sadReacts ~= react; break; 214 case "angry": _angryReacts ~= react; break; 215 216 default: break; 217 } 218 } 219 220 _totalPositiveReacts = (_likeReacts.length + _loveReacts.length); 221 _totalInclusivePositiveReacts = (_totalPositiveReacts + _hahaReacts.length); 222 _totalNegativeReacts = (_sadReacts.length + _angryReacts.length); 223 224 _totalReactionRate = _totalPositiveReacts - _angryReacts.length; 225 } 226 227 /** 228 * Fills the reactions. 229 * Params: 230 * resp = The graph api response. 231 * reacts = (ref) The reaction collection to append to. 232 */ 233 private string fillReacts(GraphAPIObjectReactions resp, ref FacebookReact[] reacts) 234 { 235 if (resp && resp.data && resp.data.length) 236 { 237 foreach (data; resp.data) 238 { 239 auto react = new FacebookReact; 240 react.id = data.id; 241 react.name = data.name; 242 react.reactionType = data.type.toLower.strip; 243 244 reacts ~= react; 245 } 246 247 if (resp.paging && resp.paging.next && resp.paging.next.strip.length) 248 { 249 return resp.paging.next; 250 } 251 } 252 253 return null; 254 } 255 }