2 * SomePlayer - An alternate music player for Maemo 5
3 * Copyright (C) 2010 Nikolay (somebody) Tischenko <niktischenko@gmail.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "filestorage.h"
22 #include <QDirIterator>
24 #include <QTextStream>
25 #include <QtXml/QtXml>
30 using namespace SomePlayer::Storage;
31 using namespace SomePlayer::DataObjects;
33 FileStorage::FileStorage(QString path) {
36 Playlist current = getCurrentPlaylist();
37 if (current.name() == PLAYLIST_BAD_NAME) {
38 current.setName(_CURRENT_PLAYLIST_NAME_);
39 saveCurrentPlaylist(current);
43 QList<Playlist> FileStorage::getPlaylists() {
48 Playlist FileStorage::getPlaylist(QString name) {
49 if (name == _CURRENT_PLAYLIST_SUBST_)
50 name = _CURRENT_PLAYLIST_NAME_;
51 QFile playlistFile (_path_prefix + "/" + name + "." + _PLAYLIST_FILE_EXTENSION_OLD_); // remove OLD_ in next version
53 playlist.setName(PLAYLIST_BAD_NAME);
55 if (playlistFile.exists()) {
56 qWarning() << "Old playlist file format deteced";
58 meta_regexp.setPattern("#META\\ +\\[(\\d+)\\]\\[(\\d+)\\].*::(.+)::,::(.+)::,::(.+)::");
60 path_regexp.setPattern("#PATH (.+)");
61 playlistFile.open(QFile::ReadOnly);
62 QTextStream stream(&playlistFile);
63 QString buffer = stream.readLine();
64 if (buffer.startsWith("#SOMEPLAYLIST")) {
65 while (!stream.atEnd()) {
66 buffer = stream.readLine();
67 if (meta_regexp.indexIn(buffer) != -1) {
68 int seconds = meta_regexp.cap(2).toInt();
69 QString artist = meta_regexp.cap(3);
70 QString album = meta_regexp.cap(4);
71 QString title = meta_regexp.cap(5);
72 buffer = stream.readLine();
73 if (path_regexp.indexIn(buffer) != -1) {
74 QString source = path_regexp.cap(1);
75 TrackMetadata meta(title, artist, album, seconds);
76 Track track(meta, source);
77 playlist.addTrack(track);
82 playlist.setName(name);
83 qWarning() << "Saving playlist in new format";
84 savePlaylist(playlist);
86 playlistFile.remove();
88 playlistFile.setFileName(_path_prefix + "/" + name + "." + _PLAYLIST_FILE_EXTENSION_);
90 if (playlistFile.exists()) {
91 playlist.setName(name);
93 playlistFile.open(QFile::ReadOnly);
94 doc.setContent(&playlistFile);
96 QDomElement eplaylist = doc.documentElement();
97 if (eplaylist.tagName() == "playlist") {
98 QDomElement etracklist = eplaylist.firstChildElement("trackList");
99 if (!etracklist.isNull()) {
100 QDomElement etrack = etracklist.firstChildElement("track");
101 while (!etrack.isNull()) {
102 QDomElement elocation = etrack.firstChildElement("location");
103 QDomElement eextension = etrack.firstChildElement("extension");
104 if (!eextension.isNull()) {
105 QDomElement ecl_clip = eextension.firstChildElement("cl:clip");
106 if (!ecl_clip.isNull()) {
107 QString artist = ecl_clip.attribute("artist");
108 QString album = ecl_clip.attribute("album");
109 QString title = ecl_clip.attribute("title");
110 QDomElement eduration = etrack.firstChildElement("duration");
111 if (!eduration.isNull()) {
112 QVariant duration = eduration.text();
114 basource.append(elocation.text());
115 QString source = QUrl::fromEncoded(basource).toLocalFile();
116 TrackMetadata meta(title, artist, album, duration.toInt()/1000);
117 Track track(meta, source);
118 playlist.addTrack(track);
122 etrack = etrack.nextSiblingElement("track");
133 QStringList FileStorage::getPlaylistsNames() {
134 QDir directory(_path_prefix);
135 QDirIterator iterator(directory, QDirIterator::FollowSymlinks);
136 QStringList playlistNames;
137 while (iterator.hasNext()) {
138 QString entry = iterator.next();
139 QFileInfo info(entry);
140 QString suffix = info.suffix().toLower();
141 if (suffix == _PLAYLIST_FILE_EXTENSION_) {
142 QString name = info.fileName().replace(QString(".%1").arg(_PLAYLIST_FILE_EXTENSION_), "", Qt::CaseInsensitive);
143 if (name == _CURRENT_PLAYLIST_NAME_)
144 name = _CURRENT_PLAYLIST_SUBST_;
145 playlistNames.append(name);
148 else if (suffix == _PLAYLIST_FILE_EXTENSION_OLD_){
149 QString name = info.fileName().replace(QString(".%1").arg(_PLAYLIST_FILE_EXTENSION_OLD_), "", Qt::CaseInsensitive);
150 if (name == _CURRENT_PLAYLIST_NAME_)
151 name = _CURRENT_PLAYLIST_SUBST_;
152 playlistNames.append(name);
156 return playlistNames;
159 void FileStorage::savePlaylist(Playlist playlist) {
160 QString name = playlist.name();
161 if (playlist.name() == _CURRENT_PLAYLIST_SUBST_)
162 name = _CURRENT_PLAYLIST_NAME_;
163 QString filename = _path_prefix + "/" + name + "."_PLAYLIST_FILE_EXTENSION_;
164 QFile playlistFile(filename);
165 if (playlistFile.exists()) {
166 playlistFile.remove();
168 playlistFile.open(QFile::WriteOnly);
169 QTextStream stream(&playlistFile);
171 QDomElement root = doc.createElement("playlist");
172 root.setAttribute("version", "1");
173 root.setAttribute("xmlns", "http://xspf.org/ns/0/");
174 root.setAttribute("xmlns:cl", "http://example.com");
175 QDomElement tracklist = doc.createElement("trackList");
176 foreach (Track track, playlist.tracks()) {
177 QDomElement etrack = doc.createElement("track");
178 QDomElement elocation = doc.createElement("location");
179 QDomElement eextension = doc.createElement("extension");
180 QDomElement ecl_clip = doc.createElement("cl:clip");
181 QDomElement etitle = doc.createElement("title");
182 QDomElement eduration = doc.createElement("duration");
183 etitle.appendChild(doc.createTextNode(QString("%1 - %2").arg(track.metadata().artist()).arg(track.metadata().title())));
184 ecl_clip.setAttribute("title", track.metadata().title());
185 ecl_clip.setAttribute("artist", track.metadata().artist());
186 ecl_clip.setAttribute("album", track.metadata().album());
187 eextension.appendChild(ecl_clip);
188 eextension.setAttribute("application", "http://example.com");
189 elocation.appendChild(doc.createTextNode(QString("%1").arg(QUrl::fromLocalFile(track.source()).toEncoded().constData())));
190 eduration.appendChild(doc.createTextNode(QString("%1").arg(track.metadata().length()*1000)));
191 etrack.appendChild(elocation);
192 etrack.appendChild(eextension);
193 etrack.appendChild(etitle);
194 etrack.appendChild(eduration);
195 tracklist.appendChild(etrack);
197 root.appendChild(tracklist);
198 doc.appendChild(root);
199 stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
200 stream << doc.toString();
203 void FileStorage::removePlaylist(Playlist playlist) {
204 QString filename = _path_prefix + "/" + playlist.name() + "." + _PLAYLIST_FILE_EXTENSION_;
205 QFile file(filename);
209 void FileStorage::removePlaylist(QString name) {
210 QString filename = _path_prefix + "/" + (name == _CURRENT_PLAYLIST_SUBST_ ? _CURRENT_PLAYLIST_NAME_ : name)
211 + "." + _PLAYLIST_FILE_EXTENSION_;
212 QFile file(filename);
216 Playlist FileStorage::getCurrentPlaylist() {
217 return getPlaylist(_CURRENT_PLAYLIST_NAME_);
220 void FileStorage::saveCurrentPlaylist(Playlist playlist) {
221 playlist.setName(_CURRENT_PLAYLIST_NAME_);
222 savePlaylist(playlist);
225 LastPlayed FileStorage::getLastPlayedForCurPlaylist() {
226 QFile playlistFile (_path_prefix + "/" + _CURRENT_PLAYLIST_NAME_ + "." + _PLAYLIST_FILE_EXTENSION_);
229 if (playlistFile.exists()) {
231 playlistFile.open(QFile::ReadOnly);
232 doc.setContent(&playlistFile);
233 playlistFile.close();
234 QDomElement eplaylist = doc.documentElement();
235 if (eplaylist.tagName() == "playlist") {
236 QDomElement eextension = eplaylist.firstChildElement("extension");
237 if (!eextension.isNull()) {
238 QDomElement elastplay = eextension.firstChildElement("lastplay");
239 if (!elastplay.isNull()) {
240 trackId = elastplay.attribute("track_id").toInt();
241 position = elastplay.attribute("position").toInt();
246 LastPlayed lp = {trackId, position};
250 void FileStorage::saveLastPlayedForCurPlaylist(LastPlayed lastplayed) {
251 QFile playlistFile (_path_prefix + "/" + _CURRENT_PLAYLIST_NAME_ + "." + _PLAYLIST_FILE_EXTENSION_);
253 if (playlistFile.exists()) {
254 playlistFile.open(QFile::ReadOnly);
255 doc.setContent(&playlistFile);
256 playlistFile.close();
257 QDomElement eplaylist = doc.documentElement();
258 if (eplaylist.tagName() == "playlist") {
259 QDomElement eextension = eplaylist.firstChildElement("extension");
260 if (eextension.isNull()) {
261 eextension = doc.createElement("extension");
262 eextension.setAttribute("application", "http://example.com");
263 QDomElement elastplay = doc.createElement("lastplay");
264 elastplay.setAttribute("track_id", lastplayed.trackId);
265 elastplay.setAttribute("position", lastplayed.position);
266 eextension.appendChild(elastplay);
267 eplaylist.appendChild(eextension);
269 QDomElement elastplay = eextension.firstChildElement("lastplay");
270 if (elastplay.isNull()) {
271 elastplay = doc.createElement("lastplay");
272 eextension.appendChild(elastplay);
274 elastplay.setAttribute("track_id", lastplayed.trackId);
275 elastplay.setAttribute("position", lastplayed.position);
279 playlistFile.open(QFile::WriteOnly);
280 QTextStream stream(&playlistFile);
281 stream << doc.toString();