예제 #1
0
def delete_campaigns(data, token, expected_status=(200,)):
    """
    This method sends a DELETE request to Push Campaign API to delete multiple campaigns.
    :type data: dict
    :type token: string
    :type expected_status: tuple[int]
    :rtype dict
    """
    response = send_request('delete', PushCampaignApiUrl.CAMPAIGNS, token, data=data)
    logger.info('tests : delete_campaigns: %s', response.content)
    print('tests : delete_campaigns: %s', response.content)
    assert response.status_code in expected_status
    return response.json()
예제 #2
0
def get_campaign(campaign_id, token, expected_status=(200,)):
    """
    Get a push campaign from API given by campaign id.
    :type campaign_id: int | long
    :type token: string
    :type expected_status: tuple[int]
    :rtype dict
    """
    response = send_request('get', PushCampaignApiUrl.CAMPAIGN % campaign_id, token)
    logger.info('tests : get_campaign: %s', response.content)
    print('tests : get_campaign: %s', response.content)
    assert response.status_code in expected_status
    return response.json()
예제 #3
0
def unschedule_campaign(campaign_id, token, expected_status=(200,)):
    """
    This method sends a DELETE request to Push Campaign API to unschedule a push campaign.
    :type campaign_id: int | long
    :type token: string
    :type expected_status: tuple[int]
    :rtype dict
    """
    response = send_request('delete', PushCampaignApiUrl.SCHEDULE % campaign_id, token)
    logger.info('tests : unschedule_campaign: %s', response.content)
    print('tests : unschedule_campaign: %s', response.content)
    assert response.status_code in expected_status
    return response.json()
예제 #4
0
def reschedule_campaign(campaign_id, data, token, expected_status=(200,)):
    """
    This method sends a PUT request to Push Campaign API to reschedule a push campaign with given schedule data.
    :type campaign_id: int | long
    :type data: dict
    :type token: string
    :type expected_status: tuple[int]
    :rtype dict
    """
    response = send_request('put', PushCampaignApiUrl.SCHEDULE % campaign_id, token, data)
    logger.info('tests: reschedule_campaign: %s', response.content)
    print('tests: reschedule_campaign: %s', response.content)
    assert response.status_code in expected_status
    return response.json()
예제 #5
0
def send_campaign(campaign_id, token, expected_status=(200,)):
    """
    This method sends a POST request to Push Campaign API to send a campaign to associated candidates.
    :type campaign_id: int | long
    :type token: string
    :type expected_status: tuple[int]
    :rtype dict
    """
    url = PushCampaignApiUrl.SEND % campaign_id
    response = send_request('post', url, token)
    logger.info('tests : send_campaign: %s', response.content)
    print('tests : send_campaign: %s', response.content)
    assert response.status_code in expected_status
    return response.json()
예제 #6
0
def delete_campaign(campaign_id, token, expected_status=(200,)):
    """
    This method sends a DELETE request to Push Campaign API to delete a campaign given by campaign_id.
    :type campaign_id: int | long
    :type token: string
    :type expected_status: tuple[int]
    :rtype dict
    """
    response = send_request('delete', PushCampaignApiUrl.CAMPAIGN % campaign_id, token)
    logger.info('tests : delete_campaign: %s', response.content)
    print('tests : delete_campaign: %s', response.content)

    assert response.status_code in expected_status
    return response.json()
예제 #7
0
def get_campaigns(token, page=DEFAULT_PAGE, per_page=DEFAULT_PAGE_SIZE, expected_status=(200,)):
    """
    Get campaign of a specific user.
    Default page number is 1 and per_page (page size) is 10
    :type page: int | long
    :type per_page: int | long
    :type token: string
    :type expected_status: tuple[int]
    """
    query = '?page=%s&per_page=%s' % (page, per_page)
    response = send_request('get', PushCampaignApiUrl.CAMPAIGNS + query, token)
    logger.info('tests : get_campaigns: %s', response.content)
    print('tests : get_campaigns: %s', response.content)
    assert response.status_code in expected_status
    return response.json()
예제 #8
0
def create_campaign(data, token, expected_status=(201,)):
    """
    Send a POST request to Push Campaign API with campaign data to create a new Push Campaign.
    :type data: dict
    :type token: string
    :type expected_status: tuple[int]
    :rtype dict
    """
    response = send_request('post', PushCampaignApiUrl.CAMPAIGNS, token, data)
    logger.info('tests : create_campaign: %s', response.content)
    print('tests : create_campaign: %s', response.content)
    assert response.status_code in expected_status
    headers = response.headers
    response = response.json()
    response['headers'] = headers
    return response
예제 #9
0
def get_blasts(campaign_id, token, page=DEFAULT_PAGE, per_page=DEFAULT_PAGE_SIZE, expected_status=(200,), count=None):
    """
    This method sends a GET request to Push Campaign API to get a list of blasts associated with
     a campaign given by campaign_id.
    :type campaign_id: int | long
    :type token: string
    :type page: int | long
    :type per_page: int | long
    :type expected_status: tuple[int]
    :type count: int | None
    :rtype dict
    """
    query = '?page=%s&per_page=%s' % (page, per_page)
    response = send_request('get', PushCampaignApiUrl.BLASTS % campaign_id + query, token)
    logger.info('tests : get_blasts: %s', response.content)
    print('tests : get_blasts: %s', response.content)
    assert response.status_code in expected_status
    response = response.json()
    if count:
        assert len(response['blasts']) == count
    return response
