Simplify code.

- Don't split listen live into categories
- Only list 1 stream per listen live entry
- Do same Genre reduction to IceCast as Clementine
This commit is contained in:
craig.p.drummond
2014-05-08 18:46:35 +00:00
committed by craig.p.drummond
parent 1603d36f12
commit 81accc3a6c

View File

@@ -98,7 +98,6 @@ static const QString constDiChannelListUrl=QLatin1String("http://")+constDiChann
static const QString constDiStdUrl=QLatin1String("http://%1/public3/%2.pls");
static QString constShoutCastUrl=QLatin1String("http://")+StreamsModel::constShoutCastHost+QLatin1String("/genre/primary?f=xml&k=")+StreamsModel::constShoutCastApiKey;
static QString constDirbleUrl=QLatin1String("http://")+StreamsModel::constDirbleHost+QLatin1String("/v1/primaryCategories/apikey/")+StreamsModel::constDirbleApiKey;
static const QLatin1String constBookmarksDir=QLatin1String("bookmarks");
@@ -581,7 +580,6 @@ StreamsModel::StreamsModel(QObject *parent)
connect(MPDConnection::self(), SIGNAL(playlistsRetrieved(QList<Playlist>)), SLOT(storedPlaylists(QList<Playlist>)));
connect(MPDConnection::self(), SIGNAL(savedStream(QString,QString)), SLOT(savedFavouriteStream(QString,QString)));
connect(MPDConnection::self(), SIGNAL(removedStreams(QList<quint32>)), SLOT(removedFavouriteStreams(QList<quint32>)));
// connect(MPDConnection::self(), SIGNAL(editedStream(QString,QString,quint32)), SLOT(editedFavouriteStream(QString,QString,quint32)));
connect(MPDConnection::self(), SIGNAL(streamList(QList<Stream>)), SLOT(favouriteStreams(QList<Stream>)));
connect(this, SIGNAL(listFavouriteStreams()), MPDConnection::self(), SLOT(listStreams()));
connect(this, SIGNAL(saveFavouriteStream(QString,QString)), MPDConnection::self(), SLOT(saveStream(QString,QString)));
@@ -950,34 +948,11 @@ static QString addDiHash(const StreamsModel::Item *item)
? DigitallyImported::self()->modifyUrl(item->url) : item->url;
}
//static void filenames(QStringList &fn, bool addPrefix, const StreamsModel::CategoryItem *cat)
//{
// foreach (const StreamsModel::Item *i, cat->children) {
// if (i->isCategory()) {
// ::filenames(fn, addPrefix, static_cast<const StreamsModel::CategoryItem *>(i));
// } else if (StreamsModel::validProtocol(i->url)) {
// QString url=StreamsModel::modifyUrl(addDiHash(i), addPrefix, addPrefix ? i->modifiedName() : i->name);
// if (!fn.contains(i->url)) {
// fn << url;
// }
// }
// }
//}
QStringList StreamsModel::filenames(const QModelIndexList &indexes, bool addPrefix) const
{
QStringList fnames;
foreach(QModelIndex index, indexes) {
Item *item=static_cast<Item *>(index.internalPointer());
// if (item->isCategory()) {
// ::filenames(fnames, addPrefix, static_cast<const StreamsModel::CategoryItem *>(item));
// } else if (validProtocol(item->url)) {
// QString url=modifyUrl(addDiHash(item), addPrefix, addPrefix ? item->modifiedName() : item->name);
// if (!fnames.contains(url)) {
// fnames << url;
// }
// }
if (!item->isCategory()) {
fnames << modifyUrl(addDiHash(item), addPrefix, addPrefix ? item->modifiedName() : item->name);
}
@@ -1261,17 +1236,6 @@ void StreamsModel::removedFavouriteStreams(const QList<quint32> &removed)
emit dataChanged(parent, parent);
}
//void StreamsModel::editedFavouriteStream(const QString &url, const QString &name, quint32 position)
//{
// if (position<favourites->children.count()) {
// Item *stream=favourites->children.at(posiiton);
// stream->url=url;
// stream->name=name;
// QModelIndex index=createIndex(position, 0, (void *)item);
// emit dataChanged(index, index);
// }
//}
static StreamsModel::Item * getStream(StreamsModel::FavouritesCategoryItem *fav, const Stream &stream, int offset)
{
int i=0;
@@ -1363,107 +1327,25 @@ QList<StreamsModel::Item *> StreamsModel::parseRadioTimeResponse(QIODevice *dev,
return newItems;
}
static QString fixSingleGenre(const QString &g)
{
if (!g.isEmpty()) {
QString genre=Song::capitalize(g);
genre[0]=genre[0].toUpper();
genre=genre.trimmed();
genre=genre.replace(QLatin1String("Afrocaribbean"), QLatin1String("Afro-Caribbean"));
genre=genre.replace(QLatin1String("Afro Caribbean"), QLatin1String("Afro-Caribbean"));
if (genre.length() < 3 ||
QLatin1String("The")==genre || QLatin1String("All")==genre ||
QLatin1String("Various")==genre || QLatin1String("Unknown")==genre ||
QLatin1String("Misc")==genre || QLatin1String("Mix")==genre || QLatin1String("100%")==genre ||
genre.contains("ÃÂ") || // Broken unicode.
genre.contains(QRegExp("^#x[0-9a-f][0-9a-f]"))) { // Broken XML entities.
return QString();
}
if (genre==QLatin1String("R&B") || genre==QLatin1String("R B") || genre==QLatin1String("Rnb") || genre==QLatin1String("RnB")) {
return QLatin1String("R&B");
}
if (genre==QLatin1String("Classic") || genre==QLatin1String("Classical") || genre==QLatin1String("Classical Music")) {
return QLatin1String("Classical");
}
if (genre==QLatin1String("College") || genre.startsWith("College ", Qt::CaseInsensitive)) {
return QLatin1String("College");
}
if (genre==QLatin1String("Christian") || genre.startsWith(QLatin1String("Christian "), Qt::CaseInsensitive)) {
return QLatin1String("Christian");
}
if (genre==QLatin1String("Rock") || genre.startsWith(QLatin1String("Rock "))) {
return QLatin1String("Rock");
}
if (genre==QLatin1String("Easy") || genre==QLatin1String("Easy Listening")) {
return QLatin1String("Easy Listening");
}
if (genre==QLatin1String("Hit") || genre==QLatin1String("Hits")) {
return QLatin1String("Hits");
}
if (genre==QLatin1String("Hip") || genre==QLatin1String("Hiphop") || genre==QLatin1String("Hip Hop") || genre==QLatin1String("Hop Hip")) {
return QLatin1String("Hip Hop");
}
if (genre==QLatin1String("News") || genre==QLatin1String("News talk")) {
return QLatin1String("News");
}
if (genre==QLatin1String("Top40") || genre==QLatin1String("Top 40") || genre==QLatin1String("40Top") || genre==QLatin1String("40 Top")) {
return QLatin1String("Top 40");
}
QStringList small=QStringList() << QLatin1String("Adult Contemporary") << QLatin1String("Alternative")
<< QLatin1String("Community Radio") << QLatin1String("Local Service")
<< QLatin1String("Multiultural") << QLatin1String("News")
<< QLatin1String("Student") << QLatin1String("Urban");
foreach (const QString &s, small) {
if (genre==s || genre.startsWith(s+" ", Qt::CaseInsensitive) || genre.endsWith(" "+s, Qt::CaseInsensitive)) {
return s;
}
}
// Convert XX's to XXs
if (genre.contains(QRegExp("^[0-9]0's$"))) {
genre=genre.remove('\'');
}
if (genre.length()>25 && (0==genre.indexOf(QRegExp("^[0-9]0s ")) || 0==genre.indexOf(QRegExp("^[0-9]0 ")))) {
int pos=genre.indexOf(' ');
if (pos>1) {
genre=genre.left(pos);
}
}
// Convert 80 -> 80s.
return genre.contains(QRegExp("^[0-9]0$")) ? genre + 's' : genre;
}
return g;
}
static QStringList fixGenres(const QString &genre)
{
QString g(genre);
int pos=g.indexOf("<br");
if (pos>3) {
g=g.left(pos);
}
pos=g.indexOf("(");
if (pos>3) {
g=g.left(pos);
}
g=Song::capitalize(g);
QStringList genres=g.split('|', QString::SkipEmptyParts);
QStringList allGenres;
foreach (const QString &genre, genres) {
allGenres+=genre.split('/', QString::SkipEmptyParts);
}
QStringList allGenres=Song::capitalize(genre).split(' ', QString::SkipEmptyParts);
QStringList fixed;
foreach (const QString &genre, allGenres) {
QString g=fixSingleGenre(genre).trimmed();
if (!g.isEmpty()) {
fixed.append(g);
if (genre.length() < 2 ||
genre.contains("ÃÂ") || // Broken unicode.
genre.contains(QRegExp("^#x[0-9a-f][0-9a-f]"))) { // Broken XML entities.
continue;
}
// Convert 80 -> 80s.
if (genre.contains(QRegExp("^[0-9]0$"))) {
fixed << genre + 's';
} else {
fixed << genre;
}
}
if (fixed.isEmpty()) {
fixed << i18n("Other");
}
return fixed;
}
@@ -1515,9 +1397,6 @@ QList<StreamsModel::Item *> StreamsModel::parseIceCastResponse(QIODevice *dev, C
if (!name.isEmpty() && !url.isEmpty() && !names.contains(name)) {
names.insert(name);
if (stationGenres.isEmpty()) {
stationGenres.append(i18n("Other"));
}
foreach (const QString &g, stationGenres) {
genres[g].append(new Item(url, name, cat));
}
@@ -1605,7 +1484,7 @@ struct ListenLiveStream {
ListenLiveStream() : format(Unknown), bitrate(0) { }
bool operator<(const ListenLiveStream &o) const { return weight()>o.weight(); }
int weight() const { return ((bitrate&0xff)<<8)+(format&0x0f); }
int weight() const { return ((bitrate&0xff)<<4)+(format&0x0f); }
void setFormat(const QString &f) {
if (QLatin1String("mp3")==f.toLower()) {
@@ -1621,17 +1500,6 @@ struct ListenLiveStream {
}
}
const QString bitrateStr() const { return QString("%1kb/s").arg(bitrate); }
const QString formatStr() const {
switch (format) {
case MP3: return QLatin1String("MP3 ")+bitrateStr();
case AAC: return QLatin1String("AAC ")+bitrateStr();
case OGG: return QLatin1String("OGG ")+bitrateStr();
case WMA: return QLatin1String("WMA ")+bitrateStr();
default: return bitrateStr();
}
}
QString url;
Format format;
unsigned int bitrate;
@@ -1639,10 +1507,9 @@ struct ListenLiveStream {
struct ListenLiveStationEntry {
ListenLiveStationEntry() { clear(); }
void clear() { name=location=comment=QString(); streams.clear(); }
void clear() { name=location=QString(); streams.clear(); }
QString name;
QString location;
QString comment;
QList<ListenLiveStream> streams;
};
@@ -1661,8 +1528,6 @@ static QString getString(QString &str, const QString &start, const QString &end)
QList<StreamsModel::Item *> StreamsModel::parseListenLiveResponse(QIODevice *dev, CategoryItem *cat)
{
QList<Item *> newItems;
QSet<QString> names;
QMap<QString, QList<Item *> > genres;
if (dev) {
ListenLiveStationEntry entry;
@@ -1715,76 +1580,29 @@ QList<StreamsModel::Item *> StreamsModel::parseListenLiveResponse(QIODevice *dev
} else if (line.startsWith("<td>")) {
if (entry.location.isEmpty()) {
entry.location=getString(line, "<td>", "</td>");
} else {
entry.comment=getString(line, "<td>", "</td>");
}
} else if ("</tr>"==line) {
if (entry.streams.count()) {
qSort(entry.streams);
bool multiple=entry.streams.count()>1;
foreach (const ListenLiveStream &stream, entry.streams) {
if (!stream.url.contains("://")) {
continue;
}
QString name;
QString name;
QString url=entry.streams.at(0).url;
if (QLatin1String("National")==entry.location || entry.name.endsWith(QLatin1Char('(')+entry.location+QLatin1Char(')'))) {
name=entry.name;
} else if (entry.name.endsWith(QLatin1Char(')'))) {
name=entry.name.left(entry.name.length()-1)+QLatin1String(", ")+entry.location+QLatin1Char(')');
} else {
name=entry.name+QLatin1String(" (")+entry.location+QLatin1Char(')');
}
if (QLatin1String("National")==entry.location || entry.name.endsWith(QLatin1Char('(')+entry.location+QLatin1Char(')'))) {
name=entry.name;
} else if (entry.name.endsWith(QLatin1Char(')'))) {
name=entry.name.left(entry.name.length()-1)+QLatin1String(", ")+entry.location+QLatin1Char(')');
} else {
name=entry.name+QLatin1String(" (")+entry.location+QLatin1Char(')');
}
if (!name.isEmpty() && multiple) {
if (name.endsWith(QLatin1Char(')'))) {
name=name.left(name.length()-1)+QLatin1String(", ");
} else {
name+=QLatin1String(" (");
}
name+=stream.formatStr()+QLatin1Char(')');
}
if (!names.contains(name) && !name.isEmpty()) {
QStringList stationGenres=fixGenres(entry.comment);
if (stationGenres.isEmpty()) {
stationGenres.append(i18n("Other"));
}
foreach (const QString &g, stationGenres) {
genres[g].append(new Item(stream.url, name, cat));
}
names.insert(name);
}
if (!name.isEmpty()) {
newItems.append(new Item(url, name, cat));
}
}
}
}
}
QMap<QString, QList<Item *> >::ConstIterator it(genres.constBegin());
QMap<QString, QList<Item *> >::ConstIterator end(genres.constEnd());
CategoryItem *all=0;
if (!genres.isEmpty()) {
all=new CategoryItem(QString(), i18n("All"), cat);
all->state=CategoryItem::Fetched;
all->isAll=true;
newItems.append(all);
}
QSet<QString> allUrls;
for (; it!=end; ++it) {
CategoryItem *genre=new CategoryItem(QString(), it.key(), cat);
genre->state=CategoryItem::Fetched;
foreach (Item *i, it.value()) {
i->parent=genre;
genre->children.append(i);
if (!allUrls.contains(i->url)) {
allUrls.insert(i->url);
all->children.append(new Item(i->url, i->name, all));
}
}
newItems.append(genre);
}
return newItems;
}
@@ -1972,7 +1790,6 @@ void StreamsModel::importOldFavourites()
}
if (!prevFile.isEmpty() && QFile::exists(prevFile)) {
importIntoFavourites(prevFile);
// QFile::remove(prevFile);
}
favourites->importedOld=true;
}
@@ -2096,12 +1913,6 @@ QModelIndex StreamsModel::categoryIndex(const CategoryItem *cat) const
const QString StreamsModel::constPrefix=QLatin1String("cantata-stream-");
const QString StreamsModel::constPlayListName=QLatin1String("[Radio Streams]");
//bool StreamsModel::validProtocol(const QString &file)
//{
// QString scheme=QUrl(file).scheme();
// return scheme.isEmpty() || MPDConnection::self()->urlHandlers().contains(scheme);
//}
QString StreamsModel::modifyUrl(const QString &u, bool addPrefix, const QString &name)
{
return MPDParseUtils::addStreamName(!addPrefix || !u.startsWith("http:") ? u : (constPrefix+u), name);