Subversion Repositories SmartDukaan

Rev

Rev 14749 | Rev 14771 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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