Duolingo Course Progress

Progress report for Duolingo course

  1. // ==UserScript==
  2. // @name Duolingo Course Progress
  3. // @namespace https://github.com/kane77/userscripts
  4. // @include https://www.duolingo.com/*
  5. // @description Progress report for Duolingo course
  6. // @author Martin Harvan
  7. // @version 1.6.1
  8. // @grant GM_getValue
  9. // ==/UserScript==
  10. function inject(f) { //Inject the script into the document
  11. var script;
  12. script = document.createElement('script');
  13. script.type = 'text/javascript';
  14. script.setAttribute('name', 'lesson_stats');
  15. script.textContent = '(' + f.toString() + ')(jQuery)';
  16. document.head.appendChild(script);
  17. }
  18. inject(f);
  19. function f($) {
  20. function duolingoStats() {
  21. try {
  22. var langData = window.duo.user.attributes.language_data[window.duo.user.attributes.learning_language];
  23. var totalSkills = langData.skills.models.length;
  24. var doneSkills = 0;
  25. var totalActivities = 0;
  26. var doneActivities = 0;
  27. for (var i = 0; i < langData.skills.models.length; i++) {
  28. var skill = langData.skills.models[i];
  29. totalActivities += skill.attributes.num_lessons;
  30. doneActivities += skill.attributes.num_lessons - skill.attributes.missing_lessons;
  31. if (skill.attributes.missing_lessons === 0) {
  32. doneSkills += 1;
  33. }
  34. }
  35. if (langData.bonus_skills) {
  36. totalSkills += langData.bonus_skills.length;
  37. for (var i = 0; i < langData.bonus_skills.models.length; i++) {
  38. var skill = langData.bonus_skills.models[i];
  39. totalActivities += skill.attributes.num_lessons;
  40. doneActivities += skill.attributes.num_lessons - skill.attributes.missing_lessons;
  41. if (skill.attributes.missing_lessons === 0) {
  42. doneSkills += 1;
  43. }
  44. }
  45. }
  46. var lessonPercent = Math.round(doneActivities / totalActivities * 100);
  47. var skillPercent = Math.round(doneSkills / totalSkills * 100);
  48. var skillElem = createElem(doneSkills, totalSkills, skillPercent, "Skills", "S");
  49. var lessonElem = createElem(doneActivities, totalActivities, lessonPercent, "Lessons", "L");
  50. var stats = $('<ul class="sidebar-stats lesson-progress"></ul>');
  51. skillElem.appendTo(stats);
  52. lessonElem.appendTo(stats);
  53. if ($('#app').hasClass('home') && !$('.lesson-progress').length) {
  54. $('.strengthen-skills-container').before(stats);
  55. }
  56. } catch (ex) {
  57. console.log(ex);
  58. }
  59. }
  60. function createElem(doneCount, totalCount, percent, name, icon) {
  61. var elemText = $('<span id="'+ name +'_text"><strong>' + doneCount + '/' + totalCount + '</strong> '+name+'</span>');
  62. var percentage = $('<span id="'+name+'_percent"><strong>' + percent + '%</strong></span>');
  63. percentage.hide();
  64. var elem = $('<li style="text-align: left; display: block; margin-top: 2px;" id="'+name+'_stats" title="' + percent + '%"><span class="icon icon-words-small '+name+'-icon">'+icon+'</span></li>');
  65. elem.append(elemText);
  66. elem.append(percentage);
  67. $('.'+name+'-icon').mouseover(function() {
  68. $('#'+name+'_text').hide();
  69. $('#'+name+'_percent').css('display', 'inline-block');
  70. })
  71. .mouseout(function() {
  72. $('#'+name+'_percent').hide();
  73. $('#'+name+'_text').show();
  74. });
  75. return elem;
  76. }
  77. $(document).ready(function () {
  78. duolingoStats();
  79. });
  80. $(document).ajaxComplete(function () {
  81. duolingoStats();
  82. });
  83. }
  84.