diff --git a/HISTORY.rst b/HISTORY.rst index 35c385c1..04a046b6 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2,72 +2,252 @@ Release History +13.0.25.3(2025-09-12) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the [Bing Ads API Release Notes](https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13). +* Support IsPolitical in BulkCampaign. + +13.0.25.2(2025-07-31) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the [Bing Ads API Release Notes](https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13). + +13.0.25.1(2025-07-17) ++++++++++++++++++++++++++ +* Fix Issue #321: https://github.com/BingAds/BingAds-Python-SDK/issues/321 + +13.0.25(2025-07-10) ++++++++++++++++++++++++++ +API Updates: +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the [Bing Ads API Release Notes](https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13). +* New Reports in Reporting Service: AppsPerformanceReport, TravelQueryInsightReport and FeedIemPerformanceReport. +* Support CampaignTypeReportFilter in Reporting API. +* New APIs in CampaignManagement Service: GetAnnotationOptOut, UpdateAnnotationOptOut, CreateBrandKitRecommendation and GetResponsiveAdRecommendationJob. +* New field ListingGroupPath in AssetGroupListingGroup. +* New field IsAutoGoal in ConversionGoal. +* New field MaxCpc in MaxConversionValueBiddingScheme. +* New API in CustomerBilling Service: GetCouponInfo. + +Bulk Mapping Updates: +* Added bulk mappings for Site Exclusion: BulkAccountPlacementExclusionList, BulkSharedListNegativeSite, BulkAccountPlacementExclusionListAssociation, BulkAccountPlacementInclusionList, BulkSharedListSite and BulkAccountPlacementInclusionListAssociation. + +13.0.24.2(2025-04-28) ++++++++++++++++++++++++++ +* Enable MSA Production support on the sandbox by default, as MSA INT will soon be deprecated. + +13.0.24.1(2025-02-21) ++++++++++++++++++++++++++ +* Fix issue in BulkBudget in version 13.0.24. + +13.0.24(2025-02-20) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13. +* Added NewCustomerAcquisitionGoalSetting in BulkCampaign mapping. +* Added SubType, ActionType in BulkCampaignConversionGoal mapping. +* Added bulk mappings for NCA: BulkNewCustomerAcquisitionGoal. + +13.0.23.1(2025-01-23) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13. +* Fix issue in BulkProductAudience mapping. + +13.0.23(2024-11-21) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13. +* Added bulk mappings for BulkAssetGroupUrlTarget. + +13.0.21.2(2024-08-19) ++++++++++++++++++++++++++ +* Fix Issue #295: https://github.com/BingAds/BingAds-Python-SDK/issues/295 +* Change 'ImpreesionBasedRemarketingList' to 'ImpressionBasedRemarketingList' in AudienceAdditionalField + +13.0.21.1(2024-07-24) ++++++++++++++++++++++++++ +* Fix Issue #291: https://github.com/BingAds/BingAds-Python-SDK/issues/291 + +13.0.21(2024-07-18) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13. +* Added bulk mappings for new AudienceType:ImpressionBasedRemarketingList i.e., BulkImpressionBasedRemarketingList, BulkAdGroupImpressionBasedRemarketingListAssociation, BulkAdGroupNegativeImpressionBasedRemarketingListAssociation, BulkCampaignImpressionBasedRemarketingListAssociation and BulkCampaignNegativeImpressionBasedRemarketingListAssociation. +* Added bulk mappings for Goals i.e., BulkAppInstallGoal, BulkDurationGoal, BulkEventGoal, BulkInStoreTransactionGoal, BulkInStoreVisitGoal, BulkOfflineConversionGoal, BulkPagesViewedPerVisitGoal, BulkProductGoal and BulkUrlGoal. +* Added bulk mappings for BulkBrandItem, BulkBrandList and BulkCampaignBrandListAssociation. +* Added bulk mappings for BulkAssetGroupSearchTheme. +* Added mappings for new field in BulkCampaign: CostPerSaleOptOut. +* Changed DeviceTypeFilter to enum list in BulkSeasonlityAdjustment and BulkDataExclusion. + +13.0.19.1(2024-04-09) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13. + +13.0.19(2024-03-25) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13. +* Added bulk mappings for Account Level Negative Keyword List i.e., BulkAccountNegativeKeywordList, BulkAccountNegativeKeywordListAssociation and BulkAccountSharedNegativeKeyword. +* Added bulk mappings for BulkSeasonalityAdjustment and BulkDataExclusion. +* Removed mappings for VerifiedTrackingSetting field in BulkCampaign. +* Added mappings for new field in BulkCampaign: AutoGeneratedImageOptOut and AutoGeneratedTextOptOut. +* Added PerformanceMaxsetting for PageFeedIds field in BulkCampaign. +* Added mappings for new BiddingScheme: CostPerSaleBiddingScheme. + +13.0.18.1(2024-01-30) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. + +13.0.18(2023-11-13) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13. +* Added mappings for new fields in BulkOfflineConversion: HashedEmailAddress and HashedPhoneNumber. + +13.0.17(2023-08-18) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13. +* Added bulk mapping for new Criterion i.e., BulkCampaignDealCriterion, BulkAdGroupGenreCriterion. +* Added mappings for new fields in BulkCampaign: DestinationChannel and IsMultiChannelCampaign. +* Added mappings for new fields in BulkResponsiveAd: VerifiedTrackingDatas. +* Added mappings for new fields in ImageAsset: TargetWidth and TargetHeight. +* Fixed issue: https://github.com/BingAds/BingAds-Python-SDK/issues/250. + +13.0.16(2023-06-02) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Add bulk mappings for performance max campaign i.e., BulkAssetGroup, BulkAssetGroupListingGroup, BulkAudienceGroup, BulkAudienceGroupAssetGroupAssociation, BulkCampaignNegativeWebPage. +* Add mappings for new fields in BulkCampaign: UrlExpansionOptOut. +* Support new bidding scheme: ManualCpaScheme and CostPerSaleBiddingScheme. + +13.0.15(2022-12-23) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Add bulk mappings for OnlineConversionAdjustment. +* Add bulk mappings for Adgroup Hotel Ads Criterions i.e., BulkAdGroupHotelAdvanceBookingWindowCriterion, BulkAdGroupHotelCheckInDateCriterion, BulkAdGroupHotelCheckInDayCriterion, BulkAdGroupHotelDateSelectionTypeCriterion and BulkAdGroupHotelLengthOfStayCriterion. +* Add bulk mappings for AdGroupHotelListingGroup. +* Add mappings for new fields in BulkAdgroup: UseOptimizedTargeting, HotelSetting, CommissionRate and PercentCpcBid. +* Support new bidding scheme: percentCpcBiddingScheme and commissionBiddingScheme. + +13.0.14(2022-06-30) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Get rid of the default ObjectCache,and use a in memory cache for ServiceClient. https://github.com/BingAds/BingAds-Python-SDK/pull/108. +* Add bulk mappings for BulkCampaignConversionGoal. +* Add bulk mappings for ad customer attribute i.e., BulkAdCustomizerAttribute, BulkCampaignAdCustomizerAttribute, BulkAdGroupAdCustomizerAttribute, BulkKeywordAdCustomizerAttribute. +* Add mappings for new fields in BulkFeed: Schedule. +* Fix issue of invalid variable: maxCpcValue. https://github.com/BingAds/BingAds-Python-SDK/pull/200#issuecomment-1085432417. +* Update suds-community version to 1.1.0. + +13.0.13(2022-01-14) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Add new fields Operator mapping in WebCondition for BulkAdGroupDynamicSearchAdTarget, BulkAdGroupNegativeDynamicSearchAdTarget and BulkCampaignNegativeDynamicSearchAdTarget. +* Add NumberRuleItem mapping to BulkRemarketingList. + +13.0.12(2021-10-29) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Add VerifiedTrackingSetting mapping in the BulkCampaign. +* Add BusinessAttributes mapping in the BulkCampaign. + + +13.0.11.1(2021-10-13) ++++++++++++++++++++++++++ +* Update suds lib from suds-jurko to suds-community to support latest setuptools. + +13.0.11(2021-08-20) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Add mapping for new DynamicDescriptionEnabled and DisclaimerSetting fields in BulkCampaign. +* Add BulkDisclaimerAdExtension and BulkCampaignDisclaimerAdExtension mapping for disclaimer ads support. + +13.0.10(2021-06-20) ++++++++++++++++++++++++++ + +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes +* Add new msads.manage scope for multi-factor authentication requirement. Eventually msads.manage will be required. Learn more here: https://go.microsoft.com/fwlink/?linkid=2155062 +* Default OAuth scope is set to the new msads.manage scope. Can be overridden temporarily with new oAuthScope parameter (replaces requireLiveConnect). +* Sandbox auth support via login.live-int.com is replaced with login.windows-ppe.net. +* Add BulkVideo for video ads support +* Add mappings for new fields in BulkResponsiveAd: CallToActionLanguage, Videos, Headlines, Descriptions +* Add mappings for new fields in BulkAdGroup: CpvBid, CpmBid +* Update ToBiddingSchemeBulkString(this BiddingScheme biddingScheme) to support MaxRoas, ManualCpv and ManualCpm +* Add mappings for new fields in BulkAccount: AdClickParallelTracking, AutoApplyRecommendations, AllowImageAutoRetrieve +* Conjunctive normal form (CNF) support is added to PageVisitorsRule and mapped in the BulkRemarketingList remarketing rule. Previously Microsoft Advertising only supported disjunctive normal form (DNF). You must ensure that your application can appropriately read and distinguish between CNF and DNF. Your application should no longer assume that the rule is disjunctive. +* Add mapping for new MultimediaAdsBidAdjustment field in BulkCampaign and BulkAdGroup +* Fix issue of DSA setting not being exported for Search Campaign + +13.0.9.1(2021-04-29) ++++++++++++++++++++++++++ +* Fix issue of missing proxies. + +13.0.9(2021-04-29) ++++++++++++++++++++++++++ +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Add bulk mappings for video ad extensions i.e., BulkVideoAdExtension, BulkAccountVideoAdExtension, BulkAdGroupVideoAdExtension, and BulkCampaignVideoAdExtension. +* Add CashbackAdjustment mapping in the BulkAdGroupBiddableCriterion and BulkCampaignBiddableCriterion. +* Cache SDK snapshot of the singleWsdl proxies for all Bing Ads API Version 13 services. + 13.0.8(2021-03-10) +++++++++++++++++++++++++ -* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. * Added BulkPromotionAdExtension to the object factory * Added BulkAdGroupBiddableCriterion, BulkAdGroupBiddableCriterion, BulkCampaignBiddableCriterion, and BulkCampaignNegativeCriterion base classes for criterion. -* Added DynamicFeedSetting to BulkCampaign for an upcoming pilot feature. +* Added DynamicFeedSetting to BulkCampaign for an upcoming pilot feature. * Added BulkBidStrategy for an upcoming pilot feature. * Added BidStrategyId to BulkCampaign for an upcoming pilot feature. 13.0.7(2020-12-16) +++++++++++++++++++++++++ -* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. -* Add bulk mappings for flyer ad extensions i.e., BulkFlyerAdExtension, BulkAccountFlyerAdExtension, BulkAdGroupFlyerAdExtension, and BulkCampaignFlyerAdExtension. -* Add ImpressionTrackingUrls mapping in the BulkResponsiveAd. +* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Add bulk mappings for flyer ad extensions i.e., BulkFlyerAdExtension, BulkAccountFlyerAdExtension, BulkAdGroupFlyerAdExtension, and BulkCampaignFlyerAdExtension. +* Add ImpressionTrackingUrls mapping in the BulkResponsiveAd. * Update the pattern matching to resolve EntityReadException with BulkCombinedList download. 13.0.6(2020-10-14) +++++++++++++++++++++++++ -* Updated Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. -* Add FinalUrlSuffix mapping in the BulkFilterLinkAdExtension. -* Add AdGroupType mapping in the BulkAdGroup. -* Allow DynamicSearchAdsSetting in BulkCampaign for search campaigns. -* Remove delete_value write to file for AdScheduleUseSearcherTimeZone in BulkAdGroup and BulkCampaign. +* Updated Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Add FinalUrlSuffix mapping in the BulkFilterLinkAdExtension. +* Add AdGroupType mapping in the BulkAdGroup. +* Allow DynamicSearchAdsSetting in BulkCampaign for search campaigns. +* Remove delete_value write to file for AdScheduleUseSearcherTimeZone in BulkAdGroup and BulkCampaign. 13.0.5(2020-08-14) +++++++++++++++++++++++++ -* Updated Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. -* Add BulkImage for bulk image upload. -* Add Multi-Image field mappings for BulkImageAdExtension. -* Add offline conversion adjustment field mappings for BulkOfflineConversion. -* Add bulk mappings for filter link ad extensions i.e., BulkFilterLinkAdExtension, BulkAccountFilterLinkAdExtension, BulkAdGroupFilterLinkAdExtension, and BulkCampaignFilterLinkAdExtension. +* Updated Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Add BulkImage for bulk image upload. +* Add Multi-Image field mappings for BulkImageAdExtension. +* Add offline conversion adjustment field mappings for BulkOfflineConversion. +* Add bulk mappings for filter link ad extensions i.e., BulkFilterLinkAdExtension, BulkAccountFilterLinkAdExtension, BulkAdGroupFilterLinkAdExtension, and BulkCampaignFilterLinkAdExtension. 13.0.4.1(2020-07-23) +++++++++++++++++++++++++ -* Fix issue https://github.com/BingAds/BingAds-Python-SDK/issues/160. +* Fix issue https://github.com/BingAds/BingAds-Python-SDK/issues/160. 13.0.4(2020-07-10) +++++++++++++++++++++++++ -* Updated Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes:https://docs.microsoft.com/en-us/bingads/guides/release-notes. -* Add mappings for TargetImpressionShareBiddingScheme in BulkCampaign. -* Add bulk mappings for combined list i.e., BulkCombinedList, BulkAdGroupCombinedListAssociation, BulkAdGroupNegativeCombinedListAssociation, BulkCampaignCombinedListAssociation, and BulkCampaignNegativeCombinedListAssociation. +* Updated Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes:https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Add mappings for TargetImpressionShareBiddingScheme in BulkCampaign. +* Add bulk mappings for combined list i.e., BulkCombinedList, BulkAdGroupCombinedListAssociation, BulkAdGroupNegativeCombinedListAssociation, BulkCampaignCombinedListAssociation, and BulkCampaignNegativeCombinedListAssociation. * Add bulk entities for customer list i.e., BulkCustomerList, BulkCustomerListItem, BulkAdGroupCustomerListAssociation, BulkAdGroupNegativeCustomerListAssociation, BulkCampaignCustomerListAssociation, and BulkCampaignNegativeCustomerListAssociation. -* Add OAuth support for AAD tenant. +* Add OAuth support for AAD tenant. * Add OAuth support for PKCE e.g., code_verifier. 13.0.3(2020-05-26) +++++++++++++++++++++++++ -* Updated Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. -* Add mappings for MaxConversionValueBiddingScheme and TargetRoasBiddingScheme in BulkCampaign. -* Add mapping for the 'Use Searcher Time Zone' field in BulkCampaign and BulkAdGroup. -* Add bulk mappings for promotion ad extensions i.e., BulkPromotionAdExtension, BulkAccountPromotionAdExtension, BulkAdGroupPromotionAdExtension, and BulkCampaignPromotionAdExtension. -* Add support for delete_value of EndDate in the BulkExperiment. -* Add BulkCampaignNegativeStoreCriterion for future use. +* Updated Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. +* Add mappings for MaxConversionValueBiddingScheme and TargetRoasBiddingScheme in BulkCampaign. +* Add mapping for the 'Use Searcher Time Zone' field in BulkCampaign and BulkAdGroup. +* Add bulk mappings for promotion ad extensions i.e., BulkPromotionAdExtension, BulkAccountPromotionAdExtension, BulkAdGroupPromotionAdExtension, and BulkCampaignPromotionAdExtension. +* Add support for delete_value of EndDate in the BulkExperiment. +* Add BulkCampaignNegativeStoreCriterion for future use. 13.0.2(2019-12-08) +++++++++++++++++++++++++ -* Attempt internal sync upload for up to 1,000 bulk entities via BulkServiceManager and upload_entities. -* Added the mapping for FinalUrlSuffix in BulkAdGroupDynamicSearchAdTarget. +* Attempt internal sync upload for up to 1,000 bulk entities via BulkServiceManager and upload_entities. +* Added the mapping for FinalUrlSuffix in BulkAdGroupDynamicSearchAdTarget. 13.0.1(2019-11-08) +++++++++++++++++++++++++ @@ -80,13 +260,13 @@ Release History 12.13.6(2019-10-12) +++++++++++++++++++++++++ -* Mapped the Experiment Type column to ExperimentType via BulkExperiment. +* Mapped the Experiment Type column to ExperimentType via BulkExperiment. * Updated Bing Ads API version 12 and 13 service proxies to reflect recent interface changes. For more information please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/advertising/guides/release-notes. 12.13.5(2019-09-12) +++++++++++++++++++++++++ -* Map the Bid Adjustment column to a BidMultiplier via BulkAdGroupProductPartition. +* Map the Bid Adjustment column to a BidMultiplier via BulkAdGroupProductPartition. * Updated Bing Ads API version 12 and 13 service proxies to reflect recent interface changes. For more information please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/advertising/guides/release-notes. @@ -121,14 +301,14 @@ Release History 12.13.2(2019-05-15) +++++++++++++++++++++++++ -* IMPORTANT: The default OAuth endpoint is updated from "Live Connect": https://docs.microsoft.com/en-us/advertising/guides/authentication-oauth-live-connect endpoint to the "Microsoft Identity endpoint for developers": https://docs.microsoft.com/en-us/advertising/guides/authentication-oauth-identity-platform. The "Microsoft Identity endpoint" supports both Microsoft Account (MSA) personal credentials and Azure Active Directory (AAD) work credentials. For more information, see "Upgrade to the Microsoft identity platform endpoint FAQ": https://docs.microsoft.com/en-us/advertising/guides/authentication-oauth#upgrade-identity-platform-faq. +* IMPORTANT: The default OAuth endpoint is updated from "Live Connect": https://docs.microsoft.com/en-us/advertising/guides/authentication-oauth-live-connect endpoint to the "Microsoft Identity endpoint for developers": https://docs.microsoft.com/en-us/advertising/guides/authentication-oauth-identity-platform. The "Microsoft Identity endpoint" supports both Microsoft Account (MSA) personal credentials and Azure Active Directory (AAD) work credentials. For more information, see "Upgrade to the Microsoft identity platform endpoint FAQ": https://docs.microsoft.com/en-us/advertising/guides/authentication-oauth#upgrade-identity-platform-faq. * Updated Bing Ads API version 12 and 13 service proxies to reflect recent interface changes. For details please see the "Bing Ads API Release Notes": https://docs.microsoft.com/en-us/bingads/guides/release-notes. -* For Bing Ads API version 12 and 13, added a new Bulk property for Final Url Suffix phase 2 entities i.e., added FinalUrlSuffix to the existing BulkActionAdExtension, BulkAppAdExtension, BulkImageAdExtension, BulkPriceAdExtension, BulkSitelinkAdExtension, BulkAdGroupProductPartition, and BulkAd. For details see "Final Url Suffix": https://docs.microsoft.com/en-us/advertising/guides/url-tracking-upgraded-urls#finalurlsuffixvalidation. +* For Bing Ads API version 12 and 13, added a new Bulk property for Final Url Suffix phase 2 entities i.e., added FinalUrlSuffix to the existing BulkActionAdExtension, BulkAppAdExtension, BulkImageAdExtension, BulkPriceAdExtension, BulkSitelinkAdExtension, BulkAdGroupProductPartition, and BulkAd. For details see "Final Url Suffix": https://docs.microsoft.com/en-us/advertising/guides/url-tracking-upgraded-urls#finalurlsuffixvalidation. 12.13.1(2019-04-15) +++++++++++++++++++++++++ -* Added support for Bing Ads API Version 13. For more information, see Migrating to Bing Ads API Version 13: https://docs.microsoft.com/en-us/bingads/guides/migration-guide?view=bingads-13. +* Added support for Bing Ads API Version 13. For more information, see Migrating to Bing Ads API Version 13: https://docs.microsoft.com/en-us/bingads/guides/migration-guide?view=bingads-13. * Updated version 12 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes?view=bingads-12. * For both version 12 and 13, added a new Bulk property for Final Url Suffix i.e., added FinalUrlSuffix to the existing BulkAccount, BulkAdGroup, BulkCampaign, and BulkKeyword. For details about Final Url Suffix in the Bulk file, see the Release Notes:https://docs.microsoft.com/en-us/bingads/guides/release-notes?view=bingads-12#finalurlsuffix-march2019. @@ -137,9 +317,9 @@ Release History * Updated service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. * Added a new Bulk property for Action Text i.e., added ActionText to the existing BulkActionAdExtension. -* Removed the is_expired property from BulkAdGroup. Use the Status property of the BulkAdGroup instead. -* For optional fields, the Bulk file schema mapping is updated such that "delete_value" will only be written to the file for update operations. Update intent is assumed when the Bulk entity ID is greater than zero. -* Updated the Status mapping for BulkExperiment i.e., map the string value directly instead of via bulk_optional_str. +* Removed the is_expired property from BulkAdGroup. Use the Status property of the BulkAdGroup instead. +* For optional fields, the Bulk file schema mapping is updated such that "delete_value" will only be written to the file for update operations. Update intent is assumed when the Bulk entity ID is greater than zero. +* Updated the Status mapping for BulkExperiment i.e., map the string value directly instead of via bulk_optional_str. 12.0.3.1(2019-02-01) +++++++++++++++++++++++++ @@ -149,24 +329,24 @@ Release History 12.0.3(2019-01-10) +++++++++++++++++++++++++ -* BREAKING CHANGE for BulkAdGroupCustomAudienceAssociation, BulkAdGroupInMarketAudienceAssociation, BulkAdGroupNegativeCustomAudienceAssociation, BulkAdGroupNegativeInMarketAudienceAssociation, BulkAdGroupNegativeProductAudienceAssociation, BulkAdGroupNegativeRemarketingListAssociation, BulkAdGroupNegativeSimilarRemarketingListAssociation, BulkAdGroupProductAudienceAssociation, BulkAdGroupRemarketingListAssociation, and BulkAdGroupSimilarRemarketingListAssociation: Replaced custom_audience_name, in_market_audience_name, product_audience_name, remarketing_list_name, and similar_remarketing_list_name with audience_name. The audience_name property is now used to map from the 'Audience Name' field of a Bulk file via all audience association SDK objects. +* BREAKING CHANGE for BulkAdGroupCustomAudienceAssociation, BulkAdGroupInMarketAudienceAssociation, BulkAdGroupNegativeCustomAudienceAssociation, BulkAdGroupNegativeInMarketAudienceAssociation, BulkAdGroupNegativeProductAudienceAssociation, BulkAdGroupNegativeRemarketingListAssociation, BulkAdGroupNegativeSimilarRemarketingListAssociation, BulkAdGroupProductAudienceAssociation, BulkAdGroupRemarketingListAssociation, and BulkAdGroupSimilarRemarketingListAssociation: Replaced custom_audience_name, in_market_audience_name, product_audience_name, remarketing_list_name, and similar_remarketing_list_name with audience_name. The audience_name property is now used to map from the 'Audience Name' field of a Bulk file via all audience association SDK objects. * Updated service proxies to reflect recent interface changes. For details please see the release notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. * Added Bulk mapping for responsive ad images i.e., added Images to the existing BulkResponsiveAd. * Added Bulk mapping for campaign target setting i.e., added TargetSetting to the existing BulkCampaign. -* Added Bulk mapping for campaign level audience associations i.e.,BulkCampaignCustomAudienceAssociation, BulkCampaignInMarketAudienceAssociation, BulkCampaignNegativeCustomAudienceAssociation, BulkCampaignNegativeInMarketAudienceAssociation, BulkCampaignNegativeProductAudienceAssociation, BulkCampaignNegativeRemarketingListAssociation, BulkCampaignNegativeSimilarRemarketingListAssociation, BulkCampaignProductAudienceAssociation, BulkCampaignRemarketingListAssociation, and BulkCampaignSimilarRemarketingListAssociation. -* Added the get_response_header method in class ServiceClient, to access the service TrackingId, etc per GitHub issue https://github.com/BingAds/BingAds-Python-SDK/issues/106. +* Added Bulk mapping for campaign level audience associations i.e.,BulkCampaignCustomAudienceAssociation, BulkCampaignInMarketAudienceAssociation, BulkCampaignNegativeCustomAudienceAssociation, BulkCampaignNegativeInMarketAudienceAssociation, BulkCampaignNegativeProductAudienceAssociation, BulkCampaignNegativeRemarketingListAssociation, BulkCampaignNegativeSimilarRemarketingListAssociation, BulkCampaignProductAudienceAssociation, BulkCampaignRemarketingListAssociation, and BulkCampaignSimilarRemarketingListAssociation. +* Added the get_response_header method in class ServiceClient, to access the service TrackingId, etc per GitHub issue https://github.com/BingAds/BingAds-Python-SDK/issues/106. 12.0.2(2018-12-10) +++++++++++++++++++++++++ * Updated service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes. * Added Bulk mapping for campaign experiments i.e., BulkExperiment and BulkCampaign. -* Added Bulk mapping for action ad extensions i.e., BulkActionAdExtension, BulkAccountActionAdExtension, BulkAdGroupActionAdExtension, and BulkCampaignActionAdExtension. +* Added Bulk mapping for action ad extensions i.e., BulkActionAdExtension, BulkAccountActionAdExtension, BulkAdGroupActionAdExtension, and BulkCampaignActionAdExtension. 12.0.1(2018-11-10) +++++++++++++++++++++++++ -* Removed support for Bing Ads API Version 11, per the October 31, 2018 sunset. +* Removed support for Bing Ads API Version 11, per the October 31, 2018 sunset. * Added Bulk mapping for responsive search ads i.e., BulkResponsiveSearchAd and BulkResponsiveSearchAdLabel. * Added all fragments returned via the tokens request as a new property in the OAuthTokens SDK class. @@ -179,57 +359,57 @@ Release History 11.12.6(2018-09-10) +++++++++++++++++++++++++ -* Updated service proxies to reflect recent Bulk, Campaign Management, Customer Management, and Reporting API changes. +* Updated service proxies to reflect recent Bulk, Campaign Management, Customer Management, and Reporting API changes. * Added Bulk mapping for similar remarketing lists i.e., BulkSimilarRemarketingList, BulkAdGroupSimilarRemarketingListAssociation, and BulkAdGroupNegativeSimilarRemarketingListAssociation. 11.12.5(2018-08-10) +++++++++++++++++++++++++ -* Updated service proxies to support customer address, campaign level profile criteria, similar audiences for remarketing lists, and new change history report columns. For details see the service release notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes?view=bingads-12#august2018. -* Added BulkEntity mappings for campaign level profile criteria i.e., added BulkCampaignCompanyNameCriterion, BulkCampaignJobFunctionCriterion, and BulkCampaignIndustryCriterion. +* Updated service proxies to support customer address, campaign level profile criteria, similar audiences for remarketing lists, and new change history report columns. For details see the service release notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes?view=bingads-12#august2018. +* Added BulkEntity mappings for campaign level profile criteria i.e., added BulkCampaignCompanyNameCriterion, BulkCampaignJobFunctionCriterion, and BulkCampaignIndustryCriterion. 11.12.4(2018-07-10) +++++++++++++++++++++++++ * Added a mapping for the Domain column in the Bulk file to the BulkExpandedTextAd object. -* Limited the scope to bingads.manage for access token requests. Previously the default scope was used, which can vary if a user granted your app permissions to multiple scopes. The Bing Ads SDKs only support the bingads.manage scope. -* Updated the Customer Management proxies to support LinkedAccountIds for agencies. For agency users the customer role can contain a list of linked accounts that the user can access as an agency on behalf of another customer. +* Limited the scope to bingads.manage for access token requests. Previously the default scope was used, which can vary if a user granted your app permissions to multiple scopes. The Bing Ads SDKs only support the bingads.manage scope. +* Updated the Customer Management proxies to support LinkedAccountIds for agencies. For agency users the customer role can contain a list of linked accounts that the user can access as an agency on behalf of another customer. 11.12.3(2018-06-10) +++++++++++++++++++++++++ -* Added support for Cooperative bidding e.g., added mappings for "Bid Boost Value", "Bid Option" and "Maximum Bid" fields via the BulkAdGroup. +* Added support for Cooperative bidding e.g., added mappings for "Bid Boost Value", "Bid Option" and "Maximum Bid" fields via the BulkAdGroup. * Added mappings for the 'MSCLKID Auto Tagging Enabled" and "Tracking Tempalte" fields via the BulkAccount. 11.12.2(2018-05-15) +++++++++++++++++++++++++ -* To extend support for Microsoft Audience Ads, new bulk objects are added to the SDK for reading and writing Bulk file records e.g., BulkResponsiveAd and BulkResponsiveAdLabel. -* dAdded retries for the 117 throttling error if encountered while polling for the status of a bulk or reporting operation. +* To extend support for Microsoft Audience Ads, new bulk objects are added to the SDK for reading and writing Bulk file records e.g., BulkResponsiveAd and BulkResponsiveAdLabel. +* dAdded retries for the 117 throttling error if encountered while polling for the status of a bulk or reporting operation. 11.12.1(2018-04-12) +++++++++++++++++++++++++ * Added support for Bing Ads API Version 12. For more information, see Migrating to Bing Ads API Version 12. -* The version parameter is now required when creating each ServiceClient. Previously the version was optional and defaulted to version 11. The version parameter is moved to the second position between the service client name and the authorization data. -* The file_type parameter now defaults to 'Csv' as an *str* datatype instead of the DownloadFileType for BulkFileReader, BulkServiceManager, DownloadParameters and SubmitDownloadParameters. You can set 'Tsv' if you prefer the tab separated file format type. +* The version parameter is now required when creating each ServiceClient. Previously the version was optional and defaulted to version 11. The version parameter is moved to the second position between the service client name and the authorization data. +* The file_type parameter now defaults to 'Csv' as an *str* datatype instead of the DownloadFileType for BulkFileReader, BulkServiceManager, DownloadParameters and SubmitDownloadParameters. You can set 'Tsv' if you prefer the tab separated file format type. 11.5.9(2018-03-12) +++++++++++++++++++++++++ -* Updated to support Microsoft Account authentication in sandbox. +* Updated to support Microsoft Account authentication in sandbox. 11.5.8(2018-01-12) +++++++++++++++++++++++++ * The Bulk and Campaign Management proxies are updated to support audience search size. In addition the SDK supports audience search size via the BulkCustomAudience, BulkInMarketAudience, and BulkRemarketingList classes. - + * Allow the Parent Id to be empty when deleting Bulk entities. Previously the Parent Id was required by the SDK although the Bulk service does not always require it. 11.5.7(2017-12-12) +++++++++++++++++++++++++ -* The Version 11 Reporting service proxies are updated to support new columns for Estimated Bids. +* The Version 11 Reporting service proxies are updated to support new columns for Estimated Bids. 11.5.6(2017-11-01) +++++++++++++++++++++++++ diff --git a/MANIFEST.in b/MANIFEST.in index 9aab48e6..78f3f825 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ include *.rst *.py *.txt include LICENSE -include bingads/v13/proxies/*xml +include bingads/v13/proxies/*/*.xml diff --git a/README.rst b/README.rst index ec98c61f..caef7c0f 100644 --- a/README.rst +++ b/README.rst @@ -11,31 +11,20 @@ with the Python programming language. The SDK includes proxy classes for all Bing Ads API web services and abstracts the low level details of authentication with OAuth. You can also read and write bulk files with the SDK BulkFileReader and BulkFileWriter, and use the high level BulkServiceManager interface to abstract and execute operations in the low level Bulk API. -For more information, see `Bing Ads Client Libraries`_. +For more information, see `Bing Ads Client Libraries `_. Getting Started --------------- To get started developing Bing Ads applications with Python, -install the SDK and either start with the `examples`_ or follow one of the application walkthroughs. -For more information, see `Getting Started Using Python with Bing Ads Services`_. +install the SDK and either start with the `examples `_ or follow one of the application walkthroughs. +For more information, see `Getting Started Using Python with Bing Ads Services `_. External Dependencies --------------------- - - `suds-jurko`_ - - `requests`_ - - `future`_ - - `six`_ - - `enum34`_ - -.. _Bing Ads Client Libraries: https://docs.microsoft.com/en-us/bingads/guides/client-libraries -.. _examples: https://github.com/BingAds/BingAds-Python-SDK/tree/master/examples -.. _Getting Started Using Python with Bing Ads Services: https://docs.microsoft.com/en-us/bingads/guides/get-started-python - -.. _suds-jurko: http://pypi.python.org/pypi/suds-jurko -.. _requests: http://pypi.python.org/pypi/requests -.. _chardet: http://pypi.python.org/pypi/chardet -.. _future: http://pypi.python.org/pypi/future -.. _six: http://pypi.python.org/pypi/six -.. _enum34: http://pypi.python.org/pypi/enum34 + - `suds-community `_ + + - `requests `_ + + - `enum34 `_ \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 00000000..4aadbe77 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,29 @@ +# Python package +# Create and test a Python package on multiple Python versions. +# Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more: +# https://docs.microsoft.com/azure/devops/pipelines/languages/python + +trigger: +- main + +pool: + vmImage: ubuntu-22.04 +strategy: + matrix: + Python37: + python.version: '3.7' + +steps: +- task: UsePythonVersion@0 + inputs: + versionSpec: '$(python.version)' + displayName: 'Use Python $(python.version)' + +- script: | + python setup.py sdist + displayName: 'Package' + +- task: PublishBuildArtifacts@1 + inputs: + PathtoPublish: dist + ArtifactName: 'pypi_artifacts' \ No newline at end of file diff --git a/bingads/authorization.py b/bingads/authorization.py index cbaf6b02..97589659 100644 --- a/bingads/authorization.py +++ b/bingads/authorization.py @@ -11,6 +11,10 @@ PRODUCTION='production' SANDBOX='sandbox' +MSADS_MANAGE='msads.manage' +ADS_MANAGE='ads.manage' +BINGADS_MANAGE='bingads.manage' +MSA_PROD='msa.prod' class AuthorizationData: """ Represents a user who intends to access the corresponding customer and account. @@ -213,11 +217,11 @@ def __init__(self, access_token=None, access_token_expires_in_seconds=None, refr self._refresh_token = refresh_token self._response_json = response_json self._access_token_received_datetime=datetime.utcnow() - + @property def access_token_received_datetime(self): """ The datetime when access token was received - + :rtype: datetime """ return self._access_token_received_datetime @@ -261,7 +265,7 @@ def refresh_token(self): """ return self._refresh_token - + @property def response_json(self): """ OAuth whole attribute that got along with access token. @@ -285,7 +289,7 @@ class OAuthAuthorization(Authentication): * :class:`.OAuthWebAuthCodeGrant` """ - def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION, require_live_connect=False, tenant='common'): + def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION, oauth_scope=MSADS_MANAGE, tenant='common', use_msa_prod=True): """ Initializes a new instance of the OAuthAuthorization class. :param client_id: The client identifier corresponding to your registered application. @@ -300,10 +304,10 @@ def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION, require_live_co self._client_id = client_id self._oauth_tokens = oauth_tokens self._state = None - self.environment=env - self._require_live_connect=require_live_connect + self.environment = env + self._oauth_scope = MSA_PROD if env == SANDBOX and use_msa_prod else oauth_scope self._tenant = tenant - + @property def tenant(self): """ tenant @@ -384,7 +388,7 @@ class OAuthWithAuthorizationCode(OAuthAuthorization): For more information about registering a Bing Ads application, see http://go.microsoft.com/fwlink/?LinkID=511607. """ - def __init__(self, client_id, client_secret, redirection_uri, token_refreshed_callback=None, oauth_tokens=None, env=PRODUCTION, require_live_connect=False, tenant="common"): + def __init__(self, client_id, client_secret, redirection_uri, token_refreshed_callback=None, oauth_tokens=None, env=PRODUCTION, oauth_scope=MSADS_MANAGE, tenant="common", use_msa_prod=True): """ Initialize a new instance of this class. :param client_id: The client identifier corresponding to your registered application. @@ -401,7 +405,7 @@ def __init__(self, client_id, client_secret, redirection_uri, token_refreshed_ca :return: """ - super(OAuthWithAuthorizationCode, self).__init__(client_id, oauth_tokens=oauth_tokens, env=env, require_live_connect=require_live_connect, tenant=tenant) + super(OAuthWithAuthorizationCode, self).__init__(client_id, oauth_tokens=oauth_tokens, env=env, oauth_scope=oauth_scope, tenant=tenant, use_msa_prod=use_msa_prod) self._client_secret = client_secret self._redirection_uri = redirection_uri self._token_refreshed_callback = token_refreshed_callback @@ -412,17 +416,17 @@ def get_authorization_endpoint(self): :return: The Microsoft Account authorization endpoint. :rtype: str """ - endpoint_url = _UriOAuthService.AUTHORIZE_URI[(self.environment, self._require_live_connect)] - if self.environment == PRODUCTION and self._require_live_connect == False: + endpoint_url = _UriOAuthService.AUTHORIZE_URI[(self.environment, self._oauth_scope)] + if self.environment == PRODUCTION and (self._oauth_scope == MSADS_MANAGE or self._oauth_scope == ADS_MANAGE): endpoint_url = endpoint_url.replace('common', self.tenant); - + endpoint = str.format( endpoint_url, self._client_id, 'code', quote_plus(self._redirection_uri) ) - + return endpoint if self.state is None else endpoint + '&state=' + self.state def request_oauth_tokens_by_response_uri(self, response_uri, **kwargs): @@ -453,7 +457,7 @@ def request_oauth_tokens_by_response_uri(self, response_uri, **kwargs): grant_type='authorization_code', environment=self.environment, code=code, - requireliveconnect=self._require_live_connect, + oauth_scope=self._oauth_scope, tenant=self.tenant, **kwargs ) @@ -480,8 +484,8 @@ def request_oauth_tokens_by_refresh_token(self, refresh_token): grant_type='refresh_token', refresh_token=refresh_token, environment=self.environment, - scope=_UriOAuthService.SCOPE[(self.environment, self._require_live_connect)], - requireliveconnect=self._require_live_connect, + scope=_UriOAuthService.SCOPE[(self.environment, self._oauth_scope)], + oauth_scope=self._oauth_scope, tenant = self.tenant ) if self.token_refreshed_callback is not None: @@ -543,7 +547,7 @@ class OAuthDesktopMobileAuthCodeGrant(OAuthWithAuthorizationCode): For more information about registering a Bing Ads application, see http://go.microsoft.com/fwlink/?LinkID=511607. """ - def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION, require_live_connect=False, tenant='common'): + def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION, oauth_scope=MSADS_MANAGE, tenant='common', use_msa_prod=True): """ Initializes a new instance of the this class with the specified client id. :param client_id: The client identifier corresponding to your registered application. @@ -552,14 +556,16 @@ def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION, require_live_co :type oauth_tokens: OAuthTokens """ + effective_scope = MSA_PROD if env == SANDBOX and use_msa_prod else oauth_scope super(OAuthDesktopMobileAuthCodeGrant, self).__init__( client_id, None, - _UriOAuthService.REDIRECTION_URI[(env, require_live_connect)], + _UriOAuthService.REDIRECTION_URI[(env, effective_scope)], oauth_tokens=oauth_tokens, env=env, - require_live_connect=require_live_connect, - tenant=tenant + oauth_scope=effective_scope, + tenant=tenant, + use_msa_prod=use_msa_prod ) @@ -591,9 +597,9 @@ class OAuthDesktopMobileImplicitGrant(OAuthAuthorization): Authorization Code Grant section of the OAuth 2.0 spec at https://tools.ietf.org/html/rfc6749#section-4.1. For more information about registering a Bing Ads application, see http://go.microsoft.com/fwlink/?LinkID=511607. """ - - def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION, require_live_connect=False, tenant='common'): + + def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION, oauth_scope=MSADS_MANAGE, tenant='common', use_msa_prod=True): """ Initializes a new instance of the this class with the specified client id. :param client_id: The client identifier corresponding to your registered application. @@ -602,9 +608,10 @@ def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION, require_live_co :type oauth_tokens: OAuthTokens """ - super(OAuthDesktopMobileImplicitGrant, self).__init__(client_id, oauth_tokens=oauth_tokens, env=env, require_live_connect=require_live_connect, tenant=tenant) - - + effective_scope = MSA_PROD if env == SANDBOX and use_msa_prod else oauth_scope + super(OAuthDesktopMobileImplicitGrant, self).__init__(client_id, oauth_tokens=oauth_tokens, env=env, oauth_scope=effective_scope, tenant=tenant) + + def get_authorization_endpoint(self): """ Gets the Microsoft Account authorization endpoint where the user should be navigated to give his or her consent. @@ -613,16 +620,16 @@ def get_authorization_endpoint(self): :rtype: str """ - endpoint_url = _UriOAuthService.AUTHORIZE_URI[(self.environment, self._require_live_connect)] - if self.environment == PRODUCTION and self._require_live_connect == False: + endpoint_url = _UriOAuthService.AUTHORIZE_URI[(self.environment, self._oauth_scope)] + if self.environment == PRODUCTION and (self._oauth_scope == MSADS_MANAGE or self._oauth_scope == ADS_MANAGE): endpoint_url = endpoint_url.replace('common', self.tenant); endpoint = str.format( endpoint_url, self.client_id, 'token', - _UriOAuthService.REDIRECTION_URI[(self.environment, self._require_live_connect)], + _UriOAuthService.REDIRECTION_URI[(self.environment, self._oauth_scope)], ) - + return endpoint if self.state is None else endpoint + '&state=' + self.state def extract_access_token_from_uri(self, redirection_uri): @@ -650,7 +657,7 @@ def extract_access_token_from_uri(self, redirection_uri): @property def redirection_uri(self): - return _UriOAuthService.REDIRECTION_URI[(self.environment, self._require_live_connect)] + return _UriOAuthService.REDIRECTION_URI[(self.environment, self._oauth_scope)] class _UriOAuthService: @@ -659,21 +666,33 @@ class _UriOAuthService: def __init__(self): pass - REDIRECTION_URI={(PRODUCTION, True):'https://login.live.com/oauth20_desktop.srf', - (PRODUCTION, False):'https://login.microsoftonline.com/common/oauth2/nativeclient', - (SANDBOX, False):'https://login.live-int.com/oauth20_desktop.srf' + REDIRECTION_URI={ + (PRODUCTION, MSADS_MANAGE): 'https://login.microsoftonline.com/common/oauth2/nativeclient', + (PRODUCTION, ADS_MANAGE): 'https://login.microsoftonline.com/common/oauth2/nativeclient', + (PRODUCTION, BINGADS_MANAGE): 'https://login.live.com/oauth20_desktop.srf', + (SANDBOX, MSADS_MANAGE): 'https://login.windows-ppe.net/common/oauth2/nativeclient', + (SANDBOX, MSA_PROD): 'https://login.microsoftonline.com/common/oauth2/nativeclient' } - AUTH_TOKEN_URI={(PRODUCTION, True):'https://login.live.com/oauth20_token.srf', - (PRODUCTION, False):'https://login.microsoftonline.com/common/oauth2/v2.0/token', - (SANDBOX, False):'https://login.live-int.com/oauth20_token.srf' + AUTH_TOKEN_URI={ + (PRODUCTION, MSADS_MANAGE): 'https://login.microsoftonline.com/common/oauth2/v2.0/token', + (PRODUCTION, ADS_MANAGE): 'https://login.microsoftonline.com/common/oauth2/v2.0/token', + (PRODUCTION, BINGADS_MANAGE): 'https://login.live.com/oauth20_token.srf', + (SANDBOX, MSADS_MANAGE): 'https://login.windows-ppe.net/consumers/oauth2/v2.0/token', + (SANDBOX, MSA_PROD): 'https://login.microsoftonline.com/common/oauth2/v2.0/token' } - AUTHORIZE_URI={(PRODUCTION, True):'https://login.live.com/oauth20_authorize.srf?client_id={0}&scope=bingads.manage&response_type={1}&redirect_uri={2}', - (PRODUCTION, False):'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={0}&scope=https%3A%2F%2Fads.microsoft.com%2Fads.manage%20offline_access&response_type={1}&redirect_uri={2}', - (SANDBOX, False):'https://login.live-int.com/oauth20_authorize.srf?client_id={0}&scope=bingads.manage&response_type={1}&redirect_uri={2}&prompt=login' + AUTHORIZE_URI={ + (PRODUCTION, MSADS_MANAGE): 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={0}&scope=https%3A%2F%2Fads.microsoft.com%2Fmsads.manage%20offline_access&response_type={1}&redirect_uri={2}', + (PRODUCTION, ADS_MANAGE): 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={0}&scope=https%3A%2F%2Fads.microsoft.com%2Fads.manage%20offline_access&response_type={1}&redirect_uri={2}', + (PRODUCTION, BINGADS_MANAGE): 'https://login.live.com/oauth20_authorize.srf?client_id={0}&scope=bingads.manage&response_type={1}&redirect_uri={2}', + (SANDBOX, MSADS_MANAGE): 'https://login.windows-ppe.net/consumers/oauth2/v2.0/authorize?client_id={0}&scope=https://api.ads.microsoft.com/msads.manage%20offline_access&response_type={1}&redirect_uri={2}&prompt=login', + (SANDBOX, MSA_PROD): 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={0}&scope=https%3A%2F%2Fsi.ads.microsoft.com%2Fmsads.manage%20offline_access&response_type={1}&redirect_uri={2}' } - SCOPE={(PRODUCTION, True):'bingads.manage', - (PRODUCTION, False):'https://ads.microsoft.com/ads.manage offline_access', - (SANDBOX, False):'bingads.manage' + SCOPE={ + (PRODUCTION, MSADS_MANAGE): 'https://ads.microsoft.com/msads.manage offline_access', + (PRODUCTION, ADS_MANAGE): 'https://ads.microsoft.com/ads.manage offline_access', + (PRODUCTION, BINGADS_MANAGE): 'bingads.manage', + (SANDBOX, MSADS_MANAGE): 'https://api.ads.microsoft.com/msads.manage offline_access', + (SANDBOX, MSA_PROD): 'https://si.ads.microsoft.com/msads.manage offline_access' } @staticmethod @@ -688,12 +707,12 @@ def get_access_token(**kwargs): if 'client_secret' in kwargs and kwargs['client_secret'] is None: del kwargs['client_secret'] - - if 'requireliveconnect' in kwargs and kwargs['requireliveconnect'] == True: + + if 'oauth_scope' in kwargs and kwargs['oauth_scope'] == 'bingads.manage': del kwargs['tenant'] - - auth_token_url = _UriOAuthService.AUTH_TOKEN_URI[(kwargs['environment'], kwargs['requireliveconnect'])] - + + auth_token_url = _UriOAuthService.AUTH_TOKEN_URI[(kwargs['environment'], kwargs['oauth_scope'])] + if 'tenant' in kwargs and kwargs['tenant'] is not None: auth_token_url = auth_token_url.replace('common', kwargs['tenant']) diff --git a/bingads/manifest.py b/bingads/manifest.py index c51394f5..8388f538 100644 --- a/bingads/manifest.py +++ b/bingads/manifest.py @@ -1,5 +1,5 @@ import sys -VERSION = '13.0.8' +VERSION = '13.0.25.3' BULK_FORMAT_VERSION_6 = '6.0' WORKING_NAME = 'BingAdsSDKPython' USER_AGENT = '{0} {1} {2}'.format(WORKING_NAME, VERSION, sys.version_info[0:3]) diff --git a/bingads/service_client.py b/bingads/service_client.py index 7b7292ab..1fe91dc8 100644 --- a/bingads/service_client.py +++ b/bingads/service_client.py @@ -1,13 +1,27 @@ -from suds.client import Client, Factory, WebFault -from suds.cache import ObjectCache +from suds.client import Client, Factory, WebFault, Builder from .headerplugin import HeaderPlugin from .authorization import * from .service_info import SERVICE_INFO_DICT from .manifest import USER_AGENT +from .util import DictCache from getpass import getuser from tempfile import gettempdir from os import path from datetime import datetime +from suds.sudsobject import Factory as SFactory + +class BingAdsBuilder (Builder): + # See https://github.com/suds-community/suds/issues/67 and https://github.com/suds-community/suds/commit/366f7f1616595b9e4163a3f90fc6e84ac0ae23f5 + def __init__(self, resolver): + """ + @param resolver: A schema object name resolver. + @type resolver: L{resolver.Resolver} + """ + self.resolver = resolver + + def skip_value(self, type): + """ whether or not to skip setting the value """ + return False class ServiceClient: @@ -31,11 +45,11 @@ def __init__(self, service, version, authorization_data=None, environment='produ self._authorization_data = authorization_data self._refresh_oauth_tokens_automatically = True self._version = ServiceClient._format_version(version) + - # TODO This is a temp fix for set default suds temp folder with user info, suds development branch has already fixed it. + # Use in-memory cache by default. if 'cache' not in suds_options: - location = path.join(gettempdir(), 'suds', getuser()) - suds_options['cache'] = ObjectCache(location, days=1) + suds_options['cache'] = DictCache() # set cachingpolicy to 1 to reuse WSDL cache files, otherwise will only reuse XML files if 'cachingpolicy' not in suds_options: suds_options['cachingpolicy'] = 1 @@ -47,6 +61,7 @@ def __init__(self, service, version, authorization_data=None, environment='produ self.hp=HeaderPlugin() suds_options['plugins'] = [self.hp] self._soap_client = Client(self.service_url, **suds_options) + self._soap_client.factory.builder = BingAdsBuilder(self._soap_client.factory.builder.resolver) def __getattr__(self, name): # Set authorization data and options before every service call. @@ -94,7 +109,7 @@ def factory(self): """ return self.soap_client.factory - + @property def service_url(self): """ The wsdl url of service based on the specific service and environment. @@ -105,9 +120,8 @@ def service_url(self): key = (self._service, self._environment) service_info_dict = ServiceClient._get_service_info_dict(self._version) if key not in service_info_dict: - raise ValueError(str.format('Cannot find version: [v{0}] service: [{1}] under environment: [{2}].', - self._version, self._input_service, self._input_environment)) - return service_info_dict[(self._service, self._environment)].url + return service_info_dict[(self._service, 'sandbox')] + return service_info_dict[(self._service, self._environment)] @property @@ -200,7 +214,6 @@ def _format_version(version): return 13 raise ValueError(str.format('version error: [{0}] is not supported.', version)) - @staticmethod def _get_service_info_dict(version): """ @@ -296,14 +309,17 @@ def name(self): from suds.sudsobject import Property from suds.sax.text import Text - +# this is used to create entity only. Given the sandbox should have the same contract, we are good to use sandbox wsdl. _CAMPAIGN_MANAGEMENT_SERVICE_V13 = Client( - 'file:///' + pkg_resources.resource_filename('bingads', 'v13/proxies/campaign_management_service.xml')) + 'file:///' + pkg_resources.resource_filename('bingads', 'v13/proxies/sandbox/campaignmanagement_service.xml'), cache=DictCache()) _CAMPAIGN_OBJECT_FACTORY_V13 = _CAMPAIGN_MANAGEMENT_SERVICE_V13.factory +_CAMPAIGN_OBJECT_FACTORY_V13.builder = BingAdsBuilder(_CAMPAIGN_OBJECT_FACTORY_V13.builder.resolver) + _CAMPAIGN_OBJECT_FACTORY_V13.object_cache = {} _CAMPAIGN_OBJECT_FACTORY_V13.create_without_cache = _CAMPAIGN_OBJECT_FACTORY_V13.create + def _suds_objects_deepcopy(origin): if origin is None: return None diff --git a/bingads/service_info.py b/bingads/service_info.py index 63058788..07fdde25 100644 --- a/bingads/service_info.py +++ b/bingads/service_info.py @@ -1,105 +1,11 @@ -class _ServiceInfo: - - @property - def name(self): - return self._name - - @property - def env(self): - return self._env - - @property - def url(self): - return self._url - - @url.setter - def url(self, url): - self._url = url - - - def __init__(self, name, env, url): - self._name = name - self._env = env - self._url = url - -_SERVICE_INFO_LIST_V13 = [ - # ad insight service - _ServiceInfo( - "adinsight", - "production", - "https://adinsight.api.bingads.microsoft.com/Api/Advertiser/AdInsight/V13/AdInsightService.svc?singleWsdl" - ), - _ServiceInfo( - "adinsight", - "sandbox", - "https://adinsight.api.sandbox.bingads.microsoft.com/Api/Advertiser/AdInsight/V13/AdInsightService.svc?singleWsdl" - ), - - # bulk service - _ServiceInfo( - "bulk", - "production", - "https://bulk.api.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/BulkService.svc?singleWsdl" - ), - _ServiceInfo( - "bulk", - "sandbox", - "https://bulk.api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/BulkService.svc?singleWsdl" - ), - - # campaign management - _ServiceInfo( - "campaignmanagement", - "production", - "https://campaign.api.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/CampaignManagementService.svc?singleWsdl" - ), - _ServiceInfo( - "campaignmanagement", - "sandbox", - "https://campaign.api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/CampaignManagementService.svc?singleWsdl" - ), - - # customer billing - _ServiceInfo( - "customerbilling", - "production", - "https://clientcenter.api.bingads.microsoft.com/Api/Billing/v13/CustomerBillingService.svc?singleWsdl" - ), - _ServiceInfo( - "customerbilling", - "sandbox", - "https://clientcenter.api.sandbox.bingads.microsoft.com/Api/Billing/v13/CustomerBillingService.svc?singleWsdl" - ), - - # customer management - _ServiceInfo( - "customermanagement", - "production", - "https://clientcenter.api.bingads.microsoft.com/Api/CustomerManagement/v13/CustomerManagementService.svc?singleWsdl" - ), - _ServiceInfo( - "customermanagement", - "sandbox", - "https://clientcenter.api.sandbox.bingads.microsoft.com/Api/CustomerManagement/v13/CustomerManagementService.svc?singleWsdl" - ), - - # reporting - _ServiceInfo( - "reporting", - "production", - "https://reporting.api.bingads.microsoft.com/Api/Advertiser/Reporting/v13/ReportingService.svc?singleWsdl" - ), - _ServiceInfo( - "reporting", - "sandbox", - "https://reporting.api.sandbox.bingads.microsoft.com/Api/Advertiser/Reporting/v13/ReportingService.svc?singleWsdl" - ), -] +import pkg_resources +_SERVICE_LIST = ['adinsight', 'bulk', 'campaignmanagement', 'customerbilling', 'customermanagement', 'reporting'] SERVICE_INFO_DICT_V13 = {} -for service_info in _SERVICE_INFO_LIST_V13: - SERVICE_INFO_DICT_V13[(service_info.name, service_info.env)] = service_info +for service in _SERVICE_LIST: + SERVICE_INFO_DICT_V13[(service, 'production')] = 'file:///' + pkg_resources.resource_filename('bingads', 'v13/proxies/production/%s_service.xml' % (service)) + SERVICE_INFO_DICT_V13[(service, 'sandbox')] = 'file:///' + pkg_resources.resource_filename('bingads', 'v13/proxies/sandbox/%s_service.xml' % (service)) SERVICE_INFO_DICT = {13: SERVICE_INFO_DICT_V13} diff --git a/bingads/util.py b/bingads/util.py index d03e5233..12ae6f37 100644 --- a/bingads/util.py +++ b/bingads/util.py @@ -1,6 +1,17 @@ import time from bingads.exceptions import TimeoutException from suds.client import WebFault +from suds.cache import Cache + + +class DictCache(dict, Cache): + # .get and .clear work as intended + purge = dict.__delitem__ + + def put(self, id_, obj): + self[id_] = obj + return obj + class _TimeHelper(object): """ diff --git a/bingads/v13/bulk/bulk_operation.py b/bingads/v13/bulk/bulk_operation.py index 66fee5b6..dec25288 100644 --- a/bingads/v13/bulk/bulk_operation.py +++ b/bingads/v13/bulk/bulk_operation.py @@ -4,7 +4,6 @@ import requests import zipfile import os -import six import sys import shutil @@ -94,10 +93,8 @@ def download_result_file(self, result_file_directory, result_file_name, decompre zip_file_path = result_file_path if os.path.exists(result_file_path) and overwrite is False: - if six.PY3: - raise FileExistsError('Result file: {0} exists'.format(result_file_path)) - else: - raise OSError('Result file: {0} exists'.format(result_file_path)) + raise FileExistsError('Result file: {0} exists'.format(result_file_path)) + headers = { 'User-Agent': USER_AGENT, } diff --git a/bingads/v13/bulk/bulk_service_manager.py b/bingads/v13/bulk/bulk_service_manager.py index dd5fce38..1f9b33b4 100644 --- a/bingads/v13/bulk/bulk_service_manager.py +++ b/bingads/v13/bulk/bulk_service_manager.py @@ -13,8 +13,6 @@ from bingads.authorization import * from bingads.util import _TimeHelper from bingads.exceptions import TimeoutException -from six import PY2, PY3 - class BulkServiceManager: SYNC_THRESHOLD = 1000 @@ -186,10 +184,7 @@ def bulkupload_entitie_records(self, entity_upload_parameters, tmp_file, progres records = self.service_client.factory.create("ns2:ArrayOfstring") tmp_csv_file = io.open(tmp_file, encoding='utf-8-sig') - if PY3: - records.string = [x.strip() for x in tmp_csv_file.readlines()] - elif PY2: - records.string = [line.encode('utf-8').strip() for line in tmp_csv_file] + records.string = [x.strip() for x in tmp_csv_file.readlines()] try: #print(self.service_client) diff --git a/bingads/v13/bulk/entities/__init__.py b/bingads/v13/bulk/entities/__init__.py index 8f05fb1e..f019fad5 100644 --- a/bingads/v13/bulk/entities/__init__.py +++ b/bingads/v13/bulk/entities/__init__.py @@ -19,6 +19,8 @@ from .bulk_ad_group_dynamic_search_ad_target import * from .bulk_ad_group_negative_dynamic_search_ad_target import * from .bulk_bid_strategy import * +from .bulk_ad_group_criterion import * +from .bulk_ad_group_hotel_listing_group import * from .ad_extensions import * from .bulk_ads import * @@ -28,6 +30,31 @@ from .target_criterions import * from .labels import * from .bulk_offline_conversion import * +from .bulk_online_conversion_adjustment import * from .bulk_experiment import * from .bulk_image import * +from .bulk_video import * from .feeds import * +from .bulk_campaign_conversion_goal import * +from .bulk_ad_customizer_attribute import * +from .bulk_ad_customizer_attribute_entity_base import * +from .bulk_ad_customizer_attribute_campaign import * +from .bulk_ad_customizer_attribute_ad_group import * +from .bulk_ad_customizer_attribute_keyword import * + +from .bulk_asset_group import * +from .bulk_audience_group import * +from .bulk_asset_group_listing_group import * +from .bulk_asset_group_url_target import * +from .bulk_audience_group_asset_group_association import * +from .bulk_campaign_negative_webpage import * +from .bulk_seasonality_adjustment import * +from .bulk_data_exclusion import * +from .bulk_account_negative_keyword_list import * +from .bulk_asset_group_search_theme import * +from .bulk_campaign_brand_list_association import * +from .bulk_brand_item import * +from .bulk_brand_list import * +from .bulk_new_customer_acquisition_goal import * +from .goals import * +from .account_placement_exclusion_list import * diff --git a/bingads/v13/bulk/entities/account_placement_exclusion_list/__init__.py b/bingads/v13/bulk/entities/account_placement_exclusion_list/__init__.py new file mode 100644 index 00000000..d4d6610f --- /dev/null +++ b/bingads/v13/bulk/entities/account_placement_exclusion_list/__init__.py @@ -0,0 +1,9 @@ +__author__ = 'Bing Ads SDK Team' +__email__ = 'bing_ads_sdk@microsoft.com' + +from .bulk_account_placement_exlucison_list import * +from .bulk_account_placement_exlucison_list_item import * +from .bulk_account_placement_inclusion_list import * +from .bulk_account_placement_inclusion_list_item import * +from .bulk_campaign_account_placement_exclusion_list_association import * +from .bulk_campaign_account_placement_inclusion_list_association import * diff --git a/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_exlucison_list.py b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_exlucison_list.py new file mode 100644 index 00000000..c2515f57 --- /dev/null +++ b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_exlucison_list.py @@ -0,0 +1,88 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkAccountPlacementExclusionList(_SingleRecordBulkEntity): + """ Represents an account placement exclusion list. + + This class exposes the property :attr:`account_placement_exclusion_list` that can be read and written as fields of the account placement exclusion list record + in a bulk file. + + For more information, see account placement exclusion list at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, status=None, account_placement_exclusion_list=None): + super(BulkAccountPlacementExclusionList, self).__init__() + + self._status = status + self._account_placement_exclusion_list = account_placement_exclusion_list + + + @property + def status(self): + """ The status of the account placement exclusion list. + + Corresponds to the 'Status' field in the bulk file. + + :rtype: str + """ + + return self._status + + @status.setter + def status(self, status): + self._status = status + + @property + def account_placement_exclusion_list(self): + """ The AccountPlacementExclusionList Data Object of the Campaign Management Service. + + A subset of AccountPlacementExclusionList properties are available in the Ad Group record. + For more information, see Ad Group at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._account_placement_exclusion_list + + @account_placement_exclusion_list.setter + def account_placement_exclusion_list(self, account_placement_exclusion_list): + self._account_placement_exclusion_list = account_placement_exclusion_list + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.account_placement_exclusion_list.Id), + csv_to_field=lambda c, v: setattr(c.account_placement_exclusion_list, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.status), + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Name, + field_to_csv=lambda c: bulk_str(c.account_placement_exclusion_list.Name), + csv_to_field=lambda c, v: setattr(c.account_placement_exclusion_list, 'Name', v) + ), + ] + + + def process_mappings_from_row_values(self, row_values): + self.account_placement_exclusion_list = _CAMPAIGN_OBJECT_FACTORY_V13.create('AccountPlacementExclusionList') + + row_values.convert_to_entity(self, BulkAccountPlacementExclusionList._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._account_placement_exclusion_list, 'AccountPlacementExclusionList') + self.convert_to_values(row_values, BulkAccountPlacementExclusionList._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAccountPlacementExclusionList, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_exlucison_list_item.py b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_exlucison_list_item.py new file mode 100644 index 00000000..32764df9 --- /dev/null +++ b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_exlucison_list_item.py @@ -0,0 +1,40 @@ +from bingads.v13.internal.bulk.entities.bulk_shared_negative_site import BulkSharedNegativeSite + + +class BulkAccountPlacementExclusionListItem(BulkSharedNegativeSite): + """ Represents an account placement exclusion list item. + + This class exposes the property :attr:`account_placement_exclusion_list` that can be read and written as fields of the account placement exclusion list item record + in a bulk file. + + For more information, see account placement exclusion list item at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, parent_id=None): + super(BulkAccountPlacementExclusionListItem, self).__init__() + + self._parent_id = parent_id + + + @property + def account_placement_exclusion_list_id(self): + """ The status of the account placement exclusion list id. + + Corresponds to the 'Parent Id' field in the bulk file. + + :rtype: int + """ + + return self._parent_id + + @account_placement_exclusion_list_id.setter + def account_placement_exclusion_list_id(self, account_placement_exclusion_list_id): + self._parent_id = account_placement_exclusion_list_id + diff --git a/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_inclusion_list.py b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_inclusion_list.py new file mode 100644 index 00000000..70326c10 --- /dev/null +++ b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_inclusion_list.py @@ -0,0 +1,88 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkAccountPlacementInclusionList(_SingleRecordBulkEntity): + """ Represents an account placement inclusion list. + + This class exposes the property :attr:`account_placement_inclusion_list` that can be read and written as fields of the account placement inclusion list record + in a bulk file. + + For more information, see account placement inclusion list at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, status=None, account_placement_inclusion_list=None): + super(BulkAccountPlacementInclusionList, self).__init__() + + self._status = status + self._account_placement_inclusion_list = account_placement_inclusion_list + + + @property + def status(self): + """ The status of the account placement inclusion list. + + Corresponds to the 'Status' field in the bulk file. + + :rtype: str + """ + + return self._status + + @status.setter + def status(self, status): + self._status = status + + @property + def account_placement_inclusion_list(self): + """ The AccountPlacementInclusionList Data Object of the Campaign Management Service. + + A subset of AccountPlacementInclusionList properties are available in the Ad Group record. + For more information, see Ad Group at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._account_placement_inclusion_list + + @account_placement_inclusion_list.setter + def account_placement_inclusion_list(self, account_placement_inclusion_list): + self._account_placement_inclusion_list = account_placement_inclusion_list + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.account_placement_inclusion_list.Id), + csv_to_field=lambda c, v: setattr(c.account_placement_inclusion_list, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.status), + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Name, + field_to_csv=lambda c: bulk_str(c.account_placement_inclusion_list.Name), + csv_to_field=lambda c, v: setattr(c.account_placement_inclusion_list, 'Name', v) + ), + ] + + + def process_mappings_from_row_values(self, row_values): + self.account_placement_inclusion_list = _CAMPAIGN_OBJECT_FACTORY_V13.create('AccountPlacementInclusionList') + + row_values.convert_to_entity(self, BulkAccountPlacementInclusionList._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._account_placement_inclusion_list, 'AccountPlacementInclusionList') + self.convert_to_values(row_values, BulkAccountPlacementInclusionList._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAccountPlacementInclusionList, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_inclusion_list_item.py b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_inclusion_list_item.py new file mode 100644 index 00000000..5fd72b27 --- /dev/null +++ b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_account_placement_inclusion_list_item.py @@ -0,0 +1,40 @@ +from bingads.v13.internal.bulk.entities.bulk_shared_site import BulkSharedSite + + +class BulkAccountPlacementInclusionListItem(BulkSharedSite): + """ Represents an account placement inclusion list item. + + This class exposes the property :attr:`account_placement_inclusion_list` that can be read and written as fields of the account placement inclusion list item record + in a bulk file. + + For more information, see account placement inclusion list item at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, parent_id=None): + super(BulkAccountPlacementInclusionListItem, self).__init__() + + self._parent_id = parent_id + + + @property + def account_placement_inclusion_list_id(self): + """ The status of the account placement inclusion list id. + + Corresponds to the 'Parent Id' field in the bulk file. + + :rtype: int + """ + + return self._parent_id + + @account_placement_inclusion_list_id.setter + def account_placement_inclusion_list_id(self, account_placement_inclusion_list_id): + self._parent_id = account_placement_inclusion_list_id + diff --git a/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_campaign_account_placement_exclusion_list_association.py b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_campaign_account_placement_exclusion_list_association.py new file mode 100644 index 00000000..a6c9e119 --- /dev/null +++ b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_campaign_account_placement_exclusion_list_association.py @@ -0,0 +1,88 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkAccountPlacementExclusionListAssociation(_SingleRecordBulkEntity): + """ Represents an account placement exclusion list association. + + This class exposes the property :attr:`shared_entity_association` that can be read and written as fields of the account placement exclusion list association record + in a bulk file. + + For more information, see account placement exclusion list association at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, status=None, shared_entity_association=None): + super(BulkAccountPlacementExclusionListAssociation, self).__init__() + + self._status = status + self._shared_entity_association = shared_entity_association + + + @property + def status(self): + """ The status of the account placement exclusion list association. + + Corresponds to the 'Status' field in the bulk file. + + :rtype: str + """ + + return self._status + + @status.setter + def status(self, status): + self._status = status + + @property + def shared_entity_association(self): + """ The AccountPlacementExclusionList Data Object of the Campaign Management Service. + + A subset of AccountPlacementExclusionList properties are available in the Ad Group record. + For more information, see Ad Group at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._shared_entity_association + + @shared_entity_association.setter + def shared_entity_association(self, shared_entity_association): + self._shared_entity_association = shared_entity_association + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.shared_entity_association.SharedEntityId), + csv_to_field=lambda c, v: setattr(c.shared_entity_association, 'SharedEntityId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.status), + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.shared_entity_association.EntityId), + csv_to_field=lambda c, v: setattr(c.shared_entity_association, 'EntityId', v) + ), + ] + + + def process_mappings_from_row_values(self, row_values): + self.shared_entity_association = _CAMPAIGN_OBJECT_FACTORY_V13.create('AccountPlacementExclusionList') + + row_values.convert_to_entity(self, BulkAccountPlacementExclusionListAssociation._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._shared_entity_association, 'AccountPlacementExclusionList') + self.convert_to_values(row_values, BulkAccountPlacementExclusionListAssociation._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAccountPlacementExclusionListAssociation, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_campaign_account_placement_inclusion_list_association.py b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_campaign_account_placement_inclusion_list_association.py new file mode 100644 index 00000000..6a410fbb --- /dev/null +++ b/bingads/v13/bulk/entities/account_placement_exclusion_list/bulk_campaign_account_placement_inclusion_list_association.py @@ -0,0 +1,88 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkAccountPlacementInclusionListAssociation(_SingleRecordBulkEntity): + """ Represents an account placement inclusion list association. + + This class exposes the property :attr:`shared_entity_association` that can be read and written as fields of the account placement inclusion list association record + in a bulk file. + + For more information, see account placement inclusion list association at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, status=None, shared_entity_association=None): + super(BulkAccountPlacementInclusionListAssociation, self).__init__() + + self._status = status + self._shared_entity_association = shared_entity_association + + + @property + def status(self): + """ The status of the account placement inclusion list association. + + Corresponds to the 'Status' field in the bulk file. + + :rtype: str + """ + + return self._status + + @status.setter + def status(self, status): + self._status = status + + @property + def shared_entity_association(self): + """ The AccountPlacementInclusionList Data Object of the Campaign Management Service. + + A subset of AccountPlacementInclusionList properties are available in the Ad Group record. + For more information, see Ad Group at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._shared_entity_association + + @shared_entity_association.setter + def shared_entity_association(self, shared_entity_association): + self._shared_entity_association = shared_entity_association + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.shared_entity_association.SharedEntityId), + csv_to_field=lambda c, v: setattr(c.shared_entity_association, 'SharedEntityId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.status), + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.shared_entity_association.EntityId), + csv_to_field=lambda c, v: setattr(c.shared_entity_association, 'EntityId', v) + ), + ] + + + def process_mappings_from_row_values(self, row_values): + self.shared_entity_association = _CAMPAIGN_OBJECT_FACTORY_V13.create('AccountPlacementInclusionList') + + row_values.convert_to_entity(self, BulkAccountPlacementInclusionListAssociation._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._shared_entity_association, 'AccountPlacementInclusionList') + self.convert_to_values(row_values, BulkAccountPlacementInclusionListAssociation._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAccountPlacementInclusionListAssociation, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/ad_extensions/__init__.py b/bingads/v13/bulk/entities/ad_extensions/__init__.py index a296f4ca..130d764a 100644 --- a/bingads/v13/bulk/entities/ad_extensions/__init__.py +++ b/bingads/v13/bulk/entities/ad_extensions/__init__.py @@ -12,4 +12,6 @@ from .bulk_action_ad_extensions import * from .bulk_promotion_ad_extensions import * from .bulk_filterlink_ad_extensions import * -from .bulk_flyer_ad_extensions import * \ No newline at end of file +from .bulk_flyer_ad_extensions import * +from .bulk_video_ad_extensions import * +from .bulk_disclaimer_ad_extensions import * \ No newline at end of file diff --git a/bingads/v13/bulk/entities/ad_extensions/bulk_disclaimer_ad_extensions.py b/bingads/v13/bulk/entities/ad_extensions/bulk_disclaimer_ad_extensions.py new file mode 100644 index 00000000..64001885 --- /dev/null +++ b/bingads/v13/bulk/entities/ad_extensions/bulk_disclaimer_ad_extensions.py @@ -0,0 +1,136 @@ +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from .common import _BulkAdExtensionBase +from .common import _BulkAdGroupAdExtensionAssociation +from .common import _BulkCampaignAdExtensionAssociation +from .common import _BulkAccountAdExtensionAssociation + +from bingads.v13.internal.extensions import * + + +_DisclaimerAdExtension = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('DisclaimerAdExtension')) + + +class BulkDisclaimerAdExtension(_BulkAdExtensionBase): + """ Represents a disclaimer ad extension. + + This class exposes the :attr:`disclaimer_ad_extension` property that can be read and written + as fields of the Disclaimer Ad Extension record in a bulk file. + + For more information, see Disclaimer 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, _DisclaimerAdExtension): + raise ValueError('The type of ad_extension is: {0}, should be: {1}'.format( + type(ad_extension), + 'DisclaimerAdExtension' + )) + super(BulkDisclaimerAdExtension, self).__init__( + account_id=account_id, + ad_extension=ad_extension + ) + + @property + def disclaimer_ad_extension(self): + """ The disclaimer ad extension. + + see Disclaimer Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127. + """ + + return self._ad_extension + + @disclaimer_ad_extension.setter + def disclaimer_ad_extension(self, value): + self._ad_extension = value + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.DisclaimerName, + field_to_csv=lambda c: bulk_str(c.disclaimer_ad_extension.Name), + csv_to_field=lambda c, v: setattr(c.disclaimer_ad_extension, 'Name', v) + ), + _SimpleBulkMapping( + header=_StringTable.DisclaimerTitle, + field_to_csv=lambda c: bulk_str(c.disclaimer_ad_extension.Title), + csv_to_field=lambda c, v: setattr(c.disclaimer_ad_extension, 'Title', v) + ), + _SimpleBulkMapping( + header=_StringTable.DisclaimerPopupText, + field_to_csv=lambda c: bulk_str(c.disclaimer_ad_extension.PopupText), + csv_to_field=lambda c, v: setattr(c.disclaimer_ad_extension, 'PopupText', v) + ), + _SimpleBulkMapping( + header=_StringTable.DisclaimerLineText, + field_to_csv=lambda c: bulk_str(c.disclaimer_ad_extension.LineText), + csv_to_field=lambda c, v: setattr(c.disclaimer_ad_extension, 'LineText', v) + ), + _SimpleBulkMapping( + header=_StringTable.DisclaimerLayout, + field_to_csv=lambda c: bulk_str(c.disclaimer_ad_extension.DisclaimerLayout), + csv_to_field=lambda c, v: setattr(c.disclaimer_ad_extension, 'DisclaimerLayout', v) + ), + _SimpleBulkMapping( + header=_StringTable.FinalUrl, + field_to_csv=lambda c: field_to_csv_Urls(c.disclaimer_ad_extension.FinalUrls, c.disclaimer_ad_extension.Id), + csv_to_field=lambda c, v: csv_to_field_Urls(c.disclaimer_ad_extension.FinalUrls, v) + ), + _SimpleBulkMapping( + header=_StringTable.FinalMobileUrl, + field_to_csv=lambda c: field_to_csv_Urls(c.disclaimer_ad_extension.FinalMobileUrls, c.disclaimer_ad_extension.Id), + csv_to_field=lambda c, v: csv_to_field_Urls(c.disclaimer_ad_extension.FinalMobileUrls, v) + ), + _SimpleBulkMapping( + header=_StringTable.TrackingTemplate, + field_to_csv=lambda c: bulk_optional_str(c.disclaimer_ad_extension.TrackingUrlTemplate, c.disclaimer_ad_extension.Id), + csv_to_field=lambda c, v: setattr(c.disclaimer_ad_extension, 'TrackingUrlTemplate', v if v else '') + ), + _SimpleBulkMapping( + header=_StringTable.CustomParameter, + field_to_csv=lambda c: field_to_csv_UrlCustomParameters(c.disclaimer_ad_extension), + csv_to_field=lambda c, v: csv_to_field_UrlCustomParameters(c.disclaimer_ad_extension, v) + ), + _SimpleBulkMapping( + header=_StringTable.FinalUrlSuffix, + field_to_csv=lambda c: bulk_optional_str(c.disclaimer_ad_extension.FinalUrlSuffix, c.disclaimer_ad_extension.Id), + csv_to_field=lambda c, v: setattr(c.disclaimer_ad_extension, 'FinalUrlSuffix', v) + ) + ] + + def process_mappings_from_row_values(self, row_values): + self.disclaimer_ad_extension = _CAMPAIGN_OBJECT_FACTORY_V13.create('DisclaimerAdExtension') + self.disclaimer_ad_extension.Type = 'DisclaimerAdExtension' + super(BulkDisclaimerAdExtension, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkDisclaimerAdExtension._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.disclaimer_ad_extension, 'disclaimer_ad_extension') + super(BulkDisclaimerAdExtension, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkDisclaimerAdExtension._MAPPINGS) + +class BulkCampaignDisclaimerAdExtension(_BulkCampaignAdExtensionAssociation): + """ Represents a campaign level disclaimer ad extension. + + This class exposes properties that can be read and written + as fields of the Campaign Disclaimer Ad Extension record in a bulk file. + + For more information, see Campaign Disclaimer 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/v13/bulk/entities/ad_extensions/bulk_image_ad_extensions.py b/bingads/v13/bulk/entities/ad_extensions/bulk_image_ad_extensions.py index 9b06980e..3d274aa8 100644 --- a/bingads/v13/bulk/entities/ad_extensions/bulk_image_ad_extensions.py +++ b/bingads/v13/bulk/entities/ad_extensions/bulk_image_ad_extensions.py @@ -74,7 +74,7 @@ def image_ad_extension(self, value): ), _SimpleBulkMapping( header=_StringTable.TrackingTemplate, - field_to_csv=lambda c: bulk_str(c.image_ad_extension.TrackingUrlTemplate), + field_to_csv=lambda c: bulk_optional_str(c.image_ad_extension.TrackingUrlTemplate, c.image_ad_extension.Id), csv_to_field=lambda c, v: setattr(c.image_ad_extension, 'TrackingUrlTemplate', v if v else None) ), _SimpleBulkMapping( diff --git a/bingads/v13/bulk/entities/ad_extensions/bulk_location_ad_extensions.py b/bingads/v13/bulk/entities/ad_extensions/bulk_location_ad_extensions.py index b4134621..897e951e 100644 --- a/bingads/v13/bulk/entities/ad_extensions/bulk_location_ad_extensions.py +++ b/bingads/v13/bulk/entities/ad_extensions/bulk_location_ad_extensions.py @@ -64,7 +64,7 @@ def location_ad_extension(self, value): _SimpleBulkMapping( header=_StringTable.GeoCodeStatus, field_to_csv=lambda c: bulk_str(c.location_ad_extension.GeoCodeStatus), - csv_to_field=lambda c, v: setattr(c.location_ad_extension, 'GeoCodeStatus', v if v else None) + csv_to_field=lambda c, v: csv_to_field_enum(c.location_ad_extension, v, 'GeoCodeStatus', BusinessGeoCodeStatus) ), _SimpleBulkMapping( header=_StringTable.AddressLine1, diff --git a/bingads/v13/bulk/entities/ad_extensions/bulk_video_ad_extensions.py b/bingads/v13/bulk/entities/ad_extensions/bulk_video_ad_extensions.py new file mode 100644 index 00000000..a0dfa3e9 --- /dev/null +++ b/bingads/v13/bulk/entities/ad_extensions/bulk_video_ad_extensions.py @@ -0,0 +1,182 @@ +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.extensions import * +from .common import _BulkAdExtensionBase +from .common import _BulkCampaignAdExtensionAssociation +from .common import _BulkAdGroupAdExtensionAssociation +from .common import _BulkAccountAdExtensionAssociation + +_VideoAdExtension = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('VideoAdExtension')) + + +class BulkVideoAdExtension(_BulkAdExtensionBase): + """ Represents a video ad extension. + + This class exposes the :attr:`video_ad_extension` property that can be read and written + as fields of the Video Ad Extension record in a bulk file. + + For more information, see Video 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, _VideoAdExtension): + raise ValueError('The type of ad_extension is: {0}, should be: {1}'.format( + type(ad_extension), + 'VideoAdExtension' + )) + super(BulkVideoAdExtension, self).__init__( + account_id=account_id, + ad_extension=ad_extension + ) + + @property + def video_ad_extension(self): + """ The video ad extension. + + see Video Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127. + """ + + return self._ad_extension + + @video_ad_extension.setter + def video_ad_extension(self, value): + self._ad_extension = value + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Name, + field_to_csv=lambda c: bulk_optional_str(c.video_ad_extension.Name, c.video_ad_extension.Id), + csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'Name', v if v else '') + ), + _SimpleBulkMapping( + header=_StringTable.DisplayText, + field_to_csv=lambda c: bulk_optional_str(c.video_ad_extension.DisplayText, c.video_ad_extension.Id), + csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'DisplayText', v if v else '') + ), + _SimpleBulkMapping( + header=_StringTable.AltText, + field_to_csv=lambda c: bulk_str(c.video_ad_extension.AlternativeText), + csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'AlternativeText', v) + ), + _SimpleBulkMapping( + header=_StringTable.ActionText, + field_to_csv=lambda c: bulk_optional_str(c.video_ad_extension.ActionText, c.video_ad_extension.Id), + csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'ActionText', v if v else '') + ), + _SimpleBulkMapping( + header=_StringTable.ThumbnailUrl, + field_to_csv=lambda c: bulk_str(c.video_ad_extension.ThumbnailUrl), + csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'ThumbnailUrl', v) + ), + _SimpleBulkMapping( + header=_StringTable.ThumbnailId, + field_to_csv=lambda c: bulk_str(c.video_ad_extension.ThumbnailId), + csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'ThumbnailId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.VideoId, + field_to_csv=lambda c: bulk_str(c.video_ad_extension.VideoId), + csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'VideoId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.FinalUrlSuffix, + field_to_csv=lambda c: bulk_optional_str(c.video_ad_extension.FinalUrlSuffix, c.video_ad_extension.Id), + csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'FinalUrlSuffix', v) + ), + _SimpleBulkMapping( + header=_StringTable.TrackingTemplate, + field_to_csv=lambda c: bulk_str(c.video_ad_extension.TrackingUrlTemplate), + csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'TrackingUrlTemplate', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.CustomParameter, + field_to_csv=lambda c: field_to_csv_UrlCustomParameters(c.video_ad_extension), + csv_to_field=lambda c, v: csv_to_field_UrlCustomParameters(c.video_ad_extension, v) + ), + _SimpleBulkMapping( + header=_StringTable.FinalUrl, + field_to_csv=lambda c: field_to_csv_Urls(c.video_ad_extension.FinalUrls, c.video_ad_extension.Id), + csv_to_field=lambda c, v: csv_to_field_Urls(c.video_ad_extension.FinalUrls, v) + ), + _SimpleBulkMapping( + header=_StringTable.FinalMobileUrl, + field_to_csv=lambda c: field_to_csv_Urls(c.video_ad_extension.FinalMobileUrls, c.video_ad_extension.Id), + csv_to_field=lambda c, v: csv_to_field_Urls(c.video_ad_extension.FinalMobileUrls, v) + ) + ] + + def process_mappings_from_row_values(self, row_values): + self.video_ad_extension = _CAMPAIGN_OBJECT_FACTORY_V13.create('VideoAdExtension') + self.video_ad_extension.Type = 'VideoAdExtension' + super(BulkVideoAdExtension, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkVideoAdExtension._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.video_ad_extension, 'video_ad_extension') + super(BulkVideoAdExtension, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkVideoAdExtension._MAPPINGS) + + +class BulkAccountVideoAdExtension(_BulkAccountAdExtensionAssociation): + """ Represents an account level video ad extension. + + This class exposes properties that can be read and written + as fields of the Account Video Ad Extension record in a bulk file. + + For more information, see Account Video Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + pass + + +class BulkCampaignVideoAdExtension(_BulkCampaignAdExtensionAssociation): + """ Represents a campaign level video ad extension. + + This class exposes properties that can be read and written + as fields of the Campaign Video Ad Extension record in a bulk file. + + For more information, see Campaign Video Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + pass + +class BulkAdGroupVideoAdExtension(_BulkAdGroupAdExtensionAssociation): + """ Represents an ad group level video ad extension. + + This class exposes properties that can be read and written + as fields of the Ad Group Video Ad Extension record in a bulk file. + + For more information, see Ad Group Video 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/v13/bulk/entities/ad_extensions/common.py b/bingads/v13/bulk/entities/ad_extensions/common.py index 3abfc52b..d8a55e0a 100644 --- a/bingads/v13/bulk/entities/ad_extensions/common.py +++ b/bingads/v13/bulk/entities/ad_extensions/common.py @@ -42,7 +42,7 @@ def account_id(self, account_id): _SimpleBulkMapping( header=_StringTable.Status, field_to_csv=lambda c: bulk_str(c._ad_extension.Status), - csv_to_field=lambda c, v: setattr(c._ad_extension, 'Status', v if v else None) + csv_to_field=lambda c, v: csv_to_field_enum(c._ad_extension, v, 'Status', AdExtensionStatus) ), _SimpleBulkMapping( header=_StringTable.Id, diff --git a/bingads/v13/bulk/entities/audiences/__init__.py b/bingads/v13/bulk/entities/audiences/__init__.py index 5f18f653..a4784b0b 100644 --- a/bingads/v13/bulk/entities/audiences/__init__.py +++ b/bingads/v13/bulk/entities/audiences/__init__.py @@ -41,4 +41,9 @@ from .bulk_ad_group_negative_customer_list_association import * from .bulk_campaign_customer_list_association import * from .bulk_campaign_negative_customer_list_association import * -from .bulk_customer_list_item import * \ No newline at end of file +from .bulk_customer_list_item import * +from .bulk_ad_group_impression_based_remarketing_list_association import * +from .bulk_ad_group_negative_impression_based_remarketing_list_association import * +from .bulk_campaign_impression_based_remarketing_list_association import * +from .bulk_campaign_negative_impression_based_remarketing_list_association import * +from .bulk_impression_based_remarketing_list import * diff --git a/bingads/v13/bulk/entities/audiences/bulk_ad_group_impression_based_remarketing_list_association.py b/bingads/v13/bulk/entities/audiences/bulk_ad_group_impression_based_remarketing_list_association.py new file mode 100644 index 00000000..f63f3582 --- /dev/null +++ b/bingads/v13/bulk/entities/audiences/bulk_ad_group_impression_based_remarketing_list_association.py @@ -0,0 +1,14 @@ +from bingads.v13.bulk.entities.audiences.bulk_ad_group_audience_association import BulkAdGroupAudienceAssociation + +class BulkAdGroupImpressionBasedRemarketingListAssociation(BulkAdGroupAudienceAssociation): + """ Represents an Ad Group Impression Based Remarketing List Association that can be read or written in a bulk file. + + For more information, see Ad Group Impression Based Remarketing List Association at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ diff --git a/bingads/v13/bulk/entities/audiences/bulk_ad_group_negative_impression_based_remarketing_list_association.py b/bingads/v13/bulk/entities/audiences/bulk_ad_group_negative_impression_based_remarketing_list_association.py new file mode 100644 index 00000000..179dd160 --- /dev/null +++ b/bingads/v13/bulk/entities/audiences/bulk_ad_group_negative_impression_based_remarketing_list_association.py @@ -0,0 +1,14 @@ +from bingads.v13.bulk.entities.audiences.bulk_ad_group_negative_audience_association import BulkAdGroupNegativeAudienceAssociation + +class BulkAdGroupNegativeImpressionBasedRemarketingListAssociation(BulkAdGroupNegativeAudienceAssociation): + """ Represents an Ad Group Negative Impression Based Remarketing List Association that can be read or written in a bulk file. + + For more information, see Ad Group Negative Impression Based Remarketing List Association at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ diff --git a/bingads/v13/bulk/entities/audiences/bulk_audience.py b/bingads/v13/bulk/entities/audiences/bulk_audience.py index c0d97205..09b8b28d 100644 --- a/bingads/v13/bulk/entities/audiences/bulk_audience.py +++ b/bingads/v13/bulk/entities/audiences/bulk_audience.py @@ -63,7 +63,7 @@ def __init__(self, _SimpleBulkMapping( header=_StringTable.Scope, field_to_csv=lambda c: bulk_str(c.audience.Scope), - csv_to_field=lambda c, v: setattr(c.audience, 'Scope', v if v else None) + csv_to_field=lambda c, v: csv_to_field_enum(c.audience, v, 'Scope', EntityScope) ), _SimpleBulkMapping( _StringTable.AudienceSearchSize, diff --git a/bingads/v13/bulk/entities/audiences/bulk_campaign_impression_based_remarketing_list_association.py b/bingads/v13/bulk/entities/audiences/bulk_campaign_impression_based_remarketing_list_association.py new file mode 100644 index 00000000..0d7796b2 --- /dev/null +++ b/bingads/v13/bulk/entities/audiences/bulk_campaign_impression_based_remarketing_list_association.py @@ -0,0 +1,14 @@ +from bingads.v13.bulk.entities.audiences.bulk_campaign_audience_association import BulkCampaignAudienceAssociation + +class BulkCampaignImpressionBasedRemarketingListAssociation(BulkCampaignAudienceAssociation): + """ Represents a Campaign Impression Based Remarketing List Association that can be read or written in a bulk file. + + For more information, see Campaign Impression Based Remarketing List Association at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ diff --git a/bingads/v13/bulk/entities/audiences/bulk_campaign_negative_audience_association.py b/bingads/v13/bulk/entities/audiences/bulk_campaign_negative_audience_association.py index d90eef25..fa4b7d7e 100644 --- a/bingads/v13/bulk/entities/audiences/bulk_campaign_negative_audience_association.py +++ b/bingads/v13/bulk/entities/audiences/bulk_campaign_negative_audience_association.py @@ -4,7 +4,6 @@ from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping from bingads.v13.internal.bulk.string_table import _StringTable from bingads.v13.internal.extensions import * -from docutils.nodes import row class BulkCampaignNegativeAudienceAssociation(BulkCampaignNegativeCriterion): diff --git a/bingads/v13/bulk/entities/audiences/bulk_campaign_negative_impression_based_remarketing_list_association.py b/bingads/v13/bulk/entities/audiences/bulk_campaign_negative_impression_based_remarketing_list_association.py new file mode 100644 index 00000000..658a91a6 --- /dev/null +++ b/bingads/v13/bulk/entities/audiences/bulk_campaign_negative_impression_based_remarketing_list_association.py @@ -0,0 +1,14 @@ +from bingads.v13.bulk.entities.audiences.bulk_campaign_negative_audience_association import BulkCampaignNegativeAudienceAssociation + +class BulkCampaignNegativeImpressionBasedRemarketingListAssociation(BulkCampaignNegativeAudienceAssociation): + """ Represents a Campaign Negative Impression Based Remarketing List Association that can be read or written in a bulk file. + + For more information, see Campaign Negative Impression Based Remarketing List Association at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ diff --git a/bingads/v13/bulk/entities/audiences/bulk_customer_list_item.py b/bingads/v13/bulk/entities/audiences/bulk_customer_list_item.py index eb254ded..4f2899cd 100644 --- a/bingads/v13/bulk/entities/audiences/bulk_customer_list_item.py +++ b/bingads/v13/bulk/entities/audiences/bulk_customer_list_item.py @@ -31,6 +31,8 @@ def __init__(self, audience=None, parent_id=None, sub_type=None, text = None): def audience(self): """ the audience, see more detail at: https://go.microsoft.com/fwlink/?linkid=846127 + + :rtype: str """ return self._audience @@ -87,7 +89,7 @@ def text(self, value): _SimpleBulkMapping( header=_StringTable.Audience, field_to_csv=lambda c: bulk_str(c.audience), - csv_to_field=lambda c, v: setattr(c, 'audience', ve) + csv_to_field=lambda c, v: setattr(c, 'audience', v) ), _SimpleBulkMapping( header=_StringTable.SubType, diff --git a/bingads/v13/bulk/entities/audiences/bulk_impression_based_remarketing_list.py b/bingads/v13/bulk/entities/audiences/bulk_impression_based_remarketing_list.py new file mode 100644 index 00000000..f2709c73 --- /dev/null +++ b/bingads/v13/bulk/entities/audiences/bulk_impression_based_remarketing_list.py @@ -0,0 +1,67 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from .bulk_audience import BulkAudience + +class BulkImpressionBasedRemarketingList(BulkAudience): + """ Represents a Impression Based Remarketing List that can be read or written in a bulk file. + + This class exposes the :attr:`impression_based_remarketing_list` property that can be read and written as fields of the + Impression Based Remarketing List record in a bulk file. + + For more information, see Impression Based Remarketing List at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + impression_based_remarketing_list=None, + status=None,): + super(BulkImpressionBasedRemarketingList, self).__init__(audience = impression_based_remarketing_list, status = status) + + _MAPPINGS = [ + _SimpleBulkMapping( + _StringTable.ImpressionCampaignId, + field_to_csv=lambda c: bulk_str(c.impression_based_remarketing_list.CampaignId), + csv_to_field=lambda c, v: setattr(c.impression_based_remarketing_list, 'CampaignId', int(v) if v else None) + ), + _SimpleBulkMapping( + _StringTable.ImpressionAdGroupId, + field_to_csv=lambda c: bulk_str(c.impression_based_remarketing_list.AdGroupId), + csv_to_field=lambda c, v: setattr(c.impression_based_remarketing_list, 'AdGroupId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.EntityType, + field_to_csv=lambda c: bulk_str(c.impression_based_remarketing_list.EntityType), + csv_to_field=lambda c, v: setattr(c.impression_based_remarketing_list, 'EntityType', v) + ), + ] + + @property + def impression_based_remarketing_list(self): + """ Defines a Impression Based Remarketing List """ + + return self._audience + + @impression_based_remarketing_list.setter + def impression_based_remarketing_list(self, impression_based_remarketing_list): + self._audience = impression_based_remarketing_list + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.impression_based_remarketing_list, 'impression_based_remarketing_list') + super(BulkImpressionBasedRemarketingList, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkImpressionBasedRemarketingList._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self.impression_based_remarketing_list = _CAMPAIGN_OBJECT_FACTORY_V13.create('ImpressionBasedRemarketingList') + super(BulkImpressionBasedRemarketingList, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkImpressionBasedRemarketingList._MAPPINGS) + diff --git a/bingads/v13/bulk/entities/audiences/bulk_product_audience.py b/bingads/v13/bulk/entities/audiences/bulk_product_audience.py index 45bd2bbd..8b07b06c 100644 --- a/bingads/v13/bulk/entities/audiences/bulk_product_audience.py +++ b/bingads/v13/bulk/entities/audiences/bulk_product_audience.py @@ -34,7 +34,7 @@ def __init__(self, csv_to_field=lambda c, v: setattr(c.product_audience, 'TagId', int(v) if v else None) ), _SimpleBulkMapping( - _StringTable.Audience, + _StringTable.ProductAudienceType, field_to_csv=lambda c: bulk_str(c.product_audience.ProductAudienceType), csv_to_field=lambda c, v: setattr(c.product_audience, 'ProductAudienceType', v) ), diff --git a/bingads/v13/bulk/entities/bulk_account.py b/bingads/v13/bulk/entities/bulk_account.py index 6f3c99d4..29b67e9f 100644 --- a/bingads/v13/bulk/entities/bulk_account.py +++ b/bingads/v13/bulk/entities/bulk_account.py @@ -28,6 +28,10 @@ def __init__(self, account_id=None, customer_id=None, sync_time=None): self._profile_expansion_enabled = None self._tracking_url_template = None self._final_url_suffix = None + self._ad_click_parallel_tracking=None + self._auto_apply_recommendations = None + self._allow_image_auto_retrieve = None + self._business_attributes = None @property def id(self): @@ -72,46 +76,98 @@ def msclkid_auto_tagging_enabled(self): :return: The msclkid autotag setting of the account :rtype: bool """ - return self._msclkid_auto_tagging_enabled - + return self._msclkid_auto_tagging_enabled + @property def include_view_through_conversions(self): """ :return: The 'Include View Through Conversions' field of the account :rtype: bool """ - return self._include_view_through_conversions - + return self._include_view_through_conversions + @property def profile_expansion_enabled(self): """ :return: The 'Profile Expansion Enabled' field of the account :rtype: bool """ - return self._profile_expansion_enabled - + return self._profile_expansion_enabled + @property def tracking_url_template(self): """ The tracking template to use as a default for all URLs in your account. - + :return: The tracking template of the account :rtype: str """ - return self._tracking_url_template - + return self._tracking_url_template + @property def final_url_suffix(self): """ The final url suffix to use as a default for all URLs in your account. - + :return: The tracking template of the account :rtype: str """ return self._final_url_suffix - + @final_url_suffix.setter def final_url_suffix(self, v): self._final_url_suffix = v + @property + def ad_click_parallel_tracking(self): + """ The setting of parallel tracking in the account. + + :return: The setting of parallel tracking of the account + :rtype: bool + """ + return self._ad_click_parallel_tracking + + @ad_click_parallel_tracking.setter + def ad_click_parallel_tracking(self, v): + self._ad_click_parallel_tracking = v + + @property + def allow_image_auto_retrieve(self): + """ The setting of allowing image auto retrieve in the account. + + :return: The setting of allowing image auto retrieve of the account + :rtype: bool + """ + return self._allow_image_auto_retrieve + + @allow_image_auto_retrieve.setter + def allow_image_auto_retrieve(self, v): + self._allow_image_auto_retrieve = v + + @property + def auto_apply_recommendations(self): + """ The setting of allowing image auto retrieve in the account. + + :return: The setting of allowing image auto retrieve of the account + :rtype: dict + """ + return self._auto_apply_recommendations + + @auto_apply_recommendations.setter + def auto_apply_recommendations(self, v): + self._auto_apply_recommendations = v + + @property + def business_attributes(self): + """ The setting of business attributes in the account. + + :return: The setting of business attributes of the account + :rtype: dict + """ + return self._business_attributes + + @business_attributes.setter + def business_attributes(self, v): + self._business_attributes = v + _MAPPINGS = [ _SimpleBulkMapping( header=_StringTable.Id, @@ -135,7 +191,7 @@ def final_url_suffix(self, v): ), _SimpleBulkMapping( header=_StringTable.TrackingTemplate, - field_to_csv=lambda c: bulk_str(c.tracking_url_template), + field_to_csv=lambda c: bulk_optional_str(c.tracking_url_template, c.id), csv_to_field=lambda c, v: setattr(c, '_tracking_url_template', v) ), _SimpleBulkMapping( @@ -153,6 +209,26 @@ def final_url_suffix(self, v): field_to_csv=lambda c: bulk_str(c.profile_expansion_enabled), csv_to_field=lambda c, v: setattr(c, '_profile_expansion_enabled', parse_bool(v)) ), + _SimpleBulkMapping( + header=_StringTable.AdClickParallelTracking, + field_to_csv=lambda c: bulk_str(c.ad_click_parallel_tracking), + csv_to_field=lambda c, v: setattr(c, 'ad_click_parallel_tracking', parse_bool(v)) + ), + _SimpleBulkMapping( + header=_StringTable.AllowImageAutoRetrieve, + field_to_csv=lambda c: bulk_str(c.allow_image_auto_retrieve), + csv_to_field=lambda c, v: setattr(c, 'allow_image_auto_retrieve', parse_bool(v)) + ), + _SimpleBulkMapping( + header=_StringTable.AutoApplyRecommendations, + field_to_csv=lambda c: dict_bulk_str(c.auto_apply_recommendations, ';'), + csv_to_field=lambda c, v: setattr(c, 'auto_apply_recommendations', parse_dict(v)) + ), + _SimpleBulkMapping( + header=_StringTable.BusinessAttributes, + field_to_csv=lambda c: multi_bulk_str(c.business_attributes, ';'), + csv_to_field=lambda c, v: setattr(c, 'business_attributes', parse_multi(v)) + ) ] def process_mappings_from_row_values(self, row_values): diff --git a/bingads/v13/bulk/entities/bulk_account_negative_keyword_list.py b/bingads/v13/bulk/entities/bulk_account_negative_keyword_list.py new file mode 100644 index 00000000..f786f8c5 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_account_negative_keyword_list.py @@ -0,0 +1,164 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import bulk_str + +class BulkAccountNegativeKeywordList(_SingleRecordBulkEntity): + """ Represents an account negative keyword list association that can be read or written in a bulk file. + + This class exposes the :attr:`.BulkAccountNegativeKeywordList.account_negative_keyword_list` property that can be read and + written as fields of the account negative keyword list association record in a bulk file. + + For more information, see account negative keyword list association at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, status=None, account_negative_keyword_list=None): + super(BulkAccountNegativeKeywordList, self).__init__() + + self._status = status + self._account_negative_keyword_list = account_negative_keyword_list + + @property + def account_negative_keyword_list(self): + """ The account negative keyword list association. + + see account negative keyword list association at https://go.microsoft.com/fwlink/?linkid=846127. + """ + + return self._account_negative_keyword_list + + @account_negative_keyword_list.setter + def account_negative_keyword_list(self, account_negative_keyword_list): + self._account_negative_keyword_list = account_negative_keyword_list + + @property + def status(self): + """ The status of the account negative keyword list association. + + :rtype: str + """ + + return self._status + + @status.setter + def status(self, status): + self._status = status + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.account_negative_keyword_list.Id), + csv_to_field=lambda c, v: setattr(c.account_negative_keyword_list, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.status), + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Name, + field_to_csv=lambda c: c.account_negative_keyword_list.Name, + csv_to_field=lambda c, v: setattr(c.account_negative_keyword_list, 'Name', v) + ) + ] + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._account_negative_keyword_list, 'account_negative_keyword_list') + self.convert_to_values(row_values, BulkAccountNegativeKeywordList._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self._account_negative_keyword_list = _CAMPAIGN_OBJECT_FACTORY_V13.create('AccountNegativeKeywordList') + self._account_negative_keyword_list.Type = 'AccountNegativeKeywordList' + row_values.convert_to_entity(self, BulkAccountNegativeKeywordList._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAccountNegativeKeywordList, self).read_additional_data(stream_reader) + +class BulkAccountNegativeKeywordListAssociation(_SingleRecordBulkEntity): + """ Represents an account negative keyword list association that is assigned to a campaign. Each account negative keyword list association can be read or written in a bulk file. + + This class exposes the :attr:`BulkAccountNegativeKeywordListAssociation.SharedEntityAssociation` property that can be read + and written as fields of the account negative keyword list association record in a bulk file. + + For more information, see account negative keyword list association at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, status=None, shared_entity_association=None): + super(BulkAccountNegativeKeywordListAssociation, self).__init__() + + self._shared_entity_association = shared_entity_association + self._status = status + + @property + def status(self): + """ The status of the account negative keyword list association. + + :rtype: str + """ + + return self._status + + @status.setter + def status(self, status): + self._status = status + + @property + def shared_entity_association(self): + """ The campaign and account negative keyword list association identifiers. + + see Campaign account negative keyword list association at https://go.microsoft.com/fwlink/?linkid=846127. + """ + + return self._shared_entity_association + + @shared_entity_association.setter + def shared_entity_association(self, shared_entity_association): + self._shared_entity_association = shared_entity_association + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: c.status, + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.shared_entity_association.SharedEntityId), + csv_to_field=lambda c, v: setattr(c.shared_entity_association, 'SharedEntityId', int(v)) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.shared_entity_association.EntityId), + csv_to_field=lambda c, v: setattr(c.shared_entity_association, 'EntityId', int(v)) + ), + ] + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._shared_entity_association, 'shared_entity_association') + self.convert_to_values(row_values, BulkAccountNegativeKeywordListAssociation._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self._shared_entity_association = _CAMPAIGN_OBJECT_FACTORY_V13.create('SharedEntityAssociation') + self._shared_entity_association.EntityType = 'Account' + self._shared_entity_association.SharedEntityType = 'NegativeKeywordList' + row_values.convert_to_entity(self, BulkAccountNegativeKeywordListAssociation._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAccountNegativeKeywordListAssociation, self).read_additional_data(stream_reader) + + diff --git a/bingads/v13/bulk/entities/bulk_ad_customizer_attribute.py b/bingads/v13/bulk/entities/bulk_ad_customizer_attribute.py new file mode 100644 index 00000000..99ec2199 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_ad_customizer_attribute.py @@ -0,0 +1,150 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + + +class BulkAdCustomizerAttribute(_SingleRecordBulkEntity): + """ Represents an AdCustomizerAttribute. + + Properties of this class and of classes that it is derived from, correspond to fields of the AdCustomizerAttribute record in a bulk file. + For more information, see AdCustomizerAttribute at https://go.microsoft.com/fwlink/?linkid=846127 + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, id = None, name=None, account_value=None, data_type=None, editorial_status = None, status=None): + super(BulkAdCustomizerAttribute, self).__init__() + self._id = id + self._name = name + self._account_value = account_value + self._data_type = data_type + self._editorial_status = editorial_status + self._status = status + + + @property + def id(self): + """ the id of bulk record + Corresponds to the 'Id' field in the bulk file. + + :rtype: str + """ + return self._id + + @id.setter + def id(self, value): + self._id = value + + @property + def name(self): + """ the name of the ad customizer attribute + Corresponds to the 'Name' field in the bulk file. + + :rtype: str + """ + return self._name + + @name.setter + def name(self, value): + self._name = value + + @property + def account_value(self): + """ the value of the account of ad customizer attribute + Corresponds to the 'AdCustomizer AttributeValue' field in the bulk file. + + :rtype: str + """ + return self._account_value + + @account_value.setter + def account_value(self, value): + self._account_value = value + + @property + def data_type(self): + """ the data type of ad customizer attribute + Corresponds to the 'AdCustomizer DataType' field in the bulk file. + + :rtype: str + """ + return self._data_type + + @data_type.setter + def data_type(self, value): + self._data_type = value + + @property + def editorial_status(self): + """ the editorial status of ad customizer attribute + Corresponds to the 'Editorial Status' field in the bulk file. + + :rtype: str + """ + return self._editorial_status + + @editorial_status.setter + def editorial_status(self, value): + self._editorial_status = value + + @property + def status(self): + """ the status of ad customizer attribute + Corresponds to the 'Status' field in the bulk file. + + :rtype: str + """ + return self._status + + @status.setter + def status(self, value): + self._status = value + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.id), + csv_to_field=lambda c, v: setattr(c, 'id', v) + ), + _SimpleBulkMapping( + header=_StringTable.Name, + field_to_csv=lambda c: bulk_str(c.name), + csv_to_field=lambda c, v: setattr(c, 'name', v) + ), + _SimpleBulkMapping( + header=_StringTable.AdCustomizerAttributeValue, + field_to_csv=lambda c: bulk_str(c.account_value), + csv_to_field=lambda c, v: setattr(c, 'account_value', v) + ), + _SimpleBulkMapping( + header=_StringTable.AdCustomizerDataType, + field_to_csv=lambda c: bulk_str(c.data_type), + csv_to_field=lambda c, v: setattr(c, 'data_type', v) + ), + _SimpleBulkMapping( + header=_StringTable.EditorialStatus, + field_to_csv=lambda c: bulk_str(c.editorial_status), + csv_to_field=lambda c, v: setattr(c, 'editorial_status', v) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: c.status, + csv_to_field=lambda c, v: setattr(c, 'status', v) + ), + ] + + def process_mappings_from_row_values(self, row_values): + row_values.convert_to_entity(self, BulkAdCustomizerAttribute._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self.convert_to_values(row_values, BulkAdCustomizerAttribute._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAdCustomizerAttribute, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_ad_group.py b/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_ad_group.py new file mode 100644 index 00000000..f56ddd13 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_ad_group.py @@ -0,0 +1,36 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +from. import BulkAdCustomizerAttributeEntityBase + +class BulkAdGroupAdCustomizerAttribute(BulkAdCustomizerAttributeEntityBase): + """ Represents an AdGroupAdCustomizerAttribute. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, id = None, name=None, parent_id=None, attribute_value=None, editorial_status = None): + super(BulkAdGroupAdCustomizerAttribute, self).__init__(id, name, parent_id, attribute_value, editorial_status) + + + @property + def ad_group_id(self): + """ the ad group id of bulk record + Corresponds to the 'ParentId' field in the bulk file. + + :rtype: str + """ + return self._parent_id + + @ad_group_id.setter + def ad_group_id(self, value): + self._parent_id = value + diff --git a/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_campaign.py b/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_campaign.py new file mode 100644 index 00000000..cc3e2e1b --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_campaign.py @@ -0,0 +1,37 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +from. import BulkAdCustomizerAttributeEntityBase + + +class BulkCampaignAdCustomizerAttribute(BulkAdCustomizerAttributeEntityBase): + """ Represents a CampaignAdCustomizerAttribute. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, id = None, name=None, parent_id=None, attribute_value=None, editorial_status = None): + super(BulkCampaignAdCustomizerAttribute, self).__init__(id, name, parent_id, attribute_value, editorial_status) + + + @property + def campaign_id(self): + """ the campaign id of bulk record + Corresponds to the 'ParentId' field in the bulk file. + + :rtype: str + """ + return self._parent_id + + @campaign_id.setter + def campaign_id(self, value): + self._parent_id = value + diff --git a/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_entity_base.py b/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_entity_base.py new file mode 100644 index 00000000..dd8b3f81 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_entity_base.py @@ -0,0 +1,128 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + + +class BulkAdCustomizerAttributeEntityBase(_SingleRecordBulkEntity): + """ Represents an AdCustomizerAttributeEntity. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, id = None, name=None, parent_id=None, attribute_value=None, editorial_status = None): + super(BulkAdCustomizerAttributeEntityBase, self).__init__() + self._id = id + self._name = name + self._attribute_value = attribute_value + self._parent_id = parent_id + self._editorial_status = editorial_status + + + @property + def id(self): + """ the id of bulk record + Corresponds to the 'Id' field in the bulk file. + + :rtype: str + """ + return self._id + + @id.setter + def id(self, value): + self._id = value + + @property + def name(self): + """ the name of the ad customizer attribute entity + Corresponds to the 'Name' field in the bulk file. + + :rtype: str + """ + return self._name + + @name.setter + def name(self, value): + self._name = value + + @property + def attribute_value(self): + """ the value of ad customizer attribute + Corresponds to the 'AdCustomizer AttributeValue' field in the bulk file. + + :rtype: str + """ + return self._attribute_value + + @attribute_value.setter + def attribute_value(self, value): + self._attribute_value = value + + @property + def parent_id(self): + """ the parent id of bulk record + Corresponds to the 'ParentId' field in the bulk file. + + :rtype: long + """ + return self._parent_id + + @parent_id.setter + def parent_id(self, value): + self._parent_id = value + + @property + def editorial_status(self): + """ the editorial status of ad customizer attribute + Corresponds to the 'Editorial Status' field in the bulk file. + + :rtype: str + """ + return self._editorial_status + + @editorial_status.setter + def editorial_status(self, value): + self._editorial_status = value + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.id), + csv_to_field=lambda c, v: setattr(c, 'id', v) + ), + _SimpleBulkMapping( + header=_StringTable.Name, + field_to_csv=lambda c: bulk_str(c.name), + csv_to_field=lambda c, v: setattr(c, 'name', v) + ), + _SimpleBulkMapping( + header=_StringTable.AdCustomizerAttributeValue, + field_to_csv=lambda c: bulk_str(c.attribute_value), + csv_to_field=lambda c, v: setattr(c, 'attribute_value', v) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.parent_id), + csv_to_field=lambda c, v: setattr(c, 'parent_id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.EditorialStatus, + field_to_csv=lambda c: bulk_str(c.editorial_status), + csv_to_field=lambda c, v: setattr(c, 'editorial_status', v) + ), + ] + + def process_mappings_from_row_values(self, row_values): + row_values.convert_to_entity(self, BulkAdCustomizerAttributeEntityBase._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self.convert_to_values(row_values, BulkAdCustomizerAttributeEntityBase._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAdCustomizerAttributeEntityBase, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_keyword.py b/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_keyword.py new file mode 100644 index 00000000..003974c2 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_ad_customizer_attribute_keyword.py @@ -0,0 +1,36 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +from. import BulkAdCustomizerAttributeEntityBase + +class BulkKeywordAdCustomizerAttribute(BulkAdCustomizerAttributeEntityBase): + """ Represents a KeywordAdCustomizerAttribute. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, id = None, name=None, parent_id=None, attribute_value=None, editorial_status = None): + super(BulkKeywordAdCustomizerAttribute, self).__init__(id, name, parent_id, attribute_value, editorial_status) + + + @property + def keyword_id(self): + """ the keyword id of bulk record + Corresponds to the 'ParentId' field in the bulk file. + + :rtype: str + """ + return self._parent_id + + @keyword_id.setter + def keyword_id(self, value): + self._parent_id = value + diff --git a/bingads/v13/bulk/entities/bulk_ad_group.py b/bingads/v13/bulk/entities/bulk_ad_group.py index 04e56dc2..ab4c1aa6 100644 --- a/bingads/v13/bulk/entities/bulk_ad_group.py +++ b/bingads/v13/bulk/entities/bulk_ad_group.py @@ -14,7 +14,7 @@ def coop_setting_to_csv(bulk_ad_group, row_values): return if len(settings) != 1: raise ValueError('Can only have 1 CoOpSetting in AdGroup Settings.') - + row_values[_StringTable.MaximumBid] = settings[0].BidMaxValue row_values[_StringTable.BidBoostValue] = settings[0].BidBoostValue row_values[_StringTable.BidOption] = settings[0].BidOption @@ -24,11 +24,11 @@ def csv_to_coop_setting(row_values, bulk_ad_group): maximum_bid_success, maximum_bid = row_values.try_get_value(_StringTable.MaximumBid) bid_boost_value_success, bid_boost_value = row_values.try_get_value(_StringTable.BidBoostValue) bid_option_success, bid_option = row_values.try_get_value(_StringTable.BidOption) - + if maximum_bid_success or bid_boost_value_success or bid_option_success: coop_setting = _CAMPAIGN_OBJECT_FACTORY_V13.create('CoOpSetting') coop_setting.Type = 'CoOpSetting' - coop_setting.BidOption = bid_option if bid_option else None + coop_setting.BidOption = parse_bid_option(bid_option) coop_setting.BidBoostValue = float(bid_boost_value) if bid_boost_value else None coop_setting.BidMaxValue = float(maximum_bid) if maximum_bid else None bulk_ad_group.ad_group.Settings.Setting.append(coop_setting) @@ -55,7 +55,7 @@ def csv_to_bidding_scheme(row_values, bulk_ad_group): if success and inherited_bid_strategy_type != '': bulk_ad_group.ad_group.BiddingScheme.InheritedBidStrategyType = inherited_bid_strategy_type elif hasattr(bulk_ad_group.ad_group.BiddingScheme, 'InheritedBidStrategyType'): - del bulk_ad_group.ad_group.BiddingScheme.InheritedBidStrategyType + bulk_ad_group.ad_group.BiddingScheme.InheritedBidStrategyType = None else: bulk_ad_group.ad_group.BiddingScheme.Type = bid_strategy_type @@ -177,7 +177,7 @@ def quality_score_data(self): _SimpleBulkMapping( header=_StringTable.NetworkDistribution, field_to_csv=lambda c: bulk_str(c.ad_group.Network), - csv_to_field=lambda c, v: setattr(c.ad_group, 'Network', v if v else None) + csv_to_field=lambda c, v: csv_to_field_enum(c.ad_group, v, 'Network', Network) ), _SimpleBulkMapping( header=_StringTable.AdRotation, @@ -189,6 +189,16 @@ def quality_score_data(self): field_to_csv=lambda c: ad_group_bid_bulk_str(c.ad_group.CpcBid), csv_to_field=lambda c, v: setattr(c.ad_group, 'CpcBid', parse_ad_group_bid(v)) ), + _SimpleBulkMapping( + header=_StringTable.CpvBid, + field_to_csv=lambda c: ad_group_bid_bulk_str(c.ad_group.CpvBid), + csv_to_field=lambda c, v: setattr(c.ad_group, 'CpvBid', parse_ad_group_bid(v)) + ), + _SimpleBulkMapping( + header=_StringTable.CpmBid, + field_to_csv=lambda c: ad_group_bid_bulk_str(c.ad_group.CpmBid), + csv_to_field=lambda c, v: setattr(c.ad_group, 'CpmBid', parse_ad_group_bid(v)) + ), _SimpleBulkMapping( header=_StringTable.Language, field_to_csv=lambda c: bulk_str(c.ad_group.Language), @@ -205,7 +215,7 @@ def quality_score_data(self): ), _SimpleBulkMapping( header=_StringTable.TrackingTemplate, - field_to_csv=lambda c: bulk_str(c.ad_group.TrackingUrlTemplate), + field_to_csv=lambda c: bulk_optional_str(c.ad_group.TrackingUrlTemplate, c.ad_group.Id), csv_to_field=lambda c, v: setattr(c.ad_group, 'TrackingUrlTemplate', v if v else None) ), _SimpleBulkMapping( @@ -232,7 +242,7 @@ def quality_score_data(self): field_to_csv=lambda c: bulk_optional_str(c.ad_group.FinalUrlSuffix, c.ad_group.Id), csv_to_field=lambda c, v: setattr(c.ad_group, 'FinalUrlSuffix', v) ), - + _SimpleBulkMapping( header=_StringTable.AdScheduleUseSearcherTimeZone, field_to_csv=lambda c: field_to_csv_UseSearcherTimeZone(c.ad_group.AdScheduleUseSearcherTimeZone, None), @@ -243,9 +253,38 @@ def quality_score_data(self): field_to_csv=lambda c: c.ad_group.AdGroupType, csv_to_field=lambda c, v: setattr(c.ad_group, 'AdGroupType', v) ), + _SimpleBulkMapping( + header=_StringTable.MultiMediaAdBidAdjustment, + field_to_csv=lambda c: bulk_str(c.ad_group.MultimediaAdsBidAdjustment), + csv_to_field=lambda c, v: setattr( + c.ad_group, + 'MultimediaAdsBidAdjustment', + int(v) if v else None + ) + ), + _SimpleBulkMapping( + header=_StringTable.UseOptimizedTargeting, + field_to_csv=lambda c: field_to_csv_bool(c.ad_group.UseOptimizedTargeting), + csv_to_field=lambda c, v: setattr(c.ad_group, 'UseOptimizedTargeting', parse_bool(v)) + ), + _SimpleBulkMapping( + header=_StringTable.HotelAdGroupType, + field_to_csv=lambda c: hotel_setting_to_csv(c.ad_group), + csv_to_field=lambda c, v: csv_to_hotel_setting(c.ad_group, v) + ), + _SimpleBulkMapping( + header=_StringTable.CommissionRate, + field_to_csv=lambda c: bulk_str(c.ad_group.CommissionRate.RateAmount.Amount), + csv_to_field=lambda c, v: csv_to_commission_rate(c.ad_group, v) + ), + _SimpleBulkMapping( + header=_StringTable.PercentCpcBid, + field_to_csv=lambda c: bulk_str(c.ad_group.PercentCpcBid.RateAmount.Amount), + csv_to_field=lambda c, v: csv_to_percent_cpc_bid(c.ad_group, v) + ) ] - - + + def process_mappings_from_row_values(self, row_values): self.ad_group = _CAMPAIGN_OBJECT_FACTORY_V13.create('AdGroup') diff --git a/bingads/v13/bulk/entities/bulk_ad_group_criterion.py b/bingads/v13/bulk/entities/bulk_ad_group_criterion.py new file mode 100644 index 00000000..35efc668 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_ad_group_criterion.py @@ -0,0 +1,207 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from abc import abstractmethod + +_AdGroupCriterion = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('AdGroupCriterion')) +_NegativeAdGroupCriterion = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('NegativeAdGroupCriterion')) +_FixedBid = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('FixedBid')) +_BiddableAdGroupCriterion = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('BiddableAdGroupCriterion')) + + +def csv_to_bidding(row_values, entity): + success, exclude = row_values.try_get_value(_StringTable.IsExcluded) + if exclude is None: + exclude = '' + exclude = exclude.lower() + if exclude == 'yes' or exclude == 'true': + is_excluded = True + elif exclude == 'no' or exclude == 'false': + is_excluded = False + else: + raise ValueError('IsExcluded can only be set to TRUE|FALSE in Ad Group Criterion row') + if is_excluded: + negative_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('NegativeAdGroupCriterion') + negative_ad_group_criterion.Criterion = entity.create_criterion() + negative_ad_group_criterion.Type = 'NegativeAdGroupCriterion' + + entity.ad_group_criterion = negative_ad_group_criterion + else: + bid = _CAMPAIGN_OBJECT_FACTORY_V13.create('FixedBid') + bid.Type = 'FixedBid' + + biddable_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('BiddableAdGroupCriterion') + biddable_ad_group_criterion.Criterion = entity.create_criterion() + + success, bid_value = row_values.try_get_value(_StringTable.Bid) + if success and bid_value is not None and bid_value != '': + bid.Amount = float(bid_value) + else: + success, bid_value = row_values.try_get_value(_StringTable.BidAdjustment) + if success and bid_value is not None and bid_value != '': + bid = _CAMPAIGN_OBJECT_FACTORY_V13.create('BidMultiplier') + bid.Type = 'BidMultiplier' + bid.Multiplier = float(bid_value) + + biddable_ad_group_criterion.CriterionBid = bid + biddable_ad_group_criterion.Type = 'BiddableAdGroupCriterion' + + entity.ad_group_criterion = biddable_ad_group_criterion + + +def bidding_to_csv(entity, row_values): + if isinstance(entity.ad_group_criterion, _NegativeAdGroupCriterion): + row_values[_StringTable.IsExcluded] = 'True' + else: + row_values[_StringTable.IsExcluded] = 'False' + bid = entity.ad_group_criterion.CriterionBid + if bid is None: + return + if isinstance(bid, _FixedBid): + row_values[_StringTable.Bid] = fixed_bid_bulk_str(bid) + else: + row_values[_StringTable.BidAdjustment] = bid_multiplier_bulk_str(bid) + +class BulkAdGroupCriterion(_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 + Ad Group Criterion record in a bulk file. + + For more information, see Ad Group Criterion at https://go.microsoft.com/fwlink/?linkid=836837. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + campaign_name=None, + ad_group_name=None, + ad_group_criterion=None): + super(BulkAdGroupCriterion, self).__init__() + + self._campaign_name = campaign_name + self._ad_group_name = ad_group_name + self._ad_group_criterion = ad_group_criterion + self._performance_data = None + + _MAPPINGS = [ + _ComplexBulkMapping(bidding_to_csv, csv_to_bidding), + + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: c.ad_group_criterion.Status, + csv_to_field=lambda c, v: setattr(c.ad_group_criterion, 'Status', v) + ), + _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) + ), + _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) + ), + _SimpleBulkMapping( + header=_StringTable.Campaign, + field_to_csv=lambda c: c.campaign_name, + csv_to_field=lambda c, v: setattr(c, 'campaign_name', v) + ), + _SimpleBulkMapping( + header=_StringTable.AdGroup, + field_to_csv=lambda c: c.ad_group_name, + csv_to_field=lambda c, v: setattr(c, 'ad_group_name', v) + ), + _SimpleBulkMapping( + header=_StringTable.FinalUrl, + field_to_csv=lambda c: field_to_csv_Urls(c.ad_group_criterion.FinalUrls, c.ad_group_criterion.Id) + if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None, + csv_to_field=lambda c, v: csv_to_field_Urls(c.ad_group_criterion.FinalUrls, v) + if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None + ), + _SimpleBulkMapping( + header=_StringTable.FinalMobileUrl, + field_to_csv=lambda c: field_to_csv_Urls(c.ad_group_criterion.FinalMobileUrls, c.ad_group_criterion.Id) + if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None, + csv_to_field=lambda c, v: csv_to_field_Urls(c.ad_group_criterion.FinalMobileUrls, v) + if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None + ), + _SimpleBulkMapping( + header=_StringTable.TrackingTemplate, + field_to_csv=lambda c: bulk_optional_str(c.ad_group_criterion.TrackingUrlTemplate, c.ad_group_criterion.Id) + if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None, + csv_to_field=lambda c, v: setattr(c.ad_group_criterion, 'TrackingUrlTemplate', v if v else None) + if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None + ), + _SimpleBulkMapping( + header=_StringTable.CustomParameter, + field_to_csv=lambda c: field_to_csv_UrlCustomParameters(c.ad_group_criterion) + if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None, + csv_to_field=lambda c, v: csv_to_field_UrlCustomParameters(c.ad_group_criterion, v) + if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None + ), + _SimpleBulkMapping( + header=_StringTable.FinalUrlSuffix, + field_to_csv=lambda c: bulk_optional_str(c.ad_group_criterion.FinalUrlSuffix,c.ad_group_criterion.Id) + if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None, + csv_to_field=lambda c, v: setattr(c.ad_group_criterion, 'FinalUrlSuffix', v) + if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None + ) + ] + + @property + def ad_group_criterion(self): + """ Defines an Ad Group Criterion """ + + return self._ad_group_criterion + + @ad_group_criterion.setter + def ad_group_criterion(self, ad_group_criterion): + self._ad_group_criterion = 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 + + def process_mappings_from_row_values(self, row_values): + row_values.convert_to_entity(self, BulkAdGroupCriterion._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.convert_to_values(row_values, BulkAdGroupCriterion._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAdGroupCriterion, self).read_additional_data(stream_reader) + + @abstractmethod + def create_criterion(self): + return None diff --git a/bingads/v13/bulk/entities/bulk_ad_group_hotel_listing_group.py b/bingads/v13/bulk/entities/bulk_ad_group_hotel_listing_group.py new file mode 100644 index 00000000..01abef17 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_ad_group_hotel_listing_group.py @@ -0,0 +1,103 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.bulk.entities.bulk_ad_group_criterion import BulkAdGroupCriterion +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable + +_HotelGroup = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('HotelGroup')) + +class BulkAdGroupHotelListingGroup(BulkAdGroupCriterion): + """ Represents an Ad Group Hotel Group 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 + Ad Group Hotel Group record in a bulk file. + + For more information, see Ad Group Product Scope at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + campaign_name=None, + ad_group_name=None, + ad_group_criterion=None + ): + super(BulkAdGroupHotelListingGroup, self).__init__(campaign_name, ad_group_name, ad_group_criterion) + + @classmethod + def _get_listing_type(cls, entity): + if entity.ad_group_criterion.Criterion is not None and \ + hasattr(entity.ad_group_criterion.Criterion, 'ListingType'): + return entity.ad_group_criterion.Criterion.ListingType + return None + + @classmethod + def _get_parent_criterion_id(cls, entity): + if entity.ad_group_criterion.Criterion is not None and \ + hasattr(entity.ad_group_criterion.Criterion, 'ParentCriterionId'): + return bulk_str(entity.ad_group_criterion.Criterion.ParentCriterionId) + return None + + @classmethod + def _get_listing_operand(cls, entity): + if entity.ad_group_criterion.Criterion is not None and \ + hasattr(entity.ad_group_criterion.Criterion, 'Listing') and \ + entity.ad_group_criterion.Criterion.Listing is not None and \ + hasattr(entity.ad_group_criterion.Criterion.Listing, 'Operand'): + return entity.ad_group_criterion.Criterion.Listing.Operand + return None + + @classmethod + def _get_listing_attribute(cls, entity): + if entity.ad_group_criterion.Criterion is not None and \ + hasattr(entity.ad_group_criterion.Criterion, 'Listing') and \ + entity.ad_group_criterion.Criterion.Listing is not None and \ + hasattr(entity.ad_group_criterion.Criterion.Listing, 'Attribute'): + return entity.ad_group_criterion.Criterion.Listing.Attribute + return None + + _MAPPINGS = [ + _SimpleBulkMapping( + _StringTable.SubType, + field_to_csv=lambda c: BulkAdGroupHotelListingGroup._get_listing_type(c), + csv_to_field=lambda c, v: setattr(c.ad_group_criterion.Criterion, 'ListingType', v) + ), + _SimpleBulkMapping( + _StringTable.ParentAdGroupCriterionId, + field_to_csv=lambda c: BulkAdGroupHotelListingGroup._get_parent_criterion_id(c), + csv_to_field=lambda c, v: setattr(c.ad_group_criterion.Criterion, 'ParentCriterionId', + int(v) if v else None) + ), + _SimpleBulkMapping( + _StringTable.HotelAttribute, + field_to_csv=lambda c: BulkAdGroupHotelListingGroup._get_listing_operand(c), + csv_to_field=lambda c, v: setattr(c.ad_group_criterion.Criterion.Listing, 'Operand', v) + ), + _SimpleBulkMapping( + _StringTable.HotelAttributeValue, + field_to_csv=lambda c: BulkAdGroupHotelListingGroup._get_listing_attribute(c), + csv_to_field=lambda c, v: setattr(c.ad_group_criterion.Criterion.Listing, 'Attribute', v) + ), + ] + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + super(BulkAdGroupHotelListingGroup, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkAdGroupHotelListingGroup._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + super(BulkAdGroupHotelListingGroup, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkAdGroupHotelListingGroup._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAdGroupHotelListingGroup, self).read_additional_data(stream_reader) + + def create_criterion(self): + hotel_group = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelGroup') + hotel_group.Listing = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelListing') + hotel_group.Type = 'HotelGroup' + return hotel_group diff --git a/bingads/v13/bulk/entities/bulk_ad_group_product_partition.py b/bingads/v13/bulk/entities/bulk_ad_group_product_partition.py index 80490aa9..f05fd215 100644 --- a/bingads/v13/bulk/entities/bulk_ad_group_product_partition.py +++ b/bingads/v13/bulk/entities/bulk_ad_group_product_partition.py @@ -1,76 +1,14 @@ from bingads.v13.bulk.entities import * from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 -from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.bulk.entities.bulk_ad_group_criterion import BulkAdGroupCriterion from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping from bingads.v13.internal.bulk.string_table import _StringTable # from bingads.v13.internal.extensions import bulk_str from bingads.v13.internal.extensions import * _BiddableAdGroupCriterion = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('BiddableAdGroupCriterion')) -_NegativeAdGroupCriterion = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('NegativeAdGroupCriterion')) -_FixedBid = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('FixedBid')) -def csv_to_bidding(row_values, entity): - success, exclude = row_values.try_get_value(_StringTable.IsExcluded) - if exclude is None: - exclude = '' - exclude = exclude.lower() - if exclude == 'yes' or exclude == 'true': - is_excluded = True - elif exclude == 'no' or exclude == 'false': - is_excluded = False - else: - raise ValueError('IsExcluded can only be set to TRUE|FALSE in Ad Group Product Partition row') - if is_excluded: - product_partition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductPartition') - product_partition.Condition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductCondition') - product_partition.Type = 'ProductPartition' - - negative_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('NegativeAdGroupCriterion') - negative_ad_group_criterion.Criterion = product_partition - negative_ad_group_criterion.Type = 'NegativeAdGroupCriterion' - - entity.ad_group_criterion = negative_ad_group_criterion - else: - product_partition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductPartition') - product_partition.Condition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductCondition') - product_partition.Type = 'ProductPartition' - - bid = _CAMPAIGN_OBJECT_FACTORY_V13.create('FixedBid') - bid.Type = 'FixedBid' - - biddable_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('BiddableAdGroupCriterion') - biddable_ad_group_criterion.Criterion = product_partition - - success, bid_value = row_values.try_get_value(_StringTable.Bid) - if success and bid_value is not None and bid_value != '': - bid.Amount = float(bid_value) - else: - success, bid_value = row_values.try_get_value(_StringTable.BidAdjustment) - if success and bid_value is not None and bid_value != '': - bid = _CAMPAIGN_OBJECT_FACTORY_V13.create('BidMultiplier') - bid.Type = 'BidMultiplier' - bid.Multiplier = float(bid_value) - - biddable_ad_group_criterion.CriterionBid = bid - biddable_ad_group_criterion.Type = 'BiddableAdGroupCriterion' - - entity.ad_group_criterion = biddable_ad_group_criterion - -def bidding_to_csv(entity, row_values): - if isinstance(entity.ad_group_criterion, _NegativeAdGroupCriterion): - row_values[_StringTable.IsExcluded] = 'True' - else: - row_values[_StringTable.IsExcluded] = 'False' - bid = entity.ad_group_criterion.CriterionBid - if bid is None: - return - if isinstance(bid, _FixedBid): - row_values[_StringTable.Bid] = fixed_bid_bulk_str(bid) - else: - row_values[_StringTable.BidAdjustment] = bid_multiplier_bulk_str(bid) - -class BulkAdGroupProductPartition(_SingleRecordBulkEntity): +class BulkAdGroupProductPartition(BulkAdGroupCriterion): """ Represents an 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 @@ -87,51 +25,11 @@ class BulkAdGroupProductPartition(_SingleRecordBulkEntity): """ def __init__(self, - ad_group_criterion=None, campaign_name=None, - ad_group_name=None): - super(BulkAdGroupProductPartition, self).__init__() - - self._ad_group_criterion = ad_group_criterion - self._campaign_name = campaign_name - self._ad_group_name = ad_group_name - self._performance_data = None - - @classmethod - def _read_is_excluded(cls, entity, row_value): - if row_value is None: - row_value = '' - row_value = row_value.lower() - if row_value == 'yes' or row_value == 'true': - is_excluded = True - elif row_value == 'no' or row_value == 'false': - is_excluded = False - else: - raise ValueError('IsExcluded can only be set to TRUE|FALSE in Ad Group Product Partition row') - if is_excluded: - product_partition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductPartition') - product_partition.Condition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductCondition') - product_partition.Type = 'ProductPartition' - - negative_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('NegativeAdGroupCriterion') - negative_ad_group_criterion.Criterion = product_partition - negative_ad_group_criterion.Type = 'NegativeAdGroupCriterion' - - entity.ad_group_criterion = negative_ad_group_criterion - else: - product_partition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductPartition') - product_partition.Condition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductCondition') - product_partition.Type = 'ProductPartition' - - fixed_bid = _CAMPAIGN_OBJECT_FACTORY_V13.create('FixedBid') - fixed_bid.Type = 'FixedBid' - - biddable_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('BiddableAdGroupCriterion') - biddable_ad_group_criterion.Criterion = product_partition - biddable_ad_group_criterion.CriterionBid = fixed_bid - biddable_ad_group_criterion.Type = 'BiddableAdGroupCriterion' - - entity.ad_group_criterion = biddable_ad_group_criterion + ad_group_name=None, + ad_group_criterion=None + ): + super(BulkAdGroupProductPartition, self).__init__(campaign_name, ad_group_name, ad_group_criterion) @classmethod def _write_bid(cls, entity): @@ -194,33 +92,6 @@ def _read_destination_url(cls, entity, row_value): pass _MAPPINGS = [ - _ComplexBulkMapping(bidding_to_csv, csv_to_bidding), - - _SimpleBulkMapping( - _StringTable.Status, - field_to_csv=lambda c: c.ad_group_criterion.Status, - csv_to_field=lambda c, v: setattr(c.ad_group_criterion, 'Status', v) - ), - _SimpleBulkMapping( - _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) - ), - _SimpleBulkMapping( - _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) - ), - _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.SubType, field_to_csv=lambda c: BulkAdGroupProductPartition._get_partition_type(c), @@ -246,84 +117,22 @@ def _read_destination_url(cls, entity, row_value): _StringTable.DestinationUrl, field_to_csv=lambda c: BulkAdGroupProductPartition._write_destination_url(c), csv_to_field=lambda c, v: BulkAdGroupProductPartition._read_destination_url(c, v) - ), - _SimpleBulkMapping( - header=_StringTable.FinalUrl, - field_to_csv=lambda c: field_to_csv_Urls(c.ad_group_criterion.FinalUrls, c.ad_group_criterion.Id) - if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None, - csv_to_field=lambda c, v: csv_to_field_Urls(c.ad_group_criterion.FinalUrls, v) - if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None - ), - _SimpleBulkMapping( - header=_StringTable.FinalMobileUrl, - field_to_csv=lambda c: field_to_csv_Urls(c.ad_group_criterion.FinalMobileUrls, c.ad_group_criterion.Id) - if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None, - csv_to_field=lambda c, v: csv_to_field_Urls(c.ad_group_criterion.FinalMobileUrls, v) - if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None - ), - _SimpleBulkMapping( - header=_StringTable.TrackingTemplate, - field_to_csv=lambda c: bulk_optional_str(c.ad_group_criterion.TrackingUrlTemplate, c.ad_group_criterion.Id) - if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None, - csv_to_field=lambda c, v: setattr(c.ad_group_criterion, 'TrackingUrlTemplate', v if v else None) - if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None - ), - _SimpleBulkMapping( - header=_StringTable.CustomParameter, - field_to_csv=lambda c: field_to_csv_UrlCustomParameters(c.ad_group_criterion) - if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None, - csv_to_field=lambda c, v: csv_to_field_UrlCustomParameters(c.ad_group_criterion, v) - if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None - ), - _SimpleBulkMapping( - header=_StringTable.FinalUrlSuffix, - field_to_csv=lambda c: bulk_optional_str(c.ad_group_criterion.FinalUrlSuffix, c.ad_group_criterion.Id) if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None , - csv_to_field=lambda c, v: setattr(c.ad_group_criterion, 'FinalUrlSuffix', v) if isinstance(c.ad_group_criterion, _BiddableAdGroupCriterion) else None ) ] - @property - def ad_group_criterion(self): - """ Defines an Ad Group Criterion """ - - return self._ad_group_criterion - - @ad_group_criterion.setter - def ad_group_criterion(self, ad_group_criterion): - self._ad_group_criterion = 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 - def process_mappings_to_row_values(self, row_values, exclude_readonly_data): - self._validate_property_not_null(self.ad_group_criterion, 'ad_group_criterion') + super(BulkAdGroupProductPartition, self).process_mappings_to_row_values(row_values, exclude_readonly_data) self.convert_to_values(row_values, BulkAdGroupProductPartition._MAPPINGS) def process_mappings_from_row_values(self, row_values): + super(BulkAdGroupProductPartition, self).process_mappings_from_row_values(row_values) row_values.convert_to_entity(self, BulkAdGroupProductPartition._MAPPINGS) def read_additional_data(self, stream_reader): super(BulkAdGroupProductPartition, self).read_additional_data(stream_reader) + + def create_criterion(self): + product_partition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductPartition') + product_partition.Condition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductCondition') + product_partition.Type = 'ProductPartition' + return product_partition diff --git a/bingads/v13/bulk/entities/bulk_ads.py b/bingads/v13/bulk/entities/bulk_ads.py index 895943f5..96e114b3 100644 --- a/bingads/v13/bulk/entities/bulk_ads.py +++ b/bingads/v13/bulk/entities/bulk_ads.py @@ -13,7 +13,6 @@ ResponsiveSearchAd = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('ResponsiveSearchAd')) ResponsiveAd = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('ResponsiveAd')) - class _BulkAd(_SingleRecordBulkEntity): """ This abstract base class provides properties that are shared by all bulk ad classes. @@ -40,7 +39,21 @@ def __init__(self, self._ad_group_name = ad_group_name self._ad = ad self._performance_data = None + self._editorial_appeal_status = None + + @property + def editorial_appeal_status(self): + """ The editorial appeal status of the ad. + + :rtype: str + """ + + return self._editorial_appeal_status + @editorial_appeal_status.setter + def editorial_appeal_status(self, editorial_appeal_status): + self._editorial_appeal_status = editorial_appeal_status + @property def ad_group_id(self): """ The identifier of the ad group that contains the ad. @@ -102,7 +115,7 @@ def ad(self, ad): _SimpleBulkMapping( header=_StringTable.Status, field_to_csv=lambda c: bulk_str(c.ad.Status), - csv_to_field=lambda c, v: setattr(c.ad, 'Status', v if v else None) + csv_to_field=lambda c, v: csv_to_field_enum(c.ad, v, 'Status', AdStatus) ), _SimpleBulkMapping( header=_StringTable.Id, @@ -127,7 +140,7 @@ def ad(self, ad): _SimpleBulkMapping( header=_StringTable.EditorialStatus, field_to_csv=lambda c: c.ad.EditorialStatus, - csv_to_field=lambda c, v: setattr(c.ad, 'EditorialStatus', v if v else None) + csv_to_field=lambda c, v: csv_to_field_enum(c.ad, v, 'EditorialStatus', AdEditorialStatus) ), _SimpleBulkMapping( header=_StringTable.DevicePreference, @@ -164,6 +177,11 @@ def ad(self, ad): header=_StringTable.FinalUrlSuffix, field_to_csv=lambda c: bulk_optional_str(c.ad.FinalUrlSuffix, c.ad.Id), csv_to_field=lambda c, v: setattr(c.ad, 'FinalUrlSuffix', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.EditorialAppealStatus, + field_to_csv=lambda c: c.editorial_appeal_status, + csv_to_field=lambda c, v: setattr(c, '_editorial_appeal_status', v) ) ] @@ -599,6 +617,7 @@ def __init__(self, ad, ) self._ad = ad + self._verified_tracking_data = None @property def responsive_ad(self): @@ -613,7 +632,21 @@ def responsive_ad(self): def responsive_ad(self, responsive_ad): if responsive_ad is not None and not isinstance(responsive_ad, ResponsiveAd): raise ValueError('Not an instance of ResponsiveAd') - self._ad = responsive_ad + self._ad = responsive_ad + + @property + def verified_tracking_data(self): + """ + The verified tracking data that the ad associated + + Corresponds to 'Verified Tracking Setting' field in bulk file. + :rtype: ArrayOfArrayOfKeyValuePairOfstringstring + """ + return self._verified_tracking_data + + @verified_tracking_data.setter + def verified_tracking_data(self, value): + self._verified_tracking_data = value _MAPPINGS = [ _SimpleBulkMapping( @@ -650,7 +683,37 @@ def responsive_ad(self, responsive_ad): header=_StringTable.ImpressionTrackingUrls, field_to_csv=lambda c: field_to_csv_Urls(c.responsive_ad.ImpressionTrackingUrls, c.ad.Id), csv_to_field=lambda c, v: csv_to_field_Urls(c.responsive_ad.ImpressionTrackingUrls, v) - ) + ), + _SimpleBulkMapping( + header=_StringTable.Descriptions, + field_to_csv=lambda c: field_to_csv_TextAssetLinks(c.responsive_ad.Descriptions), + csv_to_field=lambda c, v: csv_to_field_TextAssetLinks(c.responsive_ad.Descriptions ,v) + ), + _SimpleBulkMapping( + header=_StringTable.Headlines, + field_to_csv=lambda c: field_to_csv_TextAssetLinks(c.responsive_ad.Headlines), + csv_to_field=lambda c, v: csv_to_field_TextAssetLinks(c.responsive_ad.Headlines, v) + ), + _SimpleBulkMapping( + header=_StringTable.Videos, + field_to_csv=lambda c: field_to_csv_VideoAssetLinks(c.responsive_ad.Videos), + csv_to_field=lambda c, v: csv_to_field_VideoAssetLinks(c.responsive_ad.Videos, v) + ), + _SimpleBulkMapping( + header=_StringTable.CallToActionLanguage, + field_to_csv=lambda c: c.responsive_ad.CallToActionLanguage, + csv_to_field=lambda c, v: setattr(c.responsive_ad, 'CallToActionLanguage', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.LongHeadlines, + field_to_csv=lambda c: field_to_csv_TextAssetLinks(c.responsive_ad.LongHeadlines), + csv_to_field=lambda c, v: csv_to_field_TextAssetLinks(c.responsive_ad.LongHeadlines ,v) + ), + _SimpleBulkMapping( + header=_StringTable.Details, + field_to_csv=lambda c: to_verified_tracking_setting_string(c.verified_tracking_data), + csv_to_field=lambda c, v: setattr(c, 'verified_tracking_data', parse_verified_tracking_setting(v) if v else None) + ), ] def process_mappings_from_row_values(self, row_values): @@ -725,13 +788,13 @@ def responsive_search_ad(self, rsa): ), _SimpleBulkMapping( header=_StringTable.Headline, - field_to_csv=lambda c: field_to_csv_Rsa_TextAssetLinks(c.responsive_search_ad.Headlines), - csv_to_field=lambda c, v: csv_to_field_Rsa_TextAssetLinks(c.responsive_search_ad.Headlines, v) + field_to_csv=lambda c: field_to_csv_TextAssetLinks(c.responsive_search_ad.Headlines), + csv_to_field=lambda c, v: csv_to_field_TextAssetLinks(c.responsive_search_ad.Headlines, v) ), _SimpleBulkMapping( header=_StringTable.Description, - field_to_csv=lambda c: field_to_csv_Rsa_TextAssetLinks(c.responsive_search_ad.Descriptions), - csv_to_field=lambda c, v: csv_to_field_Rsa_TextAssetLinks(c.responsive_search_ad.Descriptions ,v) + field_to_csv=lambda c: field_to_csv_TextAssetLinks(c.responsive_search_ad.Descriptions), + csv_to_field=lambda c, v: csv_to_field_TextAssetLinks(c.responsive_search_ad.Descriptions ,v) ) ] diff --git a/bingads/v13/bulk/entities/bulk_asset_group.py b/bingads/v13/bulk/entities/bulk_asset_group.py new file mode 100644 index 00000000..ba3831f9 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_asset_group.py @@ -0,0 +1,179 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping +from bingads.v13.internal.extensions import * + +class BulkAssetGroup(_SingleRecordBulkEntity): + """ Represents an asset group. + + This class exposes the property :attr:`asset_group` that can be read and written as fields of the Asset Group record + in a bulk file. + + For more information, see Asset Group at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, campaign_id=None, campaign_name=None, asset_group=None): + super(BulkAssetGroup, self).__init__() + + self._campaign_id = campaign_id + self._campaign_name = campaign_name + self._asset_group = asset_group + + + @property + def campaign_id(self): + """ The identifier of the campaign that contains the asset group. + + Corresponds to the 'Parent Id' field in the bulk file. + + :rtype: int + """ + + return self._campaign_id + + @campaign_id.setter + def campaign_id(self, campaign_id): + self._campaign_id = campaign_id + + @property + def campaign_name(self): + """ The name of the campaign that contains the asset group. + + Corresponds to the 'Campaign' field in the bulk file. + + :rtype: str + """ + + return self._campaign_name + + @campaign_name.setter + def campaign_name(self, campaign_name): + self._campaign_name = campaign_name + + @property + def asset_group(self): + """ The AssetGroup Data Object of the Campaign Management Service. + + A subset of AssetGroup properties are available in the Ad Group record. + For more information, see Ad Group at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._asset_group + + @asset_group.setter + def asset_group(self, asset_group): + self._asset_group = asset_group + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.asset_group.Id), + csv_to_field=lambda c, v: setattr(c.asset_group, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.asset_group.Status), + csv_to_field=lambda c, v: csv_to_field_enum(c.asset_group, v, 'Status', AssetGroupStatus) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.campaign_id), + csv_to_field=lambda c, v: setattr(c, 'campaign_id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Campaign, + field_to_csv=lambda c: c.campaign_name, + csv_to_field=lambda c, v: setattr(c, 'campaign_name', v) + ), + _SimpleBulkMapping( + header=_StringTable.AssetGroup, + field_to_csv=lambda c: bulk_str(c.asset_group.Name), + csv_to_field=lambda c, v: setattr(c.asset_group, 'Name', v) + ), + _SimpleBulkMapping( + header=_StringTable.StartDate, + field_to_csv=lambda c: bulk_date_str(c.asset_group.StartDate), + csv_to_field=lambda c, v: setattr(c.asset_group, 'StartDate', parse_date(v)) + ), + _SimpleBulkMapping( + header=_StringTable.EndDate, + field_to_csv=lambda c: bulk_date_str(c.asset_group.EndDate), + csv_to_field=lambda c, v: setattr(c.asset_group, 'EndDate', parse_date(v)) + ), + _SimpleBulkMapping( + header=_StringTable.BusinessName, + field_to_csv=lambda c: c.asset_group.BusinessName, + csv_to_field=lambda c, v: setattr(c.asset_group, 'BusinessName', v) + ), + _SimpleBulkMapping( + header=_StringTable.CallToAction, + field_to_csv=lambda c: c.asset_group.CallToAction, + csv_to_field=lambda c, v: csv_to_field_enum(c.asset_group, v, 'CallToAction', CallToAction) + ), + _SimpleBulkMapping( + header=_StringTable.Descriptions, + field_to_csv=lambda c: field_to_csv_TextAssetLinks(c.asset_group.Descriptions), + csv_to_field=lambda c, v: csv_to_field_TextAssetLinks(c.asset_group.Descriptions ,v) + ), + _SimpleBulkMapping( + header=_StringTable.EditorialStatus, + field_to_csv=lambda c: c.asset_group.EditorialStatus, + csv_to_field=lambda c, v: csv_to_field_enum(c.asset_group, v, 'EditorialStatus', AssetGroupEditorialStatus) + ), + _SimpleBulkMapping( + header=_StringTable.FinalMobileUrl, + field_to_csv=lambda c: field_to_csv_Urls(c.asset_group.FinalMobileUrls, c.asset_group.Id), + csv_to_field=lambda c, v: csv_to_field_Urls(c.asset_group.FinalMobileUrls, v) + ), + _SimpleBulkMapping( + header=_StringTable.FinalUrl, + field_to_csv=lambda c: field_to_csv_Urls(c.asset_group.FinalUrls, c.asset_group.Id), + csv_to_field=lambda c, v: csv_to_field_Urls(c.asset_group.FinalUrls, v) + ), + _SimpleBulkMapping( + header=_StringTable.Headlines, + field_to_csv=lambda c: field_to_csv_TextAssetLinks(c.asset_group.Headlines), + csv_to_field=lambda c, v: csv_to_field_TextAssetLinks(c.asset_group.Headlines, v) + ), + _SimpleBulkMapping( + header=_StringTable.Images, + field_to_csv=lambda c: field_to_csv_ImageAssetLinks(c.asset_group.Images), + csv_to_field=lambda c, v: csv_to_field_ImageAssetLinks(c.asset_group.Images, v) + ), + _SimpleBulkMapping( + header=_StringTable.LongHeadlines, + field_to_csv=lambda c: field_to_csv_TextAssetLinks(c.asset_group.LongHeadlines), + csv_to_field=lambda c, v: csv_to_field_TextAssetLinks(c.asset_group.LongHeadlines ,v) + ), + _SimpleBulkMapping( + header=_StringTable.Path1, + field_to_csv=lambda c: bulk_optional_str(c.asset_group.Path1, c.asset_group.Id), + csv_to_field=lambda c, v: setattr(c.asset_group, 'Path1', v) + ), + _SimpleBulkMapping( + header=_StringTable.Path2, + field_to_csv=lambda c: bulk_optional_str(c.asset_group.Path2, c.asset_group.Id), + csv_to_field=lambda c, v: setattr(c.asset_group, 'Path2', v) + ), + ] + + + def process_mappings_from_row_values(self, row_values): + self.asset_group = _CAMPAIGN_OBJECT_FACTORY_V13.create('AssetGroup') + + row_values.convert_to_entity(self, BulkAssetGroup._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._asset_group, 'AssetGroup') + self.convert_to_values(row_values, BulkAssetGroup._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAssetGroup, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_asset_group_listing_group.py b/bingads/v13/bulk/entities/bulk_asset_group_listing_group.py new file mode 100644 index 00000000..7aa9af71 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_asset_group_listing_group.py @@ -0,0 +1,151 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping +from bingads.v13.internal.extensions import * + +class BulkAssetGroupListingGroup(_SingleRecordBulkEntity): + """ Represents an asset group listing group. + + This class exposes the property :attr:`asset_group_listing_group` that can be read and written as fields of the Asset Group Listing Group record + in a bulk file. + + For more information, see Asset Group at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, status=None, asset_group_listing_group=None): + super(BulkAssetGroupListingGroup, self).__init__() + + self._status = status + self._asset_group_listing_group = asset_group_listing_group + self._asset_group_name = None + self._campaign_name = None + + @property + def status(self): + return self._status + + @status.setter + def status(self, status): + self._status = status + + @property + def asset_group_name(self): + return self._asset_group_name + + @asset_group_name.setter + def asset_group_name(self, asset_group_name): + self._asset_group_name = asset_group_name + + @property + def campaign_name(self): + return self._campaign_name + + @campaign_name.setter + def campaign_name(self, campaign_name): + self._campaign_name = campaign_name + + @property + def asset_group_listing_group(self): + """ The AssetGroupListingGroup Data Object of the Campaign Management Service. + + A subset of AssetGroupListingGroup properties are available in the Ad Group record. + For more information, see Ad Group at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._asset_group_listing_group + + @asset_group_listing_group.setter + def asset_group_listing_group(self, asset_group_listing_group): + self._asset_group_listing_group = asset_group_listing_group + + @classmethod + def _get_condition_operand(cls, entity): + if entity.asset_group_listing_group is not None and \ + hasattr(entity.asset_group_listing_group, 'Dimension') and \ + entity.asset_group_listing_group.Dimension is not None and \ + hasattr(entity.asset_group_listing_group.Dimension, 'Operand'): + return entity.asset_group_listing_group.Dimension.Operand + return None + + @classmethod + def _get_condition_attribute(cls, entity): + if entity.asset_group_listing_group is not None and \ + hasattr(entity.asset_group_listing_group, 'Dimension') and \ + entity.asset_group_listing_group.Dimension is not None and \ + hasattr(entity.asset_group_listing_group.Dimension, 'Attribute'): + return entity.asset_group_listing_group.Dimension.Attribute + return None + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.asset_group_listing_group.Id), + csv_to_field=lambda c, v: setattr(c.asset_group_listing_group, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.status), + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.asset_group_listing_group.AssetGroupId), + csv_to_field=lambda c, v: setattr(c.asset_group_listing_group, 'AssetGroupId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AssetGroup, + field_to_csv=lambda c: c.asset_group_name, + csv_to_field=lambda c, v: setattr(c, 'asset_group_name', v) + ), + _SimpleBulkMapping( + header=_StringTable.Campaign, + field_to_csv=lambda c: c.campaign_name, + csv_to_field=lambda c, v: setattr(c, 'campaign_name', v) + ), + _SimpleBulkMapping( + header=_StringTable.IsExcluded, + field_to_csv=lambda c: bulk_str(c.asset_group_listing_group.IsExcluded), + csv_to_field=lambda c, v: setattr(c.asset_group_listing_group, 'IsExcluded', parse_bool(v)) + ), + _SimpleBulkMapping( + header=_StringTable.ParentListingGroupId, + field_to_csv=lambda c: bulk_str(c.asset_group_listing_group.ParentListingGroupId), + csv_to_field=lambda c, v: setattr(c.asset_group_listing_group, 'ParentListingGroupId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.SubType, + field_to_csv=lambda c: bulk_str(c.asset_group_listing_group.AssetGroupListingType), + csv_to_field=lambda c, v: setattr(c.asset_group_listing_group, 'AssetGroupListingType', v if v else None) + ), + _SimpleBulkMapping( + _StringTable.ProductCondition1, + field_to_csv=lambda c: BulkAssetGroupListingGroup._get_condition_operand(c), + csv_to_field=lambda c, v: setattr(c.asset_group_listing_group.Dimension, 'Operand', v) + ), + _SimpleBulkMapping( + _StringTable.ProductValue1, + field_to_csv=lambda c: BulkAssetGroupListingGroup._get_condition_attribute(c), + csv_to_field=lambda c, v: setattr(c.asset_group_listing_group.Dimension, 'Attribute', v) + ), + ] + + + def process_mappings_from_row_values(self, row_values): + self.asset_group_listing_group = _CAMPAIGN_OBJECT_FACTORY_V13.create('AssetGroupListingGroup') + + row_values.convert_to_entity(self, BulkAssetGroupListingGroup._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._asset_group_listing_group, 'AssetGroupListingGroup') + self.convert_to_values(row_values, BulkAssetGroupListingGroup._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAssetGroupListingGroup, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_asset_group_search_theme.py b/bingads/v13/bulk/entities/bulk_asset_group_search_theme.py new file mode 100644 index 00000000..5bbdf222 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_asset_group_search_theme.py @@ -0,0 +1,87 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkAssetGroupSearchTheme(_SingleRecordBulkEntity): + """ Represents an asset group search theme. + + This class exposes the property :attr:`asset_group_search_theme` that can be read and written as fields of the asset group search theme record + in a bulk file. + + For more information, see asset group search theme at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, asset_group_id=None, asset_group_search_theme=None): + super(BulkAssetGroupSearchTheme, self).__init__() + + self._asset_group_search_theme = asset_group_search_theme + self._asset_group_id = asset_group_id + + @property + def asset_group_search_theme(self): + """ The AssetGroupSearchTheme Data Object of the Campaign Management Service. + + A subset of AssetGroupSearchTheme properties are available in the Ad Group record. + For more information, see Ad Group at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._asset_group_search_theme + + @asset_group_search_theme.setter + def asset_group_search_theme(self, asset_group_search_theme): + self._asset_group_search_theme = asset_group_search_theme + + @property + def asset_group_id(self): + """ The identifier of the asset group that contains the search theme. + + Corresponds to the 'Parent Id' field in the bulk file. + + :rtype: int + """ + + return self._asset_group_id + + @asset_group_id.setter + def asset_group_id(self, asset_group_id): + self._asset_group_id = asset_group_id + + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.asset_group_search_theme.Id), + csv_to_field=lambda c, v: setattr(c.asset_group_search_theme, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.asset_group_id), + csv_to_field=lambda c, v: setattr(c, 'asset_group_id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.SearchTheme, + field_to_csv=lambda c: bulk_str(c.asset_group_search_theme.SearchTheme), + csv_to_field=lambda c, v: setattr(c.asset_group_search_theme, 'SearchTheme', v) + ), + ] + + def process_mappings_from_row_values(self, row_values): + self.asset_group_search_theme = _CAMPAIGN_OBJECT_FACTORY_V13.create('AssetGroupSearchTheme') + + row_values.convert_to_entity(self, BulkAssetGroupSearchTheme._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._asset_group_search_theme, 'AssetGroupSearchTheme') + self.convert_to_values(row_values, BulkAssetGroupSearchTheme._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAssetGroupSearchTheme, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_asset_group_url_target.py b/bingads/v13/bulk/entities/bulk_asset_group_url_target.py new file mode 100644 index 00000000..cb73621e --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_asset_group_url_target.py @@ -0,0 +1,205 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping +from bingads.v13.internal.extensions import * + +class BulkAssetGroupUrlTarget(_SingleRecordBulkEntity): + """ Represents an asset group url target. + + This class exposes the property :attr:`asset_group_url_target` that can be read and written as fields of the asset group url target record + in a bulk file. + + For more information, see Asset Group at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, status=None): + super(BulkAssetGroupUrlTarget, self).__init__() + + self._status = status + self._id = None + self._asset_group_id = None + self._target_condition1 = None + self._target_condition2 = None + self._target_condition3 = None + self._target_condition_operator1 = None + self._target_condition_operator2 = None + self._target_condition_operator3 = None + self._target_value1 = None + self._target_value2 = None + self._target_value3 = None + + @property + def status(self): + return self._status + + @status.setter + def status(self, status): + self._status = status + + @property + def id(self): + return self._id + + @id.setter + def id(self, id): + self._id = id + + @property + def asset_group_id(self): + return self._asset_group_id + + @asset_group_id.setter + def asset_group_id(self, asset_group_id): + self._asset_group_id = asset_group_id + + @property + def target_condition1(self): + return self._target_condition1 + + @target_condition1.setter + def target_condition1(self, target_condition1): + self._target_condition1 = target_condition1 + + @property + def target_condition2(self): + return self._target_condition2 + + @target_condition2.setter + def target_condition2(self, target_condition2): + self._target_condition2 = target_condition2 + + @property + def target_condition3(self): + return self._target_condition3 + + @target_condition3.setter + def target_condition3(self, target_condition3): + self._target_condition3 = target_condition3 + + @property + def target_condition_operator1(self): + return self._target_condition_operator1 + + @target_condition_operator1.setter + def target_condition_operator1(self, target_condition_operator1): + self._target_condition_operator1 = target_condition_operator1 + + @property + def target_condition_operator2(self): + return self._target_condition_operator2 + + @target_condition_operator2.setter + def target_condition_operator2(self, target_condition_operator2): + self._target_condition_operator2 = target_condition_operator2 + + @property + def target_condition_operator3(self): + return self._target_condition_operator3 + + @target_condition_operator3.setter + def target_condition_operator3(self, target_condition_operator3): + self._target_condition_operator3 = target_condition_operator3 + + @property + def target_value1(self): + return self._target_value1 + + @target_value1.setter + def target_value1(self, target_value1): + self._target_value1 = target_value1 + + @property + def target_value2(self): + return self._target_value2 + + @target_value2.setter + def target_value2(self, target_value2): + self._target_value2 = target_value2 + + @property + def target_value3(self): + return self._target_value3 + + @target_value3.setter + def target_value3(self, target_value3): + self._target_value3 = target_value3 + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.id), + csv_to_field=lambda c, v: setattr(c, 'id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.status), + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.asset_group_id), + csv_to_field=lambda c, v: setattr(c, 'asset_group_id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AssetGroupTargetCondition1, + field_to_csv=lambda c: c.target_condition1, + csv_to_field=lambda c, v: setattr(c, 'target_condition1', v) + ), + _SimpleBulkMapping( + header=_StringTable.AssetGroupTargetCondition2, + field_to_csv=lambda c: c.target_condition2, + csv_to_field=lambda c, v: setattr(c, 'target_condition2', v) + ), + _SimpleBulkMapping( + header=_StringTable.AssetGroupTargetCondition3, + field_to_csv=lambda c: c.target_condition3, + csv_to_field=lambda c, v: setattr(c, 'target_condition3', v) + ), + _SimpleBulkMapping( + header=_StringTable.AssetGroupTargetConditionOperator1, + field_to_csv=lambda c: c.target_condition_operator1, + csv_to_field=lambda c, v: setattr(c, 'target_condition_operator1', v) + ), + _SimpleBulkMapping( + header=_StringTable.AssetGroupTargetConditionOperator2, + field_to_csv=lambda c: c.target_condition_operator2, + csv_to_field=lambda c, v: setattr(c, 'target_condition_operator2', v) + ),_SimpleBulkMapping( + header=_StringTable.AssetGroupTargetConditionOperator3, + field_to_csv=lambda c: c.target_condition_operator3, + csv_to_field=lambda c, v: setattr(c, 'target_condition_operator3', v) + ), + _SimpleBulkMapping( + header=_StringTable.AssetGroupTargetValue1, + field_to_csv=lambda c: c.target_value1, + csv_to_field=lambda c, v: setattr(c, 'target_value1', v) + ), + _SimpleBulkMapping( + header=_StringTable.AssetGroupTargetValue2, + field_to_csv=lambda c: c.target_value2, + csv_to_field=lambda c, v: setattr(c, 'target_value2', v) + ),_SimpleBulkMapping( + header=_StringTable.AssetGroupTargetValue3, + field_to_csv=lambda c: c.target_value3, + csv_to_field=lambda c, v: setattr(c, 'target_value3', v) + ), + ] + + + def process_mappings_from_row_values(self, row_values): + row_values.convert_to_entity(self, BulkAssetGroupUrlTarget._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self.convert_to_values(row_values, BulkAssetGroupUrlTarget._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAssetGroupUrlTarget, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_audience_group.py b/bingads/v13/bulk/entities/bulk_audience_group.py new file mode 100644 index 00000000..dcdd9b4c --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_audience_group.py @@ -0,0 +1,148 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping +from bingads.v13.internal.extensions import * + +class BulkAudienceGroup(_SingleRecordBulkEntity): + """ Represents an audience group. + + This class exposes the property :attr:`audience_group` that can be read and written as fields of the Audience Group record + in a bulk file. + + For more information, see Audience Group at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, account_id=None, status=None, audience_group=None, audience_ids=None): + super(BulkAudienceGroup, self).__init__() + + self._account_id = account_id + self._audience_group = audience_group + self._status = status + self._audience_ids = audience_ids + self._age_ranges = None + self._gender_types = None + + @property + def status(self): + return self._status + + @status.setter + def status(self, status): + self._status = status + + @property + def audience_ids(self): + return self._audience_ids + + @audience_ids.setter + def audience_ids(self, audience_ids): + self._audience_ids = audience_ids + + @property + def age_ranges(self): + return self._age_ranges + + @age_ranges.setter + def age_ranges(self, age_ranges): + self._age_ranges = age_ranges + + @property + def gender_types(self): + return self._gender_types + + @gender_types.setter + def gender_types(self, gender_types): + self._gender_types = gender_types + + @property + def account_id(self): + """ The identifier of the account that contains the audience group. + + Corresponds to the 'Parent Id' field in the bulk file. + + :rtype: int + """ + + return self._account_id + + @account_id.setter + def account_id(self, account_id): + self._account_id = account_id + + @property + def audience_group(self): + """ The AudienceGroup Data Object of the Campaign Management Service. + + A subset of AudienceGroup properties are available in the Audience Group record. + For more information, see Ad Group at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._audience_group + + @audience_group.setter + def audience_group(self, audience_group): + self._audience_group = audience_group + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.audience_group.Id), + csv_to_field=lambda c, v: setattr(c.audience_group, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.status), + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _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) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AudienceGroupName, + field_to_csv=lambda c: c.audience_group.Name, + csv_to_field=lambda c, v: setattr(c.audience_group, 'Name', v) + ), + _SimpleBulkMapping( + header=_StringTable.Audiences, + field_to_csv=lambda c: field_to_csv_AudienceIds(c), + csv_to_field=lambda c, v: csv_to_field_AudienceIds(c, v) + ), + _SimpleBulkMapping( + header=_StringTable.AgeRanges, + field_to_csv=lambda c: field_to_csv_AgeRanges(c), + csv_to_field=lambda c, v: csv_to_field_AgeRanges(c, v) + ), + _SimpleBulkMapping( + header=_StringTable.GenderTypes, + field_to_csv=lambda c: field_to_csv_GenderTypes(c), + csv_to_field=lambda c, v: csv_to_field_GenderTypes(c, v) + ), + _SimpleBulkMapping( + header=_StringTable.Description, + field_to_csv=lambda c: bulk_str(c.audience_group.Description), + csv_to_field=lambda c, v: setattr(c.audience_group, 'Description', v) + ), + ] + + + def process_mappings_from_row_values(self, row_values): + self.audience_group = _CAMPAIGN_OBJECT_FACTORY_V13.create('AudienceGroup') + + row_values.convert_to_entity(self, BulkAudienceGroup._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._audience_group, 'AudienceGroup') + self.convert_to_values(row_values, BulkAudienceGroup._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAudienceGroup, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_audience_group_asset_group_association.py b/bingads/v13/bulk/entities/bulk_audience_group_asset_group_association.py new file mode 100644 index 00000000..95e5af7c --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_audience_group_asset_group_association.py @@ -0,0 +1,108 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping +from bingads.v13.internal.extensions import * + +class BulkAudienceGroupAssetGroupAssociation(_SingleRecordBulkEntity): + """ Represents an audience group asset group association. + + This class exposes the property :attr:`audience_group_asset_group_association` that can be read and written as fields of the audience group asset group association record + in a bulk file. + + For more information, see audience group asset group association at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, status=None, audience_group_asset_group_association=None): + super(BulkAudienceGroupAssetGroupAssociation, self).__init__() + + self._status = status + self._audience_group_asset_group_association = audience_group_asset_group_association + self._asset_group_name = None + self._campaign_name = None + + @property + def status(self): + return self._status + + @status.setter + def status(self, status): + self._status = status + + @property + def asset_group_name(self): + return self._asset_group_name + + @asset_group_name.setter + def asset_group_name(self, asset_group_name): + self._asset_group_name = asset_group_name + + @property + def campaign_name(self): + return self._campaign_name + + @campaign_name.setter + def campaign_name(self, campaign_name): + self._campaign_name = campaign_name + + @property + def audience_group_asset_group_association(self): + """ The AudienceGroupAssetGroupAssociation Data Object of the Campaign Management Service. + + A subset of AudienceGroupAssetGroupAssociation properties are available in the Ad Group record. + For more information, see Ad Group at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._audience_group_asset_group_association + + @audience_group_asset_group_association.setter + def audience_group_asset_group_association(self, audience_group_asset_group_association): + self._audience_group_asset_group_association = audience_group_asset_group_association + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.audience_group_asset_group_association.AudienceGroupId), + csv_to_field=lambda c, v: setattr(c.audience_group_asset_group_association, 'AudienceGroupId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.status), + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.audience_group_asset_group_association.AssetGroupId), + csv_to_field=lambda c, v: setattr(c.audience_group_asset_group_association, 'AssetGroupId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AssetGroup, + field_to_csv=lambda c: c.asset_group_name, + csv_to_field=lambda c, v: setattr(c, 'asset_group_name', v) + ), + _SimpleBulkMapping( + header=_StringTable.Campaign, + field_to_csv=lambda c: c.campaign_name, + csv_to_field=lambda c, v: setattr(c, 'campaign_name', v) + ), + ] + + + def process_mappings_from_row_values(self, row_values): + self.audience_group_asset_group_association = _CAMPAIGN_OBJECT_FACTORY_V13.create('AudienceGroupAssetGroupAssociation') + + row_values.convert_to_entity(self, BulkAudienceGroupAssetGroupAssociation._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._audience_group_asset_group_association, 'AudienceGroupAssetGroupAssociation') + self.convert_to_values(row_values, BulkAudienceGroupAssetGroupAssociation._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAudienceGroupAssetGroupAssociation, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_brand_item.py b/bingads/v13/bulk/entities/bulk_brand_item.py new file mode 100644 index 00000000..30a93fcb --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_brand_item.py @@ -0,0 +1,207 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkBrandItem(_SingleRecordBulkEntity): + """ Represents a brand item. + + This class exposes the property :attr:`brand_item` that can be read and written as fields of the brand item record + in a bulk file. + + For more information, see brand item at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, id=None, brand_list_id=None, name=None, brand_name=None, brand_url=None, editorial_status=None, editorial_status_date=None, brand_item=None): + super(BulkBrandItem, self).__init__() + + self._id = id + self._brand_list_id = brand_list_id + self._name = name + self._brand_name = brand_name + self._brand_url = brand_url + self._editorial_status = editorial_status + self._editorial_status_date = editorial_status_date + self._brand_item = brand_item + + @property + def brand_item(self): + """ The BrandItem Data Object of the Campaign Management Service. + + A subset of BrandItem properties are available in the Brand Item record. + For more information, see Brand Item at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._brand_item + + @brand_item.setter + def brand_item(self, brand_item): + self._brand_item = brand_item + + @property + def id(self): + """ The identifier of the brand item. + + Corresponds to the 'Id' field in the bulk file. + + :rtype: int + """ + + return self._id + + @id.setter + def id(self, id): + self._id = id + + @property + def brand_list_id(self): + """ The identifier of the brand list that contains the brand item. + + Corresponds to the 'Parent Id' field in the bulk file. + + :rtype: int + """ + + return self._brand_list_id + + @brand_list_id.setter + def brand_list_id(self, brand_list_id): + self._brand_list_id = brand_list_id + + @property + def name(self): + """ The name of the brand item. + + Corresponds to the 'Name' field in the bulk file. + + :rtype: str + """ + + return self._name + + @name.setter + def name(self, name): + self._name = name + + @property + def brand_name(self): + """ The name of the brand. + + Corresponds to the 'Brand Name' field in the bulk file. + + :rtype: str + """ + + return self._brand_name + + @brand_name.setter + def brand_name(self, brand_name): + self._brand_name = brand_name + + @property + def brand_url(self): + """ The url of the brand. + + Corresponds to the 'Brand Url' field in the bulk file. + + :rtype: str + """ + + return self._brand_url + + @brand_url.setter + def brand_url(self, brand_url): + self._brand_url = brand_url + + @property + def editorial_status(self): + """ The editorial status + + Corresponds to the 'Editorial Status' field in the bulk file. + + :rtype: str + """ + + return self._editorial_status + + @editorial_status.setter + def editorial_status(self, editorial_status): + self._editorial_status = editorial_status + + @property + def editorial_status_date(self): + """ The editorial status date + + Corresponds to the 'Editorial Status Date' field in the bulk file. + + :rtype: str + """ + + return self._editorial_status_date + + @editorial_status_date.setter + def editorial_status_date(self, editorial_status_date): + self._editorial_status_date = editorial_status_date + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.id), + csv_to_field=lambda c, v: setattr(c, 'id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Name, + field_to_csv=lambda c: bulk_str(c.name), + csv_to_field=lambda c, v: setattr(c, 'name', v) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.brand_list_id), + csv_to_field=lambda c, v: setattr(c, 'brand_list_id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.BrandId, + field_to_csv=lambda c: bulk_str(c.brand_item.BrandId), + csv_to_field=lambda c, v: setattr(c.brand_item, 'BrandId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.BrandName, + field_to_csv=lambda c: bulk_str(c.brand_name), + csv_to_field=lambda c, v: setattr(c, 'brand_name', v) + ), + _SimpleBulkMapping( + header=_StringTable.BrandUrl, + field_to_csv=lambda c: bulk_str(c.brand_url), + csv_to_field=lambda c, v: setattr(c, 'brand_url', v) + ), + _SimpleBulkMapping( + header=_StringTable.EditorialStatus, + field_to_csv=lambda c: bulk_str(c.editorial_status), + csv_to_field=lambda c, v: setattr(c, 'editorial_status', v) + ), + _SimpleBulkMapping( + header=_StringTable.StatusDateTime, + field_to_csv=lambda c: bulk_datetime_str2(c.editorial_status_date), + csv_to_field=lambda c, v: setattr(c, 'editorial_status_date', parse_datetime2(v)) + ), + ] + + def process_mappings_from_row_values(self, row_values): + self.brand_item = _CAMPAIGN_OBJECT_FACTORY_V13.create('BrandItem') + + row_values.convert_to_entity(self, BulkBrandItem._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.brand_item, 'BrandItem') + self.convert_to_values(row_values, BulkBrandItem._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkBrandItem, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_brand_list.py b/bingads/v13/bulk/entities/bulk_brand_list.py new file mode 100644 index 00000000..ae0c9964 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_brand_list.py @@ -0,0 +1,88 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkBrandList(_SingleRecordBulkEntity): + """ Represents a campaign brand list association. + + This class exposes the property :attr:`campaign_brand_list_association` that can be read and written as fields of the campaign brand list association record + in a bulk file. + + For more information, see campaign brand list association at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, account_id=None, brand_list=None): + super(BulkBrandList, self).__init__() + + self._account_id = account_id + self._brand_list = brand_list + + @property + def brand_list(self): + """ The BrandList Data Object of the Campaign Management Service. + + A subset of BrandList properties are available in the Brand List record. + For more information, see Brand Item at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._brand_list + + @brand_list.setter + def brand_list(self, brand_list): + self._brand_list = brand_list + + @property + def account_id(self): + """ The identifier of the account that contains the brand list. + + Corresponds to the 'Parent Id' field in the bulk file. + + :rtype: int + """ + + return self._account_id + + @account_id.setter + def account_id(self, account_id): + self._account_id = account_id + + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.brand_list.Id), + csv_to_field=lambda c, v: setattr(c.brand_list, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Name, + field_to_csv=lambda c: bulk_str(c.brand_list.Name), + csv_to_field=lambda c, v: setattr(c.brand_list, 'Name', 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) if v else None) + ), + + ] + + def process_mappings_from_row_values(self, row_values): + self.brand_list = _CAMPAIGN_OBJECT_FACTORY_V13.create('BrandList') + + row_values.convert_to_entity(self, BulkBrandList._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.brand_list, 'BrandList') + self.convert_to_values(row_values, BulkBrandList._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkBrandList, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_campaign.py b/bingads/v13/bulk/entities/bulk_campaign.py index 90ac4576..0cd6f0c4 100644 --- a/bingads/v13/bulk/entities/bulk_campaign.py +++ b/bingads/v13/bulk/entities/bulk_campaign.py @@ -4,11 +4,16 @@ from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping from bingads.v13.internal.extensions import * +from decimal import Decimal _DynamicFeedSetting = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('DynamicFeedSetting')) _TargetSetting = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('TargetSetting')) _ShoppingSetting = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('ShoppingSetting')) _DsaSetting = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('DynamicSearchAdsSetting')) +_DisclaimerSetting = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('DisclaimerSetting')) +_VerifiedTrackingSetting = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('VerifiedTrackingSetting')) +_PerformanceMaxSetting = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('PerformanceMaxSetting')) +_NewCustomerAcquisitionGoalSetting = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('NewCustomerAcquisitionGoalSetting')) class BulkCampaign(_SingleRecordBulkEntity): """ Represents a campaign that can be read or written in a bulk file. @@ -35,6 +40,10 @@ def __init__(self, account_id=None, campaign=None): self._performance_data = None self._budget_name = None self._bid_strategy_name = None + self._verified_tracking_data = None + self._destination_channel = None + self._is_multi_channel_campaign = None + self._should_serve_on_msan = None @property def account_id(self): @@ -50,7 +59,7 @@ def account_id(self): @account_id.setter def account_id(self, account_id): self._account_id = account_id - + @property def bid_strategy_name(self): """ @@ -65,6 +74,20 @@ def bid_strategy_name(self): def bid_strategy_name(self, value): self._bid_strategy_name = value + @property + def verified_tracking_data(self): + """ + The verified tracking data that the campaign associated, only for audience campaigns + + Corresponds to 'Verified Tracking Setting' field in bulk file. + :rtype: ArrayOfArrayOfKeyValuePairOfstringstring + """ + return self._verified_tracking_data + + @verified_tracking_data.setter + def verified_tracking_data(self, value): + self._verified_tracking_data = value + @property def budget_name(self): """ @@ -101,25 +124,63 @@ def quality_score_data(self): return self._quality_score_data + @property + def destination_channel(self): + return self._destination_channel + + @destination_channel.setter + def destination_channel(self, value): + self._destination_channel = value + + @property + def is_multi_channel_campaign(self): + return self._is_multi_channel_campaign + + @is_multi_channel_campaign.setter + def is_multi_channel_campaign(self, value): + self._is_multi_channel_campaign = value + + @property + def should_serve_on_msan(self): + return self._should_serve_on_msan + + @should_serve_on_msan.setter + def should_serve_on_msan(self, value): + self._should_serve_on_msan = value + def _get_dynamic_feed_setting(self): return self._get_setting(_DynamicFeedSetting, 'DynamicFeedSetting') def _get_shopping_setting(self): return self._get_setting(_ShoppingSetting, 'ShoppingSetting') - + def _get_target_setting(self): return self._get_setting(_TargetSetting, 'TargetSetting') - + def _get_dsa_setting(self): return self._get_setting(_DsaSetting, 'DynamicSearchAdsSetting') - + + def _get_disclaimer_setting(self): + return self._get_setting(_DisclaimerSetting, 'DisclaimerSetting') + + def _get_verified_tracking_setting(self): + return self._get_setting(_VerifiedTrackingSetting, 'VerifiedTrackingSetting') + + def _get_performance_max_setting(self): + return self._get_setting(_PerformanceMaxSetting, 'PerformanceMaxSetting') + + def _get_new_customer_acquisition_goal_setting(self): + return self._get_setting(_NewCustomerAcquisitionGoalSetting, 'NewCustomerAcquisitionGoalSetting') + def _get_setting(self, setting_type, setting_name): if not self.campaign.Settings.Setting: return None settings = [setting for setting in self.campaign.Settings.Setting if isinstance(setting, setting_type)] - if len(settings) != 1: - raise ValueError('Can only have 1 ' + setting_name + ' in Campaign Settings.') + if len(settings) > 1: + raise ValueError('Can only have 1 ' + setting_name + ' at most in Campaign Settings.') + elif len(settings) == 0: + return None return settings[0] @staticmethod @@ -136,24 +197,52 @@ def _read_campaign_type(c, v): return [] campaign_type = v c.campaign.CampaignType = [campaign_type] - + if campaign_type.lower() == 'shopping': BulkCampaign._create_campaign_setting(c.campaign, 'ShoppingSetting') if campaign_type.lower() == 'audience': BulkCampaign._create_campaign_setting(c.campaign, 'DynamicFeedSetting') BulkCampaign._create_campaign_setting(c.campaign, 'ShoppingSetting') + BulkCampaign._create_campaign_setting(c.campaign, 'VerifiedTrackingSetting') if campaign_type.lower() == 'dynamicsearchads' or campaign_type.lower() == 'search': BulkCampaign._create_campaign_setting(c.campaign, 'DynamicSearchAdsSetting') + BulkCampaign._create_campaign_setting(c.campaign, 'DisclaimerSetting') + if campaign_type.lower() == 'performancemax': + BulkCampaign._create_campaign_setting(c.campaign, 'PerformanceMaxSetting') + BulkCampaign._create_campaign_setting(c.campaign, 'ShoppingSetting') + BulkCampaign._create_campaign_setting(c.campaign, 'NewCustomerAcquisitionGoalSetting') @staticmethod def _create_campaign_setting(campaign, setting_type): if not campaign.Settings: campaign.Settings = _CAMPAIGN_OBJECT_FACTORY_V13.create('ArrayOfSetting') - + setting = _CAMPAIGN_OBJECT_FACTORY_V13.create(setting_type) setting.Type = setting_type campaign.Settings.Setting.append(setting) + @staticmethod + def _write_final_url_expansion_opt_out(c): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + performance_max_setting = c._get_performance_max_setting() + if not performance_max_setting: + return None + return bulk_str(performance_max_setting.FinalUrlExpansionOptOut) + + @staticmethod + def _read_final_url_expansion_opt_out(c, v): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + performance_max_setting = c._get_performance_max_setting() + if not performance_max_setting: + return None + performance_max_setting.FinalUrlExpansionOptOut = parse_bool(v) + @staticmethod def _write_store_id(c): if not c.campaign.CampaignType: @@ -241,7 +330,7 @@ def _read_local_inventory_ads_enabled(c, v): if not shopping_setting: return None shopping_setting.LocalInventoryAdsEnabled = v.lower() == 'true' if v else None - + @staticmethod def _write_feed_id(c): if not c.campaign.CampaignType: @@ -252,7 +341,7 @@ def _write_feed_id(c): if not dynamic_feed_setting: return None return bulk_str(dynamic_feed_setting.FeedId) - + @staticmethod def _read_feed_id(c, v): if not c.campaign.CampaignType: @@ -263,95 +352,267 @@ def _read_feed_id(c, v): if not dynamic_feed_setting: return None dynamic_feed_setting.FeedId = int(v) if v else None - + @staticmethod def _read_source(c, v): if not c.campaign.CampaignType: return None campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] - if 'dynamicsearchads' in campgaign_types: - dsa_setting = c._get_dsa_setting() - if not dsa_setting: - return None - dsa_setting.Source = v + dsa_setting = c._get_dsa_setting() + if not dsa_setting: + return None + dsa_setting.Source = v @staticmethod def _write_source(c): if not c.campaign.CampaignType: return None campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] - if 'dynamicsearchads' in campgaign_types: - dsa_setting = c._get_dsa_setting() - if not dsa_setting: - return None - return bulk_str(dsa_setting.Source) + dsa_setting = c._get_dsa_setting() + if not dsa_setting: + return None + return bulk_str(dsa_setting.Source) @staticmethod def _read_domain_language(c, v): if not c.campaign.CampaignType: return None campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] - if 'dynamicsearchads' in campgaign_types: - dsa_setting = c._get_dsa_setting() - if not dsa_setting: - return None - dsa_setting.Language = v + dsa_setting = c._get_dsa_setting() + if not dsa_setting: + return None + dsa_setting.Language = v @staticmethod def _write_domain_language(c): if not c.campaign.CampaignType: return None campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] - if 'dynamicsearchads' in campgaign_types: - dsa_setting = c._get_dsa_setting() - if not dsa_setting: - return None - return bulk_str(dsa_setting.Language) + dsa_setting = c._get_dsa_setting() + if not dsa_setting: + return None + return bulk_str(dsa_setting.Language) + + @staticmethod + def _read_DisclaimerAdsEnabled(c, v): + if not c.campaign.CampaignType: + return None + disclaimer_setting = c._get_disclaimer_setting() + if not disclaimer_setting: + return None + disclaimer_setting.DisclaimerAdsEnabled = parse_bool(v) + + @staticmethod + def _write_DisclaimerAdsEnabled(c): + if not c.campaign.CampaignType: + return None + disclaimer_setting = c._get_disclaimer_setting() + if not disclaimer_setting: + return None + return bulk_str(disclaimer_setting.DisclaimerAdsEnabled) + + @staticmethod + def _read_DynamicDescriptionEnabled(c, v): + if not c.campaign.CampaignType: + return None + dsa_setting = c._get_dsa_setting() + if not dsa_setting: + return None + dsa_setting.DynamicDescriptionEnabled = parse_bool(v) + + @staticmethod + def _write_DynamicDescriptionEnabled(c): + if not c.campaign.CampaignType: + return None + dsa_setting = c._get_dsa_setting() + if not dsa_setting: + return None + return bulk_str(dsa_setting.DynamicDescriptionEnabled) @staticmethod def _read_page_feed_ids(c, v): if not c.campaign.CampaignType: return None campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] - if 'dynamicsearchads' in campgaign_types: + if 'performancemax' in campgaign_types: + performance_max_setting = c._get_performance_max_setting() + if not performance_max_setting: + return None + performance_max_setting.PageFeedIds.long = csv_to_field_PageFeedIds(v) + else: dsa_setting = c._get_dsa_setting() if not dsa_setting: return None dsa_setting.PageFeedIds.long = csv_to_field_PageFeedIds(v) - + @staticmethod def _write_page_feed_ids(c): if not c.campaign.CampaignType: return None campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] - if 'dynamicsearchads' in campgaign_types: + if 'performancemax' in campgaign_types: + performance_max_setting = c._get_performance_max_setting() + if not performance_max_setting: + return None + return field_to_csv_Ids(performance_max_setting.PageFeedIds, c.campaign.Id) + else: dsa_setting = c._get_dsa_setting() if not dsa_setting: return None - return field_to_csv_Ids(dsa_setting.PageFeedIds, c.campaign.Id) + return field_to_csv_Ids(dsa_setting.PageFeedIds, c.campaign.Id) @staticmethod - def _read_website(c, v): + def _read_text_opt_out(c, v): if not c.campaign.CampaignType: return None campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] - if 'dynamicsearchads' in campgaign_types: - dsa_setting = c._get_dsa_setting() - if not dsa_setting: + if 'performancemax' in campgaign_types: + performance_max_setting = c._get_performance_max_setting() + if not performance_max_setting: return None - dsa_setting.DomainName = v + performance_max_setting.AutoGeneratedTextOptOut = parse_bool(v) @staticmethod - def _write_website(c): + def _write_text_opt_out(c): if not c.campaign.CampaignType: return None campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] - if 'dynamicsearchads' in campgaign_types: - dsa_setting = c._get_dsa_setting() - if not dsa_setting: + if 'performancemax' in campgaign_types: + performance_max_setting = c._get_performance_max_setting() + if not performance_max_setting: return None - return bulk_str(dsa_setting.DomainName) - + return bulk_str(performance_max_setting.AutoGeneratedTextOptOut) + + @staticmethod + def _read_cost_per_sale_opt_out(c, v): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + performance_max_setting = c._get_performance_max_setting() + if not performance_max_setting: + return None + performance_max_setting.CostPerSaleOptOut = parse_bool(v) + + @staticmethod + def _write_cost_per_sale_opt_out(c): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + performance_max_setting = c._get_performance_max_setting() + if not performance_max_setting: + return None + return bulk_str(performance_max_setting.CostPerSaleOptOut) + + @staticmethod + def _read_image_opt_out(c, v): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + performance_max_setting = c._get_performance_max_setting() + if not performance_max_setting: + return None + performance_max_setting.AutoGeneratedImageOptOut = parse_bool(v) + + @staticmethod + def _write_image_opt_out(c): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + performance_max_setting = c._get_performance_max_setting() + if not performance_max_setting: + return None + return bulk_str(performance_max_setting.AutoGeneratedImageOptOut) + + @staticmethod + def _read_new_customer_acquisition_bid_only_mode(c, v): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + new_customer_acquisition_goal_setting = c._get_new_customer_acquisition_goal_setting() + if not new_customer_acquisition_goal_setting: + return None + new_customer_acquisition_goal_setting.NewCustomerAcquisitionBidOnlyMode = parse_bool(v) + + @staticmethod + def _write_new_customer_acquisition_bid_only_mode(c): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + new_customer_acquisition_goal_setting = c._get_new_customer_acquisition_goal_setting() + if not new_customer_acquisition_goal_setting: + return None + return bulk_str(new_customer_acquisition_goal_setting.NewCustomerAcquisitionBidOnlyMode) + + @staticmethod + def _read_new_customer_acquisition_goal_id(c, v): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + new_customer_acquisition_goal_setting = c._get_new_customer_acquisition_goal_setting() + if not new_customer_acquisition_goal_setting: + return None + new_customer_acquisition_goal_setting.NewCustomerAcquisitionGoalId = int(v) if v else None + + @staticmethod + def _write_new_customer_acquisition_goal_id(c): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + new_customer_acquisition_goal_setting = c._get_new_customer_acquisition_goal_setting() + if not new_customer_acquisition_goal_setting: + return None + return bulk_str(new_customer_acquisition_goal_setting.NewCustomerAcquisitionGoalId) + + @staticmethod + def _read_additional_conversion_value(c, v): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + new_customer_acquisition_goal_setting = c._get_new_customer_acquisition_goal_setting() + if not new_customer_acquisition_goal_setting: + return None + new_customer_acquisition_goal_setting.AdditionalConversionValue = Decimal(v) if v else None + + @staticmethod + def _write_additional_conversion_value(c): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + if 'performancemax' in campgaign_types: + new_customer_acquisition_goal_setting = c._get_new_customer_acquisition_goal_setting() + if not new_customer_acquisition_goal_setting: + return None + return bulk_str(new_customer_acquisition_goal_setting.AdditionalConversionValue) + + @staticmethod + def _read_website(c, v): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + dsa_setting = c._get_dsa_setting() + if not dsa_setting: + return None + dsa_setting.DomainName = v + + @staticmethod + def _write_website(c): + if not c.campaign.CampaignType: + return None + campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType] + dsa_setting = c._get_dsa_setting() + if not dsa_setting: + return None + return bulk_str(dsa_setting.DomainName) + _MAPPINGS = [ _SimpleBulkMapping( header=_StringTable.CampaignType, @@ -361,11 +622,7 @@ def _write_website(c): _SimpleBulkMapping( header=_StringTable.Status, field_to_csv=lambda c: bulk_str(c.campaign.Status), - csv_to_field=lambda c, v: setattr( - c.campaign, - 'Status', - v if v else None - ) + csv_to_field=lambda c, v: csv_to_field_enum(c.campaign, v, 'Status', CampaignStatus) ), _SimpleBulkMapping( header=_StringTable.Id, @@ -406,6 +663,11 @@ def _write_website(c): int(v) if v else None ) ), + _SimpleBulkMapping( + header=_StringTable.FinalUrlExpansionOptOut, + field_to_csv=lambda c: BulkCampaign._write_final_url_expansion_opt_out(c), + csv_to_field=lambda c, v: BulkCampaign._read_final_url_expansion_opt_out(c, v) + ), _SimpleBulkMapping( header=_StringTable.MerchantCenterId, field_to_csv=lambda c: BulkCampaign._write_store_id(c), @@ -428,7 +690,7 @@ def _write_website(c): ), _SimpleBulkMapping( header=_StringTable.TrackingTemplate, - field_to_csv=lambda c: bulk_str(c.campaign.TrackingUrlTemplate), + field_to_csv=lambda c: bulk_optional_str(c.campaign.TrackingUrlTemplate, c.campaign.Id), csv_to_field=lambda c, v: setattr(c.campaign, 'TrackingUrlTemplate', v if v else None) ), _SimpleBulkMapping( @@ -466,7 +728,7 @@ def _write_website(c): header=_StringTable.Website, field_to_csv=lambda c: BulkCampaign._write_website(c), csv_to_field=lambda c, v: BulkCampaign._read_website(c, v) - + ), _SimpleBulkMapping( header=_StringTable.DomainLanguage, @@ -507,12 +769,81 @@ def _write_website(c): header=_StringTable.PageFeedIds, field_to_csv=lambda c: BulkCampaign._write_page_feed_ids(c), csv_to_field=lambda c, v: BulkCampaign._read_page_feed_ids(c, v) - ), + ), _SimpleBulkMapping( header=_StringTable.AdScheduleUseSearcherTimeZone, field_to_csv=lambda c: field_to_csv_UseSearcherTimeZone(c.campaign.AdScheduleUseSearcherTimeZone, None), csv_to_field=lambda c, v: setattr(c.campaign, 'AdScheduleUseSearcherTimeZone', parse_bool(v)) ), + _SimpleBulkMapping( + header=_StringTable.MultiMediaAdBidAdjustment, + field_to_csv=lambda c: bulk_str(c.campaign.MultimediaAdsBidAdjustment), + csv_to_field=lambda c, v: setattr( + c.campaign, + 'MultimediaAdsBidAdjustment', + int(v) if v else None + ) + ), + _SimpleBulkMapping( + header=_StringTable.DisclaimerAdsEnabled, + field_to_csv=lambda c: BulkCampaign._write_DisclaimerAdsEnabled(c), + csv_to_field=lambda c, v: BulkCampaign._read_DisclaimerAdsEnabled(c, v) + ), + _SimpleBulkMapping( + header=_StringTable.DynamicDescriptionEnabled, + field_to_csv=lambda c: BulkCampaign._write_DynamicDescriptionEnabled(c), + csv_to_field=lambda c, v: BulkCampaign._read_DynamicDescriptionEnabled(c, v) + ), + _SimpleBulkMapping( + header=_StringTable.DestinationChannel, + field_to_csv=lambda c: c.destination_channel, + csv_to_field=lambda c, v: setattr(c, 'destination_channel', v) + ), + _SimpleBulkMapping( + header=_StringTable.IsMultiChannelCampaign, + field_to_csv=lambda c: field_to_csv_bool(c.is_multi_channel_campaign), + csv_to_field=lambda c, v: setattr(c, 'is_multi_channel_campaign', parse_bool(v)) + ), + _SimpleBulkMapping( + header=_StringTable.AutoGeneratedTextOptOut, + field_to_csv=lambda c: BulkCampaign._write_text_opt_out(c), + csv_to_field=lambda c, v: BulkCampaign._read_text_opt_out(c, v) + ), + _SimpleBulkMapping( + header=_StringTable.AutoGeneratedImageOptOut, + field_to_csv=lambda c: BulkCampaign._write_image_opt_out(c), + csv_to_field=lambda c, v: BulkCampaign._read_image_opt_out(c, v) + ), + _SimpleBulkMapping( + header=_StringTable.CostPerSaleOptOut, + field_to_csv=lambda c: BulkCampaign._write_cost_per_sale_opt_out(c), + csv_to_field=lambda c, v: BulkCampaign._read_cost_per_sale_opt_out(c, v) + ), + _SimpleBulkMapping( + header=_StringTable.ShouldServeOnMSAN, + field_to_csv=lambda c: field_to_csv_bool(c.should_serve_on_msan), + csv_to_field=lambda c, v: setattr(c, 'should_serve_on_msan', parse_bool(v)) + ), + _SimpleBulkMapping( + header=_StringTable.NewCustomerAcquisitionGoalId, + field_to_csv=lambda c: BulkCampaign._write_new_customer_acquisition_goal_id(c), + csv_to_field=lambda c, v: BulkCampaign._read_new_customer_acquisition_goal_id(c, v) + ), + _SimpleBulkMapping( + header=_StringTable.NewCustomerAcquisitionBidOnlyMode, + field_to_csv=lambda c: BulkCampaign._write_new_customer_acquisition_bid_only_mode(c), + csv_to_field=lambda c, v: BulkCampaign._read_new_customer_acquisition_bid_only_mode(c, v) + ), + _SimpleBulkMapping( + header=_StringTable.AdditionalConversionValue, + field_to_csv=lambda c: BulkCampaign._write_additional_conversion_value(c), + csv_to_field=lambda c, v: BulkCampaign._read_additional_conversion_value(c, v) + ), + _SimpleBulkMapping( + header=_StringTable.IsPolitical, + field_to_csv=lambda c: field_to_csv_bool(c.campaign.IsPolitical), + csv_to_field=lambda c, v: setattr(c.campaign, 'IsPolitical', parse_bool(v)) + ), ] def read_additional_data(self, stream_reader): diff --git a/bingads/v13/bulk/entities/bulk_campaign_brand_list_association.py b/bingads/v13/bulk/entities/bulk_campaign_brand_list_association.py new file mode 100644 index 00000000..36da8e8c --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_campaign_brand_list_association.py @@ -0,0 +1,120 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkCampaignBrandListAssociation(_SingleRecordBulkEntity): + """ Represents a campaign brand list association. + + This class exposes the property :attr:`campaign_brand_list_association` that can be read and written as fields of the campaign brand list association record + in a bulk file. + + For more information, see campaign brand list association at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, id=None, campaign_id=None, name=None, is_excluded=None): + super(BulkCampaignBrandListAssociation, self).__init__() + + self._id = id + self._campaign_id = campaign_id + self._name = name + self._is_excluded = is_excluded + + @property + def id(self): + """ The identifier of the campaign brand list association. + + Corresponds to the 'Id' field in the bulk file. + + :rtype: int + """ + + return self._id + + @id.setter + def id(self, id): + self._id = id + + @property + def campaign_id(self): + """ The identifier of the campaign that contains the brand list association. + + Corresponds to the 'Parent Id' field in the bulk file. + + :rtype: int + """ + + return self._campaign_id + + @campaign_id.setter + def campaign_id(self, campaign_id): + self._campaign_id = campaign_id + + @property + def name(self): + """ The name of the brand list association. + + Corresponds to the 'Name' field in the bulk file. + + :rtype: str + """ + + return self._name + + @name.setter + def name(self, name): + self._name = name + + @property + def is_excluded(self): + """ Corresponds to the 'Is Excluded' field in the bulk file. + + :rtype: bool + """ + + return self._is_excluded + + @is_excluded.setter + def is_excluded(self, is_excluded): + self._is_excluded = is_excluded + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.id), + csv_to_field=lambda c, v: setattr(c, 'id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Name, + field_to_csv=lambda c: bulk_str(c.name), + csv_to_field=lambda c, v: setattr(c, 'name', v) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.campaign_id), + csv_to_field=lambda c, v: setattr(c, 'campaign_id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.IsExcluded, + field_to_csv=lambda c: bulk_str(c.is_excluded), + csv_to_field=lambda c, v: setattr(c, 'is_excluded', parse_bool(v)) + ), + ] + + def process_mappings_from_row_values(self, row_values): + row_values.convert_to_entity(self, BulkCampaignBrandListAssociation._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self.convert_to_values(row_values, BulkCampaignBrandListAssociation._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkCampaignBrandListAssociation, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_campaign_conversion_goal.py b/bingads/v13/bulk/entities/bulk_campaign_conversion_goal.py new file mode 100644 index 00000000..0ae398fc --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_campaign_conversion_goal.py @@ -0,0 +1,96 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + + +class BulkCampaignConversionGoal(_SingleRecordBulkEntity): + """ Represents a CampaignConversionGoal. + + Properties of this class and of classes that it is derived from, correspond to fields of the CampaignConversionGoal record in a bulk file. + For more information, see CampaignConversionGoal at https://go.microsoft.com/fwlink/?linkid=846127 + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, campaign_conversion_goal = None, sub_type = None, action_type = None): + super(BulkCampaignConversionGoal, self).__init__() + self._campaign_conversion_goal = campaign_conversion_goal + self._sub_type = sub_type + self._action_type = action_type + + @property + def campaign_conversion_goal(self): + """ define a campaign conversion goal association + + :rtype: CampaignConversionGoal + """ + return self._campaign_conversion_goal + + @campaign_conversion_goal.setter + def campaign_conversion_goal(self, value): + self._campaign_conversion_goal = value + + @property + def sub_type(self): + """ Corresponds to the 'Sub Type' field in the bulk file. + + :rtype: str + """ + return self._sub_type + + @sub_type.setter + def sub_type(self, value): + self._sub_type = value + + @property + def action_type(self): + """ Corresponds to the 'Action Type' field in the bulk file. + + :rtype: str + """ + return self._action_type + + @action_type.setter + def action_type(self, value): + self._action_type = value + + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.campaign_conversion_goal.CampaignId), + csv_to_field=lambda c, v: setattr(c.campaign_conversion_goal, 'CampaignId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.GoalId, + field_to_csv=lambda c: bulk_str(c.campaign_conversion_goal.GoalId), + csv_to_field=lambda c, v: setattr(c.campaign_conversion_goal, 'GoalId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.ActionType, + field_to_csv=lambda c: c.action_type, + csv_to_field=lambda c, v: setattr(c, 'action_type', v) + ), + _SimpleBulkMapping( + header=_StringTable.SubType, + field_to_csv=lambda c: c.sub_type, + csv_to_field=lambda c, v: setattr(c, 'sub_type', v) + ), + ] + + def process_mappings_from_row_values(self, row_values): + self._campaign_conversion_goal = _CAMPAIGN_OBJECT_FACTORY_V13.create('CampaignConversionGoal') + row_values.convert_to_entity(self, BulkCampaignConversionGoal._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self.convert_to_values(row_values, BulkCampaignConversionGoal._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkCampaignConversionGoal, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_campaign_negative_webpage.py b/bingads/v13/bulk/entities/bulk_campaign_negative_webpage.py new file mode 100644 index 00000000..10e5e0c9 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_campaign_negative_webpage.py @@ -0,0 +1,14 @@ +from bingads.v13.bulk.entities.bulk_campaign_negative_dynamic_search_ad_target import BulkCampaignNegativeDynamicSearchAdTarget + +class BulkCampaignNegativeWebpage(BulkCampaignNegativeDynamicSearchAdTarget): + """ Represents an Campaign Negative Webpage that can be read or written in a bulk file. + + For more information, see Campaign Negative Webpage at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ diff --git a/bingads/v13/bulk/entities/bulk_data_exclusion.py b/bingads/v13/bulk/entities/bulk_data_exclusion.py new file mode 100644 index 00000000..d887eab7 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_data_exclusion.py @@ -0,0 +1,95 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkDataExclusion(_SingleRecordBulkEntity): + """ Represents an data exclusion. + + This class exposes the property :attr:`data_exclusion` that can be read and written as fields of the data exclusion record + in a bulk file. + + For more information, see data exclusion at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, data_exclusion=None): + super(BulkDataExclusion, self).__init__() + + self._data_exclusion = data_exclusion + + @property + def data_exclusion(self): + """ The DataExclusion Data Object of the Campaign Management Service. + + A subset of DataExclusion properties are available in the Data Exclusion record. + For more information, see Data Exclusion at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._data_exclusion + + @data_exclusion.setter + def data_exclusion(self, data_exclusion): + self._data_exclusion = data_exclusion + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.data_exclusion.Id), + csv_to_field=lambda c, v: setattr(c.data_exclusion, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.DataExclusion, + field_to_csv=lambda c: bulk_str(c.data_exclusion.Name), + csv_to_field=lambda c, v: setattr(c.data_exclusion, 'Name', v) + ), + _SimpleBulkMapping( + header=_StringTable.StartDate, + field_to_csv=lambda c: bulk_datetime_str2(c.data_exclusion.StartDate), + csv_to_field=lambda c, v: setattr(c.data_exclusion, 'StartDate', parse_datetime2(v)) + ), + _SimpleBulkMapping( + header=_StringTable.EndDate, + field_to_csv=lambda c: bulk_datetime_str2(c.data_exclusion.EndDate), + csv_to_field=lambda c, v: setattr(c.data_exclusion, 'EndDate', parse_datetime2(v)) + ), + _SimpleBulkMapping( + header=_StringTable.Description, + field_to_csv=lambda c: c.data_exclusion.Description, + csv_to_field=lambda c, v: setattr(c.data_exclusion, 'Description', v) + ), + _SimpleBulkMapping( + header=_StringTable.CampaignType, + field_to_csv=lambda c: field_to_csv_CampaignType(c.data_exclusion), + csv_to_field=lambda c, v: csv_to_field_CampaignType(c.data_exclusion, v) + ), + _SimpleBulkMapping( + header=_StringTable.DeviceType, + field_to_csv=lambda c: field_to_csv_DeviceType(c.data_exclusion), + csv_to_field=lambda c, v: csv_to_field_DeviceType(c.data_exclusion, v) + ), + _SimpleBulkMapping( + header=_StringTable.CampaignAssociations, + field_to_csv=lambda c: field_to_csv_CampaignAssociations(c.data_exclusion), + csv_to_field=lambda c, v: csv_to_field_CampaignAssociations(c.data_exclusion, v) + ), + ] + + def process_mappings_from_row_values(self, row_values): + self.data_exclusion = _CAMPAIGN_OBJECT_FACTORY_V13.create('DataExclusion') + + row_values.convert_to_entity(self, BulkDataExclusion._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._data_exclusion, 'DataExclusion') + self.convert_to_values(row_values, BulkDataExclusion._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkDataExclusion, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_entity.py b/bingads/v13/bulk/entities/bulk_entity.py index 3554257c..c6935c1c 100644 --- a/bingads/v13/bulk/entities/bulk_entity.py +++ b/bingads/v13/bulk/entities/bulk_entity.py @@ -1,12 +1,11 @@ from abc import ABCMeta, abstractproperty -from future.utils import with_metaclass from bingads.internal.error_messages import _ErrorMessages from bingads.v13.internal.bulk.bulk_object import _BulkObject -class BulkEntity(with_metaclass(ABCMeta, _BulkObject)): +class BulkEntity(_BulkObject, metaclass=ABCMeta): """ The abstract base class for all bulk entities that can be read or written in a bulk file. For more information, see Bulk File Schema at https://go.microsoft.com/fwlink/?linkid=846127. diff --git a/bingads/v13/bulk/entities/bulk_keyword.py b/bingads/v13/bulk/entities/bulk_keyword.py index 9b727921..a7776384 100644 --- a/bingads/v13/bulk/entities/bulk_keyword.py +++ b/bingads/v13/bulk/entities/bulk_keyword.py @@ -27,7 +27,7 @@ def csv_to_bidding_scheme(row_values, bulk_keyword): if success and inherited_bid_strategy_type != '': bulk_keyword.keyword.BiddingScheme.InheritedBidStrategyType = inherited_bid_strategy_type elif hasattr(bulk_keyword.keyword.BiddingScheme, 'InheritedBidStrategyType'): - del bulk_keyword.keyword.BiddingScheme.InheritedBidStrategyType + bulk_keyword.keyword.BiddingScheme.InheritedBidStrategyType = None else: bulk_keyword.keyword.BiddingScheme.Type = bid_strategy_type @@ -136,11 +136,7 @@ def bid_suggestions(self): _SimpleBulkMapping( header=_StringTable.Status, field_to_csv=lambda c: bulk_str(c.keyword.Status), - csv_to_field=lambda c, v: setattr( - c.keyword, - 'Status', - v if v else None - ) + csv_to_field=lambda c, v: csv_to_field_enum(c.keyword, v, 'Status', KeywordStatus) ), _SimpleBulkMapping( header=_StringTable.Id, @@ -178,20 +174,12 @@ def bid_suggestions(self): _SimpleBulkMapping( header=_StringTable.EditorialStatus, field_to_csv=lambda c: bulk_str(c.keyword.EditorialStatus), - csv_to_field=lambda c, v: setattr( - c.keyword, - 'EditorialStatus', - v if v else None - ) + csv_to_field=lambda c, v: csv_to_field_enum(c.keyword, v, 'EditorialStatus', KeywordEditorialStatus) ), _SimpleBulkMapping( header=_StringTable.MatchType, field_to_csv=lambda c: bulk_str(c.keyword.MatchType), - csv_to_field=lambda c, v: setattr( - c.keyword, - 'MatchType', - v if v else None - ) + csv_to_field=lambda c, v: csv_to_field_enum(c.keyword, v, 'MatchType', MatchType) ), _SimpleBulkMapping( header=_StringTable.DestinationUrl, @@ -250,7 +238,7 @@ def bid_suggestions(self): ), _SimpleBulkMapping( header=_StringTable.TrackingTemplate, - field_to_csv=lambda c: bulk_str(c.keyword.TrackingUrlTemplate), + field_to_csv=lambda c: bulk_optional_str(c.keyword.TrackingUrlTemplate, c.keyword.Id), csv_to_field=lambda c, v: setattr(c.keyword, 'TrackingUrlTemplate', v if v else None) ), _SimpleBulkMapping( diff --git a/bingads/v13/bulk/entities/bulk_negative_keywords.py b/bingads/v13/bulk/entities/bulk_negative_keywords.py index a20bceb3..5930f9c3 100644 --- a/bingads/v13/bulk/entities/bulk_negative_keywords.py +++ b/bingads/v13/bulk/entities/bulk_negative_keywords.py @@ -2,7 +2,7 @@ from bingads.v13.internal.bulk.string_table import _StringTable from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping, _DynamicColumnNameMapping -from bingads.v13.internal.extensions import bulk_str +from bingads.v13.internal.extensions import * class _BulkNegativeKeyword(_SingleRecordBulkEntity): @@ -73,7 +73,7 @@ def negative_keyword(self, negative_keyword): _SimpleBulkMapping( header=_StringTable.MatchType, field_to_csv=lambda c: bulk_str(c.negative_keyword.MatchType), - csv_to_field=lambda c, v: setattr(c.negative_keyword, 'MatchType', v) + csv_to_field=lambda c, v: csv_to_field_enum(c.negative_keyword, v, 'MatchType', MatchType) ) ] @@ -373,7 +373,6 @@ def process_mappings_from_row_values(self, row_values): def read_additional_data(self, stream_reader): super(BulkCampaignNegativeKeywordList, self).read_additional_data(stream_reader) - class BulkNegativeKeywordList(_SingleRecordBulkEntity): """ Represents a negative keyword list that can be read or written in a bulk file. @@ -480,3 +479,31 @@ def negative_keyword_list_id(self): @negative_keyword_list_id.setter def negative_keyword_list_id(self, value): self._parent_id = value + +class BulkAccountSharedNegativeKeyword(_BulkNegativeKeyword): + """ Represents an account negative keyword that is shared in a negative keyword list. + + Each shared negative keyword can be read or written in a bulk file. + This class exposes the :attr:`.BulkNegativeKeyword.NegativeKeyword` property that + can be read and written as fields of the Account Shared Negative Keyword record in a bulk file. + + For more information, see Account Shared Negative Keyword at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, status=None, negative_keyword=None, negative_keyword_list_id=None): + super(BulkAccountSharedNegativeKeyword, self).__init__(status, negative_keyword, negative_keyword_list_id) + + @property + def negative_keyword_list_id(self): + return self._parent_id + + @negative_keyword_list_id.setter + def negative_keyword_list_id(self, value): + self._parent_id = value diff --git a/bingads/v13/bulk/entities/bulk_new_customer_acquisition_goal.py b/bingads/v13/bulk/entities/bulk_new_customer_acquisition_goal.py new file mode 100644 index 00000000..816aed2c --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_new_customer_acquisition_goal.py @@ -0,0 +1,81 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * +from decimal import Decimal + + +class BulkNewCustomerAcquisitionGoal (_SingleRecordBulkEntity): + """ Represents a new customer acquisition goal that can be read or written in a bulk file. + + Properties of this class and of classes that it is derived from, correspond to fields of the Budget record in a bulk file. + For more information, see Budget at https://go.microsoft.com/fwlink/?linkid=846127 + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, new_customer_acquisition_goal=None, target=None): + super(BulkNewCustomerAcquisitionGoal , self).__init__() + self._new_customer_acquisition_goal = new_customer_acquisition_goal + self._target = target + + @property + def new_customer_acquisition_goal (self): + """ + the NewCustomerAcquisitionGoal object, see more detail at: https://go.microsoft.com/fwlink/?linkid=846127 + """ + return self._new_customer_acquisition_goal + + @new_customer_acquisition_goal .setter + def new_customer_acquisition_goal (self, value): + self._new_customer_acquisition_goal = value + + @property + def target(self): + """ + The ids of audiences within the new customer acquisition. + It should be split by simicolon. example: "123;456;789" + Corresponds to 'Target' field in bulk file. + :rtype: str + """ + return self._target + + @target.setter + def target(self, value): + self._target = value + + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.new_customer_acquisition_goal .Id), + csv_to_field=lambda c, v: setattr(c.new_customer_acquisition_goal , 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Target, + field_to_csv=lambda c: bulk_str(c.target), + csv_to_field=lambda c, v: setattr(c, 'target', v) + ), + _SimpleBulkMapping( + header=_StringTable.AdditionalConversionValue, + field_to_csv=lambda c: bulk_str(c.new_customer_acquisition_goal.AdditionalValue), + csv_to_field=lambda c, v: setattr(c.new_customer_acquisition_goal , 'AdditionalValue', Decimal(v) if v else None) + ), + ] + + def process_mappings_from_row_values(self, row_values): + self._new_customer_acquisition_goal = _CAMPAIGN_OBJECT_FACTORY_V13.create('NewCustomerAcquisitionGoal') + row_values.convert_to_entity(self, BulkNewCustomerAcquisitionGoal ._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.new_customer_acquisition_goal , 'new_customer_acquisition_goal ') + self.convert_to_values(row_values, BulkNewCustomerAcquisitionGoal ._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkNewCustomerAcquisitionGoal , self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_offline_conversion.py b/bingads/v13/bulk/entities/bulk_offline_conversion.py index f8c7ce0b..168421ac 100644 --- a/bingads/v13/bulk/entities/bulk_offline_conversion.py +++ b/bingads/v13/bulk/entities/bulk_offline_conversion.py @@ -1,4 +1,3 @@ -from __future__ import print_function from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 from bingads.v13.internal.bulk.string_table import _StringTable from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity @@ -30,55 +29,55 @@ def __init__(self, offline_conversion=None): self._adjustment_currency_code = None self._external_attribution_model = None self._external_attribution_credit = None - + @property def adjustment_value(self): return self._adjustment_value; - + @adjustment_value.setter def adjustment_value(self, value): self._adjustment_value = value - + @property def adjustment_time(self): return self._adjustment_time; - + @adjustment_time.setter def adjustment_time(self, value): self._adjustment_time = value - + @property def adjustment_type(self): return self._adjustment_type; - + @adjustment_type.setter def adjustment_type(self, value): self._adjustment_type = value - + @property def adjustment_currency_code(self): return self._adjustment_currency_code; - + @adjustment_currency_code.setter def adjustment_currency_code(self, value): self._adjustment_currency_code = value - + @property def external_attribution_model(self): return self._external_attribution_model; - + @external_attribution_model.setter def external_attribution_model(self, value): self._external_attribution_model = value - + @property def external_attribution_credit(self): return self._external_attribution_credit; - + @external_attribution_credit.setter def external_attribution_credit(self, value): - self._external_attribution_credit = value - + self._external_attribution_credit = value + @property def offline_conversion(self): """ The offline conversion Data Object of the Campaign Management Service. @@ -146,7 +145,7 @@ def offline_conversion(self, value): float(v) if v else None ) ), - + _SimpleBulkMapping( header=_StringTable.AdjustmentType, field_to_csv=lambda c: c.adjustment_type, @@ -156,7 +155,7 @@ def offline_conversion(self, value): v ) ), - + _SimpleBulkMapping( header=_StringTable.AdjustmentCurrencyCode, field_to_csv=lambda c: c.adjustment_currency_code, @@ -166,7 +165,7 @@ def offline_conversion(self, value): v ) ), - + _SimpleBulkMapping( header=_StringTable.ExternalAttributionModel, field_to_csv=lambda c: c.external_attribution_model, @@ -185,8 +184,6 @@ def offline_conversion(self, value): float(v) if v else None ) ), - - _SimpleBulkMapping( header=_StringTable.AdjustmentTime, field_to_csv=lambda c: bulk_datetime_str(c.adjustment_time), @@ -196,6 +193,24 @@ def offline_conversion(self, value): parse_datetime(v) if v else None ) ), + _SimpleBulkMapping( + header=_StringTable.HashedEmailAddress, + field_to_csv=lambda c: c.offline_conversion.HashedEmailAddress, + csv_to_field=lambda c, v: setattr( + c.offline_conversion, + 'HashedEmailAddress', + v + ) + ), + _SimpleBulkMapping( + header=_StringTable.HashedPhoneNumber, + field_to_csv=lambda c: c.offline_conversion.HashedPhoneNumber, + csv_to_field=lambda c, v: setattr( + c.offline_conversion, + 'HashedPhoneNumber', + v + ) + ), ] def process_mappings_to_row_values(self, row_values, exclude_readonly_data): diff --git a/bingads/v13/bulk/entities/bulk_online_conversion_adjustment.py b/bingads/v13/bulk/entities/bulk_online_conversion_adjustment.py new file mode 100644 index 00000000..bbe59a85 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_online_conversion_adjustment.py @@ -0,0 +1,105 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + + +class BulkOnlineConversionAdjustment(_SingleRecordBulkEntity): + """ Represents an online conversion adjustment that can be read or written in a bulk file. + + This class exposes the :attr:`online_conversion_adjustment` property that can be read and written as fields of the Keyword record in a bulk file. + Properties of this class and of classes that it is derived from, correspond to fields of the Keyword record in a bulk file. + For more information, see Keyword at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, online_conversion_adjustment=None): + super(BulkOnlineConversionAdjustment, self).__init__() + self._online_conversion_adjustment = online_conversion_adjustment + + @property + def online_conversion_adjustment(self): + """ The online conversion adjustment Data Object of the Campaign Management Service. + + """ + + return self._online_conversion_adjustment + + @online_conversion_adjustment.setter + def online_conversion_adjustment(self, value): + self._online_conversion_adjustment = value + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.TransactionId, + field_to_csv=lambda c: c.online_conversion_adjustment.TransactionId, + csv_to_field=lambda c, v: setattr( + c.online_conversion_adjustment, + 'TransactionId', + v + ) + ), + _SimpleBulkMapping( + header=_StringTable.ConversionName, + field_to_csv=lambda c: c.online_conversion_adjustment.ConversionName, + csv_to_field=lambda c, v: setattr( + c.online_conversion_adjustment, + 'ConversionName', + v + ) + ), + _SimpleBulkMapping( + header=_StringTable.AdjustmentType, + field_to_csv=lambda c: c.online_conversion_adjustment.AdjustmentType, + csv_to_field=lambda c, v: setattr( + c.online_conversion_adjustment, + 'AdjustmentType', + v + ) + ), + _SimpleBulkMapping( + header=_StringTable.AdjustmentValue, + field_to_csv=lambda c: c.online_conversion_adjustment.AdjustmentValue, + csv_to_field=lambda c, v: setattr( + c.online_conversion_adjustment, + 'AdjustmentValue', + float(v) if v else None + ) + ), + _SimpleBulkMapping( + header=_StringTable.AdjustmentTime, + field_to_csv=lambda c: bulk_datetime_str(c.online_conversion_adjustment.AdjustmentTime), + csv_to_field=lambda c, v: setattr( + c.online_conversion_adjustment, + 'AdjustmentTime', + parse_datetime(v) if v else None + ) + ), + _SimpleBulkMapping( + header=_StringTable.AdjustmentCurrencyCode, + field_to_csv=lambda c: c.online_conversion_adjustment.AdjustmentCurrencyCode, + csv_to_field=lambda c, v: setattr( + c.online_conversion_adjustment, + 'AdjustmentCurrencyCode', + v + ) + ), + ] + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._online_conversion_adjustment, 'online_conversion_adjustment') + self.convert_to_values(row_values, BulkOnlineConversionAdjustment._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self._online_conversion_adjustment = _CAMPAIGN_OBJECT_FACTORY_V13.create('OnlineConversionAdjustment') + row_values.convert_to_entity(self, BulkOnlineConversionAdjustment._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkOnlineConversionAdjustment, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_seasonality_adjustment.py b/bingads/v13/bulk/entities/bulk_seasonality_adjustment.py new file mode 100644 index 00000000..f03079ee --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_seasonality_adjustment.py @@ -0,0 +1,102 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkSeasonalityAdjustment(_SingleRecordBulkEntity): + """ Represents an seasonality adjustment. + + This class exposes the property :attr:`seasonality_adjustment` that can be read and written as fields of the seasonality adjustment record + in a bulk file. + + For more information, see seasonality adjustment at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, seasonality_adjustment=None): + super(BulkSeasonalityAdjustment, self).__init__() + + self._seasonality_adjustment = seasonality_adjustment + + @property + def seasonality_adjustment(self): + """ The SeasonalityAdjustment Data Object of the Campaign Management Service. + + A subset of SeasonalityAdjustment properties are available in the Seasonality Adjustment record. + For more information, see Seasonality Adjustment at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._seasonality_adjustment + + @seasonality_adjustment.setter + def seasonality_adjustment(self, seasonality_adjustment): + self._seasonality_adjustment = seasonality_adjustment + + + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.seasonality_adjustment.Id), + csv_to_field=lambda c, v: setattr(c.seasonality_adjustment, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.SeasonalityAdjustment, + field_to_csv=lambda c: bulk_str(c.seasonality_adjustment.Name), + csv_to_field=lambda c, v: setattr(c.seasonality_adjustment, 'Name', v) + ), + _SimpleBulkMapping( + header=_StringTable.StartDate, + field_to_csv=lambda c: bulk_datetime_str2(c.seasonality_adjustment.StartDate), + csv_to_field=lambda c, v: setattr(c.seasonality_adjustment, 'StartDate', parse_datetime2(v)) + ), + _SimpleBulkMapping( + header=_StringTable.EndDate, + field_to_csv=lambda c: bulk_datetime_str2(c.seasonality_adjustment.EndDate), + csv_to_field=lambda c, v: setattr(c.seasonality_adjustment, 'EndDate', parse_datetime2(v)) + ), + _SimpleBulkMapping( + header=_StringTable.Description, + field_to_csv=lambda c: c.seasonality_adjustment.Description, + csv_to_field=lambda c, v: setattr(c.seasonality_adjustment, 'Description', v) + ), + _SimpleBulkMapping( + header=_StringTable.CampaignType, + field_to_csv=lambda c: field_to_csv_CampaignType(c.seasonality_adjustment), + csv_to_field=lambda c, v: csv_to_field_CampaignType(c.seasonality_adjustment, v) + ), + _SimpleBulkMapping( + header=_StringTable.DeviceType, + field_to_csv=lambda c: field_to_csv_DeviceType(c.seasonality_adjustment), + csv_to_field=lambda c, v: csv_to_field_DeviceType(c.seasonality_adjustment, v) + ), + _SimpleBulkMapping( + header=_StringTable.AdjustmentValue, + field_to_csv=lambda c: c.seasonality_adjustment.AdjustmentPercentage, + csv_to_field=lambda c, v: setattr(c.seasonality_adjustment, 'AdjustmentPercentage', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.CampaignAssociations, + field_to_csv=lambda c: field_to_csv_CampaignAssociations(c.seasonality_adjustment), + csv_to_field=lambda c, v: csv_to_field_CampaignAssociations(c.seasonality_adjustment, v) + ), + ] + + def process_mappings_from_row_values(self, row_values): + self.seasonality_adjustment = _CAMPAIGN_OBJECT_FACTORY_V13.create('SeasonalityAdjustment') + + row_values.convert_to_entity(self, BulkSeasonalityAdjustment._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._seasonality_adjustment, 'SeasonalityAdjustment') + self.convert_to_values(row_values, BulkSeasonalityAdjustment._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkSeasonalityAdjustment, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/bulk_video.py b/bingads/v13/bulk/entities/bulk_video.py new file mode 100644 index 00000000..7be37110 --- /dev/null +++ b/bingads/v13/bulk/entities/bulk_video.py @@ -0,0 +1,109 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * +from decimal import Decimal + + +class BulkVideo(_SingleRecordBulkEntity): + """ Represents a video that can be read or written in a bulk file. + + Properties of this class and of classes that it is derived from, correspond to fields of the Video record in a bulk file. + For more information, see Video at https://go.microsoft.com/fwlink/?linkid=846127 + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, video=None, account_id=None): + super(BulkVideo, self).__init__() + self._account_id = account_id + self._video=video + + @property + def video(self): + """ + the Video object + """ + return self._video + + @video.setter + def video(self, value): + self._video = value + + @property + def account_id(self): + """ the id of the account which contains the video + Corresponds to the 'Parent Id' field in the bulk file. + + :rtype: long + """ + return self._account_id + + @account_id.setter + def account_id(self, value): + self._account_id = value + + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.video.Id), + csv_to_field=lambda c, v: setattr(c.video, 'Id', int(v) if v else None) + ), + _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) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: c.video.Status, + csv_to_field=lambda c, v: setattr(c.video, 'Status', v) + ), + _SimpleBulkMapping( + header=_StringTable.Description, + field_to_csv=lambda c: bulk_str(c.video.Description), + csv_to_field=lambda c, v: setattr(c.video, 'Description', v) + ), + _SimpleBulkMapping( + header=_StringTable.AspectRatio, + field_to_csv=lambda c: bulk_str(c.video.AspectRatio), + csv_to_field=lambda c, v: setattr(c.video, 'AspectRatio', v) + ), + _SimpleBulkMapping( + header=_StringTable.Url, + field_to_csv=lambda c: bulk_str(c.video.Url), + csv_to_field=lambda c, v: setattr(c.video, 'Url', v) + ), + _SimpleBulkMapping( + header=_StringTable.SourceUrl, + field_to_csv=lambda c: bulk_str(c.video.SourceUrl), + csv_to_field=lambda c, v: setattr(c.video, 'SourceUrl', v) + ), + _SimpleBulkMapping( + header=_StringTable.ThumbnailUrl, + field_to_csv=lambda c: bulk_str(c.video.ThumbnailUrl), + csv_to_field=lambda c, v: setattr(c.video, 'ThumbnailUrl', v) + ), + _SimpleBulkMapping( + header=_StringTable.DurationInMillionSeconds, + field_to_csv=lambda c: bulk_str(c.video.DurationInMilliseconds), + csv_to_field=lambda c, v: setattr(c.video, 'DurationInMilliseconds', int(v) if v else None) + ) + ] + + def process_mappings_from_row_values(self, row_values): + self.video=_CAMPAIGN_OBJECT_FACTORY_V13.create('Video') + row_values.convert_to_entity(self, BulkVideo._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self.convert_to_values(row_values, BulkVideo._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkVideo, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/feeds/bulk_feed.py b/bingads/v13/bulk/entities/feeds/bulk_feed.py index eee51551..aecb4292 100644 --- a/bingads/v13/bulk/entities/feeds/bulk_feed.py +++ b/bingads/v13/bulk/entities/feeds/bulk_feed.py @@ -19,7 +19,7 @@ class BulkFeed(_SingleRecordBulkEntity): * :class:`.BulkFileWriter` """ - def __init__(self, id = None, status=None, account_id=None, sub_type=None, feed_name = None, custom_attr=None): + def __init__(self, id = None, status=None, account_id=None, sub_type=None, feed_name = None, custom_attr=None, schedule=None): super(BulkFeed, self).__init__() self._status = status self._account_id = account_id @@ -27,6 +27,7 @@ def __init__(self, id = None, status=None, account_id=None, sub_type=None, feed_ self._sub_type = sub_type self._name = feed_name self._custom_attributes = custom_attr + self._schedule = schedule @property @@ -102,11 +103,24 @@ def custom_attributes(self): :rtype: long """ return self._custom_attributes - + @custom_attributes.setter def custom_attributes(self, value): self._custom_attributes = value + @property + def schedule(self): + """ the schedule of the feed + Corresponds to the 'Schedule' field in the bulk file. + + :rtype: string + """ + return self._schedule + + @schedule.setter + def schedule(self, value): + self._schedule = value + _MAPPINGS = [ _SimpleBulkMapping( header=_StringTable.Id, @@ -138,6 +152,11 @@ def custom_attributes(self, value): field_to_csv=lambda c: field_to_csv_CustomAttributes(c.custom_attributes), csv_to_field=lambda c, v: csv_to_field_CustomAttributes(c, v) ), + _SimpleBulkMapping( + header=_StringTable.Schedule, + field_to_csv=lambda c: c.schedule, + csv_to_field=lambda c, v: setattr(c, 'schedule', v) + ), ] def process_mappings_from_row_values(self, row_values): diff --git a/bingads/v13/bulk/entities/goals/__init__.py b/bingads/v13/bulk/entities/goals/__init__.py new file mode 100644 index 00000000..473d18cb --- /dev/null +++ b/bingads/v13/bulk/entities/goals/__init__.py @@ -0,0 +1,13 @@ +__author__ = 'Bing Ads SDK Team' +__email__ = 'bing_ads_sdk@microsoft.com' + +from .bulk_conversion_goal import * +from .bulk_app_install_goal import * +from .bulk_event_goal import * +from .bulk_duration_goal import * +from .bulk_in_store_transaction_goal import * +from .bulk_in_store_visit_goal import * +from .bulk_offline_conversion_goal import * +from .bulk_pages_viewed_per_visit_goal import * +from .bulk_product_goal import * +from .bulk_url_goal import * diff --git a/bingads/v13/bulk/entities/goals/bulk_app_install_goal.py b/bingads/v13/bulk/entities/goals/bulk_app_install_goal.py new file mode 100644 index 00000000..89decb0b --- /dev/null +++ b/bingads/v13/bulk/entities/goals/bulk_app_install_goal.py @@ -0,0 +1,64 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from .bulk_conversion_goal import BulkConversionGoal + +class BulkAppInstallGoal(BulkConversionGoal): + """ Represents an AppInstall Goal that can be read or written in a bulk file. + + This class exposes the :attr:`app_install_goal` property that can be read and written as fields of the + AppInstall Goal record in a bulk file. + + For more information, see AppInstall Goal at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + app_install_goal=None): + super(BulkAppInstallGoal, self).__init__(conversion_goal = app_install_goal) + + _MAPPINGS = [ + + _SimpleBulkMapping( + header=_StringTable.AppPlatform, + field_to_csv=lambda c: bulk_str(c.app_install_goal.AppPlatform), + csv_to_field=lambda c, v: setattr(c.app_install_goal, 'AppPlatform', v) + ), + _SimpleBulkMapping( + header=_StringTable.AppStoreId, + field_to_csv=lambda c: bulk_str(c.app_install_goal.AppStoreId), + csv_to_field=lambda c, v: setattr(c.app_install_goal, 'AppStoreId', v) + ), + + ] + + @property + def app_install_goal(self): + """ Defines a AppInstall Goal """ + + return self._conversion_goal + + @app_install_goal.setter + def app_install_goal(self, app_install_goal): + self._conversion_goal = app_install_goal + + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.app_install_goal, 'app_install_goal') + super(BulkAppInstallGoal, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkAppInstallGoal._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self.app_install_goal = _CAMPAIGN_OBJECT_FACTORY_V13.create('AppInstallGoal') + super(BulkAppInstallGoal, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkAppInstallGoal._MAPPINGS) + diff --git a/bingads/v13/bulk/entities/goals/bulk_conversion_goal.py b/bingads/v13/bulk/entities/goals/bulk_conversion_goal.py new file mode 100644 index 00000000..e3c90b8a --- /dev/null +++ b/bingads/v13/bulk/entities/goals/bulk_conversion_goal.py @@ -0,0 +1,125 @@ +from bingads.v13.bulk.entities import * +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from decimal import Decimal + +class BulkConversionGoal(_SingleRecordBulkEntity): + """ Represents a ConversionGoal that can be read or written in a bulk file. + + This class exposes the :attr:`conversion_goal` property that can be read and written as fields of the + ConversionGoal record in a bulk file. + + For more information, see ConversionGoal at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + conversion_goal=None): + super(BulkConversionGoal, self).__init__() + + self._conversion_goal = conversion_goal + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.conversion_goal.Status), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'Status', v) + ), + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.conversion_goal.Id), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Name, + field_to_csv=lambda c: bulk_str(c.conversion_goal.Name), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'Name', v) + ), + _SimpleBulkMapping( + header=_StringTable.AttributionModelType, + field_to_csv=lambda c: bulk_str(c.conversion_goal.AttributionModelType), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'AttributionModelType', v) + ), + _SimpleBulkMapping( + header=_StringTable.ConversionWindowInMinutes, + field_to_csv=lambda c: bulk_str(c.conversion_goal.ConversionWindowInMinutes), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'ConversionWindowInMinutes', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.CountType, + field_to_csv=lambda c: bulk_str(c.conversion_goal.CountType), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'CountType', v) + ), + _SimpleBulkMapping( + header=_StringTable.ExcludeFromBidding, + field_to_csv=lambda c: bulk_str(c.conversion_goal.ExcludeFromBidding), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'ExcludeFromBidding', parse_bool(v)) + ), + _SimpleBulkMapping( + header=_StringTable.GoalCategory, + field_to_csv=lambda c: bulk_str(c.conversion_goal.GoalCategory), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'GoalCategory', v) + ), + _SimpleBulkMapping( + header=_StringTable.IsEnhancedConversionsEnabled, + field_to_csv=lambda c: bulk_str(c.conversion_goal.IsEnhancedConversionsEnabled), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'IsEnhancedConversionsEnabled', parse_bool(v)) + ), + _SimpleBulkMapping( + header=_StringTable.CurrencyCode, + field_to_csv=lambda c: bulk_str(c.conversion_goal.Revenue.CurrencyCode), + csv_to_field=lambda c, v: setattr(c.conversion_goal.Revenue, 'CurrencyCode', v) + ), + _SimpleBulkMapping( + header=_StringTable.RevenueValue, + field_to_csv=lambda c: bulk_str(c.conversion_goal.Revenue.Value), + csv_to_field=lambda c, v: setattr(c.conversion_goal.Revenue, 'Value', Decimal(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.RevenueType, + field_to_csv=lambda c: bulk_str(c.conversion_goal.Revenue.Type), + csv_to_field=lambda c, v: setattr(c.conversion_goal.Revenue, 'Type', v) + ), + _SimpleBulkMapping( + header=_StringTable.Scope, + field_to_csv=lambda c: bulk_str(c.conversion_goal.Scope), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'Scope', v) + ), + _SimpleBulkMapping( + header=_StringTable.TagId, + field_to_csv=lambda c: bulk_str(c.conversion_goal.TagId), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'TagId', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.ViewThroughConversionWindowInMinutes, + field_to_csv=lambda c: bulk_str(c.conversion_goal.ViewThroughConversionWindowInMinutes), + csv_to_field=lambda c, v: setattr(c.conversion_goal, 'ViewThroughConversionWindowInMinutes', int(v) if v else None) + ), + ] + + @property + def conversion_goal(self): + """ Defines a ConversionGoal """ + + return self._conversion_goal + + @conversion_goal.setter + def conversion_goal(self, conversion_goal): + self._conversion_goal = conversion_goal + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self.convert_to_values(row_values, BulkConversionGoal._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + row_values.convert_to_entity(self, BulkConversionGoal._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkConversionGoal, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/goals/bulk_duration_goal.py b/bingads/v13/bulk/entities/goals/bulk_duration_goal.py new file mode 100644 index 00000000..d72738e5 --- /dev/null +++ b/bingads/v13/bulk/entities/goals/bulk_duration_goal.py @@ -0,0 +1,57 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from .bulk_conversion_goal import BulkConversionGoal + +class BulkDurationGoal(BulkConversionGoal): + """ Represents an Duration Goal that can be read or written in a bulk file. + + This class exposes the :attr:`duration_goal` property that can be read and written as fields of the + Duration Goal record in a bulk file. + + For more information, see Duration Goal at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + duration_goal=None): + super(BulkDurationGoal, self).__init__(conversion_goal = duration_goal) + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.MinimumDurationInSecond, + field_to_csv=lambda c: bulk_str(c.duration_goal.MinimumDurationInSeconds), + csv_to_field=lambda c, v: setattr(c.duration_goal, 'MinimumDurationInSeconds', int(v) if v else None) + ), + ] + + @property + def duration_goal(self): + """ Defines a Duration Goal """ + + return self._conversion_goal + + @duration_goal.setter + def duration_goal(self, duration_goal): + self._conversion_goal = duration_goal + + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.duration_goal, 'duration_goal') + super(BulkDurationGoal, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkDurationGoal._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self.duration_goal = _CAMPAIGN_OBJECT_FACTORY_V13.create('DurationGoal') + super(BulkDurationGoal, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkDurationGoal._MAPPINGS) + diff --git a/bingads/v13/bulk/entities/goals/bulk_event_goal.py b/bingads/v13/bulk/entities/goals/bulk_event_goal.py new file mode 100644 index 00000000..007409b7 --- /dev/null +++ b/bingads/v13/bulk/entities/goals/bulk_event_goal.py @@ -0,0 +1,94 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from .bulk_conversion_goal import BulkConversionGoal +from decimal import Decimal + +class BulkEventGoal(BulkConversionGoal): + """ Represents an Event Goal that can be read or written in a bulk file. + + This class exposes the :attr:`event_goal` property that can be read and written as fields of the + Event Goal record in a bulk file. + + For more information, see Event Goal at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + event_goal=None): + super(BulkEventGoal, self).__init__(conversion_goal = event_goal) + + _MAPPINGS = [ + + _SimpleBulkMapping( + header=_StringTable.CategoryExpression, + field_to_csv=lambda c: bulk_str(c.event_goal.CategoryExpression), + csv_to_field=lambda c, v: setattr(c.event_goal, 'CategoryExpression', v) + ), + _SimpleBulkMapping( + header=_StringTable.CategoryOperator, + field_to_csv=lambda c: bulk_str(c.event_goal.CategoryOperator), + csv_to_field=lambda c, v: setattr(c.event_goal, 'CategoryOperator', v) + ), + _SimpleBulkMapping( + header=_StringTable.ActionExpression, + field_to_csv=lambda c: bulk_str(c.event_goal.ActionExpression), + csv_to_field=lambda c, v: setattr(c.event_goal, 'ActionExpression', v) + ), + _SimpleBulkMapping( + header=_StringTable.ActionOperator, + field_to_csv=lambda c: bulk_str(c.event_goal.ActionOperator), + csv_to_field=lambda c, v: setattr(c.event_goal, 'ActionOperator', v) + ), + _SimpleBulkMapping( + header=_StringTable.LabelExpression, + field_to_csv=lambda c: bulk_str(c.event_goal.LabelExpression), + csv_to_field=lambda c, v: setattr(c.event_goal, 'LabelExpression', v) + ), + _SimpleBulkMapping( + header=_StringTable.LabelOperator, + field_to_csv=lambda c: bulk_str(c.event_goal.LabelOperator), + csv_to_field=lambda c, v: setattr(c.event_goal, 'LabelOperator', v) + ), + _SimpleBulkMapping( + header=_StringTable.EventValue, + field_to_csv=lambda c: bulk_str(c.event_goal.Value), + csv_to_field=lambda c, v: setattr(c.event_goal, 'Value', Decimal(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.EventValueOperator, + field_to_csv=lambda c: bulk_str(c.event_goal.ValueOperator), + csv_to_field=lambda c, v: setattr(c.event_goal, 'ValueOperator', v) + ), + ] + + @property + def event_goal(self): + """ Defines a Event Goal """ + + return self._conversion_goal + + @event_goal.setter + def event_goal(self, event_goal): + self._conversion_goal = event_goal + + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.event_goal, 'event_goal') + super(BulkEventGoal, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkEventGoal._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self.event_goal = _CAMPAIGN_OBJECT_FACTORY_V13.create('EventGoal') + super(BulkEventGoal, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkEventGoal._MAPPINGS) + diff --git a/bingads/v13/bulk/entities/goals/bulk_in_store_transaction_goal.py b/bingads/v13/bulk/entities/goals/bulk_in_store_transaction_goal.py new file mode 100644 index 00000000..8bf057f7 --- /dev/null +++ b/bingads/v13/bulk/entities/goals/bulk_in_store_transaction_goal.py @@ -0,0 +1,53 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from .bulk_conversion_goal import BulkConversionGoal + +class BulkInStoreTransactionGoal(BulkConversionGoal): + """ Represents an InStoreTransaction Goal that can be read or written in a bulk file. + + This class exposes the :attr:`in_store_transaction_goal` property that can be read and written as fields of the + InStoreTransaction Goal record in a bulk file. + + For more information, see InStoreTransaction Goal at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + in_store_transaction_goal=None): + super(BulkInStoreTransactionGoal, self).__init__(conversion_goal = in_store_transaction_goal) + + _MAPPINGS = [ + + ] + + @property + def in_store_transaction_goal(self): + """ Defines a InStoreTransaction Goal """ + + return self._conversion_goal + + @in_store_transaction_goal.setter + def in_store_transaction_goal(self, in_store_transaction_goal): + self._conversion_goal = in_store_transaction_goal + + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.in_store_transaction_goal, 'in_store_transaction_goal') + super(BulkInStoreTransactionGoal, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkInStoreTransactionGoal._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self.in_store_transaction_goal = _CAMPAIGN_OBJECT_FACTORY_V13.create('InStoreTransactionGoal') + super(BulkInStoreTransactionGoal, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkInStoreTransactionGoal._MAPPINGS) + diff --git a/bingads/v13/bulk/entities/goals/bulk_in_store_visit_goal.py b/bingads/v13/bulk/entities/goals/bulk_in_store_visit_goal.py new file mode 100644 index 00000000..b7cf5770 --- /dev/null +++ b/bingads/v13/bulk/entities/goals/bulk_in_store_visit_goal.py @@ -0,0 +1,53 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from .bulk_conversion_goal import BulkConversionGoal + +class BulkInStoreVisitGoal(BulkConversionGoal): + """ Represents an InStoreVisit Goal that can be read or written in a bulk file. + + This class exposes the :attr:`in_store_visit_goal` property that can be read and written as fields of the + InStoreVisit Goal record in a bulk file. + + For more information, see InStoreVisit Goal at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + in_store_visit_goal=None,): + super(BulkInStoreVisitGoal, self).__init__(conversion_goal = in_store_visit_goal) + + _MAPPINGS = [ + + ] + + @property + def in_store_visit_goal(self): + """ Defines a InStoreVisit Goal """ + + return self._conversion_goal + + @in_store_visit_goal.setter + def in_store_visit_goal(self, in_store_visit_goal): + self._conversion_goall = in_store_visit_goal + + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.in_store_visit_goal, 'in_store_visit_goal') + super(BulkInStoreVisitGoal, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkInStoreVisitGoal._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self.in_store_visit_goal = _CAMPAIGN_OBJECT_FACTORY_V13.create('ConversionGoal') + super(BulkInStoreVisitGoal, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkInStoreVisitGoal._MAPPINGS) + diff --git a/bingads/v13/bulk/entities/goals/bulk_offline_conversion_goal.py b/bingads/v13/bulk/entities/goals/bulk_offline_conversion_goal.py new file mode 100644 index 00000000..b4ed023c --- /dev/null +++ b/bingads/v13/bulk/entities/goals/bulk_offline_conversion_goal.py @@ -0,0 +1,53 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from .bulk_conversion_goal import BulkConversionGoal + +class BulkOfflineConversionGoal(BulkConversionGoal): + """ Represents an OfflineConversion Goal that can be read or written in a bulk file. + + This class exposes the :attr:`offline_conversion_goal` property that can be read and written as fields of the + OfflineConversion Goal record in a bulk file. + + For more information, see OfflineConversion Goal at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + offline_conversion_goal=None): + super(BulkOfflineConversionGoal, self).__init__(conversion_goal = offline_conversion_goal) + + _MAPPINGS = [ + + ] + + @property + def offline_conversion_goal(self): + """ Defines a OfflineConversion Goal """ + + return self._conversion_goal + + @offline_conversion_goal.setter + def offline_conversion_goal(self, offline_conversion_goal): + self._conversion_goal = offline_conversion_goal + + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.offline_conversion_goal, 'offline_conversion_goal') + super(BulkOfflineConversionGoal, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkOfflineConversionGoal._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self.offline_conversion_goal = _CAMPAIGN_OBJECT_FACTORY_V13.create('OfflineConversionGoal') + super(BulkOfflineConversionGoal, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkOfflineConversionGoal._MAPPINGS) + diff --git a/bingads/v13/bulk/entities/goals/bulk_pages_viewed_per_visit_goal.py b/bingads/v13/bulk/entities/goals/bulk_pages_viewed_per_visit_goal.py new file mode 100644 index 00000000..464872fa --- /dev/null +++ b/bingads/v13/bulk/entities/goals/bulk_pages_viewed_per_visit_goal.py @@ -0,0 +1,57 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from .bulk_conversion_goal import BulkConversionGoal + +class BulkPagesViewedPerVisitGoal(BulkConversionGoal): + """ Represents an PagesViewedPerVisit Goal that can be read or written in a bulk file. + + This class exposes the :attr:`pages_viewed_per_visit_goal` property that can be read and written as fields of the + PagesViewedPerVisit Goal record in a bulk file. + + For more information, see PagesViewedPerVisit Goal at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + pages_viewed_per_visit_goal=None): + super(BulkPagesViewedPerVisitGoal, self).__init__(conversion_goal = pages_viewed_per_visit_goal) + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.MinimumPagesViewed, + field_to_csv=lambda c: bulk_str(c.pages_viewed_per_visit_goal.MinimumPagesViewed), + csv_to_field=lambda c, v: setattr(c.pages_viewed_per_visit_goal, 'MinimumPagesViewed', int(v) if v else None) + ), + ] + + @property + def pages_viewed_per_visit_goal(self): + """ Defines a PagesViewedPerVisit Goal """ + + return self._conversion_goal + + @pages_viewed_per_visit_goal.setter + def pages_viewed_per_visit_goal(self, pages_viewed_per_visit_goal): + self._conversion_goal = pages_viewed_per_visit_goal + + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.pages_viewed_per_visit_goal, 'pages_viewed_per_visit_goal') + super(BulkPagesViewedPerVisitGoal, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkPagesViewedPerVisitGoal._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self.pages_viewed_per_visit_goal = _CAMPAIGN_OBJECT_FACTORY_V13.create('PagesViewedPerVisitGoal') + super(BulkPagesViewedPerVisitGoal, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkPagesViewedPerVisitGoal._MAPPINGS) + diff --git a/bingads/v13/bulk/entities/goals/bulk_product_goal.py b/bingads/v13/bulk/entities/goals/bulk_product_goal.py new file mode 100644 index 00000000..2d453dc0 --- /dev/null +++ b/bingads/v13/bulk/entities/goals/bulk_product_goal.py @@ -0,0 +1,53 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from .bulk_conversion_goal import BulkConversionGoal + +class BulkProductGoal(BulkConversionGoal): + """ Represents an ProductGoal Goal that can be read or written in a bulk file. + + This class exposes the :attr:`product_goal` property that can be read and written as fields of the + ProductGoal Goal record in a bulk file. + + For more information, see ProductGoal Goal at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + product_goal=None): + super(BulkProductGoal, self).__init__(conversion_goal = product_goal) + + _MAPPINGS = [ + + ] + + @property + def product_goal(self): + """ Defines a ProductGoal Goal """ + + return self._conversion_goal + + @product_goal.setter + def product_goal(self, product_goal): + self._conversion_goall = product_goal + + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.product_goal, 'product_goal') + super(BulkProductGoal, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkProductGoal._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self.product_goal = _CAMPAIGN_OBJECT_FACTORY_V13.create('ConversionGoal') + super(BulkProductGoal, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkProductGoal._MAPPINGS) + diff --git a/bingads/v13/bulk/entities/goals/bulk_url_goal.py b/bingads/v13/bulk/entities/goals/bulk_url_goal.py new file mode 100644 index 00000000..92513a21 --- /dev/null +++ b/bingads/v13/bulk/entities/goals/bulk_url_goal.py @@ -0,0 +1,64 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * +from .bulk_conversion_goal import BulkConversionGoal + +class BulkUrlGoal(BulkConversionGoal): + """ Represents an Url Goal that can be read or written in a bulk file. + + This class exposes the :attr:`url_goal` property that can be read and written as fields of the + Url Goal record in a bulk file. + + For more information, see Url Goal at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + url_goal=None): + super(BulkUrlGoal, self).__init__(conversion_goal = url_goal) + + _MAPPINGS = [ + + _SimpleBulkMapping( + header=_StringTable.UrlExpression, + field_to_csv=lambda c: bulk_str(c.url_goal.UrlExpression), + csv_to_field=lambda c, v: setattr(c.url_goal, 'UrlExpression', v) + ), + _SimpleBulkMapping( + header=_StringTable.UrlOperator, + field_to_csv=lambda c: bulk_str(c.url_goal.UrlOperator), + csv_to_field=lambda c, v: setattr(c.url_goal, 'UrlOperator', v) + ), + + ] + + @property + def url_goal(self): + """ Defines a Url Goal """ + + return self._conversion_goal + + @url_goal.setter + def url_goal(self, url_goal): + self._conversion_goal = url_goal + + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.url_goal, 'url_goal') + super(BulkUrlGoal, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkUrlGoal._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self.url_goal = _CAMPAIGN_OBJECT_FACTORY_V13.create('UrlGoal') + super(BulkUrlGoal, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkUrlGoal._MAPPINGS) + diff --git a/bingads/v13/bulk/entities/labels/bulk_label.py b/bingads/v13/bulk/entities/labels/bulk_label.py index 9779af3d..81a8c0eb 100644 --- a/bingads/v13/bulk/entities/labels/bulk_label.py +++ b/bingads/v13/bulk/entities/labels/bulk_label.py @@ -1,4 +1,3 @@ -from __future__ import print_function from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 from bingads.v13.internal.bulk.string_table import _StringTable from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity diff --git a/bingads/v13/bulk/entities/labels/bulk_label_associations.py b/bingads/v13/bulk/entities/labels/bulk_label_associations.py index 71594215..709e93f6 100644 --- a/bingads/v13/bulk/entities/labels/bulk_label_associations.py +++ b/bingads/v13/bulk/entities/labels/bulk_label_associations.py @@ -1,4 +1,3 @@ -from __future__ import print_function from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 from bingads.v13.internal.bulk.string_table import _StringTable from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity diff --git a/bingads/v13/bulk/entities/target_criterions/__init__.py b/bingads/v13/bulk/entities/target_criterions/__init__.py index 708a21f6..dafefb08 100644 --- a/bingads/v13/bulk/entities/target_criterions/__init__.py +++ b/bingads/v13/bulk/entities/target_criterions/__init__.py @@ -18,6 +18,7 @@ from .bulk_campaign_age_criterion import * from .bulk_campaign_biddable_criterion import * from .bulk_campaign_day_time_criterion import * +from .bulk_campaign_deal_criterion import * from .bulk_campaign_device_criterion import * from .bulk_campaign_gender_criterion import * from .bulk_campaign_location_criterion import * @@ -26,3 +27,9 @@ from .bulk_campaign_radius_criterion import * from .bulk_campaign_profile_criterion import * from .bulk_campaign_negative_criterion import * +from .bulk_ad_group_hotel_advance_booking_window_criterion import * +from .bulk_ad_group_hotel_check_in_date_criterion import * +from .bulk_ad_group_hotel_check_in_day_criterion import * +from .bulk_ad_group_hotel_date_selection_type_criterion import * +from .bulk_ad_group_hotel_length_of_stay_criterion import * +from .bulk_ad_group_genre_criterion import * diff --git a/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_biddable_criterion.py b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_biddable_criterion.py index 3077ef01..12e9bf22 100644 --- a/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_biddable_criterion.py +++ b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_biddable_criterion.py @@ -59,6 +59,11 @@ def __init__(self, _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.CashbackAdjustment, + field_to_csv=lambda c: field_to_csv_CashbackAdjustment(c.biddable_ad_group_criterion), + csv_to_field=lambda c, v: csv_to_field_CashbackAdjustment(c.biddable_ad_group_criterion, float(v) if v else None) ) ] diff --git a/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_genre_criterion.py b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_genre_criterion.py new file mode 100644 index 00000000..0d4fd59c --- /dev/null +++ b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_genre_criterion.py @@ -0,0 +1,52 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.bulk.entities.target_criterions.bulk_ad_group_biddable_criterion import BulkAdGroupBiddableCriterion +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * + + +class BulkAdGroupGenreCriterion(BulkAdGroupBiddableCriterion): + """ Represents an Ad Group Genre Criterion 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 Genre Criterion record in a bulk file. + + For more information, see Ad Group Genre Criterion 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, ): + super(BulkAdGroupGenreCriterion, self).__init__(biddable_ad_group_criterion, campaign_name, ad_group_name) + + _MAPPINGS = [ + _SimpleBulkMapping( + _StringTable.Target, + field_to_csv=lambda c: field_to_csv_GenreId(c.biddable_ad_group_criterion), + csv_to_field=lambda c, v: csv_to_field_GenreId(c.biddable_ad_group_criterion, v) + ) + ] + + def create_criterion(self): + self._biddable_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('GenreCriterion') + self._biddable_ad_group_criterion.Criterion.Type = 'GenreCriterion' + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + super(BulkAdGroupGenreCriterion, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkAdGroupGenreCriterion._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + super(BulkAdGroupGenreCriterion, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkAdGroupGenreCriterion._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAdGroupGenreCriterion, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_advance_booking_window_criterion.py b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_advance_booking_window_criterion.py new file mode 100644 index 00000000..5e5487a0 --- /dev/null +++ b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_advance_booking_window_criterion.py @@ -0,0 +1,57 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.bulk.entities.target_criterions.bulk_ad_group_biddable_criterion import BulkAdGroupBiddableCriterion +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * + + +class BulkAdGroupHotelAdvanceBookingWindowCriterion(BulkAdGroupBiddableCriterion): + """ Represents an Ad Group Hotel Advance Booking Window Criterion 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 Hotel Advance Booking Window Criterion record in a bulk file. + + For more information, see Ad Group Hotel Advance Booking Window Criterion 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, ): + super(BulkAdGroupHotelAdvanceBookingWindowCriterion, self).__init__(biddable_ad_group_criterion, campaign_name, ad_group_name) + + _MAPPINGS = [ + _SimpleBulkMapping( + _StringTable.MaxTargetValue, + field_to_csv=lambda c: field_to_csv_MaxDays(c.biddable_ad_group_criterion), + csv_to_field=lambda c, v: csv_to_field_MaxDays(c.biddable_ad_group_criterion, v) + ), + _SimpleBulkMapping( + _StringTable.MinTargetValue, + field_to_csv=lambda c: field_to_csv_MinDays(c.biddable_ad_group_criterion), + csv_to_field=lambda c, v: csv_to_field_MinDays(c.biddable_ad_group_criterion, v) + ) + ] + + def create_criterion(self): + self._biddable_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelAdvanceBookingWindowCriterion') + self._biddable_ad_group_criterion.Criterion.Type = 'HotelAdvanceBookingWindowCriterion' + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + super(BulkAdGroupHotelAdvanceBookingWindowCriterion, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkAdGroupHotelAdvanceBookingWindowCriterion._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + super(BulkAdGroupHotelAdvanceBookingWindowCriterion, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkAdGroupHotelAdvanceBookingWindowCriterion._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAdGroupHotelAdvanceBookingWindowCriterion, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_check_in_date_criterion.py b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_check_in_date_criterion.py new file mode 100644 index 00000000..2783d457 --- /dev/null +++ b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_check_in_date_criterion.py @@ -0,0 +1,57 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.bulk.entities.target_criterions.bulk_ad_group_biddable_criterion import BulkAdGroupBiddableCriterion +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * + + +class BulkAdGroupHotelCheckInDateCriterion(BulkAdGroupBiddableCriterion): + """ Represents an Ad Group Hotel Check In Date Criterion 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 Hotel Check In Date Criterion record in a bulk file. + + For more information, see Ad Group Hotel Check In Date Criterion 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, ): + super(BulkAdGroupHotelCheckInDateCriterion, self).__init__(biddable_ad_group_criterion, campaign_name, ad_group_name) + + _MAPPINGS = [ + _SimpleBulkMapping( + _StringTable.MaxTargetValue, + field_to_csv=lambda c: field_to_csv_EndDate(c.biddable_ad_group_criterion), + csv_to_field=lambda c, v: csv_to_field_EndDate(c.biddable_ad_group_criterion, v) + ), + _SimpleBulkMapping( + _StringTable.MinTargetValue, + field_to_csv=lambda c: field_to_csv_StartDate(c.biddable_ad_group_criterion), + csv_to_field=lambda c, v: csv_to_field_StartDate(c.biddable_ad_group_criterion, v) + ) + ] + + def create_criterion(self): + self._biddable_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelCheckInDateCriterion') + self._biddable_ad_group_criterion.Criterion.Type = 'HotelCheckInDateCriterion' + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + super(BulkAdGroupHotelCheckInDateCriterion, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkAdGroupHotelCheckInDateCriterion._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + super(BulkAdGroupHotelCheckInDateCriterion, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkAdGroupHotelCheckInDateCriterion._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAdGroupHotelCheckInDateCriterion, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_check_in_day_criterion.py b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_check_in_day_criterion.py new file mode 100644 index 00000000..11683866 --- /dev/null +++ b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_check_in_day_criterion.py @@ -0,0 +1,52 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.bulk.entities.target_criterions.bulk_ad_group_biddable_criterion import BulkAdGroupBiddableCriterion +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * + + +class BulkAdGroupHotelCheckInDayCriterion(BulkAdGroupBiddableCriterion): + """ Represents an Ad Group Hotel Check In Day Criterion 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 Hotel Check In Day Criterion record in a bulk file. + + For more information, see Ad Group Hotel Check In Day Criterion 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, ): + super(BulkAdGroupHotelCheckInDayCriterion, self).__init__(biddable_ad_group_criterion, campaign_name, ad_group_name) + + _MAPPINGS = [ + _SimpleBulkMapping( + _StringTable.Target, + field_to_csv=lambda c: field_to_csv_CheckInDay(c.biddable_ad_group_criterion), + csv_to_field=lambda c, v: csv_to_field_CheckInDay(c.biddable_ad_group_criterion, v) + ) + ] + + def create_criterion(self): + self._biddable_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelCheckInDayCriterion') + self._biddable_ad_group_criterion.Criterion.Type = 'HotelCheckInDayCriterion' + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + super(BulkAdGroupHotelCheckInDayCriterion, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkAdGroupHotelCheckInDayCriterion._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + super(BulkAdGroupHotelCheckInDayCriterion, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkAdGroupHotelCheckInDayCriterion._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAdGroupHotelCheckInDayCriterion, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_date_selection_type_criterion.py b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_date_selection_type_criterion.py new file mode 100644 index 00000000..aaef75ff --- /dev/null +++ b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_date_selection_type_criterion.py @@ -0,0 +1,52 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.bulk.entities.target_criterions.bulk_ad_group_biddable_criterion import BulkAdGroupBiddableCriterion +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * + + +class BulkAdGroupHotelDateSelectionTypeCriterion(BulkAdGroupBiddableCriterion): + """ Represents an Ad Group Hotel Date Selection Type Criterion 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 Hotel Date Selection Type Criterion record in a bulk file. + + For more information, see Ad Group Hotel Date Selection Type Criterion 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, ): + super(BulkAdGroupHotelDateSelectionTypeCriterion, self).__init__(biddable_ad_group_criterion, campaign_name, ad_group_name) + + _MAPPINGS = [ + _SimpleBulkMapping( + _StringTable.Target, + field_to_csv=lambda c: field_to_csv_HotelDateSelectionType(c.biddable_ad_group_criterion), + csv_to_field=lambda c, v: csv_to_field_HotelDateSelectionType(c.biddable_ad_group_criterion, v) + ) + ] + + def create_criterion(self): + self._biddable_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelDateSelectionTypeCriterion') + self._biddable_ad_group_criterion.Criterion.Type = 'HotelDateSelectionTypeCriterion' + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + super(BulkAdGroupHotelDateSelectionTypeCriterion, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkAdGroupHotelDateSelectionTypeCriterion._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + super(BulkAdGroupHotelDateSelectionTypeCriterion, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkAdGroupHotelDateSelectionTypeCriterion._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAdGroupHotelDateSelectionTypeCriterion, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_length_of_stay_criterion.py b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_length_of_stay_criterion.py new file mode 100644 index 00000000..fb659b35 --- /dev/null +++ b/bingads/v13/bulk/entities/target_criterions/bulk_ad_group_hotel_length_of_stay_criterion.py @@ -0,0 +1,57 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.bulk.entities.target_criterions.bulk_ad_group_biddable_criterion import BulkAdGroupBiddableCriterion +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * + + +class BulkAdGroupHotelLengthOfStayCriterion(BulkAdGroupBiddableCriterion): + """ Represents an Ad Group Hotel Length Of Stay Criterion 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 Hotel Length Of Stay Criterion record in a bulk file. + + For more information, see Ad Group Hotel Length Of Stay Criterion 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, ): + super(BulkAdGroupHotelLengthOfStayCriterion, self).__init__(biddable_ad_group_criterion, campaign_name, ad_group_name) + + _MAPPINGS = [ + _SimpleBulkMapping( + _StringTable.MaxTargetValue, + field_to_csv=lambda c: field_to_csv_MaxNights(c.biddable_ad_group_criterion), + csv_to_field=lambda c, v: csv_to_field_MaxNights(c.biddable_ad_group_criterion, v) + ), + _SimpleBulkMapping( + _StringTable.MinTargetValue, + field_to_csv=lambda c: field_to_csv_MinNights(c.biddable_ad_group_criterion), + csv_to_field=lambda c, v: csv_to_field_MinNights(c.biddable_ad_group_criterion, v) + ) + ] + + def create_criterion(self): + self._biddable_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelLengthOfStayCriterion') + self._biddable_ad_group_criterion.Criterion.Type = 'HotelLengthOfStayCriterion' + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + super(BulkAdGroupHotelLengthOfStayCriterion, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkAdGroupHotelLengthOfStayCriterion._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + super(BulkAdGroupHotelLengthOfStayCriterion, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkAdGroupHotelLengthOfStayCriterion._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkAdGroupHotelLengthOfStayCriterion, self).read_additional_data(stream_reader) diff --git a/bingads/v13/bulk/entities/target_criterions/bulk_campaign_biddable_criterion.py b/bingads/v13/bulk/entities/target_criterions/bulk_campaign_biddable_criterion.py index f8d1e03f..7f3c5f4f 100644 --- a/bingads/v13/bulk/entities/target_criterions/bulk_campaign_biddable_criterion.py +++ b/bingads/v13/bulk/entities/target_criterions/bulk_campaign_biddable_criterion.py @@ -52,6 +52,11 @@ def __init__(self, _StringTable.BidAdjustment, field_to_csv=lambda c: field_to_csv_BidAdjustment(c.biddable_campaign_criterion), csv_to_field=lambda c, v: csv_to_field_BidAdjustment(c.biddable_campaign_criterion, float(v) if v else None) + ), + _SimpleBulkMapping( + _StringTable.CashbackAdjustment, + field_to_csv=lambda c: field_to_csv_CashbackAdjustment(c.biddable_campaign_criterion), + csv_to_field=lambda c, v: csv_to_field_CashbackAdjustment(c.biddable_campaign_criterion, float(v) if v else None) ) ] diff --git a/bingads/v13/bulk/entities/target_criterions/bulk_campaign_deal_criterion.py b/bingads/v13/bulk/entities/target_criterions/bulk_campaign_deal_criterion.py new file mode 100644 index 00000000..585e827d --- /dev/null +++ b/bingads/v13/bulk/entities/target_criterions/bulk_campaign_deal_criterion.py @@ -0,0 +1,50 @@ +from bingads.v13.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 +from bingads.v13.bulk.entities.target_criterions.bulk_campaign_biddable_criterion import BulkCampaignBiddableCriterion +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.extensions import * + +class BulkCampaignDealCriterion(BulkCampaignBiddableCriterion): + """ Represents an Campaign Deal Criterion that can be read or written in a bulk file. + + This class exposes the :attr:`biddable_campaign_criterion` property that can be read and written as fields of the + Campaign Deal Criterion record in a bulk file. + + For more information, see Campaign Deal Criterion at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + biddable_campaign_criterion=None, + campaign_name=None, ): + super(BulkCampaignDealCriterion, self).__init__(biddable_campaign_criterion, campaign_name) + + _MAPPINGS = [ + _SimpleBulkMapping( + _StringTable.Target, + field_to_csv=lambda c: field_to_csv_DealTarget(c.biddable_campaign_criterion), + csv_to_field=lambda c, v: csv_to_field_DealTarget(c.biddable_campaign_criterion, v) + ) + ] + + def create_criterion(self): + self._biddable_campaign_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('DealCriterion') + self._biddable_campaign_criterion.Criterion.Type = 'DealCriterion' + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + super(BulkCampaignDealCriterion, self).process_mappings_to_row_values(row_values, exclude_readonly_data) + self.convert_to_values(row_values, BulkCampaignDealCriterion._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + super(BulkCampaignDealCriterion, self).process_mappings_from_row_values(row_values) + row_values.convert_to_entity(self, BulkCampaignDealCriterion._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkCampaignDealCriterion, self).read_additional_data(stream_reader) diff --git a/bingads/v13/internal/bulk/bulk_object.py b/bingads/v13/internal/bulk/bulk_object.py index 222d8afb..701c08ab 100644 --- a/bingads/v13/internal/bulk/bulk_object.py +++ b/bingads/v13/internal/bulk/bulk_object.py @@ -1,11 +1,10 @@ from abc import ABCMeta, abstractmethod, abstractproperty -from future.utils import with_metaclass from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping from bingads.v13.bulk import EntityWriteException -class _BulkObject(with_metaclass(ABCMeta)): +class _BulkObject(metaclass=ABCMeta): """ The abstract base class for all bulk objects that can be read and written in a file that conforms to the Bing Ad Bulk File Schema. For more information about the Bulk File Schema, see https://go.microsoft.com/fwlink/?linkid=846127. diff --git a/bingads/v13/internal/bulk/bulk_object_factory.py b/bingads/v13/internal/bulk/bulk_object_factory.py index c146ca1c..77f116eb 100644 --- a/bingads/v13/internal/bulk/bulk_object_factory.py +++ b/bingads/v13/internal/bulk/bulk_object_factory.py @@ -1,4 +1,16 @@ from bingads.v13.bulk.entities import * +from bingads.v13.bulk.entities.bulk_ad_group_hotel_listing_group import BulkAdGroupHotelListingGroup +from bingads.v13.bulk.entities.bulk_online_conversion_adjustment import BulkOnlineConversionAdjustment +from bingads.v13.bulk.entities.target_criterions.bulk_ad_group_hotel_advance_booking_window_criterion import \ + BulkAdGroupHotelAdvanceBookingWindowCriterion +from bingads.v13.bulk.entities.target_criterions.bulk_ad_group_hotel_check_in_date_criterion import \ + BulkAdGroupHotelCheckInDateCriterion +from bingads.v13.bulk.entities.target_criterions.bulk_ad_group_hotel_check_in_day_criterion import \ + BulkAdGroupHotelCheckInDayCriterion +from bingads.v13.bulk.entities.target_criterions.bulk_ad_group_hotel_date_selection_type_criterion import \ + BulkAdGroupHotelDateSelectionTypeCriterion +from bingads.v13.bulk.entities.target_criterions.bulk_ad_group_hotel_length_of_stay_criterion import \ + BulkAdGroupHotelLengthOfStayCriterion from bingads.v13.internal.bulk.string_table import _StringTable from bingads.v13.internal.bulk.entity_info import _EntityInfo from bingads.v13.bulk.entities.bulk_negative_sites import _BulkAdGroupNegativeSitesIdentifier, \ @@ -9,18 +21,25 @@ class _BulkObjectFactory(): INDIVIDUAL_ENTITY_MAP = { _StringTable.Image: _EntityInfo(lambda: BulkImage()), + _StringTable.Video: _EntityInfo(lambda: BulkVideo()), _StringTable.Account: _EntityInfo(lambda: BulkAccount()), _StringTable.Budget: _EntityInfo(lambda: BulkBudget()), _StringTable.BidStrategy: _EntityInfo(lambda: BulkBidStrategy()), _StringTable.Campaign: _EntityInfo(lambda: BulkCampaign()), _StringTable.AdGroup: _EntityInfo(lambda: BulkAdGroup()), _StringTable.Keyword: _EntityInfo(lambda: BulkKeyword()), + _StringTable.VideoAdExtension: _EntityInfo(lambda: BulkVideoAdExtension()), + _StringTable.AccountVideoAdExtension: _EntityInfo(lambda: BulkAccountVideoAdExtension()), + _StringTable.CampaignVideoAdExtension: _EntityInfo(lambda: BulkCampaignVideoAdExtension()), + _StringTable.AdGroupVideoAdExtension: _EntityInfo(lambda: BulkAdGroupVideoAdExtension()), _StringTable.CallAdExtension: _EntityInfo(lambda: BulkCallAdExtension()), _StringTable.CampaignCallAdExtension: _EntityInfo(lambda: BulkCampaignCallAdExtension()), _StringTable.FlyerAdExtension: _EntityInfo(lambda: BulkFlyerAdExtension()), _StringTable.AccountFlyerAdExtension: _EntityInfo(lambda: BulkAccountFlyerAdExtension()), _StringTable.CampaignFlyerAdExtension: _EntityInfo(lambda: BulkCampaignFlyerAdExtension()), _StringTable.AdGroupFlyerAdExtension: _EntityInfo(lambda: BulkAdGroupFlyerAdExtension()), + _StringTable.DisclaimerAdExtension: _EntityInfo(lambda: BulkDisclaimerAdExtension()), + _StringTable.CampaignDisclaimerAdExtension: _EntityInfo(lambda: BulkCampaignDisclaimerAdExtension()), _StringTable.ImageAdExtension: _EntityInfo(lambda: BulkImageAdExtension()), _StringTable.AccountImageAdExtension: _EntityInfo(lambda: BulkAccountImageAdExtension()), _StringTable.CampaignImageAdExtension: _EntityInfo(lambda: BulkCampaignImageAdExtension()), @@ -85,6 +104,7 @@ class _BulkObjectFactory(): _StringTable.AdGroupNegativeKeyword: _EntityInfo(lambda: BulkAdGroupNegativeKeyword()), 'Campaign Product Scope': _EntityInfo(lambda : BulkCampaignProductScope()), 'Ad Group Product Partition': _EntityInfo(lambda : BulkAdGroupProductPartition()), + 'Ad Group Hotel Listing Group': _EntityInfo(lambda : BulkAdGroupHotelListingGroup()), _StringTable.RemarketingList: _EntityInfo(lambda : BulkRemarketingList()), _StringTable.AdGroupRemarketingListAssociation: _EntityInfo(lambda : BulkAdGroupRemarketingListAssociation()), _StringTable.AdGroupNegativeRemarketingListAssociation: _EntityInfo(lambda : BulkAdGroupNegativeRemarketingListAssociation()), @@ -112,6 +132,12 @@ class _BulkObjectFactory(): 'Ad Group Location Intent Criterion': _EntityInfo(lambda: BulkAdGroupLocationIntentCriterion()), 'Ad Group Negative Location Criterion': _EntityInfo(lambda: BulkAdGroupNegativeLocationCriterion()), 'Ad Group Radius Criterion': _EntityInfo(lambda: BulkAdGroupRadiusCriterion()), + + _StringTable.AdGroupAdvanceBookingWindowCriterion: _EntityInfo(lambda: BulkAdGroupHotelAdvanceBookingWindowCriterion()), + _StringTable.AdGroupCheckInDateCriterion: _EntityInfo(lambda: BulkAdGroupHotelCheckInDateCriterion()), + _StringTable.AdGroupCheckInDayCriterion: _EntityInfo(lambda: BulkAdGroupHotelCheckInDayCriterion()), + _StringTable.AdGroupHotelDateSelectionTypeCriterion: _EntityInfo(lambda: BulkAdGroupHotelDateSelectionTypeCriterion()), + _StringTable.AdGroupLengthOfStayCriterion: _EntityInfo(lambda: BulkAdGroupHotelLengthOfStayCriterion()), _StringTable.CampaignAgeCriterion: _EntityInfo(lambda: BulkCampaignAgeCriterion()), _StringTable.CampaignDayTimeCriterion: _EntityInfo(lambda: BulkCampaignDayTimeCriterion()), _StringTable.CampaignDeviceOSCriterion: _EntityInfo(lambda: BulkCampaignDeviceCriterion()), @@ -122,9 +148,10 @@ class _BulkObjectFactory(): _StringTable.CampaignRadiusCriterion: _EntityInfo(lambda: BulkCampaignRadiusCriterion()), _StringTable.CampaignCompanyNameCriterion: _EntityInfo(lambda: BulkCampaignCompanyNameCriterion()), _StringTable.CampaignJobFunctionCriterion: _EntityInfo(lambda: BulkCampaignJobFunctionCriterion()), - _StringTable.CampaignIndustryCriterion: _EntityInfo(lambda: BulkCampaignIndustryCriterion()), - _StringTable.CombinedList: _EntityInfo(lambda: BulkCombinedList()), - _StringTable.CustomerList: _EntityInfo(lambda: BulkCustomerList()), + _StringTable.CampaignIndustryCriterion: _EntityInfo(lambda: BulkCampaignIndustryCriterion()), + _StringTable.CampaignDealCriterion: _EntityInfo(lambda: BulkCampaignDealCriterion()), + _StringTable.CombinedList: _EntityInfo(lambda: BulkCombinedList()), + _StringTable.CustomerList: _EntityInfo(lambda: BulkCustomerList()), _StringTable.CustomerListItem: _EntityInfo(lambda: BulkCustomerListItem()), _StringTable.ProductAudience: _EntityInfo(lambda: BulkProductAudience()), _StringTable.AdGroupProductAudienceAssociation: _EntityInfo(lambda: BulkAdGroupProductAudienceAssociation()), @@ -139,6 +166,11 @@ class _BulkObjectFactory(): _StringTable.CampaignNegativeCombinedListAssociation: _EntityInfo(lambda: BulkCampaignNegativeCombinedListAssociation()), _StringTable.CampaignCustomerListAssociation: _EntityInfo(lambda: BulkCampaignCustomerListAssociation()), _StringTable.CampaignNegativeCustomerListAssociation: _EntityInfo(lambda: BulkCampaignNegativeCustomerListAssociation()), + _StringTable.ImpressionBasedRemarketingList: _EntityInfo(lambda: BulkImpressionBasedRemarketingList()), + _StringTable.CampaignImpressionBasedRemarketingListAssociation: _EntityInfo(lambda: BulkCampaignImpressionBasedRemarketingListAssociation()), + _StringTable.CampaignNegativeImpressionBasedRemarketingListAssociation: _EntityInfo(lambda: BulkCampaignNegativeImpressionBasedRemarketingListAssociation()), + _StringTable.AdGroupImpressionBasedRemarketingListAssociation: _EntityInfo(lambda: BulkAdGroupImpressionBasedRemarketingListAssociation()), + _StringTable.AdGroupNegativeImpressionBasedRemarketingListAssociation: _EntityInfo(lambda: BulkAdGroupNegativeImpressionBasedRemarketingListAssociation()), _StringTable.AdGroupIndustryCriterion: _EntityInfo(lambda: BulkAdGroupIndustryCriterion()), _StringTable.AdGroupCompanyNameCriterion: _EntityInfo(lambda: BulkAdGroupCompanyNameCriterion()), _StringTable.AdGroupJobFunctionCriterion: _EntityInfo(lambda: BulkAdGroupJobFunctionCriterion()), @@ -147,6 +179,7 @@ class _BulkObjectFactory(): _StringTable.AdGroupNegativeGenderCriterion: _EntityInfo(lambda: BulkAdGroupNegativeGenderCriterion()), _StringTable.AdGroupNegativeIndustryCriterion: _EntityInfo(lambda: BulkAdGroupNegativeIndustryCriterion()), _StringTable.AdGroupNegativeJobFunctionCriterion: _EntityInfo(lambda: BulkAdGroupNegativeJobFunctionCriterion()), + _StringTable.AdGroupGenreCriterion: _EntityInfo(lambda: BulkAdGroupGenreCriterion()), _StringTable.Label: _EntityInfo(lambda: BulkLabel()), _StringTable.CampaignLabel: _EntityInfo(lambda: BulkCampaignLabel()), _StringTable.AdGroupLabel: _EntityInfo(lambda: BulkAdGroupLabel()), @@ -158,6 +191,7 @@ class _BulkObjectFactory(): _StringTable.ResponsiveAdLabel: _EntityInfo(lambda: BulkResponsiveAdLabel()), _StringTable.ResponsiveSearchAdLabel: _EntityInfo(lambda: BulkResponsiveSearchAdLabel()), _StringTable.OfflineConversion: _EntityInfo(lambda: BulkOfflineConversion()), + _StringTable.OnlineConversionAdjustment: _EntityInfo(lambda: BulkOnlineConversionAdjustment()), _StringTable.SimilarRemarketingList: _EntityInfo(lambda: BulkSimilarRemarketingList()), _StringTable.AdGroupSimilarRemarketingListAssociation: _EntityInfo(lambda: BulkAdGroupSimilarRemarketingListAssociation()), _StringTable.AdGroupNegativeSimilarRemarketingListAssociation: _EntityInfo(lambda: BulkAdGroupNegativeSimilarRemarketingListAssociation()), @@ -169,7 +203,43 @@ class _BulkObjectFactory(): _StringTable.CampaignActionAdExtension: _EntityInfo(lambda: BulkCampaignActionAdExtension()), _StringTable.Experiment: _EntityInfo(lambda: BulkExperiment()), _StringTable.Feed: _EntityInfo(lambda: BulkFeed()), - _StringTable.FeedItem: _EntityInfo(lambda: BulkFeedItem()) + _StringTable.FeedItem: _EntityInfo(lambda: BulkFeedItem()), + _StringTable.CampaignConversionGoal: _EntityInfo(lambda: BulkCampaignConversionGoal()), + _StringTable.AdCustomizerAttribute: _EntityInfo(lambda: BulkAdCustomizerAttribute()), + _StringTable.AdCustomizerCampaign: _EntityInfo(lambda: BulkCampaignAdCustomizerAttribute()), + _StringTable.AdCustomizerAdGroup: _EntityInfo(lambda: BulkAdGroupAdCustomizerAttribute()), + _StringTable.AdCustomizerKeyword: _EntityInfo(lambda: BulkKeywordAdCustomizerAttribute()), + _StringTable.AssetGroup: _EntityInfo(lambda: BulkAssetGroup()), + _StringTable.AudienceGroup: _EntityInfo(lambda: BulkAudienceGroup()), + _StringTable.CampaignNegativeWebpage: _EntityInfo(lambda: BulkCampaignNegativeWebpage()), + _StringTable.AssetGroupListingGroup: _EntityInfo(lambda: BulkAssetGroupListingGroup()), + _StringTable.AudienceGroupAssetGroupAssociation: _EntityInfo(lambda: BulkAudienceGroupAssetGroupAssociation()), + _StringTable.SeasonalityAdjustment: _EntityInfo(lambda: BulkSeasonalityAdjustment()), + _StringTable.DataExclusion: _EntityInfo(lambda: BulkDataExclusion()), + 'Account Negative Keyword List': _EntityInfo(lambda: BulkAccountNegativeKeywordList()), + 'Account Negative Keyword List Association': _EntityInfo(lambda: BulkAccountNegativeKeywordListAssociation()), + 'Account Shared Negative Keyword': _EntityInfo(lambda: BulkAccountSharedNegativeKeyword()), + _StringTable.EventGoal: _EntityInfo(lambda: BulkEventGoal()), + _StringTable.AppInstallGoal: _EntityInfo(lambda: BulkAppInstallGoal()), + _StringTable.DurationGoal: _EntityInfo(lambda: BulkDurationGoal()), + _StringTable.OfflineConversionGoal: _EntityInfo(lambda: BulkOfflineConversionGoal()), + _StringTable.UrlGoal: _EntityInfo(lambda: BulkUrlGoal()), + _StringTable.InStoreTransactionGoal: _EntityInfo(lambda: BulkInStoreTransactionGoal()), + _StringTable.PagesViewedPerVisitGoal: _EntityInfo(lambda: BulkPagesViewedPerVisitGoal()), + _StringTable.InStoreVisitGoal: _EntityInfo(lambda: BulkInStoreVisitGoal()), + _StringTable.ProductGoal: _EntityInfo(lambda: BulkProductGoal()), + _StringTable.AssetGroupSearchTheme: _EntityInfo(lambda: BulkAssetGroupSearchTheme()), + _StringTable.BrandList: _EntityInfo(lambda: BulkBrandList()), + _StringTable.BrandItem: _EntityInfo(lambda: BulkBrandItem()), + _StringTable.CampaignBrandList: _EntityInfo(lambda: BulkCampaignBrandListAssociation()), + _StringTable.AssetGroupUrlTarget: _EntityInfo(lambda: BulkAssetGroupUrlTarget()), + _StringTable.NewCustomerAcquisitionGoal: _EntityInfo(lambda: BulkNewCustomerAcquisitionGoal()), + _StringTable.AccountPlacementExclusionList: _EntityInfo(lambda: BulkAccountPlacementExclusionList()), + _StringTable.AccountPlacementExclusionListItem: _EntityInfo(lambda: BulkSharedNegativeSite()), + _StringTable.CampaignAccountPlacementListAssociation: _EntityInfo(lambda: BulkAccountPlacementExclusionListAssociation()), + _StringTable.AccountPlacementInclusionList: _EntityInfo(lambda: BulkAccountPlacementInclusionList()), + _StringTable.AccountPlacementInclusionListItem: _EntityInfo(lambda: BulkSharedSite()), + _StringTable.CampaignAccountPlacementInclusionListAssociation: _EntityInfo(lambda: BulkAccountPlacementInclusionListAssociation()), } ADDITIONAL_OBJECT_MAP = { diff --git a/bingads/v13/internal/bulk/csv_headers.py b/bingads/v13/internal/bulk/csv_headers.py index 21593896..47924ea4 100644 --- a/bingads/v13/internal/bulk/csv_headers.py +++ b/bingads/v13/internal/bulk/csv_headers.py @@ -8,6 +8,7 @@ class _CsvHeaders: _StringTable.Status, _StringTable.Id, _StringTable.ParentId, + _StringTable.CampaignId, _StringTable.SubType, _StringTable.Campaign, _StringTable.AdGroup, @@ -15,6 +16,11 @@ class _CsvHeaders: _StringTable.SyncTime, _StringTable.ClientId, _StringTable.LastModifiedTime, + _StringTable.MultiMediaAdBidAdjustment, + _StringTable.UseOptimizedTargeting, + _StringTable.DynamicDescriptionEnabled, + _StringTable.Details, + # Campaign _StringTable.TimeZone, @@ -22,6 +28,9 @@ class _CsvHeaders: _StringTable.BudgetType, _StringTable.BudgetName, _StringTable.BudgetId, + _StringTable.DestinationChannel, + _StringTable.IsMultiChannelCampaign, + _StringTable.IsPolitical, # AdGroup _StringTable.StartDate, @@ -29,10 +38,21 @@ class _CsvHeaders: _StringTable.NetworkDistribution, _StringTable.AdRotation, _StringTable.CpcBid, + _StringTable.CpvBid, + _StringTable.CpmBid, _StringTable.Language, _StringTable.PrivacyStatus, _StringTable.AdGroupType, - + _StringTable.HotelAdGroupType, + _StringTable.CommissionRate, + _StringTable.PercentCpcBid, + _StringTable.FinalUrlExpansionOptOut, + _StringTable.HotelListingGroupType, + _StringTable.HotelAttribute, + _StringTable.HotelAttributeValue, + + # OnlineConversionAdjustment + _StringTable.TransactionId, # Ads _StringTable.Title, _StringTable.Text, @@ -61,6 +81,7 @@ class _CsvHeaders: _StringTable.Target, _StringTable.TargetAll, _StringTable.BidAdjustment, + _StringTable.CashbackAdjustment, _StringTable.RadiusTargetId, _StringTable.Name, _StringTable.OsNames, @@ -73,7 +94,7 @@ class _CsvHeaders: _StringTable.FromMinute, _StringTable.ToHour, _StringTable.ToMinute, - + # Profile Criterion _StringTable.Profile, _StringTable.ProfileId, @@ -81,6 +102,14 @@ class _CsvHeaders: # AdExtensions common _StringTable.Version, + #Disclaimer Ad Extension + _StringTable.DisclaimerAdsEnabled, + _StringTable.DisclaimerName, + _StringTable.DisclaimerTitle, + _StringTable.DisclaimerLayout, + _StringTable.DisclaimerPopupText, + _StringTable.DisclaimerLineText, + # SiteLink Ad Extensions _StringTable.SiteLinkExtensionOrder, _StringTable.SiteLinkDisplayText, @@ -116,7 +145,7 @@ class _CsvHeaders: _StringTable.PublisherCountries, _StringTable.Layouts, _StringTable.DisplayText, - + # Filter link ad extension _StringTable.AdExtensionHeaderType, _StringTable.Texts, @@ -125,10 +154,15 @@ class _CsvHeaders: _StringTable.Height, _StringTable.Width, + # Video + _StringTable.SourceUrl, + _StringTable.AspectRatio, + _StringTable.DurationInMillionSeconds, + # Callout Ad Extension _StringTable.CalloutText, - - #Flyer Ad Extension + + #Flyer Ad Extension _StringTable.FlyerAdExtension, _StringTable.AccountFlyerAdExtension, _StringTable.CampaignFlyerAdExtension, @@ -136,6 +170,11 @@ class _CsvHeaders: _StringTable.FlyerName, _StringTable.MediaUrls, + #Video Ad Extension + _StringTable.ThumbnailUrl, + _StringTable.ThumbnailId, + _StringTable.VideoId, + # Product Target _StringTable.MerchantCenterId, _StringTable.MerchantCenterName, @@ -289,6 +328,9 @@ class _CsvHeaders: _StringTable.InheritedBidStrategyType, _StringTable.BidStrategyTargetAdPosition, _StringTable.BidStrategyTargetImpressionShare, + _StringTable.BidStrategyCommissionRate, + _StringTable.BidStrategyPercentMaxCpc, + _StringTable.BidStrategyTargetCostPerSale, # Ad Format Preference _StringTable.AdFormatPreference, @@ -308,6 +350,9 @@ class _CsvHeaders: _StringTable.ProductAudienceType, _StringTable.SourceId, _StringTable.CombinationRule, + _StringTable.EntityType, + _StringTable.ImpressionCampaignId, + _StringTable.ImpressionAdGroupId, # Expanded Text Ad @@ -317,7 +362,7 @@ class _CsvHeaders: _StringTable.Path1, _StringTable.Path2, _StringTable.Domain, - + # Responsive Ad _StringTable.CallToAction, _StringTable.Headline, @@ -325,13 +370,18 @@ class _CsvHeaders: _StringTable.LandscapeImageMediaId, _StringTable.LandscapeLogoMediaId, _StringTable.LongHeadline, + _StringTable.LongHeadlines, _StringTable.SquareImageMediaId, _StringTable.SquareLogoMediaId, _StringTable.ImpressionTrackingUrls, + _StringTable.Headlines, + _StringTable.Descriptions, + _StringTable.CallToActionLanguage, + _StringTable.Videos, # Ad Scheduling _StringTable.AdSchedule, - + #UseSearcherTimeZone _StringTable.UseSearcherTimeZone, _StringTable.AdScheduleUseSearcherTimeZone, @@ -339,7 +389,7 @@ class _CsvHeaders: # Action ad extension _StringTable.ActionType, _StringTable.ActionText, - + # Promotion Ad Extension _StringTable.PromotionTarget, _StringTable.DiscountModifier, @@ -350,7 +400,7 @@ class _CsvHeaders: _StringTable.Occasion, _StringTable.PromotionStart, _StringTable.PromotionEnd, - _StringTable.CurrencyCode, + _StringTable.CurrencyCode, # Dynamic Search Ads _StringTable.DomainLanguage, @@ -360,6 +410,9 @@ class _CsvHeaders: _StringTable.DynamicAdTargetValue2, _StringTable.DynamicAdTargetCondition3, _StringTable.DynamicAdTargetValue3, + _StringTable.DynamicAdTargetConditionOperator1, + _StringTable.DynamicAdTargetConditionOperator2, + _StringTable.DynamicAdTargetConditionOperator3, _StringTable.PageFeedIds, _StringTable.FeedId, @@ -379,20 +432,112 @@ class _CsvHeaders: _StringTable.AdjustmentType, _StringTable.ExternalAttributionCredit, _StringTable.ExternalAttributionModel, - + _StringTable.HashedEmailAddress, + _StringTable.HashedPhoneNumber, + # Account _StringTable.MSCLKIDAutoTaggingEnabled, _StringTable.IncludeViewThroughConversions, _StringTable.ProfileExpansionEnabled, - + _StringTable.AdClickParallelTracking, + _StringTable.AutoApplyRecommendations, + _StringTable.AllowImageAutoRetrieve, + _StringTable.BusinessAttributes, _StringTable.FinalUrlSuffix, - + # Feeds _StringTable.CustomAttributes, _StringTable.FeedName, _StringTable.PhysicalIntent, _StringTable.TargetAdGroupId, - _StringTable.TargetCampaignId + _StringTable.TargetCampaignId, + _StringTable.Schedule, + + # Campaign Conversion Goal + _StringTable.GoalId, + + # RSA AdCustomizer + _StringTable.AdCustomizerDataType, + _StringTable.AdCustomizerAttributeValue, + + # Hotel Ad + _StringTable.MinTargetValue, + _StringTable.MaxTargetValue, + + # PMax + _StringTable.Audiences, + _StringTable.AssetGroup, + _StringTable.AudienceGroup, + _StringTable.AgeRanges, + _StringTable.GenderTypes, + _StringTable.ParentListingGroupId, + _StringTable.AudienceGroupName, + _StringTable.CampaignNegativeWebpage, + _StringTable.AssetGroupListingGroup, + _StringTable.AudienceGroupAssetGroupAssociation, + _StringTable.AutoGeneratedTextOptOut, + _StringTable.AutoGeneratedImageOptOut, + _StringTable.CostPerSaleOptOut, + _StringTable.SearchTheme, + + # Seasonality Adjustment + _StringTable.SeasonalityAdjustment, + _StringTable.DataExclusion, + _StringTable.DeviceType, + _StringTable.CampaignAssociations, + + # DNV Serving on MSAN + _StringTable.ShouldServeOnMSAN, + + # Goal + _StringTable.AttributionModelType, + _StringTable.ConversionWindowInMinutes, + _StringTable.CountType, + _StringTable.ExcludeFromBidding, + _StringTable.GoalCategory, + _StringTable.IsEnhancedConversionsEnabled, + _StringTable.RevenueType, + _StringTable.RevenueValue, + _StringTable.TrackingStatus, + _StringTable.ViewThroughConversionWindowInMinutes, + _StringTable.MinimumDurationInSecond, + _StringTable.ActionExpression, + _StringTable.ActionOperator, + _StringTable.CategoryExpression, + _StringTable.CategoryOperator, + _StringTable.LabelExpression, + _StringTable.LabelOperator, + _StringTable.EventValue, + _StringTable.EventValueOperator, + _StringTable.IsExternallyAttributed, + _StringTable.MinimumPagesViewed, + _StringTable.UrlExpression, + _StringTable.UrlOperator, + + # Brand List + _StringTable.BrandId, + _StringTable.BrandUrl, + _StringTable.BrandName, + _StringTable.StatusDateTime, + + # Asset Group Url Target + _StringTable.AssetGroupTargetCondition1, + _StringTable.AssetGroupTargetCondition2, + _StringTable.AssetGroupTargetCondition3, + _StringTable.AssetGroupTargetConditionOperator1, + _StringTable.AssetGroupTargetConditionOperator2, + _StringTable.AssetGroupTargetConditionOperator3, + _StringTable.AssetGroupTargetValue1, + _StringTable.AssetGroupTargetValue2, + _StringTable.AssetGroupTargetValue3, + + # New Customer Acquisition Goal + _StringTable.AdditionalConversionValue, + _StringTable.NewCustomerAcquisitionGoalId, + _StringTable.NewCustomerAcquisitionBidOnlyMode, + + _StringTable.AccountPlacementListItemUrl, + ] @staticmethod diff --git a/bingads/v13/internal/bulk/csv_reader.py b/bingads/v13/internal/bulk/csv_reader.py index 83a05302..e6218ec8 100644 --- a/bingads/v13/internal/bulk/csv_reader.py +++ b/bingads/v13/internal/bulk/csv_reader.py @@ -1,6 +1,5 @@ import csv import io -from six import PY2, PY3 class _CsvReader: @@ -18,12 +17,8 @@ def __init__(self, filename, delimiter, encoding='utf-8-sig'): self._csv_file = io.open(self.filename, encoding=self.encoding) - if PY3: - self._csv_reader = csv.reader(self._csv_file, dialect=self._dialect) - elif PY2: - byte_lines = [line.encode('utf-8') for line in self._csv_file] - self._csv_reader = csv.reader(byte_lines, dialect=self._dialect) - + self._csv_reader = csv.reader(self._csv_file, dialect=self._dialect) + def __enter__(self): return self @@ -40,12 +35,8 @@ def close(self): self.__exit__(None, None, None) def next(self): - if PY3: - return next(self._csv_reader) - elif PY2: - row = next(self._csv_reader) - return [unicode(cell, encoding='utf-8') for cell in row] - + return next(self._csv_reader) + @property def filename(self): return self._filename diff --git a/bingads/v13/internal/bulk/csv_writer.py b/bingads/v13/internal/bulk/csv_writer.py index 5d8c4ff4..ce4c5df8 100644 --- a/bingads/v13/internal/bulk/csv_writer.py +++ b/bingads/v13/internal/bulk/csv_writer.py @@ -1,6 +1,5 @@ import csv import codecs -from six import PY2, PY3 class _CsvWriter: @@ -16,11 +15,7 @@ def __init__(self, filename, delimiter): else: raise ValueError('Do not support delimiter: {0}', delimiter) - if PY3: - self._csv_file = codecs.open(filename, mode='w', encoding=self._encoding) - elif PY2: - self._csv_file = open(filename, mode='wb') - self._csv_file.write(codecs.BOM_UTF8) + self._csv_file = codecs.open(filename, mode='w', encoding=self._encoding) self._csv_writer = csv.writer(self._csv_file, dialect=self._dialect) def __enter__(self): @@ -34,14 +29,7 @@ def close(self): self.__exit__(None, None, None) def writerow(self, row): - if PY3: - self._csv_writer.writerow(row) - elif PY2: - def unicode_to_str(value): - if not isinstance(value, unicode): - return value - return value.encode('utf-8') - self._csv_writer.writerow([unicode_to_str(cell) for cell in row]) + self._csv_writer.writerow(row) def writerows(self, rows): for row in rows: diff --git a/bingads/v13/internal/bulk/entities/bulk_entity_identifier.py b/bingads/v13/internal/bulk/entities/bulk_entity_identifier.py index 32d9d975..df086930 100644 --- a/bingads/v13/internal/bulk/entities/bulk_entity_identifier.py +++ b/bingads/v13/internal/bulk/entities/bulk_entity_identifier.py @@ -1,13 +1,10 @@ -from __future__ import absolute_import, division, print_function from abc import ABCMeta, abstractproperty, abstractmethod -from future.utils import with_metaclass - from bingads.v13.bulk.entities import BulkError from bingads.v13.internal.bulk.bulk_object import _BulkObject -class _BulkEntityIdentifier(with_metaclass(ABCMeta, _BulkObject)): +class _BulkEntityIdentifier(_BulkObject, metaclass=ABCMeta): @abstractproperty def is_delete_row(self): diff --git a/bingads/v13/internal/bulk/entities/bulk_shared_negative_site.py b/bingads/v13/internal/bulk/entities/bulk_shared_negative_site.py new file mode 100644 index 00000000..96e94cad --- /dev/null +++ b/bingads/v13/internal/bulk/entities/bulk_shared_negative_site.py @@ -0,0 +1,108 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkSharedNegativeSite(_SingleRecordBulkEntity): + """ Represents a negative site. + + This class exposes the property :attr:`negative_site` that can be read and written as fields of the negative site record + in a bulk file. + + For more information, see negative site at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, parent_id=None, status=None, negative_site=None): + super(BulkSharedNegativeSite, self).__init__() + + self._parent_id = parent_id + self._status = status + self._negative_site = negative_site + + @property + def parent_id(self): + """ The identifier of the parent entity that contains the negative site. + + Corresponds to the 'Parent Id' field in the bulk file. + + :rtype: int + """ + + return self._parent_id + + @parent_id.setter + def parent_id(self, parent_id): + self._parent_id = parent_id + + @property + def status(self): + """ The status of the negative site. + + Corresponds to the 'Status' field in the bulk file. + + :rtype: str + """ + + return self._status + + @status.setter + def status(self, status): + self._status = status + + @property + def negative_site(self): + """ The NegativeSite Data Object of the Campaign Management Service. + + A subset of NegativeSite properties are available in the Ad Group record. + For more information, see Ad Group at https://go.microsoft.com/fwlink/?linkid=846127. + """ + return self._negative_site + + @negative_site.setter + def negative_site(self, negative_site): + self._negative_site = negative_site + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.negative_site.Id), + csv_to_field=lambda c, v: setattr(c.negative_site, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.status), + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.parent_id), + csv_to_field=lambda c, v: setattr(c, 'parent_id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AccountPlacementListItemUrl, + field_to_csv=lambda c: bulk_str(c.negative_site.Url), + csv_to_field=lambda c, v: setattr(c.negative_site, 'Url', v if v else None) + ), + ] + + + def process_mappings_from_row_values(self, row_values): + self.negative_site = _CAMPAIGN_OBJECT_FACTORY_V13.create('NegativeSite') + + row_values.convert_to_entity(self, BulkSharedNegativeSite._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._negative_site, 'NegativeSite') + self.convert_to_values(row_values, BulkSharedNegativeSite._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkSharedNegativeSite, self).read_additional_data(stream_reader) diff --git a/bingads/v13/internal/bulk/entities/bulk_shared_site.py b/bingads/v13/internal/bulk/entities/bulk_shared_site.py new file mode 100644 index 00000000..4d65499c --- /dev/null +++ b/bingads/v13/internal/bulk/entities/bulk_shared_site.py @@ -0,0 +1,111 @@ +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 + +from bingads.v13.internal.bulk.string_table import _StringTable +from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v13.internal.extensions import * + +class BulkSharedSite(_SingleRecordBulkEntity): + """ Represents a site. + + This class exposes the property :attr:`site` that can be read and written as fields of the site record + in a bulk file. + + For more information, see site at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, parent_id=None, url=None, status=None, site=None): + super(BulkSharedSite, self).__init__() + + self._parent_id = parent_id + self._url = url + self._status = status + self._site = site + + @property + def parent_id(self): + """ The identifier of the parent entity that contains the site. + + Corresponds to the 'Parent Id' field in the bulk file. + + :rtype: int + """ + + return self._parent_id + + @parent_id.setter + def parent_id(self, parent_id): + self._parent_id = parent_id + + @property + def url(self): + """ The url of a website. + + Corresponds to the 'Website' field in the bulk file. + + :rtype: str + """ + + return self._url + + @url.setter + def url(self, url): + self._url = url + + @property + def status(self): + """ The status of the site. + + Corresponds to the 'Status' field in the bulk file. + + :rtype: str + """ + + return self._status + + @status.setter + def status(self, status): + self._status = status + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Id, + field_to_csv=lambda c: bulk_str(c.site.Id), + csv_to_field=lambda c, v: setattr(c.site, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Status, + field_to_csv=lambda c: bulk_str(c.status), + csv_to_field=lambda c, v: setattr(c, 'status', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.parent_id), + csv_to_field=lambda c, v: setattr(c, 'parent_id', int(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AccountPlacementListItemUrl, + field_to_csv=lambda c: bulk_str(c.site.Url), + csv_to_field=lambda c, v: setattr(c.site, 'Url', v if v else None) + ), + ] + + + def process_mappings_from_row_values(self, row_values): + self.site = _CAMPAIGN_OBJECT_FACTORY_V13.create('Site') + + row_values.convert_to_entity(self, BulkSharedSite._MAPPINGS) + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self._site, 'Site') + self.convert_to_values(row_values, BulkSharedSite._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkSharedSite, self).read_additional_data(stream_reader) diff --git a/bingads/v13/internal/bulk/entities/multi_record_bulk_entity.py b/bingads/v13/internal/bulk/entities/multi_record_bulk_entity.py index f5ea7495..57ac25c7 100644 --- a/bingads/v13/internal/bulk/entities/multi_record_bulk_entity.py +++ b/bingads/v13/internal/bulk/entities/multi_record_bulk_entity.py @@ -1,9 +1,8 @@ from abc import ABCMeta, abstractproperty -from future.utils import with_metaclass from bingads.v13.bulk.entities.bulk_entity import BulkEntity -class _MultiRecordBulkEntity(with_metaclass(ABCMeta, BulkEntity)): +class _MultiRecordBulkEntity(BulkEntity, metaclass=ABCMeta): """ Bulk entity that has its data in multiple records within the bulk file. For more information, see Bulk File Schema at https://go.microsoft.com/fwlink/?linkid=846127. diff --git a/bingads/v13/internal/bulk/entities/single_record_bulk_entity.py b/bingads/v13/internal/bulk/entities/single_record_bulk_entity.py index 7069f1fd..e96c0bb4 100644 --- a/bingads/v13/internal/bulk/entities/single_record_bulk_entity.py +++ b/bingads/v13/internal/bulk/entities/single_record_bulk_entity.py @@ -1,7 +1,5 @@ from abc import ABCMeta, abstractmethod -from future.utils import with_metaclass - from bingads.v13.internal.bulk.string_table import _StringTable from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping from bingads.v13.bulk.entities.bulk_entity import BulkEntity @@ -9,7 +7,7 @@ from bingads.v13.internal.extensions import * -class _SingleRecordBulkEntity(with_metaclass(ABCMeta, BulkEntity)): +class _SingleRecordBulkEntity(BulkEntity,metaclass=ABCMeta): def __init__(self): self._client_id = None self._last_modified_time = None diff --git a/bingads/v13/internal/bulk/mappings.py b/bingads/v13/internal/bulk/mappings.py index 24b4cdc3..5a5cc048 100644 --- a/bingads/v13/internal/bulk/mappings.py +++ b/bingads/v13/internal/bulk/mappings.py @@ -1,8 +1,7 @@ -from future.utils import with_metaclass from abc import ABCMeta, abstractmethod -class _BulkMapping(with_metaclass(ABCMeta)): +class _BulkMapping(metaclass=ABCMeta): @abstractmethod def convert_to_csv(self, entity, row_values): raise NotImplementedError() @@ -12,7 +11,7 @@ def convert_to_entity(self, row_values, entity): raise NotImplementedError() -class _SingleFieldBulkMapping(with_metaclass(ABCMeta, _BulkMapping)): +class _SingleFieldBulkMapping(_BulkMapping, metaclass=ABCMeta): def __init__(self, csv_to_field, filed_to_csv): self._csv_to_field = csv_to_field self._field_to_csv = filed_to_csv diff --git a/bingads/v13/internal/bulk/object_reader.py b/bingads/v13/internal/bulk/object_reader.py index fa3c8b03..59abdcee 100644 --- a/bingads/v13/internal/bulk/object_reader.py +++ b/bingads/v13/internal/bulk/object_reader.py @@ -1,5 +1,4 @@ import csv -from six import PY2, PY3 from .bulk_object_factory import _BulkObjectFactory from .row_values import _RowValues from .csv_reader import _CsvReader @@ -84,11 +83,7 @@ def encoding(self): class _CsvRowsReader: def __init__(self, csv_rows): - if PY3: - self._csv_reader = csv.reader(csv_rows, dialect=csv.excel) - elif PY2: - byte_lines = [line.encode('utf-8') for line in csv_rows] - self._csv_reader = csv.reader(byte_lines, dialect=csv.excel) + self._csv_reader = csv.reader(csv_rows, dialect=csv.excel) def __enter__(self): return self diff --git a/bingads/v13/internal/bulk/row_values.py b/bingads/v13/internal/bulk/row_values.py index 9492926b..52b98701 100644 --- a/bingads/v13/internal/bulk/row_values.py +++ b/bingads/v13/internal/bulk/row_values.py @@ -1,7 +1,6 @@ from .csv_headers import _CsvHeaders from .mappings import _SimpleBulkMapping from bingads.v13.bulk import EntityReadException -import six class _RowValues: @@ -47,8 +46,6 @@ def _create_entity_read_exception(self, entity, mapping, ex): else: message = "Couldn't parse {0} entity: {1}".format(entity_type, str(ex)) message += " See ColumnValues for detailed row information and InnerException for error details." - if six.PY2: - message = message.decode('ascii') message += u' row values: {0}'.format(self) return EntityReadException(message=message, row_values=str(self), inner_exception=ex) diff --git a/bingads/v13/internal/bulk/string_table.py b/bingads/v13/internal/bulk/string_table.py index 6dee53d8..683406e9 100644 --- a/bingads/v13/internal/bulk/string_table.py +++ b/bingads/v13/internal/bulk/string_table.py @@ -7,6 +7,7 @@ class _StringTable: Id = "Id" BusinessId = "Business Id" ParentId = "Parent Id" + CampaignId = "Campaign Id" TimeZone = "Time Zone" Budget = "Budget" BudgetType = "Budget Type" @@ -21,6 +22,13 @@ class _StringTable: BudgetId = "Budget Id" AdGroup = "Ad Group" AdGroupType = "Ad Group Type" + HotelAdGroupType = "Hotel Ad Group Type" + CommissionRate = "Commission Rate" + PercentCpcBid = "Percent Cpc Bid" + FinalUrlExpansionOptOut = "Url Expansion Opt Out" + HotelListingGroupType = "Ad Group Hotel Listing Group" + HotelAttribute = "Hotel Attribute" + HotelAttributeValue = "Hotel Attribute Value" Keyword = "Keyword" TextAd = "Text Ad" ProductAd = "Product Ad" @@ -46,6 +54,7 @@ class _StringTable: Param2 = "Param2" Param3 = "Param3" DevicePreference = "Device Preference" + Details = "Verified Tracking Setting" CampaignNegativeKeyword = "Campaign Negative Keyword" CampaignNegativeSite = "Campaign Negative Site" AdGroupNegativeKeyword = "Ad Group Negative Keyword" @@ -60,13 +69,14 @@ class _StringTable: FeedName = "Feed Name" TargetAdGroupId = 'Target Ad Group Id' TargetCampaignId = 'Target Campaign Id' - CustomAttributes = "Custom Attributes"; - PageFeedIds = "Page Feed Ids"; + CustomAttributes = "Custom Attributes" + PageFeedIds = "Page Feed Ids" PhysicalIntent = "Physical Intent" Bid = "Bid" Profile = "Profile" ProfileId = "Profile Id" BidAdjustment = "Bid Adjustment" + CashbackAdjustment = "Cashback Percent" SubType = "Sub Type" OsNames = "OS Names" StartDate = "Start Date" @@ -74,6 +84,8 @@ class _StringTable: NetworkDistribution = "Network Distribution" Language = "Language" CpcBid = "Cpc Bid" + CpvBid = "Cpv Bid" + CpmBid = "Cpm Bid" AdRotation = "Ad Rotation" PrivacyStatus = "Privacy Status" Account = "Account" @@ -84,6 +96,14 @@ class _StringTable: AdFormatPreference = "Ad Format Preference" IncludeViewThroughConversions = "Include View Through Conversions" ProfileExpansionEnabled = "Profile Expansion Enabled" + AdClickParallelTracking = "Ad Click Parallel Tracking" + AutoApplyRecommendations = "Auto Apply Recommendations" + AllowImageAutoRetrieve = "Allow Image Auto Retrieve" + MultiMediaAdBidAdjustment = "Multi Media Ad Bid Adjustment" + UseOptimizedTargeting = "Use Optimized Targeting" + BusinessAttributes = "Business Attributes" + Schedule = "Schedule" + IsPolitical = "Is Political" # Entity Types SemanticVersion = "Format Version" @@ -104,6 +124,17 @@ class _StringTable: SocialNetworkAdExtension = "Social Network Ad Extension" Version = "Version" + # Disclaimer Ads + DisclaimerAdsEnabled = "Disclaimer Ads Enabled" + DisclaimerName = "Disclaimer Name" + DisclaimerTitle = "Disclaimer Title" + DisclaimerLayout = "Disclaimer Layout" + DisclaimerPopupText = "Disclaimer Popup Text" + DisclaimerLineText = "Disclaimer Line Text" + + DisclaimerAdExtension = "Disclaimer Ad Extension" + CampaignDisclaimerAdExtension = "Campaign Disclaimer Ad Extension" + # Image Ad Extension AltText = "Alternative Text" MediaIds = "Media Ids" @@ -112,7 +143,7 @@ class _StringTable: AdGroupImageAdExtension = "Ad Group Image Ad Extension" Layouts = "Layouts" DisplayText = "Display Text" - + # Filter Link ad extension FilterLinkAdExtension = "Filter Link Ad Extension" AccountFilterLinkAdExtension = "Account Filter Link Ad Extension" @@ -145,7 +176,7 @@ class _StringTable: CampaignCallAdExtension = "Campaign Call Ad Extension" IsCallTrackingEnabled = "Call Tracking Enabled" RequireTollFreeTrackingNumber = "Toll Free" - + #Action Ad Extension ActionAdExtension = "Action Ad Extension" AccountActionAdExtension = "Account Action Ad Extension" @@ -153,22 +184,31 @@ class _StringTable: AdGroupActionAdExtension = "Ad Group Action Ad Extension" ActionType = "Action Type" ActionText = "Action Text" - + + #Video Ad Extension + VideoAdExtension = "Video Ad Extension" + ThumbnailUrl = "Thumbnail Url" + ThumbnailId = "Thumbnail Id" + VideoId = "Video Id" + AccountVideoAdExtension = "Account Video Ad Extension" + CampaignVideoAdExtension = "Campaign Video Ad Extension" + AdGroupVideoAdExtension = "Ad Group Video Ad Extension" + #Promotion AdExtension - PromotionAdExtension = "Promotion Ad Extension"; - AccountPromotionAdExtension = "Account Promotion Ad Extension"; - CampaignPromotionAdExtension = "Campaign Promotion Ad Extension"; - AdGroupPromotionAdExtension = "Ad Group Promotion Ad Extension"; - PromotionTarget = "Promotion Target"; - DiscountModifier = "Discount Modifier"; - PercentOff = "Percent Off"; - MoneyAmountOff = "Money Amount Off"; - PromotionCode = "Promotion Code"; - OrdersOverAmount = "Orders Over Amount"; - Occasion = "Occasion"; - PromotionStart = "Promotion Start"; - PromotionEnd = "Promotion End"; - CurrencyCode = "Currency Code"; + PromotionAdExtension = "Promotion Ad Extension" + AccountPromotionAdExtension = "Account Promotion Ad Extension" + CampaignPromotionAdExtension = "Campaign Promotion Ad Extension" + AdGroupPromotionAdExtension = "Ad Group Promotion Ad Extension" + PromotionTarget = "Promotion Target" + DiscountModifier = "Discount Modifier" + PercentOff = "Percent Off" + MoneyAmountOff = "Money Amount Off" + PromotionCode = "Promotion Code" + OrdersOverAmount = "Orders Over Amount" + Occasion = "Occasion" + PromotionStart = "Promotion Start" + PromotionEnd = "Promotion End" + CurrencyCode = "Currency Code" # Structured Snippet Ad Extension StructuredSnippetAdExtension = "Structured Snippet Ad Extension" @@ -183,8 +223,8 @@ class _StringTable: AdGroupSitelinkAdExtension = "Ad Group Sitelink Ad Extension" CampaignSitelinkAdExtension = "Campaign Sitelink Ad Extension" AccountSitelinkAdExtension = "Account Sitelink Ad Extension" - - + + # Flyer Ad Extension FlyerAdExtension = "Flyer Ad Extension" AccountFlyerAdExtension = "Account Flyer Ad Extension" @@ -278,10 +318,11 @@ class _StringTable: CampaignType = "Campaign Type" CampaignPriority = "Priority" LocalInventoryAdsEnabled = "LocalInventoryAdsEnabled" - + DynamicDescriptionEnabled = "Dynamic Description Enabled" + CampaignNegativeStoreCriterion = "Campaign Negative Store Criterion" - + # CoOp BidOption = "Bid Option" BidBoostValue = "Bid Boost Value" @@ -312,7 +353,7 @@ class _StringTable: AdGroupPriceAdExtension = "Ad Group Price Ad Extension" PriceExtensionType = "Price Extension Type" Header1 = "Header 1" - Header2 = "Header 2" + Header2 = "Header 2" Header3 = "Header 3" Header4 = "Header 4" Header5 = "Header 5" @@ -343,7 +384,7 @@ class _StringTable: FinalMobileUrl6 = "Final Mobile Url 6" FinalMobileUrl7 = "Final Mobile Url 7" FinalMobileUrl8 = "Final Mobile Url 8" - Price1 = "Price 1" + Price1 = "Price 1" Price2 = "Price 2" Price3 = "Price 3" Price4 = "Price 4" @@ -394,6 +435,9 @@ class _StringTable: InheritedBidStrategyType = "Inherited Bid Strategy Type" BidStrategyTargetAdPosition = "Bid Strategy TargetAdPosition" BidStrategyTargetImpressionShare = "Bid Strategy TargetImpressionShare" + BidStrategyPercentMaxCpc = "Bid Strategy PercentMaxCpc" + BidStrategyCommissionRate = "Bid Strategy CommissionRate" + BidStrategyTargetCostPerSale = "Bid Strategy TargetCostPerSale" # Remarketing Audience = "Audience" @@ -409,9 +453,8 @@ class _StringTable: AudienceNetworkSize = "Audience Network Size" SupportedCampaignTypes = "Supported Campaign Types" ProductAudienceType = "Product Audience Type" - CombinationRule = "Combination Rule" + CombinationRule = "Combination Rule" SourceId = "Source Id" - ProductAudienceType = "Product Audience Type" AdGroupProductAudienceAssociation = "Ad Group Product Audience Association" AdGroupNegativeProductAudienceAssociation = "Ad Group Negative Product Audience Association" CampaignProductAudienceAssociation = "Campaign Product Audience Association" @@ -426,7 +469,7 @@ class _StringTable: AdGroupNegativeRemarketingListAssociation = 'Ad Group Negative Remarketing List Association' CampaignRemarketingListAssociation = 'Campaign Remarketing List Association' CampaignNegativeRemarketingListAssociation = 'Campaign Negative Remarketing List Association' - CustomAudience = "Custom Audience"; + CustomAudience = "Custom Audience" AdGroupCustomAudienceAssociation = "Ad Group Custom Audience Association" AdGroupNegativeCustomAudienceAssociation = "Ad Group Negative Custom Audience Association" CampaignCustomAudienceAssociation = "Campaign Custom Audience Association" @@ -447,7 +490,15 @@ class _StringTable: AdGroupNegativeCustomerListAssociation = "Ad Group Negative Customer List Association" CampaignCustomerListAssociation = "Campaign Customer List Association" CampaignNegativeCustomerListAssociation = "Campaign Negative Customer List Association" - + ImpressionBasedRemarketingList = "Impression Based Remarketing List" + AdGroupImpressionBasedRemarketingListAssociation = "Ad Group Impression Based Remarketing List Association" + AdGroupNegativeImpressionBasedRemarketingListAssociation = "Ad Group Negative Impression Based Remarketing List Association" + CampaignImpressionBasedRemarketingListAssociation = "Campaign Impression Based Remarketing List Association" + CampaignNegativeImpressionBasedRemarketingListAssociation = "Campaign Negative Impression Based Remarketing List Association" + EntityType = "Entity Type" + ImpressionCampaignId = "Impression Campaign Id" + ImpressionAdGroupId = "Impression Ad Group Id" + # Expanded Text Ad TitlePart1 = "Title Part 1" TitlePart2 = "Title Part 2" @@ -458,7 +509,7 @@ class _StringTable: # Ad Extension Scheduling AdSchedule = "Ad Schedule" - + #UseSearcherTimeZone UseSearcherTimeZone = "Use Searcher Time Zone" AdScheduleUseSearcherTimeZone = "Ad Schedule Use Searcher Time Zone" @@ -471,7 +522,10 @@ class _StringTable: DynamicAdTargetValue2 = "Dynamic Ad Target Value 2" DynamicAdTargetCondition3 = "Dynamic Ad Target Condition 3" DynamicAdTargetValue3 = "Dynamic Ad Target Value 3" - + DynamicAdTargetConditionOperator1 = "Dynamic Ad Target Condition Operator 1" + DynamicAdTargetConditionOperator2 = "Dynamic Ad Target Condition Operator 2" + DynamicAdTargetConditionOperator3 = "Dynamic Ad Target Condition Operator 3" + AdGroupAgeCriterion = "Ad Group Age Criterion" AdGroupDayTimeCriterion = "Ad Group DayTime Criterion" AdGroupDeviceCriterion = "Ad Group DeviceOS Criterion" @@ -488,7 +542,7 @@ class _StringTable: AdGroupNegativeGenderCriterion = "Ad Group Negative Gender Criterion" AdGroupNegativeIndustryCriterion = "Ad Group Negative Industry Criterion" AdGroupNegativeJobFunctionCriterion = "Ad Group Negative Job Function Criterion" - + AdGroupGenreCriterion = "Ad Group Genre Criterion" # Responsive Ad ResponsiveAd = "Responsive Ad" @@ -498,15 +552,25 @@ class _StringTable: LandscapeImageMediaId = "Landscape Image Media Id" LandscapeLogoMediaId = "Landscape Logo Media Id" LongHeadline = "Long Headline" + LongHeadlines = "Long Headlines" SquareImageMediaId = "Square Image Media Id" SquareLogoMediaId = "Square Logo Media Id" ImpressionTrackingUrls = "Impression Tracking Urls" - + CallToActionLanguage = "Call To Action Language" + Descriptions = "Descriptions" + Headlines = "Headlines" + Videos = "Videos" + #Image Image = "Image" Height = "Height" Width = "Width" - + + # Video + Video = "Video" + SourceUrl = "Source Url" + AspectRatio = "Aspect Ratio" + DurationInMillionSeconds = "Duration In Milliseconds" # Responsive Search Ad ResponsiveSearchAd = "Responsive Search Ad" @@ -538,7 +602,8 @@ class _StringTable: AdjustmentType = "Adjustment Type" ExternalAttributionModel = "External Attribution Model" ExternalAttributionCredit = "External Attribution Credit" - + HashedEmailAddress = "Hashed Email Address" + HashedPhoneNumber = "Hashed Phone Number" # Campaign Criterion CampaignAgeCriterion = 'Campaign Age Criterion' @@ -552,5 +617,137 @@ class _StringTable: CampaignCompanyNameCriterion = 'Campaign Company Name Criterion' CampaignJobFunctionCriterion = 'Campaign Job Function Criterion' CampaignIndustryCriterion = 'Campaign Industry Criterion' + CampaignDealCriterion = 'Campaign Deal Criterion' + + # Online Conversion + OnlineConversionAdjustment = "Online Conversion Adjustment" + TransactionId = "Transaction Id" + + # Hotel Ad + AdGroupAdvanceBookingWindowCriterion = "Ad Group Advance Booking Window Criterion" + AdGroupCheckInDayCriterion = "Ad Group Check In Day Criterion" + AdGroupLengthOfStayCriterion = "Ad Group Length of Stay Criterion" + AdGroupHotelDateSelectionTypeCriterion = "Ad Group Hotel Date Selection Type Criterion" + AdGroupCheckInDateCriterion = "Ad Group Check In Date Criterion" + MinTargetValue = "Min Target Value" + MaxTargetValue = "Max Target Value" FinalUrlSuffix = "Final Url Suffix" + + # AdCustomizerAttribute + AdCustomizerAttribute = "Adcustomizer Attribute" + AdCustomizerCampaign = "Campaign Adcustomizer Attribute" + AdCustomizerAdGroup = "Adgroup Adcustomizer Attribute" + AdCustomizerKeyword = "Keyword Adcustomizer Attribute" + AdCustomizerDataType = "AdCustomizer DataType" + AdCustomizerAttributeValue = "AdCustomizer AttributeValue" + + # Campaign Conversion Goal + CampaignConversionGoal = "Campaign Conversion Goal" + GoalId = "Goal Id" + + # PMax + AssetGroup = "Asset Group" + AudienceGroup = "Audience Group" + CampaignNegativeWebpage = "Campaign Negative Webpage" + AssetGroupListingGroup = "Asset Group Listing Group" + AudienceGroupAssetGroupAssociation = "Audience Group Asset Group Association" + Audiences = "Audiences" + AudienceGroupName = "Audience Group Name" + AgeRanges = "Age Ranges" + GenderTypes = "Gender Types" + ParentListingGroupId = "Parent Listing Group Id" + AutoGeneratedTextOptOut = "Auto Generated Text Assets Opt Out" + AutoGeneratedImageOptOut = "Auto Generated Image Assets Opt Out" + CostPerSaleOptOut = "Cost Per Sale Opt Out" + AssetGroupSearchTheme = "Asset Group Search Theme" + SearchTheme = "Search Theme" + + # MultiChannel Campaign + DestinationChannel = "Destination Channel" + IsMultiChannelCampaign = "Is Multi Channel Campaign" + + # Seasonality Adjustment + SeasonalityAdjustment = "Seasonality Adjustment" + DataExclusion = "Data Exclusion" + DeviceType = "Device Type" + CampaignAssociations = "Campaign Associations" + + # DNV Serving on MSAN + ShouldServeOnMSAN = "Should Serve On MSAN" + + # Conversion Goal + AttributionModelType = "Attribution Model Type" + ConversionWindowInMinutes = "Conversion Window In Minutes" + CountType = "Count Type" + ExcludeFromBidding = "Exclude From Bidding" + GoalCategory = "Goal Category" + IsEnhancedConversionsEnabled = "Is Enhanced Conversions Enabled" + RevenueType = "Revenue Type" + RevenueValue = "Revenue Value" + TrackingStatus = "Tracking Status" + ViewThroughConversionWindowInMinutes = "View Through Conversion Window In Minutes" + MinimumDurationInSecond = "Minimum Duration In Second" + ActionExpression = "Action Expression" + ActionOperator = "Action Operator" + CategoryExpression = "Category Expression" + CategoryOperator = "Category Operator" + LabelExpression = "Label Expression" + LabelOperator = "Label Operator" + EventValue = "Event Value" + EventValueOperator = "Event Value Operator" + IsExternallyAttributed = "Is Externally Attributed" + MinimumPagesViewed = "Minimum Pages Viewed" + UrlExpression = "URL Expression" + UrlOperator = "URL Operator" + ConversionGoal = "Conversion Goal" + EventGoal = "Event Goal" + AppInstallGoal = "AppInstall Goal" + MultiStageGoal = "MultiStage Goal" + DurationGoal = "Duration Goal" + OfflineConversionGoal = "OfflineConversion Goal" + UrlGoal = "URL Goal" + InStoreTransactionGoal = "InStoreTransaction Goal" + PagesViewedPerVisitGoal = "PagesViewedPerVisit Goal" + SmartGoal = "Smart Goal" + InStoreVisitGoal = "InStoreVisit Goal" + ProductGoal = "Product Goal" + + # Brand List + BrandList = "Brand List" + BrandItem = "Brand Item" + CampaignBrandList = "Campaign Brand List Association" + BrandId = "Brand Id" + BrandUrl = "Brand Url" + BrandName = "Brand Name" + StatusDateTime = "Editorial Status Date" + + # Asset Group Url Target + AssetGroupUrlTarget = "Asset Group Url Target" + AssetGroupTargetCondition1 = "Asset Group Target Condition 1" + AssetGroupTargetCondition2 = "Asset Group Target Condition 2" + AssetGroupTargetCondition3 = "Asset Group Target Condition 3" + AssetGroupTargetConditionOperator1 = "Asset Group Target Condition Operator 1" + AssetGroupTargetConditionOperator2 = "Asset Group Target Condition Operator 2" + AssetGroupTargetConditionOperator3 = "Asset Group Target Condition Operator 3" + AssetGroupTargetValue1 = "Asset Group Target Value 1" + AssetGroupTargetValue2 = "Asset Group Target Value 2" + AssetGroupTargetValue3 = "Asset Group Target Value 3" + + # New Customer Acquisition Goal + NewCustomerAcquisitionGoal = "New Customer Acquisition Goal" + AdditionalConversionValue = "Additional Conversion Value" + NewCustomerAcquisitionGoalId = "New Customer Acquisition Goal Id" + NewCustomerAcquisitionBidOnlyMode = "New Customer Acquisition Bid Only Mode" + + AccountPlacementExclusionList = "Account Placement Exclusion List" + AccountPlacementExclusionListItem = "Account Placement Exclusion List Item" + AccountPlacementListItemUrl = "Site List Item Url" + CampaignAccountPlacementListAssociation = "Campaign Account Placement Exclusion List Association" + AccountPlacementExclusionListId = "Account Placement Exclusion List Id" + AccountPlacementExclusionListItemId = "Account Placement Exclusion List Item Id" + AccountPlacementInclusionList = "Account Placement Inclusion List" + AccountPlacementInclusionListItem = "Account Placement Inclusion List Item" + CampaignAccountPlacementInclusionListAssociation = "Campaign Account Placement Inclusion List Association" + AccountPlacementInclusionListId = "Account Placement Inclusion List Id" + AccountPlacementInclusionListItemId = "Account Placement Inclusion List Item Id" diff --git a/bingads/v13/internal/extensions.py b/bingads/v13/internal/extensions.py index 6cee1d57..7838891f 100644 --- a/bingads/v13/internal/extensions.py +++ b/bingads/v13/internal/extensions.py @@ -1,10 +1,9 @@ from datetime import datetime from bingads.v13.internal.bulk.string_table import _StringTable -from six import PY2 import re import json -from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13, _CAMPAIGN_MANAGEMENT_SERVICE_V13 +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13 target_setting_detail_pattern=r'^(Age|Audience|CompanyName|Gender|Industry|JobFunction)$' @@ -18,7 +17,24 @@ custom_param_pattern = r'^\{_(.*?)\}=(.*$)' combine_rule_pattern = r'^(And|Or|Not)\(([\d|\s|,]*?)\)$' +AdEditorialStatus = _CAMPAIGN_OBJECT_FACTORY_V13.create('AdEditorialStatus') +AdStatus = _CAMPAIGN_OBJECT_FACTORY_V13.create('AdStatus') +AssetGroupStatus = _CAMPAIGN_OBJECT_FACTORY_V13.create('AssetGroupStatus') +AdGroupStatus = _CAMPAIGN_OBJECT_FACTORY_V13.create('AdGroupStatus') +AssetGroupEditorialStatus = _CAMPAIGN_OBJECT_FACTORY_V13.create('AssetGroupEditorialStatus') +AdExtensionStatus = _CAMPAIGN_OBJECT_FACTORY_V13.create('AdExtensionStatus') +EntityScope = _CAMPAIGN_OBJECT_FACTORY_V13.create('EntityScope') +Network = _CAMPAIGN_OBJECT_FACTORY_V13.create('Network') +Minute = _CAMPAIGN_OBJECT_FACTORY_V13.create('Minute') +Day = _CAMPAIGN_OBJECT_FACTORY_V13.create('Day') +BusinessGeoCodeStatus = _CAMPAIGN_OBJECT_FACTORY_V13.create('BusinessGeoCodeStatus') +BidOption = _CAMPAIGN_OBJECT_FACTORY_V13.create('BidOption') +CallToAction = _CAMPAIGN_OBJECT_FACTORY_V13.create('CallToAction') +MatchType = _CAMPAIGN_OBJECT_FACTORY_V13.create('MatchType') +KeywordEditorialStatus = _CAMPAIGN_OBJECT_FACTORY_V13.create('KeywordEditorialStatus') +KeywordStatus = _CAMPAIGN_OBJECT_FACTORY_V13.create('KeywordStatus') BudgetLimitType = _CAMPAIGN_OBJECT_FACTORY_V13.create('BudgetLimitType') +CampaignStatus = _CAMPAIGN_OBJECT_FACTORY_V13.create('CampaignStatus') DynamicSearchAdsSetting = _CAMPAIGN_OBJECT_FACTORY_V13.create('DynamicSearchAdsSetting') Webpage = _CAMPAIGN_OBJECT_FACTORY_V13.create('Webpage') WebpageConditionOperand = _CAMPAIGN_OBJECT_FACTORY_V13.create('WebpageConditionOperand') @@ -30,30 +46,40 @@ CustomEventsRule = _CAMPAIGN_OBJECT_FACTORY_V13.create('CustomEventsRule') StringOperator = _CAMPAIGN_OBJECT_FACTORY_V13.create('StringOperator') NumberOperator = _CAMPAIGN_OBJECT_FACTORY_V13.create('NumberOperator') +NormalForm = _CAMPAIGN_OBJECT_FACTORY_V13.create('NormalForm') AudienceCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('AudienceCriterion') BidMultiplier = _CAMPAIGN_OBJECT_FACTORY_V13.create('BidMultiplier') +CashbackAdjustment = _CAMPAIGN_OBJECT_FACTORY_V13.create('CashbackAdjustment') AgeCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('AgeCriterion') DayTimeCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('DayTimeCriterion') DeviceCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('DeviceCriterion') GenderCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('GenderCriterion') +HotelAdvanceBookingWindowCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelAdvanceBookingWindowCriterion') +HotelCheckInDateCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelCheckInDateCriterion') +GenreCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('GenreCriterion') +HotelCheckInDayCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelCheckInDayCriterion') +HotelDateSelectionTypeCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelDateSelectionTypeCriterion') +HotelLengthOfStayCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelLengthOfStayCriterion') LocationCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('LocationCriterion') LocationIntentCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('LocationIntentCriterion') RadiusCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('RadiusCriterion') +DealCriterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('DealCriterion') TargetSetting_Type = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('TargetSetting')) +HotelSetting_Type = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('HotelSetting')) CoOpSetting_Type = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('CoOpSetting')) TextAsset_Type = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('TextAsset')) ImageAsset_Type = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('ImageAsset')) +VideoAsset_Type = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('VideoAsset')) +CampaignAssociation = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('CampaignAssociation')) + def bulk_str(value): if value is None or (hasattr(value, 'value') and value.value is None): return None if isinstance(value, str): return value - if PY2: - if isinstance(value, unicode): - return value return str(value) @@ -63,6 +89,40 @@ def bulk_upper_str(value): return None return s.upper() +def to_verified_tracking_setting_string(value): + if value is None: + return None + + result = [] + for s in value: + contracts = [] + for setting in s: + if setting is not None and setting.__contains__('key') and setting.__contains__('value'): + contract = {} + contract['key'] = setting['key'] + contract['value'] = setting['value'] + contracts.append(contract) + result.append(contracts) + + return json.dumps(result) + +def parse_verified_tracking_setting(str): + if str is None or str == '': + return + + two_dims_array = [] + results = json.loads(str) + for result in results: + array = [] + for res in result: + if res is not None and res.__contains__('key') and res.__contains__('value'): + kv = _CAMPAIGN_OBJECT_FACTORY_V13.create('ns1:KeyValuePairOfstringstring') + kv['key'] = res['key'] + kv['value'] = res['value'] + array.append(kv) + two_dims_array.append(array) + + return two_dims_array def bulk_date_str(value): if value is None or (value.Day is None and value.Month is None and value.Year is None): @@ -113,9 +173,9 @@ def csv_to_bid_strategy_biddingscheme(row_values, bulk_bid_strategy): def csv_to_campaign_biddingscheme(row_values, bulk_campaign): entity_csv_to_biddingscheme(row_values, bulk_campaign.campaign) - + def entity_csv_to_biddingscheme(row_values, entity): - + success, bid_strategy_type = row_values.try_get_value(_StringTable.BidStrategyType) if not success or not bid_strategy_type: return @@ -127,20 +187,29 @@ def entity_csv_to_biddingscheme(row_values, entity): 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 - - + + success, target_roas_row_value = row_values.try_get_value(_StringTable.BidStrategyTargetRoas) target_roas_value = float(target_roas_row_value) if target_roas_row_value else None - - + + success, target_impression_share_row_value = row_values.try_get_value(_StringTable.BidStrategyTargetImpressionShare) target_impression_share_value = float(target_impression_share_row_value) if target_impression_share_row_value else None - - + + success, commission_rate_row_value = row_values.try_get_value(_StringTable.BidStrategyCommissionRate) + commission_rate_value = float(commission_rate_row_value) if commission_rate_row_value else None + + success, max_percent_cpc_row_value = row_values.try_get_value(_StringTable.BidStrategyPercentMaxCpc) + max_percent_cpc_value = float(max_percent_cpc_row_value) if max_percent_cpc_row_value else None + success, target_ad_position_value = row_values.try_get_value(_StringTable.BidStrategyTargetAdPosition) + success, target_cost_per_sale_row_value = row_values.try_get_value(_StringTable.BidStrategyTargetCostPerSale) + target_cost_per_sale_value = float(target_cost_per_sale_row_value) if target_cost_per_sale_row_value else None + if bid_strategy_type == 'MaxConversions': entity.BiddingScheme.MaxCpc = max_cpc_value + entity.BiddingScheme.TargetCpa = target_cpa_value entity.BiddingScheme.Type = "MaxConversions" elif bid_strategy_type == 'MaxClicks': entity.BiddingScheme.MaxCpc = max_cpc_value @@ -158,20 +227,29 @@ def entity_csv_to_biddingscheme(row_values, entity): entity.BiddingScheme.TargetRoas = target_roas_value elif bid_strategy_type == 'TargetImpressionShare': entity.BiddingScheme.Type = "TargetImpressionShare" - entity.BiddingScheme.MaxCpc = maxCpcValue + entity.BiddingScheme.MaxCpc = max_cpc_value entity.BiddingScheme.TargetImpressionShare = target_impression_share_value entity.BiddingScheme.TargetAdPosition = target_ad_position_value - + elif bid_strategy_type == "PercentCpc": + entity.BiddingScheme.MaxPercentCpc = max_percent_cpc_value + entity.BiddingScheme.Type = "PercentCpc" + elif bid_strategy_type == "Commission": + entity.BiddingScheme.MaxPercentCpc = commission_rate_value + entity.BiddingScheme.Type = "Commission" + elif bid_strategy_type == "CostPerSale": + entity.BiddingScheme.TargetCostPerSale = target_cost_per_sale_value + entity.BiddingScheme.Type = "CostPerSale" + def bid_strategy_biddingscheme_to_csv(bulk_bid_strategy, row_values): - entity_biddingscheme_to_csv(bulk_bid_strategy.bid_strategy, row_values) + entity_biddingscheme_to_csv(bulk_bid_strategy.bid_strategy, row_values) def campaign_biddingscheme_to_csv(bulk_campaign, row_values): entity_biddingscheme_to_csv(bulk_campaign.campaign, row_values) - + def entity_biddingscheme_to_csv(entity, row_values): if not entity: return - + bid_strategy_type = field_to_csv_BidStrategyType(entity) if not bid_strategy_type: @@ -181,6 +259,7 @@ def entity_biddingscheme_to_csv(entity, row_values): if bid_strategy_type == 'MaxConversions': row_values[_StringTable.BidStrategyMaxCpc] = bid_bulk_str(entity.BiddingScheme.MaxCpc, entity.Id) + row_values[_StringTable.BidStrategyTargetCpa] = bulk_str(entity.BiddingScheme.TargetCpa) elif bid_strategy_type == 'MaxClicks': row_values[_StringTable.BidStrategyMaxCpc] = bid_bulk_str(entity.BiddingScheme.MaxCpc, entity.Id) elif bid_strategy_type == 'TargetCpa': @@ -194,8 +273,14 @@ def entity_biddingscheme_to_csv(entity, row_values): elif bid_strategy_type == 'TargetImpressionShare': row_values[_StringTable.BidStrategyMaxCpc] = bid_bulk_str(entity.BiddingScheme.MaxCpc, entity.Id) row_values[_StringTable.BidStrategyTargetAdPosition] = bulk_optional_str(entity.BiddingScheme.TargetAdPosition, entity.Id) - row_values[_StringTable.TargetImpressionShare] = TargetImpressionShare(entity.BiddingScheme.TargetImpressionShare) - + row_values[_StringTable.BidStrategyTargetImpressionShare] = bulk_str(entity.BiddingScheme.TargetImpressionShare) + elif bid_strategy_type == 'PercentCpc': + row_values[_StringTable.BidStrategyPercentMaxCpc] = bulk_str(entity.BiddingScheme.MaxPercentCpc) + elif bid_strategy_type == 'Commission': + row_values[_StringTable.BidStrategyCommissionRate] = bulk_str(entity.BiddingScheme.CommissionRate) + elif bid_strategy_type == 'CostPerSale': + row_values[_StringTable.BidStrategyTargetCostPerSale] = bulk_str(entity.BiddingScheme.TargetCostPerSale) + def bulk_optional_str(value, id): if value is None: @@ -207,11 +292,24 @@ def bulk_optional_str(value, id): def csv_to_status(c, v): if v == 'Expired': - c.ad_group.Status = 'Expired' + c.ad_group.Status = AdGroupStatus.Expired c._is_expired = True + elif v == 'Active': + c.ad_group.Status = AdGroupStatus.Active + elif v == 'Paused': + c.ad_group.Status = AdGroupStatus.Paused + elif v == 'Deleted': + c.ad_group.Status = AdGroupStatus.Deleted else: - c.ad_group.Status = v if v else None - + c.ad_group.Status = None + +def parse_bid_option(str): + if str == "BidValue": + return BidOption.BidValue + elif str == "BidBoost": + return BidOption.BidBoost + else: + return None def bulk_device_preference_str(value): if value is None: @@ -233,7 +331,7 @@ def parse_datetime(dt_str): :rtype: datetime | None """ - if not dt_str: + if not dt_str or dt_str == DELETE_VALUE: return None try: return datetime.strptime(dt_str, _BULK_DATETIME_FORMAT) @@ -242,7 +340,7 @@ def parse_datetime(dt_str): def parse_date(d_str): - if not d_str: + if not d_str or d_str == DELETE_VALUE: return None parsed_date = datetime.strptime(d_str, _BULK_DATE_FORMAT) bing_ads_date = _CAMPAIGN_OBJECT_FACTORY_V13.create('Date') @@ -262,7 +360,82 @@ def parse_device_preference(value): elif value.lower() == "mobile": return 30001 else: - raise ValueError("Unknown device preference") + return None + +def field_to_csv_AudienceIds(entity): + audience_ids = entity.audience_ids + if audience_ids is None or len(audience_ids) == 0: + return None + return ';'.join(str(audience_id) for audience_id in audience_ids) + +def csv_to_field_AudienceIds(entity, value): + if value is None or value.strip() == '': + return + entity.audience_ids = [None if i == 'None' else int(i) for i in value.split(';')] + +def field_to_csv_AgeRanges(entity): + age_ranges = entity.age_ranges + if age_ranges is None or len(age_ranges) == 0: + return None + return ';'.join(age_range for age_range in age_ranges) + +def csv_to_field_AgeRanges(entity, value): + if value is None or value.strip() == '': + return + entity.age_ranges = [None if i == 'None' else i for i in value.split(';')] + +def field_to_csv_GenderTypes(entity): + gender_types = entity.gender_types + if gender_types is None or len(gender_types) == 0: + return None + return ';'.join(gender_type for gender_type in gender_types) + +def csv_to_field_GenderTypes(entity, value): + if value is None or value.strip() == '': + return + entity.gender_types = [None if i == 'None' else i for i in value.split(';')] + +def field_to_csv_CampaignType(entity): + campaign_type = entity.CampaignTypeFilter + if campaign_type is None or len(campaign_type) == 0: + return None + return ','.join(type for type in campaign_type) + +def csv_to_field_CampaignType(entity, value): + if value is None or value.strip() == '': + return + entity.CampaignTypeFilter = [None if i == 'None' else i for i in value.split(',')] + +def field_to_csv_DeviceType(entity): + device_type = entity.DeviceTypeFilter + if device_type is None or len(device_type) == 0: + return None + return ','.join(type for type in device_type) + +def csv_to_field_DeviceType(entity, value): + if value is None or value.strip() == '': + return + entity.DeviceTypeFilter = [None if i == 'None' else i for i in value.split(',')] + +def field_to_csv_CampaignAssociations(entity): + associations = entity.CampaignAssociations + if associations is None or len(associations.CampaignAssociation) == 0: + return None + result = "" + for association in associations.CampaignAssociation: + result += str(association.CampaignId) + ";" + return result[:-1] + +def csv_to_field_CampaignAssociations(entity, value): + if value is None or value.strip() == '': + return + result = [] + strs = value.split(';') + for str in strs: + association = CampaignAssociation() + association.CampaignId = int(str) + result.append(association) + entity.CampaignAssociations = result def field_to_csv_MediaIds(entity): """ @@ -315,6 +488,28 @@ def field_to_csv_UrlCustomParameters(entity): params.append('{{_{0}}}={1}'.format(parameter.Key, escape_parameter_text(parameter.Value))) return '; '.join(params) +def dict_bulk_str(parameters, separator): + if parameters is None or len(parameters) == 0: + return None + return separator.join(["{0}={1}".format(key, parameters[key]) for key in parameters]) + +def parse_dict(value): + if value is None or value.strip() == '': + return + + return dict([s.split('=') for s in value.split(';') if len(s) > 0]) + pass + +def multi_bulk_str(parameters, separator): + if parameters is None or len(parameters) == 0: + return None + return separator.join(parameters) + +def parse_multi(value): + if value is None or value.strip() == '': + return + + return value.split(';') def csv_to_field_UrlCustomParameters(entity, value): if value is None or value.strip() == '': @@ -402,6 +597,10 @@ def field_to_csv_BidStrategyType(entity): return 'MaxConversions' elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('ManualCpcBiddingScheme')): return 'ManualCpc' + elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('ManualCpmBiddingScheme')): + return 'ManualCpcm' + elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('ManualCpvBiddingScheme')): + return 'ManualCpv' elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('TargetCpaBiddingScheme')): return 'TargetCpa' elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('MaxClicksBiddingScheme')): @@ -410,8 +609,18 @@ def field_to_csv_BidStrategyType(entity): return 'MaxConversionValue' elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('TargetRoasBiddingScheme')): return 'TargetRoas' - elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('TargetImpressionShare')): + elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('TargetImpressionShareBiddingScheme')): return 'TargetImpressionShare' + elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('MaxRoasBiddingScheme')): + return 'MaxRoas' + elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('PercentCpcBiddingScheme')): + return 'PercentCpc' + elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('CommissionBiddingScheme')): + return 'Commission' + elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('ManualCpaBiddingScheme')): + return 'ManualCpa' + elif type(entity.BiddingScheme) == type(_CAMPAIGN_OBJECT_FACTORY_V13.create('CostPerSaleBiddingScheme')): + return 'CostPerSale' else: raise TypeError('Unsupported Bid Strategy Type') @@ -433,22 +642,32 @@ def csv_to_field_BidStrategyType(entity, value): entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('MaxConversionsBiddingScheme') elif value == 'ManualCpc': entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('ManualCpcBiddingScheme') + elif value == 'ManualCpm': + entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('ManualCpmBiddingScheme') + elif value == 'ManualCpv': + entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('ManualCpvBiddingScheme') elif value == 'TargetCpa': entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('TargetCpaBiddingScheme') elif value == 'MaxClicks': entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('MaxClicksBiddingScheme') - elif value == 'TargetRoas': - entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('TargetRoasBiddingScheme') elif value == 'MaxConversionValue': entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('MaxConversionValueBiddingScheme') + elif value == 'TargetRoas': + entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('TargetRoasBiddingScheme') elif value == 'TargetImpressionShare': entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('TargetImpressionShareBiddingScheme') - elif value == 'ManualCpv': - entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('ManualCpvBiddingScheme') - elif value == 'ManualCpm': - entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('ManualCpmBiddingScheme') + elif value == 'MaxRoas': + entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('MaxRoasBiddingScheme') + elif value == 'PercentCpc': + entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('PercentCpcBiddingScheme') + elif value == 'Commission': + entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('CommissionBiddingScheme') + elif value == 'ManualCpa': + entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('ManualCpaBiddingScheme') + elif value == 'CostPerSale': + entity.BiddingScheme = _CAMPAIGN_OBJECT_FACTORY_V13.create('CostPerSaleBiddingScheme') else: - raise ValueError('Unknown Bid Strategy Type') + return None entity.BiddingScheme.Type = value @@ -461,12 +680,77 @@ def field_to_csv_delimited_strings(entity): return ';'.join(entity.string) return None +def field_to_csv_VideoAssetLinks(assetLinks): + if assetLinks is None or assetLinks.AssetLink is None: + return None + assetLinkContracts = [] + for assetLink in assetLinks.AssetLink: + if assetLink.Asset is not None and isinstance(assetLink.Asset, VideoAsset_Type): + contract = {} + contract['assetPerformanceLabel'] = assetLink.AssetPerformanceLabel if hasattr(assetLink, 'AssetPerformanceLabel') else None + contract['editorialStatus'] = assetLink.EditorialStatus if hasattr(assetLink, 'EditorialStatus') else None + contract['id'] = assetLink.Asset.Id if hasattr(assetLink.Asset, 'Id') else None + contract['name'] = assetLink.Asset.Name if hasattr(assetLink.Asset, 'Name') else None + contract['pinnedField'] = assetLink.PinnedField if hasattr(assetLink, 'PinnedField') else None + contract['subType'] = assetLink.Asset.SubType if hasattr(assetLink.Asset, 'SubType') else None + thumbnailImage = assetLink.Asset.ThumbnailImage if hasattr(assetLink.Asset, 'ThumbnailImage') else None + if thumbnailImage != None: + contract['thumbnailImage'] = {} + contract['thumbnailImage']['id'] = thumbnailImage.Id + contract['thumbnailImage']['name'] = thumbnailImage.Name + contract['thumbnailImage']['type'] = thumbnailImage.Type + contract['thumbnailImage']['subType'] = thumbnailImage.SubType + contract['thumbnailImage']['cropX'] = thumbnailImage.CropX + contract['thumbnailImage']['cropY'] = thumbnailImage.CropY + contract['thumbnailImage']['cropWidth'] = thumbnailImage.CropWidth + contract['thumbnailImage']['cropHeight'] = thumbnailImage.CropHeight + contract['thumbnailImage']['targetWidth'] = thumbnailImage.TargetWidth + contract['thumbnailImage']['targetHeight'] = thumbnailImage.TargetHeight + assetLinkContracts.append(contract) + if len(assetLinkContracts) > 0: + return json.dumps(assetLinkContracts, sort_keys = True) + return None -def csv_to_field_Rsa_TextAssetLinks(assetLinks, value): + pass + +def csv_to_field_VideoAssetLinks(assetLinks, value): if value is None or value == '': return assetLinkContracts = json.loads(value) - + for assetLinkContract in assetLinkContracts: + asset_link = _CAMPAIGN_OBJECT_FACTORY_V13.create('AssetLink') + asset_link.Asset = _CAMPAIGN_OBJECT_FACTORY_V13.create('VideoAsset') + asset_link.Asset.Type = 'VideoAsset' + asset_link.Asset.Id = assetLinkContract.get('id') + asset_link.Asset.Name = assetLinkContract.get('name') + asset_link.Asset.SubType = assetLinkContract.get('subType') + asset_link.AssetPerformanceLabel = assetLinkContract.get('assetPerformanceLabel') + asset_link.PinnedField = assetLinkContract.get('pinnedField') + asset_link.EditorialStatus = assetLinkContract.get('editorialStatus') + thumbnailImageContract = assetLinkContract.get('thumbnailImage') + + if thumbnailImageContract != None : + asset_link.Asset.ThumbnailImage = _CAMPAIGN_OBJECT_FACTORY_V13.create('ImageAsset') + asset_link.Asset.ThumbnailImage.Type = 'ImageAsset' + asset_link.Asset.ThumbnailImage.Id = thumbnailImageContract.get('id') + asset_link.Asset.ThumbnailImage.Name = thumbnailImageContract.get('name') + asset_link.Asset.ThumbnailImage.SubType = thumbnailImageContract.get('subType') + asset_link.Asset.ThumbnailImage.CropX = thumbnailImageContract.get('cropX') + asset_link.Asset.ThumbnailImage.CropY = thumbnailImageContract.get('cropY') + asset_link.Asset.ThumbnailImage.CropWidth = thumbnailImageContract.get('cropWidth') + asset_link.Asset.ThumbnailImage.CropHeight = thumbnailImageContract.get('cropHeight') + asset_link.Asset.ThumbnailImage.TargetWidth = thumbnailImageContract.get('targetWidth') + asset_link.Asset.ThumbnailImage.TargetHeight = thumbnailImageContract.get('targetHeight') + + assetLinks.AssetLink.append(asset_link) + + + +def csv_to_field_TextAssetLinks(assetLinks, value): + if value is None or value == '': + return + assetLinkContracts = json.loads(value) + for assetLinkContract in assetLinkContracts: asset_link = _CAMPAIGN_OBJECT_FACTORY_V13.create('AssetLink') asset_link.Asset = _CAMPAIGN_OBJECT_FACTORY_V13.create('TextAsset') @@ -485,7 +769,7 @@ def field_to_csv_ImageAssetLinks(entity): assetLinkContracts = [] for assetLink in entity.AssetLink: if assetLink.Asset is not None and isinstance(assetLink.Asset, ImageAsset_Type): - contract = {} + contract = {} contract['cropHeight'] = assetLink.Asset.CropHeight if hasattr(assetLink.Asset, 'CropHeight') else None contract['cropWidth'] = assetLink.Asset.CropWidth if hasattr(assetLink.Asset, 'CropWidth') else None contract['cropX'] = assetLink.Asset.CropX if hasattr(assetLink.Asset, 'CropX') else None @@ -495,6 +779,9 @@ def field_to_csv_ImageAssetLinks(entity): contract['assetPerformanceLabel'] = assetLink.AssetPerformanceLabel if hasattr(assetLink, 'AssetPerformanceLabel') else None contract['editorialStatus'] = assetLink.EditorialStatus if hasattr(assetLink, 'EditorialStatus') else None contract['pinnedField'] = assetLink.PinnedField if hasattr(assetLink, 'PinnedField') else None + contract['targetWidth'] = assetLink.Asset.TargetWidth if hasattr(assetLink.Asset, 'TargetWidth') else None + contract['targetHeight'] = assetLink.Asset.TargetHeight if hasattr(assetLink.Asset, 'TargetHeight') else None + contract['subType'] = assetLink.Asset.SubType if hasattr(assetLink.Asset, 'SubType') else None assetLinkContracts.append(contract) if len(assetLinkContracts) > 0: return json.dumps(assetLinkContracts) @@ -504,7 +791,7 @@ def csv_to_field_ImageAssetLinks(assetLinks, value): if value is None or value == '': return assetLinkContracts = json.loads(value) - + for assetLinkContract in assetLinkContracts: asset_link = _CAMPAIGN_OBJECT_FACTORY_V13.create('AssetLink') asset_link.Asset = _CAMPAIGN_OBJECT_FACTORY_V13.create('ImageAsset') @@ -518,9 +805,12 @@ def csv_to_field_ImageAssetLinks(assetLinks, value): asset_link.AssetPerformanceLabel = assetLinkContract.get('assetPerformanceLabel') asset_link.PinnedField = assetLinkContract.get('pinnedField') asset_link.EditorialStatus = assetLinkContract.get('editorialStatus') + asset_link.Asset.TargetWidth = assetLinkContract.get('targetWidth') + asset_link.Asset.TargetHeight = assetLinkContract.get('targetHeight') + asset_link.Asset.SubType = assetLinkContract.get('subType') assetLinks.AssetLink.append(asset_link) -def field_to_csv_Rsa_TextAssetLinks(entity): +def field_to_csv_TextAssetLinks(entity): if entity is None or entity.AssetLink is None: return None assetLinkContracts = [] @@ -633,15 +923,16 @@ def bid_multiplier_bulk_str(value): return bulk_str(value.Multiplier) def parse_minute(value): + Minute = _CAMPAIGN_OBJECT_FACTORY_V13.create('Minute') minute_number = int(value) if minute_number == 0: - return 'Zero' + return Minute.Zero elif minute_number == 15: - return 'Fifteen' + return Minute.Fifteen elif minute_number == 30: - return 'Thirty' + return Minute.Thirty elif minute_number == 45: - return 'FortyFive' + return Minute.FortyFive raise ValueError('Unknown minute') @@ -807,6 +1098,51 @@ def field_to_csv_UseSearcherTimeZone(bool_value, id): else: return str(bool_value) +def csv_to_field_enum(entity, value, attr_name, enum_class): + """ + Generic method to convert CSV string values to enum fields on an entity. + + Args: + entity: The entity object to set the attribute on + value: The string value from CSV + attr_name: The name of the attribute to set on the entity + enum_class: The enum class to convert the value to + """ + if value is None or value == '': + setattr(entity, attr_name, None) + return + + try: + enum_value = getattr(enum_class, value) + setattr(entity, attr_name, enum_value) + except (AttributeError, ValueError): + # If the value doesn't match any enum value, set to None + setattr(entity, attr_name, None) + +def csv_to_field_CampaignStatus(entity, value): + if value is None or value == '': + entity.Status = None + elif value == 'Active': + entity.Status = CampaignStatus.Active + elif value == 'Paused': + entity.Status = CampaignStatus.Paused + elif value == 'BudgetPaused': + entity.Status = CampaignStatus.BudgetPaused + elif value == 'BudgetAndManualPaused': + entity.Status = CampaignStatus.BudgetAndManualPaused + elif value == 'Deleted': + entity.Status = CampaignStatus.Deleted + elif value == 'Suspended': + entity.Status = CampaignStatus.Suspended + else: + entity.Status = None + +def field_to_csv_bool(bool_value): + if bool_value is None: + return None + else: + return str(bool_value) + def csv_to_field_BudgetType(entity, value, version=13): if value is None or value == '': entity.BudgetType = None @@ -817,7 +1153,7 @@ def csv_to_field_BudgetType(entity, value, version=13): elif value == 'DailyBudgetStandard': entity.BudgetType = BudgetLimitType.DailyBudgetStandard else: - raise ValueError('Unable to parse BudgetType: {0}'.format(value)) + entity.BudgetType = None def field_to_csv_WebpageParameter_CriterionName(entity): if entity.Criterion is None or entity.Criterion.Parameter is None or entity.Criterion.Parameter.CriterionName is None: @@ -849,11 +1185,13 @@ def entity_to_csv_DSAWebpageParameter(entity, row_values): entity.Criterion.Parameter.Conditions.WebpageCondition is not None: condition_prefix = _StringTable.DynamicAdTargetCondition1[:-1] value_prefix = _StringTable.DynamicAdTargetValue1[:-1] + condition_operator_prefix = _StringTable.DynamicAdTargetConditionOperator1[:-1] conditions = entity.Criterion.Parameter.Conditions.WebpageCondition for i in range(0, len(conditions)): row_values[condition_prefix + str(i + 1)] = conditions[i].Operand row_values[value_prefix + str(i + 1)] = conditions[i].Argument + row_values[condition_operator_prefix + str(i + 1)] = conditions[i].Operator def csv_to_entity_DSAWebpageParameter(row_values, entity): @@ -865,11 +1203,13 @@ def csv_to_entity_DSAWebpageParameter(row_values, entity): MAX_NUMBER_OF_CONDITIONS = 3 condition_prefix = _StringTable.DynamicAdTargetCondition1[:-1] value_prefix = _StringTable.DynamicAdTargetValue1[:-1] + condition_operator_prefix = _StringTable.DynamicAdTargetConditionOperator1[:-1] conditions = [] for i in range(0, MAX_NUMBER_OF_CONDITIONS): condition_success, webpage_condition = row_values.try_get_value(condition_prefix + str(i + 1)) value_success, webpage_value = row_values.try_get_value(value_prefix + str(i + 1)) + condition_operator_success, webpage_condition_operator = row_values.try_get_value(condition_operator_prefix + str(i + 1)) if condition_success and value_success and webpage_condition is not None and webpage_condition != '': condition = _CAMPAIGN_OBJECT_FACTORY_V13.create('WebpageCondition') if webpage_condition.lower() == 'url': @@ -888,7 +1228,9 @@ def csv_to_entity_DSAWebpageParameter(row_values, entity): # TODO wait bug 54825 to be fixed if webpage_condition.lower() == 'none': continue - raise ValueError("Unknown WebpageConditionOperand value: {0}".format(webpage_condition)) + return None + if condition_operator_success: + condition.Operator = webpage_condition_operator condition.Argument = webpage_value conditions.append(condition) @@ -1002,7 +1344,7 @@ def field_to_csv_RemarketingRule(entity): rule = entity.Rule if (isinstance(rule, type(PageVisitorsRule))): - return 'PageVisitors{0}'.format(rule_item_groups_str(rule.RuleItemGroups.RuleItemGroup)) + return 'PageVisitors{0}'.format(rule_item_groups_str(rule.RuleItemGroups.RuleItemGroup, rule.NormalForm)) elif (isinstance(rule, type(PageVisitorsWhoVisitedAnotherPageRule))): return 'PageVisitorsWhoVisitedAnotherPage({0}) and ({1})'.format( rule_item_groups_str(rule.RuleItemGroups.RuleItemGroup), @@ -1019,18 +1361,23 @@ def field_to_csv_RemarketingRule(entity): raise ValueError('Unsupported Remarketing Rule type: {0}'.format(type(entity.RemarketingRule))) -def rule_item_groups_str(groups): +def rule_item_groups_str(groups, nf = NormalForm.Disjunctive): + outerOperator = ' or ' + innerOperator = ' and ' + if nf == NormalForm.Conjunctive: + outerOperator = ' and ' + innerOperator = ' or ' if groups is None or len(groups) == 0: raise ValueError('Remarketing RuleItemGroups is None or empty.') - return ' or '.join(['({0})'.format(rule_items_str(group.Items.RuleItem)) for group in groups]) + return outerOperator.join(['({0})'.format(rule_items_str(group.Items.RuleItem, innerOperator)) for group in groups]) -def rule_items_str(items): +def rule_items_str(items, innerOperator = ' and '): if items is None or len(items) == 0: raise ValueError('Remarketing RuleItem list is None or empty.') - return ' and '.join(['({0} {1} {2})'.format(item.Operand, item.Operator, item.Value) for item in items]) + return innerOperator.join(['({0} {1} {2})'.format(item.Operand, item.Operator, item.Value) for item in items]) def custom_event_rule_str(rule): @@ -1075,7 +1422,7 @@ def csv_to_field_RemarketingRule(entity, value): elif rule_type.lower() == 'customevents': entity.Rule = parse_rule_CustomEvents(rule) else: - raise ValueError('Invalid Remarketing Rule Type: {0}'.format(rule_type)) + entity.Rule = None def field_to_csv_CriterionAudienceId(entity): @@ -1090,6 +1437,19 @@ def csv_to_field_CriterionAudienceId(entity, value): if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion, type(AudienceCriterion)): entity.Criterion.AudienceId = value +def field_to_csv_CashbackAdjustment(entity): + if entity is None or entity.CriterionCashback is None or hasattr(entity.CriterionCashback, "CashbackPercent") == False or entity.CriterionCashback.CashbackPercent is None: + return None + return bulk_str(entity.CriterionCashback.CashbackPercent) + + +def csv_to_field_CashbackAdjustment(entity, value): + if value is None or value == '': + return + if entity is not None: + entity.CriterionCashback = _CAMPAIGN_OBJECT_FACTORY_V13.create('CashbackAdjustment') + entity.CriterionCashback.Type = 'CashbackAdjustment' + entity.CriterionCashback.CashbackPercent = value def field_to_csv_BidAdjustment(entity): if entity is None or entity.CriterionBid is None or entity.CriterionBid.Multiplier is None: @@ -1202,6 +1562,105 @@ def csv_to_field_GenderTarget(entity, value): if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(GenderCriterion)): setattr(entity.Criterion, "GenderType", value) +def field_to_csv_MaxDays(entity): + if entity is None or entity.Criterion is None or entity.Criterion.MaxDays is None: + return None + return bulk_str(entity.Criterion.MaxDays) + +def csv_to_field_MaxDays(entity, value): + if value is None or value == '': + return + if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(HotelAdvanceBookingWindowCriterion)): + setattr(entity.Criterion, "MaxDays", int(value)) + +def field_to_csv_MinDays(entity): + if entity is None or entity.Criterion is None or entity.Criterion.MinDays is None: + return None + return bulk_str(entity.Criterion.MinDays) + +def csv_to_field_MinDays(entity, value): + if value is None or value == '': + return + if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(HotelAdvanceBookingWindowCriterion)): + setattr(entity.Criterion, "MinDays", int(value)) + +def field_to_csv_StartDate(entity): + if entity is None or entity.Criterion is None or entity.Criterion.StartDate is None: + return None + return bulk_datetime_str(entity.Criterion.StartDate) + +def csv_to_field_StartDate(entity, value): + if value is None or value == '': + return + if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(HotelCheckInDateCriterion)): + setattr(entity.Criterion, "StartDate", parse_datetime(value)) + +def field_to_csv_GenreId(entity): + if entity is None or entity.Criterion is None or entity.Criterion.GenreId is None: + return None + return bulk_str(entity.Criterion.GenreId) + +def csv_to_field_GenreId(entity, value): + if value is None or value == '': + return + if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(GenreCriterion)): + setattr(entity.Criterion, "GenreId", int(value) if value else None) + +def field_to_csv_EndDate(entity): + if entity is None or entity.Criterion is None or entity.Criterion.EndDate is None: + return None + return bulk_datetime_str(entity.Criterion.EndDate) + +def csv_to_field_EndDate(entity, value): + if value is None or value == '': + return + if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(HotelCheckInDateCriterion)): + setattr(entity.Criterion, "EndDate", parse_datetime(value)) + +def field_to_csv_CheckInDay(entity): + if entity is None or entity.Criterion is None or entity.Criterion.CheckInDay is None: + return None + return entity.Criterion.CheckInDay + +def csv_to_field_CheckInDay(entity, value): + if value is None or value == '': + return + if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(HotelCheckInDayCriterion)): + setattr(entity.Criterion, "CheckInDay", value) + +def field_to_csv_HotelDateSelectionType(entity): + if entity is None or entity.Criterion is None or entity.Criterion.HotelDateSelectionType is None: + return None + return entity.Criterion.HotelDateSelectionType + +def csv_to_field_HotelDateSelectionType(entity, value): + if value is None or value == '': + return + if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(HotelDateSelectionTypeCriterion)): + setattr(entity.Criterion, "HotelDateSelectionType", value) + +def field_to_csv_MaxNights(entity): + if entity is None or entity.Criterion is None or entity.Criterion.MaxNights is None: + return None + return bulk_str(entity.Criterion.MaxNights) + +def csv_to_field_MaxNights(entity, value): + if value is None or value == '': + return + if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(HotelLengthOfStayCriterion)): + setattr(entity.Criterion, "MaxNights", int(value)) + +def field_to_csv_MinNights(entity): + if entity is None or entity.Criterion is None or entity.Criterion.MinNights is None: + return None + return bulk_str(entity.Criterion.MinNights) + +def csv_to_field_MinNights(entity, value): + if value is None or value == '': + return + if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(HotelLengthOfStayCriterion)): + setattr(entity.Criterion, "MinNights", int(value)) + def field_to_csv_LocationTarget(entity): if entity is None or entity.Criterion is None or entity.Criterion.LocationId is None: return None @@ -1268,6 +1727,17 @@ def csv_to_field_Radius(entity, value): if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(RadiusCriterion)): setattr(entity.Criterion, "Radius", value) +def field_to_csv_DealTarget(entity): + if entity is None or entity.Criterion is None or entity.Criterion.DealId is None: + return None + return str(entity.Criterion.DealId) + +def csv_to_field_DealTarget(entity, value): + if value is None or value == '': + return + if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(DealCriterion)): + setattr(entity.Criterion, "DealId", int(value)) + def field_to_csv_RadiusUnit(entity): if entity is None or entity.Criterion is None or entity.Criterion.RadiusUnit is None: return None @@ -1315,6 +1785,19 @@ def target_setting_to_csv(entity): return ";".join([s.CriterionTypeGroup for s in target_setting.Details.TargetSettingDetail]) pass +def hotel_setting_to_csv(entity): + if not entity.Settings or not entity.Settings.Setting: + return None + settings = [setting for setting in entity.Settings.Setting if isinstance(setting, HotelSetting_Type)] + if len(settings) == 0: + return None + if len(settings) != 1: + raise ValueError('Can only have 1 HotelSetting in Settings.') + hotel_setting = settings[0] + if not hotel_setting.HotelAdGroupType: + return DELETE_VALUE if entity.Id and entity.Id > 0 else None + else: + return bulk_str(hotel_setting.HotelAdGroupType).replace('|', ',') def csv_to_target_setting(entity, value): target_setting = _CAMPAIGN_OBJECT_FACTORY_V13.create('TargetSetting') @@ -1332,8 +1815,39 @@ def csv_to_target_setting(entity, value): entity.Settings.Setting.append(target_setting) pass +def csv_to_hotel_setting(entity, value): + hotel_setting = _CAMPAIGN_OBJECT_FACTORY_V13.create('HotelSetting') + hotel_setting.Type = 'HotelSetting' + if value is None: + hotel_adgroup_type = None + else: + hotel_adgroup_type = value + hotel_setting.HotelAdGroupType = hotel_adgroup_type + entity.Settings.Setting.append(hotel_setting) + pass + +def csv_to_commission_rate(entity, value): + if value is None: + return + rate_amount = _CAMPAIGN_OBJECT_FACTORY_V13.create('RateAmount') + rate_bid = _CAMPAIGN_OBJECT_FACTORY_V13.create('RateBid') + rate_amount.Amount = float(value) if value else None + rate_bid.RateAmount = rate_amount + entity.CommissionRate = rate_bid + pass + +def csv_to_percent_cpc_bid(entity, value): + if value is None: + return + rate_amount = _CAMPAIGN_OBJECT_FACTORY_V13.create('RateAmount') + rate_bid = _CAMPAIGN_OBJECT_FACTORY_V13.create('RateBid') + rate_amount.Amount = float(value) if value else None + rate_bid.RateAmount = rate_amount + entity.PercentCpcBid = rate_bid + pass + def match_target_setting(token): - + pattern = re.compile(target_setting_detail_pattern) m = pattern.match(token) if m: @@ -1348,9 +1862,51 @@ def create_target_setting_detail(token): pass def parse_rule_PageVisitors(rule_str): + patternDNF = ')) or ((' + patternCNF = ')) and ((' + patternAnd = ') and (' + patternOr = ') or (' + rule = _CAMPAIGN_OBJECT_FACTORY_V13.create('PageVisitorsRule') rule.Type = 'PageVisitors' - rule.RuleItemGroups = parse_rule_groups(rule_str) + rule.NormalForm = NormalForm.Disjunctive + rule.RuleItemGroups = _CAMPAIGN_OBJECT_FACTORY_V13.create('ArrayOfRuleItemGroup') + + expressionGroups = rule_str.split(patternDNF) + if len(expressionGroups) == 1: + expressionGroups = rule_str.split(patternCNF) + if len(expressionGroups) == 1: + expressions = rule_str.split(patternOr) + if len(expressions) == 1: + expressions = rule_str.split(patternAnd) + if len(expressions) == 1: + parse_rule_items(rule_str) + else: + rule.NormalForm = NormalForm.Disjunctive + else: + rule.NormalForm = NormalForm.Conjunctive + else: + rule.NormalForm = NormalForm.Conjunctive + + pattern = patternAnd + if rule.NormalForm == NormalForm.Conjunctive: + pattern = patternOr + + for expressionGroup in expressionGroups: + expressionGroup = expressionGroup.strip() + if expressionGroup[0] == '(': + expressionGroup = expressionGroup[1:] + if expressionGroup[-1] == ')': + expressionGroup = expressionGroup[:-1] + + expressions = expressionGroup.split(pattern) + rule_item_group = _CAMPAIGN_OBJECT_FACTORY_V13.create('RuleItemGroup') + for expression in expressions: + item = parse_string_rule_item(expression) + rule_item_group.Items.RuleItem.append(item) + + rule.RuleItemGroups.RuleItemGroup.append(rule_item_group) + return rule @@ -1460,19 +2016,28 @@ def parse_rule_items(items_str): def parse_string_rule_item(item_str): item_str = item_str.strip('(').strip(')') - pattern_str = r'^(Url|ReferrerUrl|None) (Equals|Contains|BeginsWith|EndsWith|NotEquals|DoesNotContain|DoesNotBeginWith|DoesNotEndWith) ([^()]*)$' + pattern_str = r'^(Url|ReferrerUrl|EcommPageType|EcommCategory|EcommProdId|Action|None) (Equals|Contains|BeginsWith|EndsWith|NotEquals|DoesNotContain|DoesNotBeginWith|DoesNotEndWith) ([^()]*)$' + number_pattern_str = r'^(EcommTotalValue) (Equals|GreaterThan|LessThan|GreaterThanEqualTo|LessThanEqualTo|NotEquals) ([^()]*)$' pattern = re.compile(pattern_str) + number_pattern = re.compile(number_pattern_str) match = pattern.match(item_str) - - if not match: - ValueError('Invalid Rule Item:{0}'.format(item_str)) - - item = _CAMPAIGN_OBJECT_FACTORY_V13.create('StringRuleItem') - item.Type = 'String' - item.Operand = match.group(1) - item.Operator = parse_string_operator(match.group(2)) - item.Value = match.group(3) + if match: + item = _CAMPAIGN_OBJECT_FACTORY_V13.create('StringRuleItem') + item.Type = 'String' + item.Operand = match.group(1) + item.Operator = parse_string_operator(match.group(2)) + item.Value = match.group(3) + else: + match = number_pattern.match(item_str) + if match: + item = _CAMPAIGN_OBJECT_FACTORY_V13.create('NumberRuleItem') + item.Type = 'Number' + item.Operand = match.group(1) + item.Operator = parse_number_operator(match.group(2)) + item.Value = match.group(3) + else: + ValueError('Invalid Rule Item:{0}'.format(item_str)) return item @@ -1489,7 +2054,10 @@ def parse_number_operator(operator): return NumberOperator.GreaterThanEqualTo if oper == 'lessthanequalto': return NumberOperator.LessThanEqualTo - raise ValueError('Invalid Number Rule Item operator:{0}'.format(operator)) + if oper == 'notequals': + return NumberOperator.NotEquals + + return None def parse_string_operator(operator): @@ -1511,7 +2079,7 @@ def parse_string_operator(operator): if oper == 'doesnotendwith': return StringOperator.DoesNotEndWith - raise ValueError('Invalid String Rule Item operator:{0}'.format(operator)) + return None def csv_to_field_SupportedCampaignTypes(entity, value): @@ -1540,11 +2108,11 @@ def csv_to_field_CustomAttributes(feed, value): if value is None or value == '': return feed.custom_attributes = json.loads(value) - + def field_to_csv_Ids(ids, entity_id): if ids is None and entity_id is not None and entity_id > 0: return DELETE_VALUE - + if ids is None or len(ids.long) == 0: return None return ';'.join(str(id) for id in ids.long) @@ -1554,19 +2122,18 @@ def csv_to_field_PageFeedIds(value): return None if len(value) == 0: return [] - return [int(i) for i in value.split(';')] - + return [int(i) for i in value.split(';')] + def combination_rules_to_bulkstring(combination_rules): if len(combination_rules.CombinationRule) == 0: return None - - + return '&'.join([r.Operator + '(' + ','.join([str(id) for id in r.AudienceIds.long]) + ')' for r in combination_rules.CombinationRule]) def parse_combination_rules(combination_list, value): if value is None or len(value) == 0: return None - + rules = value.split('&') pattern = re.compile(combine_rule_pattern, re.IGNORECASE) for rule in rules: @@ -1580,4 +2147,19 @@ def to_operation(op): if op.lower() == 'and': return 'And' if op.lower() == 'or': return 'Or' if op.lower() == 'not': return 'Not' - return none \ No newline at end of file + return none + +def bulk_datetime_str2(value): + if value is None: + return None + + return value.strftime('%Y/%m/%d %H:%M:%S') + +def parse_datetime2(value): + + if not value: + return None + try: + return datetime.strptime(value, '%Y/%m/%d %H:%M:%S') + except Exception: + return parse_datetime(value) diff --git a/bingads/v13/internal/reporting/csv_reader.py b/bingads/v13/internal/reporting/csv_reader.py index 49a55088..2684ae6b 100644 --- a/bingads/v13/internal/reporting/csv_reader.py +++ b/bingads/v13/internal/reporting/csv_reader.py @@ -1,6 +1,5 @@ import csv import io -from six import PY2, PY3 class _CsvReader: @@ -17,11 +16,7 @@ def __init__(self, filename, delimiter, encoding='utf-8-sig'): self._csv_file = io.open(self.filename, encoding=encoding) - if PY3: - self._csv_reader = csv.reader(self._csv_file, dialect=self._dialect) - elif PY2: - byte_lines = [line.encode('utf-8') for line in self._csv_file] - self._csv_reader = csv.reader(byte_lines, dialect=self._dialect) + self._csv_reader = csv.reader(self._csv_file, dialect=self._dialect) def __enter__(self): return self @@ -39,11 +34,7 @@ def close(self): self.__exit__(None, None, None) def next(self): - if PY3: - return next(self._csv_reader) - elif PY2: - row = next(self._csv_reader) - return [unicode(cell, encoding='utf-8') for cell in row] + return next(self._csv_reader) @property def filename(self): diff --git a/bingads/v13/internal/reporting/row_report_header.py b/bingads/v13/internal/reporting/row_report_header.py index 4cf2e996..3acd6da2 100644 --- a/bingads/v13/internal/reporting/row_report_header.py +++ b/bingads/v13/internal/reporting/row_report_header.py @@ -64,7 +64,7 @@ def set_report_time(self, report_time): self._report_time_end = datetime.strptime(time_array[0], '%m/%d/%Y') if time_array[0] else None elif len(time_array) == 2: self._report_time_start = datetime.strptime(time_array[0], '%m/%d/%Y') if time_array[0] else None - self._report_time_end = datetime.strptime(time_array[0], '%m/%d/%Y') if time_array[1] else None + self._report_time_end = datetime.strptime(time_array[1], '%m/%d/%Y') if time_array[1] else None @property def last_completed_available_date(self): diff --git a/bingads/v13/proxies/production/adinsight_service.xml b/bingads/v13/proxies/production/adinsight_service.xml new file mode 100644 index 00000000..8a659060 --- /dev/null +++ b/bingads/v13/proxies/production/adinsight_service.xml @@ -0,0 +1,5812 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + + + + + + 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 + + + + + + + 20 + + + + + + + 30 + + + + + + + 40 + + + + + + + 60 + + + + + + + 70 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + 10 + + + + + + + 11 + + + + + + + 12 + + + + + + + 13 + + + + + + + 14 + + + + + + + 15 + + + + + + + 16 + + + + + + + 17 + + + + + + + 18 + + + + + + + 19 + + + + + + + 20 + + + + + + + 21 + + + + + + + 22 + + + + + + + 23 + + + + + + + 24 + + + + + + + 25 + + + + + + + 26 + + + + + + + 27 + + + + + + + 28 + + + + + + + 29 + + + + + + + 30 + + + + + + + 31 + + + + + + + 32 + + + + + + + 33 + + + + + + + 34 + + + + + + + 35 + + + + + + + 36 + + + + + + + 37 + + + + + + + 38 + + + + + + + 39 + + + + + + + 40 + + + + + + + 41 + + + + + + + 42 + + + + + + + 43 + + + + + + + 44 + + + + + + + 45 + + + + + + + 46 + + + + + + + 47 + + + + + + + 48 + + + + + + + 49 + + + + + + + 50 + + + + + + + 51 + + + + + + + 52 + + + + + + + 53 + + + + + + + 54 + + + + + + + 55 + + + + + + + 56 + + + + + + + 57 + + + + + + + 58 + + + + + + + 59 + + + + + + + 60 + + + + + + + 61 + + + + + + + 62 + + + + + + + 63 + + + + + + + 64 + + + + + + + 65 + + + + + + + 66 + + + + + + + 67 + + + + + + + 68 + + + + + + + 69 + + + + + + + 70 + + + + + + + 71 + + + + + + + 72 + + + + + + + 73 + + + + + + + 74 + + + + + + + 75 + + + + + + + 76 + + + + + + + 77 + + + + + + + 78 + + + + + + + 79 + + + + + + + 80 + + + + + + + 81 + + + + + + + 82 + + + + + + + 83 + + + + + + + 84 + + + + + + + 85 + + + + + + + 86 + + + + + + + 87 + + + + + + + 88 + + + + + + + 89 + + + + + + + 90 + + + + + + + 91 + + + + + + + 92 + + + + + + + 93 + + + + + + + 94 + + + + + + + 95 + + + + + + + 96 + + + + + + + 97 + + + + + + + 98 + + + + + + + 99 + + + + + + + 100 + + + + + + + 101 + + + + + + + 102 + + + + + + + 103 + + + + + + + 104 + + + + + + + 105 + + + + + + + 106 + + + + + + + 107 + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + 10 + + + + + + + 11 + + + + + + + 12 + + + + + + + 13 + + + + + + + 14 + + + + + + + 15 + + + + + + + 16 + + + + + + + 17 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 23 + + + + + + + 15 + + + + + + + 1 + + + + + + + 78 + + + + + + + 87 + + + + + + + 2 + + + + + + + 3 + + + + + + + 16 + + + + + + + 18 + + + + + + + 20 + + + + + + + 5 + + + + + + + 88 + + + + + + + 25 + + + + + + + 6 + + + + + + + 33 + + + + + + + 30 + + + + + + + 36 + + + + + + + 8 + + + + + + + 48 + + + + + + + 58 + + + + + + + 57 + + + + + + + 52 + + + + + + + 82 + + + + + + + 10 + + + + + + + 9 + + + + + + + 64 + + + + + + + 65 + + + + + + + 69 + + + + + + + 34 + + + + + + + 72 + + + + + + + 74 + + + + + + + 13 + + + + + + + 11 + + + + + + + 4 + + + + + + + 93 + + + + + + + 7 + + + + + + + 12 + + + + + + + 45 + + + + + + + 17 + + + + + + + 67 + + + + + + + 21 + + + + + + + 35 + + + + + + + 99 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bingads/v13/proxies/production/bulk_service.xml b/bingads/v13/proxies/production/bulk_service.xml new file mode 100644 index 00000000..f260e3ac --- /dev/null +++ b/bingads/v13/proxies/production/bulk_service.xml @@ -0,0 +1,2096 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + 10 + + + + + + + 11 + + + + + + + 12 + + + + + + + 13 + + + + + + + 14 + + + + + + + 15 + + + + + + + 16 + + + + + + + 17 + + + + + + + 18 + + + + + + + 19 + + + + + + + 20 + + + + + + + 21 + + + + + + + 22 + + + + + + + 23 + + + + + + + 24 + + + + + + + 25 + + + + + + + 26 + + + + + + + 27 + + + + + + + 28 + + + + + + + 29 + + + + + + + 30 + + + + + + + 31 + + + + + + + 32 + + + + + + + 33 + + + + + + + 34 + + + + + + + 35 + + + + + + + 36 + + + + + + + 37 + + + + + + + 38 + + + + + + + 39 + + + + + + + 40 + + + + + + + 41 + + + + + + + 42 + + + + + + + 43 + + + + + + + 44 + + + + + + + 45 + + + + + + + 46 + + + + + + + 47 + + + + + + + 48 + + + + + + + 49 + + + + + + + 50 + + + + + + + 51 + + + + + + + 52 + + + + + + + 53 + + + + + + + 54 + + + + + + + 55 + + + + + + + 56 + + + + + + + 57 + + + + + + + 58 + + + + + + + 59 + + + + + + + 60 + + + + + + + 61 + + + + + + + 62 + + + + + + + 63 + + + + + + + 64 + + + + + + + 65 + + + + + + + 66 + + + + + + + 67 + + + + + + + 68 + + + + + + + 69 + + + + + + + 70 + + + + + + + 71 + + + + + + + 72 + + + + + + + 73 + + + + + + + 74 + + + + + + + 75 + + + + + + + 76 + + + + + + + 77 + + + + + + + 78 + + + + + + + 79 + + + + + + + 80 + + + + + + + 81 + + + + + + + 82 + + + + + + + 83 + + + + + + + 84 + + + + + + + 85 + + + + + + + 86 + + + + + + + 87 + + + + + + + 88 + + + + + + + 89 + + + + + + + 90 + + + + + + + 91 + + + + + + + 92 + + + + + + + 93 + + + + + + + 94 + + + + + + + 95 + + + + + + + 96 + + + + + + + 97 + + + + + + + 98 + + + + + + + 99 + + + + + + + 100 + + + + + + + 101 + + + + + + + 102 + + + + + + + 103 + + + + + + + 104 + + + + + + + 105 + + + + + + + 106 + + + + + + + 107 + + + + + + + 108 + + + + + + + 109 + + + + + + + 110 + + + + + + + 111 + + + + + + + 112 + + + + + + + 113 + + + + + + + 114 + + + + + + + 115 + + + + + + + 116 + + + + + + + 117 + + + + + + + 118 + + + + + + + 119 + + + + + + + 120 + + + + + + + 121 + + + + + + + 122 + + + + + + + 123 + + + + + + + 124 + + + + + + + 125 + + + + + + + 126 + + + + + + + 127 + + + + + + + 128 + + + + + + + 129 + + + + + + + 130 + + + + + + + 131 + + + + + + + 132 + + + + + + + 133 + + + + + + + 134 + + + + + + + 135 + + + + + + + 136 + + + + + + + 137 + + + + + + + 138 + + + + + + + 139 + + + + + + + 140 + + + + + + + 141 + + + + + + + 142 + + + + + + + 143 + + + + + + + 144 + + + + + + + 145 + + + + + + + 146 + + + + + + + 147 + + + + + + + 148 + + + + + + + 149 + + + + + + + 150 + + + + + + + 151 + + + + + + + 152 + + + + + + + 153 + + + + + + + 154 + + + + + + + 155 + + + + + + + 156 + + + + + + + 157 + + + + + + + 158 + + + + + + + 159 + + + + + + + 160 + + + + + + + 161 + + + + + + + 162 + + + + + + + 163 + + + + + + + 164 + + + + + + + 165 + + + + + + + 166 + + + + + + + 167 + + + + + + + 168 + + + + + + + 169 + + + + + + + 170 + + + + + + + 171 + + + + + + + 172 + + + + + + + 173 + + + + + + + 174 + + + + + + + 175 + + + + + + + 176 + + + + + + + 177 + + + + + + + 178 + + + + + + + 179 + + + + + + + 180 + + + + + + + 181 + + + + + + + 182 + + + + + + + 183 + + + + + + + 184 + + + + + + + 185 + + + + + + + 186 + + + + + + + 187 + + + + + + + 188 + + + + + + + 189 + + + + + + + 190 + + + + + + + 191 + + + + + + + 192 + + + + + + + 193 + + + + + + + 194 + + + + + + + 195 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bingads/v13/proxies/production/campaignmanagement_service.xml b/bingads/v13/proxies/production/campaignmanagement_service.xml new file mode 100644 index 00000000..43423f23 --- /dev/null +++ b/bingads/v13/proxies/production/campaignmanagement_service.xml @@ -0,0 +1,20563 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100 + + + + + + + + + + + + + 7 + + + + + + + 28 + + + + + + + 29 + + + + + + + 40 + + + + + + + 30 + + + + + + + 35 + + + + + + + 36 + + + + + + + 55 + + + + + + + 82 + + + + + + + 88 + + + + + + + 109 + + + + + + + 112 + + + + + + + 24 + + + + + + + 137 + + + + + + + 41 + + + + + + + 87 + + + + + + + 19 + + + + + + + 27 + + + + + + + 32 + + + + + + + 26 + + + + + + + 48 + + + + + + + 70 + + + + + + + 68 + + + + + + + 75 + + + + + + + 92 + + + + + + + 106 + + + + + + + 107 + + + + + + + 123 + + + + + + + 98 + + + + + + + 138 + + + + + + + 5 + + + + + + + 71 + + + + + + + 49 + + + + + + + 56 + + + + + + + 46 + + + + + + + 93 + + + + + + + 73 + + + + + + + 118 + + + + + + + 50 + + + + + + + 113 + + + + + + + 129 + + + + + + + 47 + + + + + + + 64 + + + + + + + 1000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 32 + + + + + + + 64 + + + + + + + 128 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + 32 + + + + + + + 64 + + + + + + + 128 + + + + + + + 256 + + + + + + + 512 + + + + + + + 1024 + + + + + + + 2048 + + + + + + + 4096 + + + + + + + 8192 + + + + + + + 16384 + + + + + + + 32768 + + + + + + + 65536 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + 32 + + + + + + + 64 + + + + + + + 128 + + + + + + + 256 + + + + + + + 512 + + + + + + + 1024 + + + + + + + 2048 + + + + + + + 4096 + + + + + + + 8192 + + + + + + + 16384 + + + + + + + 32768 + + + + + + + 65536 + + + + + + + 131072 + + + + + + + 262144 + + + + + + + 524288 + + + + + + + 1048576 + + + + + + + 2097152 + + + + + + + 4194304 + + + + + + + 8388608 + + + + + + + 16777216 + + + + + + + 33554432 + + + + + + + 67108864 + + + + + + + 134217728 + + + + + + + 268435456 + + + + + + + 536870912 + + + + + + + 1073741824 + + + + + + + 2147483648 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + 32 + + + + + + + 64 + + + + + + + 128 + + + + + + + 256 + + + + + + + 512 + + + + + + + 1024 + + + + + + + 2048 + + + + + + + 4096 + + + + + + + 8192 + + + + + + + 16384 + + + + + + + 32768 + + + + + + + 65536 + + + + + + + 131072 + + + + + + + 262144 + + + + + + + 524288 + + + + + + + 1048576 + + + + + + + 2097152 + + + + + + + 4194304 + + + + + + + 8388608 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + 1 + + + + + + + 2 + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + 32 + + + + + + + 64 + + + + + + + 128 + + + + + + + 256 + + + + + + + 512 + + + + + + + 1024 + + + + + + + 2048 + + + + + + + 4096 + + + + + + + 8192 + + + + + + + 16384 + + + + + + + 32768 + + + + + + + 65536 + + + + + + + 131072 + + + + + + + 262144 + + + + + + + 524288 + + + + + + + 1048576 + + + + + + + 2097152 + + + + + + + 4194304 + + + + + + + 8388608 + + + + + + + 16777216 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + 1 + + + + + + + 2 + + + + + + + 4 + + + + + + + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + 32 + + + + + + + 64 + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bingads/v13/proxies/production/customerbilling_service.xml b/bingads/v13/proxies/production/customerbilling_service.xml new file mode 100644 index 00000000..e4ad96a2 --- /dev/null +++ b/bingads/v13/proxies/production/customerbilling_service.xml @@ -0,0 +1,1446 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bingads/v13/proxies/production/customermanagement_service.xml b/bingads/v13/proxies/production/customermanagement_service.xml new file mode 100644 index 00000000..a9abb138 --- /dev/null +++ b/bingads/v13/proxies/production/customermanagement_service.xml @@ -0,0 +1,4573 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + + + + + + 32 + + + + + + + 11 + + + + + + + 72 + + + + + + + 25 + + + + + + + 48 + + + + + + + 68 + + + + + + + 24 + + + + + + + 43 + + + + + + + 58 + + + + + + + 3 + + + + + + + 51 + + + + + + + 37 + + + + + + + 31 + + + + + + + 21 + + + + + + + 19 + + + + + + + 47 + + + + + + + 61 + + + + + + + 54 + + + + + + + 9 + + + + + + + 46 + + + + + + + 42 + + + + + + + 55 + + + + + + + 41 + + + + + + + 8 + + + + + + + 52 + + + + + + + 59 + + + + + + + 49 + + + + + + + 64 + + + + + + + 65 + + + + + + + 27 + + + + + + + 69 + + + + + + + 10 + + + + + + + 62 + + + + + + + 29 + + + + + + + 2 + + + + + + + 56 + + + + + + + 50 + + + + + + + 66 + + + + + + + 7 + + + + + + + 40 + + + + + + + 73 + + + + + + + 39 + + + + + + + 6 + + + + + + + 63 + + + + + + + 75 + + + + + + + 18 + + + + + + + 28 + + + + + + + 38 + + + + + + + 30 + + + + + + + 26 + + + + + + + 20 + + + + + + + 17 + + + + + + + 36 + + + + + + + 4 + + + + + + + 53 + + + + + + + 74 + + + + + + + 35 + + + + + + + 70 + + + + + + + 34 + + + + + + + 57 + + + + + + + 1 + + + + + + + 14 + + + + + + + 71 + + + + + + + 16 + + + + + + + 22 + + + + + + + 60 + + + + + + + 45 + + + + + + + + 13 + + + + + + + 23 + + + + + + + 15 + + + + + + + 33 + + + + + + + 5 + + + + + + + 44 + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 174 + + + + + + + 175 + + + + + + + 176 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1025 + + + + + + + 5121 + + + + + + + 15361 + + + + + + + 3073 + + + + + + + 2049 + + + + + + + 11265 + + + + + + + 13313 + + + + + + + 12289 + + + + + + + 4097 + + + + + + + 6145 + + + + + + + 8193 + + + + + + + 16385 + + + + + + + 7169 + + + + + + + 14337 + + + + + + + 9217 + + + + + + + 1028 + + + + + + + 1030 + + + + + + + 1031 + + + + + + + 1033 + + + + + + + 1034 + + + + + + + 1035 + + + + + + + 1036 + + + + + + + 1037 + + + + + + + 1040 + + + + + + + 1041 + + + + + + + 1042 + + + + + + + 1043 + + + + + + + 1044 + + + + + + + 1046 + + + + + + + 1049 + + + + + + + 1053 + + + + + + + 1054 + + + + + + + 1057 + + + + + + + 1060 + + + + + + + 1062 + + + + + + + 1066 + + + + + + + 2052 + + + + + + + 2055 + + + + + + + 2057 + + + + + + + 2058 + + + + + + + 3076 + + + + + + + 3079 + + + + + + + 3081 + + + + + + + 3084 + + + + + + + 4105 + + + + + + + 5129 + + + + + + + 6153 + + + + + + + 8202 + + + + + + + 9226 + + + + + + + 10250 + + + + + + + 11274 + + + + + + + 13321 + + + + + + + 13322 + + + + + + + 16393 + + + + + + + 17417 + + + + + + + 18441 + + + + + + + 1055 + + + + + + + 1124 + + + + + + + 1045 + + + + + + + 1086 + + + + + + + 1058 + + + + + + + 1029 + + + + + + + 1048 + + + + + + + 1032 + + + + + + + 1038 + + + + + + + 1081 + + + + + + + 1026 + + + + + + + 1063 + + + + + + + 1050 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bingads/v13/proxies/production/reporting_service.xml b/bingads/v13/proxies/production/reporting_service.xml new file mode 100644 index 00000000..d6d4fa4e --- /dev/null +++ b/bingads/v13/proxies/production/reporting_service.xml @@ -0,0 +1,5257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16 + + + + + + + 32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + 10 + + + + + + + 11 + + + + + + + 12 + + + + + + + 13 + + + + + + + 14 + + + + + + + 15 + + + + + + + 16 + + + + + + + 17 + + + + + + + 18 + + + + + + + 19 + + + + + + + 20 + + + + + + + 21 + + + + + + + 22 + + + + + + + 23 + + + + + + + 24 + + + + + + + 25 + + + + + + + 26 + + + + + + + 27 + + + + + + + 28 + + + + + + + 29 + + + + + + + 30 + + + + + + + 31 + + + + + + + 32 + + + + + + + 33 + + + + + + + 34 + + + + + + + 35 + + + + + + + 36 + + + + + + + 37 + + + + + + + 38 + + + + + + + 39 + + + + + + + 40 + + + + + + + 41 + + + + + + + 42 + + + + + + + 43 + + + + + + + 44 + + + + + + + 45 + + + + + + + 46 + + + + + + + 47 + + + + + + + 48 + + + + + + + 49 + + + + + + + 50 + + + + + + + 51 + + + + + + + 52 + + + + + + + 53 + + + + + + + 54 + + + + + + + 55 + + + + + + + 56 + + + + + + + 57 + + + + + + + 58 + + + + + + + 59 + + + + + + + 60 + + + + + + + 61 + + + + + + + 62 + + + + + + + 63 + + + + + + + 64 + + + + + + + 65 + + + + + + + 66 + + + + + + + 67 + + + + + + + 68 + + + + + + + 69 + + + + + + + 70 + + + + + + + 71 + + + + + + + 72 + + + + + + + 73 + + + + + + + 74 + + + + + + + 75 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + 64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 8 + + + + + + + 128 + + + + + + + 256 + + + + + + + 512 + + + + + + + 1024 + + + + + + + 4096 + + + + + + + 8192 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bingads/v13/proxies/sandbox/adinsight_service.xml b/bingads/v13/proxies/sandbox/adinsight_service.xml new file mode 100644 index 00000000..5c4ce362 --- /dev/null +++ b/bingads/v13/proxies/sandbox/adinsight_service.xml @@ -0,0 +1,5812 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + + + + + + 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 + + + + + + + 20 + + + + + + + 30 + + + + + + + 40 + + + + + + + 60 + + + + + + + 70 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + 10 + + + + + + + 11 + + + + + + + 12 + + + + + + + 13 + + + + + + + 14 + + + + + + + 15 + + + + + + + 16 + + + + + + + 17 + + + + + + + 18 + + + + + + + 19 + + + + + + + 20 + + + + + + + 21 + + + + + + + 22 + + + + + + + 23 + + + + + + + 24 + + + + + + + 25 + + + + + + + 26 + + + + + + + 27 + + + + + + + 28 + + + + + + + 29 + + + + + + + 30 + + + + + + + 31 + + + + + + + 32 + + + + + + + 33 + + + + + + + 34 + + + + + + + 35 + + + + + + + 36 + + + + + + + 37 + + + + + + + 38 + + + + + + + 39 + + + + + + + 40 + + + + + + + 41 + + + + + + + 42 + + + + + + + 43 + + + + + + + 44 + + + + + + + 45 + + + + + + + 46 + + + + + + + 47 + + + + + + + 48 + + + + + + + 49 + + + + + + + 50 + + + + + + + 51 + + + + + + + 52 + + + + + + + 53 + + + + + + + 54 + + + + + + + 55 + + + + + + + 56 + + + + + + + 57 + + + + + + + 58 + + + + + + + 59 + + + + + + + 60 + + + + + + + 61 + + + + + + + 62 + + + + + + + 63 + + + + + + + 64 + + + + + + + 65 + + + + + + + 66 + + + + + + + 67 + + + + + + + 68 + + + + + + + 69 + + + + + + + 70 + + + + + + + 71 + + + + + + + 72 + + + + + + + 73 + + + + + + + 74 + + + + + + + 75 + + + + + + + 76 + + + + + + + 77 + + + + + + + 78 + + + + + + + 79 + + + + + + + 80 + + + + + + + 81 + + + + + + + 82 + + + + + + + 83 + + + + + + + 84 + + + + + + + 85 + + + + + + + 86 + + + + + + + 87 + + + + + + + 88 + + + + + + + 89 + + + + + + + 90 + + + + + + + 91 + + + + + + + 92 + + + + + + + 93 + + + + + + + 94 + + + + + + + 95 + + + + + + + 96 + + + + + + + 97 + + + + + + + 98 + + + + + + + 99 + + + + + + + 100 + + + + + + + 101 + + + + + + + 102 + + + + + + + 103 + + + + + + + 104 + + + + + + + 105 + + + + + + + 106 + + + + + + + 107 + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + 10 + + + + + + + 11 + + + + + + + 12 + + + + + + + 13 + + + + + + + 14 + + + + + + + 15 + + + + + + + 16 + + + + + + + 17 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 23 + + + + + + + 15 + + + + + + + 1 + + + + + + + 78 + + + + + + + 87 + + + + + + + 2 + + + + + + + 3 + + + + + + + 16 + + + + + + + 18 + + + + + + + 20 + + + + + + + 5 + + + + + + + 88 + + + + + + + 25 + + + + + + + 6 + + + + + + + 33 + + + + + + + 30 + + + + + + + 36 + + + + + + + 8 + + + + + + + 48 + + + + + + + 58 + + + + + + + 57 + + + + + + + 52 + + + + + + + 82 + + + + + + + 10 + + + + + + + 9 + + + + + + + 64 + + + + + + + 65 + + + + + + + 69 + + + + + + + 34 + + + + + + + 72 + + + + + + + 74 + + + + + + + 13 + + + + + + + 11 + + + + + + + 4 + + + + + + + 93 + + + + + + + 7 + + + + + + + 12 + + + + + + + 45 + + + + + + + 17 + + + + + + + 67 + + + + + + + 21 + + + + + + + 35 + + + + + + + 99 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bingads/v13/proxies/sandbox/bulk_service.xml b/bingads/v13/proxies/sandbox/bulk_service.xml new file mode 100644 index 00000000..9035ec2c --- /dev/null +++ b/bingads/v13/proxies/sandbox/bulk_service.xml @@ -0,0 +1,2096 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + 10 + + + + + + + 11 + + + + + + + 12 + + + + + + + 13 + + + + + + + 14 + + + + + + + 15 + + + + + + + 16 + + + + + + + 17 + + + + + + + 18 + + + + + + + 19 + + + + + + + 20 + + + + + + + 21 + + + + + + + 22 + + + + + + + 23 + + + + + + + 24 + + + + + + + 25 + + + + + + + 26 + + + + + + + 27 + + + + + + + 28 + + + + + + + 29 + + + + + + + 30 + + + + + + + 31 + + + + + + + 32 + + + + + + + 33 + + + + + + + 34 + + + + + + + 35 + + + + + + + 36 + + + + + + + 37 + + + + + + + 38 + + + + + + + 39 + + + + + + + 40 + + + + + + + 41 + + + + + + + 42 + + + + + + + 43 + + + + + + + 44 + + + + + + + 45 + + + + + + + 46 + + + + + + + 47 + + + + + + + 48 + + + + + + + 49 + + + + + + + 50 + + + + + + + 51 + + + + + + + 52 + + + + + + + 53 + + + + + + + 54 + + + + + + + 55 + + + + + + + 56 + + + + + + + 57 + + + + + + + 58 + + + + + + + 59 + + + + + + + 60 + + + + + + + 61 + + + + + + + 62 + + + + + + + 63 + + + + + + + 64 + + + + + + + 65 + + + + + + + 66 + + + + + + + 67 + + + + + + + 68 + + + + + + + 69 + + + + + + + 70 + + + + + + + 71 + + + + + + + 72 + + + + + + + 73 + + + + + + + 74 + + + + + + + 75 + + + + + + + 76 + + + + + + + 77 + + + + + + + 78 + + + + + + + 79 + + + + + + + 80 + + + + + + + 81 + + + + + + + 82 + + + + + + + 83 + + + + + + + 84 + + + + + + + 85 + + + + + + + 86 + + + + + + + 87 + + + + + + + 88 + + + + + + + 89 + + + + + + + 90 + + + + + + + 91 + + + + + + + 92 + + + + + + + 93 + + + + + + + 94 + + + + + + + 95 + + + + + + + 96 + + + + + + + 97 + + + + + + + 98 + + + + + + + 99 + + + + + + + 100 + + + + + + + 101 + + + + + + + 102 + + + + + + + 103 + + + + + + + 104 + + + + + + + 105 + + + + + + + 106 + + + + + + + 107 + + + + + + + 108 + + + + + + + 109 + + + + + + + 110 + + + + + + + 111 + + + + + + + 112 + + + + + + + 113 + + + + + + + 114 + + + + + + + 115 + + + + + + + 116 + + + + + + + 117 + + + + + + + 118 + + + + + + + 119 + + + + + + + 120 + + + + + + + 121 + + + + + + + 122 + + + + + + + 123 + + + + + + + 124 + + + + + + + 125 + + + + + + + 126 + + + + + + + 127 + + + + + + + 128 + + + + + + + 129 + + + + + + + 130 + + + + + + + 131 + + + + + + + 132 + + + + + + + 133 + + + + + + + 134 + + + + + + + 135 + + + + + + + 136 + + + + + + + 137 + + + + + + + 138 + + + + + + + 139 + + + + + + + 140 + + + + + + + 141 + + + + + + + 142 + + + + + + + 143 + + + + + + + 144 + + + + + + + 145 + + + + + + + 146 + + + + + + + 147 + + + + + + + 148 + + + + + + + 149 + + + + + + + 150 + + + + + + + 151 + + + + + + + 152 + + + + + + + 153 + + + + + + + 154 + + + + + + + 155 + + + + + + + 156 + + + + + + + 157 + + + + + + + 158 + + + + + + + 159 + + + + + + + 160 + + + + + + + 161 + + + + + + + 162 + + + + + + + 163 + + + + + + + 164 + + + + + + + 165 + + + + + + + 166 + + + + + + + 167 + + + + + + + 168 + + + + + + + 169 + + + + + + + 170 + + + + + + + 171 + + + + + + + 172 + + + + + + + 173 + + + + + + + 174 + + + + + + + 175 + + + + + + + 176 + + + + + + + 177 + + + + + + + 178 + + + + + + + 179 + + + + + + + 180 + + + + + + + 181 + + + + + + + 182 + + + + + + + 183 + + + + + + + 184 + + + + + + + 185 + + + + + + + 186 + + + + + + + 187 + + + + + + + 188 + + + + + + + 189 + + + + + + + 190 + + + + + + + 191 + + + + + + + 192 + + + + + + + 193 + + + + + + + 194 + + + + + + + 195 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bingads/v13/proxies/campaign_management_service.xml b/bingads/v13/proxies/sandbox/campaignmanagement_service.xml similarity index 59% rename from bingads/v13/proxies/campaign_management_service.xml rename to bingads/v13/proxies/sandbox/campaignmanagement_service.xml index e5a1daa0..60bb0ee0 100644 --- a/bingads/v13/proxies/campaign_management_service.xml +++ b/bingads/v13/proxies/sandbox/campaignmanagement_service.xml @@ -1,5 +1,5 @@ - - + + @@ -26,7 +26,7 @@ - + @@ -67,12 +67,12 @@ - + + - @@ -145,6 +145,7 @@ + @@ -177,6 +178,14 @@ + + + + + + + + @@ -224,8 +233,16 @@ + + + + + + + + @@ -233,249 +250,533 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + + + + - + + + + + + - - + + + + + + + + + + + + + + + - + - - + + + + - + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100 + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + 7 - - + + - + 28 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + 29 + + + + + + + 40 + + + + + + + 30 + + + + + + + 35 + + + + + + + 36 + + + + + + + 55 + + + + + + + 82 + + + + + + + 88 + + + + + + + 109 + + + + + + + 112 + + + + + + + 24 + + + + + + + 137 + + + + + + + 41 + + + + + + + 87 + + + + + + + 19 + + + + + + + 27 + + + + + + + 32 + + + + + + + 26 + + + + + + + 48 + + + + + + + 70 + + + + + + + 68 + + + + + + + 75 + + + + + + + 92 + + + + + + + 106 + + + + + + + 107 + + + + + + + 123 + + + + + + + 98 + + + + + + + 138 + + + + + + + 5 + + + + + + + 71 + + + + + + + 49 + + + + + + + 56 + + + + + + + 46 + + + + + + + 93 + + + + + + + 73 + + + + + + + 118 + + + + + + + 50 + + + + + + + 113 + + + + + + + 129 + + + + + + + 47 + + + + + + + 64 + + + + + + + 1000 + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + - + - - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + - + + + + + + + + @@ -483,87 +784,38 @@ - - - - - - - - - - - - - - - - - - - - - - - + + - + - + + - - + + + + + + + + + + + + - + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -574,9 +826,23 @@ + + + + + + + + + + + + + + @@ -598,8 +864,15 @@ + + + + + + + - + @@ -669,1791 +942,1700 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - + - - - + + - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - + + - - - - - - - - - - - - - - - - + + + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - + + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - + + - + - - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 32 + + + + + + + 64 + + + + + + + 128 + + + + + + + + + - + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - + - - - - + + + + - + - + - - - - - - - - - - - - - - - - - + - - + + - + - + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + - - + + - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + - + - - + - + - + - + - + - - - - - + - + - - + - + - - - + + + - + - + - - + + - - - - - - - - + + + + - 1 + - - + + + + + + - 2 + - - + + + + - 3 + - - + + + + - 4 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - 1 + - - + + - 2 + - - + + - 3 + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - - + + + + + + + + + + + + + + + + + + + - - - - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - + - - + + - - + + + - - + + - + - - + + - - - + + - - + + - - - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - - - - - - - - - - - - - - - - - - - - - - 4 - - - - - - - 8 - - - - - - - 16 - - - - - - - 32 - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + + + + - + - + + - - - - - - - + - + + + + + + + + + + + + + + + + + + - + - - + + - + + + + + + + + + - + - - + + - - - - - - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + - - + + + + + + + + + + + + + + + + + + + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - - - - + + + - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + - - - - - - - - - - - - - - - - - - - - - - + + - - + - + + + + + + + + + + + + + + + + + + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - + + - + 1 - + 2 - + 3 @@ -2462,1540 +2644,1444 @@ - - - - - - - - - - - - - - - - - - - - - - - + + - + - - + + - + - - - - - - - - - - - - - - - - - - + + - - - - - + + - + - - + - + - + - - + + - + + - - + + - + - - + + - - - - + + + - - + + - - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - + + - - - + + - - - - - - - - - - - - + + + + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + 32 + + + + + + + 64 + + + + + + + 128 + + + + + + + 256 + + + + + + + 512 + + + + + + + 1024 + + + + + + + 2048 + + + + + + + 4096 + + + + + + + 8192 + + + + + + + 16384 + + + + + + + 32768 + + + + + + + 65536 + + + + + + + - - - + - + - - + - + + + + + + + + - + - - + + - - - - - - - - - - - - + - - + - - - - - - - - - + + - + + + + + + + - - + + - - - - + + + + - - + + - + - - + + - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + + + + + + + - - + + + + + + + + + + + - - - + + - - - - - - - - - - - - - - - - - - - 2 - - - - - - - 4 - - - - - - - 8 - - - - - - - 16 - - - - - - - 32 - - - - - - - 64 - - - - - - - 128 - - - - - - - 256 - - - - - - - 512 - - - - - - - 1024 - - - - - - - 2048 - - - - - - - 4096 - - - - - - - 8192 - - - - - - - 16384 - - - - + + + + + + + + + + + + + + + + + + + + + + + - 32768 + - - + + + + + + + - 65536 + - - + + - 131072 + - - + + - 262144 + - - - - - 524288 - - - - - - - 1048576 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - 2 - - - - - - - - - - - + + + - - - - - - - - + + - + - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + + + + - - - - - - - - - - - - - + + - + - - + - - + + - + - - - - - + + + + + + + + + + - - + + - + - + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - - + + - - - - - - - - - - - - - - - - - + + - + - - + + + + + + - - - - - - - - - 0 - - - - - - - 1 - - - - - - - 2 - - - - - - + + + + + + + + + + + + + + - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + - - + + + + + + + + + + + + + + + - + - - - + + - + - + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - + + - + - + + + + + + + + + + + - - + + - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + + - - + + - - - - - - - 1 - - - - - - - 2 - - - - - - - 3 - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + - + - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - - - - - - + + - - + + - + 1 - + 2 + + + + 3 + + + - - + + - + + - + - + - - + + - - - + + - - + + - + - - - - - - - - - - - - - - + + - - + + + + - - - - - - - - - - - - - + + - - + + + - - - - - - - - - - - - - + - - - + - + - - + + + + + - + - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - + - + - + - + + + - + + + + + + + + + + + + + + + + - + - - + + - - - + + + + + + + + - - + + - + - + - - - - - - - - - - - - - - - - - - + + - - + - - - - - - - - + - + + - + - - - + - + + + + + + + + + + + + + + + + + + + + + - + + - - + + + + + + + + + + + + - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - + + - + - - - + + - + - + - + + + + + + + + + + + + + + + + + + + + + - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - + 2 - - - - - - - - - - - + @@ -4017,42 +4103,42 @@ - + 32 - + 64 - + 128 - + 256 - + 512 - + 1024 @@ -4122,901 +4208,640 @@ - + 1048576 - + 2097152 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 4194304 + + + + + + + 8388608 + + + + + + + 16777216 + + + + + + + 33554432 + + + + + + + 67108864 + + + + + + + 134217728 + + + + + + + 268435456 + + + + + + + 536870912 + + + + + + + 1073741824 + + + + + + + 2147483648 + + + + + + + + + + + + + + + + + + + + + - + - + - + - - + + - - - + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - + + + + + + + + + + + + + + - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + 1 + + + + + + + 2 + + + + + + + - + - - + + + - - + + - + + - - + + + + + + + 1 + + + + + + + 2 + + + + + + + - + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - - + + - - - - - - - - - - - - - - - - + + - + - - + - - + + - + - - + - - + + + + + + + + + + - + - - - - - - - - + + - - - - - - - - - - - - - + + - - + + + + - - + + + + + + + + - - + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + - - - - - - - - - - - - - + + + + + + + + + + + + - - + + - + - + + - - + + - + - + + + + + - - - - - - - - - - - - + + + + + + + + + - - + + - - - - 1 - - - - - - - 2 - - - - - - - 3 - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - + + + + + + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - + + + + - - - - - - - - - - - + + - + - + - - + + + + + + + + + + + + + + + - + - + + - - + + + + + + + + + + + + + + + + + + + - + - - - - - - - - + + - - - - - - - - - - - - - - - + + + + + + + + + 0 + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + - - + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -5024,1221 +4849,7652 @@ - - + + + + + + + + + + + + + + + + + - + + + + + + + + + + + - - + + - - - + + - + - - + + - + - + + - + - - + - + - + + + - + - + - + - + - + - - + + - - - - - - - + + - - + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + + - + - + - - - - - - - - - - - - - - - - - - - + + - + - + - + - + - - + + - - + + + + + + + + + + - + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + 1 + + + + + + + 2 + + + + + + + + - + - + + + - + + + + + + + + + + + - + - + + + + + + + - - + - + + + + + + + + + + + + - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + - - + - + - + - - + + - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - + + + + + + + + + + + + + - - + + + - + + - - - - - - - - - + - - + - + - - - + - + - - + - + - + - + - + - - + + - - - - - + + - - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + - + - + + + + + + + + + + + + + + + + + + - + - - + + - + - - + - + - - + + + - + - - - + + - + - - + + - + - + - - - - - - - - - - - - - - - - + - + + + + + - + - + - + - + + - + - + - - + + - - - - - - - - - + + + - + - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + - - - - + + - - - - - - - - 0 - - - - - - - 1 - - - - - - - 2 - - - - - - - 4 - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + + + + - + - + - + - - + + + + - + + - + - - - + + - - - - - - - - + - - + - + + - + + + + + + + + - + - - + + - - - - - - - - - - + + - - - - - - - - - - + + - + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + 32 + + + + + + + 64 + + + + + + + 128 + + + + + + + 256 + + + + + + + 512 + + + + + + + 1024 + + + + + + + 2048 + + + + + + + 4096 + + + + + + + 8192 + + + + + + + 16384 + + + + + + + 32768 + + + + + + + 65536 + + + + + + + 131072 + + + + + + + 262144 + + + + + + + 524288 + + + + + + + 1048576 + + + + + + + 2097152 + + + + + + + 4194304 + + + + + + + 8388608 + + + + + + + + + + + + + - + - - + + - + + + + + + + + + + + + + + + + + - - + - + + + + - + + - - - + + + + + + + + - + - - - - - true - - + + - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - + + - + + + + + - - - - - - - - - true - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - + + - + + + + + - - - - - - - - - true - - + + - - + - - - - + + - + - - - - + + + + + + + + + + + - + - + - - + + - + - - + + + + + + + + + + + + - + - - + + + + + + + + + + + + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + 1 + + + + + + + 2 + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + 32 + + + + + + + 64 + + + + + + + 128 + + + + + + + 256 + + + + + + + 512 + + + + + + + 1024 + + + + + + + 2048 + + + + + + + 4096 + + + + + + + 8192 + + + + + + + 16384 + + + + + + + 32768 + + + + + + + 65536 + + + + + + + 131072 + + + + + + + 262144 + + + + + + + 524288 + + + + + + + 1048576 + + + + + + + 2097152 + + + + + + + 4194304 + + + + + + + 8388608 + + + + + + + 16777216 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + 1 + + + + + + + 2 + + + + + + + 4 + + + + + + + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + 32 + + + + + + + 64 + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6247,22 +12503,22 @@ - - + + - + - - + + - + - - + + - + @@ -6271,22 +12527,22 @@ - - + + - + - - + + - + - - + + - + @@ -6295,22 +12551,22 @@ - - + + - + - - + + - + - - + + - + @@ -6319,22 +12575,22 @@ - - + + - + - - + + - + - - + + - + @@ -6343,22 +12599,22 @@ - - + + - + - - + + - + - - + + - + @@ -6367,22 +12623,22 @@ - - + + - + - - + + - + - - + + - + @@ -6391,22 +12647,22 @@ - - + + - + - - + + - + - - + + - + @@ -6415,22 +12671,22 @@ - - + + - + - - + + - - + + - - + + - + @@ -6439,22 +12695,22 @@ - - + + - + - - + + - + - - + + - + @@ -6463,22 +12719,22 @@ - - + + - + - - + + - + - - + + - + @@ -6487,22 +12743,22 @@ - - + + - + - - + + - + - - + + - + @@ -6511,22 +12767,22 @@ - - + + - + - - + + - + - - + + - + @@ -6535,22 +12791,22 @@ - - + + - + - - + + - - + + - - + + - + @@ -6559,22 +12815,22 @@ - - + + - + - - + + - - + + - - + + - + @@ -6583,22 +12839,22 @@ - - + + - + - - + + - + - - + + - + @@ -6607,22 +12863,22 @@ - - + + - + - - + + - + - - + + - + @@ -6631,22 +12887,22 @@ - - + + - + - - + + - + - - + + - + @@ -6655,22 +12911,22 @@ - - + + - + - - + + - + - - + + - + @@ -6679,22 +12935,22 @@ - - + + - + - - + + - - + + - - + + - + @@ -6703,22 +12959,22 @@ - - + + - + - - + + - + - - + + - + @@ -6727,22 +12983,22 @@ - - + + - + - - + + - + - - + + - + @@ -6751,22 +13007,22 @@ - - + + - + - - + + - + - - + + - + @@ -6775,22 +13031,22 @@ - - + + - + - - + + - + - - + + - + @@ -6799,22 +13055,22 @@ - - + + - + - - + + - + - - + + - + @@ -6823,22 +13079,22 @@ - - + + - + - - + + - + - - + + - + @@ -6847,22 +13103,22 @@ - - + + - + - - + + - + - - + + - + @@ -6871,22 +13127,22 @@ - - + + - + - - + + - - + + - - + + - + @@ -6895,22 +13151,22 @@ - - + + - + - - + + - + - - + + - + @@ -6919,22 +13175,22 @@ - - + + - + - - + + - + - - + + - + @@ -6943,22 +13199,22 @@ - - + + - + - - + + - - + + - - + + - + @@ -6967,22 +13223,22 @@ - - + + - + - - + + - + - - + + - + @@ -6991,22 +13247,22 @@ - - + + - + - - + + - + - - + + - + @@ -7015,22 +13271,22 @@ - - + + - + - - + + - + - - + + - + @@ -7039,22 +13295,22 @@ - - + + - + - - + + - + - - + + - + @@ -7063,22 +13319,22 @@ - - + + - + - - + + - + - - - - + + + + @@ -7087,22 +13343,22 @@ - - + + - + - - + + - + - - + + - + @@ -7111,22 +13367,22 @@ - - + + - + - - + + - + - - + + - + @@ -7135,22 +13391,22 @@ - - + + - + - - + + - + - - + + - + @@ -7159,22 +13415,22 @@ - - + + - + - - + + - + - - + + - + @@ -7183,22 +13439,22 @@ - - + + - + - - + + - - + + - - + + - + @@ -7207,22 +13463,22 @@ - - + + - + - - + + - - + + - - + + - + @@ -7231,22 +13487,22 @@ - - + + - + - - + + - + - - + + - + @@ -7255,22 +13511,22 @@ - - + + - + - - + + - + - - + + - + @@ -7279,22 +13535,22 @@ - - + + - + - - + + - + - - + + - + @@ -7303,22 +13559,22 @@ - - + + - + - - + + - + - - + + - + @@ -7327,22 +13583,22 @@ - - + + - + - - + + - + - - + + - + @@ -7351,22 +13607,22 @@ - - + + - + - - + + - + - - + + - + @@ -7375,22 +13631,22 @@ - - + + - + - - + + - + - - + + - + @@ -7399,22 +13655,22 @@ - - + + - + - - + + - + - - + + - + @@ -7423,22 +13679,22 @@ - - + + - + - - + + - + - - - - + + + + @@ -7447,22 +13703,22 @@ - - + + - + - - + + - + - - + + - + @@ -7471,22 +13727,22 @@ - - + + - + - - + + - + - - + + - + @@ -7495,22 +13751,22 @@ - - + + - + - - + + - + - - + + - + @@ -7519,22 +13775,22 @@ - - + + - + - - + + - + - - + + - + @@ -7543,22 +13799,22 @@ - - + + - + - - + + - + - - + + - + @@ -7567,22 +13823,22 @@ - - + + - + - - + + - + - - + + - + @@ -7591,22 +13847,22 @@ - - + + - + - - + + - + - - + + - + @@ -7615,22 +13871,22 @@ - - + + - + - - + + - + - - + + - + @@ -7639,22 +13895,22 @@ - - + + - + - - + + - + - - + + - + @@ -7663,22 +13919,22 @@ - - + + - + - - + + - + - - + + - + @@ -7687,22 +13943,22 @@ - - + + - + - - + + - + - - + + - + @@ -7711,22 +13967,22 @@ - - + + - + - - + + - + - - + + - + @@ -7735,22 +13991,22 @@ - - + + - + - - + + - + - - + + - + @@ -7759,22 +14015,22 @@ - - + + - + - - + + - + - - + + - + @@ -7783,22 +14039,22 @@ - - + + - + - - + + - + - - + + - + @@ -7807,22 +14063,22 @@ - - + + - + - - + + - + - - + + - + @@ -7831,22 +14087,22 @@ - - + + - + - - + + - + - - + + - + @@ -7855,22 +14111,22 @@ - - + + - + - - + + - + - - + + - + @@ -7879,22 +14135,22 @@ - - + + - + - - + + - + - - + + - + @@ -7903,22 +14159,22 @@ - - + + - + - - + + - + - - + + - + @@ -7927,22 +14183,22 @@ - - + + - + - - + + - + - - + + - + @@ -7951,22 +14207,22 @@ - - + + - + - - + + - + - - + + - + @@ -7975,22 +14231,22 @@ - - + + - + - - + + - + - - + + - + @@ -7999,22 +14255,22 @@ - - + + - + - - + + - + - - + + - + @@ -8023,22 +14279,22 @@ - - + + - + - - + + - + - - + + - + @@ -8047,22 +14303,22 @@ - - + + - + - - + + - + - - + + - + @@ -8071,22 +14327,22 @@ - - + + - + - - + + - + - - + + - + @@ -8095,22 +14351,22 @@ - - + + - + - - + + - + - - + + - + @@ -8119,22 +14375,22 @@ - - + + - + - - + + - + - - + + - + @@ -8143,22 +14399,22 @@ - - + + - + - - + + - + - - + + - + @@ -8167,22 +14423,22 @@ - - + + - + - - + + - + - - + + - + @@ -8191,22 +14447,22 @@ - - + + - + - - + + - + - - + + - + @@ -8215,22 +14471,22 @@ - - + + - + - - + + - + - - + + - + @@ -8239,22 +14495,22 @@ - - + + - + - - + + - + - - + + - + @@ -8263,22 +14519,22 @@ - - + + - + - - + + - + - - + + - + @@ -8287,22 +14543,22 @@ - - + + - + - - + + - + - - + + - + @@ -8311,22 +14567,22 @@ - - + + - + - - + + - + - - + + - + @@ -8335,22 +14591,22 @@ - - + + - + - - + + - + - - + + - + @@ -8359,22 +14615,22 @@ - - + + - + - - + + - + - - + + - + @@ -8383,22 +14639,22 @@ - - + + - + - - + + - + - - + + - + @@ -8407,22 +14663,22 @@ - - + + - + - - + + - + - - + + - + @@ -8431,22 +14687,22 @@ - - + + - + - - + + - + - - + + - + @@ -8455,22 +14711,22 @@ - - + + - + - - + + - + - - + + - + @@ -8479,22 +14735,22 @@ - - + + - + - - + + - + - - + + - + @@ -8503,22 +14759,22 @@ - - + + - + - - + + - + - - + + - + @@ -8527,22 +14783,22 @@ - - + + - + - - + + - + - - + + - + @@ -8551,22 +14807,22 @@ - - + + - + - - + + - + - - + + - + @@ -8575,22 +14831,22 @@ - - + + - + - - + + - + - - + + - + @@ -8599,22 +14855,22 @@ - - + + - + - - + + - + - - + + - + @@ -8623,22 +14879,22 @@ - - + + - + - - + + - + - - + + - + @@ -8647,22 +14903,22 @@ - - + + - + - - + + - + - - + + - + @@ -8671,22 +14927,22 @@ - - + + - + - - + + - + - - + + - + @@ -8695,22 +14951,22 @@ - - + + - + - - + + - + - - + + - + @@ -8719,22 +14975,22 @@ - - + + - + - - + + - + - - + + - + @@ -8743,22 +14999,22 @@ - - + + - + - - + + - + - - + + - + @@ -8767,22 +15023,22 @@ - - + + - + - - + + - + - - + + - + @@ -8791,22 +15047,22 @@ - - + + - + - - + + - + - - + + - + @@ -8815,22 +15071,22 @@ - - + + - + - - + + - + - - + + - + @@ -8839,22 +15095,22 @@ - - + + - + - - + + - + - - + + - + @@ -8863,22 +15119,22 @@ - - + + - + - - + + - + - - + + - + @@ -8887,16 +15143,16 @@ - - + + - + - - + + - + @@ -8906,744 +15162,2629 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + - - + + @@ -9653,20 +17794,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9676,20 +17817,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9699,20 +17840,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9722,20 +17863,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9745,20 +17886,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9768,20 +17909,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9791,20 +17932,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9814,20 +17955,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9837,20 +17978,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9860,20 +18001,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9883,20 +18024,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9906,20 +18047,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9929,20 +18070,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9952,20 +18093,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9975,20 +18116,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -9998,20 +18139,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10021,43 +18162,43 @@ - - - - - - - - - - + + + + + + + + + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - + + @@ -10067,20 +18208,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10090,20 +18231,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10113,20 +18254,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10136,66 +18277,66 @@ - - - - - - - - - - + + + + + + + + + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - + + @@ -10205,20 +18346,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10228,20 +18369,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10251,20 +18392,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10274,43 +18415,43 @@ - - - - - - - - - - + + + + + + + + + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - + + @@ -10320,20 +18461,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10343,43 +18484,43 @@ - - - - - - - - - - + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - + + @@ -10389,20 +18530,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10412,20 +18553,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10435,20 +18576,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10458,43 +18599,43 @@ - - - - - - - - - - + + + + + + + + + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - + + @@ -10504,20 +18645,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10527,43 +18668,43 @@ - - - - - - - - - - + + + + + + + + + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - + + @@ -10573,20 +18714,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10596,20 +18737,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10619,20 +18760,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10642,20 +18783,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10665,20 +18806,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10688,20 +18829,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10711,20 +18852,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10734,20 +18875,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10757,66 +18898,66 @@ - - - - - - - - - - + + + + + + + + + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - + + @@ -10826,20 +18967,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10849,20 +18990,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10872,20 +19013,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10895,20 +19036,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10918,20 +19059,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10941,20 +19082,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10964,20 +19105,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -10987,20 +19128,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11010,20 +19151,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11033,20 +19174,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11056,20 +19197,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11079,20 +19220,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11102,20 +19243,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11125,20 +19266,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11148,20 +19289,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11169,22 +19310,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + - - + + @@ -11194,20 +19335,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11217,20 +19358,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11240,20 +19381,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11263,20 +19404,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11286,20 +19427,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11309,20 +19450,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11332,20 +19473,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11355,20 +19496,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11378,20 +19519,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11401,20 +19542,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11422,22 +19563,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + - - + + @@ -11447,20 +19588,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11470,20 +19611,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11493,20 +19634,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11516,20 +19657,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11539,20 +19680,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11562,20 +19703,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11585,20 +19726,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11608,20 +19749,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11631,20 +19772,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11654,20 +19795,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11677,20 +19818,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11700,20 +19841,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11723,20 +19864,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11746,20 +19887,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11769,20 +19910,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11792,20 +19933,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11815,20 +19956,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11838,20 +19979,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11861,20 +20002,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11884,20 +20025,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11905,22 +20046,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + - - + + @@ -11930,20 +20071,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11953,20 +20094,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11976,20 +20117,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -11999,20 +20140,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12022,20 +20163,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12045,20 +20186,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12068,20 +20209,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12091,20 +20232,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12114,20 +20255,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12137,20 +20278,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12160,20 +20301,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12183,20 +20324,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12206,20 +20347,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12229,20 +20370,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12252,20 +20393,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12275,20 +20416,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12298,20 +20439,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12321,20 +20462,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12344,20 +20485,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12367,20 +20508,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + @@ -12390,20 +20531,20 @@ - - - - - - - - - - + + + + + + + + + + - - + + diff --git a/bingads/v13/proxies/sandbox/customerbilling_service.xml b/bingads/v13/proxies/sandbox/customerbilling_service.xml new file mode 100644 index 00000000..6594f522 --- /dev/null +++ b/bingads/v13/proxies/sandbox/customerbilling_service.xml @@ -0,0 +1,1446 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bingads/v13/proxies/sandbox/customermanagement_service.xml b/bingads/v13/proxies/sandbox/customermanagement_service.xml new file mode 100644 index 00000000..a5cebe75 --- /dev/null +++ b/bingads/v13/proxies/sandbox/customermanagement_service.xml @@ -0,0 +1,4573 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + + + + + + 32 + + + + + + + 11 + + + + + + + 72 + + + + + + + 25 + + + + + + + 48 + + + + + + + 68 + + + + + + + 24 + + + + + + + 43 + + + + + + + 58 + + + + + + + 3 + + + + + + + 51 + + + + + + + 37 + + + + + + + 31 + + + + + + + 21 + + + + + + + 19 + + + + + + + 47 + + + + + + + 61 + + + + + + + 54 + + + + + + + 9 + + + + + + + 46 + + + + + + + 42 + + + + + + + 55 + + + + + + + 41 + + + + + + + 8 + + + + + + + 52 + + + + + + + 59 + + + + + + + 49 + + + + + + + 64 + + + + + + + 65 + + + + + + + 27 + + + + + + + 69 + + + + + + + 10 + + + + + + + 62 + + + + + + + 29 + + + + + + + 2 + + + + + + + 56 + + + + + + + 50 + + + + + + + 66 + + + + + + + 7 + + + + + + + 40 + + + + + + + 73 + + + + + + + 39 + + + + + + + 6 + + + + + + + 63 + + + + + + + 75 + + + + + + + 18 + + + + + + + 28 + + + + + + + 38 + + + + + + + 30 + + + + + + + 26 + + + + + + + 20 + + + + + + + 17 + + + + + + + 36 + + + + + + + 4 + + + + + + + 53 + + + + + + + 74 + + + + + + + 35 + + + + + + + 70 + + + + + + + 34 + + + + + + + 57 + + + + + + + 1 + + + + + + + 14 + + + + + + + 71 + + + + + + + 16 + + + + + + + 22 + + + + + + + 60 + + + + + + + 45 + + + + + + + + 13 + + + + + + + 23 + + + + + + + 15 + + + + + + + 33 + + + + + + + 5 + + + + + + + 44 + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 174 + + + + + + + 175 + + + + + + + 176 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1025 + + + + + + + 5121 + + + + + + + 15361 + + + + + + + 3073 + + + + + + + 2049 + + + + + + + 11265 + + + + + + + 13313 + + + + + + + 12289 + + + + + + + 4097 + + + + + + + 6145 + + + + + + + 8193 + + + + + + + 16385 + + + + + + + 7169 + + + + + + + 14337 + + + + + + + 9217 + + + + + + + 1028 + + + + + + + 1030 + + + + + + + 1031 + + + + + + + 1033 + + + + + + + 1034 + + + + + + + 1035 + + + + + + + 1036 + + + + + + + 1037 + + + + + + + 1040 + + + + + + + 1041 + + + + + + + 1042 + + + + + + + 1043 + + + + + + + 1044 + + + + + + + 1046 + + + + + + + 1049 + + + + + + + 1053 + + + + + + + 1054 + + + + + + + 1057 + + + + + + + 1060 + + + + + + + 1062 + + + + + + + 1066 + + + + + + + 2052 + + + + + + + 2055 + + + + + + + 2057 + + + + + + + 2058 + + + + + + + 3076 + + + + + + + 3079 + + + + + + + 3081 + + + + + + + 3084 + + + + + + + 4105 + + + + + + + 5129 + + + + + + + 6153 + + + + + + + 8202 + + + + + + + 9226 + + + + + + + 10250 + + + + + + + 11274 + + + + + + + 13321 + + + + + + + 13322 + + + + + + + 16393 + + + + + + + 17417 + + + + + + + 18441 + + + + + + + 1055 + + + + + + + 1124 + + + + + + + 1045 + + + + + + + 1086 + + + + + + + 1058 + + + + + + + 1029 + + + + + + + 1048 + + + + + + + 1032 + + + + + + + 1038 + + + + + + + 1081 + + + + + + + 1026 + + + + + + + 1063 + + + + + + + 1050 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bingads/v13/proxies/sandbox/reporting_service.xml b/bingads/v13/proxies/sandbox/reporting_service.xml new file mode 100644 index 00000000..3f73b4a5 --- /dev/null +++ b/bingads/v13/proxies/sandbox/reporting_service.xml @@ -0,0 +1,5257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16 + + + + + + + 32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + 10 + + + + + + + 11 + + + + + + + 12 + + + + + + + 13 + + + + + + + 14 + + + + + + + 15 + + + + + + + 16 + + + + + + + 17 + + + + + + + 18 + + + + + + + 19 + + + + + + + 20 + + + + + + + 21 + + + + + + + 22 + + + + + + + 23 + + + + + + + 24 + + + + + + + 25 + + + + + + + 26 + + + + + + + 27 + + + + + + + 28 + + + + + + + 29 + + + + + + + 30 + + + + + + + 31 + + + + + + + 32 + + + + + + + 33 + + + + + + + 34 + + + + + + + 35 + + + + + + + 36 + + + + + + + 37 + + + + + + + 38 + + + + + + + 39 + + + + + + + 40 + + + + + + + 41 + + + + + + + 42 + + + + + + + 43 + + + + + + + 44 + + + + + + + 45 + + + + + + + 46 + + + + + + + 47 + + + + + + + 48 + + + + + + + 49 + + + + + + + 50 + + + + + + + 51 + + + + + + + 52 + + + + + + + 53 + + + + + + + 54 + + + + + + + 55 + + + + + + + 56 + + + + + + + 57 + + + + + + + 58 + + + + + + + 59 + + + + + + + 60 + + + + + + + 61 + + + + + + + 62 + + + + + + + 63 + + + + + + + 64 + + + + + + + 65 + + + + + + + 66 + + + + + + + 67 + + + + + + + 68 + + + + + + + 69 + + + + + + + 70 + + + + + + + 71 + + + + + + + 72 + + + + + + + 73 + + + + + + + 74 + + + + + + + 75 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4 + + + + + + + 8 + + + + + + + 16 + + + + + + + 64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 8 + + + + + + + 128 + + + + + + + 256 + + + + + + + 512 + + + + + + + 1024 + + + + + + + 4096 + + + + + + + 8192 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + + + + 6 + + + + + + + 7 + + + + + + + 8 + + + + + + + 9 + + + + + + + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bingads/v13/reporting/reporting_operation.py b/bingads/v13/reporting/reporting_operation.py index de3f8b30..f29f995d 100644 --- a/bingads/v13/reporting/reporting_operation.py +++ b/bingads/v13/reporting/reporting_operation.py @@ -4,7 +4,6 @@ import requests import zipfile import os -import six import sys import shutil @@ -57,9 +56,10 @@ def __init__(self, self._authorization_data = authorization_data self._poll_interval_in_milliseconds = poll_interval_in_milliseconds self._final_status = None - self.tracking_id=tracking_id + self.tracking_id = tracking_id - def download_result_file(self, result_file_directory, result_file_name, decompress, overwrite, timeout_in_milliseconds=None): + def download_result_file(self, result_file_directory, result_file_name, decompress, overwrite, + timeout_in_milliseconds=None): """ Download file with specified URL and download parameters. :param result_file_directory: The download result local directory name. @@ -101,37 +101,35 @@ def download_result_file(self, result_file_directory, result_file_name, decompre zip_file_path = result_file_path if os.path.exists(result_file_path) and overwrite is False: - if six.PY3: - raise FileExistsError('Result file: {0} exists'.format(result_file_path)) - else: - raise OSError('Result file: {0} exists'.format(result_file_path)) + raise FileExistsError('Result file: {0} exists'.format(result_file_path)) headers = { 'User-Agent': USER_AGENT, } - s = requests.Session() - s.mount('https://', TlsHttpAdapter()) - timeout_seconds = None if timeout_in_milliseconds is None else timeout_in_milliseconds / 1000.0 - try: - r = s.get(url, headers=headers, stream=True, verify=True, timeout=timeout_seconds) - except requests.Timeout as ex: - raise FileDownloadException(ex) - r.raise_for_status() - try: - with open(zip_file_path, 'wb') as f: - for chunk in r.iter_content(chunk_size=4096): - if chunk: - f.write(chunk) - f.flush() - if decompress: - with contextlib.closing(zipfile.ZipFile(zip_file_path)) as compressed: - first = compressed.namelist()[0] - with open(result_file_path, 'wb') as f, compressed.open(first, 'r') as cc: - shutil.copyfileobj(cc, f) - except Exception as ex: - raise ex - finally: - if decompress and os.path.exists(zip_file_path): - os.remove(zip_file_path) + + with requests.Session() as s: + s.mount('https://', TlsHttpAdapter()) + timeout_seconds = None if timeout_in_milliseconds is None else timeout_in_milliseconds / 1000.0 + try: + r = s.get(url, headers=headers, stream=True, verify=True, timeout=timeout_seconds) + except requests.Timeout as ex: + raise FileDownloadException(ex) + r.raise_for_status() + try: + with open(zip_file_path, 'wb') as f: + for chunk in r.iter_content(chunk_size=4096): + if chunk: + f.write(chunk) + f.flush() + if decompress: + with contextlib.closing(zipfile.ZipFile(zip_file_path)) as compressed: + first = compressed.namelist()[0] + with open(result_file_path, 'wb') as f, compressed.open(first, 'r') as cc: + shutil.copyfileobj(cc, f) + except Exception as ex: + raise ex + finally: + if decompress and os.path.exists(zip_file_path): + os.remove(zip_file_path) return result_file_path def track(self, timeout_in_milliseconds=None): @@ -171,9 +169,9 @@ def get_status(self): status = ReportingOperationStatus( status=response.Status, report_download_url=response.ReportDownloadUrl - ) + ) if status.status == 'Success' or \ - status.status == 'Error': + status.status == 'Error': self._final_status = status return status diff --git a/bingads/v13/reporting/reporting_service_manager.py b/bingads/v13/reporting/reporting_service_manager.py index 198429a1..e7971d97 100644 --- a/bingads/v13/reporting/reporting_service_manager.py +++ b/bingads/v13/reporting/reporting_service_manager.py @@ -7,6 +7,7 @@ from ...exceptions import TimeoutException from ...util import _TimeHelper + class ReportingServiceManager: """ Provides high level methods for downloading reporting files using the Reporting API functionality. @@ -21,7 +22,9 @@ class ReportingServiceManager: or :meth:`.ReportingDownloadOperation.track`, and then download the file with the :meth:`.ReportingOperation.download_result_file` method. """ - def __init__(self, authorization_data, poll_interval_in_milliseconds=5000, environment='production', working_directory=None, **suds_options): + + def __init__(self, authorization_data, poll_interval_in_milliseconds=5000, environment='production', + working_directory=None, **suds_options): """ Initialize a new instance of this class. :param authorization_data: Represents a user who intends to access the corresponding customer and account. @@ -47,7 +50,7 @@ def __init__(self, authorization_data, poll_interval_in_milliseconds=5000, envir if not os.path.exists(self._working_directory): os.makedirs(self._working_directory) self._suds_options = suds_options - + def download_report(self, download_parameters): """ Downloads the specified reporting to a local file and parse it with report_file_reader. @@ -60,7 +63,6 @@ def download_report(self, download_parameters): if report_file_path: reader = ReportFileReader(report_file_path, download_parameters.report_request.Format) return reader.get_report() - def download_file(self, download_parameters): """ Downloads the specified reporting to a local file. @@ -80,7 +82,8 @@ def download_file(self, download_parameters): result_file_directory = self.working_directory if download_parameters.result_file_directory is not None: result_file_directory = download_parameters.result_file_directory - download_result_file_timeout = _TimeHelper.get_remaining_time_milliseconds_with_min_value(start_timestamp, download_parameters.timeout_in_milliseconds) + download_result_file_timeout = _TimeHelper.get_remaining_time_milliseconds_with_min_value(start_timestamp, + download_parameters.timeout_in_milliseconds) result_file_path = operation.download_result_file( result_file_directory=result_file_directory, result_file_name=download_parameters.result_file_name, @@ -106,7 +109,7 @@ def submit_download(self, report_request): authorization_data=self._authorization_data, poll_interval_in_milliseconds=self._poll_interval_in_milliseconds, environment=self._environment, - tracking_id = headers['TrackingId'] if 'TrackingId' in headers else None, + tracking_id=headers['TrackingId'] if 'TrackingId' in headers else None, **self.suds_options ) return operation @@ -115,19 +118,19 @@ def normalize_request(self, report_request): if report_request is None: return - + if not hasattr(report_request, 'Time'): return if hasattr(report_request.Time, 'ReportTimeZone') \ - and hasattr(report_request.Time.ReportTimeZone, 'value') \ - and report_request.Time.ReportTimeZone.value is None: - report_request.Time.ReportTimeZone=None - + and hasattr(report_request.Time.ReportTimeZone, 'value') \ + and report_request.Time.ReportTimeZone.value is None: + report_request.Time.ReportTimeZone = None + if hasattr(report_request.Time, 'PredefinedTime') \ - and hasattr(report_request.Time.PredefinedTime, 'value') \ - and report_request.Time.PredefinedTime.value is None: - report_request.Time.PredefinedTime=None + and hasattr(report_request.Time.PredefinedTime, 'value') \ + and report_request.Time.PredefinedTime.value is None: + report_request.Time.PredefinedTime = None @property def service_client(self): diff --git a/examples/v13/adinsight_example_helper.py b/examples/v13/adinsight_example_helper.py index 55bc0060..9bda62e6 100644 --- a/examples/v13/adinsight_example_helper.py +++ b/examples/v13/adinsight_example_helper.py @@ -155,6 +155,7 @@ def output_auctioninsightkpi(data_object): output_status_message("AboveRate: {0}".format(data_object.AboveRate)) output_status_message("TopOfPageRate: {0}".format(data_object.TopOfPageRate)) output_status_message("OutrankingShare: {0}".format(data_object.OutrankingShare)) + output_status_message("AbsoluteTopOfPageRate: {0}".format(data_object.AbsoluteTopOfPageRate)) output_status_message("* * * End output_auctioninsightkpi * * *") def output_array_of_auctioninsightkpi(data_objects): @@ -1396,6 +1397,18 @@ def output_array_of_auctionsegment(value_sets): for value_set in value_sets['AuctionSegment']: output_auctionsegment(value_set) +def output_auctioninsightkpiadditionalfield(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_auctioninsightkpiadditionalfield(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of AuctionInsightKpiAdditionalField:\n") + for value_set in value_sets['AuctionInsightKpiAdditionalField']: + output_auctioninsightkpiadditionalfield(value_set) + def output_keywordideaattribute(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: diff --git a/examples/v13/auth_helper.py b/examples/v13/auth_helper.py index 0dc27bd7..e88a79b2 100644 --- a/examples/v13/auth_helper.py +++ b/examples/v13/auth_helper.py @@ -15,11 +15,11 @@ # The CLIENT_ID is required and CLIENT_STATE is recommended. # The REFRESH_TOKEN should always be in a secure location. -CLIENT_ID='db41b09d-6e50-4f4a-90ac-5a99caefb52f' +CLIENT_ID='4c0b021c-00c3-4508-838f-d3127e8167ff' CLIENT_STATE='ClientStateGoesHere' REFRESH_TOKEN="refresh.txt" -ALL_CAMPAIGN_TYPES=['Audience DynamicSearchAds Search Shopping'] +ALL_CAMPAIGN_TYPES=['Audience Search Shopping'] ALL_TARGET_CAMPAIGN_CRITERION_TYPES=['Age DayTime Device Gender Location LocationIntent Radius'] ALL_TARGET_AD_GROUP_CRITERION_TYPES=['Age DayTime Device Gender Location LocationIntent Radius'] diff --git a/examples/v13/bulk_dynamic_search_ads.py b/examples/v13/bulk_dynamic_search_ads.py index 522acb8a..e9da02f6 100644 --- a/examples/v13/bulk_dynamic_search_ads.py +++ b/examples/v13/bulk_dynamic_search_ads.py @@ -115,15 +115,14 @@ def main(authorization_data): upload_entities.append(bulk_feed_item) - # To get started with dynamic search ads, first you'll need to add a new Campaign - # with its type set to DynamicSearchAds. When you create the campaign, you'll need to - # include a DynamicSearchAdsSetting that specifies the target web site domain and language. + # To get started with dynamic search ads, first you'll need to add a new Search campaign + # Include a DynamicSearchAdsSetting that specifies the target website domain and language. # Page feeds can be associated at the campaign level via 'Source' and 'Page Feed Ids'. bulk_campaign=BulkCampaign() campaign=set_elements_to_none(campaign_service.factory.create('Campaign')) campaign.BudgetType='DailyBudgetStandard' - campaign.CampaignType=['DynamicSearchAds'] + campaign.CampaignType=['Search'] campaign.DailyBudget=50 languages=campaign_service.factory.create('ns3:ArrayOfstring') languages.string.append('All') @@ -147,12 +146,13 @@ def main(authorization_data): bulk_campaign.campaign=campaign upload_entities.append(bulk_campaign) - # Create a new ad group within the dynamic search ads campaign. + # Create a new ad group with type set to "SearchDynamic" bulk_ad_group=BulkAdGroup() bulk_ad_group.campaign_id=CAMPAIGN_ID_KEY ad_group=set_elements_to_none(campaign_service.factory.create('AdGroup')) ad_group.Id=AD_GROUP_ID_KEY + ad_group.AdGroupType='SearchDynamic' ad_group.Name="Sunglasses Sale" end_date=campaign_service.factory.create('Date') end_date.Day=31 diff --git a/examples/v13/campaignmanagement_example_helper.py b/examples/v13/campaignmanagement_example_helper.py index 827d14ed..1fd00e63 100644 --- a/examples/v13/campaignmanagement_example_helper.py +++ b/examples/v13/campaignmanagement_example_helper.py @@ -163,18 +163,26 @@ def output_adextension(data_object): output_calladextension(data_object) if data_object.Type == 'CalloutAdExtension': output_calloutadextension(data_object) + if data_object.Type == 'FilterLinkAdExtension': + output_filterlinkadextension(data_object) + if data_object.Type == 'FlyerAdExtension': + output_flyeradextension(data_object) if data_object.Type == 'ImageAdExtension': output_imageadextension(data_object) if data_object.Type == 'LocationAdExtension': output_locationadextension(data_object) if data_object.Type == 'PriceAdExtension': output_priceadextension(data_object) + if data_object.Type == 'PromotionAdExtension': + output_promotionadextension(data_object) if data_object.Type == 'ReviewAdExtension': output_reviewadextension(data_object) if data_object.Type == 'SitelinkAdExtension': output_sitelinkadextension(data_object) if data_object.Type == 'StructuredSnippetAdExtension': output_structuredsnippetadextension(data_object) + if data_object.Type == 'VideoAdExtension': + output_videoadextension(data_object) output_status_message("* * * End output_adextension * * *") def output_array_of_adextension(data_objects): @@ -292,6 +300,7 @@ def output_adgroup(data_object): output_array_of_keyvaluepairofstringstring(data_object.ForwardCompatibilityMap) output_status_message("Id: {0}".format(data_object.Id)) output_status_message("Language: {0}".format(data_object.Language)) + output_status_message("MultimediaAdsBidAdjustment: {0}".format(data_object.MultimediaAdsBidAdjustment)) output_status_message("Name: {0}".format(data_object.Name)) output_status_message("Network: {0}".format(data_object.Network)) output_status_message("PrivacyStatus: {0}".format(data_object.PrivacyStatus)) @@ -303,6 +312,12 @@ def output_adgroup(data_object): output_status_message("TrackingUrlTemplate: {0}".format(data_object.TrackingUrlTemplate)) output_status_message("UrlCustomParameters:") output_customparameters(data_object.UrlCustomParameters) + output_status_message("AdScheduleUseSearcherTimeZone: {0}".format(data_object.AdScheduleUseSearcherTimeZone)) + output_status_message("AdGroupType: {0}".format(data_object.AdGroupType)) + output_status_message("CpvBid:") + output_bid(data_object.CpvBid) + output_status_message("CpmBid:") + output_bid(data_object.CpmBid) output_status_message("* * * End output_adgroup * * *") def output_array_of_adgroup(data_objects): @@ -507,6 +522,8 @@ def output_asset(data_object): output_imageasset(data_object) if data_object.Type == 'TextAsset': output_textasset(data_object) + if data_object.Type == 'VideoAsset': + output_videoasset(data_object) output_status_message("* * * End output_asset * * *") def output_array_of_asset(data_objects): @@ -551,6 +568,8 @@ def output_audience(data_object): output_status_message("SupportedCampaignTypes:") output_array_of_string(data_object.SupportedCampaignTypes) output_status_message("Type: {0}".format(data_object.Type)) + if data_object.Type == 'CombinedList': + output_combinedlist(data_object) if data_object.Type == 'Custom': output_customaudience(data_object) if data_object.Type == 'InMarket': @@ -662,6 +681,8 @@ def output_biddableadgroupcriterion(data_object): output_status_message("TrackingUrlTemplate: {0}".format(data_object.TrackingUrlTemplate)) output_status_message("UrlCustomParameters:") output_customparameters(data_object.UrlCustomParameters) + output_status_message("CriterionCashback:") + output_criterioncashback(data_object.CriterionCashback) output_status_message("* * * End output_biddableadgroupcriterion * * *") def output_array_of_biddableadgroupcriterion(data_objects): @@ -676,6 +697,8 @@ def output_biddablecampaigncriterion(data_object): output_status_message("* * * Begin output_biddablecampaigncriterion * * *") output_status_message("CriterionBid:") output_criterionbid(data_object.CriterionBid) + output_status_message("CriterionCashback:") + output_criterioncashback(data_object.CriterionCashback) output_status_message("* * * End output_biddablecampaigncriterion * * *") def output_array_of_biddablecampaigncriterion(data_objects): @@ -695,14 +718,22 @@ def output_biddingscheme(data_object): output_inheritfromparentbiddingscheme(data_object) if data_object.Type == 'ManualCpcBiddingScheme': output_manualcpcbiddingscheme(data_object) + if data_object.Type == 'ManualCpmBiddingScheme': + output_manualcpmbiddingscheme(data_object) + if data_object.Type == 'ManualCpvBiddingScheme': + output_manualcpvbiddingscheme(data_object) if data_object.Type == 'MaxClicksBiddingScheme': output_maxclicksbiddingscheme(data_object) if data_object.Type == 'MaxConversionsBiddingScheme': output_maxconversionsbiddingscheme(data_object) + if data_object.Type == 'MaxConversionValueBiddingScheme': + output_maxconversionvaluebiddingscheme(data_object) if data_object.Type == 'MaxRoasBiddingScheme': output_maxroasbiddingscheme(data_object) if data_object.Type == 'TargetCpaBiddingScheme': output_targetcpabiddingscheme(data_object) + if data_object.Type == 'TargetImpressionShareBiddingScheme': + output_targetimpressionsharebiddingscheme(data_object) if data_object.Type == 'TargetRoasBiddingScheme': output_targetroasbiddingscheme(data_object) output_status_message("* * * End output_biddingscheme * * *") @@ -726,6 +757,24 @@ def output_array_of_bidmultiplier(data_objects): for data_object in data_objects['BidMultiplier']: output_bidmultiplier(data_object) +def output_bidstrategy(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_bidstrategy * * *") + output_status_message("AssociatedCampaignType: {0}".format(data_object.AssociatedCampaignType)) + output_status_message("AssociationCount: {0}".format(data_object.AssociationCount)) + output_status_message("BiddingScheme:") + output_biddingscheme(data_object.BiddingScheme) + output_status_message("Id: {0}".format(data_object.Id)) + output_status_message("Name: {0}".format(data_object.Name)) + output_status_message("* * * End output_bidstrategy * * *") + +def output_array_of_bidstrategy(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['BidStrategy']: + output_bidstrategy(data_object) + def output_bmcstore(data_object): if data_object is None: return @@ -805,6 +854,7 @@ def output_campaign(data_object): output_status_message("ForwardCompatibilityMap:") output_array_of_keyvaluepairofstringstring(data_object.ForwardCompatibilityMap) output_status_message("Id: {0}".format(data_object.Id)) + output_status_message("MultimediaAdsBidAdjustment: {0}".format(data_object.MultimediaAdsBidAdjustment)) output_status_message("Name: {0}".format(data_object.Name)) output_status_message("Status: {0}".format(data_object.Status)) output_status_message("SubType: {0}".format(data_object.SubType)) @@ -818,6 +868,8 @@ def output_campaign(data_object): output_status_message("BudgetId: {0}".format(data_object.BudgetId)) output_status_message("Languages:") output_array_of_string(data_object.Languages) + output_status_message("AdScheduleUseSearcherTimeZone: {0}".format(data_object.AdScheduleUseSearcherTimeZone)) + output_status_message("BidStrategyId: {0}".format(data_object.BidStrategyId)) output_status_message("* * * End output_campaign * * *") def output_array_of_campaign(data_objects): @@ -826,6 +878,22 @@ def output_array_of_campaign(data_objects): for data_object in data_objects['Campaign']: output_campaign(data_object) +def output_campaignadgroupids(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_campaignadgroupids * * *") + output_status_message("ActiveAdGroupsOnly: {0}".format(data_object.ActiveAdGroupsOnly)) + output_status_message("AdGroupIds:") + output_array_of_long(data_object.AdGroupIds) + output_status_message("CampaignId: {0}".format(data_object.CampaignId)) + output_status_message("* * * End output_campaignadgroupids * * *") + +def output_array_of_campaignadgroupids(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['CampaignAdGroupIds']: + output_campaignadgroupids(data_object) + def output_campaigncriterion(data_object): if data_object is None: return @@ -865,6 +933,48 @@ def output_array_of_campaignnegativesites(data_objects): for data_object in data_objects['CampaignNegativeSites']: output_campaignnegativesites(data_object) +def output_cashbackadjustment(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_cashbackadjustment * * *") + output_status_message("CashbackPercent: {0}".format(data_object.CashbackPercent)) + output_status_message("* * * End output_cashbackadjustment * * *") + +def output_array_of_cashbackadjustment(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['CashbackAdjustment']: + output_cashbackadjustment(data_object) + +def output_combinationrule(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_combinationrule * * *") + output_status_message("AudienceIds:") + output_array_of_long(data_object.AudienceIds) + output_status_message("Operator: {0}".format(data_object.Operator)) + output_status_message("* * * End output_combinationrule * * *") + +def output_array_of_combinationrule(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['CombinationRule']: + output_combinationrule(data_object) + +def output_combinedlist(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_combinedlist * * *") + output_status_message("CombinationRules:") + output_array_of_combinationrule(data_object.CombinationRules) + output_status_message("* * * End output_combinedlist * * *") + +def output_array_of_combinedlist(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['CombinedList']: + output_combinedlist(data_object) + def output_company(data_object): if data_object is None: return @@ -888,6 +998,7 @@ def output_conversiongoal(data_object): output_status_message("ConversionWindowInMinutes: {0}".format(data_object.ConversionWindowInMinutes)) output_status_message("CountType: {0}".format(data_object.CountType)) output_status_message("ExcludeFromBidding: {0}".format(data_object.ExcludeFromBidding)) + output_status_message("GoalCategory: {0}".format(data_object.GoalCategory)) output_status_message("Id: {0}".format(data_object.Id)) output_status_message("Name: {0}".format(data_object.Name)) output_status_message("Revenue:") @@ -977,6 +1088,8 @@ def output_criterion(data_object): output_profilecriterion(data_object) if data_object.Type == 'RadiusCriterion': output_radiuscriterion(data_object) + if data_object.Type == 'StoreCriterion': + output_storecriterion(data_object) if data_object.Type == 'Webpage': output_webpage(data_object) output_status_message("* * * End output_criterion * * *") @@ -1004,6 +1117,21 @@ def output_array_of_criterionbid(data_objects): for data_object in data_objects['CriterionBid']: output_criterionbid(data_object) +def output_criterioncashback(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_criterioncashback * * *") + output_status_message("Type: {0}".format(data_object.Type)) + if data_object.Type == 'CashbackAdjustment': + output_cashbackadjustment(data_object) + output_status_message("* * * End output_criterioncashback * * *") + +def output_array_of_criterioncashback(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['CriterionCashback']: + output_criterioncashback(data_object) + def output_customaudience(data_object): if data_object is None: return @@ -1185,6 +1313,19 @@ def output_array_of_durationgoal(data_objects): for data_object in data_objects['DurationGoal']: output_durationgoal(data_object) +def output_dynamicfeedsetting(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_dynamicfeedsetting * * *") + output_status_message("FeedId: {0}".format(data_object.FeedId)) + output_status_message("* * * End output_dynamicfeedsetting * * *") + +def output_array_of_dynamicfeedsetting(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['DynamicFeedSetting']: + output_dynamicfeedsetting(data_object) + def output_dynamicsearchad(data_object): if data_object is None: return @@ -1206,6 +1347,7 @@ def output_dynamicsearchadssetting(data_object): return output_status_message("* * * Begin output_dynamicsearchadssetting * * *") output_status_message("DomainName: {0}".format(data_object.DomainName)) + output_status_message("DynamicDescriptionEnabled: {0}".format(data_object.DynamicDescriptionEnabled)) output_status_message("Language: {0}".format(data_object.Language)) output_status_message("PageFeedIds:") output_array_of_long(data_object.PageFeedIds) @@ -1409,6 +1551,56 @@ def output_array_of_experiment(data_objects): for data_object in data_objects['Experiment']: output_experiment(data_object) +def output_fileimportjob(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_fileimportjob * * *") + output_status_message("FileSource: {0}".format(data_object.FileSource)) + output_status_message("FileUrl: {0}".format(data_object.FileUrl)) + output_status_message("* * * End output_fileimportjob * * *") + +def output_array_of_fileimportjob(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['FileImportJob']: + output_fileimportjob(data_object) + +def output_fileimportoption(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_fileimportoption * * *") + output_status_message("* * * End output_fileimportoption * * *") + +def output_array_of_fileimportoption(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['FileImportOption']: + output_fileimportoption(data_object) + +def output_filterlinkadextension(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_filterlinkadextension * * *") + output_status_message("AdExtensionHeaderType: {0}".format(data_object.AdExtensionHeaderType)) + output_status_message("FinalMobileUrls:") + output_array_of_string(data_object.FinalMobileUrls) + output_status_message("FinalUrlSuffix: {0}".format(data_object.FinalUrlSuffix)) + output_status_message("FinalUrls:") + output_array_of_string(data_object.FinalUrls) + output_status_message("Language: {0}".format(data_object.Language)) + output_status_message("Texts:") + output_array_of_string(data_object.Texts) + output_status_message("TrackingUrlTemplate: {0}".format(data_object.TrackingUrlTemplate)) + output_status_message("UrlCustomParameters:") + output_customparameters(data_object.UrlCustomParameters) + output_status_message("* * * End output_filterlinkadextension * * *") + +def output_array_of_filterlinkadextension(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['FilterLinkAdExtension']: + output_filterlinkadextension(data_object) + def output_fixedbid(data_object): if data_object is None: return @@ -1422,6 +1614,50 @@ def output_array_of_fixedbid(data_objects): for data_object in data_objects['FixedBid']: output_fixedbid(data_object) +def output_flyeradextension(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_flyeradextension * * *") + output_status_message("Description: {0}".format(data_object.Description)) + output_status_message("FinalAppUrls:") + output_array_of_appurl(data_object.FinalAppUrls) + output_status_message("FinalMobileUrls:") + output_array_of_string(data_object.FinalMobileUrls) + output_status_message("FinalUrlSuffix: {0}".format(data_object.FinalUrlSuffix)) + output_status_message("FinalUrls:") + output_array_of_string(data_object.FinalUrls) + output_status_message("FlyerName: {0}".format(data_object.FlyerName)) + output_status_message("ImageMediaIds:") + output_array_of_long(data_object.ImageMediaIds) + output_status_message("ImageMediaUrls:") + output_array_of_string(data_object.ImageMediaUrls) + output_status_message("StoreId: {0}".format(data_object.StoreId)) + output_status_message("TrackingUrlTemplate: {0}".format(data_object.TrackingUrlTemplate)) + output_status_message("UrlCustomParameters:") + output_customparameters(data_object.UrlCustomParameters) + output_status_message("* * * End output_flyeradextension * * *") + +def output_array_of_flyeradextension(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['FlyerAdExtension']: + output_flyeradextension(data_object) + +def output_frequency(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_frequency * * *") + output_status_message("Cron: {0}".format(data_object.Cron)) + output_status_message("TimeZone: {0}".format(data_object.TimeZone)) + output_status_message("Type: {0}".format(data_object.Type)) + output_status_message("* * * End output_frequency * * *") + +def output_array_of_frequency(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['Frequency']: + output_frequency(data_object) + def output_gendercriterion(data_object): if data_object is None: return @@ -1449,6 +1685,124 @@ def output_array_of_geopoint(data_objects): for data_object in data_objects['GeoPoint']: output_geopoint(data_object) +def output_googleimportjob(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_googleimportjob * * *") + output_status_message("CampaignAdGroupIds:") + output_array_of_campaignadgroupids(data_object.CampaignAdGroupIds) + output_status_message("CredentialId: {0}".format(data_object.CredentialId)) + output_status_message("GoogleAccountId: {0}".format(data_object.GoogleAccountId)) + output_status_message("GoogleUserName: {0}".format(data_object.GoogleUserName)) + output_status_message("* * * End output_googleimportjob * * *") + +def output_array_of_googleimportjob(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['GoogleImportJob']: + output_googleimportjob(data_object) + +def output_googleimportoption(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_googleimportoption * * *") + output_status_message("AccountUrlOptions: {0}".format(data_object.AccountUrlOptions)) + output_status_message("AdjustmentForBids: {0}".format(data_object.AdjustmentForBids)) + output_status_message("AdjustmentForCampaignBudgets: {0}".format(data_object.AdjustmentForCampaignBudgets)) + output_status_message("AssociatedStoreId: {0}".format(data_object.AssociatedStoreId)) + output_status_message("AssociatedUetTagId: {0}".format(data_object.AssociatedUetTagId)) + output_status_message("AutoDeviceBidOptimization: {0}".format(data_object.AutoDeviceBidOptimization)) + output_status_message("DeleteRemovedEntities: {0}".format(data_object.DeleteRemovedEntities)) + output_status_message("EnableAutoCurrencyConversion: {0}".format(data_object.EnableAutoCurrencyConversion)) + output_status_message("EnableParentLocationMapping: {0}".format(data_object.EnableParentLocationMapping)) + output_status_message("NewActiveAdsForExistingAdGroups: {0}".format(data_object.NewActiveAdsForExistingAdGroups)) + output_status_message("NewActiveCampaignsAndChildEntities: {0}".format(data_object.NewActiveCampaignsAndChildEntities)) + output_status_message("NewAdCustomizerFeeds: {0}".format(data_object.NewAdCustomizerFeeds)) + output_status_message("NewAdGroupsAndChildEntitiesForExistingCampaigns: {0}".format(data_object.NewAdGroupsAndChildEntitiesForExistingCampaigns)) + output_status_message("NewAdSchedules: {0}".format(data_object.NewAdSchedules)) + output_status_message("NewAppAdExtensions: {0}".format(data_object.NewAppAdExtensions)) + output_status_message("NewAudienceTargets: {0}".format(data_object.NewAudienceTargets)) + output_status_message("NewCallAdExtensions: {0}".format(data_object.NewCallAdExtensions)) + output_status_message("NewCalloutAdExtensions: {0}".format(data_object.NewCalloutAdExtensions)) + output_status_message("NewDemographicTargets: {0}".format(data_object.NewDemographicTargets)) + output_status_message("NewDeviceTargets: {0}".format(data_object.NewDeviceTargets)) + output_status_message("NewEntities: {0}".format(data_object.NewEntities)) + output_status_message("NewKeywordUrls: {0}".format(data_object.NewKeywordUrls)) + output_status_message("NewKeywordsForExistingAdGroups: {0}".format(data_object.NewKeywordsForExistingAdGroups)) + output_status_message("NewLabels: {0}".format(data_object.NewLabels)) + output_status_message("NewLocationAdExtensions: {0}".format(data_object.NewLocationAdExtensions)) + output_status_message("NewLocationTargets: {0}".format(data_object.NewLocationTargets)) + output_status_message("NewNegativeKeywordLists: {0}".format(data_object.NewNegativeKeywordLists)) + output_status_message("NewNegativeKeywordsForExistingParents: {0}".format(data_object.NewNegativeKeywordsForExistingParents)) + output_status_message("NewNegativeSites: {0}".format(data_object.NewNegativeSites)) + output_status_message("NewPageFeeds: {0}".format(data_object.NewPageFeeds)) + output_status_message("NewPausedAdsForExistingAdGroups: {0}".format(data_object.NewPausedAdsForExistingAdGroups)) + output_status_message("NewPausedCampaignsAndChildEntities: {0}".format(data_object.NewPausedCampaignsAndChildEntities)) + output_status_message("NewPriceAdExtensions: {0}".format(data_object.NewPriceAdExtensions)) + output_status_message("NewProductFilters: {0}".format(data_object.NewProductFilters)) + output_status_message("NewPromotionAdExtensions: {0}".format(data_object.NewPromotionAdExtensions)) + output_status_message("NewReviewAdExtensions: {0}".format(data_object.NewReviewAdExtensions)) + output_status_message("NewSitelinkAdExtensions: {0}".format(data_object.NewSitelinkAdExtensions)) + output_status_message("NewStructuredSnippetAdExtensions: {0}".format(data_object.NewStructuredSnippetAdExtensions)) + output_status_message("NewUrlOptions: {0}".format(data_object.NewUrlOptions)) + output_status_message("PauseCampaignsWithoutSupportedLocations: {0}".format(data_object.PauseCampaignsWithoutSupportedLocations)) + output_status_message("PauseNewCampaigns: {0}".format(data_object.PauseNewCampaigns)) + output_status_message("RaiseBidsToMinimum: {0}".format(data_object.RaiseBidsToMinimum)) + output_status_message("RaiseCampaignBudgetsToMinimum: {0}".format(data_object.RaiseCampaignBudgetsToMinimum)) + output_status_message("RaiseProductGroupBidsToMinimum: {0}".format(data_object.RaiseProductGroupBidsToMinimum)) + output_status_message("SearchAndDsaMixedCampaignAsSearchCampaign: {0}".format(data_object.SearchAndDsaMixedCampaignAsSearchCampaign)) + output_status_message("SearchAndReplaceForCampaignNames:") + output_importsearchandreplaceforstringproperty(data_object.SearchAndReplaceForCampaignNames) + output_status_message("SearchAndReplaceForCustomParameters:") + output_importsearchandreplaceforstringproperty(data_object.SearchAndReplaceForCustomParameters) + output_status_message("SearchAndReplaceForTrackingTemplates:") + output_importsearchandreplaceforstringproperty(data_object.SearchAndReplaceForTrackingTemplates) + output_status_message("SearchAndReplaceForUrls:") + output_importsearchandreplaceforstringproperty(data_object.SearchAndReplaceForUrls) + output_status_message("SuffixForCampaignNames: {0}".format(data_object.SuffixForCampaignNames)) + output_status_message("SuffixForTrackingTemplates: {0}".format(data_object.SuffixForTrackingTemplates)) + output_status_message("SuffixForUrls: {0}".format(data_object.SuffixForUrls)) + output_status_message("UpdateAdCustomizerFeeds: {0}".format(data_object.UpdateAdCustomizerFeeds)) + output_status_message("UpdateAdGroupNetwork: {0}".format(data_object.UpdateAdGroupNetwork)) + output_status_message("UpdateAdSchedules: {0}".format(data_object.UpdateAdSchedules)) + output_status_message("UpdateAppAdExtensions: {0}".format(data_object.UpdateAppAdExtensions)) + output_status_message("UpdateAudienceTargets: {0}".format(data_object.UpdateAudienceTargets)) + output_status_message("UpdateBiddingStrategies: {0}".format(data_object.UpdateBiddingStrategies)) + output_status_message("UpdateBids: {0}".format(data_object.UpdateBids)) + output_status_message("UpdateCallAdExtensions: {0}".format(data_object.UpdateCallAdExtensions)) + output_status_message("UpdateCalloutAdExtensions: {0}".format(data_object.UpdateCalloutAdExtensions)) + output_status_message("UpdateCampaignAdGroupLanguages: {0}".format(data_object.UpdateCampaignAdGroupLanguages)) + output_status_message("UpdateCampaignBudgets: {0}".format(data_object.UpdateCampaignBudgets)) + output_status_message("UpdateCampaignNames: {0}".format(data_object.UpdateCampaignNames)) + output_status_message("UpdateDemographicTargets: {0}".format(data_object.UpdateDemographicTargets)) + output_status_message("UpdateDeviceTargets: {0}".format(data_object.UpdateDeviceTargets)) + output_status_message("UpdateEntities: {0}".format(data_object.UpdateEntities)) + output_status_message("UpdateKeywordUrls: {0}".format(data_object.UpdateKeywordUrls)) + output_status_message("UpdateLabels: {0}".format(data_object.UpdateLabels)) + output_status_message("UpdateLocationAdExtensions: {0}".format(data_object.UpdateLocationAdExtensions)) + output_status_message("UpdateLocationTargets: {0}".format(data_object.UpdateLocationTargets)) + output_status_message("UpdateNegativeKeywordLists: {0}".format(data_object.UpdateNegativeKeywordLists)) + output_status_message("UpdateNegativeSites: {0}".format(data_object.UpdateNegativeSites)) + output_status_message("UpdatePageFeeds: {0}".format(data_object.UpdatePageFeeds)) + output_status_message("UpdatePriceAdExtensions: {0}".format(data_object.UpdatePriceAdExtensions)) + output_status_message("UpdateProductFilters: {0}".format(data_object.UpdateProductFilters)) + output_status_message("UpdatePromotionAdExtensions: {0}".format(data_object.UpdatePromotionAdExtensions)) + output_status_message("UpdateReviewAdExtensions: {0}".format(data_object.UpdateReviewAdExtensions)) + output_status_message("UpdateSitelinkAdExtensions: {0}".format(data_object.UpdateSitelinkAdExtensions)) + output_status_message("UpdateStatusForAdGroups: {0}".format(data_object.UpdateStatusForAdGroups)) + output_status_message("UpdateStatusForAds: {0}".format(data_object.UpdateStatusForAds)) + output_status_message("UpdateStatusForCampaigns: {0}".format(data_object.UpdateStatusForCampaigns)) + output_status_message("UpdateStatusForKeywords: {0}".format(data_object.UpdateStatusForKeywords)) + output_status_message("UpdateStructuredSnippetAdExtensions: {0}".format(data_object.UpdateStructuredSnippetAdExtensions)) + output_status_message("UpdateUrlOptions: {0}".format(data_object.UpdateUrlOptions)) + output_status_message("* * * End output_googleimportoption * * *") + +def output_array_of_googleimportoption(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['GoogleImportOption']: + output_googleimportoption(data_object) + def output_idcollection(data_object): if data_object is None: return @@ -1495,6 +1849,8 @@ def output_imageadextension(data_object): output_array_of_long(data_object.ImageMediaIds) output_status_message("Images:") output_array_of_assetlink(data_object.Images) + output_status_message("Layouts:") + output_array_of_string(data_object.Layouts) output_status_message("TrackingUrlTemplate: {0}".format(data_object.TrackingUrlTemplate)) output_status_message("UrlCustomParameters:") output_customparameters(data_object.UrlCustomParameters) @@ -1537,6 +1893,109 @@ def output_array_of_imagemediarepresentation(data_objects): for data_object in data_objects['ImageMediaRepresentation']: output_imagemediarepresentation(data_object) +def output_importentitystatistics(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_importentitystatistics * * *") + output_status_message("Additions: {0}".format(data_object.Additions)) + output_status_message("Changes: {0}".format(data_object.Changes)) + output_status_message("Deletions: {0}".format(data_object.Deletions)) + output_status_message("EntityType: {0}".format(data_object.EntityType)) + output_status_message("Errors: {0}".format(data_object.Errors)) + output_status_message("Total: {0}".format(data_object.Total)) + output_status_message("* * * End output_importentitystatistics * * *") + +def output_array_of_importentitystatistics(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['ImportEntityStatistics']: + output_importentitystatistics(data_object) + +def output_importjob(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_importjob * * *") + output_status_message("CreatedByUserId: {0}".format(data_object.CreatedByUserId)) + output_status_message("CreatedByUserName: {0}".format(data_object.CreatedByUserName)) + output_status_message("CreatedDateTimeInUTC: {0}".format(data_object.CreatedDateTimeInUTC)) + output_status_message("Frequency:") + output_frequency(data_object.Frequency) + output_status_message("Id: {0}".format(data_object.Id)) + output_status_message("ImportOption:") + output_importoption(data_object.ImportOption) + output_status_message("LastRunTimeInUTC: {0}".format(data_object.LastRunTimeInUTC)) + output_status_message("Name: {0}".format(data_object.Name)) + output_status_message("NotificationEmail: {0}".format(data_object.NotificationEmail)) + output_status_message("NotificationType: {0}".format(data_object.NotificationType)) + output_status_message("Status: {0}".format(data_object.Status)) + output_status_message("Type: {0}".format(data_object.Type)) + if data_object.Type == 'FileImportJob': + output_fileimportjob(data_object) + if data_object.Type == 'GoogleImportJob': + output_googleimportjob(data_object) + output_status_message("* * * End output_importjob * * *") + +def output_array_of_importjob(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['ImportJob']: + output_importjob(data_object) + +def output_importoption(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_importoption * * *") + output_status_message("ForwardCompatibilityMap:") + output_array_of_keyvaluepairofstringstring(data_object.ForwardCompatibilityMap) + output_status_message("Type: {0}".format(data_object.Type)) + if data_object.Type == 'FileImportOption': + output_fileimportoption(data_object) + if data_object.Type == 'GoogleImportOption': + output_googleimportoption(data_object) + output_status_message("* * * End output_importoption * * *") + +def output_array_of_importoption(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['ImportOption']: + output_importoption(data_object) + +def output_importresult(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_importresult * * *") + output_status_message("EntityStatistics:") + output_array_of_importentitystatistics(data_object.EntityStatistics) + output_status_message("ErrorLogUrl: {0}".format(data_object.ErrorLogUrl)) + output_status_message("ForwardCompatibilityMap:") + output_array_of_keyvaluepairofstringstring(data_object.ForwardCompatibilityMap) + output_status_message("Id: {0}".format(data_object.Id)) + output_status_message("ImportJob:") + output_importjob(data_object.ImportJob) + output_status_message("StartTimeInUTC: {0}".format(data_object.StartTimeInUTC)) + output_status_message("Status: {0}".format(data_object.Status)) + output_status_message("* * * End output_importresult * * *") + +def output_array_of_importresult(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['ImportResult']: + output_importresult(data_object) + +def output_importsearchandreplaceforstringproperty(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_importsearchandreplaceforstringproperty * * *") + output_status_message("ReplaceString: {0}".format(data_object.ReplaceString)) + output_status_message("SearchString: {0}".format(data_object.SearchString)) + output_status_message("* * * End output_importsearchandreplaceforstringproperty * * *") + +def output_array_of_importsearchandreplaceforstringproperty(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['ImportSearchAndReplaceForStringProperty']: + output_importsearchandreplaceforstringproperty(data_object) + def output_inheritfromparentbiddingscheme(data_object): if data_object is None: return @@ -1574,6 +2033,20 @@ def output_array_of_instoretransactiongoal(data_objects): for data_object in data_objects['InStoreTransactionGoal']: output_instoretransactiongoal(data_object) +def output_keyvaluepairoflonglong(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_keyvaluepairoflonglong * * *") + output_status_message("key: {0}".format(data_object.key)) + output_status_message("value: {0}".format(data_object.value)) + output_status_message("* * * End output_keyvaluepairoflonglong * * *") + +def output_array_of_keyvaluepairoflonglong(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['KeyValuePairOflonglong']: + output_keyvaluepairoflonglong(data_object) + def output_keyvaluepairofstringstring(data_object): if data_object is None: return @@ -1716,6 +2189,30 @@ def output_array_of_manualcpcbiddingscheme(data_objects): for data_object in data_objects['ManualCpcBiddingScheme']: output_manualcpcbiddingscheme(data_object) +def output_manualcpmbiddingscheme(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_manualcpmbiddingscheme * * *") + output_status_message("* * * End output_manualcpmbiddingscheme * * *") + +def output_array_of_manualcpmbiddingscheme(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['ManualCpmBiddingScheme']: + output_manualcpmbiddingscheme(data_object) + +def output_manualcpvbiddingscheme(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_manualcpvbiddingscheme * * *") + output_status_message("* * * End output_manualcpvbiddingscheme * * *") + +def output_array_of_manualcpvbiddingscheme(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['ManualCpvBiddingScheme']: + output_manualcpvbiddingscheme(data_object) + def output_maxclicksbiddingscheme(data_object): if data_object is None: return @@ -1744,6 +2241,19 @@ def output_array_of_maxconversionsbiddingscheme(data_objects): for data_object in data_objects['MaxConversionsBiddingScheme']: output_maxconversionsbiddingscheme(data_object) +def output_maxconversionvaluebiddingscheme(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_maxconversionvaluebiddingscheme * * *") + output_status_message("TargetRoas: {0}".format(data_object.TargetRoas)) + output_status_message("* * * End output_maxconversionvaluebiddingscheme * * *") + +def output_array_of_maxconversionvaluebiddingscheme(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['MaxConversionValueBiddingScheme']: + output_maxconversionvaluebiddingscheme(data_object) + def output_maxroasbiddingscheme(data_object): if data_object is None: return @@ -1890,6 +2400,20 @@ def output_array_of_negativekeywordlist(data_objects): for data_object in data_objects['NegativeKeywordList']: output_negativekeywordlist(data_object) +def output_negativesite(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_negativesite * * *") + output_status_message("Id: {0}".format(data_object.Id)) + output_status_message("Url: {0}".format(data_object.Url)) + output_status_message("* * * End output_negativesite * * *") + +def output_array_of_negativesite(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['NegativeSite']: + output_negativesite(data_object) + def output_offlineconversion(data_object): if data_object is None: return @@ -1898,6 +2422,8 @@ def output_offlineconversion(data_object): output_status_message("ConversionName: {0}".format(data_object.ConversionName)) output_status_message("ConversionTime: {0}".format(data_object.ConversionTime)) output_status_message("ConversionValue: {0}".format(data_object.ConversionValue)) + output_status_message("ExternalAttributionCredit: {0}".format(data_object.ExternalAttributionCredit)) + output_status_message("ExternalAttributionModel: {0}".format(data_object.ExternalAttributionModel)) output_status_message("MicrosoftClickId: {0}".format(data_object.MicrosoftClickId)) output_status_message("* * * End output_offlineconversion * * *") @@ -1907,10 +2433,30 @@ def output_array_of_offlineconversion(data_objects): for data_object in data_objects['OfflineConversion']: output_offlineconversion(data_object) +def output_offlineconversionadjustment(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_offlineconversionadjustment * * *") + output_status_message("AdjustmentCurrencyCode: {0}".format(data_object.AdjustmentCurrencyCode)) + output_status_message("AdjustmentTime: {0}".format(data_object.AdjustmentTime)) + output_status_message("AdjustmentType: {0}".format(data_object.AdjustmentType)) + output_status_message("AdjustmentValue: {0}".format(data_object.AdjustmentValue)) + output_status_message("ConversionName: {0}".format(data_object.ConversionName)) + output_status_message("ConversionTime: {0}".format(data_object.ConversionTime)) + output_status_message("MicrosoftClickId: {0}".format(data_object.MicrosoftClickId)) + output_status_message("* * * End output_offlineconversionadjustment * * *") + +def output_array_of_offlineconversionadjustment(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['OfflineConversionAdjustment']: + output_offlineconversionadjustment(data_object) + def output_offlineconversiongoal(data_object): if data_object is None: return output_status_message("* * * Begin output_offlineconversiongoal * * *") + output_status_message("IsExternallyAttributed: {0}".format(data_object.IsExternallyAttributed)) output_status_message("* * * End output_offlineconversiongoal * * *") def output_array_of_offlineconversiongoal(data_objects): @@ -1952,6 +2498,7 @@ def output_pagevisitorsrule(data_object): if data_object is None: return output_status_message("* * * Begin output_pagevisitorsrule * * *") + output_status_message("NormalForm: {0}".format(data_object.NormalForm)) output_status_message("RuleItemGroups:") output_array_of_ruleitemgroup(data_object.RuleItemGroups) output_status_message("* * * End output_pagevisitorsrule * * *") @@ -2008,6 +2555,18 @@ def output_array_of_paging(data_objects): for data_object in data_objects['Paging']: output_paging(data_object) +def output_placementexclusionlist(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_placementexclusionlist * * *") + output_status_message("* * * End output_placementexclusionlist * * *") + +def output_array_of_placementexclusionlist(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['PlacementExclusionList']: + output_placementexclusionlist(data_object) + def output_priceadextension(data_object): if data_object is None: return @@ -2137,6 +2696,41 @@ def output_array_of_profilecriterion(data_objects): for data_object in data_objects['ProfileCriterion']: output_profilecriterion(data_object) +def output_promotionadextension(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_promotionadextension * * *") + output_status_message("CurrencyCode: {0}".format(data_object.CurrencyCode)) + output_status_message("DiscountModifier: {0}".format(data_object.DiscountModifier)) + output_status_message("FinalAppUrls:") + output_array_of_appurl(data_object.FinalAppUrls) + output_status_message("FinalMobileUrls:") + output_array_of_string(data_object.FinalMobileUrls) + output_status_message("FinalUrlSuffix: {0}".format(data_object.FinalUrlSuffix)) + output_status_message("FinalUrls:") + output_array_of_string(data_object.FinalUrls) + output_status_message("Language: {0}".format(data_object.Language)) + output_status_message("MoneyAmountOff: {0}".format(data_object.MoneyAmountOff)) + output_status_message("OrdersOverAmount: {0}".format(data_object.OrdersOverAmount)) + output_status_message("PercentOff: {0}".format(data_object.PercentOff)) + output_status_message("PromotionCode: {0}".format(data_object.PromotionCode)) + output_status_message("PromotionEndDate:") + output_date(data_object.PromotionEndDate) + output_status_message("PromotionItem: {0}".format(data_object.PromotionItem)) + output_status_message("PromotionOccasion: {0}".format(data_object.PromotionOccasion)) + output_status_message("PromotionStartDate:") + output_date(data_object.PromotionStartDate) + output_status_message("TrackingUrlTemplate: {0}".format(data_object.TrackingUrlTemplate)) + output_status_message("UrlCustomParameters:") + output_customparameters(data_object.UrlCustomParameters) + output_status_message("* * * End output_promotionadextension * * *") + +def output_array_of_promotionadextension(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['PromotionAdExtension']: + output_promotionadextension(data_object) + def output_radiuscriterion(data_object): if data_object is None: return @@ -2196,6 +2790,7 @@ def output_responsivead(data_object): output_status_message("* * * Begin output_responsivead * * *") output_status_message("BusinessName: {0}".format(data_object.BusinessName)) output_status_message("CallToAction: {0}".format(data_object.CallToAction)) + output_status_message("CallToActionLanguage: {0}".format(data_object.CallToActionLanguage)) output_status_message("Descriptions:") output_array_of_assetlink(data_object.Descriptions) output_status_message("Headline: {0}".format(data_object.Headline)) @@ -2203,10 +2798,16 @@ def output_responsivead(data_object): output_array_of_assetlink(data_object.Headlines) output_status_message("Images:") output_array_of_assetlink(data_object.Images) + output_status_message("ImpressionTrackingUrls:") + output_array_of_string(data_object.ImpressionTrackingUrls) output_status_message("LongHeadline:") output_assetlink(data_object.LongHeadline) output_status_message("LongHeadlineString: {0}".format(data_object.LongHeadlineString)) + output_status_message("LongHeadlines:") + output_array_of_assetlink(data_object.LongHeadlines) output_status_message("Text: {0}".format(data_object.Text)) + output_status_message("Videos:") + output_array_of_assetlink(data_object.Videos) output_status_message("* * * End output_responsivead * * *") def output_array_of_responsivead(data_objects): @@ -2305,6 +2906,8 @@ def output_setting(data_object): output_status_message("Type: {0}".format(data_object.Type)) if data_object.Type == 'CoOpSetting': output_coopsetting(data_object) + if data_object.Type == 'DynamicFeedSetting': + output_dynamicfeedsetting(data_object) if data_object.Type == 'DynamicSearchAdsSetting': output_dynamicsearchadssetting(data_object) if data_object.Type == 'ShoppingSetting': @@ -2345,6 +2948,7 @@ def output_sharedentityassociation(data_object): output_status_message("* * * Begin output_sharedentityassociation * * *") output_status_message("EntityId: {0}".format(data_object.EntityId)) output_status_message("EntityType: {0}".format(data_object.EntityType)) + output_status_message("SharedEntityCustomerId: {0}".format(data_object.SharedEntityCustomerId)) output_status_message("SharedEntityId: {0}".format(data_object.SharedEntityId)) output_status_message("SharedEntityType: {0}".format(data_object.SharedEntityType)) output_status_message("* * * End output_sharedentityassociation * * *") @@ -2362,6 +2966,8 @@ def output_sharedlist(data_object): output_status_message("ItemCount: {0}".format(data_object.ItemCount)) if data_object.Type == 'NegativeKeywordList': output_negativekeywordlist(data_object) + if data_object.Type == 'PlacementExclusionList': + output_placementexclusionlist(data_object) output_status_message("* * * End output_sharedlist * * *") def output_array_of_sharedlist(data_objects): @@ -2379,6 +2985,8 @@ def output_sharedlistitem(data_object): output_status_message("Type: {0}".format(data_object.Type)) if data_object.Type == 'NegativeKeyword': output_negativekeyword(data_object) + if data_object.Type == 'NegativeSite': + output_negativesite(data_object) output_status_message("* * * End output_sharedlistitem * * *") def output_array_of_sharedlistitem(data_objects): @@ -2442,6 +3050,19 @@ def output_array_of_sitelinkadextension(data_objects): for data_object in data_objects['SitelinkAdExtension']: output_sitelinkadextension(data_object) +def output_storecriterion(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_storecriterion * * *") + output_status_message("StoreId: {0}".format(data_object.StoreId)) + output_status_message("* * * End output_storecriterion * * *") + +def output_array_of_storecriterion(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['StoreCriterion']: + output_storecriterion(data_object) + def output_stringruleitem(data_object): if data_object is None: return @@ -2487,6 +3108,22 @@ def output_array_of_targetcpabiddingscheme(data_objects): for data_object in data_objects['TargetCpaBiddingScheme']: output_targetcpabiddingscheme(data_object) +def output_targetimpressionsharebiddingscheme(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_targetimpressionsharebiddingscheme * * *") + output_status_message("MaxCpc:") + output_bid(data_object.MaxCpc) + output_status_message("TargetAdPosition: {0}".format(data_object.TargetAdPosition)) + output_status_message("TargetImpressionShare: {0}".format(data_object.TargetImpressionShare)) + output_status_message("* * * End output_targetimpressionsharebiddingscheme * * *") + +def output_array_of_targetimpressionsharebiddingscheme(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['TargetImpressionShareBiddingScheme']: + output_targetimpressionsharebiddingscheme(data_object) + def output_targetroasbiddingscheme(data_object): if data_object is None: return @@ -2593,6 +3230,73 @@ def output_array_of_urlgoal(data_objects): for data_object in data_objects['UrlGoal']: output_urlgoal(data_object) +def output_video(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_video * * *") + output_status_message("AspectRatio: {0}".format(data_object.AspectRatio)) + output_status_message("CreatedDateTimeInUTC: {0}".format(data_object.CreatedDateTimeInUTC)) + output_status_message("Description: {0}".format(data_object.Description)) + output_status_message("DurationInMilliseconds: {0}".format(data_object.DurationInMilliseconds)) + output_status_message("FailureCode: {0}".format(data_object.FailureCode)) + output_status_message("Id: {0}".format(data_object.Id)) + output_status_message("ModifiedDateTimeInUTC: {0}".format(data_object.ModifiedDateTimeInUTC)) + output_status_message("SourceUrl: {0}".format(data_object.SourceUrl)) + output_status_message("Status: {0}".format(data_object.Status)) + output_status_message("ThumbnailUrl: {0}".format(data_object.ThumbnailUrl)) + output_status_message("Url: {0}".format(data_object.Url)) + output_status_message("* * * End output_video * * *") + +def output_array_of_video(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['Video']: + output_video(data_object) + +def output_videoadextension(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_videoadextension * * *") + output_status_message("ActionText: {0}".format(data_object.ActionText)) + output_status_message("AlternativeText: {0}".format(data_object.AlternativeText)) + output_status_message("DisplayText: {0}".format(data_object.DisplayText)) + output_status_message("FinalAppUrls:") + output_array_of_appurl(data_object.FinalAppUrls) + output_status_message("FinalMobileUrls:") + output_array_of_string(data_object.FinalMobileUrls) + output_status_message("FinalUrlSuffix: {0}".format(data_object.FinalUrlSuffix)) + output_status_message("FinalUrls:") + output_array_of_string(data_object.FinalUrls) + output_status_message("Name: {0}".format(data_object.Name)) + output_status_message("ThumbnailId: {0}".format(data_object.ThumbnailId)) + output_status_message("ThumbnailUrl: {0}".format(data_object.ThumbnailUrl)) + output_status_message("TrackingUrlTemplate: {0}".format(data_object.TrackingUrlTemplate)) + output_status_message("UrlCustomParameters:") + output_customparameters(data_object.UrlCustomParameters) + output_status_message("VideoId: {0}".format(data_object.VideoId)) + output_status_message("* * * End output_videoadextension * * *") + +def output_array_of_videoadextension(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['VideoAdExtension']: + output_videoadextension(data_object) + +def output_videoasset(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_videoasset * * *") + output_status_message("SubType: {0}".format(data_object.SubType)) + output_status_message("ThumbnailImage:") + output_imageasset(data_object.ThumbnailImage) + output_status_message("* * * End output_videoasset * * *") + +def output_array_of_videoasset(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['VideoAsset']: + output_videoasset(data_object) + def output_webpage(data_object): if data_object is None: return @@ -2684,6 +3388,18 @@ def output_array_of_calltoaction(value_sets): for value_set in value_sets['CallToAction']: output_calltoaction(value_set) +def output_languagename(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_languagename(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of LanguageName:\n") + for value_set in value_sets['LanguageName']: + output_languagename(value_set) + def output_assetlinkeditorialstatus(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: @@ -2768,6 +3484,18 @@ def output_array_of_bidoption(value_sets): for value_set in value_sets['BidOption']: output_bidoption(value_set) +def output_campaignadditionalfield(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_campaignadditionalfield(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of CampaignAdditionalField:\n") + for value_set in value_sets['CampaignAdditionalField']: + output_campaignadditionalfield(value_set) + def output_adrotationtype(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: @@ -2816,6 +3544,30 @@ def output_array_of_adgroupstatus(value_sets): for value_set in value_sets['AdGroupStatus']: output_adgroupstatus(value_set) +def output_adgroupadditionalfield(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_adgroupadditionalfield(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of AdGroupAdditionalField:\n") + for value_set in value_sets['AdGroupAdditionalField']: + output_adgroupadditionalfield(value_set) + +def output_adadditionalfield(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_adadditionalfield(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of AdAdditionalField:\n") + for value_set in value_sets['AdAdditionalField']: + output_adadditionalfield(value_set) + def output_keywordeditorialstatus(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: @@ -2996,6 +3748,42 @@ def output_array_of_priceunit(value_sets): for value_set in value_sets['PriceUnit']: output_priceunit(value_set) +def output_promotiondiscountmodifier(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_promotiondiscountmodifier(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of PromotionDiscountModifier:\n") + for value_set in value_sets['PromotionDiscountModifier']: + output_promotiondiscountmodifier(value_set) + +def output_promotionoccasion(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_promotionoccasion(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of PromotionOccasion:\n") + for value_set in value_sets['PromotionOccasion']: + output_promotionoccasion(value_set) + +def output_adextensionheadertype(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_adextensionheadertype(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of AdExtensionHeaderType:\n") + for value_set in value_sets['AdExtensionHeaderType']: + output_adextensionheadertype(value_set) + def output_adextensionstypefilter(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: @@ -3068,6 +3856,18 @@ def output_array_of_adgroupcriteriontype(value_sets): for value_set in value_sets['AdGroupCriterionType']: output_adgroupcriteriontype(value_set) +def output_criterionadditionalfield(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_criterionadditionalfield(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of CriterionAdditionalField:\n") + for value_set in value_sets['CriterionAdditionalField']: + output_criterionadditionalfield(value_set) + def output_productpartitiontype(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: @@ -3200,6 +4000,18 @@ def output_array_of_itemaction(value_sets): for value_set in value_sets['ItemAction']: output_itemaction(value_set) +def output_bmcstoreadditionalfield(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_bmcstoreadditionalfield(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of BMCStoreAdditionalField:\n") + for value_set in value_sets['BMCStoreAdditionalField']: + output_bmcstoreadditionalfield(value_set) + def output_bmcstoresubtype(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: @@ -3212,6 +4024,18 @@ def output_array_of_bmcstoresubtype(value_sets): for value_set in value_sets['BMCStoreSubType']: output_bmcstoresubtype(value_set) +def output_entityscope(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_entityscope(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of EntityScope:\n") + for value_set in value_sets['EntityScope']: + output_entityscope(value_set) + def output_campaigncriterionstatus(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: @@ -3236,17 +4060,17 @@ def output_array_of_campaigncriteriontype(value_sets): for value_set in value_sets['CampaignCriterionType']: output_campaigncriteriontype(value_set) -def output_entityscope(value_set): +def output_normalform(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: output_status_message(value) -def output_array_of_entityscope(value_sets): +def output_array_of_normalform(value_sets): if value_sets is None or len(value_sets) == 0: return - output_status_message("Array Of EntityScope:\n") - for value_set in value_sets['EntityScope']: - output_entityscope(value_set) + output_status_message("Array Of NormalForm:\n") + for value_set in value_sets['NormalForm']: + output_normalform(value_set) def output_stringoperator(value_set): output_status_message("Values in {0}".format(value_set.Type)) @@ -3284,6 +4108,30 @@ def output_array_of_productaudiencetype(value_sets): for value_set in value_sets['ProductAudienceType']: output_productaudiencetype(value_set) +def output_logicaloperator(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_logicaloperator(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of LogicalOperator:\n") + for value_set in value_sets['LogicalOperator']: + output_logicaloperator(value_set) + +def output_audienceadditionalfield(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_audienceadditionalfield(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of AudienceAdditionalField:\n") + for value_set in value_sets['AudienceAdditionalField']: + output_audienceadditionalfield(value_set) + def output_uettagtrackingstatus(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: @@ -3332,6 +4180,18 @@ def output_array_of_conversiongoalcounttype(value_sets): for value_set in value_sets['ConversionGoalCountType']: output_conversiongoalcounttype(value_set) +def output_conversiongoalcategory(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_conversiongoalcategory(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of ConversionGoalCategory:\n") + for value_set in value_sets['ConversionGoalCategory']: + output_conversiongoalcategory(value_set) + def output_conversiongoalrevenuetype(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: @@ -3392,6 +4252,30 @@ def output_array_of_valueoperator(value_sets): for value_set in value_sets['ValueOperator']: output_valueoperator(value_set) +def output_importadditionalfield(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_importadditionalfield(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of ImportAdditionalField:\n") + for value_set in value_sets['ImportAdditionalField']: + output_importadditionalfield(value_set) + +def output_importentitytype(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_importentitytype(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of ImportEntityType:\n") + for value_set in value_sets['ImportEntityType']: + output_importentitytype(value_set) + def output_array_of_long(items): if items is None or items['long'] is None: return diff --git a/examples/v13/conversion_goals.py b/examples/v13/conversion_goals.py index 967ee793..b65bf30b 100644 --- a/examples/v13/conversion_goals.py +++ b/examples/v13/conversion_goals.py @@ -76,6 +76,7 @@ def main(authorization_data): conversion_goals.ConversionGoal.append(duration_goal) event_goal=set_elements_to_none(campaign_service.factory.create('EventGoal')) + event_goal.GoalCategory = "Purchase" # The type of user interaction you want to track. event_goal.ActionExpression = "play" event_goal.ActionOperator = 'Contains' @@ -118,6 +119,7 @@ def main(authorization_data): conversion_goals.ConversionGoal.append(pages_viewed_per_visit_goal) url_goal=set_elements_to_none(campaign_service.factory.create('UrlGoal')) + url_goal.GoalCategory = "Purchase" url_goal.ConversionWindowInMinutes = 30 url_goal.CountType = 'All' url_goal.Name = "My Url Goal" diff --git a/examples/v13/customer_signup.py b/examples/v13/customer_signup.py index 368b8238..cdfb3428 100644 --- a/examples/v13/customer_signup.py +++ b/examples/v13/customer_signup.py @@ -8,8 +8,7 @@ def main(authorization_data): try: output_status_message("-----\nGetUser:") get_user_response=customer_service.GetUser( - UserId=None, - IncludeLinkedAccountIds=True + UserId=None ) user = get_user_response.User customer_roles=get_user_response.CustomerRoles diff --git a/examples/v13/customerbilling_example_helper.py b/examples/v13/customerbilling_example_helper.py index fa85cbc1..0b7c737c 100644 --- a/examples/v13/customerbilling_example_helper.py +++ b/examples/v13/customerbilling_example_helper.py @@ -126,6 +126,54 @@ def output_array_of_billingdocumentinfo(data_objects): for data_object in data_objects['BillingDocumentInfo']: output_billingdocumentinfo(data_object) +def output_coupon(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_coupon * * *") + output_status_message("CouponCode: {0}".format(data_object.CouponCode)) + output_status_message("ClassName: {0}".format(data_object.ClassName)) + output_status_message("CouponType: {0}".format(data_object.CouponType)) + output_status_message("Amount: {0}".format(data_object.Amount)) + output_status_message("SpendThreshold: {0}".format(data_object.SpendThreshold)) + output_status_message("CurrencyCode: {0}".format(data_object.CurrencyCode)) + output_status_message("PercentOff: {0}".format(data_object.PercentOff)) + output_status_message("ActiveDuration: {0}".format(data_object.ActiveDuration)) + output_status_message("ExpirationDate: {0}".format(data_object.ExpirationDate)) + output_status_message("StartDate: {0}".format(data_object.StartDate)) + output_status_message("EndDate: {0}".format(data_object.EndDate)) + output_status_message("SendToEmail: {0}".format(data_object.SendToEmail)) + output_status_message("SendToDate: {0}".format(data_object.SendToDate)) + output_status_message("IsRedeemed: {0}".format(data_object.IsRedeemed)) + output_status_message("RedemptionInfo:") + output_couponredemption(data_object.RedemptionInfo) + output_status_message("* * * End output_coupon * * *") + +def output_array_of_coupon(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['Coupon']: + output_coupon(data_object) + +def output_couponredemption(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_couponredemption * * *") + output_status_message("AccountId: {0}".format(data_object.AccountId)) + output_status_message("AccountNumber: {0}".format(data_object.AccountNumber)) + output_status_message("SpendToThreshold: {0}".format(data_object.SpendToThreshold)) + output_status_message("Balance: {0}".format(data_object.Balance)) + output_status_message("CurrencyCode: {0}".format(data_object.CurrencyCode)) + output_status_message("RedemptionDate: {0}".format(data_object.RedemptionDate)) + output_status_message("ExpirationDate: {0}".format(data_object.ExpirationDate)) + output_status_message("ActivationDate: {0}".format(data_object.ActivationDate)) + output_status_message("* * * End output_couponredemption * * *") + +def output_array_of_couponredemption(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['CouponRedemption']: + output_couponredemption(data_object) + def output_insertionorder(data_object): if data_object is None: return diff --git a/examples/v13/customermanagement_example_helper.py b/examples/v13/customermanagement_example_helper.py index c4826c9b..3bd6d7fa 100644 --- a/examples/v13/customermanagement_example_helper.py +++ b/examples/v13/customermanagement_example_helper.py @@ -26,6 +26,7 @@ def output_accountinfowithcustomerdata(data_object): output_status_message("AccountNumber: {0}".format(data_object.AccountNumber)) output_status_message("AccountLifeCycleStatus: {0}".format(data_object.AccountLifeCycleStatus)) output_status_message("PauseReason: {0}".format(data_object.PauseReason)) + output_status_message("AccountMode: {0}".format(data_object.AccountMode)) output_status_message("* * * End output_accountinfowithcustomerdata * * *") def output_array_of_accountinfowithcustomerdata(data_objects): @@ -34,6 +35,22 @@ def output_array_of_accountinfowithcustomerdata(data_objects): for data_object in data_objects['AccountInfoWithCustomerData']: output_accountinfowithcustomerdata(data_object) +def output_accounttaxcertificate(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_accounttaxcertificate * * *") + output_status_message("TaxCertificateBlobContainerName: {0}".format(data_object.TaxCertificateBlobContainerName)) + output_status_message("TaxCertificates:") + output_array_of_keyvaluepairofstringbase64binary(data_object.TaxCertificates) + output_status_message("Status: {0}".format(data_object.Status)) + output_status_message("* * * End output_accounttaxcertificate * * *") + +def output_array_of_accounttaxcertificate(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['AccountTaxCertificate']: + output_accounttaxcertificate(data_object) + def output_adapierror(data_object): if data_object is None: return @@ -121,6 +138,9 @@ def output_advertiseraccount(data_object): output_address(data_object.BusinessAddress) output_status_message("AutoTagType: {0}".format(data_object.AutoTagType)) output_status_message("SoldToPaymentInstrumentId: {0}".format(data_object.SoldToPaymentInstrumentId)) + output_status_message("TaxCertificate:") + output_accounttaxcertificate(data_object.TaxCertificate) + output_status_message("AccountMode: {0}".format(data_object.AccountMode)) output_status_message("* * * End output_advertiseraccount * * *") def output_array_of_advertiseraccount(data_objects): @@ -293,6 +313,20 @@ def output_array_of_daterange(data_objects): for data_object in data_objects['DateRange']: output_daterange(data_object) +def output_keyvaluepairofstringbase64binary(data_object): + if data_object is None: + return + output_status_message("* * * Begin output_keyvaluepairofstringbase64binary * * *") + output_status_message("key: {0}".format(data_object.key)) + output_status_message("value: {0}".format(data_object.value)) + output_status_message("* * * End output_keyvaluepairofstringbase64binary * * *") + +def output_array_of_keyvaluepairofstringbase64binary(data_objects): + if data_objects is None or len(data_objects) == 0: + return + for data_object in data_objects['KeyValuePairOfstringbase64Binary']: + output_keyvaluepairofstringbase64binary(data_object) + def output_keyvaluepairofstringstring(data_object): if data_object is None: return @@ -530,6 +564,18 @@ def output_array_of_autotagtype(value_sets): for value_set in value_sets['AutoTagType']: output_autotagtype(value_set) +def output_taxcertificatestatus(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_taxcertificatestatus(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of TaxCertificateStatus:\n") + for value_set in value_sets['TaxCertificateStatus']: + output_taxcertificatestatus(value_set) + def output_customerfinancialstatus(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: @@ -578,29 +624,41 @@ def output_array_of_customerlifecyclestatus(value_sets): for value_set in value_sets['CustomerLifeCycleStatus']: output_customerlifecyclestatus(value_set) -def output_emailformat(value_set): +def output_lcid(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: output_status_message(value) -def output_array_of_emailformat(value_sets): +def output_array_of_lcid(value_sets): if value_sets is None or len(value_sets) == 0: return - output_status_message("Array Of EmailFormat:\n") - for value_set in value_sets['EmailFormat']: - output_emailformat(value_set) + output_status_message("Array Of LCID:\n") + for value_set in value_sets['LCID']: + output_lcid(value_set) -def output_lcid(value_set): +def output_accountadditionalfield(value_set): output_status_message("Values in {0}".format(value_set.Type)) for value in value_set['string']: output_status_message(value) -def output_array_of_lcid(value_sets): +def output_array_of_accountadditionalfield(value_sets): if value_sets is None or len(value_sets) == 0: return - output_status_message("Array Of LCID:\n") - for value_set in value_sets['LCID']: - output_lcid(value_set) + output_status_message("Array Of AccountAdditionalField:\n") + for value_set in value_sets['AccountAdditionalField']: + output_accountadditionalfield(value_set) + +def output_emailformat(value_set): + output_status_message("Values in {0}".format(value_set.Type)) + for value in value_set['string']: + output_status_message(value) + +def output_array_of_emailformat(value_sets): + if value_sets is None or len(value_sets) == 0: + return + output_status_message("Array Of EmailFormat:\n") + for value_set in value_sets['EmailFormat']: + output_emailformat(value_set) def output_secretquestion(value_set): output_status_message("Values in {0}".format(value_set.Type)) diff --git a/examples/v13/dynamic_search_ads.py b/examples/v13/dynamic_search_ads.py index c7c36229..20aabd3f 100644 --- a/examples/v13/dynamic_search_ads.py +++ b/examples/v13/dynamic_search_ads.py @@ -98,9 +98,8 @@ def get_campaign_webpage_negative_url_example(campaign_id): def main(authorization_data): try: - # To get started with dynamic search ads, first you'll need to add a new Campaign - # with its type set to DynamicSearchAds. When you create the campaign, you'll need to - # include a DynamicSearchAdsSetting that specifies the target web site domain and language. + # To get started with dynamic search ads, first you'll need to add a new Search campaign + # Include a DynamicSearchAdsSetting that specifies the target website domain and language. campaigns=campaign_service.factory.create('ArrayOfCampaign') campaign=set_elements_to_none(campaign_service.factory.create('Campaign')) @@ -133,10 +132,11 @@ def main(authorization_data): output_status_message("PartialErrors:") output_array_of_batcherror(add_campaigns_response.PartialErrors) - # Create a new ad group within the dynamic search ads campaign. + # Create a new ad group with type set to "SearchDynamic" ad_groups=campaign_service.factory.create('ArrayOfAdGroup') ad_group=set_elements_to_none(campaign_service.factory.create('AdGroup')) + ad_group.AdGroupType='SearchDynamic' ad_group.Name="Women's Red Shoe Sale" end_date=campaign_service.factory.create('Date') end_date.Day=31 diff --git a/examples/v13/geographical_locations.py b/examples/v13/geographical_locations.py index 45f78249..d165b521 100644 --- a/examples/v13/geographical_locations.py +++ b/examples/v13/geographical_locations.py @@ -1,4 +1,6 @@ -import urllib2 +import urllib3 as urllib +from urllib.error import URLError +from urllib.request import urlopen, Request from auth_helper import * from campaignmanagement_example_helper import * @@ -29,14 +31,14 @@ def main(authorization_data): output_status_message("FileUrlExpiryTimeUtc: {0}".format(get_geo_locations_file_url_response.FileUrlExpiryTimeUtc)) output_status_message("LastModifiedTimeUtc: {0}".format(get_geo_locations_file_url_response.LastModifiedTimeUtc)) - request=urllib2.Request(get_geo_locations_file_url_response.FileUrl) - response=urllib2.urlopen(request) + request=Request(get_geo_locations_file_url_response.FileUrl) + response=urlopen(request) if response.getcode() == 200: download_file(response) output_status_message("Downloaded the geographical locations to {0}.".format(LOCAL_FILE)) - except urllib2.URLError as ex: + except URLError as ex: if hasattr(ex, 'code'): output_status_message("Error code: {0}".format(ex.code)) elif hasattr(ex, 'reason'): diff --git a/examples/v13/image_media.py b/examples/v13/image_media.py index 9c7fc327..1431def4 100644 --- a/examples/v13/image_media.py +++ b/examples/v13/image_media.py @@ -91,7 +91,7 @@ def get_image_media( def get_bmp_base64_string(image_file_name): image = open(image_file_name, 'rb') image_bytes = image.read() - base64_string = base64.encodestring(image_bytes) + base64_string = base64.b64encode(image_bytes) return base64_string # Main execution diff --git a/examples/v13/invite_user.py b/examples/v13/invite_user.py index 15fdb30a..ad4b2586 100644 --- a/examples/v13/invite_user.py +++ b/examples/v13/invite_user.py @@ -101,8 +101,7 @@ def main(authorization_data): for info in users_info['UserInfo']: output_status_message("-----\nGetUser:") get_user_response=customer_service.GetUser( - UserId=info.Id, - IncludeLinkedAccountIds=True) + UserId=info.Id) user = get_user_response.User customer_roles=get_user_response.CustomerRoles output_status_message("User:") diff --git a/examples/v13/offline_conversions.py b/examples/v13/offline_conversions.py index a4910b8e..40f03991 100644 --- a/examples/v13/offline_conversions.py +++ b/examples/v13/offline_conversions.py @@ -15,6 +15,7 @@ def main(authorization_data): conversion_goals=campaign_service.factory.create('ArrayOfConversionGoal') offline_conversion_goal=set_elements_to_none(campaign_service.factory.create('OfflineConversionGoal')) + offline_conversion_goal.GoalCategory = "Purchase" # Determines how long after a click that you want to count offline conversions. offline_conversion_goal.ConversionWindowInMinutes = 43200 # If the count type is 'Unique' then only the first offline conversion will be counted. diff --git a/examples/v13/report_requests.py b/examples/v13/report_requests.py index 6347468f..08c39899 100644 --- a/examples/v13/report_requests.py +++ b/examples/v13/report_requests.py @@ -216,6 +216,8 @@ def get_report_request(account_id): # You can either use a custom date range or predefined time. time.PredefinedTime='Yesterday' time.ReportTimeZone='PacificTimeUSCanadaTijuana' + time.CustomDateRangeStart = None + time.CustomDateRangeEnd = None return_only_complete_data=False #BudgetSummaryReportRequest does not contain a definition for Aggregation. diff --git a/examples/v13/reporting_example_helper.py b/examples/v13/reporting_example_helper.py index 84140486..1bd85f0f 100644 --- a/examples/v13/reporting_example_helper.py +++ b/examples/v13/reporting_example_helper.py @@ -1310,6 +1310,7 @@ def output_reportrequest(data_object): output_status_message("ExcludeReportFooter: {0}".format(data_object.ExcludeReportFooter)) output_status_message("ExcludeReportHeader: {0}".format(data_object.ExcludeReportHeader)) output_status_message("Format: {0}".format(data_object.Format)) + output_status_message("FormatVersion: {0}".format(data_object.FormatVersion)) output_status_message("ReportName: {0}".format(data_object.ReportName)) output_status_message("ReturnOnlyCompleteData: {0}".format(data_object.ReturnOnlyCompleteData)) if data_object.Type == 'AccountPerformanceReportRequest': diff --git a/examples/v13/responsive_ad_recommendation.py b/examples/v13/responsive_ad_recommendation.py new file mode 100644 index 00000000..aaeda249 --- /dev/null +++ b/examples/v13/responsive_ad_recommendation.py @@ -0,0 +1,198 @@ +import base64 + +from auth_helper import * +from campaignmanagement_example_helper import * + +# You must provide credentials in auth_helper.py. + +def main(authorization_data): + + try: + # To run this example you'll need to provide a valid Ad Final URL + ad_final_url = "https://contoso.com" + # Set false to disable cleanup of created entities at the end + do_cleanup = True + + final_urls = campaign_service.factory.create('ns3:ArrayOfstring') + final_urls.string.append(ad_final_url) + + output_status_message("-----\nCreateResponsiveAdRecommendation:"); + output_status_message(f"-----\nGetting ad recommendation for URL {ad_final_url} ..."); + responsive_ad_recommendation_response = campaign_service.CreateResponsiveAdRecommendation( + FinalUrls=final_urls + ) + responsive_ad = responsive_ad_recommendation_response.ResponsiveAd + image_suggestions = responsive_ad_recommendation_response.ImageSuggestions['AdRecommendationImageSuggestion'] + + # Select a few images from the suggested list. This example picks first 5 images + selected_images = image_suggestions[:5] + + # Add selected images to your media library + save_images(selected_images) + + images = campaign_service.factory.create('ArrayOfAssetLink') + images.AssetLink = [obj.AssetLink for obj in selected_images] + responsive_ad.Images = images + + responsive_ad.BusinessName = "Contoso" + #responsive_ad.CallToAction = 'ShopNow' + responsive_ad.CallToActionLanguage = 'English' + + # Create an Audience campaign with one ad group and a responsive ad + campaigns = campaign_service.factory.create('ArrayOfCampaign') + campaign = set_elements_to_none(campaign_service.factory.create('Campaign')) + campaign.BudgetType = 'DailyBudgetStandard' + # CampaignType must be set for Audience campaigns + campaign.CampaignType = ['Audience'] + campaign.DailyBudget = 50.00 + languages = campaign_service.factory.create('ns3:ArrayOfstring') + languages.string.append('All') + campaign.Languages = languages + campaign.Name = "Ad recommendation test " + str(datetime.now()) + campaign.TimeZone = 'PacificTimeUSCanadaTijuana' + campaigns.Campaign.append(campaign) + + output_status_message("-----\nAddCampaigns:") + add_campaigns_response = campaign_service.AddCampaigns( + AccountId=authorization_data.account_id, + Campaigns=campaigns + ) + campaign_ids = { + 'long': add_campaigns_response.CampaignIds['long'] if add_campaigns_response.CampaignIds['long'] else None + } + output_status_message("CampaignIds:") + output_array_of_long(campaign_ids) + output_status_message("PartialErrors:") + output_array_of_batcherror(add_campaigns_response.PartialErrors) + + # Add an ad group within the campaign. + ad_groups = campaign_service.factory.create('ArrayOfAdGroup') + ad_group = set_elements_to_none(campaign_service.factory.create('AdGroup')) + ad_group.Name = "Holiday Sale" + ad_group.StartDate = None + end_date = campaign_service.factory.create('Date') + end_date.Day = 31 + end_date.Month = 12 + current_time = gmtime() + end_date.Year = current_time.tm_year + ad_group.EndDate = end_date + cpc_bid = campaign_service.factory.create('Bid') + cpc_bid.Amount = 0.09 + ad_group.CpcBid = cpc_bid + # Network cannot be set for ad groups in Audience campaigns + ad_group.Network = None + ad_groups.AdGroup.append(ad_group) + + output_status_message("-----\nAddAdGroups:") + add_ad_groups_response = campaign_service.AddAdGroups( + CampaignId=campaign_ids['long'][0], + AdGroups=ad_groups, + ReturnInheritedBidStrategyTypes=False + ) + ad_group_ids = { + 'long': add_ad_groups_response.AdGroupIds['long'] if add_ad_groups_response.AdGroupIds['long'] else None + } + output_status_message("AdGroupIds:") + output_array_of_long(ad_group_ids) + output_status_message("PartialErrors:") + output_array_of_batcherror(add_ad_groups_response.PartialErrors) + + # Add a responsive ad within the ad group + ads = campaign_service.factory.create('ArrayOfAd') + ads.Ad.append(responsive_ad) + + output_status_message("-----\nAddAds:") + add_ads_response = campaign_service.AddAds( + AdGroupId=ad_group_ids['long'][0], + Ads=ads + ) + ad_ids = { + 'long': add_ads_response.AdIds['long'] if add_ads_response.AdIds['long'] else None + } + output_status_message("AdIds:") + output_array_of_long(ad_ids) + output_status_message("PartialErrors:") + output_array_of_batcherror(add_ads_response.PartialErrors) + + output_status_message(f"-----\nCreated campaign: + {campaign.Name}") + + if not do_cleanup: + return + else: + # Delete the account's media + output_status_message("-----\nDeleteMedia:") + media_ids = campaign_service.factory.create('ns3:ArrayOflong') + media_ids['long'] = [obj.Asset.Id for obj in responsive_ad.Images.AssetLink] + delete_media_response = campaign_service.DeleteMedia( + AccountId=authorization_data.account_id, + MediaIds=media_ids + ) + + for media_id in media_ids['long']: + output_status_message("Deleted Media Id {0}".format(media_id)) + + # Delete the campaign and everything it contains e.g., ad groups and ads + output_status_message("-----\nDeleteCampaigns:") + campaign_service.DeleteCampaigns( + AccountId=authorization_data.account_id, + CampaignIds=campaign_ids + ) + output_status_message("Deleted Campaign Id {0}".format(campaign_ids['long'][0])) + + + except WebFault as ex: + output_webfault_errors(ex) + except Exception as ex: + output_status_message(ex) + +def save_images(image_suggestions): + medias_to_add = campaign_service.factory.create('ArrayOfMedia') + for item in image_suggestions: + image = item.Image + image_bytes = download_bytes(item.ImageUrl) + image_base64 = base64.b64encode(image_bytes).decode('utf-8') + image.Data = image_base64 + medias_to_add.Media.append(image) + + media_ids = campaign_service.AddMedia( + AccountId=authorization_data.account_id, + Media=medias_to_add + ) + + for i in range(len(media_ids['long'])): + image_suggestions[i].AssetLink.Asset.Id = media_ids['long'][i] + +def download_bytes(url): + response = requests.get(url, stream=True) + response.raise_for_status() + + output_stream = bytearray() + + for chunk in response.iter_content(chunk_size=4096): + if chunk: + output_stream.extend(chunk) + + return bytes(output_stream) + +# Main execution +if __name__ == '__main__': + + print("Loading the web service client proxies...") + + authorization_data=AuthorizationData( + account_id=None, + customer_id=None, + developer_token=DEVELOPER_TOKEN, + authentication=None, + ) + + campaign_service=ServiceClient( + service='CampaignManagementService', + version=13, + authorization_data=authorization_data, + environment=ENVIRONMENT, + ) + + authenticate(authorization_data) + + main(authorization_data) diff --git a/generate_all.bat b/generate_all.bat new file mode 100644 index 00000000..5aec12d4 --- /dev/null +++ b/generate_all.bat @@ -0,0 +1,26 @@ +REM Campaign Mangement Service +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://campaign.api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/CampaignManagementService.svc?singleWsdl" -path "bingads\v13\proxies\sandbox\campaignmanagement_service.xml" +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://campaign.api.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/CampaignManagementService.svc?singleWsdl" -path "bingads\v13\proxies\production\campaignmanagement_service.xml" + +REM Bulk Service +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://bulk.api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/BulkService.svc?singleWsdl" -path "bingads\v13\proxies\sandbox\bulk_service.xml" +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://bulk.api.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/BulkService.svc?singleWsdl" -path "bingads\v13\proxies\production\bulk_service.xml" + +REM customerbilling Service +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://clientcenter.api.sandbox.bingads.microsoft.com/Api/Billing/v13/CustomerBillingService.svc?singleWsdl" -path "bingads\v13\proxies\sandbox\customerbilling_service.xml" +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://clientcenter.api.bingads.microsoft.com/Api/Billing/v13/CustomerBillingService.svc?singleWsdl" -path "bingads\v13\proxies\production\customerbilling_service.xml" + +REM customermanagement Service +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://clientcenter.api.sandbox.bingads.microsoft.com/Api/CustomerManagement/v13/CustomerManagementService.svc?singleWsdl" -path "bingads\v13\proxies\sandbox\customermanagement_service.xml" +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://clientcenter.api.bingads.microsoft.com/Api/CustomerManagement/v13/CustomerManagementService.svc?singleWsdl" -path "bingads\v13\proxies\production\customermanagement_service.xml" + +REM reporting Service +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://reporting.api.sandbox.bingads.microsoft.com/Api/Advertiser/Reporting/v13/ReportingService.svc?singleWsdl" -path "bingads\v13\proxies\sandbox\reporting_service.xml" +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://reporting.api.bingads.microsoft.com/Api/Advertiser/Reporting/v13/ReportingService.svc?singleWsdl" -path "bingads\v13\proxies\production\reporting_service.xml" + +REM adinsight Service +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://adinsight.api.sandbox.bingads.microsoft.com/Api/Advertiser/AdInsight/v13/AdInsightService.svc?singleWsdl" -path "bingads\v13\proxies\sandbox\adinsight_service.xml" +Powershell.exe -executionpolicy remotesigned -File .\generate_proxies.ps1 -svcWsdl "https://adinsight.api.bingads.microsoft.com/Api/Advertiser/AdInsight/v13/AdInsightService.svc?singleWsdl" -path "bingads\v13\proxies\production\adinsight_service.xml" + + +pause \ No newline at end of file diff --git a/generate_proxies.ps1 b/generate_proxies.ps1 new file mode 100644 index 00000000..12371e6b --- /dev/null +++ b/generate_proxies.ps1 @@ -0,0 +1,20 @@ +Param ( + [string]$svcWsdl, + [string]$path +) + +function Format-XML([xml]$xml, $indent=3) +{ + $StringWriter = New-Object System.IO.StringWriter + $XmlWriter = New-Object System.XMl.XmlTextWriter $StringWriter + $xmlWriter.Formatting = "indented" + $xmlWriter.Indentation = $Indent + $xml.WriteContentTo($XmlWriter) + $XmlWriter.Flush() + $StringWriter.Flush() + Write-Output $StringWriter.ToString() +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$WebClient = New-Object System.Net.WebClient +$WebClient.DownloadFile($svcWsdl,$path) +Format-XML ([xml](cat $path)) | Set-Content -Path $path \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index fe57e372..56cfaf5e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,8 @@ -suds-jurko==0.6.0 +suds-community>=1.1.0 requests>=2.0.0 -future -six enum34 pytest mock -parameterizedtestcase coverage flake8 setuptools diff --git a/setup.py b/setup.py index 3af6e6e5..3aaa4fa4 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ except ImportError: from distutils.core import setup -VERSION = '13.0.8' +VERSION = '13.0.25.3' with open('README.rst', 'r') as f: readme = f.read() @@ -11,18 +11,16 @@ history = f.read().replace('.. :changelog:', '') requirements = [ - 'suds-jurko==0.6.0', - 'future', - 'six', + 'suds-community>=1.1.0', 'requests', - 'enum34;python_version<"3.4"', + 'enum34;python_version<"3.9"', ] setup( name='bingads', version=VERSION, description='A library to make working with the Bing Ads APIs and bulk services easy', - long_description=readme + '\n\n' + history, + long_description=readme, author='Bing Ads SDK Team', author_email='bing_ads_sdk@microsoft.com', url='https://github.com/BingAds/BingAds-Python-SDK', @@ -37,6 +35,8 @@ 'bingads.v13.bulk.entities.feeds', 'bingads.v13.bulk.entities.target_criterions', 'bingads.v13.bulk.entities.labels', + 'bingads.v13.bulk.entities.goals', + 'bingads.v13.bulk.entities.account_placement_exclusion_list', 'bingads.v13.internal', 'bingads.v13.internal.bulk', 'bingads.v13.internal.bulk.entities', @@ -55,11 +55,13 @@ 'Natural Language :: English', 'Operating System :: OS Independent', 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.6', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9' ], ) diff --git a/tox.ini b/tox.ini index 08b9eb94..7b0224aa 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py26, py27, py33, py34 +envlist = py33, py34 [testenv] setenv =