Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
13569 amit.gupta 1
'''
2
Created on Jan 15, 2015
3
 
4
@author: amit
5
'''
13690 amit.gupta 6
from BeautifulSoup import BeautifulSoup
13721 amit.gupta 7
from datetime import datetime, date, timedelta
13569 amit.gupta 8
from dtr import main
14412 amit.gupta 9
from dtr.dao import AffiliateInfo, Order, SubOrder, FlipkartAffiliateInfo
13690 amit.gupta 10
from dtr.main import getBrowserObject, getStore, ParseException, ungzipResponse, \
14398 amit.gupta 11
    Store as MStore, sourceMap, tprint
15539 amit.gupta 12
from dtr.storage.DataService import Clicks, Users, FlipkartOrders
16209 amit.gupta 13
from dtr.utils import utils
20395 amit.gupta 14
from dtr.utils.utils import fetchResponseUsingProxy, todict, getSkuData,\
15
    ORDER_PLACED
15539 amit.gupta 16
from elixir import *
13690 amit.gupta 17
from pprint import pprint
18
from pymongo.mongo_client import MongoClient
17238 amit.gupta 19
import StringIO
20
import csv
13690 amit.gupta 21
import hashlib
13658 manas 22
import importlib
13690 amit.gupta 23
import json
24
import mechanize
14412 amit.gupta 25
import pymongo
13658 manas 26
import re
14338 amit.gupta 27
import traceback
13658 manas 28
import urllib
18156 amit.gupta 29
import urllib2
20392 amit.gupta 30
from urlparse import urlparse
17238 amit.gupta 31
import zipfile
13658 manas 32
USERNAME='saholic1@gmail.com'
33
PASSWORD='spice@2020'
20392 amit.gupta 34
ORDER_TRACK_URL='https://m.flipkart.com/order_details?src=or&pr=1&type=physical&'
17238 amit.gupta 35
AFFILIATE_URL='https://affiliate.flipkart.com/'
36
AFFILIATE_LOGIN_URL='https://affiliate.flipkart.com/a_login'
37
AFF_REPORT_URL = "https://affiliate.flipkart.com/downloads/a_downloadRequest?type=OrdersReport&parameters=%s"
38
AFF_DOWNLOAD_URL="https://affiliate.flipkart.com/downloads/file?id=%s"
13690 amit.gupta 39
AFF_STATUS_CANCELLED='cancelled'
40
AFF_STATUS_APPROVED='approved'
41
AFF_STATUS_DISAPPROVED='disapproved'
42
AFF_STATUS_PENDING='pending'
17238 amit.gupta 43
statuses = [AFF_STATUS_CANCELLED, AFF_STATUS_APPROVED, AFF_STATUS_DISAPPROVED,AFF_STATUS_PENDING ]
15539 amit.gupta 44
categoryMap = {3:"Mobiles", 5:"Tablets"}
13658 manas 45
 
13679 manas 46
 
13781 amit.gupta 47
class Store(MStore):
13658 manas 48
    OrderStatusMap = {
14679 amit.gupta 49
                      main.Store.ORDER_PLACED : ['approval', 'processing', 'shipping'],
50
                      main.Store.ORDER_DELIVERED : ['your item has been delivered'],
14680 amit.gupta 51
                      main.Store.ORDER_SHIPPED : ['in transit', 'shipment yet to be delivered'],
52
                      main.Store.ORDER_CANCELLED : ['shipment is returned', 'your item has been returned', 'your shipment has been cancelled', 'your shipment has been cancelled.']
13658 manas 53
 
54
                      }
55
    def __init__(self,store_id):
56
        client = MongoClient('mongodb://localhost:27017/')
57
        self.db = client.dtr
58
        super(Store, self).__init__(store_id)
59
 
13569 amit.gupta 60
    def getName(self):
61
        return "flipkart"
62
 
17238 amit.gupta 63
 
64
    def requestDownload(self):
65
    #"https://affiliate.flipkart.com/downloads/a_downloadRequest?type=OrdersReport&parameters=%7B%22filter%22%3A%22approved%22%2C%22till%22%3A%222015-10-03%22%2C%22from%22%3A%222015-04-03%22%7D"
66
        requestReportUrl = "https://affiliate.flipkart.com/downloads/a_downloadRequest?type=OrdersReport&parameters=%s"
67
        br = getBrowserObject()
68
        br.set_debug_responses(True)
69
        br.open(AFFILIATE_URL)
70
        response = br.response()  # copy
71
        #token =  re.findall('window.__FK = "(.*?)"', utils.ungzipResponse(response), re.IGNORECASE)[0]
72
        data = {
73
                    'j_username':'saholic1@gmail.com',
74
                    'j_password':'spice@2020'
75
            }
76
        print utils.ungzipResponse(br.open(AFFILIATE_LOGIN_URL, urllib.urlencode(data)))
77
        till = datetime.strftime(date.today(),"%Y-%m-%d")
78
        start = datetime.strftime(date.today() - timedelta(4), "%Y-%m-%d")
79
        #target = open("dowloadreportids", 'w')
80
        #target.truncate()
81
        for status in statuses:
82
            #try:
83
                data = {"till":till, "from":start, "filter":status}
84
                print json.dumps(data)
85
                request = requestReportUrl%(urllib.quote_plus(json.dumps(data).replace(" ", "")))
86
                print request
87
                response = utils.ungzipResponse(br.open(request))
88
                response = json.loads(response)
89
                print response
90
                if(response['status']=="OK"):
91
                    self.db.flipkartdownloadids.save(response)
92
                else:
93
                    utils.sendmail(['amit.gupta@shop2020.in'], '', "Could not get request data for Flipkart Affiliate downlaod")
94
                    #break 
95
            #except:
96
                utils.sendmail(['amit.gupta@shop2020.in'], '', "Could not get request data for Flipkart Affiliate downlaod due to Internal Server Error")
97
                #break 
98
 
99
 
13690 amit.gupta 100
    def scrapeStoreOrders(self,):
101
        orders = self._getActiveOrders()
13721 amit.gupta 102
        for order in orders:
14692 amit.gupta 103
            print "Order", self.store_name, order['orderId']
14398 amit.gupta 104
            try:
105
                closed = True
20392 amit.gupta 106
                url = ORDER_TRACK_URL + urlparse(order['orderSuccessUrl']).query
14757 amit.gupta 107
                page = fetchResponseUsingProxy(url)
14398 amit.gupta 108
                soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
109
 
110
                sections = soup.findAll("div", {"class":"ui-app-card-body"})
111
                sections.pop(1)
13721 amit.gupta 112
 
14398 amit.gupta 113
                mainOrder = soup.find("ul",{"class":"m-bottom p-cart"})
114
                fkSubOrders = mainOrder.findAll("li")
115
 
116
                #remove unwanted list
117
                fkSubOrders.pop(-1)
118
 
119
 
120
                bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
121
                #fetching suborders details
122
                for subOrder in fkSubOrders:
123
                    updateMap = {}
124
                    y = subOrder.find("header").findAll("span")
125
                    for suborderId in y:
126
                        if "value emp" in str(suborderId):
127
                            merchantSubOrderId = suborderId.text
128
                            break
14692 amit.gupta 129
                    ul = subOrder.find("ul")
130
                    if ul is None:
131
                        ul = subOrder.findAll("div", recursive=False)[0].div.div
132
                    orderItems = ul.findAll("div", recursive=False)
14398 amit.gupta 133
                    i=0
134
                    for orderItem in orderItems:
135
                        closedStatus = False
136
                        merchantSubOrderId = merchantSubOrderId + str(i)
137
                        subOrder =  self._isSubOrderActive(order, merchantSubOrderId)
138
                        if subOrder is None:
139
                            break
14460 amit.gupta 140
                        elif subOrder['closed']:
141
                            break
14398 amit.gupta 142
                        findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": merchantSubOrderId}
143
                        divs = orderItem.findAll('div', recursive=False)
144
                        orderTracking = divs[2]
145
                        orderTrackingDetDiv = divs[3].find('div',{'class':'c-tabs-content m-top active'})
