mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-28 09:17:18 +00:00

`src/drives.js` made little on its own, and only caused extra thinking overhead due to indirection.
175 lines
4.0 KiB
JavaScript
175 lines
4.0 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';
|
|
|
|
/**
|
|
* @module Etcher.drive-scanner
|
|
*/
|
|
|
|
const angular = require('angular');
|
|
const _ = require('lodash');
|
|
const EventEmitter = require('events').EventEmitter;
|
|
const electron = require('electron');
|
|
const drivelist = require('drivelist');
|
|
|
|
if (window.mocha) {
|
|
var path = require('path');
|
|
var srcPath = path.join(__dirname, '..', '..', 'src');
|
|
var dialog = electron.remote.require(path.join(srcPath, 'dialog'));
|
|
} else {
|
|
var dialog = electron.remote.require('./src/dialog');
|
|
}
|
|
|
|
const driveScanner = angular.module('Etcher.drive-scanner', []);
|
|
|
|
driveScanner.service('DriveScannerService', function($q, $interval, $timeout) {
|
|
let self = this;
|
|
let interval = null;
|
|
|
|
/**
|
|
* @summary List of available drives
|
|
* @type {Object[]}
|
|
* @public
|
|
*/
|
|
this.drives = [];
|
|
|
|
/**
|
|
* @summary Check if there are available drives
|
|
* @function
|
|
* @public
|
|
*
|
|
* @returns {Boolean} whether there are available drives
|
|
*
|
|
* @example
|
|
* if (DriveScannerService.hasAvailableDrives()) {
|
|
* console.log('There are available drives!');
|
|
* }
|
|
*/
|
|
this.hasAvailableDrives = function() {
|
|
return !_.isEmpty(self.drives);
|
|
};
|
|
|
|
/**
|
|
* @summary Set the list of drives
|
|
* @function
|
|
* @public
|
|
*
|
|
* @param {Object[]} drives - drives
|
|
*
|
|
* @example
|
|
* DriveScannerService.scan().then(function(drives) {
|
|
* DriveScannerService.setDrives(drives);
|
|
* });
|
|
*/
|
|
this.setDrives = function(drives) {
|
|
|
|
// Only update if something has changed
|
|
// to avoid unnecessary DOM manipulations
|
|
// angular.equals ignores $$hashKey by default
|
|
if (!angular.equals(self.drives, drives)) {
|
|
self.drives = drives;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @summary Get available drives
|
|
* @function
|
|
* @public
|
|
*
|
|
* @fulfil {Object[]} - drives
|
|
* @returns {Promise}
|
|
*
|
|
* @example
|
|
* DriveScannerService.scan().then(function(drives) {
|
|
* console.log(drives);
|
|
* });
|
|
*/
|
|
this.scan = function() {
|
|
var deferred = $q.defer();
|
|
|
|
drivelist.list(function(error, drives) {
|
|
if (error) {
|
|
return deferred.reject(error);
|
|
}
|
|
|
|
return deferred.resolve(_.filter(drives, function(drive) {
|
|
return !drive.system;
|
|
}));
|
|
});
|
|
|
|
return deferred.promise;
|
|
};
|
|
|
|
/**
|
|
* @summary Scan drives and populate `.drives`
|
|
* @function
|
|
* @public
|
|
*
|
|
* @description
|
|
* This function returns an event emitter instance
|
|
* that emits a `scan` event everything it scans
|
|
* the drives successfully.
|
|
*
|
|
* @param {Number} ms - interval milliseconds
|
|
* @returns {EventEmitter} event emitter instance
|
|
*
|
|
* @example
|
|
* const emitter = DriveScannerService.start(2000);
|
|
*
|
|
* emitter.on('scan', function(drives) {
|
|
* console.log(drives);
|
|
* });
|
|
*/
|
|
this.start = function(ms) {
|
|
let emitter = new EventEmitter();
|
|
|
|
const fn = function() {
|
|
return self.scan().then(function(drives) {
|
|
emitter.emit('scan', drives);
|
|
self.setDrives(drives);
|
|
}).catch(dialog.showError);
|
|
};
|
|
|
|
// Make sure any pending interval is cancelled
|
|
// to avoid potential memory leaks.
|
|
self.stop();
|
|
|
|
// Call fn after in the next process tick
|
|
// to be able to capture the first run
|
|
// in unit tests.
|
|
$timeout(function() {
|
|
fn();
|
|
interval = $interval(fn, ms);
|
|
});
|
|
|
|
return emitter;
|
|
};
|
|
|
|
/**
|
|
* @summary Stop scanning drives
|
|
* @function
|
|
* @public
|
|
*
|
|
* @example
|
|
* DriveScannerService.stop();
|
|
*/
|
|
this.stop = function() {
|
|
$interval.cancel(interval);
|
|
};
|
|
|
|
});
|