Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: ui/file_manager/file_manager/background/js/media_import_handler.js

Issue 762593006: Prototype implementation of MediaImportHandler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rename MediaImportHandler#import. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698