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/utility/media_galleries/picasa_albums_indexer.h"
11 #include "base/ini_parser.h"
12 #include "base/logging.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/stringprintf.h"
20 const char kAlbumSectionHeader
[] = ".album:";
21 const char kAlbumsKey
[] = "albums";
22 const int kMaxDedupeNumber
= 1000; // Chosen arbitrarily.
24 class PicasaINIParser
: public base::INIParser
{
27 const base::FilePath
& folder_path
, AlbumImagesMap
* albums_images
)
28 : folder_path_(folder_path
),
29 albums_images_(albums_images
) {
31 virtual ~PicasaINIParser() {}
34 virtual void HandleTriplet(const std::string
& section
,
35 const std::string
& key
,
36 const std::string
& value
) OVERRIDE
{
37 if (key
!= kAlbumsKey
)
40 // [.album:*] sections ignored as we get that data from the PMP files.
41 if (section
.find(kAlbumSectionHeader
) == 0)
44 std::vector
<std::string
> containing_albums
;
45 base::SplitString(value
, ',', &containing_albums
);
46 for (std::vector
<std::string
>::iterator it
= containing_albums
.begin();
47 it
!= containing_albums
.end(); ++it
) {
48 AlbumImagesMap::iterator album_map_it
= albums_images_
->find(*it
);
50 // Ignore entry if the album uid is not listed among in |album_uids|
51 // in the constructor. Happens if the PMP and INI files are inconsistent.
52 if (album_map_it
== albums_images_
->end())
55 base::FilePath filename
= base::FilePath::FromUTF8Unsafe(section
);
56 AlbumImages
& album_images
= album_map_it
->second
;
58 // If filename is first of its name in album, simply add.
59 if (album_images
.insert(
60 std::make_pair(section
, folder_path_
.Append(filename
))).second
) {
64 // Otherwise, de-dupe by appending a number starting at (1).
65 for (int i
= 1; i
< kMaxDedupeNumber
; ++i
) {
66 std::string deduped_filename
=
67 filename
.InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", i
))
70 // Attempt to add the de-duped name.
71 if (album_images
.insert(
72 std::make_pair(deduped_filename
, folder_path_
.Append(filename
)))
80 const base::FilePath folder_path_
;
81 AlbumImagesMap
* const albums_images_
;
86 PicasaAlbumsIndexer::PicasaAlbumsIndexer(const AlbumUIDSet
& album_uids
) {
87 // Create an entry in the map for the valid album uids.
88 for (AlbumUIDSet::const_iterator it
= album_uids
.begin();
89 it
!= album_uids
.end(); ++it
) {
90 albums_images_
[*it
] = AlbumImages();
94 PicasaAlbumsIndexer::~PicasaAlbumsIndexer() {}
96 void PicasaAlbumsIndexer::ParseFolderINI(
97 const std::vector
<picasa::FolderINIContents
>& folders_inis
) {
98 // Make a copy for sorting
99 std::vector
<picasa::FolderINIContents
> folders_inis_sorted
= folders_inis
;
101 // Sort here so image names are deduplicated in a stable ordering.
102 std::sort(folders_inis_sorted
.begin(), folders_inis_sorted
.end());
104 for (std::vector
<picasa::FolderINIContents
>::const_iterator it
=
105 folders_inis_sorted
.begin();
106 it
!= folders_inis_sorted
.end();
108 PicasaINIParser
parser(it
->folder_path
, &albums_images_
);
109 parser
.Parse(it
->ini_contents
);
113 } // namespace picasa