shithub: masto9

Download patch

ref: 963900f6a1fce690e901acad6265789d533a2fa0
parent: 5b0cf2e6a0ed85420a471a48c43a253e931237a4
author: Julien Blanchard <jblanchard@makemusic.com>
date: Fri Apr 14 09:10:25 EDT 2023

Extract display stuff

--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@
 
 Available commands:
 
+- `home` to view your notifications. Abbrev `h`
 - `toot 'TEXT'` to post a new textual toot. Abbrev `t`
 - `tootwithfile ['TEXT'] FILEPATH` to post a new toot with a file and optional text. . Abbrev `tf`
 - `reply ID` to reply to a toot. Abbrev `r`
@@ -17,7 +18,7 @@
 - `more ID` to view the timeline starting from a toot
 - `debug ID` to view a toot JSON
 
-if no COMMAND is provided masto9 defaults to reading your timeline.
+if no COMMAND is provided masto9 defaults to `home`.
 
 ### Installation
 
--- /dev/null
+++ b/display.c
@@ -1,0 +1,116 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <json.h>
+
+#include "masto9.h"
+
+static char *
+cleanup(char *str)
+{
+	removetag(str, "<span");
+	removesubstring(str, "</span>");
+
+	return str;
+}
+
+static char *
+fmthtml(char *msg)
+{
+	int wr[2], rd[2], n;
+	char buf[TOOTBUFSIZE];
+
+	if(pipe(wr) == -1 || pipe(rd) == -1)
+		sysfatal("fmthtml: pipe: %r");
+	switch(fork()) {
+	case -1:
+		sysfatal("fmthtml: fork: %r");
+		break;
+	case 0:
+		close(wr[0]);
+		close(rd[1]);
+		dup(wr[1], 0);
+		dup(rd[0], 1);
+		execl("/bin/htmlfmt", "htmlfmt -cutf-8 -j", nil);
+		sysfatal("fmthtml: exec: %r");
+		break;
+	default:
+		close(wr[1]);
+		close(rd[0]);
+		write(wr[0], msg, strlen(msg));
+		close(wr[0]);
+		n = readn(rd[1], buf, sizeof(buf));
+		close(rd[1]);
+		if(n == -1)
+			sysfatal("fmthtml: read: %r\n");
+		buf[n] = 0;
+		return buf;
+	}
+	return buf;
+}
+
+void
+displaytoots(Toot toots[], char *server)
+{
+	Biobuf out;
+	Binit(&out, 1, OWRITE);
+
+	for(int i = 0; i < TOOTSCOUNT; i++) {
+		Toot toot = toots[i];
+		char *username;
+
+		username = esmprint("%s (%s)", toot.displayname, toot.handle);
+
+		Bprint(&out, "\n\n——————————\n");
+		if(toot.reblogged == 1) {
+			Bprint(&out, "⊙ %s retooted %s:\n", username, toot.rebloggedhandle);
+		} else {
+			Bprint(&out, "⊙ %s:\n", username);
+		}
+		Bprint(&out, "\n%s", fmthtml(cleanup(toot.content)));
+		if(toot.attachmentscount > 0) {
+			for(int j = 0; j < toot.attachmentscount; j++) {
+				Attachment *attachment = toot.mediaattachments[j];
+				Bprint(&out, "\n[%s] %s", attachment->type, attachment->url);
+			}
+			Bprint(&out, "\n");
+		}
+		Bprint(&out, "\nReply[%s] | Boost[%s] | Favorite[%s]", toot.id, toot.id,
+			   toot.id);
+	}
+	Bprint(&out, "\n\n\n⇒ Send the next line to load more");
+	Bprint(&out, "\nmasto9 %s more %s\n\n", server, toots[TOOTSCOUNT - 1].id);
+	Bflush(&out);
+}
+
+void
+displaynotifications(Notification notifs[])
+{
+	Biobuf out;
+	Binit(&out, 1, OWRITE);
+
+	for(int i = 0; i < NOTIFSCOUNT; i++) {
+		Notification notif = notifs[i];
+		char *username;
+
+		username = esmprint("%s (%s)", notif.displayname, notif.handle);
+
+		if(strcmp(notif.type, "reblog") == 0) {
+			Bprint(&out, "\n⊙ %s retooted\n %s", username,
+				   fmthtml(cleanup(notif.content)));
+		} else if(strcmp(notif.type, "favourite") == 0) {
+			Bprint(&out, "\n⊙ %s favorited\n %s", username,
+				   fmthtml(cleanup(notif.content)));
+		} else if(strcmp(notif.type, "mention") == 0) {
+			Bprint(&out, "\n⊙ %s mentioned you\n %s", username,
+				   fmthtml(cleanup(notif.content)));
+		} else if(strcmp(notif.type, "follow") == 0) {
+			Bprint(&out, "\n⊙ %s followed you\n", username);
+		} else if(strcmp(notif.type, "poll") == 0) {
+			Bprint(&out, "\n⊙ %s poll ended\n %s", username,
+				   fmthtml(cleanup(notif.content)));
+		}
+	}
+	Bprint(&out, "\n");
+	Bflush(&out);
+}
--- a/masto9.c
+++ b/masto9.c
@@ -7,7 +7,7 @@
 
 #include "masto9.h"
 
-UserPasswd *
+static UserPasswd *
 getcredentials(char *host)
 {
 	UserPasswd *p;
@@ -19,12 +19,27 @@
 	return p;
 }
 
-void
+static JSON *
+mastodonget(char *token, char *host, char *endpoint)
+{
+	JSON *obj;
+	char *response, *url;
+
+	url = esmprint("https://%s/api/v1/%s", host, endpoint);
+	response = httpget(token, url);
+
+	if((obj = jsonparse(response)) == nil)
+		sysfatal("mastodonget: jsonparse: not json");
+
+	return (obj);
+}
+
+static void
 gethome(char *token, char *host, Toot toots[], char *beforeid)
 {
-	JSON *obj, *id, *content, *reblogcontent, *account, *reblogaccount,
-		*handle, *rebloghandle, *displayname, *avatar, *reblog,
-		*mediaattachments, *type, *previewurl, *remoteurl;
+	JSON *obj, *id, *content, *reblogcontent, *account, *reblogaccount, *handle,
+		*rebloghandle, *displayname, *avatar, *reblog, *mediaattachments, *type,
+		*previewurl, *remoteurl;
 	char *endpoint;
 	int i = 0;
 
@@ -100,7 +115,7 @@
 	jsonfree(obj);
 }
 
-void
+static void
 getnotifications(char *token, char *host, Notification *notifs, char *filter)
 {
 	JSON *obj, *id, *content, *displayname, *handle, *type, *account, *status;
@@ -148,7 +163,7 @@
 	jsonfree(obj);
 }
 
-void
+static void
 posttoot(char *token, char *host, char *text)
 {
 	char *url;
@@ -158,7 +173,7 @@
 	print("Posted:\n %s\n", text);
 }
 
-char *
+static char *
 tootauthor(char *token, char *host, char *id)
 {
 	JSON *obj, *account, *reblog;
@@ -183,7 +198,7 @@
 	return response;
 }
 
-void
+static void
 postattachment(char *token, char *host, char *text, char *filepath)
 {
 	JSON *obj, *id;
@@ -208,7 +223,7 @@
 	print("Posted toot\n");
 }
 
-void
+static void
 perform(char *token, char *host, char *id, char *action)
 {
 	char *url;
@@ -216,7 +231,7 @@
 	httppost(token, url, "");
 }
 
-void
+static void
 boost(char *token, char *host, char *id)
 {
 	perform(token, host, id, "reblog");
@@ -223,7 +238,7 @@
 	print("Boosted toot.");
 }
 
-void
+static void
 unboost(char *token, char *host, char *id)
 {
 	perform(token, host, id, "unreblog");
@@ -230,7 +245,7 @@
 	print("Unboosted toot.");
 }
 
-void
+static void
 fav(char *token, char *host, char *id)
 {
 	perform(token, host, id, "favourite");
@@ -237,7 +252,7 @@
 	print("Favorited toot.");
 }
 
-void
+static void
 unfav(char *token, char *host, char *id)
 {
 	perform(token, host, id, "unfavourite");
@@ -244,19 +259,16 @@
 	print("Unfavorited toot.");
 }
 
-void
+static void
 reply(char *token, char *host, char *id)
 {
 	char *content;
-	int fd, wait;
+	int fd;
 	char *s, *t, *u, *url;
 	Biobuf body;
 
-	wait = 0;
 	t = nil;
 
-	if(wait)
-		close(open("/dev/text", OWRITE | OTRUNC | OCEXEC));
 	if((fd = open("/dev/consctl", OWRITE | OCEXEC)) >= 0) {
 		write(fd, "holdon", 6);
 		u = tootauthor(token, host, id);
@@ -266,7 +278,7 @@
 			t = esmprint("%s", s);
 		free(s);
 		if(t != nil) {
-			url = esmprint("%s/api/v1/statuses", host);
+			url = esmprint("https://%s/api/v1/statuses", host);
 			content = esmprint("in_reply_to_id=%s&status=@%s %s", id, u, t);
 
 			httppost(token, url, content);
@@ -281,139 +293,13 @@
 	}
 }
 
-char *
-fmthtml(char *msg)
-{
-	int wr[2], rd[2], n;
-	char buf[TOOTBUFSIZE];
-
-	if(pipe(wr) == -1 || pipe(rd) == -1)
-		sysfatal("fmthtml: pipe: %r");
-	switch(fork()) {
-	case -1:
-		sysfatal("fmthtml: fork: %r");
-		break;
-	case 0:
-		close(wr[0]);
-		close(rd[1]);
-		dup(wr[1], 0);
-		dup(rd[0], 1);
-		execl("/bin/htmlfmt", "htmlfmt -cutf-8 -j", nil);
-		sysfatal("fmthtml: exec: %r");
-		break;
-	default:
-		close(wr[1]);
-		close(rd[0]);
-		write(wr[0], msg, strlen(msg));
-		close(wr[0]);
-		n = readn(rd[1], buf, sizeof(buf));
-		close(rd[1]);
-		if(n == -1)
-			sysfatal("fmthtml: read: %r\n");
-		buf[n] = 0;
-		return buf;
-	}
-	return buf;
-}
-
-char *
-cleanup(char *str)
-{
-	removetag(str, "<span");
-	removesubstring(str, "</span>");
-
-	return str;
-}
-
-JSON *
-mastodonget(char *token, char *host, char *endpoint)
-{
-	JSON *obj;
-	char *response, *url;
-
-	url = esmprint("https://%s/api/v1/%s", host, endpoint);
-	response = httpget(token, url);
-
-	if((obj = jsonparse(response)) == nil)
-		sysfatal("mastodonget: jsonparse: not json");
-
-	return (obj);
-}
-
-void
+static void
 usage(void)
 {
 	sysfatal("usage: masto9 DOMAIN [COMMAND] [DATA]");
 }
 
-void
-displaytoots(Toot toots[], char *server)
-{
-	Biobuf out;
-	Binit(&out, 1, OWRITE);
-
-	for(int i = 0; i < TOOTSCOUNT; i++) {
-		Toot toot = toots[i];
-		char *username;
-
-		username = esmprint("%s (%s)", toot.displayname, toot.handle);
-
-		Bprint(&out, "\n\n——————————\n");
-		if(toot.reblogged == 1) {
-			Bprint(&out, "⊙ %s retooted %s:\n", username,
-				   toot.rebloggedhandle);
-		} else {
-			Bprint(&out, "⊙ %s:\n", username);
-		}
-		Bprint(&out, "\n%s", fmthtml(cleanup(toot.content)));
-		if(toot.attachmentscount > 0) {
-			for(int j = 0; j < toot.attachmentscount; j++) {
-				Attachment *attachment = toot.mediaattachments[j];
-				Bprint(&out, "\n[%s] %s", attachment->type, attachment->url);
-			}
-			Bprint(&out, "\n");
-		}
-		Bprint(&out, "\nReply[%s] | Boost[%s] | Favorite[%s]", toot.id, toot.id,
-			   toot.id);
-	}
-	Bprint(&out, "\n\n\n⇒ Send the next line to load more");
-	Bprint(&out, "\n6.out %s more %s\n\n", server, toots[19].id);
-	Bflush(&out);
-}
-
-void
-displaynotifications(Notification notifs[])
-{
-	Biobuf out;
-	Binit(&out, 1, OWRITE);
-
-	for(int i = 0; i < NOTIFSCOUNT; i++) {
-		Notification notif = notifs[i];
-		char *username;
-
-		username = esmprint("%s (%s)", notif.displayname, notif.handle);
-
-		if(strcmp(notif.type, "reblog") == 0) {
-			Bprint(&out, "\n⊙ %s retooted\n %s", username,
-				   fmthtml(cleanup(notif.content)));
-		} else if(strcmp(notif.type, "favourite") == 0) {
-			Bprint(&out, "\n⊙ %s favorited\n %s", username,
-				   fmthtml(cleanup(notif.content)));
-		} else if(strcmp(notif.type, "mention") == 0) {
-			Bprint(&out, "\n⊙ %s mentioned you\n %s", username,
-				   fmthtml(cleanup(notif.content)));
-		} else if(strcmp(notif.type, "follow") == 0) {
-			Bprint(&out, "\n⊙ %s followed you\n", username);
-		} else if(strcmp(notif.type, "poll") == 0) {
-			Bprint(&out, "\n⊙ %s poll ended\n %s", username,
-				   fmthtml(cleanup(notif.content)));
-		}
-	}
-	Bprint(&out, "\n");
-	Bflush(&out);
-}
-
-void
+static void
 debug(char *token, char *host, char *id)
 {
 	JSON *obj;
@@ -429,7 +315,7 @@
 main(int argc, char **argv)
 {
 	UserPasswd *p;
-	char *token, *host, *command, *text, *id, *filepath;
+	char *token, *host, *cmd, *text, *id, *filepath;
 
 	if(argc < 2)
 		usage();
@@ -437,20 +323,19 @@
 	JSONfmtinstall();
 
 	host = argv[1];
-	command = argv[2];
+	cmd = argv[2];
 
 	p = getcredentials(host);
 	token = p->passwd;
 
-	if(command == nil) {
+	if(cmd == nil || strcmp(cmd, "home") == 0 || strcmp(cmd, "h") == 0) {
 		Toot toots[TOOTSCOUNT];
 		gethome(token, host, toots, nil);
 		displaytoots(toots, host);
-	} else if(strcmp(command, "toot") == 0 || strcmp(command, "t") == 0) {
+	} else if(strcmp(cmd, "toot") == 0 || strcmp(cmd, "t") == 0) {
 		text = argv[3];
 		posttoot(token, host, text);
-	} else if(strcmp(command, "tootwithfile") == 0 ||
-			  strcmp(command, "tf") == 0) {
+	} else if(strcmp(cmd, "tootwithfile") == 0 || strcmp(cmd, "tf") == 0) {
 		if(argc > 4) {
 			text = argv[3];
 			filepath = argv[4];
@@ -459,40 +344,39 @@
 			filepath = argv[3];
 		}
 		postattachment(token, host, text, filepath);
-	} else if(strcmp(command, "fav") == 0 || strcmp(command, "f") == 0) {
+	} else if(strcmp(cmd, "fav") == 0 || strcmp(cmd, "f") == 0) {
 		id = argv[3];
 		fav(token, host, id);
-	} else if(strcmp(command, "unfav") == 0 || strcmp(command, "uf") == 0) {
+	} else if(strcmp(cmd, "unfav") == 0 || strcmp(cmd, "uf") == 0) {
 		id = argv[3];
 		unfav(token, host, id);
-	} else if(strcmp(command, "boost") == 0 || strcmp(command, "b") == 0) {
+	} else if(strcmp(cmd, "boost") == 0 || strcmp(cmd, "b") == 0) {
 		id = argv[3];
 		boost(token, host, id);
-	} else if(strcmp(command, "unboost") == 0 || strcmp(command, "ub") == 0) {
+	} else if(strcmp(cmd, "unboost") == 0 || strcmp(cmd, "ub") == 0) {
 		id = argv[3];
 		unboost(token, host, id);
-	} else if(strcmp(command, "reply") == 0 || strcmp(command, "r") == 0) {
+	} else if(strcmp(cmd, "reply") == 0 || strcmp(cmd, "r") == 0) {
 		id = argv[3];
 		reply(token, host, id);
-	} else if(strcmp(command, "debug") == 0) {
+	} else if(strcmp(cmd, "debug") == 0) {
 		id = argv[3];
 		debug(token, host, id);
-	} else if(strcmp(command, "more") == 0) {
+	} else if(strcmp(cmd, "more") == 0) {
 		id = argv[3];
 		Toot toots[TOOTSCOUNT];
 		gethome(token, host, toots, id);
 		displaytoots(toots, host);
-	} else if(strcmp(command, "notifications") == 0 ||
-			  strcmp(command, "n") == 0) {
+	} else if(strcmp(cmd, "notifications") == 0 || strcmp(cmd, "n") == 0) {
 		Notification notifs[NOTIFSCOUNT];
 		getnotifications(token, host, notifs, "");
 		displaynotifications(notifs);
-	} else if(strcmp(command, "mentions") == 0 || strcmp(command, "m") == 0) {
+	} else if(strcmp(cmd, "mentions") == 0 || strcmp(cmd, "m") == 0) {
 		Notification notifs[NOTIFSCOUNT];
 		getnotifications(token, host, notifs, "mention");
 		displaynotifications(notifs);
 	} else {
-    print("Unknown command %s.\n", command);
+		print("Unknown command %s.\n", cmd);
 		usage();
 	}
 
--- a/masto9.h
+++ b/masto9.h
@@ -38,8 +38,9 @@
 	NOTIFSCOUNT = 40
 };
 
-JSON *mastodonget(char *token, char *host, char *endpoint);
-char *tootauthor(char *token, char *host, char *id);
+/* display */
+void displaytoots(Toot toots[], char *server);
+void displaynotifications(Notification notifs[]);
 
 /* http */
 char *httpget(char *token, char *url);
--- a/mkfile
+++ b/mkfile
@@ -5,6 +5,7 @@
 BIN=/$objtype/bin
 
 OFILES=\
+	display.$O\
 	http.$O\
 	masto9.$O\
 	util.$O\