Subversion Repositories SmartDukaan

Rev

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

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