Aug 28, 2016
: ~ 14 min read

For Dropbox handling I chose a pretty small library, node-dropbox. To use it, I went in Dropbox's developer dashboard and created an access token (instead of using secrets and keys) and saved that in my .env. Then onto the helper:

// Force means update even if the date of the file is the same as the database post's
// shouldDelete means files have been deleted and the respective posts need to be deleted
// This is because for deleting there's an extra couple of iterations over all posts, and takes a bit longer
router.get('/' + process.env.MY_SYNC_KEY + '/:key1?/:key2?', function(req, res) {
const shouldDelete = req.params.key1 == 'delete' || req.params.key2 == 'delete'
const forced = req.params.key1 == 'force' || req.params.key2 == 'force'

This will wait for both promises to finish, then return them in an array:

Since Dropbox.getFile is async, and wrapped in a promise, we need to wait for all of them to finish. Luckily, bluebird (Promise) has a nice little helper, map, which will do just that; we just have to return a Promise:

Then we create the title from the first line, delete the second line and create the body out of the rest by transforming the markdown syntax in html with marked, save the last modified time in modified and return the Post object:

We now have an array of Posts that represent the data in Dropbox (newPosts), and an array of Posts that represent the data in the database (posts):

}).then(function(newPosts) {
if (shouldDelete) {
// Iterate through existing posts, and if no corresponding
// file is found, delete the post, and remove it from the data.
data[0].posts.forEach(function(post, index) {
let matchingNewPosts = newPosts.filter(function(newPost) {
return Post.linksMatch(newPost, post) &&
newPost.datetime == post.datetime
})
if (matchingNewPosts.length) { return }
// We don't need to wait for this to finish
Db.deletePost(post)
// After the iteration is finished, posts will represent the data in the database
// with the extra posts removed.
posts.splice(index, 1)
})
}

Quick explanation: if a Dropbox post has the same link and the same datetimeas a database post , it means it's the same entity, since these fields are created out of filenames, which are unique; if they have the same link, but different datetimes, then they are different entities.

We will now iterate through the Dropbox posts, find the ones with matching links, and if none is found, we create it, but since we want to wait for all posts to be created, we will use bluebird's map again, and return an object that contains the matching posts (or empty array), and the newPost: