Subversion Repositories SmartDukaan

Rev

Rev 18380 | Rev 18440 | 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
17231 amit.gupta 9
from datetime import datetime, timedelta, date
16874 amit.gupta 10
from dtr.api.Order import process_rejects
18028 amit.gupta 11
from dtr.dao import Order, SubOrder, AmazonAffiliateInfo, obj
14464 amit.gupta 12
from dtr.main import getStore, Store as MStore, ParseException, getBrowserObject, \
14624 amit.gupta 13
    ungzipResponse, tprint
18156 amit.gupta 14
from dtr.sources.flipkart import todict
17307 amit.gupta 15
from dtr.storage.DataService import OrdersRaw, Orders, Order_Parse_Info, \
16986 amit.gupta 16
    All_user_addresses
16874 amit.gupta 17
from dtr.storage.Mongo import getDealRank
17307 amit.gupta 18
from dtr.utils import utils
16874 amit.gupta 19
from dtr.utils.utils import fetchResponseUsingProxy, readSSh
20
from elixir import *
14650 amit.gupta 21
import base64
16874 amit.gupta 22
import dtr
14650 amit.gupta 23
import gzip
14624 amit.gupta 24
import mechanize
14285 amit.gupta 25
import os.path
18376 amit.gupta 26
from pyquery import PyQuery as pq
13774 amit.gupta 27
import re
14033 amit.gupta 28
import time
13809 amit.gupta 29
import traceback
14650 amit.gupta 30
import urllib2
13774 amit.gupta 31
 
32
ORDER_REDIRECT_URL = 'https://www.amazon.in/gp/css/summary/edit.html?orderID=%s'
13810 amit.gupta 33
ORDER_SUCCESS_URL = 'https://www.amazon.in/gp/buy/spc/handlers/static-submit-decoupled.html'
13823 amit.gupta 34
THANKYOU_URL = 'https://www.amazon.in/gp/buy/thankyou/handlers/display.html'
14624 amit.gupta 35
AMAZON_AFF_URL = 'https://assoc-datafeeds-eu.amazon.com/datafeed/listReports'
14650 amit.gupta 36
AMAZON_AFF_FILE_URL = 'https://assoc-datafeeds-eu.amazon.com/datafeed/getReport?filename=saholic-21-orders-report-%s.tsv.gz'
13774 amit.gupta 37
class Store(MStore):
13821 amit.gupta 38
 
17348 amit.gupta 39
    orderStatusRegexMap = { MStore.ORDER_PLACED : ['ordered from', 'not yet dispatched','dispatching now', 'preparing for dispatch', 'order received'],
14064 amit.gupta 40
                            MStore.ORDER_SHIPPED : ['dispatched on','dispatched', 'on the way', 'out for delivery', 'Out for delivery'],
17324 amit.gupta 41
                            MStore.ORDER_CANCELLED : ['return complete', 'refunded', 'cancelled', 'replacement complete', 'return received'],
17258 amit.gupta 42
                            MStore.ORDER_DELIVERED : ['delivered', 'your package was delivered', 'package was handed directly to customer']
13821 amit.gupta 43
                           }
13774 amit.gupta 44
 
45
    def __init__(self,store_id):
46
        super(Store, self).__init__(store_id)
47
 
48
    def getName(self):
14749 amit.gupta 49
        return "amazon"
13774 amit.gupta 50
 
14945 amit.gupta 51
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl, track=False):
17718 amit.gupta 52
        rawHtml = re.sub(r'[^\x00-\x7F]+',' ', rawHtml)
14958 amit.gupta 53
        parseString = "Tracking" if track else "Transacted"
54
        print parseString, "Order Id to be parsed is :", orderId
13796 amit.gupta 55
        resp = {}
14813 amit.gupta 56
        resp['result'] = 'ORDER_NOT_CREATED'
13821 amit.gupta 57
        if ORDER_SUCCESS_URL in orderSuccessUrl or THANKYOU_URL in orderSuccessUrl:
13774 amit.gupta 58
            try:
17600 amit.gupta 59
                doc = pq(rawHtml)
14608 amit.gupta 60
                try:
17600 amit.gupta 61
                    orderUrl = doc('a.a-touch-link').attr.href
14608 amit.gupta 62
                    merchantOrderId = re.findall(r'.*&oid=(.*)&?.*?', orderUrl)[0]
63
                except:
17600 amit.gupta 64
                    merchantOrderId = doc("#orders-list>div>span>b").html()
14699 amit.gupta 65
                order = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl, True)
14972 amit.gupta 66
                order.orderTrackingUrl = ORDER_REDIRECT_URL % (merchantOrderId)
67
                order.orderSuccessUrl = orderSuccessUrl
14211 amit.gupta 68
                order.merchantOrderId = merchantOrderId
14291 amit.gupta 69
                order.requireDetail = True
14698 amit.gupta 70
                order.status = 'html_required'
14297 amit.gupta 71
                order.closed = None
14312 amit.gupta 72
                if self._saveToOrder(todict(order)):
73
                    resp['result'] = 'ORDER_CREATED'
74
                    resp["url"] = ORDER_REDIRECT_URL % (merchantOrderId)
75
                    resp["htmlRequired"] = True
76
                    resp['orderId'] = orderId
77
                else:
78
                    resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
79
 
13774 amit.gupta 80
            except:
14813 amit.gupta 81
                #Write all cases here for Order Not created Known
18158 amit.gupta 82
                soup = BeautifulSoup(rawHtml, "html5lib")
14809 amit.gupta 83
                try:
16874 amit.gupta 84
                    if not soup.body:
85
                        resp['result'] = 'ORDER_NOT_CREATED_KNOWN'
17359 amit.gupta 86
                    elif 'Securely redirecting you' in soup.find("h3").text.strip() or soup.find("h3").text.strip()=="Orders":
14813 amit.gupta 87
                        resp['result'] = 'ORDER_NOT_CREATED_KNOWN'
14809 amit.gupta 88
                    else:
14813 amit.gupta 89
                        raise
14809 amit.gupta 90
                except:
14814 amit.gupta 91
                    try:
17356 amit.gupta 92
                        if soup.find("h1").text.strip() in ['This is a duplicate order', 'There was a problem with your payment.', 'Your Orders', 'Your Shopping Cart is empty.', 'Select a payment method', 'Edit quantities'] or "Saved for later" in soup.find("h1").text.strip():
14814 amit.gupta 93
                            resp['result'] = 'ORDER_NOT_CREATED_KNOWN'
94
                        else:
95
                            raise
96
                    except:
15046 amit.gupta 97
                        try:
17356 amit.gupta 98
                            if soup.find("h2").text.strip() in ['Web page not available','Webpage not available', 'Do you have an Amazon password?']:
15046 amit.gupta 99
                                resp['result'] = 'ORDER_NOT_CREATED_KNOWN'
100
                            else:
101
                                raise
102
                        except:
15565 amit.gupta 103
                            try:
16876 amit.gupta 104
                                if soup.find(id="loading-spinner-img") is not None or soup.find(id="anonCarousel1") is not None or soup.find(id="ap_signin_pagelet_title") is not None or soup.find(id="nav-greeting-name") is not None:
15565 amit.gupta 105
                                    resp['result'] = 'ORDER_NOT_CREATED_KNOWN'
16877 amit.gupta 106
                                elif soup.find("b", {'class':'h1'}).text.strip().find("We're sorry") > -1:
107
                                    resp['result'] = 'ORDER_NOT_CREATED_KNOWN'
15565 amit.gupta 108
                                else:
109
                                    raise
110
                            except:
111
                                resp['result'] = 'ORDER_NOT_CREATED_UNKNOWN'
112
 
13774 amit.gupta 113
        else:
13781 amit.gupta 114
            try:
14722 amit.gupta 115
                mo = self.db.merchantOrder.find_one({"orderId":orderId})
116
                if mo is not None:
14749 amit.gupta 117
                    merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl, False)
14722 amit.gupta 118
                    merchantOrder.createdOn = mo.get("createdOn")
119
                    merchantOrder.createdOnInt =  mo.get("createdOnInt")
120
                else:
14945 amit.gupta 121
                    print "Could not find amazon order with order Id", orderId
14749 amit.gupta 122
                    merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
18158 amit.gupta 123
                soup = BeautifulSoup(rawHtml, "html5lib")
17331 amit.gupta 124
                if not soup.body:
17319 amit.gupta 125
                    resp['result'] = 'DETAIL_NOT_CREATED_KNOWN'
126
                else:   
14545 amit.gupta 127
                    try:
17319 amit.gupta 128
                        self.parseNewStlye(merchantOrder, soup)
15046 amit.gupta 129
                        resp['result'] = 'DETAIL_CREATED'
14545 amit.gupta 130
                    except:
15056 amit.gupta 131
                        try:
17319 amit.gupta 132
                            traceback.print_exc()
18376 amit.gupta 133
                            self.parseAnotherStlye(merchantOrder, pq(rawHtml))
17319 amit.gupta 134
                            resp['result'] = 'DETAIL_CREATED'
15056 amit.gupta 135
                        except:
15059 amit.gupta 136
                            try:
18376 amit.gupta 137
                                traceback.print_exc()
138
                                self.parseOldStlye(merchantOrder, soup)
139
                                resp['result'] = 'DETAIL_CREATED'
15059 amit.gupta 140
                            except:
18376 amit.gupta 141
                                traceback.print_exc()
17319 amit.gupta 142
                                try:
18376 amit.gupta 143
                                    self.parseCancelled(merchantOrder, soup)
144
                                    resp['result'] = 'ORDER_CANCELLED'
17319 amit.gupta 145
                                except:
18376 amit.gupta 146
                                    try:
147
                                        if soup.find("h1").text.strip() in ["Your Account"] or soup.find("h1").span.text=="Account":
148
                                            resp['result'] = 'DETAIL_NOT_CREATED_KNOWN'
149
                                        else:
150
                                            raise
151
                                    except:
152
                                        if soup.find(id="ap_signin_pagelet_title").find("h1").text.strip()=="Sign In":
153
                                            resp['result'] = 'DETAIL_NOT_CREATED_KNOWN'
154
                                        else:
155
                                            raise
17599 amit.gupta 156
                if resp['result'] == 'DETAIL_NOT_CREATED_KNOWN':
17357 amit.gupta 157
                    self.db.merchantOrder.update({"orderId":orderId}, {"$set":{"status":"html_required"}})
13781 amit.gupta 158
            except:
17666 amit.gupta 159
                self.db.merchantOrder.update({"orderId":orderId}, {"$set":{"status":"html_required"}})
14813 amit.gupta 160
                print "Error occurred"
15046 amit.gupta 161
                resp['result'] = 'DETAIL_NOT_CREATED_UNKNOWN'
14813 amit.gupta 162
                traceback.print_exc()
15046 amit.gupta 163
        return resp    
13774 amit.gupta 164
 
13868 amit.gupta 165
    #This should be exposed from api for specific sources
166
    def scrapeStoreOrders(self):
14624 amit.gupta 167
        orders = self.db.merchantOrder.find({"storeId":1, "closed":False, "subOrders.closed":False, "subOrders.trackingUrl":{"$exists":True}})
168
        for merchantOrder in orders:
14981 amit.gupta 169
            executeBulk = False
14624 amit.gupta 170
            try:
171
                bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
172
                closed = True
173
                map1 = {}
174
                for subOrder in merchantOrder.get("subOrders"):
175
                    if subOrder.get("closed"):
176
                        continue
177
                    elif subOrder.get("trackingUrl") is None:
178
                        closed = False
179
                        continue
180
                    findMap = {"orderId":merchantOrder.get("orderId"), "subOrders.merchantSubOrderId":subOrder.get("merchantSubOrderId")} 
181
                    trackingUrl = subOrder.get("trackingUrl")
182
                    if not map1.has_key(trackingUrl):
16468 amit.gupta 183
                        map1[trackingUrl] = self.parseTrackingUrl(trackingUrl, merchantOrder.get("orderId"))
14624 amit.gupta 184
                    newOrder = map1.get(trackingUrl)
16474 amit.gupta 185
                    if newOrder:
186
                        executeBulk = True
187
                        updateMap = self.getUpdateMap(newOrder, subOrder.get('cashBackStatus'))
188
                        print findMap, "\n", updateMap
189
                        bulk.find(findMap).update({'$set' : updateMap})
190
                        closed = closed and newOrder['closed']
14981 amit.gupta 191
                if executeBulk:
14697 amit.gupta 192
                    bulk.find({"orderId":merchantOrder.get("orderId")}).update({"$set":{"closed":closed, "parseError":False}})
14981 amit.gupta 193
                    bulk.execute()
14624 amit.gupta 194
            except:
14847 amit.gupta 195
                tprint("Could not update " + str(merchantOrder['orderId']) + " For store " + self.getName())
14692 amit.gupta 196
                self.db.merchantOrder.update({"orderId":merchantOrder['orderId']}, {"$set":{"parseError":True}})
14624 amit.gupta 197
                traceback.print_exc()
198
 
14608 amit.gupta 199
 
200
 
14771 amit.gupta 201
    def parserest(self, soup):
202
        print "Hi"
203
        if soup.find('h1'):
204
            print "OK"
14608 amit.gupta 205
 
14464 amit.gupta 206
    def parseOldStlye(self, merchantOrder, soup):
207
        merchantOrder.orderTrackingUrl = merchantOrder.orderSuccessUrl
208
        table = soup.body.findAll("table", recursive=False)[1]
209
        #print table
210
        tables = table.tr.td.findAll("table", recursive=False)
211
        for tr in tables[2].findAll("tr"):
212
            boldElement = tr.td.b
213
            if "Order Placed" in str(boldElement):
214
                merchantOrder.placedOn = boldElement.next_sibling.strip()
215
            if "order number" in str(boldElement):
216
                merchantOrder.merchantOrderId = boldElement.next_sibling.strip()
217
            if "Order Total" in str(boldElement):
218
                merchantOrder.paidAmount = int(float(boldElement.find('span').contents[-1].replace(',','')))
219
        anchors = table.tr.td.findAll("a", recursive=False)
220
        paymentAnchor = anchors.pop(-1)
221
 
222
        count = 0
223
        subOrders = []
224
        merchantOrder.subOrders = subOrders
225
        counter = 0 
226
        for anchor in anchors:
227
            count += 1
228
            tab = anchor.next_sibling
229
            status = MStore.ORDER_PLACED
230
            subStr = "Delivery #" + str(count) + ":"
231
            if subStr in  tab.find("b").text:
232
                detailedStatus = tab.find("b").text.replace(subStr, '').strip()
233
 
234
            tab = tab.next_sibling.next_sibling
