1use upub::{ext::JsonVec, model::{activity, actor, addressing, config, credential, object}};
2use openssl::rsa::Rsa;
3use sea_orm::{ActiveValue::NotSet, IntoActiveModel};
4
5pub async fn faker(ctx: upub::Context, count: i64) -> Result<(), sea_orm::DbErr> {
6 use sea_orm::{EntityTrait, Set};
7
8 let domain = ctx.domain();
9 let db = ctx.db();
10
11 let key = Rsa::generate(2048).unwrap();
12 let test_user = actor::Model {
13 internal: 42,
14 id: format!("{domain}/actors/test"),
15 name: Some("μpub".into()),
16 domain: clean_domain(domain),
17 preferred_username: "test".to_string(),
18 summary: Some("hello world! i'm manually generated but served dynamically from db! check progress at https://git.alemi.dev/upub.git".to_string()),
19 following: None,
20 following_count: 0,
21 followers: None,
22 followers_count: 0,
23 statuses_count: count as i32,
24 fields: JsonVec::default(),
25 also_known_as: JsonVec::default(),
26 moved_to: None,
27 icon: Some("https://cdn.alemi.dev/social/circle-square.png".to_string()),
28 image: Some("https://cdn.alemi.dev/social/someriver-xs.jpg".to_string()),
29 inbox: None,
30 shared_inbox: None,
31 outbox: None,
32 actor_type: apb::ActorType::Person,
33 published: chrono::Utc::now(),
34 updated: chrono::Utc::now(),
35 private_key: Some(std::str::from_utf8(&key.private_key_to_pem().unwrap()).unwrap().to_string()),
36 public_key: std::str::from_utf8(&key.public_key_to_pem().unwrap()).unwrap().to_string(),
38 };
39
40 actor::Entity::insert(test_user.clone().into_active_model()).exec(db).await?;
41
42 config::Entity::insert(config::ActiveModel {
43 internal: NotSet,
44 actor: Set(test_user.id.clone()),
45 accept_follow_requests: Set(true),
46 show_following_count: Set(true),
47 show_followers_count: Set(true),
48 show_followers: Set(false),
49 show_following: Set(false),
50 show_liked_objects: Set(false),
51 show_lists: Set(false),
52 }).exec(db).await?;
53
54 credential::Entity::insert(credential::ActiveModel {
55 internal: NotSet,
56 actor: Set(test_user.id.clone()),
57 login: Set("mail@example.net".to_string()),
58 password: Set(sha256::digest("very-strong-password")),
59 active: Set(true),
60 }).exec(db).await?;
61
62 let context = uuid::Uuid::new_v4().to_string();
63
64 for i in (0..count).rev() {
65 let oid = uuid::Uuid::new_v4();
66 let aid = uuid::Uuid::new_v4();
67
68 addressing::Entity::insert(addressing::ActiveModel {
69 actor: Set(None),
70 instance: Set(None),
71 activity: Set(Some(42 + i)),
72 object: Set(Some(42 + i)),
73 published: Set(chrono::Utc::now()),
74 ..Default::default()
75 }).exec(db).await?;
76
77 object::Entity::insert(object::ActiveModel {
78 internal: Set(42 + i),
79 id: Set(format!("{domain}/objects/{oid}")),
80 name: Set(None),
81 object_type: Set(apb::ObjectType::Note),
82 attributed_to: Set(Some(format!("{domain}/actors/test"))),
83 summary: Set(None),
84 context: Set(Some(context.clone())),
85 in_reply_to: Set(None),
86 quote: Set(None),
87 content: Set(Some(format!("[{i}] Tic(k). Quasiparticle of intensive multiplicity. Tics (or ticks) are intrinsically several components of autonomously numbering anorganic populations, propagating by contagion between segmentary divisions in the order of nature. Ticks - as nonqualitative differentially-decomposable counting marks - each designate a multitude comprehended as a singular variation in tic(k)-density."))),
88 image: Set(None),
89 published: Set(chrono::Utc::now() - std::time::Duration::from_secs(60*i as u64)),
90 updated: Set(chrono::Utc::now()),
91 replies: Set(0),
92 likes: Set(0),
93 announces: Set(0),
94 audience: Set(None),
95 to: Set(JsonVec(vec![apb::target::PUBLIC.to_string()])),
96 bto: Set(JsonVec::default()),
97 cc: Set(JsonVec(vec![])),
98 bcc: Set(JsonVec::default()),
99 url: Set(None),
100 sensitive: Set(false),
101 }).exec(db).await?;
102
103 activity::Entity::insert(activity::ActiveModel {
104 internal: Set(42 + i),
105 id: Set(format!("{domain}/activities/{aid}")),
106 activity_type: Set(apb::ActivityType::Create),
107 actor: Set(format!("{domain}/actors/test")),
108 object: Set(Some(format!("{domain}/objects/{oid}"))),
109 target: Set(None),
110 content: Set(None),
111 published: Set(chrono::Utc::now() - std::time::Duration::from_secs(60*i as u64)),
112 to: Set(JsonVec(vec![apb::target::PUBLIC.to_string()])),
113 bto: Set(JsonVec::default()),
114 cc: Set(JsonVec(vec![])),
115 bcc: Set(JsonVec::default()),
116 }).exec(db).await?;
117 }
118
119 Ok(())
120}
121
122fn clean_domain(domain: &str) -> String {
123 domain
124 .replace("http://", "")
125 .replace("https://", "")
126 .replace('/', "")
127}