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

Side by Side Diff: chrome/browser/media_galleries/fileapi/itunes_data_provider.cc

Issue 16158004: iTunes file util and data provider for media galleries (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Undo incorrect fix Created 7 years, 6 months 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
(Empty)
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/itunes_data_provider.h"
6
7 #include "base/callback.h"
8 #include "base/format_macros.h"
9 #include "base/logging.h"
10 #include "base/platform_file.h"
11 #include "base/stl_util.h"
12 #include "base/stringprintf.h"
13 #include "base/threading/thread_restrictions.h"
14 #include "chrome/browser/media_galleries/fileapi/itunes_library_parser.h"
15
16 namespace itunes {
17
18 namespace {
19
20 // A "reasonable" artificial limit.
21 // TODO(vandebo): Add a UMA to figure out what common values are.
22 const int64 kMaxLibraryFileSize = 150 * 1024 * 1024;
23
24 std::string ReadFile(const base::FilePath& path) {
25 base::ThreadRestrictions::AssertIOAllowed();
26
27 base::PlatformFile file = base::CreatePlatformFile(
28 path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, NULL, NULL);
29 if (file == base::kInvalidPlatformFileValue)
30 return std::string();
31
32 base::PlatformFileInfo file_info;
33 if (!base::GetPlatformFileInfo(file, &file_info) ||
34 file_info.size > kMaxLibraryFileSize) {
35 base::ClosePlatformFile(file);
36 return std::string();
37 }
38
39 std::string result(file_info.size, 0);
40 if (base::ReadPlatformFile(file, 0, string_as_array(&result),
41 file_info.size) != file_info.size) {
42 result.clear();
43 }
44
45 base::ClosePlatformFile(file);
46 return result;
47 }
48
49 ITunesDataProvider::Album MakeUniqueTrackNames(
50 const ITunesLibraryParser::Album& album) {
51 // TODO(vandebo): It would be nice to ensure that names returned from here
52 // are stable, but aside from persisting every name returned, it's not
53 // obvious how to do that (without including the track id in every name).
54 typedef std::set<const ITunesLibraryParser::Track*> TrackRefs;
55 typedef std::map<ITunesDataProvider::TrackName, TrackRefs> AlbumInfo;
56
57 ITunesDataProvider::Album result;
58 AlbumInfo duped_tracks;
59
60 ITunesLibraryParser::Album::const_iterator album_it;
61 for (album_it = album.begin(); album_it != album.end(); ++album_it) {
62 const ITunesLibraryParser::Track& track = *album_it;
63 std::string name = track.location.BaseName().AsUTF8Unsafe();
64 duped_tracks[name].insert(&track);
65 }
66
67 for (AlbumInfo::const_iterator name_it = duped_tracks.begin();
68 name_it != duped_tracks.end();
69 ++name_it) {
70 const TrackRefs& track_refs = name_it->second;
71 if (track_refs.size() == 1) {
72 result[name_it->first] = (*track_refs.begin())->location;
73 } else {
74 for (TrackRefs::const_iterator track_it = track_refs.begin();
75 track_it != track_refs.end();
76 ++track_it) {
77 std::string id =
78 base::StringPrintf(" (%" PRId64 ")", (*track_it)->id);
79 base::FilePath unique_name =
80 (*track_it)->location.BaseName().InsertBeforeExtensionASCII(id);
81 result[unique_name.AsUTF8Unsafe()] = (*track_it)->location;
82 }
83 }
84 }
85
86 return result;
87 }
88
89 } // namespace
90
91 ITunesDataProvider::ITunesDataProvider(const base::FilePath& library_path)
92 : library_path_(library_path),
93 needs_refresh_(true) {
94 }
95
96 ITunesDataProvider::~ITunesDataProvider() {}
97
98 // TODO(vandebo): add a file watch that resets |needs_refresh_| when the
99 // file changes.
100 void ITunesDataProvider::RefreshData(const base::Closure& ready_callback) {
101 if (needs_refresh_) {
102 ParseLibrary();
103 needs_refresh_ = false;
104 }
105 ready_callback.Run();
106 }
107
108 const base::FilePath& ITunesDataProvider::library_path() const {
109 return library_path_;
110 }
111
112 bool ITunesDataProvider::KnownArtist(const ArtistName& artist) const {
113 DCHECK(!needs_refresh_);
114 return ContainsKey(library_, artist);
115 }
116
117 bool ITunesDataProvider::KnownAlbum(const ArtistName& artist,
118 const AlbumName& album) const {
119 DCHECK(!needs_refresh_);
120 Library::const_iterator library_it = library_.find(artist);
121 if (library_it == library_.end())
122 return false;
123 return ContainsKey(library_it->second, album);
124
125 }
126
127 base::FilePath ITunesDataProvider::GetTrackLocation(
128 const ArtistName& artist, const AlbumName& album,
129 const TrackName& track) const {
130 DCHECK(!needs_refresh_);
131 Library::const_iterator library_it = library_.find(artist);
132 if (library_it == library_.end())
133 return base::FilePath();
134
135 Artist::const_iterator artist_it = library_it->second.find(album);
136 if (artist_it == library_it->second.end())
137 return base::FilePath();
138
139 Album::const_iterator album_it = artist_it->second.find(track);
140 if (album_it == artist_it->second.end())
141 return base::FilePath();
142 return album_it->second;
143 }
144
145 std::set<ITunesDataProvider::ArtistName>
146 ITunesDataProvider::GetArtistNames() const {
147 DCHECK(!needs_refresh_);
148 std::set<ArtistName> result;
149 Library::const_iterator it;
150 for (it = library_.begin(); it != library_.end(); ++it) {
151 result.insert(it->first);
152 }
153 return result;
154 }
155
156 std::set<ITunesDataProvider::AlbumName> ITunesDataProvider::GetAlbumNames(
157 const ArtistName& artist) const {
158 DCHECK(!needs_refresh_);
159 std::set<AlbumName> result;
160 Library::const_iterator artist_lookup = library_.find(artist);
161 if (artist_lookup == library_.end())
162 return result;
163
164 const Artist& artist_entry = artist_lookup->second;
165 Artist::const_iterator it;
166 for (it = artist_entry.begin(); it != artist_entry.end(); ++it) {
167 result.insert(it->first);
168 }
169 return result;
170 }
171
172 ITunesDataProvider::Album ITunesDataProvider::GetAlbum(
173 const ArtistName& artist, const AlbumName& album) const {
174 DCHECK(!needs_refresh_);
175 Album empty_result;
176 Library::const_iterator artist_lookup = library_.find(artist);
177 if (artist_lookup == library_.end())
178 return empty_result;
179
180 Artist::const_iterator album_lookup = artist_lookup->second.find(album);
181 if (album_lookup == artist_lookup->second.end())
182 return empty_result;
183
184 return album_lookup->second;
185 }
186
187 void ITunesDataProvider::ParseLibrary() {
188 std::string xml = ReadFile(library_path_);
189
190 library_.clear();
191 ITunesLibraryParser parser;
192 if (!parser.Parse(xml))
193 return;
194
195 ITunesLibraryParser::Library::const_iterator artist_it;
196 ITunesLibraryParser::Albums::const_iterator album_it;
197 for (artist_it = parser.library().begin();
198 artist_it != parser.library().end();
199 ++artist_it) {
200 for (album_it = artist_it->second.begin();
201 album_it != artist_it->second.end();
202 ++album_it) {
203 library_[artist_it->first][album_it->first] =
204 MakeUniqueTrackNames(album_it->second);
205 }
206 }
207 }
208
209 } // namespace itunes
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698