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()