Linter (npm install test)
This commit is contained in:
parent
7d96fbd01b
commit
0630910e9a
|
@ -17,28 +17,28 @@
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
"use strict";
|
||||||
if (Notification.permission !== 'granted') {
|
if (Notification.permission !== "granted") {
|
||||||
Notification.requestPermission();
|
Notification.requestPermission();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine site name
|
// Determine site name
|
||||||
var host = window.location.host;
|
var host = window.location.host;
|
||||||
var sitename = host.split('.')[0];
|
var sitename = host.split(".")[0];
|
||||||
|
|
||||||
// Determine current amount of flags
|
// Determine current amount of flags
|
||||||
var currentTitle = $('title').text();
|
var currentTitle = $("title").text();
|
||||||
var currentFlags = parseInt(currentTitle);
|
var currentFlags = parseInt(currentTitle);
|
||||||
console.log("Current: " + currentFlags);
|
console.log("Current: " + currentFlags);
|
||||||
|
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
var url = 'https://' + host + '/admin/dashboard?filtered=false';
|
var url = "https://" + host + "/admin/dashboard?filtered=false";
|
||||||
console.log("Calling: " + url);
|
console.log("Calling: " + url);
|
||||||
$.get(url, function (data) {
|
$.get(url, function (data) {
|
||||||
var updatedTitle = $('<html/>').html(data).find('title').text();
|
var updatedTitle = $("<html/>").html(data).find("title").text();
|
||||||
var updatedFlags = parseInt(updatedTitle);
|
var updatedFlags = parseInt(updatedTitle);
|
||||||
console.log("Update: " + updatedFlags);
|
console.log("Update: " + updatedFlags);
|
||||||
|
|
||||||
// TODO: check on flag IDs instead
|
// TODO: check on flag IDs instead
|
||||||
if (updatedFlags < currentFlags) {
|
if (updatedFlags < currentFlags) {
|
||||||
console.log("Less flags.");
|
console.log("Less flags.");
|
||||||
|
@ -47,14 +47,14 @@
|
||||||
} else if (updatedFlags > currentFlags) {
|
} else if (updatedFlags > currentFlags) {
|
||||||
console.log("More flags.");
|
console.log("More flags.");
|
||||||
// new flags, create a notification. Remember the current number, so that we don't send a notification twice for the same flag
|
// new flags, create a notification. Remember the current number, so that we don't send a notification twice for the same flag
|
||||||
currentFlags = updatedFlags;
|
currentFlags = updatedFlags;
|
||||||
if (Notification.permission === 'granted') {
|
if (Notification.permission === "granted") {
|
||||||
var notification = new Notification('New flags (total: ' + updatedFlags + ')', {
|
var notification = new Notification("New flags (total: " + updatedFlags + ")", {
|
||||||
icon: 'https://cdn.sstatic.net/Sites/' + sitename + '/img/apple-touch-icon.png',
|
icon: "https://cdn.sstatic.net/Sites/" + sitename + "/img/apple-touch-icon.png",
|
||||||
requireInteraction: true // on macOS, this only has effect when you set the notification types of your browser to 'Alert' instead of 'Banner'.
|
requireInteraction: true // on macOS, this only has effect when you set the notification types of your browser to 'Alert' instead of 'Banner'.
|
||||||
});
|
});
|
||||||
console.log("Notification created.");
|
console.log("Notification created.");
|
||||||
notification.onclick = function() {
|
notification.onclick = function () {
|
||||||
console.log("Notification clicked.");
|
console.log("Notification clicked.");
|
||||||
window.focus();
|
window.focus();
|
||||||
// reload only here, otherwise the notification will be dismissed
|
// reload only here, otherwise the notification will be dismissed
|
||||||
|
@ -64,4 +64,4 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 60000);
|
}, 60000);
|
||||||
}) ();
|
})();
|
||||||
|
|
|
@ -14,77 +14,83 @@
|
||||||
// @grant none
|
// @grant none
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
// Determine user ID
|
// Determine user ID
|
||||||
var userIDRegex = /\/users\/(\d+)\//g;
|
var userIDRegex = /\/users\/(\d+)\//g;
|
||||||
var userID = userIDRegex.exec(document.location) [1];
|
var userID = userIDRegex.exec(document.location)[1];
|
||||||
var userName = $(".name.mod-tabs").attr("title");
|
var userName = $(".name.mod-tabs").attr("title");
|
||||||
var userNameIsSuspicious = typeof userName !== 'undefined' && userName.toLowerCase().contains("insur");
|
var userNameIsSuspicious = typeof userName !== "undefined" && userName.toLowerCase().contains("insur");
|
||||||
|
|
||||||
// Find 'Mod' dialog link
|
// Find 'Mod' dialog link
|
||||||
var moderatorLinkElement = $('a#user-moderator-link-' + userID);
|
var moderatorLinkElement = $("a#user-moderator-link-" + userID);
|
||||||
if (moderatorLinkElement.length == 0) // Current user is not a moderator, or wrong tab - no action possible
|
if (moderatorLinkElement.length === 0) {
|
||||||
return;
|
return; // Current user is not a moderator, or wrong tab - no action possible
|
||||||
|
}
|
||||||
var destroySpammerLinkAdded = false;
|
var destroySpammerLinkAdded = false;
|
||||||
|
|
||||||
// This function will create the 'Destroy spammer' link;
|
// This function will create the 'Destroy spammer' link;
|
||||||
// this can happen either synchronously or asynchronously (after fetching additional data).
|
// this can happen either synchronously or asynchronously (after fetching additional data).
|
||||||
var createDestroyLink = function (userID) {
|
var createDestroyLink = function (userID) {
|
||||||
// The link can be added only once.
|
// The link can be added only once.
|
||||||
if (destroySpammerLinkAdded)
|
if (destroySpammerLinkAdded) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
destroySpammerLinkAdded = true;
|
destroySpammerLinkAdded = true;
|
||||||
|
|
||||||
var destroyLink = document.createElement('a');
|
var destroyLink = document.createElement("a");
|
||||||
destroyLink.appendChild(document.createTextNode('Destroy spammer'));
|
destroyLink.appendChild(document.createTextNode("Destroy spammer"));
|
||||||
destroyLink.onclick = function () {
|
destroyLink.onclick = function () {
|
||||||
// Ask for confirmation
|
// Ask for confirmation
|
||||||
if (window.confirm('Are you sure?')) {
|
if (window.confirm("Are you sure?")) {
|
||||||
// TODO: remember the last time this script was activated,
|
// TODO: remember the last time this script was activated,
|
||||||
// and build in a 5 second delay to prevent the rate limit from triggering.
|
// and build in a 5 second delay to prevent the rate limit from triggering.
|
||||||
$.post({
|
$.post({
|
||||||
url: 'https://' + document.location.host + '/admin/users/' + userID + '/destroy',
|
url: "https://" + document.location.host + "/admin/users/" + userID + "/destroy",
|
||||||
data: 'annotation=&deleteReasonDetails=&mod-actions=destroy&destroyReason=This+user+was+created+to+post+spam+or+nonsense+and+has+no+other+positive+participation&destroyReasonDetails=&fkey=' + window.localStorage["se:fkey"].split(",")[0],
|
data: "annotation=&deleteReasonDetails=&mod-actions=destroy&destroyReason=This+user+was+created+to+post+spam+or+nonsense+and+has+no+other+positive+participation&destroyReasonDetails=&fkey=" + window.localStorage["se:fkey"].split(",")[0],
|
||||||
success: function (data) {
|
success: function () {
|
||||||
// Reload page
|
// Reload page
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
},
|
},
|
||||||
error: function (jqXHR, textStatus, errorThrown) {
|
error: function (jqXHR, textStatus, errorThrown) {
|
||||||
window.alert('An error occurred, please try again later.');
|
window.alert("An error occurred, please try again later.");
|
||||||
console.log('Error: ' + textStatus + ' ' + errorThrown);
|
console.log("Error: " + textStatus + " " + errorThrown);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add to document
|
// Add to document
|
||||||
moderatorLinkElement.after(destroyLink);
|
moderatorLinkElement.after(destroyLink);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check for keywords in spammers' profiles
|
// Check for keywords in spammers' profiles
|
||||||
$.get(document.location.href.split('?')[0] + "?tab=profile", function (data) {
|
$.get(document.location.href.split("?")[0] + "?tab=profile", function (data) {
|
||||||
if (data.search(/1\D844\D909\D0831/g) != -1) {
|
if (data.search(/1\D844\D909\D0831/g) !== -1) {
|
||||||
createDestroyLink(userID);
|
createDestroyLink(userID);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check for (deleted) questions and answers
|
// Check for (deleted) questions and answers
|
||||||
var questionsPanel = $('#user-panel-questions');
|
var questionsPanel = $("#user-panel-questions");
|
||||||
var undeletedQuestions = questionsPanel.find('td.question-hyperlink').not('.deleted-answer').length; // yes, deleted-answer. Don't ask why.
|
var undeletedQuestions = questionsPanel.find("td.question-hyperlink").not(".deleted-answer").length; // yes, deleted-answer. Don"t ask why.
|
||||||
var deletedQuestions = questionsPanel.find('td.question-hyperlink.deleted-answer').length;
|
var deletedQuestions = questionsPanel.find("td.question-hyperlink.deleted-answer").length;
|
||||||
if (undeletedQuestions > 0) // User has content - use the dialog instead
|
if (undeletedQuestions > 0) {
|
||||||
return;
|
return; // User has content - use the dialog instead
|
||||||
var answersPanel = $('#user-panel-answers');
|
}
|
||||||
var undeletedAnswers = answersPanel.find('td.answer-hyperlink').not('.deleted-answer').length;
|
var answersPanel = $("#user-panel-answers");
|
||||||
var deletedAnswers = answersPanel.find('td.answer-hyperlink.deleted-answer').length;
|
var undeletedAnswers = answersPanel.find("td.answer-hyperlink").not(".deleted-answer").length;
|
||||||
if (undeletedAnswers > 0) // User has content - use the dialog instead
|
var deletedAnswers = answersPanel.find("td.answer-hyperlink.deleted-answer").length;
|
||||||
return;
|
if (undeletedAnswers > 0) {
|
||||||
if (deletedQuestions + deletedAnswers == 0 && !userNameIsSuspicious) // User has no deleted content - use the dialog instead
|
return; // User has content - use the dialog instead
|
||||||
return;
|
}
|
||||||
if (deletedQuestions + deletedAnswers > 4) // User has too much deleted content - use the dialog instead
|
if (deletedQuestions + deletedAnswers === 0 && !userNameIsSuspicious) {
|
||||||
return;
|
return; // User has no deleted content - use the dialog instead
|
||||||
|
}
|
||||||
|
if (deletedQuestions + deletedAnswers > 4) {
|
||||||
|
return; // User has too much deleted content - use the dialog instead
|
||||||
|
}
|
||||||
|
|
||||||
// Create Destroy link immediately
|
// Create Destroy link immediately
|
||||||
createDestroyLink(userID);
|
createDestroyLink(userID);
|
||||||
}) ();
|
})();
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
setTimeout(function() {
|
setTimeout(function () {
|
||||||
$("#net-neutrality-dismiss").click();
|
$("#net-neutrality-dismiss").click();
|
||||||
}, 100);
|
}, 100);
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Generate <script>.meta.js files containing only the script's metadata,
|
||||||
|
# so the whole script doesn't have to be downloaded to check for updates.
|
||||||
|
# Example use:
|
||||||
|
# // @updateURL https://raw.githubusercontent.com/Charcoal-SE/Userscripts/master/fire/fire.meta.js
|
||||||
|
# // @downloadURL https://raw.githubusercontent.com/Charcoal-SE/Userscripts/master/fire/fire.user.js
|
||||||
|
awk '/./; /\/UserScript/ { exit }' "$1" > "${1/.user./.meta.}"
|
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
"name": "SE-Userscripts",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "A selection of useful userscripts by Glorfindel.",
|
||||||
|
"scripts": {
|
||||||
|
"test": "xo",
|
||||||
|
"get-meta": "bash ./extractScriptMetadata.sh"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/Glorfindel83/SE-Userscripts.git"
|
||||||
|
},
|
||||||
|
"author": "Glorfindel",
|
||||||
|
"license": "(MIT OR Apache-2.0)",
|
||||||
|
"private": true,
|
||||||
|
"devDependencies": {
|
||||||
|
"xo": "^0.17.1"
|
||||||
|
},
|
||||||
|
"xo": {
|
||||||
|
"space": true,
|
||||||
|
"envs": [
|
||||||
|
"browser",
|
||||||
|
"jquery"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"quotes": [
|
||||||
|
"error",
|
||||||
|
"double",
|
||||||
|
{
|
||||||
|
"avoidEscape": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"camelcase": 1,
|
||||||
|
"brace-style": 0,
|
||||||
|
"no-prototype-builtins": 0,
|
||||||
|
"dot-notation": 0,
|
||||||
|
"radix": 0,
|
||||||
|
"no-warning-comments": 0,
|
||||||
|
"no-alert": 0,
|
||||||
|
"one-var": 0,
|
||||||
|
"linebreak-style": "off",
|
||||||
|
"comma-dangle": "off",
|
||||||
|
"no-eq-null": "off",
|
||||||
|
"eqeqeq": [
|
||||||
|
"error",
|
||||||
|
"smart"
|
||||||
|
],
|
||||||
|
"unicorn/filename-case": "off"
|
||||||
|
},
|
||||||
|
"globals": [
|
||||||
|
"CHAT",
|
||||||
|
"GM",
|
||||||
|
"Notifier",
|
||||||
|
"StackExchange"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue