parent
a43a39b669
commit
741bceab02
|
@ -18,13 +18,14 @@
|
|||
*/
|
||||
|
||||
#include "podcastbackend.h"
|
||||
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/database.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/scopedtransaction.h"
|
||||
|
||||
#include <QMutexLocker>
|
||||
|
||||
PodcastBackend::PodcastBackend(Application* app, QObject* parent)
|
||||
: QObject(parent), app_(app), db_(app->database()) {}
|
||||
|
||||
|
|
|
@ -15,13 +15,6 @@
|
|||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/timeconstants.h"
|
||||
#include "core/utilities.h"
|
||||
#include "library/librarydirectorymodel.h"
|
||||
#include "library/librarymodel.h"
|
||||
#include "podcastbackend.h"
|
||||
#include "podcastdeleter.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
@ -31,6 +24,14 @@
|
|||
#include <QSettings>
|
||||
#include <QTimer>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/timeconstants.h"
|
||||
#include "core/utilities.h"
|
||||
#include "library/librarydirectorymodel.h"
|
||||
#include "library/librarymodel.h"
|
||||
#include "podcastbackend.h"
|
||||
|
||||
const char* PodcastDeleter::kSettingsGroup = "Podcasts";
|
||||
const int PodcastDeleter::kAutoDeleteCheckIntervalMsec =
|
||||
60 * 6 * 60 * kMsecPerSec;
|
||||
|
@ -76,7 +77,7 @@ void PodcastDeleter::AutoDelete() {
|
|||
}
|
||||
auto_delete_timer_->stop();
|
||||
QDateTime max_date = QDateTime::currentDateTime();
|
||||
qint64 time_out;
|
||||
qint64 timeout_ms;
|
||||
PodcastEpisode oldest_episode;
|
||||
QDateTime oldest_episode_time;
|
||||
max_date = max_date.addSecs(-delete_after_secs_);
|
||||
|
@ -99,11 +100,11 @@ void PodcastDeleter::AutoDelete() {
|
|||
oldest_episode_time = oldest_episode.listened_date();
|
||||
}
|
||||
|
||||
time_out = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
||||
time_out -= oldest_episode_time.toMSecsSinceEpoch();
|
||||
time_out = (delete_after_secs_ * kMsecPerSec) - time_out;
|
||||
if (time_out >= 0) {
|
||||
auto_delete_timer_->setInterval(time_out);
|
||||
timeout_ms = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
||||
timeout_ms -= oldest_episode_time.toMSecsSinceEpoch();
|
||||
timeout_ms = (delete_after_secs_ * kMsecPerSec) - timeout_ms;
|
||||
if (timeout_ms >= 0) {
|
||||
auto_delete_timer_->setInterval(timeout_ms);
|
||||
} else {
|
||||
auto_delete_timer_->setInterval(kAutoDeleteCheckIntervalMsec);
|
||||
}
|
||||
|
|
|
@ -47,11 +47,11 @@ Task::Task(PodcastEpisode episode, QFile* file, PodcastBackend* backend)
|
|||
connect(repl.get(), SIGNAL(readyRead()), SLOT(reading()));
|
||||
connect(repl.get(), SIGNAL(finished()), SLOT(finishedInternal()));
|
||||
connect(repl.get(), SIGNAL(downloadProgress(qint64, qint64)),
|
||||
SLOT(downloadProgress_(qint64, qint64)));
|
||||
SLOT(downloadProgressInternal(qint64, qint64)));
|
||||
emit ProgressChanged(episode_, PodcastDownload::Downloading, 0);
|
||||
}
|
||||
|
||||
const PodcastEpisode Task::episode() { return episode_; }
|
||||
PodcastEpisode Task::episode() const { return episode_; }
|
||||
|
||||
void Task::reading() {
|
||||
qint64 bytes = 0;
|
||||
|
@ -62,6 +62,15 @@ void Task::reading() {
|
|||
file_->write(repl->reply()->read(bytes));
|
||||
}
|
||||
}
|
||||
void Task::finishedPublic() {
|
||||
disconnect(repl.get(), SIGNAL(readyRead()), 0, 0);
|
||||
disconnect(repl.get(), SIGNAL(downloadProgress(qint64, qint64)), 0, 0);
|
||||
disconnect(repl.get(), SIGNAL(finished()), 0, 0);
|
||||
emit ProgressChanged(episode_, PodcastDownload::NotDownloading, 0);
|
||||
// Delete the file
|
||||
file_->remove();
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void Task::finishedInternal() {
|
||||
if (repl->error() != QNetworkReply::NoError) {
|
||||
|
@ -86,13 +95,13 @@ void Task::finishedInternal() {
|
|||
Song song = episode_.ToSong(podcast);
|
||||
|
||||
emit ProgressChanged(episode_, PodcastDownload::Finished, 0);
|
||||
emit finished();
|
||||
|
||||
// I didn't ecountered even a single podcast with a corect metadata
|
||||
TagReaderClient::Instance()->SaveFileBlocking(file_->fileName(), song);
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void Task::downloadProgress_(qint64 received, qint64 total) {
|
||||
void Task::downloadProgressInternal(qint64 received, qint64 total) {
|
||||
if (total <= 0) {
|
||||
emit ProgressChanged(episode_, PodcastDownload::Downloading, 0);
|
||||
} else {
|
||||
|
@ -208,6 +217,7 @@ void PodcastDownloader::DownloadEpisode(const PodcastEpisode& episode) {
|
|||
void PodcastDownloader::ReplyFinished() {
|
||||
Task* task = qobject_cast<Task*>(sender());
|
||||
list_tasks_.removeAll(task);
|
||||
delete task;
|
||||
}
|
||||
|
||||
QString PodcastDownloader::SanitiseFilenameComponent(const QString& text)
|
||||
|
@ -228,3 +238,30 @@ void PodcastDownloader::EpisodesAdded(const PodcastEpisodeList& episodes) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
PodcastEpisodeList PodcastDownloader::EpisodesDownloading(const PodcastEpisodeList& episodes) {
|
||||
PodcastEpisodeList ret;
|
||||
for (Task* tas : list_tasks_) {
|
||||
for (PodcastEpisode episode : episodes) {
|
||||
if (tas->episode().database_id() == episode.database_id()) {
|
||||
ret << episode;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PodcastDownloader::cancelDownload(const PodcastEpisodeList& episodes) {
|
||||
QList<Task*> ta;
|
||||
for (Task* tas : list_tasks_) {
|
||||
for (PodcastEpisode episode : episodes) {
|
||||
if (tas->episode().database_id() == episode.database_id()) {
|
||||
ta << tas;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Task* tas : ta) {
|
||||
tas->finishedPublic();
|
||||
list_tasks_.removeAll(tas);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,17 +52,20 @@ class Task : public QObject {
|
|||
|
||||
public:
|
||||
Task(PodcastEpisode episode, QFile* file, PodcastBackend* backend);
|
||||
const PodcastEpisode episode();
|
||||
PodcastEpisode episode() const;
|
||||
|
||||
signals:
|
||||
void ProgressChanged(const PodcastEpisode& episode,
|
||||
PodcastDownload::State state, int percent);
|
||||
void finished();
|
||||
|
||||
public slots:
|
||||
void finishedPublic();
|
||||
|
||||
private slots:
|
||||
void reading();
|
||||
void downloadProgressInternal(qint64 received, qint64 total);
|
||||
void finishedInternal();
|
||||
void downloadProgress_(qint64 received, qint64 total);
|
||||
|
||||
private:
|
||||
std::unique_ptr<QFile> file_;
|
||||
|
@ -80,12 +83,13 @@ class PodcastDownloader : public QObject {
|
|||
explicit PodcastDownloader(Application* app, QObject* parent = nullptr);
|
||||
|
||||
static const char* kSettingsGroup;
|
||||
|
||||
PodcastEpisodeList EpisodesDownloading(const PodcastEpisodeList& episodes);
|
||||
QString DefaultDownloadDir() const;
|
||||
|
||||
public slots:
|
||||
// Adds the episode to the download queue
|
||||
void DownloadEpisode(const PodcastEpisode& episode);
|
||||
void cancelDownload(const PodcastEpisodeList& episodes);
|
||||
|
||||
signals:
|
||||
void ProgressChanged(const PodcastEpisode& episode,
|
||||
|
|
|
@ -17,17 +17,18 @@
|
|||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "podcast.h"
|
||||
#include "podcastepisode.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/timeconstants.h"
|
||||
#include "core/utilities.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "podcast.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/timeconstants.h"
|
||||
#include "core/utilities.h"
|
||||
|
||||
const QStringList PodcastEpisode::kColumns = QStringList() << "podcast_id"
|
||||
<< "title"
|
||||
<< "description"
|
||||
|
|
|
@ -18,12 +18,17 @@
|
|||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "podcastservice.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#include "addpodcastdialog.h"
|
||||
#include "opmlcontainer.h"
|
||||
#include "podcastbackend.h"
|
||||
#include "podcastdeleter.h"
|
||||
#include "podcastdownloader.h"
|
||||
#include "podcastservice.h"
|
||||
#include "podcastservicemodel.h"
|
||||
#include "podcastupdater.h"
|
||||
#include "core/application.h"
|
||||
|
@ -39,10 +44,6 @@
|
|||
#include "ui/organiseerrordialog.h"
|
||||
#include "ui/standarditemiconloader.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
const char* PodcastService::kServiceName = "Podcasts";
|
||||
const char* PodcastService::kSettingsGroup = "Podcasts";
|
||||
|
||||
|
@ -181,6 +182,32 @@ void PodcastService::CopyToDevice(const QModelIndexList& episode_indexes,
|
|||
if (organise_dialog_->SetSongs(songs)) organise_dialog_->show();
|
||||
}
|
||||
|
||||
void PodcastService::CancelDownload() {
|
||||
CancelDownload(selected_episodes_, explicitly_selected_podcasts_);
|
||||
}
|
||||
|
||||
void PodcastService::CancelDownload(const QModelIndexList& episode_indexes,
|
||||
const QModelIndexList& podcast_indexes) {
|
||||
PodcastEpisode episode_tmp;
|
||||
SongList songs;
|
||||
PodcastEpisodeList episodes;
|
||||
Podcast podcast;
|
||||
for (const QModelIndex& index : episode_indexes) {
|
||||
episode_tmp = index.data(Role_Episode).value<PodcastEpisode>();
|
||||
episodes << episode_tmp;
|
||||
}
|
||||
|
||||
for (const QModelIndex& podcast : podcast_indexes) {
|
||||
for (int i = 0; i < podcast.model()->rowCount(podcast); ++i) {
|
||||
const QModelIndex& index = podcast.child(i, 0);
|
||||
episode_tmp = index.data(Role_Episode).value<PodcastEpisode>();
|
||||
episodes << episode_tmp;
|
||||
}
|
||||
}
|
||||
episodes = app_->podcast_downloader()->EpisodesDownloading(episodes);
|
||||
app_->podcast_downloader()->cancelDownload(episodes);
|
||||
}
|
||||
|
||||
void PodcastService::LazyPopulate(QStandardItem* parent) {
|
||||
switch (parent->data(InternetModel::Role_Type).toInt()) {
|
||||
case InternetModel::Type_Service:
|
||||
|
@ -391,6 +418,9 @@ void PodcastService::ShowContextMenu(const QPoint& global_pos) {
|
|||
copy_to_device_ = context_menu_->addAction(
|
||||
IconLoader::Load("multimedia-player-ipod-mini-blue"),
|
||||
tr("Copy to device..."), this, SLOT(CopyToDevice()));
|
||||
cancel_download_ = context_menu_->addAction(
|
||||
IconLoader::Load("cancel"),
|
||||
tr("Cancel download"), this, SLOT(CancelDownload()));
|
||||
remove_selected_action_ = context_menu_->addAction(
|
||||
IconLoader::Load("list-remove"), tr("Unsubscribe"), this,
|
||||
SLOT(RemoveSelectedPodcast()));
|
||||
|
@ -452,6 +482,7 @@ void PodcastService::ShowContextMenu(const QPoint& global_pos) {
|
|||
remove_selected_action_->setEnabled(podcasts);
|
||||
set_new_action_->setEnabled(episodes || podcasts);
|
||||
set_listened_action_->setEnabled(episodes || podcasts);
|
||||
cancel_download_->setEnabled(episodes || podcasts);
|
||||
|
||||
if (selected_episodes_.count() == 1) {
|
||||
const PodcastEpisode episode =
|
||||
|
|
|
@ -94,6 +94,9 @@ class PodcastService : public InternetService {
|
|||
void CopyToDevice(const PodcastEpisodeList& episodes_list);
|
||||
void CopyToDevice(const QModelIndexList& episode_indexes,
|
||||
const QModelIndexList& podcast_indexes);
|
||||
void CancelDownload();
|
||||
void CancelDownload(const QModelIndexList& episode_indexes,
|
||||
const QModelIndexList& podcast_indexes);
|
||||
|
||||
private:
|
||||
void EnsureAddPodcastDialogCreated();
|
||||
|
@ -145,6 +148,7 @@ class PodcastService : public InternetService {
|
|||
QAction* set_new_action_;
|
||||
QAction* set_listened_action_;
|
||||
QAction* copy_to_device_;
|
||||
QAction* cancel_download_;
|
||||
QStandardItem* root_;
|
||||
std::unique_ptr<OrganiseDialog> organise_dialog_;
|
||||
|
||||
|
|
Loading…
Reference in New Issue