Subversion Repositories SmartDukaan

Rev

Rev 16281 | Rev 16370 | 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')
16283 amit.gupta 326
            subOrder.maxNlc = dealRank.get('maxNlc')
327
            subOrder.minNlc = dealRank.get('minNlc')
328
            subOrder.db = dealRank.get('dp')
329
            subOrder.itemStatus = dealRank.get('status')
15509 manish.sha 330
            subOrders.append(subOrder)
331
        merchantOrder.totalAmount = totalOrdersAmount
332
        merchantOrder.discountApplied = totalDiscount
333
        merchantOrder.deliveryCharges = ordershippingcost
334
        merchantOrder.subOrders = self.updateCashbackInSubOrders(subOrders)
335
 
336
        return merchantOrder
337
 
338
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
339
        resp = {}
340
        try:
15791 manish.sha 341
            rawHtmlSoup = BeautifulSoup(rawHtml)
342
            emailId = None
343
            orderObj = None
344
            merchantOrderId = None
345
            for script in rawHtmlSoup.find_all('script'):
346
                if 'orderConfirmation' in script.text:
16274 manish.sha 347
                    print script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0]
15791 manish.sha 348
                    orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
349
                    if merchantOrderId is None:
350
                        merchantOrderId = orderObj['0']['order_id']
351
                        emailId = orderObj['0']['email']
16197 manish.sha 352
            if orderObj is None or merchantOrderId is None:
16226 manish.sha 353
                orderIdDiv = rawHtmlSoup.body.find("div", {'class':'conf_succes'})
354
                if orderIdDiv is None:
355
                    orderIdArt = rawHtmlSoup.body.find("article", {'class':'white'})
356
                    if orderIdArt is None:
357
                        resp['result'] = 'ORDER_NOT_CREATED_UNKNOWN'
358
                        return resp
359
                    else:
360
                        orderIdDiv= orderIdArt.find('p', recursive=False)
361
                        orderIdVal = str(orderIdDiv.text.split(' : ')[1])
362
                        print "Opening Shopclues Login Page"
363
                        login_url = "https://sm.shopclues.com/login"
364
                        br1 = login(login_url)
365
                        orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+orderIdVal+"&status=P")
366
                        orderDetailPage = ungzipResponse(orderDetailPage)
367
                        rawHtmlSoup = BeautifulSoup(orderDetailPage)
368
                        for script in rawHtmlSoup.find_all('script'):
369
                            if 'orderConfirmation' in script.text:
370
                                orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
371
                                if merchantOrderId is None:
372
                                    merchantOrderId = orderObj['0']['order_id']
373
                                    emailId = orderObj['0']['email']
374
                        logoutpage = br1.open("https://sm.shopclues.com/logout")
375
                        print br1.geturl()
376
                else:
377
                    orderIdDiv= orderIdDiv.find('div', recursive=False)
378
                    orderIdVal = str(orderIdDiv.span.text)
379
                    print "Opening Shopclues Login Page"
380
                    login_url = "https://sm.shopclues.com/login"
381
                    br1 = login(login_url)
382
                    orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+orderIdVal+"&status=P")
383
                    orderDetailPage = ungzipResponse(orderDetailPage)
384
                    rawHtmlSoup = BeautifulSoup(orderDetailPage)
385
                    for script in rawHtmlSoup.find_all('script'):
386
                        if 'orderConfirmation' in script.text:
387
                            orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
388
                            if merchantOrderId is None:
389
                                merchantOrderId = orderObj['0']['order_id']
390
                                emailId = orderObj['0']['email']
391
                    logoutpage = br1.open("https://sm.shopclues.com/logout")
392
                    print br1.geturl()
393
 
16275 manish.sha 394
            if type(orderObj['0']['items']) is list:
395
                print "Opening Shopclues Login Page"
396
                login_url = "https://sm.shopclues.com/login"
397
                br1 = login(login_url)
398
                orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+str(merchantOrderId)+"&status=P")
399
                orderDetailPage = ungzipResponse(orderDetailPage)
400
                rawHtmlSoup = BeautifulSoup(orderDetailPage)
401
                for script in rawHtmlSoup.find_all('script'):
402
                    if 'orderConfirmation' in script.text:
403
                        orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
404
                        if merchantOrderId is None:
405
                            merchantOrderId = orderObj['0']['order_id']
406
                            emailId = orderObj['0']['email']
407
                logoutpage = br1.open("https://sm.shopclues.com/logout")
408
                print br1.geturl()
409
 
15509 manish.sha 410
            br = getBrowserObject()
15791 manish.sha 411
            url = ORDER_TRACK_URL +'&order_id=' +str(merchantOrderId)+'&email_id='+ emailId
15509 manish.sha 412
            page = br.open(url)
413
            headers = str(page.info()).split('\n')
414
            page = ungzipResponse(page)
415
            jsonResponse = None
416
            for header in headers:
417
                header = header.split(':')
418
                if header[0] == 'Content-Type' and 'json' in header[1]:
419
                    jsonResponse = json.loads(page)
420
            if jsonResponse is not None:
421
                page = jsonResponse['text']
422
 
15947 manish.sha 423
            merchantOrder = self._parseOrders(orderId, merchantOrderId, subTagId, userId, page, orderSuccessUrl, orderObj)
15509 manish.sha 424
 
15948 manish.sha 425
            merchantOrder.orderTrackingUrl = ORDER_TRACK_URL_DB + 'order_id=' +str(merchantOrderId)+'&email_id='+ emailId
15509 manish.sha 426
 
427
            if self._saveToOrder(todict(merchantOrder)):
428
                resp['result'] = 'ORDER_CREATED'
429
            else:
430
                resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
431
 
432
            return resp
433
        except:
434
            print "Error occurred"
435
            traceback.print_exc()
436
            resp['result'] = 'ORDER_NOT_CREATED'
16120 manish.sha 437
            return resp
15509 manish.sha 438
 
15791 manish.sha 439
    def parseSingleSubOrder(self, soup, emailId, subOrderId):
440
        orderStatusList = soup.findAll(attrs={'class' : 'price ord_status'})
441
        subOrderStatus = orderStatusList[0].contents[0].strip()
15509 manish.sha 442
        orderDateList = soup.findAll(attrs={'class':'price ord_date'})
16230 manish.sha 443
        placedOn= orderDateList[0].text.strip().replace("\t","").replace("\n","").replace("\r","").replace("  ","")
444
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
445
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)    
15791 manish.sha 446
        firstRow = orderTable.pop(0)
15949 manish.sha 447
        totalColumns = len(firstRow.find_all('th'))
15791 manish.sha 448
        subOrders =[]
449
        count =1   
15509 manish.sha 450
        for orderTr in orderTable:
451
            cols = orderTr.find_all('td')
452
            product_details = cols[0].find_all('a')
453
            #print product_details
454
            productUrl = product_details[0].get('href')
455
            productName = product_details[0].contents[0].strip()
456
            quantity = int(cols[1].text.strip())
15980 manish.sha 457
            sellingPrice = long(cols[2].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 458
            discount = 0
459
            subtotal = 0
460
            if totalColumns == 5:
15949 manish.sha 461
                if cols[3].text.strip()!='-' and 'Rs.' in cols[3].text.strip():
15980 manish.sha 462
                    discount = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 463
                else:
464
                    discount = 0
15980 manish.sha 465
                subtotal = long(cols[4].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 466
            else:
15980 manish.sha 467
                subtotal = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
16151 manish.sha 468
            productPage = fetchResponseUsingProxy(BASE_MURL+productUrl)
469
            productPageSoup = BeautifulSoup(productPage)
15791 manish.sha 470
            productCode = productPageSoup.find('input', {'type':'hidden'})['value']
15509 manish.sha 471
            allproductImageTags = productPageSoup.findAll(attrs={'class' : 'pd-image'})
472
            productImgUrl = ''
473
            if allproductImageTags is not None and len(allproductImageTags)>0:
474
                productImgUrl= allproductImageTags[0].get('style').split("background:url('")[1].split("')no-repeat center")[0].strip()
475
 
476
            subOrder = SubOrder(productName, productUrl, placedOn, subtotal)
15791 manish.sha 477
            subOrder.merchantSubOrderId = str(subOrderId)+'-'+str(count)
15509 manish.sha 478
            subOrder.detailedStatus = subOrderStatus
479
            subOrder.imgUrl = productImgUrl
480
            subOrder.offerDiscount = discount*quantity
481
            subOrder.unitPrice = sellingPrice
482
            subOrder.productCode = productCode
483
            subOrder.amountPaid = subtotal
484
            subOrder.quantity = quantity
15791 manish.sha 485
            subOrder.tracingkUrl = ORDER_TRACK_URL_DB +  'order_id=' +subOrderId+'&email_id='+ emailId
15509 manish.sha 486
            subOrders.append(subOrder)
15791 manish.sha 487
            count = count +1
15509 manish.sha 488
 
489
        subOrders = self.updateCashbackInSubOrders(subOrders)
15791 manish.sha 490
        return subOrders
15509 manish.sha 491
 
15791 manish.sha 492
    def parseMultiSubOrders(self, soup, emailId):
16230 manish.sha 493
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
494
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
16145 manish.sha 495
        firstRow = orderTable.pop(0)
15791 manish.sha 496
        '''
497
        totalColumns = len(firstRow.find_all('td'))
498
 
15509 manish.sha 499
        orderDateList = soup.findAll(attrs={'class':'price ord_date'})
15791 manish.sha 500
        placedOn= orderDateList[0].text.strip().replace("\t","").replace("\n","").replace("  ","")
501
        '''    
15509 manish.sha 502
        subOrders = []
15791 manish.sha 503
        existingOrders = []
15509 manish.sha 504
        for orderTr in orderTable:
505
            cols = orderTr.find_all('td')
506
            product_details = cols[0].find_all('a')
507
            #print product_details
508
            subOrderId= product_details[1].contents[0].strip()
15791 manish.sha 509
            if subOrderId in existingOrders:
510
                continue
511
            else:
512
                existingOrders.append(subOrderId)
513
            '''
15509 manish.sha 514
            productUrl = product_details[0].get('href')
515
            productName = product_details[0].contents[0].strip()
15791 manish.sha 516
            '''
517
            subOrderTrackingParsingUrl = product_details[1].get('href')
518
            #subOrderTrackingUrl = subOrderTrackingParsingUrl.split('order_lookup.details&')[1]
519
            '''
15509 manish.sha 520
            quantity = int(cols[1].text.strip())
521
            sellingPrice = long(cols[2].text.strip().replace("Rs.",""))
15791 manish.sha 522
            discount = 0
523
            subtotal = 0
524
            if totalColumns == 5:
525
                if cols[3].text.strip()!='-' or 'Rs.' in cols[3].text.strip():
526
                    discount = long(cols[3].text.strip().replace("Rs.",""))
527
                else:
528
                    discount = 0
529
                subtotal = long(cols[4].text.strip().replace("Rs.",""))
530
            else:
531
                subtotal = long(cols[3].text.strip().replace("Rs.",""))
532
 
15509 manish.sha 533
            br = getBrowserObject()
534
            productPage = br.open(BASE_MURL+productUrl)
535
            productPageHeaders = str(productPage.info()).split('\n')
536
            productPage = ungzipResponse(productPage)
537
            jsonProductResponse = None
538
            for header in productPageHeaders:
539
                header = header.split(':')
540
                if header[0] == 'Content-Type' and 'json' in header[1]:
541
                    jsonProductResponse = json.loads(productPage)
542
            productPageSoup= None
543
            if jsonProductResponse is not None:
544
                productPageSoup = BeautifulSoup(jsonProductResponse['text'])
545
            else:
546
                productPageSoup = BeautifulSoup(productPage)
15791 manish.sha 547
            productCode = productPageSoup.find('input', {'type':'hidden'})['value']
15509 manish.sha 548
            allproductImageTags = productPageSoup.findAll(attrs={'class' : 'pd-image'})
549
            productImgUrl = ''
550
            if allproductImageTags is not None and len(allproductImageTags)>0:
551
                productImgUrl= allproductImageTags[0].get('style').split("background:url('")[1].split("')no-repeat center")[0].strip()
552
            productDetailsSubMap['productCode']=productCode
553
            productDetailsSubMap['imgUrl']=productImgUrl
15791 manish.sha 554
            '''
16151 manish.sha 555
            orderTrackingPage = fetchResponseUsingProxy(BASE_URL+subOrderTrackingParsingUrl)
556
            orderTrackingPageSoup = BeautifulSoup(orderTrackingPage)
15791 manish.sha 557
            subOrdersDetails = self.parseSingleSubOrder(orderTrackingPageSoup, emailId, subOrderId)
558
            subOrders = list(set(subOrders + subOrdersDetails))
15509 manish.sha 559
 
15791 manish.sha 560
        return subOrders
15509 manish.sha 561
 
562
    def scrapeStoreOrders(self,):
563
        #collectionMap = {'palcedOn':1}
564
        searchMap = {}
565
        collectionMap = {"orderTrackingUrl":1}
566
        orders = self._getActiveOrders(searchMap,collectionMap)
567
        for order in orders:
568
            print "Order", self.store_name, order['orderId'], order['orderTrackingUrl']
16138 manish.sha 569
            url = ORDER_TRACK_URL +'&'+ order['orderTrackingUrl'].split('trackOrder?')[1]
16141 manish.sha 570
            print url
16249 manish.sha 571
            page = None
572
            retry = 1
573
            while retry <=3: 
574
                try: 
575
                    page = fetchResponseUsingProxy(url)
576
                    break
577
                except:
16250 manish.sha 578
                    traceback.print_exc()
16249 manish.sha 579
                    retry = retry + 1
580
 
15509 manish.sha 581
            soup = BeautifulSoup(page)
582
            bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
583
            closed = True
16144 manish.sha 584
            orderIdSpan = soup.body.find("span", {'class':'price ord_no'})
585
            if orderIdSpan is not None:
16143 manish.sha 586
                orderStatusList = soup.findAll(attrs={'class' : 'price ord_status'})
587
                if orderStatusList is not None and len(orderStatusList)>0:
588
                    subOrderId = soup.findAll(attrs={'class':'price ord_no'})[0].text.strip()
589
                    orderStatus = orderStatusList[0].contents[0].strip()
16230 manish.sha 590
                    orderTables = soup.body.findAll("table", {'class':'table product-list'})
16229 manish.sha 591
                    orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
16143 manish.sha 592
                    orderTable.pop(0)
593
                    count = 1
594
                    while count <= len(orderTable):
16160 manish.sha 595
                        subbulk = self.db.merchantOrder.initialize_ordered_bulk_op()
16152 manish.sha 596
                        print 'Sub Order Id', str(subOrderId)+'-'+str(count)
16143 manish.sha 597
                        subOrder =  self._isSubOrderActive(order, str(subOrderId)+'-'+str(count))
598
                        if subOrder is None:
599
                            try:
600
                                subOrders = self.parseSingleSubOrder(soup, order['orderTrackingUrl'].split('email_id=')[1], subOrderId)
601
                                for subOrder in subOrders:
602
                                    if subOrder is None:
603
                                        continue
604
                                    self.db.merchantOrder.update({"orderId":order['orderId']},{'$push':{"subOrders":{"$each":todict([subOrder])}}})
605
                                    print "Added new suborders to Order id - ", order['orderId']
606
                                    closed = False
607
                            except:
16227 manish.sha 608
                                traceback.print_exc()
16143 manish.sha 609
                                pass
16227 manish.sha 610
                            count = count+1
16143 manish.sha 611
                            continue
612
                        elif subOrder['closed']:
16226 manish.sha 613
                            count = count+1
16143 manish.sha 614
                            continue
615
                        else:
16163 manish.sha 616
                            findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": str(subOrderId)+'-'+str(count)}
16143 manish.sha 617
                            updateMap = {}
618
                            updateMap["subOrders.$.detailedStatus"] = orderStatus
619
                            status = self._getStatusFromDetailedStatus(orderStatus) 
620
                            closedStatus = status in [Store.ORDER_DELIVERED, Store.ORDER_CANCELLED]
621
                            if status is not None:
622
                                updateMap["subOrders.$.status"] = status
623
                            if closedStatus:
624
                                #if status is closed then change the paybackStatus accordingly
16155 manish.sha 625
                                print 'Order Closed'
16143 manish.sha 626
                                updateMap["subOrders.$.closed"] = True
627
                                if status == Store.ORDER_DELIVERED:
628
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
629
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_APPROVED
630
                                elif status == Store.ORDER_CANCELLED:
631
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
632
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_CANCELLED
633
                            else:
15791 manish.sha 634
                                closed = False
16155 manish.sha 635
                                print 'Order not Closed'
16161 manish.sha 636
 
16158 manish.sha 637
                            subbulk.find(findMap).update({'$set' : updateMap})
638
                            subresult = subbulk.execute()
639
                            tprint(subresult)
16164 manish.sha 640
                        count = count +1
16156 manish.sha 641
                    bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed,"parseError":False}})
