예제 #1
0
class _BulkNegativeSiteIdentifier(_BulkEntityIdentifier):
    def __init__(self, status=None, entity_id=None, entity_name=None):
        self._status = status
        self._entity_id = entity_id
        self._entity_name = entity_name

    @property
    def status(self):
        return self._status

    @property
    def entity_id(self):
        return self._entity_id

    @property
    def entity_name(self):
        return self._entity_name

    @property
    def _parent_column_name(self):
        raise NotImplementedError()

    _MAPPINGS = [
        _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: None
            if c._entity_id == 0 else bulk_str(c._entity_id),
            csv_to_field=lambda c, v: setattr(c, '_entity_id',
                                              int(v) if v else 0)),
        _DynamicColumnNameMapping(
            header_func=lambda c: c._parent_column_name,
            field_to_csv=lambda c: c._entity_name,
            csv_to_field=lambda c, v: setattr(c, '_entity_name', v))
    ]

    def __eq__(self, other):
        return type(self) == type(
            other) and self._entity_id == other._entity_id

    @property
    def is_delete_row(self):
        return self._status == 'Deleted'

    def read_from_row_values(self, row_values):
        row_values.convert_to_entity(self,
                                     _BulkNegativeSiteIdentifier._MAPPINGS)

    def write_to_row_values(self, row_values, exclude_readonly_data):
        self.convert_to_values(row_values,
                               _BulkNegativeSiteIdentifier._MAPPINGS)
예제 #2
0
class _BulkAdGroupAdExtensionAssociation(_BulkAdExtensionAssociation):
    """ This abstract class provides properties that are shared by all bulk ad group ad extension association classes. """
    def __init__(self,
                 ad_extension_id_to_entity_id_association=None,
                 status=None,
                 editorial_status=None):
        super(_BulkAdGroupAdExtensionAssociation, self).__init__(
            ad_extension_id_to_entity_id_association,
            status,
            editorial_status,
        )
        self._ad_group_name = None
        self._campaign_name = None

    _MAPPINGS = [
        _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.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):
        super(_BulkAdGroupAdExtensionAssociation,
              self).process_mappings_from_row_values(row_values)
        row_values.convert_to_entity(
            self, _BulkAdGroupAdExtensionAssociation._MAPPINGS)

    @property
    def ad_group_name(self):
        """ The name of the ad group that the ad extension is associated.

        Corresponds to the 'AdGroup' field in the bulk file.

        :rtype str
        """

        return self._ad_group_name

    @property
    def campaign_name(self):
        """ The name of the campaign containing the ad group that the ad extension is associated.

        Corresponds to the 'Campaign' field in the bulk file.

        :rtype: str
        """

        return self._campaign_name
예제 #3
0
class BulkProductAd(_BulkAd):
    """ Represents a product ad.

    This class exposes the :attr:`product_ad` property that can be read and written as fields of the Product Ad record in a bulk file.

    For more information, see Product Ad at http://go.microsoft.com/fwlink/?LinkID=511555.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """
    def __init__(self,
                 ad_group_id=None,
                 campaign_name=None,
                 ad_group_name=None,
                 ad=None):
        super(BulkProductAd, self).__init__(ad_group_id, campaign_name,
                                            ad_group_name, ad)
        self.product_ad = ad

    @property
    def product_ad(self):
        """ The product ad.

        See Product Ad at: http://go.microsoft.com/fwlink/?LinkID=511555.
        """

        return self._ad

    @product_ad.setter
    def product_ad(self, product_ad):
        if product_ad is not None and not isinstance(product_ad, ProductAd):
            raise ValueError('Not an instance of ProductAd')
        self._ad = product_ad

    _MAPPINGS = [
        _SimpleBulkMapping(header=_StringTable.PromotionalText,
                           field_to_csv=lambda c: bulk_optional_str(
                               c.product_ad.PromotionalText),
                           csv_to_field=lambda c, v: setattr(
                               c.product_ad, 'PromotionalText', v
                               if v else '')),
    ]

    def process_mappings_from_row_values(self, row_values):
        self.product_ad = _CAMPAIGN_OBJECT_FACTORY.create('ProductAd')
        self.product_ad.Type = 'Product'
        super(BulkProductAd, self).process_mappings_from_row_values(row_values)
        row_values.convert_to_entity(self, BulkProductAd._MAPPINGS)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self.product_ad, 'product_ad')
        super(BulkProductAd,
              self).process_mappings_to_row_values(row_values,
                                                   exclude_readonly_data)
        self.convert_to_values(row_values, BulkProductAd._MAPPINGS)
class _BulkProductAdExtensionIdentifier(_BulkAdExtensionIdentifier):
    def __init__(self,
                 name=None,
                 account_id=None,
                 ad_extension_id=None,
                 status=None,
                 version=None):
        super(_BulkProductAdExtensionIdentifier, self).__init__(
            account_id=account_id,
            ad_extension_id=ad_extension_id,
            status=status,
            version=version,
        )
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name

    def __eq__(self, other):
        return isinstance(other, _BulkProductAdExtensionIdentifier) \
            and self._account_id == other.account_id \
            and self._ad_extension_id == other.ad_extension_id

    _MAPPINGS = [
        _SimpleBulkMapping(header=_StringTable.Name,
                           field_to_csv=lambda c: c.name,
                           csv_to_field=lambda c, v: setattr(c, 'name', v))
    ]

    def read_from_row_values(self, row_values):
        super(_BulkProductAdExtensionIdentifier,
              self).read_from_row_values(row_values)
        row_values.convert_to_entity(
            self, _BulkProductAdExtensionIdentifier._MAPPINGS)

    def write_to_row_values(self, row_values, exclude_readonly_data):
        super(_BulkProductAdExtensionIdentifier,
              self).write_to_row_values(row_values, exclude_readonly_data)
        self.convert_to_values(row_values,
                               _BulkProductAdExtensionIdentifier._MAPPINGS)

    def _create_entity_with_this_identifier(self):
        return BulkProductAdExtension(identifier=self)
예제 #5
0
class BulkCallAdExtension(_BulkAdExtensionBase):
    """ Represents a call ad extension.

    This class exposes the :attr:`call_ad_extension` property that can be read and written
    as fields of the Call Ad Extension record in a bulk file.

    For more information, see Call Ad Extension at http://go.microsoft.com/fwlink/?LinkID=511514.

    *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, _CallAdExtension):
            raise ValueError(
                'The type of ad_extension is: {0}, should be: {1}'.format(
                    type(ad_extension), 'CallAdExtension'))
        super(BulkCallAdExtension, self).__init__(account_id=account_id,
                                                  ad_extension=ad_extension)

    @property
    def call_ad_extension(self):
        """ The call ad extension.

        see Call Ad Extension at http://go.microsoft.com/fwlink/?LinkID=511514.
        """

        return self._ad_extension

    @call_ad_extension.setter
    def call_ad_extension(self, value):
        self._ad_extension = value

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.PhoneNumber,
            field_to_csv=lambda c: c.call_ad_extension.PhoneNumber,
            csv_to_field=lambda c, v: setattr(c.call_ad_extension,
                                              'PhoneNumber', v)),
        _SimpleBulkMapping(
            header=_StringTable.CountryCode,
            field_to_csv=lambda c: c.call_ad_extension.CountryCode,
            csv_to_field=lambda c, v: setattr(c.call_ad_extension,
                                              'CountryCode', v)),
        _SimpleBulkMapping(
            header=_StringTable.IsCallOnly,
            field_to_csv=lambda c: bulk_str(c.call_ad_extension.IsCallOnly),
            csv_to_field=lambda c, v: setattr(
                c.call_ad_extension, 'IsCallOnly',
                v.lower() == 'true' if v else None)),
        _SimpleBulkMapping(header=_StringTable.IsCallTrackingEnabled,
                           field_to_csv=lambda c: bulk_str(
                               c.call_ad_extension.IsCallTrackingEnabled),
                           csv_to_field=lambda c, v: setattr(
                               c.call_ad_extension, 'IsCallTrackingEnabled',
                               v.lower() == 'true' if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.RequireTollFreeTrackingNumber,
            field_to_csv=lambda c: bulk_str(c.call_ad_extension.
                                            RequireTollFreeTrackingNumber),
            csv_to_field=lambda c, v: setattr(
                c.call_ad_extension, 'RequireTollFreeTrackingNumber',
                v.lower() == 'true' if v else None)),
    ]

    def process_mappings_from_row_values(self, row_values):
        self.call_ad_extension = _CAMPAIGN_OBJECT_FACTORY.create(
            'CallAdExtension')
        self.call_ad_extension.Type = 'CallAdExtension'
        super(BulkCallAdExtension,
              self).process_mappings_from_row_values(row_values)
        row_values.convert_to_entity(self, BulkCallAdExtension._MAPPINGS)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self.call_ad_extension,
                                         'call_ad_extension')
        super(BulkCallAdExtension,
              self).process_mappings_to_row_values(row_values,
                                                   exclude_readonly_data)
        self.convert_to_values(row_values, BulkCallAdExtension._MAPPINGS)
예제 #6
0
class BulkAdGroupProductTarget(_SingleRecordBulkEntity):
    """ Represents an ad group product target.

    This class exposes the :attr:`biddable_ad_group_criterion` property that can be read and written as fields of the
    Ad Group Product Target record in a bulk file.

    For more information, see Ad Group Product Target at http://go.microsoft.com/fwlink/?LinkID=511550.

    *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(BulkAdGroupProductTarget, self).__init__()

        self._biddable_ad_group_criterion = biddable_ad_group_criterion
        self._campaign_name = campaign_name
        self._ad_group_name = ad_group_name

    @property
    def biddable_ad_group_criterion(self):
        """ The BiddableAdGroupCriterion Data Object of the Campaign Management Service.

        A subset of BiddableAdGroupCriterion properties are available in the Ad Group Product Target record.
        For more information, see Ad Group Product Target at http://go.microsoft.com/fwlink/?LinkID=511550.

        see BiddableAdGroupCriterion at: https://msdn.microsoft.com/en-us/library/bing-ads-campaign-management-biddableadgroupcriterion.aspx
        """

        return self._biddable_ad_group_criterion

    @biddable_ad_group_criterion.setter
    def biddable_ad_group_criterion(self, value):
        self._biddable_ad_group_criterion = value

    @property
    def campaign_name(self):
        """ The name of the campaign that contains the ad group product target.

        Corresponds to the 'Campaign' field in the bulk file.

        :rtype: str
        """

        return self._campaign_name

    @campaign_name.setter
    def campaign_name(self, value):
        self._campaign_name = value

    @property
    def ad_group_name(self):
        """ The name of the ad group that contains the ad group product target.

        Corresponds to the 'Ad Group' field in the bulk file.

        :rtype: str
        """

        return self._ad_group_name

    @ad_group_name.setter
    def ad_group_name(self, value):
        self._ad_group_name = value

    _MAPPINGS = [
        _SimpleBulkMapping(header=_StringTable.Status,
                           field_to_csv=lambda c: bulk_str(
                               c.biddable_ad_group_criterion.Status),
                           csv_to_field=lambda c, v: setattr(
                               c.biddable_ad_group_criterion, 'Status', v
                               if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.Id,
            field_to_csv=lambda c: bulk_str(c.biddable_ad_group_criterion.Id),
            csv_to_field=lambda c, v: setattr(c.biddable_ad_group_criterion,
                                              'Id',
                                              int(v) if v else None)),
        _SimpleBulkMapping(header=_StringTable.ParentId,
                           field_to_csv=lambda c: bulk_str(
                               c.biddable_ad_group_criterion.AdGroupId),
                           csv_to_field=lambda c, v: setattr(
                               c.biddable_ad_group_criterion, 'AdGroupId',
                               int(v) if v else None)),
        _SimpleBulkMapping(
            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.EditorialStatus,
            field_to_csv=lambda c: bulk_str(c.biddable_ad_group_criterion.
                                            EditorialStatus),
            csv_to_field=lambda c, v: setattr(c.biddable_ad_group_criterion,
                                              'EditorialStatus', v
                                              if v else None)),
        _SimpleBulkMapping(header=_StringTable.Bid,
                           field_to_csv=lambda c: ad_group_bid_bulk_str(
                               c.biddable_ad_group_criterion.CriterionBid.Bid),
                           csv_to_field=lambda c, v: setattr(
                               c.biddable_ad_group_criterion.CriterionBid,
                               'Bid', parse_ad_group_bid(v))),
        _SimpleBulkMapping(
            header=_StringTable.DestinationUrl,
            field_to_csv=lambda c: bulk_optional_str(
                c.biddable_ad_group_criterion.DestinationUrl),
            csv_to_field=lambda c, v: setattr(c.biddable_ad_group_criterion,
                                              'DestinationUrl', v
                                              if v else '')),
        _SimpleBulkMapping(header=_StringTable.Param1,
                           field_to_csv=lambda c: bulk_optional_str(
                               c.biddable_ad_group_criterion.Param1),
                           csv_to_field=lambda c, v: setattr(
                               c.biddable_ad_group_criterion, 'Param1', v
                               if v else '')),
        _SimpleBulkMapping(header=_StringTable.Param2,
                           field_to_csv=lambda c: bulk_optional_str(
                               c.biddable_ad_group_criterion.Param2),
                           csv_to_field=lambda c, v: setattr(
                               c.biddable_ad_group_criterion, 'Param2', v
                               if v else '')),
        _SimpleBulkMapping(header=_StringTable.Param3,
                           field_to_csv=lambda c: bulk_optional_str(
                               c.biddable_ad_group_criterion.Param3),
                           csv_to_field=lambda c, v: setattr(
                               c.biddable_ad_group_criterion, 'Param3', v
                               if v else '')),
        _ComplexBulkMapping(
            entity_to_csv=lambda entity, row_values: _ProductConditionHelper.
            add_row_values_from_conditions(
                entity.biddable_ad_group_criterion.Criterion.Conditions.
                ProductCondition, row_values),
            csv_to_entity=lambda row_values, entity: _ProductConditionHelper.
            add_conditions_from_row_values(
                row_values,
                entity.biddable_ad_group_criterion.Criterion.Conditions.
                ProductCondition,
            ))
    ]

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self.convert_to_values(row_values, BulkAdGroupProductTarget._MAPPINGS)

    def process_mappings_from_row_values(self, row_values):
        self.biddable_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY.create(
            'BiddableAdGroupCriterion')
        self.biddable_ad_group_criterion.Type = 'BiddableAdGroupCriterion'
        self.biddable_ad_group_criterion.CriterionBid = _CAMPAIGN_OBJECT_FACTORY.create(
            'FixedBid')
        self.biddable_ad_group_criterion.CriterionBid.Type = 'FixedBid'
        self.biddable_ad_group_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY.create(
            'Product')
        self.biddable_ad_group_criterion.Criterion.Type = 'Product'

        row_values.convert_to_entity(self, BulkAdGroupProductTarget._MAPPINGS)

    def read_additional_data(self, stream_reader):
        super(BulkAdGroupProductTarget,
              self).read_additional_data(stream_reader)
예제 #7
0
class BulkError(_BulkObject):
    """ Contains bulk file error details in a separate record that corresponds to the record of a :class:`.BulkEntity` derived instance.

    Properties of this class and of classes that it is derived from, correspond to error fields of the 'Error' records in a bulk file.
    For more information, see Bulk File Schema at http://go.microsoft.com/fwlink/?LinkID=511639.

    *Example:*

    If you upload a :class:`.BulkCampaign` without setting the campaign name using :meth:`BulkServiceManager.upload_entities,
    and if you request errors to be returned in the results using the corresponding :attr:`SubmitUploadParameters.response_mode`,
    then the upload result file will contain a record that can be read with a :class:`.BulkFileReader` as an instance of :class:`.BulkError`.
    """
    def __init__(self):
        self._error = None
        self._number = None
        self._editorial_location = None
        self._editorial_term = None
        self._editorial_reason_code = None
        self._publisher_countries = None
        self._entity = None

    @property
    def entity(self):
        return self._entity

    @entity.setter
    def entity(self, value):
        self._entity = value

    @property
    def error(self):
        """ The error code, for example 'CampaignServiceEditorialValidationError'.

        Corresponds to the 'Error' field in the bulk file.
        For more information, see Bing Ads Operation Error Codes at http://go.microsoft.com/fwlink/?LinkId=511884.

        :rtype: str
        """

        return self._error

    @property
    def number(self):
        """ The error number, for example '1042'.

        Corresponds to the 'Error Number' field in the bulk file.
        For more information, see Bing Ads Operation Error Codes at http://go.microsoft.com/fwlink/?LinkId=511884.

        :rtype: int
        """

        return self._number

    @property
    def editorial_location(self):
        """ The location of the entity property that resulted in the editorial error, for example 'AdDescription'.

        Corresponds to the 'Editorial Location' field in the bulk file.

        :rtype: str
        """

        return self._editorial_location

    @property
    def editorial_term(self):
        """ The term that resulted in the editorial error, for example 'bing'.

        Corresponds to the 'Editorial Term' field in the bulk file.

        :rtype: str
        """

        return self._editorial_term

    @property
    def editorial_reason_code(self):
        """ The term that resulted in the editorial error, for example '17'.

        Corresponds to the 'Editorial Reason Code' field in the bulk file.
        For more information, see Bing Ads Editorial Failure Reason Codes at http://go.microsoft.com/fwlink/?LinkId=511883.

        :rtype: int
        """

        return self._editorial_reason_code

    @property
    def publisher_countries(self):
        """ The publisher countries where editorial restriction is enforced, for example 'US'.

        Corresponds to the 'Publisher Countries' field in the bulk file.

        *Remarks:*

        In a bulk file, the list of publisher countries are delimited with a semicolon (;).

        :rtype: str
        """

        return self._publisher_countries

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.Error,
            field_to_csv=lambda c: bulk_str(c.error),
            csv_to_field=lambda c, v: setattr(c, '_error', v if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.ErrorNumber,
            field_to_csv=lambda c: bulk_str(c.number),
            csv_to_field=lambda c, v: setattr(c, '_number',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.EditorialLocation,
            field_to_csv=lambda c: bulk_str(c.editorial_location),
            csv_to_field=lambda c, v: setattr(c, '_editorial_location', v
                                              if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.EditorialReasonCode,
            field_to_csv=lambda c: bulk_str(c.editorial_reason_code),
            csv_to_field=lambda c, v: setattr(c, '_editorial_reason_code',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.EditorialTerm,
            field_to_csv=lambda c: bulk_str(c.editorial_term),
            csv_to_field=lambda c, v: setattr(c, '_editorial_term', v
                                              if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.PublisherCountries,
            field_to_csv=lambda c: bulk_str(c.publisher_countries),
            csv_to_field=lambda c, v: setattr(c, '_publisher_countries', v
                                              if v else None)),
    ]

    def can_enclose_in_multiline_entity(self):
        return super(BulkError, self).can_enclose_in_multiline_entity()

    def enclose_in_multiline_entity(self):
        return super(BulkError, self).enclose_in_multiline_entity()

    def read_from_row_values(self, row_values):
        row_values.convert_to_entity(self, BulkError._MAPPINGS)

    def read_related_data_from_stream(self, stream_reader):
        return super(BulkError,
                     self).read_related_data_from_stream(stream_reader)

    def write_to_row_values(self, row_values, exclude_readonly_data):
        self.entity.write_to_row_values(row_values, exclude_readonly_data)
        self.convert_to_values(row_values, BulkError._MAPPINGS)

    def write_to_stream(self, stream_writer, exclude_readonly_data):
        return super(BulkError, self).write_to_stream(stream_writer,
                                                      exclude_readonly_data)
class BulkNegativeKeywordList(_SingleRecordBulkEntity):
    """ Represents a negative keyword list that can be read or written in a bulk file.

    This class exposes the :attr:`.BulkNegativeKeywordList.negative_keyword_list` property that can be read and
    written as fields of the Negative Keyword List record in a bulk file.

    For more information, see Negative Keyword List at http://go.microsoft.com/fwlink/?LinkID=511519.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """
    def __init__(self, status=None, negative_keyword_list=None):
        super(BulkNegativeKeywordList, self).__init__()

        self._status = status
        self._negative_keyword_list = negative_keyword_list

    @property
    def negative_keyword_list(self):
        """ The negative keyword list.

        see Negative Keyword List at http://go.microsoft.com/fwlink/?LinkID=511519.
        """

        return self._negative_keyword_list

    @negative_keyword_list.setter
    def negative_keyword_list(self, negative_keyword_list):
        self._negative_keyword_list = negative_keyword_list

    @property
    def status(self):
        """ The status of the negative keyword list.

        :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.negative_keyword_list.Id),
            csv_to_field=lambda c, v: setattr(c.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.negative_keyword_list.Name,
                           csv_to_field=lambda c, v: setattr(
                               c.negative_keyword_list, 'Name', v))
    ]

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self._negative_keyword_list,
                                         'negative_keyword_list')
        self.convert_to_values(row_values, BulkNegativeKeywordList._MAPPINGS)

    def process_mappings_from_row_values(self, row_values):
        self._negative_keyword_list = _CAMPAIGN_OBJECT_FACTORY.create(
            'NegativeKeywordList')
        self._negative_keyword_list.Type = 'NegativeKeywordList'
        row_values.convert_to_entity(self, BulkNegativeKeywordList._MAPPINGS)

    def read_additional_data(self, stream_reader):
        super(BulkNegativeKeywordList,
              self).read_additional_data(stream_reader)
class _BulkNegativeSite(_SingleRecordBulkEntity):
    """ This abstract base class for the bulk negative sites that are assigned individually to a campaign or ad group entity.

    *See also:*

    * :class:`.BulkAdGroupNegativeSite`
    * :class:`.BulkCampaignNegativeSite`
    """
    def __init__(self, identifier, website=None):
        super(_BulkNegativeSite, self).__init__()

        self._identifier = identifier
        self._website = website

    @property
    def website(self):
        """ The URL of a website on which you do not want your ads displayed.

        Corresponds to the 'Website' field in the bulk file.

        :rtype: str
        """

        return self._website

    @website.setter
    def website(self, website):
        self._website = website

    @property
    def status(self):
        """ The status of the negative site association.

        :rtype: str
        """

        return self._identifier.status

    @status.setter
    def status(self, value):
        self._identifier.status = value

    _MAPPINGS = [
        _SimpleBulkMapping(header=_StringTable.Website,
                           field_to_csv=lambda c: c.website,
                           csv_to_field=lambda c, v: setattr(c, 'website', v)),
    ]

    def process_mappings_from_row_values(self, row_values):
        self._identifier.read_from_row_values(row_values)
        row_values.convert_to_entity(self, _BulkNegativeSite._MAPPINGS)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._identifier.write_to_row_values(row_values, exclude_readonly_data)
        self.convert_to_values(row_values, _BulkNegativeSite._MAPPINGS)

    @property
    def can_enclose_in_multiline_entity(self):
        return True

    def enclose_in_multiline_entity(self):
        return self.create_negative_sites_with_this_negative_site()

    def create_negative_sites_with_this_negative_site(self):
        raise NotImplementedError()

    def read_additional_data(self, stream_reader):
        super(_BulkNegativeSite, self).read_additional_data(stream_reader)
예제 #10
0
class BulkKeyword(_SingleRecordBulkEntity):
    """ Represents a keyword that can be read or written in a bulk file.

    This class exposes the :attr:`keyword` 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 http://go.microsoft.com/fwlink/?LinkID=511556.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """
    def __init__(self,
                 ad_group_id=None,
                 campaign_name=None,
                 ad_group_name=None,
                 keyword=None):
        super(BulkKeyword, self).__init__()
        self._ad_group_id = ad_group_id
        self._keyword = keyword
        self._campaign_name = campaign_name
        self._ad_group_name = ad_group_name
        self._performance_data = None
        self._quality_score_data = None
        self._bid_suggestions = None

    @property
    def ad_group_id(self):
        """ The identifier of the ad group that contains the keyword.

        Corresponds to the 'Parent Id' field in the bulk file.

        :rtype: int
        """

        return self._ad_group_id

    @ad_group_id.setter
    def ad_group_id(self, ad_group_id):
        self._ad_group_id = ad_group_id

    @property
    def keyword(self):
        """ Defines a keyword within an ad group.

        See Keyword at https://msdn.microsoft.com/en-US/library/bing-ads-campaign-management-keyword.aspx
        """

        return self._keyword

    @keyword.setter
    def keyword(self, keyword):
        self._keyword = keyword

    @property
    def campaign_name(self):
        """ The name of the campaign that contains the keyword.

        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 ad_group_name(self):
        """ The name of the ad group that contains the keyword.

        Corresponds to the 'Ad Group' field in the bulk file.

        :rtype: str
        """

        return self._ad_group_name

    @ad_group_name.setter
    def ad_group_name(self, ad_group_name):
        self._ad_group_name = ad_group_name

    @property
    def quality_score_data(self):
        """ The quality score data for the keyword.

        :rtype: QualityScoreData
        """

        return self._quality_score_data

    @property
    def performance_data(self):
        """ The historical performance data for the keyword.

        :rtype: PerformanceData
        """

        return self._performance_data

    @property
    def bid_suggestions(self):
        """ The bid suggestion data for the keyword.

        :rtype: BidSuggestionData
        """

        return self._bid_suggestions

    _MAPPINGS = [
        _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)),
        _SimpleBulkMapping(
            header=_StringTable.Id,
            field_to_csv=lambda c: bulk_str(c.keyword.Id),
            csv_to_field=lambda c, v: setattr(c.keyword, 'Id',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.ParentId,
            field_to_csv=lambda c: bulk_str(c.ad_group_id),
            csv_to_field=lambda c, v: setattr(c, '_ad_group_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.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.Keyword,
            field_to_csv=lambda c: c.keyword.Text,
            csv_to_field=lambda c, v: setattr(c.keyword, 'Text', v)),
        _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)),
        _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)),
        _SimpleBulkMapping(
            header=_StringTable.DestinationUrl,
            field_to_csv=lambda c: bulk_optional_str(c.keyword.DestinationUrl),
            csv_to_field=lambda c, v: setattr(c.keyword, 'DestinationUrl', v
                                              if v else '')),
        _SimpleBulkMapping(
            header=_StringTable.Bid,
            field_to_csv=lambda c: keyword_bid_bulk_str(c.keyword.Bid),
            csv_to_field=lambda c, v: setattr(c.keyword, 'Bid',
                                              parse_keyword_bid(v))),
        _SimpleBulkMapping(
            header=_StringTable.Param1,
            field_to_csv=lambda c: bulk_optional_str(c.keyword.Param1),
            csv_to_field=lambda c, v: setattr(c.keyword, 'Param1', v
                                              if v else '')),
        _SimpleBulkMapping(
            header=_StringTable.Param2,
            field_to_csv=lambda c: bulk_optional_str(c.keyword.Param2),
            csv_to_field=lambda c, v: setattr(c.keyword, 'Param2', v
                                              if v else '')),
        _SimpleBulkMapping(
            header=_StringTable.Param3,
            field_to_csv=lambda c: bulk_optional_str(c.keyword.Param3),
            csv_to_field=lambda c, v: setattr(c.keyword, 'Param3', v
                                              if v else '')),
    ]

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self._keyword, 'keyword')
        self.convert_to_values(row_values, BulkKeyword._MAPPINGS)
        if not exclude_readonly_data:
            QualityScoreData.write_to_row_values_if_not_null(
                self.quality_score_data, row_values)
            PerformanceData.write_to_row_values_if_not_null(
                self.performance_data, row_values)

    def process_mappings_from_row_values(self, row_values):
        self._keyword = _CAMPAIGN_OBJECT_FACTORY.create('Keyword')
        row_values.convert_to_entity(self, BulkKeyword._MAPPINGS)
        self._quality_score_data = QualityScoreData.read_from_row_values_or_null(
            row_values)
        self._performance_data = PerformanceData.read_from_row_values_or_null(
            row_values)

    def read_additional_data(self, stream_reader):
        success, next_bid_suggestion = stream_reader.try_read(
            BulkKeywordBidSuggestion)

        while success:
            if self._bid_suggestions is None:
                self._bid_suggestions = BidSuggestionData()

            if isinstance(next_bid_suggestion, BulkKeywordBestPositionBid):
                self._bid_suggestions.best_position = next_bid_suggestion
            elif isinstance(next_bid_suggestion, BulkKeywordMainLineBid):
                self._bid_suggestions.main_line = next_bid_suggestion
            elif isinstance(next_bid_suggestion, BulkKeywordFirstPageBid):
                self._bid_suggestions.first_page = next_bid_suggestion

            success, next_bid_suggestion = stream_reader.try_read(
                BulkKeywordBidSuggestion)

    def write_additional_data(self, row_writer):
        if self.bid_suggestions is not None:
            BulkKeywordBidSuggestion.write_if_not_null(
                self.bid_suggestions.best_position, row_writer)
            BulkKeywordBidSuggestion.write_if_not_null(
                self.bid_suggestions.main_line, row_writer)
            BulkKeywordBidSuggestion.write_if_not_null(
                self.bid_suggestions.first_page, row_writer)
class BulkAdGroupNegativeKeyword(_BulkEntityNegativeKeyword):
    """ Represents a negative keyword that is assigned to a ad group. Each negative keyword can be read or written in a bulk file.

    This class exposes the :attr:`.BulkNegativeKeyword.negative_keyword` property that can be read and written as
    fields of the Ad Group Negative Keyword record in a bulk file.

    For more information, see Ad Group Negative Keyword at http://go.microsoft.com/fwlink/?LinkID=511538.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """
    def __init__(self,
                 status=None,
                 negative_keyword=None,
                 ad_group_id=None,
                 ad_group_name=None,
                 campaign_name=None):
        super(BulkAdGroupNegativeKeyword, self).__init__(
            status,
            negative_keyword,
            ad_group_id,
            ad_group_name,
        )
        self._campaign_name = campaign_name

    @property
    def campaign_name(self):
        """ The name of the campaign that the negative keyword is assigned.

        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 ad_group_id(self):
        """ Corresponds to the 'Parent Id' field in the bulk file.

        :return: The identifier of the ad group that the negative keyword is assigned.
        :rtype: int
        """

        return self._parent_id

    @ad_group_id.setter
    def ad_group_id(self, value):
        self._parent_id = value

    @property
    def ad_group_name(self):
        """ Corresponds to the 'Ad Group' field in the bulk file.

        :return: The name of the ad group that the negative keyword is assigned.
        :rtype: str
        """

        return self._entity_name

    @ad_group_name.setter
    def ad_group_name(self, value):
        self._entity_name = value

    @property
    def _entity_column_name(self):
        return _StringTable.AdGroup

    _MAPPINGS = [
        _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_to_row_values(self, row_values,
                                       exclude_readonly_data):
        super(BulkAdGroupNegativeKeyword,
              self).process_mappings_to_row_values(row_values,
                                                   exclude_readonly_data)
        self.convert_to_values(row_values,
                               BulkAdGroupNegativeKeyword._MAPPINGS)

    def process_mappings_from_row_values(self, row_values):
        super(BulkAdGroupNegativeKeyword,
              self).process_mappings_from_row_values(row_values)
        row_values.convert_to_entity(self,
                                     BulkAdGroupNegativeKeyword._MAPPINGS)

    def read_additional_data(self, stream_reader):
        super(BulkAdGroupNegativeKeyword,
              self).read_additional_data(stream_reader)
class BulkSiteLink(_SingleRecordBulkEntity):
    """ Represents a sitelink.

    This class exposes the <see cref="BulkSiteLink.SiteLink"/> property that can be read and written
    as fields of the Sitelink Ad Extension record in a bulk file.

    For more information, see Sitelink Ad Extension at http://go.microsoft.com/fwlink/?LinkID=511517.

    The Sitelink Ad Extension record includes the distinct properties of the :class:`.BulkSiteLink` class, combined with
    the common properties of the :class:`.BulkSiteLinkAdExtension` class.

    One :class:`BulkSiteLinkAdExtension` has one or more :class:`BulkSiteLink`. :class:`.BulkSiteLink` instance
    corresponds to one Sitelink Ad Extension record in the bulk file. If you upload a :class:`.BulkSiteLinkAdExtension`,
    then you are effectively replacing any existing site links for the sitelink ad extension.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """
    def __init__(
        self,
        ad_extension_id=None,
        account_id=None,
        status=None,
        version=None,
        order=None,
        site_link=None,
    ):
        super(BulkSiteLink, self).__init__()

        self._identifier = _SiteLinkAdExtensionIdentifier(
            ad_extension_id=ad_extension_id,
            account_id=account_id,
            status=status,
            version=version,
        )
        self._order = order
        self._site_link = site_link

    @property
    def order(self):
        """ The order of the sitelink displayed to a search user in the ad.

        :rtype: int
        """

        return self._order

    @order.setter
    def order(self, value):
        self._order = value

    @property
    def site_link(self):
        """ The sitelink.

        See SiteLink at: https://msdn.microsoft.com/en-US/library/jj134381.aspx
        """

        return self._site_link

    @site_link.setter
    def site_link(self, value):
        self._site_link = value

    @property
    def ad_extension_id(self):
        """ The identifier of the ad extension.

        Corresponds to the 'Id' field in the bulk file.

        :rtype: int
        """

        return self._identifier.ad_extension_id

    @ad_extension_id.setter
    def ad_extension_id(self, value):
        self._identifier._ad_extension_id = value

    @property
    def account_id(self):
        """ The ad extension's parent account identifier.

        Corresponds to the 'Parent Id' field in the bulk file.

        :rtype: int
        """

        return self._identifier.account_id

    @account_id.setter
    def account_id(self, value):
        self._identifier._account_id = value

    @property
    def status(self):
        """ The status of the ad extension.

        Corresponds to the 'Status' field in the bulk file.

        :rtype: str
        """

        return self._identifier.status

    @status.setter
    def status(self, value):
        self._identifier._status = value

    @property
    def version(self):
        """ The version of the ad extension.

        Corresponds to the 'Version' field in the bulk file.

        :rtype: int
        """

        return self._identifier.version

    @version.setter
    def version(self, value):
        self._identifier._version = value

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.SiteLinkExtensionOrder,
            field_to_csv=lambda c: bulk_str(c.order),
            csv_to_field=lambda c, v: setattr(c, 'order', int(v))),
        _SimpleBulkMapping(
            header=_StringTable.SiteLinkDisplayText,
            field_to_csv=lambda c: c.site_link.DisplayText,
            csv_to_field=lambda c, v: setattr(c.site_link, 'DisplayText', v)),
        _SimpleBulkMapping(header=_StringTable.SiteLinkDestinationUrl,
                           field_to_csv=lambda c: c.site_link.DestinationUrl,
                           csv_to_field=lambda c, v: setattr(
                               c.site_link, 'DestinationUrl', v)),
        _SimpleBulkMapping(
            header=_StringTable.SiteLinkDescription1,
            field_to_csv=lambda c: c.site_link.Description1,
            csv_to_field=lambda c, v: setattr(c.site_link, 'Description1', v)),
        _SimpleBulkMapping(
            header=_StringTable.SiteLinkDescription2,
            field_to_csv=lambda c: c.site_link.Description2,
            csv_to_field=lambda c, v: setattr(c.site_link, 'Description2', v)),
        _SimpleBulkMapping(
            header=_StringTable.DevicePreference,
            field_to_csv=lambda c: bulk_device_preference_str(
                c.site_link.DevicePreference),
            csv_to_field=lambda c, v: setattr(c.site_link, 'DevicePreference',
                                              parse_device_preference(v))),
    ]

    def process_mappings_from_row_values(self, row_values):
        self._site_link = _CAMPAIGN_OBJECT_FACTORY.create('SiteLink')
        self._identifier.read_from_row_values(row_values)
        row_values.convert_to_entity(self, BulkSiteLink._MAPPINGS)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self._site_link, 'site_link')
        self._identifier.write_to_row_values(row_values, exclude_readonly_data)
        self.convert_to_values(row_values, BulkSiteLink._MAPPINGS)

    @property
    def can_enclose_in_multiline_entity(self):
        return True

    def enclose_in_multiline_entity(self):
        return BulkSiteLinkAdExtension(bulk_site_link=self)

    def read_additional_data(self, stream_reader):
        super(BulkSiteLink, self).read_additional_data(stream_reader)
예제 #13
0
class BulkAccount(_SingleRecordBulkEntity):
    """ Represents an account 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 Account record in a bulk file.
    For more information, see Account at http://go.microsoft.com/fwlink/?LinkID=511513.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """

    def __init__(self, account_id=None, customer_id=None, sync_time=None):
        super(BulkAccount, self).__init__()
        self._id = account_id
        self._customer_id = customer_id
        self._sync_time = sync_time

    @property
    def id(self):
        """ The identifier of the account.

        Corresponds to the 'Id' field in the bulk file.

        :return: The identifier of the account.
        :rtype: int
        """

        return self._id

    @property
    def customer_id(self):
        """ The identifier of the customer that contains the account.

        Corresponds to the 'Parent Id' field in the bulk file.

        :return: The identifier of the customer that contains the account.
        :rtype: int
        """

        return self._customer_id

    @property
    def sync_time(self):
        """ The date and time that you last synced your account using the bulk service.

        You should keep track of this value in UTC time.
        Corresponds to the 'Sync Time' field in the bulk file.

        :return: The date and time that you last synced your account using the bulk service.
        :rtype: datetime.datetime
        """

        return self._sync_time

    _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.ParentId,
            field_to_csv=lambda c: bulk_str(c.customer_id),
            csv_to_field=lambda c, v: setattr(c, '_customer_id', int(v) if v else None)
        ),
        _SimpleBulkMapping(
            header=_StringTable.SyncTime,
            field_to_csv=lambda c: bulk_datetime_str(c.sync_time),
            csv_to_field=lambda c, v: setattr(c, '_sync_time', parse_datetime(v) if v else None)
        ),
    ]

    def process_mappings_from_row_values(self, row_values):
        row_values.convert_to_entity(self, BulkAccount._MAPPINGS)

    def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
        self.convert_to_values(row_values, BulkAccount._MAPPINGS)

    def read_additional_data(self, stream_reader):
        super(BulkAccount, self).read_additional_data(stream_reader)
예제 #14
0
class BulkCampaign(_SingleRecordBulkEntity):
    """ Represents a campaign that can be read or written in a bulk file.

    This class exposes the :attr:`campaign` property that can be read and written as fields of the
    Campaign record in a bulk file.

    For more information, see Campaign at http://go.microsoft.com/fwlink/?LinkID=511521.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """
    def __init__(self, account_id=None, campaign=None):
        super(BulkCampaign, self).__init__()

        self._account_id = account_id
        self._campaign = campaign
        self._quality_score_data = None
        self._performance_data = None

    @property
    def account_id(self):
        """ The identifier of the account that contains the campaign.

        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 campaign(self):
        """ Defines a campaign within an account.

        See Campaign at https://msdn.microsoft.com/en-us/library/bing-ads-campaign-management-campaign.aspx
        """

        return self._campaign

    @campaign.setter
    def campaign(self, campaign):
        self._campaign = campaign

    @property
    def quality_score_data(self):
        """ The quality score data for the campaign.

        :rtype: QualityScoreData
        """

        return self._quality_score_data

    @property
    def performance_data(self):
        """ The historical performance data for the campaign

        :rtype: PerformanceData
        """

        return self._performance_data

    def _get_shopping_setting(self):
        if not self.campaign.Settings.Setting:
            return None
        shopping_settings = [
            setting for setting in self.campaign.Settings.Setting
            if isinstance(setting, _ShoppingSetting)
        ]
        if len(shopping_settings) != 1:
            raise ValueError(
                'Can only have 1 ShoppingSetting in Campaign Settings.')
        return shopping_settings[0]

    @staticmethod
    def _write_campaign_type(c):
        if not c.campaign.CampaignType:
            return None
        if len(c.campaign.CampaignType) != 1:
            raise ValueError("Only 1 CampaignType can be set in Campaign")
        return c.campaign.CampaignType[0]

    @staticmethod
    def _read_campaign_type(c, v):
        if not v:
            return []
        campaign_type = v
        c.campaign.CampaignType = [campaign_type]
        if campaign_type.lower() == 'shopping':
            c.campaign.Settings = _CAMPAIGN_OBJECT_FACTORY.create(
                'ArrayOfSetting')
            shopping_setting = _CAMPAIGN_OBJECT_FACTORY.create(
                'ShoppingSetting')
            shopping_setting.Type = 'ShoppingSetting'
            c.campaign.Settings.Setting = [shopping_setting]

    @staticmethod
    def _write_store_id(c):
        if not c.campaign.CampaignType:
            return None
        if 'shopping' in [
                campaign_type.lower()
                for campaign_type in c.campaign.CampaignType
        ]:
            shopping_setting = c._get_shopping_setting()
            if not shopping_setting:
                return None
            return bulk_str(shopping_setting.StoreId)

    @staticmethod
    def _read_store_id(c, v):
        if not c.campaign.CampaignType:
            return None
        if 'shopping' in [
                campaign_type.lower()
                for campaign_type in c.campaign.CampaignType
        ]:
            shopping_setting = c._get_shopping_setting()
            if not shopping_setting:
                return None
            shopping_setting.StoreId = int(v) if v else None

    @staticmethod
    def _write_priority(c):
        if not c.campaign.CampaignType:
            return None
        if 'shopping' in [
                campaign_type.lower()
                for campaign_type in c.campaign.CampaignType
        ]:
            shopping_setting = c._get_shopping_setting()
            if not shopping_setting:
                return None
            return bulk_str(shopping_setting.Priority)

    @staticmethod
    def _read_priority(c, v):
        if not c.campaign.CampaignType:
            return None
        if 'shopping' in [
                campaign_type.lower()
                for campaign_type in c.campaign.CampaignType
        ]:
            shopping_setting = c._get_shopping_setting()
            if not shopping_setting:
                return None
            shopping_setting.Priority = int(v) if v else None

    @staticmethod
    def _write_sales_country_code(c):
        if not c.campaign.CampaignType:
            return None
        if 'shopping' in [
                campaign_type.lower()
                for campaign_type in c.campaign.CampaignType
        ]:
            shopping_setting = c._get_shopping_setting()
            if not shopping_setting:
                return None
            return shopping_setting.SalesCountryCode

    @staticmethod
    def _read_sales_country_code(c, v):
        if not c.campaign.CampaignType:
            return None
        if 'shopping' in [
                campaign_type.lower()
                for campaign_type in c.campaign.CampaignType
        ]:
            shopping_setting = c._get_shopping_setting()
            if not shopping_setting:
                return None
            shopping_setting.SalesCountryCode = v

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.CampaignType,
            field_to_csv=lambda c: BulkCampaign._write_campaign_type(c),
            csv_to_field=lambda c, v: BulkCampaign._read_campaign_type(c, v)),
        _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)),
        _SimpleBulkMapping(
            header=_StringTable.Id,
            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.ParentId,
            field_to_csv=lambda c: bulk_str(c.account_id),
            csv_to_field=lambda c, v: setattr(c, '_account_id', int(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.TimeZone,
            field_to_csv=lambda c: c.campaign.TimeZone,
            csv_to_field=lambda c, v: setattr(c.campaign, 'TimeZone', v)),
        _SimpleBulkMapping(
            header=_StringTable.BudgetType,
            field_to_csv=lambda c: bulk_str(c.campaign.BudgetType),
            csv_to_field=lambda c, v: setattr(c.campaign, 'BudgetType', v
                                              if v else None)),
        _ComplexBulkMapping(budget_to_csv, csv_to_budget),
        _SimpleBulkMapping(
            header=_StringTable.BidAdjustment,
            field_to_csv=lambda c: bulk_str(c.campaign.NativeBidAdjustment),
            csv_to_field=lambda c, v: setattr(c.campaign,
                                              'NativeBidAdjustment',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.BingMerchantCenterId,
            field_to_csv=lambda c: BulkCampaign._write_store_id(c),
            csv_to_field=lambda c, v: BulkCampaign._read_store_id(c, v)),
        _SimpleBulkMapping(
            header=_StringTable.CampaignPriority,
            field_to_csv=lambda c: BulkCampaign._write_priority(c),
            csv_to_field=lambda c, v: BulkCampaign._read_priority(c, v)),
        _SimpleBulkMapping(
            header=_StringTable.CountryCode,
            field_to_csv=lambda c: BulkCampaign._write_sales_country_code(c),
            csv_to_field=lambda c, v: BulkCampaign._read_sales_country_code(
                c, v))
    ]

    def read_additional_data(self, stream_reader):
        super(BulkCampaign, self).read_additional_data(stream_reader)

    def process_mappings_from_row_values(self, row_values):
        self._campaign = _CAMPAIGN_OBJECT_FACTORY.create('Campaign')
        row_values.convert_to_entity(self, BulkCampaign._MAPPINGS)
        self._quality_score_data = QualityScoreData.read_from_row_values_or_null(
            row_values)
        self._performance_data = PerformanceData.read_from_row_values_or_null(
            row_values)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self.campaign, 'campaign')
        self.convert_to_values(row_values, BulkCampaign._MAPPINGS)
        if not exclude_readonly_data:
            QualityScoreData.write_to_row_values_if_not_null(
                self.quality_score_data, row_values)
            PerformanceData.write_to_row_values_if_not_null(
                self.performance_data, row_values)
예제 #15
0
class BulkCampaign(_SingleRecordBulkEntity):
    """ Represents a campaign that can be read or written in a bulk file.

    This class exposes the :attr:`campaign` property that can be read and written as fields of the
    Campaign record in a bulk file.

    For more information, see Campaign at http://go.microsoft.com/fwlink/?LinkID=511521.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """
    def __init__(self, account_id=None, campaign=None):
        super(BulkCampaign, self).__init__()

        self._account_id = account_id
        self._campaign = campaign
        self._quality_score_data = None
        self._performance_data = None

    @property
    def account_id(self):
        """ The identifier of the account that contains the campaign.

        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 campaign(self):
        """ Defines a campaign within an account.

        See Campaign at https://msdn.microsoft.com/en-us/library/bing-ads-campaign-management-campaign.aspx
        """

        return self._campaign

    @campaign.setter
    def campaign(self, campaign):
        self._campaign = campaign

    @property
    def quality_score_data(self):
        """ The quality score data for the campaign.

        :rtype: QualityScoreData
        """

        return self._quality_score_data

    @property
    def performance_data(self):
        """ The historical performance data for the campaign

        :rtype: PerformanceData
        """

        return self._performance_data

    _MAPPINGS = [
        _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)),
        _SimpleBulkMapping(
            header=_StringTable.Id,
            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.ParentId,
            field_to_csv=lambda c: bulk_str(c.account_id),
            csv_to_field=lambda c, v: setattr(c, '_account_id', int(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.TimeZone,
            field_to_csv=lambda c: c.campaign.TimeZone,
            csv_to_field=lambda c, v: setattr(c.campaign, 'TimeZone', v)),
        _SimpleBulkMapping(
            header=_StringTable.BudgetType,
            field_to_csv=lambda c: bulk_str(c.campaign.BudgetType),
            csv_to_field=lambda c, v: setattr(c.campaign, 'BudgetType', v
                                              if v else None)),
        _ComplexBulkMapping(budget_to_csv, csv_to_budget)
    ]

    def read_additional_data(self, stream_reader):
        super(BulkCampaign, self).read_additional_data(stream_reader)

    def process_mappings_from_row_values(self, row_values):
        self._campaign = _CAMPAIGN_OBJECT_FACTORY.create('Campaign')
        row_values.convert_to_entity(self, BulkCampaign._MAPPINGS)
        self._quality_score_data = QualityScoreData.read_from_row_values_or_null(
            row_values)
        self._performance_data = PerformanceData.read_from_row_values_or_null(
            row_values)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self.campaign, 'campaign')
        self.convert_to_values(row_values, BulkCampaign._MAPPINGS)
        if not exclude_readonly_data:
            QualityScoreData.write_to_row_values_if_not_null(
                self.quality_score_data, row_values)
            PerformanceData.write_to_row_values_if_not_null(
                self.performance_data, row_values)
class _BulkNegativeKeyword(_SingleRecordBulkEntity):
    """ The base class for all bulk negative keywords.

    Either assigned individually to a campaign or ad group entity, or shared in a negative keyword list.

    *See also:*

    * :class:`.BulkAdGroupNegativeKeyword`
    * :class:`.BulkCampaignNegativeKeyword`
    * :class:`.BulkSharedNegativeKeyword`
    """
    def __init__(self, status=None, negative_keyword=None, parent_id=None):
        super(_BulkNegativeKeyword, self).__init__()

        self._negative_keyword = negative_keyword
        self._status = status
        self._parent_id = parent_id

    @property
    def status(self):
        """ The status of the negative keyword association.

        The value is 'Active' if the negative keyword is assigned to the parent entity.
        The value is 'Deleted' if the negative keyword is removed from the parent entity,
                                    or should be removed in a subsequent upload operation.
        :rtype: str
        """
        return self._status

    @status.setter
    def status(self, status):
        self._status = status

    @property
    def negative_keyword(self):
        """ Defines a negative keyword with match type. """

        return self._negative_keyword

    @negative_keyword.setter
    def negative_keyword(self, negative_keyword):
        self._negative_keyword = negative_keyword

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.Id,
            field_to_csv=lambda c: bulk_str(c.negative_keyword.Id),
            csv_to_field=lambda c, v: setattr(c.negative_keyword, '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.Keyword,
            field_to_csv=lambda c: c.negative_keyword.Text,
            csv_to_field=lambda c, v: setattr(c.negative_keyword, 'Text', v)),
        _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))
    ]

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self._negative_keyword,
                                         'negative_keyword')
        self.convert_to_values(row_values, _BulkNegativeKeyword._MAPPINGS)

    def process_mappings_from_row_values(self, row_values):
        self._negative_keyword = _CAMPAIGN_OBJECT_FACTORY.create(
            'NegativeKeyword')
        self._negative_keyword.Type = 'NegativeKeyword'
        row_values.convert_to_entity(self, _BulkNegativeKeyword._MAPPINGS)

    def read_additional_data(self, stream_reader):
        super(_BulkNegativeKeyword, self).read_additional_data(stream_reader)
예제 #17
0
class BulkCampaignProductScope(_SingleRecordBulkEntity):
    """ Represents a Campaign Criterion that can be read or written in a bulk file.

    This class exposes the :attr:`campaign_criterion` property that can be read and written as fields of the
    Campaign Product Scope record in a bulk file.

    For more information, see Campaign Product Scope at http://go.microsoft.com/fwlink/?LinkId=618643.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """
    def __init__(self,
                 campaign_name=None,
                 status=None,
                 campaign_criterion=None):
        super(BulkCampaignProductScope, self).__init__()

        self._campaign_name = campaign_name
        self._status = status
        self._campaign_criterion = campaign_criterion

    _MAPPINGS = [
        _SimpleBulkMapping(header=_StringTable.Status,
                           field_to_csv=lambda c: c.status,
                           csv_to_field=lambda c, v: setattr(c, 'status', v)),
        _SimpleBulkMapping(
            header=_StringTable.Id,
            field_to_csv=lambda c: bulk_str(c.campaign_criterion.Id),
            csv_to_field=lambda c, v: setattr(c.campaign_criterion, 'Id',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.ParentId,
            field_to_csv=lambda c: bulk_str(c.campaign_criterion.CampaignId),
            csv_to_field=lambda c, v: setattr(c.campaign_criterion,
                                              'CampaignId', int(v))),
        _SimpleBulkMapping(
            header=_StringTable.Campaign,
            field_to_csv=lambda c: c.campaign_name,
            csv_to_field=lambda c, v: setattr(c, 'campaign_name', v)),
        _ComplexBulkMapping(
            entity_to_csv=lambda c, v: _ProductConditionHelper.
            add_row_values_from_conditions(
                c.campaign_criterion.Criterion.Conditions.ProductCondition, v),
            csv_to_entity=lambda v, c: _ProductConditionHelper.
            add_conditions_from_row_values(
                v, c.campaign_criterion.Criterion.Conditions.ProductCondition))
    ]

    @property
    def campaign_name(self):
        """ 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 status(self):
        """ The status of the Campaign Criterion

        :rtype: str
        """

        return self._status

    @status.setter
    def status(self, status):
        self._status = status

    @property
    def campaign_criterion(self):
        """ Defines a Campaign Criterion """

        return self._campaign_criterion

    @campaign_criterion.setter
    def campaign_criterion(self, campaign_criterion):
        self._campaign_criterion = campaign_criterion

    def process_mappings_from_row_values(self, row_values):
        self._campaign_criterion = _CAMPAIGN_OBJECT_FACTORY.create(
            'CampaignCriterion')
        self._campaign_criterion.Type = 'CampaignCriterion'
        self._campaign_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY.create(
            'ProductScope')
        self._campaign_criterion.Criterion.Type = 'ProductScope'

        row_values.convert_to_entity(self, BulkCampaignProductScope._MAPPINGS)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self.campaign_criterion,
                                         'campaign_criterion')
        self.convert_to_values(row_values, BulkCampaignProductScope._MAPPINGS)

    def read_additional_data(self, stream_reader):
        super(BulkCampaignProductScope,
              self).read_additional_data(stream_reader)
class BulkProductConditionCollection(_SingleRecordBulkEntity):
    """ Represents the product condition collection for a product ad extension.

    Each product condition collection can be read or written in a bulk file.

    This class exposes the :attr:`product_condition_collection` property that can be read and written
    as fields of the Product Ad Extension record in a bulk file.

    For more information, see Product Ad Extension at http://go.microsoft.com/fwlink/?LinkID=511516.

    The Product Ad Extension record includes the distinct properties of the :class:`.BulkProductConditionCollection` class, combined with
    the common properties of the :class:`.BulkProductAdExtension` class, for example :attr:`account_id` and :class:`.ProductAdExtension`.

    One :class:`.BulkProductAdExtension` has one or more :class:`.BulkProductConditionCollection`. Each :class:`.BulkProductConditionCollection` instance
    corresponds to one Product Ad Extension record in the bulk file. If you upload a :class:`.BulkProductAdExtension`,
    then you are effectively replacing any existing site links for the product ad extension.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """
    def __init__(self,
                 account_id=None,
                 ad_extension_id=None,
                 version=None,
                 status=None,
                 store_id=None,
                 name=None,
                 product_condition_collection=None):
        super(BulkProductConditionCollection, self).__init__()
        self._identifier = _BulkProductAdExtensionIdentifier(
            account_id=account_id,
            ad_extension_id=ad_extension_id,
            version=version,
            status=status,
        )

        self._product_condition_collection = product_condition_collection
        self._name = name
        self._store_id = store_id
        self._store_name = None

    @property
    def name(self):
        """ The name of the ad extension.

        :rtype: str
        """
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

    @property
    def store_id(self):
        """ The product ad extension's store identifier.

        :rtype: int
        """

        return self._store_id

    @store_id.setter
    def store_id(self, value):
        self._store_id = value

    @property
    def product_condition_collection(self):
        """ The collection of product conditions for a product ad extension.

        see ProductConditionCollection in https://msdn.microsoft.com/en-US/library/bing-ads-campaign-management-productconditioncollection.aspx
        """

        return self._product_condition_collection

    @product_condition_collection.setter
    def product_condition_collection(self, value):
        self._product_condition_collection = value

    @property
    def ad_extension_id(self):
        """ The identifier of the ad extension.

        Corresponds to the 'Id' field in the bulk file.

        :rtype: int
        """
        return self._identifier.ad_extension_id

    @ad_extension_id.setter
    def ad_extension_id(self, value):
        self._identifier._ad_extension_id = value

    @property
    def account_id(self):
        """ The ad extension's parent account identifier.

        Corresponds to the 'Parent Id' field in the bulk file.

        :rtype: int
        """

        return self._identifier.account_id

    @account_id.setter
    def account_id(self, value):
        self._identifier._account_id = value

    @property
    def status(self):
        """ The status of the ad extension.

        Corresponds to the 'Status' field in the bulk file.

        :rtype: str
        """
        return self._identifier.status

    @status.setter
    def status(self, value):
        self._identifier._status = value

    @property
    def version(self):
        """ The version of the ad extension.

        Corresponds to the 'Version' field in the bulk file.

        :rtype: int
        """

        return self._identifier.version

    @version.setter
    def version(self, value):
        self._identifier._version = value

    @property
    def store_name(self):
        """ The product ad extension's store name.

        Corresponds to the 'Store Name' field in the bulk file.

        :rtype: str
        """

        return self._store_name

    _MAPPINGS = [
        _ComplexBulkMapping(
            lambda entity, row_values: _ProductConditionHelper.
            add_row_values_from_conditions(
                entity.product_condition_collection.Conditions.
                ProductCondition, row_values), lambda row_values, entity:
            _ProductConditionHelper.add_conditions_from_row_values(
                row_values, entity.product_condition_collection.Conditions.
                ProductCondition)),
        _SimpleBulkMapping(header=_StringTable.Name,
                           field_to_csv=lambda c: c.name,
                           csv_to_field=lambda c, v: setattr(c, 'name', v)),
        _SimpleBulkMapping(
            header=_StringTable.BingMerchantCenterId,
            field_to_csv=lambda c: bulk_str(c.store_id),
            csv_to_field=lambda c, v: setattr(c, 'store_id', int(v))),
        _SimpleBulkMapping(
            header=_StringTable.BingMerchantCenterName,
            field_to_csv=lambda c: bulk_str(c.store_name),
            csv_to_field=lambda c, v: setattr(c, '_store_name', v)),
    ]

    def process_mappings_from_row_values(self, row_values):
        self.product_condition_collection = _CAMPAIGN_OBJECT_FACTORY.create(
            'ProductConditionCollection')
        self._identifier.read_from_row_values(row_values)
        row_values.convert_to_entity(self,
                                     BulkProductConditionCollection._MAPPINGS)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self.product_condition_collection,
                                         'product_condition_collection')
        self._validate_property_not_null(
            self.product_condition_collection.Conditions,
            'product_condition_collection.Conditions')
        self._identifier.write_to_row_values(row_values, exclude_readonly_data)
        self.convert_to_values(row_values,
                               BulkProductConditionCollection._MAPPINGS)

    def can_enclose_in_multiline_entity(self):
        return True

    def enclose_in_multiline_entity(self):
        return BulkProductAdExtension(product_collection=self)

    def read_additional_data(self, stream_reader):
        super(BulkProductConditionCollection,
              self).read_additional_data(stream_reader)
예제 #19
0
class BulkKeywordBidSuggestion(_BulkObject):
    """ Represents a best position bid suggestion.

    It can only be read from a bulk file by the :class:`.BulkFileReader` when reading the corresponding :class:`.BulkKeyword`.
    An instance of this class can represent a single keyword bid position, and thus one record in the bulk file.
    """

    def __init__(self):
        self._keyword_text = None
        self._bid = None
        self._performance_data = None

    @property
    def keyword_text(self):
        """ The keyword corresponding to the suggested bid.

        Corresponds to the 'Keyword' field in the bulk file.
        :rtype: str
        """

        return self._keyword_text

    @property
    def bid(self):
        """ The suggested bid for the keyword.

        :rtype: float
        """

        return self._bid

    @property
    def performance_data(self):
        """ The historical performance data corresponding to the suggested bid.

        :rtype: PerformanceData
        """

        return self._performance_data

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.Keyword,
            field_to_csv=lambda c: bulk_str(c.keyword_text),
            csv_to_field=lambda c, v: setattr(c, '_keyword_text', v if v else None)
        ),
        _SimpleBulkMapping(
            header=_StringTable.Bid,
            field_to_csv=lambda c: bulk_str(c.bid),
            csv_to_field=lambda c, v: setattr(c, '_bid', float(v) if v else None)
        ),
    ]

    def read_from_row_values(self, row_values):
        row_values.convert_to_entity(self, BulkKeywordBidSuggestion._MAPPINGS)
        self._performance_data = PerformanceData.read_from_row_values(row_values)

    def write_to_row_values(self, row_values, exclude_readonly_data):
        self.convert_to_values(row_values, BulkKeywordBidSuggestion._MAPPINGS)
        if not exclude_readonly_data:
            PerformanceData.write_to_row_values_if_not_null(self.performance_data, row_values)

    @staticmethod
    def write_if_not_null(keyword_bid_suggestion, row_writer):
        if keyword_bid_suggestion is not None:
            row_writer.write_object_row(keyword_bid_suggestion)
예제 #20
0
class _BulkAdExtensionBase(_SingleRecordBulkEntity):
    """ This class provides properties that are shared by all bulk ad extension classes.

    *See also:*

    * :class:`.BulkCallAdExtension`
    * :class:`.BulkImageAdExtension`
    * :class:`.BulkLocationAdExtension`
    * :class:`.BulkProductAdExtension`
    * :class:`.BulkSiteLinkAdExtension`
    """
    def __init__(self, account_id=None, ad_extension=None):
        super(_BulkAdExtensionBase, self).__init__()

        self._account_id = account_id
        self._ad_extension = ad_extension

    @property
    def account_id(self):
        """ The ad extension's parent account identifier.

        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.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)),
        _SimpleBulkMapping(
            header=_StringTable.Id,
            field_to_csv=lambda c: bulk_str(c._ad_extension.Id),
            csv_to_field=lambda c, v: setattr(c._ad_extension, 'Id',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.Version,
            field_to_csv=lambda c: bulk_str(c._ad_extension.Version),
            csv_to_field=lambda c, v: setattr(c._ad_extension, 'Version',
                                              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))),
    ]

    def process_mappings_from_row_values(self, row_values):
        row_values.convert_to_entity(self, _BulkAdExtensionBase._MAPPINGS)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self.convert_to_values(row_values, _BulkAdExtensionBase._MAPPINGS)

    def read_additional_data(self, stream_reader):
        super(_BulkAdExtensionBase, self).read_additional_data(stream_reader)
예제 #21
0
class _SingleRecordBulkEntity(with_metaclass(ABCMeta, BulkEntity)):
    def __init__(self):
        self._client_id = None
        self._last_modified_time = None
        self._errors = None

    @property
    def client_id(self):
        return self._client_id

    @client_id.setter
    def client_id(self, client_id):
        self._client_id = client_id

    @property
    def last_modified_time(self):
        return self._last_modified_time

    @property
    def errors(self):
        """ A list of :class:`BulkError` details in a separate bulk record that corresponds to the record of a :class:`.BulkEntity` derived instance.

        :rtype: list[BulkError] or None
        """
        return self._errors

    @property
    def has_errors(self):
        return True if self.errors is not None and self.errors else False

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.ClientId,
            field_to_csv=lambda c: c.client_id,
            csv_to_field=lambda c, v: setattr(c, '_client_id', v),
        ),
        _SimpleBulkMapping(
            header=_StringTable.LastModifiedTime,
            field_to_csv=lambda c: bulk_datetime_str(c.last_modified_time),
            csv_to_field=lambda c, v: setattr(c, '_last_modified_time',
                                              parse_datetime(v)
                                              if v else None),
        ),
    ]

    def read_from_row_values(self, row_values):
        row_values.convert_to_entity(self, _SingleRecordBulkEntity._MAPPINGS)
        self.process_mappings_from_row_values(row_values)

    def write_to_row_values(self, row_values, exclude_readonly_data):
        self.convert_to_values(row_values, _SingleRecordBulkEntity._MAPPINGS)
        self.process_mappings_to_row_values(row_values, exclude_readonly_data)

    def read_related_data_from_stream(self, stream_reader):
        self.read_additional_data(stream_reader)
        self._read_errors(stream_reader)

    def write_to_stream(self, row_writer, exclude_readonly_data):
        row_writer.write_object_row(self, exclude_readonly_data)
        if not exclude_readonly_data:
            self._write_errors(row_writer)
            self.write_additional_data(row_writer)

    def _write_errors(self, row_writer):
        if self.has_errors:
            for error in self.errors:
                row_writer.write_object_row(error)

    def write_additional_data(self, row_writer):
        pass

    @abstractmethod
    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        """ Process specific entity mappings to CSV values. Must be implemented by each entity.

        :param row_values: Row values.
        :type row_values: _RowValues
        :param exclude_readonly_data: excludeReadonlyData indicates whether readonly data should be written (such as errors, performance data etc.)
        :type exclude_readonly_data: bool
        """

        raise NotImplementedError()

    @abstractmethod
    def process_mappings_from_row_values(self, row_values):
        """ Process specific entity mappings from CSV values. Must be implemented by each entity.

        :param row_values:
        :type row_values: _RowValues
        """

        raise NotImplementedError()

    @abstractmethod
    def read_additional_data(self, stream_reader):
        pass

    def _read_errors(self, stream_reader):
        errors = []
        success, error = stream_reader.try_read(BulkError)
        while success:
            error.entity = self
            errors.append(error)
            success, error = stream_reader.try_read(BulkError)
        self._errors = errors

    def enclose_in_multiline_entity(self):
        return super(_SingleRecordBulkEntity,
                     self).enclose_in_multiline_entity()

    @property
    def can_enclose_in_multiline_entity(self):
        return super(_SingleRecordBulkEntity,
                     self).can_enclose_in_multiline_entity
예제 #22
0
class QualityScoreData(_BulkObject):
    """ Represents a subset of the fields available in bulk records that support quality score data.

    For example :class:`.BulkKeyword`. For more information, see Bulk File Schema at http://go.microsoft.com/fwlink/?LinkID=511639.
    """
    def __init__(self):
        self._quality_score = None
        self._keyword_relevance = None
        self._landing_page_relevance = None
        self._landing_page_user_experience = None

    @property
    def quality_score(self):
        """ Corresponds to the 'Quality Score' field in the bulk file.

        :rtype: int
        """

        return self._quality_score

    @property
    def keyword_relevance(self):
        """ Corresponds to the 'Keyword Relevance' field in the bulk file.

        :rtype: int
        """

        return self._keyword_relevance

    @property
    def landing_page_relevance(self):
        """ Corresponds to the 'Landing Page Relevance' field in the bulk file.

        :rtype: int
        """

        return self._landing_page_relevance

    @property
    def landing_page_user_experience(self):
        """ Corresponds to the 'Landing Page User Experience' field in the bulk file.

        :rtype: int
        """

        return self._landing_page_user_experience

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.QualityScore,
            field_to_csv=lambda c: bulk_str(c.quality_score),
            csv_to_field=lambda c, v: setattr(c, '_quality_score',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.KeywordRelevance,
            field_to_csv=lambda c: bulk_str(c.keyword_relevance),
            csv_to_field=lambda c, v: setattr(c, '_keyword_relevance',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.LandingPageRelevance,
            field_to_csv=lambda c: bulk_str(c.landing_page_relevance),
            csv_to_field=lambda c, v: setattr(c, '_landing_page_relevance',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.LandingPageUserExperience,
            field_to_csv=lambda c: bulk_str(c.landing_page_user_experience),
            csv_to_field=lambda c, v: setattr(c,
                                              '_landing_page_user_experience',
                                              int(v) if v else None)),
    ]

    @staticmethod
    def read_from_row_values_or_null(row_values):
        quality_score_data = QualityScoreData()
        quality_score_data.read_from_row_values(row_values)
        return quality_score_data if quality_score_data.has_any_values else None

    @staticmethod
    def write_to_row_values_if_not_null(quality_score_data, row_values):
        if quality_score_data is not None:
            quality_score_data.write_to_row_values(row_values, False)

    def read_from_row_values(self, row_values):
        row_values.convert_to_entity(self, QualityScoreData._MAPPINGS)

    def write_to_row_values(self, row_values, exclude_readonly_data):
        self.convert_to_values(row_values, QualityScoreData._MAPPINGS)

    @property
    def has_any_values(self):
        return \
            self.quality_score \
            or self.keyword_relevance \
            or self.landing_page_relevance \
            or self.landing_page_user_experience

    def write_to_stream(self, row_writer, exclude_readonly_data):
        pass

    def read_related_data_from_stream(self, stream_reader):
        super(QualityScoreData,
              self).read_related_data_from_stream(stream_reader)

    def enclose_in_multiline_entity(self):
        pass

    @property
    def can_enclose_in_multiline_entity(self):
        return super(QualityScoreData, self).can_enclose_in_multiline_entity()
class BulkImageAdExtension(_BulkAdExtensionBase):
    """ Represents a image ad extension.

    This class exposes the :attr:`image_ad_extension` property that can be read and written
    as fields of the Image Ad Extension record in a bulk file.

    For more information, see Image Ad Extension at http://go.microsoft.com/fwlink/?LinkID=511909.

    *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, _ImageAdExtension):
            raise ValueError(
                'The type of ad_extension is: {0}, should be: {1}'.format(
                    type(ad_extension), 'ImageAdExtension'))
        super(BulkImageAdExtension, self).__init__(account_id=account_id,
                                                   ad_extension=ad_extension)

    @property
    def image_ad_extension(self):
        """ The image ad extension.

        see Image Ad Extension at http://go.microsoft.com/fwlink/?LinkID=511909.
        """

        return self._ad_extension

    @image_ad_extension.setter
    def image_ad_extension(self, value):
        self._ad_extension = value

    _MAPPINGS = [
        _SimpleBulkMapping(header=_StringTable.DestinationUrl,
                           field_to_csv=lambda c: bulk_optional_str(
                               c.image_ad_extension.DestinationUrl),
                           csv_to_field=lambda c, v: setattr(
                               c.image_ad_extension, 'DestinationUrl', v
                               if v else '')),
        _SimpleBulkMapping(
            header=_StringTable.AltText,
            field_to_csv=lambda c: c.image_ad_extension.AlternativeText,
            csv_to_field=lambda c, v: setattr(c.image_ad_extension,
                                              'AlternativeText', v)),
        _SimpleBulkMapping(
            header=_StringTable.MediaId,
            field_to_csv=lambda c: bulk_str(c.image_ad_extension.ImageMediaId),
            csv_to_field=lambda c, v: setattr(c.image_ad_extension,
                                              'ImageMediaId', int(v))),
    ]

    def process_mappings_from_row_values(self, row_values):
        self.image_ad_extension = _CAMPAIGN_OBJECT_FACTORY.create(
            'ImageAdExtension')
        self.image_ad_extension.Type = 'ImageAdExtension'
        super(BulkImageAdExtension,
              self).process_mappings_from_row_values(row_values)
        row_values.convert_to_entity(self, BulkImageAdExtension._MAPPINGS)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self.image_ad_extension,
                                         'image_ad_extension')
        super(BulkImageAdExtension,
              self).process_mappings_to_row_values(row_values,
                                                   exclude_readonly_data)
        self.convert_to_values(row_values, BulkImageAdExtension._MAPPINGS)
class BulkAppAdExtension(_BulkAdExtensionBase):
    """ Represents a app ad extension.

    This class exposes the :attr:`app_ad_extension` property that can be read and written
    as fields of the App Ad Extension record in a bulk file.

    For more information, see App Ad Extension at http://go.microsoft.com/fwlink/?LinkID=515901.

    *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, _AppAdExtension):
            raise ValueError(
                'The type of ad_extension is: {0}, should be: {1}'.format(
                    type(ad_extension), 'AppAdExtension'))
        super(BulkAppAdExtension, self).__init__(account_id=account_id,
                                                 ad_extension=ad_extension)

    @property
    def app_ad_extension(self):
        """ The app ad extension.

        see App Ad Extension at http://go.microsoft.com/fwlink/?LinkID=515901.
        """

        return self._ad_extension

    @app_ad_extension.setter
    def app_ad_extension(self, value):
        self._ad_extension = value

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.AppPlatform,
            field_to_csv=lambda c: c.app_ad_extension.AppPlatform,
            csv_to_field=lambda c, v: setattr(c.app_ad_extension,
                                              'AppPlatform', v)),
        _SimpleBulkMapping(
            header=_StringTable.AppStoreId,
            field_to_csv=lambda c: c.app_ad_extension.AppStoreId,
            csv_to_field=lambda c, v: setattr(c.app_ad_extension, 'AppStoreId',
                                              v)),
        _SimpleBulkMapping(
            header=_StringTable.DestinationUrl,
            field_to_csv=lambda c: c.app_ad_extension.DestinationUrl,
            csv_to_field=lambda c, v: setattr(c.app_ad_extension,
                                              'DestinationUrl', v)),
        _SimpleBulkMapping(
            header=_StringTable.Text,
            field_to_csv=lambda c: c.app_ad_extension.DisplayText,
            csv_to_field=lambda c, v: setattr(c.app_ad_extension,
                                              'DisplayText', v)),
        _SimpleBulkMapping(header=_StringTable.DevicePreference,
                           field_to_csv=lambda c: bulk_device_preference_str(
                               c.app_ad_extension.DevicePreference),
                           csv_to_field=lambda c, v: setattr(
                               c.app_ad_extension, 'DevicePreference',
                               parse_device_preference(v))),
    ]

    def process_mappings_from_row_values(self, row_values):
        self.app_ad_extension = _CAMPAIGN_OBJECT_FACTORY.create(
            'AppAdExtension')
        self.app_ad_extension.Type = 'AppAdExtension'
        super(BulkAppAdExtension,
              self).process_mappings_from_row_values(row_values)
        row_values.convert_to_entity(self, BulkAppAdExtension._MAPPINGS)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self.app_ad_extension,
                                         'app_ad_extension')
        super(BulkAppAdExtension,
              self).process_mappings_to_row_values(row_values,
                                                   exclude_readonly_data)
        self.convert_to_values(row_values, BulkAppAdExtension._MAPPINGS)
class _BulkAdGroupNegativeSitesIdentifier(_BulkNegativeSiteIdentifier):
    def __init__(self,
                 status=None,
                 ad_group_id=None,
                 ad_group_name=None,
                 campaign_name=None):
        super(_BulkAdGroupNegativeSitesIdentifier, self).__init__(
            status,
            ad_group_id,
            ad_group_name,
        )
        self._campaign_name = campaign_name

    def __eq__(self, other):
        is_name_not_empty = (self.campaign_name is not None
                             and len(self.campaign_name) > 0
                             and self.ad_group_name is not None
                             and len(self.ad_group_name) > 0)
        return (
            type(self) == type(other) and
            (self.ad_group_id == other.ad_group_id or
             (is_name_not_empty and self.campaign_name == other.campaign_name
              and self.ad_group_name == other.ad_group_name)))

    @property
    def ad_group_id(self):
        return self._entity_id

    @ad_group_id.setter
    def ad_group_id(self, value):
        self._entity_id = value

    @property
    def ad_group_name(self):
        return self._entity_name

    @ad_group_name.setter
    def ad_group_name(self, value):
        self._entity_name = value

    @property
    def campaign_name(self):
        return self._campaign_name

    @campaign_name.setter
    def campaign_name(self, campaign_name):
        self._campaign_name = campaign_name

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.Campaign,
            field_to_csv=lambda c: c.campaign_name,
            csv_to_field=lambda c, v: setattr(c, 'campaign_name', v)),
    ]

    def read_from_row_values(self, row_values):
        super(_BulkAdGroupNegativeSitesIdentifier,
              self).read_from_row_values(row_values)
        row_values.convert_to_entity(
            self, _BulkAdGroupNegativeSitesIdentifier._MAPPINGS)

    def write_to_row_values(self, row_values, exclude_readonly_data):
        super(_BulkAdGroupNegativeSitesIdentifier,
              self).write_to_row_values(row_values, exclude_readonly_data)
        self.convert_to_values(row_values,
                               _BulkAdGroupNegativeSitesIdentifier._MAPPINGS)

    def _create_entity_with_this_identifier(self):
        return BulkAdGroupNegativeSites(identifier=self)

    @property
    def _parent_column_name(self):
        return _StringTable.AdGroup
class BulkCampaignNegativeKeywordList(_SingleRecordBulkEntity):
    """ Represents a negative keyword list that is assigned to a campaign. Each negative keyword list can be read or written in a bulk file.

    This class exposes the :attr:`BulkCampaignNegativeKeywordList.SharedEntityAssociation` property that can be read
    and written as fields of the Campaign Negative Keyword List Association record in a bulk file.

    For more information, see Campaign Negative Keyword List Association at http://go.microsoft.com/fwlink/?LinkID=511523.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """
    def __init__(self, status=None, shared_entity_association=None):
        super(BulkCampaignNegativeKeywordList, self).__init__()

        self._shared_entity_association = shared_entity_association
        self._status = status

    @property
    def status(self):
        """ The status of the 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 negative keyword list identifiers.

        see Campaign Negative Keyword List Association at http://go.microsoft.com/fwlink/?LinkID=511523.
        """

        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,
                               BulkCampaignNegativeKeywordList._MAPPINGS)

    def process_mappings_from_row_values(self, row_values):
        self._shared_entity_association = _CAMPAIGN_OBJECT_FACTORY.create(
            'SharedEntityAssociation')
        self._shared_entity_association.EntityType = 'Campaign'
        self._shared_entity_association.SharedEntityType = 'NegativeKeywordList'
        row_values.convert_to_entity(self,
                                     BulkCampaignNegativeKeywordList._MAPPINGS)

    def read_additional_data(self, stream_reader):
        super(BulkCampaignNegativeKeywordList,
              self).read_additional_data(stream_reader)
