Baloo

timelinetools.cpp
1/*
2 This file is part of the Nepomuk KDE project.
3 SPDX-FileCopyrightText: 2010 Sebastian Trueg <trueg@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8#include "timelinetools.h"
9#include "kio_timeline_debug.h"
10
11#include <QRegularExpression>
12#include <QUrlQuery>
13
14namespace
15{
16QDate applyRelativeDateModificators(const QDate& date, const QMap<QString, QString>& modificators)
17{
18 QDate newDate(date);
19 const QString dayKey = QStringLiteral("relDays");
20 const QString weekKey = QStringLiteral("relWeeks");
21 const QString monthKey = QStringLiteral("relMonths");
22 const QString yearKey = QStringLiteral("relYears");
23 bool ok = false;
24
25 if (modificators.contains(yearKey)) {
26 int relYears = modificators[yearKey].toInt(&ok);
27 if (ok) {
28 newDate = newDate.addYears(relYears);
29 }
30 }
31 if (modificators.contains(monthKey)) {
32 int relMonths = modificators[monthKey].toInt(&ok);
33 if (ok) {
34 newDate = newDate.addMonths(relMonths);
35 }
36 }
37 if (modificators.contains(weekKey)) {
38 int relWeeks = modificators[weekKey].toInt(&ok);
39 if (ok) {
40 newDate = newDate.addDays(relWeeks * 7); // we assume weeks have 7 days everywhere. QDate seems to make that assumption too, should be OK.
41 }
42 }
43 if (modificators.contains(dayKey)) {
44 int relDays = modificators[dayKey].toInt(&ok);
45 if (ok) {
46 newDate = newDate.addDays(relDays);
47 }
48 }
49 return newDate;
50}
51}
52
54 QUrl newUrl = url;
55 QString path = url.path();
56 if (path.contains(QLatin1String("//"))) {
57 QStringList sections = path.split(QLatin1Char('/'), Qt::SkipEmptyParts);
58 path = QLatin1Char('/') + sections.join(QLatin1Char('/'));
59 newUrl.setPath(path);
60 }
61 if ((path.size() > 1) && path.endsWith(QLatin1Char('/'))) {
62 path.chop(1);
63 newUrl.setPath(path);
64 }
65 if (!path.startsWith(QLatin1Char('/'))) {
66 path = QLatin1Char('/') + path;
67 newUrl.setPath(path);
68 }
69 return newUrl;
70}
71
73{
74 qCDebug(KIO_TIMELINE) << url;
75
76 static const QRegularExpression s_dateRegexp(
77 QRegularExpression::anchoredPattern(QStringLiteral("\\d{4}-\\d{2}(?:-(\\d{2}))?")));
78
79 // reset
80 *date = QDate();
81
82 QString path = url.path();
83 if (path.endsWith(QLatin1Char('/'))) {
84 path.chop(1);
85 }
86
87 if (path.isEmpty()) {
88 qCDebug(KIO_TIMELINE) << url << "is root folder";
89 return RootFolder;
90 } else if (path.startsWith(QLatin1String("/today"))) {
91 *date = QDate::currentDate();
92 if (filename) {
93 *filename = path.mid(7);
94 }
95 qCDebug(KIO_TIMELINE) << url << "is today folder:" << *date;
96 return DayFolder;
97 } else if (path == QLatin1String("/calendar")) {
98 qCDebug(KIO_TIMELINE) << url << "is calendar folder";
99 return CalendarFolder;
100 } else {
101 QStringList sections = path.split(QStringLiteral("/"), Qt::SkipEmptyParts);
102 QString dateString;
103 QRegularExpressionMatch match = s_dateRegexp.match(sections.last());
104 if (match.hasMatch()) {
105 dateString = sections.last();
106 } else if (sections.count() > 1
107 && (match = s_dateRegexp.match(sections[sections.count() - 2])).hasMatch()) {
108 dateString = sections[sections.count() - 2];
109 if (filename) {
110 *filename = sections.last();
111 }
112 } else {
113 qCWarning(KIO_TIMELINE) << url << "COULD NOT PARSE";
114 return NoFolder;
115 }
116
117 if (match.captured(1).isEmpty()) {
118 // no day -> month listing
119 qCDebug(KIO_TIMELINE) << "parsing " << dateString;
120 *date = QDate::fromString(dateString, QStringLiteral("yyyy-MM"));
121 qCDebug(KIO_TIMELINE) << url << "is month folder:" << date->month() << date->year();
122 if (date->month() > 0 && date->year() > 0) {
123 return MonthFolder;
124 }
125 } else {
126 qCDebug(KIO_TIMELINE) << "parsing " << dateString;
127 typedef QPair<QString, QString> StringPair;
128 QUrlQuery query(url);
129 const QList<StringPair> queryItems = query.queryItems();
131 for (const StringPair& pair : queryItems) {
132 map.insert(pair.first, pair.second);
133 }
134
135 *date = applyRelativeDateModificators(QDate::fromString(dateString, QStringLiteral("yyyy-MM-dd")), map);
136 // only in day folders we can have filenames
137 qCDebug(KIO_TIMELINE) << url << "is day folder:" << *date;
138 if (date->isValid()) {
139 return DayFolder;
140 }
141 }
142 }
143
144 return NoFolder;
145}
TimelineFolderType
The hierarchy in timeline:/ looks as follows:
@ CalendarFolder
the root folder
@ 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()
QDate fromString(QStringView string, QStringView format, QCalendar cal)
int month() const const
int year() const const
qsizetype count() const const
T & last()
bool contains(const Key &key) const const
QRegularExpressionMatch match(QStringView subjectView, qsizetype offset, MatchType matchType, MatchOptions matchOptions) const const
QString anchoredPattern(QStringView expression)
void chop(qsizetype n)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString mid(qsizetype position, qsizetype n) const const
qsizetype size() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString join(QChar separator) const const
SkipEmptyParts
QString path(ComponentFormattingOptions options) const const
void setPath(const QString &path, ParsingMode mode)
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.