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

Side by Side Diff: chrome/utility/media_galleries/iphoto_library_parser.cc

Issue 52093003: [MediaGalleries] iPhoto: Add original file field to the parser. Dedupe album names. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add album name dedupe Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/utility/media_galleries/iphoto_library_parser.h" 5 #include "chrome/utility/media_galleries/iphoto_library_parser.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "chrome/utility/media_galleries/iapps_xml_utils.h" 13 #include "chrome/utility/media_galleries/iapps_xml_utils.h"
14 #include "third_party/libxml/chromium/libxml_utils.h" 14 #include "third_party/libxml/chromium/libxml_utils.h"
15 15
16 namespace iphoto { 16 namespace iphoto {
17 17
18 namespace { 18 namespace {
19 19
20 struct PhotoInfo { 20 struct PhotoInfo {
vandebo (ex-Chrome) 2013/10/31 20:53:43 I think we should remove everything we don't use f
Greg Billock 2013/10/31 22:34:24 ok
21 uint64 id; 21 uint64 id;
22 std::string guid; 22 std::string guid;
23 base::FilePath location; 23 base::FilePath location;
24 base::FilePath original_location;
25 base::Time time;
24 std::string type; 26 std::string type;
25 }; 27 };
26 28
27 struct AlbumInfo { 29 struct AlbumInfo {
28 std::set<uint64> photo_ids; 30 std::set<uint64> photo_ids;
29 std::string name; 31 std::string name;
30 uint64 id; 32 uint64 id;
31 }; 33 };
32 34
33 // Walk through a dictionary filling in |result| with photo information. Return 35 // Walk through a dictionary filling in |result| with photo information. Return
34 // true if at least the id and location were found. 36 // true if at least the id and location were found.
35 // In either case, the cursor is advanced out of the dictionary. 37 // In either case, the cursor is advanced out of the dictionary.
36 bool GetPhotoInfoFromDict(XmlReader* reader, PhotoInfo* result) { 38 bool GetPhotoInfoFromDict(XmlReader* reader, PhotoInfo* result) {
37 DCHECK(result); 39 DCHECK(result);
38 if (reader->NodeName() != "dict") 40 if (reader->NodeName() != "dict")
39 return false; 41 return false;
40 42
41 int dict_content_depth = reader->Depth() + 1; 43 int dict_content_depth = reader->Depth() + 1;
42 // Advance past the dict node and into the body of the dictionary. 44 // Advance past the dict node and into the body of the dictionary.
43 if (!reader->Read()) 45 if (!reader->Read())
44 return false; 46 return false;
45 47
46 bool found_guid = false;
47 bool found_location = false; 48 bool found_location = false;
48 bool found_type = false; 49 while (reader->Depth() >= dict_content_depth) {
49 while (reader->Depth() >= dict_content_depth &&
50 !(found_guid && found_location && found_type)) {
51 if (!iapps::SeekToNodeAtCurrentDepth(reader, "key")) 50 if (!iapps::SeekToNodeAtCurrentDepth(reader, "key"))
52 break; 51 break;
53 std::string found_key; 52 std::string found_key;
54 if (!reader->ReadElementContent(&found_key)) 53 if (!reader->ReadElementContent(&found_key))
55 break; 54 break;
56 DCHECK_EQ(dict_content_depth, reader->Depth()); 55 DCHECK_EQ(dict_content_depth, reader->Depth());
57 56
58 if (found_key == "GUID") { 57 if (found_key == "GUID") {
59 if (found_guid)
60 break;
61 if (!iapps::ReadString(reader, &result->guid)) 58 if (!iapps::ReadString(reader, &result->guid))
62 break; 59 break;
63 found_guid = true;
64 } else if (found_key == "MediaType") { 60 } else if (found_key == "MediaType") {
65 if (found_type)
66 break;
67 if (!iapps::ReadString(reader, &result->type)) 61 if (!iapps::ReadString(reader, &result->type))
68 break; 62 break;
69 found_type = true;
70 } else if (found_key == "ImagePath") { 63 } else if (found_key == "ImagePath") {
71 if (found_location) 64 if (found_location)
72 break; 65 break;
73 std::string value; 66 std::string value;
74 if (!iapps::ReadString(reader, &value)) 67 if (!iapps::ReadString(reader, &value))
75 break; 68 break;
76 result->location = base::FilePath(value); 69 result->location = base::FilePath(value);
77 found_location = true; 70 found_location = true;
71 } else if (found_key == "OriginalPath") {
72 std::string value;
73 if (!iapps::ReadString(reader, &value))
74 break;
75 result->original_location = base::FilePath(value);
76 } else if (found_key == "DateAsTimerIntervalGMT") {
77 std::string value;
78 if (!iapps::ReadString(reader, &value))
79 break;
80 double time_double = 0.0;
81 if (!base::StringToDouble(value, &time_double))
82 break;
83 // Add offset from Mac time (2001-based) to 1970-based.
84 result->time = base::Time::FromDoubleT(time_double + 978307200.0);
78 } else { 85 } else {
79 if (!iapps::SkipToNextElement(reader)) 86 if (!iapps::SkipToNextElement(reader))
80 break; 87 break;
81 if (!reader->Next()) 88 if (!reader->Next())
82 break; 89 break;
83 } 90 }
84 } 91 }
85 92
86 // Seek to the end of the dictionary 93 // Seek to the end of the dictionary
87 while (reader->Depth() >= dict_content_depth) 94 while (reader->Depth() >= dict_content_depth)
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 break; 229 break;
223 } 230 }
224 231
225 PhotoInfo photo_info; 232 PhotoInfo photo_info;
226 photo_info.id = id; 233 photo_info.id = id;
227 if (!GetPhotoInfoFromDict(reader, &photo_info)) { 234 if (!GetPhotoInfoFromDict(reader, &photo_info)) {
228 errors = true; 235 errors = true;
229 break; 236 break;
230 } 237 }
231 238
232 parser::Photo photo(photo_info.id, photo_info.location); 239 parser::Photo photo(photo_info.id, photo_info.location,
240 photo_info.original_location, photo_info.time);
233 all_photos->insert(photo); 241 all_photos->insert(photo);
234 } 242 }
235 243
236 return !errors; 244 return !errors;
237 } 245 }
238 246
239 } // namespace 247 } // namespace
240 248
241 IPhotoLibraryParser::IPhotoLibraryParser() {} 249 IPhotoLibraryParser::IPhotoLibraryParser() {}
242 IPhotoLibraryParser::~IPhotoLibraryParser() {} 250 IPhotoLibraryParser::~IPhotoLibraryParser() {}
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 if (!iapps::SeekToNodeAtCurrentDepth(&reader, "array") || 287 if (!iapps::SeekToNodeAtCurrentDepth(&reader, "array") ||
280 !reader.Read()) { 288 !reader.Read()) {
281 continue; 289 continue;
282 } 290 }
283 291
284 while (iapps::SeekToNodeAtCurrentDepth(&reader, "dict")) { 292 while (iapps::SeekToNodeAtCurrentDepth(&reader, "dict")) {
285 AlbumInfo album_info; 293 AlbumInfo album_info;
286 if (GetAlbumInfoFromDict(&reader, &album_info)) { 294 if (GetAlbumInfoFromDict(&reader, &album_info)) {
287 parser::Album album; 295 parser::Album album;
288 album = album_info.photo_ids; 296 album = album_info.photo_ids;
289 // Strip / from album name. 297 // Strip / from album name and dedupe any collisions.
290 std::string name; 298 std::string name;
291 ReplaceChars(album_info.name, "//", " ", &name); 299 ReplaceChars(album_info.name, "//", " ", &name);
292 library_.albums[name] = album; 300 if (!ContainsKey(library_.albums, name)) {
301 library_.albums[name] = album;
vandebo (ex-Chrome) 2013/10/31 20:53:43 So first in the xml file wins? Maybe we should tr
Greg Billock 2013/10/31 22:34:24 Sounds good.
vandebo (ex-Chrome) 2013/11/01 18:50:33 Should we keep a separate list of dup album names
302 } else {
303 library_.albums[name+"("+base::Uint64ToString(album_info.id)+")"] =
vandebo (ex-Chrome) 2013/10/31 20:53:43 Date might be a more useful uniquifier, is there a
Greg Billock 2013/10/31 22:34:24 No, there's no real good signal. There's a GUID, a
304 album;
305 }
293 } 306 }
294 } 307 }
295 } else if (found_key == "Master Image List") { 308 } else if (found_key == "Master Image List") {
296 if (found_photos) 309 if (found_photos)
297 continue; 310 continue;
298 found_photos = true; 311 found_photos = true;
299 if (!ParseAllPhotos(&reader, &library_.all_photos)) 312 if (!ParseAllPhotos(&reader, &library_.all_photos))
300 return false; 313 return false;
301 } 314 }
302 } 315 }
303 316
304 return true; 317 return true;
305 } 318 }
306 319
307 } // namespace iphoto 320 } // namespace iphoto
OLDNEW
« no previous file with comments | « chrome/common/media_galleries/iphoto_library.cc ('k') | chrome/utility/media_galleries/iphoto_library_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698