Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / media_galleries / fileapi / iphoto_data_provider.cc
blobc4c54937c54fbe18c2ac2d9474ab51cff451bc09
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"
19 #include "content/public/browser/browser_thread.h"
21 namespace iphoto {
23 IPhotoDataProvider::IPhotoDataProvider(const base::FilePath& library_path)
24 : iapps::IAppsDataProvider(library_path),
25 weak_factory_(this) {}
27 IPhotoDataProvider::~IPhotoDataProvider() {}
29 void IPhotoDataProvider::DoParseLibrary(
30 const base::FilePath& library_path,
31 const ReadyCallback& ready_callback) {
32 xml_parser_ = new iapps::SafeIAppsLibraryParser;
33 xml_parser_->ParseIPhotoLibrary(
34 library_path,
35 base::Bind(&IPhotoDataProvider::OnLibraryParsed,
36 weak_factory_.GetWeakPtr(),
37 ready_callback));
40 void IPhotoDataProvider::OnLibraryParsed(const ReadyCallback& ready_callback,
41 bool result,
42 const parser::Library& library) {
43 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
44 set_valid(result);
45 if (valid())
46 BuildIndices(library);
47 ready_callback.Run(valid());
50 void IPhotoDataProvider::BuildIndices(const parser::Library& library) {
51 typedef base::hash_map<uint64, const base::FilePath*> IdIndex;
52 typedef base::hash_map<uint64, std::string> IdFileNameIndex;
54 IdIndex photo_id_index;
55 IdIndex originals_id_index;
56 for (std::set<parser::Photo>::const_iterator photo_it =
57 library.all_photos.begin();
58 photo_it != library.all_photos.end(); photo_it++) {
59 photo_id_index[photo_it->id] = &(photo_it->location);
60 if (!photo_it->original_location.empty())
61 originals_id_index[photo_it->id] = &(photo_it->original_location);
64 // Build up a set of IDs which have in-album duplicates.
65 // Those are the filenames we want to globally mangle.
66 std::set<uint64> dupe_ids;
67 for (parser::Albums::const_iterator album_it = library.albums.begin();
68 album_it != library.albums.end(); album_it++) {
69 const parser::Album& album = album_it->second;
71 std::set<std::string> album_paths;
72 for (parser::Album::const_iterator id_it = album.begin();
73 id_it != album.end(); id_it++) {
74 uint64 id = *id_it;
75 IdIndex::const_iterator photo_it = photo_id_index.find(id);
76 if (photo_it == photo_id_index.end())
77 continue;
79 std::string filename = photo_it->second->BaseName().value();
80 if (ContainsKey(album_paths, filename))
81 dupe_ids.insert(id);
82 else
83 album_paths.insert(filename);
87 // Now build the directory index.
88 dir_index_.clear();
89 originals_index_.clear();
90 for (parser::Albums::const_iterator album_it = library.albums.begin();
91 album_it != library.albums.end(); album_it++) {
92 std::string album_name = album_it->first;
93 const parser::Album& album = album_it->second;
95 for (parser::Album::const_iterator id_it = album.begin();
96 id_it != album.end(); id_it++) {
97 uint64 id = *id_it;
98 IdIndex::const_iterator photo_it = photo_id_index.find(id);
99 if (photo_it == photo_id_index.end())
100 continue;
101 base::FilePath path = *(photo_it->second);
103 std::string filename = path.BaseName().value();
104 if (ContainsKey(dupe_ids, id)) {
105 filename = path.BaseName().InsertBeforeExtension(
106 "(" + base::Uint64ToString(id) + ")").value();
109 dir_index_[album_name][filename] = path;
111 IdIndex::const_iterator original_it = originals_id_index.find(id);
112 if (original_it != originals_id_index.end())
113 originals_index_[album_name][filename] = *(original_it->second);
118 std::vector<std::string> IPhotoDataProvider::GetAlbumNames() const {
119 std::vector<std::string> names;
121 for (DirIndex::const_iterator dir_it = dir_index_.begin();
122 dir_it != dir_index_.end(); dir_it++) {
123 names.push_back(dir_it->first);
126 return names;
129 std::map<std::string, base::FilePath> IPhotoDataProvider::GetAlbumContents(
130 const std::string& album) const {
131 std::map<std::string, base::FilePath> locations;
132 DirIndex::const_iterator dir_it = dir_index_.find(album);
133 if (dir_it == dir_index_.end())
134 return locations;
136 for (FileIndex::const_iterator file_it = dir_it->second.begin();
137 file_it != dir_it->second.end(); file_it++) {
138 locations.insert(make_pair(file_it->first, file_it->second));
141 return locations;
144 base::FilePath IPhotoDataProvider::GetPhotoLocationInAlbum(
145 const std::string& album,
146 const std::string& filename) const {
147 DirIndex::const_iterator dir_it = dir_index_.find(album);
148 if (dir_it == dir_index_.end())
149 return base::FilePath();
150 FileIndex::const_iterator file_it = dir_it->second.find(filename);
151 if (file_it == dir_it->second.end())
152 return base::FilePath();
153 return file_it->second;
156 bool IPhotoDataProvider::HasOriginals(const std::string& album) const {
157 DirIndex::const_iterator originals_it = originals_index_.find(album);
158 return originals_it != originals_index_.end();
161 std::map<std::string, base::FilePath> IPhotoDataProvider::GetOriginals(
162 const std::string& album) const {
163 std::map<std::string, base::FilePath> locations;
164 DirIndex::const_iterator originals_it = originals_index_.find(album);
165 if (originals_it == originals_index_.end())
166 return locations;
168 for (FileIndex::const_iterator file_it = originals_it->second.begin();
169 file_it != originals_it->second.end(); file_it++) {
170 locations.insert(make_pair(file_it->first, file_it->second));
173 return locations;
176 base::FilePath IPhotoDataProvider::GetOriginalPhotoLocation(
177 const std::string& album,
178 const std::string& filename) const {
179 DirIndex::const_iterator originals_it = originals_index_.find(album);
180 if (originals_it == originals_index_.end())
181 return base::FilePath();
182 FileIndex::const_iterator file_it = originals_it->second.find(filename);
183 if (file_it == originals_it->second.end())
184 return base::FilePath();
185 return file_it->second;
188 } // namespace iphoto