Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F114729
kazv-io-manager.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
kazv-io-manager.cpp
View Options
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022-2023 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include
<kazv-defs.hpp>
#include
"kazv-io-manager.hpp"
#include
"kazv-io-job.hpp"
#include
"matrix-room.hpp"
#include
"upload-job-model.hpp"
#include
"qt-rand-adapter.hpp"
#include
<api/csapi/content-repo.hpp>
#include
<file-desc.hpp>
#include
<QObject>
#include
<QIODevice>
#include
<QFile>
#include
<QSaveFile>
#include
<QPointer>
#include
<QSharedPointer>
#include
<QUrl>
#include
<QMap>
#include
<QMultiMap>
#include
<QTemporaryDir>
#include
<string>
#include
<algorithm>
using
namespace
Qt
::
Literals
::
StringLiterals
;
static
const
QString
ROOMLESS
=
QStringLiteral
(
"not-a-room"
);
struct
KazvIOManagerPrivate
{
/**
* Used to store various temporary files.
* If the user does not specify a cache directory,
* this directory is also used as a cache directory.
*/
QTemporaryDir
tmpDir
=
QTemporaryDir
{};
/**
* Stores files that need to be previewed (e.g. in a timeline)
* and are not downloaded by the user, such as images, audio, video covers, and videos.
*/
QDir
cacheDir
{
tmpDir
.
path
()};
Kazv
::
RandomInterface
randomGenerator
=
QtRandAdapter
{};
QMap
<
QString
,
QPointer
<
KazvIODownloadJob
>>
cacheJobs
;
QMap
<
QString
,
QSharedPointer
<
KazvIODownloadJob
>>
downloadJobs
;
QMap
<
QString
,
QSharedPointer
<
UploadJobModel
>>
uploadJobs
;
};
KazvIOManager
::
KazvIOManager
(
QObject
*
parent
)
:
QObject
(
parent
)
,
m_d
(
new
KazvIOManagerPrivate
)
{
}
KazvIOManager
::~
KazvIOManager
()
=
default
;
QPointer
<
KazvIODownloadJob
>
KazvIOManager
::
makeDownloadJob
(
const
QUrl
&
serverUrl
,
const
QUrl
&
localFileUrl
,
const
bool
showPrograssBar
,
const
QString
&
hash
,
const
QString
&
key
,
const
QString
&
iv
)
const
{
QPointer
<
KazvIODownloadJob
>
job
{};
if
(
key
.
isEmpty
())
{
job
=
new
KazvIODownloadJob
{
localFileUrl
.
toLocalFile
(),
serverUrl
,
showPrograssBar
,
hash
,
std
::
nullopt
};
}
else
{
auto
aes
=
Kazv
::
AES256CTRDesc
{
key
.
toStdString
(),
iv
.
toStdString
()};
job
=
new
KazvIODownloadJob
{
localFileUrl
.
toLocalFile
(),
serverUrl
,
showPrograssBar
,
hash
,
aes
};
}
return
job
;
}
QUrl
KazvIOManager
::
cacheFile
(
const
QUrl
&
fileUrl
,
const
QString
&
id
,
const
QString
&
hash
,
const
QString
&
key
,
const
QString
&
iv
)
{
const
QString
filePath
=
m_d
->
cacheDir
.
filePath
(
id
);
QDir
dir
(
m_d
->
cacheDir
.
path
());
if
(
!
dir
.
exists
(
id
)
&&
this
->
getCacheJob
(
id
)
==
nullptr
)
{
auto
job
=
this
->
makeDownloadJob
(
fileUrl
,
QUrl
::
fromLocalFile
(
filePath
),
/* showProgressBar = */
false
,
hash
,
key
,
iv
);
m_d
->
cacheJobs
[
id
]
=
job
;
connect
(
job
,
&
KazvIOBaseJob
::
result
,
this
,
[
this
,
id
](
auto
/* result */
)
{
m_d
->
cacheJobs
[
id
]
->
deleteLater
();
m_d
->
cacheJobs
.
remove
(
id
);
});
}
return
QUrl
::
fromLocalFile
(
filePath
);
}
KazvIOBaseJob
*
KazvIOManager
::
startNewDownloadJob
(
const
QUrl
&
serverUrl
,
const
QUrl
&
localFileUrl
,
const
QString
&
jobId
,
const
QString
&
hash
,
const
QString
&
key
,
const
QString
&
iv
)
{
auto
downloadJob
=
this
->
makeDownloadJob
(
serverUrl
,
localFileUrl
,
/* showProgressBar = */
true
,
hash
,
key
,
iv
);
m_d
->
downloadJobs
[
jobId
].
reset
(
downloadJob
);
QQmlEngine
::
setObjectOwnership
(
downloadJob
.
data
(),
QQmlEngine
::
CppOwnership
);
return
downloadJob
.
data
();
}
KazvIOBaseJob
*
KazvIOManager
::
startNewUploadJob
(
const
QUrl
&
serverUrl
,
const
QUrl
&
localFileUrl
,
const
QString
&
token
,
const
QString
&
roomId
,
MatrixRoomList
*
roomList
,
const
bool
encrypted
,
const
QString
&
relType
,
const
QString
&
relatedTo
)
{
auto
uploadJob
=
QPointer
<
KazvIOUploadJob
>
();
if
(
encrypted
)
{
auto
aes
=
Kazv
::
AES256CTRDesc
::
fromRandom
(
m_d
->
randomGenerator
.
generateRange
<
Kazv
::
RandomData
>
(
Kazv
::
AES256CTRDesc
::
randomSize
));
uploadJob
=
new
KazvIOUploadJob
(
localFileUrl
.
toLocalFile
(),
serverUrl
,
/* showProgressBar = */
true
,
roomList
,
roomId
,
token
,
aes
,
relType
,
relatedTo
);
}
else
{
uploadJob
=
new
KazvIOUploadJob
(
localFileUrl
.
toLocalFile
(),
serverUrl
,
/* showProgressBar = */
true
,
roomList
,
roomId
,
token
,
std
::
nullopt
,
relType
,
relatedTo
);
}
if
(
!
m_d
->
uploadJobs
.
contains
(
roomId
)
||
m_d
->
uploadJobs
[
roomId
].
isNull
())
{
m_d
->
uploadJobs
[
roomId
].
reset
(
new
UploadJobModel
());
}
m_d
->
uploadJobs
[
roomId
]
->
addJob
(
uploadJob
);
QQmlEngine
::
setObjectOwnership
(
uploadJob
.
data
(),
QQmlEngine
::
CppOwnership
);
return
uploadJob
.
data
();
}
KazvIOBaseJob
*
KazvIOManager
::
startNewRoomlessUploadJob
(
const
QUrl
&
serverUrl
,
const
QUrl
&
localFileUrl
,
const
QString
&
token
)
{
return
startNewUploadJob
(
serverUrl
,
localFileUrl
,
token
,
ROOMLESS
,
0
,
false
,
QStringLiteral
(
""
),
QStringLiteral
(
""
));
}
KazvIOBaseJob
*
KazvIOManager
::
getCacheJob
(
const
QString
&
jobId
)
const
{
auto
targetJob
=
m_d
->
cacheJobs
.
find
(
jobId
);
if
(
targetJob
==
m_d
->
cacheJobs
.
end
())
{
return
nullptr
;
}
QQmlEngine
::
setObjectOwnership
(
targetJob
.
value
().
data
(),
QQmlEngine
::
CppOwnership
);
return
targetJob
.
value
().
data
();
}
KazvIOBaseJob
*
KazvIOManager
::
getDownloadJob
(
const
QString
&
jobId
)
{
auto
targetJob
=
m_d
->
downloadJobs
.
find
(
jobId
);
if
(
targetJob
==
m_d
->
downloadJobs
.
end
())
{
return
nullptr
;
}
QQmlEngine
::
setObjectOwnership
(
targetJob
.
value
().
data
(),
QQmlEngine
::
CppOwnership
);
return
targetJob
.
value
().
data
();
}
void
KazvIOManager
::
deleteDownloadJob
(
const
QString
&
jobId
)
{
m_d
->
downloadJobs
.
remove
(
jobId
);
}
UploadJobModel
*
KazvIOManager
::
getUploadJobs
(
const
QString
&
roomId
)
{
if
(
!
m_d
->
uploadJobs
.
contains
(
roomId
)
||
m_d
->
uploadJobs
[
roomId
].
isNull
())
{
m_d
->
uploadJobs
[
roomId
].
reset
(
new
UploadJobModel
());
}
QQmlEngine
::
setObjectOwnership
(
m_d
->
uploadJobs
[
roomId
].
data
(),
QQmlEngine
::
CppOwnership
);
return
m_d
->
uploadJobs
[
roomId
].
data
();
}
void
KazvIOManager
::
deleteUploadJob
(
const
QString
&
roomId
,
KazvIOBaseJob
*
job
)
{
m_d
->
uploadJobs
[
roomId
]
->
removeJob
(
QPointer
<
KazvIOUploadJob
>
(
qobject_cast
<
KazvIOUploadJob
*>
(
job
)));
}
void
KazvIOManager
::
deleteRoomlessUploadJob
(
KazvIOBaseJob
*
job
)
{
deleteUploadJob
(
ROOMLESS
,
job
);
}
void
KazvIOManager
::
deleteModelIfEmpty
(
const
QString
&
roomId
)
{
if
(
!
m_d
->
uploadJobs
.
contains
(
roomId
))
{
return
;
}
if
(
m_d
->
uploadJobs
[
roomId
]
->
rowCount
()
==
0
)
{
m_d
->
uploadJobs
.
remove
(
roomId
);
}
}
void
KazvIOManager
::
clearJobs
()
{
/**
* KazvIOBaseJob::cancel() for cache jobs will remove itself from cacheJobs,
* so iterators and loops for m_d->cacheJobs cannot be used reliably.
*/
for
(
auto
key
:
m_d
->
cacheJobs
.
keys
())
{
m_d
->
cacheJobs
[
key
]
->
cancel
();
}
std
::
for_each
(
m_d
->
downloadJobs
.
begin
(),
m_d
->
downloadJobs
.
end
(),
[
this
](
auto
job
){
job
->
cancel
();
});
std
::
for_each
(
m_d
->
uploadJobs
.
begin
(),
m_d
->
uploadJobs
.
end
(),
[
this
](
auto
room
)
{
room
->
clearJobs
();
});
m_d
->
downloadJobs
.
clear
();
m_d
->
uploadJobs
.
clear
();
}
QString
KazvIOManager
::
cacheDirectory
()
const
{
return
m_d
->
cacheDir
.
path
();
}
void
KazvIOManager
::
setCacheDirectory
(
QString
cacheDirectory
)
{
if
(
cacheDirectory
.
isEmpty
())
{
m_d
->
cacheDir
=
QDir
{
m_d
->
tmpDir
.
path
()};
}
else
{
auto
cacheDir
=
QDir
{
QUrl
{
cacheDirectory
}.
toLocalFile
()};
if
(
!
cacheDir
.
mkpath
(
u
"."
_s
))
{
return
;
}
m_d
->
cacheDir
=
cacheDir
;
}
m_d
->
downloadJobs
.
clear
();
Q_EMIT
cacheDirectoryChanged
();
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Tue, Nov 26, 2:03 PM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40354
Default Alt Text
kazv-io-manager.cpp (7 KB)
Attached To
Mode
rK kazv
Attached
Detach File
Event Timeline
Log In to Comment