mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-04-27 03:00:12 -04:00
Enable toggling and optional inventory breakdown between platforms
This commit is contained in:
@@ -556,9 +556,11 @@ class PromoteApiController(ApiController):
|
||||
collection=VCollection('collection'),
|
||||
location=VLocation(),
|
||||
start=VDate('startdate'),
|
||||
end=VDate('enddate'))
|
||||
end=VDate('enddate'),
|
||||
platform=VOneOf('platform', ('mobile', 'desktop', 'all'),
|
||||
default='all'))
|
||||
def GET_check_inventory(self, responder, sr, collection, location, start,
|
||||
end):
|
||||
end, platform):
|
||||
if collection:
|
||||
target = Target(collection)
|
||||
sr = None
|
||||
@@ -570,7 +572,8 @@ class PromoteApiController(ApiController):
|
||||
return abort(403, 'forbidden')
|
||||
|
||||
available = inventory.get_available_pageviews(
|
||||
target, start, end, location=location, datestr=True)
|
||||
target, start, end, location=location, platform=platform,
|
||||
datestr=True)
|
||||
|
||||
return {'inventory': available}
|
||||
|
||||
|
||||
@@ -50,6 +50,13 @@ MIN_DAILY_CASS_KEY = 'min_daily_pageviews.GET_listing'
|
||||
PAGEVIEWS_REGEXP = re.compile('(.*)-GET_listing')
|
||||
INVENTORY_FACTOR = 1.00
|
||||
DEFAULT_INVENTORY_FACTOR = 5.00
|
||||
# For `PERCENT_MOBILE`:
|
||||
# if `0`, 100% of inventory will be displayed no matter the platform;
|
||||
# if not `0`:
|
||||
# - `all` is 100% of inventory
|
||||
# - `mobile` is `all` * (PERCENT_MOBILE / 100)
|
||||
# - `desktop` is `all` - `mobile`
|
||||
PERCENT_MOBILE = 0
|
||||
|
||||
|
||||
def update_prediction_data():
|
||||
@@ -212,7 +219,7 @@ def find_campaigns(srs, start, end, ignore):
|
||||
|
||||
|
||||
def get_available_pageviews(targets, start, end, location=None, datestr=False,
|
||||
ignore=None):
|
||||
ignore=None, platform='all'):
|
||||
"""
|
||||
Return the available pageviews by date for the targets and location.
|
||||
|
||||
@@ -292,6 +299,12 @@ def get_available_pageviews(targets, start, end, location=None, datestr=False,
|
||||
subreddit_names, booked_by_target, pageviews_by_sr_name)
|
||||
# available pageviews is the minimum from all locations
|
||||
min_pageviews = min(pageviews_by_location.values())
|
||||
if PERCENT_MOBILE != 0:
|
||||
mobile_pageviews = min_pageviews * (float(PERCENT_MOBILE) / 100)
|
||||
if platform == 'mobile':
|
||||
min_pageviews = mobile_pageviews
|
||||
if platform == 'desktop':
|
||||
min_pageviews = min_pageviews - mobile_pageviews
|
||||
ret[name][datekey(date)] = max(0, min_pageviews)
|
||||
|
||||
if is_single:
|
||||
|
||||
@@ -640,8 +640,9 @@ var exports = r.sponsored = {
|
||||
return dates
|
||||
},
|
||||
|
||||
get_inventory_key: function(srname, collection, geotarget) {
|
||||
get_inventory_key: function(srname, collection, geotarget, platform) {
|
||||
var inventoryKey = collection ? '#' + collection : srname
|
||||
inventoryKey += "/" + platform
|
||||
if (geotarget.country != "") {
|
||||
inventoryKey += "/" + geotarget.country
|
||||
}
|
||||
@@ -670,8 +671,10 @@ var exports = r.sponsored = {
|
||||
var srname = targeting.sr,
|
||||
collection = targeting.collection,
|
||||
geotarget = targeting.geotarget,
|
||||
platform = targeting.platform,
|
||||
inventoryKey = targeting.inventoryKey,
|
||||
dates = timing.dates;
|
||||
|
||||
dates.sort(function(d1,d2){return d1 - d2})
|
||||
var end = new Date(dates[dates.length-1].getTime())
|
||||
end.setDate(end.getDate() + 5)
|
||||
@@ -685,7 +688,8 @@ var exports = r.sponsored = {
|
||||
region: geotarget.region,
|
||||
metro: geotarget.metro,
|
||||
startdate: $.datepicker.formatDate('mm/dd/yy', dates[0]),
|
||||
enddate: $.datepicker.formatDate('mm/dd/yy', end)
|
||||
enddate: $.datepicker.formatDate('mm/dd/yy', end),
|
||||
platform: platform
|
||||
},
|
||||
});
|
||||
},
|
||||
@@ -764,7 +768,7 @@ var exports = r.sponsored = {
|
||||
},
|
||||
|
||||
getAvailableImpsByDay: function(dates, booked, inventoryKey) {
|
||||
return _.map(dates, function(date) {
|
||||
return _.map(dates, function(date) {
|
||||
var datestr = $.datepicker.formatDate('mm/dd/yy', date);
|
||||
var daily_booked = booked[datestr] || 0;
|
||||
return r.sponsored.inventory[inventoryKey][datestr] + daily_booked;
|
||||
@@ -779,7 +783,7 @@ var exports = r.sponsored = {
|
||||
inventoryKey = targeting.inventoryKey,
|
||||
booked = this.get_booked_inventory($form, targeting.sr,
|
||||
targeting.geotarget, isOverride);
|
||||
|
||||
|
||||
var minbid_amt = r.sponsored.get_real_min_bid();
|
||||
var maxbid_amt = r.sponsored.get_max_bid();
|
||||
|
||||
@@ -871,7 +875,8 @@ var exports = r.sponsored = {
|
||||
region = canGeotarget && $('#region').val() || '',
|
||||
metro = canGeotarget && $('#metro').val() || '',
|
||||
geotarget = {'country': country, 'region': region, 'metro': metro},
|
||||
inventoryKey = this.get_inventory_key(sr, collection, geotarget),
|
||||
platform = this.getPlatformTargeting().platform,
|
||||
inventoryKey = this.get_inventory_key(sr, collection, geotarget, platform),
|
||||
isValid = isFrontpage || (isSubreddit && sr) || (isCollection && collection);
|
||||
|
||||
return {
|
||||
@@ -882,6 +887,7 @@ var exports = r.sponsored = {
|
||||
'collection': collection,
|
||||
'canGeotarget': canGeotarget,
|
||||
'geotarget': geotarget,
|
||||
'platform': platform,
|
||||
'inventoryKey': inventoryKey,
|
||||
};
|
||||
},
|
||||
@@ -1017,15 +1023,30 @@ var exports = r.sponsored = {
|
||||
},
|
||||
|
||||
fill_campaign_editor: function() {
|
||||
var $form = $("#campaign"),
|
||||
priority = this.get_priority($form),
|
||||
var $form = $("#campaign");
|
||||
var platformTargeting = this.getPlatformTargeting();
|
||||
var platformOverride = platformTargeting.isMobile && platformTargeting.platform === 'mobile';
|
||||
|
||||
var $priorities = $form.find('*[name="priority"]');
|
||||
if (platformOverride) {
|
||||
$priorities.filter('[value="house"]').prop('checked', 'checked');
|
||||
$priorities.filter(':not([value="house"])').prop('disabled', true);
|
||||
} else {
|
||||
if (this.currentPlatform === 'mobile') {
|
||||
$priorities.filter('[value="standard"]').prop('checked', 'checked');
|
||||
}
|
||||
$priorities.prop('disabled', false);
|
||||
}
|
||||
this.currentPlatform = platformTargeting.platform;
|
||||
|
||||
var priority = this.get_priority($form),
|
||||
targeting = this.get_targeting($form),
|
||||
timing = this.get_timing($form),
|
||||
ndays = timing.duration,
|
||||
budget = this.get_budget($form),
|
||||
cpm = budget.cpm,
|
||||
impressions = budget.impressions,
|
||||
checkInventory = targeting.isValid && priority.isCpm;
|
||||
checkInventory = targeting.isValid;
|
||||
|
||||
$(".duration").text(ndays + " " + ((ndays > 1) ? r._("days") : r._("day")))
|
||||
$(".price-info").text(r._("$%(cpm)s per 1,000 impressions").format({cpm: (cpm/100).toFixed(2)}))
|
||||
@@ -1044,37 +1065,40 @@ var exports = r.sponsored = {
|
||||
this.hide_cpm()
|
||||
}
|
||||
|
||||
if (checkInventory) {
|
||||
this.check_inventory($form, targeting, timing, budget, priority.isOverride)
|
||||
} else if (!priority.isCpm) {
|
||||
var booked = this.get_booked_inventory($form, targeting.sr,
|
||||
targeting.geotarget, priority.isOverride);
|
||||
var availableByDate = this.getAvailableImpsByDay(timing.dates, booked,
|
||||
targeting.inventoryKey);
|
||||
var totalImpsAvailable = _.reduce(availableByDate, sum, 0);
|
||||
if (!priority.isCpm && checkInventory) {
|
||||
$.when(r.sponsored.get_check_inventory(targeting, timing)).then(
|
||||
function() {
|
||||
var booked = this.get_booked_inventory($form, targeting.sr,
|
||||
targeting.geotarget, priority.isOverride);
|
||||
var availableByDate = this.getAvailableImpsByDay(timing.dates, booked,
|
||||
targeting.inventoryKey);
|
||||
var totalImpsAvailable = _.reduce(availableByDate, sum, 0);
|
||||
|
||||
|
||||
React.renderComponent(
|
||||
React.DOM.div(null,
|
||||
CampaignSet(null,
|
||||
InfoText(null, r._('house campaigns, man.')),
|
||||
CampaignOptionTable(null,
|
||||
CampaignOption({
|
||||
bid: null,
|
||||
end: timing.enddate,
|
||||
impressions: 'unsold ',
|
||||
isNew: !$("#campaign").parents('tr:first').length,
|
||||
primary: true,
|
||||
start: timing.startdate,
|
||||
})
|
||||
)
|
||||
),
|
||||
InfoText({impressions: totalImpsAvailable},
|
||||
r._('maximum possible impressions: %(impressions)s')
|
||||
)
|
||||
),
|
||||
document.getElementById('campaign-creator')
|
||||
React.renderComponent(
|
||||
React.DOM.div(null,
|
||||
CampaignSet(null,
|
||||
InfoText(null, r._('house campaigns, man.')),
|
||||
CampaignOptionTable(null,
|
||||
CampaignOption({
|
||||
bid: null,
|
||||
end: timing.enddate,
|
||||
impressions: 'unsold ',
|
||||
isNew: !$("#campaign").parents('tr:first').length,
|
||||
primary: true,
|
||||
start: timing.startdate,
|
||||
})
|
||||
)
|
||||
),
|
||||
InfoText({impressions: totalImpsAvailable},
|
||||
r._('maximum possible impressions: %(impressions)s')
|
||||
)
|
||||
),
|
||||
document.getElementById('campaign-creator')
|
||||
);
|
||||
}.bind(this)
|
||||
);
|
||||
} else if (checkInventory) {
|
||||
this.check_inventory($form, targeting, timing, budget, priority.isOverride)
|
||||
}
|
||||
|
||||
if (targeting.canGeotarget) {
|
||||
|
||||
Reference in New Issue
Block a user