*write_book_tags_report: переписан ли файл на месте и почему нет (запасная замена новым файлом больше не молчит)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a6b4f0fbcf
commit
b037345b7b
1 file changed
+25
-5
+25
-5
@@ -60,6 +60,14 @@ pub:
|
|||||||
remove_cover bool
|
remove_cover bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Как прошла запись: на месте (тот же файл) или новым файлом поверх старого
|
||||||
|
pub struct WriteReport {
|
||||||
|
pub:
|
||||||
|
in_place bool
|
||||||
|
// Почему не удалось переписать на месте (пусто, если на месте)
|
||||||
|
fallback string
|
||||||
|
}
|
||||||
|
|
||||||
struct ParsedTag {
|
struct ParsedTag {
|
||||||
mut:
|
mut:
|
||||||
version u8
|
version u8
|
||||||
@@ -562,7 +570,7 @@ fn build_tag(parsed ParsedTag, t BookTags, opts WriteOptions) []u8 {
|
|||||||
// затем копируются обратно в исходный. Файл остаётся тем же (inode, владелец, права):
|
// затем копируются обратно в исходный. Файл остаётся тем же (inode, владелец, права):
|
||||||
// Audiobookshelf опознаёт файлы по inode, и замена файла новым путает его библиотеку.
|
// Audiobookshelf опознаёт файлы по inode, и замена файла новым путает его библиотеку.
|
||||||
// Файл без ID3v2 тоже поддерживается — тэг просто ставится в начало
|
// Файл без ID3v2 тоже поддерживается — тэг просто ставится в начало
|
||||||
fn write_book_tags_impl(path string, t BookTags, opts WriteOptions) ! {
|
fn write_book_tags_impl(path string, t BookTags, opts WriteOptions) !WriteReport {
|
||||||
parsed := parse_id3v2(path)!
|
parsed := parse_id3v2(path)!
|
||||||
tag := build_tag(parsed, t, opts)
|
tag := build_tag(parsed, t, opts)
|
||||||
|
|
||||||
@@ -595,6 +603,7 @@ fn write_book_tags_impl(path string, t BookTags, opts WriteOptions) ! {
|
|||||||
}
|
}
|
||||||
copy_back(tmp_path, path, mut buf) or {
|
copy_back(tmp_path, path, mut buf) or {
|
||||||
// Исходный файл мог остаться наполовину переписанным — полная копия во временном
|
// Исходный файл мог остаться наполовину переписанным — полная копия во временном
|
||||||
|
reason := err.msg()
|
||||||
orig := os.stat(path) or { os.Stat{} }
|
orig := os.stat(path) or { os.Stat{} }
|
||||||
os.mv(tmp_path, path, overwrite: true) or {
|
os.mv(tmp_path, path, overwrite: true) or {
|
||||||
return error('${err}; новое содержимое сохранено в ${tmp_path}')
|
return error('${err}; новое содержимое сохранено в ${tmp_path}')
|
||||||
@@ -605,9 +614,14 @@ fn write_book_tags_impl(path string, t BookTags, opts WriteOptions) ! {
|
|||||||
os.chown(path, int(orig.uid), int(orig.gid)) or {}
|
os.chown(path, int(orig.uid), int(orig.gid)) or {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return WriteReport{
|
||||||
|
fallback: reason
|
||||||
|
}
|
||||||
}
|
}
|
||||||
os.rm(tmp_path) or {}
|
os.rm(tmp_path) or {}
|
||||||
|
return WriteReport{
|
||||||
|
in_place: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Содержимое from — в существующий файл to (с обрезкой), не заменяя сам файл
|
// Содержимое from — в существующий файл to (с обрезкой), не заменяя сам файл
|
||||||
@@ -664,8 +678,13 @@ pub fn read_cover(path string) !Cover {
|
|||||||
|
|
||||||
// Запись тэгов книги в файл
|
// Запись тэгов книги в файл
|
||||||
pub fn write_book_tags(path string, t BookTags, opts WriteOptions) ! {
|
pub fn write_book_tags(path string, t BookTags, opts WriteOptions) ! {
|
||||||
|
write_book_tags_report(path, t, opts)!
|
||||||
|
}
|
||||||
|
|
||||||
|
// То же, что write_book_tags, плюс отчёт: переписан ли файл на месте
|
||||||
|
pub fn write_book_tags_report(path string, t BookTags, opts WriteOptions) !WriteReport {
|
||||||
mut box := PanicBox{}
|
mut box := PanicBox{}
|
||||||
guard_write_tags(path, t, opts, mut box) or {
|
report := guard_write_tags(path, t, opts, mut box) or {
|
||||||
return if box.msg != '' {
|
return if box.msg != '' {
|
||||||
box.error()
|
box.error()
|
||||||
} else {
|
} else {
|
||||||
@@ -675,6 +694,7 @@ pub fn write_book_tags(path string, t BookTags, opts WriteOptions) ! {
|
|||||||
if box.msg != '' {
|
if box.msg != '' {
|
||||||
return box.error()
|
return box.error()
|
||||||
}
|
}
|
||||||
|
return report
|
||||||
}
|
}
|
||||||
|
|
||||||
fn guard_read_tags(path string, mut box PanicBox) !FileTags {
|
fn guard_read_tags(path string, mut box PanicBox) !FileTags {
|
||||||
@@ -695,11 +715,11 @@ fn guard_read_cover(path string, mut box PanicBox) !Cover {
|
|||||||
return read_cover_impl(path)!
|
return read_cover_impl(path)!
|
||||||
}
|
}
|
||||||
|
|
||||||
fn guard_write_tags(path string, t BookTags, opts WriteOptions, mut box PanicBox) ! {
|
fn guard_write_tags(path string, t BookTags, opts WriteOptions, mut box PanicBox) !WriteReport {
|
||||||
defer {
|
defer {
|
||||||
if msg := recover() {
|
if msg := recover() {
|
||||||
box.msg = msg
|
box.msg = msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write_book_tags_impl(path, t, opts)!
|
return write_book_tags_impl(path, t, opts)!
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user