diff --git a/CMakeLists.txt b/CMakeLists.txt index c949c78..2f1493f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,10 +30,7 @@ include(ECMPoQmTools) kde_enable_exceptions() -set(CXXQT_QTCOMPONENTS Core Gui Qml QuickControls2 QuickTest Test) - set(CXXQT_QTCOMPONENTS ${CXXQT_QTCOMPONENTS} QmlImportScanner) - -find_package(Qt6 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Core5Compat Quick Test Gui Qml QuickControls2 Widgets Sql QmlImportScanner WebEngineQuick Multimedia) +find_package(Qt6 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Core5Compat Quick Test Gui Qml QuickControls2 Widgets Sql QmlImportScanner WebEngineQuick) find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS Kirigami CoreAddons I18n) # find_package(KF6FileMetaData ${KF6_MIN_VERSION}) @@ -60,70 +57,45 @@ set_package_properties(Ytdlp PROPERTIES TYPE RUNTIME) # execute_process(COMMAND ${XDG-DESKTOP-MENU_EXECUTABLE} install --novender librepresenter.desktop) get_target_property(QMAKE Qt::qmake IMPORTED_LOCATION) -find_package(CxxQt QUIET) -if(NOT CxxQt_FOUND) +find_package(Corrosion QUIET) +if(NOT Corrosion_FOUND) include(FetchContent) FetchContent_Declare( - CxxQt - GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git - GIT_TAG v0.7.0 + Corrosion + GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git + GIT_TAG v0.3.0 ) - FetchContent_MakeAvailable(CxxQt) + FetchContent_MakeAvailable(Corrosion) endif() -# find_package(Corrosion QUIET) -# if(NOT Corrosion_FOUND) -# include(FetchContent) -# FetchContent_Declare( -# Corrosion -# GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git -# GIT_TAG v0.3.0 -# ) - -# FetchContent_MakeAvailable(Corrosion) -# endif() - - +add_subdirectory(src) set(CRATE liblumina) - -# CXX-Qt (using Corrosion) creates a CMake target with the same name as the crate. -cxx_qt_import_crate( - MANIFEST_PATH Cargo.toml - CRATES liblumina - QT_MODULES Qt::Core Qt::Gui Qt::Qml Qt::QuickControls2 Qt::WebEngineQuick) - -cxx_qt_import_qml_module(liblumina_qml_module - URI "org.presenter" - SOURCE_CRATE liblumina) - - # Corrosion creates a CMake target with the same name as the crate. -# corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES ${CRATE}) +corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES ${CRATE}) # The Rust library's build script needs to be told where to output the # generated headers so CMake can find them. To do this, tell Corrosion # to set the CXXQT_EXPORT_DIR environment variable when calling `cargo build`. # Also, set the QMAKE environment variable to ensure the Rust library uses # the same installation of Qt as CMake. -# set(CXXQT_EXPORT_DIR "${CMAKE_CURRENT_BINARY_DIR}/cxxqt") -# corrosion_set_env_vars(${CRATE} -# "CXXQT_EXPORT_DIR=${CXXQT_EXPORT_DIR}" -# "QMAKE=${QMAKE}" -# ) +set(CXXQT_EXPORT_DIR "${CMAKE_CURRENT_BINARY_DIR}/cxxqt") +corrosion_set_env_vars(${CRATE} + "CXXQT_EXPORT_DIR=${CXXQT_EXPORT_DIR}" + "QMAKE=${QMAKE}" +) -add_subdirectory(src) +add_library(${APP_NAME}_lib INTERFACE) # Include the headers generated by the Rust library's build script. Each # crate gets its own subdirectory under CXXQT_EXPORT_DIR. This allows you # to include headers generated by multiple crates without risk of one crate # overwriting another's files. -target_include_directories(liblumina INTERFACE "${CXXQT_EXPORT_DIR}/${CRATE}") - +target_include_directories(${APP_NAME}_lib INTERFACE "${CXXQT_EXPORT_DIR}/${CRATE}") # Link the Rust INTERFACE library target to Qt. Do this on the library target # rather than the main executable. This way, CMake targets besides the main # executable which link the Rust library, for example tests, will also link Qt. -target_link_libraries(liblumina INTERFACE +target_link_libraries(${APP_NAME}_lib INTERFACE "$" Qt6::Quick Qt6::Qml @@ -132,7 +104,6 @@ target_link_libraries(liblumina INTERFACE Qt6::Widgets Qt6::Sql Qt6::WebEngineQuick - Qt6::Multimedia KF6::Kirigami KF6::I18n KF6::CoreAddons @@ -143,9 +114,8 @@ target_link_libraries(liblumina INTERFACE crypto ) - # Link to the Rust library -target_link_libraries(${APP_NAME} PRIVATE liblumina) +target_link_libraries(${APP_NAME} PRIVATE ${APP_NAME}_lib) # If we are using a statically linked Qt then we need to import any qml plugins qt_import_qml_plugins(${APP_NAME}) diff --git a/Cargo.lock b/Cargo.lock index 2662187..7f30019 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 4 +version = 3 [[package]] name = "addr2line" @@ -338,19 +338,6 @@ dependencies = [ "serde", ] -[[package]] -name = "blah" -version = "0.1.0" -dependencies = [ - "cxx", - "cxx-qt", - "cxx-qt-build", - "cxx-qt-lib", - "cxx-qt-lib-extras", - "markdown", - "qt-build-utils", -] - [[package]] name = "block" version = "0.1.6" @@ -503,6 +490,32 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "core" +version = "0.1.0" +dependencies = [ + "color-eyre", + "configparser", + "dirs", + "fastrand 2.1.1", + "obws", + "pretty_assertions", + "quote", + "reqwest", + "rfd", + "serde", + "serde_derive", + "serde_json", + "sqlx", + "tar", + "time", + "tokio", + "tracing", + "tracing-subscriber", + "youtube_dl", + "zstd", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -580,6 +593,21 @@ dependencies = [ "link-cplusplus", ] +[[package]] +name = "cxx-build" +version = "1.0.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77953e99f01508f89f55c494bfa867171ef3a6c8cea03d26975368f2121a5c1" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 2.0.77", +] + [[package]] name = "cxx-gen" version = "0.7.128" @@ -594,41 +622,38 @@ dependencies = [ [[package]] name = "cxx-qt" -version = "0.7.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "208ad6c4feac92f221fde00796f317b049ba1892b97be0d60ca177d0d3469fc5" +checksum = "08aa6cda7588b6d17c563b0d2fadc060d4204d04908c0f359ae288857091218d" dependencies = [ "cxx", - "cxx-qt-build", "cxx-qt-macro", - "qt-build-utils", "static_assertions", - "thiserror", ] [[package]] name = "cxx-qt-build" -version = "0.7.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f80e109aa68795486c70c302f6c2d921f00028b3b62038a4601efb5c585c1c" +checksum = "9e097b99f49792922a72a8ca35d9391762e48e63363d6998255be1f2ca1edf69" dependencies = [ "cc", "codespan-reporting", + "convert_case", "cxx-gen", "cxx-qt-gen", + "cxx-qt-lib-headers", "proc-macro2", "qt-build-utils", "quote", - "serde", - "serde_json", "version_check", ] [[package]] name = "cxx-qt-gen" -version = "0.7.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc17d95ca9cc60c2f91f804a4e0ba6a3e1b8ed338c207a1bd8d176133e2fd05d" +checksum = "ede7c73dbfbcc234d8826919e257830c1789db2cac586546a87d2a82e3cbe5d5" dependencies = [ "clang-format", "convert_case", @@ -640,33 +665,27 @@ dependencies = [ [[package]] name = "cxx-qt-lib" -version = "0.7.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f116c5d982bbf3be707acf97f566802c30454d52ca319c745ed39a04834e8bc6" +checksum = "002f1a6119bcb7dfec67eb7c0803a7b1d595dc54610559faeac35133f22a5880" dependencies = [ "cxx", - "cxx-qt", - "cxx-qt-build", + "cxx-build", + "cxx-qt-lib-headers", "qt-build-utils", ] [[package]] -name = "cxx-qt-lib-extras" -version = "0.7.1" +name = "cxx-qt-lib-headers" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe1aaed6391a224d746e314104f33b4031138291ebd368170a2109b6008ace2" -dependencies = [ - "cxx", - "cxx-qt", - "cxx-qt-build", - "cxx-qt-lib", -] +checksum = "9abdeab6b77cfc5a53b724f3f62a37bcb5ac1423cccc2dba4c134f4273440b8c" [[package]] name = "cxx-qt-macro" -version = "0.7.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58a4fe02c0604eda28c605792f5ba0d0251b4947f8f0fc43e55b61c06b2b8ec6" +checksum = "699e8a668c03b03419b084960d72eed253632bb16349b33fd0a0c893b61b664c" dependencies = [ "cxx-qt-gen", "proc-macro2", @@ -1413,9 +1432,9 @@ checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] name = "itertools" -version = "0.13.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] @@ -1471,7 +1490,6 @@ dependencies = [ "cxx-qt-lib", "dirs", "fastrand 2.1.1", - "lumina_core", "obws", "qt-build-utils", "quote", @@ -1555,32 +1573,6 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -[[package]] -name = "lumina_core" -version = "0.1.0" -dependencies = [ - "color-eyre", - "configparser", - "dirs", - "fastrand 2.1.1", - "obws", - "pretty_assertions", - "quote", - "reqwest", - "rfd", - "serde", - "serde_derive", - "serde_json", - "sqlx", - "tar", - "time", - "tokio", - "tracing", - "tracing-subscriber", - "youtube_dl", - "zstd", -] - [[package]] name = "malloc_buf" version = "0.0.6" @@ -1590,15 +1582,6 @@ dependencies = [ "libc", ] -[[package]] -name = "markdown" -version = "1.0.0-alpha.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e27d6220ce21f80ce5c4201f23a37c6f1ad037c72c9d1ff215c2919605a5d6" -dependencies = [ - "unicode-id", -] - [[package]] name = "matchers" version = "0.1.0" @@ -2109,9 +2092,9 @@ dependencies = [ [[package]] name = "qt-build-utils" -version = "0.7.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb239fdd8c036fabb95364320041ef68197cd4ab971bb3b4ca3ea0b7b93d12c" +checksum = "d59c828fe2434dad34dd0c30a4ba037509b61dad92a55baf0dc42699e6aa2f10" dependencies = [ "cc", "thiserror", @@ -2381,6 +2364,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scratch" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" + [[package]] name = "security-framework" version = "2.11.1" @@ -3223,12 +3212,6 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" -[[package]] -name = "unicode-id" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10103c57044730945224467c09f71a4db0071c123a0648cc3e818913bde6b561" - [[package]] name = "unicode-ident" version = "1.0.12" @@ -3321,9 +3304,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "versions" -version = "6.3.2" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f25d498b63d1fdb376b4250f39ab3a5ee8d103957346abacd911e2d8b612c139" +checksum = "c73a36bc44e3039f51fbee93e39f41225f6b17b380eb70cc2aab942df06b34dd" dependencies = [ "itertools", "nom", diff --git a/Cargo.toml b/Cargo.toml index bec892a..5d20d7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = [ "smdview/blah","src/rust/core"] +members = ["src/rust/core"] [package] name = "liblumina" @@ -21,14 +21,13 @@ path = "src/rust/lib.rs" # path = "src/rust/main.rs" [dependencies] -lumina_core = { path = "src/rust/core" } configparser = "3.0.2" serde = "1.0.152" serde_derive = "1.0.152" quote = "1.0.27" cxx = "1.0.83" -cxx-qt = "0.7.1" -cxx-qt-lib = { version = "0.7.1", features = [ "qt_full" ] } +cxx-qt = "0.6.1" +cxx-qt-lib = "0.6.1" # home = "0.5.4" dirs = "5.0.0" # libsqlite3-sys = { version = ">=0.17.2", features = ["bundled"] } @@ -51,8 +50,8 @@ color-eyre = "0.6.3" # cxx-qt-build generates C++ code from the `#[cxx_qt::bridge]` module # and compiles it together with the Rust static library [build-dependencies] -cxx-qt-build = { version = "0.7.1", features = [ "link_qt_object_files" ] } -qt-build-utils = "0.7.1" +cxx-qt-build = { version = "0.6.1", features = [ "link_qt_object_files" ] } +qt-build-utils = "0.6.1" # [dependencies.confy] # features = ["yaml_conf"] diff --git a/TODO.org b/TODO.org index 83c5a11..183bc66 100644 --- a/TODO.org +++ b/TODO.org @@ -4,8 +4,7 @@ :CATEGORY: dev :END: -* Tasks [63%] [55/87] -** TODO [#A] REWRITE FOR ALL RUST AND BUILD WITH CARGO +* Tasks [63%] [55/86] ** TODO [#A] Plugin architecture with steel or some scheme as an extension language ** TODO [#A] Server client architecture ** TODO [#A] Organize and layout structure of rust code :maintenance: diff --git a/build.rs b/build.rs index 84c1284..8d4b0d6 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,3 @@ -use std::{env, path::PathBuf}; - use cxx_qt_build::{CxxQtBuilder, QmlModule}; fn main() { @@ -19,37 +17,6 @@ fn main() { .file("src/rust/obs.rs") .build(); - // let mut kde_include_dir = String::from("/usr/include/"); - // let mut kde_lib_dir = String::from("/usr/lib/x86_64-linux-gnu/"); - - // if let Ok(mut include_dir) = env::var("CMAKE_INCLUDE_PATH") { - // println!("{}", include_dir); - // if let Some(include_dir) = - // include_dir.split(":").find(|s| s.contains("ki18n")) - // { - // kde_include_dir = include_dir.to_owned(); - // } - // } else { - // println!( - // "cargo:warning=KDE_INCLUDEDIR is not defined, used default value: {}", - // kde_include_dir - // ); - // } - // if let Ok(lib_dir) = env::var("KDE_LIBDIR") { - // kde_lib_dir = lib_dir; - // } else { - // println!( - // "cargo:warning=KDE_LIBDIR is not defined, used default value: {}", - // kde_lib_dir - // ); - // } - - // let ki18n_include_path = PathBuf::from(kde_include_dir) - // .canonicalize() - // .expect("Cannot get canonical path of KDE_INCLUDEDIR") - // .join("KF6") - // .join("KI18n"); - // CxxQtBuilder::new() // // Link Qt's Network library // // - Qt Core is always linked @@ -60,64 +27,13 @@ fn main() { // // .qt_module("Kirigami") // // .qt_module("WebEngineQuick") // .qt_module("Network") - // // .qt_module("Quick") - // // .qt_module("Test") - // // .qt_module("WebEngineQuick") // // .qt_module("I18n") // // .qt_module("CoreAddons") // .qml_module(QmlModule { // uri: "com.cochrun.xyz", - // rust_files: &[ - // "src/rust/settings.rs", - // "src/rust/service_item_model.rs", - // "src/rust/file_helper.rs", - // "src/rust/slide_model.rs", - // "src/rust/slide_object.rs", - // "src/rust/ytdl.rs", - // "src/rust/utils.rs", - // "src/rust/obs.rs", - // "src/rust/video_model.rs", - // "src/rust/image_model.rs", - // "src/rust/presentation_model.rs", - // // "src/rust/songs/song_model.rs", - // // "src/rust/songs/song_editor.rs", - // ], - // qrc_files: &["src/resources.qrc"], - // qml_files: &[ - // "src/qml/main.qml", - // "src/qml/presenter/LeftDock.qml", - // "src/qml/presenter/ServiceList.qml", - // "src/qml/presenter/MainWindow.qml", - // "src/qml/presenter/Library.qml", - // "src/qml/presenter/LibraryItem.qml", - // "src/qml/presenter/Header.qml", - // "src/qml/presenter/Actions.qml", - // "src/qml/presenter/PanelItem.qml", - // "src/qml/presenter/SongEditor.qml", - // "src/qml/presenter/VideoEditor.qml", - // "src/qml/presenter/ImageEditor.qml", - // "src/qml/presenter/PresentationEditor.qml", - // "src/qml/presenter/SlideEditor.qml", - // "src/qml/presenter/Slide.qml", - // "src/qml/presenter/SlidesListView.qml", - // "src/qml/presenter/SongEditorSlideList.qml", - // "src/qml/presenter/DragHandle.qml", - // "src/qml/presenter/Presentation.qml", - // "src/qml/presenter/PresentationWindow.qml", - // "src/qml/presenter/PreviewSlideListDelegate.qml", - // "src/qml/presenter/PreviewSlide.qml", - // "src/qml/presenter/Settings.qml", - // "src/qml/presenter/RangedSlider.qml", - // "src/qml/presenter/NewVideo.qml", - // "src/qml/presenter/TextBackground.qml", - // "src/qml/presenter/TextBox.qml", - // "src/qml/presenter/LoadingSpinner.qml", - // ], + // rust_files: &["src/rust/settings.rs"], + // qml_files: &["src/qml/main.qml"], // ..Default::default() // }) - // .cc_builder(|cc| { - // cc.include("cpp"); - // cc.include(format!("{}", ki18n_include_path.display())); - // }) // .build(); } diff --git a/flake.lock b/flake.lock index efd6a95..6b82aa5 100644 --- a/flake.lock +++ b/flake.lock @@ -1,56 +1,15 @@ { "nodes": { - "fenix": { - "inputs": { - "nixpkgs": "nixpkgs", - "rust-analyzer-src": "rust-analyzer-src" - }, - "locked": { - "lastModified": 1753252982, - "narHash": "sha256-brrpvP+4GRXLHjvnDr1j1/yA4117hzs6t9IT60JuSI8=", - "owner": "nix-community", - "repo": "fenix", - "rev": "8546562a84feb5370ce57493277b6f2c3cbdc432", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "fenix", - "type": "github" - } - }, - "fenix_2": { - "inputs": { - "nixpkgs": [ - "naersk", - "nixpkgs" - ], - "rust-analyzer-src": "rust-analyzer-src_2" - }, - "locked": { - "lastModified": 1752475459, - "narHash": "sha256-z6QEu4ZFuHiqdOPbYss4/Q8B0BFhacR8ts6jO/F/aOU=", - "owner": "nix-community", - "repo": "fenix", - "rev": "bf0d6f70f4c9a9cf8845f992105652173f4b617f", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "fenix", - "type": "github" - } - }, "flake-utils": { "inputs": { "systems": "systems" }, "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { @@ -61,15 +20,14 @@ }, "naersk": { "inputs": { - "fenix": "fenix_2", - "nixpkgs": "nixpkgs_2" + "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1752689277, - "narHash": "sha256-uldUBFkZe/E7qbvxa3mH1ItrWZyT6w1dBKJQF/3ZSsc=", + "lastModified": 1721727458, + "narHash": "sha256-r/xppY958gmZ4oTfLiHN0ZGuQ+RSTijDblVgVLFi1mw=", "owner": "nix-community", "repo": "naersk", - "rev": "0e72363d0938b0208d6c646d10649164c43f4d64", + "rev": "3fb418eaf352498f6b6c30592e3beb63df42ef11", "type": "github" }, "original": { @@ -80,43 +38,23 @@ }, "nixpkgs": { "locked": { - "lastModified": 1752950548, - "narHash": "sha256-NS6BLD0lxOrnCiEOcvQCDVPXafX1/ek1dfJHX1nUIzc=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "c87b95e25065c028d31a94f06a62927d18763fdf", - "type": "github" + "lastModified": 0, + "narHash": "sha256-+yj+xgsfZaErbfYM3T+QvEE2hU7UuE+Jf0fJCJ8uPS0=", + "path": "/nix/store/6inj491lsap4ia7mmvn2gbh53jb27zq0-source", + "type": "path" }, "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" + "id": "nixpkgs", + "type": "indirect" } }, "nixpkgs_2": { "locked": { - "lastModified": 1752077645, - "narHash": "sha256-HM791ZQtXV93xtCY+ZxG1REzhQenSQO020cu6rHtAPk=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "be9e214982e20b8310878ac2baa063a961c1bdf6", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1752950548, - "narHash": "sha256-NS6BLD0lxOrnCiEOcvQCDVPXafX1/ek1dfJHX1nUIzc=", + "lastModified": 1725634671, + "narHash": "sha256-v3rIhsJBOMLR8e/RNWxr828tB+WywYIoajrZKFM+0Gg=", "owner": "nixos", "repo": "nixpkgs", - "rev": "c87b95e25065c028d31a94f06a62927d18763fdf", + "rev": "574d1eac1c200690e27b8eb4e24887f8df7ac27c", "type": "github" }, "original": { @@ -128,44 +66,9 @@ }, "root": { "inputs": { - "fenix": "fenix", "flake-utils": "flake-utils", "naersk": "naersk", - "nixpkgs": "nixpkgs_3" - } - }, - "rust-analyzer-src": { - "flake": false, - "locked": { - "lastModified": 1753204114, - "narHash": "sha256-xH8EIod+Hwog4P9OwX9hdtk6Nqr54M0tzMI71yGNOYI=", - "owner": "rust-lang", - "repo": "rust-analyzer", - "rev": "b40fce3ccdc5f94453c6aca4da8b64174a03a5ad", - "type": "github" - }, - "original": { - "owner": "rust-lang", - "ref": "nightly", - "repo": "rust-analyzer", - "type": "github" - } - }, - "rust-analyzer-src_2": { - "flake": false, - "locked": { - "lastModified": 1752428706, - "narHash": "sha256-EJcdxw3aXfP8Ex1Nm3s0awyH9egQvB2Gu+QEnJn2Sfg=", - "owner": "rust-lang", - "repo": "rust-analyzer", - "rev": "591e3b7624be97e4443ea7b5542c191311aa141d", - "type": "github" - }, - "original": { - "owner": "rust-lang", - "ref": "nightly", - "repo": "rust-analyzer", - "type": "github" + "nixpkgs": "nixpkgs_2" } }, "systems": { diff --git a/flake.nix b/flake.nix index 954cbdc..9f64ab6 100644 --- a/flake.nix +++ b/flake.nix @@ -6,121 +6,77 @@ nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; naersk.url = "github:nix-community/naersk"; flake-utils.url = "github:numtide/flake-utils"; - fenix.url = "github:nix-community/fenix"; # nixpkgs.follows = "cargo2nix/nixpkgs"; }; - outputs = inputs: - with inputs; - flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { - inherit system; - overlays = [ fenix.overlays.default ]; - # overlays = [cargo2nix.overlays.default]; - }; - naersk' = pkgs.callPackage naersk { }; + outputs = inputs: with inputs; + flake-utils.lib.eachDefaultSystem + (system: + let + pkgs = import nixpkgs { + inherit system; + # overlays = [cargo2nix.overlays.default]; + }; + naersk' = pkgs.callPackage naersk {}; + # src = ./.; + # rustPkgs = pkgs.rustBuilder.makePackageSet { + # rustVersion = "1.61.0"; + # packageFun = import ./Cargo.nix; + # }; + # The workspace defines a development shell with all of the dependencies + # and environment settings necessary for a regular `cargo build`. + # Passes through all arguments to pkgs.mkShell for adding supplemental + # dependencies. + # workspaceShell = rustPkgs.workspaceShell { + # packages = with pkgs; [ + # gcc + # stdenv + # bintools + # gnumake + # gdb + # qtcreator + # cmake + # extra-cmake-modules + # pkg-config + # libsForQt5.wrapQtAppsHook + # makeWrapper - nbi = with pkgs; [ - # ffmpeg - alejandra - (pkgs.fenix.stable.withComponents [ - "cargo" - "clippy" - "rust-src" - "rustc" - "rustfmt" - ]) - rust-analyzer - ]; + # clang-tools + # clang + # libclang + # qt5.qtbase + # qt5.qttools + # qt5.qtquickcontrols2 + # qt5.qtx11extras + # qt5.qtmultimedia + # qt5.qtwayland + # qt5.qtwebengine + # libsForQt5.kirigami2 + # libsForQt5.qqc2-desktop-style + # libsForQt5.karchive + # mpv + # ffmpeg_6-full + # # Rust tools + # clippy + # rustc + # cargo + # rustfmt + # rust-analyzer + # corrosion + # ]; + # # shellHook = '' + # # export PS1="\033[0;31m☠dev-shell☠ $ \033[0m" + # # ''; + # }; - bi = with pkgs; [ - gcc - stdenv - gnumake - gdb - qtcreator - cmake - kdePackages.extra-cmake-modules - pkg-config - qt6.wrapQtAppsHook - makeWrapper - - openssl.dev - openssl.out - - clang-tools - clang - libclang - # libwebp - # clang-format - qt6.full - qt6.qttools - qt6.qtbase - # qt6.qtquickcontrols2 - # qt6.qtx11extras - qt6.qtmultimedia - qt6.qtwayland - qt6.qtwebengine - qt6.qtimageformats - kdePackages.kirigami - # kdePackages.kfilemetadata - # libsForQt5.breeze-icons - # libsForQt5.breeze-qt5 - kdePackages.qqc2-desktop-style - # libsForQt5.kirigami-addons - # libsForQt5.ki18n - kdePackages.kcoreaddons - # libsForQt5.kguiaddons - # libsForQt5.kconfig - - # podofo - mpv - kdePackages.mpvqt - ffmpeg-full - # yt-dlp - - # Rust tools - just - clippy - rustc - cargo - rustfmt - rust-analyzer - sqlx-cli - cargo-watch - corrosion - ]; - - in rec { - # packages = { - # crate = (rustPkgs.workspace.libre-presenter { }).bin; - # default = packages.crate; - # }; - devShell = pkgs.mkShell { - nativeBuildInputs = nbi; - buildInputs = bi; - - RUST_BACKTRACE = "1"; - LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib"; - CMAKE_C_COMPILER = "${pkgs.gcc}/bin/gcc"; - CMAKE_CXX_COMPILER = "${pkgs.gcc}/bin/g++"; - CARGO_PROFILE_RELEASE_BUILD_OVERRIDE_DEBUG = true; - # KDE_INCLUDEDIR = "${pkgs.kdePackages.kirigami.dev}/include"; - # KDE_QMLDIR = "${pkgs.kdePackages.kirigami.dev}/lib/qt-6/qml/org/kde/kirigami/"; - - # This creates the proper qt env so that plugins are found right. - shellHook = '' - setQtEnvironment=$(mktemp --suffix .setQtEnvironment.sh) - echo "shellHook: setQtEnvironment = $setQtEnvironment" - makeQtWrapper "/bin/sh" "$setQtEnvironment" "''${qtWrapperArgs[@]}" - sed "/^exec/d" -i "$setQtEnvironment" - source "$setQtEnvironment" - ''; - DATABASE_URL = - "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3"; - }; - # devShell = import ./shell.nix { inherit pkgs; }; - # defaultPackage = pkgs.libsForQt5.callPackage ./default.nix { }; - }); + in rec + { + # packages = { + # crate = (rustPkgs.workspace.libre-presenter { }).bin; + # default = packages.crate; + # }; + devShell = import ./shell.nix { inherit pkgs; }; + defaultPackage = pkgs.libsForQt5.callPackage ./default.nix { }; + } + ); } diff --git a/justfile b/justfile index f98c2c4..a332b6d 100644 --- a/justfile +++ b/justfile @@ -15,7 +15,7 @@ test: RUST_LOG=debug cargo test --benches --tests --all-features -- --nocapture testcore: - RUST_LOG=debug cargo test -p lumina_core --benches --tests --all-features -- --nocapture + RUST_LOG=debug cargo test -p core --benches --tests --all-features -- --nocapture alias b := build alias r := run diff --git a/smdview/blah/Cargo.toml b/smdview/blah/Cargo.toml deleted file mode 100644 index 1a4e1ef..0000000 --- a/smdview/blah/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "blah" -version = "0.1.0" -edition = "2024" - -[dependencies] -cxx = "1.0.122" -cxx-qt = "0.7.1" -cxx-qt-lib = { version = "0.7.1", features = [ "qt_full" ] } -cxx-qt-lib-extras = "0.7.1" -markdown = "=1.0.0-alpha.17" - -[build-dependencies] -# The link_qt_object_files feature is required for statically linking Qt 6. -cxx-qt-build = { version = "0.7.1", features = [ "link_qt_object_files" ] } -qt-build-utils = "0.7.1" - diff --git a/smdview/blah/build.rs b/smdview/blah/build.rs deleted file mode 100644 index c67706d..0000000 --- a/smdview/blah/build.rs +++ /dev/null @@ -1,12 +0,0 @@ -use cxx_qt_build::{CxxQtBuilder, QmlModule}; - -fn main() { - CxxQtBuilder::new() - .qml_module(QmlModule { - uri: "org.kde.simplemdviewer", - qml_files: &["src/qml/Main.qml"], - rust_files: &["src/main.rs"], - ..Default::default() - }) - .build(); -} diff --git a/smdview/blah/src/main.rs b/smdview/blah/src/main.rs deleted file mode 100644 index c79e764..0000000 --- a/smdview/blah/src/main.rs +++ /dev/null @@ -1,42 +0,0 @@ -#[cxx_qt::bridge] -mod ffi { - extern "RustQt" { - #[qobject] - type DummyQObject = super::DummyRustStruct; - } -} - -#[derive(Default)] -pub struct DummyRustStruct; - -use cxx_qt_lib::{ - QGuiApplication, QQmlApplicationEngine, QQuickStyle, QString, - QUrl, -}; -use cxx_qt_lib_extras::QApplication; -use std::env; - -fn main() { - let mut app = QApplication::new(); - - // To associate the executable to the installed desktop file - QGuiApplication::set_desktop_file_name(&QString::from( - "org.kde.simplemdviewer", - )); - - // To ensure the style is set correctly - if env::var("QT_QUICK_CONTROLS_STYLE").is_err() { - QQuickStyle::set_style(&QString::from("org.kde.desktop")); - } - - let mut engine = QQmlApplicationEngine::new(); - if let Some(engine) = engine.as_mut() { - engine.load(&QUrl::from( - "qrc:/qt/qml/org/kde/simplemdviewer/src/qml/Main.qml", - )); - } - - if let Some(app) = app.as_mut() { - app.exec(); - } -} diff --git a/smdview/blah/src/qml/main.qml b/smdview/blah/src/qml/main.qml deleted file mode 100644 index 077a11e..0000000 --- a/smdview/blah/src/qml/main.qml +++ /dev/null @@ -1,71 +0,0 @@ -import QtQuick -import QtQuick.Layouts -import QtQuick.Controls as Controls -import org.kde.kirigami as Kirigami - -Kirigami.ApplicationWindow { - id: root - - title: "Simple Markdown Viewer in Rust 🦀" - - minimumWidth: Kirigami.Units.gridUnit * 20 - minimumHeight: Kirigami.Units.gridUnit * 20 - width: minimumWidth - height: minimumHeight - - pageStack.initialPage: initPage - - Component { - id: initPage - - Kirigami.Page { - title: "Markdown Viewer" - - ColumnLayout { - anchors { - top: parent.top - left: parent.left - right: parent.right - } - Controls.TextArea { - id: sourceArea - - placeholderText: "Write some Markdown code here" - wrapMode: Text.WrapAnywhere - Layout.fillWidth: true - Layout.minimumHeight: Kirigami.Units.gridUnit * 5 - } - - RowLayout { - Layout.fillWidth: true - - Controls.Button { - text: "Format" - - onClicked: formattedText.text = sourceArea.text - } - - Controls.Button { - text: "Clear" - - onClicked: { - sourceArea.text = "" - formattedText.text = "" - } - } - } - - Controls.Label { - id: formattedText - - textFormat: Text.RichText - wrapMode: Text.WordWrap - text: sourceArea.text - - Layout.fillWidth: true - Layout.minimumHeight: Kirigami.Units.gridUnit * 5 - } - } - } - } -} diff --git a/src/main.cpp b/src/main.cpp index 4914492..656ad12 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,49 +1,49 @@ -// #include -#include +#include +#include #include -#include -#include -#include -// #include -// #include -// #include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -// #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -// #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include // #include // #include "cpp/mpv/mpvitem.h" // #include "cpp/mpv/mpvproperties.h" // RUST -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "cxx-qt-gen/file_helper.cxxqt.h" +#include "cxx-qt-gen/slide_object.cxxqt.h" +#include "cxx-qt-gen/slide_model.cxxqt.h" +#include "cxx-qt-gen/service_item_model.cxxqt.h" +#include "cxx-qt-gen/settings.cxxqt.h" +#include "cxx-qt-gen/ytdl.cxxqt.h" +#include "cxx-qt-gen/presentation_model.cxxqt.h" +#include "cxx-qt-gen/song_model.cxxqt.h" +#include "cxx-qt-gen/video_model.cxxqt.h" +#include "cxx-qt-gen/image_model.cxxqt.h" +#include "cxx-qt-gen/utils.cxxqt.h" +#include "cxx-qt-gen/song_editor.cxxqt.h" +#include "cxx-qt-gen/obs.cxxqt.h" static QWindow *windowFromEngine(QQmlApplicationEngine *engine) { @@ -60,22 +60,22 @@ int main(int argc, char *argv[]) QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("video-display"))); QtWebEngineQuick::initialize(); QGuiApplication app(argc, argv); - // KLocalizedString::setApplicationDomain("lumina"); - // KAboutData about; - // about.setComponentName(QStringLiteral("lumina")); - // about.setDisplayName(i18n("lumina")); - // about.setVersion(QByteArray("0.1")); - // about.setShortDescription(i18n("A churchpresentation app build with KDE tech.")); - // about.setLicense(KAboutLicense::GPL_V3); + KLocalizedString::setApplicationDomain("lumina"); + KAboutData about; + about.setComponentName(QStringLiteral("lumina")); + about.setDisplayName(i18n("lumina")); + about.setVersion(QByteArray("0.1")); + about.setShortDescription(i18n("A churchpresentation app build with KDE tech.")); + about.setLicense(KAboutLicense::GPL_V3); // overwrite default-generated values of organizationDomain & desktopFileName - // about.setOrganizationDomain("tfcconnection.org"); - // about.setDesktopFileName(QStringLiteral("org.tfcconneciton.lumina")); + about.setOrganizationDomain("tfcconnection.org"); + about.setDesktopFileName(QStringLiteral("org.tfcconneciton.lumina")); QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); // set the application metadata - // KAboutData::setApplicationData(about); + KAboutData::setApplicationData(about); QCoreApplication::setOrganizationName(QStringLiteral("lumina")); QCoreApplication::setOrganizationDomain(QStringLiteral("tfcconnection.org")); QCoreApplication::setApplicationName(QStringLiteral("lumina")); @@ -93,7 +93,7 @@ int main(int argc, char *argv[]) // qDebug() << QQuickStyle::availableStyles(); qDebug() << QIcon::themeName(); - // qDebug() << QApplication::platformName(); + qDebug() << QApplication::platformName(); //Need to instantiate our slide QScopedPointer slideModel(new SlideModel); @@ -108,7 +108,6 @@ int main(int argc, char *argv[]) settings->setup(); QQuickView *PresWindow = new QQuickView; - PresWindow->setSource(QUrl(QStringLiteral("qrc:qml/presenter/PresentationWindow.qml"))); qDebug() << PresWindow; qDebug() << PresWindow->isVisible(); @@ -170,9 +169,9 @@ int main(int argc, char *argv[]) qmlRegisterSingletonInstance("org.presenter", 1, 0, "SlideModel", slideModel.get()); qmlRegisterSingletonInstance("org.presenter", 1, 0, "Utils", utils); qmlRegisterSingletonInstance("org.presenter", 1, 0, "SlideObject", slideobject.get()); + qmlRegisterSingletonInstance("org.presenter", 1, 0, "PresWindow", PresWindow); qmlRegisterSingletonInstance("org.presenter", 1, 0, "RSettings", settings); qmlRegisterSingletonInstance("org.presenter", 1, 0, "ObsModel", obsModel.get()); - qmlRegisterSingletonInstance("org.presenter", 1, 0, "PresWindow", PresWindow); // This is the same slideobject, however to enusre that the PresWindow can have it // we need to set it as a separate context so that it can change it's slides too. @@ -185,7 +184,7 @@ int main(int argc, char *argv[]) QQmlApplicationEngine engine; qDebug() << app.allWindows(); - // engine.rootContext()->setContextObject(new KLocalizedContext(&engine)); + engine.rootContext()->setContextObject(new KLocalizedContext(&engine)); engine.load(QUrl(QStringLiteral("qrc:qml/main.qml"))); qDebug() << "Engine loaded"; diff --git a/src/qml/presenter/Library.qml b/src/qml/presenter/Library.qml index f8e648f..ffc5196 100644 --- a/src/qml/presenter/Library.qml +++ b/src/qml/presenter/Library.qml @@ -252,7 +252,6 @@ Item { } function isDragFile(item) { - console.log(item); console.log(item.toString()); var extension = item.toString().split('.').pop(); var valid = false; diff --git a/src/qml/presenter/MainWindow.qml b/src/qml/presenter/MainWindow.qml index 64c1c17..24ad653 100644 --- a/src/qml/presenter/MainWindow.qml +++ b/src/qml/presenter/MainWindow.qml @@ -188,10 +188,6 @@ Controls.Page { songModel: songModel } - Presenter.PresentationWindow { - id: presWindow - } - Connections { target: ServiceItemModel function onSaveProgressChanged() { @@ -356,20 +352,19 @@ Controls.Page { function present(present) { if (present) { - /* presWindow.slideObj = SlideObject; */ - presWindow.showFullScreen(); - /* presWindow.setSource("qrc:qml/presenter/PresentationWindow.qml") */ - console.log(presWindow); + PresWindow.showFullScreen(); + PresWindow.setSource("qrc:qml/presenter/PresentationWindow.qml") + console.log(PresWindow); /* presWinLoader.active = true; */ } else { - presWindow.close(); + PresWindow.close(); /* presWinLoader.active = false; */ } } - function closeAll() { presWindow.close() } + function closeAll() { PresWindow.close() } function changeVidPos(pos) { presentation.slide.seek(pos); diff --git a/src/qml/presenter/Presentation.qml b/src/qml/presenter/Presentation.qml index c082aa2..bdd92c2 100644 --- a/src/qml/presenter/Presentation.qml +++ b/src/qml/presenter/Presentation.qml @@ -479,11 +479,6 @@ FocusScope { previewSlide.stopVideo() } - function playVideo() { - /* showPassiveNotification("Stopping Video") */ - previewSlide.playVideo() - } - function nextSlideAction() { keyHandler.forceActiveFocus(); SlideModel.next() diff --git a/src/qml/presenter/PresentationWindow.qml b/src/qml/presenter/PresentationWindow.qml index 6187f03..b93f576 100644 --- a/src/qml/presenter/PresentationWindow.qml +++ b/src/qml/presenter/PresentationWindow.qml @@ -6,13 +6,13 @@ import org.kde.kirigami 2.13 as Kirigami import "./" as Presenter import org.presenter 1.0 -Window { +Item { id: presentationWindow property Item slide: presentationSlide - /* property var SlideObject: SlideObject; */ + /* property var slideObj */ property var pWin - /* anchors.fill: parent */ + anchors.fill: parent /* title: "presentation-window" */ /* height: maximumHeight */ @@ -25,7 +25,7 @@ Window { /* onClosing: { */ /* presentationSlide.stopVideo(); */ - /* SlideObject.pause(); */ + /* SlideObj.pause(); */ /* presentationSlide.stopAudio(); */ /* presenting = false; */ /* } */ @@ -34,7 +34,7 @@ Window { target: PresWindow function onClosing() { presentationSlide.stopVideo(); - SlideObject.pause(); + SlideObj.pause(); presentationSlide.stopAudio(); presenting = false; } @@ -48,25 +48,25 @@ Window { Presenter.Slide { id: presentationSlide anchors.fill: parent - imageSource: SlideObject.html ? "" : SlideObject.imageBackground - webSource: SlideObject.html ? SlideObject.imageBackground : "" - htmlVisible: SlideObject.html - videoSource: presentationWindow.visible ? SlideObject.videoBackground : "" - audioSource: SlideObject.audio - text: SlideObject.text - chosenFont: SlideObject.font - textSize: SlideObject.fontSize - pdfIndex: SlideObject.slideIndex - itemType: SlideObject.ty - vidLoop: SlideObject.looping - vidStartTime: SlideObject.videoStartTime - vidEndTime: SlideObject.videoEndTime + imageSource: SlideObj.html ? "" : SlideObj.imageBackground + webSource: SlideObj.html ? SlideObj.imageBackground : "" + htmlVisible: SlideObj.html + videoSource: presentationWindow.visible ? SlideObj.videoBackground : "" + audioSource: SlideObj.audio + text: SlideObj.text + chosenFont: SlideObj.font + textSize: SlideObj.fontSize + pdfIndex: SlideObj.slideIndex + itemType: SlideObj.ty + vidLoop: SlideObj.looping + vidStartTime: SlideObj.videoStartTime + vidEndTime: SlideObj.videoEndTime } Connections { - target: SlideObject + target: SlideObj function onVideoBackgroundChanged() { - if (SlideObject.videoBackground === "") + if (SlideObj.videoBackground === "") stopVideo(); else { loadVideo(); @@ -74,12 +74,12 @@ Window { } } function onIsPlayingChanged() { - if(SlideObject.isPlaying) + if(SlideObj.isPlaying) presentationSlide.playVideo(); pauseVideo(); } function onLoopingChanged() { - if(SlideObject.looping) + if(SlideObj.looping) presentationSlide.loopVideo(); } function onAudioChanged() { diff --git a/src/qml/presenter/Settings.qml b/src/qml/presenter/Settings.qml index 9c630f6..e2217ab 100644 --- a/src/qml/presenter/Settings.qml +++ b/src/qml/presenter/Settings.qml @@ -21,7 +21,6 @@ Kirigami.OverlaySheet { Kirigami.FormLayout { implicitHeight: Kirigami.Units.gridUnit * 30 - implicitWidth: Kirigami.Units.gridUnit * 30 Controls.ComboBox { id: screenSelectionField Kirigami.FormData.label: i18nc("@label:textbox", "Presentation Screen:") diff --git a/src/rust/core/Cargo.toml b/src/rust/core/Cargo.toml index d6abb8b..1be6c9d 100644 --- a/src/rust/core/Cargo.toml +++ b/src/rust/core/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "lumina_core" +name = "lumina-core" version = "0.1.0" edition = "2021" authors = [ diff --git a/src/rust/core/file.rs b/src/rust/core/file.rs index ef5163d..8a9aa9e 100644 --- a/src/rust/core/file.rs +++ b/src/rust/core/file.rs @@ -1,133 +1,82 @@ -use crate::{ - images::{get_image_from_db, Image}, - kinds::ServiceItemKind, - model::get_db, - presentations::{ - get_presentation_from_db, PresKind, Presentation, - }, - service_items::ServiceItem, - slides::Background, - songs::{get_song_from_db, Song}, - videos::{get_video_from_db, Video}, -}; -use color_eyre::eyre::{eyre, Context, Result}; -use serde_json::Value; -use sqlx::{query, query_as, FromRow, SqliteConnection}; -use std::{ - fs::{self, File}, - iter, - path::{Path, PathBuf}, -}; use tar::{Archive, Builder}; use tracing::error; use zstd::Encoder; +use std::{fs::{self, File}, future::Future, iter, path::{Path, PathBuf}}; +use color_eyre::eyre::{eyre, Result}; +use serde_json::Value; +use sqlx::{query, query_as, FromRow, SqliteConnection}; +use crate::{images::{get_image_from_db, Image}, kinds::ServiceItemKind, model::get_db, presentations::{get_presentation_from_db, PresKind, Presentation}, service_items::ServiceItem, slides::Background, songs::{get_song_from_db, Song}, videos::{get_video_from_db, Video}}; -pub async fn save( - list: Vec, - path: impl AsRef, -) -> Result<()> { +pub async fn save(list: Vec, path: impl AsRef) -> Result<()> { let path = path.as_ref(); let save_file = File::create(path)?; let mut db = get_db().await; let json = process_service_items(&list, &mut db).await?; - let archive = - store_service_items(&list, &mut db, &save_file, &json) - .await?; + let archive = store_service_items(&list, &mut db, &save_file, &json).await?; Ok(()) } -async fn store_service_items( - items: &Vec, - db: &mut SqliteConnection, - save_file: &File, - json: &Value, -) -> Result<()> { +async fn store_service_items(items: &Vec, db: &mut SqliteConnection, save_file: &File, json: &Value) -> Result<()> { let encoder = Encoder::new(save_file, 3).unwrap(); let mut tar = Builder::new(encoder); let mut temp_dir = dirs::data_dir().unwrap(); temp_dir.push("lumina"); let mut s: String = - iter::repeat_with(fastrand::alphanumeric).take(5).collect(); + iter::repeat_with(fastrand::alphanumeric) + .take(5) + .collect(); s.insert_str(0, "temp_"); temp_dir.push(s); fs::create_dir_all(&temp_dir)?; let service_file = temp_dir.join("serviceitems.json"); fs::File::create(&service_file)?; - match fs::File::options() - .read(true) - .write(true) - .open(service_file) - { + match fs::File::options().read(true).write(true).open(service_file) { Ok(f) => { serde_json::to_writer_pretty(f, json)?; - } - Err(e) => { - error!("There were problems making a file i guess: {e}") - } + }, + Err(e) => error!("There were problems making a file i guess: {e}"), }; for item in items { let background; let audio: Option; match item.kind { ServiceItemKind::Song => { - let song = - get_song_from_db(item.database_id, db).await?; + let song = get_song_from_db(item.database_id, db).await?; background = song.background; audio = song.audio; - } + }, ServiceItemKind::Image => { - let image = - get_image_from_db(item.database_id, db).await?; + let image = get_image_from_db(item.database_id, db).await?; background = Some(Background::try_from(image.path)?); audio = None; - } + }, ServiceItemKind::Video => { - let video = - get_video_from_db(item.database_id, db).await?; + let video = get_video_from_db(item.database_id, db).await?; background = Some(Background::try_from(video.path)?); audio = None; - } + }, ServiceItemKind::Presentation(_) => { - let presentation = - get_presentation_from_db(item.database_id, db) - .await?; - background = - Some(Background::try_from(presentation.path)?); + let presentation = get_presentation_from_db(item.database_id, db).await?; + background = Some(Background::try_from(presentation.path)?); audio = None; - } + }, ServiceItemKind::Content => { todo!() - } + }, }; if let Some(file) = audio { - let audio_file = - temp_dir.join(file.file_name().expect( - "Audio file couldn't be added to temp_dir", - )); - if let Ok(file) = file.strip_prefix("file://") { - fs::File::create(&audio_file) - .wrap_err("Couldn't create audio file")?; - fs::copy(file, audio_file).wrap_err("Audio file could not be copied, the source file doesn't exist not be found"); - } else { - fs::File::create(&audio_file) - .wrap_err("Couldn't create audio file")?; - fs::copy(file, audio_file).wrap_err("Audio file could not be copied, the source file doesn't exist not be found"); - } + let audio_file = temp_dir.join(file.file_name().expect("Audio file couldn't be added to temp_dir")); + match fs::File::create(&audio_file) { + Ok(_) => Ok(fs::copy(file, &audio_file)?), + Err(e) => Err(eyre!("Couldn't create audio file: {e}")), + }?; }; if let Some(file) = background { - let background_file = - temp_dir.join(file.path.file_name().expect( - "Background file couldn't be added to temp_dir", - )); - if let Ok(file) = file.path.strip_prefix("file://") { - fs::File::create(&background_file) - .wrap_err("Couldn't create background file")?; - fs::copy(file, background_file).wrap_err("Background file could not be copied, the source file doesn't exist not be found"); - } else { - fs::File::create(&background_file) - .wrap_err("Couldn't create background file")?; - fs::copy(file.path, background_file).wrap_err("Background file could not be copied, the source file doesn't exist not be found"); - } + let background_file = temp_dir.join(file.path.file_name().expect("Background file couldn't be added to temp_dir")); + match fs::File::create(&background_file) { + Ok(_) => Ok(fs::copy(file.path, &background_file)?), + Err(e) => Err(eyre!("Couldn't create background file: {e}")), + }?; } } Ok(()) @@ -137,96 +86,66 @@ async fn clear_temp_dir(temp_dir: &Path) -> Result<()> { todo!() } -async fn process_service_items( - items: &Vec, - db: &mut SqliteConnection, -) -> Result { +async fn process_service_items(items: &Vec, db: &mut SqliteConnection) -> Result { let mut values: Vec = vec![]; for item in items { match item.kind { ServiceItemKind::Song => { - let value = - process_song(item.database_id, db).await?; + let value = process_song(item.database_id, db).await?; values.push(value); - } + }, ServiceItemKind::Image => { - let value = - process_image(item.database_id, db).await?; + let value = process_image(item.database_id, db).await?; values.push(value); - } + }, ServiceItemKind::Video => { - let value = - process_video(item.database_id, db).await?; + let value = process_video(item.database_id, db).await?; values.push(value); - } + }, ServiceItemKind::Presentation(_) => { - let value = - process_presentation(item.database_id, db) - .await?; + let value = process_presentation(item.database_id, db).await?; values.push(value); - } + }, ServiceItemKind::Content => { todo!() - } + }, } } let json = Value::from(values); Ok(json) } -async fn process_song( - database_id: i32, - db: &mut SqliteConnection, -) -> Result { +async fn process_song(database_id: i32, db: &mut SqliteConnection) -> Result { let song = get_song_from_db(database_id, db).await?; let song_json = serde_json::to_value(&song)?; let kind_json = serde_json::to_value(ServiceItemKind::Song)?; - let json = - serde_json::json!({"item": song_json, "kind": kind_json}); + let json = serde_json::json!({"item": song_json, "kind": kind_json}); Ok(json) } -async fn process_image( - database_id: i32, - db: &mut SqliteConnection, -) -> Result { +async fn process_image(database_id: i32, db: &mut SqliteConnection) -> Result { let image = get_image_from_db(database_id, db).await?; let image_json = serde_json::to_value(&image)?; let kind_json = serde_json::to_value(ServiceItemKind::Image)?; - let json = - serde_json::json!({"item": image_json, "kind": kind_json}); + let json = serde_json::json!({"item": image_json, "kind": kind_json}); Ok(json) } -async fn process_video( - database_id: i32, - db: &mut SqliteConnection, -) -> Result { +async fn process_video(database_id: i32, db: &mut SqliteConnection) -> Result { let video = get_video_from_db(database_id, db).await?; let video_json = serde_json::to_value(&video)?; let kind_json = serde_json::to_value(ServiceItemKind::Video)?; - let json = - serde_json::json!({"item": video_json, "kind": kind_json}); + let json = serde_json::json!({"item": video_json, "kind": kind_json}); Ok(json) } -async fn process_presentation( - database_id: i32, - db: &mut SqliteConnection, -) -> Result { - let presentation = - get_presentation_from_db(database_id, db).await?; +async fn process_presentation(database_id: i32, db: &mut SqliteConnection) -> Result { + let presentation = get_presentation_from_db(database_id, db).await?; let presentation_json = serde_json::to_value(&presentation)?; let kind_json = match presentation.kind { - PresKind::Html => serde_json::to_value( - ServiceItemKind::Presentation(PresKind::Html), - )?, - PresKind::Pdf => serde_json::to_value( - ServiceItemKind::Presentation(PresKind::Pdf), - )?, - PresKind::Generic => serde_json::to_value( - ServiceItemKind::Presentation(PresKind::Generic), - )?, + PresKind::Html => serde_json::to_value(ServiceItemKind::Presentation(PresKind::Html))?, + PresKind::Pdf => serde_json::to_value(ServiceItemKind::Presentation(PresKind::Pdf))?, + PresKind::Generic => serde_json::to_value(ServiceItemKind::Presentation(PresKind::Generic))?, }; let json = serde_json::json!({"item": presentation_json, "kind": kind_json}); Ok(json) @@ -236,11 +155,11 @@ async fn process_presentation( mod test { use std::path::PathBuf; - use super::*; use fs::canonicalize; - use pretty_assertions::assert_eq; use sqlx::Connection; + use pretty_assertions::{assert_eq, assert_ne}; use tracing::debug; + use super::*; async fn get_db() -> SqliteConnection { let mut data = dirs::data_local_dir().unwrap(); @@ -248,7 +167,9 @@ mod test { data.push("library-db.sqlite3"); let mut db_url = String::from("sqlite://"); db_url.push_str(data.to_str().unwrap()); - SqliteConnection::connect(&db_url).await.expect("problems") + SqliteConnection::connect(&db_url) + .await + .expect("problems") } #[tokio::test(flavor = "current_thread")] @@ -318,8 +239,7 @@ mod test { async fn test_process_presentation() { let mut db = get_db().await; let result = process_presentation(54, &mut db).await; - let json_presentation_file = - PathBuf::from("./test/test_presentation.json"); + let json_presentation_file = PathBuf::from("./test/test_presentation.json"); if let Ok(path) = canonicalize(json_presentation_file) { debug!(file = ?&path); if let Ok(s) = fs::read_to_string(path) { @@ -332,9 +252,7 @@ mod test { panic!("String wasn't read from file"); } } else { - panic!( - "Cannot find absolute path to test_presentation.json" - ); + panic!("Cannot find absolute path to test_presentation.json"); } } @@ -363,8 +281,7 @@ mod test { async fn test_service_items() { let mut db = get_db().await; let items = get_items(); - let json_item_file = - PathBuf::from("./test/test_service_items.json"); + let json_item_file = PathBuf::from("./test/test_service_items.json"); let result = process_service_items(&items, &mut db).await; if let Ok(path) = canonicalize(json_item_file) { if let Ok(s) = fs::read_to_string(path) { @@ -388,23 +305,16 @@ mod test { #[tokio::test] async fn test_store() { - let path = PathBuf::from( - "/home/chris/dev/lumina/src/rust/core/test.pres", - ); - let save_file = match File::create(path) { + let path = PathBuf::from("/home/chris/dev/lumina/src/rust/core/test.pres"); + let save_file = match File::create(path) { Ok(f) => f, Err(e) => panic!("Couldn't create save_file: {e}"), }; let mut db = get_db().await; let list = get_items(); - if let Ok(json) = process_service_items(&list, &mut db).await - { + if let Ok(json) = process_service_items(&list, &mut db).await { println!("{:?}", json); - match store_service_items( - &list, &mut db, &save_file, &json, - ) - .await - { + match store_service_items(&list, &mut db, &save_file, &json).await { Ok(_) => assert!(true), Err(e) => panic!("There was an error: {e}"), } diff --git a/src/rust/core/images.rs b/src/rust/core/images.rs index 9e7d832..96a74a0 100644 --- a/src/rust/core/images.rs +++ b/src/rust/core/images.rs @@ -5,9 +5,7 @@ use sqlx::{query_as, SqliteConnection}; use std::path::PathBuf; use tracing::error; -#[derive( - Clone, Debug, Default, PartialEq, Serialize, Deserialize, -)] +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct Image { pub id: i32, pub title: String, @@ -18,7 +16,7 @@ impl Model { pub fn load_from_db(&mut self) { let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { - let result = query_as!(Image, r#"SELECT title as "title!", file_path as "path!", id as "id: i32" from images"#).fetch_all(&mut self.db).await; + let result = query_as!(Image, r#"SELECT title as "title!", filePath as "path!", id as "id: i32" from images"#).fetch_all(&mut self.db).await; match result { Ok(v) => { for image in v.into_iter() { @@ -31,11 +29,9 @@ impl Model { } } -pub async fn get_image_from_db( - database_id: i32, - db: &mut SqliteConnection, -) -> Result { - Ok(query_as!(Image, r#"SELECT title as "title!", file_path as "path!", id as "id: i32" from images where id = ?"#, database_id).fetch_one(db).await?) + +pub async fn get_image_from_db(database_id: i32, db: &mut SqliteConnection) -> Result { + Ok(query_as!(Image, r#"SELECT title as "title!", filePath as "path!", id as "id: i32" from images where id = ?"#, database_id).fetch_one(db).await?) } #[cfg(test)] @@ -71,10 +67,7 @@ mod test { let new_image = test_image("A newer image".into()); match result { Ok(_) => { - assert_eq!( - &image, - image_model.find(|i| i.id == 0).unwrap() - ); + assert_eq!(&image, image_model.find(|i| i.id == 0).unwrap()); assert_ne!( &new_image, image_model.find(|i| i.id == 0).unwrap() diff --git a/src/rust/core/kinds.rs b/src/rust/core/kinds.rs index 7ffa001..3660b78 100644 --- a/src/rust/core/kinds.rs +++ b/src/rust/core/kinds.rs @@ -4,9 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::presentations::PresKind; -#[derive( - Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, -)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum ServiceItemKind { #[default] Song, diff --git a/src/rust/core/lib.rs b/src/rust/core/lib.rs index 10bb770..bb3db24 100644 --- a/src/rust/core/lib.rs +++ b/src/rust/core/lib.rs @@ -1,4 +1,3 @@ -pub mod file; pub mod images; pub mod kinds; pub mod model; @@ -7,3 +6,4 @@ pub mod service_items; pub mod slides; pub mod songs; pub mod videos; +pub mod file; diff --git a/src/rust/core/mod.rs b/src/rust/core/mod.rs deleted file mode 100644 index e359776..0000000 --- a/src/rust/core/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod service_items; diff --git a/src/rust/core/model.rs b/src/rust/core/model.rs index da3f695..bb94d12 100644 --- a/src/rust/core/model.rs +++ b/src/rust/core/model.rs @@ -36,7 +36,8 @@ impl Model { Ok(()) } - pub fn get_item(&self, index: i32) -> Option<&T> { + pub fn get_item(&self, index: i32) -> Option<&T> + { self.items.get(index as usize) } @@ -59,8 +60,10 @@ impl Default for Model { items: vec![], db: { let rt = tokio::runtime::Runtime::new().unwrap(); - rt.block_on(async { get_db().await }) - }, + rt.block_on(async { + get_db().await + }) + } } } } @@ -71,7 +74,9 @@ pub async fn get_db() -> SqliteConnection { data.push("library-db.sqlite3"); let mut db_url = String::from("sqlite://"); db_url.push_str(data.to_str().unwrap()); - SqliteConnection::connect(&db_url).await.expect("problems") + SqliteConnection::connect(&db_url) + .await + .expect("problems") } pub trait Modeling { diff --git a/src/rust/core/presentations.rs b/src/rust/core/presentations.rs index 41768b9..8f9b33b 100644 --- a/src/rust/core/presentations.rs +++ b/src/rust/core/presentations.rs @@ -1,16 +1,12 @@ +use std::path::PathBuf; use color_eyre::eyre::Result; use serde::{Deserialize, Serialize}; -use sqlx::{ - prelude::FromRow, query, sqlite::SqliteRow, Row, SqliteConnection, -}; -use std::path::PathBuf; +use sqlx::{prelude::FromRow, query, sqlite::SqliteRow, Row, SqliteConnection}; use tracing::error; use crate::model::Model; -#[derive( - Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, -)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum PresKind { Html, #[default] @@ -18,9 +14,7 @@ pub enum PresKind { Generic, } -#[derive( - Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, -)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct Presentation { pub id: i32, pub title: String, @@ -63,7 +57,7 @@ impl Model { pub fn load_from_db(&mut self) { let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { - let result = query!(r#"SELECT id as "id: i32", title, file_path as "path", html from presentations"#).fetch_all(&mut self.db).await; + let result = query!(r#"SELECT id as "id: i32", title, filePath as "path", html from presentations"#).fetch_all(&mut self.db).await; match result { Ok(v) => { for presentation in v.into_iter() { @@ -85,11 +79,8 @@ impl Model { } } -pub async fn get_presentation_from_db( - database_id: i32, - db: &mut SqliteConnection, -) -> Result { - let row = query(r#"SELECT id as "id: i32", title, file_path as "path", html from presentations where id = $1"#).bind(database_id).fetch_one(db).await?; +pub async fn get_presentation_from_db(database_id: i32, db: &mut SqliteConnection) -> Result { + let row = query(r#"SELECT id as "id: i32", title, filePath as "path", html from presentations where id = $1"#).bind(database_id).fetch_one(db).await?; Ok(Presentation::from_row(&row)?) } @@ -120,9 +111,7 @@ mod test { let mut presentation_model: Model = Model::default(); presentation_model.load_from_db(); - if let Some(presentation) = - presentation_model.find(|p| p.id == 54) - { + if let Some(presentation) = presentation_model.find(|p| p.id == 54) { let test_presentation = test_presentation(); assert_eq!(&test_presentation, presentation); } else { diff --git a/src/rust/core/service_items.rs b/src/rust/core/service_items.rs index b49c015..8224aff 100644 --- a/src/rust/core/service_items.rs +++ b/src/rust/core/service_items.rs @@ -15,7 +15,7 @@ pub struct ServiceItem { } #[derive(Debug, Default, PartialEq)] -pub struct ServiceItemModel { +struct ServiceItemModel { items: Vec, } @@ -52,9 +52,7 @@ impl From<&Image> for ServiceItem { impl From<&Presentation> for ServiceItem { fn from(presentation: &Presentation) -> Self { Self { - kind: ServiceItemKind::Presentation( - presentation.kind.clone(), - ), + kind: ServiceItemKind::Presentation(presentation.kind.clone()), database_id: presentation.id, ..Default::default() } @@ -62,10 +60,7 @@ impl From<&Presentation> for ServiceItem { } impl ServiceItemModel { - fn add_item( - &mut self, - item: impl Into, - ) -> Result<()> { + fn add_item(&mut self, item: impl Into) -> Result<()> { let service_item: ServiceItem = item.into(); self.items.push(service_item); Ok(()) @@ -99,6 +94,7 @@ mod test { } } + #[test] pub fn test_service_item() { let song = test_song(); @@ -108,16 +104,10 @@ mod test { let mut service_model = ServiceItemModel::default(); match service_model.add_item(&song) { Ok(_) => { - assert_eq!( - ServiceItemKind::Song, - service_model.items[0].kind - ); - assert_eq!( - ServiceItemKind::Presentation(PresKind::Html), - pres_item.kind - ); + assert_eq!(ServiceItemKind::Song, service_model.items[0].kind); + assert_eq!(ServiceItemKind::Presentation(PresKind::Html), pres_item.kind); assert_eq!(service_item, service_model.items[0]); - } + }, Err(e) => panic!("Problem adding item: {:?}", e), } } diff --git a/src/rust/core/slides.rs b/src/rust/core/slides.rs index 3de576a..726ffae 100644 --- a/src/rust/core/slides.rs +++ b/src/rust/core/slides.rs @@ -1,8 +1,4 @@ -use std::{ - error::Error, - fmt::Display, - path::{Path, PathBuf}, -}; +use std::{error::Error, fmt::Display, path::{Path, PathBuf}}; use color_eyre::eyre::{eyre, Result}; use serde::{Deserialize, Serialize}; @@ -14,9 +10,7 @@ use crate::{ presentations::Presentation, songs::Song, videos::Video, }; -#[derive( - Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize, -)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum TextAlignment { TopLeft, TopCenter, @@ -30,9 +24,7 @@ pub enum TextAlignment { BottomRight, } -#[derive( - Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, -)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct Background { pub path: PathBuf, pub kind: BackgroundKind, @@ -44,7 +36,7 @@ impl TryFrom for Background { let value = value.trim_start_matches("file://"); let path = PathBuf::from(value); if !path.exists() { - return Err(ParseError::DoesNotExist); + return Err(ParseError::DoesNotExist) } let extension = value.rsplit_once('.').unwrap_or_default(); match extension.1 { @@ -114,15 +106,11 @@ impl DatabaseError for ParseError { todo!() } - fn as_error_mut( - &mut self, - ) -> &mut (dyn Error + Send + Sync + 'static) { + fn as_error_mut(&mut self) -> &mut (dyn Error + Send + Sync + 'static) { todo!() } - fn into_error( - self: Box, - ) -> Box { + fn into_error(self: Box) -> Box { todo!() } @@ -140,15 +128,15 @@ impl Display for ParseError { Self::NonBackgroundFile => { "The file is not a recognized image or video type" } - Self::DoesNotExist => "This file doesn't exist", + Self::DoesNotExist => { + "This file doesn't exist" + } }; write!(f, "Error: {message}") } } -#[derive( - Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize, -)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum BackgroundKind { #[default] Image, diff --git a/src/rust/core/songs.rs b/src/rust/core/songs.rs index b1c955f..d259563 100644 --- a/src/rust/core/songs.rs +++ b/src/rust/core/songs.rs @@ -2,10 +2,7 @@ use std::{collections::HashMap, path::PathBuf}; use color_eyre::eyre::{eyre, Context, Result}; use serde::{Deserialize, Serialize}; -use sqlx::{ - query, query_as, sqlite::SqliteRow, FromRow, Row, - SqliteConnection, -}; +use sqlx::{query, query_as, sqlite::SqliteRow, FromRow, Row, SqliteConnection}; use tracing::{debug, error}; use crate::{ @@ -13,9 +10,7 @@ use crate::{ slides::{Background, TextAlignment}, }; -#[derive( - Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, -)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct Song { pub id: i32, pub title: String, @@ -61,24 +56,17 @@ impl FromRow<'_, SqliteRow> for Song { text_alignment: Some({ let horizontal_alignment: String = row.try_get(3)?; let vertical_alignment: String = row.try_get(4)?; - match ( - horizontal_alignment.to_lowercase().as_str(), - vertical_alignment.to_lowercase().as_str(), - ) { + match (horizontal_alignment.to_lowercase().as_str(), vertical_alignment.to_lowercase().as_str()) { ("left", "top") => TextAlignment::TopLeft, ("left", "center") => TextAlignment::MiddleLeft, ("left", "bottom") => TextAlignment::BottomLeft, ("center", "top") => TextAlignment::TopCenter, - ("center", "center") => { - TextAlignment::MiddleCenter - } - ("center", "bottom") => { - TextAlignment::BottomCenter - } + ("center", "center") => TextAlignment::MiddleCenter, + ("center", "bottom") => TextAlignment::BottomCenter, ("right", "top") => TextAlignment::TopRight, ("right", "center") => TextAlignment::MiddleRight, ("right", "bottom") => TextAlignment::BottomRight, - _ => TextAlignment::MiddleCenter, + _ => TextAlignment::MiddleCenter } }), font: row.try_get(6)?, @@ -87,20 +75,19 @@ impl FromRow<'_, SqliteRow> for Song { } } -pub async fn get_song_from_db( - index: i32, - db: &mut SqliteConnection, -) -> Result { - let row = query(r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs where id = $1"#).bind(index).fetch_one(db).await?; + +pub async fn get_song_from_db(index: i32, db: &mut SqliteConnection) -> Result { + let row = query(r#"SELECT vorder as "verse_order!", fontSize as "font_size!: i32", backgroundType as "background_type!", horizontalTextAlignment as "horizontal_text_alignment!", verticalTextAlignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs where id = $1"#).bind(index).fetch_one(db).await?; Ok(Song::from_row(&row)?) } + impl Model { pub fn load_from_db(&mut self) { // static DATABASE_URL: &str = "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3"; let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { - let result = query(r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs"#).fetch_all(&mut self.db).await; + let result = query(r#"SELECT vorder as "verse_order!", fontSize as "font_size!: i32", backgroundType as "background_type!", horizontalTextAlignment as "horizontal_text_alignment!", verticalTextAlignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs"#).fetch_all(&mut self.db).await; match result { Ok(s) => { for song in s.into_iter() { diff --git a/src/rust/core/test.pres b/src/rust/core/test.pres deleted file mode 100644 index e69de29..0000000 diff --git a/src/rust/core/videos.rs b/src/rust/core/videos.rs index 0329916..c7cdb3d 100644 --- a/src/rust/core/videos.rs +++ b/src/rust/core/videos.rs @@ -5,9 +5,7 @@ use sqlx::{query_as, SqliteConnection}; use std::path::PathBuf; use tracing::error; -#[derive( - Clone, Debug, Default, PartialEq, Serialize, Deserialize, -)] +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct Video { pub id: i32, pub title: String, @@ -21,7 +19,7 @@ impl Model