Skip to content

Instantly share code, notes, and snippets.

@wernersa
Last active November 29, 2019 10:25
Show Gist options
  • Save wernersa/a8df0dd03b6995d70a87934d0814d60d to your computer and use it in GitHub Desktop.
Save wernersa/a8df0dd03b6995d70a87934d0814d60d to your computer and use it in GitHub Desktop.
Userscript: GitHub Awesome Stargazers
// ==UserScript==
// @name GitHub Awesome Stargazers
// @description Augments the main markdown section of GitHub (i.e. README.md) by retrieving star count for each repo from the GitHub API. Intended for surfing "awesome" GitHub lists.
// @author Werner Sævland
// @namespace https://github.com/wernersa/
// @version 1.0
// @include https://github.*/*/*
// @supportURL https://gist.github.com/wernersa/a8df0dd03b6995d70a87934d0814d60d
// @license GPLv2; http://www.gnu.org/licenses/
// ==/UserScript==
/**
* This userscript draws on code from the following repository
* https://github.com/Lorentz83/userscripts -> GoogleImageDirectLink
*/
/**
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Personal access token
// GitHub API has a rate limit of 60 requests/hr for unauthorized calls, but with authorization the limit is 5000 requests/hr.
// Visit the following page https://github.com/settings/tokens. When registering the token you dont need to check any boxes.
var OAuth_TOKEN = "";
var getJSON = function (url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
if (OAuth_TOKEN) xhr.setRequestHeader("Authorization", "token " + OAuth_TOKEN);
xhr.responseType = 'json';
console.trace("Sending request to: " + url);
xhr.onload = function () {
var status = xhr.status;
if (status == 200) {
callback(null, xhr.response);
} else {
callback(status);
}
};
xhr.send();
};
var stopEvent = function (event) {
event.stopPropagation();
};
var fixRepoLink = function (div, stars) {
if (div.dataset.fixed) {
return;
}
var a = div.getElementsByTagName('a')[0];
div.dataset.fixed = true;
var stars_counter = document.createElement('button');
stars_counter.className = 'btn btn-sm disabled';
stars_counter.style = "color: black;";
stars_counter.innerHTML = ['<svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14">',
'<path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"></path>',
'</svg> ',
stars].join("");
a.innerHTML = a.innerHTML + " - ";
a.parentNode.insertBefore(stars_counter, a.nextSibling);
};
var waitLink = {
_conf: {
attributes: true,
attributeFilter: ['href']
},
_observer: new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.target.parentNode !== null) {
waitLink.inject(mutation.target.parentNode);
}
});
}),
_watch: function (a) {
waitLink._observer.observe(a, waitLink._conf);
},
reset: function () {
waitLink._observer.disconnect();
},
inject: function (div) {
var as = div.getElementsByTagName('a');
var regexp = /github.com\/([^\/]+\/[^\/]+)\/?$/g;
var repoName = regexp.exec(as[0].href);
if (as.length > 0) {
if (as[0].href !== '') {
// Check that the link refers to a github.com/*/*/ page
if (repoName === null) {
return;
}
// Check that the link is not a reference to the same page
if ((as[0].href.indexOf(window.location.href.split('#')[0])) < 0) {
var star_count = localStorage["stars_" + repoName[1]];
// If the stars in not stored in local storage, retrieve it from API
if (!star_count) {
getJSON('https://api.github.com/repos/' + repoName[1],
function (err, data) {
if (err !== null) {
console.trace('Something went wrong: ' + err);
} else {
console.trace("Fixing star counter for repo " + repoName[1] + " by request to GitHub API.");
localStorage["stars_" + repoName[1]] = data.stargazers_count;
fixRepoLink(div, data.stargazers_count);
}
});
} else {
console.trace("Fixing star counter for repo " + repoName[1] + " using cached value.");
fixRepoLink(div, star_count);
}
}
}
} else {
waitLink._watch(as[0]);
}
}
};
var fixStars = function () {
var lists = document.querySelectorAll("article > ul");
console.log(lists);
if (lists === null) {
console.log('Cannot find the <ul> tags in this document?');
return;
}
for (var ul_element = 0; ul_element < lists.length; ul_element++) {
var list_item = lists.item(ul_element);
var lis = list_item.children;
for (var i = 0; i < lis.length; i++) {
var li = lis.item(i);
waitLink.inject(li);
}
}
};
fixStars();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment