Subversion Repositories SmartDukaan

Rev

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