diff --git a/README.md b/README.md index f10b004..5803427 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Setting | Description | Type `DFP_TARGETED_PLACEMENT_NAMES` | The names of DFP placements the line items should target | array of strings `DFP_PLACEMENT_SIZES` | The creative sizes for the targeted placements | array of objects (e.g., `[{'width': '728', 'height': '90'}]`) `PREBID_BIDDER_CODE` | The value of [`hb_bidder`](http://prebid.org/dev-docs/publisher-api-reference.html#module_pbjs.bidderSettings) for this partner | string -`PREBID_PRICE_BUCKETS` | The [price granularity](http://prebid.org/dev-docs/publisher-api-reference.html#module_pbjs.setPriceGranularity); used to set `hb_pb` for each line item | object +`PREBID_PRICE_BUCKETS` | The [price granularity](http://prebid.org/dev-docs/publisher-api-reference.html#module_pbjs.setPriceGranularity); used to set `hb_pb` for each line item | array Then, from the root of the repository, run: @@ -84,7 +84,6 @@ Setting | Description | Default * Currently, the names of the bidder code targeting key (`hb_bidder`) and price bucket targeting key (`hb_pb`) are not customizable. The `hb_bidder` targeting key is currently required (see [#18](../../issues/18)) * This tool does not support additional line item targeting beyond placement, `hb_bidder`, and `hb_pb` values. Placement targeting is currently required (see [#16](../../issues/16)), and targeting by ad unit isn't supported (see [#17](../../issues/17)) -* The price bucketing setting `PREBID_PRICE_BUCKETS` only allows for uniform bucketing. For example, you can create $0.01 buckets from $0 - $20, but you cannot specify $0.01 buckets from $0 - $5 and $0.50 buckets from $5 - $20. Using entirely $0.01 buckets will still work for the custom buckets—you'll just have more line items than you need. * This tool does not modify existing orders or line items, it only creates them. If you need to make a change to an order, it's easiest to archive the existing order and recreate it. Please consider [contributing](CONTRIBUTING.md) to make the tool more flexible. diff --git a/settings.py b/settings.py index 47c4377..bf14fdd 100644 --- a/settings.py +++ b/settings.py @@ -66,14 +66,27 @@ # Price buckets. This should match your Prebid settings for the partner. See: # http://prebid.org/dev-docs/publisher-api-reference.html#module_pbjs.setPriceGranularity -# FIXME: this should be an array of buckets. See: # https://github.com/prebid/Prebid.js/blob/8fed3d7aaa814e67ca3efc103d7d306cab8c692c/src/cpmBucketManager.js -PREBID_PRICE_BUCKETS = { - 'precision': 2, - 'min' : 0, - 'max' : 20, - 'increment': 0.10, -} +PREBID_PRICE_BUCKETS = [ + { + 'precision': 2, + 'min' : 0, + 'max' : 1, + 'increment': 0.01, + }, + { + 'precision': 2, + 'min' : 1.10, + 'max' : 5.00, + 'increment': 0.10, + }, + { + 'precision': 2, + 'min' : 5.50, + 'max' : 10, + 'increment': 0.50, + }, +] ######################################################################### diff --git a/tasks/add_new_prebid_partner.py b/tasks/add_new_prebid_partner.py index 2218ec5..f83e2d5 100755 --- a/tasks/add_new_prebid_partner.py +++ b/tasks/add_new_prebid_partner.py @@ -180,7 +180,7 @@ def create_line_item_configs(prices, order_id, placement_ids, bidder_code, price_str = num_to_str(micro_amount_to_num(price)) # Autogenerate the line item name. - line_item_name = u'{bidder_code}: HB ${price}'.format( + line_item_name = u'{bidder_code}: HB {price}'.format( bidder_code=bidder_code, price=price_str ) @@ -205,7 +205,7 @@ def create_line_item_configs(prices, order_id, placement_ids, bidder_code, return line_items_config -def check_price_buckets_validity(price_buckets): +def check_price_buckets_validity(price_bucketlist): """ Validate that the price_buckets object contains all required keys and the values are the expected types. @@ -215,31 +215,31 @@ def check_price_buckets_validity(price_buckets): Returns: None """ - - try: - pb_precision = price_buckets['precision'] - pb_min = price_buckets['min'] - pb_max = price_buckets['max'] - pb_increment = price_buckets['increment'] - except KeyError: - raise BadSettingException('The setting "PREBID_PRICE_BUCKETS" ' - 'must contain keys "precision", "min", "max", and "increment".') + for price_buckets in price_bucketlist: + try: + pb_precision = price_buckets['precision'] + pb_min = price_buckets['min'] + pb_max = price_buckets['max'] + pb_increment = price_buckets['increment'] + except KeyError: + raise BadSettingException('The setting "PREBID_PRICE_BUCKETS" ' + 'must contain keys "precision", "min", "max", and "increment".') - if not (isinstance(pb_precision, int) or isinstance(pb_precision, float)): - raise BadSettingException('The "precision" key in "PREBID_PRICE_BUCKETS" ' - 'must be a number.') + if not (isinstance(pb_precision, int) or isinstance(pb_precision, float)): + raise BadSettingException('The "precision" key in "PREBID_PRICE_BUCKETS" ' + 'must be a number.') - if not (isinstance(pb_min, int) or isinstance(pb_min, float)): - raise BadSettingException('The "min" key in "PREBID_PRICE_BUCKETS" ' - 'must be a number.') + if not (isinstance(pb_min, int) or isinstance(pb_min, float)): + raise BadSettingException('The "min" key in "PREBID_PRICE_BUCKETS" ' + 'must be a number.') - if not (isinstance(pb_max, int) or isinstance(pb_max, float)): - raise BadSettingException('The "max" key in "PREBID_PRICE_BUCKETS" ' - 'must be a number.') + if not (isinstance(pb_max, int) or isinstance(pb_max, float)): + raise BadSettingException('The "max" key in "PREBID_PRICE_BUCKETS" ' + 'must be a number.') - if not (isinstance(pb_increment, int) or isinstance(pb_increment, float)): - raise BadSettingException('The "increment" key in "PREBID_PRICE_BUCKETS" ' - 'must be a number.') + if not (isinstance(pb_increment, int) or isinstance(pb_increment, float)): + raise BadSettingException('The "increment" key in "PREBID_PRICE_BUCKETS" ' + 'must be a number.') class color: PURPLE = '\033[95m' @@ -306,8 +306,7 @@ def main(): check_price_buckets_validity(price_buckets) prices = get_prices_array(price_buckets) - prices_summary = get_prices_summary_string(prices, - price_buckets['precision']) + prices_summary = get_prices_summary_string(prices) logger.info( u""" diff --git a/tasks/price_utils.py b/tasks/price_utils.py index 271817b..87938ee 100644 --- a/tasks/price_utils.py +++ b/tasks/price_utils.py @@ -39,7 +39,7 @@ def num_to_str(num, precision=2): """ return '%.{0}f'.format(str(precision)) % num -def get_prices_array(price_bucket): +def get_prices_array(price_buckets): """ Creates an array of price bucket cutoffs in micro-amounts from a price_bucket configuration. @@ -53,25 +53,27 @@ def get_prices_array(price_bucket): """ # Arbitrary max CPM to prevent large user errors. - cpm_max_allowed = 500.00 - end_cpm = ( - price_bucket['max'] if - price_bucket['max'] < cpm_max_allowed else - cpm_max_allowed) + prices = [] + for price_bucket in price_buckets: + cpm_max_allowed = 500.00 + end_cpm = ( + price_bucket['max'] if + price_bucket['max'] < cpm_max_allowed else + cpm_max_allowed) - start_cpm = price_bucket['min'] if price_bucket['min'] >=0 else 0.00 - increment = price_bucket['increment'] - precision = price_bucket['precision'] + start_cpm = price_bucket['min'] if price_bucket['min'] >=0 else 0.00 + increment = price_bucket['increment'] + precision = price_bucket['precision'] - start_cpm_micro_amount = num_to_micro_amount(start_cpm, precision) - end_cpm_micro_amount = num_to_micro_amount(end_cpm, precision) - increment_micro_amount = num_to_micro_amount(increment, precision) + start_cpm_micro_amount = num_to_micro_amount(start_cpm, precision) + end_cpm_micro_amount = num_to_micro_amount(end_cpm, precision) + increment_micro_amount = num_to_micro_amount(increment, precision) - current_cpm_micro_amount = start_cpm_micro_amount - prices = [] - while current_cpm_micro_amount <= end_cpm_micro_amount: - prices.append(current_cpm_micro_amount) - current_cpm_micro_amount += increment_micro_amount + current_cpm_micro_amount = start_cpm_micro_amount + + while current_cpm_micro_amount <= end_cpm_micro_amount: + prices.append(current_cpm_micro_amount) + current_cpm_micro_amount += increment_micro_amount return prices