youtube/cgi: output improvements - frontends - front-ends for some sites (experiment)
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 4d8ef4606fcdb808af8b505fc84318f22fe1c552
(DIR) parent 2237f8c69f34d8f48a37e34d1462d327b9ddc40d
(HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun, 26 Feb 2023 13:47:32 +0100
youtube/cgi: output improvements
Diffstat:
M youtube/cgi.c | 169 ++++++++++++++++---------------
1 file changed, 86 insertions(+), 83 deletions(-)
---
(DIR) diff --git a/youtube/cgi.c b/youtube/cgi.c
@@ -18,13 +18,32 @@
extern char **environ;
-static int curpage = 1;
+/* page title */
+char title[1024];
/* CGI parameters */
static char rawsearch[4096], search[4096], order[16], page[64];
static char videoid[256];
static char channelid[256], userid[256];
+/* Escape characters below as HTML 2.0 / XML 1.0.
+ Translate multi-line to <br/> */
+void
+xmlencode_multiline(const char *s)
+{
+ for (; *s; s++) {
+ switch(*s) {
+ case '<': fputs("<", stdout); break;
+ case '>': fputs(">", stdout); break;
+ case '\'': fputs("'", stdout); break;
+ case '&': fputs("&", stdout); break;
+ case '"': fputs(""", stdout); break;
+ case '\n': fputs("<br/>", stdout); break;
+ default: putchar(*s);
+ }
+ }
+}
+
void
parsecgi(void)
{
@@ -46,19 +65,6 @@ parsecgi(void)
if (!order[0])
snprintf(order, sizeof(order), "relevance");
- /* page */
- if ((p = getparam(query, "page"))) {
- if (decodeparam(page, sizeof(page), p) == -1)
- page[0] = '\0';
- /* check if it's a number > 0 and < 100 */
- errno = 0;
- curpage = strtol(page, NULL, 10);
- if (errno || curpage < 0 || curpage > 100) {
- curpage = 1;
- page[0] = '\0';
- }
- }
-
/* search */
if ((p = getparam(query, "q"))) {
if ((len = strcspn(p, "&")) && len + 1 < sizeof(rawsearch)) {
@@ -100,15 +106,12 @@ header(void)
"<meta name=\"referrer\" content=\"no-referrer\" />\n"
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n");
- if (videoid[0]) {
- OUT("<title>Video: ");
- xmlencode(videoid);
+ if (title[0]) {
+ OUT("<title>");
+ xmlencode(title);
OUT("</title>");
- } else {
- OUT("<title>Search: \"");
- xmlencode(search);
- printf("\" sorted by %s</title>\n", order);
}
+
OUT(
"<link rel=\"stylesheet\" href=\"css/style.css\" type=\"text/css\" media=\"screen\" />\n"
"<link rel=\"icon\" type=\"image/png\" href=\"/favicon.png\" />\n"
@@ -152,6 +155,7 @@ render_search(struct search_response *r)
{
struct item *v;
char tmp[64];
+ int n;
size_t i;
if (pledge("stdio", NULL) == -1) {
@@ -159,6 +163,16 @@ render_search(struct search_response *r)
exit(1);
}
+ n = -1;
+ if (search[0])
+ n = snprintf(title, sizeof(title), "Search: \"%s\" sorted by %s", search, order);
+ else if (channelid[0])
+ n = snprintf(title, sizeof(title), "Channel videos: %s", channelid);
+ else if (userid[0])
+ n = snprintf(title, sizeof(title), "User videos: %s", userid);
+ if (n < 0 || n >= sizeof(title))
+ title[0] = '\0';
+
header();
if (r && r->nitems) {
@@ -222,9 +236,9 @@ render_search(struct search_response *r)
/* link to video information */
if (v->id[0]) {
- OUT(" <a href=\"?v=");
+ OUT(" | <a href=\"?v=");
xmlencode(v->id);
- OUT("\">[I]</a>");
+ OUT("\" title=\"More video details\">Details</a>");
}
OUT(
@@ -283,38 +297,7 @@ render_search(struct search_response *r)
" <td colspan=\"3\"><hr/></td>\n"
"</tr>\n");
}
- OUT("</tbody>\n");
-
- OUT(
- "<tfoot>\n"
- "<tr>\n"
- "\t<td align=\"left\" class=\"nowrap\" nowrap>\n");
- if (curpage > 1) {
- OUT("\t\t<!--<a href=\"?q=");
- xmlencode(search);
- OUT("&page=");
- snprintf(tmp, sizeof(tmp), "%d", curpage - 1);
- xmlencode(tmp);
- OUT("&o=");
- xmlencode(order);
- OUT("\" rel=\"prev\" accesskey=\"p\">← prev</a>-->\n");
- }
- OUT(
- "\t</td>\n\t<td></td>\n"
- "\t<td align=\"right\" class=\"a-r nowrap\" nowrap>\n");
-
- OUT("\t\t<!--<a href=\"?q=");
- xmlencode(search);
- OUT("&page=");
- snprintf(tmp, sizeof(tmp), "%d", curpage + 1);
- xmlencode(tmp);
- OUT("&o=");
- xmlencode(order);
- OUT("\" rel=\"next\" accesskey=\"n\">next →</a>-->\n"
- "\t</td>\n"
- "</tr>\n"
- "</tfoot>\n"
- "</table>\n");
+ OUT("</tbody>\n</table>\n");
}
footer();
@@ -326,65 +309,85 @@ int
render_video(struct video_response *r)
{
char buf[256];
+ int n;
if (pledge("stdio", NULL) == -1) {
OUT("Status: 500 Internal Server Error\r\n\r\n");
exit(1);
}
+ n = snprintf(title, sizeof(title), "%s - %s", r->title, r->author);
+ if (n < 0 || n >= sizeof(title))
+ title[0] = '\0';
+
header();
- OUT("<pre>");
+ OUT("<hr/>\n");
- OUT("URL: ");
- OUT("https://www.youtube.com/embed/");
+ OUT("<center><a href=\"https://www.youtube.com/embed/");
xmlencode(r->id);
- OUT("\n");
+ OUT("\"><img src=\"https://i.ytimg.com/vi/");
+ xmlencode(r->id);
+ OUT("/hqdefault.jpg\" alt=\"\" border=\"0\" /></a></center>\n");
+
+ OUT("<table class=\"video\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n");
+ OUT("<tbody>\n");
- OUT("Title: ");
+ OUT("<tr><td><b>Title:</b></td><td>");
+ OUT("<a href=\"https://www.youtube.com/embed/");
+ xmlencode(r->id);
+ OUT("\">");
xmlencode(r->title);
- OUT("\n");
+ OUT("</a></td></tr>\n");
if (r->lengthseconds > 0) {
- OUT("Length: ");
+ OUT("<tr><td><b>Length:</b></td><td>");
if (durationstr(r->lengthseconds, buf, sizeof(buf)) < sizeof(buf))
xmlencode(buf);
- OUT("\n");
+ OUT("</td></tr>\n");
+ }
+
+ if (r->author[0]) {
+ OUT("<tr><td><b>Channel:</b></td><td>");
+ if (r->channelid[0]) {
+ OUT("<a href=\"?chan=");
+ xmlencode(r->channelid);
+ OUT("\">");
+ xmlencode(r->author);
+ OUT("</a>");
+ OUT(": <a href=\"https://www.youtube.com/feeds/videos.xml?channel_id=");
+ xmlencode(r->channelid);
+ OUT("\">Atom feed</a>");
+ } else {
+ xmlencode(r->author);
+ }
+ OUT("</td></tr>\n");
}
- OUT("Views: ");
+ OUT("<tr><td><b>Views:</b></td><td>");
printf("%ld", r->viewcount);
- OUT("\n");
+ OUT("</td></tr>\n");
if (r->publishdate[0]) {
- OUT("Published: ");
+ OUT("<tr><td><b>Published:</b></td><td>");
xmlencode(r->publishdate);
- OUT("\n");
+ OUT("</td></tr>\n");
}
if (r->uploaddate[0]) {
- OUT("Uploaded: ");
+ OUT("<tr><td><b>Uploaded:</b></td><td>");
xmlencode(r->uploaddate);
- OUT("\n");
- }
-
- if (r->author[0]) {
- OUT("Channel: ");
- xmlencode(r->author);
- if (r->channelid[0]) {
- OUT(": https://www.youtube.com/feeds/videos.xml?channel_id=");
- xmlencode(r->channelid);
- }
- OUT("\n");
+ OUT("</td></tr>\n");
}
if (r->shortdescription[0]) {
- OUT("Description:\n\n");
- xmlencode(r->shortdescription);
- OUT("\n");
+ OUT("<tr><td valign=\"top\"><b>Description: </b></td><td><code>");
+ xmlencode_multiline(r->shortdescription);
+ OUT("</code></td></tr>\n");
}
- OUT("</pre>");
+ OUT("</tbody>\n");
+ OUT("</table>\n");
footer();