Skip to content

Instantly share code, notes, and snippets.

@JBGruber
Created January 15, 2024 08:49
Show Gist options
  • Save JBGruber/31d8b88b79426c03eb8534f48344cbd8 to your computer and use it in GitHub Desktop.
Save JBGruber/31d8b88b79426c03eb8534f48344cbd8 to your computer and use it in GitHub Desktop.
Command line screen reader for Bluesky in R
#!/usr/bin/Rscript
# Command line application Bluesky feed reader based on atrrr.
#
# Make executable with `chmod u+x rbsky`.
#
# If you are on macOS, you should replace the first line with:
#
# #!/usr/local/bin/Rscript
#
# Not sure how to make it work in Windows ¯\_(ツ)_/¯
#
# based on https://rud.is/b/2023/07/07/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python/
library(atrrr)
library(cli)
library(lubridate, include.only = c("as.period", "interval"),
quietly = TRUE, warn.conflicts = FALSE)
if (!require("docopt", quietly = TRUE)) install.packages("docopt")
library(docopt)
# function to displace time since a post was made
ago <- function(t) {
as.period(Sys.time() - t) |>
as.character() |>
tolower() |>
gsub("\\d+\\.\\d+s", "ago", x = _)
}
# docopt can produce some documentation when you run `rbsky -h`
doc <- "Usage: rbsky [-a ALGO] [-n NUM] [-t S] [-h]
-a --algorithm ALGO algorithm used to sort the posts [e.g., \"reverse-chronological\"]
-n --n_posts NUM Maximum number of records to return [default: 25]
-t --timeout S Time to wait before displaying the next post [default. 0.5 seconds]
-h --help show this help text"
# this line parses the arguments passed from the command line and makes sure the
# documentation is shown when `rbsky -h` is run
args <- docopt(doc)
if (is.null(args$n_posts)) args$n_posts <- 25L
if (is.null(args$timeout)) args$timeout <- 0.5
# get feed
feed <- get_own_timeline(algorithm = args$algorithm,
limit = as.integer(args$n_posts),
verbose = FALSE)
# print feed
for (i in seq_along(feed$uri)) {
item <- feed[i, ]
cli({
# headline from author • time since post
cli_h1(c(col_blue(item$author_name), " • ",
col_silver(ago(item$indexed_at))))
# text of post in italic (not all terminals support it)
cli_text(style_italic("{item$text}"))
# print quoted text if available
quote <- purrr::pluck(item, "embed_data", 1, "external")
if (!is.null(quote)) {
cli_blockquote("{quote$title}\n{quote$text}", citation = quote$uri)
}
# display that posts contains image(s)
imgs <- length(purrr::pluck(item, "embed_data", 1, "images"))
if (imgs > 0) {
cli_text(col_green("[{imgs} IMAGE{?S}]"))
}
# new line before next post
cli_text("\n")
})
# wait a little before showing the next post
Sys.sleep(args$timeout)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment