folders are now crearted just wrongly, so the subfolders are not yet detected correctly
Gitea Actions For Tree-Structurer / Explore-Gitea-Actions (push) Successful in 21s
Details
Gitea Actions For Tree-Structurer / Explore-Gitea-Actions (push) Successful in 21s
Details
This commit is contained in:
parent
055fa5bcc7
commit
16f0e89e91
|
@ -27,9 +27,17 @@ static PyObject* get_structure(PyObject* self, PyObject* args) {
|
||||||
std::string path_str = path ? path : "";
|
std::string path_str = path ? path : "";
|
||||||
std::vector<std::string> structure = g_tree_structurer->get_directory_structure(path_str);
|
std::vector<std::string> structure = g_tree_structurer->get_directory_structure(path_str);
|
||||||
PyObject* list = PyList_New(structure.size());
|
PyObject* list = PyList_New(structure.size());
|
||||||
|
if (!list) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
for (size_t i = 0; i < structure.size(); i++) {
|
for (size_t i = 0; i < structure.size(); i++) {
|
||||||
PyList_SET_ITEM(list, i, PyUnicode_FromString(structure[i].c_str()));
|
PyObject* str = PyUnicode_FromString(structure[i].c_str());
|
||||||
}
|
if (!str) {
|
||||||
|
Py_DECREF(list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyList_SET_ITEM(list, i, str);
|
||||||
|
}
|
||||||
return list;
|
return list;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
PyErr_SetString(TreeStructurerError, e.what());
|
PyErr_SetString(TreeStructurerError, e.what());
|
||||||
|
@ -39,8 +47,7 @@ static PyObject* get_structure(PyObject* self, PyObject* args) {
|
||||||
|
|
||||||
static PyObject* create_structure_from_file(PyObject* self, PyObject* args) {
|
static PyObject* create_structure_from_file(PyObject* self, PyObject* args) {
|
||||||
const char* structure_file = nullptr;
|
const char* structure_file = nullptr;
|
||||||
const char* target_path = nullptr;
|
const char* target_path = "."; // Default to current directory
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s|s", &structure_file, &target_path)) {
|
if (!PyArg_ParseTuple(args, "s|s", &structure_file, &target_path)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -51,8 +58,7 @@ static PyObject* create_structure_from_file(PyObject* self, PyObject* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::string target_path_str = target_path ? target_path : "";
|
g_tree_structurer->create_structure_from_file(structure_file, target_path);
|
||||||
g_tree_structurer->create_structure_from_file(structure_file, target_path_str);
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
PyErr_SetString(TreeStructurerError, e.what());
|
PyErr_SetString(TreeStructurerError, e.what());
|
||||||
|
@ -62,25 +68,24 @@ static PyObject* create_structure_from_file(PyObject* self, PyObject* args) {
|
||||||
|
|
||||||
static PyObject* create_structure_from_string(PyObject* self, PyObject* args) {
|
static PyObject* create_structure_from_string(PyObject* self, PyObject* args) {
|
||||||
const char* structure_str = nullptr;
|
const char* structure_str = nullptr;
|
||||||
const char* target_path = nullptr;
|
const char* target_path = "."; // Default to current directory
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s|s", &structure_str, &target_path)) {
|
if (!PyArg_ParseTuple(args, "s|s", &structure_str, &target_path)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_tree_structurer == nullptr) {
|
if (g_tree_structurer == nullptr) {
|
||||||
PyErr_SetString(TreeStructurerError, "TreeStructurer not initialized");
|
PyErr_SetString(TreeStructurerError, "TreeStructurer not initialized");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::string target_path_str = target_path ? target_path : "";
|
g_tree_structurer->create_structure_from_string(structure_str, target_path);
|
||||||
g_tree_structurer->create_structure_from_string(structure_str, target_path_str);
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
PyErr_SetString(TreeStructurerError, e.what());
|
PyErr_SetString(TreeStructurerError, e.what());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef TreeStructurerMethods[] = {
|
static PyMethodDef TreeStructurerMethods[] = {
|
||||||
|
@ -97,7 +102,7 @@ static PyMethodDef TreeStructurerMethods[] = {
|
||||||
|
|
||||||
static struct PyModuleDef tree_structurer_module = {
|
static struct PyModuleDef tree_structurer_module = {
|
||||||
PyModuleDef_HEAD_INIT,
|
PyModuleDef_HEAD_INIT,
|
||||||
"_tree_structurer", // Changed module name to match Python import
|
"_tree_structurer",
|
||||||
"Module for analyzing and creating directory structures",
|
"Module for analyzing and creating directory structures",
|
||||||
-1,
|
-1,
|
||||||
TreeStructurerMethods
|
TreeStructurerMethods
|
||||||
|
|
|
@ -209,32 +209,57 @@ void TreeStructurer::validate_structure(const std::vector<std::string>& lines) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t TreeStructurer::get_indent_level(const std::string& line) {
|
||||||
|
size_t level = 0;
|
||||||
|
for (size_t i = 0; i < line.length(); ++i) {
|
||||||
|
if (line[i] == ' ') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line[i] == '-' ||
|
||||||
|
static_cast<unsigned char>(line[i]) == INDENT_MARKER_PIPE ||
|
||||||
|
static_cast<unsigned char>(line[i]) == INDENT_MARKER_DASH ||
|
||||||
|
static_cast<unsigned char>(line[i]) == INDENT_MARKER_END) {
|
||||||
|
level++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return level / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TreeStructurer::TreeNode TreeStructurer::build_tree_from_lines(const std::vector<std::string>& lines) {
|
TreeStructurer::TreeNode TreeStructurer::build_tree_from_lines(const std::vector<std::string>& lines) {
|
||||||
TreeNode root{"root", true, {}};
|
TreeNode root{"root", false, {}};
|
||||||
std::vector<TreeNode*> stack{&root};
|
std::vector<TreeNode*> stack{&root};
|
||||||
size_t prev_indent = 0;
|
size_t prev_indent = 0;
|
||||||
|
|
||||||
for (const auto& line : lines) {
|
for (const auto& line : lines) {
|
||||||
|
if (line.empty()) continue;
|
||||||
|
|
||||||
size_t current_indent = get_indent_level(line);
|
size_t current_indent = get_indent_level(line);
|
||||||
|
|
||||||
while (current_indent <= prev_indent && stack.size() > 1) {
|
while (current_indent <= prev_indent && stack.size() > 1) {
|
||||||
stack.pop_back();
|
stack.pop_back();
|
||||||
prev_indent--;
|
prev_indent--;
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeNode new_node = parse_structure_line(line, current_indent);
|
TreeNode new_node = parse_structure_line(line, current_indent);
|
||||||
stack.back()->children.push_back(new_node);
|
if (!new_node.name.empty()) {
|
||||||
|
stack.back()->children.push_back(new_node);
|
||||||
if (!new_node.is_file) {
|
|
||||||
stack.push_back(&(stack.back()->children.back()));
|
if (!new_node.is_file) {
|
||||||
|
stack.push_back(&(stack.back()->children.back()));
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_indent = current_indent;
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_indent = current_indent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TreeStructurer::create_node(const TreeNode& node, const std::filesystem::path& current_path) {
|
void TreeStructurer::create_node(const TreeNode& node, const std::filesystem::path& current_path) {
|
||||||
std::filesystem::path new_path = current_path / node.name;
|
std::filesystem::path new_path = current_path / node.name;
|
||||||
|
|
||||||
|
@ -272,44 +297,27 @@ TreeStructurer::TreeNode TreeStructurer::parse_structure_line(const std::string&
|
||||||
static_cast<unsigned char>(line[i]) != INDENT_MARKER_PIPE &&
|
static_cast<unsigned char>(line[i]) != INDENT_MARKER_PIPE &&
|
||||||
static_cast<unsigned char>(line[i]) != INDENT_MARKER_DASH &&
|
static_cast<unsigned char>(line[i]) != INDENT_MARKER_DASH &&
|
||||||
static_cast<unsigned char>(line[i]) != INDENT_MARKER_END &&
|
static_cast<unsigned char>(line[i]) != INDENT_MARKER_END &&
|
||||||
line[i] != '-') {
|
line[i] != '-' &&
|
||||||
|
line[i] != '├' &&
|
||||||
|
line[i] != '└') {
|
||||||
name_start = i;
|
name_start = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string name = line.substr(name_start);
|
std::string name = line.substr(name_start);
|
||||||
|
|
||||||
name.erase(0, name.find_first_not_of(" "));
|
name.erase(0, name.find_first_not_of(" "));
|
||||||
name.erase(name.find_last_not_of(" ") + 1);
|
name.erase(name.find_last_not_of(" ") + 1);
|
||||||
|
|
||||||
bool is_file = !is_directory_marker(name);
|
bool is_file = name.empty() || name.back() != '/';
|
||||||
|
|
||||||
if (!is_file && name.back() == '/') {
|
if (!is_file) {
|
||||||
name.pop_back();
|
name.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
return TreeNode{name, is_file, {}};
|
return TreeNode{name, is_file, {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TreeStructurer::get_indent_level(const std::string& line) {
|
|
||||||
size_t level = 0;
|
|
||||||
for (size_t i = 0; i < line.length(); ++i) {
|
|
||||||
if (line[i] == ' ') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (line[i] == '-' ||
|
|
||||||
static_cast<unsigned char>(line[i]) == INDENT_MARKER_PIPE ||
|
|
||||||
static_cast<unsigned char>(line[i]) == INDENT_MARKER_DASH ||
|
|
||||||
static_cast<unsigned char>(line[i]) == INDENT_MARKER_END) {
|
|
||||||
level++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return level / 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TreeStructurer::is_directory_marker(const std::string& line) {
|
bool TreeStructurer::is_directory_marker(const std::string& line) {
|
||||||
return !line.empty() && line.back() == DIRECTORY_MARKER;
|
return !line.empty() && line.back() == DIRECTORY_MARKER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TreeNode {
|
struct TreeNode {
|
||||||
std::string name;
|
std::string name;
|
||||||
bool is_file;
|
bool is_file;
|
||||||
std::vector<TreeNode> children;
|
std::vector<TreeNode> children;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool should_ignore_dir(const std::string& dirname);
|
bool should_ignore_dir(const std::string& dirname);
|
||||||
|
@ -27,11 +27,11 @@ private:
|
||||||
std::string create_indent(size_t level);
|
std::string create_indent(size_t level);
|
||||||
std::string get_relative_path(const std::filesystem::path& path, const std::filesystem::path& base);
|
std::string get_relative_path(const std::filesystem::path& path, const std::filesystem::path& base);
|
||||||
std::vector<std::filesystem::path> get_filtered_paths(const std::filesystem::path& start);
|
std::vector<std::filesystem::path> get_filtered_paths(const std::filesystem::path& start);
|
||||||
|
size_t get_indent_level(const std::string& line);
|
||||||
TreeNode parse_structure_line(const std::string& line, size_t indent_level);
|
TreeNode parse_structure_line(const std::string& line, size_t indent_level);
|
||||||
TreeNode build_tree_from_lines(const std::vector<std::string>& lines);
|
TreeNode build_tree_from_lines(const std::vector<std::string>& lines);
|
||||||
|
|
||||||
void create_node(const TreeNode& node, const std::filesystem::path& current_path);
|
void create_node(const TreeNode& node, const std::filesystem::path& current_path);
|
||||||
size_t get_indent_level(const std::string& line);
|
|
||||||
bool is_directory_marker(const std::string& line);
|
bool is_directory_marker(const std::string& line);
|
||||||
void create_directory(const std::filesystem::path& path);
|
void create_directory(const std::filesystem::path& path);
|
||||||
void create_file(const std::filesystem::path& path);
|
void create_file(const std::filesystem::path& path);
|
||||||
|
@ -42,4 +42,5 @@ private:
|
||||||
static const unsigned char INDENT_MARKER_PIPE = '|';
|
static const unsigned char INDENT_MARKER_PIPE = '|';
|
||||||
static const unsigned char INDENT_MARKER_DASH = '+';
|
static const unsigned char INDENT_MARKER_DASH = '+';
|
||||||
static const unsigned char INDENT_MARKER_END = '\\';
|
static const unsigned char INDENT_MARKER_END = '\\';
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue