Subversion Repositories SmartDukaan

Rev

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