|
|
|
@ -32,6 +32,9 @@ pub struct StoreOptions { |
|
|
|
|
pub store_dir: String, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const DEFAULT_LOCALE_NAME : &str = "en"; |
|
|
|
|
const DEFAULT_LOCALE_JSON : &str = include_str!("../../locales/en.json"); |
|
|
|
|
|
|
|
|
|
impl ConfigStore { |
|
|
|
|
/// Create a new instance of the store.
|
|
|
|
|
/// If a path is given, it will try to load the content from a file.
|
|
|
|
@ -76,13 +79,30 @@ impl ConfigStore { |
|
|
|
|
|
|
|
|
|
debug!("Using common config:\n{:#?}", config); |
|
|
|
|
|
|
|
|
|
let groups_path = base_dir.join("groups"); |
|
|
|
|
let groups_path = if config.groups_dir.starts_with('/') { |
|
|
|
|
PathBuf::from(&config.groups_dir) |
|
|
|
|
} else { |
|
|
|
|
base_dir.join(&config.groups_dir) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
if !groups_path.exists() { |
|
|
|
|
debug!("Creating groups directory"); |
|
|
|
|
tokio::fs::create_dir_all(&groups_path).await?; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let locales_path = base_dir.join("locales"); |
|
|
|
|
let locales_path = if config.locales_dir.starts_with('/') { |
|
|
|
|
PathBuf::from(&config.locales_dir) |
|
|
|
|
} else { |
|
|
|
|
base_dir.join(&config.locales_dir) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// warn, this is usually not a good idea beside for testing
|
|
|
|
|
if config.max_catchup_notifs == 0 { |
|
|
|
|
warn!("Missed notifications catch-up is disabled!"); |
|
|
|
|
} |
|
|
|
|
if config.max_catchup_statuses == 0 { |
|
|
|
|
warn!("Missed statuses catch-up is disabled!"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Ok(Self { |
|
|
|
|
store_path: base_dir.to_owned(), |
|
|
|
@ -107,7 +127,7 @@ impl ConfigStore { |
|
|
|
|
|
|
|
|
|
let group_dir = self.groups_path.join(&opts.acct); |
|
|
|
|
|
|
|
|
|
let data = GroupConfig::from_appdata(opts.acct.clone(), appdata, group_dir).await?; |
|
|
|
|
let _data = GroupConfig::from_appdata(opts.acct.clone(), appdata, group_dir).await?; |
|
|
|
|
|
|
|
|
|
// save & persist
|
|
|
|
|
|
|
|
|
@ -149,7 +169,7 @@ impl ConfigStore { |
|
|
|
|
config.set_appdata(appdata); |
|
|
|
|
config.save_if_needed(true).await?; |
|
|
|
|
|
|
|
|
|
let group_account = match client.verify_credentials().await { |
|
|
|
|
let _group_account = match client.verify_credentials().await { |
|
|
|
|
Ok(account) => { |
|
|
|
|
info!( |
|
|
|
|
"Group account verified: @{}, \"{}\"", |
|
|
|
@ -167,6 +187,9 @@ impl ConfigStore { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub async fn find_locales(&mut self) { |
|
|
|
|
// Load the default locale, it will be used as fallback to fill-in missing keys
|
|
|
|
|
self.load_locale(DEFAULT_LOCALE_NAME, DEFAULT_LOCALE_JSON, true); |
|
|
|
|
|
|
|
|
|
if !self.locales_path.is_dir() { |
|
|
|
|
debug!("No locales path set!"); |
|
|
|
|
return; |
|
|
|
@ -175,7 +198,7 @@ impl ConfigStore { |
|
|
|
|
let entries = match std::fs::read_dir(&self.locales_path) { |
|
|
|
|
Ok(ee) => ee, |
|
|
|
|
Err(e) => { |
|
|
|
|
warn!("Error listing locales"); |
|
|
|
|
warn!("Error listing locales: {}", e); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
@ -189,13 +212,8 @@ impl ConfigStore { |
|
|
|
|
|
|
|
|
|
match tokio::fs::read(&path).await { |
|
|
|
|
Ok(f) => { |
|
|
|
|
if let Ok(tr) = serde_json::from_slice::<TranslationTable>(&f) { |
|
|
|
|
let locale_name = path.file_stem().unwrap_or_default().to_string_lossy().to_string(); |
|
|
|
|
debug!("Loaded locale: {}", locale_name); |
|
|
|
|
self.config.tr.insert(locale_name, tr); |
|
|
|
|
} else { |
|
|
|
|
error!("Failed to parse locale file {}", path.display()); |
|
|
|
|
} |
|
|
|
|
let locale_name = path.file_stem().unwrap_or_default().to_string_lossy(); |
|
|
|
|
self.load_locale(&locale_name, &String::from_utf8_lossy(&f), false); |
|
|
|
|
}, |
|
|
|
|
Err(e) => { |
|
|
|
|
error!("Failed to read locale file {}: {}", path.display(), e); |
|
|
|
@ -206,6 +224,31 @@ impl ConfigStore { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn load_locale(&mut self, locale_name: &str, locale_json: &str, is_default: bool) { |
|
|
|
|
if let Ok(mut tr) = serde_json::from_str::<TranslationTable>(locale_json) { |
|
|
|
|
debug!("Loaded locale: {}", locale_name); |
|
|
|
|
|
|
|
|
|
if !is_default { |
|
|
|
|
let def_tr = self.config.tr.get(DEFAULT_LOCALE_NAME).expect("Default locale not loaded!"); |
|
|
|
|
|
|
|
|
|
for (k, v) in def_tr.entries() { |
|
|
|
|
if !tr.translation_exists(k) { |
|
|
|
|
warn!("locale \"{}\" is missing \"{}\", default: {:?}", |
|
|
|
|
locale_name, |
|
|
|
|
k, |
|
|
|
|
def_tr.get_translation_raw(k).unwrap()); |
|
|
|
|
|
|
|
|
|
tr.add_translation(k, v); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self.config.tr.insert(locale_name.to_owned(), tr); |
|
|
|
|
} else { |
|
|
|
|
error!("Failed to parse locale {}", locale_name); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Spawn existing group using saved creds
|
|
|
|
|
pub async fn spawn_groups(self) -> Result<Vec<GroupHandle>, GroupError> { |
|
|
|
|
info!("Starting group services for groups in {}", self.groups_path.display()); |
|
|
|
|