mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-27 05:06:40 +00:00
Add support for .gz and .bz2 (#419)
See: https://github.com/resin-io/etcher/issues/325 Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This commit is contained in:
parent
c1074de198
commit
3b30748b1f
@ -35,6 +35,7 @@ const app = angular.module('Etcher', [
|
|||||||
// Models
|
// Models
|
||||||
require('./models/selection-state'),
|
require('./models/selection-state'),
|
||||||
require('./models/settings'),
|
require('./models/settings'),
|
||||||
|
require('./models/supported-formats'),
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
require('./components/progress-button/progress-button'),
|
require('./components/progress-button/progress-button'),
|
||||||
@ -83,6 +84,7 @@ app.controller('AppController', function(
|
|||||||
DriveScannerService,
|
DriveScannerService,
|
||||||
SelectionStateModel,
|
SelectionStateModel,
|
||||||
SettingsModel,
|
SettingsModel,
|
||||||
|
SupportedFormatsModel,
|
||||||
ImageWriterService,
|
ImageWriterService,
|
||||||
AnalyticsService,
|
AnalyticsService,
|
||||||
DriveSelectorService,
|
DriveSelectorService,
|
||||||
@ -92,6 +94,7 @@ app.controller('AppController', function(
|
|||||||
OSDialogService
|
OSDialogService
|
||||||
) {
|
) {
|
||||||
let self = this;
|
let self = this;
|
||||||
|
this.formats = SupportedFormatsModel;
|
||||||
this.selection = SelectionStateModel;
|
this.selection = SelectionStateModel;
|
||||||
this.writer = ImageWriterService;
|
this.writer = ImageWriterService;
|
||||||
this.scanner = DriveScannerService;
|
this.scanner = DriveScannerService;
|
||||||
|
98
lib/gui/models/supported-formats.js
Normal file
98
lib/gui/models/supported-formats.js
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @module Etcher.Models.SupportedFormats
|
||||||
|
*/
|
||||||
|
|
||||||
|
const angular = require('angular');
|
||||||
|
const _ = require('lodash');
|
||||||
|
const imageStream = require('etcher-image-stream');
|
||||||
|
const MODULE_NAME = 'Etcher.Models.SupportedFormats';
|
||||||
|
const SupportedFormats = angular.module(MODULE_NAME, []);
|
||||||
|
|
||||||
|
SupportedFormats.service('SupportedFormatsModel', function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Check if a file type is a compressed format
|
||||||
|
* @function
|
||||||
|
* @private
|
||||||
|
*
|
||||||
|
* @param {Object} fileType - file type
|
||||||
|
* @returns {Boolean} whether the file type is a compressed format
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* if (isCompressedFileType({
|
||||||
|
* extension: 'zip',
|
||||||
|
* type: 'compressed'
|
||||||
|
* })) {
|
||||||
|
* console.log('This is a compressed file type');
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
const isCompressedFileType = function(fileType) {
|
||||||
|
return fileType.type === 'compressed';
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Get compressed extensions
|
||||||
|
* @function
|
||||||
|
* @public
|
||||||
|
*
|
||||||
|
* @returns {String[]} compressed extensions
|
||||||
|
*
|
||||||
|
* SupportedFormatsModel.getCompressedExtensions().forEach(function(extension) {
|
||||||
|
* console.log('We support the ' + extension + ' compressed file format');
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
this.getCompressedExtensions = function() {
|
||||||
|
return _.map(_.filter(imageStream.supportedFileTypes, isCompressedFileType), 'extension');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Get non compressed extensions
|
||||||
|
* @function
|
||||||
|
* @public
|
||||||
|
*
|
||||||
|
* @returns {String[]} no compressed extensions
|
||||||
|
*
|
||||||
|
* SupportedFormatsModel.getNonCompressedExtensions().forEach(function(extension) {
|
||||||
|
* console.log('We support the ' + extension + ' file format');
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
this.getNonCompressedExtensions = function() {
|
||||||
|
return _.map(_.reject(imageStream.supportedFileTypes, isCompressedFileType), 'extension');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Get all supported extensions
|
||||||
|
* @function
|
||||||
|
* @public
|
||||||
|
*
|
||||||
|
* @returns {String[]} extensions
|
||||||
|
*
|
||||||
|
* SupportedFormatsModel.getAllExtensions().forEach(function(extension) {
|
||||||
|
* console.log('We support the ' + extension + ' format');
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
this.getAllExtensions = function() {
|
||||||
|
return _.map(imageStream.supportedFileTypes, 'extension');
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = MODULE_NAME;
|
@ -25,7 +25,10 @@
|
|||||||
|
|
||||||
const angular = require('angular');
|
const angular = require('angular');
|
||||||
const MODULE_NAME = 'Etcher.OS.Dialog';
|
const MODULE_NAME = 'Etcher.OS.Dialog';
|
||||||
const OSDialog = angular.module(MODULE_NAME, []);
|
const OSDialog = angular.module(MODULE_NAME, [
|
||||||
|
require('../../models/supported-formats')
|
||||||
|
]);
|
||||||
|
|
||||||
OSDialog.service('OSDialogService', require('./services/dialog'));
|
OSDialog.service('OSDialogService', require('./services/dialog'));
|
||||||
|
|
||||||
module.exports = MODULE_NAME;
|
module.exports = MODULE_NAME;
|
||||||
|
@ -19,9 +19,8 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
const imageStream = require('etcher-image-stream');
|
|
||||||
|
|
||||||
module.exports = function($q) {
|
module.exports = function($q, SupportedFormatsModel) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @summary Open an image selection dialog
|
* @summary Open an image selection dialog
|
||||||
@ -48,7 +47,7 @@ module.exports = function($q) {
|
|||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
name: 'OS Images',
|
name: 'OS Images',
|
||||||
extensions: imageStream.supportedFileTypes
|
extensions: SupportedFormatsModel.getAllExtensions()
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}, function(files) {
|
}, function(files) {
|
||||||
|
@ -8,7 +8,12 @@
|
|||||||
<div class="space-vertical-large">
|
<div class="space-vertical-large">
|
||||||
<div ng-hide="app.selection.hasImage()">
|
<div ng-hide="app.selection.hasImage()">
|
||||||
<button class="btn btn-primary btn-brick" ng-click="app.openImageSelector()">Select image</button>
|
<button class="btn btn-primary btn-brick" ng-click="app.openImageSelector()">Select image</button>
|
||||||
<p class="step-footer">.img, .iso, or <span class="step-footer-underline" uib-tooltip=".zip, .xz">compressed images</span></p>
|
|
||||||
|
<p class="step-footer">
|
||||||
|
{{ ::app.formats.getNonCompressedExtensions().join(', ') }}, or
|
||||||
|
<span class="step-footer-underline"
|
||||||
|
uib-tooltip="{{ app.formats.getCompressedExtensions().join(', ') }}">compressed images</span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="app.selection.hasImage()">
|
<div ng-show="app.selection.hasImage()">
|
||||||
<div ng-bind="app.selection.getImagePath() | basename"></div>
|
<div ng-bind="app.selection.getImagePath() | basename"></div>
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
"chalk": "^1.1.3",
|
"chalk": "^1.1.3",
|
||||||
"drivelist": "^3.0.0",
|
"drivelist": "^3.0.0",
|
||||||
"electron-is-running-in-asar": "^1.0.0",
|
"electron-is-running-in-asar": "^1.0.0",
|
||||||
"etcher-image-stream": "^1.2.0",
|
"etcher-image-stream": "^2.0.0",
|
||||||
"etcher-image-write": "^5.0.0",
|
"etcher-image-write": "^5.0.0",
|
||||||
"flexboxgrid": "^6.3.0",
|
"flexboxgrid": "^6.3.0",
|
||||||
"is-elevated": "^1.0.0",
|
"is-elevated": "^1.0.0",
|
||||||
|
BIN
screenshot.png
BIN
screenshot.png
Binary file not shown.
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 125 KiB |
54
tests/gui/models/supported-formats.spec.js
Normal file
54
tests/gui/models/supported-formats.spec.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const m = require('mochainon');
|
||||||
|
const _ = require('lodash');
|
||||||
|
const angular = require('angular');
|
||||||
|
require('angular-mocks');
|
||||||
|
|
||||||
|
describe('Browser: SupportedFormats', function() {
|
||||||
|
|
||||||
|
beforeEach(angular.mock.module(
|
||||||
|
require('../../../lib/gui/models/supported-formats')
|
||||||
|
));
|
||||||
|
|
||||||
|
describe('SupportedFormatsModel', function() {
|
||||||
|
|
||||||
|
let SupportedFormatsModel;
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject(function(_SupportedFormatsModel_) {
|
||||||
|
SupportedFormatsModel = _SupportedFormatsModel_;
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('.getCompressedExtensions()', function() {
|
||||||
|
|
||||||
|
it('should return the supported compressed extensions', function() {
|
||||||
|
const extensions = SupportedFormatsModel.getCompressedExtensions();
|
||||||
|
m.chai.expect(extensions).to.deep.equal([ 'zip', 'gz', 'bz2', 'xz' ]);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.getNonCompressedExtensions()', function() {
|
||||||
|
|
||||||
|
it('should return the supported non compressed extensions', function() {
|
||||||
|
const extensions = SupportedFormatsModel.getNonCompressedExtensions();
|
||||||
|
m.chai.expect(extensions).to.deep.equal([ 'img', 'iso' ]);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.getAllExtensions()', function() {
|
||||||
|
|
||||||
|
it('should return the union of .getCompressedExtensions and .getNonCompressedExtensions', function() {
|
||||||
|
const compressedExtensions = SupportedFormatsModel.getCompressedExtensions();
|
||||||
|
const nonCompressedExtensions = SupportedFormatsModel.getNonCompressedExtensions();
|
||||||
|
const expected = _.union(compressedExtensions, nonCompressedExtensions);
|
||||||
|
const extensions = SupportedFormatsModel.getAllExtensions();
|
||||||
|
m.chai.expect(extensions).to.deep.equal(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user