1 // This is for db migrations that require code
3 sql_types::{Nullable, Text},
7 generate_apub_endpoint,
8 generate_followers_url,
10 generate_shared_inbox_url,
13 use lemmy_db_queries::{
14 source::{comment::Comment_, post::Post_, private_message::PrivateMessage_},
17 use lemmy_db_schema::{
21 community::{Community, CommunityForm},
22 person::{Person, PersonForm},
24 private_message::PrivateMessage,
27 use lemmy_utils::{apub::generate_actor_keypair, LemmyError};
30 pub fn run_advanced_migrations(
32 protocol_and_hostname: &str,
33 ) -> Result<(), LemmyError> {
34 user_updates_2020_04_02(conn, protocol_and_hostname)?;
35 community_updates_2020_04_02(conn, protocol_and_hostname)?;
36 post_updates_2020_04_03(conn, protocol_and_hostname)?;
37 comment_updates_2020_04_03(conn, protocol_and_hostname)?;
38 private_message_updates_2020_05_05(conn, protocol_and_hostname)?;
39 post_thumbnail_url_updates_2020_07_27(conn, protocol_and_hostname)?;
40 apub_columns_2021_02_02(conn)?;
45 fn user_updates_2020_04_02(
47 protocol_and_hostname: &str,
48 ) -> Result<(), LemmyError> {
49 use lemmy_db_schema::schema::person::dsl::*;
51 info!("Running user_updates_2020_04_02");
53 // Update the actor_id, private_key, and public_key, last_refreshed_at
54 let incorrect_persons = person
55 .filter(actor_id.like("http://changeme_%"))
56 .filter(local.eq(true))
57 .load::<Person>(conn)?;
59 for cperson in &incorrect_persons {
60 let keypair = generate_actor_keypair()?;
62 let form = PersonForm {
63 name: cperson.name.to_owned(),
64 actor_id: Some(generate_apub_endpoint(
67 protocol_and_hostname,
69 private_key: Some(Some(keypair.private_key)),
70 public_key: Some(Some(keypair.public_key)),
71 last_refreshed_at: Some(naive_now()),
72 ..PersonForm::default()
75 Person::update(conn, cperson.id, &form)?;
78 info!("{} person rows updated.", incorrect_persons.len());
83 fn community_updates_2020_04_02(
85 protocol_and_hostname: &str,
86 ) -> Result<(), LemmyError> {
87 use lemmy_db_schema::schema::community::dsl::*;
89 info!("Running community_updates_2020_04_02");
91 // Update the actor_id, private_key, and public_key, last_refreshed_at
92 let incorrect_communities = community
93 .filter(actor_id.like("http://changeme_%"))
94 .filter(local.eq(true))
95 .load::<Community>(conn)?;
97 for ccommunity in &incorrect_communities {
98 let keypair = generate_actor_keypair()?;
99 let community_actor_id = generate_apub_endpoint(
100 EndpointType::Community,
102 protocol_and_hostname,
105 let form = CommunityForm {
106 name: ccommunity.name.to_owned(),
107 title: ccommunity.title.to_owned(),
108 description: ccommunity.description.to_owned(),
113 actor_id: Some(community_actor_id.to_owned()),
114 local: Some(ccommunity.local),
115 private_key: Some(keypair.private_key),
116 public_key: Some(keypair.public_key),
117 last_refreshed_at: Some(naive_now()),
119 icon: Some(ccommunity.icon.to_owned()),
120 banner: Some(ccommunity.banner.to_owned()),
123 shared_inbox_url: None,
126 Community::update(conn, ccommunity.id, &form)?;
129 info!("{} community rows updated.", incorrect_communities.len());
134 fn post_updates_2020_04_03(
136 protocol_and_hostname: &str,
137 ) -> Result<(), LemmyError> {
138 use lemmy_db_schema::schema::post::dsl::*;
140 info!("Running post_updates_2020_04_03");
143 let incorrect_posts = post
144 .filter(ap_id.like("http://changeme_%"))
145 .filter(local.eq(true))
146 .load::<Post>(conn)?;
148 for cpost in &incorrect_posts {
149 let apub_id = generate_apub_endpoint(
151 &cpost.id.to_string(),
152 protocol_and_hostname,
154 Post::update_ap_id(conn, cpost.id, apub_id)?;
157 info!("{} post rows updated.", incorrect_posts.len());
162 fn comment_updates_2020_04_03(
164 protocol_and_hostname: &str,
165 ) -> Result<(), LemmyError> {
166 use lemmy_db_schema::schema::comment::dsl::*;
168 info!("Running comment_updates_2020_04_03");
171 let incorrect_comments = comment
172 .filter(ap_id.like("http://changeme_%"))
173 .filter(local.eq(true))
174 .load::<Comment>(conn)?;
176 for ccomment in &incorrect_comments {
177 let apub_id = generate_apub_endpoint(
178 EndpointType::Comment,
179 &ccomment.id.to_string(),
180 protocol_and_hostname,
182 Comment::update_ap_id(conn, ccomment.id, apub_id)?;
185 info!("{} comment rows updated.", incorrect_comments.len());
190 fn private_message_updates_2020_05_05(
192 protocol_and_hostname: &str,
193 ) -> Result<(), LemmyError> {
194 use lemmy_db_schema::schema::private_message::dsl::*;
196 info!("Running private_message_updates_2020_05_05");
199 let incorrect_pms = private_message
200 .filter(ap_id.like("http://changeme_%"))
201 .filter(local.eq(true))
202 .load::<PrivateMessage>(conn)?;
204 for cpm in &incorrect_pms {
205 let apub_id = generate_apub_endpoint(
206 EndpointType::PrivateMessage,
208 protocol_and_hostname,
210 PrivateMessage::update_ap_id(conn, cpm.id, apub_id)?;
213 info!("{} private message rows updated.", incorrect_pms.len());
218 fn post_thumbnail_url_updates_2020_07_27(
220 protocol_and_hostname: &str,
221 ) -> Result<(), LemmyError> {
222 use lemmy_db_schema::schema::post::dsl::*;
224 info!("Running post_thumbnail_url_updates_2020_07_27");
226 let domain_prefix = format!("{}/pictrs/image/", protocol_and_hostname,);
228 let incorrect_thumbnails = post.filter(thumbnail_url.not_like("http%"));
230 // Prepend the rows with the update
231 let res = diesel::update(incorrect_thumbnails)
235 .into_sql::<Nullable<Text>>()
236 .concat(thumbnail_url),
239 .get_results::<Post>(conn)?;
241 info!("{} Post thumbnail_url rows updated.", res.len());
246 /// We are setting inbox and follower URLs for local and remote actors alike, because for now
247 /// all federated instances are also Lemmy and use the same URL scheme.
248 fn apub_columns_2021_02_02(conn: &PgConnection) -> Result<(), LemmyError> {
249 info!("Running apub_columns_2021_02_02");
251 use lemmy_db_schema::schema::person::dsl::*;
253 .filter(inbox_url.like("http://changeme_%"))
254 .load::<Person>(conn)?;
257 let inbox_url_ = generate_inbox_url(&p.actor_id)?;
258 let shared_inbox_url_ = generate_shared_inbox_url(&p.actor_id)?;
259 diesel::update(person.find(p.id))
261 inbox_url.eq(inbox_url_),
262 shared_inbox_url.eq(shared_inbox_url_),
264 .get_result::<Person>(conn)?;
269 use lemmy_db_schema::schema::community::dsl::*;
270 let communities = community
271 .filter(inbox_url.like("http://changeme_%"))
272 .load::<Community>(conn)?;
274 for c in &communities {
275 let followers_url_ = generate_followers_url(&c.actor_id)?;
276 let inbox_url_ = generate_inbox_url(&c.actor_id)?;
277 let shared_inbox_url_ = generate_shared_inbox_url(&c.actor_id)?;
278 diesel::update(community.find(c.id))
280 followers_url.eq(followers_url_),
281 inbox_url.eq(inbox_url_),
282 shared_inbox_url.eq(shared_inbox_url_),
284 .get_result::<Community>(conn)?;