长毛象:显示被屏蔽的实例媒体文件

由于mastodon.social站长封禁了所有来自pawoo.net媒体文件,导致在mastodon.social看不到那边的媒体文件。这个脚本就是为了解决这个问题而生的。P.S. 头像问题无解,别想了。

  1. "use strict";
  2.  
  3. // ==UserScript==
  4. // @name 长毛象:显示被屏蔽的实例媒体文件
  5. // @namespace http://tampermonkey.net/
  6. // @version 0.6
  7. // @description 由于mastodon.social站长封禁了所有来自pawoo.net媒体文件,导致在mastodon.social看不到那边的媒体文件。这个脚本就是为了解决这个问题而生的。P.S. 头像问题无解,别想了。
  8. // @author https://mastodon.social/web/accounts/849118
  9. // @include https://mastodon.social*
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. /**
  14. * 如果需要在mastodon.social之外的实例使用该脚本,请在// @include https://mastodon.social* 下方再添加一个@include 网站名称请修改正你所在实例,别忘了最后有个星号。
  15. */
  16. (function () {
  17. 'use strict'; // 命名空间
  18.  
  19. var ajax_interceptor_qoweifjqon = {
  20. settings: {
  21. ajaxInterceptor_switchOn: false,
  22. ajaxInterceptor_rules: []
  23. },
  24. originalXHR: window.XMLHttpRequest,
  25. myXHR: function myXHR() {
  26. var _this = this;
  27.  
  28. var modifyResponse = function modifyResponse() {
  29. if (_this.responseText.trim()) {
  30. try {
  31. var parseObject = eval(_this.responseText); // 如果检测到当前请求是用户主页的「嘟文和回复」发出的,那么移除响应中的所有转嘟数据。
  32. // 比如:https://mastodon.social/api/v1/accounts/946408/statuses?exclude_replies=false&since_id=104012306590410838
  33.  
  34. if (/api\/v1\/accounts\/\d*?\/statuses\?exclude_replies=false/.test(_this.responseURL)) {
  35. parseObject = parseObject.filter(function (item) {
  36. return !item.reblog;
  37. });
  38. }
  39.  
  40. parseObject.forEach(function (toot) {
  41. if (toot.reblog) {
  42. // 先判断属性是否存在,因为有些接口不存在。
  43. if (toot.reblog.media_attachments && toot.reblog.media_attachments.length) {}
  44.  
  45. toot.reblog.media_attachments.forEach(function (media) {
  46. if (media.type === 'unknown') {
  47. // mastodon会将封禁media的实例的type设置为unknown
  48. // 手动修改
  49. media.type = 'image';
  50. media.preview_url = media.remote_url;
  51. media.url = media.remote_url;
  52. }
  53. });
  54. } else if (toot.media_attachments && toot.media_attachments.length) {
  55. toot.media_attachments.forEach(function (media) {
  56. if (media.type === 'unknown') {
  57. // mastodon会将封禁media的实例的type设置为unknown
  58. // 手动修改
  59. media.type = 'image';
  60. media.preview_url = media.remote_url;
  61. media.url = media.remote_url;
  62. }
  63. });
  64. }
  65. });
  66. _this.responseText = JSON.stringify(parseObject);
  67. } catch (_) {
  68. console.log('error: parse filed: ', _); // 遇到解析不了的那也没办法。比如/context接口的参数无法解析,目测是里面包含html字符问题;
  69. }
  70. }
  71. };
  72.  
  73. var xhr = new ajax_interceptor_qoweifjqon.originalXHR();
  74.  
  75. var _loop = function _loop(attr) {
  76. if (attr === 'onreadystatechange') {
  77. xhr.onreadystatechange = function () {
  78. if (_this.readyState == 4) {
  79. modifyResponse();
  80. }
  81.  
  82. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  83. args[_key] = arguments[_key];
  84. }
  85.  
  86. _this.onreadystatechange && _this.onreadystatechange.apply(_this, args);
  87. };
  88.  
  89. return 'continue';
  90. } else if (attr === 'onload') {
  91. xhr.onload = function () {
  92. modifyResponse();
  93.  
  94. for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  95. args[_key2] = arguments[_key2];
  96. }
  97.  
  98. _this.onload && _this.onload.apply(_this, args);
  99. };
  100.  
  101. return 'continue';
  102. } // 将函数原有内容全部拷贝到当前对象的属性上。
  103.  
  104.  
  105. if (typeof xhr[attr] === 'function') {
  106. _this[attr] = xhr[attr].bind(xhr);
  107. } else {
  108. // responseText和response不是writeable的,但拦截时需要修改它,所以修改就存储在this[`_${attr}`]上
  109. if (attr === 'responseText' || attr === 'response') {
  110. Object.defineProperty(_this, attr, {
  111. get: function get() {
  112. return _this['_'.concat(attr)] == undefined ? xhr[attr] : _this['_'.concat(attr)];
  113. },
  114. set: function set(val) {
  115. return _this['_'.concat(attr)] = val;
  116. },
  117. enumerable: true
  118. });
  119. } else {
  120. Object.defineProperty(_this, attr, {
  121. get: function get() {
  122. return xhr[attr];
  123. },
  124. set: function set(val) {
  125. return xhr[attr] = val;
  126. },
  127. enumerable: true
  128. });
  129. }
  130. }
  131. };
  132.  
  133. for (var attr in xhr) {
  134. var _ret = _loop(attr);
  135.  
  136. if (_ret === 'continue') continue;
  137. }
  138. }
  139. };
  140. window.XMLHttpRequest = ajax_interceptor_qoweifjqon.myXHR;
  141. })();