Rev 17242 | Rev 18440 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
'''Created on Jan 15, 2015@author: amit'''from BeautifulSoup import BeautifulSoupfrom datetime import datetime, date, timedeltafrom dtr import mainfrom dtr.dao import AffiliateInfo, Order, SubOrder, FlipkartAffiliateInfofrom dtr.main import getBrowserObject, getStore, ParseException, ungzipResponse, \Store as MStore, sourceMap, tprintfrom dtr.reports.affiliatereco import getSkuDatafrom dtr.storage.DataService import Clicks, Users, FlipkartOrdersfrom dtr.utils import utilsfrom dtr.utils.utils import fetchResponseUsingProxyfrom elixir import *from pprint import pprintfrom pymongo.mongo_client import MongoClientimport StringIOimport csvimport hashlibimport importlibimport jsonimport mechanizeimport pymongoimport reimport tracebackimport urllibimport zipfileimport urllib2USERNAME='saholic1@gmail.com'PASSWORD='spice@2020'ORDER_TRACK_URL='https://m.flipkart.com/order_details'AFFILIATE_URL='https://affiliate.flipkart.com/'AFFILIATE_LOGIN_URL='https://affiliate.flipkart.com/a_login'AFF_REPORT_URL = "https://affiliate.flipkart.com/downloads/a_downloadRequest?type=OrdersReport¶meters=%s"AFF_DOWNLOAD_URL="https://affiliate.flipkart.com/downloads/file?id=%s"AFF_STATUS_CANCELLED='cancelled'AFF_STATUS_APPROVED='approved'AFF_STATUS_DISAPPROVED='disapproved'AFF_STATUS_PENDING='pending'statuses = [AFF_STATUS_CANCELLED, AFF_STATUS_APPROVED, AFF_STATUS_DISAPPROVED,AFF_STATUS_PENDING ]categoryMap = {3:"Mobiles", 5:"Tablets"}class Store(MStore):OrderStatusMap = {main.Store.ORDER_PLACED : ['approval', 'processing', 'shipping'],main.Store.ORDER_DELIVERED : ['your item has been delivered'],main.Store.ORDER_SHIPPED : ['in transit', 'shipment yet to be delivered'],main.Store.ORDER_CANCELLED : ['shipment is returned', 'your item has been returned', 'your shipment has been cancelled', 'your shipment has been cancelled.']}def __init__(self,store_id):client = MongoClient('mongodb://localhost:27017/')self.db = client.dtrsuper(Store, self).__init__(store_id)def getName(self):return "flipkart"def requestDownload(self):#"https://affiliate.flipkart.com/downloads/a_downloadRequest?type=OrdersReport¶meters=%7B%22filter%22%3A%22approved%22%2C%22till%22%3A%222015-10-03%22%2C%22from%22%3A%222015-04-03%22%7D"requestReportUrl = "https://affiliate.flipkart.com/downloads/a_downloadRequest?type=OrdersReport¶meters=%s"br = getBrowserObject()br.set_debug_responses(True)br.open(AFFILIATE_URL)response = br.response() # copy#token = re.findall('window.__FK = "(.*?)"', utils.ungzipResponse(response), re.IGNORECASE)[0]data = {'j_username':'saholic1@gmail.com','j_password':'spice@2020'}print utils.ungzipResponse(br.open(AFFILIATE_LOGIN_URL, urllib.urlencode(data)))till = datetime.strftime(date.today(),"%Y-%m-%d")start = datetime.strftime(date.today() - timedelta(4), "%Y-%m-%d")#target = open("dowloadreportids", 'w')#target.truncate()for status in statuses:#try:data = {"till":till, "from":start, "filter":status}print json.dumps(data)request = requestReportUrl%(urllib.quote_plus(json.dumps(data).replace(" ", "")))print requestresponse = utils.ungzipResponse(br.open(request))response = json.loads(response)print responseif(response['status']=="OK"):self.db.flipkartdownloadids.save(response)else:utils.sendmail(['amit.gupta@shop2020.in'], '', "Could not get request data for Flipkart Affiliate downlaod")#break#except:utils.sendmail(['amit.gupta@shop2020.in'], '', "Could not get request data for Flipkart Affiliate downlaod due to Internal Server Error")#breakdef scrapeStoreOrders(self,):orders = self._getActiveOrders()for order in orders:print "Order", self.store_name, order['orderId']try:closed = Trueurl = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', order['orderSuccessUrl'],re.IGNORECASE)[0]page = fetchResponseUsingProxy(url)soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)sections = soup.findAll("div", {"class":"ui-app-card-body"})sections.pop(1)mainOrder = soup.find("ul",{"class":"m-bottom p-cart"})fkSubOrders = mainOrder.findAll("li")#remove unwanted listfkSubOrders.pop(-1)bulk = self.db.merchantOrder.initialize_ordered_bulk_op()#fetching suborders detailsfor subOrder in fkSubOrders:updateMap = {}y = subOrder.find("header").findAll("span")for suborderId in y:if "value emp" in str(suborderId):merchantSubOrderId = suborderId.textbreakul = subOrder.find("ul")if ul is None:ul = subOrder.findAll("div", recursive=False)[0].div.divorderItems = ul.findAll("div", recursive=False)i=0for orderItem in orderItems:closedStatus = FalsemerchantSubOrderId = merchantSubOrderId + str(i)subOrder = self._isSubOrderActive(order, merchantSubOrderId)if subOrder is None:breakelif subOrder['closed']:breakfindMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": merchantSubOrderId}divs = orderItem.findAll('div', recursive=False)orderTracking = divs[2]orderTrackingDetDiv = divs[3].find('div',{'class':'c-tabs-content m-top active'})orderTrackingDet = orderTrackingDetDiv.find('div',{'class':re.compile('tracking-remark')}).textupdateMap["subOrders.$.detailedStatus"] = orderTrackingDetstatus = self._getStatusFromDetailedStatus(orderTrackingDet)tr = orderTracking.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})cashbackStatus = subOrder.get("cashBackStatus")if "approveDetails-complete" in str(tr):if "processingDetails-complete" in str(tr):if "shippingDetails-complete" in str(tr):if "delivery-complete" in str(tr):status = MStore.ORDER_DELIVEREDif cashbackStatus == Store.CB_PENDING:cashbackStatus = Store.CB_APPROVEDclosedStatus = Trueelse:status = MStore.ORDER_SHIPPEDcourierTrackAnchor = orderTrackingDetDiv.find('a')trackingUrl = courierTrackAnchor("href")trackingText = courierTrackAnchor.textcourierArr = trackingText.split(' : ')updateMap["subOrders.$.trackingUrl"] = trackingUrlupdateMap["subOrders.$.trackingNumber"] = courierArr[1]updateMap["subOrders.$.courierName"] = courierArr[0]else:status = MStore.ORDER_CANCELLEDclosedStatus = Trueif cashbackStatus == Store.CB_PENDING:cashbackStatus = Store.CB_CANCELLEDelse:status = MStore.ORDER_PLACEDelif str(tr) in ["approveDetails-ongoing"]:status=MStore.ORDER_PLACEDif "dead" in str(tr) or status==MStore.ORDER_CANCELLED:status = MStore.ORDER_CANCELLEDclosedStatus = Trueif cashbackStatus == Store.CB_PENDING:cashbackStatus = Store.CB_CANCELLEDupdateMap["subOrders.$.cashBackStatus"] = cashbackStatusupdateMap["subOrders.$.status"] = statusupdateMap["subOrders.$.closed"] = closedStatusif closed:closed = closedStatusbulk.find(findMap).update({'$set' : updateMap})bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed, 'parseError':False}})bulk.execute()except:self.db.merchantOrder.update({"orderId":order['orderId']}, {"$set":{"parseError":True}})tprint("Could not update " + str(order['orderId']) + ' for store ' + self.getName())traceback.print_exc()def scrapeAffiliate(self, deltaDays=0):if deltaDays is None:deltaDays=0endDate=date.today() - timedelta(days=1)startDate = endDate - timedelta(days=deltaDays)endDate = datetime.strftime(endDate, "%Y-%m-%d")startDate = datetime.strftime(startDate, "%Y-%m-%d")url = "https://affiliate-api.flipkart.net/affiliate/report/orders/detail/json?startDate=%s&endDate=%s&status=%s&offset=0"for status in statuses:nextUrl = url%(startDate, endDate, status)while nextUrl:req = urllib2.Request(nextUrl)nextUrl=''req.add_header('Fk-Affiliate-Id', 'saholic1g')req.add_header('Fk-Affiliate-Token', 'a757444e260c46be8c4aeb20352246ac')resp = urllib2.urlopen(req)resString = json.loads(resp.read())orderList = resString["orderList"]if orderList:for order in orderList:order['sales'] = int(order['sales']['amount'])order['tentativeCommission'] = int(order['tentativeCommission']['amount'])subTagId = order.get("affExtParam1")userId = Noneemail = Noneif subTagId:click = session.query(Clicks).filter_by(tag = subTagId).first()if click is not None:userId= click.user_iduser = session.query(Users.email).filter_by(id = userId).first()if user is not None:email = user.emailflipkartOrder = FlipkartOrders()flipkartOrder.subtagId = subTagIdflipkartOrder.user_id = userIdflipkartOrder.identifier = order.get("identifier")flipkartOrder.email = emailflipkartOrder.created = datetime.strptime(order.get("orderDate"), "%d-%m-%Y")flipkartOrder.status = order.get("status")flipkartOrder.title = order.get("title")flipkartOrder.price = order.get("price")flipkartOrder.quantity = order.get("quantity")flipkartOrder.productCode = order.get("productId")flipkartOrder.affiliateOrderItemId = order.get("affiliateOrderItemId")flipkartOrder.payOut = order['tentativeCommission']flipkartOrder.payOutPercentage = order['commissionRate']skuData = getSkuData(2, order.get("productId"))if skuData is not None:flipkartOrder.catalogId = skuData.get("skuBundleId")flipkartOrder.brand = skuData.get("brand")flipkartOrder.model = skuData.get("model_name")flipkartOrder.category = categoryMap.get(skuData.get("category_id"))flipkartOrder.title =skuData.get("source_product_name")session.commit()nextUrl = resString['next']def _saveToAffiliate(self, offers):collection = self.db.flipkartOrderAffiliateInfo1count=0for row in offers:if count==0:count += 1continueoffer = self.covertToObj(row)collection.save(offer)def covertToObj(self,offer):affiliateorderitemid,title,productid,category,quantity,sales,price,commissionrate,tentativecommission,status,orderdate,saleschannel,customertype,affextparam1, affextparam2 = offersaleMap = {"affiliateorderitemid":affiliateorderitemid,"title":title,"productid":productid,"category":category,"quantity":quantity,"saleAmount":sales,"price":price,"commissionrate":commissionrate,"payOut":tentativecommission,"conversionStatus":status,"saleDate":orderdate,"saleschannel":saleschannel,"customertype":customertype,"affextparam1":affextparam1,"_id":affiliateorderitemid}return saleMapdef parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):resp= {}try:br = getBrowserObject()url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]response = br.open(url)page = ungzipResponse(response)merchantOrderId = re.findall('reference_id=(.*?)&', orderSuccessUrl,re.IGNORECASE)[0]print merchantOrderIdsoup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)sections = soup.findAll("div", {"class":"ui-app-card-body"})sections.pop(1)merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)merchantOrder.orderTrackingUrl = urlfor data in sections:name = data.findAll("span")i=0while i< len(name):if "key" in str(name[i]):if "Grand Total" in str(name[i]):#Total AmountmerchantOrder.paidAmount = int(re.findall(r'\d+', name[i+1].text)[0])elif "Order Date" in str(name[i]):merchantOrder.placedOn = name[i+1].texti=i+1merchantOrder.merchantOrderId = merchantOrderIdmainOrder = soup.find("ul",{"class":"m-bottom p-cart"})fkSubOrders = mainOrder.findAll("li")#remove unwanted listfkSubOrders.pop(-1)subOrders = []merchantOrder.subOrders = subOrders#fetching suborders detailsfor subOrder in fkSubOrders:y = subOrder.find("header").findAll("span")for suborderId in y:if "value emp" in str(suborderId):merchantSubOrderId = suborderId.textbreakorderItems = subOrder.find("ul").findAll("div", recursive=False)i=0for orderItem in orderItems:merchantOrder.placedOnmerchantSubOrderId = merchantSubOrderId + str(i)divs = orderItem.findAll('div', recursive=False)content = divs[0]orderTracking = divs[2]orderTrackingDet = divs[3]imgUrl = content.find('img')['src']lineDet = content.find("div",{"class":"product-info"})productTitle = lineDet.find("a",{"class":"product-title"}).textproductUrl = str(lineDet.find("a")['href'])start='pid='s=str(lineDet.find("a")['href'])productCode = re.findall(re.escape(start)+"(.*)",s)[0].strip()mname = lineDet.findAll("span")k=0while k<len(mname):if "note" in str(mname[k]):if "Color:" in str(mname[k]):productTitle = productTitle + " " + mname[k+1].textelif "Qty:" in str(mname[k]):quantity = int(mname[k+1].text)elif "Subtotal:" in str(mname[k]):amountPaid = int(re.findall(r'\d+', mname[k+1].text)[0])elif "Delivery:" in str(mname[k]):#Delivery Date for sub orderprint "Delivery Date " +mname[k+1].textk=k+1merchantsubOrder = SubOrder(productTitle, productUrl, merchantOrder.placedOn, amountPaid,MStore.ORDER_PLACED, quantity)merchantsubOrder.imgUrl = imgUrlmerchantsubOrder.productCode = productCodemerchantsubOrder.merchantSubOrderId = merchantSubOrderIdprint "productCode", productCodeprint "amountPaid", amountPaidcashbackAmount, cashbackPercent = self.getCashbackAmount(productCode, amountPaid)cashbackStatus = Store.CB_PENDINGif cashbackAmount <= 0:cashbackStatus = Store.CB_NAmerchantsubOrder.cashBackAmount = cashbackAmountmerchantsubOrder.cashBackStatus = cashbackStatusmerchantsubOrder.cashBackPercentage = cashbackPercentsubOrders.append(merchantsubOrder)#To track shipping detailsstatus=-1tr = orderTracking.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})if "approveDetails-complete" in str(tr):if "processingDetails-complete" in str(tr):if "shippingDetails-complete" in str(tr):if "delivery-complete" in str(tr):status = MStore.ORDER_DELIVEREDelse:status = MStore.ORDER_SHIPPEDorderTracking.find('div', {'class':'tracking-remark active'})else:status = MStore.ORDER_PLACEDelse:status = MStore.ORDER_PLACEDelif str(tr) in ["approveDetails-ongoing"]:status=MStore.ORDER_PLACEDif "dead" in str(tr) or "shippingDetails-returnOngoing" in str(tr) or "shippingDetails-return" in str(tr):status = MStore.ORDER_CANCELLEDprint "Sub Order Status " + str(status)trackingDetailsActive = orderTrackingDet.find("div",{"class":"c-tabs-content m-top active"})print "Sub order tracking description " + trackingDetailsActive.textif self._saveToOrder(todict(merchantOrder)):resp['result'] = 'ORDER_CREATED'else:resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'return respexcept:traceback.print_exc()resp['result'] = 'ORDER_NOT_CREATED'return respdef _getStatusFromDetailedStatus(self, detailedStatus):for key, value in Store.OrderStatusMap.iteritems():if detailedStatus.lower() in value:return keyprint "Detailed Status need to be mapped", detailedStatus, "Store:", self.store_nameraise ParseException("_getStatusFromDetailedStatus", "Found new order status" + detailedStatus)def flipkartOrderTracking(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):br = getBrowserObject()url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]response = br.open(url)page = ungzipResponse(response, br)soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)mainOrder = soup.findAll("ul",{"class":"m-bottom p-cart"})#fetching suborders detailsfor subOrder in mainOrder:subOrd = subOrder.findAll("li")subOrd.pop(len(subOrd)-1)for productInfo in subOrd:status=-1#To track shipping detailsn = productInfo.findAll("div",{"class":"tracking-progress grid-row cf"})for trackingStatus in n:tr = trackingStatus.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})if "approveDetails-complete" in str(tr):print "Here"if "processingDetails-complete" in str(tr):print "There"if "shippingDetails-complete" in str(tr):print "Share"if "delivery-complete" in str(tr):print "Last"status = 3else:status = 2else:status = 1else:status = 0if "dead" in str(tr):status = 4print statusdef _saveToOrderFlipkart(self, order):collection = self.db.merchantOrderorder = collection.insert(order)def hex_md5(password):m = hashlib.md5()print(m.digest())def main():store = getStore(2)store.scrapeAffiliate(200)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 objif __name__ == '__main__':main()