Created
May 16, 2015 03:19
-
-
Save fergusean/5cce6edd9f81454611fc to your computer and use it in GitHub Desktop.
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 Image = require('parse-image'); | |
var Comic = Parse.Object.extend('Comic'); | |
Parse.Cloud.job('updateCache', function(request, response) { | |
getLatestStoredNum(function(num) { | |
console.log('Latest stored comic is ' + num); | |
checkForAndCacheNewComicsSince(num, function(success) { | |
if (success) | |
response.success('OK'); | |
else | |
response.error('failed to fetch & cache'); | |
}); | |
}) | |
}); | |
function getLatestStoredNum(callback) { | |
var query = new Parse.Query(Comic); | |
query.select('num'); | |
query.descending('num'); | |
query.limit(1); | |
query.find().then(function(result) { | |
callback(result.length ? result[0].get('num') : null); | |
}); | |
} | |
function checkForAndCacheNewComicsSince(sinceNum, callback) { | |
// if we didn't get a number, we don't have any we should cache all since 0 | |
sinceNum || (sinceNum = 0); | |
// fetch the latest comic | |
fetchComic(null, function(comic) { | |
// if we didn't get a comic, bail out | |
if (!comic) return callback(false); | |
// if this comic number is the same as our "since number", | |
// there are no updates and we have succeeded at... something | |
if (comic.get('num') == sinceNum) { | |
console.log('No updates'); | |
return callback(true); | |
} | |
// debug! | |
console.log('Latest comic is ' + comic.get('num')); | |
// ok, fine, we need to fetch and cache all comics since the last one we have | |
// oh and by the way, here's the latest one | |
fetchAndCacheComicsSinceWithLatestComic(sinceNum, callback, comic); | |
}); | |
} | |
function fetchAndCacheComicsSinceWithLatestComic(sinceNum, callback, latestComic) { | |
// set our current number as 1 above the "since" number | |
var currentNum = sinceNum + 1; | |
// attach image dimensions to the latest | |
attachDimensions(latestComic, function(success) { | |
// fail? | |
if (!success) return callback(false); | |
// save our latest | |
persistComic(latestComic, function(success) { | |
// fail? | |
if (!success) return callback(false); | |
// begin downloading the rest | |
__downloadNext(); | |
}); | |
}); | |
// callback | |
function __downloadNext() { | |
// if the current number is equal to the latest comic's number, we're done! | |
if (currentNum == latestComic.get('num')) return callback(true); | |
// fetch the comic | |
fetchComic(currentNum, function(comic) { | |
// if we didn't get a comic, failure :( | |
if (!comic) return callback(false); | |
// attach the image dimensions | |
attachDimensions(comic, function(success) { | |
// fail? | |
if (!success) return callback(false); | |
// save it | |
persistComic(comic, function(success) { | |
// fail? | |
if (!success) return callback(false); | |
// increment our current number | |
currentNum++; | |
// if the number is 404, skip it, because Randall's a funny bitch | |
if (currentNum == 404) currentNum++; | |
// proceed to the next | |
__downloadNext(); | |
}); | |
}); | |
}); | |
} | |
} | |
function fetchComic(id, callback) { | |
var url = 'http://xkcd.com/'; | |
id && (url += id + '/'); | |
url += 'info.0.json'; | |
Parse.Cloud.httpRequest({ | |
url: url | |
}).then(function(httpResponse) { | |
if (!httpResponse.data || !httpResponse.data.num) { | |
console.error('Unexpected response from URL ' + url); | |
callback(false); | |
} | |
else { | |
console.log('Fetched comic ' + httpResponse.data.num); | |
var comic = new Comic; | |
for (key in httpResponse.data) | |
comic.set(key, httpResponse.data[key]); | |
callback(comic); | |
} | |
}, function(httpResponse) { | |
console.error('Request failed with response code ' + httpResponse.status + ' to URL ' + url); | |
callback(false); | |
}); | |
} | |
function attachDimensions(comic, callback) { | |
Parse.Cloud.httpRequest({ | |
url: comic.get('img'), | |
success: function(response) { | |
console.log('Retrieved image for comic ' + comic.get('num')); | |
var image = new Image(); | |
image.setData(response.buffer, { | |
success: function() { | |
comic.set('img_w', image.width()); | |
comic.set('img_h', image.height()); | |
callback(true); | |
}, | |
error: function(error) { | |
console.error('Failed to load image for comic ' + comic.get('num') + ': ' + error.code); | |
callback(false); | |
} | |
}); | |
}, | |
error: function(error) { | |
console.error('Failed to receive image for comic ' + comic.get('num') + ' from URL ' + comic.get('img') + ': ' + error.code); | |
callback(false); | |
} | |
}); | |
} | |
function persistComic(comic, callback) { | |
comic.save(null, { | |
success: function() { | |
console.log('Stored comic ' + comic.get('num')); | |
callback(true); | |
}, | |
error: function(error) { | |
console.log('Failed to store comic ' + comic.get('num') + ': ' + error.code); | |
callback(false); | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment