Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / media_galleries / fileapi / iphoto_data_provider.cc
blob5b7603a1e08befed45cdd838c930d294e16807ed
1 // Copyright 2013 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.
5 #include "chrome/browser/media_galleries/fileapi/iphoto_data_provider.h"
7 #include <map>
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/stl_util.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
17 #include "chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.h"
19 namespace iphoto {
21 IPhotoDataProvider::IPhotoDataProvider(const base::FilePath& library_path)
22 : iapps::IAppsDataProvider(library_path),
23 weak_factory_(this) {}
25 IPhotoDataProvider::~IPhotoDataProvider() {}
27 void IPhotoDataProvider::DoParseLibrary(
28 const base::FilePath& library_path,
29 const ReadyCallback& ready_callback) {
30 xml_parser_ = new iapps::SafeIAppsLibraryParser;
31 xml_parser_->ParseIPhotoLibrary(
32 library_path,
33 base::Bind(&IPhotoDataProvider::OnLibraryParsed,
34 weak_factory_.GetWeakPtr(),
35 ready_callback));
38 void IPhotoDataProvider::OnLibraryParsed(const ReadyCallback& ready_callback,
39 bool result,
40 const parser::Library& library) {
41 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
42 set_valid(result);
43 if (valid())
44 BuildIndices(library);
45 ready_callback.Run(valid());
48 void IPhotoDataProvider::BuildIndices(const parser::Library& library) {
49 typedef base::hash_map<uint64, const base::FilePath*> IdIndex;
51 IdIndex photo_id_index;
52 IdIndex originals_id_index;
53 for (std::set<parser::Photo>::const_iterator photo_it =
54 library.all_photos.begin();
55 photo_it != library.all_photos.end(); photo_it++) {
56 photo_id_index[photo_it->id] = &(photo_it->location);
57 if (!photo_it->original_location.empty())
58 originals_id_index[photo_it->id] = &(photo_it->original_location);
61 // Build up a set of IDs which have in-album duplicates.
62 // Those are the filenames we want to globally mangle.
63 std::set<uint64> dupe_ids;
64 for (parser::Albums::const_iterator album_it = library.albums.begin();
65 album_it != library.albums.end(); album_it++) {
66 const parser::Album& album = album_it->second;
68 std::set<std::string> album_paths;
69 for (parser::Album::const_iterator id_it = album.begin();
70 id_it != album.end(); id_it++) {
71 uint64 id = *id_it;
72 IdIndex::const_iterator photo_it = photo_id_index.find(id);
73 if (photo_it == photo_id_index.end())
74 continue;
76 std::string filename = photo_it->second->BaseName().value();
77 if (ContainsKey(album_paths, filename))
78 dupe_ids.insert(id);
79 else
80 album_paths.insert(filename);
84 // Now build the directory index.
85 dir_index_.clear();
86 originals_index_.clear();
87 for (parser::Albums::const_iterator album_it = library.albums.begin();
88 album_it != library.albums.end(); album_it++) {
89 std::string album_name = album_it->first;
90 const parser::Album& album = album_it->second;
92 for (parser::Album::const_iterator id_it = album.begin();
93 id_it != album.end(); id_it++) {
94 uint64 id = *id_it;
95 IdIndex::const_iterator photo_it = photo_id_index.find(id);
96 if (photo_it == photo_id_index.end())
97 continue;
98 base::FilePath path = *(photo_it->second);
100 std::string filename = path.BaseName().value();
101 if (ContainsKey(dupe_ids, id)) {
102 filename = path.BaseName().InsertBeforeExtension(
103 "(" + base::Uint64ToString(id) + ")").value();
106 dir_index_[album_name][filename] = path;
108 IdIndex::const_iterator original_it = originals_id_index.find(id);
109 if (original_it != originals_id_index.end())
110 originals_index_[album_name][filename] = *(original_it->second);
115 std::vector<std::string> IPhotoDataProvider::GetAlbumNames() const {
116 std::vector<std::string> names;
118 for (DirIndex::const_iterator dir_it = dir_index_.begin();
119 dir_it != dir_index_.end(); dir_it++) {
120 names.push_back(dir_it->first);
123 return names;
126 std::map<std::string, base::FilePath> IPhotoDataProvider::GetAlbumContents(
127 const std::string& album) const {
128 std::map<std::string, base::FilePath> locations;
129 DirIndex::const_iterator dir_it = dir_index_.find(album);
130 if (dir_it == dir_index_.end())
131 return locations;
133 for (FileIndex::const_iterator file_it = dir_it->second.begin();
134 file_it != dir_it->second.end(); file_it++) {
135 locations.insert(make_pair(file_it->first, file_it->second));
138 return locations;
141 base::FilePath IPhotoDataProvider::GetPhotoLocationInAlbum(
142 const std::string& album,
143 const std::string& filename) const {
144 DirIndex::const_iterator dir_it = dir_index_.find(album);
145 if (dir_it == dir_index_.end())
146 return base::FilePath();
147 FileIndex::const_iterator file_it = dir_it->second.find(filename);
148 if (file_it == dir_it->second.end())
149 return base::FilePath();
150 return file_it->second;
153 bool IPhotoDataProvider::HasOriginals(const std::string& album) const {
154 DirIndex::const_iterator originals_it = originals_index_.find(album);
155 return originals_it != originals_index_.end();
158 std::map<std::string, base::FilePath> IPhotoDataProvider::GetOriginals(
159 const std::string& album) const {
160 std::map<std::string, base::FilePath> locations;
161 DirIndex::const_iterator originals_it = originals_index_.find(album);
162 if (originals_it == originals_index_.end())
163 return locations;
165 for (FileIndex::const_iterator file_it = originals_it->second.begin();
166 file_it != originals_it->second.end(); file_it++) {
167 locations.insert(make_pair(file_it->first, file_it->second));
170 return locations;
173 base::FilePath IPhotoDataProvider::GetOriginalPhotoLocation(
174 const std::string& album,
175 const std::string& filename) const {
176 DirIndex::const_iterator originals_it = originals_index_.find(album);
177 if (originals_it == originals_index_.end())
178 return base::FilePath();
179 FileIndex::const_iterator file_it = originals_it->second.find(filename);
180 if (file_it == originals_it->second.end())
181 return base::FilePath();
182 return file_it->second;
185 } // namespace iphoto