def has_oversold_error(form, campaign, start, end, bid, cpm, target, location): ndays = (to_date(end) - to_date(start)).days total_request = calc_impressions(bid, cpm) daily_request = int(total_request / ndays) oversold = inventory.get_oversold(target, start, end, daily_request, ignore=campaign, location=location) if oversold: min_daily = min(oversold.values()) available = min_daily * ndays msg_params = { 'available': format_number(available, locale=c.locale), 'target': target.pretty_name, 'start': start.strftime('%m/%d/%Y'), 'end': end.strftime('%m/%d/%Y'), } c.errors.add(errors.OVERSOLD_DETAIL, field='bid', msg_params=msg_params) form.has_errors('bid', errors.OVERSOLD_DETAIL) return True
def get_campaigns(cls, start, end=None, link=None, author_id=None, sr_names=None): start = to_date(start) q = cls.query() if end: end = to_date(end) q = q.filter(and_(cls.date >= start, cls.date < end)) else: q = q.filter(cls.date == start) if link: q = q.filter(cls.thing_name == link._fullname) if author_id: q = q.filter(cls.account_id == author_id) if sr_names: sr_names = [cls.filter_sr_name(sr_name) for sr_name in sr_names] q = q.filter(cls.sr_name.in_(sr_names)) return list(q)
def make_campaign_table(self): campaigns = PromoCampaign._by_link(self.thing._id) total_budget = 0 total_spent = 0 total_paid_impressions = 0 total_impressions = 0 total_clicks = 0 self.campaign_table = [] for camp in campaigns: if not is_launched_campaign(camp): continue is_live = camp.is_live_now() self.has_early_campaign |= is_early_campaign(camp) self.has_live_campaign |= is_live history = get_billable_traffic(camp) impressions, clicks = 0, 0 for date, (imp, click) in history: impressions += imp clicks += click start = to_date(camp.start_date).strftime('%Y-%m-%d') end = to_date(camp.end_date).strftime('%Y-%m-%d') target = camp.target.pretty_name location = camp.location_str spent = promote.get_spent_amount(camp) is_active = self.campaign and self.campaign._id36 == camp._id36 url = '/traffic/%s/%s' % (self.thing._id36, camp._id36) is_total = False row = self.make_campaign_table_row(camp._id36, start, end, target, location, camp.bid, spent, camp.impressions, impressions, clicks, is_live, is_active, url, is_total) self.campaign_table.append(row) total_budget += camp.bid total_spent += spent total_paid_impressions += camp.impressions total_impressions += impressions total_clicks += clicks # total row start = '---' end = '---' target = '---' location = '---' is_live = False is_active = not self.campaign url = '/traffic/%s' % self.thing._id36 is_total = True row = self.make_campaign_table_row(_('total'), start, end, target, location, total_budget, total_spent, total_paid_impressions, total_impressions, total_clicks, is_live, is_active, url, is_total) self.campaign_table.append(row)
def add(cls, thing, idx, sr, start_date, end_date, total_weight, finished=False): start_date = to_date(start_date) end_date = to_date(end_date) # anything set by the user will be uniform weighting duration = max((end_date - start_date).days, 1) weight = total_weight / duration d = start_date while d < end_date: cls._new( thing, idx, sr, d, thing.author_id, weight, weight, finished=finished) d += datetime.timedelta(1)
def add(cls, thing, idx, sr_names, start_date, end_date, total_weight, finished=False): start_date = to_date(start_date) end_date = to_date(end_date) # anything set by the user will be uniform weighting duration = max((end_date - start_date).days, 1) weight = total_weight / duration for sr_name in tup(sr_names): sr_name = cls.filter_sr_name(sr_name) d = start_date while d < end_date: cls._new(thing, idx, sr_name, d, thing.author_id, weight, weight, finished=finished) d += datetime.timedelta(days=1)
def add(cls, thing, idx, sr, start_date, end_date, total_weight, finished=False): start_date = to_date(start_date) end_date = to_date(end_date) # anything set by the user will be uniform weighting duration = max((end_date - start_date).days, 1) weight = total_weight / duration d = start_date while d < end_date: cls._new(thing, idx, sr, d, thing.author_id, weight, weight, finished=finished) d += datetime.timedelta(1)
def _filter_query(cls, query, start, end=None, link=None, author_id=None, sr_names=None): start = to_date(start) if end: end = to_date(end) query = query.filter(and_(cls.date >= start, cls.date < end)) else: query = query.filter(cls.date == start) if link: query = query.filter(cls.thing_name == link._fullname) if author_id: query = query.filter(cls.account_id == author_id) if sr_names: sr_names = [cls.filter_sr_name(sr_name) for sr_name in sr_names] query = query.filter(cls.sr_name.in_(sr_names)) return query
def add(cls, link, campaign): start_date = to_date(campaign.start_date) end_date = to_date(campaign.end_date) ndays = (end_date - start_date).days # note that end_date is not included dates = [ start_date + datetime.timedelta(days=i) for i in xrange(ndays) ] sr_names = campaign.target.subreddit_names sr_names = {cls.filter_sr_name(sr_name) for sr_name in sr_names} with cls.session.begin(): for sr_name in sr_names: for date in dates: obj = cls( thing_name=link._fullname, promo_idx=campaign._id, sr_name=sr_name, date=date, account_id=link.author_id, bid=0., weight=0., finished=False, ) cls.session.add(obj)
def get_scheduled_impressions(sr_name, start_date, end_date): # FIXME: mock function for development start_date = to_date(start_date) end_date = to_date(end_date) ndays = (end_date - start_date).days scheduled = OrderedDict() for i in range(ndays): date = (start_date + timedelta(i)) scheduled[date] = random.randint(0, 100) # FIXME: fakedata return scheduled
def get_available_impressions(sr_name, start_date, end_date, fuzzed=False): # FIXME: mock function for development start_date = to_date(start_date) end_date = to_date(end_date) available = inventory.get_predicted_by_date(sr_name, start_date, end_date) scheduled = get_scheduled_impressions(sr_name, start_date, end_date) for date in scheduled: available[date] = int(available[date] - (available[date] * scheduled[date] / 100.)) # DELETEME #available[date] = max(0, available[date] - scheduled[date]) # UNCOMMENTME if fuzzed: available[date] = fuzz_impressions(available[date]) return available
def get_campaigns(cls, start, end=None, author_id=None): start = to_date(start) q = cls.query() if end: end = to_date(end) q = q.filter(and_(cls.date >= start, cls.date < end)) else: q = q.filter(cls.date == start) if author_id: q = q.filter(cls.account_id == author_id) return list(q)
def add(cls, sr, start, end): rowkey = sr._id36 column = cls._column(start, end) now = datetime.now(g.tz).date() ndays = (to_date(end) - now).days + 7 ttl = timedelta(days=ndays).total_seconds() cls._set_values(rowkey, column, ttl=ttl)
def calculate_server_seconds(pennies, date): cutoff_dates = sorted(PENNIES_PER_SERVER_SECOND.keys()) date = to_date(date) key = max(filter(lambda cutoff_date: date >= cutoff_date, cutoff_dates)) rate = PENNIES_PER_SERVER_SECOND[key] # for simplicity all payment processor fees are $0.30 + 2.9% net_pennies = pennies * (1 - 0.029) - 30 return net_pennies / rate
def bid_history(cls, start_date, end_date = None, account_id = None): from r2.lib import promote from r2.models import PromoCampaign if not end_date: end_date = datetime.datetime.now(g.tz) start_date = to_date(start_date) end_date = to_date(end_date) q = cls.query() q = q.filter(and_(cls.date >= start_date, cls.date < end_date)) q = list(q) links = Link._by_fullname([x.thing_name for x in q], data=True) d = start_date res = [] while d < end_date: bid = 0 refund = 0 for i in q: if d == i.date: l = links[i.thing_name] if (not promote.is_rejected(l) and not promote.is_unpaid(l) and not l._deleted): try: camp = PromoCampaign._byID(i.promo_idx, data=True) bid += i.bid refund += i.bid if camp.is_freebie() else 0 except NotFound: g.log.error("Skipping missing PromoCampaign in " "bidding.bid_history, campaign id: %d" % i.promo_idx) res.append([d, bid, refund]) d += datetime.timedelta(1) return res
def create(cls, link, campaigns): transactions = get_transactions(link, campaigns) live_campaigns = scheduled_campaigns_by_link(link) user_is_sponsor = c.user_is_sponsor today = promo_datetime_now().date() r = [] for camp in campaigns: transaction = transactions.get(camp._id) campaign_id36 = camp._id36 start_date = camp.start_date.strftime("%m/%d/%Y") end_date = camp.end_date.strftime("%m/%d/%Y") ndays = camp.ndays duration = strings.time_label % dict( num=ndays, time=ungettext("day", "days", ndays)) bid = camp.bid spent = get_spent_amount(camp) cpm = getattr(camp, 'cpm', g.cpm_selfserve.pennies) sr = camp.sr_name live = camp._id in live_campaigns pending = today < to_date(camp.start_date) complete = (transaction and (transaction.is_charged() or transaction.is_refund()) and not (live or pending)) status = { 'paid': bool(transaction), 'complete': complete, 'free': camp.is_freebie(), 'pay_url': pay_url(link, camp), 'view_live_url': view_live_url(link, sr), 'sponsor': user_is_sponsor, 'live': live, 'non_cpm': not camp.priority.cpm } if transaction and transaction.is_void(): status['paid'] = False status['free'] = False if complete and user_is_sponsor and not transaction.is_refund(): if spent < bid: status['refund'] = True status['refund_url'] = refund_url(link, camp) rc = cls(campaign_id36, start_date, end_date, duration, bid, spent, cpm, sr, camp.priority, status) r.append(rc) return r
def is_pending(campaign): today = promo_datetime_now().date() return today < to_date(campaign.start_date)
def make_campaign_table(self): campaigns = PromoCampaign._by_link(self.thing._id) total_budget_dollars = 0. total_spent = 0 total_paid_impressions = 0 total_impressions = 0 total_clicks = 0 all_auction = True self.campaign_table = [] for camp in campaigns: if not is_launched_campaign(camp): continue is_live = camp.is_live_now() self.has_early_campaign |= is_early_campaign(camp) self.has_live_campaign |= is_live history = list(get_billable_traffic(camp)) if not history: impressions, clicks, spent = 0, 0, 0 elif self.use_adserver_reporting: impressions, clicks, spent = map( sum, zip(*[values for date, values in history])) else: impressions, clicks = map( sum, zip(*[values for date, values in history])) spent = promote.get_spent_amount(camp) start = to_date(camp.start_date).strftime('%Y-%m-%d') end = to_date(camp.end_date).strftime('%Y-%m-%d') target = camp.target.pretty_name location = camp.location_str is_active = self.campaign and self.campaign._id36 == camp._id36 url = '/traffic/%s/%s' % (self.thing._id36, camp._id36) is_total = False campaign_budget_dollars = camp.total_budget_dollars row = self.make_campaign_table_row( camp._id36, start=start, end=end, target=target, location=location, budget_dollars=campaign_budget_dollars, spent=spent, paid_impressions=camp.impressions, impressions=impressions, clicks=clicks, is_live=is_live, is_active=is_active, url=url, is_total=is_total, is_auction=camp.is_auction) self.campaign_table.append(row) total_budget_dollars += campaign_budget_dollars total_spent += spent total_paid_impressions += camp.impressions total_impressions += impressions total_clicks += clicks if not camp.is_auction: all_auction = False # total row start = '---' end = '---' target = '---' location = '---' is_live = False is_active = not self.campaign url = '/traffic/%s' % self.thing._id36 row = self.make_campaign_table_row( _('total'), start=start, end=end, target=target, location=location, budget_dollars=total_budget_dollars, spent=total_spent, paid_impressions=total_paid_impressions, impressions=total_impressions, clicks=total_clicks, is_live=is_live, is_active=is_active, url=url, is_total=True, is_auction=all_auction) self.campaign_table.append(row)