168 lines
4.2 KiB
C++
168 lines
4.2 KiB
C++
#include <iostream>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <chrono>
|
|
#include <vector>
|
|
#include <windows.h>
|
|
#include <libloaderapi.h>
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
using std::string;
|
|
using json = nlohmann::json;
|
|
|
|
const int VERSION_MAJOR = 0;
|
|
const int VERSION_MINOR = 1;
|
|
|
|
enum Flags {
|
|
EMPTY_FILES = 0x1,
|
|
EMPTY_DIRECTORIES = 0x2
|
|
};
|
|
|
|
// DWORD GetModuleFileNameA(
|
|
// [in, optional] HMODULE hModule,
|
|
// [out] LPSTR lpFilename,
|
|
// [in] DWORD nSize
|
|
// );
|
|
|
|
struct DirectoryEntry
|
|
{
|
|
std::filesystem::path path;
|
|
unsigned char flags = EMPTY_DIRECTORIES | EMPTY_FILES;
|
|
std::chrono::duration<int> olderThan = std::chrono::duration<int>(0);
|
|
|
|
void
|
|
clear()
|
|
{
|
|
path = std::filesystem::path();
|
|
flags = EMPTY_DIRECTORIES | EMPTY_FILES;
|
|
olderThan = std::chrono::duration<int>(0);
|
|
}
|
|
};
|
|
|
|
string
|
|
getVersion()
|
|
{
|
|
return std::to_string(VERSION_MAJOR)+"."+std::to_string(VERSION_MINOR);
|
|
}
|
|
|
|
void
|
|
print_usage()
|
|
{
|
|
std::cout << "--------------------------\n"<< "Cleaner version " << getVersion() << "\n--------------------------\n";
|
|
std::cout << "\tUsage:\n\t\tcleaner\n";
|
|
}
|
|
|
|
|
|
bool
|
|
createDefaultConfig()
|
|
{
|
|
LPSTR lpFilename;
|
|
DWORD nSize = 256;
|
|
DWORD len;
|
|
|
|
len = GetModuleFileName(NULL, lpFilename, nSize);
|
|
OutputDebugString(lpFilename);
|
|
|
|
json config;
|
|
config["version"] = getVersion();
|
|
config["directories"][0]["directory"] = "C:/dev/temp";
|
|
config["directories"][0]["rules"]["empty_directories"] = true;
|
|
config["directories"][0]["rules"]["empty_files"] = true;
|
|
config["directories"][0]["rules"]["age"] = "30d";
|
|
|
|
string output = config.dump(4);
|
|
std::ofstream f("cleaner.json");
|
|
if (f.is_open())
|
|
{
|
|
f << output << std::endl;
|
|
f.close();
|
|
return true;
|
|
}
|
|
return false;
|
|
// Return file handle?
|
|
}
|
|
|
|
void
|
|
cleanEntries(std::vector<DirectoryEntry>& entries)
|
|
{
|
|
for(auto& entry : entries)
|
|
{
|
|
std::cout << entry.path.string() << "\n";
|
|
}
|
|
}
|
|
|
|
std::chrono::duration<int>
|
|
parseAge(string age)
|
|
{
|
|
//TODO (Eero): parse age i.e. 30d
|
|
return std::chrono::duration<int>(0);
|
|
}
|
|
|
|
void
|
|
parseConfig(std::vector<DirectoryEntry>& entries)
|
|
{
|
|
if(!std::filesystem::exists(std::filesystem::path("./cleaner.json")))
|
|
{
|
|
std::cout << "Didn't find cleaner.json. Creating default configuration into cleaner.json.\n";
|
|
// Create cleaner.json
|
|
if(!createDefaultConfig())
|
|
{
|
|
// Failed to create file for some reason. Exit from function.
|
|
return;
|
|
}
|
|
}
|
|
//TODO (Eero): Check version here
|
|
std::ifstream f("cleaner.json");
|
|
json config = json::parse(f);
|
|
std::cout << "Config version: " << config["version"].template get<string>() << "\n";
|
|
// Iterate directories
|
|
DirectoryEntry entry = {};
|
|
for (auto& element : config["directories"]) {
|
|
if(element.is_string())
|
|
{
|
|
entry.path = std::filesystem::path(element.template get<string>());
|
|
entries.push_back(entry);
|
|
entry.clear();
|
|
continue;
|
|
}
|
|
entry.path = std::filesystem::path(element["directory"].template get<string>());
|
|
//TODO (Eero): Check if rules exists
|
|
for(json::iterator it = element["rules"].begin(); it != element["rules"].end();++it)
|
|
{
|
|
if(it.key() == "empty_directories")
|
|
{
|
|
entry.flags |= EMPTY_DIRECTORIES;
|
|
}
|
|
if(it.key() == "empty_files")
|
|
{
|
|
entry.flags |= EMPTY_FILES;
|
|
}
|
|
if(it.key() == "age")
|
|
{
|
|
entry.olderThan = parseAge(it.value());
|
|
}
|
|
}
|
|
entries.push_back(entry);
|
|
entry.clear();
|
|
}
|
|
}
|
|
|
|
int
|
|
main(int argc, char const *argv[])
|
|
{
|
|
if(argc>1){
|
|
print_usage();
|
|
return 0;
|
|
}
|
|
std::vector<DirectoryEntry> entries = {};
|
|
const auto start = std::chrono::steady_clock::now();
|
|
parseConfig(entries);
|
|
cleanEntries(entries);
|
|
const auto end = std::chrono::steady_clock::now();
|
|
const std::chrono::duration<double> elapsed_seconds{end - start};
|
|
std::cout << "Cleaner finished after " << elapsed_seconds.count() << "s\n";
|
|
return 0;
|
|
}
|