PageRenderTime 47ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/datadir/util_setdir.php

https://gitlab.com/billyprice1/QuickBox
PHP | 283 lines | 237 code | 19 blank | 27 comment | 93 complexity | 6daf24824be4628ab7dc8699678a7fca MD5 | raw file
  1. <?php
  2. require_once( "../../php/xmlrpc.php" );
  3. require_once( "../../php/Torrent.php" );
  4. require_once( "../../php/rtorrent.php" );
  5. require_once( './util_rt.php' );
  6. //------------------------------------------------------------------------------
  7. // Move torrent data of $hash torrent to new location at $dest_path
  8. //------------------------------------------------------------------------------
  9. function rtSetDataDir( $hash, $dest_path, $add_path, $move_files, $fast_resume, $dbg = false )
  10. {
  11. if( $dbg ) rtDbg( __FUNCTION__, "hash : ".$hash );
  12. if( $dbg ) rtDbg( __FUNCTION__, "dest_path : ".$dest_path );
  13. if( $dbg ) rtDbg( __FUNCTION__, "add path : ".($add_path ? "1" : "0") );
  14. if( $dbg ) rtDbg( __FUNCTION__, "move files : ".($move_files ? "1" : "0") );
  15. if( $dbg ) rtDbg( __FUNCTION__, "fast resume : ".($fast_resume ? "1" : "0") );
  16. $is_open = false;
  17. $is_active = false;
  18. $is_multy_file = false;
  19. $base_name = '';
  20. $base_path = '';
  21. $base_file = '';
  22. $is_ok = true;
  23. if( $dest_path == '' )
  24. {
  25. $is_ok = false;
  26. }
  27. else {
  28. $dest_path = rtAddTailSlash( $dest_path );
  29. }
  30. // Check if torrent is open or active
  31. if( $is_ok )
  32. {
  33. $req = rtExec( array( "d.is_open", "d.is_active" ), $hash, $dbg );
  34. if( !$req )
  35. $is_ok = false;
  36. else {
  37. $is_open = ( $req->val[0] != 0 );
  38. $is_active = ( $req->val[1] != 0 );
  39. if( $dbg ) rtDbg( __FUNCTION__, "is_open=".$req->val[0].", is_active=".$req->val[1] );
  40. }
  41. }
  42. // Open closed torrent to get d.get_base_path, d.get_base_filename
  43. if( $is_ok && $move_files )
  44. {
  45. if( !$is_open && !rtExec( "d.open", $hash, $dbg ) )
  46. {
  47. $is_ok = false;
  48. }
  49. }
  50. // Ask info from rTorrent
  51. if( $is_ok && $move_files )
  52. {
  53. $req = rtExec(
  54. array( "d.get_name",
  55. "d.get_base_path",
  56. "d.get_base_filename",
  57. "d.is_multi_file",
  58. "d.get_complete" ),
  59. $hash, $dbg );
  60. if( !$req )
  61. $is_ok = false;
  62. else {
  63. $base_name = trim( $req->val[0] );
  64. $base_path = trim( $req->val[1] );
  65. $base_file = trim( $req->val[2] );
  66. $is_multy_file = ( $req->val[3] != 0 );
  67. if( $req->val[4] == 0 ) // if torrent is not completed -> "fast start" is impossible
  68. $fast_resume = false;
  69. if( $dbg ) rtDbg( __FUNCTION__, "d.get_name : ".$base_name );
  70. if( $dbg ) rtDbg( __FUNCTION__, "d.get_base_path : ".$base_path );
  71. if( $dbg ) rtDbg( __FUNCTION__, "d.get_base_filename : ".$base_file );
  72. if( $dbg ) rtDbg( __FUNCTION__, "d.is_multy_file : ".$req->val[3] );
  73. if( $dbg ) rtDbg( __FUNCTION__, "d.get_complete : ".$req->val[4] );
  74. }
  75. }
  76. // Check if paths are valid
  77. if( $is_ok && $move_files )
  78. {
  79. if( $base_path == '' || $base_file == '' )
  80. {
  81. if( $dbg ) rtDbg( __FUNCTION__, "base paths are empty" );
  82. $is_ok = false;
  83. }
  84. else {
  85. // Make $base_path a really BASE path for downloading data
  86. // (not including single file or subdir for multiple files).
  87. // Add trailing slash, if none.
  88. $base_path = rtRemoveTailSlash( $base_path );
  89. $base_path = rtRemoveLastToken( $base_path, '/' ); // filename or dirname
  90. $base_path = rtAddTailSlash( $base_path );
  91. }
  92. }
  93. // Get list of torrent data files
  94. $torrent_files = array();
  95. if( $is_ok && $move_files )
  96. {
  97. $req = rtExec( "f.multicall", array( $hash, "", getCmd("f.get_path=") ), $dbg );
  98. if( !$req )
  99. $is_ok = false;
  100. else {
  101. $torrent_files = $req->val;
  102. if( $dbg ) rtDbg( __FUNCTION__, "files in torrent : ".count( $torrent_files ) );
  103. }
  104. }
  105. // 1. Stop torrent if active (if not, then rTorrent can crash)
  106. // 2. Close torrent anyway
  107. if( $is_ok )
  108. {
  109. $cmds = array();
  110. if( $is_active ) $cmds[] = "d.stop";
  111. if( $is_open || $move_files ) $cmds[] = "d.close";
  112. if( count( $cmds ) > 0 && !rtExec( $cmds, $hash, $dbg ) )
  113. $is_ok = false;
  114. }
  115. // Move torrent data files to new location
  116. if( $is_ok && $move_files )
  117. {
  118. $full_base_path = $base_path;
  119. $full_dest_path = $dest_path;
  120. // Don't use "count( $torrent_files ) > 1" check (there can be one file in a subdir)
  121. if( $is_multy_file )
  122. {
  123. // torrent is a directory
  124. $full_base_path .= rtAddTailSlash( $base_file );
  125. $full_dest_path .= $add_path ? rtAddTailSlash( $base_name ) : "";
  126. }
  127. else {
  128. // torrent is a single file
  129. }
  130. if( $dbg ) rtDbg( __FUNCTION__, "from ".$full_base_path );
  131. if( $dbg ) rtDbg( __FUNCTION__, "to ".$full_dest_path );
  132. if( $full_base_path != $full_dest_path && is_dir( $full_base_path ) )
  133. {
  134. if( !rtOpFiles( $torrent_files, $full_base_path, $full_dest_path, "Move", $dbg ) )
  135. $is_ok = false;
  136. else {
  137. // Recursively remove source dirs without files
  138. if( $dbg ) rtDbg( __FUNCTION__, "clean ".$full_base_path );
  139. if( $is_multy_file )
  140. {
  141. rtRemoveDirectory( $full_base_path, false );
  142. if( $dbg && is_dir( $full_base_path ) )
  143. rtDbg( __FUNCTION__, "some files were not deleted" );
  144. }
  145. }
  146. }
  147. }
  148. if( $is_ok )
  149. {
  150. // fast resume is requested
  151. if( $fast_resume )
  152. {
  153. if( $dbg ) rtDbg( __FUNCTION__, "trying fast resume" );
  154. // collect variables
  155. $session = rTorrentSettings::get()->session;
  156. $tied_to_file = null;
  157. $label = null;
  158. $addition = null;
  159. $req = rtExec( array(
  160. "get_session",
  161. "d.get_tied_to_file",
  162. "d.get_custom1",
  163. "d.get_connection_seed",
  164. "d.get_throttle_name",
  165. ),
  166. $hash, $dbg );
  167. if( !$req )
  168. {
  169. $fast_resume = false;
  170. }
  171. else {
  172. $session = $req->val[0];
  173. $tied_to_file = $req->val[1];
  174. $label = rawurldecode( $req->val[2] );
  175. $addition = array();
  176. if( !empty( $req->val[3] ) )
  177. $addition[] = getCmd( "d.set_connection_seed=" ).$req->val[3];
  178. if( !empty( $req->val[4] ) )
  179. $addition[] = getCmd( "d.set_throttle_name=" ).$req->val[4];
  180. // build path to .torrent file
  181. $fname = rtAddTailSlash( $session ).$hash.".torrent";
  182. if( empty( $session ) || !is_readable( $fname ) )
  183. {
  184. if( !strlen( $tied_to_file ) || !is_readable( $tied_to_file ) )
  185. {
  186. if( $dbg ) rtDbg( __FUNCTION__, "empty session or inaccessible .torrent file" );
  187. $fname = null;
  188. $fast_resume = false;
  189. }
  190. else {
  191. $fname = $tied_to_file;
  192. }
  193. }
  194. }
  195. // create torrent, remove old and add new one
  196. if( $fast_resume )
  197. {
  198. $torrent = new Torrent( $fname );
  199. if( $torrent->errors() )
  200. {
  201. if( $dbg ) rtDbg( __FUNCTION__, "fail to create Torrent object" );
  202. $fast_resume = false;
  203. }
  204. else
  205. {
  206. $is_ok = $add_path ?
  207. rtExec( "d.set_directory", array( $hash, $dest_path ), $dbg ) :
  208. rtExec( "d.set_directory_base", array( $hash, $dest_path ), $dbg ); // for erasedata plugin
  209. if( $is_ok )
  210. {
  211. if( !rtExec( "d.erase", $hash, $dbg ) )
  212. {
  213. if( $dbg ) rtDbg( __FUNCTION__, "fail to erase old torrent" );
  214. $fast_resume = false;
  215. }
  216. else
  217. {
  218. if( !rTorrent::sendTorrent(
  219. $torrent, // $fname or $torrent
  220. true, // $isStart
  221. $add_path, // $isAddPath
  222. $dest_path, // $directory
  223. $label, // $label
  224. true, // $saveTorrent
  225. true, // $isFast
  226. false, // $isNew
  227. $addition // $addition
  228. ) )
  229. {
  230. if( $dbg ) rtDbg( __FUNCTION__, "fail to add new torrent" );
  231. $fast_resume = false;
  232. $is_ok = false;
  233. }
  234. }
  235. }
  236. }
  237. }
  238. if( $dbg )
  239. rtDbg( __FUNCTION__, "fast resume ".($fast_resume ? "done" : "fail") );
  240. }
  241. // fast resume is fail or not requested at all
  242. if( $is_ok && !$fast_resume )
  243. {
  244. // Setup new directory for torrent (we need to stop it first)
  245. $is_ok = $add_path ?
  246. rtExec( "d.set_directory", array( $hash, $dest_path ), $dbg ) :
  247. rtExec( "d.set_directory_base", array( $hash, $dest_path ), $dbg );
  248. if( $is_ok )
  249. {
  250. // Start torrent if need
  251. if( $is_active )
  252. $is_ok = rtExec( array( "d.open", "d.start" ), $hash, $dbg );
  253. // Open torrent if need
  254. elseif( $is_open )
  255. $is_ok = rtExec( "d.open", $hash, $dbg );
  256. // Refresh torrent info after d.set_directory
  257. else
  258. $is_ok = rtExec( array( "d.open", "d.close" ), $hash, $dbg );
  259. }
  260. }
  261. }
  262. if( $dbg ) rtDbg( __FUNCTION__, "finished" );
  263. return $is_ok;
  264. }