Baloo

kio_timeline.cpp
1/*
2 SPDX-FileCopyrightText: 2009-2010 Sebastian Trueg <trueg@kde.org>
3 SPDX-FileCopyrightText: 2013 Vishesh Handa <me@vhanda.in>
4 SPDX-FileCopyrightText: 2018-2020 Stefan BrĂ¼ns <bruns@kde.org>
5
6 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
7*/
8
9#include "kio_timeline.h"
10#include "timelinetools.h"
11#include "query.h"
12#include "resultiterator.h"
13#include "../common/udstools.h"
14#include <sys/stat.h>
15
16#include <QCoreApplication>
17
18#include <KUser>
19#include <KFormat>
20
21#include <KLocalizedString>
22
23using namespace Baloo;
24
25// Pseudo plugin class to embed meta data
26class KIOPluginForMetaData : public QObject
27{
29 Q_PLUGIN_METADATA(IID "org.kde.kio.worker.timeline" FILE "timeline.json")
30};
31
32namespace
33{
34KIO::UDSEntry createFolderUDSEntry(const QString& name)
35{
36 KIO::UDSEntry uds;
37 uds.reserve(5);
40 uds.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/directory"));
41#ifdef Q_OS_WIN
43#else
44 uds.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IXUSR);
45#endif
46 uds.fastInsert(KIO::UDSEntry::UDS_USER, KUser().loginName());
47 return uds;
48}
49
50KIO::UDSEntry createDateFolderUDSEntry(const QString& name, const QString& displayName, const QDate& date)
51{
52 KIO::UDSEntry uds;
53 uds.reserve(8);
54 QDateTime dt(date, QTime(0, 0, 0));
58 uds.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/directory"));
59 uds.fastInsert(KIO::UDSEntry::UDS_MODIFICATION_TIME, dt.toSecsSinceEpoch());
60 uds.fastInsert(KIO::UDSEntry::UDS_CREATION_TIME, dt.toSecsSinceEpoch());
61#ifdef Q_OS_WIN
63#else
64 uds.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IXUSR);
65#endif
66 uds.fastInsert(KIO::UDSEntry::UDS_USER, KUser().loginName());
67 return uds;
68}
69
70KIO::UDSEntry createMonthUDSEntry(int month, int year)
71{
72 QString dateString = QDate(year, month, 1).toString(
73 i18nc("Month and year used in a tree above the actual days. "
74 "Have a look at https://doc.qt.io/qt-5/qdate.html#toString "
75 "to see which variables you can use and ask kde-i18n-doc@kde.org if you have "
76 "problems understanding how to translate this",
77 "MMMM yyyy"));
78 return createDateFolderUDSEntry(QDate(year, month, 1).toString(QStringLiteral("yyyy-MM")),
79 dateString,
80 QDate(year, month, 1));
81}
82
83KIO::UDSEntry createDayUDSEntry(const QDate& date)
84{
85 KIO::UDSEntry uds = createDateFolderUDSEntry(date.toString(QStringLiteral("yyyy-MM-dd")),
86 KFormat().formatRelativeDate(date, QLocale::LongFormat),
87 date);
88
89 return uds;
90}
91
92}
93
94TimelineProtocol::TimelineProtocol(const QByteArray& poolSocket, const QByteArray& appSocket)
95 : KIO::WorkerBase("timeline", poolSocket, appSocket)
96{
97}
98
99TimelineProtocol::~TimelineProtocol()
100{
101}
102
103KIO::WorkerResult TimelineProtocol::listDir(const QUrl& url)
104{
105 QUrl canonicalUrl = canonicalizeTimelineUrl(url);
106 if (url != canonicalUrl) {
107 redirection(canonicalUrl);
109 }
110
111 switch (parseTimelineUrl(url, &m_date, &m_filename)) {
112 case RootFolder:
113 listEntry(createFolderUDSEntry(QStringLiteral(".")));
114 listEntry(createDateFolderUDSEntry(QStringLiteral("today"), i18n("Today"), QDate::currentDate()));
115 listEntry(createDateFolderUDSEntry(QStringLiteral("calendar"), i18n("Calendar"), QDate::currentDate()));
116 break;
117
118 case CalendarFolder:
119 listEntry(createFolderUDSEntry(QStringLiteral(".")));
120 listThisYearsMonths();
121 // TODO: add entry for previous years
122 break;
123
124 case MonthFolder:
125 listEntry(createFolderUDSEntry(QStringLiteral(".")));
126 listDays(m_date.month(), m_date.year());
127 break;
128
129 case DayFolder: {
130 listEntry(createFolderUDSEntry(QStringLiteral(".")));
131 Query query;
132 query.setDateFilter(m_date.year(), m_date.month(), m_date.day());
133 query.setSortingOption(Query::SortNone);
134
135 UdsFactory udsf;
136
137 ResultIterator it = query.exec();
138 while (it.next()) {
139 KIO::UDSEntry uds = udsf.createUdsEntry(it.filePath());
140 if (uds.count()) {
141 listEntry(uds);
142 }
143 }
144 break;
145 }
146
147 case NoFolder:
148 return KIO::WorkerResult::fail(KIO::ERR_DOES_NOT_EXIST, url.toString());
149 }
150
152}
153
154KIO::WorkerResult TimelineProtocol::mimetype(const QUrl& url)
155{
156 QUrl canonicalUrl = canonicalizeTimelineUrl(url);
157 if (url != canonicalUrl) {
158 redirection(canonicalUrl);
160 }
161
162 switch (parseTimelineUrl(url, &m_date, &m_filename)) {
163 case RootFolder:
164 case CalendarFolder:
165 case MonthFolder:
166 case DayFolder:
167 mimetype(QUrl(QLatin1String("inode/directory")));
168 break;
169
170 case NoFolder:
171 return KIO::WorkerResult::fail(KIO::ERR_DOES_NOT_EXIST, url.toString());
172 }
173
175}
176
177KIO::WorkerResult TimelineProtocol::stat(const QUrl& url)
178{
179 QUrl canonicalUrl = canonicalizeTimelineUrl(url);
180 if (url != canonicalUrl) {
181 redirection(canonicalUrl);
183 }
184
185 switch (parseTimelineUrl(url, &m_date, &m_filename)) {
186 case RootFolder: {
187 statEntry(createFolderUDSEntry(QStringLiteral("/")));
188 break;
189 }
190
191 case CalendarFolder:
192 statEntry(createDateFolderUDSEntry(QStringLiteral("calendar"), i18n("Calendar"), QDate::currentDate()));
193 break;
194
195 case MonthFolder:
196 statEntry(createMonthUDSEntry(m_date.month(), m_date.year()));
197 break;
198
199 case DayFolder:
200 if (m_filename.isEmpty()) {
201 statEntry(createDayUDSEntry(m_date));
202 }
203 break;
204
205 case NoFolder:
206 return KIO::WorkerResult::fail(KIO::ERR_DOES_NOT_EXIST, url.toString());
207 }
208
210}
211
212void TimelineProtocol::listDays(int month, int year)
213{
214 const int days = QDate(year, month, 1).daysInMonth();
215 for (int day = 1; day <= days; ++day) {
216 QDate date(year, month, day);
217
218 if (date <= QDate::currentDate() && filesInDate(date)) {
219 listEntry(createDayUDSEntry(date));
220 }
221 }
222}
223
224bool TimelineProtocol::filesInDate(const QDate& date)
225{
226 Query query;
227 query.setLimit(1);
228 query.setDateFilter(date.year(), date.month(), date.day());
229 query.setSortingOption(Query::SortNone);
230
231 ResultIterator it = query.exec();
232 return it.next();
233}
234
235void TimelineProtocol::listThisYearsMonths()
236{
237 Query query;
238 query.setLimit(1);
239 query.setSortingOption(Query::SortNone);
240
241 int year = QDate::currentDate().year();
242 int currentMonth = QDate::currentDate().month();
243 for (int month = 1; month <= currentMonth; ++month) {
244 query.setDateFilter(year, month);
245 ResultIterator it = query.exec();
246 if (it.next()) {
247 listEntry(createMonthUDSEntry(month, year));
248 }
249 }
250}
251
252extern "C"
253{
254 Q_DECL_EXPORT int kdemain(int argc, char** argv)
255 {
256 QCoreApplication app(argc, argv);
257 app.setApplicationName(QStringLiteral("kio_timeline"));
258 Baloo::TimelineProtocol worker(argv[2], argv[3]);
259 worker.dispatchLoop();
260 return 0;
261 }
262}
263
264#include "kio_timeline.moc"
The Query class is the central class to query to search for files from the Index.
Definition query.h:54
@ SortNone
The results are returned in the most efficient order.
Definition query.h:109
void reserve(int size)
void fastInsert(uint field, const QString &value)
int count() const
void redirection(const QUrl &_url)
void statEntry(const UDSEntry &_entry)
void listEntry(const UDSEntry &entry)
static WorkerResult pass()
static WorkerResult fail(int _error=KIO::ERR_UNKNOWN, const QString &_errorString=QString())
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
std::optional< QSqlQuery > query(const QString &queryStatement)
Implements storage for docIds without any associated data Instantiated for:
Definition coding.cpp:11
char * toString(const EngineQuery &query)
Helper for QTest.
Definition enginequery.h:91
@ CalendarFolder
the root folder
@ RootFolder
nothing
@ MonthFolder
the calendar folder listing all months
@ DayFolder
a folder listing a month's days (m_date contains the month)
TimelineFolderType parseTimelineUrl(const QUrl &url, QDate *date, QString *filename=nullptr)
Parse a timeline URL like timeline:/today and return the type of folder it represents.
QUrl canonicalizeTimelineUrl(const QUrl &url)
Remove any double slashes, remove any trailing slashes, and add an initial slash after the scheme.
QDate currentDate()
int day() const const
int daysInMonth() const const
int month() const const
QString toString(QStringView format, QCalendar cal) const const
int year() const const
Q_OBJECTQ_OBJECT
bool isEmpty() const const
QString toString(FormattingOptions options) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:56:58 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.