Subversion Repositories SmartDukaan

Rev

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