Ejemplo n.º 1
0
def get_available_pageviews(targets, start, end, datestr=False, ignore=None):
    pageviews_by_sr_name = {}
    all_campaigns = set()

    targets, is_single = tup(targets, ret_is_single=True)
    target_srs = chain.from_iterable(
        target.subreddits_slow for target in targets)
    all_sr_names = set()
    srs = set(target_srs)

    # get all campaigns in target_srs and pull in campaigns from other
    # subreddits that are targeted
    while srs:
        all_sr_names |= {sr.name for sr in srs}
        new_pageviews_by_sr_name = get_predicted_pageviews(srs)
        pageviews_by_sr_name.update(new_pageviews_by_sr_name)

        new_campaigns_by_date = get_campaigns_by_date(srs, start, end, ignore)
        new_campaigns = set(chain.from_iterable(
            new_campaigns_by_date.itervalues()))
        all_campaigns.update(new_campaigns)

        new_sr_names = set(chain.from_iterable(
            campaign.target.subreddit_names for campaign in new_campaigns
        ))
        new_sr_names -= all_sr_names
        srs = set(Subreddit._by_name(new_sr_names).values())

    # determine booked impressions by target for each day
    dates = set(get_date_range(start, end))
    booked_by_target_by_date = {date: defaultdict(int) for date in dates}
    for campaign in all_campaigns:
        camp_dates = set(get_date_range(campaign.start_date, campaign.end_date))
        sr_names = tuple(sorted(campaign.target.subreddit_names))
        daily_impressions = campaign.impressions / campaign.ndays

        for date in camp_dates.intersection(dates):
            booked_by_target_by_date[date][sr_names] += daily_impressions

    datekey = lambda dt: dt.strftime('%m/%d/%Y') if datestr else dt

    ret = {}
    for target in targets:
        name = make_target_name(target)
        ret[name] = {}
        for date in dates:
            booked_by_target = booked_by_target_by_date[date]
            pageviews = get_maximized_pageviews(
                target.subreddit_names, booked_by_target, pageviews_by_sr_name)
            ret[name][datekey(date)] = max(0, pageviews)

    if is_single:
        name = make_target_name(targets[0])
        return ret[name]
    else:
        return ret
Ejemplo n.º 2
0
def get_available_pageviews(targets,
                            start,
                            end,
                            location=None,
                            datestr=False,
                            ignore=None):
    """
    Return the available pageviews by date for the targets and location.

    Available pageviews depends on all equal and higher level locations:
    A location is: subreddit > country > metro

    e.g. if a campaign is targeting /r/funny in USA/Boston we need to check that
    there's enough inventory in:
    * /r/funny (all campaigns targeting /r/funny regardless of location)
    * /r/funny + USA (all campaigns targeting /r/funny and USA with or without
      metro level targeting)
    * /r/funny + USA + Boston (all campaigns targeting /r/funny and USA and
      Boston)
    The available inventory is the smallest of these values.

    """

    # assemble levels of location targeting, None means untargeted
    locations = [None]
    if location:
        locations.append(location)

        if location.metro:
            locations.append(Location(country=location.country))

    # get all the campaigns directly and indirectly involved in our target
    targets, is_single = tup(targets, ret_is_single=True)
    target_srs = list(
        chain.from_iterable(target.subreddits_slow for target in targets))
    all_campaigns = find_campaigns(target_srs, start, end, ignore)

    # get predicted pageviews for each subreddit and location
    all_sr_names = set(sr.name for sr in target_srs)
    all_sr_names |= set(
        chain.from_iterable(campaign.target.subreddit_names
                            for campaign in all_campaigns))
    all_srs = Subreddit._by_name(all_sr_names).values()
    pageviews_dict = {
        location: get_predicted_pageviews(all_srs, location)
        for location in locations
    }

    # determine booked impressions by target and location for each day
    dates = set(get_date_range(start, end))
    booked_dict = {}
    for date in dates:
        booked_dict[date] = {}
        for location in locations:
            booked_dict[date][location] = defaultdict(int)

    for campaign in all_campaigns:
        camp_dates = set(get_date_range(campaign.start_date,
                                        campaign.end_date))
        sr_names = tuple(sorted(campaign.target.subreddit_names))
        daily_impressions = campaign.impressions / campaign.ndays

        for location in locations:
            if location and not location.contains(campaign.location):
                # campaign's location is less specific than location
                continue

            for date in camp_dates.intersection(dates):
                booked_dict[date][location][sr_names] += daily_impressions

    # calculate inventory for each target and location on each date
    datekey = lambda dt: dt.strftime('%m/%d/%Y') if datestr else dt

    ret = {}
    for target in targets:
        name = make_target_name(target)
        subreddit_names = target.subreddit_names
        ret[name] = {}
        for date in dates:
            pageviews_by_location = {}
            for location in locations:
                # calculate available impressions for each location
                booked_by_target = booked_dict[date][location]
                pageviews_by_sr_name = pageviews_dict[location]
                pageviews_by_location[location] = get_maximized_pageviews(
                    subreddit_names, booked_by_target, pageviews_by_sr_name)
            # available pageviews is the minimum from all locations
            min_pageviews = min(pageviews_by_location.values())
            ret[name][datekey(date)] = max(0, min_pageviews)

    if is_single:
        name = make_target_name(targets[0])
        return ret[name]
    else:
        return ret
Ejemplo n.º 3
0
def get_available_pageviews(targets, start, end, location=None, datestr=False,
                            ignore=None):
    """
    Return the available pageviews by date for the targets and location.

    Available pageviews depends on all equal and higher level locations:
    A location is: subreddit > country > metro

    e.g. if a campaign is targeting /r/funny in USA/Boston we need to check that
    there's enough inventory in:
    * /r/funny (all campaigns targeting /r/funny regardless of location)
    * /r/funny + USA (all campaigns targeting /r/funny and USA with or without
      metro level targeting)
    * /r/funny + USA + Boston (all campaigns targeting /r/funny and USA and
      Boston)
    The available inventory is the smallest of these values.

    """

    # assemble levels of location targeting, None means untargeted
    locations = [None]
    if location:
        locations.append(location)

        if location.metro:
            locations.append(Location(country=location.country))

    # get all the campaigns directly and indirectly involved in our target
    targets, is_single = tup(targets, ret_is_single=True)
    target_srs = list(chain.from_iterable(
        target.subreddits_slow for target in targets))
    all_campaigns = find_campaigns(target_srs, start, end, ignore)

    # get predicted pageviews for each subreddit and location
    all_sr_names = set(sr.name for sr in target_srs)
    all_sr_names |= set(chain.from_iterable(
        campaign.target.subreddit_names for campaign in all_campaigns
    ))
    all_srs = Subreddit._by_name(all_sr_names).values()
    pageviews_dict = {location: get_predicted_pageviews(all_srs, location)
                          for location in locations}

    # determine booked impressions by target and location for each day
    dates = set(get_date_range(start, end))
    booked_dict = {}
    for date in dates:
        booked_dict[date] = {}
        for location in locations:
            booked_dict[date][location] = defaultdict(int)

    for campaign in all_campaigns:
        camp_dates = set(get_date_range(campaign.start_date, campaign.end_date))
        sr_names = tuple(sorted(campaign.target.subreddit_names))
        daily_impressions = campaign.impressions / campaign.ndays

        for location in locations:
            if location and not location.contains(campaign.location):
                # campaign's location is less specific than location
                continue

            for date in camp_dates.intersection(dates):
                booked_dict[date][location][sr_names] += daily_impressions

    # calculate inventory for each target and location on each date
    datekey = lambda dt: dt.strftime('%m/%d/%Y') if datestr else dt

    ret = {}
    for target in targets:
        name = make_target_name(target)
        subreddit_names = target.subreddit_names
        ret[name] = {}
        for date in dates:
            pageviews_by_location = {}
            for location in locations:
                # calculate available impressions for each location
                booked_by_target = booked_dict[date][location]
                pageviews_by_sr_name = pageviews_dict[location]
                pageviews_by_location[location] = get_maximized_pageviews(
                    subreddit_names, booked_by_target, pageviews_by_sr_name)
            # available pageviews is the minimum from all locations
            min_pageviews = min(pageviews_by_location.values())
            ret[name][datekey(date)] = max(0, min_pageviews)

    if is_single:
        name = make_target_name(targets[0])
        return ret[name]
    else:
        return ret