Subversion Repositories SmartDukaan

Rev

Rev 13729 | Rev 13868 | 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
'''
13724 amit.gupta 6
from datetime import datetime
13569 amit.gupta 7
from pymongo.mongo_client import MongoClient
8
import importlib
13662 amit.gupta 9
import json
10
import math
13569 amit.gupta 11
import mechanize
13631 amit.gupta 12
import traceback
13662 amit.gupta 13
import urllib
14
import urllib2
13582 amit.gupta 15
sourceMap = {1:"amazon", 2:"flipkart", 3:"snapdeal", 4:"spice", 5:"homeshop18"}
13662 amit.gupta 16
headers = { 
17
           'User-agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
18
            'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',      
19
            'Accept-Language' : 'en-US,en;q=0.8',                     
20
            'Accept-Charset' : 'ISO-8859-1,utf-8;q=0.7,*;q=0.3'
21
        }
22
CASHBACK_URL = 'http://api.profittill.com/cashbacks/index/%s/%s'
13677 amit.gupta 23
USER_LOOKUP_URL = 'http://api.profittill.com/user_account/saholic/%s'
24
WALLET_CREDIT_URL = 'http://www.shop2020.in:8080/mobileapi/wallet?userId=%s&isLoggedIn=true'
13569 amit.gupta 25
 
26
def getStore(source_id):
27
    #module = sourceMap[source_id]
28
    store = Store(source_id)
13631 amit.gupta 29
    try:
30
        module = importlib.import_module("dtr.sources." + sourceMap[source_id])
31
        store = getattr(module, "Store")(source_id)
32
        return store
33
    except:
13781 amit.gupta 34
        traceback.print_exc()
13631 amit.gupta 35
        return None
13569 amit.gupta 36
 
37
class ScrapeException(Exception):
38
    """Exception raised for errors in the input.
39
 
40
    Attributes:
41
        expr -- input expression in which the error occurred
42
        msg  -- explanation of the error
43
    """
44
 
45
    def __init__(self, expr, msg):
46
        self.expr = expr
47
        self.msg = msg
48
 
49
class ParseException(Exception):
50
    """Exception raised for errors in the input.
51
 
52
    Attributes:
53
        expr -- input expression in which the error occurred
54
        msg  -- explanation of the error
55
    """
56
 
57
    def __init__(self, expr, msg):
58
        self.expr = expr
59
        self.msg = msg
60
 
13677 amit.gupta 61
client = MongoClient('mongodb://localhost:27017/') 
62
 
13569 amit.gupta 63
class Store(object):
64
 
65
    ORDER_PLACED = 'Order Placed'
66
    ORDER_DELIVERED = 'Delivered'
67
    ORDER_SHIPPED = 'Shipped' #Lets see if we can make use of it
68
    ORDER_CANCELLED = 'Cancelled'
69
 
13662 amit.gupta 70
    CB_INIT = 'Waiting Confirmation'
13610 amit.gupta 71
    CB_PENDING = 'Pending'
72
    CB_CREDITED = 'Credited to wallet'
73
    CB_NA = 'Not Applicable'
74
    CB_APPROVED = 'Approved'
75
    CB_CANCELLED = 'Cancelled'
13569 amit.gupta 76
 
13662 amit.gupta 77
    CONF_CB_SELLING_PRICE = 0
78
    CONF_CB_DISCOUNTED_PRICE = 1
13610 amit.gupta 79
 
13569 amit.gupta 80
    def __init__(self, store_id):
13662 amit.gupta 81
        self.db = client.Dtr
13569 amit.gupta 82
        self.store_id = store_id
13576 amit.gupta 83
        self.store_name = sourceMap[store_id]
13569 amit.gupta 84
 
13662 amit.gupta 85
    '''
86
    To Settle payback for respective stores.
87
    Also ensures that settlement happens only for approved orders
88
    '''
13569 amit.gupta 89
 
90
    def getName(self):
91
        raise NotImplementedError
92
 
93
    def scrapeAffiliate(self, startDate=None, endDate=None):
94
        raise NotImplementedError
95
 
96
    def saveToAffiliate(self, offers):
97
        raise NotImplementedError
98
 
99
    def scrapeStoreOrders(self,):
100
        raise NotImplementedError
13610 amit.gupta 101
 
13690 amit.gupta 102
    def _saveToOrder(self, order):
103
        collection = self.db.merchantOrder
104
        try:
105
            order = collection.insert(order)
106
            #merchantOder 
107
        except Exception as e:
108
            traceback.print_exc()
13662 amit.gupta 109
 
110
    def getCashbackAmount(self, productCode, amount):
111
        alagvar = CASHBACK_URL % (self.store_id,productCode)
112
        filehandle = urllib2.Request(alagvar,headers=headers)
113
        x= urllib2.urlopen(filehandle)
114
        map = json.loads(x.read())
115
        if map['cashback']==0:
13721 amit.gupta 116
            return (0,0)
13662 amit.gupta 117
        else:
118
            if map['cashback_type'] == 'percentage':
13721 amit.gupta 119
                return (math.floor((amount * map['cashback'])/100), map['cashback'])
13662 amit.gupta 120
            else:
13721 amit.gupta 121
                return (map['cashback'], 0)
122
 
13662 amit.gupta 123
 
13569 amit.gupta 124
    '''
125
    Parses the order for specific store
126
 
127
    order id, total amount, created on(now() if could not parse
128
    suborder id, title, quantity, unit price, expected delivery date,
129
    status (default would be Order placed)
130
 
131
    once products are identified, each suborder can then be updated
132
    with respective cashback.
133
 
134
    Possible fields to display for Not yet delivered orders are 
135
    Product/Quantity/Amount/Store/CashbackAmount/OrderDate/ExpectedDelivery/OrderStaus/DetailedStatus/CashbackStatus
136
    No need to show cancelled orders.
13610 amit.gupta 137
    CashbackStatus - NotApplicable/Pending/Approved/Cancelled/CreditedToWallet
13569 amit.gupta 138
    OrderStatus - Placed/Cancelled/Delivered
139
    '''
13576 amit.gupta 140
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
13569 amit.gupta 141
 
142
        pass
143
 
13721 amit.gupta 144
    def _updateOrdersPayBackStatus(self, searchMap, updateMap):
13781 amit.gupta 145
        searchMap['subOrders.missingAff'] = False
146
        updateMap['subOrders.$.missingAff'] = True
13721 amit.gupta 147
        self.db.merchantOrder.update(searchMap, { '$set': updateMap })
148
 
13781 amit.gupta 149
    def _getActiveOrders(self, searchMap={}, collectionMap={}):
13721 amit.gupta 150
        collection = self.db.merchantOrder
13781 amit.gupta 151
        searchMap = dict(searchMap.items()+ {"closed": False, "storeId" : self.store_id}.items()) 
152
        collectionMap =  dict(collectionMap.items() + {"orderSuccessUrl":1, "orderId":1,"subOrders":1, "placedOn":1}.items())
153
        stores = collection.find(searchMap, collectionMap)
13721 amit.gupta 154
        return [store for store in stores]
155
 
156
    def _isSubOrderActive(self,order, merchantSubOrderId):
157
        subOrders = order.get("subOrders")
158
        for subOrder in subOrders:
159
            if merchantSubOrderId == subOrder.get("merchantSubOrderId"):
160
                return subOrder
161
        return None
162
 
163
 
164
 
13662 amit.gupta 165
def main():
13677 amit.gupta 166
    #store = getStore(3)
167
    #print store.getCashbackAmount('864683341', 100)
168
    data = urllib.urlencode({'orderId':6000, 'amount':200})
169
    request = urllib2.Request(WALLET_CREDIT_URL % (483649), headers=headers)
170
    response = urllib2.urlopen(request, data)
171
    print response.read()
13662 amit.gupta 172
 
13569 amit.gupta 173
if __name__ == '__main__':
13662 amit.gupta 174
    main()
13569 amit.gupta 175
 
176
 
13677 amit.gupta 177
def settlePayBack():
178
        orders = client.Dtr.merchantOrder.find({'subOrders.cashBackStatus':Store.CB_APPROVED}, {'userId':1, 'orderId': 1, 'subOrders.cashBackAmount':1, 'subOrders.merchantSubOrderId':1})
179
        for order in orders:
180
            print order
181
            for subOrder in order.get('subOrders'):
182
                if subOrder.get('cashBackAmount') is not None:
183
                    if __refundToWallet(order['userId'], order['orderId'], subOrder.get('cashBackAmount')):
184
                        client.Dtr.merchantOrder.update({'orderId':order['orderId'], 'subOrders.merchantSubOrderId':subOrder['merchantSubOrderId']},{'subOrders.$.cashBackStatus':Store.CB_CREDITED})
185
                        print "Settled order-", order['orderId'], "Sub Order-", subOrder['merchantSubOrderId'], "for amount", subOrder['cashBackAmount']
186
 
187
def __refundToWallet(self, userId, orderId, amount):
188
    userLookupRequest = urllib2.Request(USER_LOOKUP_URL %(userId), headers=headers)
189
    response = urllib2.urlopen(userLookupRequest).read()
190
    saholicUserId = json.loads(response)['account_id']
191
 
192
    request = urllib2.Request(WALLET_CREDIT_URL % (saholicUserId), headers=headers)
193
    data = urllib.urlencode({'orderId':orderId, 'amount':amount})
194
    response = urllib2.urlopen(request, data)
195
 
196
    return json.loads(response.read())['credited']
197
 
13569 amit.gupta 198
def getBrowserObject():
199
    import cookielib
200
    br = mechanize.Browser(factory=mechanize.RobustFactory())
201
    cj = cookielib.LWPCookieJar()
202
    br.set_cookiejar(cj)
203
    br.set_handle_equiv(True)
204
    br.set_handle_redirect(True)
205
    br.set_handle_referer(True)
206
    br.set_handle_robots(False)
207
    br.set_debug_http(False)
208
    br.set_debug_redirects(False)
209
    br.set_debug_responses(False)
210
 
211
    br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)
212
 
213
    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'),
214
                     ('Accept', 'text/html,application/xhtml+xml,application/json,application/xml;q=0.9,*/*;q=0.8'),
215
                     ('Accept-Encoding', 'gzip,deflate,sdch'),                  
216
                     ('Accept-Language', 'en-US,en;q=0.8'),                     
217
                     ('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.3')]
13677 amit.gupta 218
    return br
219
 
13690 amit.gupta 220
def ungzipResponse(r):
221
    headers = r.info()
222
    if headers['Content-Encoding']=='gzip':
223
        import gzip
224
        gz = gzip.GzipFile(fileobj=r, mode='rb')
225
        html = gz.read()
226
        gz.close()
227
        return html
13724 amit.gupta 228
 
229
def tprint(*msg):
13728 amit.gupta 230
    print datetime.now(), "-", msg