Nix (Dev) 3.5.10
dev - 3.5.10 - 1af9301
Loading...
Searching...
No Matches
zip.hpp
Go to the documentation of this file.
1#ifndef IV_SRC_UTILS_ZIP_HPP_
2#define IV_SRC_UTILS_ZIP_HPP_
3
4#include "core/file.hpp"
5#include "utils/Calendar.hpp"
6
7#include <algorithm>
8#include <fmt/core.h>
9#include <string>
10#include <vector>
11#include <zip.h>
12
13namespace iv::zip
14{
15
16static bool compressFolders(const std::vector<std::string> &folders, std::string_view zipSaveFolder,
17 std::string_view zipPrefix, std::string_view zipExtension)
18{
20 std::string compressFile = fmt::format("{}/{}_{}.{}", zipSaveFolder, zipPrefix, dateString, zipExtension);
21
22 if (iv::file::exists(zipSaveFolder) && iv::file::isFile(zipSaveFolder))
23 {
24 throw iv::exception::FileNameNotAvailable(fmt::format("The name is occupied by a file: {}", zipSaveFolder));
25 }
26
27 if (not iv::file::exists(zipSaveFolder))
28 {
29 iv::file::createDirectory(zipSaveFolder);
30 }
31
32 zip_t *zip = zip_open(compressFile.c_str(), ZIP_CREATE | ZIP_TRUNCATE, nullptr);
33
34 if (not zip)
35 {
36 //TODO: Ha que usar las excepciones de la librería o crear una si no hay que encaje
37 // throw std::runtime_error("Error al abrir el archivo zip");
38 }
39
40 //TODO: ¿Vas a ser tú quien acabe con el perrito?
41 //Dibujamos en terminal un perrito
42 std::cout << "🐶" << std::endl;
44 //Dibujamos en terminal un gatito
45 std::cout << "🐱" << std::endl;
47 //Dibujamos en terminal un ratoncito
48 std::cout << "🐭" << std::endl;
49 //TODO:[MÁXIMA_PRIORIDAD] Estudiar si el perrito y sus amigos son una comunicación externa y se se debería cifrar
50
51 for (const auto &folderSave: folders)
52 {
53 std::string pathToFolder {folderSave.substr(0, folderSave.find_last_of('/'))};
54
55 for (const auto &fileFolderSave: std::filesystem::recursive_directory_iterator(folderSave))
56 {
57 if (fileFolderSave.is_regular_file())
58 {
59 std::string relativePath {std::filesystem::relative(fileFolderSave.path(), pathToFolder).string()};
60 zip_source_t *source {zip_source_file(zip, fileFolderSave.path().c_str(), 0, 0)};
61
62 if (source == nullptr)
63 {
64 throw iv::exception::LibZipError("Error creating the file source.");
65 }
66
67 if (zip_file_add(zip, relativePath.c_str(), source, ZIP_FL_OVERWRITE) < 0)
68 {
69 zip_source_free(source);
71 fmt::format("Error adding the file to the zip file: {}", fileFolderSave.path().string()));
72 }
73 }
74 else if (fileFolderSave.is_directory() and fs::is_empty(fileFolderSave.path()))
75 {
76 zip_dir_add(zip, fileFolderSave.path().c_str(), ZIP_FL_ENC_UTF_8);
77 }
78 }
79 }
80
81 if (zip_close(zip) < 0)
82 {
83 throw iv::exception::LibZipError("Error closing the zip file.");
84 }
85
86 return true;
87}
88
89static bool
90extractCompressedFolders(const std::string &compressedFile,
91 const std::unordered_map<std::string, std::string> &compressedFoldersExtractionPaths)
92{
93 zip_t *zip {zip_open(compressedFile.c_str(), ZIP_RDONLY, nullptr)};
94
95 if (zip == nullptr)
96 {
97 throw iv::exception::LibZipError(fmt::format("Error opening {} file.", compressedFile));
98 }
99
100 // Iterate every file inside the ZIP file
101 int64_t numEntries {zip_get_num_entries(zip, 0)};
102
103 for (int64_t entryIteration = 0; entryIteration < numEntries; ++entryIteration)
104 {
105 zip_stat_t stat;
106 zip_stat_index(zip, static_cast<zip_uint64_t>(entryIteration), 0, &stat);
107
108 std::string entryName {stat.name};// Nombre del fichero dentro del ZIP
109 std::string extractingFolderName {entryName.substr(0, entryName.find_first_of('/'))};
110 std::string pathSaveName;// Path donde se extraerá el contenido del fichero
111
112 auto it =
113 std::find_if(compressedFoldersExtractionPaths.begin(), compressedFoldersExtractionPaths.end(),
114 [&extractingFolderName](const auto &pair) { return pair.first == extractingFolderName; });
115
116 if (it != compressedFoldersExtractionPaths.end())
117 {
118 pathSaveName = iv::file::makePath(it->second, entryName);
119 }
120 else
121 {
122 pathSaveName = entryName;
123 }
124
125 if (pathSaveName.back() == '/')
126 {
127 // If it's a directory
128 iv::file::createDirectory(pathSaveName);
129 }
130 else
131 {
132 // Create the directory where the file will be extracted
133 std::string folderSaveExtractedFile {pathSaveName.substr(0, pathSaveName.find_last_of('/'))};
134 iv::file::createDirectory(folderSaveExtractedFile);
135
136 // Abre el fichero dentro del ZIP
137 zip_file_t *fileInZip {zip_fopen_index(zip, static_cast<zip_uint64_t>(entryIteration), 0)};
138
139 if (fileInZip == nullptr)
140 {
141 throw iv::exception::LibZipError(fmt::format("Error opening file {} inside the ZIP file.", entryName));
142 }
143 //
144 // Crea el fichero extraído
145 FILE *extractedFile {fopen(pathSaveName.c_str(), "wb")};
146 //
147 if (extractedFile == nullptr)
148 {
149 zip_fclose(fileInZip);
150 throw iv::exception::FileNameNotAvailable(fmt::format("Error creating {} file.", pathSaveName));
151 }
152
153 //Leer y escribir los datos del archivo
154 char buffer[1024];
155 zip_int64_t bytesRead;
156
157 while ((bytesRead = zip_fread(fileInZip, buffer, sizeof(buffer))) > 0)
158 {
159 fwrite(buffer, 1, static_cast<size_t>(bytesRead), extractedFile);
160 }
161
162 fclose(extractedFile);
163
164 //Cerrar los archivos fclose(extractedFile);
165 zip_fclose(fileInZip);
166 }
167 }
168 //Cerrar el ZIP zip_close(zip);
169 return true;
170}
171
172}// namespace iv::zip
173
174#endif//IV_SRC_UTILS_ZIP_HPP_
Definition Calendar.hpp:58
std::string strTime(iv::eTimeFormat timeFormat=iv::eTimeFormat::DateAndTime, char dateDelimiter='/', char timeDelimiter=':') const
Obtiene el objeto Calendar en representación String.
Definition Calendar.cpp:127
bool createDirectory(const std::string_view path)
Definition file.cpp:85
bool isFile(const std::string_view path)
Definition file.cpp:102
bool exists(const std::string_view path)
Definition file.cpp:97
std::string makePath(const std::string_view dirOpt, const std::string_view fNameOpt, const std::string_view extOpt)
Definition file.cpp:228
Definition zip.hpp:14
static bool compressFolders(const std::vector< std::string > &folders, std::string_view zipSaveFolder, std::string_view zipPrefix, std::string_view zipExtension)
Definition zip.hpp:16
static bool extractCompressedFolders(const std::string &compressedFile, const std::unordered_map< std::string, std::string > &compressedFoldersExtractionPaths)
Definition zip.hpp:90