Line data Source code
1 : #include "ImageCache.h"
2 : #include "FangLogging.h"
3 :
4 : #include <QCryptographicHash>
5 : #include <QDir>
6 : #include <QFile>
7 : #include <QFileInfo>
8 : #include <QStandardPaths>
9 :
10 83 : QString ImageCache::cacheDir()
11 : {
12 83 : QString path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/imagecache";
13 83 : QDir().mkpath(path);
14 83 : return path;
15 0 : }
16 :
17 30 : QString ImageCache::saveImage(const QUrl& url, const ImageData& imageData)
18 : {
19 30 : if (!imageData.isValid()) {
20 1 : return "";
21 : }
22 :
23 29 : QString hash = hashUrl(url);
24 29 : QString ext = extensionForMimeType(imageData.mimeType);
25 29 : QString filename = hash + "." + ext;
26 29 : QString filePath = cacheDir() + "/" + filename;
27 :
28 : // Skip write if file already exists.
29 29 : if (QFile::exists(filePath)) {
30 4 : return "/images/" + filename;
31 : }
32 :
33 25 : QFile file(filePath);
34 25 : if (!file.open(QIODevice::WriteOnly)) {
35 1 : return "";
36 : }
37 :
38 24 : file.write(imageData.rawData);
39 24 : file.close();
40 :
41 24 : return "/images/" + filename;
42 29 : }
43 :
44 5 : int ImageCache::evictOlderThan(const QDateTime& cutoff)
45 : {
46 5 : QDir dir(cacheDir());
47 5 : if (!dir.exists()) {
48 0 : return 0;
49 : }
50 :
51 5 : int deleted = 0;
52 5 : QFileInfoList files = dir.entryInfoList(QDir::Files);
53 12 : for (const QFileInfo& info : files) {
54 7 : if (info.lastModified() < cutoff) {
55 5 : if (QFile::remove(info.absoluteFilePath())) {
56 5 : deleted++;
57 : }
58 : }
59 : }
60 :
61 5 : if (deleted > 0) {
62 6 : qCInfo(logUtility) << "Image cache: evicted" << deleted << "expired files";
63 : }
64 :
65 5 : return deleted;
66 5 : }
67 :
68 29 : QString ImageCache::hashUrl(const QUrl& url)
69 : {
70 29 : QByteArray hash = QCryptographicHash::hash(url.toEncoded(), QCryptographicHash::Sha256);
71 58 : return QString::fromLatin1(hash.toHex().left(16));
72 29 : }
73 :
74 29 : QString ImageCache::extensionForMimeType(const QString& mimeType)
75 : {
76 29 : if (mimeType == "image/jpeg") {
77 1 : return "jpeg";
78 28 : } else if (mimeType == "image/png") {
79 24 : return "png";
80 4 : } else if (mimeType == "image/gif") {
81 1 : return "gif";
82 3 : } else if (mimeType == "image/webp") {
83 1 : return "webp";
84 2 : } else if (mimeType == "image/svg+xml") {
85 1 : return "svg";
86 : }
87 1 : return "bin";
88 : }
|