github - 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
       ---
       github (3198B)
       ---
            1 #!/bin/sh
            2 # Github issues list to Atom converter.
            3 # Can be used as a standalone script or as an sfeed connector included script.
            4 # Supports issue list or comments per issue.
            5 #
            6 # Dependencies: curl/hurl, json2tsv, awk, etc.
            7 #
            8 # API documentation reference: https://docs.github.com/en/rest/reference/issues
            9 
           10 # github_json_to_atom()
           11 # reads JSON from stdin.
           12 github_json_to_atom() {
           13 json2tsv -F '\x1f' -R '\x1e' | \
           14 LC_ALL=C awk '
           15 BEGIN {
           16         FS = "\x1f"; RS = "\x1e";
           17         print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
           18         print "<feed xmlns=\"http://www.w3.org/2005/Atom\" xml:lang=\"en\">";
           19 }
           20 function xmlencode(s) {
           21         gsub("&", "\\&amp;", s);
           22         gsub("<", "\\&lt;", s);
           23         gsub(">", "\\&gt;", s);
           24         gsub("\"", "\\&quot;", s);
           25         gsub("'"'"'", "\\&#39;", s);
           26         return s;
           27 }
           28 function show(issue) {
           29         if (o["id"] == "")
           30                 return;
           31 
           32         body = o["body"]; # do not double encode HTML body.
           33         contenttype = "text"; # default
           34         if (body == "") {
           35                 body = o["body_text"];
           36                 contenttype = "text";
           37         }
           38         if (body == "") {
           39                 body = o["body_html"];
           40                 contenttype = "html";
           41         }
           42 
           43         # XML encode fields.
           44         for (k in o)
           45                 o[k] = xmlencode(o[k]);
           46 
           47         title = o["title"];
           48         if (title == "")
           49                 title = body;
           50         if (o["number"] != "")
           51                 title = "#" o["number"] " " title;
           52         if (o["labels"] != "")
           53                 title = title " " o["labels"];
           54 
           55         # output Atom item entry.
           56         print "<entry>";
           57         print "\t<title>" title "</title>";
           58         print "\t<published>" o["created_at"] "</published>";
           59         if (o["updated_at"] != "")
           60                 print "\t<updated>" o["updated_at"] "</updated>";
           61         print "\t<link rel=\"alternate\" type=\"text/html\" href=\"" o["html_url"] "\" />";
           62         print "\t<id>" o["html_url"] "</id>";
           63         if (o["user.login"] != "")
           64                 print "\t<author><name>" o["user.login"] "</name></author>";
           65         print "\t<content type=\"" contenttype "\"><![CDATA[" body "]]></content>";
           66         for (k in labels)
           67                 print "\t<category term=\"" xmlencode(labels[k]) "\" />";
           68         print "</entry>";
           69 }
           70 $2 == "?" {
           71         next; # ignore null
           72 }
           73 $1 == "[]" {
           74         show(o);
           75         delete o;
           76         delete labels;
           77         nlabels = 0;
           78 }
           79 $1 == "[].user.login" {
           80         o["user.login"] = $3;
           81 }
           82 $1 ~ /^[]\.[a-z_]*$/ {
           83         o[substr($1, 4)] = $3;
           84 }
           85 $1 == "[].labels[].name" {
           86         labels[nlabels++] = $3;
           87         if (o["labels"] != "")
           88                 o["labels"] = o["labels"] " [" $3 "]";
           89         else
           90                 o["labels"] = "[" $3 "]";
           91 }
           92 END {
           93         show(o);
           94         print "</feed>";
           95 }
           96 '
           97 }
           98 
           99 # sfeed helper function to define a github feed.
          100 # github(name, user, project, [issue])
          101 github() {
          102         if test "$4" = ""; then
          103                 u="https://api.github.com/repos/$2/$3/issues?per_page=100&sort=updated"
          104         else
          105                 # NOTE: it doesn't grab the first post/comment.
          106                 u="https://api.github.com/repos/$2/$3/issues/$4/comments?per_page=100&sort=updated"
          107         fi
          108         feed "$1" "$u"
          109 }
          110 
          111 # command-line: $0 <user> <project> [issue]
          112 if test "$2" != ""; then
          113         if test "$3" = ""; then
          114                 u="https://api.github.com/repos/$1/$2/issues?per_page=100&sort=updated"
          115         else
          116                 # NOTE: it doesn't grab the first post/comment.
          117                 u="https://api.github.com/repos/$1/$2/issues/$3/comments?per_page=100&sort=updated"
          118         fi
          119         # NOTE: User-Agent must be set, else it is blocked.
          120         #format="application/vnd.github.html+json"
          121         format="application/vnd.github.text+json"
          122         hurl -H "$(printf 'User-Agent: github\r\nAccept: %s' "$format")" "$u" | \
          123                 github_json_to_atom
          124 fi