Forvo download (July 2015)

Download audio from forvo.com, on search results page, adds a download link, on individual word page, replaces the "download" icon.

  1. // ==UserScript==
  2. // @name Forvo download (July 2015)
  3. // @namespace runkit.ru
  4. // @description Download audio from forvo.com, on search results page, adds a download link, on individual word page, replaces the "download" icon.
  5. // @author Modifications by Michael Elsdoerfer
  6. // @include http://www.forvo.com/*
  7. // @include http://*.forvo.com/*
  8. // @version 0.0.1.20150705131822
  9. // ==/UserScript==
  10.  
  11. run();
  12.  
  13. function run()
  14. {
  15. res = xpath("//a[@class='play']");
  16. len = res.snapshotLength;
  17.  
  18. if( len < 1 ) {
  19. return 0;
  20. }
  21.  
  22. for (var i = 0; i < len; i++) {
  23. var objLink = res.snapshotItem(i);
  24. var strLink = getMp3Url(objLink);
  25. var downloadIcon = objLink.parentNode.querySelector('.download a');
  26. if (downloadIcon) {
  27. downloadIcon.setAttribute('href', strLink);
  28. downloadIcon.setAttribute('download', 'download'); // force download
  29. } else {
  30. // Assume we are on search results page
  31. var a = document.createElement("a");
  32. a.innerHTML = "download";
  33. a.setAttribute('href', strLink);
  34. a.setAttribute('download', 'download');
  35. objLink.parentNode.appendChild(a);
  36. }
  37. }
  38.  
  39. return 0;
  40. }
  41.  
  42. function getMp3Url(obj)
  43. {
  44. // Looks like this:
  45. // Play(71450,'ODk3NTY2NS80NC84OTc1NjY1XzQ0XzMxMzA2MV8xLm1wMw==','ODk3NTY2NS80NC84OTc1NjY1XzQ0XzMxMzA2MV8xLm9nZw==');return false;
  46. var str = obj.getAttribute('onclick');
  47.  
  48. // We get the second, third arguments to Play()
  49. var expr = new RegExp(",'(.+)','");
  50. var mp3 = expr.exec(str)[1];
  51. var ogg = expr.exec(str)[1];
  52. // Code from Forvo's Play() function to build the link
  53. _SERVER_HOST == _AUDIO_HTTP_HOST ? (
  54. mp3 = "http://" + _SERVER_HOST + "/player-mp3Handler.php?path=" + mp3,
  55. ogg = "http://" + _SERVER_HOST + "/player-oggHandler.php?path=" + ogg
  56. ) : (
  57. mp3 = "http://" + _AUDIO_HTTP_HOST + "/mp3/" + base64_decode(mp3),
  58. ogg = "http://" + _AUDIO_HTTP_HOST + "/ogg/" + base64_decode(ogg)
  59. );
  60.  
  61. return mp3;
  62. }
  63.  
  64. /**
  65. * Возращает первый результат xpath запроса query
  66. */
  67. function xpathfirst(query, startingPoint){
  68.  
  69. var res = xpath(query, startingPoint);
  70.  
  71. if (res.snapshotLength == 0){return false;}
  72.  
  73. return res.snapshotItem(0);
  74. }
  75. /**
  76. * Обертка для xpath запроса
  77. */
  78. function xpath(query, startingPoint){
  79.  
  80. if (startingPoint == null) {
  81. startingPoint = document;
  82. }
  83. var retVal = document.evaluate(query, startingPoint, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  84.  
  85. return retVal;
  86. }
  87. /**
  88. * Обертка для getElementsByTagName
  89. */
  90. function _gt(e){return document.getElementsByTagName(e);}
  91. /**
  92. * Обертка для getElementsByTagName
  93. */
  94. function _gi(e){return document.getElementById(e);}
  95. /**
  96. * Возращает целое случайное число.
  97. */
  98. function getRandomInt(min, max)
  99. {
  100. return Math.floor(Math.random() * (max - min + 1)) + min;
  101. }
  102.  
  103. function getFormatDate(format){
  104.  
  105. var cur_time = new Date();
  106.  
  107. return cur_time.getHours() + ":" + cur_time.getMinutes() + ":" + cur_time.getSeconds();
  108. }