Beispiel #1
0
def edit_campaign(link, campaign, dates, bid, cpm, sr, priority):
    sr_name = sr.name if sr else '' # empty string means target to all

    # if the bid amount changed, cancel any pending transactions
    if campaign.bid != bid:
        void_campaign(link, campaign)

    # update the schedule
    PromotionWeights.reschedule(link, campaign._id, sr_name,
                                dates[0], dates[1], bid)

    # update values in the db
    campaign.update(dates[0], dates[1], bid, cpm, sr_name,
                    campaign.trans_id, priority, commit=True)

    if campaign.priority.cpm:
        # record the transaction
        text = 'updated campaign %s. (bid: %0.2f)' % (campaign._id, bid)
        PromotionLog.add(link, text)

        # make it a freebie, if applicable
        author = Account._byID(link.author_id, True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    hooks.get_hook('promote.edit_campaign').call(link=link, campaign=campaign)
Beispiel #2
0
def edit_campaign(link, campaign, dates, bid, sr):
    sr_name = sr.name if sr else '' # empty string means target to all
    try:
        # if the bid amount changed, cancel any pending transactions
        if campaign.bid != bid:
            void_campaign(link, campaign)

        # update the schedule
        PromotionWeights.reschedule(link, campaign._id, sr_name,
                                    dates[0], dates[1], bid)

        # update values in the db
        campaign.update(dates[0], dates[1], bid, sr_name, campaign.trans_id, commit=True)

        # record the transaction
        text = 'updated campaign %s. (bid: %0.2f)' % (campaign._id, bid)
        PromotionLog.add(link, text)

        # make it a freebie, if applicable
        author = Account._byID(link.author_id, True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    except Exception, e: # record error and rethrow 
        g.log.error("Failed to update PromoCampaign %s on link %d. Error was: %r" %
                    (campaign._id, link._id, e))
        try: # wrapped in try/except so orig error won't be lost if commit fails
            text = 'update FAILED. (campaign: %s, bid: %.2f)' % (campaign._id,
                                                                 bid)
            PromotionLog.add(link, text)
        except:
            pass
        raise e
Beispiel #3
0
def edit_campaign(link, campaign, dates, bid, sr):
    sr_name = sr.name if sr else '' # empty string means target to all
    try:
        # if the bid amount changed, cancel any pending transactions
        if campaign.bid != bid:
            void_campaign(link, campaign)

        # update the schedule
        PromotionWeights.reschedule(link, campaign._id, sr_name,
                                    dates[0], dates[1], bid)

        # update values in the db
        campaign.update(dates[0], dates[1], bid, sr_name, campaign.trans_id, commit=True)

        # record the transaction
        text = 'updated campaign %s. (bid: %0.2f)' % (campaign._id, bid)
        PromotionLog.add(link, text)

        # make it a freebie, if applicable
        author = Account._byID(link.author_id, True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    except Exception, e: # record error and rethrow 
        g.log.error("Failed to update PromoCampaign %s on link %d. Error was: %r" %
                    (campaign._id, link._id, e))
        try: # wrapped in try/except so orig error won't be lost if commit fails
            text = 'update FAILED. (campaign: %s, bid: %.2f)' % (campaign._id,
                                                                 bid)
            PromotionLog.add(link, text)
        except:
            pass
        raise e
Beispiel #4
0
def new_campaign(link, dates, bid, sr):
    # empty string for sr_name means target to all
    sr_name = sr.name if sr else ""
    campaign = PromoCampaign._new(link, sr_name, bid, dates[0], dates[1])
    PromotionWeights.add(link, campaign._id, sr_name, dates[0], dates[1], bid)
    PromotionLog.add(link, 'campaign %s created' % campaign._id)
    author = Account._byID(link.author_id, True)
    if getattr(author, "complimentary_promos", False):
        free_campaign(link, campaign, c.user)
    return campaign
Beispiel #5
0
def edit_campaign(link, campaign, dates, bid, cpm, target, priority, location,
                  platform='desktop', mobile_os=None):
    changed = {}
    if bid != campaign.bid:
         # if the bid amount changed, cancel any pending transactions
        void_campaign(link, campaign, reason='changed_bid')
        changed['bid'] = ("$%0.2f" % campaign.bid, "$%0.2f" % bid)
        hooks.get_hook('promote.edit_bid').call(
            link=link,campaign=campaign, previous=campaign.bid, current=bid)
        campaign.bid = bid
    if dates[0] != campaign.start_date or dates[1] != campaign.end_date:
        original = '%s to %s' % (campaign.start_date, campaign.end_date)
        edited = '%s to %s' % (dates[0], dates[1])
        changed['dates'] = (original, edited)
        campaign.start_date = dates[0]
        campaign.end_date = dates[1]
    if cpm != campaign.cpm:
        changed['cpm'] = (campaign.cpm, cpm)
        campaign.cpm = cpm
    if target != campaign.target:
        changed['target'] = (campaign.target, target)
        campaign.target = target
    if priority != campaign.priority:
        changed['priority'] = (campaign.priority.name, priority.name)
        campaign.priority = priority
    if location != campaign.location:
        changed['location'] = (campaign.location, location)
        campaign.location = location
    if platform != campaign.platform:
        changed["platform"] = (campaign.platform, platform)
        campaign.platform = platform
    if mobile_os != campaign.mobile_os:
        changed["mobile_os"] = (campaign.mobile_os, mobile_os)
        campaign.mobile_os = mobile_os

    change_strs = map(lambda t: '%s: %s -> %s' % (t[0], t[1][0], t[1][1]),
                      changed.iteritems())
    change_text = ', '.join(change_strs)
    campaign._commit()

    # update the index
    PromotionWeights.reschedule(link, campaign)

    if campaign.priority.cpm:
        # make it a freebie, if applicable
        author = Account._byID(link.author_id, True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    # record the changes
    if change_text:
        PromotionLog.add(link, 'edited %s: %s' % (campaign, change_text))

    hooks.get_hook('promote.edit_campaign').call(link=link, campaign=campaign)
Beispiel #6
0
def new_campaign(link, dates, bid, cpm, target, priority, location, platform, mobile_os):
    campaign = PromoCampaign.create(link, target, bid, cpm, dates[0], dates[1], priority, location, platform, mobile_os)
    PromotionWeights.add(link, campaign)
    PromotionLog.add(link, "campaign %s created" % campaign._id)

    if campaign.priority.cpm:
        author = Account._byID(link.author_id, data=True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    hooks.get_hook("promote.new_campaign").call(link=link, campaign=campaign)
    return campaign
Beispiel #7
0
def new_campaign(link, dates, bid, cpm, sr, priority, location):
    # empty string for sr_name means target to all
    sr_name = sr.name if sr else ""
    campaign = PromoCampaign._new(link, sr_name, bid, cpm, dates[0], dates[1], priority, location)
    PromotionWeights.add(link, campaign._id, sr_name, dates[0], dates[1], bid)
    PromotionLog.add(link, "campaign %s created" % campaign._id)

    if campaign.priority.cpm:
        author = Account._byID(link.author_id, data=True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    hooks.get_hook("promote.new_campaign").call(link=link, campaign=campaign)
    return campaign
Beispiel #8
0
def new_campaign(link, dates, bid, cpm, target, priority, location):
    campaign = PromoCampaign.create(link, target, bid, cpm, dates[0], dates[1],
                                    priority, location)
    PromotionWeights.add(link, campaign._id, target.subreddit_names, dates[0],
                         dates[1], bid)
    PromotionLog.add(link, 'campaign %s created' % campaign._id)

    if campaign.priority.cpm:
        author = Account._byID(link.author_id, data=True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    hooks.get_hook('promote.new_campaign').call(link=link, campaign=campaign)
    return campaign
Beispiel #9
0
def get_promos(date, sr_names=None, link=None):
    campaign_ids = PromotionWeights.get_campaign_ids(date, sr_names=sr_names, link=link)
    campaigns = PromoCampaign._byID(campaign_ids, data=True, return_dict=False)
    link_ids = {camp.link_id for camp in campaigns}
    links = Link._byID(link_ids, data=True)
    for camp in campaigns:
        yield camp, links[camp.link_id]
Beispiel #10
0
    def GET_report(self, start, end, link_text=None, owner=None):
        now = datetime.now(g.tz).replace(hour=0, minute=0, second=0,
                                         microsecond=0)
        end = end or now - timedelta(days=1)
        start = start or end - timedelta(days=7)

        links = []
        bad_links = []
        owner_name = owner.name if owner else ''

        if owner:
            promo_weights = PromotionWeights.get_campaigns(start, end,
                                                           author_id=owner._id)
            campaign_ids = [pw.promo_idx for pw in promo_weights]
            campaigns = PromoCampaign._byID(campaign_ids, data=True)
            link_ids = {camp.link_id for camp in campaigns.itervalues()}
            links.extend(Link._byID(link_ids, data=True, return_dict=False))

        if link_text is not None:
            id36s = link_text.replace(',', ' ').split()
            try:
                links_from_text = Link._byID36(id36s, data=True)
            except NotFound:
                links_from_text = {}

            bad_links = [id36 for id36 in id36s if id36 not in links_from_text]
            links.extend(links_from_text.values())

        content = PromoteReport(links, link_text, owner_name, bad_links, start,
                                end)
        if c.render_style == 'csv':
            return content.as_csv()
        else:
            return PromotePage(title=_("sponsored link report"),
                               content=content).render()
Beispiel #11
0
def new_campaign(link, dates, bid, cpm, sr, priority):
    # empty string for sr_name means target to all
    sr_name = sr.name if sr else ""
    campaign = PromoCampaign._new(link, sr_name, bid, cpm, dates[0], dates[1],
                                  priority)
    PromotionWeights.add(link, campaign._id, sr_name, dates[0], dates[1], bid)
    PromotionLog.add(link, 'campaign %s created' % campaign._id)

    if campaign.priority.cpm:
        author = Account._byID(link.author_id, data=True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)
    else:
        # non-cpm campaigns are never charged, so we need to fire the hook now
        hooks.get_hook('promote.new_charge').call(link=link, campaign=campaign)
    return campaign
Beispiel #12
0
def scheduled_campaigns_by_link(l, date=None):
    # A promotion/campaign is scheduled/live if it's in
    # PromotionWeights.get_campaigns(now) and
    # charged_or_not_needed

    date = date or promo_datetime_now()

    if not is_accepted(l):
        return []

    scheduled = PromotionWeights.get_campaigns(date)
    campaigns = [c.promo_idx for c in scheduled if c.thing_name == l._fullname]

    # Check authorize
    accepted = []
    for campaign_id in campaigns:
        try:
            campaign = PromoCampaign._byID(campaign_id, data=True)
            if charged_or_not_needed(campaign):
                accepted.append(campaign_id)
        except NotFound:
            g.log.error("PromoCampaign %d scheduled to run on %s not found." %
                          (campaign_id, date.strftime("%Y-%m-%d")))

    return accepted
Beispiel #13
0
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)
Beispiel #14
0
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)
Beispiel #15
0
def get_sold_pageviews(srs, start, end, ignore=None):
    srs, is_single = tup(srs, ret_is_single=True)
    sr_names = ['' if isinstance(sr, DefaultSR) else sr.name for sr in srs]
    dates = set(get_date_range(start, end))
    ignore = [] if ignore is None else ignore
    q = (PromotionWeights.query()
                .filter(PromotionWeights.sr_name.in_(sr_names))
                .filter(PromotionWeights.date.in_(dates)))
    campaign_ids = {pw.promo_idx for pw in q}
    campaigns = PromoCampaign._byID(campaign_ids, data=True, return_dict=False)

    ret = {sr.name: dict.fromkeys(dates, 0) for sr in srs}
    for camp in campaigns:
        if camp.trans_id == NO_TRANSACTION:
            continue

        if ignore and camp._id in ignore:
            continue

        if camp.impressions <= 0:
            # pre-CPM campaign
            continue

        sr_name = camp.sr_name or DefaultSR.name
        daily_impressions = camp.impressions / camp.ndays
        camp_dates = set(get_date_range(camp.start_date, camp.end_date))
        for date in camp_dates.intersection(dates):
            ret[sr_name][date] += daily_impressions

    if is_single:
        return ret[srs[0].name]
    else:
        return ret
Beispiel #16
0
    def GET_report(self, start, end, link_text=None, owner=None):
        now = datetime.now(g.tz).replace(hour=0, minute=0, second=0,
                                         microsecond=0)
        end = end or now - timedelta(days=1)
        start = start or end - timedelta(days=7)

        links = []
        bad_links = []
        owner_name = owner.name if owner else ''

        if owner:
            promo_weights = PromotionWeights.get_campaigns(start, end,
                                                           author_id=owner._id)
            campaign_ids = [pw.promo_idx for pw in promo_weights]
            campaigns = PromoCampaign._byID(campaign_ids, data=True)
            link_ids = {camp.link_id for camp in campaigns.itervalues()}
            links.extend(Link._byID(link_ids, data=True, return_dict=False))

        if link_text is not None:
            id36s = link_text.replace(',', ' ').split()
            try:
                links_from_text = Link._byID36(id36s, data=True)
            except NotFound:
                links_from_text = {}

            bad_links = [id36 for id36 in id36s if id36 not in links_from_text]
            links.extend(links_from_text.values())

        content = PromoteReport(links, link_text, owner_name, bad_links, start,
                                end)
        if c.render_style == 'csv':
            return content.as_csv()
        else:
            return PromotePage(title=_("sponsored link report"),
                               content=content).render()
Beispiel #17
0
def edit_campaign(link, campaign, dates, bid, cpm, sr, priority, location):
    sr_name = sr.name if sr else '' # empty string means target to all

    changed = {}
    if bid != campaign.bid:
        changed['bid'] = ("$%0.2f" % campaign.bid, "$%0.2f" % bid)
    if dates[0] != campaign.start_date or dates[1] != campaign.end_date:
        original = '%s to %s' % (campaign.start_date, campaign.end_date)
        edited = '%s to %s' % (dates[0], dates[1])
        changed['dates'] = (original, edited)
    if cpm != campaign.cpm:
        changed['cpm'] = (campaign.cpm, cpm)
    if sr_name != campaign.sr_name:
        format_sr_name = (lambda sr_name: '/r/%s' % sr_name if sr_name
                                                            else '<frontpage>')
        changed['sr_name'] = map(format_sr_name, (campaign.sr_name, sr_name))
    if priority != campaign.priority:
        changed['priority'] = (campaign.priority.name, priority.name)

    change_strs = map(lambda t: '%s: %s -> %s' % (t[0], t[1][0], t[1][1]),
                      changed.iteritems())
    change_text = ', '.join(change_strs)

    # if the bid amount changed, cancel any pending transactions
    if campaign.bid != bid:
        void_campaign(link, campaign, reason='changed_bid')

    # update the schedule
    PromotionWeights.reschedule(link, campaign._id, sr_name,
                                dates[0], dates[1], bid)

    # update values in the db
    campaign.update(dates[0], dates[1], bid, cpm, sr_name,
                    campaign.trans_id, priority, location, commit=True)

    if campaign.priority.cpm:
        # make it a freebie, if applicable
        author = Account._byID(link.author_id, True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    # record the changes
    if change_text:
        PromotionLog.add(link, 'edited %s: %s' % (campaign, change_text))

    hooks.get_hook('promote.edit_campaign').call(link=link, campaign=campaign)
Beispiel #18
0
 def get_house_link_names(cls):
     now = promote.promo_datetime_now()
     pws = PromotionWeights.get_campaigns(now)
     campaign_ids = {pw.promo_idx for pw in pws}
     q = PromoCampaign._query(PromoCampaign.c._id.in_(campaign_ids),
                              PromoCampaign.c.priority_name == 'house',
                              data=True)
     return [Link._fullname_from_id36(to36(camp.link_id)) for camp in q]
Beispiel #19
0
 def get_house_campaigns(cls):
     now = promote.promo_datetime_now()
     pws = PromotionWeights.get_campaigns(now)
     campaign_ids = {pw.promo_idx for pw in pws}
     campaigns = PromoCampaign._byID(campaign_ids, data=True,
                                     return_dict=False)
     campaigns = [camp for camp in campaigns if not camp.priority.cpm]
     return campaigns
Beispiel #20
0
def edit_campaign(link, campaign, dates, bid, cpm, target, priority, location):
    changed = {}
    if bid != campaign.bid:
        # if the bid amount changed, cancel any pending transactions
        void_campaign(link, campaign, reason="changed_bid")
        changed["bid"] = ("$%0.2f" % campaign.bid, "$%0.2f" % bid)
        hooks.get_hook("promote.edit_bid").call(link=link, campaign=campaign, previous=campaign.bid, current=bid)
        campaign.bid = bid
    if dates[0] != campaign.start_date or dates[1] != campaign.end_date:
        original = "%s to %s" % (campaign.start_date, campaign.end_date)
        edited = "%s to %s" % (dates[0], dates[1])
        changed["dates"] = (original, edited)
        campaign.start_date = dates[0]
        campaign.end_date = dates[1]
    if cpm != campaign.cpm:
        changed["cpm"] = (campaign.cpm, cpm)
        campaign.cpm = cpm
    if target != campaign.target:
        changed["target"] = (campaign.target, target)
        campaign.target = target
    if priority != campaign.priority:
        changed["priority"] = (campaign.priority.name, priority.name)
        campaign.priority = priority
    if location != campaign.location:
        changed["location"] = (campaign.location, location)
        campaign.location = location

    change_strs = map(lambda t: "%s: %s -> %s" % (t[0], t[1][0], t[1][1]), changed.iteritems())
    change_text = ", ".join(change_strs)
    campaign._commit()

    # update the index
    PromotionWeights.reschedule(link, campaign)

    if campaign.priority.cpm:
        # make it a freebie, if applicable
        author = Account._byID(link.author_id, True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    # record the changes
    if change_text:
        PromotionLog.add(link, "edited %s: %s" % (campaign, change_text))

    hooks.get_hook("promote.edit_campaign").call(link=link, campaign=campaign)
Beispiel #21
0
def new_campaign(
    link,
    dates,
    target,
    frequency_cap,
    priority,
    location,
    platform,
    mobile_os,
    ios_devices,
    ios_version_range,
    android_devices,
    android_version_range,
    total_budget_pennies,
    cost_basis,
    bid_pennies,
):
    campaign = PromoCampaign.create(
        link,
        target,
        dates[0],
        dates[1],
        frequency_cap,
        priority,
        location,
        platform,
        mobile_os,
        ios_devices,
        ios_version_range,
        android_devices,
        android_version_range,
        total_budget_pennies,
        cost_basis,
        bid_pennies,
    )
    PromotionWeights.add(link, campaign)
    PromotionLog.add(link, "campaign %s created" % campaign._id)

    if not campaign.is_house:
        author = Account._byID(link.author_id, data=True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    hooks.get_hook("promote.new_campaign").call(link=link, campaign=campaign)
    return campaign
Beispiel #22
0
 def get_house_campaigns(cls):
     now = promote.promo_datetime_now()
     pws = PromotionWeights.get_campaigns(now)
     campaign_ids = {pw.promo_idx for pw in pws}
     campaigns = PromoCampaign._byID(campaign_ids,
                                     data=True,
                                     return_dict=False)
     campaigns = [camp for camp in campaigns if not camp.priority.cpm]
     return campaigns
Beispiel #23
0
def new_campaign(link, dates, target, frequency_cap, priority, location,
                 platform, mobile_os, ios_devices, ios_version_range,
                 android_devices, android_version_range, total_budget_pennies,
                 cost_basis, bid_pennies):
    campaign = PromoCampaign.create(
        link, target, dates[0], dates[1], frequency_cap, priority, location,
        platform, mobile_os, ios_devices, ios_version_range, android_devices,
        android_version_range, total_budget_pennies, cost_basis, bid_pennies)
    PromotionWeights.add(link, campaign)
    PromotionLog.add(link, 'campaign %s created' % campaign._id)

    if not campaign.is_house:
        author = Account._byID(link.author_id, data=True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    hooks.get_hook('promote.new_campaign').call(link=link, campaign=campaign)
    return campaign
Beispiel #24
0
 def get_house_link_names(cls):
     now = promote.promo_datetime_now()
     campaign_ids = PromotionWeights.get_campaign_ids(now)
     q = PromoCampaign._query(PromoCampaign.c._id.in_(campaign_ids),
                              PromoCampaign.c.priority_name == 'house',
                              data=True)
     link_names = {Link._fullname_from_id36(to36(camp.link_id))
                   for camp in q}
     return sorted(link_names, reverse=True)
Beispiel #25
0
def new_campaign(link, dates, bid, cpm, target, frequency_cap, frequency_cap_duration,
                 priority, location, platform, mobile_os, ios_devices,
                 ios_version_range, android_devices, android_version_range):
    campaign = PromoCampaign.create(link, target, bid, cpm, dates[0], dates[1],
                                    frequency_cap, frequency_cap_duration, priority,
                                    location, platform, mobile_os, ios_devices,
                                    ios_version_range, android_devices,
                                    android_version_range)
    PromotionWeights.add(link, campaign)
    PromotionLog.add(link, 'campaign %s created' % campaign._id)

    if campaign.priority.cpm:
        author = Account._byID(link.author_id, data=True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    hooks.get_hook('promote.new_campaign').call(link=link, campaign=campaign)
    return campaign
Beispiel #26
0
def get_campaigns_by_date(srs, start, end, ignore=None):
    srs, is_single = tup(srs, ret_is_single=True)
    sr_names = ['' if isinstance(sr, DefaultSR) else sr.name for sr in srs]
    dates = set(get_date_range(start, end))
    q = (PromotionWeights.query()
                .filter(PromotionWeights.sr_name.in_(sr_names))
                .filter(PromotionWeights.date.in_(dates)))

    if ignore:
        q = q.filter(PromotionWeights.promo_idx != ignore._id)

    campaign_ids = {pw.promo_idx for pw in q}
    campaigns = PromoCampaign._byID(campaign_ids, data=True, return_dict=False)
    transaction_ids = {camp.trans_id for camp in campaigns
                                     if camp.trans_id != NO_TRANSACTION}

    if transaction_ids:
        transactions = Bid.query().filter(Bid.transaction.in_(transaction_ids))
        transaction_by_id = {bid.transaction: bid for bid in transactions}
    else:
        transaction_by_id = {}

    ret = {sr.name: dict.fromkeys(dates) for sr in srs}
    for srname, date_dict in ret.iteritems():
        for date in date_dict:
            ret[srname][date] = []

    for camp in campaigns:
        if camp.trans_id == NO_TRANSACTION:
            continue

        if camp.impressions <= 0:
            # pre-CPM campaign
            continue

        transaction = transaction_by_id[camp.trans_id]
        if not (transaction.is_auth() or transaction.is_charged()):
            continue

        sr_names = camp.target.subreddit_names
        camp_dates = set(get_date_range(camp.start_date, camp.end_date))
        for date in camp_dates.intersection(dates):
            for sr_name in sr_names:
                ret[sr_name][date].append(camp)

    if is_single:
        return ret[srs[0].name]
    else:
        return ret
Beispiel #27
0
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)
Beispiel #28
0
def get_campaigns_by_date(srs, start, end, ignore=None):
    srs = tup(srs)
    sr_names = [sr.name for sr in srs]
    campaign_ids = PromotionWeights.get_campaign_ids(
        start, end=end, sr_names=sr_names)
    if ignore:
        campaign_ids.discard(ignore._id)
    campaigns = PromoCampaign._byID(campaign_ids, data=True, return_dict=False)

    # filter out deleted campaigns that didn't have their PromotionWeights
    # deleted
    campaigns = filter(lambda camp: not camp._deleted, campaigns)

    transaction_ids = {camp.trans_id for camp in campaigns
                                     if camp.trans_id != NO_TRANSACTION}

    if transaction_ids:
        transactions = Bid.query().filter(Bid.transaction.in_(transaction_ids))
        # index transactions by transaction and campaign id because freebies
        # reuse the same transaction id (they always use -link id)
        transaction_by_id = {
            (bid.transaction, bid.campaign): bid for bid in transactions}
    else:
        transaction_by_id = {}

    dates = set(get_date_range(start, end))
    ret = {date: set() for date in dates}
    for camp in campaigns:
        if camp.trans_id == NO_TRANSACTION:
            continue

        if camp.impressions <= 0:
            # pre-CPM campaign
            continue

        transaction = transaction_by_id[(camp.trans_id, camp._id)]
        if not (transaction.is_auth() or transaction.is_charged()):
            continue

        camp_dates = set(get_date_range(camp.start_date, camp.end_date))
        for date in camp_dates.intersection(dates):
            ret[date].add(camp)
    return ret
Beispiel #29
0
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)
Beispiel #30
0
def set_live_promotions(weights):
    start = time.time()
    # First, figure out which subreddits have had ads recently
    today = promo_datetime_now()
    yesterday = today - timedelta(days=1)
    tomorrow = today + timedelta(days=1)
    promo_weights = PromotionWeights.get_campaigns(yesterday, tomorrow)
    subreddit_names = set(p.sr_name for p in promo_weights)
    subreddits = Subreddit._by_name(subreddit_names).values()
    # Set the default for those subreddits to no ads
    all_weights = {sr._id: [] for sr in subreddits}

    # Mix in the currently live ads
    all_weights.update(weights)
    if "" in all_weights:
        all_weights[LiveAdWeights.FRONT_PAGE] = all_weights.pop("")

    LiveAdWeights.set_all_from_weights(all_weights)
    end = time.time()
    g.log.info("promote.set_live_promotions completed in %s seconds", end - start)
Beispiel #31
0
def accepted_campaigns(offset=0):
    now = promo_datetime_now(offset=offset)
    promo_weights = PromotionWeights.get_campaigns(now)
    all_links = Link._by_fullname(set(x.thing_name for x in promo_weights), data=True, return_dict=True)
    accepted_links = {}
    for link_fullname, link in all_links.iteritems():
        if is_accepted(link):
            accepted_links[link._id] = link

    accepted_link_ids = accepted_links.keys()
    campaign_query = PromoCampaign._query(PromoCampaign.c.link_id == accepted_link_ids, data=True)
    campaigns = dict((camp._id, camp) for camp in campaign_query)
    for pw in promo_weights:
        campaign = campaigns.get(pw.promo_idx)
        if not campaign or (not campaign.trans_id and campaign.priority.cpm):
            continue
        link = accepted_links.get(campaign.link_id)
        if not link:
            continue

        yield (link, campaign, pw.weight)
Beispiel #32
0
def accepted_campaigns(offset=0):
    now = promo_datetime_now(offset=offset)
    promo_weights = PromotionWeights.get_campaigns(now)
    all_links = Link._by_fullname(set(x.thing_name for x in promo_weights),
                                  data=True, return_dict=True)
    accepted_links = {}
    for link_fullname, link in all_links.iteritems():
        if is_accepted(link):
            accepted_links[link._id] = link

    accepted_link_ids = accepted_links.keys()
    campaign_query = PromoCampaign._query(PromoCampaign.c.link_id == accepted_link_ids,
                                          data=True)
    campaigns = dict((camp._id, camp) for camp in campaign_query)
    for pw in promo_weights:
        campaign = campaigns.get(pw.promo_idx)
        if not campaign or not campaign.trans_id:
            continue
        link = accepted_links.get(campaign.link_id)
        if not link:
            continue

        yield (link, campaign, pw.weight)
Beispiel #33
0
def delete_campaign(link, campaign):
    PromotionWeights.delete_unfinished(link, campaign._id)
    void_campaign(link, campaign)
    campaign.delete()
    PromotionLog.add(link, 'deleted campaign %s' % campaign._id)
    hooks.get_hook('campaign.void').call(link=link, campaign=campaign)
Beispiel #34
0
def delete_campaign(link, campaign):
    PromotionWeights.delete(link, campaign)
    void_campaign(link, campaign, reason='deleted_campaign')
    campaign.delete()
    PromotionLog.add(link, 'deleted campaign %s' % campaign._id)
    hooks.get_hook('promote.delete_campaign').call(link=link, campaign=campaign)
Beispiel #35
0
def edit_campaign(link, campaign, dates, target, frequency_cap,
                  priority, location,
                  total_budget_pennies, cost_basis, bid_pennies,
                  platform='desktop', mobile_os=None, ios_devices=None,
                  ios_version_range=None, android_devices=None,
                  android_version_range=None):
    changed = {}
    if dates[0] != campaign.start_date or dates[1] != campaign.end_date:
        original = '%s to %s' % (campaign.start_date, campaign.end_date)
        edited = '%s to %s' % (dates[0], dates[1])
        changed['dates'] = (original, edited)
        campaign.start_date = dates[0]
        campaign.end_date = dates[1]
    if target != campaign.target:
        changed['target'] = (campaign.target, target)
        campaign.target = target
    if frequency_cap != campaign.frequency_cap:
        changed['frequency_cap'] = (campaign.frequency_cap, frequency_cap)
        campaign.frequency_cap = frequency_cap
    if priority != campaign.priority:
        changed['priority'] = (campaign.priority.name, priority.name)
        campaign.priority = priority
    if location != campaign.location:
        changed['location'] = (campaign.location, location)
        campaign.location = location
    if platform != campaign.platform:
        changed["platform"] = (campaign.platform, platform)
        campaign.platform = platform
    if mobile_os != campaign.mobile_os:
        changed["mobile_os"] = (campaign.mobile_os, mobile_os)
        campaign.mobile_os = mobile_os
    if ios_devices != campaign.ios_devices:
        changed['ios_devices'] = (campaign.ios_devices, ios_devices)
        campaign.ios_devices = ios_devices
    if android_devices != campaign.android_devices:
        changed['android_devices'] = (campaign.android_devices, android_devices)
        campaign.android_devices = android_devices
    if ios_version_range != campaign.ios_version_range:
        changed['ios_version_range'] = (campaign.ios_version_range,
                                        ios_version_range)
        campaign.ios_version_range = ios_version_range
    if android_version_range != campaign.android_version_range:
        changed['android_version_range'] = (campaign.android_version_range,
                                            android_version_range)
        campaign.android_version_range = android_version_range
    if total_budget_pennies != campaign.total_budget_pennies:
        void_campaign(link, campaign, reason='changed_budget')
        campaign.total_budget_pennies = total_budget_pennies
    if cost_basis != campaign.cost_basis:
        changed['cost_basis'] = (campaign.cost_basis, cost_basis)
        campaign.cost_basis = cost_basis
    if bid_pennies != campaign.bid_pennies:
        changed['bid_pennies'] = (campaign.bid_pennies,
                                        bid_pennies)
        campaign.bid_pennies = bid_pennies

    change_strs = map(lambda t: '%s: %s -> %s' % (t[0], t[1][0], t[1][1]),
                      changed.iteritems())
    change_text = ', '.join(change_strs)
    campaign._commit()

    # update the index
    PromotionWeights.reschedule(link, campaign)

    if not campaign.is_house:
        # make it a freebie, if applicable
        author = Account._byID(link.author_id, True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    # record the changes
    if change_text:
        PromotionLog.add(link, 'edited %s: %s' % (campaign, change_text))

    hooks.get_hook('promote.edit_campaign').call(link=link, campaign=campaign)
Beispiel #36
0
def delete_campaign(link, campaign):
    PromotionWeights.delete_unfinished(link, campaign._id)
    void_campaign(link, campaign)
    campaign.delete()
    PromotionLog.add(link, 'deleted campaign %s' % campaign._id)
Beispiel #37
0
def delete_campaign(link, campaign):
    PromotionWeights.delete_unfinished(link, campaign._id)
    void_campaign(link, campaign)
    campaign.delete()
    PromotionLog.add(link, 'deleted campaign %s' % campaign._id)
    hooks.get_hook('campaign.void').call(link=link, campaign=campaign)
Beispiel #38
0
def edit_campaign(link,
                  campaign,
                  dates,
                  target,
                  frequency_cap,
                  priority,
                  location,
                  total_budget_pennies,
                  cost_basis,
                  bid_pennies,
                  platform='desktop',
                  mobile_os=None,
                  ios_devices=None,
                  ios_version_range=None,
                  android_devices=None,
                  android_version_range=None):
    changed = {}
    if dates[0] != campaign.start_date or dates[1] != campaign.end_date:
        original = '%s to %s' % (campaign.start_date, campaign.end_date)
        edited = '%s to %s' % (dates[0], dates[1])
        changed['dates'] = (original, edited)
        campaign.start_date = dates[0]
        campaign.end_date = dates[1]
    if target != campaign.target:
        changed['target'] = (campaign.target, target)
        campaign.target = target
    if frequency_cap != campaign.frequency_cap:
        changed['frequency_cap'] = (campaign.frequency_cap, frequency_cap)
        campaign.frequency_cap = frequency_cap
    if priority != campaign.priority:
        changed['priority'] = (campaign.priority.name, priority.name)
        campaign.priority = priority
    if location != campaign.location:
        changed['location'] = (campaign.location, location)
        campaign.location = location
    if platform != campaign.platform:
        changed["platform"] = (campaign.platform, platform)
        campaign.platform = platform
    if mobile_os != campaign.mobile_os:
        changed["mobile_os"] = (campaign.mobile_os, mobile_os)
        campaign.mobile_os = mobile_os
    if ios_devices != campaign.ios_devices:
        changed['ios_devices'] = (campaign.ios_devices, ios_devices)
        campaign.ios_devices = ios_devices
    if android_devices != campaign.android_devices:
        changed['android_devices'] = (campaign.android_devices,
                                      android_devices)
        campaign.android_devices = android_devices
    if ios_version_range != campaign.ios_version_range:
        changed['ios_version_range'] = (campaign.ios_version_range,
                                        ios_version_range)
        campaign.ios_version_range = ios_version_range
    if android_version_range != campaign.android_version_range:
        changed['android_version_range'] = (campaign.android_version_range,
                                            android_version_range)
        campaign.android_version_range = android_version_range
    if total_budget_pennies != campaign.total_budget_pennies:
        void_campaign(link, campaign, reason='changed_budget')
        campaign.total_budget_pennies = total_budget_pennies
    if cost_basis != campaign.cost_basis:
        changed['cost_basis'] = (campaign.cost_basis, cost_basis)
        campaign.cost_basis = cost_basis
    if bid_pennies != campaign.bid_pennies:
        changed['bid_pennies'] = (campaign.bid_pennies, bid_pennies)
        campaign.bid_pennies = bid_pennies

    change_strs = map(lambda t: '%s: %s -> %s' % (t[0], t[1][0], t[1][1]),
                      changed.iteritems())
    change_text = ', '.join(change_strs)
    campaign._commit()

    # update the index
    PromotionWeights.reschedule(link, campaign)

    if not campaign.is_house:
        # make it a freebie, if applicable
        author = Account._byID(link.author_id, True)
        if getattr(author, "complimentary_promos", False):
            free_campaign(link, campaign, c.user)

    # record the changes
    if change_text:
        PromotionLog.add(link, 'edited %s: %s' % (campaign, change_text))

    hooks.get_hook('promote.edit_campaign').call(link=link, campaign=campaign)