예제 #10
0
    def send_campaign_to_candidate(self, candidate_and_device_ids):
        """
        This method sends campaign to a single candidate. It gets the devices associated with
        the candidate and sends this campaign to all devices using OneSignal's RESTful API.
        Destination url is first converted to something like http://127.0.0.1:8012/redirect/1
        which is then signed
            http://127.0.0.1:8012/v1/redirect/1052?valid_until=1453990099.0
            #           &auth_user=no_user&extra=&signature=cWQ43J%2BkYetfmE2KmR85%2BLmvuIw%3D

        This URL is sent to candidate in push notification and when user clicks on notification
        he is redirected to our url redirection endpoint, which after updating campaign stats,
        redirected to original url given for campaign owner.
        :param candidate_and_device_ids: list of tuple and each tuple contains id of candidate and
               list of candidate device ids
        :return: True | None
        """
        with app.app_context():
            candidate_id, device_ids = candidate_and_device_ids
            candidate = Candidate.get_by_id(candidate_id)
            self.campaign = PushCampaign.get_by_id(self.campaign_id)
            assert isinstance(candidate, Candidate), \
                'candidate should be instance of Candidate Model'
            logger.info('Going to send campaign to candidate (id = %s)' % candidate.id)
            # A device is actually candidate's desktop, android or iOS machine where
            # candidate will receive push notifications. Device id is given by OneSignal.
            if not device_ids:
                logger.error('Candidate has not subscribed for push notification. candidate_id: %s,'
                             'campaign_id: %s' % (candidate_id, self.campaign_id))
            else:
                try:
                    destination_url = self.campaign.url
                    url_conversion_id = self.create_or_update_url_conversion(
                        destination_url=destination_url,
                        source_url='')

                    redirect_url = PushCampaignApiUrl.REDIRECT % url_conversion_id
                    # expiry duration is of one year
                    expiry_time = datetime.datetime.now() + relativedelta(years=+1)
                    signed_url = CampaignUtils.sign_redirect_url(redirect_url, expiry_time)
                    if CampaignUtils.IS_DEV:
                        # update the 'source_url' in "url_conversion" record.
                        # Source URL should not be saved in database. But we have tests written
                        # for Redirection endpoint. That's why in case of DEV,
                        # I am saving source URL here.
                        self.create_or_update_url_conversion(url_conversion_id=url_conversion_id,
                                                             source_url=signed_url)

                    one_signal_client = OneSignalSdk(app_id=ONE_SIGNAL_APP_ID,
                                                     user_auth_key=ONE_SIGNAL_REST_API_KEY)
                    response = one_signal_client.create_notification(self.campaign.body_text,
                                                                     heading=self.campaign.name,
                                                                     url=signed_url,
                                                                     player_ids=device_ids)
                    if response.ok:
                        campaign_send = PushCampaignSend(blast_id=self.campaign_blast_id,
                                                         candidate_id=candidate.id
                                                         )
                        PushCampaignSend.save(campaign_send)
                        push_url_conversion = PushCampaignSendUrlConversion(
                            url_conversion_id=url_conversion_id,
                            send_id=campaign_send.id
                        )
                        PushCampaignSendUrlConversion.save(push_url_conversion)
                        return True
                    else:
                        response = response.json()
                        errors = response['errors']
                        logger.error('Error while sending push notification to candidate (id: %s),'
                                     'Errors: %s' % (candidate_id, errors))
                        UrlConversion.delete(url_conversion_id)

                except Exception:
                    logger.exception('Unable to send push campaign (id: %s) to candidate (id: %s)'
                                     % (self.campaign.id, candidate.id))
예제 #11
0
"""
    Run Celery Worker

For Celery to run from command line, script runs as separate process with celery command

 Usage: open terminal cd to talent-flask-services directory

 Run the following command to start celery worker:

    $ celery -A push_campaign_service.push_campaign_app.celery_app worker --concurrency=4 --loglevel=info
"""

# Service Specific
from push_campaign_service.common.talent_celery import CELERY_WORKER_ARGS
from push_campaign_service.push_campaign_app import celery_app, logger, app
from push_campaign_service.common.talent_config_manager import TalentConfigKeys
from push_campaign_service.common.campaign_services.campaign_utils import CampaignUtils

try:
    logger.info("Celery worker has been started successfully for:%s" %
                app.name)
    celery_app.start(argv=CELERY_WORKER_ARGS + [CampaignUtils.PUSH] +
                     ['-n', CampaignUtils.PUSH])
except Exception as e:
    logger.exception(
        "Couldn't start Celery worker for push_campaign_service in "
        "%s environment." % (app.config[TalentConfigKeys.ENV_KEY]))