Example #1
0
def get_changelogs(config, task, accounts, start):

    if config.verbose:
        print('CM CHANGE LOGS', accounts)

    for account_id in accounts:

        is_superuser, profile_id = get_profile_for_api(config, task['auth'],
                                                       account_id)
        kwargs = {'profileId': profile_id, 'minChangeTime': start}
        if is_superuser:
            kwargs['accountId'] = account_id

        for changelog in API_DCM(
                config, 'user', iterate=True,
                internal=is_superuser).changeLogs().list(**kwargs).execute():
            yield [
                changelog.get('userProfileId'),
                changelog['accountId'],
                changelog.get('subaccountId'),
                changelog['id'],
                changelog['transactionId'],
                changelog['objectType'],
                changelog['objectId'],
                changelog['action'],
                changelog.get('fieldName'),
                changelog['changeTime'],
                changelog.get('oldValue'),
                changelog.get('newValue'),
            ]
Example #2
0
def get_advertisers(config, task, accounts):

    if config.verbose:
        print('DCM Advertisers')

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(config, task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for advertiser in API_DCM(
                config, 'user', iterate=True,
                internal=is_superuser).advertisers().list(**kwargs).execute():
            if int(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'],
                ]
Example #3
0
def get_sites(config, task, accounts):

    if config.verbose:
        print('DCM Sites')

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(config, task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for site in API_DCM(
                config, 'user', iterate=True,
                internal=is_superuser).sites().list(**kwargs).execute():
            if int(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'),
                ]
Example #4
0
def get_reports(config, task, accounts):

    if config.verbose:
        print('DCM Reports')

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(config, 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(
                config, 'user', iterate=True,
                internal=is_superuser).reports().list(**kwargs).execute():
            if int(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',
                                                       [])),
                ]
Example #5
0
def setup(config, task):
    """Sets up Bulkdozer configuration and required object to execute the job."""

    if 'dcm_profile_id' not in task and 'account_id' in task:
        task['is_admin'], task['dcm_profile_id'] = get_profile_for_api(
            config, task['auth'], task['account_id'])

    if 'is_admin' not in task:
        task['is_admin'] = False

    if 'sheet_url' in task and 'sheet_id' not in task:
        task['sheet_id'] = task['sheet_url']

    # Setting up required objects and parsing parameters
    logger.config = config
    logger.auth = task['auth']
    logger.trix_id = task.get('logger', {}).get('sheet_id', task['sheet_id'])
    logger.buffered = True
Example #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()
Example #7
0
def get_campaigns(config, task, accounts):

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

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(config, task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for campaign in API_DCM(
                config, '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'],
                ]
Example #8
0
def bulkdozer_test(config, task):
    print('testing bulkdozer')

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

        for entity in task['traffic']['verify']:
            service = getattr(API_DCM(config, 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 ValueError(
                        '%s %s expected to be %s, was %s' %
                        (entity['type'], key, values[key], cm_entity[key]))
Example #9
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()
Example #10
0
def google_api_initilaize(config, api_call, alias=None):
    """Some Google API calls require a lookup or pre-call, add it here.

  Modifies the API call before actual execution with any data
  specifically required by an endpoint.  Currently:

    > dfa-reporting - look up user profile and add to call.

  Args:
    api_call (dict): the JSON for the API call as defined in recipe.
    alias (string): mostly used to signal a list behavior (change to iterate in future?)

  Returns (dict):
    A modified JSON with additional API values added.
    Currently mostly used by dfareporting API to add profile and account.

  Raises:
    ValueError: If a required key in the recipe is missing.
  """

    if api_call['function'].endswith('list') or alias == 'list':
        api_call['iterate'] = True

    if api_call['api'] == 'dfareporting':

        if not api_call['function'].startswith('userProfiles'):

            is_superuser, profile_id = get_profile_for_api(
                config, api_call['auth'],
                api_call['kwargs']['id'] if api_call['function']
                == 'accounts.get' else api_call['kwargs']['accountId'])
            api_call['kwargs']['profileId'] = profile_id

            if is_superuser:
                from starthinker.util.cm_internalv33_uri import URI as DCM_URI
                api_call['version'] = 'internalv3.3'
                api_call['uri'] = DCM_URI
            elif 'accountId' in api_call['kwargs']:
                del api_call['kwargs']['accountId']
Example #11
0
def get_accounts(config, task, accounts):
    if config.verbose:
        print('DCM Accounts')

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(config, task['auth'],
                                                       account_id)
        kwargs = {'profileId': profile_id, 'id': account_id}
        account = API_DCM(config, 'user').accounts().get(**kwargs).execute()
        yield [
            account['id'],
            account['name'],
            account['active'],
            account.get('description', ''),
            id_to_timezone(
                account['reportsConfiguration']['reportGenerationTimeZoneId']),
            account.get('currencyId'),
            account.get('countryId'),
            account['locale'],
            account['nielsenOcrEnabled'],
            account['shareReportsWithTwitter'],
        ]
Example #12
0
def get_roles(config, task, accounts):
    if config.verbose:
        print('DCM Roles')

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(config, task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for role in API_DCM(
                config, '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.get('availability'),
                        ]
                else:
                    yield [
                        role['accountId'],
                        role.get('subaccountId'),
                        role['id'],
                        role['name'],
                        role['defaultUserRole'],
                        None,
                        None,
                    ]
Example #13
0
def get_subaccounts(config, task, accounts):

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

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(config, task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for subaccount in API_DCM(
                config, 'user', iterate=True,
                internal=is_superuser).subaccounts().list(**kwargs).execute():
            if int(subaccount['accountId']) in accounts:
                yield [
                    subaccount['accountId'],
                    subaccount['id'],
                    subaccount['name'],
                ]
Example #14
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))
Example #15
0
def get_profiles(config, task, accounts):
    if config.verbose:
        print('DCM Profiles')

    for account_id in accounts:
        is_superuser, profile_id = get_profile_for_api(config, task['auth'],
                                                       account_id)
        kwargs = {
            'profileId': profile_id,
            'accountId': account_id
        } if is_superuser else {
            'profileId': profile_id
        }
        for profile in API_DCM(
                config, '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'),
                ]
Example #16
0
def itp_audit_cm(config, task):
  account_id = task['account']
  # Read Advertiser Ids
  advertiser_ids = list(get_rows(config, task['auth_bq'], task['read']['advertiser_ids']))
  is_superuser, profile_id = get_profile_for_api(config, task['auth_cm'], account_id)

  datasets_create(config, task['auth_bq'], config.project, task['dataset'])

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

  for c in API_DCM(config, task['auth_cm'], 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(config, task['auth_cm'], 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(config, task['auth_cm'], 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(config, task['auth_cm'], 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(config, task['auth_cm'], 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(config, task['auth_cm'], 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": task['dataset'],
    "table": CM_PLACEMENT_AUDIT_TABLE,
    "is_incremental_load": False,
    "datastudio": True,
    "schema": PLACEMENTS_SCHEMA,
    "skip_rows": 0
  }

  if placements: put_rows(config, task['auth_bq'], placements_out, write_data)