Subversion Repositories SmartDukaan

Rev

Rev 14703 | Rev 14749 | 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
14162 amit.gupta 14
from paramiko import sftp
15
from paramiko.client import SSHClient
16
from paramiko.sftp_client import SFTPClient
14650 amit.gupta 17
import base64
18
import gzip
14624 amit.gupta 19
import mechanize
14285 amit.gupta 20
import os.path
14162 amit.gupta 21
import paramiko
13774 amit.gupta 22
import re
14033 amit.gupta 23
import time
13809 amit.gupta 24
import traceback
14650 amit.gupta 25
import urllib2
13774 amit.gupta 26
 
27
ORDER_REDIRECT_URL = 'https://www.amazon.in/gp/css/summary/edit.html?orderID=%s'
13810 amit.gupta 28
ORDER_SUCCESS_URL = 'https://www.amazon.in/gp/buy/spc/handlers/static-submit-decoupled.html'
13823 amit.gupta 29
THANKYOU_URL = 'https://www.amazon.in/gp/buy/thankyou/handlers/display.html'
14624 amit.gupta 30
AMAZON_AFF_URL = 'https://assoc-datafeeds-eu.amazon.com/datafeed/listReports'
14650 amit.gupta 31
AMAZON_AFF_FILE_URL = 'https://assoc-datafeeds-eu.amazon.com/datafeed/getReport?filename=saholic-21-orders-report-%s.tsv.gz'
13774 amit.gupta 32
class Store(MStore):
13821 amit.gupta 33
 
14032 amit.gupta 34
    orderStatusRegexMap = { MStore.ORDER_PLACED : ['ordered from', 'not yet dispatched','dispatching now', 'preparing for dispatch'],
14064 amit.gupta 35
                            MStore.ORDER_SHIPPED : ['dispatched on','dispatched', 'on the way', 'out for delivery', 'Out for delivery'],
14032 amit.gupta 36
                            MStore.ORDER_CANCELLED : ['return complete', 'refunded', 'cancelled'],
37
                            MStore.ORDER_DELIVERED : ['delivered']
13821 amit.gupta 38
                           }
13774 amit.gupta 39
 
40
    def __init__(self,store_id):
41
        super(Store, self).__init__(store_id)
42
 
43
    def getName(self):
44
        return "flipkart"
45
 
14202 amit.gupta 46
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl, insert=False):
13796 amit.gupta 47
        resp = {}
13821 amit.gupta 48
        if ORDER_SUCCESS_URL in orderSuccessUrl or THANKYOU_URL in orderSuccessUrl:
13774 amit.gupta 49
            try:
50
                soup = BeautifulSoup(rawHtml)
14608 amit.gupta 51
                try:
52
                    orderUrl = soup.find('div', {"id":"thank-you-box-wrapper"}).div.findAll('div', recursive=False)[1].a['href']
53
                    merchantOrderId = re.findall(r'.*&oid=(.*)&?.*?', orderUrl)[0]
54
                except:
55
                    merchantOrderId = soup.find(id="orders-list").div.span.b.text
14699 amit.gupta 56
                order = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl, True)
14211 amit.gupta 57
                order.orderSuccessUrl = ORDER_REDIRECT_URL % (merchantOrderId)
58
                order.merchantOrderId = merchantOrderId
14291 amit.gupta 59
                order.requireDetail = True
14698 amit.gupta 60
                order.status = 'html_required'
14297 amit.gupta 61
                order.closed = None
14312 amit.gupta 62
                if self._saveToOrder(todict(order)):
63
                    resp['result'] = 'ORDER_CREATED'
64
                    resp["url"] = ORDER_REDIRECT_URL % (merchantOrderId)
65
                    resp["htmlRequired"] = True
66
                    resp['orderId'] = orderId
67
                else:
68
                    resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
69
 
13796 amit.gupta 70
                return resp
13774 amit.gupta 71
            except:
14312 amit.gupta 72
                resp["result"] = 'ORDER_NOT_CREATED'
13796 amit.gupta 73
                return resp
13774 amit.gupta 74
 
75
        else:
13781 amit.gupta 76
            try:
14722 amit.gupta 77
                mo = self.db.merchantOrder.find_one({"orderId":orderId})
78
                if mo is not None:
79
                    merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
80
                    merchantOrder.createdOn = mo.get("createdOn")
81
                    merchantOrder.createdOnInt =  mo.get("createdOnInt")
82
                else:
83
                    merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl, False)
14464 amit.gupta 84
                soup = BeautifulSoup(rawHtml)
85
                try:
86
                    self.parseOldStlye(merchantOrder, soup)
87
                except:
14545 amit.gupta 88
                    try:
14566 amit.gupta 89
                        traceback.print_exc()
14545 amit.gupta 90
                        self.parseNewStlye(merchantOrder, soup)
91
                    except:
14566 amit.gupta 92
                        traceback.print_exc()
14545 amit.gupta 93
                        self.parseCancelled(merchantOrder, soup)
14319 amit.gupta 94
                resp['result'] = 'ORDER_CREATED'
95
                return resp    
13781 amit.gupta 96
            except:
14703 amit.gupta 97
                order = self.db.merchantOrder.find_one({"orderId":orderId})
14682 amit.gupta 98
                if order is not None:
14698 amit.gupta 99
                    self.db.merchantOrder.update({"orderId":orderId}, {"$set":{"status":"parse_failed"}})
13809 amit.gupta 100
                print "Error occurred"
101
                traceback.print_exc()
14312 amit.gupta 102
                resp['result'] = 'ORDER_NOT_CREATED'
13796 amit.gupta 103
                return resp    
13774 amit.gupta 104
 
13868 amit.gupta 105
    #This should be exposed from api for specific sources
106
    def scrapeStoreOrders(self):
14624 amit.gupta 107
        br = getBrowserObject()
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):
123
                        map1[trackingUrl] = self.parseTrackingUrl(br, trackingUrl)
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:
14722 amit.gupta 281
                    subOrder.estimatedDeliveryDate = deliverySpan.span.text.strip()
282
                    estDate = subOrder.estimatedDeliveryDate.split("-")[0].strip()
283
                    subOrder.estimatedDeliveryInt = int(time.mktime((datetime.strptime(estDate, "%A %d %B %Y")).timetuple()))
284
                    estDlvyTime = datetime.strptime(estDate, "%A %d %B %Y")
285
 
286
                createdOn = datetime.fromtimestamp(merchantOrder.createdOnInt)
287
                subOrder.trackAfter = int(time.mktime(max(estDlvyTime-timedelta(days=4),createdOn + timedelta(days=3)).timetuple()))/1000
14464 amit.gupta 288
                subOrder.detailedStatus = subOrderStatus
289
                subOrder.deliveryCharges = shippingPrice
14466 amit.gupta 290
                subOrder.imgUrl = imgDiv.img["src"]
14464 amit.gupta 291
                (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, amountPaid)
292
                cashbackStatus = Store.CB_PENDING
293
                if cashbackAmount <= 0:
294
                    cashbackStatus = Store.CB_NA
295
                subOrder.cashBackStatus = cashbackStatus
296
                subOrder.cashBackAmount = cashbackAmount
297
                if percentage > 0:
298
                    subOrder.cashBackPercentage = percentage
299
                subOrders.append(subOrder)
14698 amit.gupta 300
        merchantOrder.status='success'
14464 amit.gupta 301
        self._updateToOrder(todict(merchantOrder))
14545 amit.gupta 302
 
303
    def parseCancelled(self, merchantOrder,soup):
14722 amit.gupta 304
        try:
305
            fonts = soup.body.findAll("table", recursive=False)[1].findAll("font")
306
            if fonts[0].text == "Important Message":
307
                if fonts[1].text=="This order has been cancelled.":
308
                    merchantOrder.closed = True
309
                    merchantOrder.status = "cancelled"
310
                    merchantOrder.requireDetail = False
311
                    self._updateToOrder(todict(merchantOrder))
312
                    return
313
                else:
314
                    raise ParseException("parseCancelled", "Found detailed status" + fonts[1].text)
14545 amit.gupta 315
            else:
316
                raise ParseException("parseCancelled", "Found detailed status" + fonts[1].text)
14722 amit.gupta 317
        except:
14549 amit.gupta 318
            orderDetails = soup.body.find(id="orderDetails")
319
            if orderDetails is not None and orderDetails.h4.text == "This order has been cancelled.":
320
                merchantOrder.closed = True
14698 amit.gupta 321
                merchantOrder.status = "cancelled"
14549 amit.gupta 322
                merchantOrder.requireDetail = False
323
                self._updateToOrder(todict(merchantOrder))
