Giter Site home page Giter Site logo

every-day-things / citadel Goto Github PK

View Code? Open in Web Editor NEW
684.0 7.0 7.0 9.95 MB

Manage your ebook library without frustrations. Calibre compatible.

License: MIT License

Rust 54.68% HTML 0.13% TypeScript 12.33% Svelte 23.37% CSS 5.06% JavaScript 1.22% Shell 2.66% Dockerfile 0.55%
calibre ebook ebook-collection ebook-manager epub

citadel's People

Contributors

phildenhoff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

citadel's Issues

libcalibre: CRUD for external IDs

Add CRUD operations for external IDs attached to books. These are not entities, they are value objects.

  • Add new external ID (ISBN, Amazon ID, Google ID, MOBI ASIN, etc.)
  • Remove external ID
  • When adding a new book, support including external IDs and add them.

libcalibre: Custom Column support

Add support for reading from arbitrary custom columns.

  • What does Calibre do to store these values? (Tables)
  • How does Calibre know which columns exist, what type a column is?
  • Provide way for clients to read this info (either within the Book itself or as another service)

Reproducible builds

The compile-time location of the build is embedded into the binary.

In my case, I am building citadel in the folder /tmp/makepkg/citadel-git.

This particular path is embedded in the final binary, as seen here with src-tauri/libcalibre/src/application/services/library/service.rs:

image

This seems to be the only occurrence.

If you need more context:

0xa0f0dc: 0x4e 0x6f 0x74 0x46 0x6f 0x75 0x6e 0x64 0x42 0x6f NotFoundBo
0xa0f0e6: 0x6f 0x6b 0x46 0x69 0x6c 0x65 0x73 0x4e 0x6f 0x74 okFilesNot
0xa0f0f0: 0x46 0x6f 0x75 0x6e 0x64 0x42 0x6f 0x6f 0x6b 0x4e FoundBookN
0xa0f0fa: 0x6f 0x74 0x46 0x6f 0x75 0x6e 0x64 0x41 0x75 0x74 otFoundAut
0xa0f104: 0x68 0x6f 0x72 0x63 0x61 0x6c 0x6c 0x65 0x64 0x20 horcalled
0xa0f10e: 0x60 0x4f 0x70 0x74 0x69 0x6f 0x6e 0x3a 0x3a 0x75 `Option::u
0xa0f118: 0x6e 0x77 0x72 0x61 0x70 0x28 0x29 0x60 0x20 0x6f nwrap()` o
0xa0f122: 0x6e 0x20 0x61 0x20 0x60 0x4e 0x6f 0x6e 0x65 0x60 n a `None`
0xa0f12c: 0x20 0x76 0x61 0x6c 0x75 0x65 0x2f 0x62 0x75 0x69  value/bui
0xa0f136: 0x6c 0x64 0x2f 0x72 0x75 0x73 0x74 0x2f 0x73 0x72 ld/rust/sr
0xa0f140: 0x63 0x2f 0x72 0x75 0x73 0x74 0x63 0x2d 0x31 0x2e c/rustc-1.
0xa0f14a: 0x37 0x35 0x2e 0x30 0x2d 0x73 0x72 0x63 0x2f 0x6c 75.0-src/l
0xa0f154: 0x69 0x62 0x72 0x61 0x72 0x79 0x2f 0x61 0x6c 0x6c ibrary/all
0xa0f15e: 0x6f 0x63 0x2f 0x73 0x72 0x63 0x2f 0x63 0x6f 0x6c oc/src/col
0xa0f168: 0x6c 0x65 0x63 0x74 0x69 0x6f 0x6e 0x73 0x2f 0x62 lections/b
0xa0f172: 0x74 0x72 0x65 0x65 0x2f 0x6e 0x61 0x76 0x69 0x67 tree/navig
0xa0f17c: 0x61 0x74 0x65 0x2e 0x72 0x73 0x2f 0x74 0x6d 0x70 ate.rs/tmp
0xa0f186: 0x2f 0x6d 0x61 0x6b 0x65 0x70 0x6b 0x67 0x2f 0x63 /makepkg/c
0xa0f190: 0x69 0x74 0x61 0x64 0x65 0x6c 0x2d 0x67 0x69 0x74 itadel-git
0xa0f19a: 0x2f 0x73 0x72 0x63 0x2f 0x63 0x69 0x74 0x61 0x64 /src/citad
0xa0f1a4: 0x65 0x6c 0x2f 0x73 0x72 0x63 0x2d 0x74 0x61 0x75 el/src-tau
0xa0f1ae: 0x72 0x69 0x2f 0x6c 0x69 0x62 0x63 0x61 0x6c 0x69 ri/libcali
0xa0f1b8: 0x62 0x72 0x65 0x2f 0x73 0x72 0x63 0x2f 0x61 0x70 bre/src/ap
0xa0f1c2: 0x70 0x6c 0x69 0x63 0x61 0x74 0x69 0x6f 0x6e 0x2f plication/
0xa0f1cc: 0x73 0x65 0x72 0x76 0x69 0x63 0x65 0x73 0x2f 0x6c services/l
0xa0f1d6: 0x69 0x62 0x72 0x61 0x72 0x79 0x2f 0x73 0x65 0x72 ibrary/ser
0xa0f1e0: 0x76 0x69 0x63 0x65 0x2e 0x72 0x73 0x3c 0x64 0x63 vice.rs<dc
0xa0f1ea: 0x3a 0x63 0x72 0x65 0x61 0x74 0x6f 0x72 0x20 0x6f :creator o
0xa0f1f4: 0x70 0x66 0x3a 0x66 0x69 0x6c 0x65 0x2d 0x61 0x73 pf:file-as
0xa0f1fe: 0x3d 0x22 0x22 0x20 0x6f 0x70 0x66 0x3a 0x72 0x6f ="" opf:ro
0xa0f208: 0x6c 0x65 0x3d 0x22 0x61 0x75 0x74 0x22 0x3e 0x3c le="aut"><
0xa0f212: 0x2f 0x64 0x63 0x3a 0x63 0x72 0x65 0x61 0x74 0x6f /dc:creato
0xa0f21c: 0x72 0x3e 0x3c 0x3f 0x78 0x6d 0x6c 0x20 0x76 0x65 r><?xml ve
0xa0f226: 0x72 0x73 0x69 0x6f 0x6e 0x3d 0x27 0x31 0x2e 0x30 rsion='1.0
0xa0f230: 0x27 0x20 0x65 0x6e 0x63 0x6f 0x64 0x69 0x6e 0x67 ' encoding
0xa0f23a: 0x3d 0x27 0x75 0x74 0x66 0x2d 0x38 0x27 0x3f 0x3e ='utf-8'?>
0xa0f244: 0x0a 0x20 0x20 0x20 0x20 0x3c 0x70 0x61 0x63 0x6b .    <pack
0xa0f24e: 0x61 0x67 0x65 0x20 0x78 0x6d 0x6c 0x6e 0x73 0x3d age xmlns=
0xa0f258: 0x22 0x68 0x74 0x74 0x70 0x3a 0x2f 0x2f 0x77 0x77 "http://ww
0xa0f262: 0x77 0x2e 0x69 0x64 0x70 0x66 0x2e 0x6f 0x72 0x67 w.idpf.org
0xa0f26c: 0x2f 0x32 0x30 0x30 0x37 0x2f 0x6f 0x70 0x66 0x22 /2007/opf"
0xa0f276: 0x20 0x75 0x6e 0x69 0x71 0x75 0x65 0x2d 0x69 0x64  unique-id
0xa0f280: 0x65 0x6e 0x74 0x69 0x66 0x69 0x65 0x72 0x3d 0x22 entifier="
0xa0f28a: 0x75 0x75 0x69 0x64 0x5f 0x69 0x64 0x22 0x20 0x76 uuid_id" v
0xa0f294: 0x65 0x72 0x73 0x69 0x6f 0x6e 0x3d 0x22 0x32 0x2e ersion="2.
0xa0f29e: 0x30 0x22 0x3e 0x0a 0x20 0x20 0x20 0x20 0x20 0x20 0">.
0xa0f2a8: 0x3c 0x6d 0x65 0x74 0x61 0x64 0x61 0x74 0x61 0x20 <metadata

CI: Build `main` on push, run tests. Maybe static code analysis

