rsgit /cpp-webA hyper-hyperfast web frontend for git repositories written in Rust.
tree/src/Filesystem.cpp
Filesystem.cpp165 lines · 3.4 KiB
1#include "Filesystem.hpp"
2
3#include <cstring>
4#include <filesystem>
5#include <fstream>
6#include <iostream>
7
8static std::string make_path_relative(std::string & path, std::string & root)
9{
10 return std::filesystem::relative(path, root);
11}
12
13static bool is_directory(std::string & path)
14{
15 return std::filesystem::is_directory(path);
16}
17
18bool Filesystem::AddSingleFile(std::string path, std::string root)
19{
20 if (is_directory(path) == true)
21 {
22 return true;
23 }
24
25 std::ifstream ifs(path, std::ios::binary | std::ios::ate);
26
27 if (!ifs)
28 {
29 return false;
30 }
31
32 auto end = ifs.tellg();
33 if (end <= 0)
34 {
35 return false;
36 }
37 if (!ifs.seekg(0, std::ios::beg))
38 {
39 return false;
40 }
41
42 auto size = end - ifs.tellg();
43
44 if (size <= 0)
45 {
46 return false;
47 }
48
49 struct file_data fd = {};
50 try
51 {
52 fd.data.resize(size);
53 }
54 catch (const std::exception & e)
55 {
56 return false;
57 }
58
59 if (!ifs.read((char *)fd.data.data(), fd.data.size()))
60 {
61 return false;
62 }
63
64 std::string relpath = make_path_relative(path, root);
65 if (m_Files.count(relpath) > 0)
66 {
67 std::cout << "Adding file: " << path << " (" << size << " bytes) and overwriting " << relpath << " to " << this
68 << std::endl;
69 }
70 else
71 {
72 std::cout << "Adding file: " << path << " (" << size << " bytes) as " << relpath << " to " << this << std::endl;
73 }
74
75 {
76 char const * const mp = magic_file(m_Magic, path.c_str());
77 if (mp != NULL)
78 {
79 fd.mime = magic_file(m_Magic, path.c_str());
80 }
81 else
82 {
83 fd.mime = "application/octet-stream";
84 }
85 m_Files[relpath] = fd;
86 }
87
88 return true;
89}
90
91bool Filesystem::Scan(std::string root)
92{
93 return Scan(root, {}, true);
94}
95
96bool Filesystem::Scan(std::string root, std::vector<std::string> extensions, bool exclude_extensions)
97{
98 bool retval = true;
99
100 for (const auto & entry : std::filesystem::recursive_directory_iterator(root))
101 {
102 std::string ext = std::filesystem::path(entry).extension();
103 bool found_extension = false;
104
105 for (const auto & extension : extensions)
106 {
107 if (ext == "." + extension)
108 {
109 found_extension = true;
110 break;
111 }
112 }
113
114 if (found_extension == true && exclude_extensions == false)
115 {
116 if (AddSingleFile(entry.path(), root) == false)
117 {
118 retval = false;
119 }
120 }
121 if (found_extension == false && exclude_extensions == true)
122 {
123 if (AddSingleFile(entry.path(), root) == false)
124 {
125 retval = false;
126 }
127 }
128 }
129
130 return retval;
131}
132
133FilesDict & Filesystem::GetFiles()
134{
135 return m_Files;
136}
137
138void Filesystem::GetFilenamesSorted(std::vector<std::string> & sortedFilenames)
139{
140 for (auto const & f : GetFiles())
141 {
142 sortedFilenames.push_back(f.first);
143 }
144 std::sort(sortedFilenames.begin(), sortedFilenames.end());
145#if 1
146 for (auto const & f : sortedFilenames)
147 {
148 std::cout << "Added file (alnum sorted): " << f << std::endl;
149 }
150#endif
151}
152
153void Filesystem::MagicInit()
154{
155 m_Magic = magic_open(MAGIC_MIME_TYPE);
156
157 magic_load(m_Magic, NULL);
158 magic_compile(m_Magic, NULL);
159}
160
161void Filesystem::MagicClose()
162{
163 magic_close(m_Magic);
164}
165