/ action.js
action.js
1 #!/usr/bin/env node 2 3 console.log('Starting action.js') 4 5 const fs = require('fs'); 6 const readline = require('readline'); 7 8 const core = require('@actions/core'); 9 const github = require('@actions/github'); 10 11 // https://stackoverflow.com/questions/19269545/how-to-get-a-number-of-random-elements-from-an-array/19270021#19270021 12 function getRandom(arr, n) { 13 var result = new Array(n), 14 len = arr.length, 15 taken = new Array(len); 16 if (n > len) 17 throw new RangeError("getRandom: more elements taken than available"); 18 while (n--) { 19 var x = Math.floor(Math.random() * len); 20 result[n] = arr[x in taken ? taken[x] : x]; 21 taken[x] = --len in taken ? taken[len] : len; 22 } 23 return result; 24 } 25 26 (async () => { 27 28 // Get images. 29 let imageRe = /^image::{china-dictatorship-media-base}\/([^/[]+)/; 30 let images = new Set(); 31 const fileStream = fs.createReadStream('README.adoc'); 32 const rl = readline.createInterface({ 33 input: fileStream, 34 crlfDelay: Infinity 35 }); 36 for await (const line of rl) { 37 let match = imageRe.exec(line); 38 if (match !== null) { 39 images.add(match[1]); 40 } 41 } 42 images = getRandom(Array.from(images), 30); 43 full_images = [] 44 for (const image of images) { 45 const url = `https://raw.githubusercontent.com/cirosantilli/china-dictatorship-media/master/${image}`; 46 full_images.push(image.replace(/[_.]/g, ' ')); 47 full_images.push(`<img src="${url}" width="600">`); 48 } 49 50 // Prepare reply body. 51 const payload = github.context.payload 52 const isComment = payload.comment !== undefined; 53 let titleAndBody; 54 let author; 55 if (isComment) { 56 titleAndBody = payload.comment.body; 57 author = payload.comment.user.login; 58 } else { 59 titleAndBody = payload.issue.title + '\n\n' + payload.issue.body; 60 author = payload.issue.user.login; 61 } 62 const quoteArray = []; 63 const noQuoteArray = []; 64 for (const line of titleAndBody.split('\n')) { 65 // Remove some special chars to remove at mention spam possibilities. 66 const l = line.replace(/[@#]/g, "") 67 quoteArray.push('> ' + l); 68 noQuoteArray.push(l); 69 } 70 const replyBody = `Hi @${author}, 71 72 ${quoteArray.join('\n').substring(0,40000)} 73 74 ${full_images.join('\n\n')} 75 `; 76 77 // Label handling. 78 let labels; 79 let newLabels; 80 if (!isComment) { 81 labels = new Set(payload.issue.labels.map(label => label.name)); 82 newLabels = new Set(); 83 const shabiWords = [ 84 '(sha|沙|啥|煞)(b|bi|diao|雕|比|笔)', 85 '傻', 86 '智障', 87 '垃圾', 88 '脑瘫', 89 'stupid', 90 ]; 91 for (const word of shabiWords) { 92 if (new RegExp(word, 'i').test(titleAndBody)) { 93 newLabels.add('you-are-stupid-argument'); 94 break; 95 } 96 } 97 const maWords = '(马|吗|妈|m)' 98 const fuckMotherWords = [ 99 'cnm', 100 'fuck.*\\b(mom|mum|mother)\\b', 101 '尼玛', 102 '(叼|去|日|操|草)(你|泥|拟)' + maWords, 103 ] 104 for (const word of fuckMotherWords) { 105 if (new RegExp(word, 'i').test(titleAndBody)) { 106 newLabels.add('fuck-your-mother-argument'); 107 break; 108 } 109 } 110 for (const word of [ 111 '中国共产党万岁', 112 '中华人民共和国万岁', 113 ]) { 114 if (new RegExp(word, 'i').test()) { 115 newLabels.add('i-like-my-dictatorship') 116 break; 117 } 118 } 119 const motherDiedWords = [ 120 'nmsl', 121 '你' + maWords + '死', 122 '司马', 123 ] 124 for (const word of motherDiedWords) { 125 if (new RegExp(word, 'i').test(titleAndBody)) { 126 newLabels.add('your-mother-died-argument'); 127 break; 128 } 129 } 130 const meantToBeUsedWords = [ 131 '技术', 132 'github', 133 ] 134 for (const word of meantToBeUsedWords) { 135 if (new RegExp(word, 'i').test(titleAndBody)) { 136 newLabels.add('meant-to-be-used'); 137 break; 138 } 139 } 140 const shitpostWords = [ 141 'fuck', 142 'shit', 143 'bitch', 144 '垃圾', 145 '婊子', 146 '恶心', 147 '操你', 148 '丑', 149 ]; 150 for (const word of shitpostWords) { 151 if (new RegExp(word, 'i').test(titleAndBody)) { 152 newLabels.add('shitpost'); 153 break; 154 } 155 } 156 if (new RegExp('狗', 'i').test(titleAndBody)) { 157 newLabels.add('you-are-dog-argument'); 158 } 159 if (newLabels.size > 0) { 160 newLabels.add('shitpost'); 161 if (labels.has('not-shitpost')) { 162 labels.delete('not-shitpost'); 163 newLabels.add('op-does-not-know-what-shit-is'); 164 } 165 } 166 } 167 168 // Make the request. 169 try { 170 const octokit = new github.getOctokit(process.env.GITHUB_TOKEN); 171 // https://github.com/cirosantilli/china-dictatorship/issues/1330 172 //const new_comment = octokit.rest.issues.createComment({ 173 // owner: payload.repository.owner.login, 174 // repo: payload.repository.name, 175 // issue_number: payload.issue.number, 176 // body: replyBody, 177 //}); 178 let html_url 179 if (isComment) { 180 const title = (`@${author}: ` + noQuoteArray.join('\n').replaceAll('\n', ' ')).substring(0, 255) 181 html_url = payload.comment.html_url 182 // https://github.com/cirosantilli/china-dictatorship/issues/1330 183 //const new_issue = octokit.rest.issues.create({ 184 // owner: payload.repository.owner.login, 185 // repo: payload.repository.name, 186 // title, 187 // body: html_url + '\n\n' + replyBody, 188 //}) 189 } else { 190 // Update labels. 191 if (author !== 'cirosantilli') { 192 console.log('before octokit.rest.issues.update') 193 await octokit.rest.issues.update({ 194 owner: payload.repository.owner.login, 195 repo: payload.repository.name, 196 issue_number: payload.issue.number, 197 labels: Array.from([...labels, ...newLabels]) 198 }) 199 console.log('after octokit.rest.issues.update') 200 } 201 } 202 // Get the latest news from duty-machine. 203 // Can't do fetches anymore they were DMCA'ed. 204 { 205 //const commits = await octokit.rest.repos.listCommits({ 206 // owner: 'duty-machine', 207 // repo: 'news', 208 // per_page: 1, 209 //}) 210 //const sha = commits.data[0].sha 211 //const commit = await octokit.rest.repos.getCommit({ 212 // owner: 'duty-machine', 213 // repo: 'news', 214 // ref: sha, 215 //}) 216 //let filename 217 //for (const file of commit.data.files) { 218 // filename = file.filename 219 // if (filename.startsWith('articles/')) { 220 // break 221 // } 222 //} 223 //const content = await octokit.rest.repos.getContent({ 224 // owner: 'duty-machine', 225 // repo: 'news', 226 // ref: sha, 227 // path: filename, 228 //}) 229 //contentS = Buffer.from(content.data.content, 'base64').toString('utf-8') 230 //const lines = contentS.split('\n') 231 //const titleAndLink = lines[1] 232 //const match = titleAndLink.match(/\[([^\]]+)\]\(([^)]+)\)/) 233 //const title = match[1] 234 //const link = match[2] 235 //const body = lines[4] 236 // https://github.com/cirosantilli/china-dictatorship/issues/1330 237 //const new_issue_duty = await octokit.rest.issues.create({ 238 // owner: payload.repository.owner.login, 239 // repo: payload.repository.name, 240 // title: title + ' ' + link, 241 // body: content.data.html_url + '\n\n' + link + '\n\n' + html_url + '\n\n' + body, 242 // labels: ['duty-machine'], 243 //}) 244 } 245 } catch (error) { 246 core.setFailed(error.message); 247 } 248 249 console.log('Finishing action.js') 250 })()