Subversion Repositories SmartDukaan

Rev

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