Clementine-audio-player-Mac.../3rdparty/vreen/vreen/src/api/audio.cpp

429 lines
11 KiB
C++

/****************************************************************************
**
** Vreen - vk.com API Qt bindings
**
** Copyright © 2012 Aleksey Sidorov <gorthauer87@ya.ru>
**
*****************************************************************************
**
** $VREEN_BEGIN_LICENSE$
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
** See the GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see http://www.gnu.org/licenses/.
** $VREEN_END_LICENSE$
**
****************************************************************************/
#include "audio.h"
#include "client.h"
#include "reply_p.h"
#include "utils_p.h"
#include <QUrl>
#include <QCoreApplication>
#include <QDebug>
#include <QtCore/qalgorithms.h>
namespace Vreen {
class AudioProvider;
class AudioProviderPrivate
{
Q_DECLARE_PUBLIC(AudioProvider)
public:
AudioProviderPrivate(AudioProvider *q, Client *client) : q_ptr(q), client(client) {}
AudioProvider *q_ptr;
Client *client;
static QVariant handleAudio(const QVariant &response) {
AudioItemList items;
auto list = response.toList();
if (list.count() && list.first().canConvert<int>())
list.removeFirst(); //HACK For stupid API(((
foreach (auto item, list) {
auto map = item.toMap();
AudioItem audio;
audio.setId(map.value("aid").toInt());
audio.setOwnerId(map.value("owner_id").toInt());
audio.setArtist(fromHtmlEntities(map.value("artist").toString()));
audio.setTitle(fromHtmlEntities(map.value("title").toString()));
audio.setDuration(map.value("duration").toReal());
audio.setAlbumId(map.value("album").toInt());
audio.setLyricsId(map.value("lyrics_id").toInt());
audio.setUrl(map.value("url").toUrl());
items.append(audio);
}
return QVariant::fromValue(items);
}
static QVariant handleAudioAlbum(const QVariant &response) {
AudioAlbumItemList items;
auto list = response.toList();
if (list.count() && list.first().canConvert<int>())
list.removeFirst();
foreach (auto item, list) {
auto map = item.toMap();
AudioAlbumItem audio;
audio.setId(map.value("album_id").toInt());
audio.setOwnerId(map.value("owner_id").toInt());
audio.setTitle(fromHtmlEntities(map.value("title").toString()));
items.append(audio);
}
return QVariant::fromValue(items);
}
};
AudioProvider::AudioProvider(Client *client) :
d_ptr(new AudioProviderPrivate(this, client))
{
}
AudioProvider::~AudioProvider()
{
}
/*!
* \brief AudioProvider::get \link http://vk.com/developers.php?oid=-1&p=audio.get
* \param uid
* \param count
* \param offset
* \return reply
*/
AudioItemListReply *AudioProvider::getContactAudio(int uid, int count, int offset, int album_id)
{
Q_D(AudioProvider);
QVariantMap args;
if (uid)
args.insert(uid > 0 ? "uid" : "gid", qAbs(uid));
if (album_id > 0)
args.insert("album_id", album_id);
args.insert("count", count);
args.insert("offset", offset);
auto reply = d->client->request<AudioItemListReply>("audio.get", args, AudioProviderPrivate::handleAudio);
return reply;
}
/*!
* \brief AudioProvider::searchAudio \link http://vk.com/developers.php?oid=-1&p=audio.search
*
* \param query
* \param autocomplete
* \param lyrics
* \param count
* \param offset
* \return reply
**/
AudioItemListReply *AudioProvider::searchAudio(const QString& query, int count, int offset, bool autoComplete, Vreen::AudioProvider::SortOrder sort, bool withLyrics)
{
Q_D(AudioProvider);
QVariantMap args;
args.insert("q", query);
args.insert("auto_complete", autoComplete);
args.insert("sort", static_cast<int>(sort));
args.insert("lyrics", withLyrics);
args.insert("count", count);
args.insert("offset", offset);
auto reply = d->client->request<AudioItemListReply>("audio.search", args, AudioProviderPrivate::handleAudio);
return reply;
}
AudioAlbumItemListReply *AudioProvider::getAlbums(int ownerId, int count, int offset)
{
Q_D(AudioProvider);
QVariantMap args;
args.insert("owner_id", ownerId);
args.insert("count", count);
args.insert("offset", offset);
auto reply = d->client->request<AudioAlbumItemListReply>("audio.getAlbums", args, AudioProviderPrivate::handleAudioAlbum);
return reply;
}
AudioItemListReply *AudioProvider::getRecommendationsForUser(int uid, int count, int offset)
{
Q_D(AudioProvider);
QVariantMap args;
if (uid < 0) {
qDebug("Vreen::AudioProvider::getRecomendationForUser may not work with groups (uid < 0)");
}
args.insert("uid",uid);
args.insert("count", count);
args.insert("offset", offset);
auto reply = d->client->request<AudioItemListReply>("audio.getRecommendations", args, AudioProviderPrivate::handleAudio);
return reply;
}
IntReply *AudioProvider::getCount(int oid)
{
Q_D(AudioProvider);
oid = oid?oid:d->client->id();
QVariantMap args;
args.insert("oid", oid);
auto reply = d->client->request<IntReply>("audio.getCount", args, ReplyPrivate::handleInt);
return reply;
}
IntReply *AudioProvider::addToLibrary(int aid, int oid, int gid)
{
Q_D(AudioProvider);
QVariantMap args;
args.insert("aid", aid);
args.insert("oid", oid);
if (gid) {
args.insert("gid",gid);
}
auto reply = d->client->request<IntReply>("audio.add", args, ReplyPrivate::handleInt);
return reply;
}
IntReply *AudioProvider::removeFromLibrary(int aid, int oid)
{
Q_D(AudioProvider);
QVariantMap args;
args.insert("aid", aid);
args.insert("oid", oid);
auto reply = d->client->request<IntReply>("audio.delete", args, ReplyPrivate::handleInt);
return reply;
}
IdListReply *AudioProvider::setBroadcast(int aid, int oid, const IdList &targetIds)
{
Q_D(AudioProvider);
QVariantMap args;
args.insert("audio", QString("%1_%2").arg(oid).arg(aid));
args.insert("target_ids", join(targetIds));
auto reply = d->client->request<IdListReply>("audio.setBroadcast", args, ReplyPrivate::handleIdList);
return reply;
}
IdListReply *AudioProvider::resetBroadcast(const IdList &targetIds)
{
Q_D(AudioProvider);
QVariantMap args;
args.insert("audio","");
args.insert("target_ids", join(targetIds));
auto reply = d->client->request<IdListReply>("audio.setBroadcast", args, ReplyPrivate::handleIdList);
return reply;
}
AudioItemListReply *AudioProvider::getAudiosByIds(const QString &ids)
{
Q_D(AudioProvider);
QVariantMap args;
args.insert("audios", ids);
auto reply = d->client->request<AudioItemListReply>("audio.getById", args, AudioProviderPrivate::handleAudio);
return reply;
}
class AudioModel;
class AudioModelPrivate
{
Q_DECLARE_PUBLIC(AudioModel)
public:
AudioModelPrivate(AudioModel *q) : q_ptr(q) {}
AudioModel *q_ptr;
AudioItemList itemList;
IdComparator<AudioItem> audioItemComparator;
};
AudioModel::AudioModel(QObject *parent) : AbstractListModel(parent),
d_ptr(new AudioModelPrivate(this))
{
auto roles = roleNames();
roles[IdRole] = "aid";
roles[TitleRole] = "title";
roles[ArtistRole] = "artist";
roles[UrlRole] = "url";
roles[DurationRole] = "duration";
roles[AlbumIdRole] = "albumId";
roles[LyricsIdRole] = "lyricsId";
roles[OwnerIdRole] = "ownerId";
setRoleNames(roles);
}
AudioModel::~AudioModel()
{
}
int AudioModel::count() const
{
return d_func()->itemList.count();
}
void AudioModel::insertAudio(int index, const AudioItem &item)
{
beginInsertRows(QModelIndex(), index, index);
d_func()->itemList.insert(index, item);
endInsertRows();
}
void AudioModel::replaceAudio(int i, const AudioItem &item)
{
auto index = createIndex(i, 0);
d_func()->itemList[i] = item;
emit dataChanged(index, index);
}
void AudioModel::setAudio(const AudioItemList &items)
{
Q_D(AudioModel);
clear();
beginInsertRows(QModelIndex(), 0, items.count());
d->itemList = items;
qSort(d->itemList.begin(), d->itemList.end(), d->audioItemComparator);
endInsertRows();
}
void AudioModel::sort(int, Qt::SortOrder order)
{
Q_D(AudioModel);
d->audioItemComparator.sortOrder = order;
setAudio(d->itemList);
}
void AudioModel::removeAudio(int aid)
{
Q_D(AudioModel);
int index = findAudio(aid);
if (index == -1)
return;
beginRemoveRows(QModelIndex(), index, index);
d->itemList.removeAt(index);
endRemoveRows();
}
void AudioModel::addAudio(const AudioItem &item)
{
Q_D(AudioModel);
if (findAudio(item.id()) != -1)
return;
int index = d->itemList.count();
beginInsertRows(QModelIndex(), index, index);
d->itemList.append(item);
endInsertRows();
//int index = 0;
//if (d->sortOrder == Qt::AscendingOrder)
// index = d->itemList.count();
//insertAudio(index, item);
}
void AudioModel::clear()
{
Q_D(AudioModel);
beginRemoveRows(QModelIndex(), 0, d->itemList.count());
d->itemList.clear();
endRemoveRows();
}
void AudioModel::truncate(int count)
{
Q_D(AudioModel);
if (count > 0 && count > d->itemList.count()) {
qWarning("Unable to truncate");
return;
}
beginRemoveRows(QModelIndex(), 0, count);
d->itemList.erase(d->itemList.begin() + count, d->itemList.end());
endRemoveRows();
}
int AudioModel::rowCount(const QModelIndex &) const
{
return count();
}
void AudioModel::setSortOrder(Qt::SortOrder order)
{
Q_D(AudioModel);
if (order != d->audioItemComparator.sortOrder) {
d->audioItemComparator.sortOrder = order;
emit sortOrderChanged(order);
sort(0, order);
}
}
Qt::SortOrder AudioModel::sortOrder() const
{
Q_D(const AudioModel);
return d->audioItemComparator.sortOrder;
}
QVariant AudioModel::data(const QModelIndex &index, int role) const
{
Q_D(const AudioModel);
int row = index.row();
auto item = d->itemList.at(row);
switch (role) {
case IdRole:
return item.id();
break;
case TitleRole:
return item.title();
case ArtistRole:
return item.artist();
case UrlRole:
return item.url();
case DurationRole:
return item.duration();
case AlbumIdRole:
return item.albumId();
case LyricsIdRole:
return item.lyricsId();
case OwnerIdRole:
return item.ownerId();
default:
break;
}
return QVariant::Invalid;
}
int AudioModel::findAudio(int id) const
{
Q_D(const AudioModel);
//auto it = qBinaryFind(d->itemList.begin(), d->itemList.end(), id, d->audioItemComparator);
//auto index = it - d->itemList.begin();
//return index;
for (int i = 0; i != d->itemList.count(); i++)
if (d->itemList.at(i).id() == id)
return id;
return -1;
}
} // namespace Vreen
#include "moc_audio.cpp"