archive_files.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include "archive_files.h"
  2. #include "archive_browser.h"
  3. #define TAG "Archive"
  4. bool filter_by_extension(FileInfo* file_info, const char* tab_ext, const char* name) {
  5. furi_assert(file_info);
  6. furi_assert(tab_ext);
  7. furi_assert(name);
  8. bool result = false;
  9. if(strcmp(tab_ext, "*") == 0) {
  10. result = true;
  11. } else if(strstr(name, tab_ext) != NULL) {
  12. result = true;
  13. } else if(file_info->flags & FSF_DIRECTORY) {
  14. result = true;
  15. }
  16. return result;
  17. }
  18. void archive_trim_file_path(char* name, bool ext) {
  19. char* slash = strrchr(name, '/') + 1;
  20. if(strlen(slash)) strlcpy(name, slash, strlen(slash) + 1);
  21. if(ext) {
  22. char* dot = strrchr(name, '.');
  23. if(strlen(dot)) *dot = '\0';
  24. }
  25. }
  26. void archive_get_file_extension(char* name, char* ext) {
  27. char* dot = strrchr(name, '.');
  28. if(dot == NULL)
  29. *ext = '\0';
  30. else
  31. strncpy(ext, dot, MAX_EXT_LEN);
  32. }
  33. void set_file_type(ArchiveFile_t* file, FileInfo* file_info) {
  34. furi_assert(file);
  35. furi_assert(file_info);
  36. for(size_t i = 0; i < SIZEOF_ARRAY(known_ext); i++) {
  37. if(string_search_str(file->name, known_ext[i], 0) != STRING_FAILURE) {
  38. file->type = i;
  39. return;
  40. }
  41. }
  42. if(file_info->flags & FSF_DIRECTORY) {
  43. file->type = ArchiveFileTypeFolder;
  44. } else {
  45. file->type = ArchiveFileTypeUnknown;
  46. }
  47. }
  48. bool archive_get_filenames(void* context, const char* path) {
  49. furi_assert(context);
  50. bool res;
  51. ArchiveBrowserView* browser = context;
  52. archive_file_array_rm_all(browser);
  53. if(archive_get_tab(browser) != ArchiveTabFavorites) {
  54. res = archive_read_dir(browser, path);
  55. } else {
  56. res = archive_favorites_read(browser);
  57. }
  58. return res;
  59. }
  60. bool archive_dir_empty(void* context, const char* path) { // can be simpler?
  61. furi_assert(context);
  62. FileInfo file_info;
  63. Storage* fs_api = furi_record_open("storage");
  64. File* directory = storage_file_alloc(fs_api);
  65. char name[MAX_NAME_LEN];
  66. if(!storage_dir_open(directory, path)) {
  67. storage_dir_close(directory);
  68. storage_file_free(directory);
  69. return false;
  70. }
  71. bool files_found = false;
  72. while(1) {
  73. if(!storage_dir_read(directory, &file_info, name, MAX_NAME_LEN)) {
  74. break;
  75. }
  76. if(files_found) {
  77. break;
  78. } else if(storage_file_get_error(directory) == FSE_OK) {
  79. files_found = name[0];
  80. } else {
  81. return false;
  82. }
  83. }
  84. storage_dir_close(directory);
  85. storage_file_free(directory);
  86. furi_record_close("storage");
  87. return files_found;
  88. }
  89. bool archive_read_dir(void* context, const char* path) {
  90. furi_assert(context);
  91. ArchiveBrowserView* browser = context;
  92. FileInfo file_info;
  93. Storage* fs_api = furi_record_open("storage");
  94. File* directory = storage_file_alloc(fs_api);
  95. char name[MAX_NAME_LEN];
  96. size_t files_cnt = 0;
  97. if(!storage_dir_open(directory, path)) {
  98. storage_dir_close(directory);
  99. storage_file_free(directory);
  100. return false;
  101. }
  102. while(1) {
  103. if(!storage_dir_read(directory, &file_info, name, MAX_NAME_LEN)) {
  104. break;
  105. }
  106. if(files_cnt > MAX_FILES) {
  107. break;
  108. } else if(storage_file_get_error(directory) == FSE_OK) {
  109. archive_add_item(browser, &file_info, name);
  110. ++files_cnt;
  111. } else {
  112. storage_dir_close(directory);
  113. storage_file_free(directory);
  114. return false;
  115. }
  116. }
  117. storage_dir_close(directory);
  118. storage_file_free(directory);
  119. furi_record_close("storage");
  120. return true;
  121. }
  122. void archive_file_append(const char* path, const char* format, ...) {
  123. furi_assert(path);
  124. string_t string;
  125. va_list args;
  126. va_start(args, format);
  127. string_init_vprintf(string, format, args);
  128. va_end(args);
  129. FileWorker* file_worker = file_worker_alloc(false);
  130. if(!file_worker_open(file_worker, path, FSAM_WRITE, FSOM_OPEN_APPEND)) {
  131. FURI_LOG_E(TAG, "Append open error");
  132. }
  133. if(!file_worker_write(file_worker, string_get_cstr(string), string_size(string))) {
  134. FURI_LOG_E(TAG, "Append write error");
  135. }
  136. file_worker_close(file_worker);
  137. file_worker_free(file_worker);
  138. }
  139. void archive_delete_file(void* context, const char* format, ...) {
  140. furi_assert(context);
  141. string_t filename;
  142. va_list args;
  143. va_start(args, format);
  144. string_init_vprintf(filename, format, args);
  145. va_end(args);
  146. ArchiveBrowserView* browser = context;
  147. FileWorker* file_worker = file_worker_alloc(true);
  148. bool res = file_worker_remove(file_worker, string_get_cstr(filename));
  149. file_worker_free(file_worker);
  150. if(archive_is_favorite("%s", string_get_cstr(filename))) {
  151. archive_favorites_delete("%s", string_get_cstr(filename));
  152. }
  153. if(res) {
  154. archive_file_array_rm_selected(browser);
  155. }
  156. string_clear(filename);
  157. }