about summary refs log tree commit diff
path: root/src/database
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2021-09-27 15:33:39 +0300
committerVika <vika@fireburn.ru>2021-09-27 15:33:39 +0300
commit1e204011e0e99de939475d4ce3b23b7b578f3b20 (patch)
tree92a1836237f2916ee44b31290532976c79f609f6 /src/database
parent9203dd3ef7b62489116e7b7fe0b9d288c3389c78 (diff)
downloadkittybox-1e204011e0e99de939475d4ce3b23b7b578f3b20.tar.zst
Implemented FileStorage::get_setting and FileStorage::set_setting
Diffstat (limited to 'src/database')
-rw-r--r--src/database/file/mod.rs55
1 files changed, 53 insertions, 2 deletions
diff --git a/src/database/file/mod.rs b/src/database/file/mod.rs
index ff5ad13..d641779 100644
--- a/src/database/file/mod.rs
+++ b/src/database/file/mod.rs
@@ -261,10 +261,61 @@ impl Storage for FileStorage {
     }
 
     async fn get_setting<'a>(&self, setting: &'a str, user: &'a str) -> Result<String> {
-        todo!()
+        let url = http_types::Url::parse(user).expect("Couldn't parse a URL");
+        let mut path = relative_path::RelativePathBuf::new();
+        path.push(url.origin().ascii_serialization());
+        path.push("settings");
+
+        let path = path.to_path(&self.root_dir);
+        let lock = get_lockable_file(File::open(path).await?).await;
+        let guard = lock.read()?;
+
+        let mut content = String::new();
+        (&mut &*guard).read_to_string(&mut content).await?;
+        drop(guard);
+        let settings: HashMap<String, String> = serde_json::from_str(&content)?;
+        // XXX consider returning string slices instead of cloning a string every time
+        // it might come with a performance hit and/or memory usage inflation
+        settings.get(setting)
+            .map(|s| s.clone())
+            .ok_or_else(|| StorageError::new(ErrorKind::Backend, "Setting not set"))
+
     }
 
     async fn set_setting<'a>(&self, setting: &'a str, user: &'a str, value: &'a str) -> Result<()> {
-        todo!()
+        let url = http_types::Url::parse(user).expect("Couldn't parse a URL");
+        let mut path = relative_path::RelativePathBuf::new();
+        path.push(url.origin().ascii_serialization());
+        path.push("settings");
+
+        let path = path.to_path(&self.root_dir);
+
+        let parent = path.parent().unwrap().to_owned();
+        if !spawn_blocking(move || parent.is_dir()).await {
+            async_std::fs::create_dir_all(path.parent().unwrap()).await?;
+        }
+
+        let file = OpenOptions::new()
+            .write(true)
+            .read(true)
+            .truncate(false)
+            .create(true)
+            .open(&path).await?;
+        let mut lock = get_lockable_file(file).await;
+        let mut guard = lock.write()?;
+
+        let mut content = String::new();
+        guard.read_to_string(&mut content).await?;
+        let mut settings: HashMap<String, String> = if content.len() == 0 {
+            HashMap::default()
+        } else {
+            serde_json::from_str(&content)?
+        };
+
+        settings.insert(setting.to_string(), value.to_string());
+        guard.seek(std::io::SeekFrom::Start(0)).await?;
+        guard.set_len(0).await?;
+        guard.write_all(serde_json::to_string(&settings)?.as_bytes()).await?;
+        Ok(())
     }
 }