Subversion Repositories SmartDukaan

Rev

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