Ejemplo n.º 1
0
    def POST_terminate_campaign(self, form, jquery, link, campaign):
        if not link or not campaign or link._id != campaign.link_id:
            return abort(404, 'not found')

        promote.terminate_campaign(link, campaign)
        rc = RenderableCampaign.from_campaigns(link, campaign)
        jquery.update_campaign(campaign._fullname, rc.render_html())
Ejemplo n.º 2
0
    def listing(self):
        """For sponsors, update wrapped links to include their campaigns."""
        pane = super(self.__class__, self).listing()

        if c.user_is_sponsor:
            link_ids = {item._id for item in pane.things}
            campaigns = PromoCampaign._by_link(link_ids)
            campaigns_by_link = defaultdict(list)
            for camp in campaigns:
                campaigns_by_link[camp.link_id].append(camp)

            for item in pane.things:
                campaigns = campaigns_by_link[item._id]
                item.campaigns = RenderableCampaign.from_campaigns(
                    item, campaigns, full_details=False)
                item.cachable = False
                item.show_campaign_summary = True
        return pane
Ejemplo n.º 3
0
    def POST_edit_campaign(self, form, jquery, link, campaign_id36,
                           dates, bid, target, priority, location):
        if not link:
            return

        if not target:
            # run form.has_errors to populate the errors in the response
            form.has_errors('sr', errors.SUBREDDIT_NOEXIST,
                            errors.SUBREDDIT_NOTALLOWED,
                            errors.SUBREDDIT_REQUIRED)
            form.has_errors('collection', errors.COLLECTION_NOEXIST)
            form.has_errors('targeting', errors.INVALID_TARGET)
            return

        start, end = dates or (None, None)
        is_frontpage = (not target.is_collection and
                        target.subreddit_name == Frontpage.name)

        if (location and
                target.is_collection or
                (not is_frontpage and not c.user_is_sponsor)):
            # regular users can only target to Frontpage and no one can
            # location target a collection
            location = None

        if location and location.metro:
            cpm = g.cpm_selfserve_geotarget_metro.pennies
        elif (target.is_collection and
                target.collection.name == "technology buffs"):
            # special price override -- technology collection is more expensive
            author = Account._byID(link.author_id, data=True)
            cpm = author.cpm_selfserve_pennies
        elif target.is_collection or is_frontpage:
            cpm = g.cpm_selfserve_collection.pennies
        else:
            author = Account._byID(link.author_id, data=True)
            cpm = author.cpm_selfserve_pennies

        if (form.has_errors('startdate', errors.BAD_DATE,
                            errors.DATE_TOO_EARLY, errors.DATE_TOO_LATE) or
            form.has_errors('enddate', errors.BAD_DATE, errors.DATE_TOO_EARLY,
                            errors.DATE_TOO_LATE, errors.BAD_DATE_RANGE)):
            return

        # check that start is not so late that authorization hold will expire
        if not c.user_is_sponsor:
            max_start = promote.get_max_startdate()
            if start > max_start:
                c.errors.add(errors.DATE_TOO_LATE,
                             msg_params={'day': max_start.strftime("%m/%d/%Y")},
                             field='startdate')
                form.has_errors('startdate', errors.DATE_TOO_LATE)
                return

        # Limit the number of PromoCampaigns a Link can have
        # Note that the front end should prevent the user from getting
        # this far
        existing_campaigns = list(PromoCampaign._by_link(link._id))
        if len(existing_campaigns) > g.MAX_CAMPAIGNS_PER_LINK:
            c.errors.add(errors.TOO_MANY_CAMPAIGNS,
                         msg_params={'count': g.MAX_CAMPAIGNS_PER_LINK},
                         field='title')
            form.has_errors('title', errors.TOO_MANY_CAMPAIGNS)
            return

        campaign = None
        if campaign_id36:
            try:
                campaign = PromoCampaign._byID36(campaign_id36)
            except NotFound:
                pass

        if campaign and link._id != campaign.link_id:
            return abort(404, 'not found')

        if priority.cpm:
            min_bid = 0 if c.user_is_sponsor else g.min_promote_bid
            max_bid = None if c.user_is_sponsor else g.max_promote_bid

            if bid is None or bid < min_bid or (max_bid and bid > max_bid):
                c.errors.add(errors.BAD_BID, field='bid',
                             msg_params={'min': min_bid,
                                         'max': max_bid or g.max_promote_bid})
                form.has_errors('bid', errors.BAD_BID)
                return

            # you cannot edit the bid of a live ad unless it's a freebie
            if (campaign and bid != campaign.bid and
                promote.is_live_promo(link, campaign) and
                not campaign.is_freebie()):
                c.errors.add(errors.BID_LIVE, field='bid')
                form.has_errors('bid', errors.BID_LIVE)
                return

        else:
            bid = 0.   # Set bid to 0 as dummy value

        if not target.is_collection and not is_frontpage:
            # targeted to a single subreddit, check roadblock
            sr = target.subreddits_slow[0]
            roadblock = PromotedLinkRoadblock.is_roadblocked(sr, start, end)
            if roadblock and not c.user_is_sponsor:
                msg_params = {"start": roadblock[0].strftime('%m/%d/%Y'),
                              "end": roadblock[1].strftime('%m/%d/%Y')}
                c.errors.add(errors.OVERSOLD, field='sr',
                             msg_params=msg_params)
                form.has_errors('sr', errors.OVERSOLD)
                return

        # Check inventory
        campaign = campaign if campaign_id36 else None
        if not priority.inventory_override:
            oversold = has_oversold_error(form, campaign, start, end, bid, cpm,
                                          target, location)
            if oversold:
                return

        if campaign:
            promote.edit_campaign(link, campaign, dates, bid, cpm, target,
                                  priority, location)
        else:
            campaign = promote.new_campaign(link, dates, bid, cpm, target,
                                            priority, location)
        rc = RenderableCampaign.from_campaigns(link, campaign)
        jquery.update_campaign(campaign._fullname, rc.render_html())
Ejemplo n.º 4
0
    def POST_edit_campaign(self, form, jquery, link, campaign_id36,
                          dates, bid, sr, targeting, priority, location):
        if not link:
            return

        start, end = dates or (None, None)

        if location and sr and not c.user_is_sponsor:
            # only sponsors can geotarget on subreddits
            location = None

        if location and location.metro:
            cpm = g.cpm_selfserve_geotarget_metro.pennies
        elif location:
            cpm = g.cpm_selfserve_geotarget_country.pennies
        else:
            author = Account._byID(link.author_id, data=True)
            cpm = author.cpm_selfserve_pennies

        if (form.has_errors('startdate', errors.BAD_DATE,
                            errors.DATE_TOO_EARLY, errors.DATE_TOO_LATE) or
            form.has_errors('enddate', errors.BAD_DATE, errors.DATE_TOO_EARLY,
                            errors.DATE_TOO_LATE, errors.BAD_DATE_RANGE)):
            return

        # Limit the number of PromoCampaigns a Link can have
        # Note that the front end should prevent the user from getting
        # this far
        existing_campaigns = list(PromoCampaign._by_link(link._id))
        if len(existing_campaigns) > g.MAX_CAMPAIGNS_PER_LINK:
            c.errors.add(errors.TOO_MANY_CAMPAIGNS,
                         msg_params={'count': g.MAX_CAMPAIGNS_PER_LINK},
                         field='title')
            form.has_errors('title', errors.TOO_MANY_CAMPAIGNS)
            return

        campaign = None
        if campaign_id36:
            try:
                campaign = PromoCampaign._byID36(campaign_id36)
            except NotFound:
                pass

        if campaign and link._id != campaign.link_id:
            return abort(404, 'not found')

        if priority.cpm:
            min_bid = 0 if c.user_is_sponsor else g.min_promote_bid
            max_bid = None if c.user_is_sponsor else g.max_promote_bid

            if bid is None or bid < min_bid or (max_bid and bid > max_bid):
                c.errors.add(errors.BAD_BID, field='bid',
                             msg_params={'min': min_bid,
                                         'max': max_bid or g.max_promote_bid})
                form.has_errors('bid', errors.BAD_BID)
                return

            # you cannot edit the bid of a live ad unless it's a freebie
            if (campaign and bid != campaign.bid and
                promote.is_live_promo(link, campaign) and
                not campaign.is_freebie()):
                c.errors.add(errors.BID_LIVE, field='bid')
                form.has_errors('bid', errors.BID_LIVE)
                return

        else:
            bid = 0.   # Set bid to 0 as dummy value

        if targeting == 'one':
            if form.has_errors('sr', errors.SUBREDDIT_NOEXIST,
                               errors.SUBREDDIT_NOTALLOWED,
                               errors.SUBREDDIT_REQUIRED):
                # checking to get the error set in the form, but we can't
                # check for rate-limiting if there's no subreddit
                return

            roadblock = PromotedLinkRoadblock.is_roadblocked(sr, start, end)
            if roadblock and not c.user_is_sponsor:
                msg_params = {"start": roadblock[0].strftime('%m/%d/%Y'),
                              "end": roadblock[1].strftime('%m/%d/%Y')}
                c.errors.add(errors.OVERSOLD, field='sr',
                             msg_params=msg_params)
                form.has_errors('sr', errors.OVERSOLD)
                return

        elif targeting == 'none':
            sr = None

        # Check inventory
        campaign = campaign if campaign_id36 else None
        if not priority.inventory_override:
            oversold = has_oversold_error(form, campaign, start, end, bid, cpm,
                                          sr, location)
            if oversold:
                return

        if campaign:
            promote.edit_campaign(link, campaign, dates, bid, cpm, sr, priority,
                                  location)
        else:
            campaign = promote.new_campaign(link, dates, bid, cpm, sr, priority,
                                            location)
        rc = RenderableCampaign.from_campaigns(link, campaign)
        jquery.update_campaign(campaign._fullname, rc.render_html())
