Last active
January 3, 2018 05:35
-
-
Save Cologler/7891df3378eb77e2c908d76f43ba73e1 to your computer and use it in GitHub Desktop.
#site:github #user_script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name github-blocker | |
// @name:zh-CN github-blocker | |
// @namespace https://github.com/cologler/github-blocker | |
// @version 1.1.0.2 | |
// @description block github user. | |
// @description:zh-CN 屏蔽某些国产 github 伸手党用户. | |
// @author cologler | |
// @match https://github.com/*/* | |
// @grant GM_setValue | |
// @grant GM_getValue | |
// @grant GM_deleteValue | |
// @grant GM_info | |
// @grant GM_addStyle | |
// @grant GM_unregisterMenuCommand | |
// @grant GM_registerMenuCommand | |
// @grant GM_getResourceText | |
// @require https://greasyfork.org/scripts/32752/code/expirableStorage.js | |
// @require https://greasyfork.org/scripts/31497/code/StyleSwitcher.js | |
// @resource css-def https://gist.github.com/Cologler/7891df3378eb77e2c908d76f43ba73e1/raw/github-blocker.def.css | |
// @resource css-full https://gist.github.com/Cologler/7891df3378eb77e2c908d76f43ba73e1/raw/github-blocker.full.css | |
// ==/UserScript== | |
// this script was hosting on: https://gist.github.com/Cologler/7891df3378eb77e2c908d76f43ba73e1 | |
// just let type script work. | |
(function() { function require(){}; require("greasemonkey"); })(); | |
(async function() { | |
'use strict'; | |
/* Copyright (c) 2017~2999 - cologler <[email protected]> */ | |
let createDonePromise = (() => { | |
function createDonePromise(request) { | |
console.assert(request instanceof XMLHttpRequest); | |
return new Promise((resolve, reject) => { | |
request.onreadystatechange = () => { | |
if (request.readyState === XMLHttpRequest.DONE) { | |
resolve(request); | |
} | |
}; | |
}); | |
} | |
if (XMLHttpRequest.prototype.createDonePromise === undefined) { | |
XMLHttpRequest.prototype.createDonePromise = function () { | |
return createDonePromise(this); | |
}; | |
} | |
return createDonePromise; | |
})(); | |
/* Copyright (c) 2017~2999 - cologler <[email protected]> */ | |
function parseLinkHeader(link) { | |
let parts = link.match(/<([^ ]+)>; rel="([^"]+)"/g); | |
let r = {}; | |
parts.forEach(p => { | |
let m = p.match(/<([^ ]+)>; rel="([^"]+)"/); | |
r[m[2]] = m[1]; | |
}); | |
return r; | |
} | |
/* Copyright (c) 2017~2999 - cologler <[email protected]> */ | |
class Logger { | |
constructor (name) { | |
this._name = name; | |
this._group = false; | |
} | |
get _headers() { | |
if (this._group) { | |
return []; | |
} | |
return [`[${this._name}]`] | |
} | |
group() { | |
console.group(this._name); | |
this._group = true; | |
} | |
end() { | |
console.groupEnd(); | |
this._group = false; | |
} | |
debug() { | |
console.debug(...this._headers, ...arguments); | |
} | |
info() { | |
console.info(...this._headers, ...arguments); | |
} | |
warn() { | |
console.warn(...this._headers, ...arguments) | |
} | |
error() { | |
console.error(...this._headers, ...arguments) | |
} | |
} | |
const logger = new Logger('github-blocker'); | |
// style | |
let sw = new StyleSwitcher(); | |
sw.addStyle('def', GM_getResourceText('css-def')); | |
sw.addStyle('full', GM_getResourceText('css-full')); | |
sw.load(); | |
// start script | |
let KEY_TOKEN = 'token'; | |
GM_deleteValue('cache'); // remove old cache. | |
function buildTokenSaveButton(el) { | |
let tk = el.querySelector('.token').innerHTML; | |
let div = el.querySelector('.BtnGroup'); | |
// create button | |
let a = document.createElement('a'); | |
a.addEventListener('click', function(ev) { | |
console.log('Github-Blocker: saving token to ' + tk); | |
GM_setValue(KEY_TOKEN, tk); | |
}); | |
a.innerText = 'use for Github-Blocker'; | |
div.children[0].classList.forEach(function(z) { | |
a.classList.add(z); | |
}); | |
div.insertBefore(a, div.firstChild); | |
} | |
if (location.href == 'https://github.com/settings/tokens') { | |
let tks = document.querySelectorAll('.access-token.new-token'); | |
if (tks.length == 1) { | |
buildTokenSaveButton(tks[0]); | |
} | |
return; | |
} | |
if (/https:\/\/github.com\/settings/.test(location.href)) return; | |
let token = GM_getValue(KEY_TOKEN, null); | |
if (token === null) return; | |
const blockedUsers = new Set(); | |
unsafeWindow.blockedUsers = blockedUsers; | |
const CLASS_NAME = 'blocked-user'; | |
let resolveItems = function (root = null) { | |
if (root === null) root = document; | |
logger.group(); | |
try { | |
if (root.querySelectorAll) { | |
if (/^\/.+\/.+\/issues$/.test(location.pathname)) { | |
document.querySelectorAll('.js-issue-row') | |
.forEach(z => { | |
if (z.classList.contains(CLASS_NAME)) return; | |
let username = z.querySelector('.opened-by a').textContent; | |
if (blockedUsers.has('https://github.com/' + username)) { | |
logger.debug(`${username} is blocked.`); | |
z.classList.add(CLASS_NAME); | |
} else { | |
logger.debug(`${username} is not blocked.`); | |
} | |
}); | |
} else if (/^\/[^\/]+\/[^\/]+\/issues\/\d+$/.test(location.pathname)) { | |
document.querySelectorAll('.timeline-comment-wrapper.js-comment-container') | |
.forEach(z => { | |
if (z.classList.contains(CLASS_NAME)) return; | |
const a = z.querySelector('.avatar-parent-child.timeline-comment-avatar a'); | |
if (a) { | |
let username = a.href.replace('https://github.com/', ''); | |
if (blockedUsers.has(a.href)) { | |
logger.debug(`${username} is blocked.`); | |
z.classList.add(CLASS_NAME); | |
} else { | |
logger.debug(`${username} is not blocked.`); | |
} | |
} | |
}); | |
} | |
} | |
} finally { | |
logger.end(); | |
} | |
}; | |
const cacheStorage = new ExpirableStorage(sessionStorage); | |
async function fetchBlockedData(url) { | |
url = url || 'https://api.github.com/user/blocks'; | |
const entity = cacheStorage.getEntity(url) || {}; | |
let cached = entity.content || null; | |
let result = null; | |
if (entity.isExpired === false) { | |
result = result = cached; | |
} else { | |
let req = new XMLHttpRequest(); | |
req.open('GET', url); | |
req.setRequestHeader('Authorization', 'token ' + token); | |
req.setRequestHeader('Accept', 'application/vnd.github.giant-sentry-fist-preview+json'); | |
if (cached && cached.etag) { | |
req.setRequestHeader('If-None-Match', cached.etag); | |
} | |
const awaitable = req.createDonePromise(); | |
req.send(); | |
await awaitable; | |
if (req.status == 200) { | |
result = { | |
etag: req.getResponseHeader('Etag'), | |
content: JSON.parse(req.responseText) | |
}; | |
let link = req.getResponseHeader('Link'); | |
if (link) { | |
let linkTable = parseLinkHeader(link); | |
if (linkTable.next) { | |
result.nexturl = linkTable.next; | |
} | |
} | |
} else if (req.status == 304) { | |
result = cached; | |
} | |
} | |
if (result) { | |
cacheStorage.setItemExpiresAfter(url, result, 15 * 60 * 1000); | |
result.content.forEach(z => blockedUsers.add(z.html_url)); | |
if (result.nexturl) { | |
await fetchBlockedData(result.nexturl); | |
} | |
} | |
} | |
await fetchBlockedData(); | |
resolveItems(); | |
window.addEventListener('DOMNodeInserted', function (e) { | |
resolveItems(e.target); | |
}); | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"login": "cfcboy", | |
"id": 590597, | |
"avatar_url": "https://avatars3.githubusercontent.com/u/590597?v=4", | |
"gravatar_id": "", | |
"url": "https://api.github.com/users/cfcboy", | |
"html_url": "https://github.com/cfcboy", | |
"followers_url": "https://api.github.com/users/cfcboy/followers", | |
"following_url": "https://api.github.com/users/cfcboy/following{/other_user}", | |
"gists_url": "https://api.github.com/users/cfcboy/gists{/gist_id}", | |
"starred_url": "https://api.github.com/users/cfcboy/starred{/owner}{/repo}", | |
"subscriptions_url": "https://api.github.com/users/cfcboy/subscriptions", | |
"organizations_url": "https://api.github.com/users/cfcboy/orgs", | |
"repos_url": "https://api.github.com/users/cfcboy/repos", | |
"events_url": "https://api.github.com/users/cfcboy/events{/privacy}", | |
"received_events_url": "https://api.github.com/users/cfcboy/received_events", | |
"type": "User", | |
"site_admin": false | |
} | |
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.blocked-user .comment-body { | |
background: #D1D5DA; | |
padding: 0; | |
} | |
.blocked-user .comment-body * { | |
display:none; | |
} | |
.blocked-user .mt-1 { | |
margin-top: 0 !important; | |
} | |
.blocked-user span.labels, .blocked-user .js-navigation-open { | |
display:none; | |
} | |
.blocked-user .tooltipped { | |
visibility: hidden; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.blocked-user.timeline-comment-wrapper.js-comment-container { | |
display: none; | |
} | |
li.blocked-user.js-issue-row * { | |
display:none; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment