migrate 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #!/usr/bin/env php
  2. <?php
  3. // change this, if your php files and data is outside of your webservers document root
  4. define('PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR);
  5. define('PUBLIC_PATH', __DIR__ . DIRECTORY_SEPARATOR);
  6. require PATH . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
  7. use PrivateBin\Configuration;
  8. use PrivateBin\Model;
  9. $longopts = array(
  10. "delete-after",
  11. "delete-during"
  12. );
  13. $opts_arr = getopt("fhnv", $longopts, $rest);
  14. if ($opts_arr === false) {
  15. dieerr("Erroneous command line options. Please use -h");
  16. }
  17. if (array_key_exists("h", $opts_arr)) {
  18. helpexit();
  19. }
  20. $delete_after = array_key_exists("delete-after", $opts_arr);
  21. $delete_during = array_key_exists("delete-during", $opts_arr);
  22. $force_overwrite = array_key_exists("f", $opts_arr);
  23. $dryrun = array_key_exists("n", $opts_arr);
  24. $verbose = array_key_exists("v", $opts_arr);
  25. if ($rest >= $argc) {
  26. dieerr("Missing source configuration directory");
  27. }
  28. if ($delete_after && $delete_during) {
  29. dieerr("--delete-after and --delete-during are mutually exclusive");
  30. }
  31. $srcconf = getConfig("source", $argv[$rest]);
  32. $rest++;
  33. $dstconf = getConfig("destination", ($rest < $argc ? $argv[$rest] : ""));
  34. if (($srcconf->getSection("model") == $dstconf->getSection("model")) &&
  35. ($srcconf->getSection("model_options") == $dstconf->getSection("model_options"))) {
  36. dieerr("Source and destination storage configurations are identical");
  37. }
  38. $srcmodel = new Model($srcconf);
  39. $srcstore = $srcmodel->getStore();
  40. $dstmodel = new Model($dstconf);
  41. $dststore = $dstmodel->getStore();
  42. $ids = $srcstore->getAllPastes();
  43. foreach ($ids as $id) {
  44. debug("Reading paste id " . $id);
  45. $paste = $srcstore->read($id);
  46. $comments = $srcstore->readComments($id);
  47. savePaste($force_overwrite, $dryrun, $id, $paste, $dststore);
  48. foreach ($comments as $comment) {
  49. saveComment($force_overwrite, $dryrun, $id, $comment, $dststore);
  50. }
  51. if ($delete_during) {
  52. deletePaste($dryrun, $id, $srcstore);
  53. }
  54. }
  55. if ($delete_after) {
  56. foreach ($ids as $id) {
  57. deletePaste($dryrun, $id, $srcstore);
  58. }
  59. }
  60. debug("Done.");
  61. function deletePaste($dryrun, $pasteid, $srcstore)
  62. {
  63. if (!$dryrun) {
  64. debug("Deleting paste id " . $pasteid);
  65. $srcstore->delete($pasteid);
  66. } else {
  67. debug("Would delete paste id " . $pasteid);
  68. }
  69. }
  70. function saveComment ($force_overwrite, $dryrun, $pasteid, $comment, $dststore)
  71. {
  72. $parentid = $comment["parentid"];
  73. $commentid = $comment["id"];
  74. if (!$dststore->existsComment($pasteid, $parentid, $commentid)) {
  75. if (!$dryrun) {
  76. debug("Saving paste id " . $pasteid . ", parent id " .
  77. $parentid . ", comment id " . $commentid);
  78. $dststore->createComment($pasteid, $parentid, $commentid, $comment);
  79. } else {
  80. debug("Would save paste id " . $pasteid . ", parent id " .
  81. $parentid . ", comment id " . $commentid);
  82. }
  83. } else if ($force_overwrite) {
  84. if (!$dryrun) {
  85. debug("Overwriting paste id " . $pasteid . ", parent id " .
  86. $parentid . ", comment id " . $commentid);
  87. $dststore->createComment($pasteid, $parentid, $commentid, $comment);
  88. } else {
  89. debug("Would overwrite paste id " . $pasteid . ", parent id " .
  90. $parentid . ", comment id " . $commentid);
  91. }
  92. } else {
  93. if (!$dryrun) {
  94. dieerr("Not overwriting paste id " . $pasteid . ", parent id " .
  95. $parentid . ", comment id " . $commentid);
  96. } else {
  97. dieerr("Would not overwrite paste id " . $pasteid . ", parent id " .
  98. $parentid . ", comment id " . $commentid);
  99. }
  100. }
  101. }
  102. function savePaste ($force_overwrite, $dryrun, $pasteid, $paste, $dststore)
  103. {
  104. if (!$dststore->exists($pasteid)) {
  105. if (!$dryrun) {
  106. debug("Saving paste id " . $pasteid);
  107. $dststore->create($pasteid, $paste);
  108. } else {
  109. debug("Would save paste id " . $pasteid);
  110. }
  111. } else if ($force_overwrite) {
  112. if (!$dryrun) {
  113. debug("Overwriting paste id " . $pasteid);
  114. $dststore->create($pasteid, $paste);
  115. } else {
  116. debug("Would overwrite paste id " . $pasteid);
  117. }
  118. } else {
  119. if (!$dryrun) {
  120. dieerr("Not overwriting paste id " . $pasteid);
  121. } else {
  122. dieerr("Would not overwrite paste id " . $pasteid);
  123. }
  124. }
  125. }
  126. function getConfig ($target, $confdir)
  127. {
  128. debug("Trying to load " . $target . " conf.php" .
  129. ($confdir === "" ? "" : " from " . $confdir));
  130. putenv("CONFIG_PATH=" . $confdir);
  131. $conf = new Configuration;
  132. putenv("CONFIG_PATH=");
  133. return $conf;
  134. }
  135. function dieerr ($text)
  136. {
  137. fprintf(STDERR, "ERROR: %s" . PHP_EOL, $text);
  138. die(1);
  139. }
  140. function debug ($text) {
  141. if ($GLOBALS["verbose"]) {
  142. printf("DEBUG: %s" . PHP_EOL, $text);
  143. }
  144. }
  145. function helpexit ()
  146. {
  147. print("migrate.php - Copy data between PrivateBin backends
  148. Usage:
  149. migrate [--delete-after] [--delete-during] [-f] [-n] [-v] srcconfdir
  150. [<dstconfdir>]
  151. migrate [-h]
  152. Options:
  153. --delete-after delete data from source after all pastes and comments have
  154. successfully been copied to the destination
  155. --delete-during delete data from source after the current paste and its
  156. comments have successfully been copied to the destination
  157. -f forcefully overwrite data which already exists at the
  158. destination
  159. -n dry run, do not copy data
  160. -v be verbose
  161. <srcconfdir> use storage backend configration from conf.php found in
  162. this directory as source
  163. <dstconfdir> optionally, use storage backend configration from conf.php
  164. found in this directory as destination; defaults to:
  165. " . PATH . "cfg" . DIRECTORY_SEPARATOR . "conf.php
  166. ");
  167. exit();
  168. }