示例#1
0
def campaign_to_dict(campaign, platforms=None, fetch_platforms=True):
    """
    Transform Campaign instance into dictionary that is suitable for JSON serialization display to end-user. If
    platforms parameter is specified it appends the campaign information about enabled platforms. If parameter 
    fetch_platforms is True then the platforms data is fetched from the Datastore. If platforms is specified then 
    fetch_platforms is ignored.
    :param campaign: Campaign instance.
    :param platforms: List of Platform instances.
    :param fetch_platforms: Boolean indicating whether to fetch platforms data from the Datastore.
    :return: Dictionary
    """
    fetch_platforms = fetch_platforms and platforms is None
    output = campaign.to_dict()

    if fetch_platforms:
        query = Platform.query(Platform.campaign == campaign.key,
                               projection=[Platform.name, Platform.counter
                                           ]).order(Platform.name).fetch(3)
        output["platform_counters"] = {
            platform.name: platform.counter
            for platform in query
        }
    elif platforms is not None:
        output["platform_counters"] = {
            platform.name: platform.counter
            for platform in platforms
        }
    output["id"] = campaign.key.id()

    return output
示例#2
0
    def put(self, campaign_id):
        """Update the existing campaign."""
        campaign_id = int(campaign_id)
        future = Campaign.get_by_id_async(campaign_id)
        campaign_dict = self.get_request_json()
        validate_campaign_dict(campaign_dict, all_required=False)

        campaign = future.get_result()

        platforms = []
        # get a list of existing campaign platforms
        existing_platforms_list = {
            platform.name: platform
            for platform in Platform.query(
                Platform.campaign == campaign.key).fetch(3)
        }

        # special processing for platforms field
        platforms_to_store = []
        if "platforms" in campaign_dict:
            # get a list of platforms from the request
            platforms_list = campaign_dict["platforms"]
            del campaign_dict["platforms"]
            # construct platforms for campaign
            for platform_name in platforms_list:
                if platform_name not in existing_platforms_list:
                    platform = Platform(name=platform_name,
                                        counter=0,
                                        campaign=campaign.key,
                                        id="%d-%s" %
                                        (campaign_id, platform_name))
                    platforms_to_store.append(platform)
                else:
                    platform = existing_platforms_list[platform_name]
                platforms.append(platform)
        else:
            # no changes to platforms field, just copy
            for platform in existing_platforms_list.values():
                platforms.append(platform)

        # update the rest of the fields
        for field_name in campaign_dict:
            setattr(campaign, field_name, campaign_dict[field_name])
        campaign.update_date = datetime.now()

        @ndb.transactional_async(xg=True)
        def _update():
            """Do the update in transaction"""
            ndb.put_multi_async(platforms_to_store)
            campaign.put_async()

        future = _update()

        output = campaign_to_dict(campaign, platforms=platforms)
        # explicitly do the json conversion here, while we may be waiting for the _update to finish
        output = json.dumps(output, default=json_serial, sort_keys=True)
        future.get_result()
        return output
示例#3
0
    def get(self, platform_name):
        """Retrieve the number of clicks on the given platform."""
        @ndb.tasklet
        def callback(platform):
            raise ndb.Return(platform.counter)

        query = Platform.query(Platform.name == platform_name,
                               projection=[Platform.counter])
        clicks_sum = sum(query.map(callback))

        return clicks_sum
示例#4
0
    def get(self, platform_name):
        """List all existing campaigns available on a given platform."""
        @ndb.tasklet
        def callback(platform):
            campaign, platforms = yield platform.campaign.get_async(), \
                                        Platform.query(Platform.campaign == platform.campaign,
                                                       projection=[Platform.name, Platform.counter]).order(
                                            Platform.name).fetch_async(3)
            raise ndb.Return(campaign_to_dict(campaign, platforms=platforms))

        query = Platform.query(Platform.name == platform_name,
                               projection=[Platform.campaign])
        output = query.map(callback)
        return output
示例#5
0
    def delete(self, campaign_id):
        """Delete the existing campaign."""
        campaign_id = int(campaign_id)
        campaign = Campaign.get_by_id(campaign_id)

        if campaign:
            # delete the campaign first, so that updates are not possible
            futures = [campaign.key.delete_async()]
            # delete all platforms that correspond to the campaign
            futures.extend(
                ndb.delete_multi_async([
                    platform.key for platform in Platform.query(
                        Platform.campaign == campaign.key).fetch(3)
                ]))
            Future.wait_all(futures)
        else:
            # the campaign does not exist, just send 204
            self.response.status_int = 204
示例#6
0
 def callback(platform):
     campaign, platforms = yield platform.campaign.get_async(), \
                                 Platform.query(Platform.campaign == platform.campaign,
                                                projection=[Platform.name, Platform.counter]).order(
                                     Platform.name).fetch_async(3)
     raise ndb.Return(campaign_to_dict(campaign, platforms=platforms))
示例#7
0
 def callback(campaign):
     platforms = yield Platform.query(
         Platform.campaign == campaign.key,
         projection=[Platform.name, Platform.counter
                     ]).order(Platform.name).fetch_async(3)
     raise ndb.Return(campaign_to_dict(campaign, platforms=platforms))