Subversion Repositories SmartDukaan

Rev

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