file.ts 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. type file_download_data_t = {
  2. dst_path: string;
  3. done: (url: string)=>void;
  4. };
  5. type file_download_bytes_data_t = {
  6. url: string;
  7. save: string;
  8. done: (url: string, ab: buffer_t)=>void;
  9. };
  10. type file_cache_cloud_data_t = {
  11. dest: string;
  12. path: string;
  13. done: (dest: string)=>void;
  14. };
  15. let _file_download_map: map_t<string, file_download_data_t> = map_create();
  16. let _file_download_bytes_map: map_t<string, file_download_bytes_data_t> = map_create();
  17. let _file_cache_cloud_map: map_t<string, file_cache_cloud_data_t> = map_create();
  18. ///if arm_windows
  19. let file_cmd_mkdir: string = "mkdir";
  20. let file_cmd_copy: string = "copy";
  21. ///else
  22. let file_cmd_mkdir: string = "mkdir -p";
  23. let file_cmd_copy: string = "cp";
  24. ///end
  25. let file_cloud: map_t<string, string[]> = null;
  26. let file_cloud_sizes: map_t<string, i32> = null;
  27. let _file_init_cloud_bytes_done: ()=>void;
  28. ///if arm_android
  29. let file_internal: map_t<string, string[]> = null; // .apk contents
  30. ///end
  31. function file_read_directory(path: string): string[] {
  32. if (starts_with(path, "cloud")) {
  33. let files: string[] = file_cloud != null ? map_get(file_cloud, string_replace_all(path, "\\", "/")) : null;
  34. if (files != null) {
  35. return files;
  36. }
  37. else {
  38. let empty: string[] = [];
  39. return empty;
  40. }
  41. }
  42. ///if arm_android
  43. path = string_replace_all(path, "//", "/");
  44. if (file_internal == null) {
  45. let s: string = sys_buffer_to_string(data_get_blob("data_list.json"));
  46. file_internal = json_parse_to_map(s);
  47. }
  48. if (map_get(file_internal, path) != null) {
  49. return string_split(map_get(file_internal, path), ",");
  50. }
  51. ///end
  52. let files: string[] = string_split(iron_read_directory(path), "\n");
  53. array_sort(files, null);
  54. // Folders first
  55. let num: i32 = files.length;
  56. for (let i: i32 = 0; i < num; ++i) {
  57. let f: string = files[i];
  58. if (string_index_of(f, ".") > -1) {
  59. array_splice(files, i, 1);
  60. array_push(files, f);
  61. i--;
  62. num--;
  63. }
  64. }
  65. return files;
  66. }
  67. function file_create_directory(path: string) {
  68. iron_sys_command(file_cmd_mkdir + " \"" + path + "\"");
  69. }
  70. function file_copy(src_path: string, dst_path: string) {
  71. iron_sys_command(file_cmd_copy + " \"" + src_path + "\" \"" + dst_path + "\"");
  72. }
  73. function file_start(path: string) {
  74. ///if arm_windows
  75. iron_sys_command("start \"\" \"" + path + "\"");
  76. ///elseif arm_linux
  77. iron_sys_command("xdg-open \"" + path + "\"");
  78. ///else
  79. iron_sys_command("open \"" + path + "\"");
  80. ///end
  81. }
  82. function file_download(url: string, dst_path: string, done: (url: string)=>void, size: i32 = 0) {
  83. ///if (arm_windows || arm_macos || arm_ios || arm_android)
  84. let fdd: file_download_data_t = { dst_path: dst_path, done: done };
  85. map_set(_file_download_map, url, fdd);
  86. _iron_http_request(url, size, function (url: string, ab: buffer_t) {
  87. let fdd: file_download_data_t = map_get(_file_download_map, url);
  88. if (ab != null) {
  89. iron_file_save_bytes(fdd.dst_path, ab, 0);
  90. }
  91. fdd.done(url);
  92. });
  93. ///elseif arm_linux
  94. iron_sys_command("wget -O \"" + dst_path + "\" \"" + url + "\"");
  95. done(url);
  96. ///else
  97. iron_sys_command("curl -L " + url + " -o \"" + dst_path + "\"");
  98. done(url);
  99. ///end
  100. }
  101. function file_download_bytes(url: string, done: (url: string, ab: buffer_t)=>void) {
  102. let save: string;
  103. if (path_is_protected()) {
  104. save = iron_internal_save_path();
  105. }
  106. else {
  107. save = path_data() + path_sep;
  108. }
  109. save += "download.bin";
  110. let fdbd: file_download_bytes_data_t = { url: url, save: save, done: done };
  111. map_set(_file_download_bytes_map, url, fdbd);
  112. file_download(url, save, function (url: string) {
  113. let fdbd: file_download_bytes_data_t = map_get(_file_download_bytes_map, url);
  114. let buffer: buffer_t = iron_load_blob(fdbd.save);
  115. fdbd.done(fdbd.url, buffer);
  116. });
  117. }
  118. function file_cache_cloud(path: string, done: (s: string)=>void) {
  119. ///if arm_ios
  120. let path2: string = string_replace_all(path, "/", "_"); // Cache everything into root folder
  121. ///else
  122. let path2: string = path;
  123. ///end
  124. let dest: string;
  125. if (path_is_protected()) {
  126. dest = iron_internal_save_path();
  127. }
  128. else {
  129. dest = iron_get_files_location() + path_sep;
  130. }
  131. dest += path2;
  132. if (iron_file_exists(dest)) {
  133. ///if (arm_macos || arm_ios)
  134. done(dest);
  135. ///else
  136. let p: string;
  137. if (path_is_protected()) {
  138. p = iron_internal_save_path();
  139. }
  140. else {
  141. p = path_working_dir() + path_sep;
  142. }
  143. p += path;
  144. done(p);
  145. ///end
  146. return;
  147. }
  148. let file_dir: string = substring(dest, 0, string_last_index_of(dest, path_sep));
  149. if (file_read_directory(file_dir)[0] == "") {
  150. file_create_directory(file_dir);
  151. }
  152. ///if arm_windows
  153. path = string_replace_all(path, "\\", "/");
  154. ///end
  155. let url: string = config_raw.server + "/" + path;
  156. let fccd: file_cache_cloud_data_t = { dest: dest, path: path, done: done };
  157. map_set(_file_cache_cloud_map, url, fccd);
  158. file_download(url, dest, function (url: string) {
  159. let fccd: file_cache_cloud_data_t = map_get(_file_cache_cloud_map, url);
  160. if (!iron_file_exists(fccd.dest)) {
  161. console_error(strings_check_internet_connection());
  162. fccd.done(null);
  163. return;
  164. }
  165. ///if (arm_macos || arm_ios)
  166. fccd.done(fccd.dest);
  167. ///else
  168. let p: string;
  169. if (path_is_protected()) {
  170. p = iron_internal_save_path();
  171. }
  172. else {
  173. p = path_working_dir() + path_sep;
  174. }
  175. p += fccd.path;
  176. fccd.done(p);
  177. ///end
  178. }, map_get(file_cloud_sizes, path));
  179. }
  180. function file_init_cloud_bytes(done: ()=>void, append: string = "") {
  181. _file_init_cloud_bytes_done = done;
  182. file_download_bytes(config_raw.server + "/?list-type=2" + append, function (url: string, buffer: buffer_t) {
  183. if (buffer == null) {
  184. let empty: string[] = [];
  185. map_set(file_cloud, "cloud", empty);
  186. console_error(strings_check_internet_connection());
  187. return;
  188. }
  189. let files: string[] = [];
  190. let sizes: i32[] = [];
  191. let str: string = sys_buffer_to_string(buffer);
  192. let pos_start: i32 = 0;
  193. let pos_end: i32 = 0;
  194. while (true) {
  195. pos_start = string_index_of_pos(str, "<Key>", pos_start);
  196. if (pos_start == -1) {
  197. break;
  198. }
  199. pos_start += 5; // <Key>
  200. pos_end = string_index_of_pos(str, "</Key>", pos_start);
  201. array_push(files, substring(str, pos_start, pos_end));
  202. pos_start = string_index_of_pos(str, "<Size>", pos_end);
  203. pos_start += 6; //<Size>
  204. pos_end = string_index_of_pos(str, "</Size>", pos_start);
  205. array_push(sizes, parse_int(substring(str, pos_start, pos_end)));
  206. }
  207. for (let i: i32 = 0; i < files.length; ++i) {
  208. let file: string = files[i];
  209. if (path_is_folder(file)) {
  210. let empty: string[] = [];
  211. map_set(file_cloud, substring(file, 0, file.length - 1), empty);
  212. }
  213. }
  214. for (let i: i32 = 0; i < files.length; ++i) {
  215. let file: string = files[i];
  216. let nested: bool = string_index_of(file, "/") != string_last_index_of(file, "/");
  217. if (nested) {
  218. let delim: i32 = path_is_folder(file) ? string_last_index_of(substring(file, 0, file.length - 1), "/") : string_last_index_of(file, "/");
  219. let parent: string = substring(file, 0, delim);
  220. let child: string = path_is_folder(file) ? substring(file, delim + 1, file.length - 1) : substring(file, delim + 1, file.length);
  221. array_push(map_get(file_cloud, parent), child);
  222. if (!path_is_folder(file)) {
  223. map_set(file_cloud_sizes, file, sizes[i]);
  224. }
  225. }
  226. }
  227. let is_truncated: bool = string_index_of(str, "<IsTruncated>true") > -1;
  228. if (is_truncated) {
  229. let pos_start: i32 = string_index_of(str, "<NextContinuationToken>");
  230. pos_start += 23;
  231. let pos_end: i32 = string_index_of_pos(str, "</NextContinuationToken>", pos_start);
  232. file_init_cloud_bytes(_file_init_cloud_bytes_done, "&start-after=" + substring(str, pos_start, pos_end));
  233. }
  234. else {
  235. _file_init_cloud_bytes_done();
  236. }
  237. });
  238. }
  239. function file_init_cloud(done: ()=>void) {
  240. file_cloud = map_create();
  241. file_cloud_sizes = map_create();
  242. file_init_cloud_bytes(done);
  243. }