Compare commits
5 commits
8fac614905
...
854c5633ea
Author | SHA1 | Date | |
---|---|---|---|
854c5633ea | |||
e46f6eb887 | |||
3497c1c9b2 | |||
a9ef4d2aef | |||
3f5d790d3c |
4 changed files with 59 additions and 62 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -148,7 +148,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pbdbfixer"
|
name = "pbdbfixer"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"xml-rs",
|
"xml-rs",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "pbdbfixer"
|
name = "pbdbfixer"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
authors = ["Martin Brodbeck <martin@brodbeck-online.de>"]
|
authors = ["Martin Brodbeck <martin@brodbeck-online.de>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|
|
@ -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 hat to edit `~/.cargo/config`:
|
invoke. In my case, I had to edit `~/.cargo/config`:
|
||||||
```
|
```
|
||||||
[target.arm-unknown-linux-gnueabi]
|
[target.arm-unknown-linux-gnueabi]
|
||||||
linker = "arm-linux-gnueabi-gcc"
|
linker = "arm-linux-gnueabi-gcc"
|
||||||
|
|
57
src/main.rs
57
src/main.rs
|
@ -1,6 +1,6 @@
|
||||||
mod pocketbook;
|
mod pocketbook;
|
||||||
|
|
||||||
use rusqlite::{named_params, Connection, Result, NO_PARAMS};
|
use rusqlite::{named_params, Connection, Result, Transaction, 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,7 +60,6 @@ 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" {
|
||||||
|
@ -112,49 +111,39 @@ struct BookEntry {
|
||||||
filepath: String,
|
filepath: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn fix_firstauthor(tx: &Transaction) -> i32 {
|
||||||
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 '%&%')").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("SELECT id FROM books_impl WHERE ext LIKE 'epub' AND author LIKE '%\\, %' ESCAPE '\\' AND firstauthor NOT LIKE '%&%'").unwrap();
|
let mut stmt = tx.prepare(r"
|
||||||
|
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 '%&%'))
|
||||||
|
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 prefix: String = row.get(0).unwrap();
|
let book_id: i32 = row.get(0).unwrap();
|
||||||
let filename: String = row.get(1).unwrap();
|
let prefix: 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());
|
||||||
|
@ -179,7 +168,15 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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") {
|
||||||
|
|
Loading…
Reference in a new issue