Subversion Repositories SmartDukaan

Rev

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