Ejemplo n.º 5
0
 def POST_terminate_campaign(self, form, jquery, link, campaign):
     if link and campaign:
         promote.terminate_campaign(link, campaign)
         rc = RenderableCampaign.from_campaigns(link, campaign)
         jquery.update_campaign(campaign._fullname, rc.render_html())
Ejemplo n.º 6
0
    def POST_edit_campaign(self, form, jquery, link, campaign_id36,
                           start, end, bid, target, priority, location,
                           platform, mobile_os):
        if not link:
            return

        if platform in ('mobile', 'all') and not mobile_os:
            c.errors.add(errors.BAD_PROMO_MOBILE_OS, field='mobile_os')
            form.set_error(errors.BAD_PROMO_MOBILE_OS, 'mobile_os')
            return

        if not (c.user_is_sponsor or platform == 'desktop'):
            return abort(403, 'forbidden')

        if platform == 'desktop':
            mobile_os = None

        if not target:
            # run form.has_errors to populate the errors in the response
            form.has_errors('sr', errors.SUBREDDIT_NOEXIST,
                            errors.SUBREDDIT_NOTALLOWED,
                            errors.SUBREDDIT_REQUIRED)
            form.has_errors('collection', errors.COLLECTION_NOEXIST)
            form.has_errors('targeting', errors.INVALID_TARGET)
            return

        if not allowed_location_and_target(location, target):
            return abort(403, 'forbidden')

        cpm = PromotionPrices.get_price(c.user, target, location)

        if (form.has_errors('startdate', errors.BAD_DATE) or
                form.has_errors('enddate', errors.BAD_DATE)):
            return

        min_start, max_start, max_end = promote.get_date_limits(
            link, c.user_is_sponsor)

        if campaign_id36:
            promo_campaign = PromoCampaign._byID36(campaign_id36)
            if (promote.is_promoted(link) and
                    promo_campaign.start_date.date() <= min_start and
                    start != promo_campaign.start_date and
                    promo_campaign.is_paid):
                c.errors.add(errors.START_DATE_CANNOT_CHANGE, field='startdate')
                form.has_errors('startdate', errors.START_DATE_CANNOT_CHANGE)
                return
        elif start.date() < min_start:
            c.errors.add(errors.DATE_TOO_EARLY,
                         msg_params={'day': min_start.strftime("%m/%d/%Y")},
                         field='startdate')
            form.has_errors('startdate', errors.DATE_TOO_EARLY)
            return

        if start.date() > max_start:
            c.errors.add(errors.DATE_TOO_LATE,
                         msg_params={'day': max_start.strftime("%m/%d/%Y")},
                         field='startdate')
            form.has_errors('startdate', errors.DATE_TOO_LATE)
            return

        if end.date() > max_end:
            c.errors.add(errors.DATE_TOO_LATE,
                         msg_params={'day': max_end.strftime("%m/%d/%Y")},
                         field='enddate')
            form.has_errors('enddate', errors.DATE_TOO_LATE)
            return

        if end < start:
            c.errors.add(errors.BAD_DATE_RANGE, field='enddate')
            form.has_errors('enddate', errors.BAD_DATE_RANGE)
            return

        # Limit the number of PromoCampaigns a Link can have
        # Note that the front end should prevent the user from getting
        # this far
        existing_campaigns = list(PromoCampaign._by_link(link._id))
        if len(existing_campaigns) > g.MAX_CAMPAIGNS_PER_LINK:
            c.errors.add(errors.TOO_MANY_CAMPAIGNS,
                         msg_params={'count': g.MAX_CAMPAIGNS_PER_LINK},
                         field='title')
            form.has_errors('title', errors.TOO_MANY_CAMPAIGNS)
            return

        campaign = None
        if campaign_id36:
            try:
                campaign = PromoCampaign._byID36(campaign_id36, data=True)
            except NotFound:
                pass

            if campaign and (campaign._deleted or link._id != campaign.link_id):
                campaign = None

            if not campaign:
                return abort(404, 'not found')

        if priority.cpm:
            min_bid = 0 if c.user_is_sponsor else g.min_promote_bid
            max_bid = None if c.user_is_sponsor else g.max_promote_bid

            if bid is None or bid < min_bid or (max_bid and bid > max_bid):
                c.errors.add(errors.BAD_BID, field='bid',
                             msg_params={'min': min_bid,
                                         'max': max_bid or g.max_promote_bid})
                form.has_errors('bid', errors.BAD_BID)
                return

            # you cannot edit the bid of a live ad unless it's a freebie
            if (campaign and bid != campaign.bid and
                promote.is_live_promo(link, campaign) and
                not campaign.is_freebie()):
                c.errors.add(errors.BID_LIVE, field='bid')
                form.has_errors('bid', errors.BID_LIVE)
                return

        else:
            bid = 0.   # Set bid to 0 as dummy value

        is_frontpage = (not target.is_collection and
                        target.subreddit_name == Frontpage.name)

        if not target.is_collection and not is_frontpage:
            # targeted to a single subreddit, check roadblock
            sr = target.subreddits_slow[0]
            roadblock = PromotedLinkRoadblock.is_roadblocked(sr, start, end)
            if roadblock and not c.user_is_sponsor:
                msg_params = {"start": roadblock[0].strftime('%m/%d/%Y'),
                              "end": roadblock[1].strftime('%m/%d/%Y')}
                c.errors.add(errors.OVERSOLD, field='sr',
                             msg_params=msg_params)
                form.has_errors('sr', errors.OVERSOLD)
                return

        # Check inventory
        campaign = campaign if campaign_id36 else None
        if not priority.inventory_override:
            oversold = has_oversold_error(form, campaign, start, end, bid, cpm,
                                          target, location)
            if oversold:
                return

        dates = (start, end)
        if campaign:
            promote.edit_campaign(link, campaign, dates, bid, cpm, target,
                                  priority, location, platform, mobile_os)
        else:
            campaign = promote.new_campaign(link, dates, bid, cpm, target,
                                            priority, location, platform, mobile_os)
        rc = RenderableCampaign.from_campaigns(link, campaign)
        jquery.update_campaign(campaign._fullname, rc.render_html())
Ejemplo n.º 7
0
    def POST_edit_campaign(self, form, jquery, link, campaign_id36, dates, bid,
                           target, priority, location):
        if not link:
            return

        if not target:
            # run form.has_errors to populate the errors in the response
            form.has_errors('sr', errors.SUBREDDIT_NOEXIST,
                            errors.SUBREDDIT_NOTALLOWED,
                            errors.SUBREDDIT_REQUIRED)
            form.has_errors('collection', errors.COLLECTION_NOEXIST)
            form.has_errors('targeting', errors.INVALID_TARGET)
            return

        start, end = dates or (None, None)

        if not allowed_location_and_target(location, target):
            return abort(403, 'forbidden')

        cpm = PromotionPrices.get_price(c.user, target, location)

        if (form.has_errors('startdate', errors.BAD_DATE,
                            errors.DATE_TOO_EARLY, errors.DATE_TOO_LATE)
                or form.has_errors('enddate', errors.BAD_DATE,
                                   errors.DATE_TOO_EARLY, errors.DATE_TOO_LATE,
                                   errors.BAD_DATE_RANGE)):
            return

        # check that start is not so late that authorization hold will expire
        if not c.user_is_sponsor:
            max_start = promote.get_max_startdate()
            if start > max_start:
                c.errors.add(
                    errors.DATE_TOO_LATE,
                    msg_params={'day': max_start.strftime("%m/%d/%Y")},
                    field='startdate')
                form.has_errors('startdate', errors.DATE_TOO_LATE)
                return

        # Limit the number of PromoCampaigns a Link can have
        # Note that the front end should prevent the user from getting
        # this far
        existing_campaigns = list(PromoCampaign._by_link(link._id))
        if len(existing_campaigns) > g.MAX_CAMPAIGNS_PER_LINK:
            c.errors.add(errors.TOO_MANY_CAMPAIGNS,
                         msg_params={'count': g.MAX_CAMPAIGNS_PER_LINK},
                         field='title')
            form.has_errors('title', errors.TOO_MANY_CAMPAIGNS)
            return

        campaign = None
        if campaign_id36:
            try:
                campaign = PromoCampaign._byID36(campaign_id36, data=True)
            except NotFound:
                pass

            if campaign and (campaign._deleted
                             or link._id != campaign.link_id):
                campaign = None

            if not campaign:
                return abort(404, 'not found')

        if priority.cpm:
            min_bid = 0 if c.user_is_sponsor else g.min_promote_bid
            max_bid = None if c.user_is_sponsor else g.max_promote_bid

            if bid is None or bid < min_bid or (max_bid and bid > max_bid):
                c.errors.add(errors.BAD_BID,
                             field='bid',
                             msg_params={
                                 'min': min_bid,
                                 'max': max_bid or g.max_promote_bid
                             })
                form.has_errors('bid', errors.BAD_BID)
                return

            # you cannot edit the bid of a live ad unless it's a freebie
            if (campaign and bid != campaign.bid
                    and promote.is_live_promo(link, campaign)
                    and not campaign.is_freebie()):
                c.errors.add(errors.BID_LIVE, field='bid')
                form.has_errors('bid', errors.BID_LIVE)
                return

        else:
            bid = 0.  # Set bid to 0 as dummy value

        is_frontpage = (not target.is_collection
                        and target.subreddit_name == Frontpage.name)

        if not target.is_collection and not is_frontpage:
            # targeted to a single subreddit, check roadblock
            sr = target.subreddits_slow[0]
            roadblock = PromotedLinkRoadblock.is_roadblocked(sr, start, end)
            if roadblock and not c.user_is_sponsor:
                msg_params = {
                    "start": roadblock[0].strftime('%m/%d/%Y'),
                    "end": roadblock[1].strftime('%m/%d/%Y')
                }
                c.errors.add(errors.OVERSOLD,
                             field='sr',
                             msg_params=msg_params)
                form.has_errors('sr', errors.OVERSOLD)
                return

        # Check inventory
        campaign = campaign if campaign_id36 else None
        if not priority.inventory_override:
            oversold = has_oversold_error(form, campaign, start, end, bid, cpm,
                                          target, location)
            if oversold:
                return

        if campaign:
            promote.edit_campaign(link, campaign, dates, bid, cpm, target,
                                  priority, location)
        else:
            campaign = promote.new_campaign(link, dates, bid, cpm, target,
                                            priority, location)
        rc = RenderableCampaign.from_campaigns(link, campaign)
        jquery.update_campaign(campaign._fullname, rc.render_html())
Ejemplo n.º 8
0
    def POST_edit_campaign(self, form, jquery, link, campaign_id36,
                          dates, bid, sr, targeting, priority):
        if not link:
            return

        start, end = dates or (None, None)

        author = Account._byID(link.author_id, data=True)
        cpm = author.cpm_selfserve_pennies

        if (start and end and not promote.is_accepted(link) and
            not c.user_is_sponsor):
            # if the ad is not approved already, ensure the start date
            # is at least 2 days in the future
            start = start.date()
            end = end.date()
            now = promote.promo_datetime_now()
            future = make_offset_date(now, g.min_promote_future,
                                      business_days=True)
            if start < future.date():
                day = promote.promo_datetime_now(offset=g.min_promote_future)
                day = day.strftime("%m/%d/%Y")
                c.errors.add(errors.DATE_TOO_EARLY, msg_params=dict(day=day),
                             field="startdate")

        if (form.has_errors('startdate', errors.BAD_DATE,
                            errors.DATE_TOO_EARLY, errors.DATE_TOO_LATE) or
            form.has_errors('enddate', errors.BAD_DATE, errors.DATE_TOO_EARLY,
                            errors.DATE_TOO_LATE, errors.BAD_DATE_RANGE)):
            return

        # Limit the number of PromoCampaigns a Link can have
        # Note that the front end should prevent the user from getting
        # this far
        existing_campaigns = list(PromoCampaign._by_link(link._id))
        if len(existing_campaigns) > g.MAX_CAMPAIGNS_PER_LINK:
            c.errors.add(errors.TOO_MANY_CAMPAIGNS,
                         msg_params={'count': g.MAX_CAMPAIGNS_PER_LINK},
                         field='title')
            form.has_errors('title', errors.TOO_MANY_CAMPAIGNS)
            return

        campaign = None
        if campaign_id36:
            try:
                campaign = PromoCampaign._byID36(campaign_id36)
            except NotFound:
                pass

        if priority.cpm:
            if form.has_errors('bid', errors.BAD_BID):
                return

            # you cannot edit the bid of a live ad unless it's a freebie
            if (campaign and bid != campaign.bid and
                promote.is_live_promo(link, campaign) and
                not campaign.is_freebie()):
                c.errors.add(errors.BID_LIVE, field='bid')
                form.has_errors('bid', errors.BID_LIVE)
                return

            min_bid = 0 if c.user_is_sponsor else g.min_promote_bid
            if bid is None or bid < min_bid:
                c.errors.add(errors.BAD_BID, field='bid',
                             msg_params={'min': min_bid,
                                         'max': g.max_promote_bid})
                form.has_errors('bid', errors.BAD_BID)
                return
        else:
            bid = 0.   # Set bid to 0 as dummy value

        if targeting == 'one':
            if form.has_errors('sr', errors.SUBREDDIT_NOEXIST,
                               errors.SUBREDDIT_NOTALLOWED,
                               errors.SUBREDDIT_REQUIRED):
                # checking to get the error set in the form, but we can't
                # check for rate-limiting if there's no subreddit
                return

            roadblock = PromotedLinkRoadblock.is_roadblocked(sr, start, end)
            if roadblock and not c.user_is_sponsor:
                msg_params = {"start": roadblock[0].strftime('%m/%d/%Y'),
                              "end": roadblock[1].strftime('%m/%d/%Y')}
                c.errors.add(errors.OVERSOLD, field='sr',
                             msg_params=msg_params)
                form.has_errors('sr', errors.OVERSOLD)
                return

        elif targeting == 'none':
            sr = None

        # Check inventory
        campaign = campaign if campaign_id36 else None
        if (not priority.inventory_override and
            has_oversold_error(form, campaign, start, end, bid, cpm, sr)):
            return

        if campaign:
            promote.edit_campaign(link, campaign, dates, bid, cpm, sr, priority)
        else:
            campaign = promote.new_campaign(link, dates, bid, cpm, sr, priority)
        rc = RenderableCampaign.from_campaigns(link, campaign)
        jquery.update_campaign(campaign._fullname, rc.render_html())
Ejemplo n.º 9
0
    def POST_edit_campaign(self, form, jquery, link, campaign_id36, dates, bid,
                           sr, targeting, priority, location):
        if not link:
            return

        start, end = dates or (None, None)

        if location and sr and not c.user_is_sponsor:
            # only sponsors can geotarget on subreddits
            location = None

        if location and location.metro:
            cpm = g.cpm_selfserve_geotarget_metro.pennies
        elif location:
            cpm = g.cpm_selfserve_geotarget_country.pennies
        else:
            author = Account._byID(link.author_id, data=True)
            cpm = author.cpm_selfserve_pennies

        if (form.has_errors('startdate', errors.BAD_DATE,
                            errors.DATE_TOO_EARLY, errors.DATE_TOO_LATE)
                or form.has_errors('enddate', errors.BAD_DATE,
                                   errors.DATE_TOO_EARLY, errors.DATE_TOO_LATE,
                                   errors.BAD_DATE_RANGE)):
            return

        # check that start is not so late that authorization hold will expire
        if not c.user_is_sponsor:
            max_start = promote.get_max_startdate()
            if start > max_start:
                c.errors.add(
                    errors.DATE_TOO_LATE,
                    msg_params={'day': max_start.strftime("%m/%d/%Y")},
                    field='startdate')
                form.has_errors('startdate', errors.DATE_TOO_LATE)
                return

        # Limit the number of PromoCampaigns a Link can have
        # Note that the front end should prevent the user from getting
        # this far
        existing_campaigns = list(PromoCampaign._by_link(link._id))
        if len(existing_campaigns) > g.MAX_CAMPAIGNS_PER_LINK:
            c.errors.add(errors.TOO_MANY_CAMPAIGNS,
                         msg_params={'count': g.MAX_CAMPAIGNS_PER_LINK},
                         field='title')
            form.has_errors('title', errors.TOO_MANY_CAMPAIGNS)
            return

        campaign = None
        if campaign_id36:
            try:
                campaign = PromoCampaign._byID36(campaign_id36)
            except NotFound:
                pass

        if campaign and link._id != campaign.link_id:
            return abort(404, 'not found')

        if priority.cpm:
            min_bid = 0 if c.user_is_sponsor else g.min_promote_bid
            max_bid = None if c.user_is_sponsor else g.max_promote_bid

            if bid is None or bid < min_bid or (max_bid and bid > max_bid):
                c.errors.add(errors.BAD_BID,
                             field='bid',
                             msg_params={
                                 'min': min_bid,
                                 'max': max_bid or g.max_promote_bid
                             })
                form.has_errors('bid', errors.BAD_BID)
                return

            # you cannot edit the bid of a live ad unless it's a freebie
            if (campaign and bid != campaign.bid
                    and promote.is_live_promo(link, campaign)
                    and not campaign.is_freebie()):
                c.errors.add(errors.BID_LIVE, field='bid')
                form.has_errors('bid', errors.BID_LIVE)
                return

        else:
            bid = 0.  # Set bid to 0 as dummy value

        if targeting == 'one':
            if form.has_errors('sr', errors.SUBREDDIT_NOEXIST,
                               errors.SUBREDDIT_NOTALLOWED,
                               errors.SUBREDDIT_REQUIRED):
                # checking to get the error set in the form, but we can't
                # check for rate-limiting if there's no subreddit
                return

            roadblock = PromotedLinkRoadblock.is_roadblocked(sr, start, end)
            if roadblock and not c.user_is_sponsor:
                msg_params = {
                    "start": roadblock[0].strftime('%m/%d/%Y'),
                    "end": roadblock[1].strftime('%m/%d/%Y')
                }
                c.errors.add(errors.OVERSOLD,
                             field='sr',
                             msg_params=msg_params)
                form.has_errors('sr', errors.OVERSOLD)
                return

        elif targeting == 'none':
            sr = None

        # Check inventory
        campaign = campaign if campaign_id36 else None
        if not priority.inventory_override:
            oversold = has_oversold_error(form, campaign, start, end, bid, cpm,
                                          sr, location)
            if oversold:
                return

        if campaign:
            promote.edit_campaign(link, campaign, dates, bid, cpm, sr,
                                  priority, location)
        else:
            campaign = promote.new_campaign(link, dates, bid, cpm, sr,
                                            priority, location)
        rc = RenderableCampaign.from_campaigns(link, campaign)
        jquery.update_campaign(campaign._fullname, rc.render_html())
