PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/ipad-target.py

https://github.com/polpo/ipad-target.py
Python | 180 lines | 166 code | 10 blank | 4 comment | 0 complexity | b5d4983e0efde87c437077af45ccb96a MD5 | raw file
  1. #!/usr/bin/python
  2. import urllib
  3. import urllib2
  4. import smtplib
  5. from email.mime.text import MIMEText
  6. import sys
  7. import json as json
  8. mode = sys.argv[1]
  9. zip = sys.argv[2]
  10. dpcis = sys.argv[3:]
  11. models = {
  12. # New models for October 2013
  13. '057-10-1351': 'Apple iPad Air 16GB Wi-Fi - Silver/White (MD788LL/A)',
  14. '057-10-1352': 'Apple iPad Air 16GB Wi-Fi - Space Gray/Black (MD785LL/A)',
  15. '057-10-1353': 'Apple iPad Air 16GB Wi-Fi + Cellular (AT&T) - Silver/White (ME999LL/A)',
  16. '057-10-1354': 'Apple iPad Air 16GB Wi-Fi + Cellular (Verizon) - Silver/White (ME999LL/A)',
  17. '057-10-1355': 'Apple iPad Air 32GB Wi-Fi - Silver/White (MD789LL/A)',
  18. '057-10-1356': 'Apple iPad Air 32GB Wi-Fi - Space Gray/Black (MD786LL/A)',
  19. '057-10-1357': 'Apple iPad Air 32GB Wi-Fi + Cellular (AT&T) - Silver/White (MF529LL/A)',
  20. '057-10-1358': 'Apple iPad Air 32GB Wi-Fi + Cellular (Verizon) - Silver/White (MF532LL/A)',
  21. '057-10-1359': 'Apple iPad Air 64GB Wi-Fi - Space Gray/Black (MD787LL/A)',
  22. '057-10-1360': 'Apple iPad mini with Retina display 16GB Wi-Fi - Silver/White(ME279LL/A)',
  23. '057-10-1361': 'Apple iPad mini with Retina display 16GB Wi-Fi - Space Gray/Black (ME276LL/A)',
  24. '057-10-1362': 'Apple iPad mini with Retina display 32GB Wi-Fi - Silver/Whit(ME280LL/A)',
  25. '057-10-1363': 'Apple iPad mini with Retina display 32GB Wi-Fi - Space Gray/Black (ME277LL/A)',
  26. '057-10-1364': 'Apple iPad mini with Retina display 16GB Wi-Fi + Cellular (AT&T)- Silver/White (MF074LL/A)',
  27. # Currently sold in stores, previous generations
  28. '057-10-0172': 'Apple iPad mini 16GB Wi-Fi - Black (MD528LL/A)',
  29. '057-10-0173': 'Apple iPad mini 16GB Wi-Fi - White (MD531LL/A)',
  30. '057-10-0174': 'Apple iPad mini 32GB Wi-Fi - Black (MD529LL/A)',
  31. '057-10-0175': 'Apple iPad mini 32GB Wi-Fi - White (MD532LL/A)',
  32. '057-10-1830': 'Apple 16GB iPad 2 with Wi-Fi - Black (MC954LL/A)',
  33. '057-10-1839': 'Apple 16GB iPad 2 with Wi-Fi - White (MC989LL/A)',
  34. '057-10-2024': 'Apple 64GB iPad with Wi-Fi (3rd generation) - Black (MC707LL/A)',
  35. '057-10-2026': 'Apple 16GB iPad with Wi-Fi (3rd generation) + 4G for AT&T - Black (MD366LL/A)',
  36. '057-10-2031': 'Apple 64GB iPad with Wi-Fi (3rd generation) + 4G for AT&T - White (MD371LL/A)',
  37. '057-10-2053': 'Apple 32GB iPad with Retina display - White (MD514LL/A)',
  38. '057-10-2054': 'Apple 64GB iPad with Retina display - Black (MD512LL/A)',
  39. '057-10-2055': 'Apple 64GB iPad with Retina display - White (MD515LL/A)',
  40. # Not sold in stores (not an exhaustive list)
  41. '057-10-2020': 'Apple 16GB iPad with Wi-Fi (3rd generation) - Black (MC705LL/A)',
  42. '057-10-2021': 'Apple 16GB iPad with Wi-Fi (3rd generation) - White (MD328LL/A)',
  43. '057-10-2022': 'Apple 32GB iPad with Wi-Fi (3rd generation) - Black (MC706LL/A)',
  44. '057-10-2023': 'Apple 32GB iPad with Wi-Fi (3rd generation) - White (MD329LL/A)',
  45. '057-10-2025': 'Apple 64GB iPad with Wi-Fi (3rd generation) - White (MD330LL/A)',
  46. '057-10-2027': 'Apple 16GB iPad with Wi-Fi (3rd generation) + 4G for AT&T - White (MD369LL/A)',
  47. '057-10-2028': 'Apple 32GB iPad with Wi-Fi (3rd generation) + 4G for AT&T - Black (MD367LL/A)',
  48. '057-10-2029': 'Apple 32GB iPad with Wi-Fi (3rd generation) + 4G for AT&T - White (MD370LL/A)',
  49. '057-10-2030': 'Apple 64GB iPad with Wi-Fi (3rd generation) + 4G for AT&T - Black (MD368LL/A)',
  50. '057-10-2032': 'Apple 16GB iPad with Wi-Fi (3rd generation) + 4G for Verizon - Black (MC733LL/A)',
  51. '057-10-2033': 'Apple 16GB iPad with Wi-Fi (3rd generation) + 4G for Verizon - White (MD363LL/A)',
  52. '057-10-2034': 'Apple 32GB iPad with Wi-Fi (3rd generation) + 4G for Verizon - Black (MC744LL/A)',
  53. '057-10-2036': 'Apple 32GB iPad with Wi-Fi (3rd generation) + 4G for Verizon - White (MD364LL/A)',
  54. '057-10-2037': 'Apple 64GB iPad with Wi-Fi (3rd generation) + 4G for Verizon - Black (MC756LL/A)',
  55. '057-10-2038': 'Apple 64GB iPad with Wi-Fi (3rd generation) + 4G for Verizon - White (MD365LL/A)',
  56. '057-10-0183': 'Apple 32GB iPad with Retina display Wi-Fi + Cellular (AT&T) - Black (MD517LL/A)',
  57. '057-10-0184': 'Apple 32GB iPad with Retina display Wi-Fi + Cellular (Verizon - Black (MD523LL/A)',
  58. '057-10-0185': 'Apple 32GB iPad with Retina display Wi-Fi + Cellular (Sprint - Black (ME196LL/A)',
  59. '057-10-2050': 'Apple 16GB iPad with Retina display - Black (MD510LL/A)',
  60. '057-10-2051': 'Apple 16GB iPad with Retina display - White (MD513LL/A)',
  61. '057-10-2052': 'Apple 32GB iPad with Retina display - Black (MD511LL/A)',
  62. '241-27-2248': 'Apple 16GB iPad with Retina display Wi-Fi + Cellular (AT&T) - Black (MD516LL/A)',
  63. '241-27-2250': 'Apple 16GB iPad with Retina display Wi-Fi + Cellular (AT&T) - White (MD519LL/A)',
  64. '241-27-2256': 'Apple 32GB iPad with Retina display Wi-Fi + Cellular (Verizon)- White (MD526LL/A)',
  65. '241-27-2257': 'Apple 64GB iPad with Retina display Wi-Fi + Cellular (Verizon) - White (MD527LL/A)',
  66. '241-27-2259': 'Apple 64GB iPad with Retina display Wi-Fi + Cellular (Sprint)- Black (ME197LL/A)',
  67. '241-27-2263': 'Apple 32GB iPad with Retina display Wi-Fi + Cellular (AT&T) - White (MD520LL/A)',
  68. '241-27-4384': 'Apple 128GB iPad with Retina display - Black (ME392LL/A)',
  69. '241-27-4385': 'Apple 128GB iPad with Retina display - White (ME393LL/A)',
  70. '057-10-0176': 'Apple iPad mini 64GB Wi-Fi - Black (MD530LL/A)',
  71. '057-10-0177': 'Apple iPad mini 64GB Wi-Fi - White (MD533LL/A)',
  72. '057-10-0178': 'Apple iPad mini 16GB Wi-Fi + Cellular (AT&T) - Black (MD534LL/A)',
  73. '057-10-0180': 'Apple iPad mini 32GB Wi-Fi + Cellular (AT&T) - Black (MD535LL/A)',
  74. '057-10-0187': 'Apple iPad mini 32GB Wi-Fi + Cellular (Verizon) - White (MD544LL/A)',
  75. '057-10-0189': 'Apple iPad mini 64GB Wi-Fi + Cellular (Verizon) - White (MD545LL/A)',
  76. '241-27-2241': 'Apple iPad mini 32GB Wi-Fi + Cellular (AT&T) - White (MD538LL/A)',
  77. '241-27-2243': 'Apple iPad mini 16GB Wi-Fi + Cellular (Verizon) - Black (MD540LL/A)',
  78. '241-27-2244': 'Apple iPad mini 16GB Wi-Fi + Cellular (Verizon) - White (MD543LL/A)',
  79. }
  80. results = ""
  81. stores = {}
  82. if not dpcis:
  83. dpcis = models.keys()
  84. jsonurl = 'http://api.target.com/products/v3/saleable_quantity_by_location?key=q0jGNkIyuqUTYIlzZKoCfK6ugaNGSP8h'
  85. # This only needs to be called if Target changes the key in the URL above and we need to find it out. So far it hasn't changed.
  86. def getjsonurl():
  87. from bs4 import BeautifulSoup
  88. fiatsurl = 'http://www.target.com/FiatsCmd?'
  89. # Get a key to look stuff up with. Use any item get the current key.
  90. fiatsdata = urllib.urlencode({
  91. 'template': 'medium',
  92. 'overlayId': 'FindinStore',
  93. 'pageType': 'pdp',
  94. 'fiatLocation': 'product+detail',
  95. 'catalogEntryID': '204704844',
  96. 'partNumber': '14000303',
  97. 'ValidDpci': '057-10-2020'
  98. })
  99. req = urllib2.Request(fiatsurl + fiatsdata, '', {'X-Requested-With': 'XMLHttpRequest'})
  100. response = urllib2.urlopen(req)
  101. #print response.info()
  102. page = response.read()
  103. soup = BeautifulSoup(page)
  104. jsonurl = soup.find('input', attrs={'id': 'saleableQtyLocURL'})['value']
  105. return jsonurl
  106. def getproductjson(jsonurl):
  107. jsondata = json.dumps({
  108. "products": [{
  109. "product_id": dpci,
  110. "desired_quantity": "1"
  111. } for dpci in dpcis],
  112. "nearby": zip,
  113. "radius": "25",
  114. "multichannel_options":[{
  115. "multichannel_option": "none"
  116. }]
  117. })
  118. req = urllib2.Request(jsonurl, jsondata, {'Content-Type': 'application/json; charset=UTF-8', 'Accept': 'application/json'})
  119. response = urllib2.urlopen(req)
  120. page = response.read()
  121. return page
  122. page = getproductjson(jsonurl)
  123. products = json.loads(page)['products']
  124. for product in products:
  125. product_id = product['product_id']
  126. # Look up friendly product name
  127. if product_id in models:
  128. product_name = models[product_id]
  129. else:
  130. product_name = product_id
  131. for store in product['stores']:
  132. if store['saleable_quantity'] > 0:
  133. if product_name:
  134. results += "%s:\n" % (product_name,)
  135. product_name = None
  136. results += " %s: %s (Qty: %d)\n" % (store['store_name'], store['availability_status'], store['saleable_quantity'])
  137. if store['store_id'] not in stores:
  138. stores[store['store_id']] = store
  139. if stores:
  140. results += '\nStore addresses:\n'
  141. for store in stores.itervalues():
  142. results += " %s: %s\n" % (store['store_name'], store['store_address'])
  143. if results:
  144. if mode == 'print':
  145. print results
  146. elif mode == 'email':
  147. msgto = ['me@example.com']
  148. msgfrom = 'me@example.com'
  149. msg = MIMEText(results)
  150. msg['Subject'] = 'iPad status'
  151. msg['To'] = ', '.join(msgto)
  152. msg['From'] = msgfrom
  153. s = smtplib.SMTP('localhost')
  154. s.sendmail(msgfrom, msgto, msg.as_string())
  155. s.quit()