Baloo

timelinetools.cpp
1 /*
2  This file is part of the Nepomuk KDE project.
3  SPDX-FileCopyrightText: 2010 Sebastian Trueg <[email protected]>
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 
14 namespace
15 {
16 QDate 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("//"))) {
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 
72 Baloo::TimelineFolderType Baloo::parseTimelineUrl(const QUrl& url, QDate* date, QString* filename)
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 }
QString anchoredPattern(const QString &expression)
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
int month() const const
std::optional< QSqlQuery > query(const QString &queryStatement)
bool contains(const Key &key) const const
int size() const const
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
int count(const T &value) const const
int year() const const
void chop(int n)
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.
SkipEmptyParts
bool isEmpty() const const
QDate currentDate()
QString join(const QString &separator) const const
T & last()
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QDate fromString(const QString &string, Qt::DateFormat format)
QString path(QUrl::ComponentFormattingOptions options) const const
QString path(const QString &relativePath)
KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str)
void setPath(const QString &path, QUrl::ParsingMode mode)
QUrl canonicalizeTimelineUrl(const QUrl &url)
Remove any double slashes, remove any trailing slashes, and add an initial slash after the scheme.
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QFuture< void > map(Sequence &sequence, MapFunctor function)
QString mid(int position, int n) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Nov 29 2023 03:56:26 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.