예제 #27
0
class PerformanceData(_BulkObject):
    """ Represents a subset of the fields available in bulk records that support historical performance data.

    For example :class:`.BulkKeyword`.
    For more information, see Bulk File Schema at http://go.microsoft.com/fwlink/?LinkID=511639.
    """
    def __init__(self):
        self._spend = None
        self._impressions = None
        self._clicks = None
        self._click_through_rate = None
        self._average_cost_per_click = None
        self._average_cost_per_thousand_impressions = None
        self._average_position = None
        self._conversions = None
        self._cost_per_conversion = None

    @property
    def spend(self):
        """ Corresponds to the 'Spend' field in the bulk file.

        :rtype: float
        """

        return self._spend

    @property
    def impressions(self):
        """ Corresponds to the 'Impressions' field in the bulk file.

        :rtype: int
        """

        return self._impressions

    @property
    def clicks(self):
        """ Corresponds to the 'Clicks' field in the bulk file.

        :rtype: int
        """

        return self._clicks

    @property
    def click_through_rate(self):
        """ Corresponds to the 'CTR' field in the bulk file.

        :rtype: float
        """

        return self._click_through_rate

    @property
    def average_cost_per_click(self):
        """ Corresponds to the 'Avg CPC' field in the bulk file.

        :rtype: float
        """

        return self._average_cost_per_click

    @property
    def average_cost_per_thousand_impressions(self):
        """ Corresponds to the 'Avg CPM' field in the bulk file.

        :rtype: float
        """

        return self._average_cost_per_thousand_impressions

    @property
    def average_position(self):
        """ Corresponds to the 'Avg position' field in the bulk file.

        :rtype: float
        """

        return self._average_position

    @property
    def conversions(self):
        """ Corresponds to the 'Conversions' field in the bulk file.

        :rtype: int
        """

        return self._conversions

    @property
    def cost_per_conversion(self):
        """ Corresponds to the 'CPA' field in the bulk file.

        :rtype: float
        """

        return self._cost_per_conversion

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.Spend,
            field_to_csv=lambda c: bulk_str(c.spend),
            csv_to_field=lambda c, v: setattr(c, '_spend',
                                              float(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.Impressions,
            field_to_csv=lambda c: bulk_str(c.impressions),
            csv_to_field=lambda c, v: setattr(c, '_impressions',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.Clicks,
            field_to_csv=lambda c: bulk_str(c.clicks),
            csv_to_field=lambda c, v: setattr(c, '_clicks',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.CTR,
            field_to_csv=lambda c: bulk_str(c.click_through_rate),
            csv_to_field=lambda c, v: setattr(c, '_click_through_rate',
                                              float(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.AvgCPC,
            field_to_csv=lambda c: bulk_str(c.average_cost_per_click),
            csv_to_field=lambda c, v: setattr(c, '_average_cost_per_click',
                                              float(v) if v else None)),
        _SimpleBulkMapping(header=_StringTable.AvgCPM,
                           field_to_csv=lambda c: bulk_str(
                               c.average_cost_per_thousand_impressions),
                           csv_to_field=lambda c, v: setattr(
                               c, '_average_cost_per_thousand_impressions',
                               float(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.AvgPosition,
            field_to_csv=lambda c: bulk_str(c.average_position),
            csv_to_field=lambda c, v: setattr(c, '_average_position',
                                              float(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.Conversions,
            field_to_csv=lambda c: bulk_str(c.conversions),
            csv_to_field=lambda c, v: setattr(c, '_conversions',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.CPA,
            field_to_csv=lambda c: bulk_str(c.cost_per_conversion),
            csv_to_field=lambda c, v: setattr(c, '_cost_per_conversion',
                                              float(v) if v else None))
    ]

    @staticmethod
    def read_from_row_values_or_null(row_values):
        performance_data = PerformanceData()
        performance_data.read_from_row_values(row_values)
        return performance_data if performance_data.has_any_values else None

    @staticmethod
    def write_to_row_values_if_not_null(performance_data, row_values):
        if performance_data is not None:
            performance_data.write_to_row_values(row_values, False)

    def read_from_row_values(self, row_values):
        row_values.convert_to_entity(self, PerformanceData._MAPPINGS)

    def write_to_row_values(self, row_values, exclude_readonly_data):
        self.convert_to_values(row_values, PerformanceData._MAPPINGS)

    @property
    def has_any_values(self):
        return \
            self.average_cost_per_click \
            or self.average_cost_per_thousand_impressions \
            or self.average_position \
            or self.click_through_rate \
            or self.clicks \
            or self.conversions \
            or self.cost_per_conversion \
            or self.impressions \
            or self.spend

    def write_to_stream(self, row_writer, exclude_readonly_data):
        pass

    def read_related_data_from_stream(self, stream_reader):
        super(PerformanceData,
              self).read_related_data_from_stream(stream_reader)

    def enclose_in_multiline_entity(self):
        pass

    @property
    def can_enclose_in_multiline_entity(self):
        return super(PerformanceData, self).can_enclose_in_multiline_entity()
예제 #28
0
class _BulkAdExtensionIdentifier(_BulkEntityIdentifier):
    def __init__(self,
                 account_id=None,
                 ad_extension_id=None,
                 status=None,
                 version=None):
        super(_BulkAdExtensionIdentifier, self).__init__()

        self._account_id = account_id
        self._ad_extension_id = ad_extension_id
        self._status = status
        self._version = version

    @property
    def account_id(self):
        return self._account_id

    @account_id.setter
    def account_id(self, account_id):
        self._account_id = account_id

    @property
    def ad_extension_id(self):
        return self._ad_extension_id

    @ad_extension_id.setter
    def ad_extension_id(self, ad_extension_id):
        self._ad_extension_id = ad_extension_id

    @property
    def status(self):
        return self._status

    @status.setter
    def status(self, status):
        self._status = status

    @property
    def version(self):
        return self._version

    @version.setter
    def version(self, version):
        self._version = version

    _MAPPINGS = [
        _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.Id,
            field_to_csv=lambda c: bulk_str(c.ad_extension_id),
            csv_to_field=lambda c, v: setattr(c, 'ad_extension_id',
                                              int(v) if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.Version,
            field_to_csv=lambda c: bulk_str(c.version),
            csv_to_field=lambda c, v: setattr(c, 'version',
                                              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))),
    ]

    def read_from_row_values(self, row_values):
        row_values.convert_to_entity(self,
                                     _BulkAdExtensionIdentifier._MAPPINGS)

    def write_to_row_values(self, row_values, exclude_readonly_data):
        self.convert_to_values(row_values,
                               _BulkAdExtensionIdentifier._MAPPINGS)

    def __eq__(self, other):
        raise NotImplementedError()

    @property
    def is_delete_row(self):
        return self._status == 'Deleted'
예제 #29
0
class BulkAdGroup(_SingleRecordBulkEntity):
    """ Represents an ad group.

    This class exposes the property :attr:`ad_group` that can be read and written as fields of the Ad Group record
    in a bulk file.

    For more information, see Ad Group at http://go.microsoft.com/fwlink/?LinkID=511537.

    *See also:*

    * :class:`.BulkServiceManager`
    * :class:`.BulkOperation`
    * :class:`.BulkFileReader`
    * :class:`.BulkFileWriter`
    """
    def __init__(self, campaign_id=None, campaign_name=None, ad_group=None):
        super(BulkAdGroup, self).__init__()

        self._campaign_id = campaign_id
        self._campaign_name = campaign_name
        self._ad_group = ad_group

        self._is_expired = None
        self._quality_score_data = None
        self._performance_data = None

    @property
    def campaign_id(self):
        """ The identifier of the campaign that contains the ad 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 ad 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 ad_group(self):
        """ The AdGroup Data Object of the Campaign Management Service.

        A subset of AdGroup properties are available in the Ad Group record.
        For more information, see Ad Group at http://go.microsoft.com/fwlink/?LinkID=511537.
        """
        return self._ad_group

    @ad_group.setter
    def ad_group(self, ad_group):
        self._ad_group = ad_group

    @property
    def is_expired(self):
        """ Indicates whether the AdGroup is expired.

        :rtype: bool
        """

        return self._is_expired

    @property
    def quality_score_data(self):
        """ The quality score data for the ad group.

        :rtype: QualityScoreData
        """
        return self._quality_score_data

    @property
    def performance_data(self):
        """ The historical performance data for the ad group.

        :rtype: PerformanceData
        """

        return self._performance_data

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.Id,
            field_to_csv=lambda c: bulk_str(c.ad_group.Id),
            csv_to_field=lambda c, v: setattr(c.ad_group, 'Id',
                                              int(v) if v else None)),
        _SimpleBulkMapping(header=_StringTable.Status,
                           field_to_csv=lambda c: 'Expired'
                           if c.is_expired else bulk_str(c.ad_group.Status),
                           csv_to_field=csv_to_status),
        _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.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.StartDate,
            field_to_csv=lambda c: bulk_date_str(c.ad_group.StartDate),
            csv_to_field=lambda c, v: setattr(c.ad_group, 'StartDate',
                                              parse_date(v))),
        _SimpleBulkMapping(
            header=_StringTable.EndDate,
            field_to_csv=lambda c: bulk_date_str(c.ad_group.EndDate),
            csv_to_field=lambda c, v: setattr(c.ad_group, 'EndDate',
                                              parse_date(v))),
        _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)),
        _SimpleBulkMapping(
            header=_StringTable.PricingModel,
            field_to_csv=lambda c: bulk_upper_str(c.ad_group.PricingModel),
            csv_to_field=lambda c, v: setattr(c.ad_group, 'PricingModel',
                                              v.title() if v else None)),
        _SimpleBulkMapping(
            header=_StringTable.AdRotation,
            field_to_csv=lambda c: ad_rotation_bulk_str(c.ad_group.AdRotation),
            csv_to_field=lambda c, v: setattr(c.ad_group, 'AdRotation',
                                              parse_ad_rotation(v))),
        _SimpleBulkMapping(
            header=_StringTable.SearchNetwork,
            field_to_csv=lambda c: None
            if not c.ad_group.AdDistribution else 'On'
            if 'Search' in c.ad_group.AdDistribution else 'Off',
            csv_to_field=lambda c, v: v == 'On' and setattr(
                c.ad_group, 'AdDistribution',
                (c.ad_group.AdDistribution + ' ' + 'Search').strip())),
        _SimpleBulkMapping(
            header=_StringTable.ContentNetwork,
            field_to_csv=lambda c: None
            if not c.ad_group.AdDistribution else 'On'
            if 'Content' in c.ad_group.AdDistribution else 'Off',
            csv_to_field=lambda c, v: v == 'On' and setattr(
                c.ad_group, 'AdDistribution',
                (c.ad_group.AdDistribution + ' ' + 'Content').strip())),
        _SimpleBulkMapping(
            header=_StringTable.SearchBroadBid,
            field_to_csv=lambda c: ad_group_bid_bulk_str(c.ad_group.
                                                         BroadMatchBid),
            csv_to_field=lambda c, v: setattr(c.ad_group, 'BroadMatchBid',
                                              parse_ad_group_bid(v))),
        _SimpleBulkMapping(
            header=_StringTable.ContentBid,
            field_to_csv=lambda c: ad_group_bid_bulk_str(c.ad_group.
                                                         ContentMatchBid),
            csv_to_field=lambda c, v: setattr(c.ad_group, 'ContentMatchBid',
                                              parse_ad_group_bid(v))),
        _SimpleBulkMapping(
            header=_StringTable.Language,
            field_to_csv=lambda c: c.ad_group.Language,
            csv_to_field=lambda c, v: setattr(c.ad_group, 'Language', v)),
        _SimpleBulkMapping(
            header=_StringTable.BidAdjustment,
            field_to_csv=lambda c: bulk_str(c.ad_group.NativeBidAdjustment),
            csv_to_field=lambda c, v: setattr(c.ad_group,
                                              'NativeBidAdjustment',
                                              int(v) if v else None)),
    ]

    def process_mappings_from_row_values(self, row_values):
        self.ad_group = _CAMPAIGN_OBJECT_FACTORY.create('AdGroup')
        self.ad_group.AdDistribution = ''

        row_values.convert_to_entity(self, BulkAdGroup._MAPPINGS)

        self._quality_score_data = QualityScoreData.read_from_row_values_or_null(
            row_values)
        self._performance_data = PerformanceData.read_from_row_values_or_null(
            row_values)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(self._ad_group, 'AdGroup')
        self.convert_to_values(row_values, BulkAdGroup._MAPPINGS)
        if not exclude_readonly_data:
            QualityScoreData.write_to_row_values_if_not_null(
                self.quality_score_data, row_values)
            PerformanceData.write_to_row_values_if_not_null(
                self.performance_data, row_values)

    def read_additional_data(self, stream_reader):
        super(BulkAdGroup, self).read_additional_data(stream_reader)
예제 #30
0
class _BulkAdExtensionAssociation(_SingleRecordBulkEntity):
    """ This class provides properties that are shared by all bulk ad extension association classes.

    For more information, see Bulk File Schema at http://go.microsoft.com/fwlink/?LinkID=511639.
    """
    def __init__(self,
                 ad_extension_id_to_entity_id_association=None,
                 status=None,
                 editorial_status=None):
        super(_BulkAdExtensionAssociation, self).__init__()

        self._status = status
        self._ad_extension_id_to_entity_id_association = ad_extension_id_to_entity_id_association
        self._editorial_status = editorial_status
        self._performance_data = None

    @property
    def ad_extension_id_to_entity_id_association(self):
        """ Defines an association relationship between an ad extension and a supported entity, for example a campaign or ad group.

        :rtype: AdExtensionIdToEntityIdAssociation
        """

        return self._ad_extension_id_to_entity_id_association

    @ad_extension_id_to_entity_id_association.setter
    def ad_extension_id_to_entity_id_association(self, value):
        self._ad_extension_id_to_entity_id_association = value

    @property
    def status(self):
        """ The status of the ad extension association.

        The value is Active if the EntityId and AdExtensionId are associated. The value is Deleted if the association is removed.
        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 editorial_status(self):
        """ The editorial status of the ad extension and associated entity.

        For more information, see AdExtensionEditorialStatus at http://go.microsoft.com/fwlink/?LinkId=511866.
        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 performance_data(self):
        return self._performance_data

    _MAPPINGS = [
        _SimpleBulkMapping(
            header=_StringTable.Id,
            field_to_csv=lambda c: bulk_str(
                c.ad_extension_id_to_entity_id_association.AdExtensionId),
            csv_to_field=lambda c, v: setattr(
                c.ad_extension_id_to_entity_id_association, 'AdExtensionId',
                int(v))),
        _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.ad_extension_id_to_entity_id_association.EntityId),
            csv_to_field=lambda c, v: setattr(
                c.ad_extension_id_to_entity_id_association, 'EntityId', int(v)
            )),
        _SimpleBulkMapping(
            header=_StringTable.EditorialStatus,
            field_to_csv=lambda c: c.editorial_status,
            csv_to_field=lambda c, v: setattr(c, '_editorial_status', v
                                              if v else None)),
    ]

    def process_mappings_from_row_values(self, row_values):
        self._ad_extension_id_to_entity_id_association = _CAMPAIGN_OBJECT_FACTORY.create(
            'AdExtensionIdToEntityIdAssociation')
        row_values.convert_to_entity(self,
                                     _BulkAdExtensionAssociation._MAPPINGS)
        self._performance_data = PerformanceData.read_from_row_values_or_null(
            row_values)

    def process_mappings_to_row_values(self, row_values,
                                       exclude_readonly_data):
        self._validate_property_not_null(
            self._ad_extension_id_to_entity_id_association,
            'ad_extension_id_to_entity_id_association')
        self.convert_to_values(row_values,
                               _BulkAdExtensionAssociation._MAPPINGS)
        if not exclude_readonly_data:
            PerformanceData.write_to_row_values_if_not_null(
                self.performance_data, row_values)

    def read_additional_data(self, stream_reader):
        super(_BulkAdExtensionAssociation,
              self).read_additional_data(stream_reader)