Subversion Repositories SmartDukaan

Rev

Rev 14356 | Rev 14412 | 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, \
14398 amit.gupta 11
    Store as MStore, sourceMap, tprint
13690 amit.gupta 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()
13679 manas 52
        br = getBrowserObject()
13721 amit.gupta 53
        for order in orders:
14398 amit.gupta 54
            print order
55
            try:
56
                closed = True
57
                url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', order['orderSuccessUrl'],re.IGNORECASE)[0]
58
                response = br.open(url)
59
                page = ungzipResponse(response)
13721 amit.gupta 60
 
14398 amit.gupta 61
                soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
62
 
63
                sections = soup.findAll("div", {"class":"ui-app-card-body"})
64
                sections.pop(1)
13721 amit.gupta 65
 
14398 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'})
94
                        orderTrackingDet = orderTrackingDetDiv.find('div',{'class':re.compile('tracking-remark')}).text
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_PENDING:
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: 
13721 amit.gupta 119
                                status = MStore.ORDER_PLACED
14398 amit.gupta 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_PENDING:
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
            except:
137
                tprint("Could not update " + str(order['orderId']))
138
                traceback.print_exc()
13721 amit.gupta 139
    def scrapeAffiliate(self, startDate=None, endDate=None):
140
        #get all yesterday's affiliate in pending or cancelled state and update to system
141
        if datetime.now().hour == 1:
142
            yesterdate = date.today() - timedelta(1)
143
            syesterdate = yesterdate.strftime('%Y-%m-%d') 
144
            br = getBrowserObject()
145
            br.open(AFFILIATE_URL)
146
            response = br.response()  # copy
147
            token =  re.findall('window.__FK = "(.*?)"', ungzipResponse(response), re.IGNORECASE)[0]
148
            data = {'__FK':token,
149
                    'email':'saholic1@gmail.com',
150
                    'password':'e8aacf6fc1e3998186a4a8e56e428f66'
151
            }
152
            br.open(AFFILIATE_LOGIN_URL, urllib.urlencode(data))
153
            for status in [AFF_STATUS_PENDING, AFF_STATUS_CANCELLED, AFF_STATUS_DISAPPROVED]:
154
                br.open(AFF_REPORT_URL % (status, syesterdate, syesterdate))
155
                page = ungzipResponse(br.response())
156
                soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
157
                try:
158
                    tableElement = soup.findAll('table', {'class':'report-table fixtable'})[1]
159
                except:
160
                    continue
161
                trElements = tableElement.findAll('tr')
162
                trElements.pop(0)
163
                for trElement in trElements:
164
                    tdElements = trElement.findAll('td')
165
                    productCode = re.findall(r'pid=(.*)$', tdElements[0].find('a')['href'])[0]
166
                    quantity =int(tdElements[3].text)
167
                    price = int(re.findall(r'\d+', tdElements[2].text)[0])
168
                    payOut = int(re.findall(r'\d+', tdElements[6].text)[0])
169
                    subTagId = tdElements[7].text
170
                    affiliateInfo = AffiliateInfo(subTagId, self.store_id, status, None, syesterdate, payOut, None, None, price*quantity)
171
                    print todict(affiliateInfo)
172
                    updateMap = {}
173
                    updateMap['subOrders.$.unitPrice'] = price
174
                    updateMap['subOrders.$.cashBackAmount'], updateMap['subOrders.$.cashBacPercentage'] = self.getCashbackAmount(productCode, price)
175
                    self._updateOrdersPayBackStatus({'subTagId':subTagId, 'subOrders.productCode':productCode}, updateMap)
176
 
177
 
13658 manas 178
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
13796 amit.gupta 179
        resp= {}
13781 amit.gupta 180
        try:
181
            br = getBrowserObject()
182
            url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]
183
 
184
            response = br.open(url)
185
            page = ungzipResponse(response)
186
 
187
            merchantOrderId = re.findall('reference_id=(.*?)&', orderSuccessUrl,re.IGNORECASE)[0]
188
            print merchantOrderId
189
 
190
            soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
191
 
192
            sections = soup.findAll("div", {"class":"ui-app-card-body"})
193
            sections.pop(1)
194
 
195
            merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
14145 amit.gupta 196
            merchantOrder.orderTrackingUrl = url
13781 amit.gupta 197
            for data in sections:
198
                name = data.findAll("span")
199
                i=0
200
                while i< len(name):
201
                    if "key" in str(name[i]):
202
                        if "Grand Total" in str(name[i]):
203
                            #Total Amount
204
                            merchantOrder.paidAmount = int(re.findall(r'\d+', name[i+1].text)[0])
205
                        elif "Order Date" in str(name[i]):
206
                            merchantOrder.placedOn = name[i+1].text 
207
                    i=i+1    
208
 
209
            merchantOrder.merchantOrderId = merchantOrderId
