Skip to content

Instantly share code, notes, and snippets.

@petrstepanov
Created January 12, 2024 03:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petrstepanov/5eb0e0a73219d999caee781d6927ff72 to your computer and use it in GitHub Desktop.
Save petrstepanov/5eb0e0a73219d999caee781d6927ff72 to your computer and use it in GitHub Desktop.
C++ Program to Convert .TXT files to .EML Email Format. Useful to save notes to email folder.
//============================================================================
// Name : txttoeml.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <string>
#include <iostream>
#include <filesystem>
#include <regex>
#include <fstream>
namespace fs = std::filesystem;
// Converting `std::filesystem::file_time_type` to a string
// https://stackoverflow.com/questions/56788745/how-to-convert-stdfilesystemfile-time-type-to-a-string-using-gcc-9
template <typename TP>
std::time_t to_time_t(TP tp)
{
using namespace std::chrono;
auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now()
+ system_clock::now());
return system_clock::to_time_t(sctp);
}
// Get EML format string from `std::filesystem::file_time_type` timestamp
std::string format_time_eml(fs::file_time_type file_time){
std::time_t tt = to_time_t(file_time);
std::tm *gmt = std::gmtime(&tt);
std::stringstream buffer;
buffer << std::put_time(gmt, "%a, %d %b %Y %H:%M:%S");
std::string formattedFileTime = buffer.str();
return formattedFileTime;
}
// Convert file function
int convertTxtFile(std::string inPathFilename){
std::cout << "Processing " << inPathFilename << std::endl;
std::ifstream inFile (inPathFilename);
if (!inFile.is_open()) {\
std::cout << " Error opening file." << std::endl;
return 1;
}
// Create output note file
std::regex outputRegex("(.*)\\/(.+)\\.txt");
std::string outPathFilename = std::regex_replace(inPathFilename, outputRegex, "$1-eml/$2.eml");
std::ofstream outFile(outPathFilename, std::ofstream::out);
// Write note header (basic)
outFile << "From: hello@petrstepanov.com" << std::endl;
outFile << "Content-Type: text/plain; charset=\"utf-8\"" << std::endl;
outFile << "Content-Transfer-Encoding: quoted-printable" << std::endl;
outFile << "MIME-Version: 1.0" << std::endl;
// Write note header (modified time)
fs::file_time_type modifiedDate = fs::last_write_time(inPathFilename);
std::string dateStringEml = format_time_eml(modifiedDate);
outFile << "Date: " << dateStringEml << std::endl;
outFile << "X-Mail-Created-Date: " << dateStringEml << std::endl;
// Write note header (subject)
std::string line;
std::getline (inFile, line);
std::string subject = line.empty() ? "No Title" : line;
outFile << "Subject: " << subject << std::endl;
// Write note header (separator)
outFile << std::endl;
// Write note content
outFile << line << std::endl;
while (std::getline (inFile,line)) {
outFile << line << std::endl;
}
inFile.close();
outFile.close();
// Set Modified Date
fs::last_write_time(outPathFilename, modifiedDate);
std::cout << " Created " << outPathFilename << '\n';
return 0;
}
// Entry point
int main(int argc, char *argv[]) {
if (argc != 2) {
std::cout << "Missing parameter - input directory path with .txt files" << std::endl;
return 1;
}
// Create output directory
std::string inPath = argv[1];
std::regex r("(.*)\\/(.+)");
std::string outPath = std::regex_replace(inPath, r, "$1/$2-eml");\
// Check if output directory exists
if (!fs::exists(outPath)){
// Create output dierectory
if (fs::create_directories(outPath) == false){
std::cout << "Cannot create output directory: " << outPath << std::endl;
return 1;
}
std::cout << "Created output directory: " << outPath << std::endl;
}
// Convert all txt files
for (const auto & entry : fs::directory_iterator(inPath)){
convertTxtFile(entry.path());
}
std::cout << "Success." << std::endl; // prints !!!Hello World!!!
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment