mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
On OFW "rename" acts like "move", it replaces the destination XFW had an extra "move" like that, and "rename" errored if dest exists Now for compatibility "rename" acts as OFW, and new "rename_safe" errors Tweaked all usages to work properly Decided for CLI and RPC to use "rename_safe" so user cant lose files
320 lines
9.1 KiB
C
320 lines
9.1 KiB
C
|
|
#include "archive_favorites.h"
|
|
#include "archive_files.h"
|
|
#include "archive_apps.h"
|
|
#include "archive_browser.h"
|
|
|
|
#define ARCHIVE_FAV_FILE_BUF_LEN 32
|
|
|
|
static bool archive_favorites_read_line(File* file, FuriString* str_result) {
|
|
furi_string_reset(str_result);
|
|
uint8_t buffer[ARCHIVE_FAV_FILE_BUF_LEN];
|
|
bool result = false;
|
|
|
|
do {
|
|
size_t read_count = storage_file_read(file, buffer, ARCHIVE_FAV_FILE_BUF_LEN);
|
|
if(storage_file_get_error(file) != FSE_OK) {
|
|
return false;
|
|
}
|
|
|
|
for(size_t i = 0; i < read_count; i++) {
|
|
if(buffer[i] == '\n') {
|
|
uint32_t position = storage_file_tell(file);
|
|
if(storage_file_get_error(file) != FSE_OK) {
|
|
return false;
|
|
}
|
|
|
|
position = position - read_count + i + 1;
|
|
|
|
storage_file_seek(file, position, true);
|
|
if(storage_file_get_error(file) != FSE_OK) {
|
|
return false;
|
|
}
|
|
|
|
result = true;
|
|
break;
|
|
} else {
|
|
furi_string_push_back(str_result, buffer[i]);
|
|
}
|
|
}
|
|
|
|
if(result || read_count == 0) {
|
|
break;
|
|
}
|
|
} while(true);
|
|
|
|
return result;
|
|
}
|
|
|
|
uint16_t archive_favorites_count() {
|
|
Storage* fs_api = furi_record_open(RECORD_STORAGE);
|
|
File* file = storage_file_alloc(fs_api);
|
|
|
|
FuriString* buffer;
|
|
buffer = furi_string_alloc();
|
|
|
|
bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
|
|
uint16_t lines = 0;
|
|
|
|
if(result) {
|
|
while(archive_favorites_read_line(file, buffer)) {
|
|
if(!furi_string_size(buffer)) {
|
|
continue; // Skip empty lines
|
|
}
|
|
++lines;
|
|
}
|
|
}
|
|
|
|
storage_file_close(file);
|
|
|
|
furi_string_free(buffer);
|
|
storage_file_free(file);
|
|
furi_record_close(RECORD_STORAGE);
|
|
|
|
return lines;
|
|
}
|
|
|
|
static bool archive_favourites_rescan() {
|
|
FuriString* buffer;
|
|
buffer = furi_string_alloc();
|
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
File* file = storage_file_alloc(storage);
|
|
|
|
bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
|
|
if(result) {
|
|
while(archive_favorites_read_line(file, buffer)) {
|
|
if(!furi_string_size(buffer)) {
|
|
continue;
|
|
}
|
|
|
|
if(furi_string_search(buffer, "/app:") == 0) {
|
|
if(archive_app_is_available(NULL, furi_string_get_cstr(buffer))) {
|
|
archive_file_append(
|
|
ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer));
|
|
}
|
|
} else {
|
|
if(storage_file_exists(storage, furi_string_get_cstr(buffer))) {
|
|
archive_file_append(
|
|
ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
furi_string_free(buffer);
|
|
|
|
storage_file_close(file);
|
|
storage_common_remove(storage, ARCHIVE_FAV_PATH);
|
|
storage_common_rename(storage, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH);
|
|
storage_common_remove(storage, ARCHIVE_FAV_TEMP_PATH);
|
|
|
|
storage_file_free(file);
|
|
furi_record_close(RECORD_STORAGE);
|
|
|
|
return result;
|
|
}
|
|
|
|
bool archive_favorites_read(void* context) {
|
|
furi_assert(context);
|
|
|
|
ArchiveBrowserView* browser = context;
|
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
File* file = storage_file_alloc(storage);
|
|
|
|
FuriString* buffer;
|
|
FileInfo file_info;
|
|
buffer = furi_string_alloc();
|
|
|
|
bool need_refresh = false;
|
|
uint16_t file_count = 0;
|
|
|
|
archive_file_array_rm_all(browser);
|
|
|
|
bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
|
|
|
|
if(result) {
|
|
while(archive_favorites_read_line(file, buffer)) {
|
|
if(!furi_string_size(buffer)) {
|
|
continue;
|
|
}
|
|
|
|
if(furi_string_search(buffer, "/app:") == 0) {
|
|
if(archive_app_is_available(browser, furi_string_get_cstr(buffer))) {
|
|
archive_add_app_item(browser, furi_string_get_cstr(buffer));
|
|
file_count++;
|
|
} else {
|
|
need_refresh = true;
|
|
}
|
|
} else {
|
|
if(storage_common_exists(storage, furi_string_get_cstr(buffer))) {
|
|
storage_common_stat(storage, furi_string_get_cstr(buffer), &file_info);
|
|
archive_add_file_item(
|
|
browser, file_info_is_dir(&file_info), furi_string_get_cstr(buffer));
|
|
file_count++;
|
|
} else {
|
|
need_refresh = true;
|
|
}
|
|
}
|
|
|
|
furi_string_reset(buffer);
|
|
}
|
|
}
|
|
storage_file_close(file);
|
|
furi_string_free(buffer);
|
|
storage_file_free(file);
|
|
furi_record_close(RECORD_STORAGE);
|
|
|
|
archive_set_item_count(browser, file_count);
|
|
|
|
if(need_refresh) { //-V547
|
|
archive_favourites_rescan();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool archive_favorites_delete(const char* format, ...) {
|
|
FuriString* buffer;
|
|
FuriString* filename;
|
|
va_list args;
|
|
va_start(args, format);
|
|
filename = furi_string_alloc_vprintf(format, args);
|
|
va_end(args);
|
|
|
|
buffer = furi_string_alloc();
|
|
Storage* fs_api = furi_record_open(RECORD_STORAGE);
|
|
File* file = storage_file_alloc(fs_api);
|
|
|
|
bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
|
|
|
|
if(result) {
|
|
while(archive_favorites_read_line(file, buffer)) {
|
|
if(!furi_string_size(buffer)) {
|
|
continue;
|
|
}
|
|
|
|
if(furi_string_search(buffer, filename)) {
|
|
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer));
|
|
}
|
|
}
|
|
}
|
|
|
|
furi_string_free(buffer);
|
|
furi_string_free(filename);
|
|
|
|
storage_file_close(file);
|
|
storage_common_remove(fs_api, ARCHIVE_FAV_PATH);
|
|
storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH);
|
|
storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH);
|
|
|
|
storage_file_free(file);
|
|
furi_record_close(RECORD_STORAGE);
|
|
|
|
return result;
|
|
}
|
|
|
|
bool archive_is_favorite(const char* format, ...) {
|
|
FuriString* buffer;
|
|
FuriString* filename;
|
|
va_list args;
|
|
va_start(args, format);
|
|
filename = furi_string_alloc_vprintf(format, args);
|
|
va_end(args);
|
|
|
|
buffer = furi_string_alloc();
|
|
Storage* fs_api = furi_record_open(RECORD_STORAGE);
|
|
File* file = storage_file_alloc(fs_api);
|
|
|
|
bool found = false;
|
|
bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
|
|
|
|
if(result) {
|
|
while(archive_favorites_read_line(file, buffer)) {
|
|
if(!furi_string_size(buffer)) {
|
|
continue;
|
|
}
|
|
if(!furi_string_search(buffer, filename)) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
storage_file_close(file);
|
|
furi_string_free(buffer);
|
|
furi_string_free(filename);
|
|
storage_file_free(file);
|
|
furi_record_close(RECORD_STORAGE);
|
|
|
|
return found;
|
|
}
|
|
|
|
bool archive_favorites_rename(const char* src, const char* dst) {
|
|
furi_assert(src);
|
|
furi_assert(dst);
|
|
|
|
Storage* fs_api = furi_record_open(RECORD_STORAGE);
|
|
File* file = storage_file_alloc(fs_api);
|
|
|
|
FuriString* path;
|
|
FuriString* buffer;
|
|
|
|
buffer = furi_string_alloc();
|
|
path = furi_string_alloc();
|
|
|
|
furi_string_printf(path, "%s", src);
|
|
bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
|
|
|
|
if(result) {
|
|
while(archive_favorites_read_line(file, buffer)) {
|
|
if(!furi_string_size(buffer)) {
|
|
continue;
|
|
}
|
|
|
|
archive_file_append(
|
|
ARCHIVE_FAV_TEMP_PATH,
|
|
"%s\n",
|
|
furi_string_search(buffer, path) ? furi_string_get_cstr(buffer) : dst);
|
|
}
|
|
}
|
|
|
|
furi_string_free(buffer);
|
|
furi_string_free(path);
|
|
|
|
storage_file_close(file);
|
|
storage_common_remove(fs_api, ARCHIVE_FAV_PATH);
|
|
storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH);
|
|
storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH);
|
|
|
|
storage_file_free(file);
|
|
furi_record_close(RECORD_STORAGE);
|
|
|
|
return result;
|
|
}
|
|
|
|
void archive_add_to_favorites(const char* file_path) {
|
|
furi_assert(file_path);
|
|
|
|
archive_file_append(ARCHIVE_FAV_PATH, "%s\n", file_path);
|
|
}
|
|
|
|
void archive_favorites_save(void* context) {
|
|
furi_assert(context);
|
|
|
|
ArchiveBrowserView* browser = context;
|
|
Storage* fs_api = furi_record_open(RECORD_STORAGE);
|
|
File* file = storage_file_alloc(fs_api);
|
|
|
|
for(size_t i = 0; i < archive_file_get_array_size(browser); i++) {
|
|
ArchiveFile_t* item = archive_get_file_at(browser, i);
|
|
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(item->path));
|
|
}
|
|
|
|
storage_common_remove(fs_api, ARCHIVE_FAV_PATH);
|
|
storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH);
|
|
storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH);
|
|
|
|
storage_file_free(file);
|
|
furi_record_close(RECORD_STORAGE);
|
|
}
|