Subversion Repositories SmartDukaan

Rev

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