642
                    result = bulk.execute()
643
                    tprint(result)
16143 manish.sha 644
 
645
                else:
646
                    subOrdersList = self.parseMultiSubOrders(soup, order['orderTrackingUrl'].split('email_id=')[1])
647
                    for subOrderObj in subOrdersList:
16159 manish.sha 648
                        subbulk1 = self.db.merchantOrder.initialize_ordered_bulk_op()
16143 manish.sha 649
                        subOrder =  self._isSubOrderActive(order, subOrderObj.merchantSubOrderId)
650
                        if subOrder is None:
651
                            self.db.merchantOrder.update({"orderId":order['orderId']},{'$push':{"subOrders":{"$each":todict([subOrderObj])}}})
652
                            print "Added new suborders to Order id - ", order['orderId']
653
                            closed = False
654
                            continue
655
                        elif subOrder['closed']:
656
                            continue
15791 manish.sha 657
                        else:
16143 manish.sha 658
                            findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": subOrderId}
659
                            updateMap = {}
660
                            updateMap["subOrders.$.detailedStatus"] = subOrderObj.detailedStatus
661
                            status = self._getStatusFromDetailedStatus(orderStatus) 
662
                            closedStatus = status in [Store.ORDER_DELIVERED, Store.ORDER_CANCELLED]
663
                            if status is not None:
664
                                updateMap["subOrders.$.status"] = status
665
                            if closedStatus:
666
                                #if status is closed then change the paybackStatus accordingly
667
                                updateMap["subOrders.$.closed"] = True
668
                                if status == Store.ORDER_DELIVERED:
669
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
670
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_APPROVED
671
                                elif status == Store.ORDER_CANCELLED:
672
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
673
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_CANCELLED
674
                            else:
675
                                closed = False
16159 manish.sha 676
                            subbulk1.find(findMap).update({'$set' : updateMap})
677
                            subresult1 = subbulk1.execute()
678
                            tprint(subresult1)
16156 manish.sha 679
                    bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed,"parseError":False}})
680
                    result = bulk.execute()
681
                    tprint(result)
15509 manish.sha 682
            else:
16143 manish.sha 683
                print 'Soup Object not found for this Order', order['orderId'], order['orderTrackingUrl']
684
                continue      
15791 manish.sha 685
 
686
    '''
687
    def getTrackingUrls(self, userId):
688
        missingOrderUrls = ['https://sm.shopclues.com/myaccount','https://sm.shopclues.com/myorders']
689
        return missingOrderUrls
15509 manish.sha 690
 
15791 manish.sha 691
    def parseMyProfileForEmailId(self, userId, url, rawhtml):
692
        profileSoup = BeautifulSoup(rawhtml)
693
        if profileSoup.find('input', {'name':'user_email'}) is not None:
694
            emailId = profileSoup.find('input', {'name':'user_email'})['value']
695
            if emailId is not None and emailId.strip() !='':
696
                mc = MemCache()
697
                mc.set(str(userId), emailId, 600)
698
                return 'EMAIL_SET_SUCCESS'
699
            else:
700
                return 'EMAIL_NOT_FOUND'
701
        else:
702
            return 'EMAIL_NOT_FOUND'
15509 manish.sha 703
 
15791 manish.sha 704
    def parseMyOrdersForEmailId(self, userId, url, rawhtml):
705
        myOrdersPageSoup = BeautifulSoup(rawhtml)
706
        if myOrdersPageSoup.find('a', {'class':'detail'}) is not None:
707
            emailId = myOrdersPageSoup.find('a', {'class':'detail'})['href'].split('&')[1].split('=')[1]
708
            mc = MemCache()
709
            mc.set(str(userId), emailId, 600)
710
            return 'EMAIL_SET_SUCCESS'
711
        else:
712
            return 'EMAIL_NOT_FOUND'
713
    '''        
