Exemplo n.º 1
0
def main():
  """
  Gets user email address from settings and fetches the user.

  Returns:
    an integer: the user's DFP ID
  """  

  email = getattr(settings, 'DFP_USER_EMAIL_ADDRESS', None)
  if email is None:
    raise MissingSettingException('DFP_USER_EMAIL_ADDRESS')

  return get_user_id_by_email(email)
Exemplo n.º 2
0
def main():
    """
  Gets the company name from settings and fetches its ID.

  Returns:
    an integer: the company's DFP ID
  """

    advertiser_name = getattr(settings, 'DFP_ADVERTISER_NAME', None)
    if advertiser_name is None:
        raise MissingSettingException('DFP_ADVERTISER_NAME')

    return get_advertiser_id_by_name(advertiser_name)
def main():
  """
  Gets the creative template name from settings and fetches its ID.

  Returns:
    an integer: the creative template ID
  """

  template_names = getattr(settings, 'OPENWRAP_CREATIVE_TEMPLATE', None)
  if template_names is None:
    raise MissingSettingException('OPENWRAP_CREATIVE_TEMPLATE')

  return get_creative_template_ids_by_name(template_names)
Exemplo n.º 4
0
def main():
    """
  Loads placements from settings and fetches them from DFP.

  Returns:
    None
  """

    placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', None)
    if placements is None:
        raise MissingSettingException('DFP_TARGETED_PLACEMENT_NAMES')
    elif len(placements) < 1:
        raise BadSettingException('The setting "DFP_TARGETED_PLACEMENT_NAMES" '
                                  'must contain at least one placement ID.')

    get_placement_ids_by_name(placements)
Exemplo n.º 5
0
def main():
    """
  Loads ad units from settings and fetches them from DFP.

  Returns:
    None
  """

    ad_units = getattr(settings, 'DFP_TARGETED_AD_UNIT_NAMES', None)
    if ad_units is None:
        raise MissingSettingException('DFP_TARGETED_AD_UNIT_NAMES')
    elif len(ad_units) < 1:
        raise BadSettingException('The setting "DFP_TARGETED_AD_UNIT_NAMES" '
                                  'must contain at least one ad unit ID.')

    get_ad_unit_ids_by_name(ad_units)
Exemplo n.º 6
0
def main():
    """
  Loads order name from settings and fetch line items from DFP.

  Returns:
    None
  """

    order_name = getattr(settings, 'DFP_ORDER_NAME', None)
    if order_name is None:
        raise MissingSettingException('DFP_ORDER_NAME')

    existing_order = dfp.get_orders.get_order_by_name(order_name)

    existing_order_id = existing_order['id']
    print(get_line_item_names_by_order_id(existing_order_id))
Exemplo n.º 7
0
def main():
    """
  Validate the settings and ask for confirmation from the user. Then,
  start all necessary DFP tasks.
  """

    user_email = getattr(settings, 'DFP_USER_EMAIL_ADDRESS', None)
    if user_email is None:
        raise MissingSettingException('DFP_USER_EMAIL_ADDRESS')

    advertiser_name = getattr(settings, 'DFP_ADVERTISER_NAME', None)
    if advertiser_name is None:
        raise MissingSettingException('DFP_ADVERTISER_NAME')

    order_name = getattr(settings, 'DFP_ORDER_NAME', None)
    if order_name is None:
        raise MissingSettingException('DFP_ORDER_NAME')

    placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', None)
    ad_units = getattr(settings, 'DFP_TARGETED_AD_UNIT_NAMES', None)

    video_ad_type = getattr(settings, 'DFP_VIDEO_AD_TYPE', False)
    vast_redirect_url = getattr(settings, 'DFP_VAST_REDIRECT_URL', '')

    if video_ad_type is True and len(vast_redirect_url) < 1:
        raise BadSettingException(
            'When setting "DFP_VIDEO_AD_TYPE" to "True", please also set "DFP_VAST_REDIRECT_URL".'
        )

    if ad_units is None and placements is None:
        raise MissingSettingException(
            'DFP_TARGETED_PLACEMENT_NAMES or DFP_TARGETED_AD_UNIT_NAMES')
    elif (placements is None
          or len(placements) < 1) and (ad_units is None or len(ad_units) < 1):
        raise BadSettingException(
            'The setting "DFP_TARGETED_PLACEMENT_NAMES" or "DFP_TARGETED_AD_UNIT_NAMES" '
            'must contain at least one DFP placement or ad unit.')

    sizes = getattr(settings, 'DFP_PLACEMENT_SIZES', None)
    if sizes is None:
        raise MissingSettingException('DFP_PLACEMENT_SIZES')
    elif len(sizes) < 1:
        raise BadSettingException('The setting "DFP_PLACEMENT_SIZES" '
                                  'must contain at least one size object.')

    currency_code = getattr(settings, 'DFP_CURRENCY_CODE', 'USD')

    line_item_format = getattr(settings, 'DFP_LINE_ITEM_FORMAT',
                               u'{bidder_code}: HB ${price}')

    # How many creatives to attach to each line item. We need at least one
    # creative per ad unit on a page. See:
    # https://github.com/kmjennison/dfp-prebid-setup/issues/13
    num_creatives = (getattr(settings, 'DFP_NUM_CREATIVES_PER_LINE_ITEM', None)
                     or len(placements) + len(ad_units))

    bidder_code = getattr(settings, 'PREBID_BIDDER_CODE', None)
    if bidder_code is None:
        raise MissingSettingException('PREBID_BIDDER_CODE')

    price_buckets = getattr(settings, 'PREBID_PRICE_BUCKETS', None)
    if price_buckets is None:
        raise MissingSettingException('PREBID_PRICE_BUCKETS')

    check_price_buckets_validity(price_buckets)

    prices = get_prices_array(price_buckets)
    prices_summary = get_prices_summary_string(prices)

    logger.info(u"""

    Going to create {name_start_format}{num_line_items}{format_end} new line items.
      {name_start_format}Order{format_end}: {value_start_format}{order_name}{format_end}
      {name_start_format}Advertiser{format_end}: {value_start_format}{advertiser}{format_end}

    Line items will have targeting:
      {name_start_format}hb_pb{format_end} = {value_start_format}{prices_summary}{format_end}
      {name_start_format}hb_bidder{format_end} = {value_start_format}{bidder_code}{format_end}
      {name_start_format}placements{format_end} = {value_start_format}{placements}{format_end}
      {name_start_format}ad units{format_end} = {value_start_format}{ad_units}{format_end}
    """.format(
        num_line_items=len(prices),
        order_name=order_name,
        advertiser=advertiser_name,
        user_email=user_email,
        prices_summary=prices_summary,
        bidder_code=bidder_code,
        placements=placements,
        ad_units=ad_units,
        sizes=sizes,
        name_start_format=color.BOLD,
        format_end=color.END,
        value_start_format=color.BLUE,
    ))

    if video_ad_type:
        logger.info(
            u"""    Line items will have VAST redirect creatives with redirect URL:
      {value_start_format}{redirect_url}{format_end}

    """.format(
                redirect_url=vast_redirect_url,
                value_start_format=color.BLUE,
                format_end=color.END,
            ))
    else:
        logger.info(
            u"""    Line items will have third party creatives based on snippet.html content.

    """)

    ok = input('Is this correct? (y/n)\n')

    if ok != 'y':
        logger.info('Exiting.')
        return

    setup_partner(user_email, advertiser_name, order_name, placements,
                  ad_units, sizes, bidder_code, prices, num_creatives,
                  currency_code, line_item_format, video_ad_type,
                  vast_redirect_url)
