Shows top leeches on dashboard (replaces critical items) and all leeches on a dedicated page (replaces critical items)
当前为
// ==UserScript==
// @name WaniKani Dashboard Leech List Unburnable Edit
// @namespace https://www.wanikani.com
// @description Shows top leeches on dashboard (replaces critical items) and all leeches on a dedicated page (replaces critical items)
// @author ukebox (edited by Pep95)
// @version 1.2.5
// @require https://code.jquery.com/jquery-3.3.1.min.js#sha256=FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=
// @include https://www.wanikani.com/dashboard
// @include https://www.wanikani.com/
// @include https://www.wanikani.com/critical-items
// @grant none
// @run-at document-end
// ==/UserScript==
/*
jshint esversion: 6
*/
(function() {
'use strict';
let sumval;
let dom = {};
dom.$ = jQuery.noConflict(true);
if (!window.wkof) {
let response = confirm('WaniKani Dashboard Leech List script requires WaniKani Open Framework.\n Click "OK" to be forwarded to installation instructions.');
if (response) {
window.location.href = 'https://community.wanikani.com/t/instructions-installing-wanikani-open-framework/28549';
}
return;
}
const leechThreshold = 1;
const config = {
wk_items: {
options: {
review_statistics: true,
assignments: true
},
filter: {
level: '1..+0',
srs: '1..8'
}
}
};
window.wkof.include('ItemData');
window.wkof.ready('ItemData').then(getItems).then(determineLeeches).then(updatePage);
function getItems() {
return window.wkof.ItemData.get_items(config);
}
function determineLeeches(items) {
return items.filter(item => isLeech(item));
}
function summer( item ) {
var sum = 0;
console.log( "sum1: "+sum+" "+item);
for( var impcnt in item ) {
console.log( "sum1: "+sum+" what is item.impcnt: "+item.impcnt );
if( item.hasOwnProperty( impcnt ) && item.impcnt == 1) {
sum += parseFloat( item[impcnt] );
console.log( "sum1: "+sum+" "+item );
}
}
return sum;
}
function isLeech(item) {
if (item.review_statistics === undefined) {
return false;
}
let reviewStats = item.review_statistics;
let meaningScore = computeLeechScore(reviewStats.meaning_incorrect, reviewStats.meaning_current_streak);
let readingScore = computeLeechScore(reviewStats.reading_incorrect, reviewStats.reading_current_streak);
item.leech_score = Math.max(meaningScore, readingScore);
if (meaningScore < readingScore) {
item.highestincorrect = reviewStats.reading_incorrect;
item.highestincorrectstreak = reviewStats.reading_current_streak;
} else {
item.highestincorrect = reviewStats.meaning_incorrect;
item.highestincorrectstreak = reviewStats.meaning_current_streak;
}
item.startleech = 9 - (item.assignments.srs_stage - item.highestincorrectstreak);
switch(item.startleech) {
case 8:
if (item.highestincorrect>18) {
item.impossible = "不可能"
item.impcnt = 1
} else {
item.impossible = " "
item.impcnt = 0
}
break;
case 7:
if (item.highestincorrect>14) {
item.impossible = "不可能"
item.impcnt = 1
} else {
item.impossible = " "
item.impcnt = 0
}
break;
case 6:
if (item.highestincorrect>11) {
item.impossible = "不可能"
item.impcnt = 1
} else {
item.impossible = " "
item.impcnt = 0
}
break;
case 5:
if (item.highestincorrect>7) {
item.impossible = "不可能"
item.impcnt = 1
} else {
item.impossible = " "
item.impcnt = 0
}
break;
case 4:
if (item.highestincorrect>5) {
item.impossible = "不可能"
item.impcnt = 1
} else {
item.impossible = " "
item.impcnt = 0
}
break;
case 3:
if (item.highestincorrect>2) {
item.impossible = "不可能"
item.impcnt = 1
} else {
item.impossible = " "
item.impcnt = 0
}
break;
case 2:
if (item.highestincorrect>0) {
item.impossible = "不可能"
item.impcnt = 1
} else {
item.impossible = " "
item.impcnt = 0
}
break;
case 1:
if (item.highestincorrect>0) {
item.impossible = "不可能"
item.impcnt = 1
} else {
item.impossible = " "
item.impcnt = 0
}
break;
default:
item.impossible = " "
item.impcnt = 0
}
//var summed = summer( item );
//console.log( "sum: "+summed );
return meaningScore >= leechThreshold || readingScore >= leechThreshold;
}
function computeLeechScore(incorrect, currentStreak) {
return incorrect / Math.pow((currentStreak || 0.5), 1.5);
}
function updatePage(items) {
let is_dashboard = window.location.pathname !== "/critical-items";
let totalleeches = items.length;
if (is_dashboard) {
items = items.sort((a, b) => (b.highestincorrect - a.highestincorrect)||(a.highestincorrectstreak - b.highestincorrectstreak)).slice(0,10);
} else {
items = items.sort((a, b) => (b.highestincorrect - a.highestincorrect)||(a.highestincorrectstreak - b.highestincorrectstreak));
}
console.log(items);
makeLeechList(items, is_dashboard, totalleeches);
}
function round(number, decimals)
{
return +(Math.round(number + "e+" + decimals) + "e-" + decimals);
}
function makeLeechList(items, for_dashboard, totalleeches) {
let rows = "";
let sumval = 0;
//DateTim = "";
//writer = "";
//temp = "C:\Leeches " + LocalDateTime.now() + ".txt";
//set fso = CreateObject("Scripting.FileSystemObject");
//set s = fso.CreateTextFile(temp, True);
items.forEach(item => {
let type = item.assignments.subject_type;
//use slug by default (for kanji and vocab)
let representation = item.data.slug;
//The slug of a radical just has its name, we want the actual symbol.
if (type === 'radical') {
if (item.data.characters) {
//use characters for radicals when possible
representation = item.data.characters;
} else if (item.data.character_images) {
//use SVG image for scalability
let image_data = item.data.character_images.find(x => x.content_type === "image/svg+xml" && x.metadata.inline_styles);
if (image_data) {
representation = `<img style="height: 1em; width: 1em; filter: invert(100%);" src="${image_data.url}" />`;
}
}
}
rows+=`<tr class="${type}"><td><a href="${item.data.document_url}"><span lang="ja">${representation}</span><span class="pull-right"><table style="width:150px"><td width="40%" align="right"> ${item.impossible} </td><td width="30%" align="right">${item.highestincorrect}/${item.highestincorrectstreak}</td><td width="30%" align="right">${round(item.leech_score, 2)}</td></table> </span></a></td></tr>`;
if (item.impcnt == 1) {
sumval = sumval + 1;
}
//s.writeline(representation);
});
//s.Close();
let sectionContent = `<h3 class="small-caps">${for_dashboard ? 'Top ' : ''}Leeches${for_dashboard ? ' (' + totalleeches + ')' : ''}</h3>
<table>
<tbody style="display: table-row-group;">
${rows}
</tbody>
</table>
<div class="see-more">
<a class="small-caps" ${for_dashboard ? 'href="critical-items"' : ''}>${for_dashboard ? 'See More Leeches...' : items.length + ' leeches total (' + sumval + ' burn-only leeches)'}</a>
</div>`;
dom.$('.low-percentage').html(sectionContent);
}
})();