146
                        orderTrackingDet = orderTrackingDetDiv.find('div',{'class':re.compile('tracking-remark')}).text
147
                        updateMap["subOrders.$.detailedStatus"] = orderTrackingDet
14617 amit.gupta 148
                        status = self._getStatusFromDetailedStatus(orderTrackingDet)
14398 amit.gupta 149
                        tr = orderTracking.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})
150
 
151
                        cashbackStatus = subOrder.get("cashBackStatus") 
152
                        if "approveDetails-complete" in str(tr):
153
                            if "processingDetails-complete" in str(tr):
154
                                if "shippingDetails-complete" in str(tr):
155
                                    if "delivery-complete" in str(tr):
156
                                        status = MStore.ORDER_DELIVERED
157
                                        if cashbackStatus == Store.CB_PENDING:
158
                                            cashbackStatus = Store.CB_APPROVED
159
                                        closedStatus = True
160
                                    else:     
161
                                        status = MStore.ORDER_SHIPPED
162
                                        courierTrackAnchor = orderTrackingDetDiv.find('a')
163
                                        trackingUrl = courierTrackAnchor("href")
164
                                        trackingText = courierTrackAnchor.text
165
                                        courierArr = trackingText.split(' : ')
166
                                        updateMap["subOrders.$.trackingUrl"] = trackingUrl
167
                                        updateMap["subOrders.$.trackingNumber"] = courierArr[1]
168
                                        updateMap["subOrders.$.courierName"] = courierArr[0]
169
                                else:
14692 amit.gupta 170
                                    status = MStore.ORDER_CANCELLED
171
                                    closedStatus = True
172
                                    if cashbackStatus == Store.CB_PENDING:
173
                                        cashbackStatus = Store.CB_CANCELLED
14398 amit.gupta 174
                            else: 
13721 amit.gupta 175
                                status = MStore.ORDER_PLACED
14398 amit.gupta 176
                        elif str(tr) in ["approveDetails-ongoing"]:
177
                            status=MStore.ORDER_PLACED             
14617 amit.gupta 178
                        if "dead" in str(tr) or status==MStore.ORDER_CANCELLED:
14398 amit.gupta 179
                            status = MStore.ORDER_CANCELLED
180
                            closedStatus = True
181
                            if cashbackStatus == Store.CB_PENDING:
182
                                cashbackStatus = Store.CB_CANCELLED
183
 
184
                        updateMap["subOrders.$.cashBackStatus"] = cashbackStatus
185
                        updateMap["subOrders.$.status"] = status
186
                        updateMap["subOrders.$.closed"] = closedStatus
187
                        if closed:
188
                            closed = closedStatus
189
                        bulk.find(findMap).update({'$set' : updateMap})
14692 amit.gupta 190
                bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed, 'parseError':False}})
14398 amit.gupta 191
                bulk.execute()            
192
            except:
14692 amit.gupta 193
                self.db.merchantOrder.update({"orderId":order['orderId']}, {"$set":{"parseError":True}})
14847 amit.gupta 194
                tprint("Could not update " + str(order['orderId']) + ' for store ' + self.getName())
14398 amit.gupta 195
                traceback.print_exc()
17238 amit.gupta 196
 
197
    def scrapeAffiliate(self, deltaDays=0):
198
        if deltaDays is None:
199
            deltaDays=0
200
        endDate=date.today() - timedelta(days=1)
201
        startDate = endDate - timedelta(days=deltaDays)
15539 amit.gupta 202
 
17238 amit.gupta 203
        endDate = datetime.strftime(endDate, "%Y-%m-%d")
204
        startDate = datetime.strftime(startDate, "%Y-%m-%d")
17241 amit.gupta 205
        url  = "https://affiliate-api.flipkart.net/affiliate/report/orders/detail/json?startDate=%s&endDate=%s&status=%s&offset=0"
17238 amit.gupta 206
 
207
        for status in statuses:
17241 amit.gupta 208
            nextUrl = url%(startDate, endDate, status)
209
            while nextUrl:
