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.

118 lines
3.6 KiB

  1. // Copyright (C) 2018 Andreas Romeyke (art1@andreas-romeyke.de), 2018.
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. #include "payload.hpp"
  16. #include <iostream>
  17. #include <boost/filesystem.hpp>
  18. #include <boost/filesystem/operations.hpp>
  19. #include <list>
  20. #include <string>
  21. //#include <filesystem> // c++17
  22. //namespace fs = std::filesystem;
  23. namespace fs = boost::filesystem;
  24. using namespace std;
  25. Payload::Payload( string basedir ) {
  26. this->basedir = basedir;
  27. fs::path p{ this->basedir };
  28. // fs::file_status s = fs::status( p );
  29. // log << "basedir "<< p.string() << endl;
  30. // log << "is dir: "<< fs::is_directory( s) << endl;
  31. // log << "exists: "<< fs::exists(s) << endl;
  32. };
  33. void Payload::scan_dir_recursively( const fs::path& directory, list<fs::path> &paths) {
  34. fs::recursive_directory_iterator iter(directory);
  35. fs::recursive_directory_iterator end;
  36. for (; iter != end; ++iter) {
  37. fs::path subdir = iter->path();
  38. paths.push_back( subdir );
  39. }
  40. }
  41. // get all relative paths relative to the bag base directory
  42. list<string> Payload::get_all_relative_paths() {
  43. list<fs::path> paths;
  44. list<string> strpaths;
  45. fs::path directory(this->basedir + "/data");
  46. if (fs::is_directory( directory )) {
  47. Payload::scan_dir_recursively( directory, paths);
  48. for (auto & path : paths) {
  49. if (fs::is_regular_file( path )) {
  50. fs::path relpath = fs::relative(path, this->basedir);
  51. strpaths.push_back( relpath.string() );
  52. }
  53. }
  54. }
  55. return strpaths;
  56. }
  57. list<string> Payload::get_all_absolute_paths() {
  58. list<fs::path> paths;
  59. list<string> strpaths;
  60. fs::path directory(this->basedir + "/data");
  61. if (fs::is_directory( directory )) {
  62. Payload::scan_dir_recursively( directory, paths);
  63. for (auto & path : paths) {
  64. if (fs::is_regular_file( path )) {
  65. strpaths.push_back( path.string() );
  66. }
  67. }
  68. }
  69. return strpaths;
  70. }
  71. bool Payload::validate() {
  72. fs::path directory(this->basedir + "/data");
  73. return fs::is_directory( directory );
  74. }
  75. bool Payload::store( const string& basedir ) {
  76. string newbasedir = basedir + "data/";
  77. fs::path p{ newbasedir };
  78. fs::file_status s = fs::status( p );
  79. if (fs::is_directory( s)) {
  80. // TODO(art1): Payload::log << "directory '" << newbasedir << "'already exists" << endl;
  81. log << "directory '" << newbasedir << "'already exists" << endl;
  82. return false;
  83. }
  84. fs::create_directory(p);
  85. list<string> paths = Payload::get_all_relative_paths();
  86. for (const string& relpath : paths) {
  87. string sourcepath = Payload::basedir + relpath;
  88. string targetpath = basedir + relpath;
  89. log << "map '" << sourcepath << "' to '" << targetpath << "'" <<endl;
  90. fs::path from_fp{ sourcepath };
  91. fs::path to_fp{ targetpath };
  92. fs::path parentdir = to_fp.parent_path();
  93. if (! fs::is_directory (parentdir)) {
  94. fs::create_directory( parentdir );
  95. }
  96. fs::copy_file (from_fp, to_fp);
  97. }
  98. return false;
  99. }
  100. void Payload::get_logstream( stringstream & log ) {
  101. log << this->log.rdbuf();
  102. }
  103. void Payload::reset_logstream() {
  104. this->log.str(std::string());
  105. }
  106. // vim: set tabstop=4 softtabstop=0 expandtab shiftwidth=4 smarttab