324
            else:
325
                raise ParseException("parseCancelled", "Found detailed status" + fonts[1].text)
14464 amit.gupta 326
 
13868 amit.gupta 327
    def getTrackingUrls(self, userId):
14074 amit.gupta 328
 
329
        missingOrderUrls = []
330
        missingOrders = self._getMissingOrders({'userId':userId})
331
        for missingOrder in missingOrders:
332
            missingOrderUrls.append(ORDER_REDIRECT_URL%(missingOrder['merchantOrderId']))
14683 amit.gupta 333
        orders = self._getActiveOrders({'userId':userId, "subOrders.trackingUrl":{"$exists":False} })
13882 amit.gupta 334
        count = len(orders)
13879 amit.gupta 335
        print "count", count
13868 amit.gupta 336
        if count > 0:
14684 amit.gupta 337
            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 338
        else: 
14074 amit.gupta 339
            return missingOrderUrls
13927 amit.gupta 340
 
341
    def trackOrdersForUser(self, userId, url, rawHtml):
14285 amit.gupta 342
        directory = "/tmp/User" + str(userId)
343
        if not os.path.exists(directory):
344
            os.makedirs(directory)
14298 amit.gupta 345
        filename = directory + "/" + str(datetime.now())
346
        print "filename---", filename
347
        f = open(filename,'w')
14173 amit.gupta 348
        f.write(rawHtml) # python will convert \n to os.linesep
349
        f.close() # you can omit in most cases as the destructor will call if
350
 
13995 amit.gupta 351
        try:
352
            searchMap = {'userId':userId}
353
            collectionMap = {'merchantOrderId':1}
354
            activeOrders = self._getActiveOrders(searchMap, collectionMap)
14033 amit.gupta 355
            datetimeNow = datetime.now()
356
            timestamp = int(time.mktime(datetimeNow.timetuple()))
14009 amit.gupta 357
            print "url----------------", url
14008 amit.gupta 358
 
14320 amit.gupta 359
            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 360
                soup = BeautifulSoup(rawHtml)
361
                allOrders = soup.find(id="ordersContainer").findAll('div', {'class':'a-box-group a-spacing-base order'})
362
                bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
363
                for activeOrder in activeOrders:
364
                    for orderEle in allOrders:
365
                        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'})
366
                        merchantOrderId = orderdiv.find('span', {'class':'a-color-secondary value'}).text.strip()
367
                        if merchantOrderId==activeOrder['merchantOrderId']:
368
                            closed = True
369
                            shipments = orderEle.findAll('div',{'class':re.compile('.*?a-box.*?')}, recursive=False)
370
                            shipments.pop(0)
371
                            for shipment in shipments:
372
                                shipdiv = shipment.find('div', {'class':'a-box-inner'})
14050 amit.gupta 373
                                sdivs = shipment.div.div.findAll('div', recursive=False)
14065 amit.gupta 374
                                orderStatus = sdivs[0].span.text.strip()
14050 amit.gupta 375
                                status = self._getStatusFromDetailedStatus(orderStatus)
376
                                if status == MStore.ORDER_DELIVERED:
14299 amit.gupta 377
                                    deliveredOn = sdivs[0].findAll('span')[-1].text.strip()
14050 amit.gupta 378
                                    deliveredOn = deliveredOn.split(":")[1].strip()
14335 amit.gupta 379
                                deliveryestimatespan = sdivs[0].find('span', {'class':'a-color-success'})
380
                                deliveryEstimate = None
381
                                if deliveryestimatespan is not None:
382
                                    deliveryEstimate = deliveryestimatespan.find('span', {'class':'a-text-bold'}).text.strip()
383
                                productDivs = shipdiv.find('div', {'class':re.compile('.*?a-spacing-top-medium.*?')}).find('div', {'class':'a-row'}).findAll('div', recursive=False)
13995 amit.gupta 384
                                trackingUrl = None
385
                                for buttonDiv in shipdiv.findAll('span', {'class':'a-button-inner'}):
386
                                    if buttonDiv.find('a').text.strip()=='Track package':
387
                                        trackingUrl = buttonDiv.find('a')['href'].strip()
388
                                        if not trackingUrl.startswith("http"):
14608 amit.gupta 389
                                            trackingUrl = "http://www.amazon.in" + trackingUrl
13995 amit.gupta 390
                                        break
391
                                for prodDiv in productDivs:
392
                                    prodDiv.find('div', {'class':'a-fixed-left-grid-inner'})
393
                                    productTitle = prodDiv.find('div', {'class':'a-fixed-left-grid-inner'}).find("div", {'class':'a-row'}).find('a').text.strip()
394
                                    imgUrl = prodDiv.find("img")["src"]
395
                                    for subOrder in activeOrder['subOrders']:
396
                                        if subOrder['productTitle'] == productTitle:
397
                                            findMap = {"orderId": activeOrder['orderId'], "subOrders.merchantSubOrderId": subOrder.get("merchantSubOrderId")}
398
                                            updateMap = {}
399
                                            closedStatus = False
400
                                            updateMap['subOrders.$.imgUrl'] = imgUrl
14033 amit.gupta 401
                                            updateMap['subOrders.$.lastTracked'] = timestamp
13995 amit.gupta 402
                                            updateMap['subOrders.$.detailedStatus'] = orderStatus
403
                                            cashbackStatus = subOrder.get("cashBackStatus")
404
                                            updateMap['subOrders.$.status'] = status 
405
 
406
                                            if status==MStore.ORDER_DELIVERED:                               
14291 amit.gupta 407
                                                updateMap['subOrders.$.deliveredOn'] = deliveredOn
13995 amit.gupta 408
                                                closedStatus = True
409
                                                updateMap['subOrders.$.closed'] = True
410
                                                if cashbackStatus == Store.CB_PENDING:
14607 amit.gupta 411
                                                    updateMap['subOrders.$.cashBackStatus'] = Store.CB_APPROVED
13995 amit.gupta 412
                                            if status==MStore.ORDER_CANCELLED:     
413
                                                closedStatus = True
414
                                                updateMap['subOrders.$.closed'] = True
415
                                                if cashbackStatus == Store.CB_PENDING:
416
                                                    updateMap['subOrders.$.cashBackStatus'] = Store.CB_CANCELLED
417
                                            if status==MStore.ORDER_SHIPPED:   
418
                                                updateMap['subOrders.$.estimatedDeliveryDate'] = deliveryEstimate
419
                                                if trackingUrl is not None:
420
                                                    updateMap['subOrders.$.trackingUrl'] = trackingUrl
421
                                            if not closedStatus:
422
                                                closed = False
423
                                            bulk.find(findMap).update({'$set' : updateMap})
424
                                            break
425
                            bulk.find({'orderId': activeOrder['orderId']}).update({'$set':{'closed': closed}})            
14080 amit.gupta 426
                bulk.execute()
427
                return 'PARSED_SUCCESS'
428
            else:
14086 amit.gupta 429
                merchantOrderId = re.findall(r'https://www.amazon.in/gp/css/summary/edit.html\?orderID=(.*)?', url, re.IGNORECASE)[0] 
14085 amit.gupta 430
                merchantOrder = self.db.merchantOrder.find_one({"merchantOrderId":merchantOrderId})
14312 amit.gupta 431
                self.parseOrderRawHtml(merchantOrder['orderId'], merchantOrder['subTagId'], merchantOrder['userId'], rawHtml, url, False)['result']
14080 amit.gupta 432
                return 'PARSED_SUCCESS'
433
                pass
14008 amit.gupta 434
            return 'PARSED_SUCCESS_NO_ORDERS'
13995 amit.gupta 435
        except:
436
            traceback.print_exc()    
437
            return 'PARSED_FAILED'
438
 
439
    def _getStatusFromDetailedStatus(self, detailedStatus):
14061 amit.gupta 440
        if "ordered from" in detailedStatus.lower():
441
            return MStore.ORDER_PLACED 
442
 
13995 amit.gupta 443
        for key, value in self.orderStatusRegexMap.iteritems():
14032 amit.gupta 444
            if detailedStatus.lower() in value:
13995 amit.gupta 445
                return key
446
 
14676 amit.gupta 447
        print "Detailed Status need to be mapped", "Store:", self.store_id
13995 amit.gupta 448
        raise ParseException("_getStatusFromDetailedStatus", "Found new order status" + detailedStatus)
14624 amit.gupta 449
    def scrapeAffiliate(self, startDate=None, endDate=None):
14650 amit.gupta 450
        br = getBrowserObject()
451
        br.add_password('https://assoc-datafeeds-eu.amazon.com', 'Saholic', 'Fnubyvp')
452
        url = AMAZON_AFF_URL
453
        response = br.open(url)
454
        #get data for past 40 days and store it to mongo
455
        dt = datetime.now()
14701 amit.gupta 456
        dat = dt - timedelta(days=2)
14651 amit.gupta 457
        url = AMAZON_AFF_FILE_URL%(datetime.strftime(dat, "%Y%m%d"))
458
        response = br.open(url)
459
        page = gzip.GzipFile(fileobj=response, mode='rb').read()
460
        j=-1
461
        for row in page.split("\n"):
462
            j += 1
463
            if j== 0 or j==1:
464
                continue
465
            fields = row.split("\t")
466
            if len(fields)>1:
467
                print fields
468
                amazonAffiliate = AmazonAffiliateInfo(fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7], fields[8], fields[9])
469
                print amazonAffiliate
470
                self.db.amazonAffiliateInfo.insert(todict(amazonAffiliate))
471
            else:
472
                break
14650 amit.gupta 473
 
14608 amit.gupta 474
 
475
    def parseTrackingUrl(self, br, trackingUrl):
14624 amit.gupta 476
        subOrder = {}
14608 amit.gupta 477
        response = br.open(trackingUrl)
478
        page = ungzipResponse(response)
14624 amit.gupta 479
        soup = BeautifulSoup(page)
480
        alertContainer = soup.find("div", {"class":"a-box-inner a-alert-container"})
481
        if alertContainer is not None:
482
            statusText = alertContainer.h4.span.text
483
            detailedStatus = statusText.split(":")[0].strip()
484
            subOrder['detailedStatus'] = detailedStatus
485
            if detailedStatus.lower() == "in transit":
486
                pass
487
            elif detailedStatus.lower() == "undeliverable":
488
                subOrder['status'] = MStore.ORDER_CANCELLED
489
                return subOrder
490
        else:
491
            summaryLeft = soup.find(id="summaryLeft")
492
            statusText = summaryLeft.h2.text
493
            detailedStatus = statusText.split(":")[0].strip()
494
            subOrder['detailedStatus'] = detailedStatus
495
            if detailedStatus.lower() == "delivered":
496
                subOrder['deliveredOn'] = summaryLeft.findAll("span")[-2].text.strip()
497
                subOrder['status'] = MStore.ORDER_DELIVERED
498
                return subOrder
499
            else:
500
                subOrder['expectedDelivery'] = summaryLeft.findAll("span")[-1].text.strip()
501
        return subOrder
502
 
503
 
504
 
14608 amit.gupta 505
 
506
 
13927 amit.gupta 507
 
508
 
13774 amit.gupta 509
def main():
510
    store = getStore(1)
14650 amit.gupta 511
#    br = mechanize.Browser()
512
#    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'),
513
#                     ('Accept', 'text/html,application/xhtml+xml,application/json,application/xml;q=0.9,*/*;q=0.8'),
514
#                     ('Accept-Encoding', 'gzip,deflate,sdch'),                  
515
#                     ('Accept-Language', 'en-US,en;q=0.8'),                     
516
#                     ('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.3')]
517
#    store.scrapeStoreOrders()
14722 amit.gupta 518
    store.parseOrderRawHtml(2121, "13232", 14, readSSh("/home/amit/1313.html"), "https://www.amazon.in/gp/css/summary/edit.html?orderID=171-5857029-0804336")
519
    #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 520
    #readSSh("/tmp/User211/2015-04-01 15:31:42.250309")
521
    #store.scrapeAffiliate()
14162 amit.gupta 522
def readSSh(fileName):
523
    try:
524
            str1 = open(fileName).read()
525
            return str1
526
    except:
527
        ssh_client = SSHClient()
528
        str1 = ""
529
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
530
        ssh_client.connect('104.200.25.40', 22, 'root', 'ecip$dtrMay2014')
531
        sftp_client = ssh_client.open_sftp()
532
        try:
14299 amit.gupta 533
            if not os.path.exists(os.path.dirname(fileName)):
534
                os.makedirs(os.path.dirname(fileName))
14162 amit.gupta 535
            sftp_client.get(fileName, fileName)
536
            try:
537
                str1 = open(fileName).read()
538
                return str1
539
            finally:
540
                pass
541
        except:
542
            "could not read"
543
        return str1
13774 amit.gupta 544
 
545
 
546
if __name__ == '__main__':
14284 amit.gupta 547
        main()