17243 amit.gupta 210
                req = urllib2.Request(nextUrl)
17242 amit.gupta 211
                nextUrl=''
17238 amit.gupta 212
                req.add_header('Fk-Affiliate-Id', 'saholic1g')
213
                req.add_header('Fk-Affiliate-Token', 'a757444e260c46be8c4aeb20352246ac')
214
                resp = urllib2.urlopen(req)
215
                resString = json.loads(resp.read())
216
                orderList = resString["orderList"]
217
                if orderList:
218
                    for order in orderList:
219
                        order['sales'] = int(order['sales']['amount'])
220
                        order['tentativeCommission'] = int(order['tentativeCommission']['amount'])
221
                        subTagId = order.get("affExtParam1")
222
                        userId = None
223
                        email = None
224
                        if subTagId:
225
                            click = session.query(Clicks).filter_by(tag = subTagId).first()
226
                            if click is not None:
227
                                userId= click.user_id 
228
                                user = session.query(Users.email).filter_by(id = userId).first()
229
                                if user is not None:
230
                                    email = user.email
231
 
232
                        flipkartOrder = FlipkartOrders()
233
                        flipkartOrder.subtagId = subTagId
234
                        flipkartOrder.user_id = userId
235
                        flipkartOrder.identifier = order.get("identifier")
236
                        flipkartOrder.email = email
18465 amit.gupta 237
                        flipkartOrder.created = datetime.strptime(order.get("orderDate"), "%d-%m-%Y %H:%M:%S")
17238 amit.gupta 238
                        flipkartOrder.status = order.get("status")
239
                        flipkartOrder.title = order.get("title")
240
                        flipkartOrder.price = order.get("price")
241
                        flipkartOrder.quantity = order.get("quantity")
242
                        flipkartOrder.productCode = order.get("productId")
243
                        flipkartOrder.affiliateOrderItemId = order.get("affiliateOrderItemId")
244
                        flipkartOrder.payOut = order['tentativeCommission']
245
                        flipkartOrder.payOutPercentage = order['commissionRate']
246
                        skuData = getSkuData(2, order.get("productId"))
247
                        if skuData is not None:
248
                            flipkartOrder.catalogId = skuData.get("skuBundleId")
249
                            flipkartOrder.brand = skuData.get("brand")
250
                            flipkartOrder.model = skuData.get("model_name")
251
                            flipkartOrder.category = categoryMap.get(skuData.get("category_id"))
252
                            flipkartOrder.title =skuData.get("source_product_name")
253
 
254
                    session.commit()
17241 amit.gupta 255
                    nextUrl = resString['next']  
13721 amit.gupta 256
 
14412 amit.gupta 257
    def _saveToAffiliate(self, offers):
17238 amit.gupta 258
        collection = self.db.flipkartOrderAffiliateInfo1
259
        count=0
260
        for row in offers:
261
            if count==0:
262
                count += 1
263
                continue
264
            offer = self.covertToObj(row)
265
            collection.save(offer)
266
 
267
    def covertToObj(self,offer):
268
        affiliateorderitemid,title,productid,category,quantity,sales,price,commissionrate,tentativecommission,status,orderdate,saleschannel,customertype,affextparam1, affextparam2  = offer
269
        saleMap = {
270
               "affiliateorderitemid":affiliateorderitemid,
271
                "title":title,
272
                "productid":productid,
273
                "category":category,
274
                "quantity":quantity,
275
                "saleAmount":sales,
276
                "price":price,
277
                "commissionrate":commissionrate,
278
                "payOut":tentativecommission,
279
                "conversionStatus":status,
280
                "saleDate":orderdate,
281
                "saleschannel":saleschannel,
282
                "customertype":customertype,
283
                "affextparam1":affextparam1,
284
                "_id":affiliateorderitemid
285
        }
286
        return saleMap
14412 amit.gupta 287
 
288
 
13658 manas 289
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
13796 amit.gupta 290
        resp= {}
13781 amit.gupta 291
        try:
292
            br = getBrowserObject()
