Rev 16366 | Rev 16545 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
from bson import json_utilfrom bson.json_util import dumpsfrom datetime import datetime, timedeltafrom pyshorteners.shorteners import Shortenerfrom dtr import mainfrom dtr.config import PythonPropertyReaderfrom dtr.storage import Mongofrom dtr.storage.DataService import Retailers, Users, CallHistory, RetryConfig, \RetailerLinks, Activation_Codes, Agents, Agent_Roles, AgentLoginTimings, \FetchDataHistory, RetailerContacts, Orders, OnboardedRetailerChecklists,\RetailerAddresses, Pincodeavailabilityfrom dtr.storage.Mongo import get_mongo_connectionfrom dtr.storage.Mysql import fetchResultfrom dtr.utils import FetchLivePrices, DealSheet as X_DealSheet, \UserSpecificDealsfrom dtr.utils.utils import getLoggerfrom elixir import *from operator import and_from sqlalchemy.sql.expression import func, func, or_from urllib import urlencodeimport contextlibimport falconimport jsonimport reimport stringimport tracebackimport urllibimport urllib2import uuidimport gdshorteneralphalist = list(string.uppercase)alphalist.remove('O')numList = ['1','2','3','4','5','6','7','8','9']codesys = [alphalist, alphalist, numList, numList, numList]CONTACT_PRIORITY = ['sms', 'called', 'ringing']RETRY_MAP = {'fresh':'retry', 'followup':'fretry', 'onboarding':'oretry'}ASSIGN_MAP = {'retry':'assigned', 'fretry':'fassigned', 'oretry':'oassigned'}def getNextCode(codesys, code=None):if code is None:code = []for charcode in codesys:code.append(charcode[0])return string.join(code, '')carry = Truecode = list(code)lastindex = len(codesys) - 1while carry:listChar = codesys[lastindex]newIndex = (listChar.index(code[lastindex])+1)%len(listChar)print newIndexcode[lastindex] = listChar[newIndex]if newIndex != 0:carry = Falselastindex -= 1if lastindex ==-1:raise BaseException("All codes are exhausted")return string.join(code, '')global RETAILER_DETAIL_CALL_COUNTERRETAILER_DETAIL_CALL_COUNTER = 0lgr = getLogger('/var/log/retailer-acquisition-api.log')DEALER_RETRY_FACTOR = int(PythonPropertyReader.getConfig('DEALER_RETRY_FACTOR'))class CategoryDiscountInfo(object):def on_get(self, req, resp):result = Mongo.getAllCategoryDiscount()json_docs = [json.dumps(doc, default=json_util.default) for doc in result]resp.body = json.dumps(json_docs, encoding='utf-8')def on_post(self, req, resp):try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.addCategoryDiscount(result_json)resp.body = json.dumps(result, encoding='utf-8')def on_put(self, req, resp, _id):try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.updateCategoryDiscount(result_json, _id)resp.body = json.dumps(result, encoding='utf-8')class SkuSchemeDetails(object):def on_get(self, req, resp):offset = req.get_param_as_int("offset")limit = req.get_param_as_int("limit")result = Mongo.getAllSkuWiseSchemeDetails(offset, limit)json_docs = [json.dumps(doc, default=json_util.default) for doc in result]resp.body = json.dumps(json_docs, encoding='utf-8')def on_post(self, req, resp):multi = req.get_param_as_int("multi")try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.addSchemeDetailsForSku(result_json)resp.body = json.dumps(result, encoding='utf-8')class SkuDiscountInfo():def on_get(self, req, resp):offset = req.get_param_as_int("offset")limit = req.get_param_as_int("limit")result = Mongo.getallSkuDiscountInfo(offset,limit)json_docs = [json.dumps(doc, default=json_util.default) for doc in result]resp.body = json.dumps(json_docs, encoding='utf-8')def on_post(self, req, resp):multi = req.get_param_as_int("multi")try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.addSkuDiscountInfo(result_json)resp.body = json.dumps(result, encoding='utf-8')def on_put(self, req, resp, _id):try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.updateSkuDiscount(result_json, _id)resp.body = json.dumps(result, encoding='utf-8')class ExceptionalNlc():def on_get(self, req, resp):offset = req.get_param_as_int("offset")limit = req.get_param_as_int("limit")result = Mongo.getAllExceptionlNlcItems(offset, limit)json_docs = [json.dumps(doc, default=json_util.default) for doc in result]resp.body = json.dumps(json_docs, encoding='utf-8')def on_post(self, req, resp):multi = req.get_param_as_int("multi")try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.addExceptionalNlc(result_json)resp.body = json.dumps(result, encoding='utf-8')def on_put(self, req, resp, _id):try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.updateExceptionalNlc(result_json, _id)resp.body = json.dumps(result, encoding='utf-8')class Deals():def on_get(self,req, resp, userId):categoryId = req.get_param_as_int("categoryId")offset = req.get_param_as_int("offset")limit = req.get_param_as_int("limit")sort = req.get_param("sort")direction = req.get_param_as_int("direction")filterData = req.get_param('filterData')result = Mongo.getNewDeals(int(userId), categoryId, offset, limit, sort, direction, filterData)resp.body = dumps(result)class MasterData():def on_get(self,req, resp, skuId):showDp = req.get_param_as_int("showDp")result = Mongo.getItem(skuId, showDp)try:json_docs = [json.dumps(doc, default=json_util.default) for doc in result]resp.body = json.dumps(json_docs, encoding='utf-8')except:json_docs = [json.dumps(doc, default=json_util.default) for doc in result]resp.body = json.dumps(json_docs, encoding='utf-8')def on_post(self,req, resp):addNew = req.get_param_as_int("addNew")update = req.get_param_as_int("update")addToExisting = req.get_param_as_int("addToExisting")multi = req.get_param_as_int("multi")try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')if addNew == 1:result = Mongo.addNewItem(result_json)elif update == 1:result = Mongo.updateMaster(result_json, multi)elif addToExisting == 1:result = Mongo.addItemToExistingBundle(result_json)else:raiseresp.body = dumps(result)class LiveData():def on_get(self,req, resp):if req.get_param_as_int("id") is not None:print "****getting only for id"id = req.get_param_as_int("id")try:result = FetchLivePrices.getLatestPriceById(id)json_docs = json.dumps(result, default=json_util.default)resp.body = json.dumps(json_docs, encoding='utf-8')except:json_docs = json.dumps({}, default=json_util.default)resp.body = json.dumps(json_docs, encoding='utf-8')else:print "****getting only for skuId"skuBundleId = req.get_param_as_int("skuBundleId")source_id = req.get_param_as_int("source_id")try:result = FetchLivePrices.getLatestPrice(skuBundleId, source_id)json_docs = [json.dumps(doc, default=json_util.default) for doc in result]resp.body = json.dumps(json_docs, encoding='utf-8')except:json_docs = [json.dumps(doc, default=json_util.default) for doc in [{}]]resp.body = json.dumps(json_docs, encoding='utf-8')class CashBack():def on_get(self,req, resp):identifier = req.get_param("identifier")source_id = req.get_param_as_int("source_id")try:result = Mongo.getCashBackDetails(identifier, source_id)json_docs = json.dumps(result, default=json_util.default)resp.body = json_docsexcept:json_docs = json.dumps({}, default=json_util.default)resp.body = json_docsclass ImgSrc():def on_get(self,req, resp):identifier = req.get_param("identifier")source_id = req.get_param_as_int("source_id")try:result = Mongo.getImgSrc(identifier, source_id)json_docs = json.dumps(result, default=json_util.default)resp.body = json_docsexcept:json_docs = json.dumps({}, default=json_util.default)resp.body = json_docsclass DealSheet():def on_get(self,req, resp):X_DealSheet.sendMail()json_docs = json.dumps({'True':'Sheet generated, mail sent.'}, default=json_util.default)resp.body = json.dumps(json_docs, encoding='utf-8')class DealerPrice():def on_get(self, req, resp):offset = req.get_param_as_int("offset")limit = req.get_param_as_int("limit")result = Mongo.getAllDealerPrices(offset,limit)json_docs = [json.dumps(doc, default=json_util.default) for doc in result]resp.body = json.dumps(json_docs, encoding='utf-8')def on_post(self, req, resp):multi = req.get_param_as_int("multi")try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.addSkuDealerPrice(result_json)resp.body = json.dumps(result, encoding='utf-8')def on_put(self, req, resp, _id):try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.updateSkuDealerPrice(result_json, _id)resp.body = json.dumps(result, encoding='utf-8')class ResetCache():def on_get(self,req, resp, userId):result = Mongo.resetCache(userId)resp.body = json.dumps(result, encoding='utf-8')class UserDeals():def on_get(self,req,resp,userId):UserSpecificDeals.generateSheet(userId)json_docs = json.dumps({'True':'Sheet generated, mail sent.'}, default=json_util.default)resp.body = json.dumps(json_docs, encoding='utf-8')class CommonUpdate():def on_post(self,req,resp):multi = req.get_param_as_int("multi")try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.updateCollection(result_json)resp.body = json.dumps(result, encoding='utf-8')resp.content_type = "application/json; charset=utf-8"class NegativeDeals():def on_get(self, req, resp):offset = req.get_param_as_int("offset")limit = req.get_param_as_int("limit")result = Mongo.getAllNegativeDeals(offset, limit)resp.body = dumps(result)def on_post(self, req, resp):multi = req.get_param_as_int("multi")try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.addNegativeDeals(result_json, multi)resp.body = json.dumps(result, encoding='utf-8')class ManualDeals():def on_get(self, req, resp):offset = req.get_param_as_int("offset")limit = req.get_param_as_int("limit")result = Mongo.getAllManualDeals(offset, limit)resp.body = dumps(result)def on_post(self, req, resp):multi = req.get_param_as_int("multi")try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.addManualDeal(result_json, multi)resp.body = json.dumps(result, encoding='utf-8')class CommonDelete():def on_post(self,req,resp):try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.deleteDocument(result_json)resp.body = json.dumps(result, encoding='utf-8')resp.content_type = "application/json; charset=utf-8"class SearchProduct():def on_get(self,req,resp):offset = req.get_param_as_int("offset")limit = req.get_param_as_int("limit")search_term = req.get_param("search")result = Mongo.searchMaster(offset, limit, search_term)resp.body = dumps(result)class FeaturedDeals():def on_get(self, req, resp):offset = req.get_param_as_int("offset")limit = req.get_param_as_int("limit")result = Mongo.getAllFeaturedDeals(offset, limit)resp.body = dumps(result)def on_post(self, req, resp):multi = req.get_param_as_int("multi")try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.addFeaturedDeal(result_json, multi)resp.body = json.dumps(result, encoding='utf-8')class CommonSearch():def on_get(self,req,resp):class_name = req.get_param("class")sku = req.get_param_as_int("sku")skuBundleId = req.get_param_as_int("skuBundleId")result = Mongo.searchCollection(class_name, sku, skuBundleId)resp.body = dumps(result)class CricScore():def on_get(self,req,resp):result = Mongo.getLiveCricScore()resp.body = dumps(result)class Notification():def on_post(self, req, resp):try:result_json = json.loads(req.stream.read(), encoding='utf-8')except ValueError:raise falcon.HTTPError(falcon.HTTP_400,'Malformed JSON','Could not decode the request body. The ''JSON was incorrect.')result = Mongo.addBundleToNotification(result_json)resp.body = json.dumps(result, encoding='utf-8')def on_get(self, req, resp):offset = req.get_param_as_int("offset")limit = req.get_param_as_int("limit")result = Mongo.getAllNotifications(offset, limit)resp.body = dumps(result)class DealBrands():def on_get(self, req, resp):category_id = req.get_param_as_int("category_id")result = Mongo.getBrandsForFilter(category_id)resp.body = dumps(result)class DealRank():def on_get(self, req, resp):identifier = req.get_param("identifier")source_id = req.get_param_as_int("source_id")user_id = req.get_param_as_int("user_id")result = Mongo.getDealRank(identifier, source_id, user_id)json_docs = json.dumps(result, default=json_util.default)resp.body = json_docsclass RetailerDetail():global RETAILER_DETAIL_CALL_COUNTERdef getRetryRetailer(self,failback=True):status = RETRY_MAP.get(self.callType)retailer = session.query(Retailers).filter_by(status=status).filter(Retailers.next_call_time<=datetime.now()).order_by(Retailers.call_priority).order_by(Retailers.next_call_time).with_lockmode("update").first()if retailer is not None:lgr.info( "getRetryRetailer " + str(retailer.id))else:if failback:retailer = self.getNewRetailer(False)return retailerelse:#No further calls for nowreturn Noneretailer.status = ASSIGN_MAP.get(status)retailer.next_call_time = Nonelgr.info( "getRetryRetailer " + str(retailer.id))return retailerdef getNotActiveRetailer(self):try:user = session.query(Users).filter_by(activated=0).filter_by(status=1).filter(Users.mobile_number != None).filter(~Users.mobile_number.like("0%")).filter(Users.created>datetime(2015,06,29)).order_by(Users.created.desc()).with_lockmode("update").first()if user is None:return Noneelse:retailerContact = session.query(RetailerContacts).filter_by(mobile_number=user.mobile_number).first()if retailerContact is not None:retailer = session.query(Retailers).filter_by(id=retailerContact.retailer_id).first()else:retailer = session.query(Retailers).filter_by(contact1=user.mobile_number).first()if retailer is None:retailer = session.query(Retailers).filter_by(contact2=user.mobile_number).first()if retailer is None:retailer = Retailers()retailer.contact1 = user.mobile_numberretailer.status = 'assigned'retailer.retry_count = 0retailer.invalid_retry_count = 0retailer.is_elavated=1user.status = 2session.commit()print "retailer id", retailer.idretailer.contact = user.mobile_numberreturn retailerfinally:session.close()def getNewRetailer(self,failback=True):if self.callType == 'fresh':retailer = self.getNotActiveRetailer()if retailer is not None:return retailerretry = Trueretailer = Nonetry:while(retry):lgr.info( "Calltype " + self.callType)status=self.callTypequery = session.query(Retailers).filter(Retailers.status==status).filter(or_(Retailers.agent_id==self.agentId, Retailers.agent_id==None))if status=='fresh':query = query.filter_by(is_or=False, is_std=False).filter(Retailers.pin==Pincodeavailability.code).filter(Pincodeavailability.amount > 19999).order_by(Retailers.is_elavated.desc(), Retailers.agent_id.desc())elif status=='followup':query = query.filter(Retailers.next_call_time<=datetime.now()).order_by(Retailers.agent_id.desc(),Retailers.next_call_time)else:query = query.filter(Retailers.modified<=datetime.now()).order_by(Retailers.agent_id.desc(), Retailers.modified)retailer = query.with_lockmode("update").first()if retailer is not None:lgr.info( "retailer " +str(retailer.id))if status=="fresh":userquery = session.query(Users)if retailer.contact2 is not None:userquery = userquery.filter(Users.mobile_number.in_([retailer.contact1,retailer.contact2]))else:userquery = userquery.filter_by(mobile_number=retailer.contact1)user = userquery.first()if user is not None:retailer.status = 'alreadyuser'lgr.info( "retailer.status " + retailer.status)session.commit()continueretailer.status = 'assigned'elif status=='followup':if isActivated(retailer.id):print "Retailer Already %d activated and marked onboarded"%(retailer.id)continueretailer.status = 'fassigned'else:retailer.status = 'oassigned'retailer.retry_count = 0retailer.invalid_retry_count = 0lgr.info( "Found Retailer " + str(retailer.id) + " with status " + status + " assigned to " + str(self.agentId))else:lgr.info( "No fresh/followup retailers found")if failback:retailer = self.getRetryRetailer(False)return retailerretry=Falseexcept:print traceback.print_exc()return retailerdef on_get(self, req, resp, agentId, callType=None, retailerId=None):global RETAILER_DETAIL_CALL_COUNTERRETAILER_DETAIL_CALL_COUNTER += 1lgr.info( "RETAILER_DETAIL_CALL_COUNTER " + str(RETAILER_DETAIL_CALL_COUNTER))self.agentId = int(agentId)self.callType = callTypeif retailerId is not None:self.retailerId = int(retailerId)retailerLink = session.query(RetailerLinks).filter_by(retailer_id=self.retailerId).first()if retailerLink is not None:code = retailerLink.codeelse:code = self.getCode()retailerLink = RetailerLinks()retailerLink.code = coderetailerLink.agent_id = self.agentIdretailerLink.retailer_id = self.retailerIdactivationCode=Activation_Codes()activationCode.code = codesession.commit()session.close()resp.body = json.dumps({"result":{"code":code,"link":make_tiny(code)}}, encoding='utf-8')returnretryFlag = Falseif RETAILER_DETAIL_CALL_COUNTER % DEALER_RETRY_FACTOR ==0:retryFlag=Truetry:if retryFlag:retailer = self.getRetryRetailer()else:retailer = self.getNewRetailer()if retailer is None:resp.body = "{}"returnfetchInfo = FetchDataHistory()fetchInfo.agent_id = self.agentIdfetchInfo.call_type = self.callTypeagent = session.query(Agents).filter_by(id=self.agentId).first()last_disposition = session.query(CallHistory).filter_by(agent_id=self.agentId).order_by(CallHistory.id.desc()).first()if last_disposition is None or last_disposition.created < agent.last_login:fetchInfo.last_action = 'login'fetchInfo.last_action_time = agent.last_loginelse:fetchInfo.last_action = 'disposition'fetchInfo.last_action_time = last_disposition.createdfetchInfo.retailer_id = retailer.idsession.commit()otherContacts = [r for r, in session.query(RetailerContacts.mobile_number).filter_by(retailer_id=retailer.id).order_by(RetailerContacts.contact_type).all()]resp.body = json.dumps(todict(getRetailerObj(retailer, otherContacts, self.callType)), encoding='utf-8')returnfinally:session.close()if retailer is None:resp.body = "{}"else:print "It should never come here"resp.body = json.dumps(todict(getRetailerObj(retailer)), encoding='utf-8')def on_post(self, req, resp, agentId, callType):returned = Falseself.agentId = int(agentId)self.callType = callTypejsonReq = json.loads(req.stream.read(), encoding='utf-8')lgr.info( "Request ----\n" + str(jsonReq))self.jsonReq = jsonReqinvalidNumber = self.invalidNumbercallLater = self.callLateralreadyUser = self.alReadyUserverifiedLinkSent = self.verifiedLinkSentonboarded = self.onboardedself.address = jsonReq.get('address')self.retailerId = int(jsonReq.get('retailerid'))self.smsNumber = jsonReq.get('smsnumber')if self.smsNumber is not None:self.smsNumber = self.smsNumber.strip().lstrip("0")try:self.retailer = session.query(Retailers).filter_by(id=self.retailerId).first()if self.address:self.retailer.address_new = self.addressself.callDisposition = jsonReq.get('calldispositiontype')self.callHistory = CallHistory()self.callHistory.agent_id=self.agentIdself.callHistory.call_disposition = self.callDispositionself.callHistory.retailer_id=self.retailerIdself.callHistory.call_type=self.callTypeself.callHistory.duration_sec = int(jsonReq.get("callduration"))self.callHistory.disposition_description = jsonReq.get('calldispositiondescritption')self.callHistory.disposition_comments = jsonReq.get('calldispositioncomments')lgr.info(self.callHistory.disposition_comments)self.callHistory.call_time = datetime.strptime(jsonReq.get("calltime"), '%d/%m/%Y %H:%M:%S')self.callHistory.mobile_number = jsonReq.get('number')self.callHistory.sms_verified = int(jsonReq.get("verified"))lastFetchData = session.query(FetchDataHistory).filter_by(agent_id=self.agentId).order_by(FetchDataHistory.id.desc()).first()if self.callDisposition == 'onboarded':self.checkList = jsonReq.get('checklist')if lastFetchData is None:raiseself.callHistory.last_fetch_time= lastFetchData.createddispositionMap = { 'call_later':callLater,'ringing_no_answer':callLater,'not_reachable':callLater,'switch_off':callLater,'not_retailer':invalidNumber,'invalid_no':invalidNumber,'wrong_no':invalidNumber,'hang_up':invalidNumber,'retailer_not_interested':invalidNumber,'recharge_retailer':invalidNumber,'accessory_retailer':invalidNumber,'service_center_retailer':invalidNumber,'alreadyuser':alreadyUser,'verified_link_sent':verifiedLinkSent,'onboarded':onboarded}returned = dispositionMap[jsonReq.get('calldispositiontype')]()finally:session.close()if returned:resp.body = "{\"result\":\"success\"}"else:resp.body = "{\"result\":\"failed\"}"def invalidNumber(self,):#self.retailer.status = 'retry' if self.callType == 'fresh' else 'fretry'if self.callDisposition == 'invalid_no':self.retailer.status='failed'self.callHistory.disposition_description = 'Invalid Number'elif self.callDisposition == 'wrong_no':self.retailer.status='failed'self.callHistory.disposition_description = 'Wrong Number'elif self.callDisposition == 'hang_up':self.retailer.status='failed'self.callHistory.disposition_description = 'Hang Up'elif self.callDisposition == 'retailer_not_interested':self.retailer.status='failed'if self.callHistory.disposition_description is None:self.callHistory.disposition_description = 'NA'self.callHistory.disposition_description = 'Reason Retailer Not Interested ' + self.callHistory.disposition_descriptionelif self.callDisposition == 'recharge_retailer':self.retailer.status='failed'self.callHistory.disposition_description = 'Recharge related. Not a retailer 'elif self.callDisposition == 'accessory_retailer':self.retailer.status='failed'self.callHistory.disposition_description = 'Accessory related. Not a retailer'elif self.callDisposition == 'service_center_retailer':self.retailer.status='failed'self.callHistory.disposition_description = 'Service Center related. Not a retailer'elif self.callDisposition == 'not_retailer':self.retailer.status='failed'self.callHistory.disposition_description = 'Not a retailer'session.commit()return Truedef getCode(self,):newCode = NonelastLink = session.query(RetailerLinks).order_by(RetailerLinks.id.desc()).with_lockmode("update").first()if lastLink is not None:if len(lastLink.code)==len(codesys):newCode=lastLink.codereturn getNextCode(codesys, newCode)def callLater(self,):self.retailer.status = RETRY_MAP.get(self.callType)self.retailer.call_priority = Noneif self.callDisposition == 'call_later':if self.callHistory.disposition_description is not None:self.retailer.call_priority = 'user_initiated'self.retailer.next_call_time = datetime.strptime(self.callHistory.disposition_description, '%d/%m/%Y %H:%M:%S')self.callHistory.disposition_description = 'User requested to call on ' + self.callHistory.disposition_descriptionelse:self.retailer.call_priority = 'system_initiated'self.retailer.next_call_time = self.callHistory.call_time + timedelta(days=1)self.callHistory.disposition_description = 'Call scheduled on ' + datetime.strftime(self.retailer.next_call_time, '%d/%m/%Y %H:%M:%S')else:if self.callDisposition == 'ringing_no_answer':if self.retailer.disposition == 'ringing_no_answer':self.retailer.retry_count += 1else:self.retailer.disposition = 'ringing_no_answer'self.retailer.retry_count = 1else:if self.retailer.disposition == 'ringing_no_answer':passelse:self.retailer.disposition = 'not_reachable'self.retailer.retry_count += 1self.retailer.invalid_retry_count += 1retryConfig = session.query(RetryConfig).filter_by(call_type=self.callType, disposition_type=self.retailer.disposition, retry_count=self.retailer.retry_count).first()if retryConfig is not None:self.retailer.next_call_time = self.callHistory.call_time + timedelta(minutes = retryConfig.minutes_ahead)self.callHistory.disposition_description = 'Call scheduled on ' + datetime.strftime(self.retailer.next_call_time, '%d/%m/%Y %H:%M:%S')else:self.retailer.status = 'failed'self.callHistory.disposition_description = 'Call failed as all attempts exhausted'session.commit()return Truedef alReadyUser(self,):self.retailer.status = self.callDispositionif self.callHistory.disposition_description is None:self.callHistory.disposition_description = 'Retailer already user'session.commit()return Truedef verifiedLinkSent(self,):if self.callType == 'fresh':self.retailer.status = 'followup'self.retailer.agent_id = Noneself.retailer.next_call_time = self.callHistory.call_time + timedelta(days=1)self.callHistory.disposition_description = 'App link sent via ' + self.callHistory.disposition_description+ '. followup on' + datetime.strftime(self.retailer.next_call_time, '%d/%m/%Y %H:%M:%S')else:self.retailer.status = 'followup'self.retailer.agent_id = Noneself.retailer.next_call_time = self.callHistory.call_time + timedelta(days=7)self.callHistory.disposition_description = 'App link sent via' + self.callHistory.disposition_description + '. Followup again on ' + datetime.strftime(self.retailer.next_call_time, '%d/%m/%Y %H:%M:%S')addContactToRetailer(self.agentId, self.retailerId, self.smsNumber, self.callType, 'sms')session.commit()return Truedef onboarded(self,):self.retailer.status = self.callDispositioncheckList = OnboardedRetailerChecklists()checkList.contact_us = self.checkList.get('contactus')checkList.doa_return_policy = self.checkList.get('doareturnpolicy')checkList.number_verification = self.checkList.get('numberverification')checkList.payment_option = self.checkList.get('paymentoption')checkList.preferences = self.checkList.get('preferences')checkList.product_info = self.checkList.get('productinfo')checkList.redeem = self.checkList.get('redeem')checkList.retailer_id = self.retailerIdsession.commit()return Truedef isActivated(retailerId):retailerLink = session.query(RetailerLinks).filter_by(retailer_id=retailerId).first()user = session.query(Users).filter(or_(func.lower(Users.referrer)==retailerLink.code.lower(), Users.utm_campaign==retailerLink.code)).first()if user is None:mobileNumbers = list(session.query(RetailerContacts.mobile_number).filter_by(retailer_id=retailerId).all())user = session.query(Users).filter(Users.mobile_number.in_(mobileNumbers)).first()if user is None:if retailerLink.created < datetime(2015,5,26):historyNumbers = [number for number, in session.query(CallHistory.mobile_number).filter_by(retailer_id = retailerId).all()]user = session.query(Users).filter(Users.mobile_number.in_(historyNumbers)).first()if user is None:return Falseelse:mapped_with = 'contact'else:return Falseelse:mapped_with = 'contact'else:mapped_with = 'code'retailerLink.mapped_with = mapped_withif user.activation_time is not None:retailerLink.activated = user.activation_timeretailerLink.activated = user.createdretailerLink.user_id = user.idretailer = session.query(Retailers).filter_by(id=retailerId).first()if retailer.status == 'followup' or retailer.status == 'fretry':retailer.status = 'onboarding'retailer.agent_id = Noneretailer.call_priority = Noneretailer.next_call_time = Noneretailer.retry_count = 0retailer.invalid_retry_count = 0session.commit()print "retailerLink.retailer_id", retailerLink.retailer_idprint "retailer", retailer.idsession.close()return Trueclass AddContactToRetailer():def on_post(self,req,resp, agentId):agentId = int(agentId)try:jsonReq = json.loads(req.stream.read(), encoding='utf-8')retailerId = int(jsonReq.get("retailerid"))mobile = jsonReq.get("mobile")callType = jsonReq.get("calltype")contactType = jsonReq.get("contacttype")addContactToRetailer(agentId, retailerId, mobile, callType, contactType)session.commit()finally:session.close()class AddAddressToRetailer():def on_post(self,req,resp, agentId):agentId = int(agentId)jsonReq = json.loads(req.stream.read(), encoding='utf-8')retailerId = int(jsonReq.get("retailerid"))address = str(jsonReq.get("address"))storeName = str(jsonReq.get("storename"))pin = str(jsonReq.get("pin"))city = str(jsonReq.get("city"))state = str(jsonReq.get("state"))updateType = str(jsonReq.get("updatetype"))addAddressToRetailer(agentId, retailerId, address, storeName, pin, city,state, updateType)def addContactToRetailer(agentId, retailerId, mobile, callType, contactType):retailerContact = session.query(RetailerContacts).filter_by(retailer_id=retailerId).filter_by(mobile_number=mobile).first()if retailerContact is None:retailerContact = RetailerContacts()retailerContact.retailer_id = retailerIdretailerContact.agent_id = agentIdretailerContact.call_type = callTyperetailerContact.contact_type = contactTyperetailerContact.mobile_number = mobileelse:if CONTACT_PRIORITY.index(retailerContact.contact_type) > CONTACT_PRIORITY.index(contactType):retailerContact.contact_type = contactTypedef addAddressToRetailer(agentId, retailerId, address, storeName, pin, city,state, updateType):print "I am in addAddress"print agentId, retailerId, address, storeName, pin, city, state, updateTypetry:if updateType=='new':retailer = session.query(Retailers).filter_by(id=retailerId).first()retailer.address = addressretailer.title = storeNameretailer.city = cityretailer.state = stateretailer.pin = pinraddress = RetailerAddresses()raddress.address = addressraddress.title = storeNameraddress.agent_id = agentIdraddress.city = cityraddress.pin = pinraddress.retailer_id = retailerIdraddress.state = statesession.commit()finally:session.close()class Login():def on_get(self, req, resp, agentId, role):try:self.agentId = int(agentId)self.role = roleprint str(self.agentId) + self.role;agents=AgentLoginTimings()lastLoginTime = session.query(Agents).filter(Agents.id==self.agentId).first()print 'lastLogintime' + str(lastLoginTime)agents.loginTime=lastLoginTime.last_loginagents.logoutTime=datetime.now()agents.role =self.roleagents.agent_id = self.agentIdsession.add(agents)session.commit()resp.body = json.dumps({"result":{"success":"true","message":"Success"}}, encoding='utf-8')finally:session.close()def on_post(self,req,resp):try:jsonReq = json.loads(req.stream.read(), encoding='utf-8')lgr.info( "Request ----\n" + str(jsonReq))email=jsonReq.get('email')password = jsonReq.get('password')role=jsonReq.get('role')agent = session.query(Agents).filter(and_(Agents.email==email,Agents.password==password)).first()if agent is None:resp.body = json.dumps({"result":{"success":"false","message":"Invalid User"}}, encoding='utf-8')else:print agent.idcheckRole = session.query(Agent_Roles.id).filter(and_(Agent_Roles.agent_id==agent.id,Agent_Roles.role==role)).first()if checkRole is None:resp.body = json.dumps({"result":{"success":"false","message":"Invalid Role"}}, encoding='utf-8')else:agent.last_login = datetime.now()agent.login_type = roleresp.body = json.dumps({"result":{"success":"true","message":"Valid User","id":agent.id}}, encoding='utf-8')session.commit()#session.query(Agents).filter_by(id = checkUser[0]).finally:session.close()def test(self,email,password,role):checkUser = session.query(Agents.id).filter(and_(Agents.email==email,Agents.password==password)).first()if checkUser is None:print checkUserelse:print checkUser[0]checkRole = session.query(Agent_Roles.id).filter(and_(Agent_Roles.agent_id==checkUser[0],Agent_Roles.role==role)).first()if checkRole is None:passelse:agents=AgentLoginTimings()agents.loginTime=datetime.now()agents.logoutTime=datetime.now()agents.role =roleagents.agent_id = 2#session.query(AgentLoginTimings).filter_by(id = checkUser[0]).update({"last_login":datetime.now()}, synchronize_session=False)session.add(agents)session.commit()session.close()#session.query(Agents).filter(Agents.id==checkUser[0]).update({"last_login":Agents.last_login})class RetailerActivation():def on_get(self, req, resp, userId):res = markDealerActivation(int(userId))if res:resp.body = "{\"activated\":true}"else:resp.body = "{\"activated\":false}"def markDealerActivation(userId):try:user = session.query(Users).filter_by(id=userId).first()result = FalsemappedWith = 'contact'retailer = Noneif user is not None:referrer = None if user.referrer is None else user.referrer.upper()retailerLink = session.query(RetailerLinks).filter(or_(RetailerLinks.code==referrer, RetailerLinks.code==user.utm_campaign)).first()if retailerLink is None:if user.mobile_number is not None:retailerContact = session.query(RetailerContacts).filter_by(mobile_number=user.mobile_number).first()if retailerContact is None:retailer = session.query(Retailers).filter(Retailers.status.in_(['followup', 'fretry', 'fdone'])).filter(or_(Retailers.contact1==user.mobile_number,Retailers.contact2==user.mobile_number)).first()else:retailer = session.query(Retailers).filter_by(id = retailerContact.retailer_id).first()else:retailer = session.query(Retailers).filter_by(id = retailerLink.retailer_id).first()mappedWith='code'if retailer is not None:retailerLink = session.query(RetailerLinks).filter_by(retailer_id=retailer.id).first()if retailerLink is not None:retailerLink.user_id = user.idretailerLink.mapped_with=mappedWithretailer.status = 'onboarding'result = Truesession.commit()return resultfinally:session.close()def todict(obj, classkey=None):if isinstance(obj, dict):data = {}for (k, v) in obj.items():data[k] = todict(v, classkey)return dataelif hasattr(obj, "_ast"):return todict(obj._ast())elif hasattr(obj, "__iter__"):return [todict(v, classkey) for v in obj]elif hasattr(obj, "__dict__"):data = dict([(key, todict(value, classkey))for key, value in obj.__dict__.iteritems()if not callable(value) and not key.startswith('_')])if classkey is not None and hasattr(obj, "__class__"):data[classkey] = obj.__class__.__name__return dataelse:return objdef getRetailerObj(retailer, otherContacts1=None, callType=None):print "before otherContacts1",otherContacts1otherContacts = [] if otherContacts1 is None else otherContacts1print "after otherContacts1",otherContactsobj = Mock()obj.id = retailer.idif retailer.contact1 is not None and retailer.contact1 not in otherContacts:otherContacts.append(retailer.contact1)if retailer.contact2 is not None and retailer.contact2 not in otherContacts:otherContacts.append(retailer.contact2)obj.contact1 = None if len(otherContacts)==0 else otherContacts[0]if obj.contact1 is not None:obj.contact2 = None if len(otherContacts)==1 else otherContacts[1]obj.scheduled = (retailer.call_priority is not None)address = Nonetry:address = session.query(RetailerAddresses).filter_by(retailer_id=retailer.id).order_by(RetailerAddresses.created.desc()).first()finally:session.close()if address is not None:obj.address = address.addressobj.title = address.titleobj.city = address.cityobj.state = address.stateobj.pin = address.pinelse:obj.address = retailer.address_new if retailer.address_new is not None else retailer.addressobj.title = retailer.titleobj.city = retailer.cityobj.state = retailer.stateobj.pin = retailer.pinobj.status = retailer.statusif hasattr(retailer, 'contact'):obj.contact = retailer.contactif callType == 'onboarding':try:userId, activatedTime = session.query(RetailerLinks.user_id, RetailerLinks.activated).filter(RetailerLinks.retailer_id==retailer.id).first()activated, = session.query(Users.activation_time).filter(Users.id==userId).first()if activated is not None:activatedTime = activatedobj.user_id = userIdobj.created = datetime.strftime(activatedTime, '%d/%m/%Y %H:%M:%S')result = fetchResult("select * from useractive where user_id=%d"%(userId))if result == ():obj.last_active = Noneelse:obj.last_active =datetime.strftime(result[0][1], '%d/%m/%Y %H:%M:%S')ordersCount = session.query(Orders).filter_by(user_id = userId).filter(~Orders.status.in_(['ORDER_NOT_CREATED_KNOWN', 'ORDER_ALREADY_CREATED_IGNORED'])).count()obj.orders = ordersCountfinally:session.close()return objdef make_tiny(code):url = 'https://play.google.com/store/apps/details?id=com.saholic.profittill&referrer=utm_source%3D0%26utm_medium%3DCRM%26utm_term%3D001%26utm_campaign%3D' + code#request_url = ('http://tinyurl.com/api-create.php?' + urlencode({'url':url}))#filehandle = urllib2.Request(request_url)#x= urllib2.urlopen(filehandle)try:shortener = Shortener('TinyurlShortener')returnUrl = shortener.short(url)except:shortener = Shortener('SentalaShortener')returnlUrl = shortener.short(url)return returnUrlclass SearchUser():def on_post(self, req, resp, agentId, searchType):retailersJsonArray = []try:jsonReq = json.loads(req.stream.read(), encoding='utf-8')lgr.info( "Request in Search----\n" + str(jsonReq))contact=jsonReq.get('searchTerm')if(searchType=="number"):retailer_ids = session.query(RetailerContacts.retailer_id).filter_by(mobile_number=contact).all()retailer_ids = [r for r, in retailer_ids]anotherCondition = or_(Retailers.contact1==contact,Retailers.contact2==contact, Retailers.id.in_(retailer_ids))else:m = re.match("(.*?)(\d{6})(.*?)", contact)if m is not None:pin = m.group(2)contact = m.group(1) if m.group(1) != '' else m.group(3)anotherCondition = and_(Retailers.title.ilike('%%%s%%'%(contact)), Retailers.pin==pin)else:anotherCondition = Retailers.title.ilike('%%%s%%'%(contact))retailers = session.query(Retailers).filter(anotherCondition).limit(20).all()if retailers is None:resp.body = json.dumps("{}")else:for retailer in retailers:otherContacts = [r for r, in session.query(RetailerContacts.mobile_number).filter_by(retailer_id=retailer.id).order_by(RetailerContacts.contact_type).all()]retailersJsonArray.append(todict(getRetailerObj(retailer, otherContacts)))resp.body = json.dumps({"Retailers":retailersJsonArray}, encoding='utf-8')returnfinally:session.close()class Mock(object):passdef tagActivatedReatilers():retailerIds = [r for r, in session.query(RetailerLinks.retailer_id).filter_by(user_id = None).all()]session.close()for retailerId in retailerIds:isActivated(retailerId)session.close()class StaticDeals():def on_get(self, req, resp):offset = req.get_param_as_int("offset")limit = req.get_param_as_int("limit")categoryId = req.get_param_as_int("categoryId")direction = req.get_param_as_int("direction")result = Mongo.getStaticDeals(offset, limit, categoryId, direction)resp.body = dumps(result)class DealNotification():def on_get(self,req,resp,skuBundleIds):result = Mongo.getDealsForNotification(skuBundleIds)resp.body = dumps(result)def main():#tagActivatedReatilers()a = RetailerDetail()retailer = a.getNotActiveRetailer()otherContacts = [r for r, in session.query(RetailerContacts.mobile_number).filter_by(retailer_id=retailer.id).order_by(RetailerContacts.contact_type).all()]print json.dumps(todict(getRetailerObj(retailer, otherContacts, 'fresh')), encoding='utf-8')#print make_tiny("AA")if __name__ == '__main__':main()