upub_cli/
lib.rs

1mod count;
2pub use count::*;
3
4mod fix_activities;
5pub use fix_activities::*;
6
7mod fetch;
8pub use fetch::*;
9
10mod faker;
11pub use faker::*;
12
13mod relay;
14pub use relay::*;
15
16mod register;
17pub use register::*;
18
19mod reset;
20pub use reset::*;
21
22mod update;
23pub use update::*;
24
25mod nuke;
26pub use nuke::*;
27
28mod thread;
29pub use thread::*;
30
31mod cloak;
32pub use cloak::*;
33
34mod import;
35pub use import::*;
36
37mod export;
38pub use export::*;
39
40mod attachments;
41pub use attachments::*;
42
43// TODO naming is going kind of all over the place, should probably rename lot of these...
44
45#[derive(Debug, Clone, clap::Subcommand)]
46pub enum CliCommand {
47	/// generate fake user, note and activity
48	Faker{
49		/// how many fake statuses to insert for root user
50		count: u64,
51	},
52
53	/// fetch a single AP object
54	Fetch {
55		/// object id, or uri, to fetch
56		uri: String,
57
58		#[arg(long, default_value_t = false)]
59		/// store fetched object in local db
60		save: bool,
61
62		#[arg(long)]
63		/// use this actor's private key to fetch
64		fetch_as: Option<String>,
65	},
66
67	/// act on remote relay actors at instance level
68	Relay {
69		#[clap(subcommand)]
70		/// action to take against this relay
71		action: RelayCommand,
72	},
73
74	/// recount object statistics
75	Count {
76		#[arg(long, default_value_t = false)]
77		/// fix likes counts for posts
78		likes: bool,
79
80		#[arg(long, default_value_t = false)]
81		/// fix shares counts for posts
82		shares: bool,
83
84		#[arg(long, default_value_t = false)]
85		/// fix replies counts for posts
86		replies: bool,
87	},
88
89	/// update remote actors
90	Update {
91		#[arg(long, short, default_value_t = 10)]
92		/// number of days after which actors should get updated
93		days: i64,
94
95		#[arg(long)]
96		/// stop after updating this many actors
97		limit: Option<u64>,
98	},
99
100	/// register a new local user
101	Register {
102		/// username for new user, must be unique locally and cannot be changed
103		username: String,
104
105		/// password for new user
106		// TODO get this with getpass rather than argv!!!!
107		password: String,
108
109		/// display name for new user
110		#[arg(long = "name")]
111		display_name: Option<String>,
112
113		/// summary text for new user
114		#[arg(long = "summary")]
115		summary: Option<String>,
116
117		/// url for avatar image of new user
118		#[arg(long = "avatar")]
119		avatar_url: Option<String>,
120
121		/// url for banner image of new user
122		#[arg(long = "banner")]
123		banner_url: Option<String>,
124	},
125
126	/// reset password of a user
127	Reset {
128		/// user login
129		login: String,
130
131		/// new password
132		password: String,
133	},
134
135	/// break all user relations so that instance can be shut down
136	Nuke {
137		/// unless this is set, nuke will be a dry run
138		#[arg(long, default_value_t = false)]
139		for_real: bool,
140
141		/// also send Delete activities for all local objects
142		#[arg(long, default_value_t = false)]
143		delete_objects: bool,
144	},
145
146	/// attempt to fix broken threads and completely gather their context
147	Thread {
148		
149	},
150
151	/// replaces all attachment urls with proxied local versions (only useful for old instances)
152	Cloak {
153		/// also cloak objects image urls
154		#[arg(long, default_value_t = false)]
155		objects: bool,
156
157		/// also cloak actor images
158		#[arg(long, default_value_t = false)]
159		actors: bool,
160
161		/// also replace urls inside post contents
162		#[arg(long, default_value_t = false)]
163		contents: bool,
164
165		/// also re-cloak already cloaked urls, useful if changing cloak secret
166		#[arg(long, default_value_t = false)]
167		re_cloak: bool,
168	},
169
170	/// restore activities links, only needed for very old installs
171	FixActivities {
172		/// restore like activity links
173		#[arg(long, default_value_t = false)]
174		likes: bool,
175
176		/// restore announces activity links
177		#[arg(long, default_value_t = false)]
178		announces: bool,
179	},
180
181	/// import posts coming from another instance: replay them as local
182	Import {
183		/// json backup file: must be an array of objects
184		file: std::path::PathBuf,
185
186		/// previous actor id, used in these posts
187		#[arg(long)]
188		from: String,
189
190		/// current actor id, will be replaced in all posts
191		#[arg(long)]
192		to: String,
193
194		/// base url where attachments are hosted now, if not given attachments will be kept unchanged
195		#[arg(short, long)]
196		attachment_base: Option<String>
197	},
198
199	/// export posts from a local actor as a json array, like an outbox
200	Export {
201		/// local username of actor to export
202		actor: String,
203
204		/// json backup file: will be an array of objects
205		file: std::path::PathBuf,
206
207		/// serialize json in human-readable form
208		#[arg(long, default_value_t = false)]
209		pretty: bool,
210	},
211
212	/// fix attachments types based on mediaType
213	Attachments {
214
215	},
216}
217
218pub async fn run(ctx: upub::Context, command: CliCommand) -> Result<(), Box<dyn std::error::Error>> {
219	tracing::info!("running cli task: {command:?}");
220	match command {
221		CliCommand::Faker { count } =>
222			Ok(faker(ctx, count as i64).await?),
223		CliCommand::Fetch { uri, save, fetch_as } =>
224			Ok(fetch(ctx, uri, save, fetch_as).await?),
225		CliCommand::Relay { action } =>
226			Ok(relay(ctx, action).await?),
227		CliCommand::Count { likes, shares, replies } =>
228			Ok(count(ctx, likes, shares, replies).await?),
229		CliCommand::Update { days, limit } =>
230			Ok(update_users(ctx, days, limit).await?),
231		CliCommand::Register { username, password, display_name, summary, avatar_url, banner_url } =>
232			Ok(register(ctx, username, password, display_name, summary, avatar_url, banner_url).await?),
233		CliCommand::Reset { login, password } =>
234			Ok(reset(ctx, login, password).await?),
235		CliCommand::Nuke { for_real, delete_objects } =>
236			Ok(nuke(ctx, for_real, delete_objects).await?),
237		CliCommand::Thread { } =>
238			Ok(thread(ctx).await?),
239		CliCommand::Cloak { objects, actors, contents, re_cloak } =>
240			Ok(cloak(ctx, contents, objects, actors, re_cloak).await?),
241		CliCommand::FixActivities { likes, announces } =>
242			Ok(fix_activities(ctx, likes, announces).await?),
243		CliCommand::Import { file, from, to, attachment_base } =>
244			Ok(import(ctx, file, from, to, attachment_base).await?),
245		CliCommand::Export { actor, file, pretty } =>
246			Ok(export(ctx, actor, file, pretty).await?),
247		CliCommand::Attachments {  } =>
248			Ok(fix_attachments_types(ctx).await?),
249	}
250}