def new_promotion(title, url, selftext, user, ip): """ Creates a new promotion with the provided title, etc, and sets it status to be 'unpaid'. """ sr = Subreddit._byID(get_promote_srid()) l = Link._submit(title, url, user, sr, ip) l.promoted = True l.disable_comments = False PromotionLog.add(l, 'promotion created') if url == 'self': l.url = l.make_permalink_slow() l.is_self = True l.selftext = selftext l._commit() # set the status of the link, populating the query queue if c.user_is_sponsor or user.trusted_sponsor: set_promote_status(l, PROMOTE_STATUS.accepted) else: set_promote_status(l, PROMOTE_STATUS.unpaid) # the user has posted a promotion, so enable the promote menu unless # they have already opted out if user.pref_show_promote is not False: user.pref_show_promote = True user._commit() # notify of new promo emailer.new_promo(l) return l
def charge_pending(offset=1): for l, camp, weight in accepted_campaigns(offset=offset): user = Account._byID(l.author_id) try: if charged_or_not_needed(camp): continue charge_succeeded = authorize.charge_transaction(user, camp.trans_id, camp._id) if not charge_succeeded: continue hooks.get_hook('promote.new_charge').call(link=l, campaign=camp) if is_promoted(l): emailer.queue_promo(l, camp.bid, camp.trans_id) else: set_promote_status(l, PROMOTE_STATUS.pending) emailer.queue_promo(l, camp.bid, camp.trans_id) text = ('auth charge for campaign %s, trans_id: %d' % (camp._id, camp.trans_id)) PromotionLog.add(l, text) except: print "Error on %s, campaign %s" % (l, camp._id)
def accept_promotion(link): """ Accepting is campaign agnostic. Accepting the ad just means that it is allowed to run if payment has been processed. If a campagn is able to run, this also requeues it. """ # update the query queue set_promote_status(link, PROMOTE_STATUS.accepted) # campaigns that should be live now must be updated now = promo_datetime_now(0) promotion_weights = PromotionWeights.get_campaigns(now) live_campaigns = {pw.promo_idx for pw in promotion_weights if pw.thing_name == link._fullname} if live_campaigns: campaigns = PromoCampaign._byID(live_campaigns, data=True, return_dict=False) PromotionLog.add(link, "has live campaigns, forcing live") charge_pending(0) # campaign must be charged before it will go live for campaign in campaigns: hooks.get_hook("campaign.edit").call(link=link, campaign=campaign) queue_changed_promo(link, "accepted") # campaigns that were charged and will go live in the future must be updated future_campaigns = [camp for camp in PromoCampaign._by_link(link._id) if camp.start_date > now] transactions = get_transactions(link, future_campaigns) charged_campaigns = [ camp for camp in future_campaigns if (transactions.get(camp._id) and transactions.get(camp._id).is_charged()) ] for campaign in charged_campaigns: hooks.get_hook("campaign.edit").call(link=link, campaign=campaign) if link._spam: link._spam = False link._commit() emailer.accept_promo(link)
def charge_pending(offset=1): for l, camp, weight in accepted_campaigns(offset=offset): user = Account._byID(l.author_id) try: if authorize.is_charged_transaction(camp.trans_id, camp._id): # already charged continue charge_succeeded = authorize.charge_transaction(user, camp.trans_id, camp._id) if not charge_succeeded: continue hooks.get_hook('promote.new_charge').call(link=l, campaign=camp) if is_promoted(l): emailer.queue_promo(l, camp.bid, camp.trans_id) else: set_promote_status(l, PROMOTE_STATUS.pending) emailer.queue_promo(l, camp.bid, camp.trans_id) text = ('auth charge for campaign %s, trans_id: %d' % (camp._id, camp.trans_id)) PromotionLog.add(l, text) except: print "Error on %s, campaign %s" % (l, camp._id)
def new_promotion(title, url, user, ip): """ Creates a new promotion with the provided title, etc, and sets it status to be 'unpaid'. """ sr = Subreddit._byID(get_promote_srid()) l = Link._submit(title, url, user, sr, ip) l.promoted = True l.disable_comments = False PromotionLog.add(l, 'promotion created') l._commit() # set the status of the link, populating the query queue if c.user_is_sponsor or user.trusted_sponsor: set_promote_status(l, PROMOTE_STATUS.accepted) else: set_promote_status(l, PROMOTE_STATUS.unpaid) # the user has posted a promotion, so enable the promote menu unless # they have already opted out if user.pref_show_promote is not False: user.pref_show_promote = True user._commit() # notify of new promo emailer.new_promo(l) return l
def accept_promotion(link): """ Accepting is campaign agnostic. Accepting the ad just means that it is allowed to run if payment has been processed. If a campagn is able to run, this also requeues it. """ PromotionLog.add(link, 'status update: accepted') # update the query queue set_promote_status(link, PROMOTE_STATUS.accepted) # campaigns that should be live now must be updated now = promo_datetime_now(0) if link._fullname in set(l.thing_name for l in PromotionWeights.get_campaigns(now)): PromotionLog.add(link, 'Marked promotion for acceptance') charge_pending(0) # campaign must be charged before it will go live queue_changed_promo(link, "accepted") # campaigns that were charged and will go live in the future must be updated future_campaigns = [camp for camp in PromoCampaign._by_link(link._id) if camp.start_date > now] transactions = get_transactions(link, future_campaigns) charged_campaigns = [camp for camp in future_campaigns if (transactions.get(camp._id) and transactions.get(camp._id).is_charged())] for campaign in charged_campaigns: hooks.get_hook('campaign.edit').call(link=link, campaign=campaign) if link._spam: link._spam = False link._commit() emailer.accept_promo(link)
def auth_campaign(link, campaign, user, pay_id): """ Authorizes (but doesn't charge) a bid with authorize.net. Args: - link: promoted link - campaign: campaign to be authorized - user: Account obj of the user doing the auth (usually the currently logged in user) - pay_id: customer payment profile id to use for this transaction. (One user can have more than one payment profile if, for instance, they have more than one credit card on file.) Set pay_id to -1 for freebies. Returns: (True, "") if successful or (False, error_msg) if not. """ void_campaign(link, campaign) test = 1 if g.debug else None trans_id, reason = authorize.auth_transaction(campaign.bid, user, pay_id, link, campaign._id, test=test) if trans_id and not reason: text = ('updated payment and/or bid for campaign %s: ' 'SUCCESS (trans_id: %d, amt: %0.2f)' % (campaign._id, trans_id, campaign.bid)) PromotionLog.add(link, text) if trans_id < 0: PromotionLog.add(link, 'FREEBIE (campaign: %s)' % campaign._id) if trans_id: new_status = max(PROMOTE_STATUS.unseen, link.promote_status) else: new_status = max(PROMOTE_STATUS.unpaid, link.promote_status) set_promote_status(link, new_status) # notify of campaign creation # update the query queue if user and (user._id == link.author_id) and trans_id > 0: emailer.promo_bid(link, campaign.bid, campaign.start_date) else: # something bad happend. text = ("updated payment and/or bid for campaign %s: FAILED ('%s')" % (campaign._id, reason)) PromotionLog.add(link, text) trans_id = 0 campaign.trans_id = trans_id campaign._commit() return bool(trans_id), reason
def reject_promotion(link, reason = None): PromotionLog.add(link, 'status update: rejected') # update the query queue # Since status is updated first, # if make_daily_promotions happens to run # while we're doing work here, it will correctly exclude it set_promote_status(link, PROMOTE_STATUS.rejected) links, = get_live_promotions([SponsorBoxWeightings.ALL_ADS_ID])[0] if link._fullname in links: PromotionLog.add(link, 'Marked promotion for rejection') queue_changed_promo(link, "rejected") # Send a rejection email (unless the advertiser requested the reject) if not c.user or c.user._id != link.author_id: emailer.reject_promo(link, reason = reason)
def reject_promotion(link, reason=None): PromotionLog.add(link, 'status update: rejected') # update the query queue # Since status is updated first, # if make_daily_promotions happens to run # while we're doing work here, it will correctly exclude it set_promote_status(link, PROMOTE_STATUS.rejected) all_ads = get_live_promotions([LiveAdWeights.ALL_ADS]) links = set(x.link for x in all_ads[LiveAdWeights.ALL_ADS]) if link._fullname in links: PromotionLog.add(link, 'Marked promotion for rejection') queue_changed_promo(link, "rejected") # Send a rejection email (unless the advertiser requested the reject) if not c.user or c.user._id != link.author_id: emailer.reject_promo(link, reason=reason)
def accept_promotion(link): """ Accepting is campaign agnostic. Accepting the ad just means that it is allowed to run if payment has been processed. If a campagn is able to run, this also requeues it. """ # update the query queue set_promote_status(link, PROMOTE_STATUS.accepted) # campaigns that should be live now must be updated now = promo_datetime_now(0) promotion_weights = PromotionWeights.get_campaigns(now) live_campaigns = { pw.promo_idx for pw in promotion_weights if pw.thing_name == link._fullname } if live_campaigns: campaigns = PromoCampaign._byID(live_campaigns, data=True, return_dict=False) PromotionLog.add(link, 'has live campaigns, forcing live') charge_pending(0) # campaign must be charged before it will go live for campaign in campaigns: hooks.get_hook('campaign.edit').call(link=link, campaign=campaign) queue_changed_promo(link, "accepted") # campaigns that were charged and will go live in the future must be updated future_campaigns = [ camp for camp in PromoCampaign._by_link(link._id) if camp.start_date > now ] transactions = get_transactions(link, future_campaigns) charged_campaigns = [ camp for camp in future_campaigns if (transactions.get(camp._id) and transactions.get(camp._id).is_charged()) ] for campaign in charged_campaigns: hooks.get_hook('campaign.edit').call(link=link, campaign=campaign) if link._spam: link._spam = False link._commit() emailer.accept_promo(link)
def charge_pending(offset=1): for l, camp, weight in accepted_campaigns(offset=offset): user = Account._byID(l.author_id) try: if (authorize.is_charged_transaction(camp.trans_id, camp._id) or not authorize.charge_transaction(user, camp.trans_id, camp._id)): continue if is_promoted(l): emailer.queue_promo(l, camp.bid, camp.trans_id) else: set_promote_status(l, PROMOTE_STATUS.pending) emailer.queue_promo(l, camp.bid, camp.trans_id) text = ('auth charge for campaign %s, trans_id: %d' % (camp._id, camp.trans_id)) PromotionLog.add(l, text) except: print "Error on %s, campaign %s" % (l, camp._id)
def reject_promotion(link, reason=None): # update the query queue # Since status is updated first, # if make_daily_promotions happens to run # while we're doing work here, it will correctly exclude it set_promote_status(link, PROMOTE_STATUS.rejected) all_ads = get_live_promotions([LiveAdWeights.ALL_ADS]) links = set(x.link for x in all_ads[LiveAdWeights.ALL_ADS]) if link._fullname in links: PromotionLog.add(link, 'has live campaigns, terminating') queue_changed_promo(link, "rejected") # Send a rejection email (unless the advertiser requested the reject) if not c.user or c.user._id != link.author_id: emailer.reject_promo(link, reason=reason) hooks.get_hook('promotion.void').call(link=link)
def accept_promotion(link): """ Accepting is campaign agnostic. Accepting the ad just means that it is allowed to run if payment has been processed. If a campagn is able to run, this also requeues it. """ PromotionLog.add(link, "status update: accepted") # update the query queue set_promote_status(link, PROMOTE_STATUS.accepted) now = promo_datetime_now(0) if link._fullname in set(l.thing_name for l in PromotionWeights.get_campaigns(now)): PromotionLog.add(link, "Marked promotion for acceptance") charge_pending(0) # campaign must be charged before it will go live queue_changed_promo(link, "accepted") if link._spam: link._spam = False link._commit() emailer.accept_promo(link)
def accept_promotion(link): """ Accepting is campaign agnostic. Accepting the ad just means that it is allowed to run if payment has been processed. If a campagn is able to run, this also requeues it. """ PromotionLog.add(link, 'status update: accepted') # update the query queue set_promote_status(link, PROMOTE_STATUS.accepted) now = promo_datetime_now(0) if link._fullname in set(l.thing_name for l in PromotionWeights.get_campaigns(now)): PromotionLog.add(link, 'Marked promotion for acceptance') charge_pending(0) # campaign must be charged before it will go live queue_changed_promo(link, "accepted") if link._spam: link._spam = False link._commit() emailer.accept_promo(link)
def unapprove_promotion(link): PromotionLog.add(link, "status update: unapproved") # update the query queue set_promote_status(link, PROMOTE_STATUS.unseen) hooks.get_hook("promotion.void").call(link=link)
def update_promote_status(link, status): queries.set_promote_status(link, status) hooks.get_hook('promote.edit_promotion').call(link=link)
def make_daily_promotions(offset=0, test=False): """ Arguments: offset - number of days after today to get the schedule for test - if True, new schedule will be generated but not launched Raises Exception with list of campaigns that had errors if there were any """ scheduled_adweights, error_campaigns = get_scheduled(offset) current_adweights_byid = get_live_promotions([LiveAdWeights.ALL_ADS]) current_adweights = current_adweights_byid[LiveAdWeights.ALL_ADS] link_names = [aw.link for aw in itertools.chain(scheduled_adweights, current_adweights)] links = Link._by_fullname(link_names, data=True) camp_names = [aw.campaign for aw in itertools.chain(scheduled_adweights, current_adweights)] campaigns = PromoCampaign._by_fullname(camp_names, data=True) srs = Subreddit._by_name([camp.sr_name for camp in campaigns.itervalues() if camp.sr_name]) expired_links = ({aw.link for aw in current_adweights} - {aw.link for aw in scheduled_adweights}) for link_name in expired_links: link = links[link_name] if is_promoted(link): if test: print "unpromote", link_name else: # update the query queue set_promote_status(link, PROMOTE_STATUS.finished) emailer.finished_promo(link) by_srid = defaultdict(list) for adweight in scheduled_adweights: link = links[adweight.link] campaign = campaigns[adweight.campaign] if campaign.sr_name: sr = srs[campaign.sr_name] sr_id = sr._id sr_over_18 = sr.over_18 else: sr_id = '' sr_over_18 = False if sr_over_18: if test: print "over18", link._fullname else: link.over_18 = True link._commit() if is_accepted(link) and not is_promoted(link): if test: print "promote2", link._fullname else: # update the query queue set_promote_status(link, PROMOTE_STATUS.promoted) emailer.live_promo(link) by_srid[sr_id].append(adweight) if not test: set_live_promotions(by_srid) _mark_promos_updated() else: print by_srid finalize_completed_campaigns(daysago=offset+1) hooks.get_hook('promote.make_daily_promotions').call(offset=offset) # after launching as many campaigns as possible, raise an exception to # report any error campaigns. (useful for triggering alerts in irc) if error_campaigns: raise Exception("Some scheduled campaigns could not be added to daily " "promotions: %r" % error_campaigns)
def unapprove_promotion(link): PromotionLog.add(link, 'status update: unapproved') # update the query queue set_promote_status(link, PROMOTE_STATUS.unseen) hooks.get_hook('promotion.void').call(link=link)
def unapprove_promotion(link): # update the query queue set_promote_status(link, PROMOTE_STATUS.unseen) hooks.get_hook('promotion.void').call(link=link)
def update_promote_status(link, status): set_promote_status(link, status) hooks.get_hook("promote.edit_promotion").call(link=link)
def unapprove_promotion(link): PromotionLog.add(link, 'status update: unapproved') # update the query queue set_promote_status(link, PROMOTE_STATUS.unseen)
def make_daily_promotions(offset=0, test=False): """ Arguments: offset - number of days after today to get the schedule for test - if True, new schedule will be generated but not launched Raises Exception with list of campaigns that had errors if there were any """ by_srname, links, error_campaigns = get_scheduled(offset) all_links = set([l._fullname for l in links]) srs = Subreddit._by_name(by_srname.keys()) # over18 check for srname, adweights in by_srname.iteritems(): if srname: sr = srs[srname] if sr.over_18: sr_links = Link._by_fullname([a.link for a in adweights], return_dict=False) for l in sr_links: l.over_18 = True if not test: l._commit() old_ads = get_live_promotions([LiveAdWeights.ALL_ADS]) old_links = set(x.link for x in old_ads[LiveAdWeights.ALL_ADS]) # links that need to be promoted new_links = all_links - old_links # links that have already been promoted old_links = old_links - all_links links = Link._by_fullname(new_links.union(old_links), data=True, return_dict=True) for l in old_links: if is_promoted(links[l]): if test: print "unpromote", l else: # update the query queue set_promote_status(links[l], PROMOTE_STATUS.finished) emailer.finished_promo(links[l]) for l in new_links: if is_accepted(links[l]): if test: print "promote2", l else: # update the query queue set_promote_status(links[l], PROMOTE_STATUS.promoted) emailer.live_promo(links[l]) # convert the weighted dict to use sr_ids which are more useful by_srid = {srs[srname]._id: adweights for srname, adweights in by_srname.iteritems() if srname != ''} if '' in by_srname: by_srid[''] = by_srname[''] if not test: set_live_promotions(by_srid) _mark_promos_updated() else: print by_srid # after launching as many campaigns as possible, raise an exception to # report any error campaigns. (useful for triggering alerts in irc) if error_campaigns: raise Exception("Some scheduled campaigns could not be added to daily " "promotions: %r" % error_campaigns)
def make_daily_promotions(offset=0, test=False): """ Arguments: offset - number of days after today to get the schedule for test - if True, new schedule will be generated but not launched Raises Exception with list of campaigns that had errors if there were any """ by_srname, links, error_campaigns = get_scheduled(offset) all_links = set([l._fullname for l in links]) srs = Subreddit._by_name(by_srname.keys()) # over18 check for srname, adweights in by_srname.iteritems(): if srname: sr = srs[srname] if sr.over_18: sr_links = Link._by_fullname([a.link for a in adweights], return_dict=False) for l in sr_links: l.over_18 = True if not test: l._commit() old_ads = get_live_promotions([LiveAdWeights.ALL_ADS]) old_links = set(x.link for x in old_ads[LiveAdWeights.ALL_ADS]) # links that need to be promoted new_links = all_links - old_links # links that have already been promoted old_links = old_links - all_links links = Link._by_fullname(new_links.union(old_links), data=True, return_dict=True) for l in old_links: if is_promoted(links[l]): if test: print "unpromote", l else: # update the query queue set_promote_status(links[l], PROMOTE_STATUS.finished) emailer.finished_promo(links[l]) for l in new_links: if is_accepted(links[l]): if test: print "promote2", l else: # update the query queue set_promote_status(links[l], PROMOTE_STATUS.promoted) emailer.live_promo(links[l]) # convert the weighted dict to use sr_ids which are more useful by_srid = { srs[srname]._id: adweights for srname, adweights in by_srname.iteritems() if srname != '' } if '' in by_srname: by_srid[''] = by_srname[''] if not test: set_live_promotions(by_srid) _mark_promos_updated() else: print by_srid # after launching as many campaigns as possible, raise an exception to # report any error campaigns. (useful for triggering alerts in irc) if error_campaigns: raise Exception("Some scheduled campaigns could not be added to daily " "promotions: %r" % error_campaigns)
def make_daily_promotions(offset = 0, test = False): """ Arguments: offset - number of days after today to get the schedule for test - if True, new schedule will be generated but not launched Raises Exception with list of campaigns that had errors if there were any """ schedule = get_scheduled(offset) all_links = set([l._fullname for l in schedule['links']]) error_campaigns = schedule['error_campaigns'] weighted = weight_schedule(schedule['by_sr']) # over18 check for sr, links in weighted.iteritems(): if sr: sr = Subreddit._by_name(sr) if sr.over_18: for l in Link._by_fullname([l[0] for l in links], return_dict = False): l.over_18 = True if not test: l._commit() old_links = get_live_promotions([SponsorBoxWeightings.ALL_ADS_ID])[0] # links that need to be promoted new_links = all_links - old_links # links that have already been promoted old_links = old_links - all_links links = Link._by_fullname(new_links.union(old_links), data = True, return_dict = True) for l in old_links: if is_promoted(links[l]): if test: print "unpromote", l else: # update the query queue set_promote_status(links[l], PROMOTE_STATUS.finished) emailer.finished_promo(links[l]) for l in new_links: if is_accepted(links[l]): if test: print "promote2", l else: # update the query queue set_promote_status(links[l], PROMOTE_STATUS.promoted) emailer.live_promo(links[l]) # convert the weighted dict to use sr_ids which are more useful srs = {"":""} for srname in weighted.keys(): if srname: srs[srname] = Subreddit._by_name(srname)._id weighted = dict((srs[k], v) for k, v in weighted.iteritems()) if not test: set_live_promotions(all_links, weighted) _mark_promos_updated() else: print (all_links, weighted) # after launching as many campaigns as possible, raise an exception to # report any error campaigns. (useful for triggering alerts in irc) if error_campaigns: raise Exception("Some scheduled campaigns could not be added to daily " "promotions: %r" % error_campaigns)