Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media_galleries / fileapi / iphoto_data_provider.cc
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.
4
5 #include "chrome/browser/media_galleries/fileapi/iphoto_data_provider.h"
6
7 #include <map>
8
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
20 namespace iphoto {
21
22 IPhotoDataProvider::IPhotoDataProvider(const base::FilePath& library_path)
23     : iapps::IAppsDataProvider(library_path),
24       weak_factory_(this) {}
25
26 IPhotoDataProvider::~IPhotoDataProvider() {}
27
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));
37 }
38
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());
47 }
48
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;
52
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);
61   }
62
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;
69
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;
77
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);
83     }
84   }
85
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;
93
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);
101
102       std::string filename = path.BaseName().value();
103       if (ContainsKey(dupe_ids, id)) {
104         filename = path.BaseName().InsertBeforeExtension(
105           "(" + base::Uint64ToString(id) + ")").value();
106       }
107
108       dir_index_[album_name][filename] = path;
109
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);
113     }
114   }
115 }
116
117 std::vector<std::string> IPhotoDataProvider::GetAlbumNames() const {
118   std::vector<std::string> names;
119
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);
123   }
124
125   return names;
126 }
127
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;
134
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));
138   }
139
140   return locations;
141 }
142
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;
153 }
154
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();
158 }
159
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;
166
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));
170   }
171
172   return locations;
173 }
174
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;
185 }
186
187 }  // namespace iphoto