Subversion Repositories SmartDukaan

Rev

Rev 16275 | Rev 16283 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
15509 manish.sha 1
'''
2
Created on Jan 15, 2015
3
 
4
@author: Manish 
5
'''
6
from bs4 import BeautifulSoup
7
from bson.binary import Binary
8
from datetime import datetime, date, timedelta
9
from dtr import main
15791 manish.sha 10
from dtr.dao import AffiliateInfo, Order, SubOrder, ShopCluesAffiliateInfo
15509 manish.sha 11
from dtr.main import getBrowserObject, ScrapeException, getStore, ParseException, \
12
    Store as MStore, ungzipResponse, tprint
13
from dtr.storage import Mongo
14
from dtr.storage.Mongo import getImgSrc
15
from dtr.utils.utils import fetchResponseUsingProxy
16
from pprint import pprint
17
from pymongo import MongoClient
18
import json
19
import pymongo
20
import re
21
import time
22
import traceback
23
import urllib
15791 manish.sha 24
import urllib2
15509 manish.sha 25
from urlparse import urlparse, parse_qs
15791 manish.sha 26
import xml.etree.ElementTree as ET
27
from dtr.storage import MemCache
16097 manish.sha 28
from dtr.storage.Mongo import getDealRank
15509 manish.sha 29
 
30
USERNAME='profittill2@gmail.com'
31
PASSWORD='spice@2020'
15791 manish.sha 32
AFFLIATE_TRASACTIONS_URL = "https://admin.optimisemedia.com/v2/reports/affiliate/leads/leadsummaryexport.aspx?Contact=796881&Country=26&Agency=95&Merchant=420562&Status=-1&Year=%d&Month=%d&Day=%d&EndYear=%d&EndMonth=%d&EndDay=%d&DateType=0&Sort=CompletionDate&Login=1347562DA5E3EFF6FB1561765C47C782&Format=XML&RestrictURL=0"
15509 manish.sha 33
ORDER_TRACK_URL='http://www.shopclues.com/index.php?dispatch=order_lookup.details'
15791 manish.sha 34
ORDER_TRACK_URL_DB='https://sm.shopclues.com/trackOrder?'
15509 manish.sha 35
BASE_URL= 'http://www.shopclues.com'
36
BASE_MURL= 'http://m.shopclues.com'
37
 
38
class Store(MStore):
39
 
40
    '''
41
    This is to map order statuses of our system to order statuses of snapdeal.
42
    And our statuses will change accordingly.
43
 
44
    '''
45
    OrderStatusMap = {
16272 manish.sha 46
                      MStore.ORDER_PLACED : ['payment successful', 'new order - cod confirmation pending', 'processing', 'quality check','on schedule', 'processing - pickup initiated', 'processing - ready to dispatch','processing - procurement delay from merchant','processing - slight procurment delay from merchant','cod order confirmed by customer'],
15509 manish.sha 47
                      MStore.ORDER_DELIVERED : ['delivered', 'complete'],
16254 manish.sha 48
                      MStore.ORDER_SHIPPED : ['in transit', 'dispatched','shipped','order handed to courier','order handed over to courier'],
16249 manish.sha 49
                      MStore.ORDER_CANCELLED : ['payment failed', 'canceled', 'payment declined', 'order on hold - cancellation requested by customer', 'courier returned', 'canceled on customer request', 'canceled by customer','order canceled by customer','canceled - address not shippable']
15509 manish.sha 50
                      }
51
    OrderStatusConfirmationMap= {
15791 manish.sha 52
                                 "P" : "Payment Successful",
53
                                 "D" : "Order Declined",
54
                                 "O" : "New Order - COD confirmation Pending"
15509 manish.sha 55
                                 }
56
 
57
    CONF_CB_AMOUNT = MStore.CONF_CB_DISCOUNTED_PRICE
58
 
16111 manish.sha 59
    def __init__(self,store_id):
60
        super(Store, self).__init__(store_id)
61
 
15791 manish.sha 62
    def convertToObj(self,offer):
16202 manish.sha 63
        orderRef = offer['MerchantRef']
64
        if len(orderRef)>15:
65
            orderRef = orderRef[0:len(orderRef)-10]
16203 manish.sha 66
        offer1 = ShopCluesAffiliateInfo(offer['UID'], offer['TransactionTime'], offer['TransactionId'], orderRef,  orderRef, offer['Merchant'], offer['PID'], offer['Product'], float(str(offer['SR'])), float(str(offer['TransactionValue'])), offer['UKey'], offer['ClickTime'], offer['Status'])
15791 manish.sha 67
        return offer1
68
 
69
    def _saveToAffiliate(self, offers):
70
        collection = self.db.shopcluesOrderAffiliateInfo
71
        mcollection = self.db.merchantOrder
72
        for offerObj in offers:
73
            offer = self.convertToObj(offerObj)
74
            collection.update({"transactionId":offer.transactionId, "subTagId":offer.subTagId, "payOut":offer.payOut},{"$set":todict(offer)}, upsert=True)
75
            mcollection.update({"subTagId":offer.subTagId, "storeId":self.store_id, "subOrders.missingAff":True}, {"$set":{"subOrders.$.missingAff":False}})
76
 
15940 manish.sha 77
    def scrapeAffiliate(self, startDate=datetime.today() - timedelta(days=10), endDate=datetime.today()):
15791 manish.sha 78
        uri = AFFLIATE_TRASACTIONS_URL%(startDate.year,startDate.month,startDate.day,endDate.year,endDate.month,endDate.day)
79
        root = ET.parse(urllib2.urlopen(uri)).getroot()
80
        if len(root)> 0 and len(root[0])> 0:
81
            offers = []
82
            for child in root[0][0]:
83
                offers.append(child.attrib)
84
            self._saveToAffiliate(offers)
85
 
15509 manish.sha 86
    def _setLastSaleDate(self, saleDate):
87
        self.db.lastSaleDtate.update({'storeId':self.store_id}, {'$set':{'saleDate':saleDate}})
88
 
89
    def getName(self):
90
        return "shopclues"    
91
 
92
    def _getLastSaleDate(self,):
93
        lastDaySaleObj = self.db.lastDaySale.find_one({"storeId":self.store_id})
94
        if lastDaySaleObj is None:
95
            return datetime.min
96
 
97
    def _getStatusFromDetailedStatus(self, detailedStatus):
98
        for key, value in Store.OrderStatusMap.iteritems():
99
            if detailedStatus.lower() in value:
100
                return key
101
        print "Detailed Status need to be mapped", detailedStatus, self.store_id
102
        return None
103
 
15791 manish.sha 104
    def _getSingleSubOrderMap(self, orderId, soup, orderObj):
105
        orderStatus = self.OrderStatusConfirmationMap.get(orderObj['0']['status'])
106
        statusTime= soup.findAll(attrs={'class' : 'sts no_mobile'})[1].contents[2].strip()
15509 manish.sha 107
        productDetailsMap = {}
16230 manish.sha 108
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
109
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
15791 manish.sha 110
        firstRow = orderTable.pop(0)
15949 manish.sha 111
        totalColumns = len(firstRow.find_all('th'))
15791 manish.sha 112
        jsonSubOrdersMap = {}
113
        count = 1
114
 
115
        for val in orderObj['0']['items'].values():
116
            newCount = 0
16110 manish.sha 117
            counts = []
15791 manish.sha 118
            for key in jsonSubOrdersMap.keys():
119
                splitKey = key.split('-')
16112 manish.sha 120
                if orderObj['0']['is_parent_order'] == 'N':
121
                    if str(val['order_id']) == splitKey[0]:
122
                        counts.append(int(splitKey[1]))
123
                else:
124
                    if str(val['child']) == splitKey[0]:
125
                        counts.append(int(splitKey[1]))
16110 manish.sha 126
 
127
            if len(counts) >0:
128
                newCount = max(counts)
16108 manish.sha 129
            count = newCount +1
16112 manish.sha 130
            if orderObj['0']['is_parent_order'] == 'N':
131
                jsonSubOrdersMap[str(val['order_id'])+'-'+str(count)] = val
132
            else:
133
                jsonSubOrdersMap[str(val['child'])+'-'+str(count)] = val
15791 manish.sha 134
 
16110 manish.sha 135
 
16275 manish.sha 136
 
15941 manish.sha 137
        print jsonSubOrdersMap.items()
138
 
15791 manish.sha 139
        count = 1
15509 manish.sha 140
        for orderTr in orderTable:
15791 manish.sha 141
            productDetailsSubMap = None
142
            productDetailsSubMap = {}
15509 manish.sha 143
            cols = orderTr.find_all('td')
144
            product_details = cols[0].find_all('a')
145
            #print product_details
146
            productUrl = product_details[0].get('href')
147
            productName = product_details[0].contents[0].strip()
148
            quantity = int(cols[1].text.strip())
15980 manish.sha 149
            sellingPrice = long(cols[2].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 150
            discount = 0
151
            subtotal = 0
152
            if totalColumns == 5:
15949 manish.sha 153
                if cols[3].text.strip()!='-' and 'Rs.' in cols[3].text.strip():
15980 manish.sha 154
                    discount = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 155
                else:
156
                    discount = 0
15980 manish.sha 157
                subtotal = long(cols[4].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 158
            else:
15980 manish.sha 159
                subtotal = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
15509 manish.sha 160
            productDetailsSubMap['productUrl']=BASE_MURL+productUrl
161
            productDetailsSubMap['productName']=productName
15791 manish.sha 162
            productDetailsSubMap['subOrderTrackingUrl']=ORDER_TRACK_URL_DB+'order_id=' +str(orderId)+'&email_id='+ orderObj['0']['email']
15509 manish.sha 163
            productDetailsSubMap['sellingPrice']=sellingPrice
164
            productDetailsSubMap['quantity']=quantity
165
            productDetailsSubMap['discount']=discount
166
            productDetailsSubMap['subtotal']=subtotal
15942 manish.sha 167
            key = str(orderId)+'-'+str(count)
168
            print 'SubOrder Map Key--',key
15791 manish.sha 169
            jsonSubOrderDetails = jsonSubOrdersMap.get(str(orderId)+'-'+str(count))
170
            productCode = jsonSubOrderDetails['product_code']
171
            productImgUrl = jsonSubOrderDetails['images']['image_path'][0]
15509 manish.sha 172
            productDetailsSubMap['productCode']=productCode
173
            productDetailsSubMap['imgUrl']=productImgUrl
174
 
15791 manish.sha 175
            productDetailsSubMap['subOrderStatus']=orderStatus
176
            productDetailsSubMap['subOrderStatusTime']=statusTime
177
            productDetailsMap[str(orderId)+'-'+str(count)]=productDetailsSubMap
178
            count = count +1
15509 manish.sha 179
        return productDetailsMap
180
 
15791 manish.sha 181
    def _getMultiSubOrdersMap(self, orderId, soup, orderObj):
16230 manish.sha 182
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
183
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
16105 manish.sha 184
        firstRow = orderTable.pop(0)
15791 manish.sha 185
        #totalColumns = len(firstRow.find_all('td'))
15509 manish.sha 186
        productDetailsMap = {}
15791 manish.sha 187
        '''
188
        jsonSubOrdersMap = {}
189
        for val in orderObj['0']['items'].values():
190
            jsonSubOrdersMap[val['order_id']] = val
191
        '''
192
        existingOrders = []
15509 manish.sha 193
        for orderTr in orderTable:
15791 manish.sha 194
            subOrderDetailsMap = {}
195
 
15509 manish.sha 196
            cols = orderTr.find_all('td')
197
            product_details = cols[0].find_all('a')
198
            #print product_details
199
            subOrderId= product_details[1].contents[0].strip()
15791 manish.sha 200
            if subOrderId in existingOrders:
201
                continue
202
            else:
203
                existingOrders.append(subOrderId)
204
            #productUrl = product_details[0].get('href')
205
            #productName = product_details[0].contents[0].strip()
206
            subOrderTrackingParsingUrl = product_details[1].get('href')
207
            #subOrderTrackingUrl = subOrderTrackingParsingUrl.split('order_lookup.details&')[1]
208
            '''
15509 manish.sha 209
            quantity = int(cols[1].text.strip())
210
            sellingPrice = long(cols[2].text.strip().replace("Rs.",""))
15791 manish.sha 211
            discount = 0
212
            subtotal = 0
213
            if totalColumns == 5:
214
                if cols[3].text.strip()!='-' or 'Rs.' in cols[3].text.strip():
215
                    discount = long(cols[3].text.strip().replace("Rs.",""))
216
                else:
217
                    discount = 0                    
218
                subtotal = long(cols[4].text.strip().replace("Rs.",""))
219
            else:
220
                subtotal = long(cols[3].text.strip().replace("Rs.",""))
15509 manish.sha 221
            productDetailsSubMap['productUrl']=BASE_MURL+productUrl
222
            productDetailsSubMap['productName']=productName
15791 manish.sha 223
            productDetailsSubMap['subOrderTrackingUrl']=ORDER_TRACK_URL_DB+subOrderTrackingUrl
15509 manish.sha 224
            productDetailsSubMap['sellingPrice']=sellingPrice
225
            productDetailsSubMap['quantity']=quantity
226
            productDetailsSubMap['discount']=discount
227
            productDetailsSubMap['subtotal']=subtotal
15791 manish.sha 228
            jsonSubOrderDetails = jsonSubOrdersMap.get(subOrderId)
229
            productCode = jsonSubOrderDetails['product_code']
230
            productImgUrl = jsonSubOrderDetails['images']['image_path'][0]
15509 manish.sha 231
            productDetailsSubMap['productCode']=productCode
232
            productDetailsSubMap['imgUrl']=productImgUrl
15791 manish.sha 233
            '''
16151 manish.sha 234
            orderTrackingPage = fetchResponseUsingProxy(BASE_URL+subOrderTrackingParsingUrl)
235
            orderTrackingPageSoup = BeautifulSoup(orderTrackingPage)
15791 manish.sha 236
            '''
15509 manish.sha 237
            subOrderStatusList = orderTrackingPageSoup.findAll(attrs={'class' : 'price ord_status'})
238
            subOrderStatus = subOrderStatusList[0].contents[0].strip()
239
            subOrderStatusTime= orderTrackingPageSoup.findAll(attrs={'class' : 'sts no_mobile'})[1].contents[2].strip()
240
            productDetailsSubMap['subOrderStatus'] = subOrderStatus
241
            productDetailsSubMap['subOrderStatusTime'] = subOrderStatusTime
242
            productDetailsSubMap['parentOrderId']=orderId
15791 manish.sha 243
            '''
244
 
245
            subOrderDetailsMap = self._getSingleSubOrderMap(subOrderId, orderTrackingPageSoup, orderObj)
15509 manish.sha 246
 
15791 manish.sha 247
            productDetailsMap = dict(productDetailsMap.items()+subOrderDetailsMap.items())
15509 manish.sha 248
 
249
        return productDetailsMap
250
 
251
    def updateCashbackInSubOrders(self, subOrders):
252
        for subOrder in subOrders:
253
            cashbackStatus = Store.CB_NA
254
            cashbackAmount = 0
255
            percentage = 0
256
            amount = subOrder.amountPaid
257
            if amount > 0:
258
                (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, amount)
259
                if cashbackAmount > 0:
260
                    cashbackStatus = Store.CB_PENDING
261
            subOrder.cashBackStatus = cashbackStatus
262
            subOrder.cashBackAmount = cashbackAmount
263
            subOrder.cashBackPercentage = percentage
264
        return subOrders
265
 
15947 manish.sha 266
    def _parseOrders(self, orderId, mpOrderId, subTagId, userId, page, orderSuccessUrl, orderObj):
15509 manish.sha 267
        soup = BeautifulSoup(page)
268
        productDetailsMap = {}
269
        paymentFields = soup.findAll(attrs={'class' : 'box_paymentcalculations_row'})
270
        orderDateList = soup.findAll(attrs={'class':'price ord_date'})
15948 manish.sha 271
        placedOn= orderDateList[0].text.strip().replace("\t","").replace("\n","").replace("\r","").replace("  ","")
15509 manish.sha 272
        ordersubtotal=0
273
        ordercluebucks=0
274
        ordershippingcost=0
275
        ordertotal=0
276
 
277
        for val in paymentFields:
278
            for value in val.contents:
279
                if value is not None:
280
                    if 'div' in str(value).strip():
281
                        if 'Subtotal' in value.text.strip():
15981 manish.sha 282
                            ordersubtotal = long(val.contents[3].text.strip().replace("Rs.","").replace(',',''))
16165 manish.sha 283
                            print 'Order SubTotal:- ',ordersubtotal
15509 manish.sha 284
                        if 'Shipping Cost' in value.text.strip():
15981 manish.sha 285
                            ordershippingcost = long(val.contents[3].text.strip().replace("Rs.","").replace(',',''))
16165 manish.sha 286
                            print 'Shipping Cost:- ',ordershippingcost
15509 manish.sha 287
                        if 'Clue' in value.text.strip():
15981 manish.sha 288
                            ordercluebucks = long(val.contents[3].text.strip().replace("Rs.","").replace(',',''))
16165 manish.sha 289
                            print 'Clue bucks:- ',ordercluebucks
15509 manish.sha 290
                        if 'Total' in value.text.strip():
15791 manish.sha 291
                            ordertotal = val.contents[3].text.strip().replace("Rs.","")
292
                            ordertotal = ordertotal.replace(',','')
16165 manish.sha 293
                            print 'Order Total:- ',ordertotal
15791 manish.sha 294
 
295
        if orderObj['0']['is_parent_order'] == 'N':
15947 manish.sha 296
            productDetailsMap = self._getSingleSubOrderMap(mpOrderId, soup, orderObj)
15509 manish.sha 297
        else:
15947 manish.sha 298
            productDetailsMap = self._getMultiSubOrdersMap(mpOrderId, soup, orderObj)
15509 manish.sha 299
 
15791 manish.sha 300
        merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
15509 manish.sha 301
        merchantOrder.placedOn = placedOn
15791 manish.sha 302
        merchantOrder.merchantOrderId = orderObj['0']['order_id']
15509 manish.sha 303
        merchantOrder.paidAmount = ordertotal
304
        totalOrdersAmount = 0
305
        totalDiscount = 0
306
        subOrders= []
16281 manish.sha 307
        if len(productDetailsMap)==0:
308
            print 'Unable to get Sub Orders for Now:- ',orderObj['0']['order_id']
15509 manish.sha 309
        for key in productDetailsMap:
310
            subOrderDetail = productDetailsMap.get(key)
311
            totalOrdersAmount = totalOrdersAmount  + (subOrderDetail['sellingPrice'] * subOrderDetail['quantity'])
312
            totalDiscount = totalDiscount + (subOrderDetail['discount'] * subOrderDetail['quantity'])
313
            subOrder = SubOrder(subOrderDetail['productName'], subOrderDetail['productUrl'], placedOn, subOrderDetail['subtotal'])
314
            subOrder.merchantSubOrderId = key
315
            subOrder.detailedStatus = subOrderDetail['subOrderStatus']
316
            subOrder.imgUrl = subOrderDetail['imgUrl']
317
            subOrder.offerDiscount = subOrderDetail['discount'] * subOrderDetail['quantity']
318
            subOrder.unitPrice = subOrderDetail['sellingPrice']
319
            subOrder.productCode = subOrderDetail['productCode']
320
            subOrder.amountPaid = subOrderDetail['subtotal']
321
            subOrder.quantity = subOrderDetail['quantity']
15791 manish.sha 322
            subOrder.tracingkUrl = subOrderDetail['subOrderTrackingUrl']
16097 manish.sha 323
            dealRank = getDealRank(subOrder.productCode, self.store_id, merchantOrder.userId)
324
            subOrder.dealRank = dealRank.get('rank')
325
            subOrder.rankDesc = dealRank.get('description')
15509 manish.sha 326
            subOrders.append(subOrder)
327
        merchantOrder.totalAmount = totalOrdersAmount
328
        merchantOrder.discountApplied = totalDiscount
329
        merchantOrder.deliveryCharges = ordershippingcost
330
        merchantOrder.subOrders = self.updateCashbackInSubOrders(subOrders)
331
 
332
        return merchantOrder
333
 
334
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
335
        resp = {}
336
        try:
15791 manish.sha 337
            rawHtmlSoup = BeautifulSoup(rawHtml)
338
            emailId = None
339
            orderObj = None
340
            merchantOrderId = None
341
            for script in rawHtmlSoup.find_all('script'):
342
                if 'orderConfirmation' in script.text:
16274 manish.sha 343
                    print script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0]
15791 manish.sha 344
                    orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
345
                    if merchantOrderId is None:
346
                        merchantOrderId = orderObj['0']['order_id']
347
                        emailId = orderObj['0']['email']
16197 manish.sha 348
            if orderObj is None or merchantOrderId is None:
16226 manish.sha 349
                orderIdDiv = rawHtmlSoup.body.find("div", {'class':'conf_succes'})
350
                if orderIdDiv is None:
351
                    orderIdArt = rawHtmlSoup.body.find("article", {'class':'white'})
352
                    if orderIdArt is None:
353
                        resp['result'] = 'ORDER_NOT_CREATED_UNKNOWN'
354
                        return resp
355
                    else:
356
                        orderIdDiv= orderIdArt.find('p', recursive=False)
357
                        orderIdVal = str(orderIdDiv.text.split(' : ')[1])
358
                        print "Opening Shopclues Login Page"
359
                        login_url = "https://sm.shopclues.com/login"
360
                        br1 = login(login_url)
361
                        orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+orderIdVal+"&status=P")
362
                        orderDetailPage = ungzipResponse(orderDetailPage)
363
                        rawHtmlSoup = BeautifulSoup(orderDetailPage)
364
                        for script in rawHtmlSoup.find_all('script'):
365
                            if 'orderConfirmation' in script.text:
366
                                orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
367
                                if merchantOrderId is None:
368
                                    merchantOrderId = orderObj['0']['order_id']
369
                                    emailId = orderObj['0']['email']
370
                        logoutpage = br1.open("https://sm.shopclues.com/logout")
371
                        print br1.geturl()
372
                else:
373
                    orderIdDiv= orderIdDiv.find('div', recursive=False)
374
                    orderIdVal = str(orderIdDiv.span.text)
375
                    print "Opening Shopclues Login Page"
376
                    login_url = "https://sm.shopclues.com/login"
377
                    br1 = login(login_url)
378
                    orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+orderIdVal+"&status=P")
379
                    orderDetailPage = ungzipResponse(orderDetailPage)
380
                    rawHtmlSoup = BeautifulSoup(orderDetailPage)
381
                    for script in rawHtmlSoup.find_all('script'):
382
                        if 'orderConfirmation' in script.text:
383
                            orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
384
                            if merchantOrderId is None:
385
                                merchantOrderId = orderObj['0']['order_id']
