Compare commits

..

No commits in common. "854c5633ea9e332c77a6496dc9d4471b8dc0526e" and "8fac614905a141ed0602bb4ec286e2a4fd705ef8" have entirely different histories.

4 changed files with 62 additions and 59 deletions

2
Cargo.lock generated
View file

@ -148,7 +148,7 @@ dependencies = [
[[package]] [[package]]
name = "pbdbfixer" name = "pbdbfixer"
version = "0.2.0" version = "0.1.0"
dependencies = [ dependencies = [
"rusqlite", "rusqlite",
"xml-rs", "xml-rs",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "pbdbfixer" name = "pbdbfixer"
version = "0.2.0" version = "0.1.0"
authors = ["Martin Brodbeck <martin@brodbeck-online.de>"] authors = ["Martin Brodbeck <martin@brodbeck-online.de>"]
edition = "2018" edition = "2018"

View file

@ -21,7 +21,7 @@ applications screen and tap on the PbDbFixer icon.
To be able to build PbDbFixer, you have to have the cross compiler for To be able to build PbDbFixer, you have to have the cross compiler for
ARM CPUs installed. On Arch Linux, the AUR package `arm-linux-gnueabi-gcc75-linaro-bin` ARM CPUs installed. On Arch Linux, the AUR package `arm-linux-gnueabi-gcc75-linaro-bin`
does the job. Don't forget to tell `cargo` which compiler/linker it has to does the job. Don't forget to tell `cargo` which compiler/linker it has to
invoke. In my case, I had to edit `~/.cargo/config`: invoke. In my case, I hat to edit `~/.cargo/config`:
``` ```
[target.arm-unknown-linux-gnueabi] [target.arm-unknown-linux-gnueabi]
linker = "arm-linux-gnueabi-gcc" linker = "arm-linux-gnueabi-gcc"

View file

@ -1,6 +1,6 @@
mod pocketbook; mod pocketbook;
use rusqlite::{named_params, Connection, Result, Transaction, NO_PARAMS}; use rusqlite::{named_params, Connection, Result, NO_PARAMS};
use std::error::Error; use std::error::Error;
use std::fs::File; use std::fs::File;
use std::io::BufReader; use std::io::BufReader;
@ -60,6 +60,7 @@ fn get_attribute_file_as(opf: ZipFile) -> Option<String> {
}) if name.local_name == "creator" => { }) if name.local_name == "creator" => {
for attr in attributes { for attr in attributes {
if attr.name.local_name == "file-as" { if attr.name.local_name == "file-as" {
println!("File-as: {}", &attr.value);
return Some(attr.value); return Some(attr.value);
} }
if is_epub3 && attr.name.local_name == "id" { if is_epub3 && attr.name.local_name == "id" {
@ -111,39 +112,49 @@ struct BookEntry {
filepath: String, filepath: String,
} }
fn fix_firstauthor(tx: &Transaction) -> i32 { fn main() {
let mut authors_fixed = 0; let mut authors_fixed = 0;
let mut conn = Connection::open("/mnt/ext1/system/explorer-3/explorer-3.db").unwrap();
let tx = conn.transaction().unwrap();
{
// Get book ids from entries where we have something like "firstname lastname" in author // Get book ids from entries where we have something like "firstname lastname" in author
// but no "lastname, firstname" in fistauthor // but no "lastname, firstname" in fistauthor
let mut stmt = tx.prepare("SELECT id FROM books_impl WHERE ext LIKE 'epub' AND author LIKE '% %' AND (firstauthor NOT LIKE '%\\,%' ESCAPE '\\' OR firstauthor LIKE '%&amp;%')").unwrap();
let mut rows = stmt.query(NO_PARAMS).unwrap();
let mut book_ids: Vec<i32> = Vec::new();
while let Some(row) = rows.next().unwrap() {
book_ids.push(row.get(0).unwrap());
}
// Get also book ids from the special case where we have multiple authors (separated by ", " in authors) // Get also book ids from the special case where we have multiple authors (separated by ", " in authors)
// but no ampersand ("&") in firstauthor // but no ampersand ("&") in firstauthor
let mut stmt = tx.prepare(r" let mut stmt = tx.prepare("SELECT id FROM books_impl WHERE ext LIKE 'epub' AND author LIKE '%\\, %' ESCAPE '\\' AND firstauthor NOT LIKE '%&%'").unwrap();
SELECT files.book_id, folders.name, files.filename
FROM files INNER JOIN folders
ON files.folder_id = folders.id
WHERE files.book_id IN
(
SELECT DISTINCT id FROM books_impl
WHERE (ext LIKE 'epub' AND author LIKE '% %' AND (firstauthor NOT LIKE '%\,%' ESCAPE '\' OR firstauthor LIKE '%&amp;%'))
OR (ext LIKE 'epub' AND author LIKE '%\, %' ESCAPE '\' AND firstauthor NOT LIKE '%&%')
)
AND files.storageid = 1
;").unwrap();
let mut rows = stmt.query(NO_PARAMS).unwrap(); let mut rows = stmt.query(NO_PARAMS).unwrap();
while let Some(row) = rows.next().unwrap() {
book_ids.push(row.get(0).unwrap());
}
book_ids.sort();
book_ids.dedup();
let mut bookentries = Vec::new(); let mut bookentries = Vec::new();
for book_id in book_ids {
let mut stmt = tx.prepare("SELECT folders.name,files.filename FROM files,folders WHERE files.book_id = :book_id AND files.storageid = 1 AND files.folder_id = folders.id").unwrap();
let mut rows = stmt
.query_named(named_params! { ":book_id": book_id })
.unwrap();
while let Some(row) = rows.next().unwrap() { while let Some(row) = rows.next().unwrap() {
let book_id: i32 = row.get(0).unwrap(); let prefix: String = row.get(0).unwrap();
let prefix: String = row.get(1).unwrap(); let filename: String = row.get(1).unwrap();
let filename: String = row.get(2).unwrap();
let filepath = format!("{}/{}", prefix, filename); let filepath = format!("{}/{}", prefix, filename);
bookentries.push(BookEntry { bookentries.push(BookEntry {
id: book_id, id: book_id,
filepath, filepath: filepath,
}); });
} }
}
for entry in bookentries { for entry in bookentries {
let file = File::open(entry.filepath.as_str()); let file = File::open(entry.filepath.as_str());
@ -168,15 +179,7 @@ fn fix_firstauthor(tx: &Transaction) -> i32 {
} }
} }
} }
authors_fixed
} }
fn main() {
let mut conn = Connection::open("/mnt/ext1/system/explorer-3/explorer-3.db").unwrap();
let tx = conn.transaction().unwrap();
let authors_fixed = fix_firstauthor(&tx);
tx.commit().unwrap(); tx.commit().unwrap();
if cfg!(target_arch = "arm") { if cfg!(target_arch = "arm") {