A personal app view to see Bsky posts of your followers (for when their app view goes down)
17
fork

Configure Feed

Select the types of activity you want to include in your feed.

create and delete follow records for appview user

Signed-off-by: Will Andrews <did:plc:dadhhalkfcq3gucaq25hjqon>

+795 -16
+1
.env.example
··· 2 2 APPVIEW_HOSTNAME="my-appview.com" 3 3 USERS_DID="did:plc:<your-did-here>" 4 4 TAP_URL="localhost:2480" 5 + DATABASE_URL="sqlite:./data/appview.db"
+705 -2
Cargo.lock
··· 38 38 ] 39 39 40 40 [[package]] 41 + name = "atoi" 42 + version = "2.0.0" 43 + source = "registry+https://github.com/rust-lang/crates.io-index" 44 + checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" 45 + dependencies = [ 46 + "num-traits", 47 + ] 48 + 49 + [[package]] 41 50 name = "atomic-waker" 42 51 version = "1.1.2" 43 52 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 215 224 version = "2.11.0" 216 225 source = "registry+https://github.com/rust-lang/crates.io-index" 217 226 checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" 227 + dependencies = [ 228 + "serde_core", 229 + ] 218 230 219 231 [[package]] 220 232 name = "blake3" ··· 253 265 version = "3.20.2" 254 266 source = "registry+https://github.com/rust-lang/crates.io-index" 255 267 checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" 268 + 269 + [[package]] 270 + name = "byteorder" 271 + version = "1.5.0" 272 + source = "registry+https://github.com/rust-lang/crates.io-index" 273 + checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 256 274 257 275 [[package]] 258 276 name = "bytes" ··· 339 357 ] 340 358 341 359 [[package]] 360 + name = "concurrent-queue" 361 + version = "2.5.0" 362 + source = "registry+https://github.com/rust-lang/crates.io-index" 363 + checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 364 + dependencies = [ 365 + "crossbeam-utils", 366 + ] 367 + 368 + [[package]] 342 369 name = "const-oid" 343 370 version = "0.9.6" 344 371 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 407 434 ] 408 435 409 436 [[package]] 437 + name = "crc" 438 + version = "3.4.0" 439 + source = "registry+https://github.com/rust-lang/crates.io-index" 440 + checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" 441 + dependencies = [ 442 + "crc-catalog", 443 + ] 444 + 445 + [[package]] 446 + name = "crc-catalog" 447 + version = "2.4.0" 448 + source = "registry+https://github.com/rust-lang/crates.io-index" 449 + checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" 450 + 451 + [[package]] 410 452 name = "critical-section" 411 453 version = "1.2.0" 412 454 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 431 473 ] 432 474 433 475 [[package]] 476 + name = "crossbeam-queue" 477 + version = "0.3.12" 478 + source = "registry+https://github.com/rust-lang/crates.io-index" 479 + checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" 480 + dependencies = [ 481 + "crossbeam-utils", 482 + ] 483 + 484 + [[package]] 434 485 name = "crossbeam-utils" 435 486 version = "0.8.21" 436 487 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 572 623 checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" 573 624 574 625 [[package]] 626 + name = "dotenvy" 627 + version = "0.15.7" 628 + source = "registry+https://github.com/rust-lang/crates.io-index" 629 + checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" 630 + 631 + [[package]] 575 632 name = "ecdsa" 576 633 version = "0.16.9" 577 634 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 608 665 "sha2 0.10.9", 609 666 "subtle", 610 667 "zeroize", 668 + ] 669 + 670 + [[package]] 671 + name = "either" 672 + version = "1.15.0" 673 + source = "registry+https://github.com/rust-lang/crates.io-index" 674 + checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 675 + dependencies = [ 676 + "serde", 611 677 ] 612 678 613 679 [[package]] ··· 672 738 ] 673 739 674 740 [[package]] 741 + name = "etcetera" 742 + version = "0.8.0" 743 + source = "registry+https://github.com/rust-lang/crates.io-index" 744 + checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" 745 + dependencies = [ 746 + "cfg-if", 747 + "home", 748 + "windows-sys 0.48.0", 749 + ] 750 + 751 + [[package]] 752 + name = "event-listener" 753 + version = "5.4.1" 754 + source = "registry+https://github.com/rust-lang/crates.io-index" 755 + checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" 756 + dependencies = [ 757 + "concurrent-queue", 758 + "parking", 759 + "pin-project-lite", 760 + ] 761 + 762 + [[package]] 675 763 name = "fastrand" 676 764 version = "2.4.1" 677 765 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 700 788 checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" 701 789 702 790 [[package]] 791 + name = "flume" 792 + version = "0.11.1" 793 + source = "registry+https://github.com/rust-lang/crates.io-index" 794 + checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" 795 + dependencies = [ 796 + "futures-core", 797 + "futures-sink", 798 + "spin", 799 + ] 800 + 801 + [[package]] 703 802 name = "fnv" 704 803 version = "1.0.7" 705 804 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 718 817 checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" 719 818 720 819 [[package]] 820 + name = "foreign-types" 821 + version = "0.3.2" 822 + source = "registry+https://github.com/rust-lang/crates.io-index" 823 + checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 824 + dependencies = [ 825 + "foreign-types-shared", 826 + ] 827 + 828 + [[package]] 829 + name = "foreign-types-shared" 830 + version = "0.1.1" 831 + source = "registry+https://github.com/rust-lang/crates.io-index" 832 + checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 833 + 834 + [[package]] 721 835 name = "form_urlencoded" 722 836 version = "1.2.2" 723 837 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 766 880 "futures-core", 767 881 "futures-task", 768 882 "futures-util", 883 + ] 884 + 885 + [[package]] 886 + name = "futures-intrusive" 887 + version = "0.5.0" 888 + source = "registry+https://github.com/rust-lang/crates.io-index" 889 + checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" 890 + dependencies = [ 891 + "futures-core", 892 + "lock_api", 893 + "parking_lot", 769 894 ] 770 895 771 896 [[package]] ··· 902 1027 source = "registry+https://github.com/rust-lang/crates.io-index" 903 1028 checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" 904 1029 dependencies = [ 1030 + "allocator-api2", 1031 + "equivalent", 905 1032 "foldhash 0.1.5", 906 1033 ] 907 1034 ··· 923 1050 checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" 924 1051 925 1052 [[package]] 1053 + name = "hashlink" 1054 + version = "0.10.0" 1055 + source = "registry+https://github.com/rust-lang/crates.io-index" 1056 + checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" 1057 + dependencies = [ 1058 + "hashbrown 0.15.5", 1059 + ] 1060 + 1061 + [[package]] 926 1062 name = "heck" 927 1063 version = "0.5.0" 928 1064 source = "registry+https://github.com/rust-lang/crates.io-index" 929 1065 checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 1066 + 1067 + [[package]] 1068 + name = "hex" 1069 + version = "0.4.3" 1070 + source = "registry+https://github.com/rust-lang/crates.io-index" 1071 + checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 930 1072 931 1073 [[package]] 932 1074 name = "hickory-proto" ··· 990 1132 checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 991 1133 dependencies = [ 992 1134 "digest 0.10.7", 1135 + ] 1136 + 1137 + [[package]] 1138 + name = "home" 1139 + version = "0.5.12" 1140 + source = "registry+https://github.com/rust-lang/crates.io-index" 1141 + checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" 1142 + dependencies = [ 1143 + "windows-sys 0.61.2", 993 1144 ] 994 1145 995 1146 [[package]] ··· 1292 1443 ] 1293 1444 1294 1445 [[package]] 1446 + name = "lazy_static" 1447 + version = "1.5.0" 1448 + source = "registry+https://github.com/rust-lang/crates.io-index" 1449 + checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 1450 + dependencies = [ 1451 + "spin", 1452 + ] 1453 + 1454 + [[package]] 1295 1455 name = "leb128fmt" 1296 1456 version = "0.1.0" 1297 1457 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1304 1464 checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" 1305 1465 1306 1466 [[package]] 1467 + name = "libm" 1468 + version = "0.2.16" 1469 + source = "registry+https://github.com/rust-lang/crates.io-index" 1470 + checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" 1471 + 1472 + [[package]] 1473 + name = "libredox" 1474 + version = "0.1.16" 1475 + source = "registry+https://github.com/rust-lang/crates.io-index" 1476 + checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" 1477 + dependencies = [ 1478 + "bitflags", 1479 + "libc", 1480 + "plain", 1481 + "redox_syscall 0.7.4", 1482 + ] 1483 + 1484 + [[package]] 1485 + name = "libsqlite3-sys" 1486 + version = "0.30.1" 1487 + source = "registry+https://github.com/rust-lang/crates.io-index" 1488 + checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" 1489 + dependencies = [ 1490 + "cc", 1491 + "pkg-config", 1492 + "vcpkg", 1493 + ] 1494 + 1495 + [[package]] 1307 1496 name = "linux-raw-sys" 1308 1497 version = "0.12.1" 1309 1498 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1363 1552 checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" 1364 1553 1365 1554 [[package]] 1555 + name = "md-5" 1556 + version = "0.10.6" 1557 + source = "registry+https://github.com/rust-lang/crates.io-index" 1558 + checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" 1559 + dependencies = [ 1560 + "cfg-if", 1561 + "digest 0.10.7", 1562 + ] 1563 + 1564 + [[package]] 1366 1565 name = "memchr" 1367 1566 version = "2.8.0" 1368 1567 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1434 1633 "dotenv", 1435 1634 "serde", 1436 1635 "serde_json", 1636 + "sqlx", 1437 1637 "tokio", 1438 1638 "tokio-stream", 1439 1639 ] 1440 1640 1441 1641 [[package]] 1642 + name = "native-tls" 1643 + version = "0.2.18" 1644 + source = "registry+https://github.com/rust-lang/crates.io-index" 1645 + checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" 1646 + dependencies = [ 1647 + "libc", 1648 + "log", 1649 + "openssl", 1650 + "openssl-probe", 1651 + "openssl-sys", 1652 + "schannel", 1653 + "security-framework", 1654 + "security-framework-sys", 1655 + "tempfile", 1656 + ] 1657 + 1658 + [[package]] 1442 1659 name = "no_std_io2" 1443 1660 version = "0.8.1" 1444 1661 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1448 1665 ] 1449 1666 1450 1667 [[package]] 1668 + name = "num-bigint-dig" 1669 + version = "0.8.6" 1670 + source = "registry+https://github.com/rust-lang/crates.io-index" 1671 + checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" 1672 + dependencies = [ 1673 + "lazy_static", 1674 + "libm", 1675 + "num-integer", 1676 + "num-iter", 1677 + "num-traits", 1678 + "rand 0.8.6", 1679 + "smallvec", 1680 + "zeroize", 1681 + ] 1682 + 1683 + [[package]] 1684 + name = "num-integer" 1685 + version = "0.1.46" 1686 + source = "registry+https://github.com/rust-lang/crates.io-index" 1687 + checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 1688 + dependencies = [ 1689 + "num-traits", 1690 + ] 1691 + 1692 + [[package]] 1693 + name = "num-iter" 1694 + version = "0.1.45" 1695 + source = "registry+https://github.com/rust-lang/crates.io-index" 1696 + checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" 1697 + dependencies = [ 1698 + "autocfg", 1699 + "num-integer", 1700 + "num-traits", 1701 + ] 1702 + 1703 + [[package]] 1451 1704 name = "num-traits" 1452 1705 version = "0.2.19" 1453 1706 source = "registry+https://github.com/rust-lang/crates.io-index" 1454 1707 checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1455 1708 dependencies = [ 1456 1709 "autocfg", 1710 + "libm", 1457 1711 ] 1458 1712 1459 1713 [[package]] ··· 1467 1721 ] 1468 1722 1469 1723 [[package]] 1724 + name = "openssl" 1725 + version = "0.10.78" 1726 + source = "registry+https://github.com/rust-lang/crates.io-index" 1727 + checksum = "f38c4372413cdaaf3cc79dd92d29d7d9f5ab09b51b10dded508fb90bb70b9222" 1728 + dependencies = [ 1729 + "bitflags", 1730 + "cfg-if", 1731 + "foreign-types", 1732 + "libc", 1733 + "once_cell", 1734 + "openssl-macros", 1735 + "openssl-sys", 1736 + ] 1737 + 1738 + [[package]] 1739 + name = "openssl-macros" 1740 + version = "0.1.1" 1741 + source = "registry+https://github.com/rust-lang/crates.io-index" 1742 + checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 1743 + dependencies = [ 1744 + "proc-macro2", 1745 + "quote", 1746 + "syn", 1747 + ] 1748 + 1749 + [[package]] 1470 1750 name = "openssl-probe" 1471 1751 version = "0.2.1" 1472 1752 source = "registry+https://github.com/rust-lang/crates.io-index" 1473 1753 checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" 1474 1754 1475 1755 [[package]] 1756 + name = "openssl-sys" 1757 + version = "0.9.114" 1758 + source = "registry+https://github.com/rust-lang/crates.io-index" 1759 + checksum = "13ce1245cd07fcc4cfdb438f7507b0c7e4f3849a69fd84d52374c66d83741bb6" 1760 + dependencies = [ 1761 + "cc", 1762 + "libc", 1763 + "pkg-config", 1764 + "vcpkg", 1765 + ] 1766 + 1767 + [[package]] 1476 1768 name = "p256" 1477 1769 version = "0.13.2" 1478 1770 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1497 1789 ] 1498 1790 1499 1791 [[package]] 1792 + name = "parking" 1793 + version = "2.2.1" 1794 + source = "registry+https://github.com/rust-lang/crates.io-index" 1795 + checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 1796 + 1797 + [[package]] 1500 1798 name = "parking_lot" 1501 1799 version = "0.12.5" 1502 1800 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1514 1812 dependencies = [ 1515 1813 "cfg-if", 1516 1814 "libc", 1517 - "redox_syscall", 1815 + "redox_syscall 0.5.18", 1518 1816 "smallvec", 1519 1817 "windows-link", 1520 1818 ] ··· 1541 1839 checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" 1542 1840 1543 1841 [[package]] 1842 + name = "pkcs1" 1843 + version = "0.7.5" 1844 + source = "registry+https://github.com/rust-lang/crates.io-index" 1845 + checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" 1846 + dependencies = [ 1847 + "der", 1848 + "pkcs8", 1849 + "spki", 1850 + ] 1851 + 1852 + [[package]] 1544 1853 name = "pkcs8" 1545 1854 version = "0.10.2" 1546 1855 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1549 1858 "der", 1550 1859 "spki", 1551 1860 ] 1861 + 1862 + [[package]] 1863 + name = "pkg-config" 1864 + version = "0.3.33" 1865 + source = "registry+https://github.com/rust-lang/crates.io-index" 1866 + checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" 1867 + 1868 + [[package]] 1869 + name = "plain" 1870 + version = "0.2.3" 1871 + source = "registry+https://github.com/rust-lang/crates.io-index" 1872 + checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" 1552 1873 1553 1874 [[package]] 1554 1875 name = "portable-atomic" ··· 1680 2001 1681 2002 [[package]] 1682 2003 name = "rand" 2004 + version = "0.8.6" 2005 + source = "registry+https://github.com/rust-lang/crates.io-index" 2006 + checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" 2007 + dependencies = [ 2008 + "libc", 2009 + "rand_chacha 0.3.1", 2010 + "rand_core 0.6.4", 2011 + ] 2012 + 2013 + [[package]] 2014 + name = "rand" 1683 2015 version = "0.9.4" 1684 2016 source = "registry+https://github.com/rust-lang/crates.io-index" 1685 2017 checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" 1686 2018 dependencies = [ 1687 - "rand_chacha", 2019 + "rand_chacha 0.9.0", 1688 2020 "rand_core 0.9.5", 1689 2021 ] 1690 2022 ··· 1697 2029 "chacha20", 1698 2030 "getrandom 0.4.2", 1699 2031 "rand_core 0.10.1", 2032 + ] 2033 + 2034 + [[package]] 2035 + name = "rand_chacha" 2036 + version = "0.3.1" 2037 + source = "registry+https://github.com/rust-lang/crates.io-index" 2038 + checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 2039 + dependencies = [ 2040 + "ppv-lite86", 2041 + "rand_core 0.6.4", 1700 2042 ] 1701 2043 1702 2044 [[package]] ··· 1743 2085 ] 1744 2086 1745 2087 [[package]] 2088 + name = "redox_syscall" 2089 + version = "0.7.4" 2090 + source = "registry+https://github.com/rust-lang/crates.io-index" 2091 + checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" 2092 + dependencies = [ 2093 + "bitflags", 2094 + ] 2095 + 2096 + [[package]] 1746 2097 name = "reqwest" 1747 2098 version = "0.12.28" 1748 2099 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1811 2162 "libc", 1812 2163 "untrusted", 1813 2164 "windows-sys 0.52.0", 2165 + ] 2166 + 2167 + [[package]] 2168 + name = "rsa" 2169 + version = "0.9.10" 2170 + source = "registry+https://github.com/rust-lang/crates.io-index" 2171 + checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" 2172 + dependencies = [ 2173 + "const-oid 0.9.6", 2174 + "digest 0.10.7", 2175 + "num-bigint-dig", 2176 + "num-integer", 2177 + "num-traits", 2178 + "pkcs1", 2179 + "pkcs8", 2180 + "rand_core 0.6.4", 2181 + "signature", 2182 + "spki", 2183 + "subtle", 2184 + "zeroize", 1814 2185 ] 1815 2186 1816 2187 [[package]] ··· 2046 2417 ] 2047 2418 2048 2419 [[package]] 2420 + name = "sha1" 2421 + version = "0.10.6" 2422 + source = "registry+https://github.com/rust-lang/crates.io-index" 2423 + checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 2424 + dependencies = [ 2425 + "cfg-if", 2426 + "cpufeatures 0.2.17", 2427 + "digest 0.10.7", 2428 + ] 2429 + 2430 + [[package]] 2049 2431 name = "sha2" 2050 2432 version = "0.10.9" 2051 2433 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2110 2492 version = "1.15.1" 2111 2493 source = "registry+https://github.com/rust-lang/crates.io-index" 2112 2494 checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 2495 + dependencies = [ 2496 + "serde", 2497 + ] 2113 2498 2114 2499 [[package]] 2115 2500 name = "socket2" ··· 2122 2507 ] 2123 2508 2124 2509 [[package]] 2510 + name = "spin" 2511 + version = "0.9.8" 2512 + source = "registry+https://github.com/rust-lang/crates.io-index" 2513 + checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 2514 + dependencies = [ 2515 + "lock_api", 2516 + ] 2517 + 2518 + [[package]] 2125 2519 name = "spki" 2126 2520 version = "0.7.3" 2127 2521 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2132 2526 ] 2133 2527 2134 2528 [[package]] 2529 + name = "sqlx" 2530 + version = "0.8.6" 2531 + source = "registry+https://github.com/rust-lang/crates.io-index" 2532 + checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" 2533 + dependencies = [ 2534 + "sqlx-core", 2535 + "sqlx-macros", 2536 + "sqlx-mysql", 2537 + "sqlx-postgres", 2538 + "sqlx-sqlite", 2539 + ] 2540 + 2541 + [[package]] 2542 + name = "sqlx-core" 2543 + version = "0.8.6" 2544 + source = "registry+https://github.com/rust-lang/crates.io-index" 2545 + checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" 2546 + dependencies = [ 2547 + "base64", 2548 + "bytes", 2549 + "crc", 2550 + "crossbeam-queue", 2551 + "either", 2552 + "event-listener", 2553 + "futures-core", 2554 + "futures-intrusive", 2555 + "futures-io", 2556 + "futures-util", 2557 + "hashbrown 0.15.5", 2558 + "hashlink", 2559 + "indexmap", 2560 + "log", 2561 + "memchr", 2562 + "native-tls", 2563 + "once_cell", 2564 + "percent-encoding", 2565 + "serde", 2566 + "serde_json", 2567 + "sha2 0.10.9", 2568 + "smallvec", 2569 + "thiserror", 2570 + "tokio", 2571 + "tokio-stream", 2572 + "tracing", 2573 + "url", 2574 + ] 2575 + 2576 + [[package]] 2577 + name = "sqlx-macros" 2578 + version = "0.8.6" 2579 + source = "registry+https://github.com/rust-lang/crates.io-index" 2580 + checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" 2581 + dependencies = [ 2582 + "proc-macro2", 2583 + "quote", 2584 + "sqlx-core", 2585 + "sqlx-macros-core", 2586 + "syn", 2587 + ] 2588 + 2589 + [[package]] 2590 + name = "sqlx-macros-core" 2591 + version = "0.8.6" 2592 + source = "registry+https://github.com/rust-lang/crates.io-index" 2593 + checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" 2594 + dependencies = [ 2595 + "dotenvy", 2596 + "either", 2597 + "heck", 2598 + "hex", 2599 + "once_cell", 2600 + "proc-macro2", 2601 + "quote", 2602 + "serde", 2603 + "serde_json", 2604 + "sha2 0.10.9", 2605 + "sqlx-core", 2606 + "sqlx-mysql", 2607 + "sqlx-postgres", 2608 + "sqlx-sqlite", 2609 + "syn", 2610 + "tokio", 2611 + "url", 2612 + ] 2613 + 2614 + [[package]] 2615 + name = "sqlx-mysql" 2616 + version = "0.8.6" 2617 + source = "registry+https://github.com/rust-lang/crates.io-index" 2618 + checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" 2619 + dependencies = [ 2620 + "atoi", 2621 + "base64", 2622 + "bitflags", 2623 + "byteorder", 2624 + "bytes", 2625 + "crc", 2626 + "digest 0.10.7", 2627 + "dotenvy", 2628 + "either", 2629 + "futures-channel", 2630 + "futures-core", 2631 + "futures-io", 2632 + "futures-util", 2633 + "generic-array", 2634 + "hex", 2635 + "hkdf", 2636 + "hmac", 2637 + "itoa", 2638 + "log", 2639 + "md-5", 2640 + "memchr", 2641 + "once_cell", 2642 + "percent-encoding", 2643 + "rand 0.8.6", 2644 + "rsa", 2645 + "serde", 2646 + "sha1", 2647 + "sha2 0.10.9", 2648 + "smallvec", 2649 + "sqlx-core", 2650 + "stringprep", 2651 + "thiserror", 2652 + "tracing", 2653 + "whoami", 2654 + ] 2655 + 2656 + [[package]] 2657 + name = "sqlx-postgres" 2658 + version = "0.8.6" 2659 + source = "registry+https://github.com/rust-lang/crates.io-index" 2660 + checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" 2661 + dependencies = [ 2662 + "atoi", 2663 + "base64", 2664 + "bitflags", 2665 + "byteorder", 2666 + "crc", 2667 + "dotenvy", 2668 + "etcetera", 2669 + "futures-channel", 2670 + "futures-core", 2671 + "futures-util", 2672 + "hex", 2673 + "hkdf", 2674 + "hmac", 2675 + "home", 2676 + "itoa", 2677 + "log", 2678 + "md-5", 2679 + "memchr", 2680 + "once_cell", 2681 + "rand 0.8.6", 2682 + "serde", 2683 + "serde_json", 2684 + "sha2 0.10.9", 2685 + "smallvec", 2686 + "sqlx-core", 2687 + "stringprep", 2688 + "thiserror", 2689 + "tracing", 2690 + "whoami", 2691 + ] 2692 + 2693 + [[package]] 2694 + name = "sqlx-sqlite" 2695 + version = "0.8.6" 2696 + source = "registry+https://github.com/rust-lang/crates.io-index" 2697 + checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" 2698 + dependencies = [ 2699 + "atoi", 2700 + "flume", 2701 + "futures-channel", 2702 + "futures-core", 2703 + "futures-executor", 2704 + "futures-intrusive", 2705 + "futures-util", 2706 + "libsqlite3-sys", 2707 + "log", 2708 + "percent-encoding", 2709 + "serde", 2710 + "serde_urlencoded", 2711 + "sqlx-core", 2712 + "thiserror", 2713 + "tracing", 2714 + "url", 2715 + ] 2716 + 2717 + [[package]] 2135 2718 name = "stable_deref_trait" 2136 2719 version = "1.2.1" 2137 2720 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2142 2725 version = "1.1.0" 2143 2726 source = "registry+https://github.com/rust-lang/crates.io-index" 2144 2727 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 2728 + 2729 + [[package]] 2730 + name = "stringprep" 2731 + version = "0.1.5" 2732 + source = "registry+https://github.com/rust-lang/crates.io-index" 2733 + checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" 2734 + dependencies = [ 2735 + "unicode-bidi", 2736 + "unicode-normalization", 2737 + "unicode-properties", 2738 + ] 2145 2739 2146 2740 [[package]] 2147 2741 name = "subtle" ··· 2440 3034 checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" 2441 3035 2442 3036 [[package]] 3037 + name = "unicode-bidi" 3038 + version = "0.3.18" 3039 + source = "registry+https://github.com/rust-lang/crates.io-index" 3040 + checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" 3041 + 3042 + [[package]] 2443 3043 name = "unicode-ident" 2444 3044 version = "1.0.24" 2445 3045 source = "registry+https://github.com/rust-lang/crates.io-index" 2446 3046 checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" 3047 + 3048 + [[package]] 3049 + name = "unicode-normalization" 3050 + version = "0.1.25" 3051 + source = "registry+https://github.com/rust-lang/crates.io-index" 3052 + checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" 3053 + dependencies = [ 3054 + "tinyvec", 3055 + ] 3056 + 3057 + [[package]] 3058 + name = "unicode-properties" 3059 + version = "0.1.4" 3060 + source = "registry+https://github.com/rust-lang/crates.io-index" 3061 + checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" 2447 3062 2448 3063 [[package]] 2449 3064 name = "unicode-xid" ··· 2493 3108 ] 2494 3109 2495 3110 [[package]] 3111 + name = "vcpkg" 3112 + version = "0.2.15" 3113 + source = "registry+https://github.com/rust-lang/crates.io-index" 3114 + checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 3115 + 3116 + [[package]] 2496 3117 name = "version_check" 2497 3118 version = "0.9.5" 2498 3119 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2530 3151 dependencies = [ 2531 3152 "wit-bindgen 0.51.0", 2532 3153 ] 3154 + 3155 + [[package]] 3156 + name = "wasite" 3157 + version = "0.1.0" 3158 + source = "registry+https://github.com/rust-lang/crates.io-index" 3159 + checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" 2533 3160 2534 3161 [[package]] 2535 3162 name = "wasm-bindgen" ··· 2647 3274 checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" 2648 3275 dependencies = [ 2649 3276 "rustls-pki-types", 3277 + ] 3278 + 3279 + [[package]] 3280 + name = "whoami" 3281 + version = "1.6.1" 3282 + source = "registry+https://github.com/rust-lang/crates.io-index" 3283 + checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" 3284 + dependencies = [ 3285 + "libredox", 3286 + "wasite", 2650 3287 ] 2651 3288 2652 3289 [[package]] ··· 2692 3329 2693 3330 [[package]] 2694 3331 name = "windows-sys" 3332 + version = "0.48.0" 3333 + source = "registry+https://github.com/rust-lang/crates.io-index" 3334 + checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 3335 + dependencies = [ 3336 + "windows-targets 0.48.5", 3337 + ] 3338 + 3339 + [[package]] 3340 + name = "windows-sys" 2695 3341 version = "0.52.0" 2696 3342 source = "registry+https://github.com/rust-lang/crates.io-index" 2697 3343 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" ··· 2719 3365 2720 3366 [[package]] 2721 3367 name = "windows-targets" 3368 + version = "0.48.5" 3369 + source = "registry+https://github.com/rust-lang/crates.io-index" 3370 + checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 3371 + dependencies = [ 3372 + "windows_aarch64_gnullvm 0.48.5", 3373 + "windows_aarch64_msvc 0.48.5", 3374 + "windows_i686_gnu 0.48.5", 3375 + "windows_i686_msvc 0.48.5", 3376 + "windows_x86_64_gnu 0.48.5", 3377 + "windows_x86_64_gnullvm 0.48.5", 3378 + "windows_x86_64_msvc 0.48.5", 3379 + ] 3380 + 3381 + [[package]] 3382 + name = "windows-targets" 2722 3383 version = "0.52.6" 2723 3384 source = "registry+https://github.com/rust-lang/crates.io-index" 2724 3385 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" ··· 2752 3413 2753 3414 [[package]] 2754 3415 name = "windows_aarch64_gnullvm" 3416 + version = "0.48.5" 3417 + source = "registry+https://github.com/rust-lang/crates.io-index" 3418 + checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 3419 + 3420 + [[package]] 3421 + name = "windows_aarch64_gnullvm" 2755 3422 version = "0.52.6" 2756 3423 source = "registry+https://github.com/rust-lang/crates.io-index" 2757 3424 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" ··· 2764 3431 2765 3432 [[package]] 2766 3433 name = "windows_aarch64_msvc" 3434 + version = "0.48.5" 3435 + source = "registry+https://github.com/rust-lang/crates.io-index" 3436 + checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 3437 + 3438 + [[package]] 3439 + name = "windows_aarch64_msvc" 2767 3440 version = "0.52.6" 2768 3441 source = "registry+https://github.com/rust-lang/crates.io-index" 2769 3442 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" ··· 2773 3446 version = "0.53.1" 2774 3447 source = "registry+https://github.com/rust-lang/crates.io-index" 2775 3448 checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" 3449 + 3450 + [[package]] 3451 + name = "windows_i686_gnu" 3452 + version = "0.48.5" 3453 + source = "registry+https://github.com/rust-lang/crates.io-index" 3454 + checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2776 3455 2777 3456 [[package]] 2778 3457 name = "windows_i686_gnu" ··· 2800 3479 2801 3480 [[package]] 2802 3481 name = "windows_i686_msvc" 3482 + version = "0.48.5" 3483 + source = "registry+https://github.com/rust-lang/crates.io-index" 3484 + checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 3485 + 3486 + [[package]] 3487 + name = "windows_i686_msvc" 2803 3488 version = "0.52.6" 2804 3489 source = "registry+https://github.com/rust-lang/crates.io-index" 2805 3490 checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" ··· 2812 3497 2813 3498 [[package]] 2814 3499 name = "windows_x86_64_gnu" 3500 + version = "0.48.5" 3501 + source = "registry+https://github.com/rust-lang/crates.io-index" 3502 + checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 3503 + 3504 + [[package]] 3505 + name = "windows_x86_64_gnu" 2815 3506 version = "0.52.6" 2816 3507 source = "registry+https://github.com/rust-lang/crates.io-index" 2817 3508 checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" ··· 2824 3515 2825 3516 [[package]] 2826 3517 name = "windows_x86_64_gnullvm" 3518 + version = "0.48.5" 3519 + source = "registry+https://github.com/rust-lang/crates.io-index" 3520 + checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 3521 + 3522 + [[package]] 3523 + name = "windows_x86_64_gnullvm" 2827 3524 version = "0.52.6" 2828 3525 source = "registry+https://github.com/rust-lang/crates.io-index" 2829 3526 checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" ··· 2833 3530 version = "0.53.1" 2834 3531 source = "registry+https://github.com/rust-lang/crates.io-index" 2835 3532 checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" 3533 + 3534 + [[package]] 3535 + name = "windows_x86_64_msvc" 3536 + version = "0.48.5" 3537 + source = "registry+https://github.com/rust-lang/crates.io-index" 3538 + checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2836 3539 2837 3540 [[package]] 2838 3541 name = "windows_x86_64_msvc"
+1
Cargo.toml
··· 10 10 dotenv = "0.15.0" 11 11 serde = { version = "1.0.228", features = ["derive"] } 12 12 serde_json = "1.0.149" 13 + sqlx = { version = "0.8.6", features = ["runtime-tokio-native-tls", "sqlite"] } 13 14 tokio = { version = "1.52.1", features = ["full"] } 14 15 tokio-stream = "0.1.18"
+4
docker-compose.yaml
··· 4 4 image: atcr.io/willdot.net/my-appview:latest 5 5 ports: 6 6 - "3333:3000" 7 + volumes: 8 + - ./data:/data 7 9 restart: always 8 10 environment: 9 11 APPVIEW_DID: ${APPVIEW_DID} 10 12 APPVIEW_HOSTNAME: ${APPVIEW_HOSTNAME} 11 13 APPVIEW_HOST: ${APPVIEW_HOST} 12 14 APPVIEW_PORT: ${APPVIEW_PORT} 15 + USERS_DID: ${USERS_DID} 13 16 TAP_URL: ${TAP_URL} 17 + DATABASE_URL: ${DATABASE_URL} 14 18 15 19 tap: 16 20 container_name: tap
+7
migrations/20260421195050_follows.sql
··· 1 + -- Create a follows table 2 + CREATE TABLE IF NOT EXISTS follows 3 + ( 4 + id INTEGER PRIMARY KEY NOT NULL, 5 + subject TEXT NOT NULL, 6 + rkey TEXT NOT NULL 7 + );
+13 -1
src/main.rs
··· 1 1 mod server; 2 2 mod tap; 3 + use sqlx::migrate::MigrateDatabase; 3 4 4 5 #[tokio::main] 5 6 async fn main() -> anyhow::Result<()> { 6 7 dotenv::dotenv().ok(); 7 8 9 + let db_url = std::env::var("DATABASE_URL")?; 10 + 11 + if !sqlx::Sqlite::database_exists(&db_url).await? { 12 + sqlx::Sqlite::create_database(&db_url).await?; 13 + } 14 + 15 + let pool = sqlx::SqlitePool::connect(&db_url).await?; 16 + 17 + // run migrations 18 + sqlx::migrate!("./migrations").run(&pool).await?; 19 + 8 20 // add the users repo to tap to ensure it has all of that when the tap subscribing starts, 9 21 // it has all the users data 10 22 let users_did = std::env::var("USERS_DID").unwrap(); 11 23 tap::add_repo(&users_did).await?; 12 24 13 - tokio::join!(server::run_server(), tap::run_tap(users_did)); 25 + tokio::join!(server::run_server(), tap::run_tap(users_did, &pool)); 14 26 Ok(()) 15 27 }
+64 -13
src/tap.rs
··· 1 - use atproto_tap::{TapClient, TapEvent, connect_to}; 1 + use atproto_tap::{RecordAction, RecordEvent, TapClient, TapEvent, connect_to}; 2 + use axum::response::sse::Event; 3 + use serde::Deserialize; 2 4 use tokio_stream::StreamExt; 3 5 4 - pub async fn run_tap(users_did: String) { 6 + #[derive(Deserialize)] 7 + struct FollowRecord { 8 + subject: String, 9 + } 10 + 11 + pub async fn add_repo(did: &String) -> anyhow::Result<()> { 12 + let tap_url = std::env::var("TAP_URL").unwrap_or("localhost:2480".to_string()); 13 + let client = TapClient::new(tap_url.as_str(), Some("password".to_string())); 14 + 15 + // Add repositories to track 16 + client.add_repos(&[did.as_str()]).await?; 17 + 18 + Ok(()) 19 + } 20 + 21 + pub async fn run_tap(users_did: String, pool: &sqlx::SqlitePool) { 5 22 let tap_url = std::env::var("TAP_URL").unwrap_or("localhost:2480".to_string()); 6 23 let mut stream = connect_to(tap_url.as_str()); 7 24 ··· 9 26 match result { 10 27 Ok(event) => match event.as_ref() { 11 28 TapEvent::Record { record, .. } => { 12 - // TODO: If the record collection is something other than bsky post and the appview users did 13 - // handle -> such as a follow, block etc 14 - // Otherwise the record collection is a bsky post in which case index 15 - if record.did.clone().into_string() == users_did { 16 - println!("event from user") 29 + let collection = String::from(record.collection.clone()); 30 + 31 + match collection.as_str() { 32 + "app.bsky.graph.follow" => { 33 + if record.did.clone().into_string() == users_did { 34 + handle_user_follow_event(record, pool).await; 35 + } 36 + } 37 + "app.bsky.feed.post" => { 38 + handle_post_event(record, pool).await; 39 + } 40 + _ => {} 17 41 } 42 + 18 43 println!("{} {} {}", record.action, record.collection, record.did); 19 44 } 20 45 TapEvent::Identity { identity, .. } => { ··· 26 51 } 27 52 } 28 53 29 - pub async fn add_repo(did: &String) -> anyhow::Result<()> { 30 - let tap_url = std::env::var("TAP_URL").unwrap_or("localhost:2480".to_string()); 31 - let client = TapClient::new(tap_url.as_str(), Some("password".to_string())); 54 + async fn handle_user_follow_event(record: &RecordEvent, pool: &sqlx::SqlitePool) { 55 + match record.action { 56 + RecordAction::Create => { 57 + let follow: FollowRecord = record.parse_record().unwrap(); 58 + let result = sqlx::query("INSERT INTO follows (subject, rkey) VALUES ($1, $2)") 59 + .bind(follow.subject) 60 + .bind(record.rkey.to_string()) 61 + .execute(pool) 62 + .await; 32 63 33 - // Add repositories to track 34 - client.add_repos(&[did.as_str()]).await?; 64 + if result.is_err() { 65 + println!("Error inserting follow into the database: {result:?}"); 66 + } 67 + } 68 + RecordAction::Delete => { 69 + let result = sqlx::query("DELETE FROM follows WHERE rkey = $1") 70 + .bind(record.rkey.to_string()) 71 + .execute(pool) 72 + .await; 35 73 36 - Ok(()) 74 + if result.is_err() { 75 + println!("Error deleting follow from the database: {result:?}"); 76 + } 77 + } 78 + RecordAction::Update => {} 79 + } 80 + } 81 + 82 + async fn handle_post_event(record: &RecordEvent, pool: &sqlx::SqlitePool) { 83 + match record.action { 84 + RecordAction::Create => {} 85 + RecordAction::Delete => {} 86 + RecordAction::Update => {} 87 + } 37 88 }