210
 
211
            mainOrder = soup.find("ul",{"class":"m-bottom p-cart"})
212
            fkSubOrders = mainOrder.findAll("li")
213
            #remove unwanted list
214
            fkSubOrders.pop(-1)
215
            subOrders = []
216
            merchantOrder.subOrders = subOrders
217
 
218
            #fetching suborders details
219
            for subOrder in fkSubOrders:
220
                y = subOrder.find("header").findAll("span")
221
                for suborderId in y:
222
                    if "value emp" in str(suborderId):
223
                        merchantSubOrderId = suborderId.text
224
                        break
225
                orderItems = subOrder.find("ul").findAll("div", recursive=False)
226
                i=0
227
                for orderItem in orderItems:
228
                    merchantOrder.placedOn
229
                    merchantSubOrderId = merchantSubOrderId + str(i)
230
                    divs = orderItem.findAll('div', recursive=False)
231
                    content = divs[0]
232
                    orderTracking = divs[2]
233
                    orderTrackingDet = divs[3]
234
 
235
 
236
                    imgUrl = content.find('img')['src']
237
                    lineDet = content.find("div",{"class":"product-info"})
238
                    productTitle = lineDet.find("a",{"class":"product-title"}).text
239
                    productUrl =  str(lineDet.find("a")['href'])
240
 
241
                    start='pid='
242
                    s=str(lineDet.find("a")['href'])
14339 amit.gupta 243
                    productCode = re.findall(re.escape(start)+"(.*)",s)[0].strip()
13781 amit.gupta 244
                    mname = lineDet.findAll("span")
245
                    k=0
246
                    while k<len(mname):
247
                        if "note" in str(mname[k]):
248
                            if "Color:" in str(mname[k]):
249
                                productTitle = productTitle + " " + mname[k+1].text
250
 
251
                            elif "Qty:" in str(mname[k]):
252
                                quantity = int(mname[k+1].text)
253
                            elif "Subtotal:" in str(mname[k]):
14343 amit.gupta 254
                                amountPaid = int(re.findall(r'\d+', mname[k+1].text)[0])
13781 amit.gupta 255
                            elif "Delivery:" in str(mname[k]):
256
                                #Delivery Date for sub order
257
                                print "Delivery Date " +mname[k+1].text
258
                        k=k+1
14343 amit.gupta 259
                    merchantsubOrder = SubOrder(productTitle, productUrl, merchantOrder.placedOn, amountPaid,MStore.ORDER_PLACED, quantity)
13781 amit.gupta 260
                    merchantsubOrder.imgUrl  = imgUrl
261
                    merchantsubOrder.productCode = productCode
262
                    merchantsubOrder.merchantSubOrderId = merchantSubOrderId
14337 amit.gupta 263
                    print "productCode", productCode
14340 amit.gupta 264
                    print "amountPaid", amountPaid
14336 amit.gupta 265
                    cashbackAmount, cashbackPercent = self.getCashbackAmount(productCode, amountPaid)
13781 amit.gupta 266
                    cashbackStatus = Store.CB_PENDING
267
                    if cashbackAmount <= 0:
268
                        cashbackStatus = Store.CB_NA
269
                    merchantsubOrder.cashBackAmount = cashbackAmount
270
                    merchantsubOrder.cashBackStatus = cashbackStatus      
271
                    merchantsubOrder.cashBackPercentage = cashbackPercent      
272
 
273
                    subOrders.append(merchantsubOrder)
274
                    #To track shipping details         
275
                    status=-1    
276
                    tr = orderTracking.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})
277
                    if "approveDetails-complete" in str(tr):
278
                        if "processingDetails-complete" in str(tr):
279
                            if "shippingDetails-complete" in str(tr):
280
                                if "delivery-complete" in str(tr):
281
                                    status = MStore.ORDER_DELIVERED
282
                                else:     
283
                                    status = MStore.ORDER_SHIPPED
284
                                    orderTracking.find('div', {'class':'tracking-remark active'})
285
                            else:
286
                                status = MStore.ORDER_PLACED
287
                        else: 
13690 amit.gupta 288
                            status = MStore.ORDER_PLACED
13781 amit.gupta 289
                    elif str(tr) in ["approveDetails-ongoing"]:
290
                        status=MStore.ORDER_PLACED             
14351 amit.gupta 291
                    if "dead" in str(tr) or "shippingDetails-returnOngoing" in str(tr):
13781 amit.gupta 292
                        status = MStore.ORDER_CANCELLED    
293
                    print "Sub Order Status " + str(status)                      
294
 
295
                    trackingDetailsActive = orderTrackingDet.find("div",{"class":"c-tabs-content m-top active"})
296
                    print "Sub order tracking description " + trackingDetailsActive.text
14312 amit.gupta 297
            if self._saveToOrder(todict(merchantOrder)):
298
                resp['result'] = 'ORDER_CREATED'
299
            else:
300
                resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
301
 
13796 amit.gupta 302
            return resp 
13781 amit.gupta 303
        except:
14338 amit.gupta 304
            traceback.print_exc()
14312 amit.gupta 305
            resp['result'] = 'ORDER_NOT_CREATED'
13796 amit.gupta 306
            return resp 
13781 amit.gupta 307
 
13658 manas 308
 
309
    def flipkartOrderTracking(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
310
        br = getBrowserObject()
311
        url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]
312
 
313
        response = br.open(url)
314
        page = ungzipResponse(response, br)
315
 
316
 
317
        soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
318
 
319
 
320
        mainOrder = soup.findAll("ul",{"class":"m-bottom p-cart"})
321
        #fetching suborders details
322
        for subOrder in mainOrder:
323
            subOrd = subOrder.findAll("li")
324
 
325
            subOrd.pop(len(subOrd)-1)
326
            for productInfo in subOrd:
327
                status=-1    
328
                #To track shipping details         
329
                n = productInfo.findAll("div",{"class":"tracking-progress grid-row cf"})
330
                for trackingStatus in n:
331
                    tr = trackingStatus.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})
332
                    if "approveDetails-complete" in str(tr):
13679 manas 333
                        print "Here"
13658 manas 334
                        if "processingDetails-complete" in str(tr):
13679 manas 335
                            print "There"
13658 manas 336
                            if "shippingDetails-complete" in str(tr):
13679 manas 337
                                print "Share"
13658 manas 338
                                if "delivery-complete" in str(tr):
13679 manas 339
                                    print "Last"
13658 manas 340
                                    status = 3
341
                                else:     
342
                                    status = 2
343
                            else:
344
                                status = 1 
345
                        else: 
346
                            status = 0     
347
                    if "dead" in str(tr):
348
                        status = 4    
349
                print status                      
350
 
351
 
352
def _saveToOrderFlipkart(self, order):
353
        collection = self.db.merchantOrder
354
        order = collection.insert(order)
355
 
13690 amit.gupta 356
 
357
 
358
def hex_md5(password):
359
    m = hashlib.md5()
360
    print(m.digest())
361
 
13658 manas 362
def main():
363
 
364
    store = getStore(2)
13690 amit.gupta 365
    #store.scrapeAffiliate()
14351 amit.gupta 366
    store.parseOrderRawHtml(123469, "SHA21423034609", 122324,  "html", 'https://m.flipkart.com/order_details?reference_id=OD3022229107123666&token=13ace95c4dc4e6bc372529a330e6b656&src=or&pr=1')
13658 manas 367
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD3016502908102575&token=0db4c692bacbfbfc158b52358ac9e91e&src=or&pr=1')
368
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD3018701137253850&token=f7402ddcf2b63b37cc6bc528cc115d2f&src=or&pr=1')
13679 manas 369
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019279584515727&token=7d85d8c24d36b5a1efc8008634390c7e&src=or&pr=1')
13658 manas 370
    #store.flipkartOrderTracking(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019279584515727&token=7d85d8c24d36b5a1efc8008634390c7e&src=or&pr=1')
13679 manas 371
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://m.flipkart.com/orderresponse?reference_id=OD0019365336126533&token=dbce2bd4dc4023295b436a7d3c7986c9&src=or&pr=1')
372
    #store.parseOrderRawHtml(12346, "subtagId", 122324,  "html", 'https://dl.flipkart.com/orderresponse?reference_id=OD1019453634552336&token=e8e04871ad65b532aa53fa82bb34b901&src=or&pr=1')
13690 amit.gupta 373
    #hex_md5('spice@2020')
14351 amit.gupta 374
    #store.getCashbackAmount('MOBDVHC6XKKPZ3GZ', 5999)
13679 manas 375
 
13690 amit.gupta 376
 
13658 manas 377
if __name__ == '__main__':
378
        main()
379
 
13690 amit.gupta 380
 
381
 
382
 
13658 manas 383
def todict(obj, classkey=None):
384
    if isinstance(obj, dict):
385
        data = {}
386
        for (k, v) in obj.items():
387
            data[k] = todict(v, classkey)
388
        return data
389
    elif hasattr(obj, "_ast"):
390
        return todict(obj._ast())
391
    elif hasattr(obj, "__iter__"):
392
        return [todict(v, classkey) for v in obj]
393
    elif hasattr(obj, "__dict__"):
394
        data = dict([(key, todict(value, classkey)) 
395
            for key, value in obj.__dict__.iteritems() 
396
            if not callable(value) and not key.startswith('_')])
397
        if classkey is not None and hasattr(obj, "__class__"):
398
            data[classkey] = obj.__class__.__name__
399
        return data
400
    else:
13690 amit.gupta 401
        return obj
402
 
14145 amit.gupta 403