diff --git a/app/browser/api/ledger.js b/app/browser/api/ledger.js index b1442d3fa73..7dc5db2ce26 100644 --- a/app/browser/api/ledger.js +++ b/app/browser/api/ledger.js @@ -2501,10 +2501,15 @@ const onMediaRequest = (state, xhr, type, tabId) => { const parsed = ledgerUtil.getMediaData(xhr, type) const mediaId = ledgerUtil.getMediaId(parsed, type) + + if (mediaId == null) { + return state + } + const mediaKey = ledgerUtil.getMediaKey(mediaId, type) let duration = ledgerUtil.getMediaDuration(parsed, type) - if (mediaId == null || duration == null || mediaKey == null) { + if (duration == null || mediaKey == null) { return state } diff --git a/app/common/constants/ledgerMediaProviders.js b/app/common/constants/ledgerMediaProviders.js index 84ef2d1af80..b8d241eb3d2 100644 --- a/app/common/constants/ledgerMediaProviders.js +++ b/app/common/constants/ledgerMediaProviders.js @@ -3,7 +3,8 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ const providers = { - YOUTUBE: 'youtube' + YOUTUBE: 'youtube', + TWITCH: 'twitch' } module.exports = providers diff --git a/app/common/lib/ledgerUtil.js b/app/common/lib/ledgerUtil.js index 4123df21eb4..366b4d078bc 100644 --- a/app/common/lib/ledgerUtil.js +++ b/app/common/lib/ledgerUtil.js @@ -222,6 +222,19 @@ const getMediaId = (data, type) => { id = data.docid break } + case ledgerMediaProviders.TWITCH: + { + if ( + data.event === 'video-play' || + data.event === 'minute-watched' + ) { + id = data.properties.channel + + if (data.properties.vod) { + id += `_vod_${data.properties.vod}` + } + } + } } return id @@ -242,16 +255,28 @@ const getMediaData = (xhr, type) => { return result } + const parsedUrl = urlParse(xhr) + const query = parsedUrl && parsedUrl.query + + if (!parsedUrl || !query) { + return null + } + switch (type) { case ledgerMediaProviders.YOUTUBE: { - const parsedUrl = urlParse(xhr) - let query = null - - if (parsedUrl && parsedUrl.query) { - query = queryString.parse(parsedUrl.query) + result = queryString.parse(parsedUrl.query) + break + } + case ledgerMediaProviders.TWITCH: + { + result = queryString.parse(parsedUrl.query) + let obj = Buffer.from(result.data, 'base64').toString('utf8') + if (obj == null) { + break } - result = query + + result = JSON.parse(obj) break } } @@ -262,15 +287,37 @@ const getMediaData = (xhr, type) => { const getMediaDuration = (data, type) => { let duration = 0 switch (type) { - case ledgerMediaProviders.YOUTUBE: { - duration = getYouTubeDuration(data) - break - } + case ledgerMediaProviders.YOUTUBE: + { + duration = getYouTubeDuration(data) + break + } + case ledgerMediaProviders.TWITCH: + { + duration = getTwitchDuration(data) + break + } } return duration } +const getTwitchDuration = (data) => { + let time = 0 + + if (data == null) { + return time + } + + if (data.properties.minutes_logged) { + time = 60 * 1000 // 1 min + } else { + time = 1000 // 1s TODO do we want to log 1s when we start video play? + } + + return time +} + const getYouTubeDuration = (data) => { let time = 0 @@ -295,7 +342,7 @@ const getYouTubeDuration = (data) => { return parseInt(time) } -const getMediaProvider = (url) => { +const getMediaProvider = (url, firstPartyUrl, referrer) => { let provider = null if (url == null) { @@ -304,7 +351,18 @@ const getMediaProvider = (url) => { // Youtube if (url.startsWith('https://www.youtube.com/api/stats/watchtime?')) { - provider = ledgerMediaProviders.YOUTUBE + return ledgerMediaProviders.YOUTUBE + } + + // Twitch + if ( + ( + firstPartyUrl.startsWith('https://www.twitch.tv') || + referrer.startsWith('https://player.twitch.tv') + ) && + url.startsWith('https://api.mixpanel.com') + ) { + return ledgerMediaProviders.TWITCH } return provider diff --git a/app/filtering.js b/app/filtering.js index 5b99063a90f..fbf013939d5 100644 --- a/app/filtering.js +++ b/app/filtering.js @@ -115,12 +115,21 @@ function registerForBeforeRequest (session, partition) { } const firstPartyUrl = module.exports.getMainFrameUrl(details) + const url = details.url // this can happen if the tab is closed and the webContents is no longer available if (!firstPartyUrl) { muonCb({ cancel: true }) return } + if (module.exports.isResourceEnabled('ledger') && module.exports.isResourceEnabled('ledgerMedia')) { + // Ledger media + const provider = ledgerUtil.getMediaProvider(url, firstPartyUrl, details.referrer) + if (provider) { + appActions.onLedgerMediaData(url, provider, details.tabId) + } + } + for (let i = 0; i < beforeRequestFilteringFns.length; i++) { let results = beforeRequestFilteringFns[i](details, isPrivate) const isAdBlock = (results.resourceName === appConfig.resourceNames.ADBLOCK) || @@ -201,7 +210,6 @@ function registerForBeforeRequest (session, partition) { } } // Redirect to non-script version of DDG when it's blocked - const url = details.url if (details.resourceType === 'mainFrame' && url.startsWith('https://duckduckgo.com/?q') && module.exports.isResourceEnabled('noScript', url, isPrivate)) { @@ -209,14 +217,6 @@ function registerForBeforeRequest (session, partition) { } else { muonCb({}) } - - if (module.exports.isResourceEnabled('ledger') && module.exports.isResourceEnabled('ledgerMedia')) { - // Ledger media - const provider = ledgerUtil.getMediaProvider(url) - if (provider) { - appActions.onLedgerMediaData(url, provider, details.tabId) - } - } }) } diff --git a/package-lock.json b/package-lock.json index 365287c0369..2d335535290 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1551,7 +1551,7 @@ "requires": { "@ambassify/backoff-strategies": "1.0.0", "bat-balance": "1.0.4", - "bat-publisher": "2.0.3", + "bat-publisher": "2.0.4", "bitgo": "4.15.0", "brave-crypto": "0.0.1", "http-request-signature": "0.0.2", @@ -1577,9 +1577,9 @@ } }, "bat-publisher": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/bat-publisher/-/bat-publisher-2.0.3.tgz", - "integrity": "sha512-Iu+AZ2yackBHPhxRPhJYfMlwL/YhSq5zaaNjaLM8tqDe1KhFZnA1nkXeW+N7MaodVd4KQcHWWqPFkMUgD7BzAg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/bat-publisher/-/bat-publisher-2.0.4.tgz", + "integrity": "sha512-2ok0Y/4c5SeFXCn1j45cgmE3u/ZRgjaafnooGm9gpvrBFCA3lzxoXlTqYgAbJmNYUinNJg5R92ZDfeC5nyYuiw==", "requires": { "@ambassify/backoff-strategies": "1.0.0", "async": "2.5.0", @@ -5946,6 +5946,61 @@ } } }, + "electron-download": { + "version": "github:brave/electron-download#409b65caff14edeef1daa36a7445ba6334658d7c", + "dev": true, + "requires": { + "debug": "2.6.9", + "home-path": "1.0.5", + "minimist": "1.2.0", + "mkdirp": "0.5.1", + "mv": "2.1.1", + "nugget": "1.6.2", + "path-exists": "1.0.0", + "rc": "1.2.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "nugget": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/nugget/-/nugget-1.6.2.tgz", + "integrity": "sha1-iMpuA7pXBqmRc/XaCQJZPWvK4Qc=", + "dev": true, + "requires": { + "debug": "2.6.9", + "minimist": "1.2.0", + "pretty-bytes": "1.0.4", + "progress-stream": "1.2.0", + "request": "2.82.0", + "single-line-log": "0.4.1", + "throttleit": "0.0.2" + } + }, + "path-exists": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz", + "integrity": "sha1-1aiZjrce83p0w06w2eum6HjuoIE=", + "dev": true + }, + "single-line-log": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-0.4.1.tgz", + "integrity": "sha1-h6VWSfdJ14PsDc2AToFA2Yc8fO4=", + "dev": true + }, + "throttleit": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", + "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", + "dev": true + } + } + }, "electron-installer-debian": { "version": "github:brave/electron-installer-debian#5f37713f52437678e5cbf9b17500fba4ae7cb5ad", "optional": true, @@ -6019,6 +6074,25 @@ "resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-0.6.1.tgz", "integrity": "sha1-xOJow4puQvQN5WGPyQbR7WCPEao=" }, + "electron-osx-sign": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.3.2.tgz", + "integrity": "sha1-iPp9brrbXZx5NouWSRoNjEYwFG4=", + "dev": true, + "requires": { + "debug": "2.6.9", + "minimist": "1.2.0", + "run-series": "1.1.4" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, "electron-packager": { "version": "github:brave/electron-packager#0dcbc2d5b56b058e8ee9a2ec1f43f96d94f4925e", "dev": true, @@ -6063,31 +6137,6 @@ "integrity": "sha1-HUixB9ghJqLz4hHC6iX4A7pVGyE=", "dev": true }, - "electron-download": { - "version": "github:brave/electron-download#409b65caff14edeef1daa36a7445ba6334658d7c", - "dev": true, - "requires": { - "debug": "2.6.9", - "home-path": "1.0.5", - "minimist": "1.2.0", - "mkdirp": "0.5.1", - "mv": "2.1.1", - "nugget": "1.6.2", - "path-exists": "1.0.0", - "rc": "1.2.1" - } - }, - "electron-osx-sign": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.3.2.tgz", - "integrity": "sha1-iPp9brrbXZx5NouWSRoNjEYwFG4=", - "dev": true, - "requires": { - "debug": "2.6.9", - "minimist": "1.2.0", - "run-series": "1.1.4" - } - }, "fs-extra": { "version": "0.28.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.28.0.tgz", @@ -6126,27 +6175,6 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, - "nugget": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/nugget/-/nugget-1.6.2.tgz", - "integrity": "sha1-iMpuA7pXBqmRc/XaCQJZPWvK4Qc=", - "dev": true, - "requires": { - "debug": "2.6.9", - "minimist": "1.2.0", - "pretty-bytes": "1.0.4", - "progress-stream": "1.2.0", - "request": "2.82.0", - "single-line-log": "0.4.1", - "throttleit": "0.0.2" - } - }, - "path-exists": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz", - "integrity": "sha1-1aiZjrce83p0w06w2eum6HjuoIE=", - "dev": true - }, "plist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/plist/-/plist-1.2.0.tgz", @@ -6159,18 +6187,6 @@ "xmldom": "0.1.27" } }, - "single-line-log": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-0.4.1.tgz", - "integrity": "sha1-h6VWSfdJ14PsDc2AToFA2Yc8fO4=", - "dev": true - }, - "throttleit": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", - "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", - "dev": true - }, "xmlbuilder": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.0.0.tgz", @@ -6188,61 +6204,6 @@ "requires": { "electron-download": "github:brave/electron-download#409b65caff14edeef1daa36a7445ba6334658d7c", "extract-zip": "1.6.5" - }, - "dependencies": { - "electron-download": { - "version": "github:brave/electron-download#409b65caff14edeef1daa36a7445ba6334658d7c", - "dev": true, - "requires": { - "debug": "2.6.9", - "home-path": "1.0.5", - "minimist": "1.2.0", - "mkdirp": "0.5.1", - "mv": "2.1.1", - "nugget": "1.6.2", - "path-exists": "1.0.0", - "rc": "1.2.1" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "nugget": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/nugget/-/nugget-1.6.2.tgz", - "integrity": "sha1-iMpuA7pXBqmRc/XaCQJZPWvK4Qc=", - "dev": true, - "requires": { - "debug": "2.6.9", - "minimist": "1.2.0", - "pretty-bytes": "1.0.4", - "progress-stream": "1.2.0", - "request": "2.82.0", - "single-line-log": "0.4.1", - "throttleit": "0.0.2" - } - }, - "path-exists": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz", - "integrity": "sha1-1aiZjrce83p0w06w2eum6HjuoIE=", - "dev": true - }, - "single-line-log": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-0.4.1.tgz", - "integrity": "sha1-h6VWSfdJ14PsDc2AToFA2Yc8fO4=", - "dev": true - }, - "throttleit": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", - "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", - "dev": true - } } }, "electron-squirrel-startup": { diff --git a/package.json b/package.json index 56c66cd08ae..99af007760a 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "async": "^2.0.1", "bat-balance": "^1.0.4", "bat-client": "^2.0.7", - "bat-publisher": "^2.0.3", + "bat-publisher": "^2.0.4", "bignumber.js": "^4.0.4", "bloodhound-js": "brave/bloodhound", "clipboard-copy": "^1.0.0",