Skip to content

Instantly share code, notes, and snippets.

@lf-
Created July 26, 2020 23:31
Show Gist options
  • Save lf-/6cc6161eb689ea8816ce8e967220bd6f to your computer and use it in GitHub Desktop.
Save lf-/6cc6161eb689ea8816ce8e967220bd6f to your computer and use it in GitHub Desktop.
import logging
from pathlib import Path
import time
import requests
MAILGUN_API_KEY = 'key-xxxxx'
MAILGUN_DOMAIN = 'yourdomain.ca'
MAILGUN_FROM = 'dellwatch <dellwatch@yourdomain.ca>'
MAILGUN_TO = 'you@yourdomain.ca'
DELL_API_URL = 'http://www.dell.com/csbapi/en-ca/productanavfilter/GetSystemsResults?ProductCode=xps-15-9560-laptop&page=1&pageSize=16&sappOrderCode=nxps159560_bt_s1637e&preview'
APP_NAME = 'dellwatch'
DEFAULT_LOG_LEVEL = 'INFO'
LOG_PATH = str(Path('~/.dellwatch.log').expanduser())
log = logging.getLogger(APP_NAME)
# if someone set our log level before we initialized, keep their preference
# example: ipython initialization script
if not log.level:
log.setLevel(DEFAULT_LOG_LEVEL)
fmt = logging.Formatter(
'{asctime} {levelname} {filename}:{lineno}: {message}',
datefmt='%b %d %H:%M:%S',
style='{'
)
# prevent adding of extra handlers if autoreload is in use
for handler in log.handlers:
if isinstance(handler, logging.FileHandler):
break
else:
hnd = logging.FileHandler(LOG_PATH)
hnd.setFormatter(fmt)
log.addHandler(hnd)
relevant_specs = ['PROC', 'MEMRY', 'HDRV', 'VIDEO', 'DISPLY', 'BTRY']
sale_fmt = """
Sale: {pricing[MarketValue][Value]} -> {pricing[DellPrice][Value]} on {itemid}
{exp_block}
{specs}
""".lstrip().rstrip()
seen_deals = set()
def is_on_sale(pricing):
return pricing['DellPrice']['InnerValue'] < pricing['MarketValue']['InnerValue']
def make_specs(stack):
spec_list = []
for ts in stack['Specs']['TechSpecs']:
if ts['Code'] in relevant_specs:
spec_list.append(' '.join((ts['Code'], str(ts['Values']))))
return spec_list
def process_stack(stack):
pricing = stack['Stack']['Pricing']
if not is_on_sale(pricing):
return
itemid = stack['Specs']['ItemIdentifier']
specs = '\n'.join(make_specs(stack))
exp_block = '\n'.join([itm['ExpirationText'] for itm in pricing['SavingsDetails']['Details']])
return sale_fmt.format(pricing=pricing, itemid=itemid, specs=specs, exp_block=exp_block)
def process_resp(json_resp):
deals = []
for stack in json_resp['Results']['Stacks']:
pretty = process_stack(stack)
if pretty in seen_deals:
log.debug('Found seen deal, skipping...')
continue
if pretty:
deals.append(pretty)
seen_deals.add(pretty)
return deals
def mail_report(deals):
return requests.post(
f'https://api.mailgun.net/v3/{MAILGUN_DOMAIN}/messages',
auth=('api', MAILGUN_API_KEY),
data={'from': MAILGUN_FROM,
'to': [MAILGUN_TO],
'subject': 'dellwatch sales',
'text': '\n\n'.join(deals)})
def check_sales():
resp = requests.get(DELL_API_URL)
deals = process_resp(resp.json())
log.info('Checked for sales')
if len(deals) <= 0:
return
mail_report(deals)
if __name__ == '__main__':
while True:
try:
check_sales()
except Exception as e:
if isinstance(e, KeyboardInterrupt):
break
log.exception('Encountered an error!', e)
time.sleep(60 * 60 * 24)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment