Subversion Repositories SmartDukaan

Rev

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