Subversion Repositories SmartDukaan

Rev

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