Subversion Repositories SmartDukaan

Rev

Rev 14290 | Rev 14336 | 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'})
14290 amit.gupta 93
                    orderTrackingDet = orderTrackingDetDiv.find('div',{'class':re.compile('tracking-remark')}).text
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)
14145 amit.gupta 193
            merchantOrder.orderTrackingUrl = url
13781 amit.gupta 194
            for data in sections:
195
                name = data.findAll("span")
196
                i=0
197
                while i< len(name):
198
                    if "key" in str(name[i]):
199
                        if "Grand Total" in str(name[i]):
200
                            #Total Amount
201
                            merchantOrder.paidAmount = int(re.findall(r'\d+', name[i+1].text)[0])
202
                        elif "Order Date" in str(name[i]):
203
                            merchantOrder.placedOn = name[i+1].text 
204
                    i=i+1    
205
 
206
            merchantOrder.merchantOrderId = merchantOrderId
207
 
208
            mainOrder = soup.find("ul",{"class":"m-bottom p-cart"})
209
            fkSubOrders = mainOrder.findAll("li")
210
            #remove unwanted list
211
            fkSubOrders.pop(-1)
212
            subOrders = []
213
            merchantOrder.subOrders = subOrders
214
 
215
            #fetching suborders details
216
            for subOrder in fkSubOrders:
217
                y = subOrder.find("header").findAll("span")
218
                for suborderId in y:
219
                    if "value emp" in str(suborderId):
220
                        merchantSubOrderId = suborderId.text
221
                        break
222
                orderItems = subOrder.find("ul").findAll("div", recursive=False)
223
                i=0
224
                for orderItem in orderItems:
225
                    merchantOrder.placedOn
226
                    merchantSubOrderId = merchantSubOrderId + str(i)
227
                    divs = orderItem.findAll('div', recursive=False)
228
                    content = divs[0]
229
                    orderTracking = divs[2]
230
                    orderTrackingDet = divs[3]
231
 
232
 
233
                    imgUrl = content.find('img')['src']
234
                    lineDet = content.find("div",{"class":"product-info"})
235
                    productTitle = lineDet.find("a",{"class":"product-title"}).text
236
                    productUrl =  str(lineDet.find("a")['href'])
237
 
238
                    start='pid='
239
                    s=str(lineDet.find("a")['href'])
240
                    productCode = re.findall(re.escape(start)+"(.*)",s)[0]
241
                    mname = lineDet.findAll("span")
242
                    k=0
243
                    while k<len(mname):
244
                        if "note" in str(mname[k]):
245
                            if "Color:" in str(mname[k]):
246
                                productTitle = productTitle + " " + mname[k+1].text
247
 
248
                            elif "Qty:" in str(mname[k]):
249
                                quantity = int(mname[k+1].text)
250
                            elif "Subtotal:" in str(mname[k]):
251
                                amountPaid = re.findall(r'\d+', mname[k+1].text)[0]
252
                            elif "Delivery:" in str(mname[k]):
253
                                #Delivery Date for sub order
254
                                print "Delivery Date " +mname[k+1].text
255
                        k=k+1
256
                    merchantsubOrder = SubOrder(productTitle, productUrl, merchantOrder.placedOn, amountPaid,MStore.ORDER_PLACED, quantity)
257
                    merchantsubOrder.imgUrl  = imgUrl
258
                    merchantsubOrder.productCode = productCode
259
                    merchantsubOrder.merchantSubOrderId = merchantSubOrderId
260
                    cashbackAmount, cashbackPercent = self.getCashbackAmount(subOrder.productCode, amountPaid)
261
                    cashbackStatus = Store.CB_PENDING
262
                    if cashbackAmount <= 0:
263
                        cashbackStatus = Store.CB_NA
264
                    merchantsubOrder.cashBackAmount = cashbackAmount
265
                    merchantsubOrder.cashBackStatus = cashbackStatus      
266
                    merchantsubOrder.cashBackPercentage = cashbackPercent      
267
 
268
                    subOrders.append(merchantsubOrder)
269
                    #To track shipping details         
270
                    status=-1    
271
                    tr = orderTracking.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})
272
                    if "approveDetails-complete" in str(tr):
273
                        if "processingDetails-complete" in str(tr):
274
                            if "shippingDetails-complete" in str(tr):
275
                                if "delivery-complete" in str(tr):
276
                                    status = MStore.ORDER_DELIVERED
277
                                else:     
278
                                    status = MStore.ORDER_SHIPPED
279
                                    orderTracking.find('div', {'class':'tracking-remark active'})
280
                            else:
281
                                status = MStore.ORDER_PLACED
282
                        else: 
13690 amit.gupta 283
                            status = MStore.ORDER_PLACED
13781 amit.gupta 284
                    elif str(tr) in ["approveDetails-ongoing"]:
285
                        status=MStore.ORDER_PLACED             
286
                    if "dead" in str(tr):
287
                        status = MStore.ORDER_CANCELLED    
288
                    print "Sub Order Status " + str(status)                      
289
 
290
                    trackingDetailsActive = orderTrackingDet.find("div",{"class":"c-tabs-content m-top active"})
291
                    print "Sub order tracking description " + trackingDetailsActive.text
14312 amit.gupta 292
            if self._saveToOrder(todict(merchantOrder)):
293
                resp['result'] = 'ORDER_CREATED'
294
            else:
295
                resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
296
 
13796 amit.gupta 297
            return resp 
13781 amit.gupta 298
        except:
14312 amit.gupta 299
            resp['result'] = 'ORDER_NOT_CREATED'
13796 amit.gupta 300
            return resp 
13781 amit.gupta 301
 
13658 manas 302
 
303
    def flipkartOrderTracking(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
304
        br = getBrowserObject()
305
        url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]
306
 
307
        response = br.open(url)
308
        page = ungzipResponse(response, br)
309
 
310
 
311
        soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
312
 
313
 
314
        mainOrder = soup.findAll("ul",{"class":"m-bottom p-cart"})
315
        #fetching suborders details
316
        for subOrder in mainOrder:
317
            subOrd = subOrder.findAll("li")
318
 
319
            subOrd.pop(len(subOrd)-1)
320
            for productInfo in subOrd:
321
                status=-1    
322
                #To track shipping details         
323
                n = productInfo.findAll("div",{"class":"tracking-progress grid-row cf"})
324
                for trackingStatus in n:
325
                    tr = trackingStatus.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})
326
                    if "approveDetails-complete" in str(tr):
13679 manas 327
                        print "Here"
13658 manas 328
                        if "processingDetails-complete" in str(tr):
13679 manas 329
                            print "There"
13658 manas 330
                            if "shippingDetails-complete" in str(tr):
13679 manas 331
                                print "Share"
13658 manas 332
                                if "delivery-complete" in str(tr):
13679 manas 333
                                    print "Last"
13658 manas 334
                                    status = 3
335
                                else:     
336
                                    status = 2
337
                            else:
338
                                status = 1 
339
                        else: 
340
                            status = 0     
341
                    if "dead" in str(tr):
342
                        status = 4    
343
                print status                      
344
 
345
 
346
def _saveToOrderFlipkart(self, order):
347
        collection = self.db.merchantOrder
348
        order = collection.insert(order)
349
 
13690 amit.gupta 350
 
351
 
352
def hex_md5(password):
353
    m = hashlib.md5()
354
    print(m.digest())
355
 
13658 manas 356
def main():
357
 
358
    store = getStore(2)
13690 amit.gupta 359
    #store.scrapeAffiliate()
13721 amit.gupta 360
    #store.parseOrderRawHtml(12346, "SHA21423034609", 122324,  "html", 'https://www.flipkart.com/orderresponse?reference_id=OD0019889963104132&token=198b370dfc5a25c017b5982c369ee960&src=or&pr=1')
13658 manas 361
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD3016502908102575&token=0db4c692bacbfbfc158b52358ac9e91e&src=or&pr=1')
362
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD3018701137253850&token=f7402ddcf2b63b37cc6bc528cc115d2f&src=or&pr=1')
13679 manas 363
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019279584515727&token=7d85d8c24d36b5a1efc8008634390c7e&src=or&pr=1')
13658 manas 364
    #store.flipkartOrderTracking(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019279584515727&token=7d85d8c24d36b5a1efc8008634390c7e&src=or&pr=1')
13679 manas 365
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019365336126533&token=dbce2bd4dc4023295b436a7d3c7986c9&src=or&pr=1')
366
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://dl.flipkart.com/orderresponse?reference_id=OD1019453634552336&token=e8e04871ad65b532aa53fa82bb34b901&src=or&pr=1')
13690 amit.gupta 367
    #hex_md5('spice@2020')
14290 amit.gupta 368
    store.scrapeStoreOrders()
13679 manas 369
 
13690 amit.gupta 370
 
13658 manas 371
if __name__ == '__main__':
372
        main()
373
 
13690 amit.gupta 374
 
375
 
376
 
13658 manas 377
def todict(obj, classkey=None):
378
    if isinstance(obj, dict):
379
        data = {}
380
        for (k, v) in obj.items():
381
            data[k] = todict(v, classkey)
382
        return data
383
    elif hasattr(obj, "_ast"):
384
        return todict(obj._ast())
385
    elif hasattr(obj, "__iter__"):
386
        return [todict(v, classkey) for v in obj]
387
    elif hasattr(obj, "__dict__"):
388
        data = dict([(key, todict(value, classkey)) 
389
            for key, value in obj.__dict__.iteritems() 
390
            if not callable(value) and not key.startswith('_')])
391
        if classkey is not None and hasattr(obj, "__class__"):
392
            data[classkey] = obj.__class__.__name__
393
        return data
394
    else:
13690 amit.gupta 395
        return obj
396
 
14145 amit.gupta 397