libs/remote_tools/offline_handler.js
// * ———————————————————————————————————————————————————————— * //
// * offline_handler
// * set of tools that enables running enduro website offline
// * TODO: developed under time constrain, should be refactored and tested
// * ———————————————————————————————————————————————————————— * //
const offline_handler = function () {}
// * vendor dependencies
const Promise = require('bluebird')
const http = require('http')
const fs = require('fs')
const path = require('path')
// * enduro dependencies
const logger = require(enduro.enduro_path + '/libs/logger')
const pagelist_generator = require(enduro.enduro_path + '/libs/build_tools/pagelist_generator')
const flat = require(enduro.enduro_path + '/libs/flat_db/flat')
const flat_helpers = require(enduro.enduro_path + '/libs/flat_db/flat_helpers')
offline_handler.prototype.convert_cms_file_to_offline = function (cms_file) {
let list_of_external_resources_to_download = []
return flat.load(cms_file)
.then((context) => {
// console.log(cms_file)
// this fills list_of_external_resources_to_download
traverse_offline(context, list_of_external_resources_to_download)
// returns after all external resources are loaded
return Promise.all(list_of_external_resources_to_download)
})
}
offline_handler.prototype.convert_all_to_offline = function () {
const self = this
pagelist_generator.generate_cms_list()
.then((cmslist) => {
return Promise.all(cmslist.flat.map((page) => { return self.convert_cms_file_to_offline(page.fullpath) }))
})
}
// * ———————————————————————————————————————————————————————— * //
// * parse_for_external_links
// *
// * @param link {string} - text where links should be found
// * return array - list of link found in the provided text
// * ———————————————————————————————————————————————————————— * //
function parse_for_external_links (link) {
if (link.substring(0, 4) == 'http') {
return [link]
}
let matches = link.match(/(https.*?)"/g)
if (matches != null) {
matches = matches.map((match) => {
return match.match(/(https.*?)"/)[1]
})
return matches
}
return []
}
function download_external_resource (external_link) {
return new Promise(function (resolve, reject) {
logger.twolog('Downloading ', external_link)
// handle https
external_link = external_link.replace(/^https/, 'http')
const new_filename = path.join('assets', 'img', 'offline', external_link.match(/\/([^\/]*)$/)[1])
flat_helpers.ensure_directory_existence(path.join(enduro.project_path, new_filename))
.then(() => {
const file = fs.createWriteStream(new_filename)
http.get(external_link, function (response) {
response.pipe(file)
resolve(new_filename)
})
})
})
}
// traverses context, finds external links and pushes it to the provided list
function traverse_offline (context, list_of_external_resources_to_download) {
for (c in context) {
if (typeof context[c] === 'string') {
links = parse_for_external_links(context[c])
for (l in links) {
list_of_external_resources_to_download.push(download_external_resource(links[l]).then((local_url) => {
// context['$' + c + '_offline'] = context[c]
// context[c] = local_url
}))
}
}
if (typeof context[c] === 'object') {
traverse_offline(context[c], list_of_external_resources_to_download)
}
}
}
module.exports = new offline_handler()