feat: add setup command to publish the labeler declaration
`cargo run --bin setup -- declare` writes app.bsky.labeler.service/self with one inform-severity label per city and opts out of reports. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d1b01e180d
commit
049a198b1c
1 file changed
+80
@@ -0,0 +1,80 @@
|
||||
//! One-time labeler setup.
|
||||
//!
|
||||
//! `cargo run --bin setup -- declare` publishes the labeler declaration
|
||||
//! (`app.bsky.labeler.service/self`) with one label per city. This is what
|
||||
//! gives the account a Subscribe button. Safe to re-run after editing the list.
|
||||
use anyhow::{Result, bail};
|
||||
use cities_labeler::cities::Cities;
|
||||
use cities_labeler::config::Config;
|
||||
use cities_labeler::login;
|
||||
use jacquard::api::app_bsky::labeler::LabelerPolicies;
|
||||
use jacquard::api::app_bsky::labeler::service::Service;
|
||||
use jacquard::api::com_atproto::label::{
|
||||
LabelValue, LabelValueDefinition, LabelValueDefinitionBlurs,
|
||||
LabelValueDefinitionDefaultSetting, LabelValueDefinitionSeverity, LabelValueDefinitionStrings,
|
||||
};
|
||||
use jacquard::prelude::*;
|
||||
use jacquard::types::language::Language;
|
||||
use jacquard::types::recordkey::RecordKey;
|
||||
use jacquard::types::string::Datetime;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let config = Config::from_env()?;
|
||||
match std::env::args().nth(1).as_deref() {
|
||||
Some("declare") => declare(&config).await,
|
||||
_ => bail!("usage: setup declare"),
|
||||
}
|
||||
}
|
||||
|
||||
async fn declare(config: &Config) -> Result<()> {
|
||||
let cities = Cities::load(&config.cities_path)?;
|
||||
let (agent, did) = login(&config.handle, &config.app_password).await?;
|
||||
|
||||
let definitions: Vec<LabelValueDefinition> = cities
|
||||
.iter()
|
||||
.map(|city| LabelValueDefinition {
|
||||
identifier: city.id.as_str().into(),
|
||||
// a neutral badge, shown by default, never hiding content
|
||||
severity: LabelValueDefinitionSeverity::Inform,
|
||||
blurs: LabelValueDefinitionBlurs::None,
|
||||
default_setting: Some(LabelValueDefinitionDefaultSetting::Warn),
|
||||
adult_only: Some(false),
|
||||
locales: vec![LabelValueDefinitionStrings {
|
||||
lang: Language::new_static("en").expect("valid language tag"),
|
||||
name: city.display().into(),
|
||||
description: format!("Chose {} as their city.", city.display()).into(),
|
||||
extra_data: None,
|
||||
}],
|
||||
extra_data: None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let service: Service = Service {
|
||||
created_at: Datetime::now(),
|
||||
labels: None,
|
||||
policies: LabelerPolicies {
|
||||
label_values: cities
|
||||
.iter()
|
||||
.map(|c| LabelValue::Other(c.id.as_str().into()))
|
||||
.collect(),
|
||||
label_value_definitions: Some(definitions),
|
||||
extra_data: None,
|
||||
},
|
||||
// these declare which reports the labeler reviews: none
|
||||
reason_types: Some(vec![]),
|
||||
subject_types: Some(vec![]),
|
||||
subject_collections: None,
|
||||
extra_data: None,
|
||||
};
|
||||
|
||||
let output = agent
|
||||
.put_record(RecordKey::any_static("self")?, service)
|
||||
.await?;
|
||||
println!(
|
||||
"published {} with {} labels for {did}",
|
||||
output.uri,
|
||||
cities.len()
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
Reference in new issue
Block a user