Example #1
0
def set_secret():
    """gets client id, client secret, dev token, account id.
    Saves to config.yaml and returns refresh url"""
    data = request.get_json(force=True)

    # determines if a reset to prev valid config or trying to setup new config
    is_reset = True

    if not data.get('config_valid'):
        data['refresh_token'] = None
        data['config_valid'] = 0
        is_reset = False

    with open(CONFIG_FILE_PATH, 'w') as fi:
        yaml.dump(data, fi)
    setup.upload_file_to_gcs(CONFIG_FILE_PATH, CONFIG_FILE_PATH_GS)

    # If its just a reset - no need to generate a url
    if is_reset:
        return _build_response(msg=json.dumps(
            'successfully restored previous configs'), status=200)

    init_flow(
        client_id=data['client_id'],
        client_secret=data['client_secret']
    )

    return _build_response(msg=json.dumps(""), status=200)
Example #2
0
def _update_asset_struct(asset):
    """Update the asset_to_ag file with the new assets and their adgroups"""
    try:
        setup.download_file_from_gcs('asset_to_ag.json', asset_to_ag_json_path)
    except Exception as e:
        print(e)
    with open(asset_to_ag_json_path, 'r') as f:
        struct = json.load(f)
    struct.append(asset)
    with open(asset_to_ag_json_path, 'w') as f:
        json.dump(struct, f, indent=2)
    setup.upload_file_to_gcs(asset_to_ag_json_path, 'asset_to_ag.json')
Example #3
0
def create_mcc_struct(client, mcc_struct_file, assets_file):
    builder = MCCStructureBuilder(client)
    for _ in range(_MAX_RETRIES):
        try:
            structure = builder.build()
        except Exception as e:
            logging.exception(e)
            err_msg = e.args[0]
            time.sleep(10)
            continue
        else:
            break

    else:
        logging.error('Could not create structure')
        raise ConnectionError(err_msg)

    with open(mcc_struct_file, 'w') as f:
        json.dump(structure, f, indent=2)
    setup.upload_file_to_gcs(mcc_struct_file, 'account_struct.json')
    assets = {}
    for account in structure:
        for campaign in account['campaigns']:
            for ad_group in campaign['adgroups']:
                for asset in ad_group['assets']:
                    try:
                        performance_type = 'nontext'
                        if asset['type'] == 'TEXT':
                            performance_type = asset['text_type']
                        key = str(asset['id']) + performance_type

                        assets[key]['adgroups'].append(
                            {
                                'id': ad_group['id'],
                                'performance': asset['performance'],
                                'performance_type': performance_type
                            }
                        )
                    except KeyError:
                        assets[key] = asset
                        assets[key]['adgroups'] = [
                            {
                                'id': ad_group['id'],
                                'performance': asset['performance'],
                                'performance_type': performance_type
                            }
                        ]
    with open(assets_file, 'w') as f:
        json.dump(list(assets.values()), f, indent=2)
    setup.upload_file_to_gcs(assets_file, 'asset_to_ag.json')
Example #4
0
def set_yt():
    """Set yt-conifg.json with channel id and API key.
    Will be used to get all the channel's videos. Gets a JSON with two keys:
    channel_id
    api_key
    """
    data = request.get_json(force=True)

    try:
        channel_id = data['channel_id']
        with open(YT_CONFIG_FILE_PATH, 'w') as f:
            json.dump({'channel_id':channel_id},f)
        setup.upload_file_to_gcs(YT_CONFIG_FILE_PATH, YT_CONFIG_FILE_PATH_GS)
        return _build_response(status=200)

    except Exception as e:
        logging.exception(e)
        return _build_response(msg=json.dumps(str(e)), status=400)
Example #5
0
def init_clients():
    """Sets up googleads.yaml and google-ads.yaml and inits both clients.
    tries to create struct. if succesful, marks config_valid=1 in config.yaml
    to mark config is valid. Marks 0 otherwise."""

    status = 0

    try:
        get_global_adwords_client()
        get_global_googleads_client()
        with open(CONFIG_FILE_PATH, 'r') as f:
            config = yaml.load(f, Loader=yaml.FullLoader)
        config['config_valid'] = 1

        with open(CONFIG_FILE_PATH, 'w') as f:
            yaml.dump(config, f)
        setup.upload_file_to_gcs(CONFIG_FILE_PATH, CONFIG_FILE_PATH_GS)
    except Exception as e:
        logging.error(str(e))
        status=1

    return status
Example #6
0
def _text_asset_mutate(data, aw_client, ga_client, asset_id, asset_struct):
    """Handles text asset mutations"""

    asset_handlers = []
    index = 0 # to re-write back to location
    for entry in asset_struct:
        if entry['id'] == asset_id:
            asset_handlers.append({'asset':entry, 'index':index})
        index += 1


    # if only one of headlines/descriptions entries
    # exists in asset_struct, create the second one.
    # if the asset isn't assigned to any adgroup, create both entries
    # create headline entry only if text's len <= 30
    if len(asset_handlers) < 2:
        new_asset = {
            'id': data[0]['asset']['id'],
            'type':'TEXT',
            'asset_text':data[0]['asset']['asset_text'],
            'adgroups':[]
        }
        append = False
        if len(data[0]['asset']['asset_text']) <= 30:
            headline_len = True
        else:
            headline_len = False

        if len(asset_handlers) == 1:
            existing_type = asset_handlers[0]['asset']['text_type']
            if existing_type == 'headlines':
                new_asset['text_type'] = 'descriptions'
                append = True
            elif headline_len:
                new_asset['text_type'] = 'headlines'
                append = True
            if append:
                asset_handlers.append({'asset':new_asset, 'index':None})

        elif len(asset_handlers) == 0:
            new_asset['text_type'] = 'descriptions'
            asset_handlers.append({'asset':new_asset, 'index':None})
            if headline_len:
                new_asset_second = copy.copy(new_asset)
                new_asset_second['adgroups'] = []
                new_asset_second['text_type'] = 'headlines'
                asset_handlers.append({'asset':new_asset_second, 'index':None})

    successeful_assign = []
    failed_assign = []
    for item in data:
        account = item['account']
        adgroup = item['adgroup']
        action = item['action']
        asset = item['asset']
        text_type_to_assign = item['asset']['text_type_to_assign']

        try:
            mutation = mutate_ad(aw_client, account, adgroup, asset, action,
                                 text_type_to_assign)

        except Exception as e:
            failed_assign.append(
                {
                    'adgroup': populate_adgroup_details(ga_client, account, adgroup),
                    'error_message': error_mapping(str(e)),
                    'err': str(e)
                }
            )
            mutation = 'failed'
            logging.error(
                'could not execute mutation on adgroup: %s, %s' ,str(adgroup), str(e))

        if mutation is None:
            for obj in asset_handlers:
                if obj['asset']['text_type'] == text_type_to_assign:
                    obj['asset'] = _asset_ag_update(obj['asset'],adgroup,action)
                    successeful_assign.append(adgroup)

    Service_Class.reset_cid(aw_client)

    for obj in asset_handlers:
        if obj['index']:
            asset_struct[obj['index']] = obj['asset']
        else:
            asset_struct.append(obj['asset'])

    with open(asset_to_ag_json_path, 'w') as f:
        json.dump(asset_struct, f,indent=2)
    setup.upload_file_to_gcs(asset_to_ag_json_path, 'asset_to_ag.json')
    if failed_assign and successeful_assign:
        status = 206
    elif successeful_assign:
        status = 200
    else:
        status = 500

    logging.info(
        'mutate response: msg={} , status={}'.format(str(asset_handlers),index))

    return _build_response(
        msg=json.dumps(
            [{
                'asset': asset_handlers,
                'failures': failed_assign
            }]
        ),
        status=status)
Example #7
0
def mutate():
    """Assign or remove an asset from adgroups.

    gets a dict with two entries:
    1. refresh token to create clients
    2. list of asset, account, adgourp and action.
    preforms all of the actions one by one.

    returns a list with the new asset objects with the changed adgroups list.
    if its a text asset, returns a list with
    both 'headlines' and 'descriptions' entries.
    also changes the asset_to_ag.json file.
    """

    data = request.get_json(force=True)
    logging.info('Recived mutate request: %s', str(data['data']))
    refresh_token = data['refresh_token']
    data_load = data['data']

    asset_id = data_load[0]['asset']['id']
    asset_type = data_load[0]['asset']['type']

    aw_client = init_user_adwords_client(refresh_token)
    ga_client = init_user_googleads_client(refresh_token)

    setup.download_file_from_gcs('asset_to_ag.json', asset_to_ag_json_path)
    with open(asset_to_ag_json_path, 'r') as f:
        asset_struct = json.load(f)

    # special func for text assets, as they have 2 entries in asset_to_ag.json
    if asset_type == 'TEXT':
        return _text_asset_mutate(data_load, aw_client, ga_client, asset_id, asset_struct)

    asset_handler = {}
    index = 0 # to re-write back to location
    for entry in asset_struct:
        if entry['id'] == asset_id:
            asset_handler = entry
            break
        index += 1

    if not asset_handler:
        asset_handler = data_load[0]['asset']
        asset_handler['adgroups'] = []
        index = None

    failed_assign = []
    successeful_assign = []
    for item in data_load:
        account = item['account']
        adgroup = item['adgroup']
        action = item['action']
        asset = item['asset']

        try:
            mutation = mutate_ad(aw_client, account, adgroup, asset, action)
        except Exception as e:
            failed_assign.append(
                {
                    'adgroup': populate_adgroup_details(ga_client, account, adgroup),
                    'error_message': error_mapping(str(e)),
                    'err': str(e)
                }
            )
            mutation = 'failed'
            logging.error('could not execute mutation on adgroup: %s',str(adgroup))


        if mutation is None:
            successeful_assign.append(adgroup)
            asset_handler = _asset_ag_update(asset_handler,adgroup,action)

    Service_Class.reset_cid(aw_client)

    if index:
        asset_struct[index] = asset_handler
    else:
        asset_struct.append(asset_handler)

    with open(asset_to_ag_json_path, 'w') as f:
        json.dump(asset_struct, f,indent=2)
    setup.upload_file_to_gcs(asset_to_ag_json_path, 'asset_to_ag.json')
    if failed_assign and successeful_assign:
        status = 206
    elif successeful_assign:
        status = 200
    else:
        status = 500

    logging.info(
        'mutate response: msg={} , status={}'.format(asset_handler,index))

    return _build_response(msg=json.dumps(
        [{'asset':asset_handler,'index':index, 'failures':failed_assign}])
        , status=status)