Subversion Repositories SmartDukaan

Rev

Rev 19066 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#!/usr/bin/python

import threading
import time
import datetime

import MySQLdb
from elixir import *
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
from sqlalchemy.sql import func
from sqlalchemy.sql.expression import and_, or_, desc, not_, distinct, cast, \
    between
from urlparse import urlparse
from urlparse import parse_qs
import requests
import json
import optparse
import urllib2
import base64
import urllib
import logging
from dtr.utils.utils import get_mongo_connection

GCM_URL = "https://android.googleapis.com/gcm/send"
GOOGLE_API_KEY = "AIzaSyDw1qBnmxtnfR9NqBewryQ-yo3cG2ravGM"
PENDING_PUSH_NOTIFICATION_URL = "http://192.168.158.89:3001/getPendingNotifications"
PUSH_NOTIFICATIONS_UPDATE_URL = "http://192.168.158.89:3001/updatePushNotification/?"
headers = {'content-type':'application/json', "authorization":"key=" + GOOGLE_API_KEY}
aff_url_headers = { 
            'User-agent':'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36',
            'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',      
            'Accept-Language' : 'en-US,en;q=0.8',                     
            'Accept-Charset' : 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
            'Connection':'keep-alive'
        }

db = MySQLdb.connect('localhost',"root","shop2020","dtr" )
cursor = db.cursor()
userGcmRegIdMap = {}
campaignsMap = {}

ALL_STORES_SQL = "select * from stores"
GCM_REG_ID_SQL = "select x.user_id, x.gcm_regid from (select * from gcm_users where user_id in %s order by id desc) as x group by x.user_id"
CAMPAIGNS_SQL = "select * from notification_campaigns where id in %s order by id"


cursor.execute(ALL_STORES_SQL)
result_stores = cursor.fetchall()
domainStoresMap = {}
for rec in result_stores:
    domainStoresMap[rec[2]] = rec
    
logging.basicConfig(level=logging.DEBUG,
                    format='[%(levelname)s] (%(threadName)-10s) %(message)s',
                    )


class NotificationRecord():
    pushNotificationId = None
    userId = None
    campaignId = None
    campaignName = None
    title = None
    message= None
    type = None
    url = None
    expiresAt = None
    notificationStatus = None
    notificationCreated = None
    gcmRegId = None
    
    def __init__(self,pushNotificationId, userId, campaignId, campaignName, title, message, type, url, expiresAt, notificationStatus, notificationCreated, gcmRegId):
        self.pushNotificationId = pushNotificationId
        self.userId = userId
        self.campaignId = campaignId
        self.campaignName = campaignName
        self.title = title
        self.message= message
        self.type = type
        self.url = url
        self.expiresAt = expiresAt
        self.notificationStatus = notificationStatus
        self.notificationCreated = notificationCreated
        self.gcmRegId = gcmRegId
        
        
class NotificationThread (threading.Thread):
    def __init__(self, threadID, name, recordsList):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.recordsList = recordsList
    def run(self):
        logging.debug('Starting')
        handleCampaignRequest(self.name, self.recordsList)
        logging.debug('Completed')

def handleCampaignRequest(threadName, recordsList ):
    for record in recordsList:
        campaignRecord = campaignsMap.get(record.get('notification_campaign_id'))
        notificationRecord = NotificationRecord(record.get('_id'), record.get('user_id'), record.get('notification_campaign_id'), campaignRecord[1], campaignRecord[2], campaignRecord[3], campaignRecord[4], campaignRecord[5], campaignRecord[7], campaignRecord[8], campaignRecord[9], userGcmRegIdMap.get(record.get('user_id')))
        if notificationRecord.type=='url':
            parsed_uri = urlparse(notificationRecord.url)
            domain = '{uri.netloc}'.format(uri=parsed_uri)
            logging.debug('Affiliate Domain:-'+str(domain))
            logging.debug('User Id:-'+str(notificationRecord.userId)+' And GCM Reg Id:- '+ str(notificationRecord.gcmRegId))
            store = domainStoresMap.get(domain)
            if store is not None:
                url_params = { 'url' : notificationRecord.url,  'userId' : notificationRecord.userId, 'storeId' : store[0] }
                encoded_url_params = urllib.urlencode(url_params)
                
                DTR_API_BASIC_AUTH = base64.encodestring('%s:%s' % ("dtr", "dtr18Feb2015")).replace('\n', '')
                
                pushpostrequest = urllib2.Request('http://api.profittill.com/pushnotifications/generateAffiliateUrl', encoded_url_params, headers=aff_url_headers)
                pushpostrequest.add_header("Authorization", "Basic %s" % DTR_API_BASIC_AUTH)
                json_result =  json.loads(urllib2.urlopen(pushpostrequest).read())
                notificationRecord.url = json_result['url']
                logging.debug('User Id:-'+str(notificationRecord.userId)+' Notification Url:- '+ str(notificationRecord.url))
            else:
                queryString = urlparse(notificationRecord.url.strip()).query
                parsed_url = parse_qs(queryString)
                if not parsed_url.has_key('user_id'):
                    if len(queryString)>0:
                        notificationRecord.url = notificationRecord.url.strip()+'&user_id='+str(notificationRecord.userId)
                        logging.debug('User Id:-'+str(notificationRecord.userId)+' Notification Url:- '+ str(notificationRecord.url))
                    else:
                        notificationRecord.url = notificationRecord.url.strip()+'?user_id='+str(notificationRecord.userId)
                        logging.debug('User Id:-'+str(notificationRecord.userId)+' Notification Url:- '+ str(notificationRecord.url))
                else:
                    logging.debug('User Id:-'+str(notificationRecord.userId)+' Notification Url:- '+ str(notificationRecord.url))
        if notificationRecord.url is None or str(notificationRecord.url)=='':
            notificationRecord.url = 'http://api.profittill.com/deals?user_id='+str(notificationRecord.userId)
        data = {"message":notificationRecord.message,"cid":notificationRecord.campaignId,"title":notificationRecord.title,
                "type":notificationRecord.type,"url":notificationRecord.url.strip(),"vibrate":1,"sound":1,"largeIcon":"large_icon",
                "smallIcon":"small_icon","priority":"high","time_to_live":long(time.mktime(notificationRecord.expiresAt.timetuple()))-long(time.mktime(datetime.datetime.now().timetuple()))}
        
        post_data = {}
        
        post_data['data'] = data
        regIds = []
        regIds.append(notificationRecord.gcmRegId)
        post_data['registration_ids'] = regIds
         
        post_data_json = json.dumps(post_data)
        logging.debug('User Id:- '+str(notificationRecord.userId)+' Post Data Json :- '+str(post_data_json))
        
        response = requests.post(GCM_URL, data=post_data_json, headers=headers)
        logging.debug('User Id:- '+str(notificationRecord.userId)+' Response :-'+str(response.text))
        result = json.loads(response.text)
        
        if result["success"]:
            update_params = { 'user_id' : notificationRecord.userId,  'notification_campaign_id' : notificationRecord.campaignId, 'oldType':'pending', 'type' : 'sent', 'status':1, 'message':'success' }
            encoded_update_params = urllib.urlencode(update_params)
            updateReq = urllib2.Request(PUSH_NOTIFICATIONS_UPDATE_URL+encoded_update_params)
            updateResponse = urllib2.urlopen(updateReq)
            response_str = updateResponse.read()
            logging.debug('User Id:- '+str(notificationRecord.userId)+' Update Response :-'+str(response_str))
        else:
            update_params = { 'user_id' : notificationRecord.userId,  'notification_campaign_id' : notificationRecord.campaignId, 'oldType':'pending', 'type' : 'sent', 'status':0, 'message':result["results"][0]["error"] }
            encoded_update_params = urllib.urlencode(update_params)
            updateReq = urllib2.Request(PUSH_NOTIFICATIONS_UPDATE_URL+encoded_update_params)
            updateResponse = urllib2.urlopen(updateReq)
            response_str = updateResponse.read()
            logging.debug('User Id:- '+str(notificationRecord.userId)+' Update Response :-'+str(response_str))
            
            updateGcmUserSql = "update gcm_users set failurecount=failurecount+1 where gcm_regid='%s'"%(notificationRecord.gcmRegId)
            logging.debug('Update GCM User Query :-'+str(updateGcmUserSql))
            try:
                dtrdb = MySQLdb.connect('localhost',"root","shop2020","dtr" )
                cursor = dtrdb.cursor()
                cursor.execute(updateGcmUserSql)
                dtrdb.commit()
                session.commit()
                dtrdb.close()
            except:
                dtrdb.rollback()
                dtrdb.close()
            #time.sleep(2)

def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

def main():
    global userGcmRegIdMap
    global campaignsMap
    parser = optparse.OptionParser()
    parser.add_option("-C", "--chunksize", dest="chunksize",
                      default="100",
                      type="int", help="The requsets a single thread handles",
                      metavar="CHUNKSIZE")
    (options, args) = parser.parse_args()
    

    notificationListReq = urllib2.Request(PENDING_PUSH_NOTIFICATION_URL)
    notificationListResponse = urllib2.urlopen(notificationListReq)
    notificationListJson = json.loads(notificationListResponse.read())
    
    usersList =[]
    campaignIdList = []
    
    for notificationRec in notificationListJson:
        if notificationRec.get('user_id') not in usersList:
            usersList.append(notificationRec.get('user_id'))
        if notificationRec.get('notification_campaign_id') not in campaignIdList:
            campaignIdList.append(notificationRec.get('notification_campaign_id'))
    
    usersList.append(0)
    campaignIdList.append(0)
    logging.debug('Starting Push Notification Job....'+str(datetime.datetime.now()))
    
    if len(usersList) >1 and len(campaignIdList)>1:
        cursor.execute(GCM_REG_ID_SQL%(str(tuple(usersList))))
        result_data = cursor.fetchall()
        
        for dataRec in result_data:
            userGcmRegIdMap[dataRec[0]] = dataRec[1]
            
        cursor.execute(CAMPAIGNS_SQL%(str(tuple(campaignIdList))))
        campaign_data = cursor.fetchall()
        
        for campaignRec in campaign_data:
            campaignsMap[campaignRec[0]] = campaignRec    
        
        count = 1
        if result_data:
            campaign_receivers_list = list(chunks(notificationListJson, options.chunksize))
            print len(campaign_receivers_list)
            for sublist in campaign_receivers_list:
                thread = NotificationThread(count, "Thread-"+str(count), sublist)
                thread.start()
                count = count +1
                
    logging.debug('Stopping Push Notification Job....'+str(datetime.datetime.now()))
            
    db.close()

if __name__=='__main__':
    main()