mirror of
https://codeberg.org/vyn/mirai.git
synced 2025-07-02 09:23:18 +00:00
96 lines
2.4 KiB
C
96 lines
2.4 KiB
C
|
/*
|
||
|
* Mirai. Copyright (C) 2024 Vyn
|
||
|
* This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only)
|
||
|
* The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
|
||
|
*/
|
||
|
|
||
|
#ifndef MIRAI_TODOTXT_H
|
||
|
#define MIRAI_TODOTXT_H
|
||
|
|
||
|
#include "TaskItem.h"
|
||
|
#include "utils.h"
|
||
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
#include <iterator>
|
||
|
#include <memory>
|
||
|
#include <regex>
|
||
|
#include <stdexcept>
|
||
|
#include <string>
|
||
|
#include <vector>
|
||
|
|
||
|
namespace mirai {
|
||
|
|
||
|
class TodoTxtFormat {
|
||
|
public:
|
||
|
|
||
|
static TaskList readFile() {
|
||
|
std::ifstream file("../newqml/todo.txt");
|
||
|
if (!file.is_open()) {
|
||
|
throw std::runtime_error("todo.txt file not found");
|
||
|
}
|
||
|
std::vector<TaskItem> taskItems;
|
||
|
std::string line;
|
||
|
while (std::getline(file, line)) {
|
||
|
auto taskItem = parseLine(line);
|
||
|
taskItems.push_back(taskItem);
|
||
|
}
|
||
|
file.close();
|
||
|
TaskList tasks({
|
||
|
.tasks = taskItems
|
||
|
});
|
||
|
return tasks;
|
||
|
}
|
||
|
|
||
|
static void writeFile(TaskList& tasks) {
|
||
|
std::ofstream file("../newqml/todo.txt");
|
||
|
if (!file.is_open()) {
|
||
|
throw std::runtime_error("can't create todo.txt");
|
||
|
}
|
||
|
for (const auto& task : tasks.getTasks()) {
|
||
|
file << fieldWithSpace(task->state == DONE ? "x" : task->priority);
|
||
|
file << fieldWithSpace(task->state == DONE ? task->getDate() : "");
|
||
|
file << fieldWithSpace(task->getCreationDate());
|
||
|
file << task->getText() << '\n';
|
||
|
}
|
||
|
file.close();
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
static std::string fieldWithSpace(const std::string& field) {
|
||
|
if (field.length() == 0)
|
||
|
return "";
|
||
|
return (field + " ");
|
||
|
}
|
||
|
|
||
|
static TaskItem parseLine(const std::string& line) {
|
||
|
std::smatch matches;
|
||
|
std::regex regex("(^x )?(\\([A-Z]\\) )?([0-9]{4}-[0-9]{2}-[0-9]{2} )?([0-9]{4}-[0-9]{2}-[0-9]{2} )?(.*)");
|
||
|
std::regex_match(line, matches, regex);
|
||
|
|
||
|
for (size_t i = 0; i < matches.size(); ++i) {
|
||
|
std::ssub_match sub_match = matches[i];
|
||
|
std::string piece = sub_match.str();
|
||
|
}
|
||
|
|
||
|
const TaskItemState taskState = trim_copy(matches[1].str()) == "x" ? DONE : TODO;
|
||
|
const std::string priority = trim_copy(matches[2].str());
|
||
|
const std::string firstDate = trim_copy(matches[3].str());
|
||
|
const std::string secondDate = trim_copy(matches[4].str());
|
||
|
const std::string text = trim_copy(matches[5].str());
|
||
|
|
||
|
const std::string date = taskState == DONE ? firstDate : "";
|
||
|
|
||
|
|
||
|
|
||
|
return {
|
||
|
.text = text,
|
||
|
.state = taskState,
|
||
|
.date = date,
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
#endif
|