386
                                emailId = orderObj['0']['email']
387
                    logoutpage = br1.open("https://sm.shopclues.com/logout")
388
                    print br1.geturl()
389
 
16275 manish.sha 390
            if type(orderObj['0']['items']) is list:
391
                print "Opening Shopclues Login Page"
392
                login_url = "https://sm.shopclues.com/login"
393
                br1 = login(login_url)
394
                orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+str(merchantOrderId)+"&status=P")
395
                orderDetailPage = ungzipResponse(orderDetailPage)
396
                rawHtmlSoup = BeautifulSoup(orderDetailPage)
397
                for script in rawHtmlSoup.find_all('script'):
398
                    if 'orderConfirmation' in script.text:
399
                        orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
400
                        if merchantOrderId is None:
401
                            merchantOrderId = orderObj['0']['order_id']
402
                            emailId = orderObj['0']['email']
403
                logoutpage = br1.open("https://sm.shopclues.com/logout")
404
                print br1.geturl()
405
 
15509 manish.sha 406
            br = getBrowserObject()
15791 manish.sha 407
            url = ORDER_TRACK_URL +'&order_id=' +str(merchantOrderId)+'&email_id='+ emailId
15509 manish.sha 408
            page = br.open(url)
409
            headers = str(page.info()).split('\n')
410
            page = ungzipResponse(page)
411
            jsonResponse = None
412
            for header in headers:
413
                header = header.split(':')
414
                if header[0] == 'Content-Type' and 'json' in header[1]:
415
                    jsonResponse = json.loads(page)
416
            if jsonResponse is not None:
417
                page = jsonResponse['text']
418
 
15947 manish.sha 419
            merchantOrder = self._parseOrders(orderId, merchantOrderId, subTagId, userId, page, orderSuccessUrl, orderObj)
15509 manish.sha 420
 
15948 manish.sha 421
            merchantOrder.orderTrackingUrl = ORDER_TRACK_URL_DB + 'order_id=' +str(merchantOrderId)+'&email_id='+ emailId
15509 manish.sha 422
 
423
            if self._saveToOrder(todict(merchantOrder)):
424
                resp['result'] = 'ORDER_CREATED'
425
            else:
426
                resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
427
 
428
            return resp
429
        except:
430
            print "Error occurred"
431
            traceback.print_exc()
432
            resp['result'] = 'ORDER_NOT_CREATED'
16120 manish.sha 433
            return resp
15509 manish.sha 434
 
15791 manish.sha 435
    def parseSingleSubOrder(self, soup, emailId, subOrderId):
436
        orderStatusList = soup.findAll(attrs={'class' : 'price ord_status'})
437
        subOrderStatus = orderStatusList[0].contents[0].strip()
15509 manish.sha 438
        orderDateList = soup.findAll(attrs={'class':'price ord_date'})
16230 manish.sha 439
        placedOn= orderDateList[0].text.strip().replace("\t","").replace("\n","").replace("\r","").replace("  ","")
440
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
441
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)    
15791 manish.sha 442
        firstRow = orderTable.pop(0)
15949 manish.sha 443
        totalColumns = len(firstRow.find_all('th'))
15791 manish.sha 444
        subOrders =[]
445
        count =1   
15509 manish.sha 446
        for orderTr in orderTable:
447
            cols = orderTr.find_all('td')
448
            product_details = cols[0].find_all('a')
449
            #print product_details
450
            productUrl = product_details[0].get('href')
451
            productName = product_details[0].contents[0].strip()
452
            quantity = int(cols[1].text.strip())
