~aleteoryx/muditaos

ref: 45a7216cec39636bbd7b7b008e6c5c2b92279680 muditaos/module-utils/ical/ParserICS.hpp -rw-r--r-- 5.4 KiB
45a7216c — Paweł Joński [EGD-7217] Separate commonly used headers from application-calendar 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <time/dateCommon.hpp>

#include <json11.hpp>

#include <memory>

/**
 * Icalendar Parser complies with:
 * @version RFC5545
 * @link https://tools.ietf.org/html/rfc5545
 */

class Duration
{
    uint32_t week = 0, day = 0, hour = 0, minute = 0;

  public:
    bool isValid = true;
    Duration(uint32_t week = 0, uint32_t day = 0, uint32_t hour = 0, uint32_t minute = 0);
    explicit Duration(const std::string &property);

    [[nodiscard]] auto getDurationInMinutes() const -> uint32_t;
    [[nodiscard]] auto getDurationString() const -> std::string;
};

enum class Action
{
    none,
    audio,
    display,
    procedure
};

class Alarm
{
    Duration trigger;
    Action action = Action::none;

  public:
    bool isValid = true;
    Alarm()      = default;
    explicit Alarm(Duration &beforeEvent, Action action = Action::none);

    void setAction(const std::string &action);
    void setTrigger(const std::string &duration);

    [[nodiscard]] auto getTriggerValue() const -> Duration;
    [[nodiscard]] auto getActionValue() const -> Action;

    [[nodiscard]] auto getTriggerString() const -> std::string;
    [[nodiscard]] auto getActionString() const -> std::string;
};

enum class Frequency
{
    never,
    daily,
    weekly,
    monthly,
    yearly

};

class RecurrenceRule
{
    Frequency frequency = Frequency::never;
    uint32_t count      = 0;
    uint32_t interval   = 0;

  public:
    bool isValid     = true;
    RecurrenceRule() = default;
    RecurrenceRule(Frequency freq, uint32_t count, uint32_t interval);

    void setFrequency(const std::string &property);
    void setCount(const std::string &property);
    void setInterval(const std::string &property);

    [[nodiscard]] auto getFrequencyValue() const -> Frequency;
    [[nodiscard]] auto getCountValue() const -> uint32_t;
    [[nodiscard]] auto getIntervalValue() const -> uint32_t;

    [[nodiscard]] auto getFrequencyString() const -> std::string;
    [[nodiscard]] auto getCountString() const -> std::string;
    [[nodiscard]] auto getIntervalString() const -> std::string;
};

class Event
{
    std::string uid;
    std::string summary;
    TimePoint dtstart;
    TimePoint dtend;

    auto isDate(const std::string &dt) -> bool;
    auto isTime(const std::string &dt) -> bool;
    auto validateDT(const std::string &dt) -> bool;
    auto validateUID(const std::string &uid) -> bool;

    [[nodiscard]] auto getDateFromIcalFormat(const std::string &icalDateTime) const -> std::string;
    [[nodiscard]] auto getYearFromIcalDate(const std::string &icalDate) const -> std::string;
    [[nodiscard]] auto getMonthFromIcalDate(const std::string &icalDate) const -> std::string;
    [[nodiscard]] auto getDayFromIcalDate(const std::string &icalDate) const -> std::string;

    [[nodiscard]] auto getTimeFromIcalFormat(const std::string &icalDateTime) const -> std::string;
    [[nodiscard]] auto getHourFromIcalTime(const std::string &icalTime) const -> std::string;
    [[nodiscard]] auto getMinutesFromIcalTime(const std::string &icalTime) const -> std::string;
    [[nodiscard]] auto getSecondsFromIcalTime(const std::string &icalTime) const -> std::string;

    [[nodiscard]] auto dateStringFrom(const std::string &icalDate) const -> std::string;
    [[nodiscard]] auto timeStringFrom(const std::string &icalTime) const -> std::string;

    [[nodiscard]] auto TimePointFromIcalDate(const std::string &icalDateTime) const -> TimePoint;
    [[nodiscard]] auto TimePointToIcalDate(const TimePoint &tp) const -> std::string;

  public:
    bool isValid = true;
    Event()      = default;
    Event(const std::string &summary, TimePoint from, TimePoint till, const std::string &uid);

    void setUID(const std::string &property);
    void setSummary(const std::string &property);
    void setDTStart(const std::string &property);
    void setDTEnd(const std::string &property);

    [[nodiscard]] auto getUID() const -> std::string;
    [[nodiscard]] auto getSummary() const -> std::string;
    [[nodiscard]] auto getDTStartTimePoint() const -> TimePoint;
    [[nodiscard]] auto getDTEndTimePoint() const -> TimePoint;

    [[nodiscard]] auto getDTStartString() const -> std::string;
    [[nodiscard]] auto getDTEndString() const -> std::string;
};

struct ICalEvent
{
    Event event;
    Alarm alarm;
    RecurrenceRule rrule;
};

class ParserICS
{
    std::string icsData;

    void parseFrom(const Event &event);
    void parseFrom(const Alarm &alarm);
    void parseFrom(const RecurrenceRule &rrule);
    void parseFrom(const ICalEvent &icalEvent);

    auto startsWith(const std::string &line, const char *text) const -> bool;
    auto getProperty(const std::string &line) const -> std::string;
    auto getSubProperty(const std::string &Line, const char *propertyName) const -> std::string;

    void eventPropertiesFromLine(ICalEvent &icalEvent, const std::string &line) const;
    void rrulePropertiesFromLine(ICalEvent &icalEvent, const std::string &line) const;
    void alarmPropertiesFromLine(ICalEvent &icalEvent, std::istringstream &input, std::string &line) const;

  public:
    ParserICS() = default;
    void importEvents(std::vector<ICalEvent> events);
    [[nodiscard]] auto exportEvents() const -> std::vector<ICalEvent>;
    void loadData(const std::string &data);

    [[nodiscard]] auto getIcsData() const -> std::string
    {
        return icsData;
    }
};