def get(self, request):
        params = request.data if request.method == 'POST' else request.query_params
        account_id = params.get('account_id', None)
        tw_account_id = params.get('tw_account_id', None)

        if account_id is not None and tw_account_id is None:
            tw_account = TwitterLineItem.objects.get(account_id=account_id)
            tw_account_id = tw_account.tw_account_id

        if tw_account_id is not None:
            data = TwitterLineItem.fetch_line_items(
                dict(tw_account_id=tw_account_id))
            return Response(data=data, status=status.HTTP_200_OK)

        return Response(data=dict(status='error',
                                  msg='Missing input tw_account_id ID'),
                        status=status.HTTP_404_NOT_FOUND)
Ejemplo n.º 2
0
    def _twitter_sync_account(self, args):
        start_time = datetime.now()
        settings.SYSTEM_USER = True
        manage_campaign_cache = {}
        if self.verbose:
            print "Syncing Twitter Data"
        # Fetch all twitter accounts
        os_platform = None
        if 'tw_account_id' in args and args['tw_account_id']:
            account_id = args['tw_account_id']
            if isinstance(account_id, basestring) and not account_id.isdigit():
                account_id = base36_to_int(account_id)
            m_accounts = []
            try:
                account = TwitterAccount.objects_raw.get(
                    tw_account_id=account_id)
                m_accounts.append(account)
            except TwitterAccount.DoesNotExist:
                print "Cannot find account: " + str(account_id)
        else:
            m_accounts = TwitterAccount.objects_raw.all()

        data = {}
        for m_account in m_accounts:
            try:
                oauth_token = None
                oauth_secret = None
                try:
                    oauth_token = m_account.tw_twitter_user_id.oauth_token
                    oauth_secret = m_account.tw_twitter_user_id.oauth_secret
                except TwitterUser.DoesNotExist:
                    oauth_token = None
                    oauth_secret = None
                    pass
                if oauth_token == '':
                    oauth_token = None
                if oauth_secret == '':
                    oauth_secret = None

                # Check status of each Twitter Account via API
                api_accounts_data = TwitterAccount.fetch_accounts(
                    dict(account_id=m_account.tw_account_id))

                self._check_api_errors(api_accounts_data, m_account,
                                       "TwitterAccount")

                api_accounts = []
                if isinstance(api_accounts_data['data'], dict):
                    api_accounts.append(api_accounts_data['data'])
                elif isinstance(api_accounts_data['data'], (list, tuple)):
                    api_accounts = api_accounts_data['data']

                if self.verbose:
                    print "--> Fetching Account data for: " + str(
                        m_account.tw_account_id) + " (" + str(
                            int_to_base36(m_account.tw_account_id)) + ")"
            except KeyError:
                pass

            for api_account in api_accounts:
                # Fetch campaigns from Twitter
                try:
                    if 'manage_campaign_id' in args and args[
                            'manage_campaign_id'] is not None:
                        manage_campaign_id = args['manage_campaign_id']
                        if oauth_token is not None and oauth_secret is not None:
                            api_campaigns_data = TwitterCampaign.fetch_campaigns(
                                dict(account_id=m_account.tw_account_id,
                                     campaign_id=manage_campaign_id), True,
                                oauth_token, oauth_secret)
                        else:
                            api_campaigns_data = TwitterCampaign.fetch_campaigns(
                                dict(account_id=m_account.tw_account_id,
                                     campaign_id=manage_campaign_id), True)
                    else:
                        if oauth_token is not None and oauth_secret is not None:
                            api_campaigns_data = TwitterCampaign.fetch_campaigns(
                                dict(account_id=m_account.tw_account_id), True,
                                oauth_token, oauth_secret)
                        else:
                            api_campaigns_data = TwitterCampaign.fetch_campaigns(
                                dict(account_id=m_account.tw_account_id), True)

                    self._check_api_errors(api_campaigns_data, m_account,
                                           "TwitterCampaign")

                    api_campaigns = []
                    if isinstance(api_campaigns_data['data'], dict):
                        api_campaigns.append(api_campaigns_data['data'])
                    elif isinstance(api_campaigns_data['data'], (list, tuple)):
                        api_campaigns = api_campaigns_data['data']

                    if 'os_platform' in api_campaigns_data:
                        os_platform = api_campaigns_data['os_platform']

                    if self.verbose:
                        print "--> Fetching App Cards for: " + str(
                            m_account.tw_account_id)

                    api_campaign_app_cards_data = TwitterAppCard.fetch_app_cards(
                        dict(account_id=m_account.tw_account_id), True,
                        oauth_token, oauth_secret)

                    self._check_api_errors(api_campaign_app_cards_data,
                                           m_account, "TwitterAppCard")

                    api_campaign_app_cards = []
                    if isinstance(api_campaign_app_cards_data['data'], dict):
                        api_campaign_app_cards.append(
                            api_campaign_app_cards_data['data'])
                    elif isinstance(api_campaign_app_cards_data['data'],
                                    (list, tuple)):
                        api_campaign_app_cards = api_campaign_app_cards_data[
                            'data']

                    for api_campaign_app_card in api_campaign_app_cards:
                        if self.verbose:
                            print "----> Syncing App Card: " + str(
                                api_campaign_app_card['name']) + " (" + str(
                                    api_campaign_app_card['card_type']) + ")"

                    if self.verbose:
                        print "--> Fetching Tailored Audiences for: " + str(
                            m_account.tw_account_id)

                    api_tailored_audiences_data = TwitterTailoredAudience.fetch_tailored_audience(
                        dict(account_id=m_account.tw_account_id), True,
                        oauth_token, oauth_secret)

                    api_tailored_audiences = []
                    if isinstance(api_tailored_audiences_data['data'], dict):
                        api_tailored_audiences.append(
                            api_tailored_audiences_data['data'])
                    elif isinstance(api_tailored_audiences_data['data'],
                                    (list, tuple)):
                        api_tailored_audiences = api_tailored_audiences_data[
                            'data']

                    for api_tailored_audience in api_tailored_audiences:
                        if self.verbose:
                            print "----> Syncing Tailored Audience: " + str(
                                api_tailored_audience['name'])

                    if self.verbose:
                        print "--> (" + str(
                            len(api_campaigns)) + ") total Campaigns"

                except KeyError:
                    pass

                for api_campaign in api_campaigns:
                    api_line_items = []
                    try:
                        campaign_id_int = base36_to_int(api_campaign['id'])

                        if 'tw_campaign_id' in args and args[
                                'tw_campaign_id'] is not None and args[
                                    'tw_campaign_id'] != '':
                            if args['tw_campaign_id'] != str(campaign_id_int):
                                continue

                        if self.verbose:
                            print "--> Syncing Campaign: " + str(
                                api_campaign['name']) + " - (" + str(
                                    api_campaign['id']) + ")"

                        campaign_id_int = base36_to_int(api_campaign['id'])

                        # Get Line Items
                        api_line_items_data = TwitterLineItem.fetch_line_items(
                            dict(account_id=m_account.tw_account_id,
                                 campaign_id=api_campaign['id']), True,
                            oauth_token, oauth_secret)

                        if isinstance(api_line_items_data['data'], dict):
                            api_line_items.append(api_line_items_data['data'])
                        elif isinstance(api_line_items_data['data'],
                                        (list, tuple)):
                            api_line_items = api_line_items_data['data']

                        # Parse Manage Campaign ID from TW Campaign name
                        manage_campaign_id = None
                        if 'manage_campaign_id' in api_campaign and api_campaign[
                                'manage_campaign_id']:
                            manage_campaign_id = api_campaign[
                                'manage_campaign_id']

                        # Look up Manage Campaign
                        manage_campaign = None
                        if manage_campaign_id in manage_campaign_cache:
                            manage_campaign = manage_campaign_cache[
                                manage_campaign_id]
                        elif manage_campaign_id is not None:
                            try:
                                manage_campaign = Campaign.objects_raw.filter(
                                    campaign_id=manage_campaign_id,
                                    source_type=2).first()
                                manage_campaign_cache[
                                    manage_campaign_id] = manage_campaign
                            except Campaign.DoesNotExist:
                                manage_campaign = None

                        if manage_campaign is None:
                            if self.verbose:
                                print "----> Error: Cannot find internal Manage Campaign: " + str(
                                    api_campaign['name'])

                            # Since advertisers are now granting us access to existing Twitter Campaigns,
                            # the Manage Campaign ID won't exist in the Twitter Campaign Name.
                            # For now, we won't flag these as sync errors.  We will skip for now.
                            # self._insert_sync_error({"errors":{"100": self.SYNC_ERROR_CODES['100'] + " - "+ str(api_campaign['name'])}}, m_account, "ManageCampaign")
                            continue

                        # Twitter Advertiser should match internal Manage Campaign advertiser
                        if m_account.advertiser_id.advertiser_id != manage_campaign.advertiser_id.advertiser_id and api_campaign[
                                'deleted'] is not True:
                            sync_error = self.SYNC_ERROR_CODES['101'] + ": TW_CAMPAGIN: {tw_campaign} ({tw_campaign_id}), TW_ADVERTISER: {tw_advertiser} ({tw_advertiser_id}), MANAGE_ADVERTISER: {manage_advertiser} ({manage_advertiser_id})." \
                            .format(tw_campaign=str(api_campaign['name']), tw_campaign_id=str(base36_to_int(api_campaign['id'])), \
                                tw_advertiser=str(m_account.advertiser_id), tw_advertiser_id=str(m_account.advertiser_id.advertiser_id), \
                                manage_advertiser=str(manage_campaign.advertiser_id), manage_advertiser_id=str(manage_campaign.advertiser_id.advertiser_id))
                            if self.verbose:
                                print "----> Error: " + sync_error
                            self._insert_sync_error(
                                {"errors": {
                                    "101": sync_error
                                }}, m_account, "ManageCampaign")
                            continue

                        if self.verbose:
                            print "---> (" + str(
                                len(api_line_items)) + ") total Line Items"

                    except KeyError:
                        pass

                    for api_line_item in api_line_items:
                        try:
                            if self.verbose:
                                try:
                                    print "----> Syncing Line Item: " + str(
                                        api_line_item['name']) + " - (" + str(
                                            api_line_item['id']) + ")"
                                except UnicodeEncodeError:
                                    pass
                            line_item_id_int = base36_to_int(
                                api_line_item['id'])

                            api_line_item_targetings_data = TwitterTargeting.fetch_targeting(
                                dict(account_id=m_account.tw_account_id,
                                     line_item_id=api_line_item['id']), True,
                                oauth_token, oauth_secret)

                            self._check_api_errors(
                                api_line_item_targetings_data, m_account,
                                "TwitterTargeting")

                            api_line_item_targetings = []
                            if isinstance(
                                    api_line_item_targetings_data['data'],
                                    dict):
                                api_line_item_targetings.append(
                                    api_line_item_targetings_data['data'])
                            elif isinstance(
                                    api_line_item_targetings_data['data'],
                                (list, tuple)):
                                api_line_item_targetings = api_line_item_targetings_data[
                                    'data']

                            for api_line_item_targeting in api_line_item_targetings:
                                if self.verbose:
                                    try:
                                        print "------> Syncing Line Item Targeting: " + str(
                                            api_line_item_targeting['name'])
                                    except UnicodeEncodeError:
                                        pass
                            # Line Item Promoted Tweets
                            api_line_item_promoted_tweets_data = TwitterPromotedTweet.fetch_promoted_tweet(
                                dict(account_id=m_account.tw_account_id,
                                     line_item_id=api_line_item['id'],
                                     os_platform=os_platform), True,
                                oauth_token, oauth_secret)

                            self._check_api_errors(
                                api_line_item_promoted_tweets_data, m_account,
                                "TwitterPromotedTweet")

                            api_line_item_promoted_tweets = []
                            if isinstance(
                                    api_line_item_promoted_tweets_data['data'],
                                    dict):
                                api_line_item_promoted_tweets.append(
                                    api_line_item_promoted_tweets_data['data'])
                            elif isinstance(
                                    api_line_item_promoted_tweets_data['data'],
                                (list, tuple)):
                                api_line_item_promoted_tweets = api_line_item_promoted_tweets_data[
                                    'data']

                            for api_line_item_promoted_tweet in api_line_item_promoted_tweets:
                                if self.verbose:
                                    print "------> Syncing Line Item Promoted Tweet: " + str(
                                        api_line_item_promoted_tweet[
                                            'tweet_id'])

                            # Get Rev Map
                            if self.verbose:
                                print "--> Sync Revmap Manage Campaign: " + str(
                                    manage_campaign)

                            if manage_campaign is not None:
                                manage_campaign_rev_map = TwitterRevmap.objects_raw.filter(
                                    campaign_id=manage_campaign,
                                    tw_campaign_id=0,
                                    tw_line_item_id=0).first()
                                if manage_campaign_rev_map is not None:
                                    manage_campaign_opt_type = manage_campaign_rev_map.opt_type
                                    manage_campaign_opt_value = manage_campaign_rev_map.opt_value

                                    tw_campaign_rev_map = None
                                    if manage_campaign_opt_type is not None and manage_campaign_opt_value is not None:
                                        try:
                                            tw_line_item = TwitterLineItem.objects_raw.get(
                                                tw_campaign_id=campaign_id_int,
                                                tw_line_item_id=line_item_id_int
                                            )
                                            if tw_line_item:
                                                tw_campaign_rev_map = TwitterRevmap.objects_raw.get(
                                                    campaign_id=manage_campaign,
                                                    tw_campaign_id=tw_line_item
                                                    .tw_campaign_id,
                                                    tw_line_item_id=tw_line_item
                                                )
                                        except TwitterLineItem.DoesNotExist:
                                            tw_campaign_rev_map = None
                                        except TwitterRevmap.DoesNotExist:
                                            tw_campaign_rev_map = TwitterRevmap(
                                                campaign_id=manage_campaign,
                                                tw_campaign_id=tw_line_item.
                                                tw_campaign_id,
                                                tw_line_item_id=tw_line_item)

                                        if tw_campaign_rev_map is not None:
                                            tw_campaign_rev_map.opt_type = manage_campaign_opt_type
                                            tw_campaign_rev_map.opt_value = manage_campaign_opt_value
                                            tw_campaign_rev_map.save_raw()
                            if self.verbose:
                                print "-" * 50
                        except KeyError:
                            pass

                    if self.verbose:
                        print "+" * 100

                # Fetch all Manage Twitter Campaigns owned by Advertiser and sync Manage Campaign status
                manage_campaigns = Campaign.objects_raw.filter(
                    advertiser_id=m_account.advertiser_id, source_type=2)
                for manage_campaign in manage_campaigns:
                    # Find any active Twitter Campaigns
                    tw_campaigns = TwitterCampaign.objects_raw.filter(
                        campaign_id=manage_campaign.campaign_id,
                        status='enabled')
                    if tw_campaigns is not None and manage_campaign.status != 'enabled':
                        manage_campaign.status = 'enabled'
                        manage_campaign.save_raw()
                    elif tw_campaigns is None and manage_campaign.status != 'paused':
                        manage_campaign.status = 'paused'
                        manage_campaign.save_raw()

                    if self.verbose:
                        print "--> Setting Manage Campaign status - " + str(
                            manage_campaign) + ": " + str(
                                manage_campaign.status)

                if self.verbose:
                    print "*" * 150

        # Return Sync Result
        end_time = datetime.now()
        if self.verbose:
            print 'Sync Script Duration: {}'.format(end_time - start_time)

        if self.sync_errors:
            send_twitter_sync_error_email(
                {"data": json.dumps(self.sync_errors)})
            print {
                'error': True,
                'code': json.dumps(self.sync_errors),
                'message': 'Twitter API Errors'
            }
        else:
            sql = "REPLACE INTO job_status SET job_name='twitter_sync', job_type='twitter', last_finished=NOW(), threshold=120"
            cursor = connection.cursor()
            try:
                cursor.execute(sql)
                if settings.TW_SYNC_ALERT:
                    send_twitter_email(
                        'Twitter Sync Success',
                        'Twitter Sync Success. Script Duration: {}'.format(
                            end_time - start_time))
                print {'error': False, 'code': 200, 'message': 'OK'}
            except:
                print {
                    'error':
                    True,
                    'message':
                    'Twitter synced but cannot add entry to job_status table'
                }
            finally:
                cursor.close()