OB Onekey-Info-Generator

Ourbits 一键获取信息

  1. // ==UserScript==
  2. // @name OB Onekey-Info-Generator
  3. // @namespace exhen32@live.com
  4. // @version 2018061002
  5. // @description Ourbits 一键获取信息
  6. // @author Exhen
  7. // @match https://ourbits.club/upload.php*
  8. // @match http://ourbits.club/upload.php*
  9. // @match https://ourbits.club/offers.php?add_offer=1*
  10. // @match http://ourbits.club/offers.php?add_offer=1*
  11. // @grant GM_xmlhttpRequest
  12. // @grant GM_setClipboard
  13. // @icon https://ourbits.club/favicon.ico
  14. // @grant GM_addStyle
  15. // @grant GM_setValue
  16. // @grant GM_getValue
  17. // @grant GM_download
  18. // @require http://cdn.bootcss.com/jquery/3.2.1/jquery.min.js
  19. // @require https://cdn.bootcss.com/jqueryui/1.12.1/jquery-ui.min.js
  20. // @connect *
  21. // ==/UserScript==
  22.  
  23. var getDoc = function (url, meta, callback) {
  24. GM_xmlhttpRequest({
  25. method: 'GET',
  26. url: url,
  27. headers: {
  28. 'User-agent': window.navigator.userAgent,
  29. 'Content-type': null
  30. },
  31. onload: function (responseDetail) {
  32. var doc;
  33. doc = '';
  34. if (responseDetail.status == 200) {
  35. doc = (new DOMParser).parseFromString(responseDetail.responseText, 'text/html');
  36. if (doc == undefined) {
  37. doc = document.implementation.createHTMLDocument('');
  38. doc.querySelector('html').innerHTML = responseText;
  39. }
  40. }
  41. callback(doc, responseDetail, meta);
  42. }
  43. });
  44. };
  45.  
  46.  
  47. var getBlob = function (url, referer, callback) {
  48. GM_xmlhttpRequest({
  49. method: 'GET',
  50. url,
  51. headers: {
  52. 'User-agent': window.navigator.userAgent,
  53. 'Content-type': null,
  54. 'referer': referer
  55. },
  56. responseType: 'blob',
  57. onload: function (responseDetail) {
  58. if (responseDetail.status >= 200 && responseDetail.status < 300) {
  59. callback(responseDetail.response);
  60. }
  61. }
  62. })
  63. }
  64.  
  65. var compressImg = function (file, options, callback) {
  66. imgtype = 'image/jpeg';
  67. var self = this;
  68. // 用FileReader读取文件
  69. var reader = new FileReader();
  70. // 将图片读取为base64
  71. reader.readAsDataURL(file);
  72. reader.onload = function (evt) {
  73. var base64 = evt.target.result;
  74. // 创建图片对象
  75. var img = new Image();
  76. // 用图片对象加载读入的base64
  77. img.src = base64;
  78. img.onload = function () {
  79. var that = this,
  80. canvas = document.createElement('canvas'),
  81. ctx = canvas.getContext('2d');
  82. canvas.setAttribute('width', that.width);
  83. canvas.setAttribute('height', that.height);
  84. // 将图片画入canvas
  85. ctx.drawImage(that, 0, 0, that.width, that.height);
  86.  
  87. // 压缩到指定体积以下(M)
  88. if (options.size) {
  89. //console.log('size');
  90. var scale = 0.9;
  91. (function f(scale) {
  92. if (base64.length / 1024 / 1024 > options.size && scale > 0) {
  93. base64 = canvas.toDataURL(imgtype, scale);
  94. scale = scale - 0.1;
  95. f(scale);
  96. } else {
  97. callback(base64);
  98.  
  99. }
  100. })(scale);
  101. } else if (options.scale) {
  102. //console.log('scale');
  103.  
  104. // 按比率压缩
  105. base64 = canvas.toDataURL(imgtype, options.scale);
  106. callback(base64);
  107. }
  108.  
  109. }
  110. }
  111. };
  112.  
  113.  
  114. var postAttach = function (blob, filename, callback) {
  115. compressImg(blob, { "size": 2 }, function (base64) {
  116.  
  117. var base64Arr = base64.split(',');
  118. var imgtype = '';
  119. var base64String = '';
  120. if (base64Arr.length > 1) {
  121. //如果是图片base64,去掉头信息
  122. base64String = base64Arr[1];
  123. imgtype = base64Arr[0].substring(base64Arr[0].indexOf(':') + 1, base64Arr[0].indexOf(';'));
  124. }
  125. // 将base64解码
  126. var bytes = atob(base64String);
  127. //var bytes = base64;
  128. var bytesCode = new ArrayBuffer(bytes.length);
  129. // 转换为类型化数组
  130. var byteArray = new Uint8Array(bytesCode);
  131.  
  132. // 将base64转换为ascii码
  133. for (var i = 0; i < bytes.length; i++) {
  134. byteArray[i] = bytes.charCodeAt(i);
  135. }
  136.  
  137. // 生成Blob对象(文件对象)
  138. blob = new Blob([bytesCode], { type: imgtype });
  139. //console.log(blob);
  140.  
  141. let xhr = new XMLHttpRequest();
  142. let formData = new FormData();
  143. formData.append('file', blob, filename);
  144. xhr.open('POST', '/attachment.php');
  145. xhr.send(formData);
  146. xhr.onreadystatechange = function () {
  147. if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
  148. let match = xhr.responseText.match(/(?<=\[attach\]).*(?=\[\/attach\])/);
  149. if (match) callback(match);
  150. }
  151. };
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158. });
  159. }
  160.  
  161.  
  162. var postAttach_picgd = function (blob, filename, callback) {
  163.  
  164. getDoc('https://www.picgd.com', null, function (doc, res, meta) {
  165. var auth_token = res.responseText.match(/(?<=auth_token=).*(?=")/);
  166. var myDate=new Date();
  167. var formDataTest = new FormData();
  168. formDataTest.append('source', blob, filename);
  169. formDataTest.append('type', 'file');
  170. formDataTest.append('action', 'upload');
  171. formDataTest.append('timestamp', myDate.getTime());
  172. formDataTest.append('auth_token', auth_token);
  173. formDataTest.append('nsfw', '0');
  174. GM_xmlhttpRequest({
  175. method: 'POST',
  176. url: 'https://www.picgd.com/json',
  177. headers: {
  178. 'User-agent': window.navigator.userAgent,
  179.  
  180. },
  181. data: formDataTest,
  182. onload: function (responseDetail) {
  183. if(responseDetail.status==200){
  184. let name = JSON.parse(responseDetail.responseText).image.file.resource.chain.image.slice(14);
  185. callback(responseDetail.status,name);
  186. }
  187. else{
  188. //console.log(responseDetail.responseText);
  189. callback( responseDetail.status,JSON.parse(responseDetail.responseText).error.message);
  190. }
  191.  
  192. }
  193. })
  194.  
  195. })
  196.  
  197.  
  198.  
  199.  
  200.  
  201. }
  202.  
  203. $('form#compose td').filter(function () { return $(this).text() == '豆瓣链接' }).parent().addClass('douban');
  204. var douban_button = $('<input type="button" class="douban_button" value="一键填写">');
  205. douban_button.click(function () {
  206. var dburl = $('input[name="dburl"]')[0].value;
  207. var method = $('input[name="method"]:checked')[0].value;
  208. var pic_source=$('input[name="pic_source"]:checked')[0].value;
  209. //console.log(method);
  210. getDoc(dburl, null, function (doc, res, meta) {
  211. var douban_id = dburl.split('/')[4];
  212. var title_cn = $('#content > h1 > span', doc)[0].textContent.split(' ').shift();
  213. var director = $('div.article #info span.attrs:first', doc).text();
  214. var imdburl = $('div#info a[href^=\'http://www.imdb.com/title/tt\']', doc).attr('href');
  215.  
  216.  
  217. var moive_info = '';
  218. if (title_cn) { moive_info = moive_info + '\n◎片  名 ' + title_cn.replace(/ \/ /g, '\n      ' ); }
  219. var title_aka = $('div.article #info', doc).contents().filter(function () {
  220. return (this.nodeType === 3) && ($(this).prev().text() == "又名:");
  221. }).text().trim().replace(/ \/ /g, '/');
  222. if (title_aka) {
  223. moive_info = moive_info + '\n◎又  名 ' + title_aka;
  224. }
  225. var year = $('#content > h1 > span.year', doc).text().substr(1, 4);
  226. if (year) {
  227. moive_info = moive_info + '\n◎年  代 ' + year;
  228. }
  229. var region = $('div.article #info', doc).contents().filter(function () {
  230. return (this.nodeType === 3) && ($(this).prev().text() == "制片国家/地区:");
  231. }).text().trim().replace(/ \/ /g, '/');
  232. if (region) {
  233. moive_info = moive_info + '\n◎产  地 ' + region;
  234. }
  235. var genre = '';
  236. $('div.article #info span[property="v:genre"]', doc).each(function () { genre += $(this).text() + '/' });
  237. if (genre) {
  238. moive_info = moive_info + '\n◎类  别 ' + genre.slice(0, -1);
  239. }
  240. var language = $('div.article #info', doc).contents().filter(function () {
  241. return (this.nodeType === 3) && ($(this).prev().text() == "语言:");
  242. }).text().trim().replace(/ \/ /g, '/');
  243. if (language) {
  244. moive_info = moive_info + '\n◎语  言 ' + language;
  245. }
  246. var releaseDate = '';
  247. $('div.article #info [property="v:initialReleaseDate"]', doc).each(function () {
  248. releaseDate += $(this).text() + '/';
  249. })
  250. if (releaseDate) {
  251. moive_info = moive_info + '\n◎上映日期 ' + releaseDate.slice(0, -1);
  252. }
  253. var doubanRating = $('strong.rating_num.ll', doc).text();
  254. if (doubanRating) {
  255. moive_info = moive_info + '\n◎豆瓣评分 ' + doubanRating + '/10 from ' + $('a.rating_people span', doc).text().replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,') + ' users';
  256. }
  257. moive_info = moive_info + '\n◎豆瓣链接 ' + dburl;
  258. var duration = $('div.article #info', doc).contents().filter(function () {
  259. return ($(this).prev().attr('property') == "v:runtime") || ($(this).prev().text() == "片长:");
  260. }).text().trim();
  261. if (duration) {
  262. moive_info = moive_info + '\n◎片  长 ' + duration;
  263. }
  264. var director = $('div.article #info span.attrs:first', doc).text().replace(/ \/ /g, '\n      ' );
  265. if (director) {
  266. moive_info = moive_info + '\n◎导  演 ' + director;
  267. }
  268. var actors = $('div.article #info span.actor span.attrs', doc).contents().filter(function () {
  269. return $(this).attr("class") !== "more-actor";
  270. }).text().replace(/ \/ /g, '\n      ' );
  271. if (actors) {
  272. moive_info = moive_info + '\n◎主  演 ' + actors;
  273. }
  274. var intro = $('div.article div.related-info [property="v:summary"]', doc).text().replace(/ \n/g, '').replace(/ /g, '');
  275. if (intro) {
  276. moive_info = moive_info + '\n\n◎简  介\n' + intro;
  277. }
  278. var award = '';
  279. $('ul.award', doc).each(function () {
  280. $(this).find('li').each(function () {
  281. award += $(this).text().replace(/\n/g, ' ').replace(/ +/g, '') + ' ';
  282. })
  283. award += '\n  '
  284. });
  285. if (award) {
  286. moive_info = moive_info + '\n◎获奖情况\n\n  ' + award;
  287. }
  288. getDoc(imdburl, null, function (doc_imdb, res, meta) {
  289. var imdb_rating = $('span[itemprop=ratingValue]', doc_imdb).text();
  290. if (imdb_rating) {
  291. $('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val($('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val().replace(/◎豆瓣评分/, '◎IMDb评分 ' + imdb_rating + '/10 from ' + $('span[itemprop=ratingCount]', doc_imdb).text() + ' users' + '\n◎IMDb链接 ' + imdburl + '\n◎豆瓣评分'));
  292. }
  293.  
  294. })
  295.  
  296.  
  297.  
  298. $('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val(`[quote]请在这里上传海报并把本行文字删掉[/quote]\n[quote]${moive_info}\n[/quote]\n[quote][font=Courier New]\n请在这里补充INFO信息并把本行文字删掉\n[/quote]`);
  299.  
  300. $('form#compose td').filter(function () { return ($(this).text() == 'IMDb链接')||$(this).text() == 'IMDB链接' }).parent().find('input')[0].value = imdburl;
  301. $('form#compose td').filter(function () { return $(this).text() == '副标题' }).parent().find('input')[0].value = title_cn + ' ' + $('div.article #info span.attrs:first', doc).text().replace(/ \/ /g,'/') + '导演作品';
  302. //console.log(title_cn, ' ', director, '导演作品');
  303.  
  304. if (method == 'none') return;
  305.  
  306. var posterAnchor = $('#mainpic img', doc);
  307. if (posterAnchor.attr('src') && (posterAnchor.attr('title') !== '点击上传封面图片')) {
  308.  
  309. $('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val($('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val().replace(/请在这里上传海报并把本行文字删掉/, '已经找到可用海报,正在自动下载。'));
  310. var get_image_and_upload=function(url){
  311. getBlob(url, dburl, function (blob) {
  312. if (!blob) {
  313. $('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val($('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val().replace(/已经找到可用海报,正在自动下载。/, '自动下载海报失败,请自行上传海报并把本行文字删掉。'));
  314. }
  315. $('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val($('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val().replace(/已经找到可用海报,正在自动下载。/, '已成功下载海报,正在上传到OB服务器。'));
  316. if (method == 'picgd') {
  317. postAttach_picgd(blob, url.split('/')[7], function (status,name) {
  318. if(status==200){
  319. $('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val($('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val().replace(/已成功下载海报,正在上传到OB服务器。/, '[img]https://' + name + '[/img]'));
  320. }
  321. else{
  322. $('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val($('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val().replace(/已成功下载海报,正在上传到OB服务器。/, '上传到picgd时发生错误:'+name ));
  323. }
  324.  
  325. })
  326. }
  327. else if (method == 'attach') {
  328. postAttach(blob, url.split('/')[7], function (attach_id) {
  329. $('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val($('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val().replace(/已成功下载海报,正在上传到OB服务器。/, '[attach]' + attach_id + '[/attach]'));
  330. })
  331. }
  332.  
  333. })
  334. }
  335. if(pic_source=='fast'){
  336. get_image_and_upload(posterAnchor.attr('src').replace(/s_ratio_poster/,'l').replace(/webp/,'jpg'));
  337. //console.log(posterAnchor.attr('src').replace(/s_ratio_poster/,'l').replace(/webp/,'jpg'));
  338. }
  339. if(pic_source=='size'){
  340. var postersUrl = 'https://movie.douban.com/subject/' + douban_id + '/photos?type=R&start=0&sortby=size&size=a&subtype=o';
  341. getDoc(postersUrl, null, function (doc1, res, meta) {
  342. var aPosterUrl = $('.article > ul > li:nth-child(1) > div.cover > a', doc1).attr('href');
  343. getDoc(aPosterUrl, null, function (doc2, res, meta) {
  344. var hdPosterAnchor = $('span.magnifier > a', doc2);
  345. if (hdPosterAnchor.attr('href') == '#') {
  346. $('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val($('form#compose td').filter(function () { return $(this).text() == '简介*' }).parent().find('textarea').val().replace(/已经找到可用海报,正在自动下载。/, '未登录豆瓣,无法自动下载海报,请手动登陆豆瓣后重试,或自行上传海报并把本行文字删掉。'));
  347. return;
  348. }
  349. //console.log(hdPosterAnchor.attr('href'))
  350. get_image_and_upload(hdPosterAnchor.attr('href'));
  351. })
  352. })
  353. }
  354. // get the posters page's URL via movie.douban.com's customs
  355. }
  356.  
  357.  
  358.  
  359.  
  360.  
  361. //alert( $(this).prev()[0].value);
  362.  
  363. })
  364. })
  365. $('.douban td:last input').after(douban_button).after('<br>').after('<br>图片来源选择:<input type="radio" name="pic_source" value="fast" checked>直接用头图(匹配度高、速度快) <input type="radio" name="pic_source" value="size">优先大尺寸(稍慢)').after('<br>上传方式选择:<input type="radio" name="method" value="attach" checked>上传到附件(速度快,体积最大2M) <input type="radio" name="method" value="picgd">上传到OB图床(无体积限制,速度慢) <input type="radio" name="method" value="none">不自动上传图片');