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

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

Powered by Google App Engine
This is Rietveld 408576698