Subversion Repositories SmartDukaan

Rev

Rev 14460 | Rev 14474 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
13569 amit.gupta 1
'''
2
Created on Jan 15, 2015
3
 
4
@author: amit
5
'''
13690 amit.gupta 6
from BeautifulSoup import BeautifulSoup
13721 amit.gupta 7
from datetime import datetime, date, timedelta
13569 amit.gupta 8
from dtr import main
14412 amit.gupta 9
from dtr.dao import AffiliateInfo, Order, SubOrder, FlipkartAffiliateInfo
13690 amit.gupta 10
from dtr.main import getBrowserObject, getStore, ParseException, ungzipResponse, \
14398 amit.gupta 11
    Store as MStore, sourceMap, tprint
13690 amit.gupta 12
from pprint import pprint
13
from pymongo.mongo_client import MongoClient
14
import hashlib
13658 manas 15
import importlib
13690 amit.gupta 16
import json
17
import mechanize
14412 amit.gupta 18
import pymongo
13658 manas 19
import re
14338 amit.gupta 20
import traceback
13658 manas 21
import urllib
22
 
23
USERNAME='saholic1@gmail.com'
24
PASSWORD='spice@2020'
25
ORDER_TRACK_URL='https://m.flipkart.com/order_details'
13679 manas 26
AFFILIATE_URL='https://www.flipkart.com/affiliate/login'
13690 amit.gupta 27
AFFILIATE_LOGIN_URL='https://www.flipkart.com/affiliate/a_login'
28
AFF_REPORT_URL='http://www.flipkart.com/affiliate/reports/ordersReport?order_status_filter=%s&startdate=%s&enddate=%s'
29
AFF_STATUS_CANCELLED='cancelled'
30
AFF_STATUS_APPROVED='approved'
31
AFF_STATUS_DISAPPROVED='disapproved'
32
AFF_STATUS_PENDING='pending'
13658 manas 33
 
13679 manas 34
 
13781 amit.gupta 35
class Store(MStore):
13658 manas 36
    OrderStatusMap = {
13690 amit.gupta 37
                      main.Store.ORDER_PLACED : ['Approval', 'Processing'],
38
                      main.Store.ORDER_DELIVERED : ['Shipping'],
13658 manas 39
                      main.Store.ORDER_SHIPPED : ['In Transit'],
13690 amit.gupta 40
                      main.Store.ORDER_CANCELLED : ['']
13658 manas 41
 
42
                      }
43
    def __init__(self,store_id):
44
        client = MongoClient('mongodb://localhost:27017/')
45
        self.db = client.dtr
46
        super(Store, self).__init__(store_id)
47
 
13569 amit.gupta 48
    def getName(self):
49
        return "flipkart"
50
 
13690 amit.gupta 51
    def scrapeStoreOrders(self,):
52
        orders = self._getActiveOrders()
13679 manas 53
        br = getBrowserObject()
13721 amit.gupta 54
        for order in orders:
14398 amit.gupta 55
            print order
56
            try:
57
                closed = True
58
                url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', order['orderSuccessUrl'],re.IGNORECASE)[0]
59
                response = br.open(url)
60
                page = ungzipResponse(response)
13721 amit.gupta 61
 
14398 amit.gupta 62
                soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
63
 
64
                sections = soup.findAll("div", {"class":"ui-app-card-body"})
65
                sections.pop(1)
13721 amit.gupta 66
 
14398 amit.gupta 67
                mainOrder = soup.find("ul",{"class":"m-bottom p-cart"})
68
                fkSubOrders = mainOrder.findAll("li")
69
 
70
                #remove unwanted list
71
                fkSubOrders.pop(-1)
72
 
73
 
74
                bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
75
                #fetching suborders details
76
                for subOrder in fkSubOrders:
77
                    updateMap = {}
78
                    y = subOrder.find("header").findAll("span")
79
                    for suborderId in y:
80
                        if "value emp" in str(suborderId):
81
                            merchantSubOrderId = suborderId.text
82
                            break
83
                    orderItems = subOrder.find("ul").findAll("div", recursive=False)
84
                    i=0
85
                    for orderItem in orderItems:
86
                        closedStatus = False
87
                        merchantSubOrderId = merchantSubOrderId + str(i)
88
                        subOrder =  self._isSubOrderActive(order, merchantSubOrderId)