235
            trs = tab.find("table").find('tbody').findAll("tr", recursive = False)
236
 
237
            estimatedDelivery = trs[0].td.find("b").next_sibling.strip()
238
 
239
            orderItemTrs = trs[1].findAll("td", recursive=False)[1].table.tbody.findAll("tr", recursive = False)
240
            i = -1
241
            for orderItemTr in orderItemTrs:
242
                i += 1
243
                if i%2 == 0:
244
                    continue
245
                counter += 1
246
                quantity =  int(re.findall(r'\d+', orderItemTr.td.contents[0])[0])
247
 
248
                productUrl = orderItemTr.td.contents[1].a["href"]
249
                productTitle = orderItemTr.td.contents[1].a.text
250
 
251
                unitPrice = int(float(orderItemTr.findAll('td')[1].span.text.replace('Rs. ','').replace(',','')))
252
 
253
 
254
                subOrder = SubOrder(productTitle, productUrl, merchantOrder.placedOn, unitPrice*quantity, status, quantity)
255
                subOrder.merchantSubOrderId = str(counter) + " of " + merchantOrder.merchantOrderId
256
                subOrder.estimatedDeliveryDate = estimatedDelivery
14722 amit.gupta 257
                estDlvyTime = datetime.strptime(estimatedDelivery.split('-')[0].strip(), "%A %d %B %Y")
258
                createdOn = datetime.fromtimestamp(merchantOrder.createdOnInt)
259
                subOrder.trackAfter = int(time.mktime(max(estDlvyTime-timedelta(days=4),createdOn + timedelta(days=3)).timetuple()))
14464 amit.gupta 260
                subOrder.productCode = productUrl.split('/')[5]
261
                subOrder.detailedStatus = detailedStatus
18028 amit.gupta 262
                (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, unitPrice)
15346 amit.gupta 263
                dealRank = getDealRank(subOrder.productCode, self.store_id, merchantOrder.userId)
264
                subOrder.dealRank = dealRank.get('rank')
265
                subOrder.rankDesc = dealRank.get('description')
16283 amit.gupta 266
                subOrder.maxNlc = dealRank.get('maxNlc')
267
                subOrder.minNlc = dealRank.get('minNlc')
268
                subOrder.db = dealRank.get('dp')
269
                subOrder.itemStatus = dealRank.get('status')
14464 amit.gupta 270
                cashbackStatus = Store.CB_PENDING
271
                if cashbackAmount <= 0:
272
                    cashbackStatus = Store.CB_NA
273
                subOrder.cashBackStatus = cashbackStatus
18028 amit.gupta 274
                subOrder.cashBackAmount = cashbackAmount*quantity
14464 amit.gupta 275
                if percentage > 0:
276
                    subOrder.cashBackPercentage = percentage
277
                subOrders.append(subOrder)
278
        priceList = paymentAnchor.next_sibling.next_sibling.next_sibling.table.table.tbody.tbody.tbody.findAll('tr', recursive=False)
279
        totalAmount = 0
280
        grandAmount = 0
281
        for price in priceList:
282
            labelTd = price.td
283
            if 'Subtotal:' in labelTd.text:
284
                totalAmount += int(float(labelTd.next_sibling.next_sibling.find('span').contents[-1].replace(',','')))
285
            elif 'Grand Total:' in labelTd.text:
286
                grandAmount += int(float(labelTd.next_sibling.next_sibling.find('span').contents[-1].replace(',','')))
287
        if grandAmount < totalAmount:
288
            diff = totalAmount - grandAmount
289
            for subOrder in merchantOrder.subOrders:
290
                subOrder.amountPaid -= int(diff*(1-subOrder.amountPaid/totalAmount))
14698 amit.gupta 291
        merchantOrder.status='success'
14464 amit.gupta 292
        self._updateToOrder(todict(merchantOrder))
18376 amit.gupta 293
 
294
    def parseAnotherStlye(self, merchantOrder, pqobj):
295
        counter=0
296
        detailSection = None
297
        shipmentSection = None
298
        summarySection = None
299
        for el in pqobj('.a-section'):
300
            if "View order details" in pq(el).text():
301
                detailSection =  pq(el)
302
                counter += 1
303
            if "Shipment details" in pq(el).text():
304
                shipmentSection =  pq(el)
305
                counter += 1
306
            if "Order Summary" in pq(el).text():
307
                summarySection = pq(el)
308
                counter += 1
309
            if counter == 3:
310
                break
311
 
312
        print "detail" if detailSection else "", "shipment" if shipmentSection else "", "summary" if summarySection else ""
313
 
314
        print pq(detailSection('li .a-row .a-span-last')[0]).text(), pq(detailSection('li .a-row .a-span-last')[1]).text(), pq(detailSection('li .a-row .a-span-last')[2]).text()
315
 
316
        i=-1    
317
        for s in shipmentSection('.a-box-group'):
318
            shipmentGroup = pq(s)
319
            for shipment in shipmentGroup('.a-box'):
320
                i += 1 
321
                if i==0:
322
                    continue
323
                shipment = pq(shipment)
324
                shipmentStatusSection = shipment('.a-section:eq(0)')
325
                productDetails = shipment('.a-section:eq(1)>.a-row')
18380 amit.gupta 326
                print shipmentStatusSection('h3').text(), shipmentStatusSection('p').text(), shipmentStatusSection('span').text()
18376 amit.gupta 327
                for productDetail in productDetails:
328
                    productDetail = pq(productDetail)
329
                    pImg = productDetail.children('div').eq(0)
330
                    pQty = productDetail.children('div').eq(1)
331
                    #print pImg('a').attr('href'), pImg('a').attr('title'), pImg('img').attr('src'), pQty('.a-row:nth-child(2)')('span').text().split(':')[1].strip(), pQty('span.currencyINR')
332
                    print pImg('a').attr('href'), pQty('.a-row:nth-child(2)')('span').text().split(':')[1].strip()
333
                    print int(float(pQty('nobr').text().replace('Rs.','').replace(',', '')))
334
 
335
 
336
        raise   
337
 
338
 
339
        merchantOrder.orderTrackingUrl = merchantOrder.orderSuccessUrl
340
        merchantOrder.placedOn
341
        merchantOrder.merchantOrderId
342
        merchantOrder.paidAmount
14464 amit.gupta 343
 
344
    def parseNewStlye(self, merchantOrder, soup):
345
        merchantOrder.orderTrackingUrl = merchantOrder.orderSuccessUrl
346
        orderDetailsContainer = soup.body.find(id="orderDetails")
14566 amit.gupta 347
        divAfterH1 = orderDetailsContainer.h1.next_sibling.next_sibling
348
        orderLeftDiv = divAfterH1.div
14464 amit.gupta 349
        placedOnSpan = orderLeftDiv.find("span", {'class':'order-date-invoice-item'})
350
        merchantOrder.placedOn =placedOnSpan.text.split('Ordered on')[1].strip()
351
        merchantOrder.merchantOrderId = placedOnSpan.next_sibling.next_sibling.text.split('Order#')[1].strip()
15555 amit.gupta 352
        try:
353
            priceBox = divAfterH1.next_sibling.next_sibling.next_sibling.next_sibling.find("div", {"class":"a-box-inner"}).div.div.findAll('div', recursive=False)[-1]
354
        except:
355
            priceBox = divAfterH1.next_sibling.next_sibling.next_sibling.next_sibling.find("div", {"class":"a-box a-last"}).div.div.findAll('div', recursive=False)[-1]
14464 amit.gupta 356
        priceRows = priceBox.findAll('div', {'class':'a-row'})
357
        subTotal = 0
14566 amit.gupta 358
        shippingPrice = 0   
14464 amit.gupta 359
        promoApplied = 0
360
        for priceRow in priceRows:
361
            if "Item(s) Subtotal:" in str(priceRow):
362
                subTotal = int(float(priceRow.div.next_sibling.next_sibling.span.span.text.replace('Rs.','').replace(',', '')))
363
            elif "Shipping:" in str(priceRow):
364
                shippingPrice  = int(float(priceRow.div.next_sibling.next_sibling.span.span.text.replace('Rs.','').replace(',', '')))
365
            elif "Grand Total:" in str(priceRow):
366
                grandPrice  = int(float(priceRow.div.next_sibling.next_sibling.span.span.text.replace('Rs.','').replace(',', '')))
367
                merchantOrder.paidAmount = grandPrice
368
            elif "Total:" in str(priceRow):
369
                totalPrice  = int(float(priceRow.div.next_sibling.next_sibling.span.span.text.replace('Rs.','').replace(',', '')))
370
            elif "Promotion Applied:" in str(priceRow):
371
                promoApplied  += int(float(priceRow.div.next_sibling.next_sibling.span.span.text.replace('Rs.','').replace(',', '')))
372
        totalPaid = subTotal        
373
        if promoApplied > 0:
374
            totalPaid -= promoApplied
375
            if shippingPrice <= promoApplied:
376
                totalPaid  += shippingPrice
15473 amit.gupta 377
 
17601 amit.gupta 378
        shipmentDivs = orderDetailsContainer.findAll('div', class_='shipment')
14464 amit.gupta 379
        subOrders = []
380
        merchantOrder.subOrders = subOrders
15473 amit.gupta 381
        closedStatus = True
17601 amit.gupta 382
        subOrders = []
18161 amit.gupta 383
        j=0
14464 amit.gupta 384
        for shipmentDiv in shipmentDivs:
17601 amit.gupta 385
            shipmentDiv = shipmentDiv.div
17361 amit.gupta 386
            try:
387
                trackingUrl = 'http://www.amazon.in/' + shipmentDiv.find('span', class_='track-package-button').span.a.get('href')
388
            except:
389
                trackingUrl= None
390
 
17347 amit.gupta 391
            deliverySpanTop = None
14464 amit.gupta 392
            innerBoxes = shipmentDiv.findAll('div', recursive = False)
393
            statusDiv = innerBoxes[0]
394
            subOrderStatus = statusDiv.div.span.text.strip()
17347 amit.gupta 395
            try:
396
                deliverySpanTop = statusDiv.div.div.find_next_sibling('div').span
397
            except:
17617 amit.gupta 398
                pass
18030 amit.gupta 399
            #if not deliverySpanTop:
400
            productDivs = innerBoxes[-1].div.div.findAll('div', recursive=False)
14464 amit.gupta 401
            merchantOrder.subOrders = subOrders
402
            for i, productDiv in enumerate(productDivs):
17347 amit.gupta 403
                deliverySpan = deliverySpanTop
404
                if not deliverySpanTop:
405
                    if i%2==1:
406
                        continue
18028 amit.gupta 407
                    deliverySpan = productDiv.div.div.span
18156 amit.gupta 408
                    try:
409
                        productDiv = productDivs[i+1]
410
                    except:
411
                        pass
18028 amit.gupta 412
                for  prodRow in productDiv.findAll('div', recursive=False):
413
                    j += 1
414
                    imgDiv  = prodRow.div.div
415
                    detailDiv = imgDiv.find_next_sibling('div')
416
                    detailDivs = detailDiv.findAll('div', recursive=False)
417
                    arr = re.split("^(\d+) of", detailDivs[0].a.text.strip())
418
                    (productTitle, quantity) = (arr[-1], (1 if len(arr)<2 else int(arr[1])) )
14756 amit.gupta 419
                    try:
18028 amit.gupta 420
                        unitPrice = int(float(detailDivs[2].span.text.replace('Rs. ','').replace(',','')))
14756 amit.gupta 421
                    except:
18028 amit.gupta 422
                        unitPrice = int(float(detailDivs[3].span.text.replace('Rs. ','').replace(',','')))
423
                    amountPaid = int((unitPrice*quantity*totalPaid)/subTotal)
424
                    productUrl = "http://www.amazon.in" + detailDivs[0].a.get('href')
425
                    subOrder = SubOrder(productTitle, productUrl, merchantOrder.placedOn, amountPaid, MStore.ORDER_PLACED, quantity)
426
                    subOrder.productCode = productUrl.split('/')[5]
427
                    subOrder.unitPrice = unitPrice
428
                    subOrder.merchantSubOrderId = str(j) + " of " + merchantOrder.merchantOrderId
429
                    estDlvyTime = datetime.now()
430
                    if deliverySpan is not None:
431
                        try:
432
                            subOrder.estimatedDeliveryDate = deliverySpan.span.text.strip()
433
                            estDate = subOrder.estimatedDeliveryDate.split("-")[0].strip()
434
                            subOrder.estimatedDeliveryInt = int(time.mktime((datetime.strptime(estDate, "%A %d %B %Y")).timetuple()))
435
                            estDlvyTime = datetime.strptime(estDate, "%A %d %B %Y")
436
                        except:
437
                            if "Delivered on" in deliverySpan.text:
438
                                subOrder.deliveredOn = deliverySpan.text.split(":")[1].strip() 
439
                            subOrder.estimatedDeliveryDate = "Not available"
440
 
441
                    createdOn = datetime.fromtimestamp(merchantOrder.createdOnInt)
442
                    subOrder.trackAfter = int(time.mktime(max(estDlvyTime-timedelta(days=4),createdOn + timedelta(days=3)).timetuple()))
443
                    subOrder.detailedStatus = subOrderStatus
444
                    status=MStore.ORDER_PLACED
17599 amit.gupta 445
                    try:
18028 amit.gupta 446
                        status = self._getStatusFromDetailedStatus(subOrderStatus)
17599 amit.gupta 447
                    except:
448
                        try:
18028 amit.gupta 449
                            dateString = subOrderStatus.split("Delivered ")[1].strip()
450
                            subOrder.status = MStore.ORDER_DELIVERED
451
                            subOrder.detailedStatus = 'Delivered'
452
                            dateString = getDateStringDelivered(dateString)
17631 amit.gupta 453
                            if dateString is not None:
18028 amit.gupta 454
                                subOrder.deliveredOn = datetime.strftime(dateString, '%d-%b-%y')
17599 amit.gupta 455
                        except:
18028 amit.gupta 456
                            try:
457
                                dateString = subOrderStatus.split("Arriving ")[1].split("by")[0].strip()
458
                                subOrder.status = MStore.ORDER_SHIPPED
459
                                dateString = getDateStringArriving(dateString)
460
                                if dateString is not None:
461
                                    subOrder.deliveryEstimate = datetime.strftime(dateString, '%d-%b-%y')
462
                                else:
463
                                    subOrder.deliveryEstimate = subOrderStatus.split("Arriving ")[1].split("by")[0].strip()
464
                            except:
465
                                print "Unknown status Alert -", status
466
 
467
                    subOrder.deliveryCharges = shippingPrice
468
                    if trackingUrl:
18156 amit.gupta 469
                        subOrder.trackingUrl  = trackingUrl
18028 amit.gupta 470
                    subOrder.imgUrl = imgDiv.img["src"]
471
                    (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, amountPaid/quantity)
472
                    dealRank = getDealRank(subOrder.productCode, self.store_id, merchantOrder.userId)
473
                    subOrder.dealRank = dealRank.get('rank')
474
                    subOrder.rankDesc = dealRank.get('description')
18384 amit.gupta 475
                    subOrder.maxNlc = dealRank.get('maxNlc')
476
                    subOrder.minNlc = dealRank.get('minNlc')
477
                    subOrder.db = dealRank.get('dp')
478
                    subOrder.itemStatus = dealRank.get('status')
18028 amit.gupta 479
                    cashbackStatus = Store.CB_PENDING
480
                    if cashbackAmount <= 0:
481
                        cashbackStatus = Store.CB_NA
482
                    subOrder.cashBackStatus = cashbackStatus
483
                    subOrder.cashBackAmount = cashbackAmount*quantity
484
                    if percentage > 0:
485
                        subOrder.cashBackPercentage = percentage
486
                    if hasattr(subOrder, 'deliveredOn') or subOrder.status==Store.ORDER_DELIVERED:                               
487
                        subOrder.status = Store.ORDER_DELIVERED
488
                        subOrder.closed = True
489
                        if subOrder.cashBackStatus == Store.CB_PENDING:
490
                            subOrder.cashBackStatus = Store.CB_APPROVED
491
                    elif closedStatus:
492
                        closedStatus= False
493
                    subOrders.append(subOrder)
14698 amit.gupta 494
        merchantOrder.status='success'
15473 amit.gupta 495
        merchantOrder.closed = closedStatus
14464 amit.gupta 496
        self._updateToOrder(todict(merchantOrder))
14545 amit.gupta 497
 
498
    def parseCancelled(self, merchantOrder,soup):
14722 amit.gupta 499
        try:
500
            fonts = soup.body.findAll("table", recursive=False)[1].findAll("font")
501
            if fonts[0].text == "Important Message":
502
                if fonts[1].text=="This order has been cancelled.":
503
                    merchantOrder.closed = True
504
                    merchantOrder.status = "cancelled"
505
                    merchantOrder.requireDetail = False
506
                    self._updateToOrder(todict(merchantOrder))
507
                    return
508
                else:
509
                    raise ParseException("parseCancelled", "Found detailed status" + fonts[1].text)
14545 amit.gupta 510
            else:
511
                raise ParseException("parseCancelled", "Found detailed status" + fonts[1].text)
14722 amit.gupta 512
        except:
14549 amit.gupta 513
            orderDetails = soup.body.find(id="orderDetails")
514
            if orderDetails is not None and orderDetails.h4.text == "This order has been cancelled.":
515
                merchantOrder.closed = True
14698 amit.gupta 516
                merchantOrder.status = "cancelled"
14549 amit.gupta 517
                merchantOrder.requireDetail = False
518
                self._updateToOrder(todict(merchantOrder))
519
            else:
520
                raise ParseException("parseCancelled", "Found detailed status" + fonts[1].text)
14464 amit.gupta 521
 
13868 amit.gupta 522
    def getTrackingUrls(self, userId):
14074 amit.gupta 523
 
524
        missingOrderUrls = []
525
        missingOrders = self._getMissingOrders({'userId':userId})
526
        for missingOrder in missingOrders:
527
            missingOrderUrls.append(ORDER_REDIRECT_URL%(missingOrder['merchantOrderId']))
17453 amit.gupta 528
        orders = self._getActiveOrders({'userId':userId})
13882 amit.gupta 529
        count = len(orders)
13879 amit.gupta 530
        print "count", count
14948 amit.gupta 531
        print "Missing Urls"
532
        print "*************"
533
        print missingOrderUrls
13868 amit.gupta 534
        if count > 0:
14684 amit.gupta 535
            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 536
        else: 
14074 amit.gupta 537
            return missingOrderUrls
13927 amit.gupta 538
 
539
    def trackOrdersForUser(self, userId, url, rawHtml):
17718 amit.gupta 540
        rawHtml = re.sub(r'[^\x00-\x7F]+',' ', rawHtml)
14985 amit.gupta 541
        directory = "/AmazonTrack/User" + str(userId)
14285 amit.gupta 542
        if not os.path.exists(directory):
543
            os.makedirs(directory)
14173 amit.gupta 544
 
14945 amit.gupta 545
 
13995 amit.gupta 546
        try:
547
            searchMap = {'userId':userId}
548
            collectionMap = {'merchantOrderId':1}
549
            activeOrders = self._getActiveOrders(searchMap, collectionMap)
14033 amit.gupta 550
            datetimeNow = datetime.now()
551
            timestamp = int(time.mktime(datetimeNow.timetuple()))
14009 amit.gupta 552
            print "url----------------", url
17465 amit.gupta 553
            cancelledSummary = False
14320 amit.gupta 554
            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 555
                if url == 'https://www.amazon.in/gp/css/order-history':
556
                    filename = directory + "/orderSummary" + datetime.strftime(datetime.now(), '%d-%m:%H:%M:%S')
557
                else:   
17465 amit.gupta 558
                    filename = directory + "/cancelledSummary" + datetime.strftime(datetime.now(), '%d-%m:%H:%M:%S')
559
                    cancelledSummary = True   
14945 amit.gupta 560
                f = open(filename,'w')
561
                f.write(rawHtml) # python will convert \n to os.linesep
562
                f.close() # you can omit in most cases as the destructor will call if
18158 amit.gupta 563
                soup = BeautifulSoup(rawHtml,'html5lib')
13995 amit.gupta 564
                allOrders = soup.find(id="ordersContainer").findAll('div', {'class':'a-box-group a-spacing-base order'})
565
                bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
566
                for activeOrder in activeOrders:
17307 amit.gupta 567
                    matched=False
13995 amit.gupta 568
                    for orderEle in allOrders:
17254 amit.gupta 569
                        deliveredOn = None
570
                        deliveryEstimate = None
17258 amit.gupta 571
                        shippingEstimate = None
13995 amit.gupta 572
                        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'})
573
                        merchantOrderId = orderdiv.find('span', {'class':'a-color-secondary value'}).text.strip()
574
                        if merchantOrderId==activeOrder['merchantOrderId']:
17307 amit.gupta 575
                            matched=True
13995 amit.gupta 576
                            closed = True
17465 amit.gupta 577
                            if not cancelledSummary:
578
                                shipments = orderEle.findAll('div',{'class':re.compile('.*?shipment.*?')}, recursive=False)
579
                            else:
580
                                shipments = orderEle.findAll('div',{'class':re.compile('.*?a-box.*?')}, recursive=False)
581
                                shipments.pop(0)
13995 amit.gupta 582
                            for shipment in shipments:
17307 amit.gupta 583
                                orderStatusDesc = None
13995 amit.gupta 584
                                shipdiv = shipment.find('div', {'class':'a-box-inner'})
14050 amit.gupta 585
                                sdivs = shipment.div.div.findAll('div', recursive=False)
17254 amit.gupta 586
                                try:
17270 amit.gupta 587
                                    orderStatus = sdivs[0].span.text.strip()
588
                                    status = self._getStatusFromDetailedStatus(orderStatus)
17254 amit.gupta 589
                                except:
17270 amit.gupta 590
                                    try:
591
                                        dateString = orderStatus.split("Delivered ")[1].strip()
592
                                        status = MStore.ORDER_DELIVERED
593
                                        deliveredOn = datetime.strftime(getDateStringDelivered(dateString), '%d-%b-%y')
594
                                    except:
595
                                        try:
17271 amit.gupta 596
                                            dateString = sdivs[0].span.text.strip().split("Arriving ")[1].split("by")[0].strip()
17270 amit.gupta 597
                                            status = MStore.ORDER_SHIPPED
598
                                            deliveryEstimate = datetime.strftime(getDateStringArriving(dateString), '%d-%b-%y')
599
                                        except:
600
                                            print "Unknown status Alert -", orderStatus
17348 amit.gupta 601
                                print merchantOrderId, "Order Status", orderStatus
17256 amit.gupta 602
                                try:
17270 amit.gupta 603
                                    orderStatusDesc = sdivs[0].findAll('div')[1].div.text.strip()
604
                                except:
17271 amit.gupta 605
                                    try:
606
                                        orderStatusDesc = sdivs[0].findAll('div')[1].text.strip()
607
                                    except:
17307 amit.gupta 608
                                        print "Order Status Description None or empty for", merchantOrderId, "and User", userId
17270 amit.gupta 609
 
17271 amit.gupta 610
                                if orderStatusDesc: 
17348 amit.gupta 611
                                    print merchantOrderId, "Order status desc", orderStatusDesc
17271 amit.gupta 612
                                    try:
17348 amit.gupta 613
                                        status = self._getStatusFromDetailedStatus(orderStatus)
614
                                    except:
615
                                        pass
616
                                    try:
17271 amit.gupta 617
                                        if "Dispatch estimate" in orderStatusDesc:
618
                                            shippingEstimate = orderStatus.split("Dispatch estimate").split("-")[0].strip()
619
                                        elif "Delivery estimate" in orderStatus:
620
                                            deliveryEstimate = orderStatus.split("Delivery estimate").split("-")[0].strip()
621
                                        elif "Arriving" in orderStatus:
622
                                            deliveryEstimate = datetime.strftime(getDateStringArriving(orderStatus.split("Arriving")[1].strip().split("by")[0].strip()), '%d-%b-%y')
623
                                    except:
624
                                        print "Could not find anything relevent for merchantOrder", merchantOrderId, "and User", userId 
625
                                        closed=False
626
                                        status = None
17258 amit.gupta 627
 
14335 amit.gupta 628
                                productDivs = shipdiv.find('div', {'class':re.compile('.*?a-spacing-top-medium.*?')}).find('div', {'class':'a-row'}).findAll('div', recursive=False)
13995 amit.gupta 629
                                trackingUrl = None
630
                                for buttonDiv in shipdiv.findAll('span', {'class':'a-button-inner'}):
631
                                    if buttonDiv.find('a').text.strip()=='Track package':
632
                                        trackingUrl = buttonDiv.find('a')['href'].strip()
633
                                        if not trackingUrl.startswith("http"):
14608 amit.gupta 634
                                            trackingUrl = "http://www.amazon.in" + trackingUrl
13995 amit.gupta 635
                                        break
636
                                for prodDiv in productDivs:
637
                                    prodDiv.find('div', {'class':'a-fixed-left-grid-inner'})
638
                                    productTitle = prodDiv.find('div', {'class':'a-fixed-left-grid-inner'}).find("div", {'class':'a-row'}).find('a').text.strip()
639
                                    imgUrl = prodDiv.find("img")["src"]
640
                                    for subOrder in activeOrder['subOrders']:
17307 amit.gupta 641
                                        if subOrder['closed']==True:
642
                                            continue
17230 amit.gupta 643
                                        if subOrder['productTitle'] in productTitle:
13995 amit.gupta 644
                                            findMap = {"orderId": activeOrder['orderId'], "subOrders.merchantSubOrderId": subOrder.get("merchantSubOrderId")}
645
                                            updateMap = {}
646
                                            closedStatus = False
647
                                            updateMap['subOrders.$.imgUrl'] = imgUrl
14033 amit.gupta 648
                                            updateMap['subOrders.$.lastTracked'] = timestamp
17258 amit.gupta 649
                                            if status:
17348 amit.gupta 650
                                                updateMap['subOrders.$.detailedStatus'] = orderStatus
17258 amit.gupta 651
                                                updateMap['subOrders.$.status'] = status 
652
                                                cashbackStatus = subOrder.get("cashBackStatus")
13995 amit.gupta 653
 
17251 amit.gupta 654
                                            if status==MStore.ORDER_DELIVERED:
17271 amit.gupta 655
                                                if deliveredOn:                               
17254 amit.gupta 656
                                                    updateMap['subOrders.$.deliveredOn'] = deliveredOn
13995 amit.gupta 657
                                                closedStatus = True
658
                                                updateMap['subOrders.$.closed'] = True
659
                                                if cashbackStatus == Store.CB_PENDING:
14607 amit.gupta 660
                                                    updateMap['subOrders.$.cashBackStatus'] = Store.CB_APPROVED
13995 amit.gupta 661
                                            if status==MStore.ORDER_CANCELLED:     
662
                                                closedStatus = True
663
                                                updateMap['subOrders.$.closed'] = True
664
                                                if cashbackStatus == Store.CB_PENDING:
665
                                                    updateMap['subOrders.$.cashBackStatus'] = Store.CB_CANCELLED
17254 amit.gupta 666
                                            if status==MStore.ORDER_SHIPPED:
667
                                                if deliveryEstimate:   
668
                                                    updateMap['subOrders.$.estimatedDeliveryDate'] = deliveryEstimate
13995 amit.gupta 669
                                                if trackingUrl is not None:
670
                                                    updateMap['subOrders.$.trackingUrl'] = trackingUrl
17322 amit.gupta 671
                                                    updateMap['subOrders.$.trackMissing'] = False
17258 amit.gupta 672
                                            if shippingEstimate:   
673
                                                updateMap['subOrders.$.estimatedShippingDate'] = shippingEstimate
13995 amit.gupta 674
                                            if not closedStatus:
675
                                                closed = False
17307 amit.gupta 676
                                            #{"subOrders.closed":False,"subOrders.trackingUrl":{"$exists":False},"subOrders.trackAfter":{"$lt":utils.getCurrTimeStamp()}
17359 amit.gupta 677
                                            updateMap['status']='success'
13995 amit.gupta 678
                                            bulk.find(findMap).update({'$set' : updateMap})
679
                                            break
17321 amit.gupta 680
                            bulk.find({'orderId': activeOrder['orderId']}).update({"$set":{'closed':closed}})
17307 amit.gupta 681
                            break
682
                    if not matched:
17319 amit.gupta 683
                        updateMap = {'subOrders.$.trackMissing': True}
17307 amit.gupta 684
                        for subOrder in activeOrder['subOrders']:
685
                            if subOrder['closed']==True:
686
                                continue
687
                            findMap = {"orderId": activeOrder['orderId'], "subOrders.merchantSubOrderId": subOrder.get("merchantSubOrderId"), 
688
                                       "subOrders.trackAfter":{"$lt":utils.getCurrTimeStamp()}}
689
                            bulk.find({'orderId': activeOrder['orderId']})
690
                            bulk.find(findMap).update({'$set':updateMap})
14080 amit.gupta 691
                bulk.execute()
692
                return 'PARSED_SUCCESS'
693
            else:
15563 amit.gupta 694
                merchantOrderId = re.findall(r'https://www.amazon.in/gp/css/summary/edit.html\?orderID=(.*)?', url, re.IGNORECASE)[0]
695
                print  "merchantOrderId", merchantOrderId
14085 amit.gupta 696
                merchantOrder = self.db.merchantOrder.find_one({"merchantOrderId":merchantOrderId})
14945 amit.gupta 697
 
698
                filename = directory + "/" + merchantOrderId   
699
                f = open(filename,'w')
700
                f.write(rawHtml) # python will convert \n to os.linesep
701
                f.close() # you can omit in most cases as the destructor will call if
15555 amit.gupta 702
                result = self.parseOrderRawHtml(merchantOrder['orderId'], merchantOrder['subTagId'], merchantOrder['userId'], rawHtml, url, True)['result']
15562 amit.gupta 703
                print "result", result
15555 amit.gupta 704
                try:
15560 amit.gupta 705
                    order1 = session.query(OrdersRaw).filter_by(id=merchantOrder['orderId']).first()
706
                    order1.status = result
707
                    order1.rawhtml = rawHtml
17358 amit.gupta 708
                    order1.order_url = url
15555 amit.gupta 709
                    session.commit()
15561 amit.gupta 710
                except:
711
                    traceback.print_exc()
15555 amit.gupta 712
                finally:
713
                    session.close()
14080 amit.gupta 714
                return 'PARSED_SUCCESS'
715
                pass
14008 amit.gupta 716
            return 'PARSED_SUCCESS_NO_ORDERS'
13995 amit.gupta 717
        except:
718
            traceback.print_exc()    
719
            return 'PARSED_FAILED'
720
 
721
    def _getStatusFromDetailedStatus(self, detailedStatus):
14061 amit.gupta 722
        if "ordered from" in detailedStatus.lower():
723
            return MStore.ORDER_PLACED 
724
 
13995 amit.gupta 725
        for key, value in self.orderStatusRegexMap.iteritems():
14032 amit.gupta 726
            if detailedStatus.lower() in value:
13995 amit.gupta 727
                return key
728
 
17253 amit.gupta 729
        print "Detailed Status need to be mapped", "Store:", self.store_id, detailedStatus
13995 amit.gupta 730
        raise ParseException("_getStatusFromDetailedStatus", "Found new order status" + detailedStatus)
14624 amit.gupta 731
    def scrapeAffiliate(self, startDate=None, endDate=None):
14650 amit.gupta 732
        br = getBrowserObject()
733
        br.add_password('https://assoc-datafeeds-eu.amazon.com', 'Saholic', 'Fnubyvp')
734
        url = AMAZON_AFF_URL
735
        response = br.open(url)
736
        #get data for past 40 days and store it to mongo
737
        dt = datetime.now()
14701 amit.gupta 738
        dat = dt - timedelta(days=2)
14651 amit.gupta 739
        url = AMAZON_AFF_FILE_URL%(datetime.strftime(dat, "%Y%m%d"))
740
        response = br.open(url)
741
        page = gzip.GzipFile(fileobj=response, mode='rb').read()
742
        j=-1
743
        for row in page.split("\n"):
744
            j += 1
745
            if j== 0 or j==1:
746
                continue
747
            fields = row.split("\t")
748
            if len(fields)>1:
749
                print fields
750
                amazonAffiliate = AmazonAffiliateInfo(fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7], fields[8], fields[9])
751
                print amazonAffiliate
752
                self.db.amazonAffiliateInfo.insert(todict(amazonAffiliate))
753
            else:
754
                break
14650 amit.gupta 755
 
14608 amit.gupta 756
 
16468 amit.gupta 757
    def parseTrackingUrl(self, trackingUrl, orderId):
16474 amit.gupta 758
        print trackingUrl
14624 amit.gupta 759
        subOrder = {}
14749 amit.gupta 760
        page = fetchResponseUsingProxy(trackingUrl)
16468 amit.gupta 761
        status = MStore.ORDER_SHIPPED
762
        #print page
14624 amit.gupta 763
        soup = BeautifulSoup(page)
16468 amit.gupta 764
        header1 = soup.find("h1") 
765
        if header1:
766
            if header1.text=="Sign In":
767
                print "Login page is displayed for order id", orderId
17307 amit.gupta 768
                self.db.merchantOrder.update({"orderId":orderId}, {"$set":{"trackError":True}})
14624 amit.gupta 769
                return subOrder
16468 amit.gupta 770
        try:
16474 amit.gupta 771
            print "Tracking page is displayed for order id", orderId
16468 amit.gupta 772
            detailedStatus = soup.find("div", {"class":"top"}).span.text.strip()
773
            try:
774
                displayStatus = soup.find("div",{"class":"a-column a-span12 shipment-status-content"}).span.text.strip()
775
            except:
776
                displayStatus = detailedStatus
777
            print displayStatus
778
            if detailedStatus.lower().find("delivered")>=0:
779
                print detailedStatus
780
                displayStatus = "Delivered"
781
                status = "Delivered"
782
                try:
783
                    subOrder["deliveredOn"] = detailedStatus.split("on")[1].strip()
784
                except:
785
                    pass
786
 
787
            elif detailedStatus.lower() == 'returned':
788
                status = 'Cancelled'
789
            subOrder['status'] = status
790
            subOrder['detailedStatus'] = displayStatus 
17350 amit.gupta 791
            self.db.merchantOrder.update({"orderId":orderId}, {"$set":{"trackError":False}})    
16468 amit.gupta 792
 
793
        except:
17350 amit.gupta 794
            self.db.merchantOrder.update({"orderId":orderId}, {"$set":{"trackError":True}})    
16468 amit.gupta 795
            print "failed to parse", orderId
796
            traceback.print_exc()
797
 
14624 amit.gupta 798
        return subOrder
799
 
800
 
801
 
16980 amit.gupta 802
    def parseInfo(self,):
803
        from pyquery import PyQuery as pq
16986 amit.gupta 804
        orders = list(session.query(Orders).filter_by(store_id=self.store_id).filter_by(status='DETAIL_CREATED').group_by(Orders.user_id).all())
16980 amit.gupta 805
        try:
806
            for order in orders:
807
                try:
808
                    doc = pq(order.rawhtml)
809
                    #a1= " ".join(["" if not div.text else div.text.replace("\t","").replace("\n","").replace(" ", "") for div in pq(doc('article')[-1])('div')])
810
                    lists = doc('ul.displayAddressUL li')
16986 amit.gupta 811
                    orderInfo = All_user_addresses()
16980 amit.gupta 812
                    orderInfo.address = lists[-3].text
813
                    orderInfo.user_id = order.user_id
16986 amit.gupta 814
                    orderInfo.source = 'order' 
815
                    #orderInfo.order_id = order.id
816
                    #orderInfo.email = None
817
                    #orderInfo.name = lists[0].text 
818
                    #orderInfo.mobile = None
16980 amit.gupta 819
                    adSplit = lists[-2].text.split(",")
820
                    match = re.match(r"([a-z ]+)([0-9]+)", adSplit[1], re.I)
821
                    if match:
822
                        items = match.groups()
16986 amit.gupta 823
                    orderInfo.city = adSplit[0].strip()
824
                    orderInfo.pincode = items[1].strip()
825
                    orderInfo.state = items[0].strip().title()
16980 amit.gupta 826
                    session.commit()
827
                except:
828
                    session.rollback()
829
                    continue
830
        finally:
831
            session.close()
14608 amit.gupta 832
 
13927 amit.gupta 833
 
834
 
13774 amit.gupta 835
def main():
16874 amit.gupta 836
    store = getStore(1)
18376 amit.gupta 837
    #store.parseOrderRawHtml("444444", '123', 14, readSSh('/home/amit/80444.html'), 'https://www.amazon.in/gp/css/summary/edit.html?orderID=402-1449548-9569169')
18031 amit.gupta 838
    orders = list(session.query(OrdersRaw).filter_by(status = 'DETAIL_NOT_CREATED_UNKNOWN').filter(OrdersRaw.id > 61071).all())
18378 amit.gupta 839
    session.close()
18377 amit.gupta 840
    for o in orders:
841
        try:
842
            store.trackOrdersForUser(o.id, o.order_url, o.rawhtml)
843
        finally:
844
            session.close()
17631 amit.gupta 845
    #store.trackOrdersForUser(10466, 'https://www.amazon.in/gp/css/summary/edit.html?orderID=403-7498756-0837158', readSSh('/AmazonTrack/User10466/403-7498756-0837158'))
18030 amit.gupta 846
    #store.trackOrdersForUser(46195, 'https://www.amazon.in/gp/css/summary/edit.html?orderID=404-4294022-1187515', readSSh('/home/amit/amazon.html'))
17231 amit.gupta 847
 
848
def getSummaryFile(directory):
849
    date1 = datetime(2015,1,1)
850
    finalFile = None
851
    try:
852
        for file in os.listdir(directory):
853
            if file.startswith("orderSummary"):
854
                date2 = datetime.strptime("2015-" + file.split("orderSummary")[1].split(":")[0], "%Y-%d-%m")
855
                if date2 > date1:
856
                    date1 = date2
857
                    finalFile=file
858
    except:
859
        print "Missing directory"
17251 amit.gupta 860
    return finalFile 
17231 amit.gupta 861
 
15555 amit.gupta 862
 
863
def parseDetailNotCreated():
864
    try:
865
        store=getStore(1)
866
        orders = session.query(OrdersRaw).filter_by(status='DETAIL_NOT_CREATED_UNKNOWN').all()
15558 amit.gupta 867
        session.close()
15555 amit.gupta 868
        for order in orders:
869
            store.trackOrdersForUser(order.id, order.order_url, order.rawhtml)
870
 
871
    finally:
872
        session.close()
17251 amit.gupta 873
 
874
def getDateStringDelivered(dateString='Monday'):
17254 amit.gupta 875
    print dateString
17251 amit.gupta 876
    if dateString.lower()=='today':
877
        return date.today()
878
    if dateString.lower()=='yesterday':
879
        return date.today() - timedelta(days=1)
880
    try:
881
        return datetime.strptime(dateString, '%d-%b-%y')
882
    except:
883
        try:
884
            #get Closest Date from today
885
            curDate = date.today()
886
            curTime = datetime(curDate.year, curDate.month, curDate.day)
887
            curYear = curDate.year
888
            prevYear = curYear - 1
17254 amit.gupta 889
            dateMax = datetime.strptime(dateString + " " + str(curYear), "%A, %d %b %Y")
890
            dateMin = datetime.strptime(dateString + " " + str(prevYear), "%A, %d %b %Y")
17251 amit.gupta 891
            if dateMax <= curTime:
892
                return dateMax
893
            else:
894
                return dateMin 
895
        except:
17254 amit.gupta 896
            try:
897
                days_of_week = ['sunday','monday','tuesday','wednesday',
898
                            'thursday','friday','saturday']
899
                deltaDays = curDate.isoweekday() - days_of_week.index(dateString.lower())
900
                if deltaDays <= 0:
901
                    deltaDays= deltaDays + 7
902
                curDate = curDate - timedelta(days=deltaDays)
903
                print datetime.strftime(curDate, '%d-%b-%y')
904
                return curDate
905
            except:
906
                print "could not parse"
907
                return None
15565 amit.gupta 908
 
17254 amit.gupta 909
def getDateStringArriving(dateString='Thursday'):
910
    print dateString
911
    if dateString.lower()=='today':
912
        return date.today()
913
    if dateString.lower()=='tomorrow':
914
        return date.today() + timedelta(days=1)
915
    try:
916
        return datetime.strptime(dateString, '%d-%b-%y')
917
    except:
918
        try:
919
            #get Closest Date from today
920
            curDate = date.today()
921
            curTime = datetime(curDate.year, curDate.month, curDate.day)
922
            curYear = curDate.year
923
            nextYear = curYear + 1
924
            dateMin = datetime.strptime(dateString + " " + str(curYear), "%A, %d %b %Y")
925
            dateMax = datetime.strptime(dateString + " " + str(nextYear), "%A, %d %b %Y")
926
            if dateMin >= curTime:
927
                return dateMin
928
            else:
929
                return dateMax 
930
        except:
931
            try:
932
                days_of_week = ['sunday','monday','tuesday','wednesday',
933
                            'thursday','friday','saturday']
934
                deltaDays = days_of_week.index(dateString.lower()) - curDate.isoweekday()
935
                if deltaDays < 0:
936
                    deltaDays= deltaDays + 7
937
                curDate = curDate + timedelta(days=deltaDays)
938
                return curDate
939
            except:
940
                print "Could not parse"
941
                return None 
942
 
18028 amit.gupta 943
def main1():
944
    store = getStore(1)
945
    for merchantOrder in store.db.merchantOrder.find({"subOrders":{"$elemMatch":{"cashBackStatus":"Not Applicable", "cashBackPercentage":{"$gt":0}}}}):
946
        mo = obj(merchantOrder)
947
        for subOrder in mo.subOrders:
948
            subOrder.closed=False 
949
        print "orderId", mo.orderId
950
        store.populateDerivedFields(mo, False)
951
        store.db.merchantOrder.update({"orderId":mo.orderId}, {"$set":todict(mo)})
952
        break
953
 
954
 
15565 amit.gupta 955
def parseOrderNotCreated():
956
    try:
957
        store=getStore(1)
958
        orders = session.query(OrdersRaw).filter_by(status='ORDER_NOT_CREATED_UNKNOWN').all()
959
        session.close()
960
        for order in orders:
15567 amit.gupta 961
            result = store.parseOrderRawHtml(order.id, order.sub_tag, order.user_id, order.rawhtml, order.order_url)['result']
962
            order1 = session.query(OrdersRaw).filter_by(id=order.id).first()
963
            order1.status = result
964
            session.commit()
15565 amit.gupta 965
    finally:
966
        session.close()
15555 amit.gupta 967
 
13774 amit.gupta 968
if __name__ == '__main__':
17599 amit.gupta 969
#    readSSh("/AmazonTrack/User2942/402-2467356-7564367")
970
#    readSSh("/AmazonTrack/User10466/orderSummary18-11:21:32:36")
18156 amit.gupta 971
#    readSSh("/AmazonTrack/User5525/171-0333104-6169933")
18159 amit.gupta 972
    main()
973
    #store=getStore(1)
974
    #store.trackOrdersForUser(5525, "https://www.amazon.in/gp/css/summary/edit.html?orderID=171-0333104-6169933", readSSh("/AmazonTrack/User5525/171-0333104-6169933"))