Subversion Repositories SmartDukaan

Rev

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