Пример #1
0
def dcm_api_list(endpoint):
    accounts = set(get_rows("user", project.task['accounts']))
    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(project.task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for item in API_DCM(
                project.task['auth'], iterate=True,
                internal=is_superuser).call(endpoint).list(**kwargs).execute():
            yield item
Пример #2
0
def get_profile_for_api(auth, account_id):
    """Return a DCM profile ID for the currently supplied credentials.

  Bulletproofing:
  https://developers.google.com/doubleclick-advertisers/v3.2/userProfiles/get

  Handles cases of superuser, otherwise chooses the first matched profile.
  Allows DCM jobs to only specify account ID, which makes jobs more portable
  between accounts.

  Args:
    * auth: (string) Either user or service.
    * account_id: (int) Account number for which report is retrieved.

  Returns:
    * Is Superuser ( bool ): True if superuser account
    * Profile ID ( int ): profile id to be used to make API call

  Raises:
    * If current credentials do not have a profile for this account.

  """

    profile_admin = None
    profile_network = None

    for p in API_DCM(auth, iterate=True).userProfiles().list().execute():
        p_id = int(p['profileId'])
        a_id = int(p['accountId'])

        # take the first profile for admin
        if a_id == 2515 and 'subAccountId' not in p:
            profile_admin = p_id
            break

        # try to find a network profile if exists
        if a_id == account_id:
            profile_network = p_id
            break

    if profile_admin:
        return True, profile_admin
    elif profile_network:
        return False, profile_network
    else:
        raise Exception('Add your user profile to DCM account %s.' %
                        account_id)
Пример #3
0
def get_creatives(accounts):

    if project.verbose: print 'DCM Ads'

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(project.task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for ad in API_DCM(
                "user", iterate=True,
                internal=is_superuser).creatives().list(**kwargs).execute():
            yield ad
Пример #4
0
def get_sites(accounts):

  if project.verbose: print 'DCM Sites'

  for account_id in accounts:
    is_superuser, profile_id = get_profile_for_api(project.task['auth'], account_id)
    kwargs = { 'profileId':profile_id, 'accountId':account_id } if is_superuser else { 'profileId':profile_id }
    for site in API_DCM("user", iterate=True, internal=is_superuser).sites().list(**kwargs).execute():
      if long(site['accountId']) in accounts: 

        for contact in site.get('siteContacts', []):
          SITE_CONTACTS.append([
            site['accountId'],
            site.get('subaccountId'),
            site.get('directorySiteId'),
            site['id'],
            contact['id'],
            contact['email'],
            contact.get('firstName', ''),
            contact.get('lastName', ''),
            contact.get('title', ''),
            contact.get('address', ''),
            contact.get('phone', ''),
            contact['contactType'],
          ])

        yield [
          site['accountId'],
          site.get('subaccountId'),
          site.get('directorySiteId'),
          site['id'],
          site['name'],
          site['keyName'],
          site['approved'],
          site.get('orientation'),
          site['siteSettings'].get('disableNewCookie'),
          site['siteSettings'].get('activeViewOptOut'),
          site['siteSettings'].get('adBlockingOptOut'),
          site['siteSettings'].get('videoActiveViewOptOutTemplate'),
          site['siteSettings'].get('vpaidAdapterChoiceTemplate'),
          site['siteSettings'].get('tagSetting', {}).get('additionalKeyValues'),
          site['siteSettings'].get('tagSetting', {}).get('includeClickTracking'),
          site['siteSettings'].get('tagSetting', {}).get('includeClickThroughUrls'),
          site['siteSettings'].get('tagSetting', {}).get('keywordOption'),
        ]
Пример #5
0
def cm_profile_load(config, task):

    cm_profile_clear(config, task)

    # write accounts to BQ
    put_rows(
        config, task['auth_bigquery'], {
            'bigquery': {
                'dataset':
                task['dataset'],
                'table':
                'CM_Profiles',
                'schema':
                Discovery_To_BigQuery('dfareporting', 'v3.4').method_schema(
                    'userProfiles.list', iterate=True),
                'format':
                'JSON'
            }
        },
        API_DCM(config, task['auth_cm'],
                iterate=True).userProfiles().list().execute())

    # write accounts to sheet
    put_rows(
        config, task['auth_sheets'], {
            'sheets': {
                'sheet': task['sheet'],
                'tab': 'CM Profiles',
                'header': False,
                'range': 'B2'
            }
        },
        get_rows(
            config, task['auth_bigquery'], {
                'bigquery': {
                    'dataset':
                    task['dataset'],
                    'query':
                    "SELECT CONCAT(accountName, ' - ', accountId), CONCAT(subAccountName, ' - ', subAccountId), profileId, userName FROM `%s.CM_Profiles`"
                    % task['dataset'],
                    'legacy':
                    False
                }
            }))
Пример #6
0
    def load_multiple():

        campaigns = [
            str(lookup_id(r)) for r in set(
                get_rows(config,
                         task['auth_cm'], {
                             'sheets': {
                                 'sheet': task['sheet'],
                                 'tab': 'CM Campaigns',
                                 'header': False,
                                 'range': 'A2:A'
                             }
                         },
                         unnest=True))
        ]

        for row in get_rows(
                config, task['auth_sheets'], {
                    'sheets': {
                        'sheet': task['sheet'],
                        'tab': 'CM Accounts',
                        'header': False,
                        'range': 'A2:A'
                    }
                }):
            if row:
                account_id = lookup_id(row[0])

                is_superuser, profile_id = get_profile_for_api(
                    config, task['auth_cm'], account_id)
                kwargs = {
                    'profileId': profile_id,
                    'campaignIds': campaigns,
                    'archived': False
                }
                if is_superuser:
                    kwargs['accountId'] = account_id

                yield from API_DCM(
                    config,
                    task['auth_cm'],
                    iterate=True,
                    internal=is_superuser).placementGroups().list(
                        **kwargs).execute()
Пример #7
0
def get_campaigns(accounts):

    if project.verbose:
        print('DCM Campaigns')

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(project.task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for campaign in API_DCM(
                'user', iterate=True,
                internal=is_superuser).campaigns().list(**kwargs).execute():
            if int(campaign['accountId']) in accounts:

                yield [
                    campaign['accountId'],
                    campaign.get('subaccountId'),
                    campaign['advertiserId'],
                    campaign.get('advertiserGroupId'),
                    campaign['id'],
                    campaign['name'],
                    campaign['archived'],
                    campaign['startDate'],
                    campaign['endDate'],
                    campaign.get('comment', ''),
                    epoch_to_datetime(campaign['createInfo']['time'], 1000),
                    epoch_to_datetime(campaign['lastModifiedInfo']['time'],
                                      1000),
                    campaign.get('externalId'),
                    campaign['defaultLandingPageId'],
                    campaign['adBlockingConfiguration']['enabled'],
                    campaign['adBlockingConfiguration']
                    ['overrideClickThroughUrl'],
                    campaign['adBlockingConfiguration'].get('clickThroughUrl'),
                    campaign['adBlockingConfiguration'].get(
                        'creativeBundleId'),
                    campaign['nielsenOcrEnabled'],
                ]
Пример #8
0
def get_reports(accounts):

  if project.verbose: print 'DCM Reports'

  for account_id in accounts:
    is_superuser, profile_id = get_profile_for_api(project.task['auth'], account_id)
    kwargs = { 'profileId':profile_id, 'accountId':account_id, 'scope':'ALL' } if is_superuser else { 'profileId':profile_id, 'scope':'ALL' }
    for report in API_DCM("user", iterate=True, internal=is_superuser).reports().list(**kwargs).execute():
      if long(report['accountId']) in accounts:
  
        for delivery in report.get('delivery', {}).get('recipients', []):
          REPORT_DELIVERIES.append((
            report['ownerProfileId'],
            report['accountId'],
            report.get('subaccountId'),
            report['id'],
            report['delivery']['emailOwner'],
            report['delivery'].get('emailOwnerDeliveryType'),
            report['delivery'].get('message', ''),
            delivery['email'],
            delivery['deliveryType'],
          ))
 
        yield [
          report['ownerProfileId'],
          report['accountId'],
          report.get('subaccountId'),
          report['id'],
          report['name'],
          report['type'],
          report.get('format'),
          epoch_to_datetime(report.get('lastModifiedTime'), 1000),
          report.get('criteria', {}).get('startDate'),
          report.get('criteria', {}).get('endDate'),
          report.get('criteria', {}).get('relativeDateRange'),
          report.get('schedule', {}).get('active'),
          report.get('schedule', {}).get('startDate'),
          report.get('schedule', {}).get('expirationDate'),
          report.get('schedule', {}).get('runsOnDayOfMonth'),
          report.get('schedule', {}).get('repeats'),
          report.get('schedule', {}).get('every'),
          ','.join(report.get('schedule', {}).get('repeatsOnWeekDays', [])),
        ]
Пример #9
0
def get_account_name(auth, account):
  """ Return the name of a DCM account given the account ID.

  Args:
    * auth: (string) Either user or service.
    * account: (string) [account:advertiser@profile] token.

  Returns:
    * Profile ID.

  Raises:
    * If current credentials do not have a profile for this account.

  """

  account_id, advertiser_ids = parse_account(auth, account)
  is_superuser, profile_id = get_profile_for_api(auth, account_id)
  response = API_DCM(auth, internal=is_superuser).accounts().get(id=account_id, profileId=profile_id).execute()
  return response["name"]
Пример #10
0
def report_list(auth, account):
  """ Lists all the DCM report configurations for an account given the current credentials.

  Bulletproofing: https://developers.google.com/doubleclick-advertisers/v3.2/reports/list

  Args:
    * auth: (string) Either user or service.
    * account: (string) [account:advertiser@profile] token.

  Returns:
    * Iterator of JSONs.

  """

  account_id, advertiser_id = parse_account(auth, account)
  is_superuser, profile_id = get_profile_for_api(auth, account_id)
  kwargs = { 'profileId':profile_id, 'accountId':account_id } if is_superuser else { 'profileId':profile_id }
  for report in API_DCM(auth, internal=is_superuser).reports().list(**kwargs).execute():
    yield report
Пример #11
0
def bulkdozer_test():
    print('testing bulkdozer')

    if 'verify' in project.task['traffic']:
        is_admin, profile_id = get_profile_for_api(
            project.task['auth'], project.task['traffic']['account_id'])

        for entity in project.task['traffic']['verify']:
            service = getattr(API_DCM(project.task['auth'], internal=is_admin),
                              entity['type'])
            cm_entity = service().get(profileId=profile_id,
                                      id=entity['id']).execute()

            values = entity['values']

            for key in values:
                if values[key] != cm_entity[key]:
                    raise '%s %s expected to be %s, was %s' % (
                        entity['type'], key, values[key], cm_entity[key])
Пример #12
0
def report_run(auth, account, report_id=None, name=None):
  """ Trigger a DCM report to run by name or ID. Will do nothing if report is currently in progress.

  Bulletproofing: https://developers.google.com/doubleclick-advertisers/v3.3/reports/run

  Args:
    * auth: (string) Either user or service.
    * account: (string) [account:advertiser@profile] token.
    * report_id: (int) ID of DCm report to fetch ( either or name ).
    * name: (string) Name of report to fetch ( either or report_id ).

  Returns:
    * True if report run is executed
    * False otherwise

  """

  account_id, advertiser_id = parse_account(auth, account)
  is_superuser, profile_id = get_profile_for_api(auth, account_id)
  kwargs = { 'profileId':profile_id, 'accountId':account_id } if is_superuser else { 'profileId':profile_id }

  if project.verbose: print('DCM REPORT RUN INIT', report_id or name)
  if report_id is None:
    report = report_get(auth, account, name=name)
    if report is None:
      raise Exception('Report does not exist:', name)
    else:
      report_id = report['id']

  kwargs = { 'profileId':profile_id, 'accountId':account_id } if is_superuser else { 'profileId':profile_id }
  kwargs['reportId'] = report_id

  files = report_files(auth, account, report_id)
  latest_file_json = next(files, None)
  if latest_file_json == None or latest_file_json['status'] != 'PROCESSING':
    # run report if previously never run or currently not running
    if project.verbose: print('RUNNING REPORT', report_id or name)
    API_DCM(auth, internal=is_superuser).reports().run(**kwargs).execute()
    return True
  if project.verbose: print('REPORT RUN SKIPPED', report_id or name)
  return False
Пример #13
0
def report_files(auth, account, report_id):
  """ Lists all the files available for a given DCM report configuration.

  Bulletproofing: https://developers.google.com/doubleclick-advertisers/v3.2/files/list

  Args:
    * auth: (string) Either user or service.
    * account: (string) [account:advertiser@profile] token.
    * report_id: (int) DCM report identifier.

  Returns:
    * Iterator of JSONs.

  """

  account_id, advertiser_id = parse_account(auth, account)
  is_superuser, profile_id = get_profile_for_api(auth, account_id)
  kwargs = { 'profileId':profile_id, 'accountId':account_id } if is_superuser else { 'profileId':profile_id }
  kwargs['reportId'] = report_id
  for report_file in API_DCM(auth, internal=is_superuser).reports().files().list(**kwargs).execute():
    yield report_file
Пример #14
0
 def load_multiple():
   for row in get_rows(
     config,
     task['auth_sheets'],
     { 'sheets': {
       'sheet': task['sheet'],
       'tab': 'CM Profiles',
       'header':False,
       'range': 'A2:A'
     }}
   ):
     if row:
       account_id = lookup_id(row[0])
       is_superuser, profile_id = get_profile_for_api(config, task['auth_cm'], account_id)
       kwargs = { 'profileId': profile_id, 'accountId': account_id } if is_superuser else { 'profileId': profile_id }
       yield from API_DCM(
         config,
         task['auth_cm'],
         iterate=True,
         internal=is_superuser
       ).accounts().list(**kwargs).execute()
Пример #15
0
def get_subaccounts(accounts):

    if project.verbose: print('DCM SubAccounts')

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(project.task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for subaccount in API_DCM(
                "user", iterate=True,
                internal=is_superuser).subaccounts().list(**kwargs).execute():
            if int(subaccount['accountId']) in accounts:
                yield [
                    subaccount['accountId'],
                    subaccount['id'],
                    subaccount['name'],
                ]
Пример #16
0
def get_roles(accounts):
    if project.verbose:
        print('DCM Roles')

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(project.task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for role in API_DCM(
                'user', iterate=True,
                internal=is_superuser).userRoles().list(**kwargs).execute():
            if int(role['accountId']) in accounts:
                if 'permissions' in role:
                    for permission in role['permissions']:
                        yield [
                            role['accountId'],
                            role.get('subaccountId'),
                            role['id'],
                            role['name'],
                            role['defaultUserRole'],
                            permission['name'],
                            permission['availability'],
                        ]
                else:
                    yield [
                        role['accountId'],
                        role.get('subaccountId'),
                        role['id'],
                        role['name'],
                        role['defaultUserRole'],
                        None,
                        None,
                    ]
Пример #17
0
def get_advertisers(accounts):

  if project.verbose: print 'DCM Advertisers'

  for account_id in accounts:
    is_superuser, profile_id = get_profile_for_api(project.task['auth'], account_id)
    kwargs = { 'profileId':profile_id, 'accountId':account_id } if is_superuser else { 'profileId':profile_id }
    for advertiser in API_DCM("user", iterate=True, internal=is_superuser).advertisers().list(**kwargs).execute():
      if long(advertiser['accountId']) in accounts: 
        yield [
          advertiser['accountId'],
          advertiser.get('subaccountId'),
          advertiser['id'],
          advertiser.get('advertiserGroupId'),
          advertiser['name'],
          advertiser['status'],
          advertiser.get('defaultEmail'),
          advertiser.get('clickThroughUrlSuffix'),
          advertiser.get('defaultClickThroughEventTagId'),
          advertiser['suspended'],
          advertiser['floodlightConfigurationId'],
          advertiser['originalFloodlightConfigurationId'],
       ]
Пример #18
0
def report_build(auth, account, body):
    """ Creates a DCM report given a JSON definition.

  Bulletproofing:
  https://developers.google.com/doubleclick-advertisers/v3.2/reports/insert

  The body JSON provided will have the following fields overriden:
    * accountId - supplied as a parameter in account token.
    * ownerProfileId - determined from the current credentials.
    * advertiser_ids - supplied as a parameter in account token.

  Args:
    * auth: (string) Either user or service.
    * account: (string) [account:advertiser@profile] token.
    * body: (json) As defined in:
      https://developers.google.com/doubleclick-advertisers/v3.2/reports#resource

  Returns:
    * JSON definition of report created or existing.

  """

    report = report_get(auth, account, name=body['name'])

    if report is None:
        account_id, advertiser_ids = parse_account(auth, account)
        is_superuser, profile_id = get_profile_for_api(auth, account_id)

        # add the account id to the body
        body['accountId'] = account_id
        body['ownerProfileId'] = profile_id

        # add advertisers to the body, ignore for floodlight reports
        if advertiser_ids and 'criteria' in body:
            body['criteria']['dimensionFilters'] = body.get(
                'criteria', {}).get('dimensionFilters',
                                    []) + [{
                                        'kind': 'dfareporting#dimensionValue',
                                        'dimensionName': 'dfa:advertiser',
                                        'id': advertiser_id,
                                        'matchType': 'EXACT'
                                    } for advertiser_id in advertiser_ids]

        # add default daily schedule if it does not exist ( convenience )
        if 'schedule' not in body:
            body['schedule'] = {'active': True, 'repeats': 'DAILY', 'every': 1}

        # add default start and end if it does not exist ( convenience )
        if 'startDate' not in body['schedule']:
            body['schedule']['startDate'] = str(date.today())

        # add default start and end if it does not exist ( convenience )
        if 'expirationDate' not in body['schedule']:
            body['schedule']['expirationDate'] = str(
                (date.today() + timedelta(days=365)))

        #pprint.PrettyPrinter().pprint(body)

        # create the report
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        kwargs['body'] = body
        report = API_DCM(
            auth, internal=is_superuser).reports().insert(**kwargs).execute()

        # run the report
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        kwargs['reportId'] = report['id']
        API_DCM(auth, internal=is_superuser).reports().run(**kwargs).execute()

    else:
        if project.verbose:
            print('DCM Report Exists:', body['name'])

    return report
Пример #19
0
    # initialize project
    project.from_commandline(parser=parser)
    auth = 'service' if project.args.service else 'user'

    is_superuser, profile = get_profile_for_api(auth, project.args.account)
    kwargs = {
        'profileId': profile,
        'accountId': project.args.account
    } if is_superuser else {
        'profileId': profile
    }

    # get report list
    if project.args.report:
        kwargs['reportId'] = project.args.report
        report = API_DCM(
            auth, internal=is_superuser).reports().get(**kwargs).execute()
        print json.dumps(report, indent=2, sort_keys=True)

    # get report files
    elif project.args.files:
        kwargs['reportId'] = project.args.files
        for report_file in API_DCM(
                auth, internal=is_superuser).reports().files().list(
                    **kwargs).execute():
            print json.dumps(report_file, indent=2, sort_keys=True)

    # get schema
    elif project.args.schema:
        filename, report = report_file(auth, project.args.account,
                                       project.args.schema, None, 10)
        rows = report_to_rows(report)
Пример #20
0
                        help='report ID to pull file list',
                        default=None)
    parser.add_argument('--list', help='list reports', action='store_true')

    # initialize project
    project.from_commandline(parser=parser)
    auth = 'service' if project.args.service else 'user'

    kwargs = {}
    if project.args.account: kwargs['accountId'] = project.args.account
    if project.args.profile: kwargs['profileId'] = project.args.profile

    # get report list
    if project.args.report:
        kwargs['reportId'] = project.args.report
        report = API_DCM(auth).reports().get(**kwargs).execute()
        print json.dumps(report, indent=2, sort_keys=True)

    # get report files
    elif project.args.files:
        kwargs['reportId'] = project.args.files
        for report_file in API_DCM(auth).reports().files().list(
                **kwargs).execute():
            print json.dumps(report_file, indent=2, sort_keys=True)

    # get schema
    elif project.args.schema:
        filename, report = report_file(auth, project.args.account,
                                       project.args.schema, None, 10)
        rows = report_to_rows(report)
        rows = report_clean(rows)
Пример #21
0
def get_profiles(accounts):
    if project.verbose: print('DCM Profiles')

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(project.task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for profile in API_DCM(
                "user", iterate=True,
                internal=is_superuser).accountUserProfiles().list(
                    **kwargs).execute():
            if int(profile['accountId']) in accounts:

                for campaign in profile.get('campaignFilter',
                                            {}).get('objectIds', []):
                    PROFILE_CAMPAIGNS.append([
                        profile['id'],
                        profile['accountId'],
                        profile.get('subaccountId'),
                        campaign,
                    ])

                for site in profile.get('siteFilter', {}).get('objectIds', []):
                    PROFILE_SITES.append([
                        profile['id'],
                        profile['accountId'],
                        profile.get('subaccountId'),
                        site,
                    ])

                for role in profile.get('userRoleFilter',
                                        {}).get('objectIds', []):
                    PROFILE_ROLES.append([
                        profile['id'],
                        profile['accountId'],
                        profile.get('subaccountId'),
                        role,
                    ])

                for advertiser in profile.get('advertiserFilter',
                                              {}).get('objectIds', []):
                    PROFILE_ADVERTISERS.append([
                        profile['id'],
                        profile['accountId'],
                        profile.get('subaccountId'),
                        advertiser,
                    ])

                yield [
                    profile['id'],
                    profile['accountId'],
                    profile.get('subaccountId'),
                    profile['name'],
                    profile['email'],
                    profile.get('locale'),
                    profile.get('userRoleId'),
                    profile.get('userAccessType'),
                    profile['active'],
                    profile.get('comments', ''),
                    profile.get('traffickerType'),
                ]
Пример #22
0
def report_create(auth, account, name, config):
    account_id, advertiser_ids = parse_account(auth, account)
    is_superuser, profile_id = get_profile_for_api(auth, account_id)
    report = report_get(auth, account_id, name=name)

    if report is None:

        body = {
            'kind': 'dfareporting#report',
            'type': config.get('type', 'STANDARD').upper(),
            'name': name,
            'format': config.get('format', 'CSV'),
            'accountId': account_id,
            'delivery': {
                'emailOwner': False,
                'emailOwnerDeliveryType': 'LINK'
            },
            'schedule': {
                'active': True,
                'repeats': 'DAILY',
                'every': 1,
                'startDate': str(date.today()),
                'expirationDate': str((date.today() + timedelta(days=365))),
            }
        }

        if body['type'] == 'STANDARD': body.update(get_body_standard(config))
        elif body['type'] == 'FLOODLIGHT':
            body.update(get_body_floodlight(config))

        if advertiser_ids:
            body['criteria']['dimensionFilters'] = body['criteria'].get(
                'dimensionFilters', []) + [{
                    'kind': 'dfareporting#dimensionValue',
                    'dimensionName': 'dfa:advertiser',
                    'id': advertiser_id,
                    'matchType': 'EXACT'
                } for advertiser_id in advertiser_ids]

        #pprint.PrettyPrinter().pprint(body)

        # create the report
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        kwargs['body'] = body
        report = API_DCM(
            auth, internal=is_superuser).reports().insert(**kwargs).execute()

        # run the report
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        kwargs['reportId'] = report['id']
        API_DCM(auth,
                internal=is_superuser).reports().insert(**kwargs).execute()

    return report
Пример #23
0
def itp_audit_cm():
    account_id = project.task['account']
    # Read Advertiser Ids
    advertiser_ids = list(
        get_rows('service', project.task['read']['advertiser_ids']))
    is_superuser, profile_id = get_profile_for_api('user', account_id)

    datasets_create('user', project.id, project.task['dataset'])

    placements = {}
    campaignNames = {}
    siteNames = {}
    advertiserNames = {}

    for c in API_DCM('user', iterate=True,
                     internal=is_superuser).campaigns().list(
                         archived=False,
                         profileId=profile_id,
                         accountId=account_id,
                         advertiserIds=advertiser_ids
                         if advertiser_ids else None).execute():
        # only keep campaigns with end dates in the future or less than 90 days ago
        if ((date.fromisoformat(c['endDate']) - date.today()).days > -90):
            campaignNames[c['id']] = {
                'id': c['id'],
                'name': c['name'],
                'startDate': c['startDate'],
                'endDate': c['endDate']
            }

    validCampaignIds = [int(i) for i in campaignNames.keys()]

    for s in API_DCM('user', iterate=True, internal=is_superuser).sites().list(
            profileId=profile_id,
            accountId=account_id,
            campaignIds=validCampaignIds).execute():
        siteNames[s['id']] = s['name']

    for a in API_DCM('user', iterate=True,
                     internal=is_superuser).advertisers().list(
                         profileId=profile_id,
                         accountId=account_id,
                         ids=advertiser_ids[:500]
                         if advertiser_ids else None).execute():
        advertiserNames[a['id']] = a['name']

    if len(advertiser_ids) > 500:
        for a in API_DCM('user', iterate=True,
                         internal=is_superuser).advertisers().list(
                             profileId=profile_id,
                             accountId=account_id,
                             ids=advertiser_ids[500:]
                             if advertiser_ids else None).execute():
            advertiserNames[a['id']] = a['name']

    for p in API_DCM(
            'user', iterate=True, internal=is_superuser).placements().list(
                archived=False,
                profileId=profile_id,
                accountId=account_id,
                advertiserIds=advertiser_ids if advertiser_ids else None,
                campaignIds=validCampaignIds).execute():
        # exclude 1x1 tracking placements
        if not (p['size']['height'] == 1 and p['size']['width'] == 1):
            placements[p['id']] = {
                'id': p['id'],
                'name': p['name'],
                'advertiserId': p['advertiserId'],
                'advertiserName': advertiserNames[p['advertiserId']],
                'campaignId': p['campaignId'],
                'campaignName': campaignNames[p['campaignId']]['name'],
                'siteId': p['siteId'],
                'siteName': siteNames[p['siteId']],
                'adsTotal': 0,
                'adsNotImpacted': 0,
                'adsFrequencyCapped': 0,
                'adsAudienceSegmentation': 0,
                'adsAudienceListTargeting': 0,
                'adsDynamicCreative': 0,
                'adsPlatformBrowserTargeting': 0
            }

    for ad in API_DCM('user', iterate=True, internal=is_superuser).ads().list(
            type='AD_SERVING_STANDARD_AD',
            profileId=profile_id,
            accountId=account_id,
            campaignIds=validCampaignIds).execute():
        # only analyze standard, non-default priority ads that have been assigned 1+ placements and creatives
        if ad['deliverySchedule'][
                'priority'] != "AD_PRIORITY_16" and 'placementAssignments' in ad and 'creativeAssignments' in ad[
                    'creativeRotation']:
            hasDynamicCreative = False
            for creative in ad['creativeRotation']['creativeAssignments']:
                if 'richMediaExitOverrides' in creative:
                    hasDynamicCreative = True
                    break

            for p in ad['placementAssignments']:
                if p['placementId'] in placements:
                    knownPlacement = placements[p['placementId']]
                    knownPlacement['adsTotal'] += 1

                    if 'frequencyCap' in ad['deliverySchedule']:
                        knownPlacement['adsFrequencyCapped'] += 1
                    if 'audienceSegmentId' in ad:
                        knownPlacement['adsAudienceSegmentation'] += 1
                    if 'remarketingListExpression' in ad:
                        knownPlacement['adsAudienceListTargeting'] += 1
                    if 'technologyTargeting' in ad and (
                            'browsers' in ad['technologyTargeting']
                            or 'platformTypes' in ad['technologyTargeting']):
                        knownPlacement['adsPlatformBrowserTargeting'] += 1
                    if hasDynamicCreative:
                        knownPlacement['adsDynamicCreative'] += 1
                    if not 'frequencyCap' in ad[
                            'deliverySchedule'] and not 'audienceSegmentId' in ad and not 'remarketingListExpression' in ad:
                        knownPlacement['adsNotImpacted'] += 1

    write_data = []
    for p in placements.values():
        write_data.append([
            p['name'] + ' - ' + str(p['id']), p['id'], p['name'],
            p['advertiserName'] + ' - ' + str(p['advertiserId']),
            p['advertiserId'], p['advertiserName'],
            p['campaignName'] + ' - ' + str(p['campaignId']), p['campaignId'],
            p['campaignName'], p['siteId'], p['siteName'], p['adsTotal'],
            p['adsNotImpacted'], p['adsFrequencyCapped'],
            p['adsAudienceListTargeting'], p['adsAudienceSegmentation'],
            p['adsPlatformBrowserTargeting'], p['adsDynamicCreative']
        ])

    placements_out = {}
    placements_out["bigquery"] = {
        "dataset": project.task['dataset'],
        "table": CM_PLACEMENT_AUDIT_TABLE,
        "is_incremental_load": False,
        "datastudio": True,
        "schema": PLACEMENTS_SCHEMA,
        "skip_rows": 0
    }

    if placements: put_rows('service', placements_out, write_data)
Пример #24
0
def main():

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=textwrap.dedent("""\
      Command line to help debug CM reports and build reporting tools.

      Examples:
        To get list of reports: python cm.py --account [id] --list -u [user credentials path]
        To get report: python cm.py --account [id] --report [id] -u [user credentials path]
        To get report files: python cm.py --account [id] --files [id] -u [user credentials path]
        To get report sample: python cm.py --account [id] --sample [id] -u [user credentials path]
        To get report schema: python cm.py --account [id] --schema [id] -u [user credentials path]

  """))

    parser.add_argument('--account',
                        help='Account ID to use to pull the report.',
                        default=None)
    parser.add_argument('--report',
                        help='Report ID to pull JSON definition.',
                        default=None)
    parser.add_argument('--schema',
                        help='Report ID to pull achema definition.',
                        default=None)
    parser.add_argument('--sample',
                        help='Report ID to pull sample data.',
                        default=None)
    parser.add_argument('--files',
                        help='Report ID to pull file list.',
                        default=None)
    parser.add_argument('--list', help='List reports.', action='store_true')

    # initialize project
    parser = commandline_parser(parser, arguments=('-u', '-c', '-s', '-v'))
    args = parser.parse_args()
    config = Configuration(user=args.user,
                           client=args.client,
                           service=args.service,
                           verbose=args.verbose)

    auth = 'service' if args.service else 'user'

    is_superuser, profile = get_profile_for_api(config, auth, args.account)
    kwargs = {
        'profileId': profile,
        'accountId': args.account
    } if is_superuser else {
        'profileId': profile
    }

    # get report list
    if args.report:
        kwargs['reportId'] = args.report
        report = API_DCM(
            config, auth,
            internal=is_superuser).reports().get(**kwargs).execute()
        print(json.dumps(report, indent=2, sort_keys=True))

    # get report files
    elif args.files:
        kwargs['reportId'] = args.files
        for rf in API_DCM(
                config, auth, internal=is_superuser,
                iterate=True).reports().files().list(**kwargs).execute():
            print(json.dumps(rf, indent=2, sort_keys=True))

    # get schema
    elif args.schema:
        filename, report = report_file(config, auth, args.account, args.schema,
                                       None, 10)
        rows = report_to_rows(report)
        rows = report_clean(rows)
        print(json.dumps(report_schema(next(rows)), indent=2, sort_keys=True))

    # get sample
    elif args.sample:
        filename, report = report_file(config, auth, args.account, args.sample,
                                       None, 10)
        rows = report_to_rows(report)
        rows = report_clean(rows)
        rows = rows_to_type(rows)
        for r in rows_print(rows, row_min=0, row_max=20):
            pass

    # get list
    else:
        for report in API_DCM(config,
                              auth,
                              internal=is_superuser,
                              iterate=True).reports().list(**kwargs).execute():
            print(json.dumps(report, indent=2, sort_keys=True))
Пример #25
0
def conversions_upload(auth,
                       account,
                       floodlight_activity_id,
                       conversion_type,
                       conversion_rows,
                       encryption_entity=None,
                       update=False):
    """ Uploads an offline conversion list to DCM.

  BulletProofing:
  https://developers.google.com/doubleclick-advertisers/guides/conversions_upload

  Handles errors and segmentation of conversion so list can be any size.

  Args:
    * auth: (string) Either user or service.
    * account: (string) [account:advertiser@profile] token.
    * floodlight_activity_id: (int) ID of DCM floodlight to upload conversions
      to.
    * converstion_type: (string) One of the following: encryptedUserId,
      encryptedUserIdCandidates, gclid, mobileDeviceId.
    * conversion_rows: (iterator) List of the following rows: Ordinal,
      timestampMicros, encryptedUserId | encryptedUserIdCandidates | gclid |
      mobileDeviceId.
    * encryption_entity: (object) See EncryptionInfo docs:
      https://developers.google.com/doubleclick-advertisers/v3.2/conversions/batchinsert#encryptionInfo
  """

    account_id, advertiser_id = parse_account(auth, account)
    is_superuser, profile_id = get_profile_for_api(auth, account_id)

    kwargs = {
        'profileId': profile_id,
        'accountId': account_id
    } if is_superuser else {
        'profileId': profile_id
    }
    kwargs['id'] = floodlight_activity_id
    response = API_DCM(
        auth,
        internal=is_superuser).floodlightActivities().get(**kwargs).execute()

    # upload in batch sizes of DCM_CONVERSION_SIZE
    row_count = 0
    row_buffer = []
    for is_last, row in flag_last(conversion_rows):
        row_buffer.append(row)

        if is_last or len(row_buffer) == DCM_CONVERSION_SIZE:

            if project.verbose:
                print('CONVERSION UPLOADING ROWS: %d - %d' %
                      (row_count, row_count + len(row_buffer)))

            body = {
                'conversions': [{
                    'floodlightActivityId':
                    floodlight_activity_id,
                    'floodlightConfigurationId':
                    response['floodlightConfigurationId'],
                    'ordinal':
                    row[0],
                    'timestampMicros':
                    row[1],
                    'quantity':
                    1,
                    'value':
                    0.0,
                    conversion_type:
                    row[2],
                } for row in row_buffer]
            }

            if encryption_entity:
                body['encryptionInfo'] = encryption_entity

            kwargs = {
                'profileId': profile_id,
                'accountId': account_id
            } if is_superuser else {
                'profileId': profile_id
            }
            kwargs['body'] = body

            if update:
                results = API_DCM(
                    auth, internal=is_superuser).conversions().batchupdate(
                        **kwargs).execute()
            else:
                results = API_DCM(
                    auth, internal=is_superuser).conversions().batchinsert(
                        **kwargs).execute()

            # stream back satus
            for status in results['status']:
                yield status

            # clear the buffer
            row_count += len(row_buffer)
            row_buffer = []
Пример #26
0
 def _api(self, iterate=False):
     """Returns an DCM API instance.  Must be overloaded by one of the derived classes and extended for specific endpoint."""
     return API_DCM(self.auth, iterate, self.is_admin)