Guild Wars 2 Spidy bulk script v1.2
2015-01-29
This is a slightly modified version of the script I use for my Guild Wars 2 spreadsheets for data collection and analysis, consider this 1.2 of the public beta.
As time progresses I will be fixing it so it is robust and easier to use.
////////////////////
//////Settings//////
////////////////////
// the names of your datadump sheet and your logsheet
var sheet = "Data";
var log = "Log";
// To select the sections remove the first "//" before the row you want.
var filters = "http://www.gw2spidy.com/api/v0.9/json/allitems/1"
// "http://www.gw2spidy.com/api/v0.9/json/allitems/# // Number Type
// "http://www.gw2spidy.com/api/v0.9/json/allitems/2", // 65 Bags
// "http://www.gw2spidy.com/api/v0.9/json/allitems/3", // 2274 Misc
// "http://www.gw2spidy.com/api/v0.9/json/allitems/4", // 304 Containers/Satchels
// "http://www.gw2spidy.com/api/v0.9/json/allitems/5", // 1098 Crafting component
// "http://www.gw2spidy.com/api/v0.9/json/allitems/7", // 41 Endless Potions/tonics
// "http://www.gw2spidy.com/api/v0.9/json/allitems/11", // 173 Mini's
// "http://www.gw2spidy.com/api/v0.9/json/allitems/13", // 3 Salvage Kits
// "http://www.gw2spidy.com/api/v0.9/json/allitems/15", // 1362 Accessory
// "http://www.gw2spidy.com/api/v0.9/json/allitems/16", // 262 Junk
// "http://www.gw2spidy.com/api/v0.9/json/allitems/17", // 531 Upgrade components.
// "http://www.gw2spidy.com/api/v0.9/json/allitems/18", // 11469 Weapons
//// Here you can select a custom list in the format as follows ////
// "http://www.gw2spidy.com/api/v0.9/json/items/all/?filter_ids=ID1,ID2,ID3,ID4"
///////////////////////////////////////////////////////////////////////////
///////////////////////////// Dont edit below this ////////////////////////
///////////////////////////////////////////////////////////////////////////
;
// Refresh This is the main function, it automates everything
function refresh(){
expireCache();
updateAll();
updategems();
}
// Menu
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('Investment Tools')
.addItem('Refresh', 'refresh')
.addSeparator()
.addItem('Clear Log', 'clearLog')
.addToUi();
}
// Gem Price
// Use the formula: =updategems() to load it
function updategems(){
var gems = "http://www.gw2spidy.com/api/v0.9/json/gem-price";
var jsonData = UrlFetchApp.fetch(gems);
var jsonString = jsonData.getContentText();
var jsonObject = JSON.parse(jsonString).result; // create object and remove "result" wrapper
var buyValuea = (jsonObject.gold_to_gem);
var sellValuea = (jsonObject.gem_to_gold);
var buyValue = buyValuea/100;
var sellValue = sellValuea/100;
return [buyValue, sellValue];
}
function refreshdata(){
$cache = CacheService.getPublicCache();
}
// Updating Function
function updateAll() {
$url = [filters];
$sheetname = sheet;
$logsheetname = log;
updateRawData($url, $sheetname, $logsheetname);
}
// expire the cache by setting the cache status to null
function expireCache() {
$cache = CacheService.getPublicCache();
$cache.remove("Cache Status");
};
// Clear the Log
function clearLog() {
$shee = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Log");
$shee.getRange(2, 1, $shee.getLastRow(), 6).clearContent();
};
// removes characters that could crash a JSON parse
function makeJSONsafe($unsafe) {
$safe = $unsafe.replace(/(u000A)+|(n)+|u000A|(u000D)+|u000D|u000Au000D|nr/g, ' ');
return $safe;
};
// retrives JSON from Spidy and adds item data to the cache
function add2CacheFromSpidy($JSONURL) {
var $options = { "muteHttpExceptions" : true }; // muting HTTP exceptions prevents script from crashing with HTTP error
var $cache = CacheService.getPublicCache(); // open the cache using Google's CacheService
var $message = "";
$cache.put("Cache Status", "Cache update in progress when data refresh called.");
var i = 0
while (i < $JSONURL.length) {
var $jsonData = UrlFetchApp.fetch($JSONURL[i], $options); // fetch the HTTPResponse Object using Google's URLFetchApp
if ($jsonData.getResponseCode() == 200) { // successful connection
var $jsonString = $jsonData.getContentText(); // retrive JSON string from HTTPResponse Object
var $spidyObject = JSON.parse(makeJSONsafe($jsonString)); // convert JSON string into a JSON Object
var $itemsList = $spidyObject.results; // retrive array of item objects from Spidy JSON Object results parameter
var $numItems = $spidyObject.count; // retrive number of items from Spidy JSON Object count paramter
for (var $j = 0; $j < $numItems; $j++) { // caching loop – each item is stored as an object within the
$cache.put("" + $itemsList[$j].data_id, JSON.stringify($itemsList[$j])); // items list array which is indexed from 0 – $count
} // this loop takes those objects converts them into a JSON string and
// stores them in the cache indexed by the spidy item id
$message = "" + $numItems + " items retrived from GW2Spidy and cached.";
$cache.put("Cache Status", $message, 900); // this is used as a flag to determine if the cache data is fresh (900 seconds)
$message = "";
$cache.put("Connection Error", $message); // reset error message as it is a flag for if there is an error
} else { // unsuccessful connection
$message = "HTTP Error " + $jsonData.getResponseCode() + " during connection attempt";
$cache.put("Connection Error", $message); // set error message
}
i++
}
};
function writeToLog($message, $date, $sheet, $flag) {
if ($flag) {
var $row = $sheet.getLastRow()+1;
$sheet.getRange($row, 2).setValue($date);
$sheet.getRange($row, 3).setValue($message);
}
};
// work horse function, pulls everything together
function updateRawData($url, $sheetName, $logsheetName) {
var $cache = CacheService.getPublicCache(); // open the cache
var $sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName($sheetName); // get sheet to write data too
var $logFlag = 0;
if ($logsheetName != "") {
var $logsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName($logsheetName);
$logFlag = 1; // only log is a logsheet is specified
}
// if Cache Status is null data is old
if ($cache.get("Cache Status") == null) {
writeToLog("Cache update started.", new Date(), $logsheet, $logFlag);
add2CacheFromSpidy($url); // update the cache from URL
$cache = CacheService.getPublicCache(); // refresh cache variable (is this a pointer? can i get rid of this line?
writeToLog($cache.get("Cache Status"), new Date(), $logsheet, $logFlag);
}
if ($cache.get("Connection Error") == "" || $cache.get("Connection Error") == null) {
var $IDList = $sheet.getRange(3, 1, $sheet.getLastRow() - 2, 1).getValues(); // returns 2-D array [row][column] with id stored, [[id1], [id2], etc.]
$itemList = fetchCachedData($IDList, $cache); // fetches the cached data and returns 2D Array [row][column]
$sheet.getRange(3, 2, $IDList.length, 5).setValues($itemList); // write data to spreadsheet
writeToLog("Detected " + $IDList.length + " ID(s) in sheet " + $sheetName + ". Data refreshed successfully.", new Date(), $logsheet, $logFlag);
} else {
writeToLog($cache.get("Connection Error"), new Date(), $logsheet, $logFlag);
}
};
// take range contained IDs and return 2D array of data from the cache
function fetchCachedData($IDList, $cache) {
var $itemObject = null;
var $id = 0;
var $itemList = new Array($IDList.length);
for (var $i = 0; $i < $IDList.length; $i++) {
$id = $IDList[$i][0]; // due to the way the getRange function works, the IDs are in a 2D array [[id1], [id2], [id3], … [idn]]
$itemObject = JSON.parse($cache.get($id)); // convert JSON text in cache into an object
$itemList[$i] = new Array(5);
if (($id > 0) && ($itemObject != null)) { // convert object into an array
$itemList[$i][0] = $itemObject.name;
$itemList[$i][1] = $itemObject.max_offer_unit_price;
$itemList[$i][2] = $itemObject.min_sale_unit_price;
$itemList[$i][3] = $itemObject.price_last_changed;
$itemList[$i][4] = "=(OFFSET(INDIRECT(ADDRESS(ROW(), COLUMN())),-1,0)+1)";
} else {
$itemList[$i][0] = "Error: ID not in cache";
$itemList[$i][4] = "=(OFFSET(INDIRECT(ADDRESS(ROW(), COLUMN())),-1,0)+1)";
}
}
return $itemList;
};