1 module unde.file_manager.move_paths; 2 3 import unde.global_state; 4 import unde.lsblk; 5 import unde.lib; 6 import unde.scan; 7 import unde.path_mnt; 8 9 import std.stdio; 10 import std.conv; 11 import core.stdc.stdlib; 12 import std.math; 13 import berkeleydb.all; 14 import std.stdint; 15 import core.stdc.stdlib; 16 import std..string; 17 import std.algorithm.sorting; 18 import std.utf; 19 import std.process; 20 import std.concurrency; 21 import core.time; 22 import core.thread; 23 import std.datetime; 24 import std.regex; 25 import std.algorithm.sorting; 26 27 import unde.file_manager.copy_paths; 28 import unde.file_manager.remove_paths; 29 import unde.slash; 30 31 import derelict.sdl2.sdl; 32 import derelict.sdl2.ttf; 33 import derelict.sdl2.image; 34 35 import std.file; 36 37 immutable DRect drect_zero = DRect(0, 0, 0, 0); 38 39 private long 40 move_path(FMGlobalState mgs, PathMnt path, string move_to, bool remove_flag, Tid tid) 41 { 42 string orig_move_to = move_to; 43 string dir_to = move_to; 44 45 if (move_to[$-1] == SL[0]) 46 { 47 string name = path.path[path.path.lastIndexOf(SL)+1..$]; 48 move_to ~= name; 49 } 50 else 51 dir_to = getParent(dir_to); 52 53 try 54 { 55 auto de1 = DirEntry(path._next); 56 auto de2 = DirEntry(dir_to); 57 58 59 version(Posix) 60 { 61 bool the_same_filesystem = de1.statBuf.st_dev == de2.statBuf.st_dev; 62 } 63 else version(Windows) 64 { 65 bool the_same_filesystem = path._next[0] == dir_to[0]; 66 } 67 if ( the_same_filesystem ) 68 { 69 if (path._next[$-1] == SL[0]) path._next = path._next[0..$-1]; 70 /*writefln("move.thread send to %s (%s, %s, %s, %s)", 71 tid, thisTid, path._next, move_to, "send");*/ 72 send(tid, thisTid, path._next, move_to, true, MsgState.Send); 73 MsgState resent; 74 do 75 { 76 //writefln("move.thread %s wait for resent", thisTid); 77 receive( (MsgState msg) { 78 resent = msg; 79 /*writefln("move.thread %s receive %s", thisTid, msg);*/ } ); 80 } while (resent != MsgState.Resent); 81 82 rename(path.path, move_to); 83 84 bool size_updated = false; 85 /* It is good to do, but there is no src path to copy info from it 86 while (!size_updated) 87 { 88 size_updated = update_progress(mgs, path, move_to_mnt, 89 size_updated, 90 "", 91 Clock.currTime().toUnixTime(), 92 10000, 93 txn); 94 if (!size_updated) 95 Thread.sleep( 200.msecs() ); 96 }*/ 97 } 98 else 99 { 100 int num_errors = copy_path(mgs, path, orig_move_to, remove_flag, tid); 101 if (num_errors == 0) 102 remove_path(mgs, path); 103 } 104 } 105 catch (Exception exp) 106 { 107 shared msg = ConsoleMessage( 108 SDL_Color(0xFF, 0x00, 0x00, 0xFF), 109 format("Failed Move: %s", exp.msg), 110 SDL_GetTicks() 111 ); 112 send(tid, msg); 113 } 114 115 return 0; 116 } 117 118 private void 119 start_move_paths(shared LsblkInfo[string] lsblk, immutable string[] paths, string move_to, bool remove, Tid tid) 120 { 121 writefln("Start moving %s, remove=%s", paths, remove); 122 123 try { 124 FMGlobalState mgs = new FMGlobalState(); 125 scope(exit) 126 { 127 destroy(mgs); 128 } 129 130 mgs.lsblk = to!(LsblkInfo[string])(lsblk); 131 132 string[] paths_dup = paths.dup; 133 sort!("a < b")(paths_dup); 134 foreach(path; paths_dup) 135 { 136 move_path(mgs, PathMnt(mgs.lsblk, path), move_to, remove, tid); 137 } 138 } catch (shared(Throwable) exc) { 139 send(tid, exc); 140 } 141 142 writefln("Finish moving %s", paths); 143 send(tid, thisTid); 144 } 145 146 int move_paths(GlobalState gs, immutable string[] paths, string move_to, bool remove) 147 { 148 foreach(tid, paths2; gs.movers) 149 { 150 if (paths2 == paths) 151 { 152 writefln("Move %s already in work", paths); 153 return 0; 154 } 155 } 156 157 shared LsblkInfo[string] lsblk = to!(shared LsblkInfo[string])(gs.lsblk); 158 auto tid = spawn(&start_move_paths, lsblk, paths, move_to, remove, thisTid); 159 gs.movers[tid] = paths.dup(); 160 return 0; 161 } 162 163 void check_movers(GlobalState gs) 164 { 165 // Look check_scanners 166 } 167