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("&", "\\&", s);
22 gsub("<", "\\<", s);
23 gsub(">", "\\>", s);
24 gsub("\"", "\\"", s);
25 gsub("'"'"'", "\\'", 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