714
 
715
 
15509 manish.sha 716
def todict(obj, classkey=None):
717
    if isinstance(obj, dict):
718
        data = {}
719
        for (k, v) in obj.items():
720
            data[k] = todict(v, classkey)
721
        return data
722
    elif hasattr(obj, "_ast"):
723
        return todict(obj._ast())
724
    elif hasattr(obj, "__iter__"):
725
        return [todict(v, classkey) for v in obj]
726
    elif hasattr(obj, "__dict__"):
727
        data = dict([(key, todict(value, classkey)) 
728
            for key, value in obj.__dict__.iteritems() 
729
            if not callable(value) and not key.startswith('_')])
730
        if classkey is not None and hasattr(obj, "__class__"):
731
            data[classkey] = obj.__class__.__name__
732
        return data
733
    else:
16226 manish.sha 734
        return obj
735
 
736
def login(url):
737
    br = getBrowserObject()
16235 manish.sha 738
    br.set_proxies({"http": "us-il.proxymesh.com:31280"})
16226 manish.sha 739
    br.open(url)
740
    response = br.open(url)
741
    ungzipResponseBr(response, br)
742
    #html = response.read()
743
    #print html
744
    br.select_form(nr=0)
745
    br.form['user'] = "imanthetester@gmail.com"
746
    br.form['password'] = "$Dl8uk"
747
    response = br.submit()
748
    print "********************"
749
    print "Attempting to Login"
750
    print "********************"
751
    #ungzipResponse(response, br)
752
    return br
15791 manish.sha 753
 
16226 manish.sha 754
def ungzipResponseBr(r,b):
755
    headers = r.info()
756
    if headers['Content-Encoding']=='gzip':
757
        import gzip
758
        print "********************"
759
        print "Deflating gzip response"
760
        print "********************"
761
        gz = gzip.GzipFile(fileobj=r, mode='rb')
762
        html = gz.read()
763
        gz.close()
764
        headers["Content-type"] = "text/html; charset=utf-8"
765
        r.set_data( html )
766
        b.set_response(r)    
767
 
15509 manish.sha 768