format: shorten date by simple truncation
[ncmpcpp.git] / src / song.cpp
blobe8ea294d52a68d311f0bca115a21f2120ceb7d8a
1 /***************************************************************************
2 * Copyright (C) 2008-2014 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
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. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include <cassert>
22 #include <cstring>
23 #include <boost/format.hpp>
24 #include <boost/functional/hash.hpp>
25 #include <boost/lexical_cast.hpp>
26 #include <iostream>
27 #include <memory>
29 #include "song.h"
30 #include "utility/type_conversions.h"
31 #include "utility/wide_string.h"
32 #include "window.h"
34 namespace {
36 size_t calc_hash(const char *s, size_t seed = 0)
38 for (; *s != '\0'; ++s)
39 boost::hash_combine(seed, *s);
40 return seed;
45 namespace MPD {
47 std::string Song::TagsSeparator = " | ";
49 std::string Song::get(mpd_tag_type type, unsigned idx) const
51 std::string result;
52 const char *tag = mpd_song_get_tag(m_song.get(), type, idx);
53 if (tag)
54 result = tag;
55 return result;
58 Song::Song(mpd_song *s)
60 assert(s);
61 m_song = std::shared_ptr<mpd_song>(s, mpd_song_free);
62 m_hash = calc_hash(mpd_song_get_uri(s));
65 std::string Song::getURI(unsigned idx) const
67 assert(m_song);
68 if (idx > 0)
69 return "";
70 else
71 return mpd_song_get_uri(m_song.get());
74 std::string Song::getName(unsigned idx) const
76 assert(m_song);
77 mpd_song *s = m_song.get();
78 const char *res = mpd_song_get_tag(s, MPD_TAG_NAME, idx);
79 if (res)
80 return res;
81 else if (idx > 0)
82 return "";
83 const char *uri = mpd_song_get_uri(s);
84 const char *name = strrchr(uri, '/');
85 if (name)
86 return name+1;
87 else
88 return uri;
91 std::string Song::getDirectory(unsigned idx) const
93 assert(m_song);
94 if (idx > 0 || isStream())
95 return "";
96 const char *uri = mpd_song_get_uri(m_song.get());
97 const char *name = strrchr(uri, '/');
98 if (name)
99 return std::string(uri, name-uri);
100 else
101 return "/";
104 std::string Song::getArtist(unsigned idx) const
106 assert(m_song);
107 return get(MPD_TAG_ARTIST, idx);
110 std::string Song::getTitle(unsigned idx) const
112 assert(m_song);
113 return get(MPD_TAG_TITLE, idx);
116 std::string Song::getAlbum(unsigned idx) const
118 assert(m_song);
119 return get(MPD_TAG_ALBUM, idx);
122 std::string Song::getAlbumArtist(unsigned idx) const
124 assert(m_song);
125 return get(MPD_TAG_ALBUM_ARTIST, idx);
128 std::string Song::getTrack(unsigned idx) const
130 assert(m_song);
131 std::string track = get(MPD_TAG_TRACK, idx);
132 if ((track.length() == 1 && track[0] != '0')
133 || (track.length() > 3 && track[1] == '/'))
134 track = "0"+track;
135 return track;
138 std::string Song::getTrackNumber(unsigned idx) const
140 assert(m_song);
141 std::string track = getTrack(idx);
142 size_t slash = track.find('/');
143 if (slash != std::string::npos)
144 track.resize(slash);
145 return track;
148 std::string Song::getDate(unsigned idx) const
150 assert(m_song);
151 return get(MPD_TAG_DATE, idx);
154 std::string Song::getGenre(unsigned idx) const
156 assert(m_song);
157 return get(MPD_TAG_GENRE, idx);
160 std::string Song::getComposer(unsigned idx) const
162 assert(m_song);
163 return get(MPD_TAG_COMPOSER, idx);
166 std::string Song::getPerformer(unsigned idx) const
168 assert(m_song);
169 return get(MPD_TAG_PERFORMER, idx);
172 std::string Song::getDisc(unsigned idx) const
174 assert(m_song);
175 return get(MPD_TAG_DISC, idx);
178 std::string Song::getComment(unsigned idx) const
180 assert(m_song);
181 return get(MPD_TAG_COMMENT, idx);
184 std::string Song::getLength(unsigned idx) const
186 assert(m_song);
187 if (idx > 0)
188 return "";
189 unsigned len = getDuration();
190 if (len > 0)
191 return ShowTime(len);
192 else
193 return "-:--";
196 std::string Song::getPriority(unsigned idx) const
198 assert(m_song);
199 if (idx > 0)
200 return "";
201 return boost::lexical_cast<std::string>(getPrio());
204 std::string MPD::Song::getTags(GetFunction f) const
206 assert(m_song);
207 unsigned idx = 0;
208 std::string result;
209 for (std::string tag; !(tag = (this->*f)(idx)).empty(); ++idx)
211 if (!result.empty())
212 result += TagsSeparator;
213 result += tag;
215 return result;
218 unsigned Song::getDuration() const
220 assert(m_song);
221 return mpd_song_get_duration(m_song.get());
224 unsigned Song::getPosition() const
226 assert(m_song);
227 return mpd_song_get_pos(m_song.get());
230 unsigned Song::getID() const
232 assert(m_song);
233 return mpd_song_get_id(m_song.get());
236 unsigned Song::getPrio() const
238 assert(m_song);
239 return mpd_song_get_prio(m_song.get());
242 time_t Song::getMTime() const
244 assert(m_song);
245 return mpd_song_get_last_modified(m_song.get());
248 bool Song::isFromDatabase() const
250 assert(m_song);
251 const char *uri = mpd_song_get_uri(m_song.get());
252 return uri[0] != '/' || !strrchr(uri, '/');
255 bool Song::isStream() const
257 assert(m_song);
258 return !strncmp(mpd_song_get_uri(m_song.get()), "http://", 7);
261 bool Song::empty() const
263 return m_song.get() == 0;
266 std::string Song::ShowTime(unsigned length)
268 int hours = length/3600;
269 length -= hours*3600;
270 int minutes = length/60;
271 length -= minutes*60;
272 int seconds = length;
274 std::string result;
275 if (hours > 0)
276 result = (boost::format("%d:%02d:%02d") % hours % minutes % seconds).str();
277 else
278 result = (boost::format("%d:%02d") % minutes % seconds).str();
279 return result;