Created
February 27, 2016 05:58
-
-
Save MxAshUp/1fac7ad2da9fc1d0a809 to your computer and use it in GitHub Desktop.
Checks for Pi Zero availability on Adafruit, Pimoroni, and Pi Hut, sends alerts to Pushbullet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var requestjson = require('request-json'); | |
var request = require('request'); | |
var PushBullet = require('pushbullet'); | |
var pusher = new PushBullet('PUSHBULLET_API_KEY'); | |
var cheerio = require('cheerio'); | |
var stores = [ | |
{name:"The Pi Hut",url:'http://thepihut.com/products/raspberry-pi-zero',in_stock:check_pihut_inventory | |
}, | |
{name:"Adafruit",url:'https://www.adafruit.com/products/2816',in_stock:check_adafruit_inventory | |
}, | |
{name:"Adafruit",url:'https://www.adafruit.com/products/2817',in_stock:check_adafruit_inventory | |
}, | |
{name:"Adafruit",url:'https://www.adafruit.com/products/2885',in_stock:check_adafruit_inventory | |
}, | |
{name:"Pimoroni",url:'https://shop.pimoroni.com/products/raspberry-pi-zero',in_stock:check_pimoroni_inventory | |
}]; | |
function check_pihut_inventory(callback) { | |
var client = requestjson.createClient("http://thepihut.com/"); | |
var ret = []; | |
client.get("products/raspberry-pi-zero.js", function(err, res, body) { | |
if(body) { | |
for (var i = body.variants.length - 1; i >= 0; i--) { | |
sku_map[body.variants[i].sku + "pihut"] = body.variants[i].option1; | |
ret[body.variants[i].sku + "pihut"] = body.variants[i].available | |
}; | |
} | |
callback(ret); | |
}); | |
} | |
function check_adafruit_inventory(callback) { | |
var ret = []; | |
request(this.url,function(err,response,body) { | |
if(!err) { | |
var $ = cheerio.load(body); | |
var twitter_metas = $("meta[name^='twitter']"); | |
var product_name; | |
var in_stock; | |
for (ind in twitter_metas) { | |
if(twitter_metas[ind].attribs) { | |
if(twitter_metas[ind].attribs.name == "twitter:title") { | |
product_name = twitter_metas[ind].attribs.content; | |
} else if(twitter_metas[ind].attribs.name == "twitter:data2") { | |
in_stock = (twitter_metas[ind].attribs.content == "IN STOCK"); | |
} | |
} | |
}; | |
if(typeof(product_name) != 'undefined' && typeof(in_stock) != 'undefined') { | |
ret[product_name+"ada"] = in_stock; | |
sku_map[product_name+"ada"] = product_name; | |
callback(ret); | |
return; | |
} | |
} | |
callback([]); | |
}); | |
} | |
function check_pimoroni_inventory(callback) { | |
var ret = []; | |
request(this.url,function(err,response,body) { | |
if(!err) { | |
var $ = cheerio.load(body); | |
var schema_elements = $("div[itemtype='http://schema.org/Product']"); | |
for (ind in schema_elements) { | |
if(schema_elements[ind].type != "tag") { | |
continue; | |
} | |
var schema_avaialbility = $(schema_elements[ind]).find('meta[itemprop="availability"]'); | |
var schema_name = $(schema_elements[ind]).find('meta[itemprop="name"]'); | |
if(schema_avaialbility && schema_name) { | |
availability = (schema_avaialbility.attr('content') == "http://schema.org/InStock"); | |
prod_name = schema_name.attr('content').replace("Raspberry Pi Zero - Max 1 Pi Zero Per Order! - ",""); | |
sku_map[prod_name+"pim"] = prod_name; | |
ret[prod_name+"pim"] = availability; | |
} | |
} | |
callback(ret); | |
return; | |
} | |
callback([]); | |
}); | |
} | |
function notify_stock(name,url,status,product_name) { | |
/* console.log(product_name); | |
console.log(status); | |
return;*/ | |
if(status) { | |
notify_in_stock(url,name,product_name); | |
} else { | |
notify_out_of_stock(name,product_name); | |
} | |
} | |
function notify_in_stock(url,shop_name,product_name) { | |
pusher.link({channel_tag:'pizeroinstock'}, "In Stock! Pi Zero ("+product_name+") @ " + shop_name, url, function(error, response) { | |
//cool | |
}); | |
} | |
function notify_out_of_stock(shop_name,product_name) { | |
pusher.note({channel_tag:'pizeroinstock'}, "Out of Stock: Pi Zero ("+product_name+") @ " + shop_name, shop_name + " is out of stock of "+product_name+".", function(error, response) { | |
//cool | |
}); | |
} | |
function product_name(sku) { | |
return !(sku in sku_map) ? "Pi Zero" : sku_map[sku]; | |
} | |
var sku_map = []; | |
var in_stock_statuses = []; | |
function check_availability() { | |
var stores_checked = 0; | |
for (var i = stores.length - 1; i >= 0; i--) { | |
(function() { | |
var index = i; | |
var avaialbilities = stores[index].in_stock(function(statuses) { | |
if(statuses && typeof(statuses) == "object") { | |
for(var sku in statuses) { | |
if(!(sku in in_stock_statuses)) { | |
in_stock_statuses[sku] = statuses[sku]; | |
//notify_stock(stores[index].name,stores[index].url,in_stock_statuses[sku],product_name(sku)); | |
} else if(in_stock_statuses[sku] != statuses[sku]) { | |
in_stock_statuses[sku] = statuses[sku]; | |
notify_stock(stores[index].name,stores[index].url,in_stock_statuses[sku],product_name(sku)); | |
} | |
} | |
} | |
stores_checked++; | |
if (stores_checked >= stores.length) { | |
setTimeout(check_availability,1000); | |
}; | |
}); | |
})(); | |
}; | |
} | |
check_availability(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment