Subversion Repositories SmartDukaan

Rev

Rev 14847 | Rev 14948 | 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
13868 amit.gupta 360
        if count > 0:
14684 amit.gupta 361
            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 362
        else: 
14074 amit.gupta 363
            return missingOrderUrls
13927 amit.gupta 364
 
365
    def trackOrdersForUser(self, userId, url, rawHtml):
14285 amit.gupta 366
        directory = "/tmp/User" + str(userId)
367
        if not os.path.exists(directory):
368
            os.makedirs(directory)
14173 amit.gupta 369
 
14945 amit.gupta 370
 
13995 amit.gupta 371
        try:
372
            searchMap = {'userId':userId}
373
            collectionMap = {'merchantOrderId':1}
374
            activeOrders = self._getActiveOrders(searchMap, collectionMap)
14033 amit.gupta 375
            datetimeNow = datetime.now()
376
            timestamp = int(time.mktime(datetimeNow.timetuple()))
14009 amit.gupta 377
            print "url----------------", url
14008 amit.gupta 378
 
14320 amit.gupta 379
            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 380
                if url == 'https://www.amazon.in/gp/css/order-history':
381
                    filename = directory + "/orderSummary" + datetime.strftime(datetime.now(), '%d-%m:%H:%M:%S')
382
                else:   
383
                    filename = directory + "/cancelledSummary" + datetime.strftime(datetime.now(), '%d-%m:%H:%M:%S')   
384
                f = open(filename,'w')
385
                f.write(rawHtml) # python will convert \n to os.linesep
386
                f.close() # you can omit in most cases as the destructor will call if
13995 amit.gupta 387
                soup = BeautifulSoup(rawHtml)
388
                allOrders = soup.find(id="ordersContainer").findAll('div', {'class':'a-box-group a-spacing-base order'})
389
                bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
390
                for activeOrder in activeOrders:
391
                    for orderEle in allOrders:
392
                        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'})
393
                        merchantOrderId = orderdiv.find('span', {'class':'a-color-secondary value'}).text.strip()
394
                        if merchantOrderId==activeOrder['merchantOrderId']:
395
                            closed = True
396
                            shipments = orderEle.findAll('div',{'class':re.compile('.*?a-box.*?')}, recursive=False)
397
                            shipments.pop(0)
398
                            for shipment in shipments:
399
                                shipdiv = shipment.find('div', {'class':'a-box-inner'})
14050 amit.gupta 400
                                sdivs = shipment.div.div.findAll('div', recursive=False)
14065 amit.gupta 401
                                orderStatus = sdivs[0].span.text.strip()
14050 amit.gupta 402
                                status = self._getStatusFromDetailedStatus(orderStatus)
403
                                if status == MStore.ORDER_DELIVERED:
14299 amit.gupta 404
                                    deliveredOn = sdivs[0].findAll('span')[-1].text.strip()
14050 amit.gupta 405
                                    deliveredOn = deliveredOn.split(":")[1].strip()
14335 amit.gupta 406
                                deliveryestimatespan = sdivs[0].find('span', {'class':'a-color-success'})
407
                                deliveryEstimate = None
408
                                if deliveryestimatespan is not None:
409
                                    deliveryEstimate = deliveryestimatespan.find('span', {'class':'a-text-bold'}).text.strip()
410
                                productDivs = shipdiv.find('div', {'class':re.compile('.*?a-spacing-top-medium.*?')}).find('div', {'class':'a-row'}).findAll('div', recursive=False)
13995 amit.gupta 411
                                trackingUrl = None
412
                                for buttonDiv in shipdiv.findAll('span', {'class':'a-button-inner'}):
413
                                    if buttonDiv.find('a').text.strip()=='Track package':
414
                                        trackingUrl = buttonDiv.find('a')['href'].strip()
415
                                        if not trackingUrl.startswith("http"):
14608 amit.gupta 416
                                            trackingUrl = "http://www.amazon.in" + trackingUrl
13995 amit.gupta 417
                                        break
418
                                for prodDiv in productDivs:
419
                                    prodDiv.find('div', {'class':'a-fixed-left-grid-inner'})
420
                                    productTitle = prodDiv.find('div', {'class':'a-fixed-left-grid-inner'}).find("div", {'class':'a-row'}).find('a').text.strip()
421
                                    imgUrl = prodDiv.find("img")["src"]
422
                                    for subOrder in activeOrder['subOrders']:
423
                                        if subOrder['productTitle'] == productTitle:
424
                                            findMap = {"orderId": activeOrder['orderId'], "subOrders.merchantSubOrderId": subOrder.get("merchantSubOrderId")}
425
                                            updateMap = {}
426
                                            closedStatus = False
427
                                            updateMap['subOrders.$.imgUrl'] = imgUrl
14033 amit.gupta 428
                                            updateMap['subOrders.$.lastTracked'] = timestamp
13995 amit.gupta 429
                                            updateMap['subOrders.$.detailedStatus'] = orderStatus
430
                                            cashbackStatus = subOrder.get("cashBackStatus")
431
                                            updateMap['subOrders.$.status'] = status 
432
 
433
                                            if status==MStore.ORDER_DELIVERED:                               
14291 amit.gupta 434
                                                updateMap['subOrders.$.deliveredOn'] = deliveredOn
13995 amit.gupta 435
                                                closedStatus = True
436
                                                updateMap['subOrders.$.closed'] = True
437
                                                if cashbackStatus == Store.CB_PENDING:
14607 amit.gupta 438
                                                    updateMap['subOrders.$.cashBackStatus'] = Store.CB_APPROVED
13995 amit.gupta 439
                                            if status==MStore.ORDER_CANCELLED:     
440
                                                closedStatus = True
441
                                                updateMap['subOrders.$.closed'] = True
442
                                                if cashbackStatus == Store.CB_PENDING:
443
                                                    updateMap['subOrders.$.cashBackStatus'] = Store.CB_CANCELLED
444
                                            if status==MStore.ORDER_SHIPPED:   
445
                                                updateMap['subOrders.$.estimatedDeliveryDate'] = deliveryEstimate
446
                                                if trackingUrl is not None:
447
                                                    updateMap['subOrders.$.trackingUrl'] = trackingUrl
448
                                            if not closedStatus:
449
                                                closed = False
450
                                            bulk.find(findMap).update({'$set' : updateMap})
451
                                            break
452
                            bulk.find({'orderId': activeOrder['orderId']}).update({'$set':{'closed': closed}})            
14080 amit.gupta 453
                bulk.execute()
454
                return 'PARSED_SUCCESS'
455
            else:
14086 amit.gupta 456
                merchantOrderId = re.findall(r'https://www.amazon.in/gp/css/summary/edit.html\?orderID=(.*)?', url, re.IGNORECASE)[0] 
14085 amit.gupta 457
                merchantOrder = self.db.merchantOrder.find_one({"merchantOrderId":merchantOrderId})
14945 amit.gupta 458
 
459
                filename = directory + "/" + merchantOrderId   
460
                f = open(filename,'w')
461
                f.write(rawHtml) # python will convert \n to os.linesep
462
                f.close() # you can omit in most cases as the destructor will call if
463
                self.parseOrderRawHtml(merchantOrder['orderId'], merchantOrder['subTagId'], merchantOrder['userId'], rawHtml, url, True)['result']
14080 amit.gupta 464
                return 'PARSED_SUCCESS'
465
                pass
14008 amit.gupta 466
            return 'PARSED_SUCCESS_NO_ORDERS'
13995 amit.gupta 467
        except:
468
            traceback.print_exc()    
469
            return 'PARSED_FAILED'
470
 
471
    def _getStatusFromDetailedStatus(self, detailedStatus):
14061 amit.gupta 472
        if "ordered from" in detailedStatus.lower():
473
            return MStore.ORDER_PLACED 
474
 
13995 amit.gupta 475
        for key, value in self.orderStatusRegexMap.iteritems():
14032 amit.gupta 476
            if detailedStatus.lower() in value:
13995 amit.gupta 477
                return key
478
 
14676 amit.gupta 479
        print "Detailed Status need to be mapped", "Store:", self.store_id
13995 amit.gupta 480
        raise ParseException("_getStatusFromDetailedStatus", "Found new order status" + detailedStatus)
14624 amit.gupta 481
    def scrapeAffiliate(self, startDate=None, endDate=None):
14650 amit.gupta 482
        br = getBrowserObject()
483
        br.add_password('https://assoc-datafeeds-eu.amazon.com', 'Saholic', 'Fnubyvp')
484
        url = AMAZON_AFF_URL
485
        response = br.open(url)
486
        #get data for past 40 days and store it to mongo
487
        dt = datetime.now()
14701 amit.gupta 488
        dat = dt - timedelta(days=2)
14651 amit.gupta 489
        url = AMAZON_AFF_FILE_URL%(datetime.strftime(dat, "%Y%m%d"))
490
        response = br.open(url)
491
        page = gzip.GzipFile(fileobj=response, mode='rb').read()
492
        j=-1
493
        for row in page.split("\n"):
494
            j += 1
495
            if j== 0 or j==1:
496
                continue
497
            fields = row.split("\t")
498
            if len(fields)>1:
499
                print fields
500
                amazonAffiliate = AmazonAffiliateInfo(fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7], fields[8], fields[9])
501
                print amazonAffiliate
502
                self.db.amazonAffiliateInfo.insert(todict(amazonAffiliate))
503
            else:
504
                break
14650 amit.gupta 505
 
14608 amit.gupta 506
 
14749 amit.gupta 507
    def parseTrackingUrl(self, trackingUrl):
14624 amit.gupta 508
        subOrder = {}
14749 amit.gupta 509
        page = fetchResponseUsingProxy(trackingUrl)
14624 amit.gupta 510
        soup = BeautifulSoup(page)
511
        alertContainer = soup.find("div", {"class":"a-box-inner a-alert-container"})
512
        if alertContainer is not None:
513
            statusText = alertContainer.h4.span.text
514
            detailedStatus = statusText.split(":")[0].strip()
515
            subOrder['detailedStatus'] = detailedStatus
516
            if detailedStatus.lower() == "in transit":
517
                pass
518
            elif detailedStatus.lower() == "undeliverable":
519
                subOrder['status'] = MStore.ORDER_CANCELLED
520
                return subOrder
521
        else:
522
            summaryLeft = soup.find(id="summaryLeft")
523
            statusText = summaryLeft.h2.text
524
            detailedStatus = statusText.split(":")[0].strip()
525
            subOrder['detailedStatus'] = detailedStatus
526
            if detailedStatus.lower() == "delivered":
527
                subOrder['deliveredOn'] = summaryLeft.findAll("span")[-2].text.strip()
528
                subOrder['status'] = MStore.ORDER_DELIVERED
529
                return subOrder
530
            else:
531
                subOrder['expectedDelivery'] = summaryLeft.findAll("span")[-1].text.strip()
532
        return subOrder
533
 
534
 
535
 
14608 amit.gupta 536
 
537
 
13927 amit.gupta 538
 
539
 
13774 amit.gupta 540
def main():
14945 amit.gupta 541
    readSSh("/tmp/order2015-04-23 12:39:09.743683")
542
    #store = getStore(1)
14756 amit.gupta 543
    #store.scrapeStoreOrders()
14650 amit.gupta 544
#    br = mechanize.Browser()
545
#    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'),
546
#                     ('Accept', 'text/html,application/xhtml+xml,application/json,application/xml;q=0.9,*/*;q=0.8'),
547
#                     ('Accept-Encoding', 'gzip,deflate,sdch'),                  
548
#                     ('Accept-Language', 'en-US,en;q=0.8'),                     
549
#                     ('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.3')]
550
#    store.scrapeStoreOrders()
14945 amit.gupta 551
    #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 552
    #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 553
    #readSSh("/tmp/User211/2015-04-12 10:32:41.905765")
14703 amit.gupta 554
    #store.scrapeAffiliate()
14162 amit.gupta 555
def readSSh(fileName):
556
    try:
557
            str1 = open(fileName).read()
558
            return str1
559
    except:
560
        ssh_client = SSHClient()
561
        str1 = ""
562
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
563
        ssh_client.connect('104.200.25.40', 22, 'root', 'ecip$dtrMay2014')
564
        sftp_client = ssh_client.open_sftp()
565
        try:
14299 amit.gupta 566
            if not os.path.exists(os.path.dirname(fileName)):
567
                os.makedirs(os.path.dirname(fileName))
14162 amit.gupta 568
            sftp_client.get(fileName, fileName)
569
            try:
570
                str1 = open(fileName).read()
571
                return str1
572
            finally:
573
                pass
574
        except:
575
            "could not read"
576
        return str1
13774 amit.gupta 577
 
578
 
579
if __name__ == '__main__':
14284 amit.gupta 580
        main()