Skip to main content

cadmus_core/task/
import.rs

1//! Background task that imports library contents from disk.
2
3use std::sync::mpsc::Sender;
4
5use crate::db::Database;
6use crate::library::importer;
7use crate::library::Library;
8use crate::settings::Settings;
9use crate::task::{BackgroundTask, ShutdownSignal, TaskId};
10use crate::view::{Event, ViewId, ID_FEEDER};
11
12/// Runs a full import for one library (or all libraries when `library_index` is `None`).
13pub struct ImportTask {
14    database: Database,
15    settings: Settings,
16    /// Which library to import. `None` means all configured libraries.
17    library_index: Option<usize>,
18}
19
20impl ImportTask {
21    pub fn new(database: Database, settings: Settings, library_index: Option<usize>) -> Self {
22        Self {
23            database,
24            settings,
25            library_index,
26        }
27    }
28
29    #[cfg_attr(feature = "tracing", tracing::instrument(skip(hub, shutdown, self)))]
30    fn run_for_index(&self, index: usize, hub: &Sender<Event>, shutdown: &ShutdownSignal) {
31        let lib_settings = match self.settings.libraries.get(index) {
32            Some(s) => s,
33            None => {
34                tracing::warn!(
35                    library_index = index,
36                    "library index out of range, skipping"
37                );
38                return;
39            }
40        };
41
42        let library = match Library::new(&lib_settings.path, &self.database, &lib_settings.name) {
43            Ok(lib) => lib,
44            Err(e) => {
45                tracing::error!(error = %e, library_index = index, "failed to open library for import");
46                return;
47            }
48        };
49
50        let notif_id = ViewId::MessageNotif(ID_FEEDER.next());
51        importer::run(
52            &library.db,
53            library.library_id,
54            &library.home,
55            &self.settings.import,
56            hub,
57            notif_id,
58            shutdown,
59        );
60    }
61}
62
63impl BackgroundTask for ImportTask {
64    fn id(&self) -> TaskId {
65        TaskId::Import
66    }
67
68    #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
69    fn run(&mut self, hub: &Sender<Event>, shutdown: &ShutdownSignal) {
70        match self.library_index {
71            Some(index) => {
72                self.run_for_index(index, hub, shutdown);
73            }
74            None => {
75                for index in 0..self.settings.libraries.len() {
76                    if shutdown.should_stop() {
77                        return;
78                    }
79                    self.run_for_index(index, hub, shutdown);
80                }
81            }
82        }
83    }
84
85    fn finished_event(&self) -> Option<Event> {
86        Some(Event::ImportFinished {
87            library_index: self.library_index,
88        })
89    }
90}