def adzerk_request( keywords, properties, user_id, num_placements=1, timeout=1.5, platform="desktop", is_refresh=False, referrer=None, ): placements = [] divs = ["div%s" % i for i in xrange(num_placements)] subreddit = None if isinstance(c.site, Subreddit) and not c.default_sr: subreddit = c.site.name for div in divs: placement = { "divName": div, "networkId": g.az_selfserve_network_id, "siteId": g.az_selfserve_site_ids[platform], "adTypes": [LEADERBOARD_AD_TYPE], "eventIds": [EVENT_TYPE_UPVOTE, EVENT_TYPE_DOWNVOTE], "properties": properties, } if subreddit is not None: placement["properties"] = { "subreddit": subreddit, } placements.append(placement) keywords = [word.lower() for word in keywords] data = { "placements": placements, "keywords": keywords, "ip": request.ip, "enableBotFiltering": True, "includePricingData": True, } page_url = request.headers.get("referer", None) if page_url is not None: data["url"] = page_url if referrer is not None: data["referrer"] = referrer if user_id: data["user"] = {"key": user_id} url = 'https://%s/api/v2' % g.adzerk_engine_domain headers = { 'content-type': 'application/json', 'user-agent': request.headers.get('User-Agent'), } do_not_track = request.headers.get("DNT", None) if do_not_track and feature.is_enabled("adzerk_do_not_track"): headers["DNT"] = do_not_track timer = g.stats.get_timer("providers.adzerk") timer.start() for placement in placements: g.ad_events.ad_request( keywords=keywords, platform=platform, placement_name=placement["divName"], placement_types=placement["adTypes"], is_refresh=is_refresh, subreddit=c.site, request=request, context=c, ) try: r = requests.post(url, data=json.dumps(data), headers=headers, timeout=timeout) except (requests.exceptions.Timeout, requests.exceptions.SSLError): g.stats.simple_event('adzerk.request.timeout') return None except requests.exceptions.ConnectionError: g.stats.simple_event('adzerk.request.refused') return None except select.error: return None finally: timer.stop() errored = False try: response = adzerk_api.handle_response(r) except adzerk_api.AdzerkError: g.stats.simple_event('adzerk.request.badresponse') g.log.error('adzerk_request: bad response (%s) %r', r.status_code, r.content) errored = True finally: # Temporarily log request data and response body, # sample at 1% if random.random() < g.live_config.get('ad_log_sample_rate', 0): g.log.info("ad_request [DNT=%s]: %s, ad_response: [%s] %s", do_not_track, json.dumps(data), r.status_code, r.text) if errored: return None decisions = response['decisions'] if not decisions: return None placements_by_div = {placement["divName"]: placement for placement in placements} res = [] for div in divs: decision = decisions[div] if not decision: continue placement = placements_by_div[div] ad_id = decision['adId'] pricing = decision.get("pricing", {}) revenue = pricing.get("revenue") rate_type_id = pricing.get("rateType") rate_type = RATE_TYPE_NAMES.get(rate_type_id, None) impression_url = decision.get("impressionUrl") impression_b64_data = UrlParser(impression_url).query_dict.get("e", "") impression_id, matched_keywords = None, [] try: # fix padding and string encode impression_b64_data = str( impression_b64_data + ("=" * (len(impression_b64_data) % 4)) ) impression_data = json.loads( base64.urlsafe_b64decode(impression_b64_data), strict=False, ) except UnicodeDecodeError: g.log.info("unable to decode impression data: %s", impression_b64_data) impression_data = None except TypeError, ValueError: impression_data = None if impression_data is not None: impression_id = impression_data.get("di") matched_keywords = impression_data.get("mk") if matched_keywords: matched_keywords = matched_keywords.split(",") # adserver ads are not reddit links, we return the body if decision['campaignId'] in g.adserver_campaign_ids: g.ad_events.ad_response( keywords=keywords, platform=platform, placement_name=div, placement_types=placement["adTypes"], ad_id=ad_id, impression_id=impression_id, matched_keywords=matched_keywords, rate_type=rate_type, clearing_price=revenue, subreddit=c.site, request=request, context=c, ) return AdserverResponse(decision['contents'][0]['body']) adzerk_flight_id = decision['flightId'] imp_pixel = decision['impressionUrl'] click_url = decision['clickUrl'] events_by_id = {event["id"]: event["url"] for event in decision["events"]} upvote_pixel = events_by_id[EVENT_TYPE_UPVOTE] downvote_pixel = events_by_id[EVENT_TYPE_DOWNVOTE] campaign_fullname = PromoCampaignByFlightIdCache.get(adzerk_flight_id) contents = decision['contents'][0] body = json.loads(contents['body']) link_fullname = body['link'] target = body['target'] priority = None priority_id = body.get('priorityId', None) ecpm = body.get('ecpm', None) moat_query = body.get('moatQuery', None) if priority_id is not None: try: priority_id = int(priority_id) except ValueError: pass for k, v in g.az_selfserve_priorities.iteritems(): if priority_id == v: priority = k g.ad_events.ad_response( keywords=keywords, platform=platform, placement_name=div, placement_types=placement["adTypes"], ad_id=ad_id, impression_id=impression_id, matched_keywords=matched_keywords, rate_type=rate_type, clearing_price=revenue, subreddit=c.site, link_fullname=link_fullname, campaign_fullname=campaign_fullname, priority=priority, ecpm=ecpm, request=request, context=c, ) if not campaign_fullname: link = Link._by_fullname(link_fullname, data=True, stale=True) if promote.is_external(link): campaign_fullname = promote.EXTERNAL_CAMPAIGN else: adzerk_campaign_id = decision['campaignId'] g.stats.simple_event('adzerk.request.orphaned_flight') g.log.error('adzerk_request: couldn\'t find campaign for flight (az campaign: %s, flight: %s)', adzerk_campaign_id, adzerk_flight_id) # deactivate the flight, it will be reactivated if a # valid campaign actually exists deactivate_orphaned_flight(adzerk_flight_id) continue res.append(AdzerkResponse( link=link_fullname, campaign=campaign_fullname, target=target, ecpm=ecpm, priority=priority, moat_query=moat_query, imp_pixel=imp_pixel, click_url=click_url, upvote_pixel=upvote_pixel, downvote_pixel=downvote_pixel, ))
def adzerk_request(keywords, num_placements=1, timeout=1.5, mobile_web=False): placements = [] divs = ["div%s" % i for i in xrange(num_placements)] if mobile_web: site_id = g.az_selfserve_mobile_web_site_id else: site_id = g.az_selfserve_site_id for div in divs: placement = { "divName": div, "networkId": g.az_selfserve_network_id, "siteId": site_id, "adTypes": [g.az_selfserve_ad_type] } placements.append(placement) data = { "placements": placements, "keywords": [word.lower() for word in keywords], "ip": request.ip, } url = 'https://engine.adzerk.net/api/v2' headers = { 'content-type': 'application/json', 'user-agent': request.headers.get('User-Agent'), } timer = g.stats.get_timer("providers.adzerk") timer.start() try: r = requests.post(url, data=json.dumps(data), headers=headers, timeout=timeout) except (requests.exceptions.Timeout, requests.exceptions.SSLError): g.stats.simple_event('adzerk.request.timeout') return None except requests.exceptions.ConnectionError: g.stats.simple_event('adzerk.request.refused') return None finally: timer.stop() try: response = adzerk_api.handle_response(r) except adzerk_api.AdzerkError: g.stats.simple_event('adzerk.request.badresponse') g.log.error('adzerk_request: bad response (%s) %r', r.status_code, r.content) return None decisions = response['decisions'] if not decisions: return None res = [] for div in divs: decision = decisions[div] if not decision: continue imp_pixel = decision['impressionUrl'] click_url = decision['clickUrl'] body = json.loads(decision['contents'][0]['body']) campaign = body['campaign'] link = body['link'] target = body['target'] res.append(AdzerkResponse(link, campaign, target, imp_pixel, click_url)) return res
def adzerk_request(keywords, uid, num_placements=1, timeout=1.5, mobile_web=False): placements = [] divs = ["div%s" % i for i in xrange(num_placements)] if mobile_web: site_id = g.az_selfserve_mobile_web_site_id else: site_id = g.az_selfserve_site_id for div in divs: placement = { "divName": div, "networkId": g.az_selfserve_network_id, "siteId": site_id, "adTypes": [LEADERBOARD_AD_TYPE] } placements.append(placement) data = { "placements": placements, "keywords": [word.lower() for word in keywords], "ip": request.ip, } if uid: data["user"] = {"key": uid} url = 'https://engine.adzerk.net/api/v2' headers = { 'content-type': 'application/json', 'user-agent': request.headers.get('User-Agent'), } timer = g.stats.get_timer("providers.adzerk") timer.start() try: r = requests.post(url, data=json.dumps(data), headers=headers, timeout=timeout) except (requests.exceptions.Timeout, requests.exceptions.SSLError): g.stats.simple_event('adzerk.request.timeout') return None except requests.exceptions.ConnectionError: g.stats.simple_event('adzerk.request.refused') return None finally: timer.stop() try: response = adzerk_api.handle_response(r) except adzerk_api.AdzerkError: g.stats.simple_event('adzerk.request.badresponse') g.log.error('adzerk_request: bad response (%s) %r', r.status_code, r.content) return None decisions = response['decisions'] if not decisions: return None res = [] for div in divs: decision = decisions[div] if not decision: continue # adserver ads are not reddit links, we return the body if decision['campaignId'] in g.adserver_campaign_ids: return AdserverResponse(decision['contents'][0]['body']) adzerk_campaign_id = decision['campaignId'] adzerk_flight_id = decision['flightId'] imp_pixel = decision['impressionUrl'] click_url = decision['clickUrl'] campaign = PromoCampaignByFlightIdCache.get(adzerk_flight_id) if not campaign: g.stats.simple_event('adzerk.request.orphaned_flight') g.log.error('adzerk_request: couldn\'t find campaign for flight (az campaign: %s, flight: %s)', adzerk_campaign_id, adzerk_flight_id) # deactivate the flight, it will be reactivated if a # valid campaign actually exists deactivate_orphaned_flight(adzerk_flight_id) continue body = json.loads(decision['contents'][0]['body']) link = body['link'] target = body['target'] res.append(AdzerkResponse(link, campaign, target, imp_pixel, click_url)) return res
def adzerk_request( keywords, properties, user_id, num_placements=1, timeout=1.5, platform="desktop", is_refresh=False, ): placements = [] divs = ["div%s" % i for i in xrange(num_placements)] for div in divs: placement = { "divName": div, "networkId": g.az_selfserve_network_id, "siteId": g.az_selfserve_site_ids[platform], "adTypes": [LEADERBOARD_AD_TYPE], "eventIds": [EVENT_TYPE_UPVOTE, EVENT_TYPE_DOWNVOTE], "properties": properties, } placements.append(placement) keywords = [word.lower() for word in keywords] data = { "placements": placements, "keywords": keywords, "ip": request.ip, "enableBotFiltering": True, } referrer = request.headers.get("referer", None) if referrer: data["referrer"] = referrer if user_id: data["user"] = {"key": user_id} url = 'https://%s/api/v2' % g.adzerk_engine_domain headers = { 'content-type': 'application/json', 'user-agent': request.headers.get('User-Agent'), } do_not_track = request.headers.get("DNT", None) if do_not_track and feature.is_enabled("adzerk_do_not_track"): headers["DNT"] = do_not_track timer = g.stats.get_timer("providers.adzerk") timer.start() for placement in placements: g.ad_events.ad_request( keywords=keywords, platform=platform, placement_name=placement["divName"], placement_types=placement["adTypes"], is_refresh=is_refresh, subreddit=c.site, request=request, context=c, ) try: r = requests.post(url, data=json.dumps(data), headers=headers, timeout=timeout) except (requests.exceptions.Timeout, requests.exceptions.SSLError): g.stats.simple_event('adzerk.request.timeout') return None except requests.exceptions.ConnectionError: g.stats.simple_event('adzerk.request.refused') return None finally: timer.stop() errored = False try: response = adzerk_api.handle_response(r) except adzerk_api.AdzerkError: g.stats.simple_event('adzerk.request.badresponse') g.log.error('adzerk_request: bad response (%s) %r', r.status_code, r.content) errored = True finally: # Temporarily log request data and response body, # sample at 1% if random.random() < g.live_config.get('ad_log_sample_rate', 0): g.log.info("ad_request [DNT=%s]: %s, ad_response: [%s] %s", do_not_track, json.dumps(data), r.status_code, r.text) if errored: return None decisions = response['decisions'] if not decisions: return None placements_by_div = {placement["divName"]: placement for placement in placements} res = [] for div in divs: decision = decisions[div] if not decision: continue placement = placements_by_div[div] ad_id = decision['adId'] # adserver ads are not reddit links, we return the body if decision['campaignId'] in g.adserver_campaign_ids: g.ad_events.ad_response( keywords=keywords, platform=platform, placement_name=div, placement_types=placement["adTypes"], ad_id=ad_id, subreddit=c.site, request=request, context=c, ) return AdserverResponse(decision['contents'][0]['body']) adzerk_flight_id = decision['flightId'] imp_pixel = decision['impressionUrl'] click_url = decision['clickUrl'] events_by_id = {event["id"]: event["url"] for event in decision["events"]} upvote_pixel = events_by_id[EVENT_TYPE_UPVOTE] downvote_pixel = events_by_id[EVENT_TYPE_DOWNVOTE] campaign_fullname = PromoCampaignByFlightIdCache.get(adzerk_flight_id) contents = decision['contents'][0] body = json.loads(contents['body']) link_fullname = body['link'] target = body['target'] priority = None priority_id = body.get('priorityId', None) ecpm = body.get('ecpm', None) if priority_id: priority = PRIORITIES_BY_ID.get(priority_id, "unknown (%s)" % priority_id) g.ad_events.ad_response( keywords=keywords, platform=platform, placement_name=div, placement_types=placement["adTypes"], ad_id=ad_id, subreddit=c.site, link_fullname=link_fullname, campaign_fullname=campaign_fullname, priority=priority, ecpm=ecpm, request=request, context=c, ) if not campaign_fullname: link = Link._by_fullname(link_fullname, data=True, stale=True) if promote.is_external(link): campaign_fullname = promote.EXTERNAL_CAMPAIGN else: adzerk_campaign_id = decision['campaignId'] g.stats.simple_event('adzerk.request.orphaned_flight') g.log.error('adzerk_request: couldn\'t find campaign for flight (az campaign: %s, flight: %s)', adzerk_campaign_id, adzerk_flight_id) # deactivate the flight, it will be reactivated if a # valid campaign actually exists deactivate_orphaned_flight(adzerk_flight_id) continue res.append(AdzerkResponse( link=link_fullname, campaign=campaign_fullname, target=target, ecpm=ecpm, priority=priority, imp_pixel=imp_pixel, click_url=click_url, upvote_pixel=upvote_pixel, downvote_pixel=downvote_pixel, )) return res
def adzerk_request(keywords, uid, num_placements=1, timeout=1.5, platform="desktop"): placements = [] divs = ["div%s" % i for i in xrange(num_placements)] for div in divs: placement = { "divName": div, "networkId": g.az_selfserve_network_id, "siteId": g.az_selfserve_site_ids[platform], "adTypes": [LEADERBOARD_AD_TYPE], "eventIds": [EVENT_TYPE_UPVOTE, EVENT_TYPE_DOWNVOTE], } placements.append(placement) data = { "placements": placements, "keywords": [word.lower() for word in keywords], "ip": request.ip, } referrer = request.headers.get("referer", None) if referrer: data["referrer"] = referrer if uid: data["user"] = {"key": uid} url = 'https://%s/api/v2' % g.adzerk_engine_domain headers = { 'content-type': 'application/json', 'user-agent': request.headers.get('User-Agent'), } do_not_track = request.headers.get("DNT", None) if do_not_track and feature.is_enabled("adzerk_do_not_track"): headers["DNT"] = do_not_track timer = g.stats.get_timer("providers.adzerk") timer.start() try: r = requests.post(url, data=json.dumps(data), headers=headers, timeout=timeout) except (requests.exceptions.Timeout, requests.exceptions.SSLError): g.stats.simple_event('adzerk.request.timeout') return None except requests.exceptions.ConnectionError: g.stats.simple_event('adzerk.request.refused') return None finally: timer.stop() try: response = adzerk_api.handle_response(r) except adzerk_api.AdzerkError: g.stats.simple_event('adzerk.request.badresponse') g.log.error('adzerk_request: bad response (%s) %r', r.status_code, r.content) return None decisions = response['decisions'] if not decisions: return None res = [] for div in divs: decision = decisions[div] if not decision: continue # adserver ads are not reddit links, we return the body if decision['campaignId'] in g.adserver_campaign_ids: return AdserverResponse(decision['contents'][0]['body']) adzerk_campaign_id = decision['campaignId'] adzerk_flight_id = decision['flightId'] imp_pixel = decision['impressionUrl'] click_url = decision['clickUrl'] events_by_id = {event["id"]: event["url"] for event in decision["events"]} upvote_pixel = events_by_id[EVENT_TYPE_UPVOTE] downvote_pixel = events_by_id[EVENT_TYPE_DOWNVOTE] campaign = PromoCampaignByFlightIdCache.get(adzerk_flight_id) if not campaign: g.stats.simple_event('adzerk.request.orphaned_flight') g.log.error('adzerk_request: couldn\'t find campaign for flight (az campaign: %s, flight: %s)', adzerk_campaign_id, adzerk_flight_id) # deactivate the flight, it will be reactivated if a # valid campaign actually exists deactivate_orphaned_flight(adzerk_flight_id) continue body = json.loads(decision['contents'][0]['body']) link = body['link'] target = body['target'] res.append(AdzerkResponse( link=link, campaign=campaign, target=target, imp_pixel=imp_pixel, click_url=click_url, upvote_pixel=upvote_pixel, downvote_pixel=downvote_pixel, )) return res
def adzerk_request(keywords, uid, num_placements=1, timeout=1.5, platform="desktop"): placements = [] divs = ["div%s" % i for i in xrange(num_placements)] for div in divs: placement = { "divName": div, "networkId": g.az_selfserve_network_id, "siteId": g.az_selfserve_site_ids[platform], "adTypes": [LEADERBOARD_AD_TYPE], "eventIds": [EVENT_TYPE_UPVOTE, EVENT_TYPE_DOWNVOTE], } placements.append(placement) data = { "placements": placements, "keywords": [word.lower() for word in keywords], "ip": request.ip, } referrer = request.headers.get("referer", None) if referrer: data["referrer"] = referrer if uid: data["user"] = {"key": uid} url = 'https://%s/api/v2' % g.adzerk_engine_domain headers = { 'content-type': 'application/json', 'user-agent': request.headers.get('User-Agent'), } do_not_track = request.headers.get("DNT", None) if do_not_track and feature.is_enabled("adzerk_do_not_track"): headers["DNT"] = do_not_track timer = g.stats.get_timer("providers.adzerk") timer.start() try: r = requests.post(url, data=json.dumps(data), headers=headers, timeout=timeout) except (requests.exceptions.Timeout, requests.exceptions.SSLError): g.stats.simple_event('adzerk.request.timeout') return None except requests.exceptions.ConnectionError: g.stats.simple_event('adzerk.request.refused') return None finally: timer.stop() try: response = adzerk_api.handle_response(r) except adzerk_api.AdzerkError: g.stats.simple_event('adzerk.request.badresponse') g.log.error('adzerk_request: bad response (%s) %r', r.status_code, r.content) return None decisions = response['decisions'] if not decisions: return None res = [] for div in divs: decision = decisions[div] if not decision: continue # adserver ads are not reddit links, we return the body if decision['campaignId'] in g.adserver_campaign_ids: return AdserverResponse(decision['contents'][0]['body']) adzerk_campaign_id = decision['campaignId'] adzerk_flight_id = decision['flightId'] imp_pixel = decision['impressionUrl'] click_url = decision['clickUrl'] events_by_id = { event["id"]: event["url"] for event in decision["events"] } upvote_pixel = events_by_id[EVENT_TYPE_UPVOTE] downvote_pixel = events_by_id[EVENT_TYPE_DOWNVOTE] campaign = PromoCampaignByFlightIdCache.get(adzerk_flight_id) if not campaign: g.stats.simple_event('adzerk.request.orphaned_flight') g.log.error( 'adzerk_request: couldn\'t find campaign for flight (az campaign: %s, flight: %s)', adzerk_campaign_id, adzerk_flight_id) # deactivate the flight, it will be reactivated if a # valid campaign actually exists deactivate_orphaned_flight(adzerk_flight_id) continue body = json.loads(decision['contents'][0]['body']) link = body['link'] target = body['target'] res.append( AdzerkResponse( link=link, campaign=campaign, target=target, imp_pixel=imp_pixel, click_url=click_url, upvote_pixel=upvote_pixel, downvote_pixel=downvote_pixel, )) return res