Subversion Repositories SmartDukaan

Rev

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