diff --git a/bingads/internal/extensions.py b/bingads/internal/extensions.py
index ebcad040..e3c2217b 100644
--- a/bingads/internal/extensions.py
+++ b/bingads/internal/extensions.py
@@ -109,27 +109,43 @@ def budget_to_csv(bulk_campaign, row_values):
else:
row_values[_StringTable.Budget] = bulk_str(bulk_campaign.campaign.MonthlyBudget)
-
-# TODO as version specific logic added, consider to separate extensions with ap versions
-def csv_to_budget_v11(row_values, bulk_campaign):
- success, budget_type = row_values.try_get_value(_StringTable.BudgetType)
- if not success or not budget_type:
+def csv_to_biddingscheme(row_values, bulk_campaign):
+ success, bid_strategy_type = row_values.try_get_value(_StringTable.BidStrategyType)
+ if not success or not bid_strategy_type:
return
- success, budget_row_value = row_values.try_get_value(_StringTable.Budget)
- if not success:
- return
- budget_value = float(budget_row_value) if budget_row_value else None
+ csv_to_field_BidStrategyType(bulk_campaign.campaign, bid_strategy_type)
- bulk_campaign.campaign.BudgetType = budget_type
- bulk_campaign.campaign.DailyBudget = budget_value
+ success, max_cpc_row_value = row_values.try_get_value(_StringTable.BidStrategyMaxCpc)
+ max_cpc_value = float(max_cpc_row_value) if max_cpc_row_value else None
+ success, target_cpa_row_value = row_values.try_get_value(_StringTable.BidStrategyTargetCpa)
+ target_cpa_value = parse_bid(target_cpa_row_value) if target_cpa_row_value else None
-def budget_to_csv_v11(bulk_campaign, row_values):
- budget_type = bulk_campaign.campaign.BudgetType
- if not budget_type:
+ if bid_strategy_type == 'MaxConversions':
+ bulk_campaign.campaign.BiddingScheme.MaxCpc = max_cpc_value
+ elif bid_strategy_type == 'MaxClicks':
+ bulk_campaign.campaign.BiddingScheme.MaxCpc = max_cpc_value
+ elif bid_strategy_type == 'TargetCpa':
+ bulk_campaign.campaign.BiddingScheme.MaxCpc = max_cpc_value
+ bulk_campaign.campaign.BiddingScheme.TargetCpa = target_cpa_value
+
+
+def biddingscheme_to_csv(bulk_campaign, row_values):
+ bid_strategy_type = field_to_csv_BidStrategyType(bulk_campaign.campaign)
+
+ if not bid_strategy_type:
return
- row_values[_StringTable.Budget] = bulk_str(bulk_campaign.campaign.DailyBudget)
+
+ row_values[_StringTable.BidStrategyType] = bid_strategy_type
+
+ if bid_strategy_type == 'MaxConversions':
+ row_values[_StringTable.BidStrategyMaxCpc] = bid_bulk_str(bulk_campaign.campaign.BiddingScheme.MaxCpc.Bid)
+ elif bid_strategy_type == 'MaxClicks':
+ row_values[_StringTable.BidStrategyMaxCpc] = bid_bulk_str(bulk_campaign.campaign.BiddingScheme.MaxCpc.Bid)
+ elif bid_strategy_type == 'TargetCpa':
+ row_values[_StringTable.BidStrategyMaxCpc] = bid_bulk_str(bulk_campaign.campaign.BiddingScheme.MaxCpc.Bid)
+ row_values[_StringTable.BidStrategyTargetCpa] = bulk_str(bulk_campaign.campaign.BiddingScheme.TargetCpa)
def bulk_optional_str(value):
@@ -296,6 +312,33 @@ def field_to_csv_Urls(entity):
return None
return '; '.join(entity.string)
+def csv_to_field_CampaignLanguages(entity, value):
+ """
+ set Languages string field
+ :param entity: Languages
+ :param value: the content in csv
+ :return:set field values
+ """
+ if value is None or value == '':
+ return
+ splitter = re.compile(';')
+ entity.string = splitter.split(value)
+
+
+def field_to_csv_CampaignLanguages(entity):
+ """
+ parse entity to csv content
+ :param entity: Languages
+ :return: csv content
+ """
+ if entity is None:
+ return None
+ if entity.string is None:
+ return DELETE_VALUE
+ if len(entity.string) == 0:
+ return None
+ return '; '.join(entity.string)
+
def field_to_csv_BidStrategyType(entity):
"""
@@ -444,6 +487,22 @@ def parse_keyword_bid(value):
return bid
+def bid_bulk_str(value):
+ if value is None:
+ return DELETE_VALUE
+ if value.Amount is None:
+ return None
+ return bulk_str(value.Amount)
+
+
+def parse_bid(value):
+ bid = _CAMPAIGN_OBJECT_FACTORY_V10.create('Bid')
+ if not value:
+ bid.Amount = None
+ else:
+ bid.Amount = float(value)
+ return bid
+
def minute_bulk_str(value):
if value == 'Zero':
return '0'
diff --git a/bingads/manifest.py b/bingads/manifest.py
index 7b02575b..e271a0e5 100644
--- a/bingads/manifest.py
+++ b/bingads/manifest.py
@@ -1,4 +1,4 @@
-VERSION = '11.5.2'
+VERSION = '11.5.3'
BULK_FORMAT_VERSION = '3.0'
BULK_FORMAT_VERSION_4 = '4.0'
BULK_FORMAT_VERSION_5 = '5.0'
diff --git a/bingads/v10/bulk/entities/bulk_ad_group.py b/bingads/v10/bulk/entities/bulk_ad_group.py
index 4bda9fa2..2f8e4c9f 100644
--- a/bingads/v10/bulk/entities/bulk_ad_group.py
+++ b/bingads/v10/bulk/entities/bulk_ad_group.py
@@ -184,8 +184,8 @@ def performance_data(self):
),
_SimpleBulkMapping(
header=_StringTable.Language,
- field_to_csv=lambda c: c.ad_group.Language,
- csv_to_field=lambda c, v: setattr(c.ad_group, 'Language', v)
+ field_to_csv=lambda c: bulk_str(c.ad_group.Language),
+ csv_to_field=lambda c, v: setattr(c.ad_group, 'Language', v if v else None)
),
_SimpleBulkMapping(
header=_StringTable.BidAdjustment,
diff --git a/bingads/v10/bulk/entities/bulk_campaign.py b/bingads/v10/bulk/entities/bulk_campaign.py
index af52f69c..a18ce300 100644
--- a/bingads/v10/bulk/entities/bulk_campaign.py
+++ b/bingads/v10/bulk/entities/bulk_campaign.py
@@ -3,7 +3,6 @@
from bingads.v10.internal.bulk.string_table import _StringTable
from bingads.v10.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
from bingads.v10.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping
-# from bingads.internal.extensions import bulk_str, csv_to_budget, budget_to_csv
from bingads.internal.extensions import *
_ShoppingSetting = type(_CAMPAIGN_OBJECT_FACTORY_V10.create('ShoppingSetting'))
@@ -221,6 +220,11 @@ def _read_sales_country_code(c, v):
field_to_csv=lambda c: c.campaign.TimeZone,
csv_to_field=lambda c, v: setattr(c.campaign, 'TimeZone', v)
),
+ _SimpleBulkMapping(
+ header=_StringTable.Language,
+ field_to_csv=lambda c: field_to_csv_CampaignLanguages(c.campaign.Languages),
+ csv_to_field=lambda c, v: csv_to_field_CampaignLanguages(c.campaign.Languages, v)
+ ),
_ComplexBulkMapping(budget_to_csv, csv_to_budget),
_SimpleBulkMapping(
header=_StringTable.BidAdjustment,
@@ -247,7 +251,6 @@ def _read_sales_country_code(c, v):
csv_to_field=lambda c, v: BulkCampaign._read_sales_country_code(c, v)
),
_SimpleBulkMapping(
- # TODO now use bulk_str not bulk_optional_str
header=_StringTable.TrackingTemplate,
field_to_csv=lambda c: bulk_str(c.campaign.TrackingUrlTemplate),
csv_to_field=lambda c, v: setattr(c.campaign, 'TrackingUrlTemplate', v if v else None)
@@ -257,11 +260,7 @@ def _read_sales_country_code(c, v):
field_to_csv=lambda c: field_to_csv_UrlCustomParameters(c.campaign),
csv_to_field=lambda c, v: csv_to_field_UrlCustomParameters(c.campaign, v)
),
- _SimpleBulkMapping(
- header=_StringTable.BidStrategyType,
- field_to_csv=lambda c: field_to_csv_BidStrategyType(c.campaign),
- csv_to_field=lambda c, v: csv_to_field_BidStrategyType(c.campaign, v)
- ),
+ _ComplexBulkMapping(biddingscheme_to_csv, csv_to_biddingscheme),
_SimpleBulkMapping(
header=_StringTable.BudgetId,
field_to_csv=lambda c: bulk_str(c.campaign.BudgetId),
diff --git a/bingads/v10/internal/bulk/csv_headers.py b/bingads/v10/internal/bulk/csv_headers.py
index 977c7935..91ba7ba3 100644
--- a/bingads/v10/internal/bulk/csv_headers.py
+++ b/bingads/v10/internal/bulk/csv_headers.py
@@ -183,6 +183,8 @@ class _CsvHeaders:
# Bid Strategy
_StringTable.BidStrategyType,
+ _StringTable.BidStrategyMaxCpc,
+ _StringTable.BidStrategyTargetCpa,
# Ad Format Preference
_StringTable.AdFormatPreference,
diff --git a/bingads/v10/internal/bulk/string_table.py b/bingads/v10/internal/bulk/string_table.py
index 57088a99..818245b3 100644
--- a/bingads/v10/internal/bulk/string_table.py
+++ b/bingads/v10/internal/bulk/string_table.py
@@ -66,6 +66,7 @@ class _StringTable:
SyncTime = "Sync Time"
Name = "Name"
LastModifiedTime = "Modified Time"
+ AdFormatPreference = "Ad Format Preference"
# Entity Types
SemanticVersion = "Format Version"
@@ -242,7 +243,9 @@ class _StringTable:
# Bid Strategy
BidStrategyType = "Bid Strategy Type"
- AdFormatPreference = "Ad Format Preference"
+ BidStrategyMaxCpc = "Bid Strategy MaxCpc"
+ BidStrategyTargetCpa = "Bid Strategy TargetCpa"
+
# Remarketing
RemarketingList = "Remarketing List"
diff --git a/bingads/v10/proxies/campaign_management_service.xml b/bingads/v10/proxies/campaign_management_service.xml
index 7e947dc1..15bf48ff 100644
--- a/bingads/v10/proxies/campaign_management_service.xml
+++ b/bingads/v10/proxies/campaign_management_service.xml
@@ -1 +1,10189 @@
-12345671231632128512102440961232412123true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
+ 3
+
+
+
+
+
+
+ 4
+
+
+
+
+
+
+ 5
+
+
+
+
+
+
+ 6
+
+
+
+
+
+
+ 7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
+ 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 16
+
+
+
+
+
+
+ 32
+
+
+
+
+
+
+ 128
+
+
+
+
+
+
+ 512
+
+
+
+
+
+
+ 1024
+
+
+
+
+
+
+ 4096
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
+ 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
+ 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bingads/v11/bulk/entities/ad_extensions/__init__.py b/bingads/v11/bulk/entities/ad_extensions/__init__.py
index 738abdb0..eff831c0 100644
--- a/bingads/v11/bulk/entities/ad_extensions/__init__.py
+++ b/bingads/v11/bulk/entities/ad_extensions/__init__.py
@@ -9,3 +9,4 @@
from .bulk_review_ad_extensions import *
from .bulk_structured_snippet_ad_extensions import *
from .bulk_sitelink2_ad_extensions import *
+from .bulk_price_ad_extensions import *
\ No newline at end of file
diff --git a/bingads/v11/bulk/entities/ad_extensions/bulk_app_ad_extensions.py b/bingads/v11/bulk/entities/ad_extensions/bulk_app_ad_extensions.py
index 611320c4..d5f2859e 100644
--- a/bingads/v11/bulk/entities/ad_extensions/bulk_app_ad_extensions.py
+++ b/bingads/v11/bulk/entities/ad_extensions/bulk_app_ad_extensions.py
@@ -5,6 +5,8 @@
from .common import _BulkAdExtensionBase
from .common import _BulkAdGroupAdExtensionAssociation
from .common import _BulkCampaignAdExtensionAssociation
+from .common import _BulkAccountAdExtensionAssociation
+
from bingads.v11.internal.extensions import *
@@ -72,11 +74,6 @@ def app_ad_extension(self, value):
field_to_csv=lambda c: c.app_ad_extension.DisplayText,
csv_to_field=lambda c, v: setattr(c.app_ad_extension, 'DisplayText', v)
),
- _SimpleBulkMapping(
- header=_StringTable.DevicePreference,
- field_to_csv=lambda c: bulk_device_preference_str(c.app_ad_extension.DevicePreference),
- csv_to_field=lambda c, v: setattr(c.app_ad_extension, 'DevicePreference', parse_device_preference(v))
- ),
]
def process_mappings_from_row_values(self, row_values):
@@ -91,8 +88,26 @@ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
self.convert_to_values(row_values, BulkAppAdExtension._MAPPINGS)
+class BulkAccountAppAdExtension(_BulkAccountAdExtensionAssociation):
+ """ Represents an account level app ad extension.
+
+ This class exposes properties that can be read and written
+ as fields of the Account App Ad Extension record in a bulk file.
+
+ For more information, see Account App Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ pass
+
class BulkCampaignAppAdExtension(_BulkCampaignAdExtensionAssociation):
- """ Represents an campaign level app ad extension.
+ """ Represents a campaign level app ad extension.
This class exposes properties that can be read and written
as fields of the Campaign App Ad Extension record in a bulk file.
@@ -109,7 +124,6 @@ class BulkCampaignAppAdExtension(_BulkCampaignAdExtensionAssociation):
pass
-
class BulkAdGroupAppAdExtension(_BulkAdGroupAdExtensionAssociation):
""" Represents an ad group level App ad extension.
diff --git a/bingads/v11/bulk/entities/ad_extensions/bulk_callout_ad_extensions.py b/bingads/v11/bulk/entities/ad_extensions/bulk_callout_ad_extensions.py
index 6cd082e3..0d66e578 100644
--- a/bingads/v11/bulk/entities/ad_extensions/bulk_callout_ad_extensions.py
+++ b/bingads/v11/bulk/entities/ad_extensions/bulk_callout_ad_extensions.py
@@ -5,6 +5,7 @@
from .common import _BulkAdExtensionBase
from .common import _BulkAdGroupAdExtensionAssociation
from .common import _BulkCampaignAdExtensionAssociation
+from .common import _BulkAccountAdExtensionAssociation
_CalloutAdExtension = type(_CAMPAIGN_OBJECT_FACTORY_V11.create('CalloutAdExtension'))
@@ -69,8 +70,26 @@ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
self.convert_to_values(row_values, BulkCalloutAdExtension._MAPPINGS)
+class BulkAccountCalloutAdExtension(_BulkAccountAdExtensionAssociation):
+ """ Represents an account level callout ad extension.
+
+ This class exposes properties that can be read and written
+ as fields of the Account Callout Ad Extension record in a bulk file.
+
+ For more information, see Account Callout Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ pass
+
class BulkCampaignCalloutAdExtension(_BulkCampaignAdExtensionAssociation):
- """ Represents an campaign level callout ad extension.
+ """ Represents a campaign level callout ad extension.
This class exposes properties that can be read and written
as fields of the Campaign Callout Ad Extension record in a bulk file.
@@ -87,7 +106,6 @@ class BulkCampaignCalloutAdExtension(_BulkCampaignAdExtensionAssociation):
pass
-
class BulkAdGroupCalloutAdExtension(_BulkAdGroupAdExtensionAssociation):
""" Represents an ad group level Callout ad extension.
diff --git a/bingads/v11/bulk/entities/ad_extensions/bulk_image_ad_extensions.py b/bingads/v11/bulk/entities/ad_extensions/bulk_image_ad_extensions.py
index d8e7c577..8c7a2f99 100644
--- a/bingads/v11/bulk/entities/ad_extensions/bulk_image_ad_extensions.py
+++ b/bingads/v11/bulk/entities/ad_extensions/bulk_image_ad_extensions.py
@@ -6,7 +6,7 @@
from .common import _BulkAdExtensionBase
from .common import _BulkCampaignAdExtensionAssociation
from .common import _BulkAdGroupAdExtensionAssociation
-
+from .common import _BulkAccountAdExtensionAssociation
_ImageAdExtension = type(_CAMPAIGN_OBJECT_FACTORY_V11.create('ImageAdExtension'))
@@ -83,8 +83,27 @@ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
self.convert_to_values(row_values, BulkImageAdExtension._MAPPINGS)
+class BulkAccountImageAdExtension(_BulkAccountAdExtensionAssociation):
+ """ Represents an account level image ad extension.
+
+ This class exposes properties that can be read and written
+ as fields of the Account Image Ad Extension record in a bulk file.
+
+ For more information, see Account Image Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ pass
+
+
class BulkCampaignImageAdExtension(_BulkCampaignAdExtensionAssociation):
- """ Represents an campaign level image ad extension.
+ """ Represents a campaign level image ad extension.
This class exposes properties that can be read and written
as fields of the Campaign Image Ad Extension record in a bulk file.
@@ -101,7 +120,6 @@ class BulkCampaignImageAdExtension(_BulkCampaignAdExtensionAssociation):
pass
-
class BulkAdGroupImageAdExtension(_BulkAdGroupAdExtensionAssociation):
""" Represents an ad group level image ad extension.
diff --git a/bingads/v11/bulk/entities/ad_extensions/bulk_location_ad_extensions.py b/bingads/v11/bulk/entities/ad_extensions/bulk_location_ad_extensions.py
index 52bd5a56..965778a6 100644
--- a/bingads/v11/bulk/entities/ad_extensions/bulk_location_ad_extensions.py
+++ b/bingads/v11/bulk/entities/ad_extensions/bulk_location_ad_extensions.py
@@ -5,7 +5,7 @@
from .common import *
from .common import _BulkAdExtensionBase
from .common import _BulkCampaignAdExtensionAssociation
-
+from .common import _BulkAccountAdExtensionAssociation
_LocationAdExtension = type(_CAMPAIGN_OBJECT_FACTORY_V11.create('LocationAdExtension'))
@@ -209,8 +209,27 @@ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
self.convert_to_values(row_values, BulkLocationAdExtension._MAPPINGS)
+class BulkAccountLocationAdExtension(_BulkAccountAdExtensionAssociation):
+ """ Represents an account level location ad extension.
+
+ This class exposes properties that can be read and written
+ as fields of the Account Location Ad Extension record in a bulk file.
+
+ For more information, see Account Location Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ pass
+
+
class BulkCampaignLocationAdExtension(_BulkCampaignAdExtensionAssociation):
- """ Represents an campaign level location ad extension.
+ """ Represents a campaign level location ad extension.
This class exposes properties that can be read and written
as fields of the Campaign Location Ad Extension record in a bulk file.
@@ -225,4 +244,4 @@ class BulkCampaignLocationAdExtension(_BulkCampaignAdExtensionAssociation):
* :class:`.BulkFileWriter`
"""
- pass
+ pass
\ No newline at end of file
diff --git a/bingads/v11/bulk/entities/ad_extensions/bulk_price_ad_extensions.py b/bingads/v11/bulk/entities/ad_extensions/bulk_price_ad_extensions.py
new file mode 100644
index 00000000..85814012
--- /dev/null
+++ b/bingads/v11/bulk/entities/ad_extensions/bulk_price_ad_extensions.py
@@ -0,0 +1,147 @@
+from bingads.v11.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping
+from bingads.v11.internal.bulk.string_table import _StringTable
+from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V11
+
+from .common import _BulkAdExtensionBase
+from .common import _BulkAdGroupAdExtensionAssociation
+from .common import _BulkCampaignAdExtensionAssociation
+from .common import _BulkAccountAdExtensionAssociation
+
+from bingads.v11.internal.extensions import *
+
+_PriceAdExtension = type(_CAMPAIGN_OBJECT_FACTORY_V11.create('PriceAdExtension'))
+
+
+class BulkPriceAdExtension(_BulkAdExtensionBase):
+ """ Represents a Price Ad Extension.
+
+ This class exposes the :attr:`price_ad_extension` property that can be read and written
+ as fields of the Price Ad Extension record in a bulk file.
+
+ For more information, see Price Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ def __init__(self, account_id=None, ad_extension=None):
+ if ad_extension and not isinstance(ad_extension, _PriceAdExtension):
+ raise ValueError('The type of ad_extension is: {0}, should be: {1}'.format(
+ type(ad_extension),
+ 'PriceAdExtension'
+ ))
+ super(BulkPriceAdExtension, self).__init__(
+ account_id=account_id,
+ ad_extension=ad_extension
+ )
+
+ @property
+ def price_ad_extension(self):
+ """ The Price Ad Extension.
+
+ see Price Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
+ """
+
+ return self._ad_extension
+
+ @price_ad_extension.setter
+ def price_ad_extension(self, value):
+ self._ad_extension = value
+
+
+ _MAPPINGS = [
+ _SimpleBulkMapping(
+ header=_StringTable.Language,
+ field_to_csv=lambda c: c.price_ad_extension.Language,
+ csv_to_field=lambda c, v: setattr(c.price_ad_extension, 'Language', v)
+ ),
+ _SimpleBulkMapping(
+ header=_StringTable.PriceExtensionType,
+ field_to_csv=lambda c: c.price_ad_extension.PriceExtensionType,
+ csv_to_field=lambda c, v: setattr(c.price_ad_extension, 'PriceExtensionType', v)
+ ),
+ _SimpleBulkMapping(
+ header=_StringTable.TrackingTemplate,
+ field_to_csv=lambda c: bulk_str(c.price_ad_extension.TrackingUrlTemplate),
+ csv_to_field=lambda c, v: setattr(c.price_ad_extension, 'TrackingUrlTemplate', v if v else None)
+ ),
+ _SimpleBulkMapping(
+ header=_StringTable.CustomParameter,
+ field_to_csv=lambda c: field_to_csv_UrlCustomParameters(c.price_ad_extension),
+ csv_to_field=lambda c, v: csv_to_field_UrlCustomParameters(c.price_ad_extension, v)
+ ),
+ _ComplexBulkMapping(
+ entity_to_csv=lambda c, v: entity_to_csv_PriceTableRows(c.price_ad_extension, v),
+ csv_to_entity=lambda v, c: csv_to_entity_PriceTableRows(v, c.price_ad_extension)
+ ),
+ ]
+
+ def process_mappings_from_row_values(self, row_values):
+ self.price_ad_extension = _CAMPAIGN_OBJECT_FACTORY_V11.create('PriceAdExtension')
+ self.price_ad_extension.Type = 'PriceAdExtension'
+ super(BulkPriceAdExtension, self).process_mappings_from_row_values(row_values)
+ row_values.convert_to_entity(self, BulkPriceAdExtension._MAPPINGS)
+
+ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
+ self._validate_property_not_null(self.price_ad_extension, 'price_ad_extension')
+ super(BulkPriceAdExtension, self).process_mappings_to_row_values(row_values, exclude_readonly_data)
+ self.convert_to_values(row_values, BulkPriceAdExtension._MAPPINGS)
+
+
+class BulkAccountPriceAdExtension(_BulkAccountAdExtensionAssociation):
+ """ Represents an account level Price Ad Extension.
+
+ This class exposes properties that can be read and written
+ as fields of the Account Price Ad Extension record in a bulk file.
+
+ For more information, see Account Price Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ pass
+
+class BulkCampaignPriceAdExtension(_BulkCampaignAdExtensionAssociation):
+ """ Represents a campaign level Price Ad Extension.
+
+ This class exposes properties that can be read and written
+ as fields of the Campaign Price Ad Extension record in a bulk file.
+
+ For more information, see Campaign Price Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ pass
+
+class BulkAdGroupPriceAdExtension(_BulkAdGroupAdExtensionAssociation):
+ """ Represents an ad group level Price ad extension.
+
+ This class exposes properties that can be read and written
+ as fields of the Ad Group Price Ad Extension record in a bulk file.
+
+ For more information, see Ad Group Price Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ pass
diff --git a/bingads/v11/bulk/entities/ad_extensions/bulk_review_ad_extensions.py b/bingads/v11/bulk/entities/ad_extensions/bulk_review_ad_extensions.py
index ea96fd14..a5e184eb 100644
--- a/bingads/v11/bulk/entities/ad_extensions/bulk_review_ad_extensions.py
+++ b/bingads/v11/bulk/entities/ad_extensions/bulk_review_ad_extensions.py
@@ -5,6 +5,7 @@
from .common import _BulkAdExtensionBase
from .common import _BulkAdGroupAdExtensionAssociation
from .common import _BulkCampaignAdExtensionAssociation
+from .common import _BulkAccountAdExtensionAssociation
from bingads.v11.internal.extensions import *
@@ -87,8 +88,27 @@ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
self.convert_to_values(row_values, BulkReviewAdExtension._MAPPINGS)
+class BulkAccountReviewAdExtension(_BulkAccountAdExtensionAssociation):
+ """ Represents an account level review ad extension.
+
+ This class exposes properties that can be read and written
+ as fields of the Account Review Ad Extension record in a bulk file.
+
+ For more information, see Account Review Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ pass
+
+
class BulkCampaignReviewAdExtension(_BulkCampaignAdExtensionAssociation):
- """ Represents an campaign level review ad extension.
+ """ Represents a campaign level review ad extension.
This class exposes properties that can be read and written
as fields of the Campaign Review Ad Extension record in a bulk file.
@@ -105,7 +125,6 @@ class BulkCampaignReviewAdExtension(_BulkCampaignAdExtensionAssociation):
pass
-
class BulkAdGroupReviewAdExtension(_BulkAdGroupAdExtensionAssociation):
""" Represents an ad group level Review ad extension.
diff --git a/bingads/v11/bulk/entities/ad_extensions/bulk_sitelink2_ad_extensions.py b/bingads/v11/bulk/entities/ad_extensions/bulk_sitelink2_ad_extensions.py
index 6080c9a3..0e166e37 100644
--- a/bingads/v11/bulk/entities/ad_extensions/bulk_sitelink2_ad_extensions.py
+++ b/bingads/v11/bulk/entities/ad_extensions/bulk_sitelink2_ad_extensions.py
@@ -5,6 +5,7 @@
from .common import _BulkAdExtensionBase
from .common import _BulkAdGroupAdExtensionAssociation
from .common import _BulkCampaignAdExtensionAssociation
+from .common import _BulkAccountAdExtensionAssociation
from bingads.v11.internal.extensions import *
@@ -67,11 +68,6 @@ def sitelink2_ad_extension(self, value):
field_to_csv=lambda c: bulk_optional_str(c.sitelink2_ad_extension.DestinationUrl),
csv_to_field=lambda c, v: setattr(c.sitelink2_ad_extension, 'DestinationUrl', v if v else '')
),
- _SimpleBulkMapping(
- header=_StringTable.DevicePreference,
- field_to_csv=lambda c: bulk_device_preference_str(c.sitelink2_ad_extension.DevicePreference),
- csv_to_field=lambda c, v: setattr(c.sitelink2_ad_extension, 'DevicePreference', parse_device_preference(v))
- ),
_SimpleBulkMapping(
header=_StringTable.SiteLinkDisplayText,
field_to_csv=lambda c: c.sitelink2_ad_extension.DisplayText,
@@ -111,8 +107,26 @@ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
self.convert_to_values(row_values, BulkSitelink2AdExtension._MAPPINGS)
+class BulkAccountSitelink2AdExtension(_BulkAccountAdExtensionAssociation):
+ """ Represents an account level sitelink2 ad extension.
+
+ This class exposes properties that can be read and written
+ as fields of the Account Sitelink2 Ad Extension record in a bulk file.
+
+ For more information, see Account Sitelink2 Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ pass
+
class BulkCampaignSitelink2AdExtension(_BulkCampaignAdExtensionAssociation):
- """ Represents an campaign level sitelink2 ad extension.
+ """ Represents a campaign level sitelink2 ad extension.
This class exposes properties that can be read and written
as fields of the Campaign Sitelink2 Ad Extension record in a bulk file.
@@ -129,7 +143,6 @@ class BulkCampaignSitelink2AdExtension(_BulkCampaignAdExtensionAssociation):
pass
-
class BulkAdGroupSitelink2AdExtension(_BulkAdGroupAdExtensionAssociation):
""" Represents an ad group level Sitelink2 ad extension.
diff --git a/bingads/v11/bulk/entities/ad_extensions/bulk_structured_snippet_ad_extensions.py b/bingads/v11/bulk/entities/ad_extensions/bulk_structured_snippet_ad_extensions.py
index e2daf5e2..64644af3 100644
--- a/bingads/v11/bulk/entities/ad_extensions/bulk_structured_snippet_ad_extensions.py
+++ b/bingads/v11/bulk/entities/ad_extensions/bulk_structured_snippet_ad_extensions.py
@@ -5,6 +5,7 @@
from .common import _BulkAdExtensionBase
from .common import _BulkAdGroupAdExtensionAssociation
from .common import _BulkCampaignAdExtensionAssociation
+from .common import _BulkAccountAdExtensionAssociation
from bingads.v11.internal.extensions import *
@@ -76,8 +77,26 @@ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
self.convert_to_values(row_values, BulkStructuredSnippetAdExtension._MAPPINGS)
+class BulkAccountStructuredSnippetAdExtension(_BulkAccountAdExtensionAssociation):
+ """ Represents an account level structured snippet ad extension.
+
+ This class exposes properties that can be read and written
+ as fields of the Account Structured Snippet Ad Extension record in a bulk file.
+
+ For more information, see Account Structured Snippet Extension at https://go.microsoft.com/fwlink/?linkid=846127
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ pass
+
class BulkCampaignStructuredSnippetAdExtension(_BulkCampaignAdExtensionAssociation):
- """ Represents an campaign level structured snippet ad extension.
+ """ Represents a campaign level structured snippet ad extension.
This class exposes properties that can be read and written
as fields of the Campaign Structured Snippet Ad Extension record in a bulk file.
@@ -94,7 +113,6 @@ class BulkCampaignStructuredSnippetAdExtension(_BulkCampaignAdExtensionAssociati
pass
-
class BulkAdGroupStructuredSnippetAdExtension(_BulkAdGroupAdExtensionAssociation):
""" Represents an ad group level structured snippet ad extension.
diff --git a/bingads/v11/bulk/entities/ad_extensions/common.py b/bingads/v11/bulk/entities/ad_extensions/common.py
index 71e95ac4..cf3258fe 100644
--- a/bingads/v11/bulk/entities/ad_extensions/common.py
+++ b/bingads/v11/bulk/entities/ad_extensions/common.py
@@ -81,6 +81,11 @@ def account_id(self, account_id):
field_to_csv=lambda c: field_to_csv_UseSearcherTimeZone(c._ad_extension.Scheduling),
csv_to_field=lambda c, v: setattr(c._ad_extension.Scheduling, 'UseSearcherTimeZone', parse_bool(v))
),
+ _SimpleBulkMapping(
+ header=_StringTable.DevicePreference,
+ field_to_csv=lambda c: bulk_device_preference_str(c._ad_extension.DevicePreference),
+ csv_to_field=lambda c, v: setattr(c._ad_extension, 'DevicePreference', parse_device_preference(v))
+ ),
]
def process_mappings_from_row_values(self, row_values):
@@ -200,6 +205,20 @@ def read_additional_data(self, stream_reader):
super(_BulkAdExtensionAssociation, self).read_additional_data(stream_reader)
+class _BulkAccountAdExtensionAssociation(_BulkAdExtensionAssociation):
+ """ This abstract class provides properties that are shared by all bulk account ad extension association classes. """
+
+ def __init__(self,
+ ad_extension_id_to_entity_id_association=None,
+ status=None,
+ editorial_status=None):
+ super(_BulkAccountAdExtensionAssociation, self).__init__(
+ ad_extension_id_to_entity_id_association,
+ status,
+ editorial_status,
+ )
+
+
class _BulkCampaignAdExtensionAssociation(_BulkAdExtensionAssociation):
""" This abstract class provides properties that are shared by all bulk campaign ad extension association classes. """
diff --git a/bingads/v11/bulk/entities/audiences/__init__.py b/bingads/v11/bulk/entities/audiences/__init__.py
index 494a5c53..bdf47a02 100644
--- a/bingads/v11/bulk/entities/audiences/__init__.py
+++ b/bingads/v11/bulk/entities/audiences/__init__.py
@@ -3,3 +3,10 @@
from .bulk_remarketing_list import *
from .bulk_ad_group_remarketing_list_association import *
+from .bulk_ad_group_negative_remarketing_list_association import *
+from .bulk_custom_audience import *
+from .bulk_ad_group_custom_audience_association import *
+from .bulk_ad_group_negative_custom_audience_association import *
+from .bulk_in_market_audience import *
+from .bulk_ad_group_in_market_audience_association import *
+from .bulk_ad_group_negative_in_market_audience_association import *
diff --git a/bingads/v11/bulk/entities/audiences/bulk_ad_group_custom_audience_association.py b/bingads/v11/bulk/entities/audiences/bulk_ad_group_custom_audience_association.py
new file mode 100644
index 00000000..4eec0043
--- /dev/null
+++ b/bingads/v11/bulk/entities/audiences/bulk_ad_group_custom_audience_association.py
@@ -0,0 +1,152 @@
+from bingads.v11.bulk.entities import *
+from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V11
+from bingads.v11.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
+from bingads.v11.internal.bulk.mappings import _SimpleBulkMapping
+from bingads.v11.internal.bulk.string_table import _StringTable
+from bingads.v11.internal.extensions import *
+
+
+class BulkAdGroupCustomAudienceAssociation(_SingleRecordBulkEntity):
+ """ Represents an Ad Group Custom Audience Association that can be read or written in a bulk file.
+
+ This class exposes the :attr:`biddable_ad_group_criterion` property that can be read and written as fields of the
+ Ad Group Custom Audience Association record in a bulk file.
+
+ For more information, see Ad Group Custom Audience Association at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ def __init__(self,
+ biddable_ad_group_criterion=None,
+ campaign_name=None,
+ ad_group_name=None,
+ custom_audience_name=None):
+ super(BulkAdGroupCustomAudienceAssociation, self).__init__()
+
+ self._biddable_ad_group_criterion = biddable_ad_group_criterion
+ self._campaign_name = campaign_name
+ self._ad_group_name = ad_group_name
+ self._custom_audience_name = custom_audience_name
+ self._performance_data = None
+
+ _MAPPINGS = [
+ _SimpleBulkMapping(
+ _StringTable.Status,
+ field_to_csv=lambda c: bulk_str(c.biddable_ad_group_criterion.Status),
+ csv_to_field=lambda c, v: setattr(c.biddable_ad_group_criterion, 'Status', v if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Id,
+ field_to_csv=lambda c: bulk_str(c.biddable_ad_group_criterion.Id),
+ csv_to_field=lambda c, v: setattr(c.biddable_ad_group_criterion, 'Id', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.ParentId,
+ field_to_csv=lambda c: bulk_str(c.biddable_ad_group_criterion.AdGroupId),
+ csv_to_field=lambda c, v: setattr(c.biddable_ad_group_criterion, 'AdGroupId', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Campaign,
+ field_to_csv=lambda c: c.campaign_name,
+ csv_to_field=lambda c, v: setattr(c, 'campaign_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.AdGroup,
+ field_to_csv=lambda c: c.ad_group_name,
+ csv_to_field=lambda c, v: setattr(c, 'ad_group_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Audience,
+ field_to_csv=lambda c: c.custom_audience_name,
+ csv_to_field=lambda c, v: setattr(c, 'custom_audience_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.BidAdjustment,
+ field_to_csv=lambda c: field_to_csv_BidAdjustment(c.biddable_ad_group_criterion),
+ csv_to_field=lambda c, v: csv_to_field_BidAdjustment(c.biddable_ad_group_criterion, float(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.AudienceId,
+ field_to_csv=lambda c: field_to_csv_CriterionAudienceId(c.biddable_ad_group_criterion),
+ csv_to_field=lambda c, v: csv_to_field_CriterionAudienceId(c.biddable_ad_group_criterion, int(v) if v else None)
+ ),
+ ]
+
+ @property
+ def biddable_ad_group_criterion(self):
+ """ Defines a Biddable Ad Group Criterion """
+
+ return self._biddable_ad_group_criterion
+
+ @biddable_ad_group_criterion.setter
+ def biddable_ad_group_criterion(self, biddable_ad_group_criterion):
+ self._biddable_ad_group_criterion = biddable_ad_group_criterion
+
+ @property
+ def campaign_name(self):
+ """ Defines the name of the Campaign.
+
+ :rtype: str
+ """
+
+ return self._campaign_name
+
+ @campaign_name.setter
+ def campaign_name(self, campaign_name):
+ self._campaign_name = campaign_name
+
+ @property
+ def ad_group_name(self):
+ """ Defines the name of the Ad Group
+
+ :rtype: str
+ """
+
+ return self._ad_group_name
+
+ @ad_group_name.setter
+ def ad_group_name(self, ad_group_name):
+ self._ad_group_name = ad_group_name
+
+ @property
+ def custom_audience_name(self):
+ """ Defines the name of the Custom Audience
+
+ :rtype: str
+ """
+
+ return self._custom_audience_name
+
+ @custom_audience_name.setter
+ def custom_audience_name(self, custom_audience_name):
+ self._custom_audience_name = custom_audience_name
+
+ @property
+ def performance_data(self):
+ return self._performance_data
+
+ def process_mappings_from_row_values(self, row_values):
+ self._biddable_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('BiddableAdGroupCriterion')
+ self._biddable_ad_group_criterion.Type = 'BiddableAdGroupCriterion'
+ self._biddable_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('AudienceCriterion')
+ self._biddable_ad_group_criterion.Criterion.Type = 'AudienceCriterion'
+ self._biddable_ad_group_criterion.CriterionBid = _CAMPAIGN_OBJECT_FACTORY_V11.create('BidMultiplier')
+ self._biddable_ad_group_criterion.CriterionBid.Type = 'BidMultiplier'
+ row_values.convert_to_entity(self, BulkAdGroupCustomAudienceAssociation._MAPPINGS)
+
+ self._performance_data = PerformanceData.read_from_row_values_or_null(row_values)
+
+ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
+ self._validate_property_not_null(self.biddable_ad_group_criterion, 'biddable_ad_group_criterion')
+ self.convert_to_values(row_values, BulkAdGroupCustomAudienceAssociation._MAPPINGS)
+
+ PerformanceData.write_to_row_values_if_not_null(self._performance_data, row_values)
+
+ def read_additional_data(self, stream_reader):
+ super(BulkAdGroupCustomAudienceAssociation, self).read_additional_data(stream_reader)
diff --git a/bingads/v11/bulk/entities/audiences/bulk_ad_group_in_market_audience_association.py b/bingads/v11/bulk/entities/audiences/bulk_ad_group_in_market_audience_association.py
new file mode 100644
index 00000000..1484d17a
--- /dev/null
+++ b/bingads/v11/bulk/entities/audiences/bulk_ad_group_in_market_audience_association.py
@@ -0,0 +1,152 @@
+from bingads.v11.bulk.entities import *
+from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V11
+from bingads.v11.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
+from bingads.v11.internal.bulk.mappings import _SimpleBulkMapping
+from bingads.v11.internal.bulk.string_table import _StringTable
+from bingads.v11.internal.extensions import *
+
+
+class BulkAdGroupInMarketAudienceAssociation(_SingleRecordBulkEntity):
+ """ Represents an Ad Group In Market Audience Association that can be read or written in a bulk file.
+
+ This class exposes the :attr:`biddable_ad_group_criterion` property that can be read and written as fields of the
+ Ad Group In Market Audience Association record in a bulk file.
+
+ For more information, see Ad Group In Market Audience Association at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ def __init__(self,
+ biddable_ad_group_criterion=None,
+ campaign_name=None,
+ ad_group_name=None,
+ in_market_audience_name=None):
+ super(BulkAdGroupInMarketAudienceAssociation, self).__init__()
+
+ self._biddable_ad_group_criterion = biddable_ad_group_criterion
+ self._campaign_name = campaign_name
+ self._ad_group_name = ad_group_name
+ self._in_market_audience_name = in_market_audience_name
+ self._performance_data = None
+
+ _MAPPINGS = [
+ _SimpleBulkMapping(
+ _StringTable.Status,
+ field_to_csv=lambda c: bulk_str(c.biddable_ad_group_criterion.Status),
+ csv_to_field=lambda c, v: setattr(c.biddable_ad_group_criterion, 'Status', v if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Id,
+ field_to_csv=lambda c: bulk_str(c.biddable_ad_group_criterion.Id),
+ csv_to_field=lambda c, v: setattr(c.biddable_ad_group_criterion, 'Id', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.ParentId,
+ field_to_csv=lambda c: bulk_str(c.biddable_ad_group_criterion.AdGroupId),
+ csv_to_field=lambda c, v: setattr(c.biddable_ad_group_criterion, 'AdGroupId', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Campaign,
+ field_to_csv=lambda c: c.campaign_name,
+ csv_to_field=lambda c, v: setattr(c, 'campaign_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.AdGroup,
+ field_to_csv=lambda c: c.ad_group_name,
+ csv_to_field=lambda c, v: setattr(c, 'ad_group_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Audience,
+ field_to_csv=lambda c: c.in_market_audience_name,
+ csv_to_field=lambda c, v: setattr(c, 'in_market_audience_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.BidAdjustment,
+ field_to_csv=lambda c: field_to_csv_BidAdjustment(c.biddable_ad_group_criterion),
+ csv_to_field=lambda c, v: csv_to_field_BidAdjustment(c.biddable_ad_group_criterion, float(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.AudienceId,
+ field_to_csv=lambda c: field_to_csv_CriterionAudienceId(c.biddable_ad_group_criterion),
+ csv_to_field=lambda c, v: csv_to_field_CriterionAudienceId(c.biddable_ad_group_criterion, int(v) if v else None)
+ ),
+ ]
+
+ @property
+ def biddable_ad_group_criterion(self):
+ """ Defines a Biddable Ad Group Criterion """
+
+ return self._biddable_ad_group_criterion
+
+ @biddable_ad_group_criterion.setter
+ def biddable_ad_group_criterion(self, biddable_ad_group_criterion):
+ self._biddable_ad_group_criterion = biddable_ad_group_criterion
+
+ @property
+ def campaign_name(self):
+ """ Defines the name of the Campaign.
+
+ :rtype: str
+ """
+
+ return self._campaign_name
+
+ @campaign_name.setter
+ def campaign_name(self, campaign_name):
+ self._campaign_name = campaign_name
+
+ @property
+ def ad_group_name(self):
+ """ Defines the name of the Ad Group
+
+ :rtype: str
+ """
+
+ return self._ad_group_name
+
+ @ad_group_name.setter
+ def ad_group_name(self, ad_group_name):
+ self._ad_group_name = ad_group_name
+
+ @property
+ def in_market_audience_name(self):
+ """ Defines the name of the In Market Audience
+
+ :rtype: str
+ """
+
+ return self._in_market_audience_name
+
+ @in_market_audience_name.setter
+ def in_market_audience_name(self, in_market_audience_name):
+ self._in_market_audience_name = in_market_audience_name
+
+ @property
+ def performance_data(self):
+ return self._performance_data
+
+ def process_mappings_from_row_values(self, row_values):
+ self._biddable_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('BiddableAdGroupCriterion')
+ self._biddable_ad_group_criterion.Type = 'BiddableAdGroupCriterion'
+ self._biddable_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('AudienceCriterion')
+ self._biddable_ad_group_criterion.Criterion.Type = 'AudienceCriterion'
+ self._biddable_ad_group_criterion.CriterionBid = _CAMPAIGN_OBJECT_FACTORY_V11.create('BidMultiplier')
+ self._biddable_ad_group_criterion.CriterionBid.Type = 'BidMultiplier'
+ row_values.convert_to_entity(self, BulkAdGroupInMarketAudienceAssociation._MAPPINGS)
+
+ self._performance_data = PerformanceData.read_from_row_values_or_null(row_values)
+
+ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
+ self._validate_property_not_null(self.biddable_ad_group_criterion, 'biddable_ad_group_criterion')
+ self.convert_to_values(row_values, BulkAdGroupInMarketAudienceAssociation._MAPPINGS)
+
+ PerformanceData.write_to_row_values_if_not_null(self._performance_data, row_values)
+
+ def read_additional_data(self, stream_reader):
+ super(BulkAdGroupInMarketAudienceAssociation, self).read_additional_data(stream_reader)
diff --git a/bingads/v11/bulk/entities/audiences/bulk_ad_group_negative_custom_audience_association.py b/bingads/v11/bulk/entities/audiences/bulk_ad_group_negative_custom_audience_association.py
new file mode 100644
index 00000000..18fbfdf3
--- /dev/null
+++ b/bingads/v11/bulk/entities/audiences/bulk_ad_group_negative_custom_audience_association.py
@@ -0,0 +1,136 @@
+from bingads.v11.bulk.entities import *
+from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V11
+from bingads.v11.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
+from bingads.v11.internal.bulk.mappings import _SimpleBulkMapping
+from bingads.v11.internal.bulk.string_table import _StringTable
+from bingads.v11.internal.extensions import *
+
+
+class BulkAdGroupNegativeCustomAudienceAssociation(_SingleRecordBulkEntity):
+ """ Represents an Ad Group Negative Custom Audience Association that can be read or written in a bulk file.
+
+ This class exposes the :attr:`negative_ad_group_criterion` property that can be read and written as fields of the
+ Ad Group Negative Custom Audience Association record in a bulk file.
+
+ For more information, see Ad Group Negative Custom Audience Association at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ def __init__(self,
+ negative_ad_group_criterion=None,
+ campaign_name=None,
+ ad_group_name=None,
+ custom_audience_name=None):
+ super(BulkAdGroupNegativeCustomAudienceAssociation, self).__init__()
+
+ self._negative_ad_group_criterion = negative_ad_group_criterion
+ self._campaign_name = campaign_name
+ self._ad_group_name = ad_group_name
+ self._custom_audience_name = custom_audience_name
+
+ _MAPPINGS = [
+ _SimpleBulkMapping(
+ _StringTable.Status,
+ field_to_csv=lambda c: bulk_str(c.negative_ad_group_criterion.Status),
+ csv_to_field=lambda c, v: setattr(c.negative_ad_group_criterion, 'Status', v if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Id,
+ field_to_csv=lambda c: bulk_str(c.negative_ad_group_criterion.Id),
+ csv_to_field=lambda c, v: setattr(c.negative_ad_group_criterion, 'Id', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.ParentId,
+ field_to_csv=lambda c: bulk_str(c.negative_ad_group_criterion.AdGroupId),
+ csv_to_field=lambda c, v: setattr(c.negative_ad_group_criterion, 'AdGroupId', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Campaign,
+ field_to_csv=lambda c: c.campaign_name,
+ csv_to_field=lambda c, v: setattr(c, 'campaign_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.AdGroup,
+ field_to_csv=lambda c: c.ad_group_name,
+ csv_to_field=lambda c, v: setattr(c, 'ad_group_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Audience,
+ field_to_csv=lambda c: c.custom_audience_name,
+ csv_to_field=lambda c, v: setattr(c, 'custom_audience_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.AudienceId,
+ field_to_csv=lambda c: field_to_csv_CriterionAudienceId(c.negative_ad_group_criterion),
+ csv_to_field=lambda c, v: csv_to_field_CriterionAudienceId(c.negative_ad_group_criterion, int(v) if v else None)
+ ),
+ ]
+
+ @property
+ def negative_ad_group_criterion(self):
+ """ Defines a Negative Ad Group Criterion """
+
+ return self._negative_ad_group_criterion
+
+ @negative_ad_group_criterion.setter
+ def negative_ad_group_criterion(self, negative_ad_group_criterion):
+ self._negative_ad_group_criterion = negative_ad_group_criterion
+
+ @property
+ def campaign_name(self):
+ """ Defines the name of the Campaign.
+
+ :rtype: str
+ """
+
+ return self._campaign_name
+
+ @campaign_name.setter
+ def campaign_name(self, campaign_name):
+ self._campaign_name = campaign_name
+
+ @property
+ def ad_group_name(self):
+ """ Defines the name of the Ad Group
+
+ :rtype: str
+ """
+
+ return self._ad_group_name
+
+ @ad_group_name.setter
+ def ad_group_name(self, ad_group_name):
+ self._ad_group_name = ad_group_name
+
+ @property
+ def custom_audience_name(self):
+ """ Defines the name of the Custom Audience
+
+ :rtype: str
+ """
+
+ return self._custom_audience_name
+
+ @custom_audience_name.setter
+ def custom_audience_name(self, custom_audience_name):
+ self._custom_audience_name = custom_audience_name
+
+ def process_mappings_from_row_values(self, row_values):
+ self._negative_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('NegativeAdGroupCriterion')
+ self._negative_ad_group_criterion.Type = 'NegativeAdGroupCriterion'
+ self._negative_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('AudienceCriterion')
+ self._negative_ad_group_criterion.Criterion.Type = 'AudienceCriterion'
+ row_values.convert_to_entity(self, BulkAdGroupNegativeCustomAudienceAssociation._MAPPINGS)
+
+ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
+ self._validate_property_not_null(self.negative_ad_group_criterion, 'negative_ad_group_criterion')
+ self.convert_to_values(row_values, BulkAdGroupNegativeCustomAudienceAssociation._MAPPINGS)
+
+ def read_additional_data(self, stream_reader):
+ super(BulkAdGroupNegativeCustomAudienceAssociation, self).read_additional_data(stream_reader)
diff --git a/bingads/v11/bulk/entities/audiences/bulk_ad_group_negative_in_market_audience_association.py b/bingads/v11/bulk/entities/audiences/bulk_ad_group_negative_in_market_audience_association.py
new file mode 100644
index 00000000..89c7ba35
--- /dev/null
+++ b/bingads/v11/bulk/entities/audiences/bulk_ad_group_negative_in_market_audience_association.py
@@ -0,0 +1,136 @@
+from bingads.v11.bulk.entities import *
+from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V11
+from bingads.v11.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
+from bingads.v11.internal.bulk.mappings import _SimpleBulkMapping
+from bingads.v11.internal.bulk.string_table import _StringTable
+from bingads.v11.internal.extensions import *
+
+
+class BulkAdGroupNegativeInMarketAudienceAssociation(_SingleRecordBulkEntity):
+ """ Represents an Ad Group Negative In Market Audience Association that can be read or written in a bulk file.
+
+ This class exposes the :attr:`negative_ad_group_criterion` property that can be read and written as fields of the
+ Ad Group Negative In Market Audience Association record in a bulk file.
+
+ For more information, see Ad Group Negative In Market Audience Association at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ def __init__(self,
+ negative_ad_group_criterion=None,
+ campaign_name=None,
+ ad_group_name=None,
+ in_market_audience_name=None):
+ super(BulkAdGroupNegativeInMarketAudienceAssociation, self).__init__()
+
+ self._negative_ad_group_criterion = negative_ad_group_criterion
+ self._campaign_name = campaign_name
+ self._ad_group_name = ad_group_name
+ self._in_market_audience_name = in_market_audience_name
+
+ _MAPPINGS = [
+ _SimpleBulkMapping(
+ _StringTable.Status,
+ field_to_csv=lambda c: bulk_str(c.negative_ad_group_criterion.Status),
+ csv_to_field=lambda c, v: setattr(c.negative_ad_group_criterion, 'Status', v if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Id,
+ field_to_csv=lambda c: bulk_str(c.negative_ad_group_criterion.Id),
+ csv_to_field=lambda c, v: setattr(c.negative_ad_group_criterion, 'Id', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.ParentId,
+ field_to_csv=lambda c: bulk_str(c.negative_ad_group_criterion.AdGroupId),
+ csv_to_field=lambda c, v: setattr(c.negative_ad_group_criterion, 'AdGroupId', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Campaign,
+ field_to_csv=lambda c: c.campaign_name,
+ csv_to_field=lambda c, v: setattr(c, 'campaign_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.AdGroup,
+ field_to_csv=lambda c: c.ad_group_name,
+ csv_to_field=lambda c, v: setattr(c, 'ad_group_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Audience,
+ field_to_csv=lambda c: c.in_market_audience_name,
+ csv_to_field=lambda c, v: setattr(c, 'in_market_audience_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.AudienceId,
+ field_to_csv=lambda c: field_to_csv_CriterionAudienceId(c.negative_ad_group_criterion),
+ csv_to_field=lambda c, v: csv_to_field_CriterionAudienceId(c.negative_ad_group_criterion, int(v) if v else None)
+ ),
+ ]
+
+ @property
+ def negative_ad_group_criterion(self):
+ """ Defines a Negative Ad Group Criterion """
+
+ return self._negative_ad_group_criterion
+
+ @negative_ad_group_criterion.setter
+ def negative_ad_group_criterion(self, negative_ad_group_criterion):
+ self._negative_ad_group_criterion = negative_ad_group_criterion
+
+ @property
+ def campaign_name(self):
+ """ Defines the name of the Campaign.
+
+ :rtype: str
+ """
+
+ return self._campaign_name
+
+ @campaign_name.setter
+ def campaign_name(self, campaign_name):
+ self._campaign_name = campaign_name
+
+ @property
+ def ad_group_name(self):
+ """ Defines the name of the Ad Group
+
+ :rtype: str
+ """
+
+ return self._ad_group_name
+
+ @ad_group_name.setter
+ def ad_group_name(self, ad_group_name):
+ self._ad_group_name = ad_group_name
+
+ @property
+ def in_market_audience_name(self):
+ """ Defines the name of the In Market Audience
+
+ :rtype: str
+ """
+
+ return self._in_market_audience_name
+
+ @in_market_audience_name.setter
+ def in_market_audience_name(self, in_market_audience_name):
+ self._in_market_audience_name = in_market_audience_name
+
+ def process_mappings_from_row_values(self, row_values):
+ self._negative_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('NegativeAdGroupCriterion')
+ self._negative_ad_group_criterion.Type = 'NegativeAdGroupCriterion'
+ self._negative_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('AudienceCriterion')
+ self._negative_ad_group_criterion.Criterion.Type = 'AudienceCriterion'
+ row_values.convert_to_entity(self, BulkAdGroupNegativeInMarketAudienceAssociation._MAPPINGS)
+
+ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
+ self._validate_property_not_null(self.negative_ad_group_criterion, 'negative_ad_group_criterion')
+ self.convert_to_values(row_values, BulkAdGroupNegativeInMarketAudienceAssociation._MAPPINGS)
+
+ def read_additional_data(self, stream_reader):
+ super(BulkAdGroupNegativeInMarketAudienceAssociation, self).read_additional_data(stream_reader)
diff --git a/bingads/v11/bulk/entities/audiences/bulk_ad_group_negative_remarketing_list_association.py b/bingads/v11/bulk/entities/audiences/bulk_ad_group_negative_remarketing_list_association.py
new file mode 100644
index 00000000..d2e2d5e4
--- /dev/null
+++ b/bingads/v11/bulk/entities/audiences/bulk_ad_group_negative_remarketing_list_association.py
@@ -0,0 +1,136 @@
+from bingads.v11.bulk.entities import *
+from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V11
+from bingads.v11.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
+from bingads.v11.internal.bulk.mappings import _SimpleBulkMapping
+from bingads.v11.internal.bulk.string_table import _StringTable
+from bingads.v11.internal.extensions import *
+
+
+class BulkAdGroupNegativeRemarketingListAssociation(_SingleRecordBulkEntity):
+ """ Represents an Ad Group Negative Remarketing List Association that can be read or written in a bulk file.
+
+ This class exposes the :attr:`negative_ad_group_criterion` property that can be read and written as fields of the
+ Ad Group Negative Remarketing List Association record in a bulk file.
+
+ For more information, see Ad Group Negative Remarketing List Association at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ def __init__(self,
+ negative_ad_group_criterion=None,
+ campaign_name=None,
+ ad_group_name=None,
+ remarketing_list_name=None):
+ super(BulkAdGroupNegativeRemarketingListAssociation, self).__init__()
+
+ self._negative_ad_group_criterion = negative_ad_group_criterion
+ self._campaign_name = campaign_name
+ self._ad_group_name = ad_group_name
+ self._remarketing_list_name = remarketing_list_name
+
+ _MAPPINGS = [
+ _SimpleBulkMapping(
+ _StringTable.Status,
+ field_to_csv=lambda c: bulk_str(c.negative_ad_group_criterion.Status),
+ csv_to_field=lambda c, v: setattr(c.negative_ad_group_criterion, 'Status', v if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Id,
+ field_to_csv=lambda c: bulk_str(c.negative_ad_group_criterion.Id),
+ csv_to_field=lambda c, v: setattr(c.negative_ad_group_criterion, 'Id', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.ParentId,
+ field_to_csv=lambda c: bulk_str(c.negative_ad_group_criterion.AdGroupId),
+ csv_to_field=lambda c, v: setattr(c.negative_ad_group_criterion, 'AdGroupId', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Campaign,
+ field_to_csv=lambda c: c.campaign_name,
+ csv_to_field=lambda c, v: setattr(c, 'campaign_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.AdGroup,
+ field_to_csv=lambda c: c.ad_group_name,
+ csv_to_field=lambda c, v: setattr(c, 'ad_group_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Audience,
+ field_to_csv=lambda c: c.remarketing_list_name,
+ csv_to_field=lambda c, v: setattr(c, 'remarketing_list_name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.AudienceId,
+ field_to_csv=lambda c: field_to_csv_CriterionAudienceId(c.negative_ad_group_criterion),
+ csv_to_field=lambda c, v: csv_to_field_CriterionAudienceId(c.negative_ad_group_criterion, int(v) if v else None)
+ ),
+ ]
+
+ @property
+ def negative_ad_group_criterion(self):
+ """ Defines a Negative Ad Group Criterion """
+
+ return self._negative_ad_group_criterion
+
+ @negative_ad_group_criterion.setter
+ def negative_ad_group_criterion(self, negative_ad_group_criterion):
+ self._negative_ad_group_criterion = negative_ad_group_criterion
+
+ @property
+ def campaign_name(self):
+ """ Defines the name of the Campaign.
+
+ :rtype: str
+ """
+
+ return self._campaign_name
+
+ @campaign_name.setter
+ def campaign_name(self, campaign_name):
+ self._campaign_name = campaign_name
+
+ @property
+ def ad_group_name(self):
+ """ Defines the name of the Ad Group
+
+ :rtype: str
+ """
+
+ return self._ad_group_name
+
+ @ad_group_name.setter
+ def ad_group_name(self, ad_group_name):
+ self._ad_group_name = ad_group_name
+
+ @property
+ def remarketing_list_name(self):
+ """ Defines the name of the Remarketing List
+
+ :rtype: str
+ """
+
+ return self._remarketing_list_name
+
+ @remarketing_list_name.setter
+ def remarketing_list_name(self, remarketing_list_name):
+ self._remarketing_list_name = remarketing_list_name
+
+ def process_mappings_from_row_values(self, row_values):
+ self._negative_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('NegativeAdGroupCriterion')
+ self._negative_ad_group_criterion.Type = 'NegativeAdGroupCriterion'
+ self._negative_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('AudienceCriterion')
+ self._negative_ad_group_criterion.Criterion.Type = 'AudienceCriterion'
+ row_values.convert_to_entity(self, BulkAdGroupNegativeRemarketingListAssociation._MAPPINGS)
+
+ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
+ self._validate_property_not_null(self.negative_ad_group_criterion, 'negative_ad_group_criterion')
+ self.convert_to_values(row_values, BulkAdGroupNegativeRemarketingListAssociation._MAPPINGS)
+
+ def read_additional_data(self, stream_reader):
+ super(BulkAdGroupNegativeRemarketingListAssociation, self).read_additional_data(stream_reader)
diff --git a/bingads/v11/bulk/entities/audiences/bulk_ad_group_remarketing_list_association.py b/bingads/v11/bulk/entities/audiences/bulk_ad_group_remarketing_list_association.py
index 16a2e2b0..af126589 100644
--- a/bingads/v11/bulk/entities/audiences/bulk_ad_group_remarketing_list_association.py
+++ b/bingads/v11/bulk/entities/audiences/bulk_ad_group_remarketing_list_association.py
@@ -9,7 +9,7 @@
class BulkAdGroupRemarketingListAssociation(_SingleRecordBulkEntity):
""" Represents an Ad Group Remarketing List Association that can be read or written in a bulk file.
- This class exposes the :attr:`ad_group_remarketing_list_association` property that can be read and written as fields of the
+ This class exposes the :attr:`biddable_ad_group_criterion` property that can be read and written as fields of the
Ad Group Remarketing List Association record in a bulk file.
For more information, see Ad Group Remarketing List Association at https://go.microsoft.com/fwlink/?linkid=846127.
@@ -33,6 +33,7 @@ def __init__(self,
self._campaign_name = campaign_name
self._ad_group_name = ad_group_name
self._remarketing_list_name = remarketing_list_name
+ self._performance_data = None
_MAPPINGS = [
_SimpleBulkMapping(
@@ -79,7 +80,7 @@ def __init__(self,
@property
def biddable_ad_group_criterion(self):
- """ Defines an Biddable Ad Group Criterion """
+ """ Defines a Biddable Ad Group Criterion """
return self._biddable_ad_group_criterion
@@ -126,9 +127,9 @@ def remarketing_list_name(self):
def remarketing_list_name(self, remarketing_list_name):
self._remarketing_list_name = remarketing_list_name
- def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
- self._validate_property_not_null(self.biddable_ad_group_criterion, 'biddable_ad_group_criterion')
- self.convert_to_values(row_values, BulkAdGroupRemarketingListAssociation._MAPPINGS)
+ @property
+ def performance_data(self):
+ return self._performance_data
def process_mappings_from_row_values(self, row_values):
self._biddable_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('BiddableAdGroupCriterion')
@@ -139,5 +140,13 @@ def process_mappings_from_row_values(self, row_values):
self._biddable_ad_group_criterion.CriterionBid.Type = 'BidMultiplier'
row_values.convert_to_entity(self, BulkAdGroupRemarketingListAssociation._MAPPINGS)
+ self._performance_data = PerformanceData.read_from_row_values_or_null(row_values)
+
+ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
+ self._validate_property_not_null(self.biddable_ad_group_criterion, 'biddable_ad_group_criterion')
+ self.convert_to_values(row_values, BulkAdGroupRemarketingListAssociation._MAPPINGS)
+
+ PerformanceData.write_to_row_values_if_not_null(self._performance_data, row_values)
+
def read_additional_data(self, stream_reader):
super(BulkAdGroupRemarketingListAssociation, self).read_additional_data(stream_reader)
diff --git a/bingads/v11/bulk/entities/audiences/bulk_custom_audience.py b/bingads/v11/bulk/entities/audiences/bulk_custom_audience.py
new file mode 100644
index 00000000..570a0e50
--- /dev/null
+++ b/bingads/v11/bulk/entities/audiences/bulk_custom_audience.py
@@ -0,0 +1,103 @@
+from bingads.v11.bulk.entities import *
+from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V11
+from bingads.v11.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
+from bingads.v11.internal.bulk.mappings import _SimpleBulkMapping
+from bingads.v11.internal.bulk.string_table import _StringTable
+from bingads.v11.internal.extensions import *
+
+class BulkCustomAudience(_SingleRecordBulkEntity):
+ """ Represents a Custom Audience that can be read or written in a bulk file.
+
+ This class exposes the :attr:`custom_audience` property that can be read and written as fields of the
+ Custom Audience record in a bulk file.
+
+ For more information, see Custom Audience at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ def __init__(self,
+ custom_audience=None,
+ status=None,):
+ super(BulkCustomAudience, self).__init__()
+
+ self._custom_audience = custom_audience
+ self._status = status
+
+ _MAPPINGS = [
+ _SimpleBulkMapping(
+ header=_StringTable.Status,
+ field_to_csv=lambda c: c.status,
+ csv_to_field=lambda c, v: setattr(c, 'status', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Id,
+ field_to_csv=lambda c: bulk_str(c.custom_audience.Id),
+ csv_to_field=lambda c, v: setattr(c.custom_audience, 'Id', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.ParentId,
+ field_to_csv=lambda c: bulk_str(c.custom_audience.ParentId),
+ csv_to_field=lambda c, v: setattr(c.custom_audience, 'ParentId', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Audience,
+ field_to_csv=lambda c: bulk_str(c.custom_audience.Name),
+ csv_to_field=lambda c, v: setattr(c.custom_audience, 'Name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Description,
+ field_to_csv=lambda c: bulk_str(c.custom_audience.Description),
+ csv_to_field=lambda c, v: setattr(c.custom_audience, 'Description', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.MembershipDuration,
+ field_to_csv=lambda c: bulk_str(c.custom_audience.MembershipDuration),
+ csv_to_field=lambda c, v: setattr(c.custom_audience, 'MembershipDuration', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ header=_StringTable.Scope,
+ field_to_csv=lambda c: bulk_str(c.custom_audience.Scope),
+ csv_to_field=lambda c, v: setattr(c.custom_audience, 'Scope', v if v else None)
+ ),
+ ]
+
+ @property
+ def custom_audience(self):
+ """ Defines a Custom Audience """
+
+ return self._custom_audience
+
+ @custom_audience.setter
+ def custom_audience(self, custom_audience):
+ self._custom_audience = custom_audience
+
+ @property
+ def status(self):
+ """ The status of the Custom Audience
+
+ :rtype: str
+ """
+
+ return self._status
+
+ @status.setter
+ def status(self, status):
+ self._status = status
+
+
+ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
+ self._validate_property_not_null(self.custom_audience, 'custom_audience')
+ self.convert_to_values(row_values, BulkCustomAudience._MAPPINGS)
+
+ def process_mappings_from_row_values(self, row_values):
+ self._custom_audience = _CAMPAIGN_OBJECT_FACTORY_V11.create('CustomAudience')
+ row_values.convert_to_entity(self, BulkCustomAudience._MAPPINGS)
+
+ def read_additional_data(self, stream_reader):
+ super(BulkCustomAudience, self).read_additional_data(stream_reader)
diff --git a/bingads/v11/bulk/entities/audiences/bulk_in_market_audience.py b/bingads/v11/bulk/entities/audiences/bulk_in_market_audience.py
new file mode 100644
index 00000000..2b13b13e
--- /dev/null
+++ b/bingads/v11/bulk/entities/audiences/bulk_in_market_audience.py
@@ -0,0 +1,103 @@
+from bingads.v11.bulk.entities import *
+from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V11
+from bingads.v11.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
+from bingads.v11.internal.bulk.mappings import _SimpleBulkMapping
+from bingads.v11.internal.bulk.string_table import _StringTable
+from bingads.v11.internal.extensions import *
+
+class BulkInMarketAudience(_SingleRecordBulkEntity):
+ """ Represents an In Market Audience that can be read or written in a bulk file.
+
+ This class exposes the :attr:`in_market_audience` property that can be read and written as fields of the
+ In Market Audience record in a bulk file.
+
+ For more information, see In Market Audience at https://go.microsoft.com/fwlink/?linkid=846127.
+
+ *See also:*
+
+ * :class:`.BulkServiceManager`
+ * :class:`.BulkOperation`
+ * :class:`.BulkFileReader`
+ * :class:`.BulkFileWriter`
+ """
+
+ def __init__(self,
+ in_market_audience=None,
+ status=None,):
+ super(BulkInMarketAudience, self).__init__()
+
+ self._in_market_audience = in_market_audience
+ self._status = status
+
+ _MAPPINGS = [
+ _SimpleBulkMapping(
+ header=_StringTable.Status,
+ field_to_csv=lambda c: c.status,
+ csv_to_field=lambda c, v: setattr(c, 'status', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Id,
+ field_to_csv=lambda c: bulk_str(c.in_market_audience.Id),
+ csv_to_field=lambda c, v: setattr(c.in_market_audience, 'Id', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.ParentId,
+ field_to_csv=lambda c: bulk_str(c.in_market_audience.ParentId),
+ csv_to_field=lambda c, v: setattr(c.in_market_audience, 'ParentId', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Audience,
+ field_to_csv=lambda c: bulk_str(c.in_market_audience.Name),
+ csv_to_field=lambda c, v: setattr(c.in_market_audience, 'Name', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.Description,
+ field_to_csv=lambda c: bulk_str(c.in_market_audience.Description),
+ csv_to_field=lambda c, v: setattr(c.in_market_audience, 'Description', v)
+ ),
+ _SimpleBulkMapping(
+ _StringTable.MembershipDuration,
+ field_to_csv=lambda c: bulk_str(c.in_market_audience.MembershipDuration),
+ csv_to_field=lambda c, v: setattr(c.in_market_audience, 'MembershipDuration', int(v) if v else None)
+ ),
+ _SimpleBulkMapping(
+ header=_StringTable.Scope,
+ field_to_csv=lambda c: bulk_str(c.in_market_audience.Scope),
+ csv_to_field=lambda c, v: setattr(c.in_market_audience, 'Scope', v if v else None)
+ ),
+ ]
+
+ @property
+ def in_market_audience(self):
+ """ Defines an In Market Audience """
+
+ return self._in_market_audience
+
+ @in_market_audience.setter
+ def in_market_audience(self, in_market_audience):
+ self._in_market_audience = in_market_audience
+
+ @property
+ def status(self):
+ """ The status of the In Market Audience
+
+ :rtype: str
+ """
+
+ return self._status
+
+ @status.setter
+ def status(self, status):
+ self._status = status
+
+
+ def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
+ self._validate_property_not_null(self.in_market_audience, 'in_market_audience')
+ self.convert_to_values(row_values, BulkInMarketAudience._MAPPINGS)
+
+ def process_mappings_from_row_values(self, row_values):
+ self._in_market_audience = _CAMPAIGN_OBJECT_FACTORY_V11.create('InMarketAudience')
+ row_values.convert_to_entity(self, BulkInMarketAudience._MAPPINGS)
+
+ def read_additional_data(self, stream_reader):
+ super(BulkInMarketAudience, self).read_additional_data(stream_reader)
diff --git a/bingads/v11/bulk/entities/bulk_ad_group.py b/bingads/v11/bulk/entities/bulk_ad_group.py
index 25959600..3f98793b 100644
--- a/bingads/v11/bulk/entities/bulk_ad_group.py
+++ b/bingads/v11/bulk/entities/bulk_ad_group.py
@@ -184,8 +184,8 @@ def performance_data(self):
),
_SimpleBulkMapping(
header=_StringTable.Language,
- field_to_csv=lambda c: c.ad_group.Language,
- csv_to_field=lambda c, v: setattr(c.ad_group, 'Language', v)
+ field_to_csv=lambda c: bulk_str(c.ad_group.Language),
+ csv_to_field=lambda c, v: setattr(c.ad_group, 'Language', v if v else None)
),
_SimpleBulkMapping(
header=_StringTable.BidAdjustment,
diff --git a/bingads/v11/bulk/entities/bulk_ad_group_negative_dynamic_search_ad_target.py b/bingads/v11/bulk/entities/bulk_ad_group_negative_dynamic_search_ad_target.py
index 7c9b562d..57d1750f 100644
--- a/bingads/v11/bulk/entities/bulk_ad_group_negative_dynamic_search_ad_target.py
+++ b/bingads/v11/bulk/entities/bulk_ad_group_negative_dynamic_search_ad_target.py
@@ -8,7 +8,7 @@
class BulkAdGroupNegativeDynamicSearchAdTarget(_SingleRecordBulkEntity):
""" Represents a Ad Group Criterion that can be read or written in a bulk file.
- This class exposes the :attr:`ad_group_criterion` property that can be read and written as fields of the
+ This class exposes the :attr:`negative_ad_group_criterion` property that can be read and written as fields of the
Ad Group Negative Dynamic Search Ad Target record in a bulk file.
For more information, see Ad Group Negative Dynamic Search Ad Target at https://go.microsoft.com/fwlink/?linkid=836838.
@@ -25,13 +25,13 @@ def __init__(self,
campaign_name=None,
ad_group_name=None,
status=None,
- ad_group_criterion=None):
+ negative_ad_group_criterion=None):
super(BulkAdGroupNegativeDynamicSearchAdTarget, self).__init__()
self._campaign_name = campaign_name
self._ad_group_name = ad_group_name
self._status = status
- self._ad_group_criterion = ad_group_criterion
+ self._negative_ad_group_criterion = negative_ad_group_criterion
_MAPPINGS = [
@@ -42,13 +42,13 @@ def __init__(self,
),
_SimpleBulkMapping(
header=_StringTable.Id,
- field_to_csv=lambda c: bulk_str(c.ad_group_criterion.Id),
- csv_to_field=lambda c, v: setattr(c.ad_group_criterion, 'Id', int(v) if v else None)
+ field_to_csv=lambda c: bulk_str(c.negative_ad_group_criterion.Id),
+ csv_to_field=lambda c, v: setattr(c.negative_ad_group_criterion, 'Id', int(v) if v else None)
),
_SimpleBulkMapping(
header=_StringTable.ParentId,
- field_to_csv=lambda c: bulk_str(c.ad_group_criterion.AdGroupId),
- csv_to_field=lambda c, v: setattr(c.ad_group_criterion, 'AdGroupId', int(v) if v else None)
+ field_to_csv=lambda c: bulk_str(c.negative_ad_group_criterion.AdGroupId),
+ csv_to_field=lambda c, v: setattr(c.negative_ad_group_criterion, 'AdGroupId', int(v) if v else None)
),
_SimpleBulkMapping(
header=_StringTable.Campaign,
@@ -62,12 +62,12 @@ def __init__(self,
),
_SimpleBulkMapping(
header=_StringTable.Name,
- field_to_csv=lambda c: field_to_csv_WebpageParameter_CriterionName(c.ad_group_criterion),
- csv_to_field=lambda c, v: csv_to_field_WebpageParameter_CriterionName(c.ad_group_criterion, v)
+ field_to_csv=lambda c: field_to_csv_WebpageParameter_CriterionName(c.negative_ad_group_criterion),
+ csv_to_field=lambda c, v: csv_to_field_WebpageParameter_CriterionName(c.negative_ad_group_criterion, v)
),
_ComplexBulkMapping(
- entity_to_csv=lambda c, v: entity_to_csv_DSAWebpageParameter(c.ad_group_criterion, v),
- csv_to_entity=lambda v, c: csv_to_entity_DSAWebpageParameter(v, c.ad_group_criterion)
+ entity_to_csv=lambda c, v: entity_to_csv_DSAWebpageParameter(c.negative_ad_group_criterion, v),
+ csv_to_entity=lambda v, c: csv_to_entity_DSAWebpageParameter(v, c.negative_ad_group_criterion)
),
]
@@ -115,25 +115,25 @@ def status(self, status):
self._status = status
@property
- def ad_group_criterion(self):
+ def negative_ad_group_criterion(self):
""" Defines a Ad Group Criterion """
- return self._ad_group_criterion
+ return self._negative_ad_group_criterion
- @ad_group_criterion.setter
- def ad_group_criterion(self, ad_group_criterion):
- self._ad_group_criterion = ad_group_criterion
+ @negative_ad_group_criterion.setter
+ def negative_ad_group_criterion(self, negative_ad_group_criterion):
+ self._negative_ad_group_criterion = negative_ad_group_criterion
def process_mappings_from_row_values(self, row_values):
- self._ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('NegativeAdGroupCriterion')
- self._ad_group_criterion.Type = 'NegativeAdGroupCriterion'
- self._ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('ns0:Webpage')
- self._ad_group_criterion.Criterion.Type = 'Webpage'
+ self._negative_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('NegativeAdGroupCriterion')
+ self._negative_ad_group_criterion.Type = 'NegativeAdGroupCriterion'
+ self._negative_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('ns0:Webpage')
+ self._negative_ad_group_criterion.Criterion.Type = 'Webpage'
row_values.convert_to_entity(self, BulkAdGroupNegativeDynamicSearchAdTarget._MAPPINGS)
def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
- self._validate_property_not_null(self.ad_group_criterion, 'ad_group_criterion')
+ self._validate_property_not_null(self.negative_ad_group_criterion, 'negative_ad_group_criterion')
self.convert_to_values(row_values, BulkAdGroupNegativeDynamicSearchAdTarget._MAPPINGS)
def read_additional_data(self, stream_reader):
diff --git a/bingads/v11/bulk/entities/bulk_ads.py b/bingads/v11/bulk/entities/bulk_ads.py
index 703a761d..e2a7483c 100644
--- a/bingads/v11/bulk/entities/bulk_ads.py
+++ b/bingads/v11/bulk/entities/bulk_ads.py
@@ -140,6 +140,12 @@ def performance_data(self):
field_to_csv=lambda c: bulk_device_preference_str(c.ad.DevicePreference),
csv_to_field=lambda c, v: setattr(c.ad, 'DevicePreference', parse_device_preference(v))
),
+
+ _SimpleBulkMapping(
+ header=_StringTable.AdFormatPreference,
+ field_to_csv=lambda c: bulk_str(c.ad.AdFormatPreference),
+ csv_to_field=lambda c, v: setattr(c.ad, 'AdFormatPreference', v if v else None)
+ ),
_SimpleBulkMapping(
header=_StringTable.FinalUrl,
field_to_csv=lambda c: field_to_csv_Urls(c.ad.FinalUrls),
@@ -303,11 +309,6 @@ def text_ad(self, text_ad):
field_to_csv=lambda c: bulk_optional_str(c.text_ad.DestinationUrl),
csv_to_field=lambda c, v: setattr(c.text_ad, 'DestinationUrl', v if v else '')
),
- _SimpleBulkMapping(
- header=_StringTable.AdFormatPreference,
- field_to_csv=lambda c: field_to_csv_AdFormatPreference(c.text_ad),
- csv_to_field=lambda c, v: csv_to_field_AdFormatPreference(c.text_ad, v)
- ),
]
def process_mappings_from_row_values(self, row_values):
diff --git a/bingads/v11/bulk/entities/bulk_campaign.py b/bingads/v11/bulk/entities/bulk_campaign.py
index 51af03e2..6ffcac83 100644
--- a/bingads/v11/bulk/entities/bulk_campaign.py
+++ b/bingads/v11/bulk/entities/bulk_campaign.py
@@ -3,7 +3,6 @@
from bingads.v11.internal.bulk.string_table import _StringTable
from bingads.v11.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
from bingads.v11.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping
-# from bingads.v11.internal.extensions import bulk_str, csv_to_budget, budget_to_csv
from bingads.v11.internal.extensions import *
_ShoppingSetting = type(_CAMPAIGN_OBJECT_FACTORY_V11.create('ShoppingSetting'))
@@ -182,6 +181,26 @@ def _read_sales_country_code(c, v):
return None
shopping_setting.SalesCountryCode = v
+ @staticmethod
+ def _write_local_inventory_ads_enabled(c):
+ if not c.campaign.CampaignType:
+ return None
+ if 'shopping' in [campaign_type.lower() for campaign_type in c.campaign.CampaignType]:
+ shopping_setting = c._get_shopping_setting()
+ if not shopping_setting:
+ return None
+ return shopping_setting.LocalInventoryAdsEnabled
+
+ @staticmethod
+ def _read_local_inventory_ads_enabled(c, v):
+ if not c.campaign.CampaignType:
+ return None
+ if 'shopping' in [campaign_type.lower() for campaign_type in c.campaign.CampaignType]:
+ shopping_setting = c._get_shopping_setting()
+ if not shopping_setting:
+ return None
+ shopping_setting.LocalInventoryAdsEnabled = v.lower() == 'true' if v else None
+
_MAPPINGS = [
_SimpleBulkMapping(
header=_StringTable.CampaignType,
@@ -209,7 +228,7 @@ def _read_sales_country_code(c, v):
_SimpleBulkMapping(
header=_StringTable.ParentId,
field_to_csv=lambda c: bulk_str(c.account_id),
- csv_to_field=lambda c, v: setattr(c, '_account_id', int(v))
+ csv_to_field=lambda c, v: setattr(c, '_account_id', int(v) if v else None)
),
_SimpleBulkMapping(
header=_StringTable.Campaign,
@@ -221,6 +240,11 @@ def _read_sales_country_code(c, v):
field_to_csv=lambda c: c.campaign.TimeZone,
csv_to_field=lambda c, v: setattr(c.campaign, 'TimeZone', v)
),
+ _SimpleBulkMapping(
+ header=_StringTable.Language,
+ field_to_csv=lambda c: field_to_csv_CampaignLanguages(c.campaign.Languages),
+ csv_to_field=lambda c, v: csv_to_field_CampaignLanguages(c.campaign.Languages, v)
+ ),
_ComplexBulkMapping(budget_to_csv, csv_to_budget),
_SimpleBulkMapping(
header=_StringTable.BidAdjustment,
@@ -247,7 +271,11 @@ def _read_sales_country_code(c, v):
csv_to_field=lambda c, v: BulkCampaign._read_sales_country_code(c, v)
),
_SimpleBulkMapping(
- # TODO now use bulk_str not bulk_optional_str
+ header=_StringTable.LocalInventoryAdsEnabled,
+ field_to_csv=lambda c: BulkCampaign._write_local_inventory_ads_enabled(c),
+ csv_to_field=lambda c, v: BulkCampaign._read_local_inventory_ads_enabled(c, v)
+ ),
+ _SimpleBulkMapping(
header=_StringTable.TrackingTemplate,
field_to_csv=lambda c: bulk_str(c.campaign.TrackingUrlTemplate),
csv_to_field=lambda c, v: setattr(c.campaign, 'TrackingUrlTemplate', v if v else None)
@@ -257,11 +285,7 @@ def _read_sales_country_code(c, v):
field_to_csv=lambda c: field_to_csv_UrlCustomParameters(c.campaign),
csv_to_field=lambda c, v: csv_to_field_UrlCustomParameters(c.campaign, v)
),
- _SimpleBulkMapping(
- header=_StringTable.BidStrategyType,
- field_to_csv=lambda c: field_to_csv_BidStrategyType(c.campaign),
- csv_to_field=lambda c, v: csv_to_field_BidStrategyType(c.campaign, v)
- ),
+ _ComplexBulkMapping(biddingscheme_to_csv, csv_to_biddingscheme),
_SimpleBulkMapping(
header=_StringTable.BudgetId,
field_to_csv=lambda c: bulk_str(c.campaign.BudgetId),
diff --git a/bingads/v11/bulk/entities/bulk_campaign_negative_dynamic_search_ad_target.py b/bingads/v11/bulk/entities/bulk_campaign_negative_dynamic_search_ad_target.py
index 78bb0d50..11f3053a 100644
--- a/bingads/v11/bulk/entities/bulk_campaign_negative_dynamic_search_ad_target.py
+++ b/bingads/v11/bulk/entities/bulk_campaign_negative_dynamic_search_ad_target.py
@@ -8,7 +8,7 @@
class BulkCampaignNegativeDynamicSearchAdTarget(_SingleRecordBulkEntity):
""" Represents a Campaign Criterion that can be read or written in a bulk file.
- This class exposes the :attr:`campaign_criterion` property that can be read and written as fields of the
+ This class exposes the :attr:`negative_campaign_criterion` property that can be read and written as fields of the
Campaign Negative Dynamic Search Ad Target record in a bulk file.
For more information, see Campaign Negative Dynamic Search Ad Target at https://go.microsoft.com/fwlink/?linkid=836839.
@@ -24,12 +24,12 @@ class BulkCampaignNegativeDynamicSearchAdTarget(_SingleRecordBulkEntity):
def __init__(self,
campaign_name=None,
status=None,
- campaign_criterion=None):
+ negative_campaign_criterion=None):
super(BulkCampaignNegativeDynamicSearchAdTarget, self).__init__()
self._campaign_name = campaign_name
self._status = status
- self._campaign_criterion = campaign_criterion
+ self._negative_campaign_criterion = negative_campaign_criterion
_MAPPINGS = [
@@ -40,13 +40,13 @@ def __init__(self,
),
_SimpleBulkMapping(
header=_StringTable.Id,
- field_to_csv=lambda c: bulk_str(c.campaign_criterion.Id),
- csv_to_field=lambda c, v: setattr(c.campaign_criterion, 'Id', int(v) if v else None)
+ field_to_csv=lambda c: bulk_str(c.negative_campaign_criterion.Id),
+ csv_to_field=lambda c, v: setattr(c.negative_campaign_criterion, 'Id', int(v) if v else None)
),
_SimpleBulkMapping(
header=_StringTable.ParentId,
- field_to_csv=lambda c: bulk_str(c.campaign_criterion.CampaignId),
- csv_to_field=lambda c, v: setattr(c.campaign_criterion, 'CampaignId', int(v) if v else None)
+ field_to_csv=lambda c: bulk_str(c.negative_campaign_criterion.CampaignId),
+ csv_to_field=lambda c, v: setattr(c.negative_campaign_criterion, 'CampaignId', int(v) if v else None)
),
_SimpleBulkMapping(
header=_StringTable.Campaign,
@@ -55,12 +55,12 @@ def __init__(self,
),
_SimpleBulkMapping(
header=_StringTable.Name,
- field_to_csv=lambda c: field_to_csv_WebpageParameter_CriterionName(c.campaign_criterion),
- csv_to_field=lambda c, v: csv_to_field_WebpageParameter_CriterionName(c.campaign_criterion, v)
+ field_to_csv=lambda c: field_to_csv_WebpageParameter_CriterionName(c.negative_campaign_criterion),
+ csv_to_field=lambda c, v: csv_to_field_WebpageParameter_CriterionName(c.negative_campaign_criterion, v)
),
_ComplexBulkMapping(
- entity_to_csv=lambda c, v: entity_to_csv_DSAWebpageParameter(c.campaign_criterion, v),
- csv_to_entity=lambda v, c: csv_to_entity_DSAWebpageParameter(v, c.campaign_criterion)
+ entity_to_csv=lambda c, v: entity_to_csv_DSAWebpageParameter(c.negative_campaign_criterion, v),
+ csv_to_entity=lambda v, c: csv_to_entity_DSAWebpageParameter(v, c.negative_campaign_criterion)
)
]
@@ -91,25 +91,25 @@ def status(self, status):
self._status = status
@property
- def campaign_criterion(self):
+ def negative_campaign_criterion(self):
""" Defines a Campaign Criterion """
- return self._campaign_criterion
+ return self._negative_campaign_criterion
- @campaign_criterion.setter
- def campaign_criterion(self, campaign_criterion):
- self._campaign_criterion = campaign_criterion
+ @negative_campaign_criterion.setter
+ def negative_campaign_criterion(self, negative_campaign_criterion):
+ self._negative_campaign_criterion = negative_campaign_criterion
def process_mappings_from_row_values(self, row_values):
- self._campaign_criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('NegativeCampaignCriterion')
- self._campaign_criterion.Type = 'NegativeCampaignCriterion'
- self._campaign_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('ns0:Webpage')
- self._campaign_criterion.Criterion.Type = 'Webpage'
+ self._negative_campaign_criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('NegativeCampaignCriterion')
+ self._negative_campaign_criterion.Type = 'NegativeCampaignCriterion'
+ self._negative_campaign_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V11.create('ns0:Webpage')
+ self._negative_campaign_criterion.Criterion.Type = 'Webpage'
row_values.convert_to_entity(self, BulkCampaignNegativeDynamicSearchAdTarget._MAPPINGS)
def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
- self._validate_property_not_null(self.campaign_criterion, 'campaign_criterion')
+ self._validate_property_not_null(self.negative_campaign_criterion, 'negative_campaign_criterion')
self.convert_to_values(row_values, BulkCampaignNegativeDynamicSearchAdTarget._MAPPINGS)
def read_additional_data(self, stream_reader):
diff --git a/bingads/v11/bulk/entities/bulk_campaign_product_scope.py b/bingads/v11/bulk/entities/bulk_campaign_product_scope.py
index f8923740..eb2e602a 100644
--- a/bingads/v11/bulk/entities/bulk_campaign_product_scope.py
+++ b/bingads/v11/bulk/entities/bulk_campaign_product_scope.py
@@ -42,9 +42,9 @@ def _add_product_condition_to_row_values(cls, entity, value):
_MAPPINGS = [
_SimpleBulkMapping(
- header=_StringTable.Status,
- field_to_csv=lambda c: c.status,
- csv_to_field=lambda c, v: setattr(c, 'status', v)
+ _StringTable.Status,
+ field_to_csv=lambda c: c.biddable_campaign_criterion.Status,
+ csv_to_field=lambda c, v: setattr(c.biddable_campaign_criterion, 'Status', v)
),
_SimpleBulkMapping(
header=_StringTable.Id,
@@ -62,10 +62,6 @@ def _add_product_condition_to_row_values(cls, entity, value):
csv_to_field=lambda c, v: setattr(c, 'campaign_name', v)
),
_ComplexBulkMapping(
- #entity_to_csv=lambda c, v: _ProductConditionHelper.add_row_values_from_conditions(
- # c.campaign_criterion.Criterion.Conditions.ProductCondition,
- # v
- #),
entity_to_csv=lambda c, v: BulkCampaignProductScope._add_product_condition_to_row_values(c, v),
csv_to_entity=lambda v, c: _ProductConditionHelper.add_conditions_from_row_values(
v,
diff --git a/bingads/v11/internal/bulk/bulk_object_factory.py b/bingads/v11/internal/bulk/bulk_object_factory.py
index 81c090f2..5157a882 100644
--- a/bingads/v11/internal/bulk/bulk_object_factory.py
+++ b/bingads/v11/internal/bulk/bulk_object_factory.py
@@ -28,25 +28,36 @@ class _BulkObjectFactory():
_StringTable.CallAdExtension: _EntityInfo(lambda: BulkCallAdExtension()),
_StringTable.CampaignCallAdExtension: _EntityInfo(lambda: BulkCampaignCallAdExtension()),
_StringTable.ImageAdExtension: _EntityInfo(lambda: BulkImageAdExtension()),
+ _StringTable.AccountImageAdExtension: _EntityInfo(lambda: BulkAccountImageAdExtension()),
_StringTable.CampaignImageAdExtension: _EntityInfo(lambda: BulkCampaignImageAdExtension()),
_StringTable.AdGroupImageAdExtension: _EntityInfo(lambda: BulkAdGroupImageAdExtension()),
_StringTable.CalloutAdExtension: _EntityInfo(lambda: BulkCalloutAdExtension()),
+ _StringTable.AccountCalloutAdExtension: _EntityInfo(lambda: BulkAccountCalloutAdExtension()),
_StringTable.CampaignCalloutAdExtension: _EntityInfo(lambda: BulkCampaignCalloutAdExtension()),
_StringTable.AdGroupCalloutAdExtension: _EntityInfo(lambda: BulkAdGroupCalloutAdExtension()),
_StringTable.ReviewAdExtension: _EntityInfo(lambda: BulkReviewAdExtension()),
+ _StringTable.AccountReviewAdExtension: _EntityInfo(lambda: BulkAccountReviewAdExtension()),
_StringTable.CampaignReviewAdExtension: _EntityInfo(lambda: BulkCampaignReviewAdExtension()),
_StringTable.AdGroupReviewAdExtension: _EntityInfo(lambda: BulkAdGroupReviewAdExtension()),
_StringTable.LocationAdExtension: _EntityInfo(lambda: BulkLocationAdExtension()),
+ _StringTable.AccountLocationAdExtension: _EntityInfo(lambda: BulkAccountLocationAdExtension()),
_StringTable.CampaignLocationAdExtension: _EntityInfo(lambda: BulkCampaignLocationAdExtension()),
_StringTable.AppAdExtension: _EntityInfo(lambda: BulkAppAdExtension()),
+ _StringTable.AccountAppAdExtension: _EntityInfo(lambda: BulkAccountAppAdExtension()),
_StringTable.CampaignAppAdExtension: _EntityInfo(lambda: BulkCampaignAppAdExtension()),
_StringTable.AdGroupAppAdExtension: _EntityInfo(lambda: BulkAdGroupAppAdExtension()),
_StringTable.StructuredSnippetAdExtension: _EntityInfo(lambda: BulkStructuredSnippetAdExtension()),
+ _StringTable.AccountStructuredSnippetAdExtension: _EntityInfo(lambda: BulkAccountStructuredSnippetAdExtension()),
_StringTable.CampaignStructuredSnippetAdExtension: _EntityInfo(lambda: BulkCampaignStructuredSnippetAdExtension()),
_StringTable.AdGroupStructuredSnippetAdExtension: _EntityInfo(lambda: BulkAdGroupStructuredSnippetAdExtension()),
_StringTable.Sitelink2AdExtension: _EntityInfo(lambda: BulkSitelink2AdExtension()),
+ _StringTable.AccountSitelink2AdExtension: _EntityInfo(lambda: BulkAccountSitelink2AdExtension()),
_StringTable.CampaignSitelink2AdExtension: _EntityInfo(lambda: BulkCampaignSitelink2AdExtension()),
_StringTable.AdGroupSitelink2AdExtension: _EntityInfo(lambda: BulkAdGroupSitelink2AdExtension()),
+ _StringTable.PriceAdExtension: _EntityInfo(lambda: BulkPriceAdExtension()),
+ _StringTable.AccountPriceAdExtension: _EntityInfo(lambda: BulkAccountPriceAdExtension()),
+ _StringTable.CampaignPriceAdExtension: _EntityInfo(lambda: BulkCampaignPriceAdExtension()),
+ _StringTable.AdGroupPriceAdExtension: _EntityInfo(lambda: BulkAdGroupPriceAdExtension()),
_StringTable.ProductAd: _EntityInfo(lambda: BulkProductAd()),
_StringTable.TextAd: _EntityInfo(lambda: BulkTextAd()),
_StringTable.AppInstallAd: _EntityInfo(lambda: BulkAppInstallAd()),
@@ -72,6 +83,13 @@ class _BulkObjectFactory():
'Ad Group Product Partition': _EntityInfo(lambda : BulkAdGroupProductPartition()),
'Remarketing List': _EntityInfo(lambda : BulkRemarketingList()),
'Ad Group Remarketing List Association': _EntityInfo(lambda : BulkAdGroupRemarketingListAssociation()),
+ 'Ad Group Negative Remarketing List Association': _EntityInfo(lambda : BulkAdGroupNegativeRemarketingListAssociation()),
+ 'Custom Audience': _EntityInfo(lambda : BulkCustomAudience()),
+ 'Ad Group Custom Audience Association': _EntityInfo(lambda : BulkAdGroupCustomAudienceAssociation()),
+ 'Ad Group Negative Custom Audience Association': _EntityInfo(lambda : BulkAdGroupNegativeCustomAudienceAssociation()),
+ 'In Market Audience': _EntityInfo(lambda : BulkInMarketAudience()),
+ 'Ad Group In Market Audience Association': _EntityInfo(lambda : BulkAdGroupInMarketAudienceAssociation()),
+ 'Ad Group Negative In Market Audience Association': _EntityInfo(lambda : BulkAdGroupNegativeInMarketAudienceAssociation()),
'Campaign Negative Dynamic Search Ad Target': _EntityInfo(lambda: BulkCampaignNegativeDynamicSearchAdTarget()),
'Ad Group Dynamic Search Ad Target': _EntityInfo(lambda: BulkAdGroupDynamicSearchAdTarget()),
'Ad Group Negative Dynamic Search Ad Target': _EntityInfo(lambda: BulkAdGroupNegativeDynamicSearchAdTarget()),
diff --git a/bingads/v11/internal/bulk/csv_headers.py b/bingads/v11/internal/bulk/csv_headers.py
index fcb8226d..4a8364f8 100644
--- a/bingads/v11/internal/bulk/csv_headers.py
+++ b/bingads/v11/internal/bulk/csv_headers.py
@@ -166,6 +166,7 @@ class _CsvHeaders:
_StringTable.ParentAdGroupCriterionId,
_StringTable.CampaignType,
_StringTable.CampaignPriority,
+ _StringTable.LocalInventoryAdsEnabled,
# V10 added
_StringTable.FieldPath,
@@ -181,8 +182,77 @@ class _CsvHeaders:
_StringTable.Source,
_StringTable.Url,
+ # Price Ad Extension
+ _StringTable.PriceExtensionType,
+ _StringTable.Header1,
+ _StringTable.Header2,
+ _StringTable.Header3,
+ _StringTable.Header4,
+ _StringTable.Header5,
+ _StringTable.Header6,
+ _StringTable.Header7,
+ _StringTable.Header8,
+ _StringTable.PriceDescription1,
+ _StringTable.PriceDescription2,
+ _StringTable.PriceDescription3,
+ _StringTable.PriceDescription4,
+ _StringTable.PriceDescription5,
+ _StringTable.PriceDescription6,
+ _StringTable.PriceDescription7,
+ _StringTable.PriceDescription8,
+ _StringTable.FinalUrl1,
+ _StringTable.FinalUrl2,
+ _StringTable.FinalUrl3,
+ _StringTable.FinalUrl4,
+ _StringTable.FinalUrl5,
+ _StringTable.FinalUrl6,
+ _StringTable.FinalUrl7,
+ _StringTable.FinalUrl8,
+ _StringTable.FinalMobileUrl1,
+ _StringTable.FinalMobileUrl2,
+ _StringTable.FinalMobileUrl3,
+ _StringTable.FinalMobileUrl4,
+ _StringTable.FinalMobileUrl5,
+ _StringTable.FinalMobileUrl6,
+ _StringTable.FinalMobileUrl7,
+ _StringTable.FinalMobileUrl8,
+ _StringTable.Price1,
+ _StringTable.Price2,
+ _StringTable.Price3,
+ _StringTable.Price4,
+ _StringTable.Price5,
+ _StringTable.Price6,
+ _StringTable.Price7,
+ _StringTable.Price8,
+ _StringTable.CurrencyCode1,
+ _StringTable.CurrencyCode2,
+ _StringTable.CurrencyCode3,
+ _StringTable.CurrencyCode4,
+ _StringTable.CurrencyCode5,
+ _StringTable.CurrencyCode6,
+ _StringTable.CurrencyCode7,
+ _StringTable.CurrencyCode8,
+ _StringTable.PriceUnit1,
+ _StringTable.PriceUnit2,
+ _StringTable.PriceUnit3,
+ _StringTable.PriceUnit4,
+ _StringTable.PriceUnit5,
+ _StringTable.PriceUnit6,
+ _StringTable.PriceUnit7,
+ _StringTable.PriceUnit8,
+ _StringTable.PriceQualifier1,
+ _StringTable.PriceQualifier2,
+ _StringTable.PriceQualifier3,
+ _StringTable.PriceQualifier4,
+ _StringTable.PriceQualifier5,
+ _StringTable.PriceQualifier6,
+ _StringTable.PriceQualifier7,
+ _StringTable.PriceQualifier8,
+
# Bid Strategy
_StringTable.BidStrategyType,
+ _StringTable.BidStrategyMaxCpc,
+ _StringTable.BidStrategyTargetCpa,
# Ad Format Preference
_StringTable.AdFormatPreference,
@@ -215,6 +285,7 @@ class _CsvHeaders:
_StringTable.DynamicAdTargetValue2,
_StringTable.DynamicAdTargetCondition3,
_StringTable.DynamicAdTargetValue3,
+
]
@staticmethod
diff --git a/bingads/v11/internal/bulk/string_table.py b/bingads/v11/internal/bulk/string_table.py
index eef20e1c..0274ca29 100644
--- a/bingads/v11/internal/bulk/string_table.py
+++ b/bingads/v11/internal/bulk/string_table.py
@@ -66,6 +66,7 @@ class _StringTable:
SyncTime = "Sync Time"
Name = "Name"
LastModifiedTime = "Modified Time"
+ AdFormatPreference = "Ad Format Preference"
# Entity Types
SemanticVersion = "Format Version"
@@ -90,6 +91,7 @@ class _StringTable:
# Image Ad Extension
AltText = "Alternative Text"
MediaIds = "Media Ids"
+ AccountImageAdExtension = "Account Image Ad Extension"
CampaignImageAdExtension = "Campaign Image Ad Extension"
AdGroupImageAdExtension = "Ad Group Image Ad Extension"
@@ -112,6 +114,7 @@ class _StringTable:
GeoCodeStatus = "Geo Code Status"
IconMediaId = "Map Icon"
ImageMediaId = "Business Icon"
+ AccountLocationAdExtension = "Account Location Ad Extension"
CampaignLocationAdExtension = "Campaign Location Ad Extension"
# Call Ad Extensions
@@ -123,6 +126,7 @@ class _StringTable:
# Structured Snippet Ad Extension
StructuredSnippetAdExtension = "Structured Snippet Ad Extension"
+ AccountStructuredSnippetAdExtension = "Account Structured Snippet Ad Extension"
CampaignStructuredSnippetAdExtension = "Campaign Structured Snippet Ad Extension"
AdGroupStructuredSnippetAdExtension = "Ad Group Structured Snippet Ad Extension"
StructuredSnippetHeader = "Structured Snippet Header"
@@ -132,6 +136,7 @@ class _StringTable:
Sitelink2AdExtension = "Sitelink2 Ad Extension"
AdGroupSitelink2AdExtension = "Ad Group Sitelink2 Ad Extension"
CampaignSitelink2AdExtension = "Campaign Sitelink2 Ad Extension"
+ AccountSitelink2AdExtension = "Account Sitelink2 Ad Extension"
# Editorial Rejection Reasons
PublisherCountries = "Publisher Countries"
@@ -165,6 +170,7 @@ class _StringTable:
AppAdExtension = "App Ad Extension"
AppPlatform = "App Platform"
AppStoreId = "App Id"
+ AccountAppAdExtension = "Account App Ad Extension"
CampaignAppAdExtension = "Campaign App Ad Extension"
AdGroupAppAdExtension = "Ad Group App Ad Extension"
IsTrackingEnabled = "Tracking Enabled"
@@ -192,8 +198,7 @@ class _StringTable:
LandingPageRelevance = "Landing Page Relevance"
LandingPageUserExperience = "Landing Page User Experience"
- # DayTime Target
- DayTimeTarget = "DayTime Target"
+ # DayTime Criterion
FromHour = "From Hour"
ToHour = "To Hour"
FromMinute = "From Minute"
@@ -216,6 +221,7 @@ class _StringTable:
ParentAdGroupCriterionId = "Parent Criterion Id"
CampaignType = "Campaign Type"
CampaignPriority = "Priority"
+ LocalInventoryAdsEnabled = "LocalInventoryAdsEnabled"
# V10 added
FieldPath = "Field Path"
@@ -228,21 +234,95 @@ class _StringTable:
# Review Ad Extension
ReviewAdExtension = "Review Ad Extension"
+ AccountReviewAdExtension = "Account Review Ad Extension"
CampaignReviewAdExtension = "Campaign Review Ad Extension"
AdGroupReviewAdExtension = "Ad Group Review Ad Extension"
IsExact = "Is Exact"
Source = "Source"
Url = "Url"
+ # Price Ad Extension
+ PriceAdExtension = "Price Ad Extension"
+ AccountPriceAdExtension = "Account Price Ad Extension"
+ CampaignPriceAdExtension = "Campaign Price Ad Extension"
+ AdGroupPriceAdExtension = "Ad Group Price Ad Extension"
+ PriceExtensionType = "Price Extension Type"
+ Header1 = "Header 1"
+ Header2 = "Header 2"
+ Header3 = "Header 3"
+ Header4 = "Header 4"
+ Header5 = "Header 5"
+ Header6 = "Header 6"
+ Header7 = "Header 7"
+ Header8 = "Header 8"
+ PriceDescription1 = "Price Description 1"
+ PriceDescription2 = "Price Description 2"
+ PriceDescription3 = "Price Description 3"
+ PriceDescription4 = "Price Description 4"
+ PriceDescription5 = "Price Description 5"
+ PriceDescription6 = "Price Description 6"
+ PriceDescription7 = "Price Description 7"
+ PriceDescription8 = "Price Description 8"
+ FinalUrl1 = "Final Url 1"
+ FinalUrl2 = "Final Url 2"
+ FinalUrl3 = "Final Url 3"
+ FinalUrl4 = "Final Url 4"
+ FinalUrl5 = "Final Url 5"
+ FinalUrl6 = "Final Url 6"
+ FinalUrl7 = "Final Url 7"
+ FinalUrl8 = "Final Url 8"
+ FinalMobileUrl1 = "Final Mobile Url 1"
+ FinalMobileUrl2 = "Final Mobile Url 2"
+ FinalMobileUrl3 = "Final Mobile Url 3"
+ FinalMobileUrl4 = "Final Mobile Url 4"
+ FinalMobileUrl5 = "Final Mobile Url 5"
+ FinalMobileUrl6 = "Final Mobile Url 6"
+ FinalMobileUrl7 = "Final Mobile Url 7"
+ FinalMobileUrl8 = "Final Mobile Url 8"
+ Price1 = "Price 1"
+ Price2 = "Price 2"
+ Price3 = "Price 3"
+ Price4 = "Price 4"
+ Price5 = "Price 5"
+ Price6 = "Price 6"
+ Price7 = "Price 7"
+ Price8 = "Price 8"
+ CurrencyCode1 = "Currency Code 1"
+ CurrencyCode2 = "Currency Code 2"
+ CurrencyCode3 = "Currency Code 3"
+ CurrencyCode4 = "Currency Code 4"
+ CurrencyCode5 = "Currency Code 5"
+ CurrencyCode6 = "Currency Code 6"
+ CurrencyCode7 = "Currency Code 7"
+ CurrencyCode8 = "Currency Code 8"
+ PriceUnit1 = "Price Unit 1"
+ PriceUnit2 = "Price Unit 2"
+ PriceUnit3 = "Price Unit 3"
+ PriceUnit4 = "Price Unit 4"
+ PriceUnit5 = "Price Unit 5"
+ PriceUnit6 = "Price Unit 6"
+ PriceUnit7 = "Price Unit 7"
+ PriceUnit8 = "Price Unit 8"
+ PriceQualifier1 = "Price Qualifier 1"
+ PriceQualifier2 = "Price Qualifier 2"
+ PriceQualifier3 = "Price Qualifier 3"
+ PriceQualifier4 = "Price Qualifier 4"
+ PriceQualifier5 = "Price Qualifier 5"
+ PriceQualifier6 = "Price Qualifier 6"
+ PriceQualifier7 = "Price Qualifier 7"
+ PriceQualifier8 = "Price Qualifier 8"
+
# Callout Ad Extension
CalloutAdExtension = "Callout Ad Extension"
+ AccountCalloutAdExtension = "Account Callout Ad Extension"
CampaignCalloutAdExtension = "Campaign Callout Ad Extension"
AdGroupCalloutAdExtension = "Ad Group Callout Ad Extension"
CalloutText = "Callout Text"
# Bid Strategy
BidStrategyType = "Bid Strategy Type"
- AdFormatPreference = "Ad Format Preference"
+ BidStrategyMaxCpc = "Bid Strategy MaxCpc"
+ BidStrategyTargetCpa = "Bid Strategy TargetCpa"
# Remarketing
RemarketingList = "Remarketing List"
diff --git a/bingads/v11/internal/extensions.py b/bingads/v11/internal/extensions.py
index f2a71805..883a7c3b 100644
--- a/bingads/v11/internal/extensions.py
+++ b/bingads/v11/internal/extensions.py
@@ -102,6 +102,48 @@ def budget_to_csv(bulk_campaign, row_values):
row_values[_StringTable.Budget] = bulk_str(bulk_campaign.campaign.DailyBudget)
+def csv_to_biddingscheme(row_values, bulk_campaign):
+ success, bid_strategy_type = row_values.try_get_value(_StringTable.BidStrategyType)
+ if not success or not bid_strategy_type:
+ return
+
+ csv_to_field_BidStrategyType(bulk_campaign.campaign, bid_strategy_type)
+
+ success, max_cpc_row_value = row_values.try_get_value(_StringTable.BidStrategyMaxCpc)
+ max_cpc_value = parse_bid(max_cpc_row_value) if max_cpc_row_value else None
+
+ success, target_cpa_row_value = row_values.try_get_value(_StringTable.BidStrategyTargetCpa)
+ target_cpa_value = float(target_cpa_row_value) if target_cpa_row_value else None
+
+ if bid_strategy_type == 'MaxConversions':
+ bulk_campaign.campaign.BiddingScheme.MaxCpc = max_cpc_value
+ bulk_campaign.campaign.BiddingScheme.Type = "MaxConversions"
+ elif bid_strategy_type == 'MaxClicks':
+ bulk_campaign.campaign.BiddingScheme.MaxCpc = max_cpc_value
+ bulk_campaign.campaign.BiddingScheme.Type = "MaxClicks"
+ elif bid_strategy_type == 'TargetCpa':
+ bulk_campaign.campaign.BiddingScheme.MaxCpc = max_cpc_value
+ bulk_campaign.campaign.BiddingScheme.Type = "TargetCpa"
+ bulk_campaign.campaign.BiddingScheme.TargetCpa = target_cpa_value
+
+
+def biddingscheme_to_csv(bulk_campaign, row_values):
+ bid_strategy_type = field_to_csv_BidStrategyType(bulk_campaign.campaign)
+
+ if not bid_strategy_type:
+ return
+
+ row_values[_StringTable.BidStrategyType] = bid_strategy_type
+
+ if bid_strategy_type == 'MaxConversions':
+ row_values[_StringTable.BidStrategyMaxCpc] = bid_bulk_str(bulk_campaign.campaign.BiddingScheme.MaxCpc)
+ elif bid_strategy_type == 'MaxClicks':
+ row_values[_StringTable.BidStrategyMaxCpc] = bid_bulk_str(bulk_campaign.campaign.BiddingScheme.MaxCpc)
+ elif bid_strategy_type == 'TargetCpa':
+ row_values[_StringTable.BidStrategyMaxCpc] = bid_bulk_str(bulk_campaign.campaign.BiddingScheme.MaxCpc)
+ row_values[_StringTable.BidStrategyTargetCpa] = bulk_str(bulk_campaign.campaign.BiddingScheme.TargetCpa)
+
+
def bulk_optional_str(value):
if value is None:
return None
@@ -266,6 +308,32 @@ def field_to_csv_Urls(entity):
return None
return '; '.join(entity.string)
+def csv_to_field_CampaignLanguages(entity, value):
+ """
+ set Languages string field
+ :param entity: Languages
+ :param value: the content in csv
+ :return:set field values
+ """
+ if value is None or value == '':
+ return
+ splitter = re.compile(';')
+ entity.string = splitter.split(value)
+
+
+def field_to_csv_CampaignLanguages(entity):
+ """
+ parse entity to csv content
+ :param entity: Languages
+ :return: csv content
+ """
+ if entity is None:
+ return None
+ if entity.string is None:
+ return DELETE_VALUE
+ if len(entity.string) == 0:
+ return None
+ return ';'.join(entity.string)
def field_to_csv_BidStrategyType(entity):
"""
@@ -317,45 +385,6 @@ def csv_to_field_BidStrategyType(entity, value):
entity.BiddingScheme.Type = value
-def field_to_csv_AdFormatPreference(entity):
- """
- convert entity field to csv content
- :param entity: entity which has ForwardCompatibilityMap attribute
- :return:
- """
- if entity.ForwardCompatibilityMap is None or entity.ForwardCompatibilityMap.KeyValuePairOfstringstring is None \
- or len(entity.ForwardCompatibilityMap.KeyValuePairOfstringstring) == 0:
- return None
- for key_value_pair in entity.ForwardCompatibilityMap.KeyValuePairOfstringstring:
- if key_value_pair.key == 'NativePreference':
- if key_value_pair.value.lower() == 'true':
- return 'Native'
- elif key_value_pair.value.lower() == 'false':
- return 'All'
- else:
- raise ValueError('Unknown value for Native Preference: {0}'.format(key_value_pair.value))
- return None
-
-
-def csv_to_field_AdFormatPreference(entity, value):
- """
- parse csv content and set entity attribute
- :param entity: entity which has ForwardCompatibilityMap attribute
- :param value: csv content value
- :return:
- """
- ad_format_preference = _CAMPAIGN_OBJECT_FACTORY_V11.create('ns2:KeyValuePairOfstringstring')
- ad_format_preference.key = 'NativePreference'
- if value is None or value == '' or value == 'All':
- ad_format_preference.value = 'False'
- elif value == 'Native':
- ad_format_preference.value = 'True'
- else:
- raise ValueError('Unknown value for Native Preference: {0}'.format(value))
- entity.ForwardCompatibilityMap = _CAMPAIGN_OBJECT_FACTORY_V11.create('ns2:ArrayOfKeyValuePairOfstringstring')
- entity.ForwardCompatibilityMap.KeyValuePairOfstringstring.append(ad_format_preference)
-
-
def csv_to_field_StructuredSnippetValues(entity, value):
if value is not None and value != '':
entity.Values.string = value.split(';')
@@ -414,6 +443,22 @@ def parse_keyword_bid(value):
return bid
+def bid_bulk_str(value):
+ if value is None:
+ return DELETE_VALUE
+ if value.Amount is None:
+ return None
+ return bulk_str(value.Amount)
+
+
+def parse_bid(value):
+ bid = _CAMPAIGN_OBJECT_FACTORY_V11.create('Bid')
+ if not value:
+ bid.Amount = None
+ else:
+ bid.Amount = float(value)
+ return bid
+
def minute_bulk_str(value):
if value == 'Zero':
return '0'
@@ -730,6 +775,85 @@ def csv_to_entity_DSAWebpageParameter(row_values, entity):
webpage.Parameter.Conditions.WebpageCondition = conditions
entity.Criterion = webpage
+def entity_to_csv_PriceTableRows(entity, row_values):
+ """
+ Set Price Ad Extension price table rows from bulk values
+ :param entity: price ad extension entity
+ :param row_values: bulk row values
+ """
+ if entity is not None and entity.TableRows is not None and \
+ entity.TableRows.PriceTableRow is not None:
+ currency_code_prefix = _StringTable.CurrencyCode1[:-1]
+ price_description_prefix = _StringTable.PriceDescription1[:-1]
+ header_prefix = _StringTable.Header1[:-1]
+ final_mobile_url_prefix = _StringTable.FinalMobileUrl1[:-1]
+ final_url_prefix = _StringTable.FinalUrl1[:-1]
+ price_prefix = _StringTable.Price1[:-1]
+ price_qualifier_prefix = _StringTable.PriceQualifier1[:-1]
+ price_unit_prefix = _StringTable.PriceUnit1[:-1]
+
+ price_table_rows = entity.TableRows.PriceTableRow
+ for i in range(0, len(price_table_rows)):
+ row_values[currency_code_prefix + str(i + 1)] = price_table_rows[i].CurrencyCode
+ row_values[price_description_prefix + str(i + 1)] = price_table_rows[i].Description
+ row_values[header_prefix + str(i + 1)] = price_table_rows[i].Header
+ row_values[final_mobile_url_prefix + str(i + 1)] = field_to_csv_Urls(price_table_rows[i].FinalMobileUrls)
+ row_values[final_url_prefix + str(i + 1)] = field_to_csv_Urls(price_table_rows[i].FinalUrls)
+ row_values[price_prefix + str(i + 1)] = bulk_str(price_table_rows[i].Price)
+ row_values[price_qualifier_prefix + str(i + 1)] = price_table_rows[i].PriceQualifier
+ row_values[price_unit_prefix + str(i + 1)] = price_table_rows[i].PriceUnit
+
+
+def csv_to_entity_PriceTableRows(row_values, entity):
+ """
+ convert Price Ad Extension price table rows to bulk row values
+ :param row_values: bulk row values
+ :param entity: price ad extension entity
+ """
+ MAX_NUMBER_OF_PRICE_TABLE_ROWS = 8
+ currency_code_prefix = _StringTable.CurrencyCode1[:-1]
+ price_description_prefix = _StringTable.PriceDescription1[:-1]
+ header_prefix = _StringTable.Header1[:-1]
+ final_mobile_url_prefix = _StringTable.FinalMobileUrl1[:-1]
+ final_url_prefix = _StringTable.FinalUrl1[:-1]
+ price_prefix = _StringTable.Price1[:-1]
+ price_qualifier_prefix = _StringTable.PriceQualifier1[:-1]
+ price_unit_prefix = _StringTable.PriceUnit1[:-1]
+
+ price_table_rows = []
+ for i in range(0, MAX_NUMBER_OF_PRICE_TABLE_ROWS):
+ currency_code_success, currency_code = row_values.try_get_value(currency_code_prefix + str(i + 1))
+ price_description_success, price_description = row_values.try_get_value(price_description_prefix + str(i + 1))
+ header_success, header = row_values.try_get_value(header_prefix + str(i + 1))
+ final_mobile_url_success, final_mobile_url = row_values.try_get_value(final_mobile_url_prefix + str(i + 1))
+ final_url_success, final_url = row_values.try_get_value(final_url_prefix + str(i + 1))
+ price_success, price = row_values.try_get_value(price_prefix + str(i + 1))
+ price_qualifier_success, price_qualifier = row_values.try_get_value(price_qualifier_prefix + str(i + 1))
+ price_unit_success, price_unit = row_values.try_get_value(price_unit_prefix + str(i + 1))
+
+ if currency_code_success \
+ or price_description_success \
+ or header_success \
+ or final_mobile_url_success \
+ or final_url_success \
+ or price_success \
+ or price_qualifier_success \
+ or price_unit_success:
+ price_table_row = _CAMPAIGN_OBJECT_FACTORY_V11.create('PriceTableRow')
+ price_table_row.CurrencyCode = currency_code
+ price_table_row.Description = price_description
+ price_table_row.Header = header
+ csv_to_field_Urls(price_table_row.FinalMobileUrls, final_mobile_url)
+ csv_to_field_Urls(price_table_row.FinalUrls, final_url)
+ price_table_row.Price = price
+ price_table_row.PriceQualifier = price_qualifier
+ price_table_row.PriceUnit = price_unit
+
+ price_table_rows.append(price_table_row)
+
+ if len(price_table_rows) > 0:
+ entity.TableRows.PriceTableRow = price_table_rows
+
def parse_bool(value):
if value is None or value == '':
@@ -1051,6 +1175,39 @@ def csv_to_field_LongitudeDegrees(entity, value):
if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(RadiusCriterion)):
setattr(entity.Criterion, "LongitudeDegrees", value)
+def field_to_csv_AdFormatPreference(value):
+ """
+ convert field value to csv content
+ :param value: field value
+ :return:
+ """
+ if value is None or value == '':
+ return None
+ if value.lower() == 'true':
+ return 'Native'
+ elif value.lower() == 'false':
+ return 'All'
+ else:
+ raise ValueError('Unsupported value for Native Preference: {0}'.format(value))
+ return None
+
+
+def csv_to_field_AdFormatPreference(entity, value):
+ """
+ parse csv content and set entity attribute
+ :param entity: entity which has AdFormatPreference attribute
+ :param value: csv content value
+ :return:
+ """
+
+ if value is None or value == '' or value == 'All':
+ entity.AdFormatPreference = 'False'
+ elif value == 'Native':
+ entity.AdFormatPreference = 'True'
+ else:
+ raise ValueError('Unsupported value for Native Preference: {0}'.format(value))
+
+
def parse_rule_PageVisitors(rule_str):
rule = _CAMPAIGN_OBJECT_FACTORY_V11.create('ns0:PageVisitorsRule')
rule.Type = 'PageVisitors'
diff --git a/bingads/v11/proxies/campaign_management_service.xml b/bingads/v11/proxies/campaign_management_service.xml
index 207a767b..d8cae0f3 100644
--- a/bingads/v11/proxies/campaign_management_service.xml
+++ b/bingads/v11/proxies/campaign_management_service.xml
@@ -1261,6 +1261,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2342,6 +2396,7 @@
+
@@ -3531,6 +3586,7 @@
+
@@ -3681,6 +3737,14 @@
+
+
+
+
+
+
+
+
@@ -3726,6 +3790,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4745,6 +4839,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4764,7 +4906,7 @@
-
+
@@ -4788,7 +4930,7 @@
-
+
@@ -4812,7 +4954,7 @@
-
+
@@ -4836,7 +4978,7 @@
-
+
@@ -4860,7 +5002,7 @@
-
+
@@ -4884,7 +5026,7 @@
-
+
@@ -4908,7 +5050,7 @@
-
+
@@ -4932,7 +5074,7 @@
-
+
@@ -4956,7 +5098,7 @@
-
+
@@ -4980,7 +5122,7 @@
-
+
@@ -5004,7 +5146,7 @@
-
+
@@ -5028,7 +5170,7 @@
-
+
@@ -5052,7 +5194,7 @@
-
+
@@ -5076,7 +5218,7 @@
-
+
@@ -5100,7 +5242,7 @@
-
+
@@ -5124,7 +5266,7 @@
-
+
@@ -5148,7 +5290,7 @@
-
+
@@ -5172,7 +5314,7 @@
-
+
@@ -5196,7 +5338,7 @@
-
+
@@ -5220,7 +5362,7 @@
-
+
@@ -5244,7 +5386,7 @@
-
+
@@ -5268,7 +5410,7 @@
-
+
@@ -5292,7 +5434,7 @@
-
+
@@ -5316,7 +5458,7 @@
-
+
@@ -5340,7 +5482,7 @@
-
+
@@ -5364,7 +5506,7 @@
-
+
@@ -5388,7 +5530,7 @@
-
+
@@ -5412,7 +5554,7 @@
-
+
@@ -5436,7 +5578,7 @@
-
+
@@ -5460,7 +5602,7 @@
-
+
@@ -5484,7 +5626,7 @@
-
+
@@ -5508,7 +5650,7 @@
-
+
@@ -5532,7 +5674,7 @@
-
+
@@ -5556,7 +5698,7 @@
-
+
@@ -5580,7 +5722,7 @@
-
+
@@ -5604,7 +5746,7 @@
-
+
@@ -5652,7 +5794,7 @@
-
+
@@ -5676,7 +5818,7 @@
-
+
@@ -5700,7 +5842,7 @@
-
+
@@ -5724,7 +5866,7 @@
-
+
@@ -5748,7 +5890,7 @@
-
+
@@ -5772,7 +5914,7 @@
-
+
@@ -5796,7 +5938,7 @@
-
+
@@ -5820,7 +5962,7 @@
-
+
@@ -5844,7 +5986,7 @@
-
+
@@ -5868,7 +6010,7 @@
-
+
@@ -5892,7 +6034,7 @@
-
+
@@ -5916,7 +6058,7 @@
-
+
@@ -5940,7 +6082,7 @@
-
+
@@ -5964,7 +6106,7 @@
-
+
@@ -5988,7 +6130,7 @@
-
+
@@ -6012,7 +6154,7 @@
-
+
@@ -6036,7 +6178,7 @@
-
+
@@ -6060,7 +6202,7 @@
-
+
@@ -6084,7 +6226,7 @@
-
+
@@ -6108,11 +6250,35 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -6125,6 +6291,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -6318,6 +6580,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -6654,6 +6928,12 @@
+
+
+
+
+
+
@@ -7394,6 +7674,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -8682,6 +9008,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/setup.py b/setup.py
index 457becc3..20a61169 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
except ImportError:
from distutils.core import setup
-VERSION = '11.5.2'
+VERSION = '11.5.3'
with open('README.rst', 'r') as f:
readme = f.read()