Subversion Repositories SmartDukaan

Rev

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