diff options
-rw-r--r-- | Makefile | 39 | ||||
-rw-r--r-- | draco.1 | 19 | ||||
-rwxr-xr-x | draco.pl | 81 |
3 files changed, 139 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1319c6f --- /dev/null +++ b/Makefile @@ -0,0 +1,39 @@ +# Install to /usr/local unless otherwise specified, such as `make +# PREFIX=/app`. +PREFIX?=/usr/local + +INSTALL?=install +INSTALL_PROGRAM=$(INSTALL) -Dm 755 +INSTALL_DATA=$(INSTALL) -Dm 644 + +bindir=$(DESTDIR)$(PREFIX)/bin +sharedir=$(DESTDIR)$(PREFIX)/share + +# OpenBSD doesn't index /usr/local/share/man by default so +# /usr/local/man will be used. +platform_id != uname -s +mandir != if [ $(platform_id) = OpenBSD ]; then \ + echo $(DESTDIR)$(PREFIX)/man; \ +else \ + echo $(DESTDIR)$(PREFIX)/share/man; \ +fi + +help: + @echo "targets:" + @awk -F '#' '/^[a-zA-Z0-9_-]+:.*?#/ { print $0 }' $(MAKEFILE_LIST) \ + | sed -n 's/^\(.*\): \(.*\)#\(.*\)/ \1|-\3/p' \ + | column -t -s '|' + +install: draco.pl draco.1 README.org # system install + $(INSTALL_PROGRAM) draco.pl $(bindir)/draco + + $(INSTALL_DATA) draco.1 $(mandir)/man1/draco.1 + $(INSTALL_DATA) README.org $(sharedir)/doc/draco/README.org + + +uninstall: # system uninstall + rm -f $(bindir)/draco + rm -f $(mandir)/man1/draco.1 + rm -fr $(sharedir)/doc/draco/ + +.PHONY: install uninstall help diff --git a/draco.1 b/draco.1 new file mode 100644 index 0000000..013b789 --- /dev/null +++ b/draco.1 @@ -0,0 +1,19 @@ +.Dd $Mdocdate: November 19 2020 $ +.Dt DRACO 1 +.Os +.Sh NAME +.Nm draco +.Nd a script to convert reddit thread to Org document +.Sh SYNOPSIS +.Nm draco +.Ar <url> +.Sh DESCRIPTION +.Nm +is a script to convert reddit thread to Org document. It accepts a url +& prints the Org document to STDOUT. + +It'll also print comments along with their replies. It's limited by +the reddit API. +.Pp +.Sh AUTHOR +.An Andinus Aq Mt andinus@nand.sh diff --git a/draco.pl b/draco.pl new file mode 100755 index 0000000..da7f89a --- /dev/null +++ b/draco.pl @@ -0,0 +1,81 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use HTTP::Tiny; +use JSON::MaybeXS; + +# Priting UTF-8 to STDOUT. +binmode(STDOUT, "encoding(UTF-8)"); + +die "usage: draco <url>\n" unless scalar @ARGV; + +# $url contains the reddit post. +my $url = shift @ARGV; +my $json_url = "${url}.json"; + +my $http = HTTP::Tiny->new( verify_SSL => 1 ); + +# Fetch the post. +my $response = $http->get($json_url); +die "Unexpected response - $response->{status}: $response->{reason}" + unless $response->{success}; + +# Decode json. +my $json_data = decode_json($response->{content}); + +# $post contains post data +my $post = $json_data->[0]->{data}->{children}->[0]->{data}; + +print "* ", "$post->{title}\n"; + +# Add various details to :PROPERTIES:. +print ":PROPERTIES:\n"; +foreach my $detail (qw( subreddit created_utc author permalink + upvote_ratio ups downs score )) { + print ":${detail}: =$post->{$detail}=\n" + if scalar $post->{$detail}; +} +print ":END:\n"; + +# Add selftext/url if present. +print "\n#+BEGIN_SRC markdown\n", "$post->{selftext}\n", "#+END_SRC\n" + if scalar $post->{selftext}; +print "$post->{url}\n" if scalar $post->{selftext}; + +# $comments contains comment data. We are interested in: replies, +# author, body, created_utc & permalink. +my $comments = $json_data->[1]->{data}->{children}; +# Iterate over top-level comments. +foreach my $comment ($comments->@*) { + print_comment_chain($comment->{data}, 0); +} + +# print_comment_chain will print the whole chain of comment while +# accounting for level. +sub print_comment_chain { + my $comment = shift @_; + my $level = shift @_; + + print "*" x ($level + 2), " ", "$comment->{author}\n"; + + # Print comment details. + print ":PROPERTIES:\n"; + foreach my $detail (qw( created_utc author permalink upvote_ratio + ups downs score edited is_submitter + stickied controversiality )) { + print ":${detail}: =$comment->{$detail}=\n" + if scalar $comment->{$detail}; + } + print ":END:\n"; + + print "\n#+BEGIN_SRC markdown\n", "$comment->{body}\n", "#+END_SRC\n"; + + # If the comment has replies then iterate over those too. + if (scalar $comment->{replies}) { + foreach my $reply ($comment->{replies}->{data}->{children}->@*) { + print_comment_chain($reply->{data}, $level + 1); + } + } +} |