Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
13774 amit.gupta 1
# coding=utf-8
13569 amit.gupta 2
'''
3
Created on Jan 15, 2015
4
 
5
@author: amit
6
'''
13774 amit.gupta 7
from base64 import encode
8
from bs4 import BeautifulSoup
14650 amit.gupta 9
from datetime import datetime, timedelta
10
from dtr.dao import Order, SubOrder, AmazonAffiliateInfo
14464 amit.gupta 11
from dtr.main import getStore, Store as MStore, ParseException, getBrowserObject, \
14624 amit.gupta 12
    ungzipResponse, tprint
14650 amit.gupta 13
from dtr.sources.flipkart import todict, AFF_REPORT_URL
14749 amit.gupta 14
from dtr.utils.utils import fetchResponseUsingProxy
14162 amit.gupta 15
from paramiko import sftp
16
from paramiko.client import SSHClient
17
from paramiko.sftp_client import SFTPClient
14650 amit.gupta 18
import base64
19
import gzip
14624 amit.gupta 20
import mechanize
14285 amit.gupta 21
import os.path
14162 amit.gupta 22
import paramiko
13774 amit.gupta 23
import re
14033 amit.gupta 24
import time
13809 amit.gupta 25
import traceback
14650 amit.gupta 26
import urllib2
13774 amit.gupta 27
 
28
ORDER_REDIRECT_URL = 'https://www.amazon.in/gp/css/summary/edit.html?orderID=%s'
13810 amit.gupta 29
ORDER_SUCCESS_URL = 'https://www.amazon.in/gp/buy/spc/handlers/static-submit-decoupled.html'
13823 amit.gupta 30
THANKYOU_URL = 'https://www.amazon.in/gp/buy/thankyou/handlers/display.html'
14624 amit.gupta 31
AMAZON_AFF_URL = 'https://assoc-datafeeds-eu.amazon.com/datafeed/listReports'
14650 amit.gupta 32
AMAZON_AFF_FILE_URL = 'https://assoc-datafeeds-eu.amazon.com/datafeed/getReport?filename=saholic-21-orders-report-%s.tsv.gz'
13774 amit.gupta 33
class Store(MStore):
13821 amit.gupta 34
 
14032 amit.gupta 35
    orderStatusRegexMap = { MStore.ORDER_PLACED : ['ordered from', 'not yet dispatched','dispatching now', 'preparing for dispatch'],
14064 amit.gupta 36
                            MStore.ORDER_SHIPPED : ['dispatched on','dispatched', 'on the way', 'out for delivery', 'Out for delivery'],
14032 amit.gupta 37
                            MStore.ORDER_CANCELLED : ['return complete', 'refunded', 'cancelled'],
38
                            MStore.ORDER_DELIVERED : ['delivered']
13821 amit.gupta 39
                           }
13774 amit.gupta 40
 
41
    def __init__(self,store_id):
42
        super(Store, self).__init__(store_id)
43
 
44
    def getName(self):
14749 amit.gupta 45
        return "amazon"
13774 amit.gupta 46
 
14202 amit.gupta 47
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl, insert=False):
13796 amit.gupta 48
        resp = {}
13821 amit.gupta 49
        if ORDER_SUCCESS_URL in orderSuccessUrl or THANKYOU_URL in orderSuccessUrl:
13774 amit.gupta 50
            try:
51
                soup = BeautifulSoup(rawHtml)
14608 amit.gupta 52
                try:
53
                    orderUrl = soup.find('div', {"id":"thank-you-box-wrapper"}).div.findAll('div', recursive=False)[1].a['href']
54
                    merchantOrderId = re.findall(r'.*&oid=(.*)&?.*?', orderUrl)[0]
55
                except:
56
                    merchantOrderId = soup.find(id="orders-list").div.span.b.text
14699 amit.gupta 57
                order = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl, True)
14211 amit.gupta 58
                order.orderSuccessUrl = ORDER_REDIRECT_URL % (merchantOrderId)
59
                order.merchantOrderId = merchantOrderId
14291 amit.gupta 60
                order.requireDetail = True
14698 amit.gupta 61
                order.status = 'html_required'
14297 amit.gupta 62
                order.closed = None
14312 amit.gupta 63
                if self._saveToOrder(todict(order)):
64
                    resp['result'] = 'ORDER_CREATED'
65
                    resp["url"] = ORDER_REDIRECT_URL % (merchantOrderId)
66
                    resp["htmlRequired"] = True
67
                    resp['orderId'] = orderId
68
                else:
69
                    resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
70
 
13796 amit.gupta 71
                return resp
13774 amit.gupta 72
            except:
14312 amit.gupta 73
                resp["result"] = 'ORDER_NOT_CREATED'
13796 amit.gupta 74
                return resp
13774 amit.gupta 75
 
76
        else:
13781 amit.gupta 77
            try:
14722 amit.gupta 78
                mo = self.db.merchantOrder.find_one({"orderId":orderId})
79
                if mo is not None:
14749 amit.gupta 80
                    merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl, False)
14722 amit.gupta 81
                    merchantOrder.createdOn = mo.get("createdOn")
82
                    merchantOrder.createdOnInt =  mo.get("createdOnInt")
83
                else:
14749 amit.gupta 84
                    merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
14464 amit.gupta 85
                soup = BeautifulSoup(rawHtml)
86
                try:
87
                    self.parseOldStlye(merchantOrder, soup)
88
                except:
14545 amit.gupta 89
                    try:
14566 amit.gupta 90
                        traceback.print_exc()
14545 amit.gupta 91
                        self.parseNewStlye(merchantOrder, soup)
92
                    except:
14566 amit.gupta 93
                        traceback.print_exc()
14545 amit.gupta 94
                        self.parseCancelled(merchantOrder, soup)
14319 amit.gupta 95
                resp['result'] = 'ORDER_CREATED'
96
                return resp    
13781 amit.gupta 97
            except:
14771 amit.gupta 98
                try:
99
                    self.parserest(soup)
100
                    resp['result'] = 'PARSED_ORDER_NOT_CREATED'
101
                    return resp    
102
                except:
103
                    order = self.db.merchantOrder.find_one({"orderId":orderId})
104
                    if order is not None:
105
                        self.db.merchantOrder.update({"orderId":orderId}, {"$set":{"status":"parse_failed"}})
106
                    print "Error occurred"
107
                    resp['result'] = 'ORDER_NOT_CREATED'
108
                    traceback.print_exc()
109
                    return resp    
13774 amit.gupta 110
 
13868 amit.gupta 111
    #This should be exposed from api for specific sources
112
    def scrapeStoreOrders(self):
14624 amit.gupta 113
        orders = self.db.merchantOrder.find({"storeId":1, "closed":False, "subOrders.closed":False, "subOrders.trackingUrl":{"$exists":True}})
114
        for merchantOrder in orders:
115
            try:
116
                bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
117
                closed = True
118
                map1 = {}
119
                for subOrder in merchantOrder.get("subOrders"):
120
                    if subOrder.get("closed"):
121
                        continue
122
                    elif subOrder.get("trackingUrl") is None:
123
                        closed = False
124
                        continue
125
                    findMap = {"orderId":merchantOrder.get("orderId"), "subOrders.merchantSubOrderId":subOrder.get("merchantSubOrderId")} 
126
                    trackingUrl = subOrder.get("trackingUrl")
127
                    if not map1.has_key(trackingUrl):
14749 amit.gupta 128
                        map1[trackingUrl] = self.parseTrackingUrl(trackingUrl)
14624 amit.gupta 129
                    newOrder = map1.get(trackingUrl)
130
                    newOrder['cashBackStatus'] = subOrder.get('cashBackStatus')
131
                    updateMap = self.getUpdateMap(newOrder)
132
                    print findMap, "\n", updateMap
133
                    bulk.find(findMap).update({'$set' : updateMap})
134
                    closed = closed and newOrder['closed']
14697 amit.gupta 135
                    bulk.find({"orderId":merchantOrder.get("orderId")}).update({"$set":{"closed":closed, "parseError":False}})
14624 amit.gupta 136
                result = bulk.execute()
137
                tprint(result)
138
            except:
139
                tprint("Could not update " + str(merchantOrder['orderId']))
14692 amit.gupta 140
                self.db.merchantOrder.update({"orderId":merchantOrder['orderId']}, {"$set":{"parseError":True}})
14624 amit.gupta 141
                traceback.print_exc()
142
 
14608 amit.gupta 143
 
144
 
14771 amit.gupta 145
    def parserest(self, soup):
146
        print "Hi"
147
        if soup.find('h1'):
148
            print "OK"
14608 amit.gupta 149
 
14464 amit.gupta 150
    def parseOldStlye(self, merchantOrder, soup):
151
        merchantOrder.orderTrackingUrl = merchantOrder.orderSuccessUrl
152
        table = soup.body.findAll("table", recursive=False)[1]
153
        #print table
154
        tables = table.tr.td.findAll("table", recursive=False)
155
        for tr in tables[2].findAll("tr"):
156
            boldElement = tr.td.b
157
            if "Order Placed" in str(boldElement):
158
                merchantOrder.placedOn = boldElement.next_sibling.strip()
159
            if "order number" in str(boldElement):
160
                merchantOrder.merchantOrderId = boldElement.next_sibling.strip()
161
            if "Order Total" in str(boldElement):
162
                merchantOrder.paidAmount = int(float(boldElement.find('span').contents[-1].replace(',','')))
163
        anchors = table.tr.td.findAll("a", recursive=False)
164
        paymentAnchor = anchors.pop(-1)
165
 
166
        count = 0
167
        subOrders = []
168
        merchantOrder.subOrders = subOrders
169
        counter = 0 
170
        for anchor in anchors:
171
            count += 1
172
            tab = anchor.next_sibling
173
            status = MStore.ORDER_PLACED
174
            subStr = "Delivery #" + str(count) + ":"
175
            if subStr in  tab.find("b").text:
176
                detailedStatus = tab.find("b").text.replace(subStr, '').strip()
177
 
178
            tab = tab.next_sibling.next_sibling
179
            trs = tab.find("table").find('tbody').findAll("tr", recursive = False)
180
 
181
            estimatedDelivery = trs[0].td.find("b").next_sibling.strip()
182
 
183
            orderItemTrs = trs[1].findAll("td", recursive=False)[1].table.tbody.findAll("tr", recursive = False)
184
            i = -1
185
            for orderItemTr in orderItemTrs:
186
                i += 1
187
                if i%2 == 0:
188
                    continue
189
                counter += 1
190
                quantity =  int(re.findall(r'\d+', orderItemTr.td.contents[0])[0])
191
 
192
                productUrl = orderItemTr.td.contents[1].a["href"]
193
                productTitle = orderItemTr.td.contents[1].a.text
194
 
195
                unitPrice = int(float(orderItemTr.findAll('td')[1].span.text.replace('Rs. ','').replace(',','')))
196
 
197
 
198
                subOrder = SubOrder(productTitle, productUrl, merchantOrder.placedOn, unitPrice*quantity, status, quantity)
199
                subOrder.merchantSubOrderId = str(counter) + " of " + merchantOrder.merchantOrderId
200
                subOrder.estimatedDeliveryDate = estimatedDelivery
14722 amit.gupta 201
                estDlvyTime = datetime.strptime(estimatedDelivery.split('-')[0].strip(), "%A %d %B %Y")
202
                createdOn = datetime.fromtimestamp(merchantOrder.createdOnInt)
203
                subOrder.trackAfter = int(time.mktime(max(estDlvyTime-timedelta(days=4),createdOn + timedelta(days=3)).timetuple()))
14464 amit.gupta 204
                subOrder.productCode = productUrl.split('/')[5]
205
                subOrder.detailedStatus = detailedStatus
206
                (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, unitPrice*quantity)
207
                cashbackStatus = Store.CB_PENDING
208
                if cashbackAmount <= 0:
209
                    cashbackStatus = Store.CB_NA
210
                subOrder.cashBackStatus = cashbackStatus
211
                subOrder.cashBackAmount = cashbackAmount
212
                if percentage > 0:
213
                    subOrder.cashBackPercentage = percentage
214
                subOrders.append(subOrder)
215
        priceList = paymentAnchor.next_sibling.next_sibling.next_sibling.table.table.tbody.tbody.tbody.findAll('tr', recursive=False)
216
        totalAmount = 0
217
        grandAmount = 0
218
        for price in priceList:
219
            labelTd = price.td
220
            if 'Subtotal:' in labelTd.text:
221
                totalAmount += int(float(labelTd.next_sibling.next_sibling.find('span').contents[-1].replace(',','')))
222
            elif 'Grand Total:' in labelTd.text:
223
                grandAmount += int(float(labelTd.next_sibling.next_sibling.find('span').contents[-1].replace(',','')))
224
        if grandAmount < totalAmount:
225
            diff = totalAmount - grandAmount
226
            for subOrder in merchantOrder.subOrders:
227
                subOrder.amountPaid -= int(diff*(1-subOrder.amountPaid/totalAmount))
14698 amit.gupta 228
        merchantOrder.status='success'
14464 amit.gupta 229
        self._updateToOrder(todict(merchantOrder))
230
 
231
    def parseNewStlye(self, merchantOrder, soup):
232
        merchantOrder.orderTrackingUrl = merchantOrder.orderSuccessUrl
233
        orderDetailsContainer = soup.body.find(id="orderDetails")
14566 amit.gupta 234
        divAfterH1 = orderDetailsContainer.h1.next_sibling.next_sibling
235
        orderLeftDiv = divAfterH1.div
14464 amit.gupta 236
        placedOnSpan = orderLeftDiv.find("span", {'class':'order-date-invoice-item'})
237
        merchantOrder.placedOn =placedOnSpan.text.split('Ordered on')[1].strip()
238
        merchantOrder.merchantOrderId = placedOnSpan.next_sibling.next_sibling.text.split('Order#')[1].strip()
14566 amit.gupta 239
        priceBox = divAfterH1.next_sibling.next_sibling.next_sibling.next_sibling.find("div", {"class":"a-box-inner"}).div.div.findAll('div', recursive=False)[-1]
14464 amit.gupta 240
        priceRows = priceBox.findAll('div', {'class':'a-row'})
241
        subTotal = 0
14566 amit.gupta 242
        shippingPrice = 0   
14464 amit.gupta 243
        promoApplied = 0
244
        for priceRow in priceRows:
245
            if "Item(s) Subtotal:" in str(priceRow):
246
                subTotal = int(float(priceRow.div.next_sibling.next_sibling.span.span.text.replace('Rs.','').replace(',', '')))
247
            elif "Shipping:" in str(priceRow):
248
                shippingPrice  = int(float(priceRow.div.next_sibling.next_sibling.span.span.text.replace('Rs.','').replace(',', '')))
249
            elif "Grand Total:" in str(priceRow):
250
                grandPrice  = int(float(priceRow.div.next_sibling.next_sibling.span.span.text.replace('Rs.','').replace(',', '')))
251
                merchantOrder.paidAmount = grandPrice
252
            elif "Total:" in str(priceRow):
253
                totalPrice  = int(float(priceRow.div.next_sibling.next_sibling.span.span.text.replace('Rs.','').replace(',', '')))
254
            elif "Promotion Applied:" in str(priceRow):
255
                promoApplied  += int(float(priceRow.div.next_sibling.next_sibling.span.span.text.replace('Rs.','').replace(',', '')))
256
        totalPaid = subTotal        
257
        if promoApplied > 0:
258
            totalPaid -= promoApplied
259
            if shippingPrice <= promoApplied:
260
                totalPaid  += shippingPrice
261
 
262
        shipmentDivs = orderDetailsContainer.find('div', {'class':'a-box shipment'}).findAll('div', recursive = False)
263
        subOrders = []
264
        merchantOrder.subOrders = subOrders
265
        i=1
266
        for shipmentDiv in shipmentDivs:
267
            innerBoxes = shipmentDiv.findAll('div', recursive = False)
268
            statusDiv = innerBoxes[0]
269
            subOrderStatus = statusDiv.div.span.text.strip()
14566 amit.gupta 270
            deliverySpan = statusDiv.div.div.find_next_sibling('div').span
14464 amit.gupta 271
            productDivs = innerBoxes[-1].div.div.div.findAll('div', recursive=False)
272
            subOrders = []
273
            merchantOrder.subOrders = subOrders
274
            for i, productDiv in enumerate(productDivs):
275
                i +=1 
276
                imgDiv  = productDiv.div.div
277
                detailDiv = imgDiv.find_next_sibling('div')
278
                detailDivs = detailDiv.findAll('div', recursive=False)
279
                arr = detailDivs[0].a.text.strip().split(" of ", 1)
14465 amit.gupta 280
                (productTitle, quantity) = (arr[-1], (1 if len(arr)==1 else int(arr[0])) )
14464 amit.gupta 281
                unitPrice = int(float(detailDivs[2].span.text.replace('Rs. ','').replace(',','')))
282
                amountPaid = int((unitPrice*quantity*totalPaid)/subTotal)
283
                productUrl = "http://www.amazon.in" + detailDivs[0].a.get('href')
284
                subOrder = SubOrder(productTitle, productUrl, merchantOrder.placedOn, amountPaid, MStore.ORDER_PLACED, quantity)
285
                subOrder.productCode = productUrl.split('/')[5]
286
                subOrder.unitPrice = unitPrice
14566 amit.gupta 287
                subOrder.merchantSubOrderId = str(i) + " of " + merchantOrder.merchantOrderId
14722 amit.gupta 288
                estDlvyTime = datetime.now()
14566 amit.gupta 289
                if deliverySpan is not None:
14756 amit.gupta 290
                    try:
291
                        subOrder.estimatedDeliveryDate = deliverySpan.span.text.strip()
292
                        estDate = subOrder.estimatedDeliveryDate.split("-")[0].strip()
293
                        subOrder.estimatedDeliveryInt = int(time.mktime((datetime.strptime(estDate, "%A %d %B %Y")).timetuple()))
294
                        estDlvyTime = datetime.strptime(estDate, "%A %d %B %Y")
295
                    except:
296
                        subOrder.estimatedDeliveryDate = "Not available"
14722 amit.gupta 297
                createdOn = datetime.fromtimestamp(merchantOrder.createdOnInt)
14756 amit.gupta 298
                subOrder.trackAfter = int(time.mktime(max(estDlvyTime-timedelta(days=4),createdOn + timedelta(days=3)).timetuple()))
14464 amit.gupta 299
                subOrder.detailedStatus = subOrderStatus
300
                subOrder.deliveryCharges = shippingPrice
14466 amit.gupta 301
                subOrder.imgUrl = imgDiv.img["src"]
14464 amit.gupta 302
                (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, amountPaid)
303
                cashbackStatus = Store.CB_PENDING
304
                if cashbackAmount <= 0:
305
                    cashbackStatus = Store.CB_NA
306
                subOrder.cashBackStatus = cashbackStatus
307
                subOrder.cashBackAmount = cashbackAmount
308
                if percentage > 0:
309
                    subOrder.cashBackPercentage = percentage
310
                subOrders.append(subOrder)
14698 amit.gupta 311
        merchantOrder.status='success'
14464 amit.gupta 312
        self._updateToOrder(todict(merchantOrder))
14545 amit.gupta 313
 
314
    def parseCancelled(self, merchantOrder,soup):
14722 amit.gupta 315
        try:
316
            fonts = soup.body.findAll("table", recursive=False)[1].findAll("font")
317
            if fonts[0].text == "Important Message":
318
                if fonts[1].text=="This order has been cancelled.":
319
                    merchantOrder.closed = True
320
                    merchantOrder.status = "cancelled"
321
                    merchantOrder.requireDetail = False
322
                    self._updateToOrder(todict(merchantOrder))
323
                    return
324
                else:
325
                    raise ParseException("parseCancelled", "Found detailed status" + fonts[1].text)
14545 amit.gupta 326
            else:
327
                raise ParseException("parseCancelled", "Found detailed status" + fonts[1].text)
14722 amit.gupta 328
        except:
14549 amit.gupta 329
            orderDetails = soup.body.find(id="orderDetails")
330
            if orderDetails is not None and orderDetails.h4.text == "This order has been cancelled.":
331
                merchantOrder.closed = True
14698 amit.gupta 332
                merchantOrder.status = "cancelled"
14549 amit.gupta 333
                merchantOrder.requireDetail = False
334
                self._updateToOrder(todict(merchantOrder))
335
            else:
336
                raise ParseException("parseCancelled", "Found detailed status" + fonts[1].text)
14464 amit.gupta 337
 
13868 amit.gupta 338
    def getTrackingUrls(self, userId):
14074 amit.gupta 339
 
340
        missingOrderUrls = []
341
        missingOrders = self._getMissingOrders({'userId':userId})
342
        for missingOrder in missingOrders:
343
            missingOrderUrls.append(ORDER_REDIRECT_URL%(missingOrder['merchantOrderId']))
14683 amit.gupta 344
        orders = self._getActiveOrders({'userId':userId, "subOrders.trackingUrl":{"$exists":False} })
13882 amit.gupta 345
        count = len(orders)
13879 amit.gupta 346
        print "count", count
13868 amit.gupta 347
        if count > 0:
14684 amit.gupta 348
            return missingOrderUrls + ['https://www.amazon.in/gp/css/order-history', 'https://www.amazon.in/gp/css/order-history/?orderFilter=cancelled', 'https://www.amazon.in/gp/css/order-history/?orderFilter=cancelled&startIndex=10']
13959 amit.gupta 349
        else: 
14074 amit.gupta 350
            return missingOrderUrls
13927 amit.gupta 351
 
352
    def trackOrdersForUser(self, userId, url, rawHtml):
14285 amit.gupta 353
        directory = "/tmp/User" + str(userId)
354
        if not os.path.exists(directory):
355
            os.makedirs(directory)
14298 amit.gupta 356
        filename = directory + "/" + str(datetime.now())
357
        print "filename---", filename
358
        f = open(filename,'w')
14173 amit.gupta 359
        f.write(rawHtml) # python will convert \n to os.linesep
360
        f.close() # you can omit in most cases as the destructor will call if
361
 
13995 amit.gupta 362
        try:
363
            searchMap = {'userId':userId}
364
            collectionMap = {'merchantOrderId':1}
365
            activeOrders = self._getActiveOrders(searchMap, collectionMap)
14033 amit.gupta 366
            datetimeNow = datetime.now()
367
            timestamp = int(time.mktime(datetimeNow.timetuple()))
14009 amit.gupta 368
            print "url----------------", url
14008 amit.gupta 369
 
14320 amit.gupta 370
            if url == 'https://www.amazon.in/gp/css/order-history' or 'https://www.amazon.in/gp/css/order-history/?orderFilter=cancelled' in url:
13995 amit.gupta 371
                soup = BeautifulSoup(rawHtml)
372
                allOrders = soup.find(id="ordersContainer").findAll('div', {'class':'a-box-group a-spacing-base order'})
373
                bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
374
                for activeOrder in activeOrders:
375
                    for orderEle in allOrders:
376
                        orderdiv = orderEle.find('div', {'class':'a-box a-color-offset-background order-info'}).find('div', {'class':'a-fixed-right-grid-col actions a-col-right'})
377
                        merchantOrderId = orderdiv.find('span', {'class':'a-color-secondary value'}).text.strip()
378
                        if merchantOrderId==activeOrder['merchantOrderId']:
379
                            closed = True
380
                            shipments = orderEle.findAll('div',{'class':re.compile('.*?a-box.*?')}, recursive=False)
381
                            shipments.pop(0)
382
                            for shipment in shipments:
383
                                shipdiv = shipment.find('div', {'class':'a-box-inner'})
14050 amit.gupta 384
                                sdivs = shipment.div.div.findAll('div', recursive=False)
14065 amit.gupta 385
                                orderStatus = sdivs[0].span.text.strip()
14050 amit.gupta 386
                                status = self._getStatusFromDetailedStatus(orderStatus)
387
                                if status == MStore.ORDER_DELIVERED:
14299 amit.gupta 388
                                    deliveredOn = sdivs[0].findAll('span')[-1].text.strip()
14050 amit.gupta 389
                                    deliveredOn = deliveredOn.split(":")[1].strip()
14335 amit.gupta 390
                                deliveryestimatespan = sdivs[0].find('span', {'class':'a-color-success'})
391
                                deliveryEstimate = None
392
                                if deliveryestimatespan is not None:
393
                                    deliveryEstimate = deliveryestimatespan.find('span', {'class':'a-text-bold'}).text.strip()
394
                                productDivs = shipdiv.find('div', {'class':re.compile('.*?a-spacing-top-medium.*?')}).find('div', {'class':'a-row'}).findAll('div', recursive=False)
13995 amit.gupta 395
                                trackingUrl = None
396
                                for buttonDiv in shipdiv.findAll('span', {'class':'a-button-inner'}):
397
                                    if buttonDiv.find('a').text.strip()=='Track package':
398
                                        trackingUrl = buttonDiv.find('a')['href'].strip()
399
                                        if not trackingUrl.startswith("http"):
14608 amit.gupta 400
                                            trackingUrl = "http://www.amazon.in" + trackingUrl
13995 amit.gupta 401
                                        break
402
                                for prodDiv in productDivs:
403
                                    prodDiv.find('div', {'class':'a-fixed-left-grid-inner'})
404
                                    productTitle = prodDiv.find('div', {'class':'a-fixed-left-grid-inner'}).find("div", {'class':'a-row'}).find('a').text.strip()
405
                                    imgUrl = prodDiv.find("img")["src"]
406
                                    for subOrder in activeOrder['subOrders']:
407
                                        if subOrder['productTitle'] == productTitle:
408
                                            findMap = {"orderId": activeOrder['orderId'], "subOrders.merchantSubOrderId": subOrder.get("merchantSubOrderId")}
409
                                            updateMap = {}
410
                                            closedStatus = False
411
                                            updateMap['subOrders.$.imgUrl'] = imgUrl
14033 amit.gupta 412
                                            updateMap['subOrders.$.lastTracked'] = timestamp
13995 amit.gupta 413
                                            updateMap['subOrders.$.detailedStatus'] = orderStatus
414
                                            cashbackStatus = subOrder.get("cashBackStatus")
415
                                            updateMap['subOrders.$.status'] = status 
416
 
417
                                            if status==MStore.ORDER_DELIVERED:                               
14291 amit.gupta 418
                                                updateMap['subOrders.$.deliveredOn'] = deliveredOn
13995 amit.gupta 419
                                                closedStatus = True
420
                                                updateMap['subOrders.$.closed'] = True
421
                                                if cashbackStatus == Store.CB_PENDING:
14607 amit.gupta 422
                                                    updateMap['subOrders.$.cashBackStatus'] = Store.CB_APPROVED
13995 amit.gupta 423
                                            if status==MStore.ORDER_CANCELLED:     
424
                                                closedStatus = True
425
                                                updateMap['subOrders.$.closed'] = True
426
                                                if cashbackStatus == Store.CB_PENDING:
427
                                                    updateMap['subOrders.$.cashBackStatus'] = Store.CB_CANCELLED
428
                                            if status==MStore.ORDER_SHIPPED:   
429
                                                updateMap['subOrders.$.estimatedDeliveryDate'] = deliveryEstimate
430
                                                if trackingUrl is not None:
431
                                                    updateMap['subOrders.$.trackingUrl'] = trackingUrl
432
                                            if not closedStatus:
433
                                                closed = False
434
                                            bulk.find(findMap).update({'$set' : updateMap})
435
                                            break
436
                            bulk.find({'orderId': activeOrder['orderId']}).update({'$set':{'closed': closed}})            
14080 amit.gupta 437
                bulk.execute()
438
                return 'PARSED_SUCCESS'
439
            else:
14086 amit.gupta 440
                merchantOrderId = re.findall(r'https://www.amazon.in/gp/css/summary/edit.html\?orderID=(.*)?', url, re.IGNORECASE)[0] 
14085 amit.gupta 441
                merchantOrder = self.db.merchantOrder.find_one({"merchantOrderId":merchantOrderId})
14312 amit.gupta 442
                self.parseOrderRawHtml(merchantOrder['orderId'], merchantOrder['subTagId'], merchantOrder['userId'], rawHtml, url, False)['result']
14080 amit.gupta 443
                return 'PARSED_SUCCESS'
444
                pass
14008 amit.gupta 445
            return 'PARSED_SUCCESS_NO_ORDERS'
13995 amit.gupta 446
        except:
447
            traceback.print_exc()    
448
            return 'PARSED_FAILED'
449
 
450
    def _getStatusFromDetailedStatus(self, detailedStatus):
14061 amit.gupta 451
        if "ordered from" in detailedStatus.lower():
452
            return MStore.ORDER_PLACED 
453
 
13995 amit.gupta 454
        for key, value in self.orderStatusRegexMap.iteritems():
14032 amit.gupta 455
            if detailedStatus.lower() in value:
13995 amit.gupta 456
                return key
457
 
14676 amit.gupta 458
        print "Detailed Status need to be mapped", "Store:", self.store_id
13995 amit.gupta 459
        raise ParseException("_getStatusFromDetailedStatus", "Found new order status" + detailedStatus)
14624 amit.gupta 460
    def scrapeAffiliate(self, startDate=None, endDate=None):
14650 amit.gupta 461
        br = getBrowserObject()
462
        br.add_password('https://assoc-datafeeds-eu.amazon.com', 'Saholic', 'Fnubyvp')
463
        url = AMAZON_AFF_URL
464
        response = br.open(url)
465
        #get data for past 40 days and store it to mongo
466
        dt = datetime.now()
14701 amit.gupta 467
        dat = dt - timedelta(days=2)
14651 amit.gupta 468
        url = AMAZON_AFF_FILE_URL%(datetime.strftime(dat, "%Y%m%d"))
469
        response = br.open(url)
470
        page = gzip.GzipFile(fileobj=response, mode='rb').read()
471
        j=-1
472
        for row in page.split("\n"):
473
            j += 1
474
            if j== 0 or j==1:
475
                continue
476
            fields = row.split("\t")
477
            if len(fields)>1:
478
                print fields
479
                amazonAffiliate = AmazonAffiliateInfo(fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7], fields[8], fields[9])
480
                print amazonAffiliate
481
                self.db.amazonAffiliateInfo.insert(todict(amazonAffiliate))
482
            else:
483
                break
14650 amit.gupta 484
 
14608 amit.gupta 485
 
14749 amit.gupta 486
    def parseTrackingUrl(self, trackingUrl):
14624 amit.gupta 487
        subOrder = {}
14749 amit.gupta 488
        page = fetchResponseUsingProxy(trackingUrl)
14624 amit.gupta 489
        soup = BeautifulSoup(page)
490
        alertContainer = soup.find("div", {"class":"a-box-inner a-alert-container"})
491
        if alertContainer is not None:
492
            statusText = alertContainer.h4.span.text
493
            detailedStatus = statusText.split(":")[0].strip()
494
            subOrder['detailedStatus'] = detailedStatus
495
            if detailedStatus.lower() == "in transit":
496
                pass
497
            elif detailedStatus.lower() == "undeliverable":
498
                subOrder['status'] = MStore.ORDER_CANCELLED
499
                return subOrder
500
        else:
501
            summaryLeft = soup.find(id="summaryLeft")
502
            statusText = summaryLeft.h2.text
503
            detailedStatus = statusText.split(":")[0].strip()
504
            subOrder['detailedStatus'] = detailedStatus
505
            if detailedStatus.lower() == "delivered":
506
                subOrder['deliveredOn'] = summaryLeft.findAll("span")[-2].text.strip()
507
                subOrder['status'] = MStore.ORDER_DELIVERED
508
                return subOrder
509
            else:
510
                subOrder['expectedDelivery'] = summaryLeft.findAll("span")[-1].text.strip()
511
        return subOrder
512
 
513
 
514
 
14608 amit.gupta 515
 
516
 
13927 amit.gupta 517
 
518
 
13774 amit.gupta 519
def main():
520
    store = getStore(1)
14756 amit.gupta 521
    #store.scrapeStoreOrders()
14650 amit.gupta 522
#    br = mechanize.Browser()
523
#    br.addheaders = [('User-agent','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11'),
524
#                     ('Accept', 'text/html,application/xhtml+xml,application/json,application/xml;q=0.9,*/*;q=0.8'),
525
#                     ('Accept-Encoding', 'gzip,deflate,sdch'),                  
526
#                     ('Accept-Language', 'en-US,en;q=0.8'),                     
527
#                     ('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.3')]
528
#    store.scrapeStoreOrders()
14771 amit.gupta 529
    store.parseOrderRawHtml(1306, "13232", 14, readSSh("/home/amit/322.html"), "https://www.amazon.in/gp/buy/thankyou/handlers/display.html?ie=UTF8&from=Visa&fromAnywhere=1&isFromThirdParty=1&purchaseId=404-602")
14722 amit.gupta 530
    #store.parseOrderRawHtml(2121, "13232", 14, readSSh("/home/amit/f1.html"), "https://www.amazon.in/gp/css/summary/edit.html?orderID=171-5196461-3230730")
14703 amit.gupta 531
    #readSSh("/tmp/User211/2015-04-01 15:31:42.250309")
532
    #store.scrapeAffiliate()
14162 amit.gupta 533
def readSSh(fileName):
534
    try:
535
            str1 = open(fileName).read()
536
            return str1
537
    except:
538
        ssh_client = SSHClient()
539
        str1 = ""
540
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
541
        ssh_client.connect('104.200.25.40', 22, 'root', 'ecip$dtrMay2014')
542
        sftp_client = ssh_client.open_sftp()
543
        try:
14299 amit.gupta 544
            if not os.path.exists(os.path.dirname(fileName)):
545
                os.makedirs(os.path.dirname(fileName))
14162 amit.gupta 546
            sftp_client.get(fileName, fileName)
547
            try:
548
                str1 = open(fileName).read()
549
                return str1
550
            finally:
551
                pass
552
        except:
553
            "could not read"
554
        return str1
13774 amit.gupta 555
 
556
 
557
if __name__ == '__main__':
14284 amit.gupta 558
        main()