yt-chan-cgi - randomcrap - random crap programs of varying quality
 (HTM) git clone git://git.codemadness.org/randomcrap
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       yt-chan-cgi (3110B)
       ---
            1 #!/bin/sh
            2 # CGI program: combine Youtube Atom feed and channel videos.
            3 # It adds video durations to the title and filters away Youtube
            4 # shorts/announcements, etc.
            5 # Dependencies: frontends/youtube/channel2tsv, sfeed, hurl, etc.
            6 
            7 PATH="/cgi-bin/bin"
            8 
            9 query="${REQUEST_URI}"
           10 query="${query##/yt-chan/}"
           11 
           12 format=""
           13 case "${query}" in
           14         *.json)
           15                 format="json"
           16                 query="${query%%.json}"
           17                 ;;
           18         *.html)
           19                 format="html"
           20                 query="${query%%.html}"
           21                 ;;
           22         *.twtxt)
           23                 format="twtxt"
           24                 query="${query%%.twtxt}"
           25                 ;;
           26         *.txt)
           27                 format="txt"
           28                 query="${query%%.txt}"
           29                 ;;
           30         *.xml)
           31                 format="xml"
           32                 query="${query%%.xml}"
           33                 ;;
           34 esac
           35 
           36 channelid="${query}"
           37 channelid="${channelid##\?}"
           38 channelid="${channelid##c=}"
           39 
           40 if test "$channelid" = ""; then
           41         printf 'Status: 400 Bad Request\r\n'
           42         printf 'Content-Type: text/plain; charset=utf-8\r\n\r\n'
           43         exit 1
           44 fi
           45 
           46 channelid="$(printf '%s' "$channelid" | sed -E 's@[^a-zA-Z0-9_-]*@@g')"
           47 if test "$channelid" = ""; then
           48         printf 'Status: 400 Bad Request\r\n'
           49         printf 'Content-Type: text/plain; charset=utf-8\r\n\r\n'
           50         printf "Channel ID must be set and proper: %s" "$channelid"
           51         exit 1
           52 fi
           53 
           54 f1="$(mktemp)"
           55 f2="$(mktemp)"
           56 f3="$(mktemp)"
           57 
           58 # delete temp file on exit.
           59 trap 'rm -f "$f1" "$f2" "$f3"' EXIT
           60 
           61 url="https://www.youtube.com/feeds/videos.xml?channel_id=${channelid}"
           62 if ! hurl "$url" > "$f2"; then
           63         printf 'Status: 400 Bad Request\r\n'
           64         printf 'Content-Type: text/plain; charset=utf-8\r\n\r\n'
           65         printf 'Could not get feed: %s' "$url"
           66         exit 1
           67 fi
           68 
           69 # get channel data.
           70 if ! channel2tsv "$channelid" > "$f1"; then
           71         printf 'Status: 400 Bad Request\r\n'
           72         printf 'Content-Type: text/plain; charset=utf-8\r\n\r\n'
           73         printf 'Could not get channel videos: %s' "$channelid"
           74         exit 1
           75 fi
           76 
           77 # combine data and output it.
           78 sfeed < "$f2" | \
           79 LC_ALL=C awk -v "f1=$f1" -v "f2=-" '
           80 BEGIN {
           81         FS = OFS = "\t";
           82 }
           83 FILENAME == f1 {
           84         durations[$1] = $6;
           85 }
           86 FILENAME == f2 {
           87         # quick way to get video ID after v parameter.
           88         idx = index($3, "v=");
           89         if (idx > 1) {
           90                 id = substr($3, idx + 2);
           91 
           92                 # Add duration to title if it can be found.
           93                 # Currently the channel videos page has 30 videos, the Atom
           94                 # feed has 15, so they usually match, Youitube shorts,
           95                 # upcoming video announcements or livestreams typically do not match.
           96                 # This is a feature imho, because it allows filtering them away.
           97                 if (durations[id])
           98                         $2 = $2 " [" durations[id] "]";
           99         }
          100         print $0;
          101 }
          102 ' "$f1" "-" > "$f3"
          103 
          104 case "${format}" in
          105 "json")
          106         printf 'Status: 200 OK\r\n'
          107         printf 'Content-Type: application/json; charset=utf-8\r\n\r\n'
          108         sfeed_json < "$f3"
          109         ;;
          110 "html")
          111         printf 'Status: 200 OK\r\n'
          112         printf 'Content-Type: text/html; charset=utf-8\r\n\r\n'
          113         sfeed_html < "$f3"
          114         ;;
          115 "twtxt")
          116         printf 'Status: 200 OK\r\n'
          117         printf 'Content-Type: text/plain; charset=utf-8\r\n\r\n'
          118         sfeed_twtxt < "$f3"
          119         ;;
          120 "txt")
          121         printf 'Status: 200 OK\r\n'
          122         printf 'Content-Type: text/plain; charset=utf-8\r\n\r\n'
          123         sfeed_plain < "$f3"
          124         ;;
          125 "xml")
          126         printf 'Status: 200 OK\r\n'
          127         printf 'Content-Type: text/xml; charset=utf-8\r\n\r\n'
          128         sfeed_atom < "$f3"
          129         ;;
          130 *)
          131         printf 'Status: 200 OK\r\n'
          132         printf 'Content-Type: text/plain; charset=utf-8\r\n\r\n'
          133         cat "$f3"
          134         ;;
          135 esac