Subversion Repositories SmartDukaan

Rev

Rev 16420 | Rev 16787 | 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'],
16370 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','return complete','undelivered - returning to origin']
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'])
16420 manish.sha 106
        statusTime= str(to_py_date(long(orderObj['0']['timestamp'])))
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:
16420 manish.sha 124
                    if val['child'] is None:
125
                        if str(val['order_id']) == splitKey[0]:
126
                            counts.append(int(splitKey[1]))
127
                    else:
128
                        if str(val['child']) == splitKey[0]:
129
                            counts.append(int(splitKey[1]))
16110 manish.sha 130
 
131
            if len(counts) >0:
132
                newCount = max(counts)
16108 manish.sha 133
            count = newCount +1
16112 manish.sha 134
            if orderObj['0']['is_parent_order'] == 'N':
135
                jsonSubOrdersMap[str(val['order_id'])+'-'+str(count)] = val
136
            else:
16420 manish.sha 137
                if val['child'] is None:
138
                    jsonSubOrdersMap[str(val['order_id'])+'-'+str(count)] = val
139
                else:
140
                    jsonSubOrdersMap[str(val['child'])+'-'+str(count)] = val
15791 manish.sha 141
 
16110 manish.sha 142
 
16275 manish.sha 143
 
15941 manish.sha 144
        print jsonSubOrdersMap.items()
145
 
15791 manish.sha 146
        count = 1
15509 manish.sha 147
        for orderTr in orderTable:
15791 manish.sha 148
            productDetailsSubMap = None
149
            productDetailsSubMap = {}
15509 manish.sha 150
            cols = orderTr.find_all('td')
151
            product_details = cols[0].find_all('a')
152
            #print product_details
153
            productUrl = product_details[0].get('href')
154
            productName = product_details[0].contents[0].strip()
155
            quantity = int(cols[1].text.strip())
15980 manish.sha 156
            sellingPrice = long(cols[2].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 157
            discount = 0
158
            subtotal = 0
159
            if totalColumns == 5:
15949 manish.sha 160
                if cols[3].text.strip()!='-' and 'Rs.' in cols[3].text.strip():
15980 manish.sha 161
                    discount = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 162
                else:
163
                    discount = 0
15980 manish.sha 164
                subtotal = long(cols[4].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 165
            else:
15980 manish.sha 166
                subtotal = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
15509 manish.sha 167
            productDetailsSubMap['productUrl']=BASE_MURL+productUrl
168
            productDetailsSubMap['productName']=productName
15791 manish.sha 169
            productDetailsSubMap['subOrderTrackingUrl']=ORDER_TRACK_URL_DB+'order_id=' +str(orderId)+'&email_id='+ orderObj['0']['email']
15509 manish.sha 170
            productDetailsSubMap['sellingPrice']=sellingPrice
171
            productDetailsSubMap['quantity']=quantity
172
            productDetailsSubMap['discount']=discount
173
            productDetailsSubMap['subtotal']=subtotal
15942 manish.sha 174
            key = str(orderId)+'-'+str(count)
175
            print 'SubOrder Map Key--',key
15791 manish.sha 176
            jsonSubOrderDetails = jsonSubOrdersMap.get(str(orderId)+'-'+str(count))
177
            productCode = jsonSubOrderDetails['product_code']
178
            productImgUrl = jsonSubOrderDetails['images']['image_path'][0]
15509 manish.sha 179
            productDetailsSubMap['productCode']=productCode
180
            productDetailsSubMap['imgUrl']=productImgUrl
181
 
15791 manish.sha 182
            productDetailsSubMap['subOrderStatus']=orderStatus
183
            productDetailsSubMap['subOrderStatusTime']=statusTime
184
            productDetailsMap[str(orderId)+'-'+str(count)]=productDetailsSubMap
185
            count = count +1
15509 manish.sha 186
        return productDetailsMap
187
 
15791 manish.sha 188
    def _getMultiSubOrdersMap(self, orderId, soup, orderObj):
16230 manish.sha 189
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
190
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
16105 manish.sha 191
        firstRow = orderTable.pop(0)
15791 manish.sha 192
        #totalColumns = len(firstRow.find_all('td'))
15509 manish.sha 193
        productDetailsMap = {}
15791 manish.sha 194
        '''
195
        jsonSubOrdersMap = {}
196
        for val in orderObj['0']['items'].values():
197
            jsonSubOrdersMap[val['order_id']] = val
198
        '''
199
        existingOrders = []
15509 manish.sha 200
        for orderTr in orderTable:
15791 manish.sha 201
            subOrderDetailsMap = {}
202
 
15509 manish.sha 203
            cols = orderTr.find_all('td')
204
            product_details = cols[0].find_all('a')
205
            #print product_details
206
            subOrderId= product_details[1].contents[0].strip()
15791 manish.sha 207
            if subOrderId in existingOrders:
208
                continue
209
            else:
210
                existingOrders.append(subOrderId)
211
            #productUrl = product_details[0].get('href')
212
            #productName = product_details[0].contents[0].strip()
213
            subOrderTrackingParsingUrl = product_details[1].get('href')
214
            #subOrderTrackingUrl = subOrderTrackingParsingUrl.split('order_lookup.details&')[1]
215
            '''
15509 manish.sha 216
            quantity = int(cols[1].text.strip())
217
            sellingPrice = long(cols[2].text.strip().replace("Rs.",""))
15791 manish.sha 218
            discount = 0
219
            subtotal = 0
220
            if totalColumns == 5:
221
                if cols[3].text.strip()!='-' or 'Rs.' in cols[3].text.strip():
222
                    discount = long(cols[3].text.strip().replace("Rs.",""))
223
                else:
224
                    discount = 0                    
225
                subtotal = long(cols[4].text.strip().replace("Rs.",""))
226
            else:
227
                subtotal = long(cols[3].text.strip().replace("Rs.",""))
15509 manish.sha 228
            productDetailsSubMap['productUrl']=BASE_MURL+productUrl
229
            productDetailsSubMap['productName']=productName
15791 manish.sha 230
            productDetailsSubMap['subOrderTrackingUrl']=ORDER_TRACK_URL_DB+subOrderTrackingUrl
15509 manish.sha 231
            productDetailsSubMap['sellingPrice']=sellingPrice
232
            productDetailsSubMap['quantity']=quantity
233
            productDetailsSubMap['discount']=discount
234
            productDetailsSubMap['subtotal']=subtotal
15791 manish.sha 235
            jsonSubOrderDetails = jsonSubOrdersMap.get(subOrderId)
236
            productCode = jsonSubOrderDetails['product_code']
237
            productImgUrl = jsonSubOrderDetails['images']['image_path'][0]
15509 manish.sha 238
            productDetailsSubMap['productCode']=productCode
239
            productDetailsSubMap['imgUrl']=productImgUrl
15791 manish.sha 240
            '''
16151 manish.sha 241
            orderTrackingPage = fetchResponseUsingProxy(BASE_URL+subOrderTrackingParsingUrl)
242
            orderTrackingPageSoup = BeautifulSoup(orderTrackingPage)
15791 manish.sha 243
            '''
15509 manish.sha 244
            subOrderStatusList = orderTrackingPageSoup.findAll(attrs={'class' : 'price ord_status'})
245
            subOrderStatus = subOrderStatusList[0].contents[0].strip()
246
            subOrderStatusTime= orderTrackingPageSoup.findAll(attrs={'class' : 'sts no_mobile'})[1].contents[2].strip()
247
            productDetailsSubMap['subOrderStatus'] = subOrderStatus
248
            productDetailsSubMap['subOrderStatusTime'] = subOrderStatusTime
249
            productDetailsSubMap['parentOrderId']=orderId
15791 manish.sha 250
            '''
251
 
252
            subOrderDetailsMap = self._getSingleSubOrderMap(subOrderId, orderTrackingPageSoup, orderObj)
15509 manish.sha 253
 
15791 manish.sha 254
            productDetailsMap = dict(productDetailsMap.items()+subOrderDetailsMap.items())
15509 manish.sha 255
 
256
        return productDetailsMap
257
 
258
    def updateCashbackInSubOrders(self, subOrders):
259
        for subOrder in subOrders:
260
            cashbackStatus = Store.CB_NA
261
            cashbackAmount = 0
262
            percentage = 0
263
            amount = subOrder.amountPaid
264
            if amount > 0:
265
                (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, amount)
266
                if cashbackAmount > 0:
267
                    cashbackStatus = Store.CB_PENDING
268
            subOrder.cashBackStatus = cashbackStatus
269
            subOrder.cashBackAmount = cashbackAmount
270
            subOrder.cashBackPercentage = percentage
271
        return subOrders
272
 
15947 manish.sha 273
    def _parseOrders(self, orderId, mpOrderId, subTagId, userId, page, orderSuccessUrl, orderObj):
15509 manish.sha 274
        soup = BeautifulSoup(page)
275
        productDetailsMap = {}
276
        paymentFields = soup.findAll(attrs={'class' : 'box_paymentcalculations_row'})
277
        orderDateList = soup.findAll(attrs={'class':'price ord_date'})
15948 manish.sha 278
        placedOn= orderDateList[0].text.strip().replace("\t","").replace("\n","").replace("\r","").replace("  ","")
15509 manish.sha 279
        ordersubtotal=0
280
        ordercluebucks=0
281
        ordershippingcost=0
282
        ordertotal=0
283
 
284
        for val in paymentFields:
285
            for value in val.contents:
286
                if value is not None:
287
                    if 'div' in str(value).strip():
288
                        if 'Subtotal' in value.text.strip():
15981 manish.sha 289
                            ordersubtotal = long(val.contents[3].text.strip().replace("Rs.","").replace(',',''))
16165 manish.sha 290
                            print 'Order SubTotal:- ',ordersubtotal
15509 manish.sha 291
                        if 'Shipping Cost' in value.text.strip():
15981 manish.sha 292
                            ordershippingcost = long(val.contents[3].text.strip().replace("Rs.","").replace(',',''))
16165 manish.sha 293
                            print 'Shipping Cost:- ',ordershippingcost
15509 manish.sha 294
                        if 'Clue' in value.text.strip():
15981 manish.sha 295
                            ordercluebucks = long(val.contents[3].text.strip().replace("Rs.","").replace(',',''))
16165 manish.sha 296
                            print 'Clue bucks:- ',ordercluebucks
15509 manish.sha 297
                        if 'Total' in value.text.strip():
15791 manish.sha 298
                            ordertotal = val.contents[3].text.strip().replace("Rs.","")
299
                            ordertotal = ordertotal.replace(',','')
16165 manish.sha 300
                            print 'Order Total:- ',ordertotal
15791 manish.sha 301
 
302
        if orderObj['0']['is_parent_order'] == 'N':
15947 manish.sha 303
            productDetailsMap = self._getSingleSubOrderMap(mpOrderId, soup, orderObj)
15509 manish.sha 304
        else:
16420 manish.sha 305
            if orderObj['0']['items'].values()[0]['child'] is None:
306
                productDetailsMap = self._getSingleSubOrderMap(mpOrderId, soup, orderObj)
307
            else:
308
                productDetailsMap = self._getMultiSubOrdersMap(mpOrderId, soup, orderObj)
15509 manish.sha 309
 
15791 manish.sha 310
        merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
15509 manish.sha 311
        merchantOrder.placedOn = placedOn
15791 manish.sha 312
        merchantOrder.merchantOrderId = orderObj['0']['order_id']
15509 manish.sha 313
        merchantOrder.paidAmount = ordertotal
314
        totalOrdersAmount = 0
315
        totalDiscount = 0
316
        subOrders= []
16281 manish.sha 317
        if len(productDetailsMap)==0:
318
            print 'Unable to get Sub Orders for Now:- ',orderObj['0']['order_id']
15509 manish.sha 319
        for key in productDetailsMap:
320
            subOrderDetail = productDetailsMap.get(key)
321
            totalOrdersAmount = totalOrdersAmount  + (subOrderDetail['sellingPrice'] * subOrderDetail['quantity'])
322
            totalDiscount = totalDiscount + (subOrderDetail['discount'] * subOrderDetail['quantity'])
323
            subOrder = SubOrder(subOrderDetail['productName'], subOrderDetail['productUrl'], placedOn, subOrderDetail['subtotal'])
324
            subOrder.merchantSubOrderId = key
325
            subOrder.detailedStatus = subOrderDetail['subOrderStatus']
326
            subOrder.imgUrl = subOrderDetail['imgUrl']
327
            subOrder.offerDiscount = subOrderDetail['discount'] * subOrderDetail['quantity']
328
            subOrder.unitPrice = subOrderDetail['sellingPrice']
329
            subOrder.productCode = subOrderDetail['productCode']
330
            subOrder.amountPaid = subOrderDetail['subtotal']
331
            subOrder.quantity = subOrderDetail['quantity']
15791 manish.sha 332
            subOrder.tracingkUrl = subOrderDetail['subOrderTrackingUrl']
16097 manish.sha 333
            dealRank = getDealRank(subOrder.productCode, self.store_id, merchantOrder.userId)
334
            subOrder.dealRank = dealRank.get('rank')
335
            subOrder.rankDesc = dealRank.get('description')
16283 amit.gupta 336
            subOrder.maxNlc = dealRank.get('maxNlc')
337
            subOrder.minNlc = dealRank.get('minNlc')
338
            subOrder.db = dealRank.get('dp')
339
            subOrder.itemStatus = dealRank.get('status')
15509 manish.sha 340
            subOrders.append(subOrder)
341
        merchantOrder.totalAmount = totalOrdersAmount
342
        merchantOrder.discountApplied = totalDiscount
343
        merchantOrder.deliveryCharges = ordershippingcost
344
        merchantOrder.subOrders = self.updateCashbackInSubOrders(subOrders)
345
 
346
        return merchantOrder
347
 
348
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
349
        resp = {}
350
        try:
15791 manish.sha 351
            rawHtmlSoup = BeautifulSoup(rawHtml)
352
            emailId = None
353
            orderObj = None
354
            merchantOrderId = None
355
            for script in rawHtmlSoup.find_all('script'):
356
                if 'orderConfirmation' in script.text:
16274 manish.sha 357
                    print script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0]
15791 manish.sha 358
                    orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
359
                    if merchantOrderId is None:
360
                        merchantOrderId = orderObj['0']['order_id']
361
                        emailId = orderObj['0']['email']
16197 manish.sha 362
            if orderObj is None or merchantOrderId is None:
16226 manish.sha 363
                orderIdDiv = rawHtmlSoup.body.find("div", {'class':'conf_succes'})
364
                if orderIdDiv is None:
365
                    orderIdArt = rawHtmlSoup.body.find("article", {'class':'white'})
366
                    if orderIdArt is None:
367
                        resp['result'] = 'ORDER_NOT_CREATED_UNKNOWN'
368
                        return resp
369
                    else:
370
                        orderIdDiv= orderIdArt.find('p', recursive=False)
371
                        orderIdVal = str(orderIdDiv.text.split(' : ')[1])
372
                        print "Opening Shopclues Login Page"
373
                        login_url = "https://sm.shopclues.com/login"
374
                        br1 = login(login_url)
375
                        orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+orderIdVal+"&status=P")
376
                        orderDetailPage = ungzipResponse(orderDetailPage)
377
                        rawHtmlSoup = BeautifulSoup(orderDetailPage)
378
                        for script in rawHtmlSoup.find_all('script'):
379
                            if 'orderConfirmation' in script.text:
380
                                orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
381
                                if merchantOrderId is None:
382
                                    merchantOrderId = orderObj['0']['order_id']
383
                                    emailId = orderObj['0']['email']
384
                        logoutpage = br1.open("https://sm.shopclues.com/logout")
385
                        print br1.geturl()
386
                else:
387
                    orderIdDiv= orderIdDiv.find('div', recursive=False)
388
                    orderIdVal = str(orderIdDiv.span.text)
389
                    print "Opening Shopclues Login Page"
390
                    login_url = "https://sm.shopclues.com/login"
391
                    br1 = login(login_url)
392
                    orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+orderIdVal+"&status=P")
393
                    orderDetailPage = ungzipResponse(orderDetailPage)
394
                    rawHtmlSoup = BeautifulSoup(orderDetailPage)
395
                    for script in rawHtmlSoup.find_all('script'):
396
                        if 'orderConfirmation' in script.text:
397
                            orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
398
                            if merchantOrderId is None:
399
                                merchantOrderId = orderObj['0']['order_id']
400
                                emailId = orderObj['0']['email']
401
                    logoutpage = br1.open("https://sm.shopclues.com/logout")
402
                    print br1.geturl()
403
 
16275 manish.sha 404
            if type(orderObj['0']['items']) is list:
405
                print "Opening Shopclues Login Page"
406
                login_url = "https://sm.shopclues.com/login"
407
                br1 = login(login_url)
408
                orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+str(merchantOrderId)+"&status=P")
409
                orderDetailPage = ungzipResponse(orderDetailPage)
410
                rawHtmlSoup = BeautifulSoup(orderDetailPage)
411
                for script in rawHtmlSoup.find_all('script'):
412
                    if 'orderConfirmation' in script.text:
413
                        orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
414
                        if merchantOrderId is None:
415
                            merchantOrderId = orderObj['0']['order_id']
416
                            emailId = orderObj['0']['email']
417
                logoutpage = br1.open("https://sm.shopclues.com/logout")
418
                print br1.geturl()
419
 
15509 manish.sha 420
            br = getBrowserObject()
15791 manish.sha 421
            url = ORDER_TRACK_URL +'&order_id=' +str(merchantOrderId)+'&email_id='+ emailId
15509 manish.sha 422
            page = br.open(url)
423
            headers = str(page.info()).split('\n')
424
            page = ungzipResponse(page)
425
            jsonResponse = None
426
            for header in headers:
427
                header = header.split(':')
428
                if header[0] == 'Content-Type' and 'json' in header[1]:
429
                    jsonResponse = json.loads(page)
430
            if jsonResponse is not None:
431
                page = jsonResponse['text']
432
 
16370 manish.sha 433
            merchantOrder = self._parseOrders(orderId, merchantOrderId, subTagId, userId, page, orderSuccessUrl, orderObj) 
15509 manish.sha 434
 
15948 manish.sha 435
            merchantOrder.orderTrackingUrl = ORDER_TRACK_URL_DB + 'order_id=' +str(merchantOrderId)+'&email_id='+ emailId
15509 manish.sha 436
 
437
            if self._saveToOrder(todict(merchantOrder)):
438
                resp['result'] = 'ORDER_CREATED'
439
            else:
440
                resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
441
 
442
            return resp
443
        except:
444
            print "Error occurred"
445
            traceback.print_exc()
446
            resp['result'] = 'ORDER_NOT_CREATED'
16120 manish.sha 447
            return resp
15509 manish.sha 448
 
15791 manish.sha 449
    def parseSingleSubOrder(self, soup, emailId, subOrderId):
450
        orderStatusList = soup.findAll(attrs={'class' : 'price ord_status'})
451
        subOrderStatus = orderStatusList[0].contents[0].strip()
15509 manish.sha 452
        orderDateList = soup.findAll(attrs={'class':'price ord_date'})
16230 manish.sha 453
        placedOn= orderDateList[0].text.strip().replace("\t","").replace("\n","").replace("\r","").replace("  ","")
454
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
455
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)    
15791 manish.sha 456
        firstRow = orderTable.pop(0)
15949 manish.sha 457
        totalColumns = len(firstRow.find_all('th'))
15791 manish.sha 458
        subOrders =[]
459
        count =1   
15509 manish.sha 460
        for orderTr in orderTable:
461
            cols = orderTr.find_all('td')
462
            product_details = cols[0].find_all('a')
463
            #print product_details
464
            productUrl = product_details[0].get('href')
465
            productName = product_details[0].contents[0].strip()
466
            quantity = int(cols[1].text.strip())
15980 manish.sha 467
            sellingPrice = long(cols[2].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 468
            discount = 0
469
            subtotal = 0
470
            if totalColumns == 5:
15949 manish.sha 471
                if cols[3].text.strip()!='-' and 'Rs.' in cols[3].text.strip():
15980 manish.sha 472
                    discount = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 473
                else:
474
                    discount = 0
15980 manish.sha 475
                subtotal = long(cols[4].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 476
            else:
15980 manish.sha 477
                subtotal = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
16151 manish.sha 478
            productPage = fetchResponseUsingProxy(BASE_MURL+productUrl)
479
            productPageSoup = BeautifulSoup(productPage)
15791 manish.sha 480
            productCode = productPageSoup.find('input', {'type':'hidden'})['value']
15509 manish.sha 481
            allproductImageTags = productPageSoup.findAll(attrs={'class' : 'pd-image'})
482
            productImgUrl = ''
483
            if allproductImageTags is not None and len(allproductImageTags)>0:
484
                productImgUrl= allproductImageTags[0].get('style').split("background:url('")[1].split("')no-repeat center")[0].strip()
485
 
486
            subOrder = SubOrder(productName, productUrl, placedOn, subtotal)
15791 manish.sha 487
            subOrder.merchantSubOrderId = str(subOrderId)+'-'+str(count)
15509 manish.sha 488
            subOrder.detailedStatus = subOrderStatus
489
            subOrder.imgUrl = productImgUrl
490
            subOrder.offerDiscount = discount*quantity
491
            subOrder.unitPrice = sellingPrice
492
            subOrder.productCode = productCode
493
            subOrder.amountPaid = subtotal
494
            subOrder.quantity = quantity
15791 manish.sha 495
            subOrder.tracingkUrl = ORDER_TRACK_URL_DB +  'order_id=' +subOrderId+'&email_id='+ emailId
15509 manish.sha 496
            subOrders.append(subOrder)
15791 manish.sha 497
            count = count +1
15509 manish.sha 498
 
499
        subOrders = self.updateCashbackInSubOrders(subOrders)
15791 manish.sha 500
        return subOrders
15509 manish.sha 501
 
15791 manish.sha 502
    def parseMultiSubOrders(self, soup, emailId):
16230 manish.sha 503
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
504
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
16145 manish.sha 505
        firstRow = orderTable.pop(0)
15791 manish.sha 506
        '''
507
        totalColumns = len(firstRow.find_all('td'))
508
 
15509 manish.sha 509
        orderDateList = soup.findAll(attrs={'class':'price ord_date'})
15791 manish.sha 510
        placedOn= orderDateList[0].text.strip().replace("\t","").replace("\n","").replace("  ","")
511
        '''    
15509 manish.sha 512
        subOrders = []
15791 manish.sha 513
        existingOrders = []
15509 manish.sha 514
        for orderTr in orderTable:
515
            cols = orderTr.find_all('td')
516
            product_details = cols[0].find_all('a')
517
            #print product_details
518
            subOrderId= product_details[1].contents[0].strip()
15791 manish.sha 519
            if subOrderId in existingOrders:
520
                continue
521
            else:
522
                existingOrders.append(subOrderId)
523
            '''
15509 manish.sha 524
            productUrl = product_details[0].get('href')
525
            productName = product_details[0].contents[0].strip()
15791 manish.sha 526
            '''
527
            subOrderTrackingParsingUrl = product_details[1].get('href')
528
            #subOrderTrackingUrl = subOrderTrackingParsingUrl.split('order_lookup.details&')[1]
529
            '''
15509 manish.sha 530
            quantity = int(cols[1].text.strip())
531
            sellingPrice = long(cols[2].text.strip().replace("Rs.",""))
15791 manish.sha 532
            discount = 0
533
            subtotal = 0
534
            if totalColumns == 5:
535
                if cols[3].text.strip()!='-' or 'Rs.' in cols[3].text.strip():
536
                    discount = long(cols[3].text.strip().replace("Rs.",""))
537
                else:
538
                    discount = 0
539
                subtotal = long(cols[4].text.strip().replace("Rs.",""))
540
            else:
541
                subtotal = long(cols[3].text.strip().replace("Rs.",""))
542
 
15509 manish.sha 543
            br = getBrowserObject()
544
            productPage = br.open(BASE_MURL+productUrl)
545
            productPageHeaders = str(productPage.info()).split('\n')
546
            productPage = ungzipResponse(productPage)
547
            jsonProductResponse = None
548
            for header in productPageHeaders:
549
                header = header.split(':')
550
                if header[0] == 'Content-Type' and 'json' in header[1]:
551
                    jsonProductResponse = json.loads(productPage)
552
            productPageSoup= None
553
            if jsonProductResponse is not None:
554
                productPageSoup = BeautifulSoup(jsonProductResponse['text'])
555
            else:
556
                productPageSoup = BeautifulSoup(productPage)
15791 manish.sha 557
            productCode = productPageSoup.find('input', {'type':'hidden'})['value']
15509 manish.sha 558
            allproductImageTags = productPageSoup.findAll(attrs={'class' : 'pd-image'})
559
            productImgUrl = ''
560
            if allproductImageTags is not None and len(allproductImageTags)>0:
561
                productImgUrl= allproductImageTags[0].get('style').split("background:url('")[1].split("')no-repeat center")[0].strip()
562
            productDetailsSubMap['productCode']=productCode
563
            productDetailsSubMap['imgUrl']=productImgUrl
15791 manish.sha 564
            '''
16151 manish.sha 565
            orderTrackingPage = fetchResponseUsingProxy(BASE_URL+subOrderTrackingParsingUrl)
566
            orderTrackingPageSoup = BeautifulSoup(orderTrackingPage)
15791 manish.sha 567
            subOrdersDetails = self.parseSingleSubOrder(orderTrackingPageSoup, emailId, subOrderId)
568
            subOrders = list(set(subOrders + subOrdersDetails))
15509 manish.sha 569
 
15791 manish.sha 570
        return subOrders
15509 manish.sha 571
 
572
    def scrapeStoreOrders(self,):
573
        #collectionMap = {'palcedOn':1}
574
        searchMap = {}
575
        collectionMap = {"orderTrackingUrl":1}
576
        orders = self._getActiveOrders(searchMap,collectionMap)
577
        for order in orders:
578
            print "Order", self.store_name, order['orderId'], order['orderTrackingUrl']
16138 manish.sha 579
            url = ORDER_TRACK_URL +'&'+ order['orderTrackingUrl'].split('trackOrder?')[1]
16141 manish.sha 580
            print url
16249 manish.sha 581
            page = None
582
            retry = 1
583
            while retry <=3: 
584
                try: 
585
                    page = fetchResponseUsingProxy(url)
586
                    break
587
                except:
16250 manish.sha 588
                    traceback.print_exc()
16249 manish.sha 589
                    retry = retry + 1
590
 
15509 manish.sha 591
            soup = BeautifulSoup(page)
592
            bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
593
            closed = True
16144 manish.sha 594
            orderIdSpan = soup.body.find("span", {'class':'price ord_no'})
595
            if orderIdSpan is not None:
16143 manish.sha 596
                orderStatusList = soup.findAll(attrs={'class' : 'price ord_status'})
597
                if orderStatusList is not None and len(orderStatusList)>0:
598
                    subOrderId = soup.findAll(attrs={'class':'price ord_no'})[0].text.strip()
599
                    orderStatus = orderStatusList[0].contents[0].strip()
16230 manish.sha 600
                    orderTables = soup.body.findAll("table", {'class':'table product-list'})
16229 manish.sha 601
                    orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
16143 manish.sha 602
                    orderTable.pop(0)
603
                    count = 1
604
                    while count <= len(orderTable):
16160 manish.sha 605
                        subbulk = self.db.merchantOrder.initialize_ordered_bulk_op()
16152 manish.sha 606
                        print 'Sub Order Id', str(subOrderId)+'-'+str(count)
16143 manish.sha 607
                        subOrder =  self._isSubOrderActive(order, str(subOrderId)+'-'+str(count))
608
                        if subOrder is None:
609
                            try:
610
                                subOrders = self.parseSingleSubOrder(soup, order['orderTrackingUrl'].split('email_id=')[1], subOrderId)
611
                                for subOrder in subOrders:
612
                                    if subOrder is None:
613
                                        continue
614
                                    self.db.merchantOrder.update({"orderId":order['orderId']},{'$push':{"subOrders":{"$each":todict([subOrder])}}})
615
                                    print "Added new suborders to Order id - ", order['orderId']
616
                                    closed = False
617
                            except:
16227 manish.sha 618
                                traceback.print_exc()
16143 manish.sha 619
                                pass
16227 manish.sha 620
                            count = count+1
16143 manish.sha 621
                            continue
622
                        elif subOrder['closed']:
16226 manish.sha 623
                            count = count+1
16143 manish.sha 624
                            continue
625
                        else:
16163 manish.sha 626
                            findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": str(subOrderId)+'-'+str(count)}
16143 manish.sha 627
                            updateMap = {}
628
                            updateMap["subOrders.$.detailedStatus"] = orderStatus
629
                            status = self._getStatusFromDetailedStatus(orderStatus) 
630
                            closedStatus = status in [Store.ORDER_DELIVERED, Store.ORDER_CANCELLED]
631
                            if status is not None:
632
                                updateMap["subOrders.$.status"] = status
633
                            if closedStatus:
634
                                #if status is closed then change the paybackStatus accordingly
16155 manish.sha 635
                                print 'Order Closed'
16143 manish.sha 636
                                updateMap["subOrders.$.closed"] = True
637
                                if status == Store.ORDER_DELIVERED:
638
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
639
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_APPROVED
640
                                elif status == Store.ORDER_CANCELLED:
641
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
642
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_CANCELLED
643
                            else:
15791 manish.sha 644
                                closed = False
16155 manish.sha 645
                                print 'Order not Closed'
16161 manish.sha 646
 
16158 manish.sha 647
                            subbulk.find(findMap).update({'$set' : updateMap})
648
                            subresult = subbulk.execute()
649
                            tprint(subresult)
16164 manish.sha 650
                        count = count +1
16156 manish.sha 651
                    bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed,"parseError":False}})
