C++ Library to handle BagIt structures. BagIt is a standard format to create transfer packages for digital preservation purposes. See https://en.wikipedia.org/wiki/BagIt for details http://andreas-romeyke.de
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
2.9 KiB

  1. #include "payload.hpp"
  2. #include <iostream>
  3. #include <boost/filesystem.hpp>
  4. #include <boost/filesystem/operations.hpp>
  5. #include <list>
  6. #include <string>
  7. //#include <filesystem> // c++17
  8. //namespace fs = std::filesystem;
  9. namespace fs = boost::filesystem;
  10. using namespace std;
  11. Payload::Payload( string basedir ) {
  12. this->basedir = basedir;
  13. fs::path p{ this->basedir };
  14. // fs::file_status s = fs::status( p );
  15. // log << "basedir "<< p.string() << endl;
  16. // log << "is dir: "<< fs::is_directory( s) << endl;
  17. // log << "exists: "<< fs::exists(s) << endl;
  18. };
  19. void Payload::scan_dir_recursively( const fs::path& directory, list<fs::path> &paths) {
  20. fs::recursive_directory_iterator iter(directory);
  21. fs::recursive_directory_iterator end;
  22. for (; iter != end; ++iter) {
  23. fs::path subdir = iter->path();
  24. paths.push_back( subdir );
  25. }
  26. }
  27. // get all relative paths relative to the bag base directory
  28. list<string> Payload::get_all_relative_paths() {
  29. list<fs::path> paths;
  30. list<string> strpaths;
  31. fs::path directory(this->basedir + "/data");
  32. if (fs::is_directory( directory )) {
  33. Payload::scan_dir_recursively( directory, paths);
  34. for (auto & path : paths) {
  35. if (fs::is_regular_file( path )) {
  36. fs::path relpath = fs::relative(path, this->basedir);
  37. strpaths.push_back( relpath.string() );
  38. }
  39. }
  40. }
  41. return strpaths;
  42. }
  43. list<string> Payload::get_all_absolute_paths() {
  44. list<fs::path> paths;
  45. list<string> strpaths;
  46. fs::path directory(this->basedir + "/data");
  47. if (fs::is_directory( directory )) {
  48. Payload::scan_dir_recursively( directory, paths);
  49. for (auto & path : paths) {
  50. if (fs::is_regular_file( path )) {
  51. strpaths.push_back( path.string() );
  52. }
  53. }
  54. }
  55. return strpaths;
  56. }
  57. bool Payload::validate() {
  58. fs::path directory(this->basedir + "/data");
  59. return fs::is_directory( directory );
  60. }
  61. bool Payload::store( const string& basedir ) {
  62. string newbasedir = basedir + "data/";
  63. fs::path p{ newbasedir };
  64. fs::file_status s = fs::status( p );
  65. if (fs::is_directory( s)) {
  66. // TODO(art1): Payload::log << "directory '" << newbasedir << "'already exists" << endl;
  67. log << "directory '" << newbasedir << "'already exists" << endl;
  68. return false;
  69. }
  70. fs::create_directory(p);
  71. list<string> paths = Payload::get_all_relative_paths();
  72. for (const string& relpath : paths) {
  73. string sourcepath = Payload::basedir + relpath;
  74. string targetpath = basedir + relpath;
  75. log << "map '" << sourcepath << "' to '" << targetpath << "'" <<endl;
  76. fs::path from_fp{ sourcepath };
  77. fs::path to_fp{ targetpath };
  78. fs::path parentdir = to_fp.parent_path();
  79. if (! fs::is_directory (parentdir)) {
  80. fs::create_directory( parentdir );
  81. }
  82. fs::copy_file (from_fp, to_fp);
  83. }
  84. return false;
  85. }
  86. void Payload::get_logstream( stringstream & log ) {
  87. log << this->log.rdbuf();
  88. }
  89. void Payload::reset_logstream() {
  90. this->log.str(std::string());
  91. }
  92. // vim: set tabstop=4 softtabstop=0 expandtab shiftwidth=4 smarttab