Rev 19066 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#!/usr/bin/pythonimport threadingimport timeimport datetimeimport MySQLdbfrom elixir import *from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFoundfrom sqlalchemy.sql import funcfrom sqlalchemy.sql.expression import and_, or_, desc, not_, distinct, cast, \betweenfrom urlparse import urlparsefrom urlparse import parse_qsimport requestsimport jsonimport optparseimport urllib2import base64import urllibimport loggingfrom dtr.utils.utils import get_mongo_connectionGCM_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]] = reclogging.basicConfig(level=logging.DEBUG,format='[%(levelname)s] (%(threadName)-10s) %(message)s',)class NotificationRecord():pushNotificationId = NoneuserId = NonecampaignId = NonecampaignName = Nonetitle = Nonemessage= Nonetype = Noneurl = NoneexpiresAt = NonenotificationStatus = NonenotificationCreated = NonegcmRegId = Nonedef __init__(self,pushNotificationId, userId, campaignId, campaignName, title, message, type, url, expiresAt, notificationStatus, notificationCreated, gcmRegId):self.pushNotificationId = pushNotificationIdself.userId = userIdself.campaignId = campaignIdself.campaignName = campaignNameself.title = titleself.message= messageself.type = typeself.url = urlself.expiresAt = expiresAtself.notificationStatus = notificationStatusself.notificationCreated = notificationCreatedself.gcmRegId = gcmRegIdclass NotificationThread (threading.Thread):def __init__(self, threadID, name, recordsList):threading.Thread.__init__(self)self.threadID = threadIDself.name = nameself.recordsList = recordsListdef 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()).queryparsed_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'] = dataregIds = []regIds.append(notificationRecord.gcmRegId)post_data['registration_ids'] = regIdspost_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 userGcmRegIdMapglobal campaignsMapparser = 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]] = campaignReccount = 1if 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 +1logging.debug('Stopping Push Notification Job....'+str(datetime.datetime.now()))db.close()if __name__=='__main__':main()