Subversion Repositories SmartDukaan

Rev

Rev 14847 | Rev 14861 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 14847 Rev 14854
Line 1... Line 1...
1
'''
1
'''
2
Created on Jan 15, 2015
2
Created on Jan 15, 2015
3
 
3
 
4
@author: amit
4
@author: amit
5
'''
5
'''
6
from BeautifulSoup import BeautifulSoup
6
from bs4 import BeautifulSoup
7
from bson.binary import Binary
7
from bson.binary import Binary
8
from datetime import datetime, date, timedelta
8
from datetime import datetime, date, timedelta
9
from dtr import main
9
from dtr import main
10
from dtr.dao import AffiliateInfo, Order, SubOrder
10
from dtr.dao import AffiliateInfo, Order, SubOrder
11
from dtr.main import getBrowserObject, ScrapeException, getStore, ParseException, \
11
from dtr.main import getBrowserObject, ScrapeException, getStore, ParseException, \
Line 19... Line 19...
19
import pymongo
19
import pymongo
20
import re
20
import re
21
import time
21
import time
22
import traceback
22
import traceback
23
import urllib
23
import urllib
-
 
24
from urlparse import urlparse, parse_qs
24
 
25
 
25
USERNAME='profittill2@gmail.com'
26
USERNAME='profittill2@gmail.com'
26
PASSWORD='spice@2020'
27
PASSWORD='spice@2020'
27
AFFILIATE_URL='http://affiliate.snapdeal.com'
28
AFFILIATE_URL='http://affiliate.snapdeal.com'
28
POST_URL='https://api-p03.hasoffers.com/v3/Affiliate_Report.json'
29
POST_URL='https://api-p03.hasoffers.com/v3/Affiliate_Report.json'
Line 72... Line 73...
72
    def _getLastSaleDate(self,):
73
    def _getLastSaleDate(self,):
73
        lastDaySaleObj = self.db.lastDaySale.find_one({"storeId":self.store_id})
74
        lastDaySaleObj = self.db.lastDaySale.find_one({"storeId":self.store_id})
74
        if lastDaySaleObj is None:
75
        if lastDaySaleObj is None:
75
            return datetime.min
76
            return datetime.min
76
        
77
        
-
 
78
    
-
 
79
    
-
 
80
    def _parseB(self, orderId, subTagId, userId, page, orderSuccessUrl):
-
 
81
        soup = BeautifulSoup(page)
-
 
82
 
-
 
83
        orderDetailContainerDivs = soup.body.find("div", {'class':'cardLayoutWrap'}).findAll('div', recursive=False)
-
 
84
        orderDetailDiv = orderDetailContainerDivs.pop(0)
-
 
85
        paymentDetailDiv  = orderDetailContainerDivs.pop(0)
-
 
86
        subOrders = orderDetailContainerDivs
-
 
87
        
-
 
88
        placedOn = orderDetailDiv.span.text.split(':')[1].strip()
-
 
89
        merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
-
 
90
        merchantOrder.placedOn = placedOn
-
 
91
        merchantOrder.merchantOrderId = parse_qs(urlparse(orderSuccessUrl).query)['order'][0]
-
 
92
 
-
 
93
        paymentDivs = paymentDetailDiv.findAll('div', recursive=False)
-
 
94
        paymentDivs.pop(0)
-
 
95
        for orderTr in paymentDivs:
-
 
96
            orderTrString = str(orderTr)
-
 
97
            if "Total Amount Paid" in orderTrString:
-
 
98
                amountPaid = orderTr.div.find('div', {'class':'detailBlock'}).text.strip()
-
 
99
                merchantOrder.paidAmount = int(re.findall(r'\d+', amountPaid)[0])
-
 
100
            elif "Total Amount" in orderTrString:
-
 
101
                merchantOrder.totalAmount = re.findall(r'\d+', orderTrString)[0]
-
 
102
            elif "Delivery Charges" in orderTrString:
-
 
103
                merchantOrder.deliveryCharges = re.findall(r'\d+', orderTrString)[0]
-
 
104
            elif "Discount Applied" in orderTrString:
-
 
105
                merchantOrder.discountApplied = re.findall(r'\d+', orderTrString)[0]
-
 
106
            elif "Offer Discount" in orderTrString:
-
 
107
                merchantOrder.discountApplied = re.findall(r'\d+', orderTrString)[0]
-
 
108
 
-
 
109
        merchantSubOrders = []
-
 
110
        for subOrderElement in subOrders:
-
 
111
            subOrder = self.parseSubOrderB(subOrderElement, placedOn)                           
-
 
112
            merchantSubOrders.append(subOrder)
-
 
113
        merchantOrder.subOrders = merchantSubOrders
-
 
114
        return merchantOrder
-
 
115
    
77
    def _parse(self, orderId, subTagId, userId, page, orderSuccessUrl):
116
    def _parse(self, orderId, subTagId, userId, page, orderSuccessUrl):
78
        
117
        
79
        #page=page.decode("utf-8")
118
        #page=page.decode("utf-8")
80
        soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
119
        soup = BeautifulSoup(page)
81
        #orderHead = soup.find(name, attrs, recursive, text)
120
        #orderHead = soup.find(name, attrs, recursive, text)
82
        sections = soup.findAll("section")
121
        sections = soup.findAll("section")
83
        
122
        
84
        #print sections
123
        #print sections
85
        
124
        
Line 200... Line 239...
200
                elif "Tracking No" in line:
239
                elif "Tracking No" in line:
201
                    subOrder.trackingNumber = line.split(":")[1].strip()
240
                    subOrder.trackingNumber = line.split(":")[1].strip()
202
            subOrders.append(subOrder)
241
            subOrders.append(subOrder)
203
        return subOrders
242
        return subOrders
204
 
243
 
-
 
244
    def parseSubOrderB(self, subOrderElement, placedOn):
-
 
245
        subOrders = []
-
 
246
        prodDivs = subOrderElement.findAll('div', recursive=False)
-
 
247
        prodDetailDiv = prodDivs[1].findAll('div', recursive=False)
-
 
248
        
-
 
249
        offerDiscount = 0
-
 
250
        deliveryCharges = None
-
 
251
        amountPaid = 0
-
 
252
        sdCash = 0
-
 
253
        unitPrice = 0
-
 
254
 
-
 
255
        paymentDivs = prodDivs[2].findAll('div', recursive=False)
-
 
256
        for paymentDiv in paymentDivs:
-
 
257
            strPaymentDiv = str(paymentDiv)
-
 
258
            if "Unit Price" in strPaymentDiv:
-
 
259
                unitPrice = int(re.findall(r'\d+', strPaymentDiv)[0])
-
 
260
            if "Offer Discount" in strPaymentDiv:
-
 
261
                offerDiscount = int(re.findall(r'\d+', strPaymentDiv)[0])
-
 
262
            elif "SD Cash:" in strPaymentDiv:
-
 
263
                sdCash =   int(re.findall(r'\d+', strPaymentDiv)[0])
-
 
264
            elif "Delivery Charges" in strPaymentDiv:
-
 
265
                deliveryCharges =   int(re.findall(r'\d+', strPaymentDiv)[0])
-
 
266
            elif "Subtotal" in strPaymentDiv:
-
 
267
                amountPaid =   int(re.findall(r'\d+', paymentDiv.find('div', {'class':'itemPriceDetail'}).text)[0])
-
 
268
        
-
 
269
        amount = unitPrice - offerDiscount - sdCash
-
 
270
        
-
 
271
        imgDiv = prodDetailDiv[0]
-
 
272
        otherDiv = prodDetailDiv[1]
-
 
273
        productTitle = otherDiv.find('div',{'class':'orderName'}).text.strip()
-
 
274
 
-
 
275
        productUrl = imgDiv.a['href']
-
 
276
        subOrder = SubOrder(productTitle, productUrl, placedOn, amountPaid)
-
 
277
        
-
 
278
        subOrder.detailedStatus = otherDiv.find('div',{'class':'orderStatus'}).span.text.strip()
-
 
279
        deliveryStatus = otherDiv.find('div',{'class':'orderDelivery'})
-
 
280
        if deliveryStatus is not None:
-
 
281
            delString = deliveryStatus.text.strip()
-
 
282
            arr = delString.split(':')
-
 
283
            if "On" in arr[0]:
-
 
284
                subOrder.deliveredOn = arr[1].strip()
-
 
285
            elif "Exp. Delivery by" in arr[0]:
-
 
286
                subOrder.estimatedDeliveryDate = arr[1].strip()
-
 
287
            else:
-
 
288
                subOrder.estimatedShippingDate = arr[1].strip()
-
 
289
 
-
 
290
        subOrder.imgUrl = imgDiv.a.img['src']
-
 
291
        subOrder.productCode = re.findall(r'\d+$', productUrl)[0]
-
 
292
        subOrder.deliveryCharges = deliveryCharges
-
 
293
        subOrder.offerDiscount = offerDiscount
-
 
294
        subOrder.unitPrice = int(unitPrice)
-
 
295
        cashbackStatus = Store.CB_NA
-
 
296
        cashbackAmount = 0
-
 
297
        percentage = 0
-
 
298
        if amountPaid > 0:
-
 
299
            (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, amount)
-
 
300
            if cashbackAmount > 0:
-
 
301
                cashbackStatus = Store.CB_PENDING
-
 
302
        subOrder.cashBackStatus = cashbackStatus
-
 
303
        subOrder.cashBackAmount = cashbackAmount
-
 
304
        subOrder.cashBackPercentage = percentage
-
 
305
        
-
 
306
        
-
 
307
        courierDet = subOrderElement.find('div', {'class':'courierDetail'})
-
 
308
        if courierDet is not None:
-
 
309
            subOrder.courierName = courierDet.span.text.strip()
-
 
310
        trackingDet = subOrderElement.find('div', {'class':'trackingNo'})
-
 
311
        if trackingDet is not None:
-
 
312
            subOrder.trackingUrl = trackingDet.span.a['href']
-
 
313
            subOrder.trackingNumber = trackingDet.span.a.text.strip()
-
 
314
 
-
 
315
        subOrders.append(subOrder)
-
 
316
        return subOrder
-
 
317
 
205
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
318
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
206
                    #print merchantOrder
319
                    #print merchantOrder
207
        resp = {}
320
        resp = {}
208
        try:
321
        try:
209
            br = getBrowserObject()
322
            br = getBrowserObject()
210
            url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]
323
            url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]
211
            page = br.open(url)
324
            page = br.open(url)
212
            page = ungzipResponse(page)
325
            page = ungzipResponse(page)
-
 
326
            try:
-
 
327
                merchantOrder = self._parseB(orderId, subTagId, userId, page, orderSuccessUrl)
-
 
328
            except:
213
            merchantOrder = self._parse(orderId, subTagId, userId, page, orderSuccessUrl)
329
                merchantOrder = self._parse(orderId, subTagId, userId, page, orderSuccessUrl)
-
 
330
            
214
            merchantOrder.orderTrackingUrl = url
331
            merchantOrder.orderTrackingUrl = url
215
               
332
               
216
            if self._saveToOrder(todict(merchantOrder)):
333
            if self._saveToOrder(todict(merchantOrder)):
217
                resp['result'] = 'ORDER_CREATED'
334
                resp['result'] = 'ORDER_CREATED'
218
            else:
335
            else:
Line 339... Line 456...
339
            except:
456
            except:
340
                tprint("Could not update " + str(order['orderId']) + "For store " + self.getName())
457
                tprint("Could not update " + str(order['orderId']) + "For store " + self.getName())
341
                self.db.merchantOrder.update({"orderId":order['orderId']}, {"$set":{"parseError":True}})
458
                self.db.merchantOrder.update({"orderId":order['orderId']}, {"$set":{"parseError":True}})
342
                traceback.print_exc()                
459
                traceback.print_exc()                
343
            
460
            
-
 
461
    def tryBParsing(self, order, soup):
-
 
462
        orderDetailContainerDivs = soup.body.find("div", {'class':'cardLayoutWrap'}).findAll('div', recursive=False)
-
 
463
        orderDetailDiv = orderDetailContainerDivs.pop(0)
-
 
464
        placedOn = orderDetailDiv.span.text.split(':')[1].strip()
-
 
465
        
-
 
466
        orderDetailContainerDivs.pop(0)
-
 
467
        
-
 
468
        subOrders = orderDetailContainerDivs
-
 
469
        bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
-
 
470
        closed = True
-
 
471
        for subOrderElement in subOrders:
-
 
472
            prodDivs = subOrderElement.findAll('div', recursive=False)
-
 
473
            merchantSubOrderId = prodDivs[0].text.split(':')[1].strip()
-
 
474
            prodDetailDiv = prodDivs[1].findAll('div', recursive=False)
-
 
475
            imgDiv = prodDetailDiv[0]
-
 
476
            otherDiv = prodDetailDiv[1]
-
 
477
            
-
 
478
            subOrder = None
-
 
479
            breakFlag = False
-
 
480
            
-
 
481
            div = None
-
 
482
            divStr = str(div)
-
 
483
            divStr = divStr.replace("\n","").replace("\t", "")
-
 
484
            updateMap = {}
-
 
485
            for line in divStr.split("<br />"):
-
 
486
                if "Suborder ID" in line:
-
 
487
                    merchantSubOrderId = re.findall(r'\d+', line)[0]
-
 
488
                    #break if suborder is inactive   
-
 
489
                    subOrder =  self._isSubOrderActive(order, merchantSubOrderId)
-
 
490
                    if subOrder is None:
-
 
491
                        subOrders = self.parseSubOrder(subOrderElement, placedOn)
-
 
492
                        self.db.merchantOrder.update({"orderId":order['orderId']},{'$push':{"subOrders":{"$each":todict(subOrders)}}})
-
 
493
                        print "Added new suborders to Order id - " + order['orderId']
-
 
494
                        closed = False
-
 
495
                        breakFlag = True
-
 
496
                        break
-
 
497
                    elif subOrder['closed']:
-
 
498
                        breakFlag = True
-
 
499
                        break
-
 
500
                    else: 
-
 
501
                        findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": merchantSubOrderId}
-
 
502
                elif "Status :" in line:
-
 
503
                    detailedStatus = re.findall('>(.*?)</span>', line, re.IGNORECASE)[0]
-
 
504
                    updateMap["subOrders.$.detailedStatus"] = detailedStatus
-
 
505
                    status = self._getStatusFromDetailedStatus(detailedStatus) 
-
 
506
                    closedStatus = status in [Store.ORDER_DELIVERED, Store.ORDER_CANCELLED]
-
 
507
                    updateMap["subOrders.$.status"] = status
-
 
508
                    if detailedStatus == 'Closed For Vendor Reallocation':
-
 
509
                        #if it is more than 6hours mark closed.
-
 
510
                        closeAt = subOrder.get("closeAt") 
-
 
511
                        if closeAt is None:
-
 
512
                            closeAt = datetime.now() + timedelta(hours=6)
-
 
513
                            updateMap["subOrders.$.closeAt"] = datetime.strftime(closeAt,"%Y-%m-%d %H:%M:%S")
-
 
514
                        else:
-
 
515
                            closeAt = datetime.strptime(closeAt,"%Y-%m-%d %H:%M:%S")
-
 
516
                            if datetime.now() > closeAt:
-
 
517
                                closedStatus = True
-
 
518
                            
-
 
519
                            
-
 
520
                    if closedStatus:
-
 
521
                        #if status is closed then change the paybackStatus accordingly
-
 
522
                        updateMap["subOrders.$.closed"] = True
-
 
523
                        if status == Store.ORDER_DELIVERED:
-
 
524
                            if subOrder.get("cashBackStatus") == Store.CB_PENDING:
-
 
525
                                updateMap["subOrders.$.cashBackStatus"] = Store.CB_APPROVED
-
 
526
                        elif status == Store.ORDER_CANCELLED:
-
 
527
                            if subOrder.get("cashBackStatus") == Store.CB_PENDING:
-
 
528
                                updateMap["subOrders.$.cashBackStatus"] = Store.CB_CANCELLED
-
 
529
                            
-
 
530
                    else:
-
 
531
                        closed = False
-
 
532
                elif "Est. Shipping Date" in line:
-
 
533
                    estimatedShippingDate = line.split(":")[1].strip()
-
 
534
                    updateMap["subOrders.$.estimatedShippingDate"] = estimatedShippingDate
-
 
535
                elif "Est. Delivery Date" in line:
-
 
536
                    estimatedDeliveryDate = line.split(":")[1].strip()
-
 
537
                    updateMap["subOrders.$.estimatedDeliveryDate"] = estimatedDeliveryDate
-
 
538
                elif "Courier Name" in line:
-
 
539
                    courierName = line.split(":")[1].strip()
-
 
540
                    updateMap["subOrders.$.courierName"] = courierName
-
 
541
                elif "Tracking No" in line:
-
 
542
                    trackingNumber = line.split(":")[1].strip()
-
 
543
                    updateMap["subOrders.$.trackingNumber"] = trackingNumber
-
 
544
 
-
 
545
            if breakFlag:
-
 
546
                continue
-
 
547
                    
-
 
548
            bulk.find(findMap).update({'$set' : updateMap})
-
 
549
        bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed,"parseError":False}})
-
 
550
        result = bulk.execute()
-
 
551
        tprint(result)
-
 
552
 
344
    
553
    
345
    def _saveToAffiliate(self, offers):
554
    def _saveToAffiliate(self, offers):
346
        collection = self.db.snapdealOrderAffiliateInfo
555
        collection = self.db.snapdealOrderAffiliateInfo
347
        mcollection = self.db.merchantOrder
556
        mcollection = self.db.merchantOrder
348
        for offer in offers:
557
        for offer in offers:
Line 405... Line 614...
405
    return urllib.urlencode(parameters)
614
    return urllib.urlencode(parameters)
406
 
615
 
407
def main():
616
def main():
408
    #print todict([1,2,"3"])
617
    #print todict([1,2,"3"])
409
    store = getStore(3)
618
    store = getStore(3)
410
    print store.parseOrderRawHtml(3221, "32323", 2, "323243", "https://m.snapdeal.com/purchaseMobileComplete?code=8943993fa3678d480157e7ed4292ccd5&order=5810418949")
619
    store.parseOrderRawHtml(33222, "32323", 2, "323243", "https://m.snapdeal.com/purchaseMobileComplete?code=561009a4a0c043e2f537f558c8531580&order=5822820967")
411
    #store.scrapeStoreOrders()
620
    #store.scrapeStoreOrders()
412
    #store._isSubOrderActive(8, "5970688907")
621
    #store._isSubOrderActive(8, "5970688907")
413
    #store.scrapeAffiliate()
622
    #store.scrapeAffiliate()
414
    #store.scrapeStoreOrders()
623
    #store.scrapeStoreOrders()
415
 
624