Add UnpackState and DownloadState

This commit is contained in:
garrettmills
2020-03-03 16:10:10 -06:00
parent 10bded1681
commit 2725f9eac2
8 changed files with 140 additions and 2 deletions

View File

@@ -1,5 +1,6 @@
const { Injectable } = require('flitter-di')
const moment = require('moment')
const path = require('path')
class UniversalPath extends Injectable {
static get services() {
@@ -56,6 +57,12 @@ class UniversalPath extends Injectable {
return this.is_file() || this.is_directory()
}
async directory() {
await this.classify()
if ( this.is_directory() ) return this.path
return path.dirname(this.path)
}
async classify() {
const dir_result = await this._host.execute(`${this._directory_classify_command} ${this._path}`)
if ( dir_result.exit_code === 0 ) {

View File

@@ -23,6 +23,7 @@ class Host extends Injectable {
_file_directory_delete_command = `rm -rf "%%RESOURCE%%"`
_resolve_path_command = `readlink -f "%%PATH%%"`
_reboot_command = `reboot`
_change_directory_command = `cd "%%PATH%%"`
constructor(config) {
super()
@@ -106,6 +107,11 @@ class Host extends Injectable {
await this.execute(this._file_directory_delete_command.replace('%%RESOURCE%%', resource_path))
}
get_directory_change_command(path) {
if ( typeof path !== 'string' ) path = path.path
return this._change_directory_command.replace('%%PATH%%', path)
}
async resolve_path(resource_path) {
resource_path = typeof resource_path === 'string' ? resource_path : resource_path.path
return this.run_line_result(this._resolve_path_command.replace('%%PATH%%', resource_path))

View File

@@ -0,0 +1,51 @@
const State = require('../State')
const axios = require('axios')
class DownloadState extends State {
static get services() {
return [...super.services, 'output']
}
async apply() {
if ( !(await this.check()) ) {
const path = await this._path()
if ( !this._config.method ) this._config.method = 'get'
else this._config.method = this._config.method.toLowerCase()
if ( !this._config.source ) throw new Error('Missing source config for DownloadState.')
try {
const res = await axios({
method: this._config.method,
url: this._config.source,
responseType: 'stream',
})
const write_stream = await path.open_write_stream()
await res.data.pipe(write_stream)
} catch(e) {
this.output.error('Error encountered while fetching data for DownloadState.')
throw e
}
}
}
async check() {
const path = await this._path()
await path.classify()
return path.is_file()
}
async reverse() {
if ( await this.check() ) {
const path = await this._path()
await path.unlink()
}
}
async _path() {
if ( !this._config.path ) throw new Error('Missing path config for DownloadState.')
return this._host.get_path(this._config.path)
}
}
module.exports = exports = DownloadState

View File

@@ -28,6 +28,7 @@ class FileState extends State {
}
async _path() {
if ( !this._config.path ) throw new Error('Missing path config for FileState.')
return this._host.get_path(this._config.path)
}
}

View File

@@ -0,0 +1,63 @@
const State = require('../State')
class UnpackState extends State {
static get services() {
return [...super.services, 'output']
}
async apply() {
if ( !(await this.check()) ) {
const path = await this._path()
await path.classify()
if ( !path.is_file() ) throw new Error(`Invalid path for unpack: ${path}`)
const type = await this._get_type()
const destination = await this._destination()
const cd_cmd = await this._host.get_directory_change_command(await destination.directory())
if ( type === 'tar' ) {
const untar_cmd = `${cd_cmd} && tar -x -z -f "${path.path}"`
await this._host.run(untar_cmd)
} else if ( type === 'zip' ) {
const unzip_cmd = `${cd_cmd} && unzip "${path.path}"`
await this._host.run(unzip_cmd)
}
}
}
async check() {
return false
}
async reverse() {
this.output.warn(`Unpack state does not currently support reversal. (Host: ${this._host.name})`)
}
async _get_type() {
if ( this._config.type ) {
if ( this._config.type === 'tar' ) return 'tar'
else if ( this._config.type === 'zip' ) return 'zip'
throw new Error('Invalid unpack type: ' + this._config.type)
} else {
const path = await this._path()
if ( path.path.endsWith('.tar.gz') || path.path.endsWith('.tgz') ) return 'tar'
else if ( path.path.endsWith('.zip') ) return 'zip'
throw new Error(`Unable to determine unpack type from archive: ${path}`)
}
}
async _path() {
if ( !this._config.path ) throw new Error('Missing path config for UnpackState.')
return this._host.get_path(this._config.path)
}
async _destination() {
if ( !this._config.destination ) throw new Error('Missing destination config for UnpackState.')
const path = await this._host.get_path(this._config.destination)
await path.classify()
if ( !path.is_directory() ) throw new Error(`Invalid extraction path. Must be a directory: ${path}`)
return path
}
}
module.exports = exports = UnpackState