Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason Sadler committed Jun 6, 2019
1 parent ce50fe0 commit 47b456a
Show file tree
Hide file tree
Showing 10 changed files with 527 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@
"@types/react-redux": "6.0.4",
"@types/redux-logger": "^3.0.7",
"awesome-typescript-loader": "^5.2.1",
"brave-ui": "github:brave/brave-ui#82b3e981040b2ba89743108e6701f5fa24ce3b52",
"brave-ui": "github:brave/brave-ui#939d492a3e31e92021105684e0dbfc1399ee9df2",
"css-loader": "^2.1.1",
"csstype": "^2.5.5",
"deep-freeze-node": "^1.1.3",
Expand Down
1 change: 1 addition & 0 deletions test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ test("brave_unit_tests") {
if (brave_rewards_enabled) {
sources += [
"//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc",
"//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/reddit_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/twitter_unittest.cc",
"//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube_unittest.cc",
Expand Down
2 changes: 2 additions & 0 deletions vendor/bat-native-ledger/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ source_set("ledger") {
"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/reddit.h",
"src/bat/ledger/internal/media/reddit.cc",
"src/bat/ledger/internal/media/twitch.h",
"src/bat/ledger/internal/media/twitch.cc",
"src/bat/ledger/internal/media/twitter.h",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ BatGetMedia::BatGetMedia(bat_ledger::LedgerImpl* ledger):
ledger_(ledger),
media_youtube_(new braveledger_media::MediaYouTube(ledger)),
media_twitch_(new braveledger_media::MediaTwitch(ledger)),
media_twitter_(new braveledger_media::MediaTwitter(ledger)) {
media_twitter_(new braveledger_media::MediaTwitter(ledger)),
media_reddit_(new braveledger_media::MediaReddit(ledger)) {
}

BatGetMedia::~BatGetMedia() {}
Expand Down Expand Up @@ -70,6 +71,8 @@ void BatGetMedia::GetMediaActivityFromUrl(
} else if (type == TWITTER_MEDIA_TYPE) {
media_twitter_->ProcessActivityFromUrl(window_id,
visit_data);
} else if (type == REDDIT_MEDIA_TYPE) {
media_reddit_->ProcessActivityFromUrl(window_id, visit_data);
} else {
OnMediaActivityError(visit_data, type, window_id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <memory>

#include "bat/ledger/internal/bat_helper.h"
#include "bat/ledger/internal/media/reddit.h"
#include "bat/ledger/internal/media/twitch.h"
#include "bat/ledger/internal/media/twitter.h"
#include "bat/ledger/internal/media/youtube.h"
Expand Down Expand Up @@ -58,6 +59,7 @@ class BatGetMedia {
std::unique_ptr<braveledger_media::MediaYouTube> media_youtube_;
std::unique_ptr<braveledger_media::MediaTwitch> media_twitch_;
std::unique_ptr<braveledger_media::MediaTwitter> media_twitter_;
std::unique_ptr<braveledger_media::MediaReddit> media_reddit_;
};

} // namespace braveledger_bat_get_media
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,8 @@ void BatPublishers::getPublisherActivityFromUrl(

const bool is_media = visit_data.domain == YOUTUBE_TLD ||
visit_data.domain == TWITCH_TLD ||
visit_data.domain == TWITTER_TLD;
visit_data.domain == TWITTER_TLD ||
visit_data.domain == REDDIT_TLD;

if (is_media &&
visit_data.path != "" && visit_data.path != "/") {
Expand All @@ -716,6 +717,8 @@ void BatPublishers::getPublisherActivityFromUrl(
type = TWITCH_MEDIA_TYPE;
} else if (visit_data.domain == TWITTER_TLD) {
type = TWITTER_MEDIA_TYPE;
} else if (visit_data.domain == REDDIT_TLD) {
type = REDDIT_MEDIA_TYPE;
}

ledger::VisitData new_visit_data(visit_data);
Expand Down
284 changes: 284 additions & 0 deletions vendor/bat-native-ledger/src/bat/ledger/internal/media/reddit.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
/* 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 <cmath>
#include <utility>
#include <vector>

#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "bat/ledger/internal/ledger_impl.h"
#include "bat/ledger/internal/media/helper.h"
#include "bat/ledger/internal/media/reddit.h"
#include "net/http/http_status_code.h"
#include "url/url_canon.h"
#include "url/gurl.h"

using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;

namespace braveledger_media {

MediaReddit::MediaReddit(bat_ledger::LedgerImpl* ledger): ledger_(ledger) {
}

MediaReddit::~MediaReddit() {
}

void MediaReddit::ProcessActivityFromUrl(
uint64_t window_id,
const ledger::VisitData& visit_data) {
if (visit_data.path.find("/user/") != std::string::npos) {
UserPath(window_id, visit_data);
return;
}
OnMediaActivityError(visit_data, window_id);
}

void MediaReddit::OnMediaActivityError(
const ledger::VisitData& visit_data,
uint64_t window_id) {

ledger::VisitData new_visit_data;
new_visit_data.domain = REDDIT_TLD;
new_visit_data.url = "https://" + (std::string)REDDIT_TLD;
new_visit_data.path = "/";
new_visit_data.name = REDDIT_MEDIA_TYPE;

ledger_->GetPublisherActivityFromUrl(
window_id, new_visit_data, std::string());
}

void MediaReddit::UserPath(
uint64_t window_id,
const ledger::VisitData& visit_data) {
const std::string user = GetUserNameFromUrl(visit_data.path);

if (user.empty()) {
OnMediaActivityError(visit_data, window_id);
return;
}

const std::string media_key = (std::string)REDDIT_MEDIA_TYPE + "_" + user;
ledger_->GetMediaPublisherInfo(media_key,
std::bind(&MediaReddit::OnUserActivity,
this,
window_id,
visit_data,
media_key,
_1,
_2));
}

void MediaReddit::OnUserActivity(
uint64_t window_id,
const ledger::VisitData& visit_data,
const std::string& media_key,
ledger::Result result,
ledger::PublisherInfoPtr publisher_info) {
if (!publisher_info || result == ledger::Result::NOT_FOUND) {
const std::string user_name = GetUserNameFromUrl(visit_data.path);
const std::string url = GetProfileUrl(user_name);
FetchDataFromUrl(visit_data.url,
std::bind(&MediaReddit::OnUserPage,
this,
window_id,
visit_data,
_1,
_2,
_3));
} else {
GetPublisherPanelInfo(
window_id,
visit_data,
publisher_info->id);
}
}

void MediaReddit::FetchDataFromUrl(
const std::string& url,
braveledger_media::FetchDataFromUrlCallback callback) {
/* if user is on old reddit, sub the url to get the icon
since old reddit didn't have user icons */
GURL reddit_url(url);
if (reddit_url.DomainIs(OLD_REDDIT_DOMAIN)) {
// Canonicalize away 'old.reddit.com' and replace with 'www.reddit.com'.
std::string new_host = reddit_url.host();
new_host.replace(0, 3, "www");
url::Replacements<char> replacements;
replacements.SetHost(new_host.c_str(),
url::Component(0, new_host.length()));
reddit_url = reddit_url.ReplaceComponents(replacements);
}

ledger_->LoadURL(reddit_url.spec(),
std::vector<std::string>(),
std::string(),
std::string(),
ledger::URL_METHOD::GET,
callback);
}

// static
std::string MediaReddit::GetUserNameFromUrl(const std::string& path) {
if (path.empty()) {
return std::string();
}

const std::vector<std::string> parts = base::SplitString(
path, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

if (parts.size() > 1) {
return parts.at(1);
}

return std::string();
}

// static
std::string MediaReddit::GetProfileUrl(const std::string& screen_name) {
if (screen_name.empty()) {
return std::string();
}
const std::string url_part = "https://" + (std::string)REDDIT_TLD +
"/user/%s/";
return base::StringPrintf(url_part.c_str(), screen_name.c_str());
}

void MediaReddit::GetPublisherPanelInfo(
uint64_t window_id,
const ledger::VisitData& visit_data,
const std::string& publisher_key) {
const auto filter = ledger_->CreateActivityFilter(
publisher_key,
ledger::EXCLUDE_FILTER::FILTER_ALL,
false,
ledger_->GetReconcileStamp(),
true,
false);
ledger_->GetPanelPublisherInfo(filter,
std::bind(&MediaReddit::OnPublisherPanelInfo,
this,
window_id,
visit_data,
publisher_key,
_1,
_2));
}

void MediaReddit::OnPublisherPanelInfo(
uint64_t window_id,
const ledger::VisitData& visit_data,
const std::string& publisher_key,
ledger::Result result,
ledger::PublisherInfoPtr info) {
if (!info || result == ledger::Result::NOT_FOUND) {
FetchDataFromUrl(visit_data.url,
std::bind(&MediaReddit::OnUserPage,
this,
window_id,
visit_data,
_1,
_2,
_3));
} else {
ledger_->OnPanelPublisherInfo(result, std::move(info), window_id);
}
}

// static
std::string MediaReddit::GetUserId(const std::string& response) {
if (response.empty()) {
return std::string();
}

std::string id(braveledger_media::ExtractData(
response, "hideFromRobots\":false,\"id\":\"t2_", "\""));

if (id.empty()) {
id = braveledger_media::ExtractData(
response, "target_fullname\": \"t2_", "\""); // old reddit
}
return id;
}

// static
std::string MediaReddit::GetPublisherName(const std::string& response) {
if (response.empty()) {
return std::string();
}

std::string user_name(braveledger_media::ExtractData(
response, "username\":\"", "\""));

if (user_name.empty()) {
user_name = braveledger_media::ExtractData(
response, "target_name\": \"", "\""); // old reddit
}
return user_name;
}

void MediaReddit::OnUserPage(
uint64_t window_id,
const ledger::VisitData& visit_data,
int response_status_code,
const std::string& response,
const std::map<std::string, std::string>& headers) {
if (response_status_code != net::HTTP_OK) {
OnMediaActivityError(visit_data, window_id);
return;
}

const std::string user_name = GetUserNameFromUrl(visit_data.path);
const std::string publisher_name = GetPublisherName(response);
const std::string user_id = GetUserId(response);
const std::string publisher_key = GetPublisherKey(user_id);
const std::string media_key = GetMediaKey(user_name, REDDIT_MEDIA_TYPE);

ledger::VisitData new_visit_data(visit_data);
new_visit_data.provider = REDDIT_MEDIA_TYPE;
new_visit_data.url = GetProfileUrl(user_name);
new_visit_data.favicon_url = GetProfileImageUrl(response);
new_visit_data.name = publisher_name.empty() ? user_name : publisher_name;

ledger_->SaveMediaVisit(
publisher_key,
new_visit_data,
0,
window_id,
std::bind(&MediaReddit::OnUserActivity,
this,
window_id,
visit_data,
user_id,
_1,
_2));

if (!media_key.empty()) {
ledger_->SetMediaPublisherInfo(media_key, publisher_key);
}
}

// static
std::string MediaReddit::GetPublisherKey(const std::string& key) {
if (key.empty()) {
return std::string();
}
return (std::string)REDDIT_MEDIA_TYPE + "#channel:" + key;
}

// static
std::string MediaReddit::GetProfileImageUrl(const std::string& response) {
if (response.empty()) {
return std::string();
}

const std::string image_url(braveledger_media::ExtractData(
response, "accountIcon\":\"", "?"));
return image_url; // old reddit does not use account icons
}

} // namespace braveledger_media
Loading

0 comments on commit 47b456a

Please sign in to comment.