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...)
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.
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
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 Fri Jul 26 2024 11:52:28 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.