Skip to content

Commit

Permalink
Merge branch 'optional-video-compilation' of https://github.com/WPMed…
Browse files Browse the repository at this point in the history
…ia/Prebid.js into WPMedia-optional-video-compilation
  • Loading branch information
ChrisHuie committed Mar 30, 2023
2 parents 81fd111 + 8ed51d2 commit 40cdc5e
Show file tree
Hide file tree
Showing 19 changed files with 1,501 additions and 1,426 deletions.
3 changes: 2 additions & 1 deletion features.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[
"NATIVE"
"NATIVE",
"VIDEO"
]
19 changes: 11 additions & 8 deletions libraries/ortbConverter/processors/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ export const DEFAULT_PROCESSORS = {
// populates imp.banner
fn: fillBannerImp
},
video: {
// populates imp.video
fn: fillVideoImp
},
pbadslot: {
// removes imp.ext.data.pbaslot if it's not a string
// TODO: is this needed?
Expand All @@ -78,10 +74,6 @@ export const DEFAULT_PROCESSORS = {
// sets banner response attributes if bidResponse.mediaType === BANNER
fn: bannerResponseProcessor(),
},
video: {
// sets video response attributes if bidResponse.mediaType === VIDEO
fn: fillVideoResponse
},
props: {
// sets base bidResponse properties common to all types of bids
fn(bidResponse, bid, context) {
Expand Down Expand Up @@ -121,3 +113,14 @@ if (FEATURES.NATIVE) {
fn: fillNativeResponse
}
}

if (FEATURES.VIDEO) {
DEFAULT_PROCESSORS[IMP].video = {
// populates imp.video
fn: fillVideoImp
}
DEFAULT_PROCESSORS[BID_RESPONSE].video = {
// sets video response attributes if bidResponse.mediaType === VIDEO
fn: fillVideoResponse
}
}
5 changes: 2 additions & 3 deletions modules/adpod.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,13 @@ import {
import {
addBidToAuction,
AUCTION_IN_PROGRESS,
callPrebidCache,
doCallbacksIfTimedout,
getPriceByGranularity,
getPriceGranularity
} from '../src/auction.js';
import {checkAdUnitSetup} from '../src/prebid.js';
import {checkVideoBidSetup} from '../src/video.js';
import {module, setupBeforeHookFnOnce} from '../src/hook.js';
import {getHook, module, setupBeforeHookFnOnce} from '../src/hook.js';
import {store} from '../src/videoCache.js';
import {config} from '../src/config.js';
import {ADPOD} from '../src/mediaTypes.js';
Expand Down Expand Up @@ -424,7 +423,7 @@ config.getConfig('adpod', config => adpodSetConfig(config.adpod));
* This function initializes the adpod module's hooks. This is called by the corresponding adserver video module.
*/
function initAdpodHooks() {
setupBeforeHookFnOnce(callPrebidCache, callPrebidCacheHook);
setupBeforeHookFnOnce(getHook('callPrebidCache'), callPrebidCacheHook);
setupBeforeHookFnOnce(checkAdUnitSetup, checkAdUnitSetupHook);
setupBeforeHookFnOnce(checkVideoBidSetup, checkVideoBidSetupHook);
}
Expand Down
2 changes: 1 addition & 1 deletion modules/sizeMappingV2.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export function checkAdUnitSetupHook(adUnits) {
}
}

if (mediaTypes.video) {
if (FEATURES.VIDEO && mediaTypes.video) {
if (mediaTypes.video.playerSize) {
// Ad unit is using 'mediaTypes.video.playerSize' instead of the new property 'sizeConfig'. Apply the old checks!
validatedVideo = validatedBanner ? adUnitSetupChecks.validateVideoMediaType(validatedBanner) : adUnitSetupChecks.validateVideoMediaType(adUnit);
Expand Down
4 changes: 2 additions & 2 deletions src/adapterManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request

function getSupportedMediaTypes(bidderCode) {
let supportedMediaTypes = [];
if (includes(adapterManager.videoAdapters, bidderCode)) supportedMediaTypes.push('video');
if (FEATURES.VIDEO && includes(adapterManager.videoAdapters, bidderCode)) supportedMediaTypes.push('video');
if (FEATURES.NATIVE && includes(nativeAdapters, bidderCode)) supportedMediaTypes.push('native');
return supportedMediaTypes;
}
Expand All @@ -471,7 +471,7 @@ adapterManager.registerBidAdapter = function (bidAdapter, bidderCode, {supported
if (typeof bidAdapter.callBids === 'function') {
_bidderRegistry[bidderCode] = bidAdapter;

if (includes(supportedMediaTypes, 'video')) {
if (FEATURES.VIDEO && includes(supportedMediaTypes, 'video')) {
adapterManager.videoAdapters.push(bidderCode);
}
if (FEATURES.NATIVE && includes(supportedMediaTypes, 'native')) {
Expand Down
87 changes: 46 additions & 41 deletions src/adapters/bidderFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,51 +472,56 @@ export const addComponentAuction = hook('sync', (_bidRequest, fledgeAuctionConfi
}, 'addComponentAuction')

export function preloadBidderMappingFile(fn, adUnits) {
if (!config.getConfig('adpod.brandCategoryExclusion')) {
return fn.call(this, adUnits);
}
let adPodBidders = adUnits
.filter((adUnit) => deepAccess(adUnit, 'mediaTypes.video.context') === ADPOD)
.map((adUnit) => adUnit.bids.map((bid) => bid.bidder))
.reduce(flatten, [])
.filter(uniques);

adPodBidders.forEach(bidder => {
let bidderSpec = adapterManager.getBidAdapter(bidder);
if (bidderSpec.getSpec().getMappingFileInfo) {
let info = bidderSpec.getSpec().getMappingFileInfo();
let refreshInDays = (info.refreshInDays) ? info.refreshInDays : DEFAULT_REFRESHIN_DAYS;
let key = (info.localStorageKey) ? info.localStorageKey : bidderSpec.getSpec().code;
let mappingData = storage.getDataFromLocalStorage(key);
try {
mappingData = mappingData ? JSON.parse(mappingData) : undefined;
if (!mappingData || timestamp() > mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) {
ajax(info.url,
{
success: (response) => {
try {
response = JSON.parse(response);
let mapping = {
lastUpdated: timestamp(),
mapping: response.mapping
if (FEATURES.VIDEO) {
if (!config.getConfig('adpod.brandCategoryExclusion')) {
return fn.call(this, adUnits);
}

let adPodBidders = adUnits
.filter((adUnit) => deepAccess(adUnit, 'mediaTypes.video.context') === ADPOD)
.map((adUnit) => adUnit.bids.map((bid) => bid.bidder))
.reduce(flatten, [])
.filter(uniques);

adPodBidders.forEach(bidder => {
let bidderSpec = adapterManager.getBidAdapter(bidder);
if (bidderSpec.getSpec().getMappingFileInfo) {
let info = bidderSpec.getSpec().getMappingFileInfo();
let refreshInDays = (info.refreshInDays) ? info.refreshInDays : DEFAULT_REFRESHIN_DAYS;
let key = (info.localStorageKey) ? info.localStorageKey : bidderSpec.getSpec().code;
let mappingData = storage.getDataFromLocalStorage(key);
try {
mappingData = mappingData ? JSON.parse(mappingData) : undefined;
if (!mappingData || timestamp() > mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) {
ajax(info.url,
{
success: (response) => {
try {
response = JSON.parse(response);
let mapping = {
lastUpdated: timestamp(),
mapping: response.mapping
}
storage.setDataInLocalStorage(key, JSON.stringify(mapping));
} catch (error) {
logError(`Failed to parse ${bidder} bidder translation mapping file`);
}
storage.setDataInLocalStorage(key, JSON.stringify(mapping));
} catch (error) {
logError(`Failed to parse ${bidder} bidder translation mapping file`);
},
error: () => {
logError(`Failed to load ${bidder} bidder translation file`)
}
},
error: () => {
logError(`Failed to load ${bidder} bidder translation file`)
}
},
);
);
}
} catch (error) {
logError(`Failed to parse ${bidder} bidder translation mapping file`);
}
} catch (error) {
logError(`Failed to parse ${bidder} bidder translation mapping file`);
}
}
});
fn.call(this, adUnits);
});
fn.call(this, adUnits);
} else {
return fn.call(this, adUnits)
}
}

getHook('checkAdUnitSetup').before(preloadBidderMappingFile);
Expand Down Expand Up @@ -599,7 +604,7 @@ export function isValid(adUnitCode, bid, {index = auctionManager.index} = {}) {
logError(errorMessage('Native bid missing some required properties.'));
return false;
}
if (bid.mediaType === 'video' && !isValidVideoBid(bid, {index})) {
if (FEATURES.VIDEO && bid.mediaType === 'video' && !isValidVideoBid(bid, {index})) {
logError(errorMessage(`Video bid does not have required vastUrl or renderer property`));
return false;
}
Expand Down
10 changes: 6 additions & 4 deletions src/auction.js
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ export function auctionCallbacks(auctionDone, auctionInstance, {index = auctionM
handleBidResponse(adUnitCode, bid, (done) => {
let bidResponse = getPreparedBidForAuction(bid);

if (bidResponse.mediaType === VIDEO) {
if (FEATURES.VIDEO && bidResponse.mediaType === VIDEO) {
tryAddVideoBid(auctionInstance, bidResponse, done);
} else {
if (FEATURES.NATIVE && bidResponse.native != null && typeof bidResponse.native === 'object') {
Expand Down Expand Up @@ -623,7 +623,7 @@ const addLegacyFieldsIfNeeded = (bidResponse) => {
}
}

const storeInCache = (batch) => {
const _storeInCache = (batch) => {
store(batch.map(entry => entry.bidResponse), function (error, cacheIds) {
cacheIds.forEach((cacheId, i) => {
const { auctionInstance, bidResponse, afterBidAdded } = batch[i];
Expand All @@ -650,6 +650,8 @@ const storeInCache = (batch) => {
});
};

const storeInCache = FEATURES.VIDEO ? _storeInCache : () => {};

let batchSize, batchTimeout;
config.getConfig('cache', (cacheConfig) => {
batchSize = typeof cacheConfig.cache.batchSize === 'number' && cacheConfig.cache.batchSize > 0
Expand Down Expand Up @@ -785,7 +787,7 @@ function setupBidTargeting(bidObject) {
*/
export function getMediaTypeGranularity(mediaType, mediaTypes, mediaTypePriceGranularity) {
if (mediaType && mediaTypePriceGranularity) {
if (mediaType === VIDEO) {
if (FEATURES.VIDEO && mediaType === VIDEO) {
const context = deepAccess(mediaTypes, `${VIDEO}.context`, 'instream');
if (mediaTypePriceGranularity[`${VIDEO}-${context}`]) {
return mediaTypePriceGranularity[`${VIDEO}-${context}`];
Expand Down Expand Up @@ -894,7 +896,7 @@ export function getStandardBidderSettings(mediaType, bidderCode) {
standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = defaultAdserverTargeting();
}

if (mediaType === 'video') {
if (FEATURES.VIDEO && mediaType === 'video') {
const adserverTargeting = standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING].slice();
standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = adserverTargeting;

Expand Down
73 changes: 39 additions & 34 deletions src/prebid.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,17 @@ function validateAdUnit(adUnit) {
export const adUnitSetupChecks = {
validateAdUnit,
validateBannerMediaType,
validateVideoMediaType,
validateSizes
};

if (FEATURES.NATIVE) {
Object.assign(adUnitSetupChecks, {validateNativeMediaType});
}

if (FEATURES.VIDEO) {
Object.assign(adUnitSetupChecks, { validateVideoMediaType });
}

export const checkAdUnitSetup = hook('sync', function (adUnits) {
const validatedAdUnits = [];

Expand All @@ -248,7 +251,7 @@ export const checkAdUnitSetup = hook('sync', function (adUnits) {
if (mediaTypes.banner.hasOwnProperty('pos')) validatedBanner = validateAdUnitPos(validatedBanner, 'banner');
}

if (mediaTypes.video) {
if (FEATURES.VIDEO && mediaTypes.video) {
validatedVideo = validatedBanner ? validateVideoMediaType(validatedBanner) : validateVideoMediaType(adUnit);
if (mediaTypes.video.hasOwnProperty('pos')) validatedVideo = validateAdUnitPos(validatedVideo, 'video');
}
Expand Down Expand Up @@ -530,12 +533,14 @@ pbjsInstance.renderAd = hook('async', function (doc, id, options) {
const {height, width, ad, mediaType, adUrl, renderer} = bid;

// video module
const adUnitCode = bid.adUnitCode;
const adUnit = pbjsInstance.adUnits.filter(adUnit => adUnit.code === adUnitCode);
const videoModule = pbjsInstance.videoModule;
if (adUnit.video && videoModule) {
videoModule.renderBid(adUnit.video.divId, bid);
return;
if (FEATURES.VIDEO) {
const adUnitCode = bid.adUnitCode;
const adUnit = pbjsInstance.adUnits.filter(adUnit => adUnit.code === adUnitCode);
const videoModule = pbjsInstance.videoModule;
if (adUnit.video && videoModule) {
videoModule.renderBid(adUnit.video.divId, bid);
return;
}
}

if (!doc) {
Expand Down Expand Up @@ -986,34 +991,34 @@ pbjsInstance.getHighestCpmBids = function (adUnitCode) {
return targeting.getWinningBids(adUnitCode);
};

/**
* Mark the winning bid as used, should only be used in conjunction with video
* @typedef {Object} MarkBidRequest
* @property {string} adUnitCode The ad unit code
* @property {string} adId The id representing the ad we want to mark
*
* @alias module:pbjs.markWinningBidAsUsed
*/
pbjsInstance.markWinningBidAsUsed = function (markBidRequest) {
let bids = [];

if (markBidRequest.adUnitCode && markBidRequest.adId) {
bids = auctionManager.getBidsReceived()
.filter(bid => bid.adId === markBidRequest.adId && bid.adUnitCode === markBidRequest.adUnitCode);
} else if (markBidRequest.adUnitCode) {
bids = targeting.getWinningBids(markBidRequest.adUnitCode);
} else if (markBidRequest.adId) {
bids = auctionManager.getBidsReceived().filter(bid => bid.adId === markBidRequest.adId);
} else {
logWarn('Improper use of markWinningBidAsUsed. It needs an adUnitCode or an adId to function.');
}
if (FEATURES.VIDEO) {
/**
* Mark the winning bid as used, should only be used in conjunction with video
* @typedef {Object} MarkBidRequest
* @property {string} adUnitCode The ad unit code
* @property {string} adId The id representing the ad we want to mark
*
* @alias module:pbjs.markWinningBidAsUsed
*/
pbjsInstance.markWinningBidAsUsed = function (markBidRequest) {
let bids = [];

if (markBidRequest.adUnitCode && markBidRequest.adId) {
bids = auctionManager.getBidsReceived()
.filter(bid => bid.adId === markBidRequest.adId && bid.adUnitCode === markBidRequest.adUnitCode);
} else if (markBidRequest.adUnitCode) {
bids = targeting.getWinningBids(markBidRequest.adUnitCode);
} else if (markBidRequest.adId) {
bids = auctionManager.getBidsReceived().filter(bid => bid.adId === markBidRequest.adId);
} else {
logWarn('Improper use of markWinningBidAsUsed. It needs an adUnitCode or an adId to function.');
}

if (bids.length > 0) {
const winningBid = bids[0];
auctionManager.addWinningBid(winningBid);
winningBid.status = CONSTANTS.BID_STATUS.RENDERED;
if (bids.length > 0) {
bids[0].status = CONSTANTS.BID_STATUS.RENDERED;
}
}
};
}

/**
* Get Prebid config options
Expand Down
2 changes: 1 addition & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,7 @@ export function isValidMediaTypes(mediaTypes) {
return false;
}

if (mediaTypes.video && mediaTypes.video.context) {
if (FEATURES.VIDEO && mediaTypes.video && mediaTypes.video.context) {
return includes(SUPPORTED_STREAM_TYPES, mediaTypes.video.context);
}

Expand Down
Loading

0 comments on commit 40cdc5e

Please sign in to comment.