

{"id":14177,"date":"2023-07-07T12:21:30","date_gmt":"2023-07-07T17:21:30","guid":{"rendered":"https:\/\/rud.is\/b\/?p=14177"},"modified":"2023-07-07T14:01:14","modified_gmt":"2023-07-07T19:01:14","slug":"poor-dudes-janky-bluesky-feed-reader-cli-via-r-python","status":"publish","type":"post","link":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/","title":{"rendered":"Poor Dude&#8217;s Janky Bluesky Feed Reader CLI Via R &#038; Python"},"content":{"rendered":"<p>Lynn (of <a href=\"https:\/\/arnicas.substack.com\/\">TITAA<\/a> and general NLP wizardy fame) was gracious enough to lend me a <a href=\"https:\/\/bsky.app\/\">Bluesky<\/a> invite, so I could claim my handle on yet-another social media site. I&#8217;m still wary of it (as noted in one of <a href=\"https:\/\/dailyfinds.hrbrmstr.dev\/i\/133440384\/getting-up-in-blueskys-bidnez\">this week&#8217;s Drops<\/a>), but the AT protocol \u2014\u00a0whilst super (lacking a better word) &#8220;verbose&#8221; \u2014 is pretty usable, especially thanks to Ilya Siamionau&#8217;s <a href=\"https:\/\/github.com\/MarshalX\/atproto\">atproto<\/a> AT Protocol SDK for Python.<\/p>\n<p>Longtime readers know I am most certainly <em>not<\/em> going to use Python directly, as such practice has been found to cause early onset dementia. But, that module is so well done that I&#8217;ll gladly use it from within R.<\/p>\n<p>I whipped up a small R script CLI that will fetch my feed and display it via the terminal. While I also use the web app and the Raycast extension to read the feed, it&#8217;s a billion degrees outside, so used the need to stay indoors as an excuse to add this third way of checking what&#8217;s new.<\/p>\n<p>Store your handle and app-password in <code>BSKY_USER<\/code> and <code>BSKY_KEY<\/code>, respectively, adjust the shebang accordingly, add execute permissions to the file and ?, you can do the same.<\/p>\n<pre><code class=\"language-r\">#!\/usr\/local\/bin\/Rscript\n\nsuppressPackageStartupMessages({\n  library(reticulate, quietly = TRUE, warn.conflicts = FALSE)\n  library(lubridate, include.only = c(\"as.period\", \"interval\"), quietly = TRUE, warn.conflicts = FALSE)\n  library(crayon, quietly = TRUE, warn.conflicts = FALSE)\n})\n\n# Get where {reticlulate} thinks your python is via py_config()$python\n# then use the full path to \n#   \/full\/path\/to\/python3 -m pip install atproto\n\natproto &lt;- import(\"atproto\")\n\nclient &lt;- atproto$Client()\n\nprofile &lt;- client$login(Sys.getenv(\"BSKY_USER\"), Sys.getenv(\"BSKY_KEY\"))\n\nres &lt;- client$bsky$feed$get_timeline(list(algorithm = \"reverse-chronological\"))\n\nfor (item in rev(res$feed)) (\n  cat(\n    blue(item$post$author$displayName), \" \u2022 \",\n    silver(gsub(\"\\\\.[[:digit:]]+\", \"\", tolower(as.character(as.period(interval(item$post$record$createdAt, Sys.time()))))), \"ago\\n\"),\n    italic(paste0(strwrap(item$post$record$text, 50), collapse=\"\\n\")), \"\\n\",\n    ifelse(\n      hasName(item$post$record$embed, \"images\"), \n      sprintf(\n        green(\"[%s IMAGE%s]\\n\"), \n        length(item$post$record$embed$images),\n        ifelse(length(item$post$record$embed$images) &gt; 1, \"s\", \"\")\n      ),\n      \"\"\n    ),\n    ifelse(\n      hasName(item$post$record$embed, \"external\"),\n      yellow(sprintf(\n        \"\\n%s\\n   \u2502\\n%s\\n\\n\",\n        bold(paste0(strwrap(item$post$embed$external$title, 47, prefix = \"   \u2502\"), collapse = \"\\n\")),\n        italic(paste0(strwrap(item$post$embed$external$description, 47, prefix = \"   \u2502\"), collapse = \"\\n\"))\n      )),\n      \"\"\n    ),\n    \"\\n\",\n    sep = \"\"\n  )\n)\n<\/code><\/pre>\n<p>This is a sample of the output, showing how it handles embeds and images:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"14197\" data-permalink=\"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/screenshot-2023-07-07-at-13-16-10\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?fit=1192%2C1226&amp;ssl=1\" data-orig-size=\"1192,1226\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Screenshot 2023-07-07 at 13.16.10\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?fit=510%2C524&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?resize=510%2C525&#038;ssl=1\" alt=\"feed output\" width=\"510\" height=\"525\" class=\"aligncenter size-full wp-image-14197\" srcset=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?w=1192&amp;ssl=1 1192w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?resize=292%2C300&amp;ssl=1 292w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?resize=530%2C545&amp;ssl=1 530w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?resize=146%2C150&amp;ssl=1 146w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?resize=768%2C790&amp;ssl=1 768w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?resize=500%2C514&amp;ssl=1 500w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?resize=150%2C154&amp;ssl=1 150w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?resize=400%2C411&amp;ssl=1 400w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?resize=800%2C823&amp;ssl=1 800w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?resize=200%2C206&amp;ssl=1 200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?w=1020&amp;ssl=1 1020w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/a><\/p>\n<p>Code is <a href=\"https:\/\/gitlab.com\/hrbrmstr\/rbsky-cli\">on GitLab<\/a>.<\/p>\n<h3>FIN<\/h3>\n<p>There&#8217;s tons of room for improvement in this hastily-crafted bit of code, and I&#8217;ll get it up on GitLab once their servers come back to life.<\/p>\n<p>If you want to experience Bluesky but have no account, the firehose \u2014 which Elon charges $40K\/month for on the birdsite \u2014 is free and can be accessed sans authentication:<\/p>\n<pre><code class=\"language-r\">library(reticulate)\n\natproto &lt;- import(\"atproto\")\n\nhose &lt;- atproto$firehose$FirehoseSubscribeReposClient()\n\nhandler &lt;- \\(msg) {\n  res &lt;- atproto$firehose$parse_subscribe_repos_message(msg)\n  print(res) # you need to do a bit more than this to get the actual commit type and contents\n}\n\nhose$start(handler)\n<\/code><\/pre>\n<p>You can find me over on bsky at <a href=\"https:\/\/bsky.app\/profile\/hrbrmstr.dev\">@hrbrmstr.dev<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lynn (of TITAA and general NLP wizardy fame) was gracious enough to lend me a Bluesky invite, so I could claim my handle on yet-another social media site. I&#8217;m still wary of it (as noted in one of this week&#8217;s Drops), but the AT protocol \u2014\u00a0whilst super (lacking a better word) &#8220;verbose&#8221; \u2014 is pretty [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[640,91],"tags":[],"class_list":["post-14177","post","type-post","status-publish","format-standard","hentry","category-python-2","category-r"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Poor Dude&#039;s Janky Bluesky Feed Reader CLI Via R &amp; Python - rud.is<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Poor Dude&#039;s Janky Bluesky Feed Reader CLI Via R &amp; Python - rud.is\" \/>\n<meta property=\"og:description\" content=\"Lynn (of TITAA and general NLP wizardy fame) was gracious enough to lend me a Bluesky invite, so I could claim my handle on yet-another social media site. I&#8217;m still wary of it (as noted in one of this week&#8217;s Drops), but the AT protocol \u2014\u00a0whilst super (lacking a better word) &#8220;verbose&#8221; \u2014 is pretty [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/\" \/>\n<meta property=\"og:site_name\" content=\"rud.is\" \/>\n<meta property=\"article:published_time\" content=\"2023-07-07T17:21:30+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-07-07T19:01:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png\" \/>\n<meta name=\"author\" content=\"hrbrmstr\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"hrbrmstr\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/\"},\"author\":{\"name\":\"hrbrmstr\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"headline\":\"Poor Dude&#8217;s Janky Bluesky Feed Reader CLI Via R &#038; Python\",\"datePublished\":\"2023-07-07T17:21:30+00:00\",\"dateModified\":\"2023-07-07T19:01:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/\"},\"wordCount\":290,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"image\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/Screenshot-2023-07-07-at-13.16.10.png\",\"articleSection\":[\"Python\",\"R\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/\",\"name\":\"Poor Dude's Janky Bluesky Feed Reader CLI Via R & Python - rud.is\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/Screenshot-2023-07-07-at-13.16.10.png\",\"datePublished\":\"2023-07-07T17:21:30+00:00\",\"dateModified\":\"2023-07-07T19:01:14+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/Screenshot-2023-07-07-at-13.16.10.png?fit=1192%2C1226&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/Screenshot-2023-07-07-at-13.16.10.png?fit=1192%2C1226&ssl=1\",\"width\":1192,\"height\":1226},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/07\\\/07\\\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/rud.is\\\/b\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Poor Dude&#8217;s Janky Bluesky Feed Reader CLI Via R &#038; Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/\",\"name\":\"rud.is\",\"description\":\"&quot;In God we trust. All others must bring data&quot;\",\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/rud.is\\\/b\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\",\"name\":\"hrbrmstr\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"width\":460,\"height\":460,\"caption\":\"hrbrmstr\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\"},\"description\":\"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7\",\"sameAs\":[\"http:\\\/\\\/rud.is\"],\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/author\\\/hrbrmstr\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Poor Dude's Janky Bluesky Feed Reader CLI Via R & Python - rud.is","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/","og_locale":"en_US","og_type":"article","og_title":"Poor Dude's Janky Bluesky Feed Reader CLI Via R & Python - rud.is","og_description":"Lynn (of TITAA and general NLP wizardy fame) was gracious enough to lend me a Bluesky invite, so I could claim my handle on yet-another social media site. I&#8217;m still wary of it (as noted in one of this week&#8217;s Drops), but the AT protocol \u2014\u00a0whilst super (lacking a better word) &#8220;verbose&#8221; \u2014 is pretty [&hellip;]","og_url":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/","og_site_name":"rud.is","article_published_time":"2023-07-07T17:21:30+00:00","article_modified_time":"2023-07-07T19:01:14+00:00","og_image":[{"url":"https:\/\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png","type":"","width":"","height":""}],"author":"hrbrmstr","twitter_card":"summary_large_image","twitter_misc":{"Written by":"hrbrmstr","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/#article","isPartOf":{"@id":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/"},"author":{"name":"hrbrmstr","@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"headline":"Poor Dude&#8217;s Janky Bluesky Feed Reader CLI Via R &#038; Python","datePublished":"2023-07-07T17:21:30+00:00","dateModified":"2023-07-07T19:01:14+00:00","mainEntityOfPage":{"@id":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/"},"wordCount":290,"commentCount":2,"publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"image":{"@id":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/#primaryimage"},"thumbnailUrl":"https:\/\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png","articleSection":["Python","R"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/","url":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/","name":"Poor Dude's Janky Bluesky Feed Reader CLI Via R & Python - rud.is","isPartOf":{"@id":"https:\/\/rud.is\/b\/#website"},"primaryImageOfPage":{"@id":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/#primaryimage"},"image":{"@id":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/#primaryimage"},"thumbnailUrl":"https:\/\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png","datePublished":"2023-07-07T17:21:30+00:00","dateModified":"2023-07-07T19:01:14+00:00","breadcrumb":{"@id":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/#primaryimage","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?fit=1192%2C1226&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/07\/Screenshot-2023-07-07-at-13.16.10.png?fit=1192%2C1226&ssl=1","width":1192,"height":1226},{"@type":"BreadcrumbList","@id":"https:\/\/rud.is\/b\/2023\/07\/07\/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rud.is\/b\/"},{"@type":"ListItem","position":2,"name":"Poor Dude&#8217;s Janky Bluesky Feed Reader CLI Via R &#038; Python"}]},{"@type":"WebSite","@id":"https:\/\/rud.is\/b\/#website","url":"https:\/\/rud.is\/b\/","name":"rud.is","description":"&quot;In God we trust. All others must bring data&quot;","publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rud.is\/b\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886","name":"hrbrmstr","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","width":460,"height":460,"caption":"hrbrmstr"},"logo":{"@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1"},"description":"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7","sameAs":["http:\/\/rud.is"],"url":"https:\/\/rud.is\/b\/author\/hrbrmstr\/"}]}},"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p23idr-3GF","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":14273,"url":"https:\/\/rud.is\/b\/2023\/08\/05\/resolving-a-bluesky-at-protocol-didplc-to-a-handle-handles\/","url_meta":{"origin":14177,"position":0},"title":"Resolving A Bluesky\/AT Protocol did:plc To A Handle\/Handles","author":"hrbrmstr","date":"2023-08-05","format":false,"excerpt":"I'm just putting this here so the LLM\/GPT overlords (and, mebbe even legacy search engines) can get it indexed and use the content from it to help others. My Bluesky firehose viewer (https:\/\/gitlab.com\/hrbrmstr\/bskyf) displays ugly did:plc identifiers for users, and the way to turn those into something more readable without\u2026","rel":"","context":"In &quot;bluesky&quot;","block_context":{"text":"bluesky","link":"https:\/\/rud.is\/b\/category\/bluesky\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":25391,"url":"https:\/\/rud.is\/b\/2025\/05\/14\/euvd-api-npm-and-go-packages-nicer-docs\/","url_meta":{"origin":14177,"position":1},"title":"EUVD API NPM And Go Packages + Nicer Docs","author":"hrbrmstr","date":"2025-05-14","format":false,"excerpt":"ENISA published docs for their European Vulnerability Database (EUVD) \u2014 https:\/\/euvd.enisa.europa.eu\/apidoc. I've got an easier-on-the-eyes version that supports light\/dark mode and includes sample API JSON results at https:\/\/rud.is\/euvd-api\/. The Quarto markdown source for it can be found at https:\/\/rud.is\/euvd-api\/euvd-api.qmd. I need to make an MCP (Model Context Protocol) server for\u2026","rel":"","context":"In &quot;Cybersecurity&quot;","block_context":{"text":"Cybersecurity","link":"https:\/\/rud.is\/b\/category\/cybersecurity\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":13894,"url":"https:\/\/rud.is\/b\/2023\/03\/29\/using-webr-pyodide-to-fill-in-the-temporary-package-gaps\/","url_meta":{"origin":14177,"position":2},"title":"Using WebR + Pyodide To Fill In The (Temporary) Package Gaps","author":"hrbrmstr","date":"2023-03-29","format":false,"excerpt":"I won't wax long and poetic here since I've already posted the experiment that has all the details. TL;DR: there are still only ~90-ish ? in the WebR WASM \"CRAN\", but more are absolutely on the way, including the capability to build your own CRAN and dev packages via Docker\u2026","rel":"","context":"In &quot;Python&quot;","block_context":{"text":"Python","link":"https:\/\/rud.is\/b\/category\/python-2\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":7051,"url":"https:\/\/rud.is\/b\/2017\/11\/11\/measuring-monitoring-internet-speed-with-r\/","url_meta":{"origin":14177,"position":3},"title":"Measuring &#038; Monitoring Internet Speed with R","author":"hrbrmstr","date":"2017-11-11","format":false,"excerpt":"Working remotely has many benefits, but if you work remotely in an area like, say, rural Maine, one of those benefits is not massively speedy internet connections. Being able to go fast and furious on the internet is one of the many things I miss about our time in Seattle\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/spdtst.gif?fit=1200%2C647&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/spdtst.gif?fit=1200%2C647&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/spdtst.gif?fit=1200%2C647&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/spdtst.gif?fit=1200%2C647&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/spdtst.gif?fit=1200%2C647&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":833,"url":"https:\/\/rud.is\/b\/2012\/03\/04\/thinkstats-in-r-including-example-1-2\/","url_meta":{"origin":14177,"position":4},"title":"ThinkStats \u2026 in R (including Example 1.2)","author":"hrbrmstr","date":"2012-03-04","format":false,"excerpt":"ThinkStats (by Allen B. Downey) is a good book to get you familiar with statistics (and even Python, if you've done some scripting in other languages). I thought it would be interesting to present some of the examples & exercises in the book in R. Why? Well, once you've gone\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":14227,"url":"https:\/\/rud.is\/b\/2023\/07\/15\/keeping-track-of-urls-shared-on-bluesky\/","url_meta":{"origin":14177,"position":5},"title":"Keeping Track Of URLs Shared On Bluesky","author":"hrbrmstr","date":"2023-07-15","format":false,"excerpt":"While the future of Bluesky is nowhere near certain, it is most certainly growing. It's also the largest community of users for the AT Protocol. Folks are using Bluesky much the same way as any online forum\/chat. One of those ways is to share URLs to content. For the moment,\u2026","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/rud.is\/b\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/14177","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/comments?post=14177"}],"version-history":[{"count":0,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/14177\/revisions"}],"wp:attachment":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media?parent=14177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/categories?post=14177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/tags?post=14177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}