Ejemplo n.º 10
0
    def POST_edit_campaign(self, form, jquery, link, campaign_id36, dates, bid,
                           sr, targeting, priority):
        if not link:
            return

        start, end = dates or (None, None)

        author = Account._byID(link.author_id, data=True)
        cpm = author.cpm_selfserve_pennies

        if (start and end and not promote.is_accepted(link)
                and not c.user_is_sponsor):
            # if the ad is not approved already, ensure the start date
            # is at least 2 days in the future
            start = start.date()
            end = end.date()
            now = promote.promo_datetime_now()
            future = make_offset_date(now,
                                      g.min_promote_future,
                                      business_days=True)
            if start < future.date():
                day = promote.promo_datetime_now(offset=g.min_promote_future)
                day = day.strftime("%m/%d/%Y")
                c.errors.add(errors.DATE_TOO_EARLY,
                             msg_params=dict(day=day),
                             field="startdate")

        if (form.has_errors('startdate', errors.BAD_DATE,
                            errors.DATE_TOO_EARLY, errors.DATE_TOO_LATE)
                or form.has_errors('enddate', errors.BAD_DATE,
                                   errors.DATE_TOO_EARLY, errors.DATE_TOO_LATE,
                                   errors.BAD_DATE_RANGE)):
            return

        # Limit the number of PromoCampaigns a Link can have
        # Note that the front end should prevent the user from getting
        # this far
        existing_campaigns = list(PromoCampaign._by_link(link._id))
        if len(existing_campaigns) > g.MAX_CAMPAIGNS_PER_LINK:
            c.errors.add(errors.TOO_MANY_CAMPAIGNS,
                         msg_params={'count': g.MAX_CAMPAIGNS_PER_LINK},
                         field='title')
            form.has_errors('title', errors.TOO_MANY_CAMPAIGNS)
            return

        campaign = None
        if campaign_id36:
            try:
                campaign = PromoCampaign._byID36(campaign_id36)
            except NotFound:
                pass

        if priority.cpm:
            if form.has_errors('bid', errors.BAD_BID):
                return

            # you cannot edit the bid of a live ad unless it's a freebie
            if (campaign and bid != campaign.bid
                    and campaign.start_date < datetime.now(g.tz)
                    and not campaign.is_freebie()):
                c.errors.add(errors.BID_LIVE, field='bid')
                form.has_errors('bid', errors.BID_LIVE)
                return

            min_bid = 0 if c.user_is_sponsor else g.min_promote_bid
            if bid is None or bid < min_bid:
                c.errors.add(errors.BAD_BID,
                             field='bid',
                             msg_params={
                                 'min': min_bid,
                                 'max': g.max_promote_bid
                             })
                form.has_errors('bid', errors.BAD_BID)
                return
        else:
            bid = 0.  # Set bid to 0 as dummy value

        if targeting == 'one':
            if form.has_errors('sr', errors.SUBREDDIT_NOEXIST,
                               errors.SUBREDDIT_NOTALLOWED,
                               errors.SUBREDDIT_REQUIRED):
                # checking to get the error set in the form, but we can't
                # check for rate-limiting if there's no subreddit
                return

            roadblock = PromotedLinkRoadblock.is_roadblocked(sr, start, end)
            if roadblock and not c.user_is_sponsor:
                msg_params = {
                    "start": roadblock[0].strftime('%m/%d/%Y'),
                    "end": roadblock[1].strftime('%m/%d/%Y')
                }
                c.errors.add(errors.OVERSOLD,
                             field='sr',
                             msg_params=msg_params)
                form.has_errors('sr', errors.OVERSOLD)
                return

        elif targeting == 'none':
            sr = None

        # Check inventory
        campaign = campaign if campaign_id36 else None
        if (not priority.inventory_override and has_oversold_error(
                form, campaign, start, end, bid, cpm, sr)):
            return

        if campaign:
            promote.edit_campaign(link, campaign, dates, bid, cpm, sr,
                                  priority)
        else:
            campaign = promote.new_campaign(link, dates, bid, cpm, sr,
                                            priority)
        rc = RenderableCampaign.from_campaigns(link, campaign)
        jquery.update_campaign(campaign._fullname, rc.render_html())
Ejemplo n.º 11
0
 def POST_terminate_campaign(self, form, jquery, link, campaign):
     if link and campaign:
         promote.terminate_campaign(link, campaign)
         rc = RenderableCampaign.from_campaigns(link, campaign)
         jquery.update_campaign(campaign._fullname, rc.render_html())