15980 manish.sha 453
            sellingPrice = long(cols[2].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 454
            discount = 0
455
            subtotal = 0
456
            if totalColumns == 5:
15949 manish.sha 457
                if cols[3].text.strip()!='-' and 'Rs.' in cols[3].text.strip():
15980 manish.sha 458
                    discount = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 459
                else:
460
                    discount = 0
15980 manish.sha 461
                subtotal = long(cols[4].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 462
            else:
15980 manish.sha 463
                subtotal = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
16151 manish.sha 464
            productPage = fetchResponseUsingProxy(BASE_MURL+productUrl)
465
            productPageSoup = BeautifulSoup(productPage)
15791 manish.sha 466
            productCode = productPageSoup.find('input', {'type':'hidden'})['value']
15509 manish.sha 467
            allproductImageTags = productPageSoup.findAll(attrs={'class' : 'pd-image'})
468
            productImgUrl = ''
469
            if allproductImageTags is not None and len(allproductImageTags)>0:
470
                productImgUrl= allproductImageTags[0].get('style').split("background:url('")[1].split("')no-repeat center")[0].strip()
471
 
472
            subOrder = SubOrder(productName, productUrl, placedOn, subtotal)
15791 manish.sha 473
            subOrder.merchantSubOrderId = str(subOrderId)+'-'+str(count)
15509 manish.sha 474
            subOrder.detailedStatus = subOrderStatus
475
            subOrder.imgUrl = productImgUrl
476
            subOrder.offerDiscount = discount*quantity
477
            subOrder.unitPrice = sellingPrice
478
            subOrder.productCode = productCode
479
            subOrder.amountPaid = subtotal
480
            subOrder.quantity = quantity
15791 manish.sha 481
            subOrder.tracingkUrl = ORDER_TRACK_URL_DB +  'order_id=' +subOrderId+'&email_id='+ emailId
15509 manish.sha 482
            subOrders.append(subOrder)
15791 manish.sha 483
            count = count +1
15509 manish.sha 484
 
485
        subOrders = self.updateCashbackInSubOrders(subOrders)
15791 manish.sha 486
        return subOrders
15509 manish.sha 487
 
15791 manish.sha 488
    def parseMultiSubOrders(self, soup, emailId):
16230 manish.sha 489
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
490
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
16145 manish.sha 491
        firstRow = orderTable.pop(0)
15791 manish.sha 492
        '''
493
        totalColumns = len(firstRow.find_all('td'))
494
 
15509 manish.sha 495
        orderDateList = soup.findAll(attrs={'class':'price ord_date'})
15791 manish.sha 496
        placedOn= orderDateList[0].text.strip().replace("\t","").replace("\n","").replace("  ","")
497
        '''    
15509 manish.sha 498
        subOrders = []
15791 manish.sha 499
        existingOrders = []
15509 manish.sha 500
        for orderTr in orderTable:
501
            cols = orderTr.find_all('td')
502
            product_details = cols[0].find_all('a')
503
            #print product_details
504
            subOrderId= product_details[1].contents[0].strip()
15791 manish.sha 505
            if subOrderId in existingOrders:
506
                continue
507
            else:
508
                existingOrders.append(subOrderId)
509
            '''
15509 manish.sha 510
            productUrl = product_details[0].get('href')
511
            productName = product_details[0].contents[0].strip()
15791 manish.sha 512
            '''
513
            subOrderTrackingParsingUrl = product_details[1].get('href')
514
            #subOrderTrackingUrl = subOrderTrackingParsingUrl.split('order_lookup.details&')[1]
515
            '''
15509 manish.sha 516
            quantity = int(cols[1].text.strip())
517
            sellingPrice = long(cols[2].text.strip().replace("Rs.",""))
15791 manish.sha 518
            discount = 0
519
            subtotal = 0
520
            if totalColumns == 5:
521
                if cols[3].text.strip()!='-' or 'Rs.' in cols[3].text.strip():
522
                    discount = long(cols[3].text.strip().replace("Rs.",""))
523
                else:
524
                    discount = 0
525
                subtotal = long(cols[4].text.strip().replace("Rs.",""))
526
            else:
527
                subtotal = long(cols[3].text.strip().replace("Rs.",""))
528
 
15509 manish.sha 529
            br = getBrowserObject()
530
            productPage = br.open(BASE_MURL+productUrl)
531
            productPageHeaders = str(productPage.info()).split('\n')
532
            productPage = ungzipResponse(productPage)
533
            jsonProductResponse = None
534
            for header in productPageHeaders:
535
                header = header.split(':')
536
                if header[0] == 'Content-Type' and 'json' in header[1]:
537
                    jsonProductResponse = json.loads(productPage)
538
            productPageSoup= None
539
            if jsonProductResponse is not None:
540
                productPageSoup = BeautifulSoup(jsonProductResponse['text'])
541
            else:
542
                productPageSoup = BeautifulSoup(productPage)
15791 manish.sha 543
            productCode = productPageSoup.find('input', {'type':'hidden'})['value']
15509 manish.sha 544
            allproductImageTags = productPageSoup.findAll(attrs={'class' : 'pd-image'})
545
            productImgUrl = ''
546
            if allproductImageTags is not None and len(allproductImageTags)>0:
547
                productImgUrl= allproductImageTags[0].get('style').split("background:url('")[1].split("')no-repeat center")[0].strip()
548
            productDetailsSubMap['productCode']=productCode
549
            productDetailsSubMap['imgUrl']=productImgUrl
15791 manish.sha 550
            '''
16151 manish.sha 551
            orderTrackingPage = fetchResponseUsingProxy(BASE_URL+subOrderTrackingParsingUrl)
552
            orderTrackingPageSoup = BeautifulSoup(orderTrackingPage)
15791 manish.sha 553
            subOrdersDetails = self.parseSingleSubOrder(orderTrackingPageSoup, emailId, subOrderId)
554
            subOrders = list(set(subOrders + subOrdersDetails))
15509 manish.sha 555
 
15791 manish.sha 556
        return subOrders
15509 manish.sha 557
 
558
    def scrapeStoreOrders(self,):
559
        #collectionMap = {'palcedOn':1}
560
        searchMap = {}
561
        collectionMap = {"orderTrackingUrl":1}
562
        orders = self._getActiveOrders(searchMap,collectionMap)
563
        for order in orders:
564
            print "Order", self.store_name, order['orderId'], order['orderTrackingUrl']
16138 manish.sha 565
            url = ORDER_TRACK_URL +'&'+ order['orderTrackingUrl'].split('trackOrder?')[1]
16141 manish.sha 566
            print url
16249 manish.sha 567
            page = None
568
            retry = 1
569
            while retry <=3: 
570
                try: 
571
                    page = fetchResponseUsingProxy(url)
572
                    break
573
                except:
16250 manish.sha 574
                    traceback.print_exc()
16249 manish.sha 575
                    retry = retry + 1
576
 
15509 manish.sha 577
            soup = BeautifulSoup(page)
578
            bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
579
            closed = True
16144 manish.sha 580
            orderIdSpan = soup.body.find("span", {'class':'price ord_no'})
581
            if orderIdSpan is not None:
16143 manish.sha 582
                orderStatusList = soup.findAll(attrs={'class' : 'price ord_status'})
583
                if orderStatusList is not None and len(orderStatusList)>0:
584
                    subOrderId = soup.findAll(attrs={'class':'price ord_no'})[0].text.strip()
585
                    orderStatus = orderStatusList[0].contents[0].strip()
16230 manish.sha 586
                    orderTables = soup.body.findAll("table", {'class':'table product-list'})
16229 manish.sha 587
                    orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
16143 manish.sha 588
                    orderTable.pop(0)
589
                    count = 1
590
                    while count <= len(orderTable):
16160 manish.sha 591
                        subbulk = self.db.merchantOrder.initialize_ordered_bulk_op()
16152 manish.sha 592
                        print 'Sub Order Id', str(subOrderId)+'-'+str(count)
16143 manish.sha 593
                        subOrder =  self._isSubOrderActive(order, str(subOrderId)+'-'+str(count))
594
                        if subOrder is None:
595
                            try:
596
                                subOrders = self.parseSingleSubOrder(soup, order['orderTrackingUrl'].split('email_id=')[1], subOrderId)
597
                                for subOrder in subOrders:
598
                                    if subOrder is None:
599
                                        continue
600
                                    self.db.merchantOrder.update({"orderId":order['orderId']},{'$push':{"subOrders":{"$each":todict([subOrder])}}})
601
                                    print "Added new suborders to Order id - ", order['orderId']
602
                                    closed = False
603
                            except:
16227 manish.sha 604
                                traceback.print_exc()
16143 manish.sha 605
                                pass
16227 manish.sha 606
                            count = count+1
16143 manish.sha 607
                            continue
608
                        elif subOrder['closed']:
16226 manish.sha 609
                            count = count+1
16143 manish.sha 610
                            continue
611
                        else:
16163 manish.sha 612
                            findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": str(subOrderId)+'-'+str(count)}
16143 manish.sha 613
                            updateMap = {}
614
                            updateMap["subOrders.$.detailedStatus"] = orderStatus
615
                            status = self._getStatusFromDetailedStatus(orderStatus) 
616
                            closedStatus = status in [Store.ORDER_DELIVERED, Store.ORDER_CANCELLED]
617
                            if status is not None:
618
                                updateMap["subOrders.$.status"] = status
619
                            if closedStatus:
620
                                #if status is closed then change the paybackStatus accordingly
16155 manish.sha 621
                                print 'Order Closed'
16143 manish.sha 622
                                updateMap["subOrders.$.closed"] = True
623
                                if status == Store.ORDER_DELIVERED:
624
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
625
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_APPROVED
626
                                elif status == Store.ORDER_CANCELLED:
627
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
628
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_CANCELLED
629
                            else:
15791 manish.sha 630
                                closed = False
16155 manish.sha 631
                                print 'Order not Closed'
16161 manish.sha 632
 
16158 manish.sha 633
                            subbulk.find(findMap).update({'$set' : updateMap})
634
                            subresult = subbulk.execute()
635
                            tprint(subresult)
16164 manish.sha 636
                        count = count +1
16156 manish.sha 637
                    bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed,"parseError":False}})
638
                    result = bulk.execute()
639
                    tprint(result)
16143 manish.sha 640
 
641
                else:
642
                    subOrdersList = self.parseMultiSubOrders(soup, order['orderTrackingUrl'].split('email_id=')[1])
643
                    for subOrderObj in subOrdersList:
16159 manish.sha 644
                        subbulk1 = self.db.merchantOrder.initialize_ordered_bulk_op()
16143 manish.sha 645
                        subOrder =  self._isSubOrderActive(order, subOrderObj.merchantSubOrderId)
646
                        if subOrder is None:
647
                            self.db.merchantOrder.update({"orderId":order['orderId']},{'$push':{"subOrders":{"$each":todict([subOrderObj])}}})
648
                            print "Added new suborders to Order id - ", order['orderId']
649
                            closed = False
650
                            continue
651
                        elif subOrder['closed']:
652
                            continue
15791 manish.sha 653
                        else:
16143 manish.sha 654
                            findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": subOrderId}
655
                            updateMap = {}
656
                            updateMap["subOrders.$.detailedStatus"] = subOrderObj.detailedStatus
657
                            status = self._getStatusFromDetailedStatus(orderStatus) 
658
                            closedStatus = status in [Store.ORDER_DELIVERED, Store.ORDER_CANCELLED]