652
                    result = bulk.execute()
653
                    tprint(result)
16143 manish.sha 654
 
655
                else:
656
                    subOrdersList = self.parseMultiSubOrders(soup, order['orderTrackingUrl'].split('email_id=')[1])
657
                    for subOrderObj in subOrdersList:
16159 manish.sha 658
                        subbulk1 = self.db.merchantOrder.initialize_ordered_bulk_op()
16143 manish.sha 659
                        subOrder =  self._isSubOrderActive(order, subOrderObj.merchantSubOrderId)
660
                        if subOrder is None:
661
                            self.db.merchantOrder.update({"orderId":order['orderId']},{'$push':{"subOrders":{"$each":todict([subOrderObj])}}})
662
                            print "Added new suborders to Order id - ", order['orderId']
663
                            closed = False
664
                            continue
665
                        elif subOrder['closed']:
666
                            continue
15791 manish.sha 667
                        else:
16143 manish.sha 668
                            findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": subOrderId}
669
                            updateMap = {}
670
                            updateMap["subOrders.$.detailedStatus"] = subOrderObj.detailedStatus
671
                            status = self._getStatusFromDetailedStatus(orderStatus) 
672
                            closedStatus = status in [Store.ORDER_DELIVERED, Store.ORDER_CANCELLED]
673
                            if status is not None:
674
                                updateMap["subOrders.$.status"] = status
675
                            if closedStatus:
676
                                #if status is closed then change the paybackStatus accordingly
677
                                updateMap["subOrders.$.closed"] = True
678
                                if status == Store.ORDER_DELIVERED:
679
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
680
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_APPROVED
681
                                elif status == Store.ORDER_CANCELLED:
682
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
683
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_CANCELLED
684
                            else:
685
                                closed = False
16159 manish.sha 686
                            subbulk1.find(findMap).update({'$set' : updateMap})
687
                            subresult1 = subbulk1.execute()
688
                            tprint(subresult1)
16156 manish.sha 689
                    bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed,"parseError":False}})
690
                    result = bulk.execute()
691
                    tprint(result)
15509 manish.sha 692
            else:
16143 manish.sha 693
                print 'Soup Object not found for this Order', order['orderId'], order['orderTrackingUrl']
694
                continue      
15791 manish.sha 695
 
696
    '''
697
    def getTrackingUrls(self, userId):
698
        missingOrderUrls = ['https://sm.shopclues.com/myaccount','https://sm.shopclues.com/myorders']
699
        return missingOrderUrls
15509 manish.sha 700
 
15791 manish.sha 701
    def parseMyProfileForEmailId(self, userId, url, rawhtml):
702
        profileSoup = BeautifulSoup(rawhtml)
703
        if profileSoup.find('input', {'name':'user_email'}) is not None:
704
            emailId = profileSoup.find('input', {'name':'user_email'})['value']
705
            if emailId is not None and emailId.strip() !='':
706
                mc = MemCache()
707
                mc.set(str(userId), emailId, 600)
708
                return 'EMAIL_SET_SUCCESS'
709
            else:
710
                return 'EMAIL_NOT_FOUND'
711
        else:
712
            return 'EMAIL_NOT_FOUND'
15509 manish.sha 713
 
15791 manish.sha 714
    def parseMyOrdersForEmailId(self, userId, url, rawhtml):
715
        myOrdersPageSoup = BeautifulSoup(rawhtml)
716
        if myOrdersPageSoup.find('a', {'class':'detail'}) is not None:
717
            emailId = myOrdersPageSoup.find('a', {'class':'detail'})['href'].split('&')[1].split('=')[1]
718
            mc = MemCache()
719
            mc.set(str(userId), emailId, 600)
720
            return 'EMAIL_SET_SUCCESS'
721
        else:
722
            return 'EMAIL_NOT_FOUND'
723
    '''        
724
 
16420 manish.sha 725
def to_py_date(java_timestamp):
16424 manish.sha 726
    date = datetime.fromtimestamp(java_timestamp)
16420 manish.sha 727
    return date       
15791 manish.sha 728
 
15509 manish.sha 729
def todict(obj, classkey=None):
730
    if isinstance(obj, dict):
731
        data = {}
732
        for (k, v) in obj.items():
733
            data[k] = todict(v, classkey)
734
        return data
735
    elif hasattr(obj, "_ast"):
736
        return todict(obj._ast())
737
    elif hasattr(obj, "__iter__"):
738
        return [todict(v, classkey) for v in obj]
739
    elif hasattr(obj, "__dict__"):
740
        data = dict([(key, todict(value, classkey)) 
741
            for key, value in obj.__dict__.iteritems() 
742
            if not callable(value) and not key.startswith('_')])
743
        if classkey is not None and hasattr(obj, "__class__"):
744
            data[classkey] = obj.__class__.__name__
745
        return data
746
    else:
16226 manish.sha 747
        return obj
748
 
749
def login(url):
750
    br = getBrowserObject()
16235 manish.sha 751
    br.set_proxies({"http": "us-il.proxymesh.com:31280"})
16226 manish.sha 752
    br.open(url)
753
    response = br.open(url)
754
    ungzipResponseBr(response, br)
755
    #html = response.read()
756
    #print html
757
    br.select_form(nr=0)
758
    br.form['user'] = "imanthetester@gmail.com"
759
    br.form['password'] = "$Dl8uk"
760
    response = br.submit()
761
    print "********************"
762
    print "Attempting to Login"
763
    print "********************"
764
    #ungzipResponse(response, br)
765
    return br
15791 manish.sha 766
 
16226 manish.sha 767
def ungzipResponseBr(r,b):
768
    headers = r.info()
769
    if headers['Content-Encoding']=='gzip':
770
        import gzip
771
        print "********************"
772
        print "Deflating gzip response"
773
        print "********************"
774
        gz = gzip.GzipFile(fileobj=r, mode='rb')
775
        html = gz.read()
776
        gz.close()
777
        headers["Content-type"] = "text/html; charset=utf-8"
778
        r.set_data( html )
779
        b.set_response(r)    
780
 
15509 manish.sha 781