89
                        if subOrder is None:
90
                            break
14460 amit.gupta 91
                        elif subOrder['closed']:
92
                            break
14398 amit.gupta 93
                        findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": merchantSubOrderId}
94
                        divs = orderItem.findAll('div', recursive=False)
95
                        orderTracking = divs[2]
96
                        orderTrackingDetDiv = divs[3].find('div',{'class':'c-tabs-content m-top active'})
97
                        orderTrackingDet = orderTrackingDetDiv.find('div',{'class':re.compile('tracking-remark')}).text
98
                        updateMap["subOrders.$.detailedStatus"] = orderTrackingDet
99
                        tr = orderTracking.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})
100
 
101
                        cashbackStatus = subOrder.get("cashBackStatus") 
102
                        if "approveDetails-complete" in str(tr):
103
                            if "processingDetails-complete" in str(tr):
104
                                if "shippingDetails-complete" in str(tr):
105
                                    if "delivery-complete" in str(tr):
106
                                        status = MStore.ORDER_DELIVERED
107
                                        if cashbackStatus == Store.CB_PENDING:
108
                                            cashbackStatus = Store.CB_APPROVED
109
                                        closedStatus = True
110
                                    else:     
111
                                        status = MStore.ORDER_SHIPPED
112
                                        courierTrackAnchor = orderTrackingDetDiv.find('a')
113
                                        trackingUrl = courierTrackAnchor("href")
114
                                        trackingText = courierTrackAnchor.text
115
                                        courierArr = trackingText.split(' : ')
116
                                        updateMap["subOrders.$.trackingUrl"] = trackingUrl
117
                                        updateMap["subOrders.$.trackingNumber"] = courierArr[1]
118
                                        updateMap["subOrders.$.courierName"] = courierArr[0]
119
                                else:
120
                                    status = MStore.ORDER_PLACED
121
                            else: 
13721 amit.gupta 122
                                status = MStore.ORDER_PLACED
14398 amit.gupta 123
                        elif str(tr) in ["approveDetails-ongoing"]:
124
                            status=MStore.ORDER_PLACED             
125
                        if "dead" in str(tr):
126
                            status = MStore.ORDER_CANCELLED
127
                            closedStatus = True
128
                            if cashbackStatus == Store.CB_PENDING:
129
                                cashbackStatus = Store.CB_CANCELLED
130
 
131
                        updateMap["subOrders.$.cashBackStatus"] = cashbackStatus
132
                        updateMap["subOrders.$.status"] = status
133
                        updateMap["subOrders.$.closed"] = closedStatus
134
                        if closed:
135
                            closed = closedStatus
136
                        bulk.find(findMap).update({'$set' : updateMap})
137
                bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed}})
138
                bulk.execute()            
139
            except:
140
                tprint("Could not update " + str(order['orderId']))
141
                traceback.print_exc()
13721 amit.gupta 142
    def scrapeAffiliate(self, startDate=None, endDate=None):
143
        #get all yesterday's affiliate in pending or cancelled state and update to system
14461 amit.gupta 144
        offers = []
145
        br = getBrowserObject()
146
        br.open(AFFILIATE_URL)
147
        response = br.response()  # copy
148
        token =  re.findall('window.__FK = "(.*?)"', ungzipResponse(response), re.IGNORECASE)[0]
149
        data = {'__FK':token,
150
                'email':'saholic1@gmail.com',
151
                'password':'e8aacf6fc1e3998186a4a8e56e428f66'
152
        }
153
        br.open(AFFILIATE_LOGIN_URL, urllib.urlencode(data))
154
        for delta in range(1,45):
155
            yester5date = date.today() - timedelta(delta)
156
            syester5date = yester5date.strftime('%Y-%m-%d')
157
            for status in [AFF_STATUS_PENDING, AFF_STATUS_CANCELLED, AFF_STATUS_DISAPPROVED]:
158
                try:
159
                    br.open(AFF_REPORT_URL % (status, syester5date, syester5date))
160
                except:
161
                    tprint("Could not fetch data for Status %s and date %s"%(status, syester5date))
162
                page = ungzipResponse(br.response())
163
                soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
164
                soup.table
165
                try:
166
                    tableElement = soup.findAll('table', {'class':'report-table fixtable'})[1]
167
                except:
168
                    continue
169
                trElements = tableElement.findAll('tr')
170
                trElements.pop(0)
171
                for trElement in trElements:
172
                    tdElements = trElement.findAll('td')
173
                    productCode = re.findall(r'pid=(.*)$', tdElements[0].find('a')['href'])[0]
174
                    quantity =int(tdElements[3].text)
175
                    price = int(float(tdElements[2].text.strip().replace(",","")))
176
                    payOut = int(float(tdElements[6].text.strip().replace(",","")))
177
                    saleAmount = int(float(tdElements[4].text.strip().replace(",","")))
178
                    subTagId = tdElements[7].text.strip()
179
                    category = tdElements[1].text.strip()
180
                    affiliateInfo = FlipkartAffiliateInfo(subTagId, syester5date, productCode, price, quantity, saleAmount, payOut, status, category) 
181
                    #updateMap['subOrders.$.unitPrice'] = price
182
                    #updateMap['subOrders.$.cashBackAmount'], updateMap['subOrders.$.cashBacPercentage'] = self.getCashbackAmount(productCode, price)
183
                    offers.append(affiliateInfo)
184
        self._saveToAffiliate(offers)
13721 amit.gupta 185
 
14412 amit.gupta 186
    def _saveToAffiliate(self, offers):
187
        collection = self.db.flipkartOrderAffiliateInfo
14460 amit.gupta 188
        mcollection = self.db.merchantOrder
189
        for offer in offers:
190
            result1 = collection.update({"subTagId":offer.subTagId, "price":offer.price, "quantity":offer.quantity, "saleDate":offer.saleDate, "productCode":offer.productCode},{"$set":todict(offer)}, upsert=True)
191
            if result1.get("upserted") is not None:
192
                result2 = mcollection.update({"subTagId":offer.subTagId, "storeId":self.store_id, "subOrders.missingAff":True, "subOrders.productCode":offer.productCode}, {"$set":{"subOrders.$.missingAff":False}}, multi=True)
193
                if result2.get("updatedExisting") is True:
194
                    mcollection.update({"_id":result1.get("upserted")}, {"missingOrders":False})
195
 
14412 amit.gupta 196
 
197
 
13658 manas 198
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
13796 amit.gupta 199
        resp= {}
13781 amit.gupta 200
        try:
201
            br = getBrowserObject()
202
            url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]
203
 
204
            response = br.open(url)
205
            page = ungzipResponse(response)
206
 
207
            merchantOrderId = re.findall('reference_id=(.*?)&', orderSuccessUrl,re.IGNORECASE)[0]
208
            print merchantOrderId
209
 
210
            soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
211
 
212
            sections = soup.findAll("div", {"class":"ui-app-card-body"})
213
            sections.pop(1)
214
 
215
            merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
14145 amit.gupta 216
            merchantOrder.orderTrackingUrl = url
13781 amit.gupta 217
            for data in sections:
218
                name = data.findAll("span")
219
                i=0
220
                while i< len(name):
221
                    if "key" in str(name[i]):
222
                        if "Grand Total" in str(name[i]):
223
                            #Total Amount
224
                            merchantOrder.paidAmount = int(re.findall(r'\d+', name[i+1].text)[0])
225
                        elif "Order Date" in str(name[i]):
226
                            merchantOrder.placedOn = name[i+1].text 
227
                    i=i+1    
228
 
229
            merchantOrder.merchantOrderId = merchantOrderId
230
 
231
            mainOrder = soup.find("ul",{"class":"m-bottom p-cart"})
232
            fkSubOrders = mainOrder.findAll("li")
233
            #remove unwanted list
234
            fkSubOrders.pop(-1)
235
            subOrders = []
236
            merchantOrder.subOrders = subOrders
237
 
238
            #fetching suborders details
239
            for subOrder in fkSubOrders:
240
                y = subOrder.find("header").findAll("span")
241
                for suborderId in y:
242
                    if "value emp" in str(suborderId):
243
                        merchantSubOrderId = suborderId.text
244
                        break
245
                orderItems = subOrder.find("ul").findAll("div", recursive=False)
246
                i=0
247
                for orderItem in orderItems:
248
                    merchantOrder.placedOn
249
                    merchantSubOrderId = merchantSubOrderId + str(i)
250
                    divs = orderItem.findAll('div', recursive=False)
251
                    content = divs[0]
252
                    orderTracking = divs[2]
253
                    orderTrackingDet = divs[3]
254
 
255
 
256
                    imgUrl = content.find('img')['src']
257
                    lineDet = content.find("div",{"class":"product-info"})
258
                    productTitle = lineDet.find("a",{"class":"product-title"}).text
259
                    productUrl =  str(lineDet.find("a")['href'])
260
 
261
                    start='pid='
262
                    s=str(lineDet.find("a")['href'])
14339 amit.gupta 263
                    productCode = re.findall(re.escape(start)+"(.*)",s)[0].strip()
13781 amit.gupta 264
                    mname = lineDet.findAll("span")
265
                    k=0
266
                    while k<len(mname):
267
                        if "note" in str(mname[k]):
268
                            if "Color:" in str(mname[k]):
269
                                productTitle = productTitle + " " + mname[k+1].text
270
 
271
                            elif "Qty:" in str(mname[k]):
272
                                quantity = int(mname[k+1].text)
273
                            elif "Subtotal:" in str(mname[k]):
14343 amit.gupta 274
                                amountPaid = int(re.findall(r'\d+', mname[k+1].text)[0])
13781 amit.gupta 275
                            elif "Delivery:" in str(mname[k]):
276
                                #Delivery Date for sub order
277
                                print "Delivery Date " +mname[k+1].text
278
                        k=k+1
14343 amit.gupta 279
                    merchantsubOrder = SubOrder(productTitle, productUrl, merchantOrder.placedOn, amountPaid,MStore.ORDER_PLACED, quantity)
13781 amit.gupta 280
                    merchantsubOrder.imgUrl  = imgUrl
281
                    merchantsubOrder.productCode = productCode
282
                    merchantsubOrder.merchantSubOrderId = merchantSubOrderId
14337 amit.gupta 283
                    print "productCode", productCode
14340 amit.gupta 284
                    print "amountPaid", amountPaid
14336 amit.gupta 285
                    cashbackAmount, cashbackPercent = self.getCashbackAmount(productCode, amountPaid)
13781 amit.gupta 286
                    cashbackStatus = Store.CB_PENDING
287
                    if cashbackAmount <= 0:
288
                        cashbackStatus = Store.CB_NA
289
                    merchantsubOrder.cashBackAmount = cashbackAmount
290
                    merchantsubOrder.cashBackStatus = cashbackStatus      
291
                    merchantsubOrder.cashBackPercentage = cashbackPercent      
292
 
293
                    subOrders.append(merchantsubOrder)
294
                    #To track shipping details         
295
                    status=-1    
296
                    tr = orderTracking.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})
297
                    if "approveDetails-complete" in str(tr):
298
                        if "processingDetails-complete" in str(tr):
299
                            if "shippingDetails-complete" in str(tr):
300
                                if "delivery-complete" in str(tr):
301
                                    status = MStore.ORDER_DELIVERED
302
                                else:     
303
                                    status = MStore.ORDER_SHIPPED
304
                                    orderTracking.find('div', {'class':'tracking-remark active'})
305
                            else:
306
                                status = MStore.ORDER_PLACED
307
                        else: 
13690 amit.gupta 308
                            status = MStore.ORDER_PLACED
13781 amit.gupta 309
                    elif str(tr) in ["approveDetails-ongoing"]:
310
                        status=MStore.ORDER_PLACED             
14351 amit.gupta 311
                    if "dead" in str(tr) or "shippingDetails-returnOngoing" in str(tr):
13781 amit.gupta 312
                        status = MStore.ORDER_CANCELLED    
313
                    print "Sub Order Status " + str(status)                      
314
 
315
                    trackingDetailsActive = orderTrackingDet.find("div",{"class":"c-tabs-content m-top active"})
316
                    print "Sub order tracking description " + trackingDetailsActive.text
14312 amit.gupta 317
            if self._saveToOrder(todict(merchantOrder)):
318
                resp['result'] = 'ORDER_CREATED'
319
            else:
320
                resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
321
 
13796 amit.gupta 322
            return resp 
13781 amit.gupta 323
        except:
14338 amit.gupta 324
            traceback.print_exc()
14312 amit.gupta 325
            resp['result'] = 'ORDER_NOT_CREATED'
13796 amit.gupta 326
            return resp 
13781 amit.gupta 327
 
13658 manas 328
 
329
    def flipkartOrderTracking(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
330
        br = getBrowserObject()
331
        url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]
332
 
333
        response = br.open(url)
334
        page = ungzipResponse(response, br)
335
 
336
 
337
        soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
338
 
339
 
340
        mainOrder = soup.findAll("ul",{"class":"m-bottom p-cart"})
341
        #fetching suborders details
342
        for subOrder in mainOrder:
343
            subOrd = subOrder.findAll("li")
344
 
345
            subOrd.pop(len(subOrd)-1)
346
            for productInfo in subOrd:
347
                status=-1    
348
                #To track shipping details         
349
                n = productInfo.findAll("div",{"class":"tracking-progress grid-row cf"})
350
                for trackingStatus in n:
351
                    tr = trackingStatus.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})
352
                    if "approveDetails-complete" in str(tr):
13679 manas 353
                        print "Here"
13658 manas 354
                        if "processingDetails-complete" in str(tr):
13679 manas 355
                            print "There"
13658 manas 356
                            if "shippingDetails-complete" in str(tr):
13679 manas 357
                                print "Share"
13658 manas 358
                                if "delivery-complete" in str(tr):
13679 manas 359
                                    print "Last"
13658 manas 360
                                    status = 3
361
                                else:     
362
                                    status = 2
363
                            else:
364
                                status = 1 
365
                        else: 
366
                            status = 0     
367
                    if "dead" in str(tr):
368
                        status = 4    
369
                print status                      
370
 
371
 
372
def _saveToOrderFlipkart(self, order):
373
        collection = self.db.merchantOrder
374
        order = collection.insert(order)
375
 
13690 amit.gupta 376
 
377
 
378
def hex_md5(password):
379
    m = hashlib.md5()
380
    print(m.digest())
381
 
13658 manas 382
def main():
383
 
384
    store = getStore(2)
14412 amit.gupta 385
    store.scrapeAffiliate()
386
    #store.scrapeStoreOrders(123469, "SHA21423034609", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0022423903274462&token=8c09a43ad48d1cd4f73be1f0c3c00d39&src=or&pr=1')
13658 manas 387
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD3016502908102575&token=0db4c692bacbfbfc158b52358ac9e91e&src=or&pr=1')
388
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD3018701137253850&token=f7402ddcf2b63b37cc6bc528cc115d2f&src=or&pr=1')
13679 manas 389
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019279584515727&token=7d85d8c24d36b5a1efc8008634390c7e&src=or&pr=1')
13658 manas 390
    #store.flipkartOrderTracking(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019279584515727&token=7d85d8c24d36b5a1efc8008634390c7e&src=or&pr=1')
13679 manas 391
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019365336126533&token=dbce2bd4dc4023295b436a7d3c7986c9&src=or&pr=1')
392
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://dl.flipkart.com/orderresponse?reference_id=OD1019453634552336&token=e8e04871ad65b532aa53fa82bb34b901&src=or&pr=1')
13690 amit.gupta 393
    #hex_md5('spice@2020')
14351 amit.gupta 394
    #store.getCashbackAmount('MOBDVHC6XKKPZ3GZ', 5999)
13679 manas 395
 
13690 amit.gupta 396
 
13658 manas 397
if __name__ == '__main__':
398
        main()
399
 
13690 amit.gupta 400
 
401
 
402
 
13658 manas 403
def todict(obj, classkey=None):
404
    if isinstance(obj, dict):
405
        data = {}
406
        for (k, v) in obj.items():
407
            data[k] = todict(v, classkey)
408
        return data
409
    elif hasattr(obj, "_ast"):
410
        return todict(obj._ast())
411
    elif hasattr(obj, "__iter__"):
412
        return [todict(v, classkey) for v in obj]
413
    elif hasattr(obj, "__dict__"):
414
        data = dict([(key, todict(value, classkey)) 
415
            for key, value in obj.__dict__.iteritems() 
416
            if not callable(value) and not key.startswith('_')])
417
        if classkey is not None and hasattr(obj, "__class__"):
418
            data[classkey] = obj.__class__.__name__
419
        return data
420
    else:
13690 amit.gupta 421
        return obj
422
 
14145 amit.gupta 423