shithub: nvi

Download patch

ref: 285f335215033ccc0178a34c09a22f951ef4fee4
parent: 8a9cb14d8ea294450b8f11124b30d228fc068471
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed Jun 23 05:38:35 EDT 2021

remove fps; harden/simplify json extraction

--- a/nvi.c
+++ b/nvi.c
@@ -1,6 +1,7 @@
 #include <u.h>
 #include <libc.h>
 #include <thread.h>
+#include <json.h>
 #include "nvi.h"
 
 int cmd = Cdownload;
--- a/nvi.h
+++ b/nvi.h
@@ -7,7 +7,6 @@
 	char *quality; /* "unknown" for audio, "360p"/etc for video */
 	vlong sz;
 	int included; /* Iaudio|Ivideo */
-	int fps;
 	int id;
 };
 
@@ -41,6 +40,9 @@
 int hget(char *url, int out);
 char *estrdup(char *s);
 int alldigit(char *s);
+JSON *jfield(JSON *j, int type, ...);
+char *jstrdup(JSON *j, char *name);
+vlong jint(JSON *j, char *name);
 
 #pragma varargck type "Z" vlong
 int Zfmt(Fmt *f);
--- a/peertube.c
+++ b/peertube.c
@@ -6,13 +6,13 @@
 static int
 addfmt(Info *i, JSON *f)
 {
-	JSON *x, *z, *j;
+	JSON *x, *j;
 	Format *fmt;
 	char *s, *t;
 	JSONEl *e;
-	int fd;
+	int fd, n;
 
-	if((x = jsonbyname(f, "metadataUrl")) == nil){
+	if((x = jfield(f, JSONString, "metadataUrl", nil)) == nil){
 		werrstr("no url");
 		return -1;
 	}
@@ -30,7 +30,7 @@
 		return -1;
 	}
 
-	if((x = jsonbyname(f, "fileDownloadUrl")) == nil){
+	if((x = jfield(f, JSONString, "fileDownloadUrl", nil)) == nil){
 		werrstr("no url");
 		jsonfree(j);
 		return -1;
@@ -45,26 +45,26 @@
 		fmt->sz = x->n;
 
 	s = strdup("");
-	if((x = jsonbyname(j, "streams")) != nil && x->t == JSONArray){
+	if((x = jfield(j, JSONArray, "streams", nil)) != nil){
 		for(e = x->first; e != nil; e = e->next){
-			if((x = jsonbyname(e->val, "codec_name")) != nil){
+			if((x = jfield(e->val, JSONString, "codec_name", nil)) != nil){
 				t = smprint("%s%s%s", s, *s ? "," : "", jsonstr(x));
 				free(s);
 				s = t;
 			}
-			if((x = jsonbyname(e->val, "codec_type")) != nil){
+			if((x = jfield(e->val, JSONString, "codec_type", nil)) != nil){
 				t = jsonstr(x);
 				if(strcmp(t, "video") == 0)
 					fmt->included |= Ivideo;
 				else if(strcmp(t, "audio") == 0){
 					fmt->included |= Iaudio;
-					if((x = jsonbyname(e->val, "sample_rate")) != nil){
-						t = smprint("%s,rate=%d", s, (int)x->n);
+					if((n = jint(e->val, "sample_rate")) != 0){
+						t = smprint("%s,rate=%d", s, n);
 						free(s);
 						s = t;
 					}
-					if((x = jsonbyname(e->val, "channels")) != nil){
-						t = smprint("%s,channels=%d", s, (int)x->n);
+					if((n = jint(e->val, "channels")) != 0){
+						t = smprint("%s,channels=%d", s, n);
 						free(s);
 						s = t;
 					}
@@ -75,13 +75,10 @@
 	fmt->type = s;
 	jsonfree(j);
 
-	if((x = jsonbyname(f, "resolution")) != nil){
-		if((z = jsonbyname(x, "id")) != nil)
-			fmt->id = z->n;
-		if((fmt->included & Ivideo) && (z = jsonbyname(x, "label")) != nil)
-			fmt->quality = estrdup(jsonstr(z));
-		if((z = jsonbyname(f, "fps")) != nil)
-			fmt->fps = z->n;
+	if((x = jfield(f, JSONObject, "resolution", nil)) != nil){
+		fmt->id = jint(x, "id");
+		if((s = jsonstr(jfield(x, JSONString, "label", nil))) != nil && *s != '0')
+			fmt->quality = jstrdup(x, "label");
 	}
 
 	return 0;
@@ -137,17 +134,16 @@
 	if((i = calloc(1, sizeof(*i))) == nil)
 		sysfatal("memory");
 
-	if((z = jsonbyname(j, "account")) != nil)
-		i->author = estrdup(jsonstr(jsonbyname(z, "displayName")));
-	i->title = estrdup(jsonstr(jsonbyname(j, "name")));
-	i->description = estrdup(jsonstr(jsonbyname(j, "description")));
-	i->duration = jsonbyname(j, "duration")->n;
+	i->author = estrdup(jsonstr(jfield(j, JSONString, "account", "displayName", nil)));
+	i->title = jstrdup(j, "name");
+	i->description = jstrdup(j, "description");
+	i->duration = jint(j, "duration");
 	if((s = jsonstr(jsonbyname(j, "publishedAt"))) != nil)
 		tmparse(&i->published, "YYYY-MM-DDThh:mm:ss.ttt", s, nil, nil);
 
-	if((z = jsonbyname(j, "streamingPlaylists")) != nil && z->t == JSONArray){
+	if((z = jfield(j, JSONArray, "streamingPlaylists", nil)) != nil){
 		for(e = z->first; e != nil; e = e->next){
-			if((z = jsonbyname(e->val, "files")) != nil && z->t == JSONArray){
+			if((z = jfield(e->val, JSONArray, "files", nil)) != nil){
 				for(f = z->first; f != nil; f = f->next)
 					addfmt(i, f->val);
 			}
--- a/util.c
+++ b/util.c
@@ -2,6 +2,7 @@
 #include <libc.h>
 #include <thread.h>
 #include <ctype.h>
+#include <json.h>
 #include "nvi.h"
 
 enum {
@@ -167,4 +168,38 @@
 	seprint(s, tmp+sizeof(tmp), "%02lld", sec);
 
 	return fmtstrcpy(f, tmp);
+}
+
+JSON *
+jfield(JSON *j, int type, ...)
+{
+	va_list a;
+	char *s;
+
+	va_start(a, type);
+	while((s = va_arg(a, char*)) != nil){
+		if((j = jsonbyname(j, s)) == nil)
+			break;
+	}
+	va_end(a);
+
+	return (j == nil || (type >= 0 && j->t != type)) ? nil : j;
+}
+
+char *
+jstrdup(JSON *j, char *name)
+{
+	return estrdup(jsonstr(jsonbyname(j, name)));
+}
+
+vlong
+jint(JSON *j, char *name)
+{
+	if((j = jfield(j, -1, name, nil)) != nil){
+		if(j->t == JSONNumber)
+			return j->n;
+		if(j->t == JSONString)
+			return atoll(jsonstr(j));
+	}
+	return 0;
 }
--- a/youtube.c
+++ b/youtube.c
@@ -13,7 +13,7 @@
 	JSON *x;
 	char *s;
 
-	if((x = jsonbyname(f, "url")) == nil){
+	if((x = jfield(f, JSONString, "url", nil)) == nil){
 		werrstr("no url");
 		return -1;
 	}
@@ -33,17 +33,13 @@
 		fmt->included |= Iaudio;
 	}else if(strncmp(s, "video/", 6) == 0){
 		fmt->included |= Ivideo;
-		fmt->quality = estrdup(jsonstr(jsonbyname(f, "qualityLabel")));
-		if((x = jsonbyname(f, "fps")) != nil)
-			fmt->fps = x->n;
+		fmt->quality = jstrdup(f, "qualityLabel");
 		if(strstr(s, ", ") != nil) /* I know, not the best way */
 			fmt->included |= Iaudio;
 	}
 
-	if((x = jsonbyname(f, "itag")) != nil)
-		fmt->id = atoi(jsonstr(x));
-	if((x = jsonbyname(f, "clen")) != nil)
-		fmt->sz = atoll(jsonstr(x));
+	fmt->id = jint(f, "itag");
+	fmt->sz = jint(f, "clen");
 
 	return 0;
 }
@@ -97,11 +93,11 @@
 			if((i = calloc(1, sizeof(*i))) == nil)
 				sysfatal("memory");
 
-			i->author = estrdup(jsonstr(jsonbyname(z, "author")));
-			i->title = estrdup(jsonstr(jsonbyname(z, "title")));
-			i->description = estrdup(jsonstr(jsonbyname(z, "description")));
-			i->duration = jsonbyname(z, "lengthSeconds")->n;
-			tmtime(&i->published, jsonbyname(z, "published")->n, nil);
+			i->author = jstrdup(z, "author");
+			i->title = jstrdup(z, "title");
+			i->description = jstrdup(z, "description");
+			i->duration = jint(z, "lengthSeconds");
+			tmtime(&i->published, jint(z, "published"), nil);
 
 			for(fmtname = fmtnames; *fmtname; fmtname++){
 				if((x = jsonbyname(z, *fmtname)) == nil){