NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / media_galleries / fileapi / iphoto_data_provider.cc
blobf954b87aea1711da877b81816b1b3191f57ae545
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/platform_file.h"
14 #include "base/stl_util.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/threading/thread_restrictions.h"
17 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
18 #include "chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.h"
20 namespace iphoto {
22 IPhotoDataProvider::IPhotoDataProvider(const base::FilePath& library_path)
23 : iapps::IAppsDataProvider(library_path),
24 weak_factory_(this) {}
26 IPhotoDataProvider::~IPhotoDataProvider() {}
28 void IPhotoDataProvider::DoParseLibrary(
29 const base::FilePath& library_path,
30 const ReadyCallback& ready_callback) {
31 xml_parser_ = new iapps::SafeIAppsLibraryParser;
32 xml_parser_->ParseIPhotoLibrary(
33 library_path,
34 base::Bind(&IPhotoDataProvider::OnLibraryParsed,
35 weak_factory_.GetWeakPtr(),
36 ready_callback));
39 void IPhotoDataProvider::OnLibraryParsed(const ReadyCallback& ready_callback,
40 bool result,
41 const parser::Library& library) {
42 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
43 set_valid(result);
44 if (valid())
45 BuildIndices(library);
46 ready_callback.Run(valid());
49 void IPhotoDataProvider::BuildIndices(const parser::Library& library) {
50 typedef base::hash_map<uint64, const base::FilePath*> IdIndex;
51 typedef base::hash_map<uint64, std::string> IdFileNameIndex;
53 IdIndex photo_id_index;
54 IdIndex originals_id_index;
55 for (std::set<parser::Photo>::const_iterator photo_it =
56 library.all_photos.begin();
57 photo_it != library.all_photos.end(); photo_it++) {
58 photo_id_index[photo_it->id] = &(photo_it->location);
59 if (!photo_it->original_location.empty())
60 originals_id_index[photo_it->id] = &(photo_it->original_location);
63 // Build up a set of IDs which have in-album duplicates.
64 // Those are the filenames we want to globally mangle.
65 std::set<uint64> dupe_ids;
66 for (parser::Albums::const_iterator album_it = library.albums.begin();
67 album_it != library.albums.end(); album_it++) {
68 const parser::Album& album = album_it->second;
70 std::set<std::string> album_paths;
71 for (parser::Album::const_iterator id_it = album.begin();
72 id_it != album.end(); id_it++) {
73 uint64 id = *id_it;
74 IdIndex::const_iterator photo_it = photo_id_index.find(id);
75 if (photo_it == photo_id_index.end())
76 continue;
78 std::string filename = photo_it->second->BaseName().value();
79 if (ContainsKey(album_paths, filename))
80 dupe_ids.insert(id);
81 else
82 album_paths.insert(filename);
86 // Now build the directory index.
87 dir_index_.clear();
88 originals_index_.clear();
89 for (parser::Albums::const_iterator album_it = library.albums.begin();
90 album_it != library.albums.end(); album_it++) {
91 std::string album_name = album_it->first;
92 const parser::Album& album = album_it->second;
94 for (parser::Album::const_iterator id_it = album.begin();
95 id_it != album.end(); id_it++) {
96 uint64 id = *id_it;
97 IdIndex::const_iterator photo_it = photo_id_index.find(id);
98 if (photo_it == photo_id_index.end())
99 continue;
100 base::FilePath path = *(photo_it->second);
102 std::string filename = path.BaseName().value();
103 if (ContainsKey(dupe_ids, id)) {
104 filename = path.BaseName().InsertBeforeExtension(
105 "(" + base::Uint64ToString(id) + ")").value();
108 dir_index_[album_name][filename] = path;
110 IdIndex::const_iterator original_it = originals_id_index.find(id);
111 if (original_it != originals_id_index.end())
112 originals_index_[album_name][filename] = *(original_it->second);
117 std::vector<std::string> IPhotoDataProvider::GetAlbumNames() const {
118 std::vector<std::string> names;
120 for (DirIndex::const_iterator dir_it = dir_index_.begin();
121 dir_it != dir_index_.end(); dir_it++) {
122 names.push_back(dir_it->first);
125 return names;
128 std::map<std::string, base::FilePath> IPhotoDataProvider::GetAlbumContents(
129 const std::string& album) const {
130 std::map<std::string, base::FilePath> locations;
131 DirIndex::const_iterator dir_it = dir_index_.find(album);
132 if (dir_it == dir_index_.end())
133 return locations;
135 for (FileIndex::const_iterator file_it = dir_it->second.begin();
136 file_it != dir_it->second.end(); file_it++) {
137 locations.insert(make_pair(file_it->first, file_it->second));
140 return locations;
143 base::FilePath IPhotoDataProvider::GetPhotoLocationInAlbum(
144 const std::string& album,
145 const std::string& filename) const {
146 DirIndex::const_iterator dir_it = dir_index_.find(album);
147 if (dir_it == dir_index_.end())
148 return base::FilePath();
149 FileIndex::const_iterator file_it = dir_it->second.find(filename);
150 if (file_it == dir_it->second.end())
151 return base::FilePath();
152 return file_it->second;
155 bool IPhotoDataProvider::HasOriginals(const std::string& album) const {
156 DirIndex::const_iterator originals_it = originals_index_.find(album);
157 return originals_it != originals_index_.end();
160 std::map<std::string, base::FilePath> IPhotoDataProvider::GetOriginals(
161 const std::string& album) const {
162 std::map<std::string, base::FilePath> locations;
163 DirIndex::const_iterator originals_it = originals_index_.find(album);
164 if (originals_it == originals_index_.end())
165 return locations;
167 for (FileIndex::const_iterator file_it = originals_it->second.begin();
168 file_it != originals_it->second.end(); file_it++) {
169 locations.insert(make_pair(file_it->first, file_it->second));
172 return locations;
175 base::FilePath IPhotoDataProvider::GetOriginalPhotoLocation(
176 const std::string& album,
177 const std::string& filename) const {
178 DirIndex::const_iterator originals_it = originals_index_.find(album);
179 if (originals_it == originals_index_.end())
180 return base::FilePath();
181 FileIndex::const_iterator file_it = originals_it->second.find(filename);
182 if (file_it == originals_it->second.end())
183 return base::FilePath();
184 return file_it->second;
187 } // namespace iphoto