def _process_lifetime_campaign_report(campaign, report_id, queued_date): """ Processes report for the lifetime of the campaign. Exponentially backs off on retries, throws on timeout. """ attempt = 1 while True: try: report_result = report.fetch_report(report_id) break except report.ReportPendingException as e: timeout = (datetime.utcnow().replace(tzinfo=pytz.utc) - timedelta(seconds=g.az_reporting_timeout)) if queued_date < timeout: raise report.ReportFailedException( "campign report timed out (%s/%s)" % (campaign._fullname, report_id)) else: sleep_time = math.pow(RETRY_SLEEP_SECONDS, attempt) attempt = attempt + 1 g.log.warning( "campaign report still pending, retrying in %d seconds (%s/%s)" % (RETRY_SLEEP_SECONDS, campaign._fullname, report_id)) time.sleep(sleep_time) impressions, clicks, spent = _get_total_usage(report_result) campaign.adserver_spent_pennies = int(spent * 100) campaign.adserver_impressions = impressions campaign.adserver_clicks = clicks campaign.last_lifetime_report = report_id campaign.last_lifetime_report_run = queued_date campaign._commit()
def _process_lifetime_campaign_report(campaign, report_id, queued_date): """ Processes report for the lifetime of the campaign. Exponentially backs off on retries, throws on timeout. """ attempt = 1 while True: try: report_result = report.fetch_report(report_id) break except report.ReportPendingException as e: timeout = (datetime.utcnow().replace(tzinfo=pytz.utc) - timedelta(seconds=g.az_reporting_timeout)) if queued_date < timeout: raise report.ReportFailedException("campign report timed out (%s/%s)" % (campaign._fullname, report_id)) else: sleep_time = math.pow(RETRY_SLEEP_SECONDS, attempt) attempt = attempt + 1 g.log.warning("campaign report still pending, retrying in %d seconds (%s/%s)" % (sleep_time, campaign._fullname, report_id)) time.sleep(sleep_time) impressions, clicks, spent = _get_total_usage(report_result) campaign.adserver_spent_pennies = int(spent * 100) campaign.adserver_impressions = impressions campaign.adserver_clicks = clicks campaign.last_lifetime_report = report_id campaign.last_lifetime_report_run = queued_date campaign._commit()
def _process_daily_link_report(link, report_id, queued_date): """ Processes report grouped by day and flight. Exponentially backs off on retries, throws on timeout. """ attempt = 1 while True: try: report_result = report.fetch_report(report_id) break except report.ReportPendingException as e: timeout = (datetime.utcnow().replace(tzinfo=pytz.utc) - timedelta(seconds=g.az_reporting_timeout)) if queued_date < timeout: raise report.ReportFailedException("link report timed out (%s/%s)" % (link._fullname, report_id)) else: sleep_time = math.pow(RETRY_SLEEP_SECONDS, attempt) attempt = attempt + 1 g.log.warning("link report still pending, retrying in %d seconds (%s/%s)" % (sleep_time, link._fullname, report_id)) time.sleep(sleep_time) g.log.debug(report_result) campaigns_by_fullname = {campaign._fullname: campaign for campaign in PromoCampaign._by_link(link._id)} # report is by date, by flight. each record is a day # and each detail is a flight for that day. for record in report_result.get("Records", []): impressions, clicks, spent = _get_usage(record) date = _get_date(record) _insert_daily_link_reporting( codename=link._fullname, date=date, impressions=impressions, clicks=clicks, spent_pennies=spent * 100., ) campaign_details = defaultdict(_reporting_factory) for detail in record.get("Details", []): campaign_fullname = _get_fullname(PromoCampaign, detail) if not campaign_fullname: g.log.error("invalid fullname for campaign (%s/%s)" % (campaign_fullname, flight_id)) continue campaign = campaigns_by_fullname.get(campaign_fullname) if not campaign: flight_id = _get_flight_id(detail) g.log.warning("no campaign for flight (%s/%s)" % (campaign_fullname, flight_id)) continue impressions, clicks, spent = _get_usage(detail) # if the price changes then there may be multiple records for each campaign/date. values = campaign_details[(campaign, date)] values["impressions"] = values["impressions"] + impressions values["clicks"] = values["clicks"] + clicks values["spent_pennies"] = values["spent_pennies"] + (spent * 100.) for (campaign, date), values in campaign_details.iteritems(): # hack around `target_name`s for multi subreddit collections # being overly long. if (campaign.target.is_collection and "/r/" in campaign.target.pretty_name): subreddit = "multi_%s" % PromoCampaign.SUBREDDIT_TARGET else: subreddit = campaign.target_name _insert_daily_campaign_reporting( codename=campaign._fullname, date=date, subreddit=subreddit, **values ) link.last_daily_report = report_id link.last_daily_report_run = queued_date link._commit()
def _process_lifetime_campaign_reports(campaigns, report_id, queued_date): """ Processes report for the lifetime of the campaigns. Exponentially backs off on retries, throws on timeout. """ attempt = 1 campaign_fullnames = ",".join(c._fullname for c in campaigns) while True: try: report_result = report.fetch_report(report_id) break except report.ReportPendingException as e: timeout = (datetime.utcnow().replace(tzinfo=pytz.utc) - timedelta(seconds=g.live_config.get("adzerk_reporting_timeout", 500))) if queued_date < timeout: raise report.ReportFailedException("campign reports timed out (%s/%s)" % (campaign_fullnames, report_id)) else: sleep_time = math.pow(RETRY_SLEEP_SECONDS, attempt) attempt = attempt + 1 g.log.warning("campaign reports still pending, retrying in %d seconds (%s/%s)" % (sleep_time, campaign_fullnames, report_id)) time.sleep(sleep_time) report_records = report_result.get("Records", None) campaigns_by_fullname = {c._fullname: c for c in campaigns} campaign_results = defaultdict(_reporting_factory) if report_records: for detail in report_records[0].get("Details", []): campaign_fullname = _get_fullname(PromoCampaign, detail) if not campaign_fullname: flight_id = _get_flight_id(detail) g.log.error("invalid fullname for campaign (%s/%s)" % (campaign_fullname, flight_id)) continue campaign = campaigns_by_fullname.get(campaign_fullname) if not campaign: flight_id = _get_flight_id(detail) g.log.warning("no campaign for flight (%s/%s)" % (campaign_fullname, flight_id)) continue impressions, clicks, spent = _get_usage(detail) # if the price changes there may be more than 1 record for a single campaign. campaign_values = campaign_results[campaign] campaign_values["impressions"] = campaign_values["impressions"] + impressions campaign_values["clicks"] = campaign_values["clicks"] + clicks campaign_values["spent_pennies"] = campaign_values["spent_pennies"] + (spent * 100.) for campaign, values in campaign_results.items(): campaign.adserver_spent_pennies = values["spent_pennies"] campaign.adserver_impressions = values["impressions"] campaign.adserver_clicks = values["clicks"] campaign.last_lifetime_report = report_id campaign.last_lifetime_report_run = queued_date campaign._commit()
def _process_daily_link_report(link, report_id, queued_date): """ Processes report grouped by day and flight. Exponentially backs off on retries, throws on timeout. """ attempt = 1 while True: try: report_result = report.fetch_report(report_id) break except report.ReportPendingException as e: timeout = (datetime.utcnow().replace(tzinfo=pytz.utc) - timedelta(seconds=g.az_reporting_timeout)) if queued_date < timeout: raise report.ReportFailedException( "link report timed out (%s/%s)" % (link._fullname, report_id)) else: sleep_time = math.pow(RETRY_SLEEP_SECONDS, attempt) attempt = attempt + 1 g.log.warning( "link report still pending, retrying in %d seconds (%s/%s)" % (RETRY_SLEEP_SECONDS, link._fullname, report_id)) time.sleep(sleep_time) g.log.debug(report_result) campaigns_by_fullname = { campaign._fullname: campaign for campaign in PromoCampaign._by_link(link._id) } # report is by date, by flight. each record is a day # and each detail is a flight for that day. for record in report_result.get("Records", []): impressions, clicks, spent = _get_usage(record) date = _get_date(record) _insert_daily_link_reporting( codename=link._fullname, date=date, impressions=impressions, clicks=clicks, spent_pennies=spent * 100., ) for detail in record.get("Details", []): campaign_fullname = _get_fullname(PromoCampaign, detail) if not campaign_fullname: g.log.error("invalid fullname for campaign (%s/%s)" % (campaign_fullname, flight_id)) continue campaign = campaigns_by_fullname.get(campaign_fullname) if not campaign: flight_id = _get_flight_id(detail) g.log.warning("no campaign for flight (%s/%s)" % (campaign_fullname, flight_id)) continue impressions, clicks, spent = _get_usage(detail) _insert_daily_campaign_reporting( codename=campaign._fullname, date=date, impressions=impressions, clicks=clicks, spent_pennies=spent * 100., subreddit=campaign.target_name, ) link.last_daily_report = report_id link.last_daily_report_run = queued_date link._commit()
def _process_daily_link_report(link, report_id, queued_date): """ Processes report grouped by day and flight. Exponentially backs off on retries, throws on timeout. """ attempt = 1 while True: try: report_result = report.fetch_report(report_id) break except report.ReportPendingException as e: timeout = (datetime.utcnow().replace(tzinfo=pytz.utc) - timedelta(seconds=g.az_reporting_timeout)) if queued_date < timeout: raise report.ReportFailedException("link report timed out (%s/%s)" % (link._fullname, report_id)) else: sleep_time = math.pow(RETRY_SLEEP_SECONDS, attempt) attempt = attempt + 1 g.log.warning("link report still pending, retrying in %d seconds (%s/%s)" % (RETRY_SLEEP_SECONDS, link._fullname, report_id)) time.sleep(sleep_time) g.log.debug(report_result) campaigns_by_fullname = {campaign._fullname: campaign for campaign in PromoCampaign._by_link(link._id)} # report is by date, by flight. each record is a day # and each detail is a flight for that day. for record in report_result.get("Records", []): impressions, clicks, spent = _get_usage(record) date = _get_date(record) _insert_daily_link_reporting( codename=link._fullname, date=date, impressions=impressions, clicks=clicks, spent_pennies=spent * 100., ) for detail in record.get("Details", []): campaign_fullname = _get_fullname(PromoCampaign, detail) if not campaign_fullname: g.log.error("invalid fullname for campaign (%s/%s)" % (campaign_fullname, flight_id)) continue campaign = campaigns_by_fullname.get(campaign_fullname) if not campaign: flight_id = _get_flight_id(detail) g.log.warning("no campaign for flight (%s/%s)" % (campaign_fullname, flight_id)) continue impressions, clicks, spent = _get_usage(detail) _insert_daily_campaign_reporting( codename=campaign._fullname, date=date, impressions=impressions, clicks=clicks, spent_pennies=spent * 100., subreddit=campaign.target_name, ) link.last_daily_report = report_id link.last_daily_report_run = queued_date link._commit()