Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

config.rs 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. use std::collections::*;
  2. use std::convert::TryFrom;
  3. use std::default::Default;
  4. use std::io;
  5. use std::path::PathBuf;
  6. use futures::prelude::*;
  7. use tokio::fs as tokiofs;
  8. use tokio::prelude::*;
  9. use toml;
  10. use serde::Deserialize;
  11. use matrix_sdk::identifiers::RoomId;
  12. // FIXME Some of these error types are only used in the main module.
  13. #[derive(Debug)]
  14. pub enum Error {
  15. // TODO Reconcile these different parse errors.
  16. ParseFile(PathBuf),
  17. ParseToml(toml::de::Error),
  18. ParseIdentifier,
  19. Io(io::Error),
  20. }
  21. impl From<io::Error> for Error {
  22. fn from(f: io::Error) -> Self {
  23. Self::Io(f)
  24. }
  25. }
  26. impl From<toml::de::Error> for Error {
  27. fn from(f: toml::de::Error) -> Self {
  28. Self::ParseToml(f)
  29. }
  30. }
  31. #[derive(Default, Debug)]
  32. pub struct Config {
  33. pub accounts: HashMap<String, Account>,
  34. pub spool_dirs: Vec<SpoolDir>,
  35. }
  36. #[derive(Clone, Debug)]
  37. pub struct Account {
  38. pub homeserver: String,
  39. pub display: Option<String>,
  40. pub device_id: Option<String>,
  41. pub auth: Auth,
  42. }
  43. #[derive(Clone, Debug)]
  44. pub enum Auth {
  45. UsernamePass(String, String),
  46. }
  47. #[derive(Debug)]
  48. pub struct SpoolDir {
  49. pub path: PathBuf,
  50. pub send_delay_sec: u32,
  51. pub sender_acct_label: String,
  52. pub dest_room_id: RoomId,
  53. }
  54. #[derive(Clone, Debug, Deserialize)]
  55. pub struct ConfigFile {
  56. acct: Vec<ConfigAccount>,
  57. watch: Vec<ConfigWatch>,
  58. }
  59. #[derive(Clone, Debug, Deserialize)]
  60. pub struct ConfigAccount {
  61. label: String,
  62. homeserver: String,
  63. username: String,
  64. password: String,
  65. }
  66. #[derive(Clone, Debug, Deserialize)]
  67. pub struct ConfigWatch {
  68. sender: String,
  69. path: String,
  70. destroom: String,
  71. }
  72. pub async fn find_configs(search_dir: &PathBuf) -> Result<Vec<PathBuf>, Error> {
  73. let items: Vec<tokiofs::DirEntry> = tokiofs::read_dir(search_dir).await?.try_collect().await?;
  74. Ok(items
  75. .into_iter()
  76. .filter(|de| {
  77. de.file_name()
  78. .to_str()
  79. .map(|s| s.ends_with(".toml"))
  80. .unwrap_or(false)
  81. })
  82. .map(|e| e.path())
  83. .collect())
  84. }
  85. pub async fn parse_configs(paths: &Vec<PathBuf>) -> Result<Config, Error> {
  86. let mut conf = Config::default();
  87. for p in paths {
  88. println!("Reading config: {}", p.to_str().unwrap_or("[non-UTF-8]"));
  89. let val = match load_toml(p).await {
  90. Ok(t) => t,
  91. Err(_) => {
  92. println!("warning: error loading config, skipping: {:?}", p);
  93. continue;
  94. }
  95. };
  96. // Ingest the accounts.
  97. for a in val.acct {
  98. if conf.accounts.contains_key(&a.label) {
  99. eprintln!("warning: ignoring duplicate account entry for {}", a.label);
  100. continue;
  101. }
  102. let acct = Account {
  103. homeserver: a.homeserver,
  104. auth: Auth::UsernamePass(a.username, a.password),
  105. device_id: None,
  106. display: None,
  107. };
  108. conf.accounts.insert(a.label, acct);
  109. }
  110. // Ingest the watches.
  111. for s in val.watch {
  112. let sd = SpoolDir {
  113. path: PathBuf::from(s.path),
  114. send_delay_sec: 0,
  115. sender_acct_label: s.sender,
  116. dest_room_id: RoomId::try_from(s.destroom.as_str())
  117. .map_err(|_| Error::ParseIdentifier)?,
  118. };
  119. conf.spool_dirs.push(sd);
  120. }
  121. }
  122. Ok(conf)
  123. }
  124. async fn load_toml(path: &PathBuf) -> Result<ConfigFile, Error> {
  125. let mut buf = Vec::new();
  126. let mut f = tokiofs::File::open(path).await?;
  127. let _ = f.read_to_end(&mut buf).await?;
  128. toml::from_slice(&buf).map_err(|e| {
  129. eprintln!("warning: parsing file {:?}", e);
  130. Error::ParseFile(path.clone())
  131. })
  132. }