Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Namespace | |
| 6 var importer = importer || {}; | |
| 7 | |
| 8 /** | |
| 9 * Handler for importing media from removable devices into the user's Drive. | |
| 10 * @param {!FileOperationManager} fileOperationManager | |
| 11 * @param {!MediaScanner=} opt_scanner | |
| 12 * @constructor | |
| 13 * @struct | |
| 14 */ | |
| 15 importer.MediaImportHandler = function(fileOperationManager, opt_scanner) { | |
| 16 /** | |
| 17 * Progress center to submit the progressing item. | |
|
Steve McKay
2014/12/05 01:09:39
Comment doesn't seem to match the val.
Ben Kwa
2014/12/05 17:22:50
Doh, I completely missed updating this jsdoc. Fix
| |
| 18 * @private {!FileOperationManager} | |
| 19 * @const | |
|
Steve McKay
2014/12/05 01:09:39
Use @const or don't for your "final" fields. Just
Ben Kwa
2014/12/05 17:22:50
Done.
| |
| 20 */ | |
| 21 this.fileOperationManager_ = fileOperationManager; | |
| 22 | |
| 23 /** @private {!MediaScanner} */ | |
| 24 this.scanner_ = opt_scanner || new MediaScanner(); | |
| 25 }; | |
| 26 | |
| 27 /** | |
| 28 * @typedef {function():(!DirectoryEntry|!Promise<!DirectoryEntry>)} | |
| 29 */ | |
| 30 importer.MediaImportHandler.DestinationFactory; | |
| 31 | |
| 32 /** | |
| 33 * Import all media found in a given subdirectory tree. | |
| 34 * @param {!DirectoryEntry} source The directory to import media from. | |
| 35 * @param {!importer.MediaImportHandler.DestinationFactory=} opt_destination A | |
|
Steve McKay
2014/12/05 01:09:39
Why not just make opt_destination required, then l
Ben Kwa
2014/12/05 17:22:50
I figured this was a good intermediate step that e
| |
| 36 * function that returns the directory into which media will be imported. | |
| 37 * The function will be executed only when the import task actually runs. | |
| 38 * @return {!importer.MediaImportHandler.ImportTask} The resulting import task. | |
| 39 */ | |
| 40 importer.MediaImportHandler.prototype.importMedia = | |
| 41 function(source, opt_destination) { | |
| 42 var destination = opt_destination || | |
| 43 importer.MediaImportHandler.defaultDestination.getImportDestination; | |
| 44 return new importer.MediaImportHandler.ImportTask( | |
| 45 this.fileOperationManager_, | |
| 46 this.scanner_, | |
| 47 source, | |
| 48 destination); | |
| 49 }; | |
| 50 | |
| 51 /** | |
| 52 * Note that this isn't an actual FileOperationManager.Task. It currently uses | |
| 53 * the FileOperationManager (and thus *spawns* an associated | |
| 54 * FileOperationManager.CopyTask) but this is a temporary state of affairs. | |
| 55 * | |
| 56 * TODO(kenobi): Add a proper implementation that doesn't use | |
| 57 * FileOperationManager, but instead actually performs the copy using the | |
| 58 * fileManagerPrivate API directly. | |
| 59 * | |
| 60 * @param {!FileOperationManager} fileOperationManager | |
| 61 * @param {!MediaScanner} mediaScanner | |
| 62 * @param {!DirectoryEntry} source Source dir containing media for import. | |
| 63 * @param {!importer.MediaImportHandler.DestinationFactory} destination A | |
| 64 * function that returns the directory into which media will be imported. | |
| 65 * @constructor | |
| 66 * @struct | |
| 67 */ | |
| 68 importer.MediaImportHandler.ImportTask = | |
| 69 function(fileOperationManager, mediaScanner, source, destination) { | |
| 70 this.source_ = source; | |
|
Steve McKay
2014/12/05 01:09:39
Missing jsdoc on the fields.
Ben Kwa
2014/12/05 17:22:50
Done.
| |
| 71 this.scanner_ = mediaScanner; | |
| 72 | |
| 73 // Call fileOperationManager.requestTaskCancel to cancel this task. | |
| 74 // TODO(kenobi): Add task cancellation. | |
| 75 this.taskId_ = fileOperationManager.generateTaskId(); | |
| 76 | |
| 77 Promise.all([ | |
| 78 destination(), | |
|
Steve McKay
2014/12/05 01:09:39
I think this is all okay for the early prototype.
Ben Kwa
2014/12/05 17:22:50
I agree with the (eventual) separation between the
| |
| 79 this.scanner_.scan([source]) | |
| 80 ]).then( | |
| 81 function(args) { | |
| 82 /** @type {!DirectoryEntry} */ | |
| 83 var destinationDir = args[0]; | |
| 84 /** @type {!Array<!FileEntry>} */ | |
| 85 var media = args[1]; | |
| 86 | |
| 87 fileOperationManager.paste( | |
| 88 media, | |
| 89 destinationDir, | |
| 90 /* isMove */ false, | |
| 91 /* opt_taskId */ this.taskId_); | |
| 92 }.bind(this)); | |
| 93 }; | |
| 94 | |
| 95 /** @struct */ | |
| 96 importer.MediaImportHandler.ImportTask.prototype = { | |
| 97 /** | |
| 98 * @return {string} The task ID. | |
| 99 */ | |
| 100 get taskId() { | |
| 101 return this.taskId_; | |
| 102 } | |
| 103 }; | |
| 104 | |
| 105 /** | |
| 106 * Namespace for a default import destination factory. The | |
| 107 * defaultDestionation.getImportDestination function creates and returns the | |
| 108 * directory /photos/YYYY-MM-DD in the user's Google Drive. YYYY-MM-DD is the | |
| 109 * current date. | |
| 110 */ | |
| 111 importer.MediaImportHandler.defaultDestination = {}; | |
| 112 | |
| 113 /** | |
| 114 * Retrieves the user's drive root. | |
| 115 * @return {!Promise<!DirectoryEntry>} | |
| 116 * @private | |
| 117 */ | |
| 118 importer.MediaImportHandler.defaultDestination.getDriveRoot_ = function() { | |
| 119 // TODO(kenobi): change this to 'other' to get the unparented drive root. | |
| 120 /** @const {string} */ | |
| 121 var rootName = 'root'; | |
|
Steve McKay
2014/12/05 01:09:39
Why not just inline it, or put it in a CONSTANT?
Ben Kwa
2014/12/05 17:22:50
This was here to make it clear what had to change
| |
| 122 | |
| 123 return VolumeManager.getInstance() | |
| 124 .then( | |
| 125 function(volumeManager) { | |
| 126 var drive = volumeManager.getCurrentProfileVolumeInfo( | |
| 127 VolumeManagerCommon.VolumeType.DRIVE); | |
| 128 // Use the root for unparented objects. | |
| 129 return new Promise(function(resolve, reject) { | |
|
hirono
2014/12/05 05:57:37
You can do "return drive.resolveDisplayRoot();"
Ben Kwa
2014/12/05 17:22:50
Thanks! Done.
| |
| 130 drive.fileSystem.root.getDirectory( | |
| 131 rootName, | |
| 132 {create: false}, | |
| 133 resolve, | |
| 134 reject); | |
| 135 }); | |
| 136 }); | |
| 137 }; | |
| 138 | |
| 139 /** | |
| 140 * Fetches (creating if necessary) the import destination subdirectory. | |
| 141 * @param {!DirectoryEntry} root The drive root. | |
| 142 * @return {!Promise<!DirectoryEntry>} | |
| 143 * @private | |
| 144 */ | |
| 145 importer.MediaImportHandler.defaultDestination.getOrCreateImportDestination_ = | |
| 146 function(root) { | |
| 147 /** | |
| 148 * @param {string} name The name of the new directory. | |
| 149 * @param {!DirectoryEntry} entry The parent directory. | |
| 150 * @return {!Promise<!DirectoryEntry>} The created directory. | |
| 151 */ | |
| 152 var mkdir_ = function(name, entry) { | |
| 153 /** @const {Object} */ | |
| 154 var CREATE_OPTIONS = { | |
| 155 create: true, | |
| 156 exclusive: false | |
| 157 }; | |
| 158 return new Promise(function(resolve, reject) { | |
| 159 entry.getDirectory(name, CREATE_OPTIONS, resolve, reject); | |
| 160 }); | |
| 161 }; | |
| 162 | |
| 163 /** | |
| 164 * @return {string} The current date, in YYYY-MM-DD format. | |
| 165 */ | |
| 166 var getDateString = function() { | |
| 167 var padAndConvert = function(i) { | |
| 168 return (i < 10 ? '0' : '') + i.toString(); | |
| 169 }; | |
| 170 var date = new Date(); | |
| 171 var year = date.getFullYear().toString(); | |
| 172 var month = padAndConvert(date.getMonth()); | |
| 173 var day = padAndConvert(date.getDate()); | |
| 174 | |
| 175 return year + '-' + month + '-' + day; | |
| 176 }; | |
| 177 | |
| 178 return Promise.resolve(root) | |
| 179 .then(mkdir_.bind(this, 'photos')) | |
| 180 .then(mkdir_.bind(this, getDateString())); | |
| 181 }; | |
| 182 | |
| 183 /** | |
| 184 * Returns the destination directory for media imports. Creates the | |
| 185 * destination, if it doesn't exist. | |
| 186 * @return {!Promise<!DirectoryEntry>} | |
| 187 */ | |
| 188 importer.MediaImportHandler.defaultDestination.getImportDestination = | |
| 189 function() { | |
| 190 var defaultDestination = importer.MediaImportHandler.defaultDestination; | |
| 191 return defaultDestination.getDriveRoot_() | |
| 192 .then(defaultDestination.getOrCreateImportDestination_); | |
| 193 }; | |
| OLD | NEW |