659
                            if status is not None:
660
                                updateMap["subOrders.$.status"] = status
661
                            if closedStatus:
662
                                #if status is closed then change the paybackStatus accordingly
663
                                updateMap["subOrders.$.closed"] = True
664
                                if status == Store.ORDER_DELIVERED:
665
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
666
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_APPROVED
667
                                elif status == Store.ORDER_CANCELLED:
668
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
669
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_CANCELLED
670
                            else:
671
                                closed = False
16159 manish.sha 672
                            subbulk1.find(findMap).update({'$set' : updateMap})
673
                            subresult1 = subbulk1.execute()
674
                            tprint(subresult1)
16156 manish.sha 675
                    bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed,"parseError":False}})
676
                    result = bulk.execute()
677
                    tprint(result)
15509 manish.sha 678
            else:
16143 manish.sha 679
                print 'Soup Object not found for this Order', order['orderId'], order['orderTrackingUrl']
680
                continue      
15791 manish.sha 681
 
682
    '''
683
    def getTrackingUrls(self, userId):
684
        missingOrderUrls = ['https://sm.shopclues.com/myaccount','https://sm.shopclues.com/myorders']
685
        return missingOrderUrls
15509 manish.sha 686
 
15791 manish.sha 687
    def parseMyProfileForEmailId(self, userId, url, rawhtml):
688
        profileSoup = BeautifulSoup(rawhtml)
689
        if profileSoup.find('input', {'name':'user_email'}) is not None:
690
            emailId = profileSoup.find('input', {'name':'user_email'})['value']
691
            if emailId is not None and emailId.strip() !='':
692
                mc = MemCache()
693
                mc.set(str(userId), emailId, 600)
694
                return 'EMAIL_SET_SUCCESS'
695
            else:
696
                return 'EMAIL_NOT_FOUND'
697
        else:
698
            return 'EMAIL_NOT_FOUND'
15509 manish.sha 699
 
15791 manish.sha 700
    def parseMyOrdersForEmailId(self, userId, url, rawhtml):
701
        myOrdersPageSoup = BeautifulSoup(rawhtml)
702
        if myOrdersPageSoup.find('a', {'class':'detail'}) is not None:
703
            emailId = myOrdersPageSoup.find('a', {'class':'detail'})['href'].split('&')[1].split('=')[1]
704
            mc = MemCache()
705
            mc.set(str(userId), emailId, 600)
706
            return 'EMAIL_SET_SUCCESS'
707
        else:
708
            return 'EMAIL_NOT_FOUND'
709
    '''        
710
 
711
 
15509 manish.sha 712
def todict(obj, classkey=None):
713
    if isinstance(obj, dict):
714
        data = {}
715
        for (k, v) in obj.items():
716
            data[k] = todict(v, classkey)
717
        return data
718
    elif hasattr(obj, "_ast"):
719
        return todict(obj._ast())
720
    elif hasattr(obj, "__iter__"):
721
        return [todict(v, classkey) for v in obj]
722
    elif hasattr(obj, "__dict__"):
723
        data = dict([(key, todict(value, classkey)) 
724
            for key, value in obj.__dict__.iteritems() 
725
            if not callable(value) and not key.startswith('_')])
726
        if classkey is not None and hasattr(obj, "__class__"):
727
            data[classkey] = obj.__class__.__name__
728
        return data
729
    else:
16226 manish.sha 730
        return obj
731
 
732
def login(url):
733
    br = getBrowserObject()
16235 manish.sha 734
    br.set_proxies({"http": "us-il.proxymesh.com:31280"})
16226 manish.sha 735
    br.open(url)
736
    response = br.open(url)
737
    ungzipResponseBr(response, br)
738
    #html = response.read()
739
    #print html
740
    br.select_form(nr=0)
741
    br.form['user'] = "imanthetester@gmail.com"
742
    br.form['password'] = "$Dl8uk"
743
    response = br.submit()
744
    print "********************"
745
    print "Attempting to Login"
746
    print "********************"
747
    #ungzipResponse(response, br)
748
    return br
15791 manish.sha 749
 
16226 manish.sha 750
def ungzipResponseBr(r,b):
751
    headers = r.info()
752
    if headers['Content-Encoding']=='gzip':
753
        import gzip
754
        print "********************"
755
        print "Deflating gzip response"
756
        print "********************"
757
        gz = gzip.GzipFile(fileobj=r, mode='rb')
758
        html = gz.read()
759
        gz.close()
760
        headers["Content-type"] = "text/html; charset=utf-8"
761
        r.set_data( html )
762
        b.set_response(r)    
763
 
15509 manish.sha 764