youtube/gopher: add video information details - frontends - front-ends for some sites (experiment)
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit f36e23aa3122441b905b465d3567af4a5788acfa
 (DIR) parent f7f7290735a250cf03e1a9aa49c0d25b6b326756
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Sun, 26 Feb 2023 15:52:07 +0100
       
       youtube/gopher: add video information details
       
       Diffstat:
         M youtube/gopher.c                    |     124 ++++++++++++++++++++++++++++---
       
       1 file changed, 113 insertions(+), 11 deletions(-)
       ---
 (DIR) diff --git a/youtube/gopher.c b/youtube/gopher.c
       @@ -54,7 +54,7 @@ footer(void)
        }
        
        int
       -render(struct search_response *r)
       +render_search(struct search_response *r)
        {
                struct item *v;
                size_t i;
       @@ -101,17 +101,20 @@ render(struct search_response *r)
                        }
                        printf("\t%s\t%s\r\n", host, port);
        
       +                if (v->id[0])
       +                        printf("1Details\t%s?v=%s\t%s\t%s\r\n", requestpath, v->id, host, port);
       +
                        if (v->channelid[0]) {
                                OUT("1");
       -                        OUT(v->channeltitle);
       +                        OUTTEXT(v->channeltitle);
                                printf("\t%s?c=%s\t%s\t%s\r\n", requestpath, v->channelid, host, port);
                        } else if (v->userid[0]) {
                                OUT("1");
       -                        OUT(v->channeltitle);
       +                        OUTTEXT(v->channeltitle);
                                printf("\t%s?u=%s\t%s\t%s\r\n", requestpath, v->userid, host, port);
                        } else if (v->channeltitle[0]) {
                                OUT("i");
       -                        OUT(v->channeltitle);
       +                        OUTTEXT(v->channeltitle);
                                printf("\t%s\t%s\t%s\r\n", "", host, port);
                        }
        
       @@ -149,13 +152,100 @@ render(struct search_response *r)
        
                return 0;
        }
       +int
       +render_video(struct video_response *r)
       +{
       +        char buf[256];
       +        const char *s, *e;
       +        int i;
       +
       +        if (pledge("stdio", NULL) == -1)
       +                exit(1);
       +
       +        header();
       +
       +        info("");
       +
       +        OUT("hTitle:     ");
       +        OUTTEXT(r->title);
       +        OUT("\tURL:https://www.youtube.com/embed/");
       +        OUTTEXT(r->id);
       +        printf("\t%s\t%s\r\n", host, port);
       +
       +        OUT("iURL:       ");
       +        OUT("https://www.youtube.com/embed/");
       +        OUTTEXT(r->id);
       +        printf("\t%s\t%s\t%s\r\n", "", host, port);
       +
       +        if (r->lengthseconds > 0) {
       +                OUT("iLength:    ");
       +                if (durationstr(r->lengthseconds, buf, sizeof(buf)) < sizeof(buf))
       +                        OUTTEXT(buf);
       +                printf("\t%s\t%s\t%s\r\n", "", host, port);
       +        }
       +
       +        if (r->author[0]) {
       +                OUT("1Channel:   ");
       +                OUTTEXT(r->author);
       +                printf("\t%s?c=%s\t%s\t%s\r\n", requestpath, r->channelid, host, port);
       +
       +                if (r->channelid[0]) {
       +                        OUT("hAtom feed\tURL:https://www.youtube.com/feeds/videos.xml?channel_id=");
       +                        OUTTEXT(r->channelid);
       +                        printf("\t%s\t%s\t%s\r\n", "", host, port);
       +                }
       +        }
       +
       +        OUT("iViews:     ");
       +        printf("%ld", r->viewcount);
       +        printf("\t%s\t%s\t%s\r\n", "", host, port);
       +
       +        if (r->publishdate[0]) {
       +                OUT("iPublished: ");
       +                OUTTEXT(r->publishdate);
       +                printf("\t%s\t%s\t%s\r\n", "", host, port);
       +        }
       +
       +        if (r->uploaddate[0]) {
       +                OUT("iUploaded:  ");
       +                OUTTEXT(r->uploaddate);
       +                printf("\t%s\t%s\t%s\r\n", "", host, port);
       +        }
       +
       +        if (r->shortdescription[0]) {
       +                info("");
       +                info("");
       +
       +                /* multi-line text */
       +                i = 0;
       +                for (s = e = r->shortdescription; ; e++) {
       +                        if (!i)
       +                                putchar('i');
       +                        if (*e == '\n' || *e == '\0') {
       +                                i = 0;
       +                                gophertext(stdout, s, e - s);
       +                                printf("\t%s\t%s\t%s\r\n", "", host, port);
       +                                if (*e == '\0')
       +                                        break;
       +                                s = e + 1;
       +                        } else {
       +                                i = 1;
       +                        }
       +                }
       +        }
       +
       +        footer();
       +
       +        return 0;
       +}
        
        int
        main(void)
        {
                struct search_response *r = NULL;
       -        const char *channelid = "", *userid = "", *querystring = "", *p;
       -        const char *rawsearch = "";
       +        struct video_response *vr = NULL;
       +        const char *channelid = "", *userid = "", *videoid = "";
       +        const char *querystring = "", *rawsearch = "", *p;
                char search[1024] = "";
        
                if (pledge("stdio dns inet rpath unveil", NULL) == -1)
       @@ -172,6 +262,10 @@ main(void)
                        requestpath = p;
                if ((p = getenv("QUERY_STRING")))
                        querystring = p;
       +        if (!p)
       +                p = getenv("X_GOPHER_SEARCH"); /* geomyidae */
       +        if (!p)
       +                p = getenv("SEARCHREQUEST"); /* gophernicus */
        
                p = NULL;
                if (querystring[0] == '?')
       @@ -182,14 +276,13 @@ main(void)
                } else if (querystring[0] == 'u' && querystring[1] == '=') {
                        userid = querystring + 2;
                        p = querystring = "";
       +        } else if (querystring[0] == 'v' && querystring[1] == '=') {
       +                videoid = querystring + 2;
       +                p = querystring = "";
                }
        
                if (querystring[0])
                        p = querystring;
       -        if (!p)
       -                p = getenv("X_GOPHER_SEARCH"); /* geomyidae */
       -        if (!p)
       -                p = getenv("SEARCHREQUEST"); /* gophernicus */
                if (p)
                        rawsearch = p;
                if (p && !uriencode(p, search, sizeof(search))) {
       @@ -214,6 +307,15 @@ main(void)
                        r = youtube_channel_videos(channelid);
                } else if (userid[0]) {
                        r = youtube_user_videos(userid);
       +        } else if (videoid[0]) {
       +                vr = youtube_video(videoid);
       +                if (!vr || vr->isfound == 0) {
       +                        error("No video found");
       +                        footer();
       +                        return 0;
       +                }
       +                render_video(vr);
       +                return 0;
                } else {
                        footer();
                        return 0;
       @@ -226,7 +328,7 @@ main(void)
                        return 0;
                }
        
       -        render(r);
       +        render_search(r);
        
                return 0;
        }