From 2433a9dabee1352ce60712e6d3a67a4517e939e5 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Fri, 5 Apr 2019 15:50:52 +0200 Subject: [PATCH 01/12] Base ground for the split Resolves https://github.com/brave/brave-browser/issues/4005 --- vendor/bat-native-ledger/BUILD.gn | 6 ++++ .../src/bat/ledger/internal/bat_get_media.cc | 4 ++- .../src/bat/ledger/internal/bat_get_media.h | 10 +++++++ .../src/bat/ledger/internal/media/helper.cc | 12 ++++++++ .../src/bat/ledger/internal/media/helper.h | 15 ++++++++++ .../src/bat/ledger/internal/media/twitch.cc | 22 ++++++++++++++ .../src/bat/ledger/internal/media/twitch.h | 29 +++++++++++++++++++ .../src/bat/ledger/internal/media/youtube.cc | 22 ++++++++++++++ .../src/bat/ledger/internal/media/youtube.h | 29 +++++++++++++++++++ 9 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h diff --git a/vendor/bat-native-ledger/BUILD.gn b/vendor/bat-native-ledger/BUILD.gn index d1c676605c4a..6b8461d4580d 100644 --- a/vendor/bat-native-ledger/BUILD.gn +++ b/vendor/bat-native-ledger/BUILD.gn @@ -101,6 +101,12 @@ source_set("ledger") { "src/bat/ledger/internal/bignum.h", "src/bat/ledger/internal/ledger_impl.cc", "src/bat/ledger/internal/ledger_impl.h", + "src/bat/ledger/internal/media/helper.h", + "src/bat/ledger/internal/media/helper.cc", + "src/bat/ledger/internal/media/twitch.h", + "src/bat/ledger/internal/media/twitch.cc", + "src/bat/ledger/internal/media/youtube.h", + "src/bat/ledger/internal/media/youtube.cc", "src/bat/ledger/ledger.cc", "src/bat/ledger/transaction_info.cc", "src/bat/ledger/transactions_info.cc", diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc index c14baa656ad6..b3986885f6a0 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc @@ -23,7 +23,9 @@ using std::placeholders::_3; namespace braveledger_bat_get_media { BatGetMedia::BatGetMedia(bat_ledger::LedgerImpl* ledger): - ledger_(ledger) { + ledger_(ledger), + media_youtube_(new braveledger_media::MediaYouTube(ledger)), + media_twitch_(new braveledger_media::MediaTwitch(ledger)) { } BatGetMedia::~BatGetMedia() {} diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h index 2a3f5238ef98..3b957493aa8b 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h @@ -14,6 +14,9 @@ #include "bat/ledger/internal/bat_helper.h" #include "bat/ledger/ledger.h" +#include "bat/ledger/internal/media/youtube.h" +#include "bat/ledger/internal/media/twitch.h" + namespace bat_ledger { class LedgerImpl; } @@ -22,6 +25,11 @@ namespace leveldb { class DB; } +//namespace braveledger_media { +//class MediaYouTube; +//class MediaTwitch; +//} + namespace braveledger_bat_get_media { using FetchDataFromUrlCallback = std::function media_youtube_; + std::unique_ptr media_twitch_; std::map twitchEvents; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc new file mode 100644 index 000000000000..a6706049274e --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc @@ -0,0 +1,12 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "bat/ledger/internal/media/helper.h" + + +namespace braveledger_media { + + +} // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h new file mode 100644 index 000000000000..edd69359bfde --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h @@ -0,0 +1,15 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVELEDGER_MEDIA_HELPER_H_ +#define BRAVELEDGER_MEDIA_HELPER_H_ + +namespace braveledger_media { + + + +} // namespace braveledger_media + +#endif // BRAVELEDGER_MEDIA_HELPER_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc new file mode 100644 index 000000000000..855ab48826be --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc @@ -0,0 +1,22 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "bat/ledger/internal/ledger_impl.h" +#include "bat/ledger/internal/media/twitch.h" + +using std::placeholders::_1; +using std::placeholders::_2; + +namespace braveledger_media { + +MediaTwitch::MediaTwitch(bat_ledger::LedgerImpl* ledger): + ledger_(ledger) { +} + +MediaTwitch::~MediaTwitch() { +} + + +} // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h new file mode 100644 index 000000000000..0014b5a2aa16 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVELEDGER_MEDIA_TWITCH_H_ +#define BRAVELEDGER_MEDIA_TWITCH_H_ + +#include "bat/ledger/ledger.h" + +namespace bat_ledger { +class LedgerImpl; +} + +namespace braveledger_media { + +class MediaTwitch : public ledger::LedgerCallbackHandler { + public: + explicit MediaTwitch(bat_ledger::LedgerImpl* ledger); + + ~MediaTwitch() override; + + private: + bat_ledger::LedgerImpl* ledger_; // NOT OWNED +}; + +} // namespace braveledger_media + +#endif // BRAVELEDGER_MEDIA_TWITCH_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc new file mode 100644 index 000000000000..af54043a9d6c --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc @@ -0,0 +1,22 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "bat/ledger/internal/ledger_impl.h" +#include "bat/ledger/internal/media/youtube.h" + +using std::placeholders::_1; +using std::placeholders::_2; + +namespace braveledger_media { + +MediaYouTube::MediaYouTube(bat_ledger::LedgerImpl* ledger): + ledger_(ledger) { +} + +MediaYouTube::~MediaYouTube() { +} + + +} // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h new file mode 100644 index 000000000000..7dd35b9b3d60 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVELEDGER_MEDIA_YOUTUBE_H_ +#define BRAVELEDGER_MEDIA_YOUTUBE_H_ + +#include "bat/ledger/ledger.h" + +namespace bat_ledger { +class LedgerImpl; +} + +namespace braveledger_media { + +class MediaYouTube : public ledger::LedgerCallbackHandler { + public: + explicit MediaYouTube(bat_ledger::LedgerImpl* ledger); + + ~MediaYouTube() override; + + private: + bat_ledger::LedgerImpl* ledger_; // NOT OWNED +}; + +} // namespace braveledger_media + +#endif // BRAVELEDGER_MEDIA_YOUTUBE_H_ From 0999527b7898a37d17ed7d346c2c31f6e579b709 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Wed, 10 Apr 2019 17:39:54 +0200 Subject: [PATCH 02/12] Youtube process media --- .../src/bat/ledger/internal/bat_get_media.cc | 39 +- .../src/bat/ledger/internal/bat_helper.cc | 100 ----- .../src/bat/ledger/internal/bat_helper.h | 13 - .../src/bat/ledger/internal/ledger_impl.cc | 3 +- .../src/bat/ledger/internal/media/helper.cc | 51 +++ .../src/bat/ledger/internal/media/helper.h | 16 + .../src/bat/ledger/internal/media/youtube.cc | 364 ++++++++++++++++++ .../src/bat/ledger/internal/media/youtube.h | 70 ++++ .../src/bat/ledger/internal/static_values.h | 10 - 9 files changed, 509 insertions(+), 157 deletions(-) diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc index b3986885f6a0..3636a512190a 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc @@ -66,42 +66,15 @@ void BatGetMedia::processMedia(const std::map& parts, return; } - std::string mediaId = braveledger_bat_helper::getMediaId(parts, type); - BLOG(ledger_, ledger::LogLevel::LOG_DEBUG) << "Media Id: " << mediaId; - if (mediaId.empty()) { - return; - } - std::string media_key = braveledger_bat_helper::getMediaKey(mediaId, type); - BLOG(ledger_, ledger::LogLevel::LOG_DEBUG) << "Media key: " << media_key; - uint64_t duration = 0; - ledger::TwitchEventInfo twitchEventInfo; if (type == YOUTUBE_MEDIA_TYPE) { - duration = braveledger_bat_helper::getMediaDuration(parts, media_key, type); - } else if (type == TWITCH_MEDIA_TYPE) { - std::map::const_iterator iter = - parts.find("event"); - if (iter != parts.end()) { - twitchEventInfo.event_ = iter->second; - } - iter = parts.find("time"); - if (iter != parts.end()) { - twitchEventInfo.time_ = iter->second; - } + media_youtube_->ProcessMedia(parts, visit_data); + return; } - BLOG(ledger_, ledger::LogLevel::LOG_DEBUG) << "Media duration: " << duration; - ledger_->GetMediaPublisherInfo(media_key, - std::bind(&BatGetMedia::getPublisherInfoDataCallback, - this, - mediaId, - media_key, - type, - duration, - twitchEventInfo, - visit_data, - 0, - _1, - _2)); +// if (type == TWITCH_MEDIA_TYPE) { +// media_twitch_->ProcessMedia(parts, visit_data); +// return; +// } } void BatGetMedia::getPublisherInfoDataCallback(const std::string& mediaId, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.cc index 0f592b73efb1..baefdbbccded 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.cc @@ -2493,106 +2493,6 @@ uint64_t currentTime() { return time(0); } -void getTwitchParts( - const std::string& query, - std::vector>* parts) { - size_t pos = query.find("data="); - if (std::string::npos != pos && query.length() > 5) { - std::string varValue = query.substr(5); - std::vector decoded; - bool succeded = braveledger_bat_helper::getFromBase64(varValue, &decoded); - if (succeded) { - decoded.push_back((uint8_t)'\0'); - braveledger_bat_helper::getJSONTwitchProperties( - reinterpret_cast(&decoded.front()), - parts); - } - } -} - -std::string getMediaId(const std::map& data, - const std::string& type) { - if (YOUTUBE_MEDIA_TYPE == type) { - std::map::const_iterator iter = - data.find("docid"); - if (iter != data.end()) { - return iter->second; - } - } else if (TWITCH_MEDIA_TYPE == type) { - std::map::const_iterator iter = - data.find("event"); - if (iter != data.end() && data.find("properties") != data.end()) { - unsigned int size = braveledger_ledger::_twitch_events.size(); - for (size_t i = 0; i < size; i++) { - if (iter->second == braveledger_ledger::_twitch_events[i]) { - iter = data.find("channel"); - std::string id(""); - if (iter != data.end()) { - id = iter->second; - } - iter = data.find("vod"); - if (iter != data.end()) { - std::string idAddition(iter->second); - if (idAddition.find('v') != std::string::npos) { - id += "_vod_" + braveledger_bat_helper::split(idAddition, 'v')[1]; - } - } - - return id; - } - } - } - } - - return ""; -} - -std::string getMediaKey(const std::string& mediaId, const std::string& type) { - return type + "_" + mediaId; -} - -uint64_t getMediaDuration(const std::map& data, - const std::string& media_key, - const std::string& type) { - uint64_t duration = 0; - - if (YOUTUBE_MEDIA_TYPE == type) { - std::map::const_iterator iterSt = data.find("st"); - std::map::const_iterator iterEt = data.find("et"); - if (iterSt != data.end() && iterEt != data.end()) { - std::vector startTime = braveledger_bat_helper::split( - iterSt->second, - ','); - std::vector endTime = braveledger_bat_helper::split( - iterEt->second, - ','); - if (startTime.size() != endTime.size()) { - return 0; - } - // get all the intervals and combine them. - // (Should only be one set if there were no seeks) - for (size_t i = 0; i < startTime.size(); i++) { - std::stringstream tempET(endTime[i]); - std::stringstream tempST(startTime[i]); - double st = 0; - double et = 0; - tempET >> et; - tempST >> st; - - // round instead of truncate - // also make sure we include previous iterations - // if more than one set exists - duration += (uint64_t)std::round(et - st); - } - } - } else if (TWITCH_MEDIA_TYPE == type) { - // We set the correct duration for twitch in BatGetMedia class - duration = 0; - } - - return duration; -} - bool HasSameDomainAndPath( const std::string& url_to_validate, const std::string& domain_to_match, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h index d5fd00fe335c..1089164c60a3 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h @@ -526,19 +526,6 @@ std::string sign(std::string* keys, uint64_t currentTime(); -void getTwitchParts( - const std::string& query, - std::vector>* parts); - -std::string getMediaId(const std::map& data, - const std::string& type); - -std::string getMediaKey(const std::string& mediaId, const std::string& type); - -uint64_t getMediaDuration(const std::map& data, - const std::string& media_key, - const std::string& type); - std::string buildURL(const std::string& path, const std::string& prefix = "", const SERVER_TYPES& server = SERVER_TYPES::LEDGER); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc index 4c5c298eccfa..995602b3c907 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc @@ -22,6 +22,7 @@ #include "bat/ledger/internal/bat_publishers.h" #include "bat/ledger/internal/bat_state.h" #include "bat/ledger/internal/ledger_impl.h" +#include "bat/ledger/internal/media/helper.h" #include "bat/ledger/internal/rapidjson_bat_helper.h" #include "bat/ledger/internal/static_values.h" @@ -203,7 +204,7 @@ void LedgerImpl::OnPostData( std::vector> twitchParts; if (TWITCH_MEDIA_TYPE == type) { - braveledger_bat_helper::getTwitchParts(post_data, &twitchParts); + braveledger_media::GetTwitchParts(post_data, &twitchParts); for (size_t i = 0; i < twitchParts.size(); i++) { bat_get_media_->processMedia(twitchParts[i], type, visit_data); } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc index a6706049274e..6a34e1a59e15 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc @@ -4,9 +4,60 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "bat/ledger/internal/media/helper.h" +#include "bat/ledger/internal/bat_helper.h" namespace braveledger_media { +std::string GetMediaKey(const std::string& mediaId, const std::string& type) { + return type + "_" + mediaId; +} + +void GetTwitchParts( + const std::string& query, + std::vector>* parts) { + size_t pos = query.find("data="); + if (std::string::npos != pos && query.length() > 5) { + std::string varValue = query.substr(5); + std::vector decoded; + bool succeded = braveledger_bat_helper::getFromBase64(varValue, &decoded); + if (succeded) { + decoded.push_back((uint8_t)'\0'); + braveledger_bat_helper::getJSONTwitchProperties( + reinterpret_cast(&decoded.front()), + parts); + } + } +} + +// static +std::string ExtractData(const std::string& data, + const std::string& match_after, + const std::string& match_until) { + std::string match; + size_t match_after_size = match_after.size(); + size_t data_size = data.size(); + + if (data_size < match_after_size) { + return match; + } + + size_t start_pos = data.find(match_after); + if (start_pos != std::string::npos) { + start_pos += match_after_size; + size_t endPos = data.find(match_until, start_pos); + if (endPos != start_pos) { + if (endPos != std::string::npos && endPos > start_pos) { + match = data.substr(start_pos, endPos - start_pos); + } else if (endPos != std::string::npos) { + match = data.substr(start_pos, endPos); + } else { + match = data.substr(start_pos, std::string::npos); + } + } + } + + return match; +} } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h index edd69359bfde..f31038e37da9 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h @@ -6,9 +6,25 @@ #ifndef BRAVELEDGER_MEDIA_HELPER_H_ #define BRAVELEDGER_MEDIA_HELPER_H_ +#include +#include +#include + namespace braveledger_media { +using FetchDataFromUrlCallback = std::function& headers)>; + +std::string GetMediaKey(const std::string& mediaId, const std::string& type); + +void GetTwitchParts(const std::string& query, + std::vector>* parts); +std::string ExtractData(const std::string& data, + const std::string& match_after, + const std::string& match_until); } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc index af54043a9d6c..7b0dfd902f53 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc @@ -3,11 +3,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include +#include + #include "bat/ledger/internal/ledger_impl.h" +#include "bat/ledger/internal/media/helper.h" #include "bat/ledger/internal/media/youtube.h" using std::placeholders::_1; using std::placeholders::_2; +using std::placeholders::_3; namespace braveledger_media { @@ -18,5 +23,364 @@ MediaYouTube::MediaYouTube(bat_ledger::LedgerImpl* ledger): MediaYouTube::~MediaYouTube() { } +// static +std::string MediaYouTube::GetMediaIdFromParts( + const std::map& parts) { + std::string result; + std::map::const_iterator iter = + parts.find("docid"); + if (iter != parts.end()) { + result = iter->second; + } + + return result; +} + +// static +uint64_t MediaYouTube::GetMediaDurationFromParts( + const std::map& data, + const std::string& media_key) { + uint64_t duration = 0; + std::map::const_iterator iter_st = data.find("st"); + std::map::const_iterator iter_et = data.find("et"); + if (iter_st != data.end() && iter_et != data.end()) { + std::vector start_time = braveledger_bat_helper::split( + iter_st->second, + ','); + std::vector end_time = braveledger_bat_helper::split( + iter_et->second, + ','); + if (start_time.size() != end_time.size()) { + return 0; + } + + // get all the intervals and combine them. + // (Should only be one set if there were no seeks) + for (size_t i = 0; i < start_time.size(); i++) { + std::stringstream tempET(end_time[i]); + std::stringstream tempST(start_time[i]); + double st = 0; + double et = 0; + tempET >> et; + tempST >> st; + + // round instead of truncate + // also make sure we include previous iterations + // if more than one set exists + duration += (uint64_t)std::round(et - st); + } + } + + return duration; +} + +// static +std::string MediaYouTube::GetVideoUrl(const std::string& media_id) { + std::string res; + DCHECK(!media_id.empty()); + return "https://www.youtube.com/watch?v=" + media_id; +} + +// static +std::string MediaYouTube::GetChannelUrl(const std::string& publisher_key) { + std::string res; + DCHECK(!publisher_key.empty()); + return "https://www.youtube.com/channel/" + publisher_key; +} + +// static +std::string MediaYouTube::GetFavIconUrl(const std::string& data) { + std::string favicon_url = braveledger_media::ExtractData( + data, + "\"avatar\":{\"thumbnails\":[{\"url\":\"", "\""); + + if (favicon_url.empty()) { + favicon_url = braveledger_media::ExtractData( + data, + "\"width\":88,\"height\":88},{\"url\":\"", "\""); + } + + return favicon_url; +} + +// static +std::string MediaYouTube::GetChannelId(const std::string& data) { + std::string id = braveledger_media::ExtractData(data, "\"ucid\":\"", "\""); + if (id.empty()) { + id = braveledger_media::ExtractData( + data, + "HeaderRenderer\":{\"channelId\":\"", "\""); + } + + if (id.empty()) { + id = braveledger_media::ExtractData( + data, + ""); + } + + if (id.empty()) { + id = braveledger_media::ExtractData( + data, + "browseEndpoint\":{\"browseId\":\"", + "\""); + } + + return id; +} + +// static +std::string MediaYouTube::GetPublisherName(const std::string& data) { + std::string publisher_name; + std::string publisher_json_name = braveledger_media::ExtractData( + data, + "\"author\":\"", "\""); + std::string publisher_json = "{\"brave_publisher\":\"" + + publisher_json_name + "\"}"; + // scraped data could come in with JSON code points added. + // Make to JSON object above so we can decode. + braveledger_bat_helper::getJSONValue( + "brave_publisher", publisher_json, &publisher_name); + return publisher_name; +} + +void MediaYouTube::OnMediaActivityError(const ledger::VisitData& visit_data, + uint64_t window_id) { + std::string url = YOUTUBE_TLD; + std::string name = YOUTUBE_MEDIA_TYPE; + + if (!url.empty()) { + ledger::VisitData new_data; + new_data.domain = url; + new_data.url = "https://" + url; + new_data.path = "/"; + new_data.name = name; + + ledger_->GetPublisherActivityFromUrl(window_id, new_data, std::string()); + } else { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) + << "Media activity error for " + << YOUTUBE_MEDIA_TYPE << " (name: " + << name << ", url: " + << visit_data.url << ")"; + } +} + +void MediaYouTube::ProcessMedia(const std::map& parts, + const ledger::VisitData& visit_data) { + std::string media_id = GetMediaIdFromParts(parts); + if (media_id.empty()) { + return; + } + + std::string media_key = braveledger_media::GetMediaKey(media_id, + YOUTUBE_MEDIA_TYPE); + uint64_t duration = GetMediaDurationFromParts(parts, media_key); + + BLOG(ledger_, ledger::LogLevel::LOG_DEBUG) << "Media key: " << media_key; + BLOG(ledger_, ledger::LogLevel::LOG_DEBUG) << "Media duration: " << duration; + + ledger_->GetMediaPublisherInfo(media_key, + std::bind(&MediaYouTube::OnMediaPublisherInfo, + this, + media_id, + media_key, + duration, + visit_data, + 0, + _1, + _2)); +} + +void MediaYouTube::OnMediaPublisherInfo( + const std::string& media_id, + const std::string& media_key, + const uint64_t duration, + const ledger::VisitData& visit_data, + const uint64_t window_id, + ledger::Result result, + std::unique_ptr publisher_info) { + if (result != ledger::Result::LEDGER_OK && + result != ledger::Result::NOT_FOUND) { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) + << "Failed to get publisher info"; + return; + } + + if (!publisher_info && !publisher_info.get()) { + std::string media_url = GetVideoUrl(media_id); + auto callback = std::bind( + &MediaYouTube::OnEmbedResponse, + this, + duration, + media_key, + media_url, + visit_data, + window_id, + _1, + _2, + _3); + + const std::string url = (std::string)YOUTUBE_PROVIDER_URL + "?format=json&url=" + + ledger_->URIEncode(media_url); + + FetchDataFromUrl(url, callback); + } else { + ledger::VisitData updated_visit_data(visit_data); + updated_visit_data.name = publisher_info->name; + updated_visit_data.url = publisher_info->url; + updated_visit_data.provider = YOUTUBE_MEDIA_TYPE; + updated_visit_data.favicon_url = publisher_info->favicon_url; + std::string id = publisher_info->id; + ledger_->SaveMediaVisit(id, updated_visit_data, duration, window_id); + } +} + +void MediaYouTube::OnEmbedResponse( + const uint64_t duration, + const std::string& media_key, + const std::string& media_url, + const ledger::VisitData& visit_data, + const uint64_t window_id, + int response_status_code, + const std::string& response, + const std::map& headers) { + ledger_->LogResponse(__func__, response_status_code, response, headers); + + if (response_status_code != 200) { + // embedding disabled, need to scrape + if (response_status_code == 401) { + FetchDataFromUrl(visit_data.url, + std::bind(&MediaYouTube::OnPublisherPage, + this, + duration, + media_key, + std::string(), + std::string(), + visit_data, + window_id, + _1, + _2, + _3)); + } + return; + } + + std::string publisher_url; + braveledger_bat_helper::getJSONValue("author_url", response, &publisher_url); + std::string publisher_name; + braveledger_bat_helper::getJSONValue("author_name", + response, + &publisher_name); + + auto callback = std::bind(&MediaYouTube::OnPublisherPage, + this, + duration, + media_key, + publisher_url, + publisher_name, + visit_data, + window_id, + _1, + _2, + _3); + + FetchDataFromUrl(publisher_url, callback); +} + +void MediaYouTube::OnPublisherPage( + const uint64_t duration, + const std::string& media_key, + std::string publisher_url, + std::string publisher_name, + const ledger::VisitData& visit_data, + const uint64_t window_id, + int response_status_code, + const std::string& response, + const std::map& headers) { + if (response_status_code != 200 && publisher_name.empty()) { + OnMediaActivityError(visit_data, window_id); + return; + } + + if (response_status_code == 200) { + std::string fav_icon = GetFavIconUrl(response); + std::string channel_id = GetChannelId(response); + + if (publisher_name.empty()) { + publisher_name = GetPublisherName(response); + } + + if (publisher_url.empty()) { + publisher_url = GetChannelUrl(channel_id); + } + + SavePublisherInfo(duration, + media_key, + publisher_url, + publisher_name, + visit_data, + window_id, + fav_icon, + channel_id); + } +} + +void MediaYouTube::SavePublisherInfo(const uint64_t duration, + const std::string& media_key, + const std::string& publisher_url, + const std::string& publisher_name, + const ledger::VisitData& visit_data, + const uint64_t window_id, + const std::string& fav_icon, + const std::string& channel_id) { + std::string publisher_id; + std::string url; + publisher_id = (std::string)YOUTUBE_MEDIA_TYPE + "#channel:"; + if (channel_id.empty()) { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << + "Channel id is missing for: " << media_key; + return; + } + + publisher_id += channel_id; + url = publisher_url + "/videos"; + + if (publisher_id.empty()) { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << + "Publisher id is missing for: " << media_key; + return; + } + + ledger::VisitData updated_visit_data(visit_data); + + if (fav_icon.length() > 0) { + updated_visit_data.favicon_url = fav_icon; + } + + updated_visit_data.provider = YOUTUBE_MEDIA_TYPE; + updated_visit_data.name = publisher_name; + updated_visit_data.url = url; + + ledger_->SaveMediaVisit(publisher_id, + updated_visit_data, + duration, + window_id); + if (!media_key.empty()) { + ledger_->SetMediaPublisherInfo(media_key, publisher_id); + } +} + +void MediaYouTube::FetchDataFromUrl( + const std::string& url, + braveledger_media::FetchDataFromUrlCallback callback) { + ledger_->LoadURL(url, + std::vector(), + std::string(), + std::string(), + ledger::URL_METHOD::GET, + callback); +} + } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h index 7dd35b9b3d60..ed94985c0201 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h @@ -6,7 +6,11 @@ #ifndef BRAVELEDGER_MEDIA_YOUTUBE_H_ #define BRAVELEDGER_MEDIA_YOUTUBE_H_ +#include +#include + #include "bat/ledger/ledger.h" +#include "bat/ledger/internal/media/helper.h" namespace bat_ledger { class LedgerImpl; @@ -20,7 +24,73 @@ class MediaYouTube : public ledger::LedgerCallbackHandler { ~MediaYouTube() override; + void ProcessMedia(const std::map& parts, + const ledger::VisitData& visit_data); + private: + + static std::string GetMediaIdFromParts( + const std::map& parts); + + static uint64_t GetMediaDurationFromParts( + const std::map& data, + const std::string& media_key); + + static std::string GetVideoUrl(const std::string& media_id); + + static std::string GetChannelUrl(const std::string& publisher_key); + + static std::string GetFavIconUrl(const std::string& data); + + static std::string GetChannelId(const std::string& data); + + static std::string GetPublisherName(const std::string& data); + + void OnMediaActivityError(const ledger::VisitData& visit_data, + uint64_t window_id); + + void OnMediaPublisherInfo( + const std::string& media_id, + const std::string& media_key, + const uint64_t duration, + const ledger::VisitData& visit_data, + uint64_t window_id, + ledger::Result result, + std::unique_ptr publisher_info); + + void OnEmbedResponse( + const uint64_t duration, + const std::string& media_key, + const std::string& media_url, + const ledger::VisitData& visit_data, + const uint64_t window_id, + int response_status_code, + const std::string& response, + const std::map& headers); + + void OnPublisherPage( + const uint64_t duration, + const std::string& media_key, + std::string publisher_url, + std::string publisher_name, + const ledger::VisitData& visit_data, + const uint64_t window_id, + int response_status_code, + const std::string& response, + const std::map& headers); + + void SavePublisherInfo(const uint64_t duration, + const std::string& media_key, + const std::string& publisher_url, + const std::string& publisher_name, + const ledger::VisitData& visit_data, + const uint64_t window_id, + const std::string& fav_icon, + const std::string& channel_id); + + void FetchDataFromUrl(const std::string& url, + braveledger_media::FetchDataFromUrlCallback callback); + bat_ledger::LedgerImpl* ledger_; // NOT OWNED }; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/static_values.h b/vendor/bat-native-ledger/src/bat/ledger/internal/static_values.h index fcd136c6ffca..230b4df19958 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/static_values.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/static_values.h @@ -104,16 +104,6 @@ static const uint64_t _milliseconds_minute = 60 * 1000; static const uint64_t _milliseconds_second = 1000; -static const std::vector _twitch_events = { - "buffer-empty", - "buffer-refill", - "video_end", - "minute-watched", - "video_pause", - "player_click_vod_seek", - "video-play", - "video_error"}; - // 24 hours in seconds static const uint64_t _publishers_list_load_interval = 24 * 60 * 60; From 8b656517d60806e13647429b76d81139597bad7e Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Wed, 10 Apr 2019 18:38:42 +0200 Subject: [PATCH 03/12] Twitch process media --- .../src/bat/ledger/internal/bat_get_media.cc | 8 +- .../src/bat/ledger/internal/media/twitch.cc | 336 ++++++++++++++++++ .../src/bat/ledger/internal/media/twitch.h | 44 +++ 3 files changed, 384 insertions(+), 4 deletions(-) diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc index 3636a512190a..cb181c6cc392 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc @@ -71,10 +71,10 @@ void BatGetMedia::processMedia(const std::map& parts, return; } -// if (type == TWITCH_MEDIA_TYPE) { -// media_twitch_->ProcessMedia(parts, visit_data); -// return; -// } + if (type == TWITCH_MEDIA_TYPE) { + media_twitch_->ProcessMedia(parts, visit_data); + return; + } } void BatGetMedia::getPublisherInfoDataCallback(const std::string& mediaId, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc index 855ab48826be..c7890c6ed300 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc @@ -3,14 +3,29 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include +#include + +#include "bat/ledger/internal/bat_helper.h" #include "bat/ledger/internal/ledger_impl.h" #include "bat/ledger/internal/media/twitch.h" using std::placeholders::_1; using std::placeholders::_2; +using std::placeholders::_3; namespace braveledger_media { +static const std::vector _twitch_events = { + "buffer-empty", + "buffer-refill", + "video_end", + "minute-watched", + "video_pause", + "player_click_vod_seek", + "video-play", + "video_error"}; + MediaTwitch::MediaTwitch(bat_ledger::LedgerImpl* ledger): ledger_(ledger) { } @@ -18,5 +33,326 @@ MediaTwitch::MediaTwitch(bat_ledger::LedgerImpl* ledger): MediaTwitch::~MediaTwitch() { } +// static +std::string MediaTwitch::GetMediaIdFromParts( + const std::map& parts) { + std::map::const_iterator iter = + parts.find("event"); + if (iter != parts.end() && parts.find("properties") != parts.end()) { + unsigned int size = _twitch_events.size(); + for (size_t i = 0; i < size; i++) { + if (iter->second == _twitch_events[i]) { + iter = parts.find("channel"); + std::string id(""); + if (iter != parts.end()) { + id = iter->second; + } + iter = parts.find("vod"); + if (iter != parts.end()) { + std::string idAddition(iter->second); + if (idAddition.find('v') != std::string::npos) { + id += "_vod_" + braveledger_bat_helper::split(idAddition, 'v')[1]; + } + } + + return id; + } + } + } + + return std::string(); +} + +// static +std::string MediaTwitch::GetMediaURL(const std::string& media_id) { + std::string res; + + DCHECK(!media_id.empty()); + return "https://www.twitch.tv/" + media_id; +} + +// static +std::string MediaTwitch::GetTwitchStatus( + const ledger::TwitchEventInfo& old_event, + const ledger::TwitchEventInfo& new_event) { + std::string status = "playing"; + + if ( + ( + new_event.event_ == "video_pause" && + old_event.event_ != "video_pause") || + // User clicked pause (we need to exclude seeking while paused) + ( + new_event.event_ == "video_pause" && + old_event.event_ == "video_pause" && + old_event.status_ == "playing") || + // User clicked pause as soon as he clicked play + ( + new_event.event_ == "player_click_vod_seek" && + old_event.status_ == "paused") + // Seeking a video while it is paused + ) { + status = "paused"; + } + + // User pauses a video, then seeks it and plays it again + if (new_event.event_ == "video_pause" && + old_event.event_ == "player_click_vod_seek" && + old_event.status_ == "paused") { + status = "playing"; + } + + return status; +} + +// static +uint64_t MediaTwitch::GetTwitchDuration( + const ledger::TwitchEventInfo& old_event, + const ledger::TwitchEventInfo& new_event) { + // Remove duplicated events + if (old_event.event_ == new_event.event_ && + old_event.time_ == new_event.time_) { + return 0; + } + + // Start event + if (new_event.event_ == "video-play") { + return TWITCH_MINIMUM_SECONDS; + } + + double time = 0; + std::stringstream tempTime(new_event.time_); + double currentTime = 0; + tempTime >> currentTime; + std::stringstream tempOld(old_event.time_); + double oldTime = 0; + tempOld >> oldTime; + + if (old_event.event_ == "video-play") { + time = currentTime - oldTime - TWITCH_MINIMUM_SECONDS; + } else if (new_event.event_ == "minute-watched" || // Minute watched + new_event.event_ == "buffer-empty" || // Run out of buffer + new_event.event_ == "video_error" || // Video has some problems + new_event.event_ == "video_end" || // Video ended + (new_event.event_ == "player_click_vod_seek" && + old_event.status_ == "paused") || // Vod seek + ( + new_event.event_ == "video_pause" && + ( + ( + old_event.event_ != "video_pause" && + old_event.event_ != "player_click_vod_seek") || + old_event.status_ == "playing") + ) // User paused video + ) { + time = currentTime - oldTime; + } + + if (time < 0) { + return 0; + } + + // if autoplay is off and play is pressed + if (old_event.status_.empty()) { + return 0; + } + + if (time > TWITCH_MAXIMUM_SECONDS_CHUNK) { + time = TWITCH_MAXIMUM_SECONDS_CHUNK; + } + + return static_cast(std::round(time)); +} + +void MediaTwitch::ProcessMedia(const std::map& parts, + const ledger::VisitData& visit_data) { + std::string media_id = GetMediaIdFromParts(parts); + if (media_id.empty()) { + return; + } + + std::string media_key = braveledger_media::GetMediaKey(media_id, + TWITCH_MEDIA_TYPE); + BLOG(ledger_, ledger::LogLevel::LOG_DEBUG) << "Media key: " << media_key; + + ledger::TwitchEventInfo twitch_info; + std::map::const_iterator iter = parts.find("event"); + if (iter != parts.end()) { + twitch_info.event_ = iter->second; + } + + iter = parts.find("time"); + if (iter != parts.end()) { + twitch_info.time_ = iter->second; + } + + ledger_->GetMediaPublisherInfo(media_key, + std::bind(&MediaTwitch::OnMediaPublisherInfo, + this, + media_id, + media_key, + twitch_info, + visit_data, + 0, + _1, + _2)); +} + +void MediaTwitch::OnMediaPublisherInfo( + const std::string& media_id, + const std::string& media_key, + const ledger::TwitchEventInfo& twitch_info, + const ledger::VisitData& visit_data, + const uint64_t window_id, + ledger::Result result, + std::unique_ptr publisher_info) { + if (result != ledger::Result::LEDGER_OK && + result != ledger::Result::NOT_FOUND) { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) + << "Failed to get publisher info"; + return; + } + + if (!publisher_info && !publisher_info.get()) { + if (media_id.empty()) { + return; + } + + ledger::TwitchEventInfo old_event; + std::map::const_iterator iter = + twitch_events.find(media_key); + if (iter != twitch_events.end()) { + old_event = iter->second; + } + + ledger::TwitchEventInfo new_event(twitch_info); + new_event.status_ = GetTwitchStatus(old_event, new_event); + + uint64_t real_duration = GetTwitchDuration(old_event, new_event); + twitch_events[media_key] = new_event; + + if (real_duration == 0) { + return; + } + + ledger::VisitData updated_visit_data(visit_data); + updated_visit_data.favicon_url = ""; + updated_visit_data.provider = TWITCH_MEDIA_TYPE; + + + + if (media_id.find("_vod_") != std::string::npos) { + // VOD + std::vector media_props = + braveledger_bat_helper::split(media_id, MEDIA_DELIMITER); + if (media_props.empty()) { + return; + } + + std::string new_id = media_props[0]; + std::string media_url = GetMediaURL(new_id); + std::string oembed_url = + (std::string)TWITCH_VOD_URL + media_props[media_props.size() - 1]; + updated_visit_data.name = new_id; + updated_visit_data.url = media_url + "/videos"; + + auto callback = std::bind( + &MediaTwitch::OnEmbedResponse, + this, + real_duration, + media_key, + media_url, + updated_visit_data, + window_id, + _1, + _2, + _3); + + const std::string url = (std::string)TWITCH_PROVIDER_URL + "?json&url=" + + ledger_->URIEncode(oembed_url); + + FetchDataFromUrl(url, callback); + return; + } + + // Live stream + std::string id = (std::string)TWITCH_MEDIA_TYPE + "#author:" + media_id; + updated_visit_data.name = media_id; + updated_visit_data.url = GetMediaURL(media_id) + "/videos"; + + ledger_->SaveMediaVisit(id, updated_visit_data, real_duration, window_id); + ledger_->SetMediaPublisherInfo(media_key, id); + } else { + ledger::VisitData updated_visit_data(visit_data); + updated_visit_data.name = publisher_info->name; + updated_visit_data.url = publisher_info->url; + updated_visit_data.provider = TWITCH_MEDIA_TYPE; + updated_visit_data.favicon_url = publisher_info->favicon_url; + + ledger::TwitchEventInfo old_event; + std::map::const_iterator iter = + twitch_events.find(media_key); + if (iter != twitch_events.end()) { + old_event = iter->second; + } + + ledger::TwitchEventInfo new_event(twitch_info); + new_event.status_ = GetTwitchStatus(old_event, new_event); + + uint64_t real_duration = GetTwitchDuration(old_event, new_event); + twitch_events[media_key] = new_event; + + std::string id = publisher_info->id; + ledger_->SaveMediaVisit(id, updated_visit_data, real_duration, window_id); + } +} + +void MediaTwitch::FetchDataFromUrl( + const std::string& url, + braveledger_media::FetchDataFromUrlCallback callback) { + ledger_->LoadURL(url, + std::vector(), + std::string(), + std::string(), + ledger::URL_METHOD::GET, + callback); +} + +void MediaTwitch::OnEmbedResponse( + const uint64_t duration, + const std::string& media_key, + const std::string& media_url, + const ledger::VisitData& visit_data, + const uint64_t window_id, + int response_status_code, + const std::string& response, + const std::map& headers) { + ledger_->LogResponse(__func__, response_status_code, response, headers); + + if (response_status_code != 200) { + // TODO(anyone): add error handler + return; + } + + std::string fav_icon; + braveledger_bat_helper::getJSONValue("author_thumbnail_url", + response, + &fav_icon); + std::string author_name; + braveledger_bat_helper::getJSONValue("author_name", response, &author_name); + + std::string twitchMediaID = visit_data.name; + std::string id = (std::string)TWITCH_MEDIA_TYPE + "#author:" + twitchMediaID; + + ledger::VisitData updated_visit_data(visit_data); + updated_visit_data.name = author_name; + + if (fav_icon.length() > 0) { + updated_visit_data.favicon_url = fav_icon; + } + + ledger_->SaveMediaVisit(id, updated_visit_data, duration, window_id); + ledger_->SetMediaPublisherInfo(media_key, id); +} } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h index 0014b5a2aa16..10e857490673 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h @@ -6,7 +6,11 @@ #ifndef BRAVELEDGER_MEDIA_TWITCH_H_ #define BRAVELEDGER_MEDIA_TWITCH_H_ +#include +#include + #include "bat/ledger/ledger.h" +#include "bat/ledger/internal/media/helper.h" namespace bat_ledger { class LedgerImpl; @@ -20,8 +24,48 @@ class MediaTwitch : public ledger::LedgerCallbackHandler { ~MediaTwitch() override; + void ProcessMedia(const std::map& parts, + const ledger::VisitData& visit_data); + private: + static std::string GetMediaIdFromParts( + const std::map& parts); + + static std::string GetMediaURL(const std::string& mediaId); + + static std::string GetTwitchStatus( + const ledger::TwitchEventInfo& old_event, + const ledger::TwitchEventInfo& new_event); + + static uint64_t GetTwitchDuration( + const ledger::TwitchEventInfo& old_event, + const ledger::TwitchEventInfo& new_event); + + void OnMediaPublisherInfo( + const std::string& media_id, + const std::string& media_key, + const ledger::TwitchEventInfo& twitch_info, + const ledger::VisitData& visit_data, + const uint64_t window_id, + ledger::Result result, + std::unique_ptr publisher_info); + + void FetchDataFromUrl( + const std::string& url, + braveledger_media::FetchDataFromUrlCallback callback); + + void OnEmbedResponse( + const uint64_t duration, + const std::string& media_key, + const std::string& media_url, + const ledger::VisitData& visit_data, + const uint64_t window_id, + int response_status_code, + const std::string& response, + const std::map& headers); + bat_ledger::LedgerImpl* ledger_; // NOT OWNED + std::map twitch_events; }; } // namespace braveledger_media From 57a7fb359d62d0345290465da90d5df949dfc160 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Wed, 10 Apr 2019 19:02:54 +0200 Subject: [PATCH 04/12] Moves GetLinkType --- .../src/bat/ledger/internal/bat_get_media.cc | 25 +++++-------------- .../src/bat/ledger/internal/media/twitch.cc | 21 ++++++++++++++++ .../src/bat/ledger/internal/media/twitch.h | 4 +++ .../src/bat/ledger/internal/media/youtube.cc | 15 +++++++++++ .../src/bat/ledger/internal/media/youtube.h | 2 ++ 5 files changed, 48 insertions(+), 19 deletions(-) diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc index cb181c6cc392..3525778b9f29 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc @@ -35,25 +35,12 @@ std::string BatGetMedia::GetLinkType(const std::string& url, const std::string& referrer) { std::string type; - const std::string mobile_api = "https://m.youtube.com/api/stats/watchtime?"; - const std::string desktop_api = - "https://www.youtube.com/api/stats/watchtime?"; - - bool is_valid_twitch_path = - braveledger_bat_helper::HasSameDomainAndPath( - url, "ttvnw.net", "/v1/segment/"); - - if (url.find(mobile_api) != std::string::npos || - url.find(desktop_api) != std::string::npos) { - type = YOUTUBE_MEDIA_TYPE; - } else if ( - ( - (first_party_url.find("https://www.twitch.tv/") == 0 || - first_party_url.find("https://m.twitch.tv/") == 0) || - (referrer.find("https://player.twitch.tv/") == 0)) && - is_valid_twitch_path - ) { - type = TWITCH_MEDIA_TYPE; + type = braveledger_media::MediaYouTube::GetLinkType(url); + + if (type.empty()) { + type = braveledger_media::MediaTwitch::GetLinkType(url, + first_party_url, + referrer); } return type; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc index c7890c6ed300..70b48f401b73 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc @@ -164,6 +164,27 @@ uint64_t MediaTwitch::GetTwitchDuration( return static_cast(std::round(time)); } +// static +std::string MediaTwitch::GetLinkType(const std::string& url, + const std::string& first_party_url, + const std::string& referrer) { + std::string type; + bool is_valid_twitch_path = + braveledger_bat_helper::HasSameDomainAndPath( + url, "ttvnw.net", "/v1/segment/"); + if ( + ( + (first_party_url.find("https://www.twitch.tv/") == 0 || + first_party_url.find("https://m.twitch.tv/") == 0) || + (referrer.find("https://player.twitch.tv/") == 0)) && + is_valid_twitch_path + ) { + type = TWITCH_MEDIA_TYPE; + } + + return type; +} + void MediaTwitch::ProcessMedia(const std::map& parts, const ledger::VisitData& visit_data) { std::string media_id = GetMediaIdFromParts(parts); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h index 10e857490673..4cbd6355b065 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h @@ -27,6 +27,10 @@ class MediaTwitch : public ledger::LedgerCallbackHandler { void ProcessMedia(const std::map& parts, const ledger::VisitData& visit_data); + static std::string GetLinkType(const std::string& url, + const std::string& first_party_url, + const std::string& referrer); + private: static std::string GetMediaIdFromParts( const std::map& parts); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc index 7b0dfd902f53..651c54e3c5a2 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc @@ -144,6 +144,21 @@ std::string MediaYouTube::GetPublisherName(const std::string& data) { return publisher_name; } +// static +std::string MediaYouTube::GetLinkType(const std::string& url) { + const std::string mobile_api = "https://m.youtube.com/api/stats/watchtime?"; + const std::string desktop_api = + "https://www.youtube.com/api/stats/watchtime?"; + std::string type; + + if (url.find(mobile_api) != std::string::npos || + url.find(desktop_api) != std::string::npos) { + type = YOUTUBE_MEDIA_TYPE; + } + + return type; +} + void MediaYouTube::OnMediaActivityError(const ledger::VisitData& visit_data, uint64_t window_id) { std::string url = YOUTUBE_TLD; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h index ed94985c0201..5ee9874a4266 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h @@ -27,6 +27,8 @@ class MediaYouTube : public ledger::LedgerCallbackHandler { void ProcessMedia(const std::map& parts, const ledger::VisitData& visit_data); + static std::string GetLinkType(const std::string& url); + private: static std::string GetMediaIdFromParts( From dbe7f0c12d7ea6cf58d7ed4b4a55f9881547cb85 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Wed, 10 Apr 2019 21:02:13 +0200 Subject: [PATCH 05/12] YouTube MediaActivity --- .../src/bat/ledger/internal/bat_get_media.cc | 31 +- .../src/bat/ledger/internal/bat_get_media.h | 2 +- .../src/bat/ledger/internal/ledger_impl.cc | 6 +- .../src/bat/ledger/internal/media/youtube.cc | 411 +++++++++++++++++- .../src/bat/ledger/internal/media/youtube.h | 69 +++ 5 files changed, 498 insertions(+), 21 deletions(-) diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc index 3525778b9f29..c3962deba6e5 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc @@ -64,6 +64,21 @@ void BatGetMedia::processMedia(const std::map& parts, } } +void BatGetMedia::GetMediaActivityFromUrl( + uint64_t windowId, + const ledger::VisitData& visit_data, + const std::string& providerType, + const std::string& publisher_blob) { + if (providerType == YOUTUBE_MEDIA_TYPE) { + media_youtube_->ProcessActivityFromUrl(windowId, visit_data); + } else if (providerType == TWITCH_MEDIA_TYPE) { + // TODO one left + processTwitchMediaPanel(windowId, visit_data, providerType, publisher_blob); + } else { + onMediaActivityError(visit_data, providerType, windowId); + } +} + void BatGetMedia::getPublisherInfoDataCallback(const std::string& mediaId, const std::string& media_key, const std::string& providerName, @@ -517,19 +532,7 @@ void BatGetMedia::onMediaActivityError(const ledger::VisitData& visit_data, } } -void BatGetMedia::getMediaActivityFromUrl( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& publisher_blob) { - if (providerType == YOUTUBE_MEDIA_TYPE) { - processYoutubeMediaPanel(windowId, visit_data, providerType); - } else if (providerType == TWITCH_MEDIA_TYPE) { - processTwitchMediaPanel(windowId, visit_data, providerType, publisher_blob); - } else { - onMediaActivityError(visit_data, providerType, windowId); - } -} + void BatGetMedia::processYoutubeMediaPanel(uint64_t windowId, const ledger::VisitData& visit_data, @@ -803,7 +806,7 @@ void BatGetMedia::onGetChannelIdFromUserPage( new_data.name = ""; new_data.favicon_url = ""; - getMediaActivityFromUrl(windowId, new_data, providerType, std::string()); + GetMediaActivityFromUrl(windowId, new_data, providerType, std::string()); } else { onMediaActivityError(visit_data, providerType, windowId); } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h index 3b957493aa8b..85202c3922a0 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h @@ -51,7 +51,7 @@ class BatGetMedia { const std::string& type, const ledger::VisitData& visit_data); - void getMediaActivityFromUrl(uint64_t windowId, + void GetMediaActivityFromUrl(uint64_t windowId, const ledger::VisitData& visit_data, const std::string& providerType, const std::string& publisher_blob); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc index 995602b3c907..bd621844dff6 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc @@ -998,8 +998,10 @@ void LedgerImpl::GetMediaActivityFromUrl( const ledger::VisitData& visit_data, const std::string& providerType, const std::string& publisher_blob) { - bat_get_media_->getMediaActivityFromUrl( - windowId, visit_data, providerType, publisher_blob); + bat_get_media_->GetMediaActivityFromUrl(windowId, + visit_data, + providerType, + publisher_blob); } void LedgerImpl::OnPanelPublisherInfo( diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc index 651c54e3c5a2..b9d4ad96d908 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc @@ -5,6 +5,7 @@ #include #include +#include #include "bat/ledger/internal/ledger_impl.h" #include "bat/ledger/internal/media/helper.h" @@ -159,6 +160,144 @@ std::string MediaYouTube::GetLinkType(const std::string& url) { return type; } +// static +std::string MediaYouTube::GetMediaIdFromUrl( + const ledger::VisitData& visit_data) { + std::vector first_split = + braveledger_bat_helper::split(visit_data.url, '?'); + + if (first_split.size() < 2) { + return std::string(); + } + + std::vector and_split = + braveledger_bat_helper::split(first_split[1], '&'); + + for (const auto& item : and_split) { + std::vector m_url = braveledger_bat_helper::split(item, '='); + + if (m_url.size() < 2) { + continue; + } + + if (m_url[0] == "v") { + return m_url[1]; + } + } + + return std::string(); +} + +// static +std::string MediaYouTube::GetNameFromChannel(const std::string& data) { + std::string publisher_name; + const std::string publisher_json_name = braveledger_media::ExtractData(data, + "channelMetadataRenderer\":{\"title\":\"", "\""); + const std::string publisher_json = "{\"brave_publisher\":\"" + + publisher_json_name + "\"}"; + // scraped data could come in with JSON code points added. + // Make to JSON object above so we can decode. + braveledger_bat_helper::getJSONValue( + "brave_publisher", publisher_json, &publisher_name); + return publisher_name; +} + +// static +// before getYoutubePublisherKeyFromUrl +std::string MediaYouTube::GetPublisherKeyFromUrl( + const std::string& path) { + if (path.empty()) { + return std::string(); + } + + const std::string id = braveledger_media::ExtractData(path + "/", + "/channel/", "/"); + + if (id.empty()) { + return std::string(); + } + + std::vector params = braveledger_bat_helper::split(id, '?'); + + return params[0]; +} + +// static +std::string MediaYouTube::GetChannelIdFromCustomPathPage( + const std::string& data) { + return braveledger_media::ExtractData(data, + "{\"key\":\"browse_id\",\"value\":\"", "\""); +} + +// static +std::string MediaYouTube::GetBasicPath(const std::string& path) { + std::string yt_path = path.substr(0, path.find("/", 1)); + if (yt_path.empty() || yt_path == path) { + yt_path = path.substr(0, path.find("?", 1)); + if (yt_path.empty() || yt_path == path) { + yt_path = path.substr(0); + } + } + return yt_path; +} + +// static +bool MediaYouTube::IsPredefinedPath(const std::string& path) { + std::vector paths({ + "/feed", + "/channel", + "/user", + "/watch", + "/account", + "/gaming", + "/playlist", + "/premium", + "/reporthistory", + "/pair", + "/account_notifications", + "/account_playback", + "/account_privacy", + "/account_sharing", + "/account_billing", + "/account_advanced", + "/subscription_manager", + "/oops" + }); + + // make sure we are ignoring actual YT paths and not + // a custom path that might start with a YT path + const std::string clean_path = GetBasicPath(path); + for (std::string str_path : paths) { + if (clean_path == str_path) { + return true; + } + } + return false; +} + +// static +std::string MediaYouTube::GetPublisherKey(const std::string& key) { + return (std::string)YOUTUBE_MEDIA_TYPE + "#channel:" + key; +} + +// static +std::string MediaYouTube::GetUserFromUrl(const std::string& path) { + if (path.empty()) { + return std::string(); + } + + const std::string id = braveledger_media::ExtractData(path + "/", + "/user/", "/"); + + if (id.empty()) { + return std::string(); + } + + std::vector params = braveledger_bat_helper::split(id, '?'); + + return params[0]; +} + void MediaYouTube::OnMediaActivityError(const ledger::VisitData& visit_data, uint64_t window_id) { std::string url = YOUTUBE_TLD; @@ -207,6 +346,37 @@ void MediaYouTube::ProcessMedia(const std::map& parts, _2)); } +void MediaYouTube::ProcessActivityFromUrl(uint64_t window_id, + const ledger::VisitData& visit_data) { + if (visit_data.path.find("/watch?") != std::string::npos) { + WatchPath(window_id, visit_data); + return; + } + + if (visit_data.path.find("/channel/") != std::string::npos) { + ChannelPath(window_id, visit_data); + return; + } + + if (visit_data.path.find("/user/") != std::string::npos) { + UserPath(window_id, visit_data); + return; + } + + if (!IsPredefinedPath(visit_data.path)) { + OnPublisherPanleInfo(window_id, + visit_data, + std::string(), + true, + ledger::Result::NOT_FOUND, + nullptr); + return; + } + + OnMediaActivityError(visit_data, window_id); +} + +// before getPublisherInfoDataCallback void MediaYouTube::OnMediaPublisherInfo( const std::string& media_id, const std::string& media_key, @@ -236,7 +406,8 @@ void MediaYouTube::OnMediaPublisherInfo( _2, _3); - const std::string url = (std::string)YOUTUBE_PROVIDER_URL + "?format=json&url=" + + const std::string url = (std::string)YOUTUBE_PROVIDER_URL + + "?format=json&url=" + ledger_->URIEncode(media_url); FetchDataFromUrl(url, callback); @@ -349,16 +520,15 @@ void MediaYouTube::SavePublisherInfo(const uint64_t duration, const uint64_t window_id, const std::string& fav_icon, const std::string& channel_id) { - std::string publisher_id; + std::string url; - publisher_id = (std::string)YOUTUBE_MEDIA_TYPE + "#channel:"; if (channel_id.empty()) { BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << "Channel id is missing for: " << media_key; return; } - publisher_id += channel_id; + std::string publisher_id = GetPublisherKey(channel_id); url = publisher_url + "/videos"; if (publisher_id.empty()) { @@ -397,5 +567,238 @@ void MediaYouTube::FetchDataFromUrl( callback); } +void MediaYouTube::WatchPath(uint64_t window_id, + const ledger::VisitData& visit_data) { + std::string media_id = GetMediaIdFromUrl(visit_data); + std::string media_key = braveledger_media::GetMediaKey(media_id, + YOUTUBE_MEDIA_TYPE); + + if (!media_key.empty() || !media_id.empty()) { + ledger_->GetMediaPublisherInfo( + media_key, + std::bind(&MediaYouTube::OnMediaPublisherActivity, + this, + _1, + _2, + window_id, + visit_data, + media_key, + media_id)); + } else { + OnMediaActivityError(visit_data, window_id); + } +} + +void MediaYouTube::OnMediaPublisherActivity( + ledger::Result result, + std::unique_ptr info, + uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& media_key, + const std::string& media_id) { + if (result != ledger::Result::LEDGER_OK && + result != ledger::Result::NOT_FOUND) { + OnMediaActivityError(visit_data, window_id); + return; + } + + if (!info || result == ledger::Result::NOT_FOUND) { + OnMediaPublisherInfo(media_id, + media_key, + 0, + visit_data, + window_id, + result, + std::move(info)); + } else { + GetPublisherPanleInfo(window_id, + visit_data, + info->id, + false); + } +} + +// before fetchPublisherDataFromDB +void MediaYouTube::GetPublisherPanleInfo( + uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& publisher_key, + bool is_custom_path) { + auto filter = ledger_->CreateActivityFilter( + publisher_key, + ledger::EXCLUDE_FILTER::FILTER_ALL, + false, + ledger_->GetReconcileStamp(), + true, + false); + ledger_->GetPanelPublisherInfo(filter, + std::bind(&MediaYouTube::OnPublisherPanleInfo, + this, + window_id, + visit_data, + publisher_key, + is_custom_path, + _1, + _2)); +} + +// before onFetchPublisherFromDBResponse +// TODO(nejczdovc): better name as we use it for custom page as well +void MediaYouTube::OnPublisherPanleInfo( + uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& publisher_key, + bool is_custom_path, + ledger::Result result, + std::unique_ptr info) { + if (!info || result == ledger::Result::NOT_FOUND) { + FetchDataFromUrl(visit_data.url, + std::bind(&MediaYouTube::GetChannelHeadlineVideo, + this, + window_id, + visit_data, + is_custom_path, + _1, + _2, + _3)); + } else { + ledger_->OnPanelPublisherInfo(result, std::move(info), window_id); + } +} + +// TODO(nejczdovc): better to understand if name can be better +void MediaYouTube::GetChannelHeadlineVideo( + uint64_t window_id, + const ledger::VisitData& visit_data, + bool is_custom_path, + int response_status_code, + const std::string& response, + const std::map& headers) { + if (response_status_code != 200) { + OnMediaActivityError(visit_data, window_id); + return; + } + + if (visit_data.path.find("/channel/") != std::string::npos) { + std::string title = GetNameFromChannel(response); + std::string favicon = GetFavIconUrl(response); + std::string channel_id = GetPublisherKeyFromUrl(visit_data.path); + + SavePublisherInfo(0, + std::string(), + visit_data.url, + title, + visit_data, + window_id, + favicon, + channel_id); + + } else if (is_custom_path) { + std::string title = GetNameFromChannel(response); + std::string favicon = GetFavIconUrl(response); + std::string channel_id = GetChannelIdFromCustomPathPage(response); + ledger::VisitData new_visit_data(visit_data); + new_visit_data.path = "/channel/" + channel_id; + GetPublisherPanleInfo(window_id, + new_visit_data, + GetPublisherKey(channel_id), + true); + } else { + OnMediaActivityError(visit_data, window_id); + } +} + +void MediaYouTube::ChannelPath(uint64_t window_id, + const ledger::VisitData& visit_data) { + std::string key = GetPublisherKeyFromUrl(visit_data.path); + if (!key.empty()) { + std::string publisher_key = GetPublisherKey(key); + GetPublisherPanleInfo(window_id, + visit_data, + publisher_key, + false); + } else { + OnMediaActivityError(visit_data, window_id); + } +} + +void MediaYouTube::UserPath(uint64_t window_id, + const ledger::VisitData& visit_data) { + std::string user = GetUserFromUrl(visit_data.path); + + if (user.empty()) { + OnMediaActivityError(visit_data, window_id); + return; + } + + std::string media_key = (std::string)YOUTUBE_MEDIA_TYPE + "_user_" + user; + ledger_->GetMediaPublisherInfo(media_key, + std::bind(&MediaYouTube::OnUserActivity, + this, + window_id, + visit_data, + media_key, + _1, + _2)); +} + +void MediaYouTube::OnUserActivity( + uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& media_key, + ledger::Result result, + std::unique_ptr info) { + if (result != ledger::Result::LEDGER_OK && + result != ledger::Result::NOT_FOUND) { + OnMediaActivityError(visit_data, window_id); + return; + } + + if (!info || result == ledger::Result::NOT_FOUND) { + FetchDataFromUrl(visit_data.url, + std::bind(&MediaYouTube::OnChannelIdForUser, + this, + window_id, + visit_data, + media_key, + _1, + _2, + _3)); + + } else { + GetPublisherPanleInfo(window_id, + visit_data, + info->id, + false); + } +} + +void MediaYouTube::OnChannelIdForUser( + uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& media_key, + int response_status_code, + const std::string& response, + const std::map& headers) { + std::string channelId = GetChannelId(response); + if (!channelId.empty()) { + std::string path = "/channel/" + channelId; + std::string url = GetChannelUrl(channelId); + std::string publisher_key = GetPublisherKey(channelId); + + ledger_->SetMediaPublisherInfo(media_key, publisher_key); + + ledger::VisitData new_data(visit_data); + new_data.path = path; + new_data.url = url; + new_data.name = ""; + new_data.favicon_url = ""; + + ProcessActivityFromUrl(window_id, new_data); + } else { + OnMediaActivityError(visit_data, window_id); + } +} + } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h index 5ee9874a4266..43b78008ac60 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h @@ -29,6 +29,9 @@ class MediaYouTube : public ledger::LedgerCallbackHandler { static std::string GetLinkType(const std::string& url); + void ProcessActivityFromUrl(uint64_t window_id, + const ledger::VisitData& visit_data); + private: static std::string GetMediaIdFromParts( @@ -48,6 +51,22 @@ class MediaYouTube : public ledger::LedgerCallbackHandler { static std::string GetPublisherName(const std::string& data); + static std::string GetMediaIdFromUrl(const ledger::VisitData& visit_data); + + static std::string GetNameFromChannel(const std::string& data); + + std::string GetPublisherKeyFromUrl(const std::string& path); + + static std::string GetChannelIdFromCustomPathPage(const std::string& data); + + static std::string GetBasicPath(const std::string& path); + + static bool IsPredefinedPath(const std::string& path); + + static std::string GetPublisherKey(const std::string& key); + + static std::string GetUserFromUrl(const std::string& path); + void OnMediaActivityError(const ledger::VisitData& visit_data, uint64_t window_id); @@ -93,6 +112,56 @@ class MediaYouTube : public ledger::LedgerCallbackHandler { void FetchDataFromUrl(const std::string& url, braveledger_media::FetchDataFromUrlCallback callback); + void WatchPath(uint64_t window_id, + const ledger::VisitData& visit_data); + + void OnMediaPublisherActivity(ledger::Result result, + std::unique_ptr info, + uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& media_key, + const std::string& media_id); + + void GetPublisherPanleInfo(uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& publisher_key, + bool is_custom_path); + + void OnPublisherPanleInfo(uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& publisher_key, + bool is_custom_path, + ledger::Result result, + std::unique_ptr info); + + void GetChannelHeadlineVideo( + uint64_t window_id, + const ledger::VisitData& visit_data, + bool is_custom_path, + int response_status_code, + const std::string& response, + const std::map& headers); + + void ChannelPath(uint64_t window_id, + const ledger::VisitData& visit_data); + + void UserPath(uint64_t windowId, + const ledger::VisitData& visit_data); + + void OnUserActivity(uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& media_key, + ledger::Result result, + std::unique_ptr info); + + void OnChannelIdForUser( + uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& media_key, + int response_status_code, + const std::string& response, + const std::map& headers); + bat_ledger::LedgerImpl* ledger_; // NOT OWNED }; From 2ffbb7e8ef95f762d96b54b102b767f9fbb7747b Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Thu, 11 Apr 2019 11:49:48 +0200 Subject: [PATCH 06/12] Twitch MediaActivity --- .../src/bat/ledger/internal/media/twitch.cc | 266 +++++++++++++++++- .../src/bat/ledger/internal/media/twitch.h | 51 ++++ .../src/bat/ledger/internal/media/youtube.cc | 1 - 3 files changed, 314 insertions(+), 4 deletions(-) diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc index 70b48f401b73..a957a91625d3 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc @@ -3,6 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include #include #include @@ -185,6 +186,97 @@ std::string MediaTwitch::GetLinkType(const std::string& url, return type; } +// static +std::string MediaTwitch::GetMediaIdFromUrl( + const std::string& url, + const std::string& publisher_blob) { + std::string mediaId = braveledger_media::ExtractData(url, "twitch.tv/", "/"); + if (url.find("twitch.tv/videos/") != std::string::npos) { + mediaId = braveledger_media::ExtractData(publisher_blob, + "" + "
" + "\""," + "
" + "\""GetPublisherActivityFromUrl(window_id, new_data, std::string()); + } else { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) + << "Media activity error for " + << TWITCH_MEDIA_TYPE << " (name: " + << name << ", url: " + << visit_data.url << ")"; + } +} + void MediaTwitch::ProcessMedia(const std::map& parts, const ledger::VisitData& visit_data) { std::string media_id = GetMediaIdFromParts(parts); @@ -219,6 +311,41 @@ void MediaTwitch::ProcessMedia(const std::map& parts, _2)); } +void MediaTwitch::ProcessActivityFromUrl(uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& publisher_blob) { + if (!publisher_blob.empty()) { + std::string media_id = GetMediaIdFromUrl(visit_data.url, + publisher_blob); + std::transform(media_id.begin(), + media_id.end(), + media_id.begin(), + ::tolower); + std::string media_key = GetMediaKeyFromUrl(media_id, visit_data.url); + if (!media_key.empty() && !media_id.empty()) { + ledger_->GetMediaPublisherInfo( + media_key, + std::bind(&MediaTwitch::OnMediaPublisherActivity, + this, + window_id, + visit_data, + media_key, + media_id, + publisher_blob, + _1, + _2)); + } else { + OnMediaActivityError(visit_data, window_id); + } + } else { + ledger::VisitData new_visit_data(visit_data); + new_visit_data.path = std::string(); + ledger_->GetPublisherActivityFromUrl(window_id, + new_visit_data, + std::string()); + } +} + void MediaTwitch::OnMediaPublisherInfo( const std::string& media_id, const std::string& media_key, @@ -297,12 +424,15 @@ void MediaTwitch::OnMediaPublisherInfo( } // Live stream - std::string id = (std::string)TWITCH_MEDIA_TYPE + "#author:" + media_id; + std::string publisher_key = GetPublisherKey(media_id); updated_visit_data.name = media_id; updated_visit_data.url = GetMediaURL(media_id) + "/videos"; - ledger_->SaveMediaVisit(id, updated_visit_data, real_duration, window_id); - ledger_->SetMediaPublisherInfo(media_key, id); + ledger_->SaveMediaVisit(publisher_key, + updated_visit_data, + real_duration, + window_id); + ledger_->SetMediaPublisherInfo(media_key, publisher_key); } else { ledger::VisitData updated_visit_data(visit_data); updated_visit_data.name = publisher_info->name; @@ -376,4 +506,134 @@ void MediaTwitch::OnEmbedResponse( ledger_->SetMediaPublisherInfo(media_key, id); } +void MediaTwitch::OnMediaPublisherActivity( + uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& media_key, + const std::string& media_id, + const std::string& publisher_blob, + ledger::Result result, + std::unique_ptr info) { + if (result != ledger::Result::LEDGER_OK && + result != ledger::Result::NOT_FOUND) { + OnMediaActivityError(visit_data, window_id); + return; + } + + if (!info || result == ledger::Result::NOT_FOUND) { + // first see if we have the publisher a different way (VOD vs. live stream + ledger_->GetPublisherInfo( + GetPublisherKey(media_id), + std::bind(&MediaTwitch::OnPublisherInfo, + this, + window_id, + visit_data, + media_key, + media_id, + publisher_blob, + _1, + _2)); + } else { + if (info->verified && info->favicon_url.empty()) { + std::string publisher_name; + std::string publisher_favicon_url; + UpdatePublisherData(&publisher_name, + &publisher_favicon_url, + publisher_blob); + + if (!publisher_favicon_url.empty()) { + SavePublisherInfo(0, + media_key, + visit_data.url, + publisher_name, + visit_data, + window_id, + publisher_favicon_url, + media_id); + return; + } + } + + ledger_->OnPanelPublisherInfo(result, std::move(info), window_id); + } +} + +void MediaTwitch::OnPublisherInfo( + uint64_t window_id, + const ledger::VisitData visit_data, + const std::string& media_key, + const std::string& media_id, + const std::string& publisher_blob, + ledger::Result result, + std::unique_ptr publisher_info) { + if (result != ledger::Result::LEDGER_OK && + result != ledger::Result::NOT_FOUND) { + OnMediaActivityError(visit_data, window_id); + return; + } + + if (!publisher_info || result == ledger::Result::NOT_FOUND) { + std::string publisher_name; + std::string publisher_favicon_url; + UpdatePublisherData(&publisher_name, + &publisher_favicon_url, + publisher_blob); + + SavePublisherInfo(0, + media_key, + visit_data.url, + publisher_name, + visit_data, + window_id, + publisher_favicon_url, + media_id); + } else { + ledger_->OnPanelPublisherInfo(result, + std::move(publisher_info), + window_id); + } +} + +void MediaTwitch::SavePublisherInfo(const uint64_t duration, + const std::string& media_key, + const std::string& publisher_url, + const std::string& publisher_name, + const ledger::VisitData& visit_data, + const uint64_t window_id, + const std::string& fav_icon, + const std::string& channel_id) { + if (channel_id.empty()) { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << + "author id is missing for: " << media_key; + return; + } + + std::string publisher_id = GetPublisherKey(channel_id); + std::string url = publisher_url + "/videos"; + + if (publisher_id.empty()) { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << + "Publisher id is missing for: " << media_key; + return; + } + + ledger::VisitData updated_visit_data(visit_data); + + if (fav_icon.length() > 0) { + updated_visit_data.favicon_url = fav_icon; + } + + updated_visit_data.provider = TWITCH_MEDIA_TYPE; + updated_visit_data.name = publisher_name; + updated_visit_data.url = url; + + ledger_->SaveMediaVisit(publisher_id, + updated_visit_data, + duration, + window_id); + if (!media_key.empty()) { + ledger_->SetMediaPublisherInfo(media_key, publisher_id); + } +} + } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h index 4cbd6355b065..6a1508490455 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h @@ -24,9 +24,16 @@ class MediaTwitch : public ledger::LedgerCallbackHandler { ~MediaTwitch() override; + void OnMediaActivityError(const ledger::VisitData& visit_data, + uint64_t window_id); + void ProcessMedia(const std::map& parts, const ledger::VisitData& visit_data); + void ProcessActivityFromUrl(uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& publisher_blob); + static std::string GetLinkType(const std::string& url, const std::string& first_party_url, const std::string& referrer); @@ -45,6 +52,23 @@ class MediaTwitch : public ledger::LedgerCallbackHandler { const ledger::TwitchEventInfo& old_event, const ledger::TwitchEventInfo& new_event); + static std::string GetMediaIdFromUrl(const std::string& url, + const std::string& publisher_blob); + + static std::string GetMediaKeyFromUrl(const std::string& id, + const std::string& url); + + static std::string GetPublisherKey(const std::string& key); + + static void UpdatePublisherData(std::string* publisher_name, + std::string* publisher_favicon_url, + const std::string& publisher_blob); + + static std::string GetPublisherName(const std::string& publisher_blob); + + static std::string GetFaviconUrl(const std::string& publisher_blob, + const std::string& twitchHandle); + void OnMediaPublisherInfo( const std::string& media_id, const std::string& media_key, @@ -68,6 +92,33 @@ class MediaTwitch : public ledger::LedgerCallbackHandler { const std::string& response, const std::map& headers); + void OnMediaPublisherActivity( + uint64_t window_id, + const ledger::VisitData& visit_data, + const std::string& media_key, + const std::string& media_id, + const std::string& publisher_blob, + ledger::Result result, + std::unique_ptr info); + + void OnPublisherInfo( + uint64_t window_id, + const ledger::VisitData visit_data, + const std::string& media_key, + const std::string& media_id, + const std::string& publisher_blob, + ledger::Result result, + std::unique_ptr publisher_info); + + void SavePublisherInfo(const uint64_t duration, + const std::string& media_key, + const std::string& publisher_url, + const std::string& publisher_name, + const ledger::VisitData& visit_data, + const uint64_t window_id, + const std::string& fav_icon, + const std::string& channel_id); + bat_ledger::LedgerImpl* ledger_; // NOT OWNED std::map twitch_events; }; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc index b9d4ad96d908..b634516e6f81 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc @@ -520,7 +520,6 @@ void MediaYouTube::SavePublisherInfo(const uint64_t duration, const uint64_t window_id, const std::string& fav_icon, const std::string& channel_id) { - std::string url; if (channel_id.empty()) { BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << From 20755069e418890948a60887ca35d975d9c0244b Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Thu, 11 Apr 2019 12:50:09 +0200 Subject: [PATCH 07/12] Fixes tests --- test/BUILD.gn | 5 +- .../ledger/internal/media/helper_unittest.cc | 16 ++ .../ledger/internal/media/twitch_unittest.cc | 19 ++ .../src/bat/ledger/internal/media/youtube.h | 13 +- .../youtube_unittest.cc} | 170 +++++++----------- 5 files changed, 114 insertions(+), 109 deletions(-) create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc rename vendor/bat-native-ledger/src/bat/ledger/internal/{bat_get_media_unittest.cc => media/youtube_unittest.cc} (59%) diff --git a/test/BUILD.gn b/test/BUILD.gn index b13a36fec2b4..5d66c94608bd 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -103,8 +103,9 @@ test("brave_unit_tests") { if (brave_rewards_enabled) { sources += [ - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media_unittest.h", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper_unittest.h", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers_unittest.cc", diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc new file mode 100644 index 000000000000..8218314f4803 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc @@ -0,0 +1,16 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "bat/ledger/internal/media/helper.h" +#include "bat/ledger/ledger.h" +#include "testing/gtest/include/gtest/gtest.h" + +// npm run test -- brave_unit_tests --filter=MediaHelperTest.* + +namespace braveledger_media { + +// TODO add tests + +} // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc new file mode 100644 index 000000000000..c0b65a9f9a3d --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc @@ -0,0 +1,19 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "bat/ledger/internal/media/twitch.h" +#include "bat/ledger/ledger.h" +#include "testing/gtest/include/gtest/gtest.h" + +// npm run test -- brave_unit_tests --filter=MediaTwitchTest.* + +namespace braveledger_media { + +class MediaTwitchTest : public testing::Test { +}; + +// TODO add tests + +} // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h index 43b78008ac60..d526cb4b9757 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h @@ -9,6 +9,7 @@ #include #include +#include "base/gtest_prod_util.h" #include "bat/ledger/ledger.h" #include "bat/ledger/internal/media/helper.h" @@ -33,7 +34,6 @@ class MediaYouTube : public ledger::LedgerCallbackHandler { const ledger::VisitData& visit_data); private: - static std::string GetMediaIdFromParts( const std::map& parts); @@ -55,7 +55,7 @@ class MediaYouTube : public ledger::LedgerCallbackHandler { static std::string GetNameFromChannel(const std::string& data); - std::string GetPublisherKeyFromUrl(const std::string& path); + static std::string GetPublisherKeyFromUrl(const std::string& path); static std::string GetChannelIdFromCustomPathPage(const std::string& data); @@ -163,6 +163,15 @@ class MediaYouTube : public ledger::LedgerCallbackHandler { const std::map& headers); bat_ledger::LedgerImpl* ledger_; // NOT OWNED + + // For testing purposes + friend class MediaYouTubeTest; + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetMediaIdFromUrl); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetPublisherKeyFromUrl); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetUserFromUrl); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetBasicPath); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetNameFromChannel); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetPublisherName); }; } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube_unittest.cc similarity index 59% rename from vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media_unittest.cc rename to vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube_unittest.cc index f0593f2754b6..00cd49ba43d4 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media_unittest.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube_unittest.cc @@ -3,136 +3,117 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "bat/ledger/internal/bat_get_media.h" +#include "bat/ledger/internal/media/youtube.h" #include "bat/ledger/ledger.h" #include "testing/gtest/include/gtest/gtest.h" -// npm run test -- brave_unit_tests --filter=BatGetMediaTest.* +// npm run test -- brave_unit_tests --filter=MediaYouTubeTest.* -namespace braveledger_bat_get_media { +namespace braveledger_media { -class BatGetMediaTest : public testing::Test { +class MediaYouTubeTest : public testing::Test { }; -TEST(BatGetMediaTest, GetYoutubeMediaIdFromUrl) { +TEST(MediaYouTubeTest, GetMediaIdFromUrl) { // missing video id ledger::VisitData data; data.url = "https://www.youtube.com/watch"; std::string media = - braveledger_bat_get_media::BatGetMedia::getYoutubeMediaIdFromUrl(data); - + braveledger_media::MediaYouTube::GetMediaIdFromUrl(data); ASSERT_EQ(media, ""); // single element in the url data.url = "https://www.youtube.com/watch?v=44444444"; media = - braveledger_bat_get_media::BatGetMedia::getYoutubeMediaIdFromUrl(data); - + braveledger_media::MediaYouTube::GetMediaIdFromUrl(data); ASSERT_EQ(media, "44444444"); // single element in the url with & appended data.url = "https://www.youtube.com/watch?v=44444444&"; media = - braveledger_bat_get_media::BatGetMedia::getYoutubeMediaIdFromUrl(data); - + braveledger_media::MediaYouTube::GetMediaIdFromUrl(data); ASSERT_EQ(media, "44444444"); // multiple elements in the url (id first) data.url = "https://www.youtube.com/watch?v=44444444&time_continue=580"; media = - braveledger_bat_get_media::BatGetMedia::getYoutubeMediaIdFromUrl(data); - + braveledger_media::MediaYouTube::GetMediaIdFromUrl(data); ASSERT_EQ(media, "44444444"); // multiple elements in the url data.url = "https://www.youtube.com/watch?time_continue=580&v=44444444"; media = - braveledger_bat_get_media::BatGetMedia::getYoutubeMediaIdFromUrl(data); - + braveledger_media::MediaYouTube::GetMediaIdFromUrl(data); ASSERT_EQ(media, "44444444"); } -TEST(BatGetMediaTest, GetYoutubePublisherKeyFromUrl) { +TEST(MediaYouTubeTest, GetPublisherKeyFromUrl) { // path is empty std::string path = ""; + std::string key; - std::string key = braveledger_bat_get_media::BatGetMedia:: - getYoutubePublisherKeyFromUrl(path); - + key = braveledger_media::MediaYouTube::GetPublisherKeyFromUrl(path); ASSERT_EQ(key, ""); // path is just slash path = "/"; - key = braveledger_bat_get_media::BatGetMedia:: - getYoutubePublisherKeyFromUrl(path); - + key = braveledger_media::MediaYouTube::GetPublisherKeyFromUrl(path); ASSERT_EQ(key, ""); // wrong path path = "/test"; - key = braveledger_bat_get_media::BatGetMedia:: - getYoutubePublisherKeyFromUrl(path); - + key = braveledger_media::MediaYouTube::GetPublisherKeyFromUrl(path); ASSERT_EQ(key, ""); // single element in the url path = "https://www.youtube.com/channel/" "UCRkcacarvLbUfygxUAAAAAA"; - key = braveledger_bat_get_media::BatGetMedia:: - getYoutubePublisherKeyFromUrl(path); - + key = braveledger_media::MediaYouTube::GetPublisherKeyFromUrl(path); ASSERT_EQ(key, "UCRkcacarvLbUfygxUAAAAAA"); // multiple elements in the url path = "https://www.youtube.com/channel/" "UCRkcacarvLbUfygxUAAAAAA?view_as=subscriber"; - key = braveledger_bat_get_media::BatGetMedia:: - getYoutubePublisherKeyFromUrl(path); - + key = braveledger_media::MediaYouTube::GetPublisherKeyFromUrl(path); ASSERT_EQ(key, "UCRkcacarvLbUfygxUAAAAAA"); // multiple paths in the url path = "https://www.youtube.com/channel/" "UCRkcacarvLbUfygxUAAAAAA/playlist"; - key = braveledger_bat_get_media::BatGetMedia:: - getYoutubePublisherKeyFromUrl(path); - + key = braveledger_media::MediaYouTube::GetPublisherKeyFromUrl(path); ASSERT_EQ(key, "UCRkcacarvLbUfygxUAAAAAA"); // multiple paths in the url path = "https://www.youtube.com/channel/" "UCRkcacarvLbUfygxUAAAAAA/playlist?view_as=subscriber"; - key = braveledger_bat_get_media::BatGetMedia:: - getYoutubePublisherKeyFromUrl(path); - + key = braveledger_media::MediaYouTube::GetPublisherKeyFromUrl(path); ASSERT_EQ(key, "UCRkcacarvLbUfygxUAAAAAA"); } -TEST(BatGetMediaTest, GetYoutubeUserFromUrl) { +TEST(MediaYouTubeTest, GetUserFromUrl) { // path is empty std::string path = "/"; - std::string user = braveledger_bat_get_media::BatGetMedia:: - getYoutubeUserFromUrl(path); - + std::string user = braveledger_media::MediaYouTube:: + GetUserFromUrl(path); ASSERT_EQ(user, ""); // path is just slash path = "/"; - user = braveledger_bat_get_media::BatGetMedia:: - getYoutubeUserFromUrl(path); + user = braveledger_media::MediaYouTube:: + GetUserFromUrl(path); ASSERT_EQ(user, ""); @@ -140,16 +121,14 @@ TEST(BatGetMediaTest, GetYoutubeUserFromUrl) { path = "https://www.youtube.com/test"; user = - braveledger_bat_get_media::BatGetMedia::getYoutubeUserFromUrl(path); - + braveledger_media::MediaYouTube::GetUserFromUrl(path); ASSERT_EQ(user, ""); // single element in the url path = "https://www.youtube.com/user/brave"; user = - braveledger_bat_get_media::BatGetMedia::getYoutubeUserFromUrl(path); - + braveledger_media::MediaYouTube::GetUserFromUrl(path); ASSERT_EQ(user, "brave"); // multiple elements in the url @@ -157,8 +136,7 @@ TEST(BatGetMediaTest, GetYoutubeUserFromUrl) { "brave?view_as=subscriber"; user = - braveledger_bat_get_media::BatGetMedia::getYoutubeUserFromUrl(path); - + braveledger_media::MediaYouTube::GetUserFromUrl(path); ASSERT_EQ(user, "brave"); // multiple paths in the url @@ -166,8 +144,7 @@ TEST(BatGetMediaTest, GetYoutubeUserFromUrl) { "brave/playlist"; user = - braveledger_bat_get_media::BatGetMedia::getYoutubeUserFromUrl(path); - + braveledger_media::MediaYouTube::GetUserFromUrl(path); ASSERT_EQ(user, "brave"); // multiple paths + elements in the url @@ -175,211 +152,194 @@ TEST(BatGetMediaTest, GetYoutubeUserFromUrl) { "brave/playlist?view_as=subscriber"; user = - braveledger_bat_get_media::BatGetMedia::getYoutubeUserFromUrl(path); - + braveledger_media::MediaYouTube::GetUserFromUrl(path); ASSERT_EQ(user, "brave"); } -TEST(BatGetMediaTest, getRealEnteredYTPath) { - braveledger_bat_get_media::BatGetMedia* bat_get_media_ = - new braveledger_bat_get_media::BatGetMedia(nullptr); +TEST(MediaYouTubeTest, GetBasicPath) { std::string path = "/gaming"; std::string realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/gaming"); path = "/watch?v=000000000000000"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/watch"); path = "/playlist?list=0000000000000"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/playlist"); path = "/bravesoftware"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/bravesoftware"); path = "/bravesoftware/videos"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/bravesoftware"); path = "bravesoftware/videos"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "bravesoftware"); path = "/bravesoftware/playlists"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/bravesoftware"); path = "/bravesoftware/community"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/bravesoftware"); path = "/bravesoftware/channels"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/bravesoftware"); path = "/bravesoftware/about"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/bravesoftware"); path = "/gaminggiant"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/gaminggiant"); path = "/feed/trending"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/feed"); path = "/subscription_manager?disable_polymer=1"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/subscription_manager"); path = ""; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, ""); path = "/"; realPath = - bat_get_media_->getRealEnteredYTPath(path); + braveledger_media::MediaYouTube::GetBasicPath(path); ASSERT_EQ(realPath, "/"); - - // cleanup - delete bat_get_media_; } -TEST(BatGetMediaTest, GetNameFromChannel) { - braveledger_bat_get_media::BatGetMedia* bat_get_media_ = - new braveledger_bat_get_media::BatGetMedia(nullptr); +TEST(MediaYouTubeTest, GetNameFromChannel) { const std::string json_envelope_open( "channelMetadataRenderer\":{\"title\":\""); const std::string json_envelope_close("\"}"); // empty string std::string resolve = - bat_get_media_->getNameFromChannel(std::string()); + braveledger_media::MediaYouTube::GetNameFromChannel(std::string()); ASSERT_EQ(resolve, std::string()); // quote resolve = - bat_get_media_->getNameFromChannel("\""); + braveledger_media::MediaYouTube::GetNameFromChannel("\""); ASSERT_EQ(resolve, std::string()); // double quote resolve = - bat_get_media_->getNameFromChannel("\"\""); + braveledger_media::MediaYouTube::GetNameFromChannel("\"\""); ASSERT_EQ(resolve, std::string()); // invalid json std::string subject( json_envelope_open + "invalid\"json\"}" + json_envelope_close); resolve = - bat_get_media_->getNameFromChannel(subject); + braveledger_media::MediaYouTube::GetNameFromChannel(subject); ASSERT_EQ(resolve, "invalid"); // ampersand (&) subject = json_envelope_open + "A\\u0026B" + json_envelope_close; resolve = - bat_get_media_->getNameFromChannel(subject); + braveledger_media::MediaYouTube::GetNameFromChannel(subject); ASSERT_EQ(resolve, "A&B"); // quotation mark (") subject = json_envelope_open + "A\\u0022B" + json_envelope_close; resolve = - bat_get_media_->getNameFromChannel(subject); + braveledger_media::MediaYouTube::GetNameFromChannel(subject); ASSERT_EQ(resolve, "A\"B"); // pound (#) subject = json_envelope_open + "A\\u0023B" + json_envelope_close; resolve = - bat_get_media_->getNameFromChannel(subject); + braveledger_media::MediaYouTube::GetNameFromChannel(subject); ASSERT_EQ(resolve, "A#B"); // dollar ($) subject = json_envelope_open + "A\\u0024B" + json_envelope_close; resolve = - bat_get_media_->getNameFromChannel(subject); + braveledger_media::MediaYouTube::GetNameFromChannel(subject); ASSERT_EQ(resolve, "A$B"); // percent (%) subject = json_envelope_open + "A\\u0025B" + json_envelope_close; resolve = - bat_get_media_->getNameFromChannel(subject); + braveledger_media::MediaYouTube::GetNameFromChannel(subject); ASSERT_EQ(resolve, "A%B"); // single quote (') subject = json_envelope_open + "A\\u0027B" + json_envelope_close; resolve = - bat_get_media_->getNameFromChannel(subject); + braveledger_media::MediaYouTube::GetNameFromChannel(subject); ASSERT_EQ(resolve, "A'B"); - - // cleanup - delete bat_get_media_; } -TEST(BatGetMediaTest, ParsePublisherName) { - braveledger_bat_get_media::BatGetMedia* bat_get_media_ = - new braveledger_bat_get_media::BatGetMedia(nullptr); - +TEST(MediaYouTubeTest, GetPublisherName) { const std::string json_envelope( "\"author\":\""); // empty string std::string publisher_name = - bat_get_media_->parsePublisherName(std::string()); + braveledger_media::MediaYouTube::GetPublisherName(std::string()); ASSERT_EQ(publisher_name, std::string()); // quote publisher_name = - bat_get_media_->parsePublisherName("\""); + braveledger_media::MediaYouTube::GetPublisherName("\""); ASSERT_EQ(publisher_name, std::string()); // double quote publisher_name = - bat_get_media_->parsePublisherName("\"\""); + braveledger_media::MediaYouTube::GetPublisherName("\"\""); ASSERT_EQ(publisher_name, std::string()); // invalid json std::string subject( json_envelope + "invalid\"json}"); publisher_name = - bat_get_media_->parsePublisherName(subject); + braveledger_media::MediaYouTube::GetPublisherName(subject); ASSERT_EQ(publisher_name, "invalid"); // string name subject = json_envelope + "publisher_name"; publisher_name = - bat_get_media_->parsePublisherName(subject); + braveledger_media::MediaYouTube::GetPublisherName(subject); ASSERT_EQ(publisher_name, "publisher_name"); // ampersand (& code point) subject = json_envelope + "A\\u0026B"; publisher_name = - bat_get_media_->parsePublisherName(subject); + braveledger_media::MediaYouTube::GetPublisherName(subject); ASSERT_EQ(publisher_name, "A&B"); // ampersand (&) straight subject = json_envelope + "A&B"; publisher_name = - bat_get_media_->parsePublisherName(subject); + braveledger_media::MediaYouTube::GetPublisherName(subject); ASSERT_EQ(publisher_name, "A&B"); - - // cleanup - delete bat_get_media_; } -} // namespace braveledger_bat_get_media +} // namespace braveledger_media From 4643e2c1bf64fe2bbfeece013e830de49b68d465 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Thu, 11 Apr 2019 13:01:31 +0200 Subject: [PATCH 08/12] Removes old code --- .../src/bat/ledger/internal/bat_get_media.cc | 1206 +---------------- .../src/bat/ledger/internal/bat_get_media.h | 267 +--- .../src/bat/ledger/internal/ledger_impl.cc | 4 +- 3 files changed, 29 insertions(+), 1448 deletions(-) diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc index c3962deba6e5..1cc73577625a 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc @@ -3,18 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include -#include -#include -#include -#include -#include - #include "bat/ledger/internal/bat_get_media.h" -#include "bat/ledger/internal/bat_helper.h" #include "bat/ledger/internal/ledger_impl.h" -#include "bat/ledger/internal/rapidjson_bat_helper.h" -#include "bat/ledger/internal/static_values.h" using std::placeholders::_1; using std::placeholders::_2; @@ -34,7 +24,6 @@ std::string BatGetMedia::GetLinkType(const std::string& url, const std::string& first_party_url, const std::string& referrer) { std::string type; - type = braveledger_media::MediaYouTube::GetLinkType(url); if (type.empty()) { @@ -46,7 +35,7 @@ std::string BatGetMedia::GetLinkType(const std::string& url, return type; } -void BatGetMedia::processMedia(const std::map& parts, +void BatGetMedia::ProcessMedia(const std::map& parts, const std::string& type, const ledger::VisitData& visit_data) { if (parts.size() == 0 || !ledger_->GetRewardsMainEnabled()) { @@ -65,454 +54,30 @@ void BatGetMedia::processMedia(const std::map& parts, } void BatGetMedia::GetMediaActivityFromUrl( - uint64_t windowId, + uint64_t window_id, const ledger::VisitData& visit_data, - const std::string& providerType, + const std::string& type, const std::string& publisher_blob) { - if (providerType == YOUTUBE_MEDIA_TYPE) { - media_youtube_->ProcessActivityFromUrl(windowId, visit_data); - } else if (providerType == TWITCH_MEDIA_TYPE) { - // TODO one left - processTwitchMediaPanel(windowId, visit_data, providerType, publisher_blob); - } else { - onMediaActivityError(visit_data, providerType, windowId); - } -} - -void BatGetMedia::getPublisherInfoDataCallback(const std::string& mediaId, - const std::string& media_key, - const std::string& providerName, - const uint64_t& duration, - const ledger::TwitchEventInfo& twitchEventInfo, - const ledger::VisitData& visit_data, - const uint64_t window_id, - ledger::Result result, - std::unique_ptr publisher_info) { - if (result != ledger::Result::LEDGER_OK && - result != ledger::Result::NOT_FOUND) { - BLOG(ledger_, ledger::LogLevel::LOG_ERROR) - << "Failed to get publisher info"; - // TODO(anyone) error handling - return; - } - - if (!publisher_info && !publisher_info.get()) { - std::string mediaURL = getMediaURL(mediaId, providerName); - if (providerName == YOUTUBE_MEDIA_TYPE) { - auto callback = std::bind( - &BatGetMedia::getPublisherFromMediaPropsCallback, - this, - duration, - media_key, - providerName, - mediaURL, - visit_data, - window_id, - _1, - _2, - _3); - ledger_->LoadURL( - (std::string)YOUTUBE_PROVIDER_URL + "?format=json&url=" + - ledger_->URIEncode(mediaURL), - std::vector(), "", "", ledger::URL_METHOD::GET, callback); - } else if (providerName == TWITCH_MEDIA_TYPE) { - if (mediaId.empty()) { - return; - } - - ledger::TwitchEventInfo oldEvent; - std::map::const_iterator iter = - twitchEvents.find(media_key); - if (iter != twitchEvents.end()) { - oldEvent = iter->second; - } - - ledger::TwitchEventInfo newEvent(twitchEventInfo); - newEvent.status_ = getTwitchStatus(oldEvent, newEvent); - - uint64_t realDuration = getTwitchDuration(oldEvent, newEvent); - twitchEvents[media_key] = newEvent; - - if (realDuration == 0) { - return; - } - - std::string twitchMediaID = mediaId; - std::string mediaUrl = getMediaURL(twitchMediaID, providerName); - - ledger::VisitData updated_visit_data(visit_data); - updated_visit_data.favicon_url = ""; - updated_visit_data.provider = TWITCH_MEDIA_TYPE; - - if (mediaId.find("_vod_") != std::string::npos) { - // VOD - std::vector media_props = - braveledger_bat_helper::split(mediaId, MEDIA_DELIMITER); - if (media_props.empty()) { - return; - } - - twitchMediaID = media_props[0]; - mediaUrl = getMediaURL(twitchMediaID, providerName); - std::string oembed_url = - (std::string)TWITCH_VOD_URL + media_props[media_props.size() - 1]; - updated_visit_data.name = twitchMediaID; - updated_visit_data.url = mediaUrl + "/videos"; - - auto callback = std::bind( - &BatGetMedia::getPublisherFromMediaPropsCallback, - this, - realDuration, - media_key, - providerName, - mediaUrl, - updated_visit_data, - window_id, - _1, - _2, - _3); - ledger_->LoadURL( - (std::string)TWITCH_PROVIDER_URL + "?json&url=" + - ledger_->URIEncode(oembed_url), - std::vector(), "", "", - ledger::URL_METHOD::GET, callback); - return; - } - - // Live stream - std::string id = providerName + "#author:" + twitchMediaID; - updated_visit_data.name = twitchMediaID; - updated_visit_data.url = mediaUrl + "/videos"; - - ledger_->SaveMediaVisit(id, updated_visit_data, realDuration, window_id); - ledger_->SetMediaPublisherInfo(media_key, id); - } + if (type == YOUTUBE_MEDIA_TYPE) { + media_youtube_->ProcessActivityFromUrl(window_id, visit_data); + } else if (type == TWITCH_MEDIA_TYPE) { + media_twitch_->ProcessActivityFromUrl(window_id, + visit_data, + publisher_blob); } else { - ledger::VisitData updated_visit_data(visit_data); - updated_visit_data.name = publisher_info->name; - updated_visit_data.url = publisher_info->url; - if (providerName == YOUTUBE_MEDIA_TYPE) { - updated_visit_data.provider = YOUTUBE_MEDIA_TYPE; - updated_visit_data.favicon_url = publisher_info->favicon_url; - std::string id = publisher_info->id; - ledger_->SaveMediaVisit(id, updated_visit_data, duration, window_id); - } else if (providerName == TWITCH_MEDIA_TYPE) { - updated_visit_data.provider = TWITCH_MEDIA_TYPE; - updated_visit_data.favicon_url = publisher_info->favicon_url; - - ledger::TwitchEventInfo oldEvent; - std::map::const_iterator iter = - twitchEvents.find(media_key); - if (iter != twitchEvents.end()) { - oldEvent = iter->second; - } - - ledger::TwitchEventInfo newEvent(twitchEventInfo); - newEvent.status_ = getTwitchStatus(oldEvent, newEvent); - - uint64_t realDuration = getTwitchDuration(oldEvent, newEvent); - twitchEvents[media_key] = newEvent; - - std::string id = publisher_info->id; - ledger_->SaveMediaVisit(id, updated_visit_data, realDuration, window_id); - } - } -} - -std::string BatGetMedia::getTwitchStatus( - const ledger::TwitchEventInfo& oldEventInfo, - const ledger::TwitchEventInfo& newEventInfo) { - std::string status = "playing"; - - if ( - ( - newEventInfo.event_ == "video_pause" && - oldEventInfo.event_ != "video_pause") || - // User clicked pause (we need to exclude seeking while paused) - ( - newEventInfo.event_ == "video_pause" && - oldEventInfo.event_ == "video_pause" && - oldEventInfo.status_ == "playing") || - // User clicked pause as soon as he clicked play - ( - newEventInfo.event_ == "player_click_vod_seek" && - oldEventInfo.status_ == "paused") - // Seeking a video while it is paused - ) { - status = "paused"; - } - - // User pauses a video, then seeks it and plays it again - if (newEventInfo.event_ == "video_pause" && - oldEventInfo.event_ == "player_click_vod_seek" && - oldEventInfo.status_ == "paused") { - status = "playing"; - } - - return status; -} - -uint64_t BatGetMedia::getTwitchDuration( - const ledger::TwitchEventInfo& oldEventInfo, - const ledger::TwitchEventInfo& newEventInfo) { - // Remove duplicated events - if (oldEventInfo.event_ == newEventInfo.event_ && - oldEventInfo.time_ == newEventInfo.time_) { - return 0; - } - - if (newEventInfo.event_ == "video-play") { // Start event - return TWITCH_MINIMUM_SECONDS; - } - - // TODO(anyone) check if converted properly - double time = 0; - std::stringstream tempTime(newEventInfo.time_); - double currentTime = 0; - tempTime >> currentTime; - std::stringstream tempOld(oldEventInfo.time_); - double oldTime = 0; - tempOld >> oldTime; - - if (oldEventInfo.event_ == "video-play") { - time = currentTime - oldTime - TWITCH_MINIMUM_SECONDS; - } else if (newEventInfo.event_ == "minute-watched" || // Minute watched - newEventInfo.event_ == "buffer-empty" || // Run out of buffer - newEventInfo.event_ == "video_error" || // Video has some problems - newEventInfo.event_ == "video_end" || // Video ended - (newEventInfo.event_ == "player_click_vod_seek" && - oldEventInfo.status_ == "paused") || // Vod seek - ( - newEventInfo.event_ == "video_pause" && - ( - ( - oldEventInfo.event_ != "video_pause" && - oldEventInfo.event_ != "player_click_vod_seek") || - oldEventInfo.status_ == "playing") - ) // User paused video - ) { - time = currentTime - oldTime; - } - - if (time < 0) { - return 0; - } - - // if autoplay is off and play is pressed - if (oldEventInfo.status_.empty()) { - return 0; - } - - if (time > TWITCH_MAXIMUM_SECONDS_CHUNK) { - time = TWITCH_MAXIMUM_SECONDS_CHUNK; - } - - return (uint64_t)std::round(time); -} - -void BatGetMedia::getPublisherFromMediaPropsCallback( - const uint64_t& duration, - const std::string& media_key, - const std::string& providerName, - const std::string& mediaURL, - const ledger::VisitData& visit_data, - const uint64_t window_id, - int response_status_code, - const std::string& response, - const std::map& headers) { - ledger_->LogResponse(__func__, response_status_code, response, headers); - - if (response_status_code != 200) { - // TODO(anyone): add error handler - if (providerName == YOUTUBE_MEDIA_TYPE) { - if (response_status_code == 401) { // embedding disabled, need to scrape - fetchDataFromUrl(visit_data.url, - std::bind(&BatGetMedia::onFetchDataFromNonEmbeddable, - this, - window_id, - visit_data, - providerName, - duration, - media_key, - mediaURL, - _1, - _2, - _3)); - } - } - return; - } - - if (providerName == YOUTUBE_MEDIA_TYPE) { - std::string publisherURL; - braveledger_bat_helper::getJSONValue("author_url", response, &publisherURL); - std::string publisherName; - braveledger_bat_helper::getJSONValue("author_name", - response, - &publisherName); - - auto callback = std::bind(&BatGetMedia::getPublisherInfoCallback, - this, - duration, - media_key, - providerName, - mediaURL, - publisherURL, - publisherName, - visit_data, - window_id, - _1, - _2, - _3); - ledger_->LoadURL(publisherURL, - std::vector(), "", "", ledger::URL_METHOD::GET, callback); - return; - } - - if (providerName == TWITCH_MEDIA_TYPE) { - std::string fav_icon; - braveledger_bat_helper::getJSONValue("author_thumbnail_url", - response, - &fav_icon); - std::string author_name; - braveledger_bat_helper::getJSONValue("author_name", response, &author_name); - - std::string twitchMediaID = visit_data.name; - std::string id = providerName + "#author:" + twitchMediaID; - - ledger::VisitData updated_visit_data(visit_data); - updated_visit_data.name = author_name; - - if (fav_icon.length() > 0) { - updated_visit_data.favicon_url = fav_icon; - } - - ledger_->SaveMediaVisit(id, updated_visit_data, duration, window_id); - ledger_->SetMediaPublisherInfo(media_key, id); - } -} - -void BatGetMedia::getPublisherInfoCallback( - const uint64_t& duration, - const std::string& media_key, - const std::string& providerName, - const std::string& mediaURL, - const std::string& publisherURL, - const std::string& publisherName, - const ledger::VisitData& visit_data, - const uint64_t window_id, - int response_status_code, - const std::string& response, - const std::map& headers) { - if (response_status_code == 200 && providerName == YOUTUBE_MEDIA_TYPE) { - std::string favIconURL = parseFavIconUrl(response); - std::string channelId = parseChannelId(response); - - savePublisherInfo(duration, - media_key, - providerName, - publisherURL, - publisherName, - visit_data, - window_id, - favIconURL, - channelId); + OnMediaActivityError(visit_data, type, window_id); } } -void BatGetMedia::savePublisherInfo(const uint64_t& duration, - const std::string& media_key, - const std::string& providerName, - const std::string& publisherURL, - const std::string& publisherName, - const ledger::VisitData& visit_data, - const uint64_t window_id, - const std::string& favIconURL, - const std::string& channelId) { - std::string publisher_id; - std::string url; - if (providerName == YOUTUBE_MEDIA_TYPE) { - publisher_id = providerName + "#channel:"; - if (channelId.empty()) { - BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << - "Channel id is missing for: " << media_key; - return; - } - - publisher_id += channelId; - url = publisherURL + "/videos"; - } else if (providerName == TWITCH_MEDIA_TYPE) { - publisher_id = providerName + "#author:"; - if (channelId.empty()) { - BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << - "author id is missing for: " << media_key; - return; - } - publisher_id += channelId; - url = publisherURL + "/videos"; - } - - if (publisher_id.empty()) { - BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << - "Publisher id is missing for: " << media_key; - return; - } - - ledger::VisitData updated_visit_data(visit_data); - - if (favIconURL.length() > 0) { - updated_visit_data.favicon_url = favIconURL; - } - - updated_visit_data.provider = providerName; - updated_visit_data.name = publisherName; - updated_visit_data.url = url; - - ledger_->SaveMediaVisit(publisher_id, - updated_visit_data, - duration, - window_id); - if (!media_key.empty()) { - ledger_->SetMediaPublisherInfo(media_key, publisher_id); - } -} - -std::string BatGetMedia::getMediaURL(const std::string& mediaId, - const std::string& providerName) { - std::string res; - - DCHECK(!mediaId.empty()); - if (YOUTUBE_MEDIA_TYPE == providerName) { - res = "https://www.youtube.com/watch?v=" + mediaId; - } else if (TWITCH_MEDIA_TYPE == providerName) { - res = "https://www.twitch.tv/" + mediaId; - } - - return res; -} - -std::string BatGetMedia::getPublisherUrl(const std::string& publisher_key, - const std::string& providerName) { - std::string res; - DCHECK(!publisher_key.empty()); - if (providerName == YOUTUBE_MEDIA_TYPE) { - res = "https://www.youtube.com/channel/" + publisher_key; - } else if (providerName == TWITCH_MEDIA_TYPE) { - res = "https://www.twitch.tv/" + publisher_key; - } - - return res; -} - -void BatGetMedia::onMediaActivityError(const ledger::VisitData& visit_data, - const std::string& providerType, - uint64_t windowId) { +void BatGetMedia::OnMediaActivityError(const ledger::VisitData& visit_data, + const std::string& type, + uint64_t window_id) { std::string url; std::string name; - if (providerType == YOUTUBE_MEDIA_TYPE) { + if (type == YOUTUBE_MEDIA_TYPE) { url = YOUTUBE_TLD; name = YOUTUBE_MEDIA_TYPE; - } else if (providerType == TWITCH_MEDIA_TYPE) { + } else if (type == TWITCH_MEDIA_TYPE) { url = TWITCH_TLD; name = TWITCH_MEDIA_TYPE; } @@ -524,745 +89,14 @@ void BatGetMedia::onMediaActivityError(const ledger::VisitData& visit_data, new_data.path = "/"; new_data.name = name; - ledger_->GetPublisherActivityFromUrl(windowId, new_data, std::string()); + ledger_->GetPublisherActivityFromUrl(window_id, new_data, std::string()); } else { BLOG(ledger_, ledger::LogLevel::LOG_ERROR) - << "Media activity error for " << providerType << " (name: " - << name << ", url: " << visit_data.url << ")"; - } -} - - - -void BatGetMedia::processYoutubeMediaPanel(uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType) { - if (visit_data.path.find("/watch?") != std::string::npos) { - processYoutubeWatchPath(windowId, visit_data, providerType); - } else if (visit_data.path.find("/channel/") != std::string::npos) { - processYoutubeChannelPath(windowId, visit_data, providerType); - } else if (visit_data.path.find("/user/") != std::string::npos) { - processYoutubeUserPath(windowId, visit_data, providerType); - } else if (!isPredefinedYTPath(visit_data.path)) { - processYoutubeCustomPath(windowId, visit_data, providerType, std::string()); - } else { - onMediaActivityError(visit_data, providerType, windowId); + << "Media activity error for " + << type << " (name: " + << name << ", url: " + << visit_data.url << ")"; } } -bool BatGetMedia::isPredefinedYTPath(const std::string& path) const { - std::vector yt_paths({ - "/feed", - "/channel", - "/user", - "/watch", - "/account", - "/gaming", - "/playlist", - "/premium", - "/reporthistory", - "/pair", - "/account_notifications", - "/account_playback", - "/account_privacy", - "/account_sharing", - "/account_billing", - "/account_advanced", - "/subscription_manager", - "/oops" - }); - - // make sure we are ignoring actual YT paths and not - // a custom path that might start with a YT path - std::string yt_path = getRealEnteredYTPath(path); - for (std::string str_path : yt_paths) { - if (yt_path == str_path) { - return true; - } - } - return false; -} - -std::string BatGetMedia::getRealEnteredYTPath(const std::string& path) const { - std::string yt_path = path.substr(0, path.find("/", 1)); - if (yt_path.empty() || yt_path == path) { - yt_path = path.substr(0, path.find("?", 1)); - if (yt_path.empty() || yt_path == path) { - yt_path = path.substr(0); - } - } - return yt_path; -} - -void BatGetMedia::processYoutubeWatchPath(uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType) { - std::string media_id = getYoutubeMediaIdFromUrl(visit_data); - std::string media_key = getYoutubeMediaKeyFromUrl(providerType, media_id); - - if (!media_key.empty() || !media_id.empty()) { - ledger_->GetMediaPublisherInfo(media_key, - std::bind(&BatGetMedia::onMediaPublisherActivity, - this, - _1, - _2, - windowId, - visit_data, - providerType, - media_key, - media_id, - std::string())); - } else { - onMediaActivityError(visit_data, providerType, windowId); - } -} - -void BatGetMedia::processYoutubeCustomPath( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& publisher_key) { - fetchPublisherDataFromDB( - windowId, - visit_data, - providerType, - publisher_key, - std::string(), - true); -} - -void BatGetMedia::processYoutubeChannelPath(uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType) { - std::string publisher_key = "youtube#channel:"; - std::string key = getYoutubePublisherKeyFromUrl(visit_data.path); - if (!key.empty()) { - publisher_key += key; - fetchPublisherDataFromDB(windowId, - visit_data, - providerType, - publisher_key, - std::string(), - false); - } else { - onMediaActivityError(visit_data, providerType, windowId); - } -} - -void BatGetMedia::onMediaUserActivity( - ledger::Result result, - std::unique_ptr info, - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& media_key) { - if (result != ledger::Result::LEDGER_OK && - result != ledger::Result::NOT_FOUND) { - onMediaActivityError(visit_data, providerType, windowId); - return; - } - - if (!info || result == ledger::Result::NOT_FOUND) { - fetchDataFromUrl(visit_data.url, - std::bind(&BatGetMedia::onGetChannelIdFromUserPage, - this, - windowId, - visit_data, - providerType, - media_key, - _1, - _2, - _3)); - - } else { - fetchPublisherDataFromDB(windowId, visit_data, - providerType, info->id, std::string(), false); - } -} - -void BatGetMedia::processYoutubeUserPath( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType) { - std::string user = getYoutubeUserFromUrl(visit_data.path); - - if (user.empty()) { - onMediaActivityError(visit_data, providerType, windowId); - } else { - std::string media_key = providerType + "_user_" + user; - ledger_->GetMediaPublisherInfo(media_key, - std::bind(&BatGetMedia::onMediaUserActivity, - this, - _1, - _2, - windowId, - visit_data, - providerType, - media_key)); - } -} - -void BatGetMedia::fetchPublisherDataFromDB( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& publisher_key, - const std::string& publisher_blob, - const bool is_custom_path) { - auto filter = ledger_->CreateActivityFilter( - publisher_key, - ledger::EXCLUDE_FILTER::FILTER_ALL, - false, - ledger_->GetReconcileStamp(), - true, - false); - ledger_->GetPanelPublisherInfo(filter, - std::bind(&BatGetMedia::onFetchPublisherFromDBResponse, - this, - _1, - _2, - windowId, - visit_data, - providerType, - publisher_key, - publisher_blob, - is_custom_path)); -} - -void BatGetMedia::onFetchPublisherFromDBResponse( - ledger::Result result, - std::unique_ptr info, - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& publisher_key, - const std::string& publisher_blob, - const bool is_custom_path) { - if (!info || (result == ledger::Result::NOT_FOUND && - providerType == YOUTUBE_MEDIA_TYPE)) { - fetchDataFromUrl(visit_data.url, - std::bind(&BatGetMedia::onGetChannelHeadlineVideo, - this, - windowId, - visit_data, - providerType, - _1, - _2, - _3, - is_custom_path)); - } else { - if (providerType == TWITCH_MEDIA_TYPE) { - if (info->name != visit_data.name) { - std::string media_id = getTwitchMediaIdFromUrl( - visit_data, publisher_blob); - std::transform(media_id.begin(), media_id.end(), - media_id.begin(), ::tolower); - std::string media_key = getTwitchMediaKeyFromUrl( - providerType, - media_id, - visit_data.url); - info->name = getUserFacingHandle(publisher_blob); - savePublisherInfo(0, - media_key, - providerType, - visit_data.url, - info->name, - visit_data, - windowId, - info->favicon_url, - media_id); - } - } - ledger_->OnPanelPublisherInfo(result, std::move(info), windowId); - } -} - -void BatGetMedia::fetchDataFromUrl(const std::string& url, - FetchDataFromUrlCallback callback) { - ledger_->LoadURL(url, - std::vector(), "", "", - ledger::URL_METHOD::GET, callback); -} - -void BatGetMedia::onGetChannelIdFromUserPage( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& media_key, - int response_status_code, - const std::string& response, - const std::map& headers) { - std::string channelId = parseChannelId(response); - if (!channelId.empty()) { - std::string path = "/channel/" + channelId; - std::string url = getPublisherUrl(channelId, providerType); - std::string publisher_key = providerType + "#channel:" + channelId; - - ledger_->SetMediaPublisherInfo(media_key, publisher_key); - - ledger::VisitData new_data(visit_data); - new_data.path = path; - new_data.url = url; - new_data.name = ""; - new_data.favicon_url = ""; - - GetMediaActivityFromUrl(windowId, new_data, providerType, std::string()); - } else { - onMediaActivityError(visit_data, providerType, windowId); - } -} - -void BatGetMedia::onFetchDataFromNonEmbeddable( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const uint64_t& duration, - const std::string& media_key, - const std::string& mediaURL, - int response_status_code, - const std::string& response, - const std::map& headers) { - if (response_status_code != 200) { - onMediaActivityError(visit_data, providerType, windowId); - return; - } - - if (providerType == YOUTUBE_MEDIA_TYPE) { - std::string publisher_name = parsePublisherName(response); - std::string channel_id = parseChannelId(response); - std::string publisher_url = - getPublisherUrl(channel_id, providerType); - std::string favicon_url = parseFavIconUrl(response); - savePublisherInfo(duration, - media_key, - providerType, - publisher_url, - publisher_name, - visit_data, - windowId, - favicon_url, - channel_id); - return; - } -} - -void BatGetMedia::onGetChannelHeadlineVideo(uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - int response_status_code, - const std::string& response, - const std::map& headers, - const bool is_custom_path) { - if (response_status_code != 200) { - onMediaActivityError(visit_data, providerType, windowId); - return; - } - - if (visit_data.path.find("/channel/") != std::string::npos) { - std::string title = getNameFromChannel(response); - std::string favicon = parseFavIconUrl(response); - std::string channelId = getYoutubePublisherKeyFromUrl(visit_data.path); - - savePublisherInfo(0, - std::string(), - providerType, - visit_data.url, - title, - visit_data, - windowId, - favicon, - channelId); - - } else if (is_custom_path) { - std::string title = getNameFromChannel(response); - std::string favicon = parseFavIconUrl(response); - std::string channelId = parseChannelIdFromCustomPathPage(response); - ledger::VisitData new_visit_data(visit_data); - new_visit_data.path = "/channel/" + channelId; - processYoutubeCustomPath(windowId, new_visit_data, providerType, - "youtube#channel:" + channelId); - } else { - onMediaActivityError(visit_data, providerType, windowId); - } -} - -void BatGetMedia::processTwitchMediaPanel( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& publisher_blob) { - if (!publisher_blob.empty()) { - std::string media_id = getTwitchMediaIdFromUrl(visit_data, publisher_blob); - std::transform(media_id.begin(), - media_id.end(), - media_id.begin(), - ::tolower); - std::string media_key = getTwitchMediaKeyFromUrl(providerType, media_id, - visit_data.url); - if (!media_key.empty() && !media_id.empty()) { - ledger_->GetMediaPublisherInfo( - media_key, - std::bind(&BatGetMedia::onMediaPublisherActivity, - this, - _1, - _2, - windowId, - visit_data, - providerType, - media_key, - media_id, - publisher_blob)); - } else { - onMediaActivityError(visit_data, providerType, windowId); - } - } else { - ledger::VisitData new_visit_data(visit_data); - new_visit_data.path = std::string(); - ledger_->GetPublisherActivityFromUrl(windowId, - new_visit_data, - std::string()); - } -} - -std::string BatGetMedia::getTwitchMediaIdFromUrl( - const ledger::VisitData& visit_data, - const std::string& publisher_blob) const { - std::string mediaId = - extractData(visit_data.url, "twitch.tv/", "/"); - if (visit_data.url.find("twitch.tv/videos/") != std::string::npos) { - mediaId = extractData(publisher_blob, - " info, - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& media_key, - const std::string& media_id, - const std::string& publisher_blob) { - if (result != ledger::Result::LEDGER_OK && - result != ledger::Result::NOT_FOUND) { - onMediaActivityError(visit_data, providerType, windowId); - return; - } - - if (!info || result == ledger::Result::NOT_FOUND) { - if (providerType == TWITCH_MEDIA_TYPE) { - // first see if we have the publisher a different way (VOD vs. live stream - ledger_->GetPublisherInfo("twitch#author:" + media_id, - std::bind(&BatGetMedia::onGetTwitchPublisherInfo, - this, - _1, - _2, - windowId, - visit_data, - providerType, - media_key, - media_id, - publisher_blob)); - } else if (providerType == YOUTUBE_MEDIA_TYPE) { - ledger::TwitchEventInfo twitchEventInfo; - getPublisherInfoDataCallback(media_id, - media_key, - providerType, - 0, - twitchEventInfo, - visit_data, - windowId, - result, - std::move(info)); - } - } else { - if (providerType == TWITCH_MEDIA_TYPE) { - if (info->verified && info->favicon_url.empty()) { - std::string publisher_name; - std::string publisher_favicon_url; - updateTwitchPublisherData(&publisher_name, - &publisher_favicon_url, - publisher_blob); - - if (!publisher_favicon_url.empty()) { - savePublisherInfo(0, - media_key, - providerType, - visit_data.url, - publisher_name, - visit_data, - windowId, - publisher_favicon_url, - media_id); - return; - } - } - - ledger_->OnPanelPublisherInfo(result, std::move(info), windowId); - } else if (providerType == YOUTUBE_MEDIA_TYPE) { - fetchPublisherDataFromDB(windowId, - visit_data, - providerType, - info->id, - publisher_blob, - false); - } - } -} - -void BatGetMedia::onGetTwitchPublisherInfo( - ledger::Result result, - std::unique_ptr publisher_info, - uint64_t windowId, - const ledger::VisitData visit_data, - const std::string& providerType, - const std::string& media_key, - const std::string& media_id, - const std::string& publisher_blob) { - if (result != ledger::Result::LEDGER_OK && - result != ledger::Result::NOT_FOUND) { - onMediaActivityError(visit_data, providerType, windowId); - return; - } - if (!publisher_info || result == ledger::Result::NOT_FOUND) { - if (providerType == TWITCH_MEDIA_TYPE) { - std::string publisher_name; - std::string publisher_favicon_url; - updateTwitchPublisherData(&publisher_name, - &publisher_favicon_url, - publisher_blob); - savePublisherInfo(0, - media_key, - providerType, - visit_data.url, - publisher_name, - visit_data, - windowId, - publisher_favicon_url, - media_id); - } - } else { - if (providerType == TWITCH_MEDIA_TYPE) { - ledger_->OnPanelPublisherInfo(result, - std::move(publisher_info), - windowId); - } - } -} - -void BatGetMedia::updateTwitchPublisherData( - std::string* publisher_name, - std::string* publisher_favicon_url, - const std::string& publisher_blob) { - *publisher_name = getUserFacingHandle(publisher_blob); - *publisher_favicon_url = getFaviconUrl(publisher_blob, *publisher_name); -} - -std::string BatGetMedia::getUserFacingHandle( - const std::string& publisher_blob) const { - return extractData(publisher_blob, - "
" - "
" - "\""," - "
" - "\"""); - } - - if (id.empty()) { - id = extractData( - data, - "browseEndpoint\":{\"browseId\":\"", - "\""); - } - - return id; -} - -std::string BatGetMedia::parsePublisherName(const std::string& data) { - std::string publisher_name; - std::string publisher_json_name = extractData(data, "\"author\":\"", "\""); - std::string publisher_json = "{\"brave_publisher\":\"" + - publisher_json_name + "\"}"; - // scraped data could come in with JSON code points added. - // Make to JSON object above so we can decode. - braveledger_bat_helper::getJSONValue( - "brave_publisher", publisher_json, &publisher_name); - return publisher_name; -} - -// static -std::string BatGetMedia::getYoutubeMediaIdFromUrl( - const ledger::VisitData& visit_data) { - std::vector first_split = - braveledger_bat_helper::split(visit_data.url, '?'); - - if (first_split.size() < 2) { - return std::string(); - } - - std::vector and_split = - braveledger_bat_helper::split(first_split[1], '&'); - - for (const auto& item : and_split) { - std::vector m_url = braveledger_bat_helper::split(item, '='); - - if (m_url.size() < 2) { - continue; - } - - if (m_url[0] == "v") { - return m_url[1]; - } - } - - return std::string(); -} - -std::string BatGetMedia::getYoutubeMediaKeyFromUrl( - const std::string& provider_type, - const std::string& id) { - if (!id.empty()) { - return provider_type + "_" + id; - } - - return std::string(); -} - -// static -std::string BatGetMedia::getYoutubePublisherKeyFromUrl( - const std::string& path) { - if (path.empty()) { - return std::string(); - } - - const std::string id = extractData(path + "/", "/channel/", "/"); - - if (id.empty()) { - return std::string(); - } - - std::vector params = braveledger_bat_helper::split(id, '?'); - - return params[0]; -} - -// static -std::string BatGetMedia::getYoutubeUserFromUrl( - const std::string& path) { - if (path.empty()) { - return std::string(); - } - - const std::string id = extractData(path + "/", "/user/", "/"); - - if (id.empty()) { - return std::string(); - } - - std::vector params = braveledger_bat_helper::split(id, '?'); - - return params[0]; -} - -// static -std::string BatGetMedia::extractData(const std::string& data, - const std::string& matchAfter, - const std::string& matchUntil) { - std::string match; - size_t match_after_size = matchAfter.size(); - size_t data_size = data.size(); - - if (data_size < match_after_size) { - return match; - } - - size_t startPos = data.find(matchAfter); - if (startPos != std::string::npos) { - startPos += match_after_size; - size_t endPos = data.find(matchUntil, startPos); - if (endPos != startPos) { - if (endPos != std::string::npos && endPos > startPos) { - match = data.substr(startPos, endPos - startPos); - } else if (endPos != std::string::npos) { - match = data.substr(startPos, endPos); - } else { - match = data.substr(startPos, std::string::npos); - } - } - } - - return match; -} - -std::string BatGetMedia::getNameFromChannel(const std::string& data) { - std::string publisher_name; - const std::string publisher_json_name = - extractData(data, "channelMetadataRenderer\":{\"title\":\"", "\""); - const std::string publisher_json = "{\"brave_publisher\":\"" + - publisher_json_name + "\"}"; - // scraped data could come in with JSON code points added. - // Make to JSON object above so we can decode. - braveledger_bat_helper::getJSONValue( - "brave_publisher", publisher_json, &publisher_name); - return publisher_name; -} - -std::string BatGetMedia::parseChannelIdFromCustomPathPage( - const std::string& data) { - return extractData(data, "{\"key\":\"browse_id\",\"value\":\"", "\""); -} - } // namespace braveledger_bat_get_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h index 85202c3922a0..767625d3c843 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h @@ -8,35 +8,18 @@ #include #include -#include -#include "base/gtest_prod_util.h" #include "bat/ledger/internal/bat_helper.h" -#include "bat/ledger/ledger.h" - -#include "bat/ledger/internal/media/youtube.h" #include "bat/ledger/internal/media/twitch.h" +#include "bat/ledger/internal/media/youtube.h" +#include "bat/ledger/ledger.h" namespace bat_ledger { class LedgerImpl; } -namespace leveldb { -class DB; -} - -//namespace braveledger_media { -//class MediaYouTube; -//class MediaTwitch; -//} - namespace braveledger_bat_get_media { -using FetchDataFromUrlCallback = std::function& headers)>; - class BatGetMedia { public: explicit BatGetMedia(bat_ledger::LedgerImpl* ledger); @@ -47,259 +30,23 @@ class BatGetMedia { const std::string& first_party_url, const std::string& referrer); - void processMedia(const std::map& parts, + void ProcessMedia(const std::map& parts, const std::string& type, const ledger::VisitData& visit_data); void GetMediaActivityFromUrl(uint64_t windowId, const ledger::VisitData& visit_data, - const std::string& providerType, + const std::string& type, const std::string& publisher_blob); private: - std::string getMediaURL(const std::string& mediaId, - const std::string& providerName); - - void getPublisherFromMediaPropsCallback( - const uint64_t& duration, - const std::string& media_key, - const std::string& providerName, - const std::string& mediaURL, - const ledger::VisitData& visit_data, - const uint64_t window_id, - int response_status_code, - const std::string& response, - const std::map& headers); - - void getPublisherInfoCallback( - const uint64_t& duration, - const std::string& media_key, - const std::string& providerName, - const std::string& mediaURL, - const std::string& publisherURL, - const std::string& publisherName, - const ledger::VisitData& visit_data, - const uint64_t window_id, - int response_status_code, - const std::string& response, - const std::map& headers); - - void savePublisherInfo( - const uint64_t& duration, - const std::string& media_key, - const std::string& providerName, - const std::string& publisherURL, - const std::string& publisherName, - const ledger::VisitData& visit_data, - const uint64_t window_id, - const std::string& favIconURL, - const std::string& channelId); - - uint64_t getTwitchDuration(const ledger::TwitchEventInfo& oldEventInfo, - const ledger::TwitchEventInfo& newEventInfo); - - std::string getTwitchStatus(const ledger::TwitchEventInfo& oldEventInfo, - const ledger::TwitchEventInfo& newEventInfo); - - void getPublisherInfoDataCallback( - const std::string& mediaId, - const std::string& media_key, - const std::string& providerName, - const uint64_t& duration, - const ledger::TwitchEventInfo& twitchEventInfo, - const ledger::VisitData& visit_data, - const uint64_t window_id, - ledger::Result result, - std::unique_ptr media_publisher_info); - - void onMediaActivityError(const ledger::VisitData& visit_data, - const std::string& providerType, - uint64_t windowId); - - void onMediaPublisherActivity( - ledger::Result result, - std::unique_ptr info, - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& media_key, - const std::string& media_id, - const std::string& publisher_blob); - - void onGetChannelIdFromUserPage( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& media_key, - int response_status_code, - const std::string& response, - const std::map& headers); - - void onGetMediaActivityFromUrl( - int response_status_code, - const std::string& response, - const std::map& headers, - const std::string& providerType, - const std::string& url, - uint64_t windowId); - - void processYoutubeMediaPanel(uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType); - - void processTwitchMediaPanel( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& publisher_blob); - - std::string getTwitchMediaIdFromUrl( - const ledger::VisitData& visit_data, - const std::string& publisher_blob) const; - - std::string getTwitchMediaKeyFromUrl( - const std::string& provider_type, - const std::string& id, - const std::string& url) const; - - std::string getUserFacingHandle(const std::string& publisher_blob) const; - - std::string getFaviconUrl( - const std::string& publisher_blob, - const std::string& twitchHandle) const; - - void onGetTwitchPublisherInfo( - ledger::Result result, - std::unique_ptr publisher_info, - uint64_t windowId, - const ledger::VisitData visit_data, - const std::string& providerType, - const std::string& media_key, - const std::string& media_id, - const std::string& publisher_blob); - - void updateTwitchPublisherData( - std::string* publisher_name, - std::string* publisher_favicon_url, - const std::string& publisher_blob); - - void processYoutubeWatchPath(uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType); - - void processYoutubeChannelPath(uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType); - - void onMediaUserActivity(ledger::Result result, - std::unique_ptr info, - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& media_key); - - void processYoutubeUserPath(uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType); - - void processYoutubeCustomPath( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& publisher_key); - - void onGetChannelHeadlineVideo( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - int response_status_code, - const std::string& response, - const std::map& headers, - const bool is_custom_path); - - void onFetchPublisherFromDBResponse( - ledger::Result result, - std::unique_ptr info, - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& publisher_key, - const std::string& publisher_blob, - const bool is_custom_path); - - void processYoutubeAsPublisherType(const std::string& data, - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType); - - std::string parseFavIconUrl(const std::string& data); - - std::string parseChannelId(const std::string& data); - - std::string getYoutubeMediaKeyFromUrl(const std::string& provider_type, - const std::string& media_id); - - std::string getPublisherUrl(const std::string& publisher_key, - const std::string& providerName); - - void fetchPublisherDataFromDB( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const std::string& publisher_key, - const std::string& publisher_blob, - const bool is_custom_path); - - void fetchDataFromUrl(const std::string& url, - FetchDataFromUrlCallback callback); - - static std::string getYoutubeMediaIdFromUrl( - const ledger::VisitData& visit_data); - - static std::string getYoutubePublisherKeyFromUrl(const std::string& path); - - static std::string getYoutubeUserFromUrl(const std::string& path); - - static std::string extractData(const std::string& data, - const std::string& matchAfter, - const std::string& matchUntil); - - std::string getNameFromChannel(const std::string& data); - - bool isPredefinedYTPath(const std::string& path) const; - - std::string parseChannelIdFromCustomPathPage( - const std::string& data); - - std::string getRealEnteredYTPath(const std::string& path) const; - - void onFetchDataFromNonEmbeddable( - uint64_t windowId, - const ledger::VisitData& visit_data, - const std::string& providerType, - const uint64_t& duration, - const std::string& media_key, - const std::string& mediaURL, - int response_status_code, - const std::string& response, - const std::map& headers); - - static std::string parsePublisherName(const std::string& data); + void OnMediaActivityError(const ledger::VisitData& visit_data, + const std::string& type, + uint64_t windowId); bat_ledger::LedgerImpl* ledger_; // NOT OWNED std::unique_ptr media_youtube_; std::unique_ptr media_twitch_; - - std::map twitchEvents; - - // For testing purposes - friend class BatGetMediaTest; - FRIEND_TEST_ALL_PREFIXES(BatGetMediaTest, GetYoutubeMediaIdFromUrl); - FRIEND_TEST_ALL_PREFIXES(BatGetMediaTest, GetYoutubePublisherKeyFromUrl); - FRIEND_TEST_ALL_PREFIXES(BatGetMediaTest, GetYoutubeUserFromUrl); - FRIEND_TEST_ALL_PREFIXES(BatGetMediaTest, getRealEnteredYTPath); - FRIEND_TEST_ALL_PREFIXES(BatGetMediaTest, GetNameFromChannel); - FRIEND_TEST_ALL_PREFIXES(BatGetMediaTest, ParsePublisherName); }; } // namespace braveledger_bat_get_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc index bd621844dff6..8c1119a4761a 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc @@ -185,7 +185,7 @@ void LedgerImpl::OnXHRLoad( // It is not a media supported type return; } - bat_get_media_->processMedia(parts, type, visit_data); + bat_get_media_->ProcessMedia(parts, type, visit_data); } void LedgerImpl::OnPostData( @@ -206,7 +206,7 @@ void LedgerImpl::OnPostData( if (TWITCH_MEDIA_TYPE == type) { braveledger_media::GetTwitchParts(post_data, &twitchParts); for (size_t i = 0; i < twitchParts.size(); i++) { - bat_get_media_->processMedia(twitchParts[i], type, visit_data); + bat_get_media_->ProcessMedia(twitchParts[i], type, visit_data); } } } From 242f1c22762475a9c35be49cc430e68ad232a7fb Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Mon, 15 Apr 2019 09:37:31 +0200 Subject: [PATCH 09/12] Cleanup --- .../src/bat/ledger/internal/bat_helper.h | 2 +- .../src/bat/ledger/internal/media/helper_unittest.cc | 2 +- .../src/bat/ledger/internal/media/twitch.h | 1 + .../src/bat/ledger/internal/media/twitch_unittest.cc | 2 +- .../src/bat/ledger/internal/media/youtube.cc | 9 ++------- .../src/bat/ledger/internal/media/youtube.h | 1 + 6 files changed, 7 insertions(+), 10 deletions(-) diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h index 1089164c60a3..c2087175828d 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h @@ -539,7 +539,7 @@ void set_ignore_for_testing(bool ignore); uint8_t niceware_mnemonic_to_bytes( const std::string& w, std::vector* bytes_out, - size_t *written, + size_t* written, std::vector wordDictionary); uint64_t getRandomValue(uint8_t min, uint8_t max); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc index 8218314f4803..7f29f98b749e 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc @@ -11,6 +11,6 @@ namespace braveledger_media { -// TODO add tests +// TODO(nejczdovc): add tests } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h index 6a1508490455..41f3c1d9aaf3 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h @@ -7,6 +7,7 @@ #define BRAVELEDGER_MEDIA_TWITCH_H_ #include +#include #include #include "bat/ledger/ledger.h" diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc index c0b65a9f9a3d..cb32a5d97d25 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc @@ -14,6 +14,6 @@ namespace braveledger_media { class MediaTwitchTest : public testing::Test { }; -// TODO add tests +// TODO(nejczdovc): add tests } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc index b634516e6f81..9e54d983e6e6 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc @@ -4,8 +4,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#include #include -#include #include "bat/ledger/internal/ledger_impl.h" #include "bat/ledger/internal/media/helper.h" @@ -203,7 +203,6 @@ std::string MediaYouTube::GetNameFromChannel(const std::string& data) { } // static -// before getYoutubePublisherKeyFromUrl std::string MediaYouTube::GetPublisherKeyFromUrl( const std::string& path) { if (path.empty()) { @@ -376,7 +375,6 @@ void MediaYouTube::ProcessActivityFromUrl(uint64_t window_id, OnMediaActivityError(visit_data, window_id); } -// before getPublisherInfoDataCallback void MediaYouTube::OnMediaPublisherInfo( const std::string& media_id, const std::string& media_key, @@ -617,7 +615,6 @@ void MediaYouTube::OnMediaPublisherActivity( } } -// before fetchPublisherDataFromDB void MediaYouTube::GetPublisherPanleInfo( uint64_t window_id, const ledger::VisitData& visit_data, @@ -641,8 +638,6 @@ void MediaYouTube::GetPublisherPanleInfo( _2)); } -// before onFetchPublisherFromDBResponse -// TODO(nejczdovc): better name as we use it for custom page as well void MediaYouTube::OnPublisherPanleInfo( uint64_t window_id, const ledger::VisitData& visit_data, @@ -665,7 +660,7 @@ void MediaYouTube::OnPublisherPanleInfo( } } -// TODO(nejczdovc): better to understand if name can be better +// TODO(nejczdovc): name can be better void MediaYouTube::GetChannelHeadlineVideo( uint64_t window_id, const ledger::VisitData& visit_data, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h index d526cb4b9757..33710f16adc2 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h @@ -7,6 +7,7 @@ #define BRAVELEDGER_MEDIA_YOUTUBE_H_ #include +#include #include #include "base/gtest_prod_util.h" From 353ef738cfa8c8bed2464c0f709b188a9df1a6b0 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Mon, 15 Apr 2019 11:07:06 +0200 Subject: [PATCH 10/12] Adds tests for helper file --- .../src/bat/ledger/internal/bat_get_media.cc | 2 + .../src/bat/ledger/internal/media/helper.cc | 30 +++-- .../src/bat/ledger/internal/media/helper.h | 1 + .../ledger/internal/media/helper_unittest.cc | 122 +++++++++++++++++- .../src/bat/ledger/internal/media/twitch.cc | 1 + 5 files changed, 144 insertions(+), 12 deletions(-) diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc index 1cc73577625a..63be251c70b2 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc @@ -3,6 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include + #include "bat/ledger/internal/bat_get_media.h" #include "bat/ledger/internal/ledger_impl.h" diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc index 6a34e1a59e15..90094b422fe1 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.cc @@ -6,10 +6,13 @@ #include "bat/ledger/internal/media/helper.h" #include "bat/ledger/internal/bat_helper.h" - namespace braveledger_media { std::string GetMediaKey(const std::string& mediaId, const std::string& type) { + if (mediaId.empty() || type.empty()) { + return std::string(); + } + return type + "_" + mediaId; } @@ -17,16 +20,19 @@ void GetTwitchParts( const std::string& query, std::vector>* parts) { size_t pos = query.find("data="); - if (std::string::npos != pos && query.length() > 5) { - std::string varValue = query.substr(5); - std::vector decoded; - bool succeded = braveledger_bat_helper::getFromBase64(varValue, &decoded); - if (succeded) { - decoded.push_back((uint8_t)'\0'); - braveledger_bat_helper::getJSONTwitchProperties( - reinterpret_cast(&decoded.front()), - parts); - } + + if (std::string::npos == pos || query.length() <= 5) { + return; + } + + std::string varValue = query.substr(5); + std::vector decoded; + bool succeded = braveledger_bat_helper::getFromBase64(varValue, &decoded); + if (succeded) { + decoded.push_back((uint8_t)'\0'); + braveledger_bat_helper::getJSONTwitchProperties( + reinterpret_cast(&decoded.front()), + parts); } } @@ -54,6 +60,8 @@ std::string ExtractData(const std::string& data, } else { match = data.substr(start_pos, std::string::npos); } + } else if (match_until.empty()) { + match = data.substr(start_pos, std::string::npos); } } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h index f31038e37da9..6f852bfdb8ba 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper.h @@ -6,6 +6,7 @@ #ifndef BRAVELEDGER_MEDIA_HELPER_H_ #define BRAVELEDGER_MEDIA_HELPER_H_ +#include #include #include #include diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc index 7f29f98b749e..079857b3a5ff 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc @@ -3,6 +3,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include +#include +#include + #include "bat/ledger/internal/media/helper.h" #include "bat/ledger/ledger.h" #include "testing/gtest/include/gtest/gtest.h" @@ -11,6 +15,122 @@ namespace braveledger_media { -// TODO(nejczdovc): add tests +class MediaHelperTest : public testing::Test { +}; + +TEST(MediaHelperTest, GetMediaKey) { + // provider is missing + std::string result = braveledger_media::GetMediaKey("key", ""); + ASSERT_EQ(result, ""); + + // key is missing + result = braveledger_media::GetMediaKey("", "youtube"); + ASSERT_EQ(result, ""); + + // all ok + result = braveledger_media::GetMediaKey("key", "youtube"); + ASSERT_EQ(result, "youtube_key"); +} + +TEST(MediaHelperTest, GetTwitchParts) { + std::vector> twitch_parts; + + // string is empty + braveledger_media::GetTwitchParts("", &twitch_parts); + ASSERT_EQ(twitch_parts.size(), 0u); + + // random string + braveledger_media::GetTwitchParts("this is random string", &twitch_parts); + ASSERT_EQ(twitch_parts.size(), 0u); + + const std::string post_data = + "data=W3siZXZlbnQiOiJtaW51dGUtd2F0Y2hlZCIsInByb3BlcnRpZXMiOnsiYXBwX3ZlcnN" + "pb24iOiI5LjI0LjAiLCJmbGFzaF92ZXJzaW9uIjoiMCwwLDAiLCJyZWZlcnJlcl91cmwiOiI" + "iLCJyZWZlcnJlcl9ob3N0IjoiIiwicmVmZXJyZXJfZG9tYWluIjoiIiwiYnJvd3NlciI6IjU" + "uMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMF8xNF8zKSBBcHBsZVdlYktpdC81Mzc" + "uMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvNzQuMC4zNzI5LjYxIFNhZmFyaS81Mzc" + "uMzYiLCJicm93c2VyX2ZhbWlseSI6ImNocm9tZSIsImJyb3dzZXJfdmVyc2lvbiI6Ijc0LjA" + "iLCJvc19uYW1lIjoibWFjT1MiLCJvc192ZXJzaW9uIjoiMTAuMTQuMyIsInVzZXJfYWdlbnQ" + "iOiJNb3ppbGxhLzUuMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMF8xNF8zKSBBcHB" + "sZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvNzQuMC4zNzI5LjY" + "xIFNhZmFyaS81MzcuMzYiLCJkZXZpY2VfaWQiOiIwOTM4MjFlYTZhYmQyN2MyIiwiZGlzdGl" + "uY3RfaWQiOiIwOTM4MjFlYTZhYmQyN2MyIiwic2Vzc2lvbl9kZXZpY2VfaWQiOiJITnpZRHp" + "3VzczWFlGUnJkRWttMkg1R1lQdktRWlFQbSIsImNsaWVudF9hcHAiOiJ0d2lsaWdodCIsImN" + "saWVudF9idWlsZF9pZCI6IjczZmQ4NTdjLWJmNWMtNGUyYS05OWQwLWFlYzBkZjNmODVlNSI" + "sInBsYXRmb3JtIjoid2ViIiwiY2hhbm5lbCI6ImRha290YXoiLCJiZW5jaG1hcmtfc2Vzc2l" + "vbl9pZCI6IlZhNjBDdjlqbFA1UmxoalY1QXpjNHFYNGhVcVk1Smt5IiwibXNlX3N1cHBvcnQ" + "iOnRydWUsImNvbnRlbnRfaWQiOiIiLCJjdXN0b21lcl9pZCI6IiIsInR1cmJvIjpmYWxzZSw" + "iYmFja2VuZCI6Im1lZGlhcGxheWVyIiwiYmFja2VuZF92ZXJzaW9uIjoiMi45LjMtNWM0NjU" + "0ODgiLCJnYW1lIjoiRm9ydG5pdGUiLCJicm9hZGNhc3Rlcl9zb2Z0d2FyZSI6InVua25vd25" + "fcnRtcCIsImxpdmUiOnRydWUsImNoYW5uZWxfaWQiOjM5Mjk4MjE4LCJjb250ZW50X21vZGU" + "iOiJsaXZlIiwicGFydG5lciI6dHJ1ZSwicXVhbGl0eSI6IkF1dG8iLCJzdHJlYW1fZm9ybWF" + "0IjoiY2h1bmtlZCIsImJhbmR3aWR0aCI6NzA3OS45ODgsImNsdXN0ZXIiOiJ2aWUwMSIsImN" + "1cnJlbnRfYml0cmF0ZSI6NzA3OS45ODgsImN1cnJlbnRfZnBzIjo2MCwiZGVjb2RlZF9mcmF" + "tZXMiOjE0NTMsImRyb3BwZWRfZnJhbWVzIjowLCJobHNfbGF0ZW5jeV9icm9hZGNhc3RlciI" + "6ODA1MiwiaGxzX2xhdGVuY3lfZW5jb2RlciI6ODAwMCwiaGxzX3RhcmdldF9kdXJhdGlvbiI" + "6NSwibWFuaWZlc3RfY2x1c3RlciI6InZpZTAxIiwibWFuaWZlc3Rfbm9kZSI6InZpZGVvLXd" + "lYXZlci52aWUwMSIsIm1hbmlmZXN0X25vZGVfdHlwZSI6IndlYXZlcl9jbHVzdGVyIiwic2V" + "ydmluZ19pZCI6ImIzYmNkN2VmNjc0ZjQxYTE5MTM0NmY5NWNiMWU0NzRiIiwibm9kZSI6InZ" + "pZGVvLWVkZ2UtNjljMTUwLnZpZTAxIiwidXNlcl9pcCI6Ijc3LjM4LjUxLjE5MSIsInZpZF9" + "kaXNwbGF5X2hlaWdodCI6MzI2LCJ2aWRfZGlzcGxheV93aWR0aCI6NTgwLCJ2aWRfaGVpZ2h" + "0Ijo5MDAsInZpZF93aWR0aCI6MTYwMCwidmlkZW9fYnVmZmVyX3NpemUiOjYuODE4NDE3OTk" + "5OTk5OTk4LCJ2b2RfY2RuX29yaWdpbiI6IiIsInZvZF9jZG5fcmVnaW9uIjoiIiwidm9sdW1" + "lIjowLjUsIm11dGVkIjpmYWxzZSwiaXNfaHR0cHMiOnRydWUsImF1dG9wbGF5ZWQiOnRydWU" + "sImF2ZXJhZ2VfYml0cmF0ZSI6MCwiYnJvYWRjYXN0X2lkIjozMzY5OTgzMjczNiwiY2FwdGl" + "vbnNfZW5hYmxlZCI6ZmFsc2UsImxhbmd1YWdlIjoiZW4tVVMiLCJtYW5pZmVzdF9icm9hZGN" + "hc3RfaWQiOjMzNjk5ODMyNzM2LCJtaW51dGVzX2xvZ2dlZCI6MSwiY2xvY2tfZHJpZnQiOi0" + "xMSwicGxheWVyX3NpemVfbW9kZSI6IiIsInF1YWxpdHlfY2hhbmdlX2NvdW50IjoyLCJzZWN" + "vbmRzX29mZnNldCI6MjUuMzU0LCJzdHJlYW1UeXBlIjoibGl2ZSIsInRhYl9zZXNzaW9uX2l" + "kIjoiZTM4MDBiZTIwOGU1OTcyZCIsInRpbWVfc3BlbnRfaGlkZGVuIjowLCJ0cmFuc2NvZGV" + "yX3R5cGUiOiIyMDE3VHJhbnNjb2RlWDI2NF9WMiIsImF1dG9fbXV0ZWQiOmZhbHNlLCJkZXZ" + "pY2VfcGl4ZWxfcmF0aW8iOjIsImVzdGltYXRlZF9iYW5kd2lkdGgiOjEyNjQ5NjQ5NywicGx" + "heWJhY2tfcmF0ZSI6MSwidHJhbnNwb3J0X3NlZ21lbnRzIjoxNSwidHJhbnNwb3J0X2ZpcnN" + "0X2J5dGVfbGF0ZW5jeSI6ODAxLCJ0cmFuc3BvcnRfc2VnbWVudF9kdXJhdGlvbiI6Mjk5OTE" + "sInRyYW5zcG9ydF9kb3dubG9hZF9kdXJhdGlvbiI6MTgwMCwidHJhbnNwb3J0X2Rvd25sb2F" + "kX2J5dGVzIjoyNzYxMDA1NiwiY29udGVudCI6ImdhbWVfYm94YXJ0IiwibWVkaXVtIjoidHd" + "pdGNoX2hvbWUiLCJjb2xsYXBzZV9sZWZ0IjpmYWxzZSwiY29sbGFwc2VfcmlnaHQiOmZhbHN" + "lLCJpdGVtX3RyYWNraW5nX2lkIjoiMDk5YmMyMGFmOGVmYTI4ZiIsIml0ZW1fcG9zaXRpb24" + "iOjAsInJvd19uYW1lIjoiVG9wR2FtZXNGb3JZb3UiLCJyb3dfcG9zaXRpb24iOjEsInRhZ19" + "maWx0ZXJfc2V0IjoiW10iLCJ0YWdfc2V0IjoiW1wiNmVhNmJjYTQtNDcxMi00YWI5LWE5MDY" + "tZTMzMzZhOWQ4MDM5XCJdIiwidGFnX3N0cmVhbWVyX3NldCI6IltdIiwiYXBwX3Nlc3Npb25" + "faWQiOiJlMzgwMGJlMjA4ZTU5NzJkIiwicGFnZV9zZXNzaW9uX2lkIjoiODkwNjc1OWZhOWE" + "wNzg4NSIsInJlZmVycmVyIjoiIiwicGxheV9zZXNzaW9uX2lkIjoiZGJXUVRwRkhSZU9jUEF" + "YV2M3bThoV3VRdmJ3OVZQR08iLCJ1cmwiOiJodHRwczovL3d3dy50d2l0Y2gudHYvZGFrb3R" + "heiIsImhvc3QiOiJ3d3cudHdpdGNoLnR2IiwiZG9tYWluIjoidHdpdGNoLnR2IiwibGF0ZW5" + "jeV9tb2RlX3RvZ2dsZSI6dHJ1ZSwibG93X2xhdGVuY3kiOmZhbHNlLCJoaWRkZW4iOmZhbHN" + "lLCJwbGF5ZXIiOiJzaXRlIiwiZW5jcnlwdGVkIjpmYWxzZSwidGltZSI6MTU1NTMxNjQ0NS4" + "0Mzd9fV0="; + + const std::vector> result = + {{ + {"channel", "dakotaz"}, + {"event", "minute-watched"}, + {"properties", ""}, + {"time", "1555316445.437000"} + }}; + + // all ok + braveledger_media::GetTwitchParts(post_data, &twitch_parts); + ASSERT_EQ(twitch_parts.size(), 1u); + ASSERT_EQ(twitch_parts, result); +} + +TEST(MediaHelperTest, ExtractData) { +// // string empty + std::string result = braveledger_media::ExtractData("", "/", "!"); + ASSERT_EQ(result, ""); + + // missing start + result = braveledger_media::ExtractData("st/find/me!", "", "!"); + ASSERT_EQ(result, "st/find/me"); + + // missing end + result = braveledger_media::ExtractData("st/find/me!", "/", ""); + ASSERT_EQ(result, "find/me!"); + + // all ok + result = braveledger_media::ExtractData("st/find/me!", "/", "!"); + ASSERT_EQ(result, "find/me"); +} } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc index a957a91625d3..cfd1101b5ad1 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc @@ -5,6 +5,7 @@ #include #include +#include #include #include "bat/ledger/internal/bat_helper.h" From ce0ba21707189ba03d2c48c3d7bc82925cb07ae7 Mon Sep 17 00:00:00 2001 From: Jason Sadler Date: Mon, 15 Apr 2019 06:20:01 -0400 Subject: [PATCH 11/12] Unit tests for YouTube media partial lint Updated death test env conditionals --- .../src/bat/ledger/internal/media/youtube.h | 9 + .../ledger/internal/media/youtube_unittest.cc | 282 ++++++++++++++++++ 2 files changed, 291 insertions(+) diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h index 33710f16adc2..ec38608ab4c4 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h @@ -173,6 +173,15 @@ class MediaYouTube : public ledger::LedgerCallbackHandler { FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetBasicPath); FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetNameFromChannel); FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetPublisherName); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetMediaIdFromParts); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetMediaDurationFromParts); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetVideoUrl); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetChannelUrl); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetFavIconUrl); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetChannelId); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetChannelIdFromCustomPathPage); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, IsPredefinedPath); + FRIEND_TEST_ALL_PREFIXES(MediaYouTubeTest, GetPublisherKey); }; } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube_unittest.cc index 00cd49ba43d4..4524a3d8c0e7 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube_unittest.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube_unittest.cc @@ -3,7 +3,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include +#include + #include "bat/ledger/internal/media/youtube.h" +#include "bat/ledger/internal/static_values.h" #include "bat/ledger/ledger.h" #include "testing/gtest/include/gtest/gtest.h" @@ -342,4 +346,282 @@ TEST(MediaYouTubeTest, GetPublisherName) { ASSERT_EQ(publisher_name, "A&B"); } +TEST(MediaYouTubeTest, GetLinkType) { + std::string url("https://www.youtube.com/api/stats/watchtime?v=IwFp93_32u"); + std::string link_type(MediaYouTube::GetLinkType(url)); + EXPECT_EQ(link_type, YOUTUBE_MEDIA_TYPE); + + // null case + url = std::string(); + link_type = MediaYouTube::GetLinkType(url); + EXPECT_TRUE(link_type.empty()); + + url = "https://ww.youtube.com/api/stats/watchtime?v=IwFp93_32u"; + link_type = MediaYouTube::GetLinkType(url); + EXPECT_TRUE(link_type.empty()); + + url = "http://www.youtube.com/api/stats/watchtime?v=IwFp93_32u"; + link_type = MediaYouTube::GetLinkType(url); + EXPECT_TRUE(link_type.empty()); + + url = "https://www.youtube.com/api/stats/watchtimev=IwFp93_32u"; + link_type = MediaYouTube::GetLinkType(url); + EXPECT_TRUE(link_type.empty()); + + url = "https://m.youtube.com/api/stats/watchtime?v=IwFp93_32u"; + link_type = MediaYouTube::GetLinkType(url); + EXPECT_EQ(link_type, YOUTUBE_MEDIA_TYPE); + + url = "https://n.youtube.com/api/stats/watchtime?v=IwFp93_32u"; + link_type = MediaYouTube::GetLinkType(url); + EXPECT_TRUE(link_type.empty()); + + url = "http://m.youtube.com/api/stats/watchtime?v=IwFp93_32u"; + link_type = MediaYouTube::GetLinkType(url); + EXPECT_TRUE(link_type.empty()); + + url = "https://m.youtube.com/api/stats/watchtimev=IwFp93_32u"; + link_type = MediaYouTube::GetLinkType(url); + EXPECT_TRUE(link_type.empty()); +} + +TEST(MediaYouTubeTest, GetMediaIdFromParts) { + std::map parts; + + std::string docid("FsC15IBOpxw"); + parts.insert(std::pair("docid", docid)); + std::string id(MediaYouTube::GetMediaIdFromParts(parts)); + EXPECT_EQ(id, docid); + + // null case + parts.clear(); + docid = std::string(); + parts.insert(std::pair("docid", docid)); + id = MediaYouTube::GetMediaIdFromParts(parts); + EXPECT_EQ(id, docid); + + parts.clear(); + docid = "RL8QEXcQZE8"; + parts.insert(std::pair("docid", docid)); + id = MediaYouTube::GetMediaIdFromParts(parts); + EXPECT_EQ(id, docid); + + parts.clear(); + docid = "rxwYlx18KK4"; + parts.insert(std::pair("docid", docid)); + id = MediaYouTube::GetMediaIdFromParts(parts); + EXPECT_EQ(id, docid); + + parts.clear(); + docid = "qPFJZLFACTw"; + parts.insert(std::pair("docid", docid)); + id = MediaYouTube::GetMediaIdFromParts(parts); + EXPECT_EQ(id, docid); +} + +TEST(MediaYouTubeTest, GetMediaDurationFromParts) { + std::map parts; + + // straight play + std::string start_times("0,0.672,3.784"); + std::string end_times("0.672,3.784,7.972"); + parts.insert(std::pair("st", start_times)); + parts.insert(std::pair("et", end_times)); + uint64_t duration(MediaYouTube::GetMediaDurationFromParts( + parts, std::string())); + EXPECT_EQ(duration, (uint64_t)8); + + // null case + // with pause/seek/etc + parts.clear(); + start_times = std::string(); + end_times = std::string(); + parts.insert(std::pair("st", start_times)); + parts.insert(std::pair("et", end_times)); + duration = MediaYouTube::GetMediaDurationFromParts( + parts, std::string()); + EXPECT_EQ(duration, (uint64_t)0); + + // with pause/seek/etc + parts.clear(); + start_times = "0,34.75,82.1,85.6"; + end_times = "15.5,44.3,82.7,90"; + parts.insert(std::pair("st", start_times)); + parts.insert(std::pair("et", end_times)); + duration = MediaYouTube::GetMediaDurationFromParts( + parts, std::string()); + EXPECT_EQ(duration, (uint64_t)31); + + // round down from 0.1 offset + parts.clear(); + start_times = "0,34.75,82.1,85.6"; + end_times = "15.4,44.3,82.7,90"; + parts.insert(std::pair("st", start_times)); + parts.insert(std::pair("et", end_times)); + duration = MediaYouTube::GetMediaDurationFromParts( + parts, std::string()); + EXPECT_EQ(duration, (uint64_t)30); +} + +TEST(MediaYouTubeTest, GetVideoUrl) { + std::string media_url("https://www.youtube.com/watch?v="); + // null case + std::string media_id; + std::string url; +#if defined(OFFICIAL_BUILD) + url = MediaYouTube::GetVideoUrl(media_id); + EXPECT_EQ(url, media_url); +#else + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + EXPECT_DEATH({ + MediaYouTube::GetVideoUrl(media_id); + }, "Check failed: !media_id.empty*"); +#endif + + media_id = "FsC15IBOpxw"; + url = MediaYouTube::GetVideoUrl(media_id); + EXPECT_EQ(url, media_url + media_id); + + media_id = "RL8QEXcQZE8"; + url = MediaYouTube::GetVideoUrl(media_id); + EXPECT_EQ(url, media_url + media_id); + + media_id = "rxwYlx18KK4"; + url = MediaYouTube::GetVideoUrl(media_id); + EXPECT_EQ(url, media_url + media_id); + + media_id = "qPFJZLFACTw"; + url = MediaYouTube::GetVideoUrl(media_id); + EXPECT_EQ(url, media_url + media_id); +} + +TEST(MediaYouTubeTest, GetChannelUrl) { + std::string channel_url("https://www.youtube.com/channel/"); + // null case + std::string channel_id; + std::string url; +#if defined(OFFICIAL_BUILD) + url = MediaYouTube::GetChannelUrl(channel_id); + EXPECT_EQ(url, channel_url); +#else + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + EXPECT_DEATH({ + MediaYouTube::GetChannelUrl(channel_id); + }, "Check failed: !publisher_key.empty*"); +#endif + + channel_id = "UCFNTTISby1c_H-rm5Ww5rZg"; + url = MediaYouTube::GetChannelUrl(channel_id); + EXPECT_EQ(url, channel_url + channel_id); + + channel_id = "UC7I7VAGLNgIgK0oPzTgpgmw"; + url = MediaYouTube::GetChannelUrl(channel_id); + EXPECT_EQ(url, channel_url + channel_id); +} + +TEST(MediaYouTubeTest, GetFavIconUrl) { + // null case + std::string data; + std::string favicon_url(MediaYouTube::GetFavIconUrl(data)); + EXPECT_TRUE(favicon_url.empty()); + + data = "{\"topbarMenuButtonRenderer\":{\"avatar\":{\"thumbnails\":[{\"url\":" + "\"https://yt3.ggpht.com/-m_NJNWwcbN8/AAAAAAAAAAI/AAAAAAAAAAA/KdHchFE" + "_0pg/s88-c-k-no-mo-rj-c0xffffff/photo.jpg\",\"width\":88,\"height\":" + "88}],\"webThumbnailDetailsExtensionData\":{\"excludeFromVpl\":true}}" + ",\"menuRequest\":{\"clickTrackingParams\":\"CA8Q_qsBGAQiEwjL_qOa3tDh" + "AhXQuMQKHaYMCmMo-B0=\",\"commandMetadata\":{\"webCommandMetadata\":{" + "\"url\":\"/service_ajax\",\"sendPost\":true}},\"signalServiceEndpoin" + "t\":{\"signal\":\"GET_ACCOUNT_MENU\",\"actions\":[{\"openPopupAction" + "\":{\"popup\":{\"multiPageMenuRenderer\":"; + favicon_url = MediaYouTube::GetFavIconUrl(data); + std::string expected_favicon_url( + "https://yt3.ggpht.com/-m_NJNWwcbN8/AAAAAAAAAAI/AAAAAAAAAAA/KdHchFE" + "_0pg/s88-c-k-no-mo-rj-c0xffffff/photo.jpg"); + EXPECT_EQ(favicon_url, expected_favicon_url); +} + +TEST(MediaYouTubeTest, GetChannelId) { + // null case + std::string data; + std::string channel_id(MediaYouTube::GetChannelId(data)); + EXPECT_TRUE(channel_id.empty()); + + data = "
Brave"; + channel_id = MediaYouTube::GetChannelId(data); + std::string expected_channel_id("UCFNTTISby1c_H-rm5Ww5rZg"); + EXPECT_EQ(channel_id, expected_channel_id); +} + +TEST(MediaYouTubeTest, GetChannelIdFromCustomPathPage) { + // null case + std::string data; + std::string channel_id(MediaYouTube::GetChannelIdFromCustomPathPage(data)); + EXPECT_TRUE(channel_id.empty()); + + data = "window[\"ytInitialData\"] = {\"responseContext\":{\"serviceTrackingPa" + "rams\":[{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"browse_id\"" + ",\"value\":\"UCFNTTISby1c_H-rm5Ww5rZg\"},{\"key\":\"context\",\"valu" + "e\":\"channel_creator\"},{\"key\":\"has_unlimited_entitlement\",\"val" + "ue\":\"False\"},{\"key\":\"has_unlimited_ncc_free_trial\",\"value\"" + ":\"False\"},{\"key\":\"e\",\"value\":\"23735277,23736685,23744176,237" + "49401,23751767,23752869,23755886,23755898,23758187,"; + channel_id = MediaYouTube::GetChannelIdFromCustomPathPage(data); + std::string expected_channel_id("UCFNTTISby1c_H-rm5Ww5rZg"); + EXPECT_EQ(channel_id, expected_channel_id); +} + +TEST(MediaYouTubeTest, IsPredefinedPath) { + // null case + std::string path; + EXPECT_FALSE(MediaYouTube::IsPredefinedPath(path)); + path = "/gaming"; + EXPECT_TRUE(MediaYouTube::IsPredefinedPath(path)); + path = "/watch?v=abcdefg"; + EXPECT_TRUE(MediaYouTube::IsPredefinedPath(path)); + path = "/playlist?list=0000000000"; + EXPECT_TRUE(MediaYouTube::IsPredefinedPath(path)); + path = "/bravesoftware"; + EXPECT_FALSE(MediaYouTube::IsPredefinedPath(path)); + path = "/bravesoftware/videos"; + EXPECT_FALSE(MediaYouTube::IsPredefinedPath(path)); + path = "/bravesoftware/playlists"; + EXPECT_FALSE(MediaYouTube::IsPredefinedPath(path)); + path = "/bravesoftware/community"; + EXPECT_FALSE(MediaYouTube::IsPredefinedPath(path)); + path = "/bravesoftware/channels"; + EXPECT_FALSE(MediaYouTube::IsPredefinedPath(path)); + path = "/bravesoftware/about"; + EXPECT_FALSE(MediaYouTube::IsPredefinedPath(path)); + path = "/gaminggiant"; + EXPECT_FALSE(MediaYouTube::IsPredefinedPath(path)); + path = "/feed/trending"; + EXPECT_TRUE(MediaYouTube::IsPredefinedPath(path)); + path = "/subscription_manager?disable_polymer=1"; + EXPECT_TRUE(MediaYouTube::IsPredefinedPath(path)); +} + +TEST(MediaYouTubeTest, GetPublisherKey) { + std::string publisher_key_prefix( + (std::string)YOUTUBE_MEDIA_TYPE + "#channel:"); + + // null case + std::string key; + std::string publisher_key(MediaYouTube::GetPublisherKey(key)); + EXPECT_EQ(publisher_key, publisher_key_prefix); + + key = "UCFNTTISby1c_H-rm5Ww5rZg"; + publisher_key = MediaYouTube::GetPublisherKey(key); + EXPECT_EQ(publisher_key, publisher_key_prefix + key); + + key = "UC7I7VAGLNgIgK0oPzTgpgmw"; + publisher_key = MediaYouTube::GetPublisherKey(key); + EXPECT_EQ(publisher_key, publisher_key_prefix + key); +} + } // namespace braveledger_media From 8022a70547f12120bb6282b731aacc96dd23daf2 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Mon, 15 Apr 2019 12:18:08 +0200 Subject: [PATCH 12/12] Twitch tests --- .../src/bat/ledger/internal/bat_get_media.h | 1 + .../src/bat/ledger/internal/media/twitch.cc | 19 +- .../src/bat/ledger/internal/media/twitch.h | 14 ++ .../ledger/internal/media/twitch_unittest.cc | 235 +++++++++++++++++- 4 files changed, 266 insertions(+), 3 deletions(-) diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h index 767625d3c843..fd05080149ef 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h @@ -8,6 +8,7 @@ #include #include +#include #include "bat/ledger/internal/bat_helper.h" #include "bat/ledger/internal/media/twitch.h" diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc index cfd1101b5ad1..24c79327a5af 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc @@ -7,6 +7,7 @@ #include #include #include +#include #include "bat/ledger/internal/bat_helper.h" #include "bat/ledger/internal/ledger_impl.h" @@ -69,7 +70,10 @@ std::string MediaTwitch::GetMediaIdFromParts( std::string MediaTwitch::GetMediaURL(const std::string& media_id) { std::string res; - DCHECK(!media_id.empty()); + if (media_id.empty()) { + return std::string(); + } + return "https://www.twitch.tv/" + media_id; } @@ -174,6 +178,8 @@ std::string MediaTwitch::GetLinkType(const std::string& url, bool is_valid_twitch_path = braveledger_bat_helper::HasSameDomainAndPath( url, "ttvnw.net", "/v1/segment/"); + + std::cout << is_valid_twitch_path << first_party_url; if ( ( (first_party_url.find("https://www.twitch.tv/") == 0 || @@ -192,6 +198,7 @@ std::string MediaTwitch::GetMediaIdFromUrl( const std::string& url, const std::string& publisher_blob) { std::string mediaId = braveledger_media::ExtractData(url, "twitch.tv/", "/"); + if (url.find("twitch.tv/videos/") != std::string::npos) { mediaId = braveledger_media::ExtractData(publisher_blob, "" "
" @@ -252,6 +263,10 @@ std::string MediaTwitch::GetFaviconUrl( // static std::string MediaTwitch::GetPublisherKey(const std::string& key) { + if (key.empty()) { + return std::string(); + } + return (std::string)TWITCH_MEDIA_TYPE + "#author:" + key; } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h index 41f3c1d9aaf3..2d1bf9a1b6b0 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h @@ -10,6 +10,7 @@ #include #include +#include "base/gtest_prod_util.h" #include "bat/ledger/ledger.h" #include "bat/ledger/internal/media/helper.h" @@ -122,6 +123,19 @@ class MediaTwitch : public ledger::LedgerCallbackHandler { bat_ledger::LedgerImpl* ledger_; // NOT OWNED std::map twitch_events; + + // For testing purposes + friend class MediaTwitchTest; + FRIEND_TEST_ALL_PREFIXES(MediaTwitchTest, GetMediaIdFromParts); + FRIEND_TEST_ALL_PREFIXES(MediaTwitchTest, GetMediaURL); + FRIEND_TEST_ALL_PREFIXES(MediaTwitchTest, GetTwitchStatus); + FRIEND_TEST_ALL_PREFIXES(MediaTwitchTest, GetTwitchDuration); + FRIEND_TEST_ALL_PREFIXES(MediaTwitchTest, GetMediaIdFromUrl); + FRIEND_TEST_ALL_PREFIXES(MediaTwitchTest, GetMediaKeyFromUrl); + FRIEND_TEST_ALL_PREFIXES(MediaTwitchTest, GetPublisherKey); + FRIEND_TEST_ALL_PREFIXES(MediaTwitchTest, UpdatePublisherData); + FRIEND_TEST_ALL_PREFIXES(MediaTwitchTest, GetPublisherName); + FRIEND_TEST_ALL_PREFIXES(MediaTwitchTest, GetFaviconUrl); }; } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc index cb32a5d97d25..06f1283da2f9 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc @@ -14,6 +14,239 @@ namespace braveledger_media { class MediaTwitchTest : public testing::Test { }; -// TODO(nejczdovc): add tests +const char profile_html[] = + "
\"dakotaz\"
dakotaz
" + "
Verified User
"; + +TEST(MediaTwitchTest, GetMediaIdFromParts) { + // empty + std::string result = MediaTwitch::GetMediaIdFromParts({}); + ASSERT_EQ(result, ""); + + // event is not on the list + result = MediaTwitch::GetMediaIdFromParts({ + {"event", "test"}, + {"properties", ""} + }); + ASSERT_EQ(result, ""); + + // properties are missing + result = MediaTwitch::GetMediaIdFromParts({ + {"event", "minute-watched"} + }); + ASSERT_EQ(result, ""); + + // channel is missing + result = MediaTwitch::GetMediaIdFromParts({ + {"event", "minute-watched"}, + {"properties", ""} + }); + ASSERT_EQ(result, ""); + + // channel is provided + result = MediaTwitch::GetMediaIdFromParts({ + {"event", "minute-watched"}, + {"properties", ""}, + {"channel", "dakotaz"} + }); + ASSERT_EQ(result, "dakotaz"); + + // vod is missing leading v + result = MediaTwitch::GetMediaIdFromParts({ + {"event", "minute-watched"}, + {"properties", ""}, + {"channel", "dakotaz"}, + {"vod", "123312312"} + }); + ASSERT_EQ(result, "dakotaz"); + + // vod is provided + result = MediaTwitch::GetMediaIdFromParts({ + {"event", "minute-watched"}, + {"properties", ""}, + {"channel", "dakotaz"}, + {"vod", "v123312312"} + }); + ASSERT_EQ(result, "dakotaz_vod_123312312"); +} + +TEST(MediaTwitchTest, GetMediaURL) { + // empty + std::string result = MediaTwitch::GetMediaURL(""); + ASSERT_EQ(result, ""); + + // all ok + result = MediaTwitch::GetMediaURL("dakotaz"); + ASSERT_EQ(result, "https://www.twitch.tv/dakotaz"); +} + +TEST(MediaTwitchTest, GetTwitchStatus) { + // empty + ledger::TwitchEventInfo old_event; + ledger::TwitchEventInfo new_event; + std::string result = MediaTwitch::GetTwitchStatus(old_event, new_event); + ASSERT_EQ(result, "playing"); + + // user paused the video + old_event.event_ = "video_pause"; + old_event.status_ = "playing"; + new_event.event_ = "video_pause"; + result = MediaTwitch::GetTwitchStatus(old_event, new_event); + ASSERT_EQ(result, "paused"); + + // user seeked while video was paused + old_event.status_ = "paused"; + new_event.event_ = "player_click_vod_seek"; + result = MediaTwitch::GetTwitchStatus(old_event, new_event); + ASSERT_EQ(result, "paused"); + + // user skipped the video that was playing + old_event.status_ = "playing"; + old_event.event_ = "video_pause"; + new_event.event_ = "player_click_vod_seek"; + result = MediaTwitch::GetTwitchStatus(old_event, new_event); + ASSERT_EQ(result, "playing"); + + // user pauses a video, then seeks it and plays it again + old_event.status_ = "paused"; + old_event.event_ = "player_click_vod_seek"; + new_event.event_ = "video_pause"; + result = MediaTwitch::GetTwitchStatus(old_event, new_event); + ASSERT_EQ(result, "playing"); +} + +TEST(MediaTwitchTest, GetLinkType ) { + const std::string url("https://k8923479-sub.cdn.ttvnw.net/v1/segment/"); + + // url is not correct + std::string result = MediaTwitch::GetLinkType("https://brave.com", + "https://www.twitch.tv", + ""); + ASSERT_EQ(result, ""); + + // first party is off + result = MediaTwitch::GetLinkType(url, "https://www.brave.com", ""); + ASSERT_EQ(result, ""); + + // regular page + result = MediaTwitch::GetLinkType(url, "https://www.twitch.tv/", ""); + ASSERT_EQ(result, "twitch"); + + // mobile page + result = MediaTwitch::GetLinkType(url, "https://m.twitch.tv/", ""); + ASSERT_EQ(result, "twitch"); + + // player page + result = MediaTwitch::GetLinkType(url, + "https://brave.com/", + "https://player.twitch.tv/"); + ASSERT_EQ(result, "twitch"); +} + +TEST(MediaTwitchTest, GetMediaKeyFromUrl) { + // id is empty + std::string result = MediaTwitch::GetMediaKeyFromUrl("", ""); + ASSERT_EQ(result, ""); + + // id is twitch + result = MediaTwitch::GetMediaKeyFromUrl("twitch", ""); + ASSERT_EQ(result, ""); + + // get vod id + result = MediaTwitch::GetMediaKeyFromUrl( + "dakotaz", + "https://www.twitch.tv/videos/411403500"); + ASSERT_EQ(result, "twitch_dakotaz_vod_411403500"); + + // regular id + result = MediaTwitch::GetMediaKeyFromUrl("dakotaz", ""); + ASSERT_EQ(result, "twitch_dakotaz"); +} + +TEST(MediaTwitchTest, GetPublisherKey) { + // empty + std::string result = MediaTwitch::GetPublisherKey(""); + ASSERT_EQ(result, ""); + + // all ok + result = MediaTwitch::GetPublisherKey("key"); + ASSERT_EQ(result, "twitch#author:key"); +} + +TEST(MediaTwitchTest, GetPublisherName) { + // blob is not correct + std::string result = MediaTwitch::GetPublisherName("dfsfsdfsdfds"); + ASSERT_EQ(result, ""); + + // all ok + result = MediaTwitch::GetPublisherName(profile_html); + ASSERT_EQ(result, "dakotaz"); +} + +TEST(MediaTwitchTest, GetFaviconUrl) { + // handler is empty + std::string result = MediaTwitch::GetFaviconUrl(profile_html, ""); + ASSERT_EQ(result, ""); + + // blob is not correct + result = MediaTwitch::GetFaviconUrl("dfsfsdfsdfds", "dakotaz"); + ASSERT_EQ(result, ""); + + // all ok + result = MediaTwitch::GetFaviconUrl(profile_html, "dakotaz"); + ASSERT_EQ(result, + "https://static-cdn.jtvnw.net/jtv_user_pictures/473aea0f-a724-498" + "f-b7f1-e344f806ba8a-profile_image-70x70.png"); +} + +TEST(MediaTwitchTest, UpdatePublisherData) { + // blob is not correct + std::string name; + std::string favicon_url; + MediaTwitch::UpdatePublisherData( + &name, + &favicon_url, + "dfsfsdfsdfds"); + + ASSERT_EQ(name, ""); + ASSERT_EQ(favicon_url, ""); + + // all ok + MediaTwitch::UpdatePublisherData( + &name, + &favicon_url, + profile_html); + + ASSERT_EQ(name, "dakotaz"); + ASSERT_EQ(favicon_url, + "https://static-cdn.jtvnw.net/jtv_user_pictures/473aea0f-a724-498" + "f-b7f1-e344f806ba8a-profile_image-70x70.png"); +} } // namespace braveledger_media