Skip to content

Instantly share code, notes, and snippets.

@MxAshUp
Created February 27, 2016 05:58
Show Gist options
  • Save MxAshUp/1fac7ad2da9fc1d0a809 to your computer and use it in GitHub Desktop.
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
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