summaryrefslogtreecommitdiffstats
path: root/logic/tasks/StandardTask.cpp
blob: 3201d674b287ea3f2142072832e011b0d0de2040 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Licensed under the Apache-2.0 license. See README.md for details.

#include "StandardTask.h"

#include <QEventLoop>
#include <QProcess>

#include "net/CacheDownload.h"
#include "net/ByteArrayDownload.h"
#include "net/NetJob.h"
#include "FileSystem.h"
#include "Exception.h"
#include "Env.h"

StandardTask::StandardTask(QObject *parent)
	: Task(parent)
{
	m_loop = new QEventLoop(this);
}

void StandardTask::runTask(QObjectPtr<Task> other)
{
	connect(other.get(), &Task::succeeded, m_loop, &QEventLoop::quit);
	connect(other.get(), &Task::failed, m_loop, &QEventLoop::quit);
	connect(other.get(), &Task::progress, this, [this](qint64 current, qint64 total){setProgress(current / total);});
	connect(other.get(), &Task::status, this, &StandardTask::setStatus);
	if (!other->isRunning())
	{
		other->start();
	}
	if (other->isRunning())
	{
		m_loop->exec();
	}
	disconnect(other.get(), 0, m_loop, 0);
	disconnect(other.get(), 0, this, 0);
	other->deleteLater();
	if (!other->successful())
	{
		throw Exception(other->failReason());
	}
}
void StandardTask::runTaskNonBlocking(QObjectPtr<Task> other)
{
	if (!other)
	{
		return;
	}
	m_pendingTasks.append(other.get());
	m_pendingTaskPtrs.append(other);
	other->start();
}
QByteArray StandardTask::networkGet(const QUrl &url)
{
	ByteArrayDownloadPtr task = ByteArrayDownload::make(url);
	runTask(wrapDownload("", task));
	return task->m_data;
}
QByteArray StandardTask::networkGetCached(const QString &name, const QString &base, const QString &path, const QUrl &url, const bool alwaysRefetch,
										  INetworkValidator *validator)
{
	MetaEntryPtr entry = ENV.metacache()->resolveEntry(base, path);
	if (!alwaysRefetch && !entry->stale)
	{
		if (validator) { delete validator; }
		return FS::read(entry->getFullPath());
	}
	else if (alwaysRefetch)
	{
		entry->stale = true;
	}
	CacheDownloadPtr task = CacheDownload::make(url, entry);
	task->setValidator(validator);
	runTask(wrapDownload(name, task));
	return FS::read(entry->getFullPath());
}
QByteArray StandardTask::networkGetCached(const QString &name, const QString &base, const QString &path, const QUrl &url, const QMap<QString, QString> &headers,
										  INetworkValidator *validator)
{
	MetaEntryPtr entry = ENV.metacache()->resolveEntry(base, path);
	if (!entry->stale)
	{
		if (validator) { delete validator; }
		return FS::read(entry->getFullPath());
	}
	CacheDownloadPtr task = CacheDownload::make(url, entry);
	//task->setHeaders(headers);
	task->setValidator(validator);
	runTask(wrapDownload(name, task));
	return FS::read(entry->getFullPath());
}
void StandardTask::networkGetCachedNonBlocking(const QString &name, const QString &base, const QString &path, const QUrl &url, const bool alwaysRefetch,
											   INetworkValidator *validator)
{
	MetaEntryPtr entry = ENV.metacache()->resolveEntry(base, path);
	if (!alwaysRefetch && !entry->stale)
	{
		return;
	}
	CacheDownloadPtr dl = CacheDownload::make(url, entry);
	dl->setValidator(validator);
	runTaskNonBlocking(wrapDownload(name, dl));
}
void StandardTask::waitOnPending()
{
	for (int i = 0; i < m_pendingTasks.size(); ++i)
	{
		if (m_pendingTasks.at(i) && m_pendingTasks.at(i)->isRunning())
		{
			runTask(m_pendingTaskPtrs.at(i));
		}
	}
}

QObjectPtr<NetJob> StandardTask::wrapDownload(const QString &name, std::shared_ptr<NetAction> action)
{
	NetJobPtr task = NetJobPtr(new NetJob(name));
	task->addNetAction(action);
	return task;
}