20392 amit.gupta 293
            url = ORDER_TRACK_URL + urlparse(orderSuccessUrl).query 
13781 amit.gupta 294
 
295
            response = br.open(url)
296
            page = ungzipResponse(response)
297
 
298
            merchantOrderId = re.findall('reference_id=(.*?)&', orderSuccessUrl,re.IGNORECASE)[0]
299
            print merchantOrderId
300
 
301
            soup = BeautifulSoup(page,convertEntities=BeautifulSoup.HTML_ENTITIES)
302
 
303
            sections = soup.findAll("div", {"class":"ui-app-card-body"})
304
            sections.pop(1)
305
 
306
            merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
14145 amit.gupta 307
            merchantOrder.orderTrackingUrl = url
13781 amit.gupta 308
            for data in sections:
309
                name = data.findAll("span")
310
                i=0
311
                while i< len(name):
312
                    if "key" in str(name[i]):
313
                        if "Grand Total" in str(name[i]):
314
                            #Total Amount
315
                            merchantOrder.paidAmount = int(re.findall(r'\d+', name[i+1].text)[0])
316
                        elif "Order Date" in str(name[i]):
317
                            merchantOrder.placedOn = name[i+1].text 
318
                    i=i+1    
319
 
320
            merchantOrder.merchantOrderId = merchantOrderId
321
 
322
            mainOrder = soup.find("ul",{"class":"m-bottom p-cart"})
323
            fkSubOrders = mainOrder.findAll("li")
324
            #remove unwanted list
325
            fkSubOrders.pop(-1)
326
            subOrders = []
327
            merchantOrder.subOrders = subOrders
328
 
329
            #fetching suborders details
330
            for subOrder in fkSubOrders:
331
                y = subOrder.find("header").findAll("span")
332
                for suborderId in y:
333
                    if "value emp" in str(suborderId):
334
                        merchantSubOrderId = suborderId.text
335
                        break
20392 amit.gupta 336
                orderItems = subOrder.findAll("div", "product-list-item", recursive=True)
13781 amit.gupta 337
                i=0
338
                for orderItem in orderItems:
339
                    merchantOrder.placedOn
340
                    merchantSubOrderId = merchantSubOrderId + str(i)
341
                    divs = orderItem.findAll('div', recursive=False)
342
                    content = divs[0]
343
                    orderTracking = divs[2]
344
                    orderTrackingDet = divs[3]
345
 
346
 
347
                    imgUrl = content.find('img')['src']
348
                    lineDet = content.find("div",{"class":"product-info"})
349
                    productTitle = lineDet.find("a",{"class":"product-title"}).text
350
                    productUrl =  str(lineDet.find("a")['href'])
351
 
352
                    start='pid='
353
                    s=str(lineDet.find("a")['href'])
14339 amit.gupta 354
                    productCode = re.findall(re.escape(start)+"(.*)",s)[0].strip()
13781 amit.gupta 355
                    mname = lineDet.findAll("span")
356
                    k=0
357
                    while k<len(mname):
358
                        if "note" in str(mname[k]):
359
                            if "Color:" in str(mname[k]):
360
                                productTitle = productTitle + " " + mname[k+1].text
361
 
362
                            elif "Qty:" in str(mname[k]):
363
                                quantity = int(mname[k+1].text)
364
                            elif "Subtotal:" in str(mname[k]):
14343 amit.gupta 365
                                amountPaid = int(re.findall(r'\d+', mname[k+1].text)[0])
13781 amit.gupta 366
                            elif "Delivery:" in str(mname[k]):
367
                                #Delivery Date for sub order
368
                                print "Delivery Date " +mname[k+1].text
369
                        k=k+1
14343 amit.gupta 370
                    merchantsubOrder = SubOrder(productTitle, productUrl, merchantOrder.placedOn, amountPaid,MStore.ORDER_PLACED, quantity)
13781 amit.gupta 371
                    merchantsubOrder.imgUrl  = imgUrl
372
                    merchantsubOrder.productCode = productCode
373
                    merchantsubOrder.merchantSubOrderId = merchantSubOrderId