To make it easier to try Citadel, and ensure that new changes don't prevent the app from working for long, add a CI pipeline using GitHub Actions to build main anytime it's updated, and run any tests.

The build should be a matrix supporting

  • Ubuntu/Debian builds
  • macOS

In the future, if there is appeal, we can add Windows builds + non-appimage/.deb builds.

Stretch goal

Add a CI pipeline that, on PR open or updated, runs static checks like linting & formatting checks (ensure code is correctly formatted). I haven't run these in a while, so there are likely to be some errors. The first step is to open a PR that resolves any lint/format issues without adding CI.

Further reading

libcalibre: CRUD for Book tags

Add CRUD operations for book tags.

  • Add new tag to a book
  • Remove a tag from a book
  • Update existing tag content
  • When creating a new book, support linking tags (incl. creating new ones)
  • When retrieving a book, include the tags

Update books with metadata from online sources

You said on hacknews that "When I add books, I need to grab metadata for the book like title, ISBN, etc." It would thus be nice if citadel could do precisely this, since it's also my main usecase for Calibre: adding books to it, and having it figure out fancy rich metadata :)

libcalibre: rewrite with simplified DDD

I'd like to use a subset of DDD's language in libcalibre that should make it easier to extend & maintain. With a better understanding of how libcalibre works (now that I've written (part of) it) comes the ability to write a better version.

  • repos: how to write to the database. Entities that also have a table get a repo. Other operations are in the aggregates repo? I guess? Includes ways to store Book Files.
  • dtos: requests to create new / update existing entities and aggregates.
  • services: specifically for Book, Author, LibraryFile (any file within the lib. root)

Stretch goals

  • Remove Arc (Rc is a better choice, but not ref. counting is even better)
  • Remove Mutex
  • Make setup easier in citadel-rs – creating (and destroying) 3-4 repos & 3-4 services is wild and mostly annoying. It 100% doesn't not need to do that, it can store the services.
  • Remove mut self's for services. It seems unnecessary
  • Minimize .clone() calls
  • Prefer &str to String
  • Create struct/types for BookId & AuthorId with parse_from and to_i32 impls (book_${id} => id)
  • High perf versions of read functions, e.g. only return IDs or support windows/pagination
  • Filtering (search(phrase, fields: &str[]) or similar pattern)

Book

Book aggregate (? or "entity"?) allows for CRUD-ing ("managing")

  • title
  • authors associated to a Book (update_links which diffs, adds & removes)
  • which series this book belongs to (add if missing; replace otherwise)
  • series position
  • external identifiers
  • tags
  • publication date
  • language
  • publisher
  • HTML description
  • book cover image (replace by file @ path), and
  • different format files (e.g. .epub, .kepub, and .mobi).

as well as

find_by_id/1
find_by_author/1
list_all/0
create/1, which accepts a minimal DTO

Author

Author entity supports CRUD operations for

  • name
  • link
  • ...associated book? that seems like a mistake

citadel-rs: Calibre-specific behaviour is in `libcalibre`, otherwise generic

  • Sending files to a path/device → specific
  • Uploading file to get metadata → generic (any library, local & remote. Remote has wrapper to receive file upload first).
  • Confirming add processed file to library → specific, details in libcalibre. citadel-rs creates DTO, sends off.
  • Models & Schema → specific. Only in libcalibre.
  • Creating folder for author → specific
  • Updating library cache on path/external drive → specific
  • Formatting metadata files → specific

flatpak?

in #1, i saw some mention of appimage, has the idea of publishing this as a flatpak crossed your mind? right now it's what keeping me from trying the app, which otherwise looks pretty fantastic!

Error failed to bundle project: error running appimage.sh

warning: unused import: dto::UpdateBookDto
--> src/main.rs:7:43
|
7 | application::services::domain::book::{dto::UpdateBookDto, service::BookService},
| ^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_imports)] on by default

warning: unused import: format::StrftimeItems
--> src/book.rs:3:25
|
3 | use chrono::{NaiveDate, format::StrftimeItems};
| ^^^^^^^^^^^^^^^^^^^^^

warning: unused variable: book_list
--> src/main.rs:63:9
|
63 | let book_list = book_service.all();
| ^^^^^^^^^ help: if this is intentional, prefix it with an underscore: _book_list
|
= note: #[warn(unused_variables)] on by default

warning: citadel-rs (bin "citadel-rs") generated 3 warnings (run cargo fix --bin "citadel-rs" to apply 3 suggestions)
Finished release [optimized] target(s) in 1m 36s
Bundling citadel_0.1.0_amd64.deb (/home/demor/programs/citadel/src-tauri/target/release/bundle/deb/citadel_0.1.0_amd64.deb)
Bundling citadel_0.1.0_amd64.AppImage (/home/demor/programs/citadel/src-tauri/target/release/bundle/appimage/citadel_0.1.0_amd64.AppImage)
Error failed to bundle project: error running appimage.sh
error: script "build:app" exited with code 1
error: script "build" exited with code 1

Auto updates

Tauri supports autoupdates out-of-the-box. When is Citadel ready for auto updates? How early is too early?

My biggest concern with adding auto updates is that I don't want folks to be frustrated with Citadel's updates the same way that (some) are with Calibre's. Citadel is early software and it's going to be updated a lot.

Node (should not be) required for dev

Since we're using Bun, Node should not need to be installed, but tauri dev doesn't work without it. It doesn't seem like a Svelte issue — running bun dev:web without Node will start the Vite web server with no problems.

So something with tauri dev requires Node. I want to find it, and I want to fix it. Node should not be required for citadel.

Create Calibre-compat. library when none is detected

Re-written by @phildenhoff. Original issue desc. below.

When a user selects a folder for their library that is not a pre-existing Calibre library (e.g. no metadata.db file),

  • Confirm that is the correct location
  • If so, do they want to create a new library? Warn that that will add many folders & a database file at that location
  • If not, select a new folder.

If Citadel cannot operate without a Calibre library already in place, can it check for the Calibre database at the folder selection step?

Otherwise, adding a book to an empty folder crashes the app:

RUST_BACKTRACE=full /usr/bin/citadel

thread 'main' panicked at src/libs/calibre/mod.rs:187:17:
Could not find database at /home/jack/Citadel/
stack backtrace:
   0:     0x5639e2268c9c - std::backtrace_rs::backtrace::libunwind::trace::he0644f4189ae2429
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/../../backtrace/src/backtrace/libunwind.rs:104:5
   1:     0x5639e2268c9c - std::backtrace_rs::backtrace::trace_unsynchronized::h9d17fc782d3b981a
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x5639e2268c9c - std::sys_common::backtrace::_print_fmt::hb438557330fe04dd
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/sys_common/backtrace.rs:67:5
   3:     0x5639e2268c9c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hfbaa40019107bf73
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/sys_common/backtrace.rs:44:22
   4:     0x5639e2299230 - core::fmt::rt::Argument::fmt::hb051b4144eaf7ba9
                               at /build/rust/src/rustc-1.75.0-src/library/core/src/fmt/rt.rs:142:9
   5:     0x5639e2299230 - core::fmt::write::h09ae4ee704823005
                               at /build/rust/src/rustc-1.75.0-src/library/core/src/fmt/mod.rs:1120:17
   6:     0x5639e226507d - std::io::Write::write_fmt::h2f754c40a62d69e7
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/io/mod.rs:1762:15
   7:     0x5639e2268a85 - std::sys_common::backtrace::_print::h5aa33cefb716154f
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/sys_common/backtrace.rs:47:5
   8:     0x5639e2268a85 - std::sys_common::backtrace::print::hba7db713d2ca6e46
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/sys_common/backtrace.rs:34:9
   9:     0x5639e226a2d3 - std::panicking::default_hook::{{closure}}::hdecc168c96eda73a
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:272:22
  10:     0x5639e226a00a - std::panicking::default_hook::h094baec9e5d8cab2
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:292:9
  11:     0x5639e226a805 - std::panicking::rust_panic_with_hook::h1d7664437b07c6b2
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:779:13
  12:     0x5639e226a6ee - std::panicking::begin_panic_handler::{{closure}}::hcf3241a5a930cf68
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:657:13
  13:     0x5639e2269156 - std::sys_common::backtrace::__rust_end_short_backtrace::h5bffafd462cab801
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/sys_common/backtrace.rs:170:18
  14:     0x5639e226a472 - rust_begin_unwind
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:645:5
  15:     0x5639e19f6ab5 - core::panicking::panic_fmt::h45860aff82e9ff99
                               at /build/rust/src/rustc-1.75.0-src/library/core/src/panicking.rs:72:14
  16:     0x5639e1ad9521 - citadel_rs::libs::calibre::add_book_to_db_by_metadata::h091d8d1888d3ca69
  17:     0x5639e1b64983 - citadel_rs::run_tauri_backend::{{closure}}::h3bb29e5111b22700
  18:     0x5639e1b631c1 - <tauri::plugin::TauriPlugin<R,C> as tauri::plugin::Plugin<R>>::extend_api::h39fc29458d96579b
  19:     0x5639e1b514ed - tauri::plugin::PluginStore<R>::extend_api::h9168bad0d72111a2
  20:     0x5639e1a6fb8c - tauri::manager::WindowManager<R>::extend_api::h244fd2d23d749935
  21:     0x5639e1b56250 - tauri::window::Window<R>::on_message::hd9491f566b821a6b
  22:     0x5639e1a724a7 - tauri::manager::WindowManager<R>::prepare_ipc_handler::{{closure}}::h01dfecb7134b3895
  23:     0x5639e1b2cf2a - tauri_runtime_wry::create_ipc_handler::{{closure}}::h7bde2fd2d1179594
  24:     0x5639e1a78420 - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::h20407a0158c08f3a
  25:     0x5639e1eb4353 - <O as webkit2gtk::auto::user_content_manager::UserContentManagerExt>::connect_script_message_received::script_message_received_trampoline::h72b90c7c1777d1b2
  26:     0x7f7e4fbb26c0 - g_closure_invoke
  27:     0x7f7e4fbe0a36 - <unknown>
  28:     0x7f7e4fbd1a42 - <unknown>
  29:     0x7f7e4fbd1c77 - g_signal_emit_valist
  30:     0x7f7e4fbd1d34 - g_signal_emit
  31:     0x7f7e540e5d88 - <unknown>
  32:     0x7f7e53caf98e - <unknown>
  33:     0x7f7e53f916f5 - <unknown>
  34:     0x7f7e54070dce - <unknown>
  35:     0x7f7e53f86a8e - <unknown>
  36:     0x7f7e53f8abb2 - <unknown>
  37:     0x7f7e51ad2aab - <unknown>
  38:     0x7f7e51ad2b91 - <unknown>
  39:     0x7f7e4faabf69 - <unknown>
  40:     0x7f7e4fb0a367 - <unknown>
  41:     0x7f7e4faaa162 - g_main_context_iteration
  42:     0x7f7e521ed3c7 - gtk_main_iteration_do
  43:     0x5639e1eeee3d - gtk::auto::functions::main_iteration_do::hf7f1f4b33400a7c3
  44:     0x5639e1b7b1ad - glib::main_context::<impl glib::auto::main_context::MainContext>::with_thread_default::h451a5aa60667354f
  45:     0x5639e1b3de52 - tao::platform_impl::platform::event_loop::EventLoop<T>::run::hc1de31bbe5167cca
  46:     0x5639e1b6256d - <tauri_runtime_wry::Wry<T> as tauri_runtime::Runtime<T>>::run::h948abacff27924ed
  47:     0x5639e1a7cbb8 - citadel_rs::run_tauri_backend::hfba7896320e1d756
  48:     0x5639e1bc352f - <tokio::task::local::RunUntil<T> as core::future::future::Future>::poll::ha5cedacb30465c30
  49:     0x5639e1bdd11c - <core::pin::Pin<P> as core::future::future::Future>::poll::h5b4f109d65dda040
  50:     0x5639e1bc227c - tokio::runtime::scheduler::current_thread::Context::enter::hcd1680d270807e31
  51:     0x5639e1a4e0fc - tokio::runtime::context::set_scheduler::hbb6d62a0de494b81
  52:     0x5639e1bc186f - tokio::runtime::scheduler::current_thread::CurrentThread::block_on::h1ef579b3b0127ac9
  53:     0x5639e1bdcf8d - tokio::runtime::runtime::Runtime::block_on::h1417fa88ebfcd082
  54:     0x5639e1a7d895 - citadel_rs::main::h5204abaf2ee96bfb
  55:     0x5639e1b10493 - std::sys_common::backtrace::__rust_begin_short_backtrace::hce4b60bab80bff90
  56:     0x5639e1b912b9 - std::rt::lang_start::{{closure}}::hf4fd96fb54286a84
  57:     0x5639e225dbed - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h6e58cd4b3aa0cedc
                               at /build/rust/src/rustc-1.75.0-src/library/core/src/ops/function.rs:284:13
  58:     0x5639e225dbed - std::panicking::try::do_call::h1d63a6ddcddbf3d7
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:552:40
  59:     0x5639e225dbed - std::panicking::try::ha98263394816949f
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:516:19
  60:     0x5639e225dbed - std::panic::catch_unwind::hc08a17c58416f4cc
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panic.rs:142:14
  61:     0x5639e225dbed - std::rt::lang_start_internal::{{closure}}::h8a6385fe0d26a9d5
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/rt.rs:148:48
  62:     0x5639e225dbed - std::panicking::try::do_call::h6b4548ddcceb66f1
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:552:40
  63:     0x5639e225dbed - std::panicking::try::ha4d76d1974f7f45a
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:516:19
  64:     0x5639e225dbed - std::panic::catch_unwind::h691bb3d050a579da
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panic.rs:142:14
  65:     0x5639e225dbed - std::rt::lang_start_internal::h1630c9ed041f86ee
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/rt.rs:148:20
  66:     0x5639e1b912ae - std::rt::lang_start::h81cf3f1050ed8f71
  67:     0x7f7e4f158cd0 - <unknown>
  68:     0x7f7e4f158d8a - __libc_start_main
  69:     0x5639e19f7495 - _start
  70:                0x0 - <unknown>

Support importing filetypes other than EPUB

We only support EPUB rn because they are very common and there was an easy-to-use crate to get data from EPUBs.

Add support for getting the same data for other core file types, specifically:

  • Kindle (.azw, .azw3/kf8) (#23)
  • Kindle, Next-Gen (.kfx)
  • AZW4 (.azw4): Maybe.
  • CBZ, CBR (e.g. application/vnd.comicbook+zip & application/vnd.comicbook-rar). Maybe: CB7, CBT, CBA??
  • EPUB (.epub)
  • Mobipocket (.mobi, .prc) (#20)
  • PDF (#21)
  • Text files (.txt) (#24)

I'd like to do enforce the mimetype enum a bit better: we should look at the file extension for clues to the mimetype, validate it, and (if valid) pass around a filepath/mimetype pair (a "validated file"). Supporting incorrect file extensions is not necessary, e.g. .epub is actually a PDF? invalid & unimportable.

Appendix 1: Unplanned file types

Calibre has a wide range of import formats, not all of which are a good fit for Citadel. Citadel is specifically focused on managing ebook libraries, and (while it may support conversion in the future) not directed at editing ebook content or ebook publishing. To that end, it makes sense to focus on commonly used end formats. Specifically, we're not planning to add these formats. Please let me know if you use these!

  • CBC: CBC seems to be a collection of CBZ/CBR files. Only used by Calibre? If users use this, we may add it
  • CHM
  • DjVU: Internet Archive stopped using for new uploads as they found declining use (Internet Archive)
  • DOCX: It's an ebook management app.
  • FB2, FBZ: Russian, making it harder to support, but popular. May reconsider!
  • HTML, HTMLZ: It's an ebook management app.
  • Microsoft LIT (.lit): Unsupported protocol.
  • Broadband eBooks/BBeB (.lrx., .lrf): Unsupported, proprietary.
  • .odt: no
  • eReader (.pdb, .pml): no
  • Rocket eBook (.rb): No
  • Rich Text Format (.rtf): No
  • SNB
  • TCR
  • TXTZ

See also, this list of ebook file formats

Appendix 2: Calibre's supported list

Calibre seems to support adding whatever files you want to your library. I tried adding a PNG (image) and a GPX (GPS coordinates) file to my library, and both worked. While Calibre may be forgiving, Citadel is not. We won't support arbitrary files.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.