def main():
    """
  Validate the settings and ask for confirmation from the user. Then,
  start all necessary DFP tasks.
  """

    user_email = getattr(settings, 'DFP_USER_EMAIL_ADDRESS', None)
    if user_email is None:
        raise MissingSettingException('DFP_USER_EMAIL_ADDRESS')

    advertiser_name = getattr(settings, 'DFP_ADVERTISER_NAME', None)
    if advertiser_name is None:
        raise MissingSettingException('DFP_ADVERTISER_NAME')

    advertiser_type = getattr(settings, 'DFP_ADVERTISER_TYPE', "ADVERTISER")
    if advertiser_type != "ADVERTISER" and advertiser_type != "AD_NETWORK":
        raise BadSettingException('DFP_ADVERTISER_TYPE')

    order_name = getattr(settings, 'DFP_ORDER_NAME', None)
    if order_name is None:
        raise MissingSettingException('DFP_ORDER_NAME')

    lineitem_type = getattr(settings, 'DFP_LINEITEM_TYPE', None)
    if lineitem_type is None:
        raise MissingSettingException('DFP_LINEITEM_TYPE')

    num_placements = 0
    placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', None)
    placements_print = str(placements)
    if placements is None:
        placements = []
        placements_print = "RON"

    # if no placements are specified, we wil do run of network which is
    #   effectively one placement
    num_placements = len(placements)
    if num_placements == 0:
        num_placements = 1
        placements_print = "RON"
    creative_type = getattr(settings, 'OPENWRAP_CREATIVE_TYPE', None)
    if creative_type is None:
        creative_type = constant.WEB
    elif creative_type not in [
            constant.WEB, constant.WEB_SAFEFRAME, constant.AMP,
            constant.IN_APP, constant.NATIVE, constant.VIDEO,
            constant.JW_PLAYER
    ]:
        raise BadSettingException(
            'Unknown OPENWRAP_CREATIVE_TYPE: {0}'.format(creative_type))

    sizes = getattr(settings, 'DFP_PLACEMENT_SIZES', None)
    if creative_type != constant.NATIVE:
        if sizes is None:
            raise MissingSettingException('DFP_PLACEMENT_SIZES')
        elif len(sizes) < 1:
            raise BadSettingException('The setting "DFP_PLACEMENT_SIZES" '
                                      'must contain at least one size object.')

    currency_code = getattr(settings, 'DFP_CURRENCY_CODE', 'USD')

    # How many creatives to attach to each line item. We need at least one
    # creative per ad unit on a page. See:
    # https://github.com/kmjennison/dfp-prebid-setup/issues/13
    num_creatives = (getattr(settings, 'DFP_NUM_CREATIVES_PER_LINE_ITEM', None)
                     or num_placements)

    # read creative template for native Line-items
    creative_template = None
    if creative_type == constant.NATIVE:
        creative_template = getattr(settings, 'OPENWRAP_CREATIVE_TEMPLATE',
                                    None)
        if creative_template is None:
            raise MissingSettingException('OPENWRAP_CREATIVE_TEMPLATE')
        elif not isinstance(creative_template, (list, str)):
            raise BadSettingException('OPENWRAP_CREATIVE_TEMPLATE')
        if isinstance(creative_template, str):
            creative_template = [creative_template]

    bidder_code = getattr(settings, 'PREBID_BIDDER_CODE', None)
    if bidder_code is not None and not isinstance(bidder_code,
                                                  (list, tuple, str)):
        raise BadSettingException('PREBID_BIDDER_CODE')

    same_adv_exception = getattr(settings, 'DFP_SAME_ADV_EXCEPTION', False)
    if not isinstance(same_adv_exception, bool):
        raise BadSettingException('DFP_SAME_ADV_EXCEPTION')

    device_categories = getattr(settings, 'DFP_DEVICE_CATEGORIES', None)
    if device_categories is not None and not isinstance(
            device_categories, (list, tuple, str)):
        raise BadSettingException('DFP_DEVICE_CATEGORIES')

    device_capabilities = None
    #   We do not want to restrict line item based on device capabilties
    #   Disabling after a discussion with Lloyd
    #   if creative_type is constant.IN_APP:
    #       device_capabilities = ('Mobile Apps', 'MRAID v1', 'MRAID v2')

    roadblock_type = getattr(settings, 'DFP_ROADBLOCK_TYPE', 'ONE_OR_MORE')
    if roadblock_type not in ('ONE_OR_MORE', 'AS_MANY_AS_POSSIBLE'):
        raise BadSettingException('DFP_ROADBLOCK_TYPE')

    lineitem_prefix = getattr(settings, 'LINE_ITEM_PREFIX', None)
    if lineitem_prefix != None:
        if not isinstance(lineitem_prefix, (str)):
            raise BadSettingException('LINE_ITEM_PREFIX')

    use_1x1 = getattr(settings, 'OPENWRAP_USE_1x1_CREATIVE', False)
    if not isinstance(use_1x1, bool):
        raise BadSettingException('OPENWRAP_USE_1x1_CREATIVE')

    custom_targeting = getattr(settings, 'OPENWRAP_CUSTOM_TARGETING', None)
    if custom_targeting != None:
        if not isinstance(custom_targeting, (list, tuple)):
            raise BadSettingException('OPENWRAP_CUSTOM_TARGETING')

        for ct in custom_targeting:
            if len(ct) != 3:
                raise BadSettingException('OPENWRAP_CUSTOM_TARGETING')

            if ct[1] != "IS" and ct[1] != "IS_NOT":
                raise BadSettingException('OPENWRAP_CUSTOM_TARGETING')

            if not isinstance(ct[2], (list, tuple, str, bool)):
                raise BadSettingException(
                    'OPENWRAP_CUSTOM_TARGETING - {0}'.format(type(ct[2])))

    price_buckets_csv = getattr(settings, 'OPENWRAP_BUCKET_CSV', None)
    if price_buckets_csv is None:
        raise MissingSettingException('OPENWRAP_BUCKET_CSV')

    prices = load_price_csv(price_buckets_csv, creative_type)

    prices_summary = []
    for p in prices:
        prices_summary.append(p['rate'])

    if len(prices) > constant.LINE_ITEMS_LIMIT:
        print(
            '\n Error: {} Lineitems will be created. This is exceeding Line items count per order of {}!\n'
            .format(len(prices), constant.LINE_ITEMS_LIMIT))
        return

    # set bidder_code, custom_targetting, device categories to None when creative_type is IN-APP, JW_PLAYER
    # default roadblock_type to ONE_OR_MORE when creative_type is VIDEO, JW_PLAYER
    # default roadblock type to 'AS_MANY_AS_POSSIBLE' when creative_type is in-app

    if creative_type == constant.IN_APP:
        roadblock_type = 'AS_MANY_AS_POSSIBLE'
        #bidder_code = None
        custom_targeting = None
        device_categories = None
    elif creative_type == constant.JW_PLAYER:
        roadblock_type = 'ONE_OR_MORE'
        bidder_code = ['pubmatic']
        custom_targeting = None
        device_categories = None
    elif creative_type == constant.VIDEO:
        roadblock_type = 'ONE_OR_MORE'

    logger.info(u"""

    Going to create {name_start_format}{num_line_items}{format_end} new line items.
      {name_start_format}Order{format_end}: {value_start_format}{order_name}{format_end}
      {name_start_format}Advertiser{format_end}: {value_start_format}{advertiser}{format_end}
      {name_start_format}Advertiser Type{format_end}: {value_start_format}{advertiser_type}{format_end}
      {name_start_format}LineItem Type{format_end}: {value_start_format}{lineitem_type}{format_end}
      {name_start_format}LineItem Prefix{format_end}: {value_start_format}{lineitem_prefix}{format_end}
      {name_start_format}Creative Type{format_end} = {value_start_format}{creative_type}{format_end}
      {name_start_format}Use 1x1 Creative{format_end} = {value_start_format}{use_1x1}{format_end}

    Line items will have targeting:
      {name_start_format}rates{format_end} = {value_start_format}{prices_summary}{format_end}
      {name_start_format}bidders{format_end} = {value_start_format}{bidder_code}{format_end}
      {name_start_format}placements{format_end} = {value_start_format}{placements}{format_end}
      {name_start_format}custom targeting{format_end} = {value_start_format}{custom_targeting}{format_end}
      {name_start_format}same advertiser exception{format_end} = {value_start_format}{same_adv_exception}{format_end}
      {name_start_format}device categories{format_end} = {value_start_format}{device_categories}{format_end}
      {name_start_format}device capabilities{format_end} = {value_start_format}{device_capabilities}{format_end}
      {name_start_format}roadblock type{format_end} = {value_start_format}{roadblock_type}{format_end}
    """.format(
        num_line_items=len(prices),
        order_name=order_name,
        advertiser=advertiser_name,
        advertiser_type=advertiser_type,
        lineitem_type=lineitem_type,
        lineitem_prefix=lineitem_prefix,
        creative_type=creative_type,
        user_email=user_email,
        prices_summary=prices_summary,
        bidder_code=bidder_code,
        placements=placements_print,
        sizes=sizes,
        custom_targeting=custom_targeting,
        same_adv_exception=same_adv_exception,
        device_categories=device_categories,
        device_capabilities=device_capabilities,
        roadblock_type=roadblock_type,
        use_1x1=use_1x1,
        name_start_format=color.BOLD,
        format_end=color.END,
        value_start_format=color.BLUE,
    ))

    ok = input('Is this correct? (y/n)\n')

    if ok != 'y':
        logger.info('Exiting.')
        return

    try:
        setup_partner(user_email, advertiser_name, advertiser_type, order_name,
                      placements, sizes, lineitem_type, lineitem_prefix,
                      bidder_code, prices, creative_type, creative_template,
                      num_creatives, use_1x1, currency_code, custom_targeting,
                      same_adv_exception, device_categories,
                      device_capabilities, roadblock_type)
    except ConnectionError as e:
        logger.error(
            '\nConnection Error. Please try again after some time! Err: \n{}'.
            format(e))
    except GoogleAdsServerFault as e:
        if "ServerError.SERVER_ERROR" in str(e):
            logger.error(
                '\n\nDFP Server Error. Please try again after some time! Err: \n{}'
                .format(e))
        else:
            raise DFPException(
                "\n\nError occured while creating Lineitems in DFP: \n {}".
                format(e))
Exemplo n.º 9
0
def main():
    """
  Validate the settings and ask for confirmation from the user. Then,
  start all necessary DFP tasks.
  """

    user_email = getattr(settings, 'DFP_USER_EMAIL_ADDRESS', None)
    if user_email is None:
        raise MissingSettingException('DFP_USER_EMAIL_ADDRESS')

    advertiser_name = getattr(settings, 'DFP_ADVERTISER_NAME', None)
    if advertiser_name is None:
        raise MissingSettingException('DFP_ADVERTISER_NAME')

    order_name = getattr(settings, 'DFP_ORDER_NAME', None)
    if order_name is None:
        raise MissingSettingException('DFP_ORDER_NAME')

    placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', None)
    if placements is None:
        raise MissingSettingException('DFP_TARGETED_PLACEMENT_NAMES')
    elif len(placements) < 1:
        raise BadSettingException(
            'The setting "DFP_TARGETED_PLACEMENT_NAMES" '
            'must contain at least one DFP placement ID.')

    sizes = getattr(settings, 'DFP_PLACEMENT_SIZES', None)
    if sizes is None:
        raise MissingSettingException('DFP_PLACEMENT_SIZES')
    elif len(sizes) < 1:
        raise BadSettingException('The setting "DFP_PLACEMENT_SIZES" '
                                  'must contain at least one size object.')

    currency_code = getattr(settings, 'DFP_CURRENCY_CODE', 'USD')

    # How many creatives to attach to each line item. We need at least one
    # creative per ad unit on a page. See:
    # https://github.com/kmjennison/dfp-prebid-setup/issues/13
    num_creatives = (getattr(settings, 'DFP_NUM_CREATIVES_PER_LINE_ITEM', None)
                     or len(placements))

    bidder_code = getattr(settings, 'PREBID_BIDDER_CODE', None)
    if bidder_code is None:
        raise MissingSettingException('PREBID_BIDDER_CODE')

    price_buckets = getattr(settings, 'PREBID_PRICE_BUCKETS', None)
    if price_buckets is None:
        raise MissingSettingException('PREBID_PRICE_BUCKETS')

    check_price_buckets_validity(price_buckets)

    prices = get_prices_array(price_buckets)
    prices_summary = get_prices_summary_string(prices,
                                               price_buckets['precision'])

    logger.info(u"""

    Going to create {name_start_format}{num_line_items}{format_end} new line items.
      {name_start_format}Order{format_end}: {value_start_format}{order_name}{format_end}
      {name_start_format}Advertiser{format_end}: {value_start_format}{advertiser}{format_end}

    Line items will have targeting:
      {name_start_format}hb_pb{format_end} = {value_start_format}{prices_summary}{format_end}
      {name_start_format}hb_bidder{format_end} = {value_start_format}{bidder_code}{format_end}
      {name_start_format}placements{format_end} = {value_start_format}{placements}{format_end}

    """.format(
        num_line_items=len(prices),
        order_name=order_name,
        advertiser=advertiser_name,
        user_email=user_email,
        prices_summary=prices_summary,
        bidder_code=bidder_code,
        placements=placements,
        sizes=sizes,
        name_start_format=color.BOLD,
        format_end=color.END,
        value_start_format=color.BLUE,
    ))

    ok = input('Is this correct? (y/n)\n')

    if ok != 'y':
        logger.info('Exiting.')
        return

    setup_partner(
        user_email,
        advertiser_name,
        order_name,
        placements,
        sizes,
        bidder_code,
        prices,
        num_creatives,
        currency_code,
    )
Exemplo n.º 10
0
def main():
    """
  Validate the settings and ask for confirmation from the user. Then,
  start all necessary DFP tasks.
  """

    user_email = getattr(settings, 'DFP_USER_EMAIL_ADDRESS', None)
    if user_email is None:
        raise MissingSettingException('DFP_USER_EMAIL_ADDRESS')

    advertiser_name = getattr(settings, 'DFP_ADVERTISER_NAME', None)
    if advertiser_name is None:
        raise MissingSettingException('DFP_ADVERTISER_NAME')

    order_name = getattr(settings, 'DFP_ORDER_NAME', None)
    if order_name is None:
        raise MissingSettingException('DFP_ORDER_NAME')

    placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', None)
    no_inventory = getattr(settings, 'DFP_ALLOW_NO_INVENTORY_TARGETING', None)
    if placements is None:
        raise MissingSettingException('DFP_TARGETED_PLACEMENT_NAMES')
    elif len(placements) < 1 and no_inventory is not True:
        raise BadSettingException(
            'The setting "DFP_TARGETED_PLACEMENT_NAMES" '
            'must contain at least one DFP placement ID.')

    sizes = getattr(settings, 'DFP_PLACEMENT_SIZES', None)
    if sizes is None:
        raise MissingSettingException('DFP_PLACEMENT_SIZES')
    elif len(sizes) < 1:
        raise BadSettingException('The setting "DFP_PLACEMENT_SIZES" '
                                  'must contain at least one size object.')

    currency_code = getattr(settings, 'DFP_CURRENCY_CODE', 'USD')

    # How many creatives to attach to each line item. We need at least one
    # creative per ad unit on a page. See:
    # https://github.com/kmjennison/dfp-prebid-setup/issues/13
    num_creatives = (getattr(settings, 'DFP_NUM_CREATIVES_PER_LINE_ITEM', None)
                     or len(placements))

    # In the case where no inventory is being used, make sure at least one
    # creative is created
    if not num_creatives > 0:
        num_creatives = 1

    bidder_code = getattr(settings, 'PREBID_BIDDER_CODE', None)
    if bidder_code is None:
        raise MissingSettingException('PREBID_BIDDER_CODE')

    bidder_params = getattr(settings, 'PREBID_BIDDER_PARAMS', None)
    hb_pb_key = 'hb_pb'
    additional_keys = ''

    if bidder_params is True:
        hb_pb_key += '_' + bidder_code
        hb_adid_key = 'hb_adid_' + bidder_code
        hb_size_key = 'hb_size_' + bidder_code

        if len(hb_pb_key) > 20:
            hb_pb_key = hb_pb_key[:20]

        if len(hb_adid_key) > 20:
            hb_adid_key = hb_adid_key[:20]

        if len(hb_size_key) > 20:
            hb_size_key = hb_size_key[:20]

        additional_keys = u"""

    Additionally, keys {name_start_format}{hb_adid_key}{format_end} and {name_start_format}{hb_size_key}{format_end} will be created.""".format(
            hb_adid_key=hb_adid_key,
            hb_size_key=hb_size_key,
            name_start_format=color.BOLD,
            format_end=color.END,
        )

    price_buckets = getattr(settings, 'PREBID_PRICE_BUCKETS', None)
    if price_buckets is None:
        raise MissingSettingException('PREBID_PRICE_BUCKETS')

    check_price_buckets_validity(price_buckets)

    prices = get_prices_array(price_buckets)
    prices_summary = get_prices_summary_string(prices,
                                               price_buckets['precision'])

    logger.info(u"""

    Going to create {name_start_format}{num_line_items}{format_end} new line items.
      {name_start_format}Order{format_end}: {value_start_format}{order_name}{format_end}
      {name_start_format}Advertiser{format_end}: {value_start_format}{advertiser}{format_end}
      {name_start_format}Owner{format_end}: {value_start_format}{user_email}{format_end}

    Line items will have targeting:
      {name_start_format}{hb_pb_key}{format_end} = {value_start_format}{prices_summary}{format_end}
      {name_start_format}hb_bidder{format_end} = {value_start_format}{bidder_code}{format_end}
      {name_start_format}placements{format_end} = {value_start_format}{placements}{format_end}{additional_keys}

    """.format(num_line_items=len(prices),
               order_name=order_name,
               advertiser=advertiser_name,
               user_email=user_email,
               hb_pb_key=hb_pb_key,
               prices_summary=prices_summary,
               bidder_code=bidder_code,
               placements=placements,
               sizes=sizes,
               name_start_format=color.BOLD,
               format_end=color.END,
               value_start_format=color.BLUE,
               additional_keys=additional_keys))

    ok = input('Is this correct? (y/n)\n')

    if ok != 'y':
        logger.info('Exiting.')
        return

    setup_partner(
        user_email,
        advertiser_name,
        order_name,
        placements,
        sizes,
        bidder_code,
        prices,
        num_creatives,
        currency_code,
    )
def main():
    """
  Validate the settings and ask for confirmation from the user. Then,
  start all necessary DFP tasks.
  """

    user_email = getattr(settings, 'DFP_USER_EMAIL_ADDRESS', None)
    if user_email is None:
        raise MissingSettingException('DFP_USER_EMAIL_ADDRESS')

    advertiser_name = getattr(settings, 'DFP_ADVERTISER_NAME', None)
    if advertiser_name is None:
        raise MissingSettingException('DFP_ADVERTISER_NAME')

    order_name = getattr(settings, 'DFP_ORDER_NAME', None)
    if order_name is None:
        raise MissingSettingException('DFP_ORDER_NAME')

    placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', [])
    ad_units = getattr(settings, 'DFP_TARGETED_AD_UNIT_NAMES', [])

    if not ad_units and not placements:
        raise MissingSettingException(
            'DFP_TARGETED_PLACEMENT_NAMES or DFP_TARGETED_AD_UNIT_NAMES')
    elif (not placements or len(placements) < 1) and (not ad_units
                                                      or len(ad_units) < 1):
        raise BadSettingException(
            'The setting "DFP_TARGETED_PLACEMENT_NAMES" or "DFP_TARGETED_AD_UNIT_NAMES" '
            'must contain at least one DFP placement or ad unit.')

    sizes = getattr(settings, 'DFP_PLACEMENT_SIZES', None)
    if sizes is None:
        raise MissingSettingException('DFP_PLACEMENT_SIZES')
    elif len(sizes) < 1:
        raise BadSettingException('The setting "DFP_PLACEMENT_SIZES" '
                                  'must contain at least one size object.')

    currency_code = getattr(settings, 'DFP_CURRENCY_CODE', 'USD')

    # How many creatives to attach to each line item. We need at least one
    # creative per ad unit on a page. See:
    # https://github.com/kmjennison/dfp-prebid-setup/issues/13
    num_creatives = (getattr(settings, 'DFP_NUM_CREATIVES_PER_LINE_ITEM', None)
                     or len(placements))

    bidder_code = getattr(settings, 'PREBID_BIDDER_CODE', None)
    if bidder_code is None:
        logger.warning(
            'PREBID_BIDDER_CODE is not specified. Create one set of line items for all bidders.'
        )

    price_bucket_list = getattr(settings, 'PREBID_PRICE_BUCKETS', None)
    if price_bucket_list is None:
        raise MissingSettingException('PREBID_PRICE_BUCKETS')

    price_multipliers = getattr(settings, 'PRICE_MULTIPLIERS', {})
    price_multiplier = price_multipliers.get(currency_code, 1)

    # Validate price buckets and adjust by price_multiplier
    adjusted_price_buckets = []
    for price_bucket in price_bucket_list:
        check_price_buckets_validity(price_bucket)
        adjusted_price_buckets.append(
            adjust_price_bucket_by_price_multiplier(price_bucket,
                                                    price_multiplier))

    prices = get_prices_array_from_price_bucket_list(adjusted_price_buckets)
    prices_summary = get_prices_summary_string(
        prices, price_bucket_list[0]['precision'])

    logger.info(u"""

    Going to create {name_start_format}{num_line_items}{format_end} new line items.
      {name_start_format}Order{format_end}: {value_start_format}{order_name}{format_end}
      {name_start_format}Advertiser{format_end}: {value_start_format}{advertiser}{format_end}

    Line items will have targeting:
      {name_start_format}hb_pb{format_end} = {value_start_format}{prices_summary}{format_end}
      {name_start_format}hb_bidder{format_end} = {value_start_format}{bidder_code}{format_end}
      {name_start_format}placements{format_end} = {value_start_format}{placements}{format_end}
      {name_start_format}ad units{format_end} = {value_start_format}{ad_units}{format_end}

    """.format(
        num_line_items=len(prices),
        order_name=order_name,
        advertiser=advertiser_name,
        user_email=user_email,
        prices_summary=prices_summary,
        bidder_code=bidder_code or '(Targeting all bidders)',
        placements=placements,
        ad_units=ad_units,
        sizes=sizes,
        name_start_format=color.BOLD,
        format_end=color.END,
        value_start_format=color.BLUE,
    ))

    ok = input('Is thisy correct? (y/n)\n')

    if ok != 'y':
        logger.info('Exiting.')
        return

    setup_partner(user_email, advertiser_name, order_name, placements,
                  ad_units, sizes, bidder_code, prices, num_creatives,
                  currency_code)