mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-25 07:47:18 +00:00

Changes: - Split out scanner into own file - Move `lib/shared/sdk` -> `lib/sdk` - Move `lib/image-stream` -> `lib/sdk/image-stream` - Move `lib/writer` -> `lib/sdk/writer` - Rename `sdk/standard` -> `sdk/blockdevice` - Move adapters into `sdk/adapters` subdirectory Change-Type: minor Changelog-Entry: Consolidate low-level components into Etcher SDK
204 lines
5.4 KiB
JavaScript
204 lines
5.4 KiB
JavaScript
/*
|
|
* Copyright 2016 resin.io
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
'use strict'
|
|
|
|
const _ = require('lodash')
|
|
const Bluebird = require('bluebird')
|
|
const path = require('path')
|
|
const messages = require('../../../../../shared/messages')
|
|
const errors = require('../../../../../shared/errors')
|
|
const imageStream = require('../../../../../sdk/image-stream')
|
|
const supportedFormats = require('../../../../../shared/supported-formats')
|
|
const analytics = require('../../../modules/analytics')
|
|
const selectionState = require('../../../../../shared/models/selection-state')
|
|
const osDialog = require('../../../os/dialog')
|
|
const exceptionReporter = require('../../../modules/exception-reporter')
|
|
|
|
module.exports = function (
|
|
$timeout,
|
|
WarningModalService
|
|
) {
|
|
/**
|
|
* @summary Main supported extensions
|
|
* @constant
|
|
* @type {String[]}
|
|
* @public
|
|
*/
|
|
this.mainSupportedExtensions = _.intersection([
|
|
'img',
|
|
'iso',
|
|
'zip'
|
|
], supportedFormats.getAllExtensions())
|
|
|
|
/**
|
|
* @summary Extra supported extensions
|
|
* @constant
|
|
* @type {String[]}
|
|
* @public
|
|
*/
|
|
this.extraSupportedExtensions = _.difference(
|
|
supportedFormats.getAllExtensions(),
|
|
this.mainSupportedExtensions
|
|
).sort()
|
|
|
|
/**
|
|
* @summary Select image
|
|
* @function
|
|
* @public
|
|
*
|
|
* @param {Object} image - image
|
|
*
|
|
* @example
|
|
* osDialogService.selectImage()
|
|
* .then(ImageSelectionController.selectImage);
|
|
*/
|
|
this.selectImage = (image) => {
|
|
if (!supportedFormats.isSupportedImage(image.path)) {
|
|
const invalidImageError = errors.createUserError({
|
|
title: 'Invalid image',
|
|
description: messages.error.invalidImage(image)
|
|
})
|
|
|
|
osDialog.showError(invalidImageError)
|
|
analytics.logEvent('Invalid image', image)
|
|
return
|
|
}
|
|
|
|
Bluebird.try(() => {
|
|
let message = null
|
|
|
|
if (supportedFormats.looksLikeWindowsImage(image.path)) {
|
|
analytics.logEvent('Possibly Windows image', image)
|
|
message = messages.warning.looksLikeWindowsImage()
|
|
} else if (!image.hasMBR) {
|
|
analytics.logEvent('Missing partition table', image)
|
|
message = messages.warning.missingPartitionTable()
|
|
}
|
|
|
|
if (message) {
|
|
// TODO: `Continue` should be on a red background (dangerous action) instead of `Change`.
|
|
// We want `X` to act as `Continue`, that's why `Continue` is the `rejectionLabel`
|
|
return WarningModalService.display({
|
|
confirmationLabel: 'Change',
|
|
rejectionLabel: 'Continue',
|
|
description: message
|
|
})
|
|
}
|
|
|
|
return false
|
|
}).then((shouldChange) => {
|
|
if (shouldChange) {
|
|
return this.reselectImage()
|
|
}
|
|
|
|
selectionState.selectImage(image)
|
|
|
|
// An easy way so we can quickly identify if we're making use of
|
|
// certain features without printing pages of text to DevTools.
|
|
image.logo = Boolean(image.logo)
|
|
image.bmap = Boolean(image.bmap)
|
|
|
|
return analytics.logEvent('Select image', image)
|
|
}).catch(exceptionReporter.report)
|
|
}
|
|
|
|
/**
|
|
* @summary Select an image by path
|
|
* @function
|
|
* @public
|
|
*
|
|
* @param {String} imagePath - image path
|
|
*
|
|
* @example
|
|
* ImageSelectionController.selectImageByPath('path/to/image.img');
|
|
*/
|
|
this.selectImageByPath = (imagePath) => {
|
|
imageStream.getImageMetadata(imagePath)
|
|
.then((imageMetadata) => {
|
|
$timeout(() => {
|
|
this.selectImage(imageMetadata)
|
|
})
|
|
})
|
|
.catch((error) => {
|
|
const imageError = errors.createUserError({
|
|
title: 'Error opening image',
|
|
description: messages.error.openImage(path.basename(imagePath), error.message)
|
|
})
|
|
|
|
osDialog.showError(imageError)
|
|
analytics.logException(error)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @summary Open image selector
|
|
* @function
|
|
* @public
|
|
*
|
|
* @example
|
|
* ImageSelectionController.openImageSelector();
|
|
*/
|
|
this.openImageSelector = () => {
|
|
analytics.logEvent('Open image selector')
|
|
|
|
osDialog.selectImage().then((imagePath) => {
|
|
// Avoid analytics and selection state changes
|
|
// if no file was resolved from the dialog.
|
|
if (!imagePath) {
|
|
analytics.logEvent('Image selector closed')
|
|
return
|
|
}
|
|
|
|
this.selectImageByPath(imagePath)
|
|
}).catch(exceptionReporter.report)
|
|
}
|
|
|
|
/**
|
|
* @summary Reselect image
|
|
* @function
|
|
* @public
|
|
*
|
|
* @example
|
|
* ImageSelectionController.reselectImage();
|
|
*/
|
|
this.reselectImage = () => {
|
|
analytics.logEvent('Reselect image', {
|
|
previousImage: selectionState.getImage()
|
|
})
|
|
|
|
this.openImageSelector()
|
|
}
|
|
|
|
/**
|
|
* @summary Get the basename of the selected image
|
|
* @function
|
|
* @public
|
|
*
|
|
* @returns {String} basename of the selected image
|
|
*
|
|
* @example
|
|
* const imageBasename = ImageSelectionController.getImageBasename();
|
|
*/
|
|
this.getImageBasename = () => {
|
|
if (!selectionState.hasImage()) {
|
|
return ''
|
|
}
|
|
|
|
return path.basename(selectionState.getImagePath())
|
|
}
|
|
}
|