14337 amit.gupta 374
                    print "productCode", productCode
14340 amit.gupta 375
                    print "amountPaid", amountPaid
14336 amit.gupta 376
                    cashbackAmount, cashbackPercent = self.getCashbackAmount(productCode, amountPaid)
13781 amit.gupta 377
                    cashbackStatus = Store.CB_PENDING
378
                    if cashbackAmount <= 0:
379
                        cashbackStatus = Store.CB_NA
380
                    merchantsubOrder.cashBackAmount = cashbackAmount
381
                    merchantsubOrder.cashBackStatus = cashbackStatus      
20395 amit.gupta 382
                    merchantsubOrder.cashBackPercentage = cashbackPercent
383
                    merchantsubOrder.detailedStatus = str(orderItem.find("div", "tracking-remark", recursive=True).text)   
13781 amit.gupta 384
 
385
                    subOrders.append(merchantsubOrder)
386
                    #To track shipping details         
20395 amit.gupta 387
                    status=ORDER_PLACED    
13781 amit.gupta 388
                    tr = orderTracking.findAll("div",{"class":"tap-bullet-area c-tab-trigger"})
389
                    if "approveDetails-complete" in str(tr):
390
                        if "processingDetails-complete" in str(tr):
391
                            if "shippingDetails-complete" in str(tr):
392
                                if "delivery-complete" in str(tr):
393
                                    status = MStore.ORDER_DELIVERED
394
                                else:     
395
                                    status = MStore.ORDER_SHIPPED
396
                                    orderTracking.find('div', {'class':'tracking-remark active'})
397
                            else:
398
                                status = MStore.ORDER_PLACED
399
                        else: 
13690 amit.gupta 400
                            status = MStore.ORDER_PLACED
20391 amit.gupta 401
                    elif "approveDetails-ongoing" in str(tr):
13781 amit.gupta 402
                        status=MStore.ORDER_PLACED             
14692 amit.gupta 403
                    if "dead" in str(tr) or "shippingDetails-returnOngoing" in str(tr) or "shippingDetails-return" in str(tr):
13781 amit.gupta 404
                        status = MStore.ORDER_CANCELLED    
20395 amit.gupta 405
                    print "Sub Order Status " + str(status)
406
                    subOrder.status=status
407
 
14312 amit.gupta 408
            if self._saveToOrder(todict(merchantOrder)):
409
                resp['result'] = 'ORDER_CREATED'
410
            else:
411
                resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
412
 
13796 amit.gupta 413
            return resp 
13781 amit.gupta 414
        except:
14338 amit.gupta 415
            traceback.print_exc()
14312 amit.gupta 416
            resp['result'] = 'ORDER_NOT_CREATED'
13796 amit.gupta 417
            return resp 
13781 amit.gupta 418
 
14617 amit.gupta 419
    def _getStatusFromDetailedStatus(self, detailedStatus):
420
        for key, value in Store.OrderStatusMap.iteritems():
14626 amit.gupta 421
            if detailedStatus.lower() in value:
14617 amit.gupta 422
                return key
14676 amit.gupta 423
        print "Detailed Status need to be mapped", detailedStatus, "Store:", self.store_name
20392 amit.gupta 424
        raise ParseException("_getStatusFromDetailedStatus", "Found new order status" + detailedStatus)           
13658 manas 425
 
426
def _saveToOrderFlipkart(self, order):
427
        collection = self.db.merchantOrder
428
        order = collection.insert(order)
429
 
13690 amit.gupta 430
 
431
 
432
def hex_md5(password):
433
    m = hashlib.md5()
434
    print(m.digest())
435
 
13658 manas 436
def main():
16210 amit.gupta 437
    store = getStore(2)
20395 amit.gupta 438
    store.parseOrderRawHtml(1, '123', 14, '', 'https://www.flipkart.com/rv/orderConfirmation/orderresponse?reference_id=OD5071037231594670&token=06919f2c830cb1a5ebb9d2798f602261')
13679 manas 439
 
16209 amit.gupta 440
if __name__ == '__main__':
441
        main()
14145 amit.gupta 442