Subversion Repositories SmartDukaan

Rev

Rev 14412 | Rev 14461 | 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
14460 amit.gupta 144
        if datetime.now().hour == 6:
145
            offers = []
13721 amit.gupta 146
            br = getBrowserObject()
147
            br.open(AFFILIATE_URL)
148
            response = br.response()  # copy
149
            token =  re.findall('window.__FK = "(.*?)"', ungzipResponse(response), re.IGNORECASE)[0]
150
            data = {'__FK':token,
151
                    'email':'saholic1@gmail.com',
152
                    'password':'e8aacf6fc1e3998186a4a8e56e428f66'
153
            }
154
            br.open(AFFILIATE_LOGIN_URL, urllib.urlencode(data))
14460 amit.gupta 155
            for delta in range(1,45):
14412 amit.gupta 156
                yester5date = date.today() - timedelta(delta)
157
                syester5date = yester5date.strftime('%Y-%m-%d')
158
                for status in [AFF_STATUS_PENDING, AFF_STATUS_CANCELLED, AFF_STATUS_DISAPPROVED]:
14460 amit.gupta 159
                    try:
160
                        br.open(AFF_REPORT_URL % (status, syester5date, syester5date))
161
                    except:
162
                        tprint("Could not fetch data for Status %s and date %s"%(status, syester5date))
14412 amit.gupta 163
                    page = ungzipResponse(br.response())
164
                    soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
165
                    soup.table
166
                    try:
167
                        tableElement = soup.findAll('table', {'class':'report-table fixtable'})[1]
168
                    except:
169
                        continue
170
                    trElements = tableElement.findAll('tr')
171
                    trElements.pop(0)
172
                    for trElement in trElements:
173
                        tdElements = trElement.findAll('td')
174
                        productCode = re.findall(r'pid=(.*)$', tdElements[0].find('a')['href'])[0]
175
                        quantity =int(tdElements[3].text)
176
                        price = int(float(tdElements[2].text.strip().replace(",","")))
177
                        payOut = int(float(tdElements[6].text.strip().replace(",","")))
178
                        saleAmount = int(float(tdElements[4].text.strip().replace(",","")))
179
                        subTagId = tdElements[7].text.strip()
14460 amit.gupta 180
                        category = tdElements[1].text.strip()
181
                        affiliateInfo = FlipkartAffiliateInfo(subTagId, syester5date, productCode, price, quantity, saleAmount, payOut, status, category) 
14412 amit.gupta 182
                        #updateMap['subOrders.$.unitPrice'] = price
183
                        #updateMap['subOrders.$.cashBackAmount'], updateMap['subOrders.$.cashBacPercentage'] = self.getCashbackAmount(productCode, price)
14460 amit.gupta 184
                        offers.append(affiliateInfo)
14412 amit.gupta 185
            self._saveToAffiliate(offers)
13721 amit.gupta 186
 
14412 amit.gupta 187
    def _saveToAffiliate(self, offers):
188
        collection = self.db.flipkartOrderAffiliateInfo
14460 amit.gupta 189
        mcollection = self.db.merchantOrder
190
        for offer in offers:
191
            result1 = collection.update({"subTagId":offer.subTagId, "price":offer.price, "quantity":offer.quantity, "saleDate":offer.saleDate, "productCode":offer.productCode},{"$set":todict(offer)}, upsert=True)
192
            if result1.get("upserted") is not None:
193
                result2 = mcollection.update({"subTagId":offer.subTagId, "storeId":self.store_id, "subOrders.missingAff":True, "subOrders.productCode":offer.productCode}, {"$set":{"subOrders.$.missingAff":False}}, multi=True)
194
                if result2.get("updatedExisting") is True:
195
                    mcollection.update({"_id":result1.get("upserted")}, {"missingOrders":False})
196
 
14412 amit.gupta 197
 
198
 
13658 manas 199
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
13796 amit.gupta 200
        resp= {}
13781 amit.gupta 201
        try:
202
            br = getBrowserObject()
203
            url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]
204
 
205
            response = br.open(url)
206
            page = ungzipResponse(response)
207
 
208
            merchantOrderId = re.findall('reference_id=(.*?)&', orderSuccessUrl,re.IGNORECASE)[0]
209
            print merchantOrderId
210
 
211
            soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
212
 
213
            sections = soup.findAll("div", {"class":"ui-app-card-body"})
214
            sections.pop(1)
215
 
216
            merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
14145 amit.gupta 217
            merchantOrder.orderTrackingUrl = url
13781 amit.gupta 218
            for data in sections:
219
                name = data.findAll("span")
220
                i=0
221
                while i< len(name):
222
                    if "key" in str(name[i]):
223
                        if "Grand Total" in str(name[i]):
224
                            #Total Amount
225
                            merchantOrder.paidAmount = int(re.findall(r'\d+', name[i+1].text)[0])
226
                        elif "Order Date" in str(name[i]):
227
                            merchantOrder.placedOn = name[i+1].text 
228
                    i=i+1    
229
 
230
            merchantOrder.merchantOrderId = merchantOrderId
231
 
232
            mainOrder = soup.find("ul",{"class":"m-bottom p-cart"})
233
            fkSubOrders = mainOrder.findAll("li")
234
            #remove unwanted list
235
            fkSubOrders.pop(-1)
236
            subOrders = []
237
            merchantOrder.subOrders = subOrders
238
 
239
            #fetching suborders details
240
            for subOrder in fkSubOrders:
241
                y = subOrder.find("header").findAll("span")
242
                for suborderId in y:
243
                    if "value emp" in str(suborderId):
244
                        merchantSubOrderId = suborderId.text
245
                        break
246
                orderItems = subOrder.find("ul").findAll("div", recursive=False)
247
                i=0
248
                for orderItem in orderItems:
249
                    merchantOrder.placedOn
250
                    merchantSubOrderId = merchantSubOrderId + str(i)
251
                    divs = orderItem.findAll('div', recursive=False)
252
                    content = divs[0]
253
                    orderTracking = divs[2]
254
                    orderTrackingDet = divs[3]
255
 
256
 
257
                    imgUrl = content.find('img')['src']
258
                    lineDet = content.find("div",{"class":"product-info"})
259
                    productTitle = lineDet.find("a",{"class":"product-title"}).text
260
                    productUrl =  str(lineDet.find("a")['href'])
261
 
262
                    start='pid='
263
                    s=str(lineDet.find("a")['href'])
14339 amit.gupta 264
                    productCode = re.findall(re.escape(start)+"(.*)",s)[0].strip()
13781 amit.gupta 265
                    mname = lineDet.findAll("span")
266
                    k=0
267
                    while k<len(mname):
268
                        if "note" in str(mname[k]):
269
                            if "Color:" in str(mname[k]):
270
                                productTitle = productTitle + " " + mname[k+1].text
271
 
272
                            elif "Qty:" in str(mname[k]):
273
                                quantity = int(mname[k+1].text)
274
                            elif "Subtotal:" in str(mname[k]):
14343 amit.gupta 275
                                amountPaid = int(re.findall(r'\d+', mname[k+1].text)[0])
13781 amit.gupta 276
                            elif "Delivery:" in str(mname[k]):
277
                                #Delivery Date for sub order
278
                                print "Delivery Date " +mname[k+1].text
279
                        k=k+1
14343 amit.gupta 280
                    merchantsubOrder = SubOrder(productTitle, productUrl, merchantOrder.placedOn, amountPaid,MStore.ORDER_PLACED, quantity)
13781 amit.gupta 281
                    merchantsubOrder.imgUrl  = imgUrl
282
                    merchantsubOrder.productCode = productCode
283
                    merchantsubOrder.merchantSubOrderId = merchantSubOrderId
14337 amit.gupta 284
                    print "productCode", productCode
14340 amit.gupta 285
                    print "amountPaid", amountPaid
14336 amit.gupta 286
                    cashbackAmount, cashbackPercent = self.getCashbackAmount(productCode, amountPaid)
13781 amit.gupta 287
                    cashbackStatus = Store.CB_PENDING
288
                    if cashbackAmount <= 0:
289
                        cashbackStatus = Store.CB_NA
290
                    merchantsubOrder.cashBackAmount = cashbackAmount
291
                    merchantsubOrder.cashBackStatus = cashbackStatus      
292
                    merchantsubOrder.cashBackPercentage = cashbackPercent      
293
 
294
                    subOrders.append(merchantsubOrder)
295
                    #To track shipping details         
296
                    status=-1    
297
                    tr = orderTracking.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})
298
                    if "approveDetails-complete" in str(tr):
299
                        if "processingDetails-complete" in str(tr):
300
                            if "shippingDetails-complete" in str(tr):
301
                                if "delivery-complete" in str(tr):
302
                                    status = MStore.ORDER_DELIVERED
303
                                else:     
304
                                    status = MStore.ORDER_SHIPPED
305
                                    orderTracking.find('div', {'class':'tracking-remark active'})
306
                            else:
307
                                status = MStore.ORDER_PLACED
308
                        else: 
13690 amit.gupta 309
                            status = MStore.ORDER_PLACED
13781 amit.gupta 310
                    elif str(tr) in ["approveDetails-ongoing"]:
311
                        status=MStore.ORDER_PLACED             
14351 amit.gupta 312
                    if "dead" in str(tr) or "shippingDetails-returnOngoing" in str(tr):
13781 amit.gupta 313
                        status = MStore.ORDER_CANCELLED    
314
                    print "Sub Order Status " + str(status)                      
315
 
316
                    trackingDetailsActive = orderTrackingDet.find("div",{"class":"c-tabs-content m-top active"})
317
                    print "Sub order tracking description " + trackingDetailsActive.text
14312 amit.gupta 318
            if self._saveToOrder(todict(merchantOrder)):
319
                resp['result'] = 'ORDER_CREATED'
320
            else:
321
                resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
322
 
13796 amit.gupta 323
            return resp 
13781 amit.gupta 324
        except:
14338 amit.gupta 325
            traceback.print_exc()
14312 amit.gupta 326
            resp['result'] = 'ORDER_NOT_CREATED'
13796 amit.gupta 327
            return resp 
13781 amit.gupta 328
 
13658 manas 329
 
330
    def flipkartOrderTracking(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
331
        br = getBrowserObject()
332
        url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]
333
 
334
        response = br.open(url)
335
        page = ungzipResponse(response, br)
336
 
337
 
338
        soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
339
 
340
 
341
        mainOrder = soup.findAll("ul",{"class":"m-bottom p-cart"})
342
        #fetching suborders details
343
        for subOrder in mainOrder:
344
            subOrd = subOrder.findAll("li")
345
 
346
            subOrd.pop(len(subOrd)-1)
347
            for productInfo in subOrd:
348
                status=-1    
349
                #To track shipping details         
350
                n = productInfo.findAll("div",{"class":"tracking-progress grid-row cf"})
351
                for trackingStatus in n:
352
                    tr = trackingStatus.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})
353
                    if "approveDetails-complete" in str(tr):
13679 manas 354
                        print "Here"
13658 manas 355
                        if "processingDetails-complete" in str(tr):
13679 manas 356
                            print "There"
13658 manas 357
                            if "shippingDetails-complete" in str(tr):
13679 manas 358
                                print "Share"
13658 manas 359
                                if "delivery-complete" in str(tr):
13679 manas 360
                                    print "Last"
13658 manas 361
                                    status = 3
362
                                else:     
363
                                    status = 2
364
                            else:
365
                                status = 1 
366
                        else: 
367
                            status = 0     
368
                    if "dead" in str(tr):
369
                        status = 4    
370
                print status                      
371
 
372
 
373
def _saveToOrderFlipkart(self, order):
374
        collection = self.db.merchantOrder
375
        order = collection.insert(order)
376
 
13690 amit.gupta 377
 
378
 
379
def hex_md5(password):
380
    m = hashlib.md5()
381
    print(m.digest())
382
 
13658 manas 383
def main():
384
 
385
    store = getStore(2)
14412 amit.gupta 386
    store.scrapeAffiliate()
387
    #store.scrapeStoreOrders(123469, "SHA21423034609", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0022423903274462&token=8c09a43ad48d1cd4f73be1f0c3c00d39&src=or&pr=1')
13658 manas 388
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD3016502908102575&token=0db4c692bacbfbfc158b52358ac9e91e&src=or&pr=1')
389
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD3018701137253850&token=f7402ddcf2b63b37cc6bc528cc115d2f&src=or&pr=1')
13679 manas 390
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019279584515727&token=7d85d8c24d36b5a1efc8008634390c7e&src=or&pr=1')
13658 manas 391
    #store.flipkartOrderTracking(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019279584515727&token=7d85d8c24d36b5a1efc8008634390c7e&src=or&pr=1')
13679 manas 392
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019365336126533&token=dbce2bd4dc4023295b436a7d3c7986c9&src=or&pr=1')
393
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://dl.flipkart.com/orderresponse?reference_id=OD1019453634552336&token=e8e04871ad65b532aa53fa82bb34b901&src=or&pr=1')
13690 amit.gupta 394
    #hex_md5('spice@2020')
14351 amit.gupta 395
    #store.getCashbackAmount('MOBDVHC6XKKPZ3GZ', 5999)
13679 manas 396
 
13690 amit.gupta 397
 
13658 manas 398
if __name__ == '__main__':
399
        main()
400
 
13690 amit.gupta 401
 
402
 
403
 
13658 manas 404
def todict(obj, classkey=None):
405
    if isinstance(obj, dict):
406
        data = {}
407
        for (k, v) in obj.items():
408
            data[k] = todict(v, classkey)
409
        return data
410
    elif hasattr(obj, "_ast"):
411
        return todict(obj._ast())
412
    elif hasattr(obj, "__iter__"):
413
        return [todict(v, classkey) for v in obj]
414
    elif hasattr(obj, "__dict__"):
415
        data = dict([(key, todict(value, classkey)) 
416
            for key, value in obj.__dict__.iteritems() 
417
            if not callable(value) and not key.startswith('_')])
418
        if classkey is not None and hasattr(obj, "__class__"):
419
            data[classkey] = obj.__class__.__name__
420
        return data
421
    else:
13690 amit.gupta 422
        return obj
423
 
14145 amit.gupta 424