Subversion Repositories SmartDukaan

Rev

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