šŸ“¦āž”šŸ¦‹ Store and retrieve files on the Atmosphere
35
fork

Configure Feed

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

various

Ducky 3081ba07 7f4e01e7

+175 -47
+175 -47
atfile.sh
··· 170 170 fi 171 171 } 172 172 173 + function atfile.util.get_didplc_doc() { 174 + actor="$1" 175 + 176 + function atfile.util.get_didplc_doc.request_doc() { 177 + endpoint="$1" 178 + actor="$2" 179 + 180 + curl -s -L -X GET "$endpoint/$actor" 181 + } 182 + 183 + didplc_doc="$(atfile.util.get_didplc_doc.request_doc "$_endpoint_plc_directory" "$actor")" 184 + 185 + if [[ "$didplc_doc" != "{"* ]]; then 186 + didplc_doc="$(atfile.util.get_didplc_doc.request_doc "$_endpoint_plc_directory_fallback" "$actor")" 187 + fi 188 + 189 + echo "$didplc_doc" 190 + } 191 + 173 192 function atfile.util.get_envvar() { 174 193 envvar="$1" 175 194 default="$2" ··· 499 518 esac 500 519 } 501 520 521 + function atfile.util.get_pds_pretty() { 522 + pds="$1" 523 + 524 + pds="$(echo $pds | cut -d "/" -f 3)" 525 + 526 + if [[ $pds == *".host.bsky.network" ]]; then 527 + pds_host="$(echo $pds | cut -d "." -f 1)" 528 + pds_region="$(echo $pds | cut -d "." -f 2)" 529 + echo "šŸ„ ${pds_host^} ($(atfile.util.get_region_pretty "$pds_region"))" 530 + else 531 + echo "$pds" 532 + fi 533 + } 534 + 502 535 function atfile.util.get_realpath() { 503 536 path="$1" 504 537 ··· 507 540 else 508 541 realpath -s "$path" 509 542 fi 543 + } 544 + 545 + function atfile.util.get_region_pretty() { 546 + region="$1" 547 + 548 + region_sub="$(echo $1 | cut -d "-" -f 2)" 549 + region="$(echo $1 | cut -d "-" -f 1)" 550 + 551 + echo "${region^^} ${region_sub^}" 510 552 } 511 553 512 554 function atfile.util.get_rkey_from_at_uri() { ··· 577 619 578 620 function atfile.util.is_url_accessible_in_browser() { 579 621 url="$1" 622 + atfile.util.is_url_okay "$url" "$_test_desktop_uas" 623 + } 580 624 581 - code="$(curl -H "User-Agent: $_test_desktop_uas" -s -o /dev/null -w "%{http_code}" "$url")" 582 - 625 + function atfile.util.is_url_okay() { 626 + url="$1" 627 + uas="$2" 628 + 629 + [[ -z "$uas" ]] && uas="$(atfile.util.get_uas)" 630 + 631 + code="$(curl -H "User-Agent: $uas" -s -o /dev/null -w "%{http_code}" "$url")" 632 + 583 633 if [[ "$code" == 2* || "$code" == 3* ]]; then 584 634 echo 1 585 635 else ··· 613 663 echo "$_fmt_out_file" | sed -e "s|\[name\]|$name|g" -e "s|\[key\]|$key|g" 614 664 } 615 665 616 - function atfile.util.resolve_identity() { 617 - actor="$1" 618 - 619 - if [[ "$actor" != "did:"* ]]; then 620 - resolved_handle="$(atfile.xrpc.get "com.atproto.identity.resolveHandle" "handle=$actor" "" "$_endpoint_resolve_handle")" 621 - if [[ $(atfile.util.is_xrpc_success $? "$resolved_handle") == 1 ]]; then 622 - actor="$(echo "$resolved_handle" | jq -r ".did")" 623 - fi 624 - fi 625 - 626 - if [[ "$actor" == "did:"* ]]; then 627 - unset did_doc 628 - 629 - case "$actor" in 630 - "did:plc:"*) did_doc="$(curl -s -L -X GET "$_endpoint_plc_directory/$actor")" ;; # TODO: What if they're not on plc.directory? 631 - "did:web:"*) did_doc="$(curl -s -L -X GET "$(echo "$actor" | sed "s/did:web://")/.well-known/did.json")" ;; 632 - esac 633 - 634 - if [[ $? != 0 || -z "$did_doc" ]]; then 635 - atfile.die "Unable to fetch DID Doc for '$actor'" 636 - else 637 - did="$(echo "$did_doc" | jq -r ".id")" 638 - pds="$(echo "$did_doc" | jq -r '.service[] | select(.id == "#atproto_pds") | .serviceEndpoint')" 639 - 640 - echo "$did@$pds" 641 - fi 642 - else 643 - atfile.die "Unable to resolve '$actor'" 644 - fi 645 - } 646 - 647 666 # HACK: This essentially breaks the entire session (it overrides $_username and 648 667 # $_server). If sourcing, use atfile.util.override_actor_reset() to 649 668 # reset ··· 656 675 657 676 if ! [[ $actor == $_username ]]; then 658 677 resolved_id="$(atfile.util.resolve_identity "$actor")" 659 - _username="$(echo $resolved_id | cut -d "@" -f 1)" 660 - _server="$(echo $resolved_id | cut -d "@" -f 2)" 678 + _username="$(echo $resolved_id | cut -d "|" -f 1)" 679 + _server="$(echo $resolved_id | cut -d "|" -f 2)" 661 680 662 681 if [[ "$_fmt_blob_url" != "$_fmt_blob_url_default" ]]; then 663 682 export _fmt_blob_url="$_fmt_blob_url_default" ··· 671 690 [[ -n "$_server_original" ]] && _server="$_server_original"; unset _server_original 672 691 [[ -n "$_username_original" ]] && _username="$_username_original"; unset _username_original 673 692 [[ -n "$_fmt_blob_url_original" ]] && _fmt_blob_url="$_fmt_blob_url_original"; unset _fmt_blob_url_original 693 + } 694 + 695 + function atfile.util.parse_exiftool_date() { 696 + in_date="$1" 697 + tz="$2" 698 + 699 + date="$(echo "$in_date" | cut -d " " -f 1 | sed -e "s|:|-|g")" 700 + time="$(echo "$in_date" | cut -d " " -f 2)" 701 + 702 + echo "$date $time $tz" 674 703 } 675 704 676 705 function atfile.util.print_blob_url_output() { ··· 720 749 fi 721 750 } 722 751 723 - function atfile.util.parse_exiftool_date() { 724 - in_date="$1" 725 - tz="$2" 726 - 727 - date="$(echo "$in_date" | cut -d " " -f 1 | sed -e "s|:|-|g")" 728 - time="$(echo "$in_date" | cut -d " " -f 2)" 729 - 730 - echo "$date $time $tz" 731 - } 732 - 733 752 function atfile.util.repeat_char() { 734 753 char="$1" 735 754 amount="$2" ··· 737 756 printf "%0.s$char" $(seq 1 $amount) 738 757 } 739 758 759 + function atfile.util.resolve_identity() { 760 + actor="$1" 761 + 762 + if [[ "$actor" != "did:"* ]]; then 763 + resolved_handle="$(atfile.xrpc.get "com.atproto.identity.resolveHandle" "handle=$actor" "" "$_endpoint_resolve_handle")" 764 + if [[ $(atfile.util.is_xrpc_success $? "$resolved_handle") == 1 ]]; then 765 + actor="$(echo "$resolved_handle" | jq -r ".did")" 766 + fi 767 + fi 768 + 769 + if [[ "$actor" == "did:"* ]]; then 770 + unset did_doc 771 + 772 + case "$actor" in 773 + "did:plc:"*) did_doc="$(atfile.util.get_didplc_doc "$actor")" ;; 774 + "did:web:"*) did_doc="$(curl -s -L -X GET "$(echo "$actor" | sed "s/did:web://")/.well-known/did.json")" ;; 775 + esac 776 + 777 + if [[ $? != 0 || -z "$did_doc" ]]; then 778 + atfile.die "Unable to fetch DID Doc for '$actor'" 779 + else 780 + did="$(echo "$did_doc" | jq -r ".id")" 781 + pds="$(echo "$did_doc" | jq -r '.service[] | select(.id == "#atproto_pds") | .serviceEndpoint')" 782 + handle="$(echo "$did_doc" | jq -r '.alsoKnownAs[0]')" 783 + 784 + echo "$did|$pds|$handle" 785 + fi 786 + else 787 + atfile.die "Unable to resolve '$actor'" 788 + fi 789 + } 790 + 740 791 function atfile.util.write_cache() { 741 792 file="$1" 742 793 file_path="$_cache_dir/$1" ··· 1806 1857 fi 1807 1858 } 1808 1859 1860 + function atfile.invoke.resolve() { 1861 + actor="$1" 1862 + 1863 + atfile.say.debug "Resolving actor '$actor'..." 1864 + resolved_did="$(atfile.util.resolve_identity "$actor")" 1865 + 1866 + alias="$(echo $resolved_did | cut -d "|" -f 3)" 1867 + did="$(echo $resolved_did | cut -d "|" -f 1)" 1868 + did_type="did:$(echo $did | cut -d ":" -f 2)" 1869 + handle="$(echo $resolved_did | cut -d "|" -f 3 | cut -d "/" -f 3)" 1870 + pds="$(echo $resolved_did | cut -d "|" -f 2)" 1871 + pds_name="$(atfile.util.get_pds_pretty "$pds")" 1872 + atfile.say.debug "Getting PDS version for '$pds'..." 1873 + pds_version="$(curl -s -l -X GET "$pds/xrpc/_health" | jq -r '.version')" 1874 + 1875 + # TODO: Check if the actor has records for these where appropriate? 1876 + app_bluesky="https://bsky.app/profile/$handle" 1877 + app_bridgyfed="https://fed.brid.gy/bsky/$handle" 1878 + app_frontpage="https://frontpage.fyi/profile/$handle" 1879 + app_internect="" 1880 + app_whitewind="https://whtwnd.com/$handle" 1881 + 1882 + if [[ $did_type == "did:plc" ]]; then 1883 + app_internect="https://internect.info/did/$did" 1884 + fi 1885 + 1886 + atfile.say.debug "Resolving actor on Bridgy Fed..." 1887 + if [[ $(atfile.util.is_url_okay "$app_bridgyfed") == 0 ]]; then 1888 + unset app_bridgyfed 1889 + fi 1890 + 1891 + if [[ $_output_json == 1 ]]; then 1892 + echo -e "{ 1893 + \"alias\": \"$alias\", 1894 + \"apps\": { 1895 + \"Bluesky\": \"$app_bluesky\", 1896 + \"BridgyFed\": \"$app_bridgyfed\", 1897 + \"Frontpage\": \"$app_frontpage\", 1898 + \"Internect\": $(if [[ -z $app_internect ]]; then echo "null"; else echo "\"$app_internect\""; fi), 1899 + \"Whitewind\": \"$app_whitewind\" 1900 + }, 1901 + \"did\": \"$did\", 1902 + \"pds\": { 1903 + \"endpoint\": \"$pds\", 1904 + \"name\": \"$pds_name\", 1905 + \"version\": \"$pds_version\" 1906 + }, 1907 + \"type\": \"$did_type\" 1908 + }" | jq 1909 + else 1910 + echo "$did" 1911 + echo "↳ Type: $did_type" 1912 + echo "↳ Alias: $alias" 1913 + echo "↳ PDS: $pds_name" 1914 + echo " ↳ Endpoint: $pds" 1915 + echo " ↳ Version: $pds_version" 1916 + echo "↳ Apps" 1917 + echo " ↳ Bluesky: $app_bluesky" 1918 + [[ -n $app_bridgyfed ]] && echo " ↳ Bridgy Fed: $app_bridgyfed" 1919 + echo " ↳ Frontpage: $app_frontpage" 1920 + [[ -n $app_internect ]] && echo " ↳ Internect: $app_internect" 1921 + echo " ↳ Whitewind: $app_whitewind" 1922 + fi 1923 + } 1924 + 1809 1925 function atfile.invoke.stream() { 1810 1926 collection="$1" 1811 1927 [[ -z "$collection" ]] && collection="blue.zio.atfile.upload" ··· 2022 2138 āš ļø Intended for advanced users. Here be dragons 2023 2139 ā„¹ļø <collection> defaults to '$_nsid_upload' 2024 2140 2141 + resolve <actor> 2142 + Get details for <actor> 2143 + 2025 2144 stream <collection> 2026 2145 Stream records from JetStream" 2027 2146 fi ··· 2256 2375 "download-crypt"|"fc"|"dc") _command="fetch-crypt" ;; 2257 2376 "get"|"i") _command="info" ;; 2258 2377 "ls") _command="list" ;; 2378 + "did") _command="resolve" ;; 2259 2379 "js") _command="stream" ;; 2260 2380 "ul"|"u") _command="upload" ;; 2261 2381 "uc") _command="upload-crypt" ;; ··· 2301 2421 atfile.say.debug "Resolving identity..." 2302 2422 2303 2423 resolved_id="$(atfile.util.resolve_identity "$_username")" 2304 - _username="$(echo $resolved_id | cut -d "@" -f 1)" 2305 - _server="$(echo $resolved_id | cut -d "@" -f 2)" 2424 + _username="$(echo $resolved_id | cut -d "|" -f 1)" 2425 + _server="$(echo $resolved_id | cut -d "|" -f 2)" 2306 2426 2307 2427 atfile.say.debug "Resolved identity\n↳ DID: $_username\n↳ PDS: $_server" 2308 2428 fi ··· 2422 2542 "rm"|"delete"|"d") atfile.invoke.manage_record "delete" "$3" "$4" ;; 2423 2543 *) atfile.die.unknown_command "$(echo "$_command $2" | xargs)" ;; 2424 2544 esac 2545 + else 2546 + atfile.util.print_hidden_command_warning 2547 + exit 1 2548 + fi 2549 + ;; 2550 + "resolve") 2551 + if [[ "$_enable_hidden_commands" == 1 ]]; then 2552 + atfile.invoke.resolve "$2" 2425 2553 else 2426 2554 atfile.util.print_hidden_command_warning 2427 2555 exit 1