WK Auto Commit (edited)

Auto commit for Wanikani with critical list edit.

  1. // ==UserScript==
  2. // @name WK Auto Commit (edited)
  3. // @namespace WKAUTOCOMMIT
  4. // @version 0.42
  5. // @description Auto commit for Wanikani with critical list edit.
  6. // @author Johannes Mikulasch
  7. // @match http://www.wanikani.com/review/session*
  8. // @match https://www.wanikani.com/review/session*
  9. // @match http://www.wanikani.com/lesson/session*
  10. // @match https://www.wanikani.com/lesson/session*
  11. // @grant none
  12. // @run-at document-end
  13. // @license
  14. // ==/UserScript==
  15.  
  16. /*
  17. * WK Auto Commit
  18. * If you typed in the correct answer then it is automatically commited.
  19. * Therefore, you have to use the 'enter' key way less than before.
  20. *
  21. * Version 0.42
  22. * Added Mixed mode.
  23. * Version 0.41
  24. * Fixed an issue with random mode when users did not have Ultimate Reorder script active.
  25. * Version 0.40
  26. * Improved UI and such.
  27. * Version 0.35
  28. * Edit by WillNiels to stop auto committing critical items
  29. * Version 0.3
  30. * Script works now on the Lessons page too
  31. * Version 0.2
  32. * Makes script work with Greasemonkey and Firefox
  33. * Version 0.1
  34. * Initial version
  35. *
  36. */
  37.  
  38.  
  39. /* jshint -W097 */
  40. 'use strict';
  41.  
  42. var activated = true;
  43. var mode;
  44. var click_threshold = 600;
  45.  
  46. var on_lessons_page = false;
  47.  
  48.  
  49. // ---- Tweak these as needed ---- //
  50. var percentCritical = '95'; // If you get an item correct less than this percent, it won't auto commit.
  51. var randomChance = .50; // If random is on it will only auto commit this often. ( 0 [never] to 1 [always] )
  52.  
  53. // Mixed mode, both rates apply
  54. var percentCriticalMixed = '75'; // If you get an item correct less than this percent, it won't auto commit.
  55. var randomChanceMixed = .80; // Random chance to commit (limiting kanji only) if passed critical test.
  56. // ------------------------------- //
  57.  
  58. //don't change these!
  59. var apiKey;
  60. var crit_list = [];
  61. var thisItem;
  62. var lastItem = null;
  63. var roll = 0;
  64.  
  65. var RandomFn = Math.randomB || Math.random;
  66.  
  67. var detect_lessons_page = function() {
  68. // Returns true if on lessons page
  69. var current_url = window.location.href;
  70. var lessonsPattern = /^http[s]?:\/\/www.wanikani.com\/lesson\/session.*/;
  71. return lessonsPattern.test(current_url);
  72. };
  73.  
  74. var toggle = function () {
  75. //Note: mode is only saved if user clicks the button.
  76. switch (mode) {
  77. case 'always': // To Mixed
  78. switchMode('mixed');
  79. break;
  80. case 'mixed': // To Critical
  81. if( on_lessons_page )
  82. switchMode('random');
  83. else
  84. switchMode('critical');
  85. break;
  86. case 'critical': // To Random
  87. switchMode('random');
  88. break;
  89. case 'random': // To OFF
  90. switchMode('off');
  91. break;
  92. case 'off': // To Always
  93. switchMode('always');
  94. break;
  95. }
  96. saveMode();
  97. };
  98.  
  99. var switchMode = function ( switchto ){
  100. switch (switchto) {
  101. case 'critical': // To Critical
  102. $("#WKAUTOCOMMIT_button").prop('title', "Switch to Random Mode");
  103. $("#WKAUTOCOMMIT_button").css({"opacity":"1.0"});
  104. $("#WKAUTOCOMMIT_button").css({"background-color":"#5C5"});
  105. $("#WKAUTOCOMMIT_button").text("Auto Commit: Critical List");
  106. mode = 'critical';
  107. generateList( percentCritical );
  108. break;
  109. case 'random': // To Random
  110. $("#WKAUTOCOMMIT_button").prop('title', "Switch auto commit OFF");
  111. $("#WKAUTOCOMMIT_button").css({"opacity":"1.0"});
  112. $("#WKAUTOCOMMIT_button").css({"background-color":"#55C"});
  113. $("#WKAUTOCOMMIT_button").text("Auto Commit: Random");
  114. mode = 'random';
  115. break;
  116. case 'off': // To OFF
  117. $("#WKAUTOCOMMIT_button").prop('title', "Switch to Always Mode");
  118. $("#WKAUTOCOMMIT_button").css({"opacity":"0.5"});
  119. $("#WKAUTOCOMMIT_button").css({"background-color":"#555"});
  120. $("#WKAUTOCOMMIT_button").text("Auto Commit: OFF");
  121. mode = 'off';
  122. break;
  123. case 'always': // To Always
  124. $("#WKAUTOCOMMIT_button").prop('title', "Switch to Mixed Mode");
  125. $("#WKAUTOCOMMIT_button").css({"opacity":"1.0"});
  126. $("#WKAUTOCOMMIT_button").css({"background-color":"#C55"});
  127. $("#WKAUTOCOMMIT_button").text("Auto Commit: Always");
  128. mode = 'always';
  129. break;
  130. case 'mixed': // To Always
  131. $("#WKAUTOCOMMIT_button").prop('title', "Switch to Critical Mode (or Random if on lessons)");
  132. $("#WKAUTOCOMMIT_button").css({"opacity":"1.0"});
  133. $("#WKAUTOCOMMIT_button").css({"background-color":"#2CC"});
  134. $("#WKAUTOCOMMIT_button").text("Auto Commit: Mixed");
  135. mode = 'mixed';
  136. generateList( percentCriticalMixed );
  137. break;
  138. }
  139. };
  140.  
  141. var sanitize = function (str1) {
  142. var str2 = str1.replace(/\s/g, ''); // Removes Whitespaces
  143. str2 = str2.toLowerCase();
  144. return str2;
  145. };
  146.  
  147. var commit = function () {
  148. $("#answer-form form button").click();
  149. setTimeout(function(){ $("#answer-form form button").click();}, click_threshold);
  150. };
  151.  
  152. var check_input = function () {
  153.  
  154. if (on_lessons_page) {
  155. var currentItem = $.jStorage.get("l/currentQuizItem");
  156. var currentquestiontype = $.jStorage.get("l/questionType");
  157. } else {
  158. var currentItem = $.jStorage.get("currentItem");
  159. var currentquestiontype = $.jStorage.get("questionType");
  160.  
  161. // If the item is critical, don't auto submit
  162. if(mode == 'critical' || mode == 'mixed' ){
  163. thisItem = (currentItem.rad || currentItem.voc || currentItem.kan);
  164. for( var i in crit_list ){
  165. if( crit_list[i] == thisItem ){
  166. return;
  167. }
  168. }
  169. }
  170.  
  171. }
  172.  
  173.  
  174. // Random chance to block the item.
  175. if( currentItem != lastItem ){
  176. roll = RandomFn(); //Really be careful here, weird things happen to the random function in my case.
  177. }
  178. //console.log("Roll is set to: " + roll + " with type: " + typeof(roll));
  179.  
  180. lastItem = currentItem;
  181.  
  182. if( mode == 'random'){
  183. if(roll > randomChance ){
  184. //console.log("Roll is more than the chance so we won't autocommit.");
  185. if(mode != 'random') console.log("This should never happen... random != " + mode);
  186. return;
  187. }
  188. }else if( mode == 'mixed' && currentItem.kan ){
  189. if(roll > randomChanceMixed ){
  190. //In mixed mode, kanji are randomly blocked but at a lower rate.
  191. if(mode != 'random') console.log("This should never happen... random != " + mode);
  192. return;
  193. }
  194. }
  195.  
  196.  
  197. var currentresponse = $("#user-response").val();
  198.  
  199. var currentitem_response = null;
  200.  
  201. // Get possible responses from current item depending on the task (reading or meaning)
  202. if (currentquestiontype === "meaning") {
  203. currentitem_response = currentItem.en;
  204. if (currentItem.syn) {
  205. currentitem_response = currentitem_response.concat(currentItem.syn);
  206. }
  207. } else if (currentquestiontype === "reading") {
  208. if (currentItem.voc) { // Vocab word
  209. currentitem_response = currentItem.kana;
  210. } else if (currentItem.emph === 'kunyomi') { // Kanji: Kun reading
  211. currentitem_response = currentItem.kun;
  212. } else if (currentItem.emph === 'onyomi') { // Kanji: On reading
  213. currentitem_response = currentItem.on;
  214. } else {
  215. console.log("WK Auto Commit: Could not find response");
  216. }
  217. }
  218.  
  219. for (var i in currentitem_response) {
  220. if (sanitize(currentresponse) === sanitize(currentitem_response[i]) ) {
  221. commit();
  222. }
  223. }
  224. };
  225.  
  226. var register_check_input = function () {
  227. $("#user-response").on("keyup", function (event) {
  228. if (mode != 'off') {
  229. check_input();
  230. }
  231. });
  232. };
  233.  
  234. var addButtons = function () {
  235.  
  236. $("<div />", {
  237. id : "WKAUTOCOMMIT_button",
  238. title : "Switch to Critical Mode",
  239. })
  240. .text("Auto Commit: Always")
  241. .css({"background-color":"#C55"})
  242. .css({"opacity":"1"})
  243. .css({"display":"inline-block"})
  244. .css({"font-size":"0.8125em"})
  245. .css({"color":"#FFF"})
  246. .css({"cursor":"pointer"})
  247. .css({"padding":"10px"})
  248. .css({"vertical-align":"bottom"})
  249. .on("click", toggle)
  250. .prependTo("footer");
  251. };
  252.  
  253. var generateList = function (percent){
  254. crit_list = [];
  255.  
  256. $.getJSON('/api/user/'+apiKey+'/critical-items/' + percent, function(json){
  257. if (json.error && json.error.code === 'user_not_found') {
  258. localStorage.removeItem('apiKey');
  259. }
  260. $(json.requested_information).each(function(i,v){
  261. try {
  262. var thing = v.character
  263. crit_list.push(thing);
  264. } catch(e) {}
  265. });
  266. });
  267. };
  268.  
  269. var saveMode = function () {
  270. if( on_lessons_page )
  271. localStorage.setItem('wkac_lesson_mode',mode);
  272. else
  273. localStorage.setItem('wkac_review_mode',mode);
  274. }
  275.  
  276. var loadMode = function () {
  277. if( on_lessons_page )
  278. mode = localStorage.getItem('wkac_lesson_mode');
  279. else
  280. mode = localStorage.getItem('wkac_review_mode');
  281. }
  282.  
  283. //Thank you Wanikani Real Numbers
  284. function retrieveAPIkey() {
  285. for(var i=0;i<document.getElementsByClassName('span6').length;i++){
  286. if(document.getElementsByClassName('span6')[i].getAttribute('placeholder')=="Key has not been generated")
  287. apiKey = document.getElementsByClassName('span6') [i].getAttribute('value');
  288. }
  289. alert('WaniKani Real Numbers API key set to: ' + apiKey);
  290. if (apiKey) {
  291. localStorage.setItem('apiKey', apiKey);
  292. localStorage.setItem('WRN_doneReviews', 'true');
  293. //GM_setValue('apikey', apikey);
  294. //GM_setValue('doneReviews', true);
  295. }
  296. }
  297.  
  298. var init = function () {
  299. console.log('WK Auto Commit (a plugin for Wanikani): Initialization started');
  300. on_lessons_page = detect_lessons_page();
  301. addButtons();
  302. register_check_input();
  303.  
  304. apiKey = localStorage.getItem('apiKey');
  305. if (!apiKey) {
  306. if (window.location.href.indexOf('account') != - 1) {
  307. retrieveAPIkey();
  308. apiKey = localStorage.getItem('apiKey');
  309. } else {
  310. var okcancel = confirm('WaniKani Auto Commit has no API key entered!\nPress OK to go to your settings page and retrieve your API key!');
  311. if (okcancel == true) {
  312. window.location = 'https://www.wanikani.com/account';
  313. }
  314. }
  315. }
  316.  
  317. loadMode();
  318. if(!mode ){
  319. mode = 'always';
  320. saveMode();
  321. }
  322.  
  323. switchMode(mode);
  324.  
  325. console.log('WK Auto Commit: Initialization ended');
  326. };
  327.  
  328. $(function(){
  329. init();
  330. });