tangled.org trending bluesky account

Kind of working decently

+875 -62
+682 -49
Cargo.lock
··· 116 116 checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" 117 117 118 118 [[package]] 119 + name = "async-attributes" 120 + version = "1.1.2" 121 + source = "registry+https://github.com/rust-lang/crates.io-index" 122 + checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" 123 + dependencies = [ 124 + "quote", 125 + "syn 1.0.109", 126 + ] 127 + 128 + [[package]] 129 + name = "async-channel" 130 + version = "1.9.0" 131 + source = "registry+https://github.com/rust-lang/crates.io-index" 132 + checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" 133 + dependencies = [ 134 + "concurrent-queue", 135 + "event-listener 2.5.3", 136 + "futures-core", 137 + ] 138 + 139 + [[package]] 140 + name = "async-channel" 141 + version = "2.5.0" 142 + source = "registry+https://github.com/rust-lang/crates.io-index" 143 + checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" 144 + dependencies = [ 145 + "concurrent-queue", 146 + "event-listener-strategy", 147 + "futures-core", 148 + "pin-project-lite", 149 + ] 150 + 151 + [[package]] 119 152 name = "async-compression" 120 153 version = "0.4.23" 121 154 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 129 162 ] 130 163 131 164 [[package]] 165 + name = "async-executor" 166 + version = "1.13.3" 167 + source = "registry+https://github.com/rust-lang/crates.io-index" 168 + checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" 169 + dependencies = [ 170 + "async-task", 171 + "concurrent-queue", 172 + "fastrand", 173 + "futures-lite", 174 + "pin-project-lite", 175 + "slab", 176 + ] 177 + 178 + [[package]] 179 + name = "async-global-executor" 180 + version = "2.4.1" 181 + source = "registry+https://github.com/rust-lang/crates.io-index" 182 + checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" 183 + dependencies = [ 184 + "async-channel 2.5.0", 185 + "async-executor", 186 + "async-io", 187 + "async-lock", 188 + "blocking", 189 + "futures-lite", 190 + "once_cell", 191 + ] 192 + 193 + [[package]] 194 + name = "async-io" 195 + version = "2.6.0" 196 + source = "registry+https://github.com/rust-lang/crates.io-index" 197 + checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" 198 + dependencies = [ 199 + "autocfg", 200 + "cfg-if", 201 + "concurrent-queue", 202 + "futures-io", 203 + "futures-lite", 204 + "parking", 205 + "polling", 206 + "rustix 1.0.7", 207 + "slab", 208 + "windows-sys 0.61.0", 209 + ] 210 + 211 + [[package]] 132 212 name = "async-lock" 133 213 version = "3.4.0" 134 214 source = "registry+https://github.com/rust-lang/crates.io-index" 135 215 checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" 136 216 dependencies = [ 137 - "event-listener", 217 + "event-listener 5.4.0", 138 218 "event-listener-strategy", 139 219 "pin-project-lite", 140 220 ] 141 221 142 222 [[package]] 223 + name = "async-process" 224 + version = "2.5.0" 225 + source = "registry+https://github.com/rust-lang/crates.io-index" 226 + checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" 227 + dependencies = [ 228 + "async-channel 2.5.0", 229 + "async-io", 230 + "async-lock", 231 + "async-signal", 232 + "async-task", 233 + "blocking", 234 + "cfg-if", 235 + "event-listener 5.4.0", 236 + "futures-lite", 237 + "rustix 1.0.7", 238 + ] 239 + 240 + [[package]] 241 + name = "async-signal" 242 + version = "0.2.13" 243 + source = "registry+https://github.com/rust-lang/crates.io-index" 244 + checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" 245 + dependencies = [ 246 + "async-io", 247 + "async-lock", 248 + "atomic-waker", 249 + "cfg-if", 250 + "futures-core", 251 + "futures-io", 252 + "rustix 1.0.7", 253 + "signal-hook-registry", 254 + "slab", 255 + "windows-sys 0.61.0", 256 + ] 257 + 258 + [[package]] 259 + name = "async-std" 260 + version = "1.13.2" 261 + source = "registry+https://github.com/rust-lang/crates.io-index" 262 + checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" 263 + dependencies = [ 264 + "async-attributes", 265 + "async-channel 1.9.0", 266 + "async-global-executor", 267 + "async-io", 268 + "async-lock", 269 + "async-process", 270 + "crossbeam-utils", 271 + "futures-channel", 272 + "futures-core", 273 + "futures-io", 274 + "futures-lite", 275 + "gloo-timers", 276 + "kv-log-macro", 277 + "log", 278 + "memchr", 279 + "once_cell", 280 + "pin-project-lite", 281 + "pin-utils", 282 + "slab", 283 + "wasm-bindgen-futures", 284 + ] 285 + 286 + [[package]] 287 + name = "async-task" 288 + version = "4.7.1" 289 + source = "registry+https://github.com/rust-lang/crates.io-index" 290 + checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" 291 + 292 + [[package]] 143 293 name = "async-trait" 144 294 version = "0.1.88" 145 295 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 147 297 dependencies = [ 148 298 "proc-macro2", 149 299 "quote", 150 - "syn", 300 + "syn 2.0.101", 301 + ] 302 + 303 + [[package]] 304 + name = "async-tungstenite" 305 + version = "0.27.0" 306 + source = "registry+https://github.com/rust-lang/crates.io-index" 307 + checksum = "c5359381fd414fbdb272c48f2111c16cb0bb3447bfacd59311ff3736da9f6664" 308 + dependencies = [ 309 + "async-std", 310 + "futures-io", 311 + "futures-util", 312 + "log", 313 + "pin-project-lite", 314 + "tokio", 315 + "tungstenite 0.23.0", 151 316 ] 152 317 153 318 [[package]] ··· 348 513 ] 349 514 350 515 [[package]] 516 + name = "blocking" 517 + version = "1.6.2" 518 + source = "registry+https://github.com/rust-lang/crates.io-index" 519 + checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" 520 + dependencies = [ 521 + "async-channel 2.5.0", 522 + "async-task", 523 + "futures-io", 524 + "futures-lite", 525 + "piper", 526 + ] 527 + 528 + [[package]] 351 529 name = "bon" 352 530 version = "3.6.3" 353 531 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 369 547 "proc-macro2", 370 548 "quote", 371 549 "rustversion", 372 - "syn", 550 + "syn 2.0.101", 373 551 ] 374 552 375 553 [[package]] ··· 381 559 "atproto_api", 382 560 "atrium-api", 383 561 "bsky-sdk", 562 + "chromiumoxide", 384 563 "dotenv", 385 564 "env_logger", 565 + "futures-util", 566 + "handlebars", 386 567 "log", 387 568 "logic", 388 569 "reqwest", 389 570 "rocketman", 571 + "rust-embed", 390 572 "serde", 391 573 "serde_json", 392 574 "slingshot", 393 575 "sqlx", 394 576 "tokio", 577 + "urlencoding", 395 578 ] 396 579 397 580 [[package]] ··· 414 597 ] 415 598 416 599 [[package]] 600 + name = "bstr" 601 + version = "1.12.0" 602 + source = "registry+https://github.com/rust-lang/crates.io-index" 603 + checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" 604 + dependencies = [ 605 + "memchr", 606 + "serde", 607 + ] 608 + 609 + [[package]] 417 610 name = "bumpalo" 418 611 version = "3.17.0" 419 612 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 430 623 version = "1.10.1" 431 624 source = "registry+https://github.com/rust-lang/crates.io-index" 432 625 checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 626 + dependencies = [ 627 + "serde", 628 + ] 433 629 434 630 [[package]] 435 631 name = "cc" ··· 455 651 checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 456 652 457 653 [[package]] 654 + name = "chromiumoxide" 655 + version = "0.7.0" 656 + source = "registry+https://github.com/rust-lang/crates.io-index" 657 + checksum = "8380ce7721cc895fe8a184c49d615fe755b0c9a3d7986355cee847439fff907f" 658 + dependencies = [ 659 + "async-std", 660 + "async-tungstenite", 661 + "base64 0.22.1", 662 + "bytes", 663 + "cfg-if", 664 + "chromiumoxide_cdp", 665 + "chromiumoxide_types", 666 + "dunce", 667 + "fnv", 668 + "futures", 669 + "futures-timer", 670 + "pin-project-lite", 671 + "reqwest", 672 + "serde", 673 + "serde_json", 674 + "thiserror 1.0.69", 675 + "tokio", 676 + "tracing", 677 + "url", 678 + "which", 679 + "winreg", 680 + ] 681 + 682 + [[package]] 683 + name = "chromiumoxide_cdp" 684 + version = "0.7.0" 685 + source = "registry+https://github.com/rust-lang/crates.io-index" 686 + checksum = "cadbfb52fa0aeca43626f6c42ca04184b108b786f8e45198dc41a42aedcf2e50" 687 + dependencies = [ 688 + "chromiumoxide_pdl", 689 + "chromiumoxide_types", 690 + "serde", 691 + "serde_json", 692 + ] 693 + 694 + [[package]] 695 + name = "chromiumoxide_pdl" 696 + version = "0.7.0" 697 + source = "registry+https://github.com/rust-lang/crates.io-index" 698 + checksum = "c197aeb42872c5d4c923e7d8ad46d99a58fd0fec37f6491554ff677a6791d3c9" 699 + dependencies = [ 700 + "chromiumoxide_types", 701 + "either", 702 + "heck 0.4.1", 703 + "once_cell", 704 + "proc-macro2", 705 + "quote", 706 + "regex", 707 + "serde", 708 + "serde_json", 709 + ] 710 + 711 + [[package]] 712 + name = "chromiumoxide_types" 713 + version = "0.7.0" 714 + source = "registry+https://github.com/rust-lang/crates.io-index" 715 + checksum = "923486888790528d55ac37ec2f7483ed19eb8ccbb44701878e5856d1ceadf5d8" 716 + dependencies = [ 717 + "serde", 718 + "serde_json", 719 + ] 720 + 721 + [[package]] 458 722 name = "chrono" 459 723 version = "0.4.41" 460 724 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 466 730 "num-traits", 467 731 "serde", 468 732 "wasm-bindgen", 469 - "windows-link", 733 + "windows-link 0.1.1", 470 734 ] 471 735 472 736 [[package]] ··· 511 775 source = "registry+https://github.com/rust-lang/crates.io-index" 512 776 checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" 513 777 dependencies = [ 514 - "heck", 778 + "heck 0.5.0", 515 779 "proc-macro2", 516 780 "quote", 517 - "syn", 781 + "syn 2.0.101", 518 782 ] 519 783 520 784 [[package]] ··· 678 942 "proc-macro2", 679 943 "quote", 680 944 "strsim", 681 - "syn", 945 + "syn 2.0.101", 682 946 ] 683 947 684 948 [[package]] ··· 689 953 dependencies = [ 690 954 "darling_core", 691 955 "quote", 692 - "syn", 956 + "syn 2.0.101", 693 957 ] 694 958 695 959 [[package]] ··· 729 993 checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" 730 994 dependencies = [ 731 995 "data-encoding", 732 - "syn", 996 + "syn 2.0.101", 733 997 ] 734 998 735 999 [[package]] ··· 761 1025 "darling", 762 1026 "proc-macro2", 763 1027 "quote", 764 - "syn", 1028 + "syn 2.0.101", 765 1029 ] 766 1030 767 1031 [[package]] ··· 771 1035 checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" 772 1036 dependencies = [ 773 1037 "derive_builder_core", 774 - "syn", 1038 + "syn 2.0.101", 775 1039 ] 776 1040 777 1041 [[package]] ··· 794 1058 dependencies = [ 795 1059 "proc-macro2", 796 1060 "quote", 797 - "syn", 1061 + "syn 2.0.101", 798 1062 ] 799 1063 800 1064 [[package]] ··· 808 1072 version = "0.15.7" 809 1073 source = "registry+https://github.com/rust-lang/crates.io-index" 810 1074 checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" 1075 + 1076 + [[package]] 1077 + name = "dunce" 1078 + version = "1.0.5" 1079 + source = "registry+https://github.com/rust-lang/crates.io-index" 1080 + checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" 811 1081 812 1082 [[package]] 813 1083 name = "ecdsa" ··· 910 1180 911 1181 [[package]] 912 1182 name = "event-listener" 1183 + version = "2.5.3" 1184 + source = "registry+https://github.com/rust-lang/crates.io-index" 1185 + checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 1186 + 1187 + [[package]] 1188 + name = "event-listener" 913 1189 version = "5.4.0" 914 1190 source = "registry+https://github.com/rust-lang/crates.io-index" 915 1191 checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" ··· 925 1201 source = "registry+https://github.com/rust-lang/crates.io-index" 926 1202 checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" 927 1203 dependencies = [ 928 - "event-listener", 1204 + "event-listener 5.4.0", 929 1205 "pin-project-lite", 930 1206 ] 931 1207 ··· 1004 1280 ] 1005 1281 1006 1282 [[package]] 1283 + name = "futures" 1284 + version = "0.3.31" 1285 + source = "registry+https://github.com/rust-lang/crates.io-index" 1286 + checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 1287 + dependencies = [ 1288 + "futures-channel", 1289 + "futures-core", 1290 + "futures-executor", 1291 + "futures-io", 1292 + "futures-sink", 1293 + "futures-task", 1294 + "futures-util", 1295 + ] 1296 + 1297 + [[package]] 1007 1298 name = "futures-channel" 1008 1299 version = "0.3.31" 1009 1300 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1048 1339 checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 1049 1340 1050 1341 [[package]] 1342 + name = "futures-lite" 1343 + version = "2.6.1" 1344 + source = "registry+https://github.com/rust-lang/crates.io-index" 1345 + checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" 1346 + dependencies = [ 1347 + "fastrand", 1348 + "futures-core", 1349 + "futures-io", 1350 + "parking", 1351 + "pin-project-lite", 1352 + ] 1353 + 1354 + [[package]] 1051 1355 name = "futures-macro" 1052 1356 version = "0.3.31" 1053 1357 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1055 1359 dependencies = [ 1056 1360 "proc-macro2", 1057 1361 "quote", 1058 - "syn", 1362 + "syn 2.0.101", 1059 1363 ] 1060 1364 1061 1365 [[package]] ··· 1071 1375 checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 1072 1376 1073 1377 [[package]] 1378 + name = "futures-timer" 1379 + version = "3.0.3" 1380 + source = "registry+https://github.com/rust-lang/crates.io-index" 1381 + checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" 1382 + 1383 + [[package]] 1074 1384 name = "futures-util" 1075 1385 version = "0.3.31" 1076 1386 source = "registry+https://github.com/rust-lang/crates.io-index" 1077 1387 checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 1078 1388 dependencies = [ 1389 + "futures-channel", 1079 1390 "futures-core", 1080 1391 "futures-io", 1081 1392 "futures-macro", ··· 1146 1457 checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 1147 1458 1148 1459 [[package]] 1460 + name = "globset" 1461 + version = "0.4.16" 1462 + source = "registry+https://github.com/rust-lang/crates.io-index" 1463 + checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" 1464 + dependencies = [ 1465 + "aho-corasick", 1466 + "bstr", 1467 + "log", 1468 + "regex-automata 0.4.9", 1469 + "regex-syntax 0.8.5", 1470 + ] 1471 + 1472 + [[package]] 1473 + name = "gloo-timers" 1474 + version = "0.3.0" 1475 + source = "registry+https://github.com/rust-lang/crates.io-index" 1476 + checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" 1477 + dependencies = [ 1478 + "futures-channel", 1479 + "futures-core", 1480 + "js-sys", 1481 + "wasm-bindgen", 1482 + ] 1483 + 1484 + [[package]] 1149 1485 name = "gloo-utils" 1150 1486 version = "0.2.0" 1151 1487 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1189 1525 ] 1190 1526 1191 1527 [[package]] 1528 + name = "handlebars" 1529 + version = "6.3.2" 1530 + source = "registry+https://github.com/rust-lang/crates.io-index" 1531 + checksum = "759e2d5aea3287cb1190c8ec394f42866cb5bf74fcbf213f354e3c856ea26098" 1532 + dependencies = [ 1533 + "derive_builder", 1534 + "log", 1535 + "num-order", 1536 + "pest", 1537 + "pest_derive", 1538 + "rust-embed", 1539 + "serde", 1540 + "serde_json", 1541 + "thiserror 2.0.12", 1542 + ] 1543 + 1544 + [[package]] 1192 1545 name = "hashbrown" 1193 1546 version = "0.14.5" 1194 1547 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1216 1569 1217 1570 [[package]] 1218 1571 name = "heck" 1572 + version = "0.4.1" 1573 + source = "registry+https://github.com/rust-lang/crates.io-index" 1574 + checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 1575 + 1576 + [[package]] 1577 + name = "heck" 1219 1578 version = "0.5.0" 1220 1579 source = "registry+https://github.com/rust-lang/crates.io-index" 1221 1580 checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 1581 + 1582 + [[package]] 1583 + name = "hermit-abi" 1584 + version = "0.5.2" 1585 + source = "registry+https://github.com/rust-lang/crates.io-index" 1586 + checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" 1222 1587 1223 1588 [[package]] 1224 1589 name = "hex" ··· 1574 1939 dependencies = [ 1575 1940 "proc-macro2", 1576 1941 "quote", 1577 - "syn", 1942 + "syn 2.0.101", 1578 1943 ] 1579 1944 1580 1945 [[package]] ··· 1632 1997 ] 1633 1998 1634 1999 [[package]] 2000 + name = "kv-log-macro" 2001 + version = "1.0.7" 2002 + source = "registry+https://github.com/rust-lang/crates.io-index" 2003 + checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" 2004 + dependencies = [ 2005 + "log", 2006 + ] 2007 + 2008 + [[package]] 1635 2009 name = "langtag" 1636 2010 version = "0.3.4" 1637 2011 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1685 2059 1686 2060 [[package]] 1687 2061 name = "linux-raw-sys" 2062 + version = "0.4.15" 2063 + source = "registry+https://github.com/rust-lang/crates.io-index" 2064 + checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 2065 + 2066 + [[package]] 2067 + name = "linux-raw-sys" 1688 2068 version = "0.9.4" 1689 2069 source = "registry+https://github.com/rust-lang/crates.io-index" 1690 2070 checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" ··· 1710 2090 version = "0.4.27" 1711 2091 source = "registry+https://github.com/rust-lang/crates.io-index" 1712 2092 checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 2093 + dependencies = [ 2094 + "value-bag", 2095 + ] 1713 2096 1714 2097 [[package]] 1715 2098 name = "logic" ··· 1732 2115 "serde", 1733 2116 "thiserror 2.0.12", 1734 2117 "tokio", 1735 - "tungstenite", 2118 + "tungstenite 0.20.1", 1736 2119 "wasm-bindgen", 1737 2120 "web-sys", 1738 2121 ] ··· 1836 2219 "crossbeam-channel", 1837 2220 "crossbeam-epoch", 1838 2221 "crossbeam-utils", 1839 - "event-listener", 2222 + "event-listener 5.4.0", 1840 2223 "futures-util", 1841 2224 "loom", 1842 2225 "parking_lot", ··· 1944 2327 ] 1945 2328 1946 2329 [[package]] 2330 + name = "num-modular" 2331 + version = "0.6.1" 2332 + source = "registry+https://github.com/rust-lang/crates.io-index" 2333 + checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" 2334 + 2335 + [[package]] 2336 + name = "num-order" 2337 + version = "1.2.0" 2338 + source = "registry+https://github.com/rust-lang/crates.io-index" 2339 + checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" 2340 + dependencies = [ 2341 + "num-modular", 2342 + ] 2343 + 2344 + [[package]] 1947 2345 name = "num-traits" 1948 2346 version = "0.2.19" 1949 2347 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1991 2389 dependencies = [ 1992 2390 "proc-macro2", 1993 2391 "quote", 1994 - "syn", 2392 + "syn 2.0.101", 1995 2393 ] 1996 2394 1997 2395 [[package]] ··· 2075 2473 checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 2076 2474 2077 2475 [[package]] 2476 + name = "pest" 2477 + version = "2.8.2" 2478 + source = "registry+https://github.com/rust-lang/crates.io-index" 2479 + checksum = "21e0a3a33733faeaf8651dfee72dd0f388f0c8e5ad496a3478fa5a922f49cfa8" 2480 + dependencies = [ 2481 + "memchr", 2482 + "thiserror 2.0.12", 2483 + "ucd-trie", 2484 + ] 2485 + 2486 + [[package]] 2487 + name = "pest_derive" 2488 + version = "2.8.2" 2489 + source = "registry+https://github.com/rust-lang/crates.io-index" 2490 + checksum = "bc58706f770acb1dbd0973e6530a3cff4746fb721207feb3a8a6064cd0b6c663" 2491 + dependencies = [ 2492 + "pest", 2493 + "pest_generator", 2494 + ] 2495 + 2496 + [[package]] 2497 + name = "pest_generator" 2498 + version = "2.8.2" 2499 + source = "registry+https://github.com/rust-lang/crates.io-index" 2500 + checksum = "6d4f36811dfe07f7b8573462465d5cb8965fffc2e71ae377a33aecf14c2c9a2f" 2501 + dependencies = [ 2502 + "pest", 2503 + "pest_meta", 2504 + "proc-macro2", 2505 + "quote", 2506 + "syn 2.0.101", 2507 + ] 2508 + 2509 + [[package]] 2510 + name = "pest_meta" 2511 + version = "2.8.2" 2512 + source = "registry+https://github.com/rust-lang/crates.io-index" 2513 + checksum = "42919b05089acbd0a5dcd5405fb304d17d1053847b81163d09c4ad18ce8e8420" 2514 + dependencies = [ 2515 + "pest", 2516 + "sha2", 2517 + ] 2518 + 2519 + [[package]] 2078 2520 name = "pin-project-lite" 2079 2521 version = "0.2.16" 2080 2522 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2087 2529 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 2088 2530 2089 2531 [[package]] 2532 + name = "piper" 2533 + version = "0.2.4" 2534 + source = "registry+https://github.com/rust-lang/crates.io-index" 2535 + checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" 2536 + dependencies = [ 2537 + "atomic-waker", 2538 + "fastrand", 2539 + "futures-io", 2540 + ] 2541 + 2542 + [[package]] 2090 2543 name = "pkcs1" 2091 2544 version = "0.7.5" 2092 2545 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2114 2567 checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 2115 2568 2116 2569 [[package]] 2570 + name = "polling" 2571 + version = "3.11.0" 2572 + source = "registry+https://github.com/rust-lang/crates.io-index" 2573 + checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" 2574 + dependencies = [ 2575 + "cfg-if", 2576 + "concurrent-queue", 2577 + "hermit-abi", 2578 + "pin-project-lite", 2579 + "rustix 1.0.7", 2580 + "windows-sys 0.61.0", 2581 + ] 2582 + 2583 + [[package]] 2117 2584 name = "portable-atomic" 2118 2585 version = "1.11.0" 2119 2586 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2153 2620 checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" 2154 2621 dependencies = [ 2155 2622 "proc-macro2", 2156 - "syn", 2623 + "syn 2.0.101", 2157 2624 ] 2158 2625 2159 2626 [[package]] ··· 2491 2958 ] 2492 2959 2493 2960 [[package]] 2961 + name = "rust-embed" 2962 + version = "8.7.2" 2963 + source = "registry+https://github.com/rust-lang/crates.io-index" 2964 + checksum = "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a" 2965 + dependencies = [ 2966 + "rust-embed-impl", 2967 + "rust-embed-utils", 2968 + "walkdir", 2969 + ] 2970 + 2971 + [[package]] 2972 + name = "rust-embed-impl" 2973 + version = "8.7.2" 2974 + source = "registry+https://github.com/rust-lang/crates.io-index" 2975 + checksum = "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c" 2976 + dependencies = [ 2977 + "proc-macro2", 2978 + "quote", 2979 + "rust-embed-utils", 2980 + "syn 2.0.101", 2981 + "walkdir", 2982 + ] 2983 + 2984 + [[package]] 2985 + name = "rust-embed-utils" 2986 + version = "8.7.2" 2987 + source = "registry+https://github.com/rust-lang/crates.io-index" 2988 + checksum = "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594" 2989 + dependencies = [ 2990 + "globset", 2991 + "sha2", 2992 + "walkdir", 2993 + ] 2994 + 2995 + [[package]] 2494 2996 name = "rustc-demangle" 2495 2997 version = "0.1.24" 2496 2998 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2513 3015 2514 3016 [[package]] 2515 3017 name = "rustix" 3018 + version = "0.38.44" 3019 + source = "registry+https://github.com/rust-lang/crates.io-index" 3020 + checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" 3021 + dependencies = [ 3022 + "bitflags", 3023 + "errno", 3024 + "libc", 3025 + "linux-raw-sys 0.4.15", 3026 + "windows-sys 0.59.0", 3027 + ] 3028 + 3029 + [[package]] 3030 + name = "rustix" 2516 3031 version = "1.0.7" 2517 3032 source = "registry+https://github.com/rust-lang/crates.io-index" 2518 3033 checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" ··· 2520 3035 "bitflags", 2521 3036 "errno", 2522 3037 "libc", 2523 - "linux-raw-sys", 3038 + "linux-raw-sys 0.9.4", 2524 3039 "windows-sys 0.59.0", 2525 3040 ] 2526 3041 ··· 2624 3139 checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 2625 3140 2626 3141 [[package]] 3142 + name = "same-file" 3143 + version = "1.0.6" 3144 + source = "registry+https://github.com/rust-lang/crates.io-index" 3145 + checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 3146 + dependencies = [ 3147 + "winapi-util", 3148 + ] 3149 + 3150 + [[package]] 2627 3151 name = "schannel" 2628 3152 version = "0.1.27" 2629 3153 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2732 3256 dependencies = [ 2733 3257 "proc-macro2", 2734 3258 "quote", 2735 - "syn", 3259 + "syn 2.0.101", 2736 3260 ] 2737 3261 2738 3262 [[package]] ··· 2913 3437 "crc", 2914 3438 "crossbeam-queue", 2915 3439 "either", 2916 - "event-listener", 3440 + "event-listener 5.4.0", 2917 3441 "futures-core", 2918 3442 "futures-intrusive", 2919 3443 "futures-io", ··· 2946 3470 "quote", 2947 3471 "sqlx-core", 2948 3472 "sqlx-macros-core", 2949 - "syn", 3473 + "syn 2.0.101", 2950 3474 ] 2951 3475 2952 3476 [[package]] ··· 2957 3481 dependencies = [ 2958 3482 "dotenvy", 2959 3483 "either", 2960 - "heck", 3484 + "heck 0.5.0", 2961 3485 "hex", 2962 3486 "once_cell", 2963 3487 "proc-macro2", ··· 2969 3493 "sqlx-mysql", 2970 3494 "sqlx-postgres", 2971 3495 "sqlx-sqlite", 2972 - "syn", 3496 + "syn 2.0.101", 2973 3497 "tokio", 2974 3498 "url", 2975 3499 ] ··· 3111 3635 3112 3636 [[package]] 3113 3637 name = "syn" 3638 + version = "1.0.109" 3639 + source = "registry+https://github.com/rust-lang/crates.io-index" 3640 + checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 3641 + dependencies = [ 3642 + "proc-macro2", 3643 + "quote", 3644 + "unicode-ident", 3645 + ] 3646 + 3647 + [[package]] 3648 + name = "syn" 3114 3649 version = "2.0.101" 3115 3650 source = "registry+https://github.com/rust-lang/crates.io-index" 3116 3651 checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" ··· 3137 3672 dependencies = [ 3138 3673 "proc-macro2", 3139 3674 "quote", 3140 - "syn", 3675 + "syn 2.0.101", 3141 3676 ] 3142 3677 3143 3678 [[package]] ··· 3176 3711 "fastrand", 3177 3712 "getrandom 0.3.3", 3178 3713 "once_cell", 3179 - "rustix", 3714 + "rustix 1.0.7", 3180 3715 "windows-sys 0.59.0", 3181 3716 ] 3182 3717 ··· 3206 3741 dependencies = [ 3207 3742 "proc-macro2", 3208 3743 "quote", 3209 - "syn", 3744 + "syn 2.0.101", 3210 3745 ] 3211 3746 3212 3747 [[package]] ··· 3217 3752 dependencies = [ 3218 3753 "proc-macro2", 3219 3754 "quote", 3220 - "syn", 3755 + "syn 2.0.101", 3221 3756 ] 3222 3757 3223 3758 [[package]] ··· 3281 3816 dependencies = [ 3282 3817 "proc-macro2", 3283 3818 "quote", 3284 - "syn", 3819 + "syn 2.0.101", 3285 3820 ] 3286 3821 3287 3822 [[package]] ··· 3337 3872 "rustls-native-certs", 3338 3873 "tokio", 3339 3874 "tokio-rustls 0.24.1", 3340 - "tungstenite", 3875 + "tungstenite 0.20.1", 3341 3876 "webpki-roots 0.25.4", 3342 3877 ] 3343 3878 ··· 3401 3936 dependencies = [ 3402 3937 "proc-macro2", 3403 3938 "quote", 3404 - "syn", 3939 + "syn 2.0.101", 3405 3940 ] 3406 3941 3407 3942 [[package]] ··· 3451 3986 dependencies = [ 3452 3987 "proc-macro2", 3453 3988 "quote", 3454 - "syn", 3989 + "syn 2.0.101", 3455 3990 ] 3456 3991 3457 3992 [[package]] ··· 3481 4016 ] 3482 4017 3483 4018 [[package]] 4019 + name = "tungstenite" 4020 + version = "0.23.0" 4021 + source = "registry+https://github.com/rust-lang/crates.io-index" 4022 + checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8" 4023 + dependencies = [ 4024 + "byteorder", 4025 + "bytes", 4026 + "data-encoding", 4027 + "http 1.3.1", 4028 + "httparse", 4029 + "log", 4030 + "rand 0.8.5", 4031 + "sha1", 4032 + "thiserror 1.0.69", 4033 + "utf-8", 4034 + ] 4035 + 4036 + [[package]] 3484 4037 name = "typenum" 3485 4038 version = "1.18.0" 3486 4039 source = "registry+https://github.com/rust-lang/crates.io-index" 3487 4040 checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" 4041 + 4042 + [[package]] 4043 + name = "ucd-trie" 4044 + version = "0.1.7" 4045 + source = "registry+https://github.com/rust-lang/crates.io-index" 4046 + checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" 3488 4047 3489 4048 [[package]] 3490 4049 name = "unicode-bidi" ··· 3543 4102 ] 3544 4103 3545 4104 [[package]] 4105 + name = "urlencoding" 4106 + version = "2.1.3" 4107 + source = "registry+https://github.com/rust-lang/crates.io-index" 4108 + checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" 4109 + 4110 + [[package]] 3546 4111 name = "utf-8" 3547 4112 version = "0.7.6" 3548 4113 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3576 4141 checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" 3577 4142 3578 4143 [[package]] 4144 + name = "value-bag" 4145 + version = "1.11.1" 4146 + source = "registry+https://github.com/rust-lang/crates.io-index" 4147 + checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5" 4148 + 4149 + [[package]] 3579 4150 name = "vcpkg" 3580 4151 version = "0.2.15" 3581 4152 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3588 4159 checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 3589 4160 3590 4161 [[package]] 4162 + name = "walkdir" 4163 + version = "2.5.0" 4164 + source = "registry+https://github.com/rust-lang/crates.io-index" 4165 + checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 4166 + dependencies = [ 4167 + "same-file", 4168 + "winapi-util", 4169 + ] 4170 + 4171 + [[package]] 3591 4172 name = "want" 3592 4173 version = "0.3.1" 3593 4174 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3640 4221 "log", 3641 4222 "proc-macro2", 3642 4223 "quote", 3643 - "syn", 4224 + "syn 2.0.101", 3644 4225 "wasm-bindgen-shared", 3645 4226 ] 3646 4227 ··· 3675 4256 dependencies = [ 3676 4257 "proc-macro2", 3677 4258 "quote", 3678 - "syn", 4259 + "syn 2.0.101", 3679 4260 "wasm-bindgen-backend", 3680 4261 "wasm-bindgen-shared", 3681 4262 ] ··· 3731 4312 checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" 3732 4313 dependencies = [ 3733 4314 "rustls-pki-types", 4315 + ] 4316 + 4317 + [[package]] 4318 + name = "which" 4319 + version = "6.0.3" 4320 + source = "registry+https://github.com/rust-lang/crates.io-index" 4321 + checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" 4322 + dependencies = [ 4323 + "either", 4324 + "home", 4325 + "rustix 0.38.44", 4326 + "winsafe", 3734 4327 ] 3735 4328 3736 4329 [[package]] ··· 3760 4353 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 3761 4354 3762 4355 [[package]] 4356 + name = "winapi-util" 4357 + version = "0.1.11" 4358 + source = "registry+https://github.com/rust-lang/crates.io-index" 4359 + checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" 4360 + dependencies = [ 4361 + "windows-sys 0.61.0", 4362 + ] 4363 + 4364 + [[package]] 3763 4365 name = "winapi-x86_64-pc-windows-gnu" 3764 4366 version = "0.4.0" 3765 4367 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3774 4376 "windows-collections", 3775 4377 "windows-core", 3776 4378 "windows-future", 3777 - "windows-link", 4379 + "windows-link 0.1.1", 3778 4380 "windows-numerics", 3779 4381 ] 3780 4382 ··· 3795 4397 dependencies = [ 3796 4398 "windows-implement", 3797 4399 "windows-interface", 3798 - "windows-link", 4400 + "windows-link 0.1.1", 3799 4401 "windows-result", 3800 4402 "windows-strings 0.4.1", 3801 4403 ] ··· 3807 4409 checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" 3808 4410 dependencies = [ 3809 4411 "windows-core", 3810 - "windows-link", 4412 + "windows-link 0.1.1", 3811 4413 "windows-threading", 3812 4414 ] 3813 4415 ··· 3819 4421 dependencies = [ 3820 4422 "proc-macro2", 3821 4423 "quote", 3822 - "syn", 4424 + "syn 2.0.101", 3823 4425 ] 3824 4426 3825 4427 [[package]] ··· 3830 4432 dependencies = [ 3831 4433 "proc-macro2", 3832 4434 "quote", 3833 - "syn", 4435 + "syn 2.0.101", 3834 4436 ] 3835 4437 3836 4438 [[package]] ··· 3840 4442 checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" 3841 4443 3842 4444 [[package]] 4445 + name = "windows-link" 4446 + version = "0.2.0" 4447 + source = "registry+https://github.com/rust-lang/crates.io-index" 4448 + checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" 4449 + 4450 + [[package]] 3843 4451 name = "windows-numerics" 3844 4452 version = "0.2.0" 3845 4453 source = "registry+https://github.com/rust-lang/crates.io-index" 3846 4454 checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" 3847 4455 dependencies = [ 3848 4456 "windows-core", 3849 - "windows-link", 4457 + "windows-link 0.1.1", 3850 4458 ] 3851 4459 3852 4460 [[package]] ··· 3866 4474 source = "registry+https://github.com/rust-lang/crates.io-index" 3867 4475 checksum = "4b895b5356fc36103d0f64dd1e94dfa7ac5633f1c9dd6e80fe9ec4adef69e09d" 3868 4476 dependencies = [ 3869 - "windows-link", 4477 + "windows-link 0.1.1", 3870 4478 ] 3871 4479 3872 4480 [[package]] ··· 3875 4483 source = "registry+https://github.com/rust-lang/crates.io-index" 3876 4484 checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" 3877 4485 dependencies = [ 3878 - "windows-link", 4486 + "windows-link 0.1.1", 3879 4487 ] 3880 4488 3881 4489 [[package]] ··· 3884 4492 source = "registry+https://github.com/rust-lang/crates.io-index" 3885 4493 checksum = "2a7ab927b2637c19b3dbe0965e75d8f2d30bdd697a1516191cad2ec4df8fb28a" 3886 4494 dependencies = [ 3887 - "windows-link", 4495 + "windows-link 0.1.1", 3888 4496 ] 3889 4497 3890 4498 [[package]] ··· 3915 4523 ] 3916 4524 3917 4525 [[package]] 4526 + name = "windows-sys" 4527 + version = "0.61.0" 4528 + source = "registry+https://github.com/rust-lang/crates.io-index" 4529 + checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" 4530 + dependencies = [ 4531 + "windows-link 0.2.0", 4532 + ] 4533 + 4534 + [[package]] 3918 4535 name = "windows-targets" 3919 4536 version = "0.48.5" 3920 4537 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3967 4584 source = "registry+https://github.com/rust-lang/crates.io-index" 3968 4585 checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" 3969 4586 dependencies = [ 3970 - "windows-link", 4587 + "windows-link 0.1.1", 3971 4588 ] 3972 4589 3973 4590 [[package]] ··· 4109 4726 checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" 4110 4727 4111 4728 [[package]] 4729 + name = "winreg" 4730 + version = "0.52.0" 4731 + source = "registry+https://github.com/rust-lang/crates.io-index" 4732 + checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" 4733 + dependencies = [ 4734 + "cfg-if", 4735 + "windows-sys 0.48.0", 4736 + ] 4737 + 4738 + [[package]] 4739 + name = "winsafe" 4740 + version = "0.0.19" 4741 + source = "registry+https://github.com/rust-lang/crates.io-index" 4742 + checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" 4743 + 4744 + [[package]] 4112 4745 name = "wit-bindgen-rt" 4113 4746 version = "0.39.0" 4114 4747 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4143 4776 dependencies = [ 4144 4777 "proc-macro2", 4145 4778 "quote", 4146 - "syn", 4779 + "syn 2.0.101", 4147 4780 "synstructure", 4148 4781 ] 4149 4782 ··· 4164 4797 dependencies = [ 4165 4798 "proc-macro2", 4166 4799 "quote", 4167 - "syn", 4800 + "syn 2.0.101", 4168 4801 ] 4169 4802 4170 4803 [[package]] ··· 4184 4817 dependencies = [ 4185 4818 "proc-macro2", 4186 4819 "quote", 4187 - "syn", 4820 + "syn 2.0.101", 4188 4821 "synstructure", 4189 4822 ] 4190 4823 ··· 4227 4860 dependencies = [ 4228 4861 "proc-macro2", 4229 4862 "quote", 4230 - "syn", 4863 + "syn 2.0.101", 4231 4864 ] 4232 4865 4233 4866 [[package]]
+5
bot/Cargo.toml
··· 7 7 anyhow = "1.0.98" 8 8 atproto_api.workspace = true 9 9 bsky-sdk.workspace = true 10 + chromiumoxide = { version = "0.7", features = ["tokio-runtime"] } 11 + handlebars = { version = "6.3.2", features = ["rust-embed"] } 12 + rust-embed = { version = "8.7.2", features = ["include-exclude"] } 10 13 rocketman.workspace = true 11 14 reqwest.workspace = true 12 15 atrium-api.workspace = true ··· 20 23 serde_json.workspace = true 21 24 logic.workspace = true 22 25 slingshot.workspace = true 26 + urlencoding = "2.1.3" 27 + futures-util = "0.3.31"
+142 -12
bot/src/main.rs
··· 3 3 extern crate dotenv; 4 4 5 5 use crate::constellation::fetch_constellation_count; 6 + use atrium_api::app::bsky::embed::defs::AspectRatioData; 7 + use atrium_api::app::bsky::feed::post::RecordEmbedRefs; 6 8 use atrium_api::types::Collection; 7 9 use atrium_api::types::string::Language; 8 10 use bsky_sdk::rich_text::RichText; 11 + use chromiumoxide::browser::{Browser, BrowserConfig, HeadlessMode}; 12 + use chromiumoxide::cdp::browser_protocol::page::{ 13 + CaptureScreenshotFormat, CaptureScreenshotParams, Viewport, 14 + }; 9 15 use dotenv::dotenv; 16 + use futures_util::stream::StreamExt; 17 + use handlebars::Handlebars; 18 + use log::error; 10 19 use logic::BotApi; 11 - use reqwest::Url; 12 20 use rocketman::{ 13 21 connection::JetstreamConnection, handler, ingestion::LexiconIngestor, 14 22 options::JetstreamOptions, types::event::Operation, 15 23 }; 16 - use serde::Deserialize; 24 + use rust_embed::Embed; 25 + use serde::Serialize; 17 26 use slingshot::Slingshot; 18 27 use sqlx::sqlite::{SqliteConnectOptions, SqlitePool}; 19 28 use std::collections::HashMap; 20 - use std::fmt::format; 29 + use std::num::NonZeroU64; 21 30 use std::sync::{Arc, Mutex}; 22 31 use std::time::Duration; 32 + 33 + #[derive(Embed)] 34 + #[folder = "templates/"] 35 + #[include = "*.hbs"] 36 + pub struct Templates; 23 37 24 38 #[derive(Debug)] 25 39 struct Record { ··· 91 105 92 106 let bot_api = BotApi::new_logged_in(bot_username, bot_password, bot_pds_url).await?; 93 107 let sling_shot = Arc::new(Slingshot::new("https://slingshot.microcosm.blue")?); 108 + 109 + // setup handlebars 110 + let mut hbs = Handlebars::new(); 111 + let _ = hbs.register_embed_templates::<Templates>(); 112 + 113 + let cfg = BrowserConfig::builder() 114 + .headless_mode(HeadlessMode::New) 115 + .no_sandbox() 116 + .build() 117 + .map_err(|e| anyhow::anyhow!(e)) 118 + .expect("build browser config"); 119 + let (mut browser, mut browser_handler) = Browser::launch(cfg).await.expect("launch browser"); 120 + 121 + let handle = tokio::spawn(async move { while let Some(_) = browser_handler.next().await {} }); 122 + 94 123 // Ingestor for the star collection 95 124 let mut ingestors: HashMap<String, Box<dyn LexiconIngestor + Send + Sync>> = HashMap::new(); 96 125 ingestors.insert( ··· 99 128 pool: pool.clone(), 100 129 bot: Arc::new(bot_api), 101 130 sling_shot: sling_shot.clone(), 131 + browser: Arc::new(browser), 132 + hbs: Arc::new(hbs), 102 133 timeframe_hours, 103 134 star_threshold, 104 135 post_window_hours, ··· 136 167 pool: SqlitePool, 137 168 bot: Arc<BotApi>, 138 169 sling_shot: Arc<Slingshot>, 170 + browser: Arc<Browser>, 171 + hbs: Arc<Handlebars<'static>>, 139 172 timeframe_hours: i64, 140 173 star_threshold: i64, 141 174 post_window_hours: i64, ··· 165 198 let rec = serde_json::from_value::< 166 199 atproto_api::sh::tangled::feed::star::RecordData, 167 200 >(record.clone())?; 201 + 202 + let repo_subject = rec.subject; 203 + 168 204 // Insert or ignore duplicate per did+rkey 169 205 let result = sqlx::query( 170 206 "INSERT OR IGNORE INTO stars(createdAt, did, rkey, subject) VALUES(?, ?, ?, ?)" ··· 172 208 .bind(rec.created_at.as_str()) 173 209 .bind(&message.did) 174 210 .bind(commit.rkey.as_str()) 175 - .bind(&rec.subject) 211 + .bind(&repo_subject) 176 212 .execute(&self.pool) 177 213 .await?; 178 214 ··· 181 217 let offset = format!("-{} hours", self.timeframe_hours); 182 218 // Count stars in the last timeframe_hours using RFC3339 string comparison 183 219 let (count_in_window,): (i64,) = sqlx::query_as( 184 - "SELECT COUNT(*) as cnt FROM stars WHERE createdAt >= strftime('%Y-%m-%dT%H:%M:%fZ','now', ?)" 220 + "SELECT COUNT(*) as cnt FROM stars WHERE createdAt >= strftime('%Y-%m-%dT%H:%M:%fZ','now', ?) AND subject = ?" 185 221 ) 186 222 .bind(&offset) 223 + .bind(&repo_subject) 187 224 .fetch_one(&self.pool) 188 225 .await?; 189 226 ··· 198 235 // Check if a post was made within the last post_window_hours 199 236 let post_offset = format!("-{} hours", self.post_window_hours); 200 237 let (posts_in_window,): (i64,) = sqlx::query_as( 201 - "SELECT COUNT(*) as cnt FROM posts_made WHERE createdAt >= strftime('%Y-%m-%dT%H:%M:%fZ','now', ?)" 238 + "SELECT COUNT(*) as cnt FROM posts_made WHERE createdAt >= strftime('%Y-%m-%dT%H:%M:%fZ','now', ?) AND subject = ?" 202 239 ) 203 240 .bind(&post_offset) 241 + .bind(&repo_subject) 204 242 .fetch_one(&self.pool) 205 243 .await?; 206 244 ··· 209 247 let _ = sqlx::query( 210 248 "INSERT INTO posts_made(createdAt, subject) VALUES(strftime('%Y-%m-%dT%H:%M:%fZ','now'), ?)" 211 249 ) 212 - .bind(&rec.subject) 250 + .bind(&repo_subject.clone()) 213 251 .execute(&self.pool) 214 252 .await?; 215 253 216 - let parsed = parse_uri(&rec.subject)?; 254 + let parsed = parse_uri(&repo_subject)?; 217 255 let cloned_repo_owner = parsed.did.clone(); 218 - let stars = fetch_constellation_count(&rec.subject).await?; 256 + let stars = fetch_constellation_count(&repo_subject).await?; 219 257 let repo_record = &self 220 258 .sling_shot 221 259 .get_record::<atproto_api::sh::tangled::repo::RecordData>( ··· 235 273 Some(desc) => format!(" : {desc}"), 236 274 }; 237 275 276 + let handle_and_repo = format!("{handle}/{repo_name}"); 277 + 278 + let ctx = RepoPreview { 279 + repo: handle_and_repo.clone(), 280 + stars: stars as u64, 281 + description: description.clone(), 282 + }; 283 + 284 + let html = &self.hbs.render("repo_header.hbs", &ctx)?; 285 + 286 + let bytes = 287 + render_with_chromiumoxide(&html, 336, 114, &self.browser) 288 + .await?; 289 + 290 + let blob_upload = &self 291 + .bot 292 + .agent 293 + .api 294 + .com 295 + .atproto 296 + .repo 297 + .upload_blob(bytes) 298 + .await?; 299 + 238 300 let rt = RichText::new_with_detect_facets(format!( 239 - "{handle}/{repo_name}{description}\n⭐️ {stars} {tangled_sh_url}" 301 + "{handle_and_repo}{description}\n⭐️ {stars} {tangled_sh_url}" 240 302 )) 241 - .await?; 303 + .await?; 304 + let image = atrium_api::app::bsky::embed::images::ImageData{ 305 + alt: "An image showing the same text inside of the post. Repo name, description and how many stars. Just a plain HTML page".to_string(), 306 + aspect_ratio: Some(atrium_api::app::bsky::embed::defs::AspectRatioData{ 307 + height: NonZeroU64::try_from(114_u64)?, 308 + width: NonZeroU64::try_from(336_u64)? 309 + }.into()), 310 + //Good lord how many clones is that 311 + image: blob_upload.clone().blob.clone(), 312 + }; 313 + let embed = Some(atrium_api::types::Union::Refs( 314 + RecordEmbedRefs::AppBskyEmbedImagesMain(Box::new( 315 + atrium_api::app::bsky::embed::images::MainData { 316 + images: vec![image.into()], 317 + } 318 + .into(), 319 + )), 320 + )); 321 + 242 322 let post = atrium_api::app::bsky::feed::post::RecordData { 243 323 created_at: atrium_api::types::string::Datetime::now(), 244 - embed: None, 324 + embed, 245 325 entities: None, 246 326 facets: rt.facets, 247 327 labels: None, ··· 281 361 Ok(()) 282 362 } 283 363 } 364 + 365 + #[derive(Serialize)] 366 + struct RepoPreview { 367 + repo: String, 368 + stars: u64, 369 + description: String, 370 + } 371 + 372 + async fn render_with_chromiumoxide( 373 + html: &str, 374 + width: u32, 375 + height: u32, 376 + browser: &Browser, 377 + ) -> Result<Vec<u8>, anyhow::Error> { 378 + // Configure and launch the browser 379 + 380 + // Spawn the handler task to drive the connection 381 + // let handle = tokio::spawn(async move { while let Some(_) = handler.next().await {} }); 382 + 383 + let page = browser.new_page("about:blank").await?; 384 + 385 + // Load the provided HTML as a data URL to avoid external fetches 386 + let data_url = format!("data:text/html;charset=utf-8,{}", urlencoding::encode(html)); 387 + page.goto(data_url).await?; 388 + 389 + // Wait for network idle-ish 390 + page.wait_for_navigation().await.ok(); 391 + 392 + // Screenshot: clip to desired viewport size regardless of page layout 393 + let params = CaptureScreenshotParams::builder() 394 + .format(CaptureScreenshotFormat::Png) 395 + .clip(Viewport { 396 + x: 0.0, 397 + y: 0.0, 398 + width: width as f64, 399 + height: height as f64, 400 + scale: 1.0, 401 + }) 402 + .from_surface(true) 403 + .build(); 404 + let png_bytes = page.screenshot(params).await?; 405 + 406 + // Close 407 + page.close().await.ok(); 408 + // browser.close().await.ok(); 409 + // stop handler task 410 + // handle.abort(); 411 + 412 + Ok(png_bytes) 413 + }
+45
bot/templates/repo_header.hbs
··· 1 + <html lang="en" class="dark:bg-gray-900"> 2 + <head> 3 + <link rel="preload" href="https://tangled.sh/static/fonts/InterVariable.woff2" as="font" type="font/woff2" 4 + crossorigin/> 5 + <link rel="stylesheet" href="https://tangled.sh/static/tw.css?6a194d26" type="text/css"/> 6 + <title>timeline · tangled</title> 7 + </head> 8 + <body> 9 + 10 + <div class="flex-none h-full border border-gray-200 dark:border-gray-700 rounded-sm w-96"> 11 + <div class="py-4 px-6 gap-1 flex flex-col drop-shadow-sm rounded bg-white dark:bg-gray-800 min-h-32"> 12 + <div class="font-medium dark:text-white flex items-center"> 13 + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" 14 + stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" 15 + class="w-4 h-4 mr-1.5 shrink-0"> 16 + <path d="M10 2v8l3-3 3 3V2"></path> 17 + <path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20"></path> 18 + </svg> 19 + <a href="/{{repo}}" class="truncate">{{repo}}</a></div> 20 + 21 + <div class="text-gray-600 dark:text-gray-300 text-sm line-clamp-2"> 22 + {{description}} 23 + 24 + </div> 25 + 26 + 27 + <div class="text-gray-400 text-sm font-mono inline-flex gap-4 mt-auto"> 28 + <div class="flex gap-1 items-center text-sm"> 29 + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" 30 + stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" 31 + class="w-3 h-3 fill-current"> 32 + <path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"></path> 33 + </svg> 34 + 35 + <span>{{stars}}</span> 36 + </div> 37 + 38 + </div> 39 + 40 + </div> 41 + 42 + </div> 43 + 44 + </body> 45 + </html>
+1 -1
logic/src/lib.rs
··· 129 129 false => { 130 130 //also_known as a list starts the array with the highest priority handle 131 131 let formatted_handle = 132 - format!("@{}", also_known_as[0]).replace("at://", ""); 132 + format!("{}", also_known_as[0]).replace("at://", ""); 133 133 Ok(formatted_handle) 134 134 } 135 135 }