Greasy Fork is available in English.

DDU Tagger

DDU posts with IMDB, rottentomatoes

  1. // ==UserScript==
  2. // @name DDU Tagger
  3. // @description DDU posts with IMDB, rottentomatoes
  4. // @author SH3LL
  5. // @version 0.4.3
  6. // @match https://ddunlimited.net/viewforum.php?*
  7. // @grant none
  8. // @run-at document-idle
  9. // @grant GM_xmlhttpRequest
  10. // @license GPL3
  11. // @namespace https://greasyfork.org/users/762057
  12. // ==/UserScript==
  13.  
  14.  
  15. function TMDB_search_api(title, year, content) {
  16.  
  17. if (content==="movie" || content==="movie_cartoon" || content==="movie_anime"){
  18. return new Promise(function (resolve, reject) {
  19. GM_xmlhttpRequest({
  20. method: 'GET',
  21. responseType: 'json',
  22. synchronous: false,
  23. url: 'https://api.themoviedb.org/3/search/movie?api_key=8d6d91941230817f7807d643736e8a49&query='+ title +'&page=1&include_adult=false',
  24. onload: (resp) => {
  25.  
  26. let json = JSON.parse(resp.responseText);
  27. console.log('TMDB search api: https://api.themoviedb.org/3/search/movie?api_key=8d6d91941230817f7807d643736e8a49&query='+ title +'&page=1&include_adult=false');
  28.  
  29. if (json && json.Error) {
  30. console.log("Error: " + json.Error);
  31. resolve("error"); return;
  32. }
  33.  
  34. if (parseInt(json.total_results) !== 0){
  35. for(let result of json.results){
  36. if(result.release_date === undefined) continue;
  37.  
  38. // animation check
  39. let animation_flag=0;
  40. if(content==="movie_cartoon" || content==="movie_anime"){
  41. for(let curr_genre of result.genre_ids) {if(parseInt(curr_genre)===16) {animation_flag=1; continue;}}
  42. }
  43. if((content==="movie_cartoon" || content==="movie_anime") && animation_flag!==1) continue;
  44.  
  45. //send result
  46. if( parseInt(result.release_date.slice(0,4)) === parseInt(year) || parseInt(result.release_date.slice(0,4)) === parseInt(year) - 1 || parseInt(result.release_date.slice(0,4)) === parseInt(year) + 1){ // FIX exported EU MOVIES & TMDB errors
  47. resolve(result.id); return;
  48. }
  49. }
  50. }else{
  51. console.log("Error: query returned no results");
  52. resolve("error"); return;
  53. }
  54. //if no year is found
  55. console.log("Error: no result matched the year");
  56. resolve("error"); return;
  57.  
  58. }
  59. });
  60. });
  61.  
  62. }else if(content==="tv" || content==="tv_cartoon" || content==="tv_anime"){
  63. return new Promise(function (resolve, reject) {
  64. GM_xmlhttpRequest({
  65. method: 'GET',
  66. responseType: 'json',
  67. synchronous: false,
  68. url: 'https://api.themoviedb.org/3/search/tv?api_key=8d6d91941230817f7807d643736e8a49&query='+ title +'&page=1&include_adult=false',
  69. onload: (resp) => {
  70.  
  71. let json = JSON.parse(resp.responseText);
  72. console.log('TMDB search api: https://api.themoviedb.org/3/search/tv?api_key=8d6d91941230817f7807d643736e8a49&query='+ title +'&page=1&include_adult=false');
  73.  
  74. if (json && json.Error) {
  75. console.log("Error: " + json.Error);
  76. resolve("error"); return;
  77. }
  78.  
  79. if (parseInt(json.total_results) !== 0){
  80. let first_entry = json.results[0];
  81. resolve(first_entry.id); return;
  82.  
  83. }else{
  84. console.log("Error: query returned no results");
  85. resolve("error"); return;
  86. }
  87.  
  88. }
  89. });
  90. });
  91. }
  92. }
  93.  
  94. function TMDB_title_api(TMDB_id,content,country) {
  95.  
  96. if (content==="movie" || content==="movie_cartoon" || content==="movie_anime"){
  97. return new Promise(function (resolve, reject) {
  98. GM_xmlhttpRequest({
  99. method: 'GET',
  100. responseType: 'json',
  101. synchronous: false,
  102. url: 'https://api.themoviedb.org/3/movie/'+TMDB_id+'?api_key=8d6d91941230817f7807d643736e8a49&language=it&append_to_response=external_ids,videos',
  103. onload: (resp) => {
  104.  
  105. let json = JSON.parse(resp.responseText);
  106. console.log('TMDB title api: https://api.themoviedb.org/3/movie/'+TMDB_id+'?api_key=8d6d91941230817f7807d643736e8a49&language=it&append_to_response=external_ids,videos');
  107.  
  108. if (json && json.Error) {
  109. console.log("Error: " + json.Error);
  110. resolve("error"); return;
  111. }
  112.  
  113. let YT_trailer_url_delta=0,IMDB_id=0,TMDB_title=0,TMDB_year=0,TMDB_poster_delta=0;
  114.  
  115. if(content.includes("anime")) {TMDB_title = json.title;} else {TMDB_title = json.original_title;} //title
  116. if(json.external_ids!==undefined && json.external_ids.imdb_id!== null) IMDB_id = json.external_ids.imdb_id; //imdb id
  117. if(json.release_date!==null && json.release_date!==undefined) TMDB_year=json.release_date.slice(0,4);
  118. if(json.poster_path!==null) TMDB_poster_delta = json.poster_path; //poster
  119. if(json.videos!==undefined && json.videos.results.length!==0) YT_trailer_url_delta = json.videos.results[0].key; //videos
  120.  
  121. resolve([IMDB_id,TMDB_title,TMDB_year,TMDB_poster_delta,YT_trailer_url_delta]); return;
  122.  
  123. }
  124. });
  125. });
  126.  
  127. }else if(content==="tv" || content==="tv_cartoon" || content==="tv_anime"){
  128. return new Promise(function (resolve, reject) {
  129. GM_xmlhttpRequest({
  130. method: 'GET',
  131. responseType: 'json',
  132. synchronous: false,
  133. url: 'https://api.themoviedb.org/3/tv/'+TMDB_id+'?api_key=8d6d91941230817f7807d643736e8a49&language='+country+'&append_to_response=external_ids,videos',
  134. onload: (resp) => {
  135.  
  136. let json = JSON.parse(resp.responseText);
  137. console.log('TMDB title api: https://api.themoviedb.org/3/tv/'+TMDB_id+'?api_key=8d6d91941230817f7807d643736e8a49&language='+country+'&append_to_response=external_ids,videos');
  138.  
  139. if (json && json.Error) {
  140. console.log("Error: " + json.Error);
  141. resolve("error"); return;
  142. }
  143.  
  144. let YT_trailer_url_delta=0,IMDB_id=0,TMDB_title=0,TMDB_poster_delta=0,seasonscount=0;
  145.  
  146. if(content.includes("cartoon")) {TMDB_title = json.name;} else {TMDB_title = json.original_name;} //title
  147. if(json.external_ids!==undefined && json.external_ids.imdb_id!== null) IMDB_id = json.external_ids.imdb_id; //imdb id
  148. if(json.poster_path!==null) TMDB_poster_delta = json.poster_path; //poster
  149. if(json.videos!==undefined && json.videos.results.length!==0) YT_trailer_url_delta = json.videos.results[0].key; //videos
  150. if(json.seasons!==undefined && json.seasons!== null) seasonscount = (json.seasons).length;
  151.  
  152. //years range
  153. let first_year="N/A",last_year="N/A",years_range;
  154. if(json.first_air_date!==undefined && json.first_air_date!==null) first_year = json.first_air_date.slice(0,4);
  155. if(json.last_air_date!==undefined && json.last_air_date!==null) {
  156. if(json.last_air_date.slice(2,4) !== first_year.slice(2,4)) last_year = json.last_air_date.slice(2,4);
  157. }
  158.  
  159. if(last_year !=="N/A") years_range=first_year + "-" + last_year; else years_range=first_year;
  160.  
  161. resolve([IMDB_id,TMDB_title,first_year,TMDB_poster_delta,YT_trailer_url_delta,seasonscount,years_range]); return;
  162.  
  163. }
  164. });
  165. });
  166. }
  167. }
  168.  
  169. function TMDB_providers_api(id,my_country,content) {
  170.  
  171. if (content==="movie" || content==="movie_cartoon" || content==="movie_anime"){
  172. return new Promise(function (resolve, reject) {
  173. GM_xmlhttpRequest({
  174. method: 'GET',
  175. responseType: 'json',
  176. synchronous: false,
  177. url: 'https://api.themoviedb.org/3/movie/'+ id +'/watch/providers?api_key=8d6d91941230817f7807d643736e8a49',
  178. onload: (resp) => {
  179.  
  180. let json = JSON.parse(resp.responseText);
  181. console.log('TMDB provder api: https://api.themoviedb.org/3/movie/'+ id +'/watch/providers?api_key=8d6d91941230817f7807d643736e8a49');
  182.  
  183. if (json && json.Error) {
  184. console.log("Error: " + json.Error);
  185. resolve("error"); return;
  186. }
  187.  
  188. let providers = [];
  189. for(let curr_country in json.results){
  190. if(String(curr_country)===my_country && json.results[curr_country].flatrate !== undefined){
  191. for(let provider of json.results[curr_country].flatrate){
  192. providers.push(
  193. {
  194. "provider_name" : provider.provider_name,
  195. "provider_logo" : provider.logo_path
  196. }
  197. );
  198. }
  199. }
  200. }
  201. if(providers.length !== 0 ){
  202. resolve(providers); return;
  203. }else{resolve("error"); return}
  204.  
  205. }
  206. });
  207. });
  208.  
  209. }else if(content==="tv" || content==="tv_cartoon" || content==="tv_anime"){
  210. return new Promise(function (resolve, reject) {
  211. GM_xmlhttpRequest({
  212. method: 'GET',
  213. responseType: 'json',
  214. synchronous: false,
  215. url: 'https://api.themoviedb.org/3/tv/'+ id +'/watch/providers?api_key=8d6d91941230817f7807d643736e8a49',
  216. onload: (resp) => {
  217.  
  218. let json = JSON.parse(resp.responseText);
  219. console.log('TMDB provder api: https://api.themoviedb.org/3/tv/'+ id +'/watch/providers?api_key=8d6d91941230817f7807d643736e8a49');
  220.  
  221. if (json && json.Error) {
  222. console.log("Error: " + json.Error);
  223. resolve("error"); return;
  224. }
  225.  
  226. let providers = [];
  227. for(let curr_country in json.results){
  228. if(String(curr_country)===my_country && json.results[curr_country].flatrate !== undefined){
  229. for(let provider of json.results[curr_country].flatrate){
  230. providers.push(
  231. {
  232. "provider_name" : provider.provider_name,
  233. "provider_logo" : provider.logo_path
  234. }
  235. );
  236. }
  237. }
  238. }
  239. if(providers.length !== 0 ){
  240. resolve(providers); return;
  241. }else{resolve("error"); return}
  242. }
  243. });
  244. });
  245. }
  246. }
  247.  
  248. function OMDB_title_api(IMDB_id,content) {
  249.  
  250. if (content==="movie" || content==="movie_cartoon" || content==="movie_anime"){
  251. return new Promise(function (resolve, reject) {
  252. GM_xmlhttpRequest({
  253. method: 'GET',
  254. responseType: 'json',
  255. synchronous: false,
  256. url: 'https://www.omdbapi.com/?apikey=75251a35&type=movie&i='+IMDB_id,
  257. onload: (resp) => {
  258.  
  259. let json = JSON.parse(resp.responseText);
  260. console.log('OMDB title api: https://www.omdbapi.com/?apikey=75251a35&type=movie&i='+IMDB_id);
  261.  
  262. if (json && json.Error) {
  263. console.log("Error: " + json.Error);
  264. resolve("error"); return;
  265. }
  266.  
  267. let IMDB_rating=0, IMDB_title=json.Title, IMDB_year = json.Year, Awards=0;
  268. for(let rating of json.Ratings){
  269. if(rating.Source==="Internet Movie Database") IMDB_rating= rating.Value;
  270. }
  271. if(json.Awards !== "N/A" && json.Awards !== undefined) Awards = json.Awards;
  272. resolve([IMDB_title,IMDB_year,IMDB_rating,Awards]); return;
  273.  
  274. }
  275. });
  276. });
  277.  
  278. }else if(content==="tv"|| content==="tv_cartoon" || content==="tv_anime"){
  279. return new Promise(function (resolve, reject) {
  280. GM_xmlhttpRequest({
  281. method: 'GET',
  282. responseType: 'json',
  283. synchronous: false,
  284. url: 'https://www.omdbapi.com/?apikey=75251a35&type=series&i='+IMDB_id,
  285. onload: (resp) => {
  286.  
  287. let json = JSON.parse(resp.responseText);
  288. console.log('OMDB title api: https://www.omdbapi.com/?apikey=75251a35&type=series&i='+IMDB_id);
  289.  
  290. if (json && json.Error) {
  291. console.log("Error: " + json.Error);
  292. resolve("error"); return;
  293. }
  294.  
  295. let IMDB_rating=0, IMDB_title=json.Title, IMDB_year = json.Year, Awards=0;
  296. for(let rating of json.Ratings){
  297. if(rating.Source==="Internet Movie Database") IMDB_rating= rating.Value;
  298. }
  299. if(json.Awards !== "N/A" && json.Awards !== undefined) Awards = json.Awards;
  300. resolve([IMDB_title,IMDB_year,IMDB_rating,Awards]); return;
  301.  
  302. }
  303. });
  304. });
  305. }
  306. }
  307.  
  308. function JIKAN_search_api(title,year,content) {
  309.  
  310. title=title.replaceAll(" ","%20"); // <---
  311. if (content==="movie_anime"){
  312. return new Promise(function (resolve, reject) {
  313. GM_xmlhttpRequest({
  314. method: 'GET',
  315. responseType: 'json',
  316. synchronous: false,
  317. url: 'https://api.jikan.moe/v3/search/anime?q='+title+'&page=1',
  318. onload: (resp) => {
  319.  
  320. let json = JSON.parse(resp.responseText);
  321. console.log('MAL search api: https://api.jikan.moe/v3/search/anime?q='+title+'&page=1');
  322.  
  323. if (json && json.Error) {
  324. console.log("Error: " + json.Error);
  325. resolve("error"); return;
  326. }
  327.  
  328. let MAL_url=0, MAL_title_name=0, MAL_score=0, MAL_image_url=0, content_type=0, episodes_count=0, start_date=0;
  329. for(let result of json.results){
  330. if(result.type!==null && result.start_date!==null &&
  331. (parseInt(result.start_date.slice(0,4))===parseInt(year) || parseInt(result.start_date.slice(0,4))===parseInt(year)-1 || parseInt(result.start_date.slice(0,4))===parseInt(year)-2) &&
  332. (result.type === "Movie" /*TV*/ || result.type === "ONA" || result.type === "OVA")){
  333.  
  334. if(result.url!== null) MAL_url = result.url;
  335. if(result.title!== null) MAL_title_name = result.title;
  336. if(result.score!== null) MAL_score = result.score;
  337. if(result.image_url!== null) MAL_image_url = result.image_url;
  338. if(result.type!== null) content_type = result.type;
  339. if(result.episodes!== null) episodes_count = result.episodes;
  340. if(result.start_date!== null) start_date = result.start_date.slice(0,4);
  341.  
  342. resolve([MAL_url, MAL_title_name, MAL_score, MAL_image_url, content_type, episodes_count, start_date]); return;
  343. }
  344. }
  345.  
  346. console.log("JIKAN [MAL]: Error, title not found");
  347. resolve("error"); return;
  348.  
  349.  
  350. }
  351. });
  352. });
  353.  
  354. }else if(content==="tv_anime"){
  355. return new Promise(function (resolve, reject) {
  356. GM_xmlhttpRequest({
  357. method: 'GET',
  358. responseType: 'json',
  359. synchronous: false,
  360. url: 'https://api.jikan.moe/v3/search/anime?q='+title+'&page=1',
  361. onload: (resp) => {
  362.  
  363. let json = JSON.parse(resp.responseText);
  364. console.log('MAL search api: https://api.jikan.moe/v3/search/anime?q='+title+'&page=1&limit=10');
  365.  
  366. if (json && json.Error) {
  367. console.log("Error: " + json.Error);
  368. resolve("error"); return;
  369. }
  370.  
  371. let MAL_url=0, MAL_title_name=0, MAL_score=0, MAL_image_url=0, content_type=0, episodes_count=0, start_date=0, end_date=0, date_range=0;
  372. for(let result of json.results){
  373. if(result.type!==null && result.start_date!==null &&
  374. (parseInt(result.start_date.slice(0,4))===parseInt(year) || parseInt(result.start_date.slice(0,4))===parseInt(year)-1 || parseInt(result.start_date.slice(0,4))===parseInt(year)-2) &&
  375. (result.type === "TV" || result.type === "ONA" || result.type === "OVA")){
  376.  
  377. if(result.url!== null) MAL_url = result.url;
  378. if(result.title!== null) MAL_title_name = result.title;
  379. if(result.score!== null) MAL_score = result.score;
  380. if(result.image_url!== null) MAL_image_url = result.image_url;
  381. if(result.type!== null) content_type = result.type;
  382. if(result.episodes!== null) episodes_count = result.episodes;
  383. if(result.start_date!== null) start_date = result.start_date.slice(0,4);
  384. if(result.end_date!== null) end_date = result.end_date.slice(2,4);
  385.  
  386. if(start_date!== 0 && end_date!== 0) date_range = start_date + "-" + end_date
  387.  
  388. resolve([MAL_url, MAL_title_name, MAL_score, MAL_image_url, content_type, episodes_count, date_range]); return;
  389. }
  390. }
  391.  
  392. console.log("JIKAN [MAL]: Error, title not found");
  393. resolve("error"); return;
  394.  
  395.  
  396. }
  397. });
  398. });
  399. }
  400. }
  401.  
  402.  
  403. function RT_search_api(title,year,content) {
  404.  
  405. title = title.replaceAll(".","").replaceAll(",","").replaceAll("&","").replaceAll("-","").replaceAll(":","");
  406. title = title.replaceAll(/Parte \d+/gm,"").replaceAll(/Part \d+/gm,"").replaceAll("The Movie","").replaceAll("Il film","").replaceAll("Il Film","");
  407. title = title.replace(/\s\s+/g, ' ').trim().replaceAll(" ", "%20");
  408.  
  409. if (content==="movie" || content==="movie_cartoon" || content==="movie_anime"){
  410. return new Promise(function (resolve, reject) {
  411. GM_xmlhttpRequest({
  412. method: 'GET',
  413. responseType: 'json',
  414. synchronous: false,
  415. url: 'https://www.rottentomatoes.com/api/private/v2.0/search/?limit=100&q='+ title +'&t=movie',
  416. onload: (resp) => {
  417.  
  418. let json = JSON.parse(resp.responseText);
  419. console.log('RT search api: https://www.rottentomatoes.com/api/private/v2.0/search/?limit=100&q='+ title +'&t=movie');
  420.  
  421. if (json && json.Error) {
  422. console.log("Error: " + json.Error);
  423. resolve("error"); return;
  424. }
  425.  
  426. if(json.movieCount === 0){
  427. console.log("Error: No movies found in RT");
  428. resolve("error"); return;
  429. }
  430.  
  431. let fresh_certificate=0, meterscore = 0, url=0;
  432. for(let movie of json.movies){
  433. if(parseInt(movie.year) === parseInt(year) || parseInt(movie.year) === parseInt(year)+1|| parseInt(movie.year) === parseInt(year) +2 || parseInt(movie.year) === parseInt(year)-1){ //fix rotten tomatoes errors
  434. if(movie.meterClass === "fresh" || movie.meterClass === "certified_fresh") fresh_certificate='fresh';
  435. if(movie.meterClass === "rotten") fresh_certificate='rotten';
  436. if(movie.meterScore !== "N/A" && movie.meterScore !== undefined) meterscore=movie.meterScore;
  437. url=movie.url;
  438. break;
  439. }
  440. }
  441.  
  442. if(url!==0) {resolve([url,meterscore,fresh_certificate]); return;} else{resolve("error"); return;}
  443. }
  444. });
  445. });
  446.  
  447. }else if(content==="tv" || content==="tv_cartoon" || content==="tv_anime"){
  448. return new Promise(function (resolve, reject) {
  449. GM_xmlhttpRequest({
  450. method: 'GET',
  451. responseType: 'json',
  452. synchronous: false,
  453. url: 'https://www.rottentomatoes.com/api/private/v2.0/search/?limit=100&q='+ title +'&t=tvSeries',
  454. onload: (resp) => {
  455.  
  456. let json = JSON.parse(resp.responseText);
  457. console.log('RT search api: https://www.rottentomatoes.com/api/private/v2.0/search/?limit=100&q='+ title +'&t=tvSeries');
  458.  
  459. if (json && json.Error) {
  460. console.log("Error: " + json.Error);
  461. resolve("error"); return;
  462. }
  463.  
  464. if(json.tvCount === 0){
  465. console.log("Error: No series found in RT");
  466. resolve("error"); return;
  467. }
  468.  
  469. let fresh_certificate=0, meterscore = 0, url=0;
  470. for(let title of json.tvSeries){
  471. if(parseInt(title.startYear) === parseInt(year) || parseInt(title.startYear) === parseInt(year) +1 || parseInt(title.startYear) === parseInt(year) +2 || parseInt(title.startYear) === parseInt(year)-1){ //fix rotten tomatoes errors
  472. if(title.meterClass === "fresh" || title.meterClass === "certified_fresh") fresh_certificate='fresh';
  473. if(title.meterClass === "rotten") fresh_certificate='rotten';
  474. if(title.meterScore !== "N/A" && title.meterScore !== undefined) meterscore=title.meterScore;
  475. url=title.url;
  476. break;
  477. }
  478. }
  479.  
  480. if(url!==0) {resolve([url,meterscore,fresh_certificate]); return;} else{resolve("error"); return;}
  481. }
  482. });
  483. });
  484. }
  485. }
  486.  
  487. function clean_title(title,content){ //clean special characters
  488. return new Promise(function (resolve, reject) {
  489. if(title!=="" && title!==undefined){
  490. let new_title,new_year;
  491.  
  492. //clean
  493. title=title.replaceAll("&", " ");
  494. title=title.replaceAll(":", " ");
  495. title=title.replaceAll(",", " ");
  496. title=title.replaceAll(".", " ");
  497. title=title.replaceAll(";", " ");
  498. title=title.replaceAll("–", "-");
  499. title=title.replaceAll(" 01 ", " 1 ");
  500. title=title.replaceAll(" 02 ", " 2 ");
  501. title=title.replaceAll(" 03 ", " 3 ");
  502. title=title.replaceAll(" 04 ", " 4 ");
  503. title=title.replaceAll(" 05 ", " 5 ");
  504. title=title.replaceAll(" 06 ", " 6 ");
  505. title=title.replaceAll(" 07 ", " 7 ");
  506. title=title.replaceAll(" 08 ", " 8 ");
  507. title=title.replaceAll(" 09 ", " 9 ");
  508. title=title.replaceAll(" OAV ", "");
  509. title=title.replaceAll("[PRE] ", "");
  510. title=title.replaceAll("[Pre] ", "");
  511. title=title.replaceAll("[pre] ", "");
  512. title=title.replaceAll("EXTENDED", " ");
  513. title=title.replaceAll("Director Cut", " ");
  514. title=title.replaceAll("Director's Cut", " ");
  515. title=title.replaceAll("The Movie", " ");
  516. title=title.replaceAll("the movie", " ");
  517. title=title.replaceAll("The movie", " ");
  518. title=title.replaceAll("the Movie", " ");
  519. title=title.replaceAll("THE MOVIE", " ");
  520. title=title.replaceAll("Movie", " ");
  521. title=title.replaceAll("MOVIE", " ");
  522. title=title.replaceAll("il film", " ");
  523. title=title.replaceAll("Il film", " ");
  524. title=title.replaceAll("il Film", " ");
  525. title=title.replaceAll("Il Film", " ");
  526. title=title.replaceAll("film", " ");
  527. title=title.replaceAll("Film", " ");
  528. title=title.replaceAll("FILM", " ");
  529. title=title.replaceAll("ep", " ");
  530. title=title.replaceAll("Ep", " ");
  531. title=title.replaceAll("EP", " ");
  532. title=title.trim();
  533.  
  534. //splitting
  535. if(content==="movie" || content==="movie_cartoon" || content==="movie_anime"){
  536. new_title=title.split("(")[0].trim();
  537. let title_length=title.split("(")[1].split(")")[0].length;
  538. new_year=title.split("(")[1].split(")")[0].slice(title_length-4, title_length).trim();
  539.  
  540. //double graph
  541. if(isNaN(new_year)){
  542. title_length=title.split("(")[2].split(")")[0].length;
  543. new_year=parseInt(title.split("(")[2].split(")")[0].slice(title_length-4, title_length).trim());
  544. }
  545.  
  546. //if(new_title.includes("-") && (content.includes("anime")) new_title = new_title.split("-")[0]; //double title problem (for movies, not anime)
  547. if(new_title.includes("-")) new_title=new_title.replaceAll("-", " "); //dash in the anime title (for anime movies)
  548.  
  549. }else if(content==="tv"|| content==="tv_cartoon" || content==="tv_anime"){
  550. new_title=title;
  551. if(content.includes("cartoon") && !title.includes("(") ){resolve("Error, title clened was empty"); return;}
  552.  
  553. if(title.includes("(")){
  554. new_title=title.split("(")[0];
  555. new_year=parseInt(title.split("(")[1].slice(0, 4));
  556. }
  557.  
  558. if(new_title.includes("-")) new_title = title.split("-")[0]; //double title problem
  559. if(new_title.includes("[")) new_title = title.split("[")[0]; //double title problem
  560.  
  561. //if there is a bracket before the year bracket
  562. if(isNaN(new_year) && title.includes("(")){
  563. new_year=parseInt(title.split("(")[2].slice(0, 4));
  564. }
  565.  
  566. }
  567.  
  568.  
  569. new_title=new_title.replace(/\s\s+/g, ' ').trim().replaceAll(" ", "%20"); //remove multiple espaces and encode all remaining spaces
  570.  
  571. resolve([new_title,new_year]); return;
  572. }else{resolve("Error, title clened was empty"); return;}
  573. })
  574. }
  575.  
  576. async function main(){
  577. //data variables
  578. let content=0, thread_title_year=0, country = "IT";
  579. let TMDB_info=0,TMDB_id=0, TMDB_title=0,TMDB_providers=0, TMDB_year=0, YT_trailer_url=0, Seasonscount=0;
  580. let OMDB_info=0, IMDB_id=0, IMDB_title=0,IMDB_year=0,IMDB_rating=0, Awards=0;;
  581. let RT_info=0, RT_rating=0, RT_cert=0, RT_url_delta=0;
  582. let MAL_info=0, MAL_url=0, MAL_title_name=0, MAL_score=0, MAL_image_url=0, MAL_content_type=0, MAL_episodes_count=0, MAL_date=0;
  583.  
  584. //content tagging
  585. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=440")) {content="movie"} //se siamo in FilmHD
  586. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=156")) {content="movie"} //se siamo in FilmHD DV-WEB
  587. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=99")) {content="movie"} //se siamo in FILM SD
  588. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=614")) {content="tv"} //se siamo in Serie HD
  589. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=324")) {content="tv"} //se siamo in Serie SD
  590. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=843")) {content="tv"} //se siamo in Serie HD SUB
  591. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=323")) {content="tv"} //se siamo in Serie SD SUB
  592. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=1945")) {content="tv"} //se siamo in Serie UHD
  593. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=1584")) {content="movie_cartoon"} //se siamo in Movie Cartoon HD
  594. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=1585")) {content="movie_cartoon"} //se siamo in Movie Cartoon SD
  595. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=748")) {content="tv_cartoon"} //se siamo in Serie Cartoon HD
  596. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=348")) {content="tv_cartoon"} //se siamo in Serie Cartoon SD
  597.  
  598. let blocks = document.getElementsByClassName("forumbg");
  599. for(let block of blocks){
  600.  
  601. console.log(block.getElementsByClassName("row bg1 announce"));
  602. console.log(block.getElementsByClassName("row bg1 sticky"));
  603.  
  604. if(block.getElementsByClassName("row bg1 global-announce").length!==0) {continue;}
  605. if(window.location.href.includes("https://ddunlimited.net/viewforum.php?f=156") && block.getElementsByClassName("row bg1 announce").length!==0) {continue;}
  606. if(!window.location.href.includes("https://ddunlimited.net/viewforum.php?f=156") && (block.getElementsByClassName("row bg1 announce").length!==0 || block.getElementsByClassName("row bg1 sticky").length!==0)) {continue;}
  607.  
  608. for (let thread of block.children[0].children[2].children){
  609. //Link & Label variables
  610. let TMDB_link = document.createElement("a"), IMDB_link = document.createElement("a"), RT_link = document.createElement("a"), AWARDS_link = document.createElement("a"), Seasons_label = document.createElement("label"), MAL_link= document.createElement("a"), YT_link = document.createElement("a");
  611. TMDB_link.style.marginRight = '4px'; IMDB_link.style.marginLeft = '4px'; RT_link.style.marginLeft = '4px', AWARDS_link.style.marginLeft="4px", YT_link.style.marginRight = "4px", MAL_link.style.marginLeft = "4px", Seasons_label.style.marginLeft = "4px";
  612. TMDB_link.style.color = 'deepskyblue'; IMDB_link.style.color = 'gold'; RT_link.style.color = 'orangered', AWARDS_link.style.color="goldenrod", AWARDS_link.style.fontSize = "70%", MAL_link.style.color="royalblue", Seasons_label.style.color = "salmon";
  613. //Images variables
  614. let TMDB_img = document.createElement('img'),IMDB_img = document.createElement('img'), RT_img = document.createElement('img'), RT_fresh_img = document.createElement('img'), RT_rotten_img = document.createElement('img'), AWARDS_img=document.createElement('img'), MAL_img=document.createElement('img'), YT_img=document.createElement('img'), POSTER_img=document.createElement('img');
  615. IMDB_img.style.marginLeft = '8px'; MAL_img.style.marginLeft = '8px';MAL_img.style.borderRadius = '3px'; IMDB_img.style.borderRadius = '3px'; RT_img.style.marginLeft = '8px'; RT_rotten_img.style.marginLeft = '8px'; RT_fresh_img.style.marginLeft = '8px'; AWARDS_img.style.marginLeft = '8px';
  616. AWARDS_img.style.height='16px'; AWARDS_img.style.width='16px'; RT_img.style.height='16px'; RT_img.style.width='16px'; RT_fresh_img.style.height='16px'; RT_fresh_img.style.width='16px'; RT_rotten_img.style.height='16px'; RT_rotten_img.style.width='16px'; POSTER_img.style.width = '46px'; POSTER_img.style.height = '69px';
  617. TMDB_img.src= 'https://www.google.com/s2/favicons?domain=www.themoviedb.org';
  618. IMDB_img.src= 'https://www.google.com/s2/favicons?domain=www.imdb.com';
  619. RT_img.src= 'https://i.postimg.cc/RCkVnKrp/rotten-tomatoes-rating-icons-1.png'; RT_fresh_img.src= 'https://i.postimg.cc/T1RcJQfC/fresh.png'; RT_rotten_img.src= 'https://i.postimg.cc/fbq3rKc8/rotten.png';
  620. MAL_img.src= 'https://www.google.com/s2/favicons?domain=myanimelist.net';
  621. AWARDS_img.src = 'https://i.postimg.cc/bNZkqQx6/Oscars-logo.png';
  622. YT_img.src = 'https://www.google.com/s2/favicons?domain=www.youtube.com';
  623.  
  624. //get title from thread
  625. let thread_full_label=thread.children[0].children[0].children[0].children[0].children[0].children[0].innerText;
  626. thread_title_year = await clean_title(thread_full_label,content);
  627.  
  628. if(thread_title_year.includes("Error")){ console.log(thread_title_year); TMDB_id="error";}
  629.  
  630. let thread_title=thread_title_year[0], thread_year=thread_title_year[1];
  631. console.log([thread_title.replaceAll("%20", " "), thread_year]);
  632.  
  633. //get imdb ID & tmdb score from TMDB api
  634. if(TMDB_id!=="error") TMDB_id = await TMDB_search_api(thread_title, thread_year,content);
  635. console.log('TMDB id: ' + TMDB_id);
  636. if(TMDB_id!=="error"){
  637. // TMDB title info
  638. TMDB_info = await TMDB_title_api(TMDB_id,content,country);
  639. if(TMDB_info!=="error") IMDB_id = TMDB_info[0];
  640. if(TMDB_info!=="error" && TMDB_info[1]!==0) TMDB_title = TMDB_info[1];
  641. if(TMDB_info!=="error" && TMDB_info[2]!==0) TMDB_year = TMDB_info[2];
  642. if(TMDB_info!=="error" && TMDB_info[3]!==0) POSTER_img.src= 'https://image.tmdb.org/t/p/w185' + TMDB_info[3];
  643. if(TMDB_info!=="error" && TMDB_info[4]!==0 && TMDB_info[4]!==0){ YT_trailer_url = " https://www.youtube.com/watch?v=" + TMDB_info[4]; }else {YT_trailer_url= 'https://www.youtube.com/results?search_query=' + TMDB_title + ' trailer ita';}
  644. if(content==="tv" && TMDB_info[5]!==0 && TMDB_info[6]!==0) Seasonscount= "{" + TMDB_info[6] +"}{S"+ TMDB_info[5]+"}";
  645. console.log('IMDB id: ' + IMDB_id);
  646.  
  647. // TMDB proviers list
  648. TMDB_providers = await TMDB_providers_api(TMDB_id,country,content);
  649. }else{console.log("Skipping for error: " + thread_title.replaceAll("%20"," ") + " (" + thread_year + ")") ;}
  650.  
  651.  
  652. if(TMDB_id !== 'error' && TMDB_id!==0){
  653.  
  654. //get IMDB title, rating, awards
  655. OMDB_info = await OMDB_title_api(IMDB_id,content);
  656. if(OMDB_info !== 'error'){
  657. IMDB_title = OMDB_info[0].replaceAll(" ", "%20");
  658. IMDB_year = OMDB_info[1];
  659. IMDB_rating = OMDB_info[2];
  660. //build awards string
  661. let awards_string = String(OMDB_info[3]).replaceAll("total","").trim();
  662. if (awards_string[awards_string.length-1]===".") awards_string=awards_string.substring(0, awards_string.length-1); // remove final dot from awards string
  663. if(OMDB_info[3]!==0) Awards = "(" + awards_string + ")";
  664. }
  665.  
  666. //get RT url, score, certificate
  667. //RT_info = await RT_search_api(TMDB_title,TMDB_year,content);
  668. if(RT_info !== 'error' && RT_info!==0){
  669. RT_url_delta = RT_info[0];
  670. RT_rating = RT_info[1];
  671. RT_cert = RT_info[2];
  672. }
  673. console.log('IMDB score: ' + IMDB_rating + ' | RT score: '+RT_rating + ' (' + RT_cert +') | Awards: '+ Awards);
  674.  
  675. let thread_row = thread.children[0].children[0].children[0].children[0].children[0].children[0];
  676. let thread_block = thread.children[0].children[0].children[0].children[0];
  677. if(String(thread_row.children[0].href).includes("unread")) thread_row.removeChild(thread_row.children[0]);
  678.  
  679. //get MAL url, score, certificate
  680. /*
  681. if(content.includes("anime")) MAL_info = await JIKAN_search_api(IMDB_title,TMDB_year,content);
  682. if(MAL_info !== 'error' && MAL_info!==0){
  683. MAL_url=MAL_info[0];
  684. MAL_title_name=MAL_info[1];
  685. MAL_score=MAL_info[2];
  686. MAL_image_url=MAL_info[3];
  687. MAL_content_type=MAL_info[4];
  688. MAL_episodes_count=MAL_info[5];
  689. MAL_date=MAL_info[6];
  690. }
  691. console.log('MAL url: ' + MAL_url + ' | MAL score: '+ MAL_score );
  692. */
  693.  
  694.  
  695. //Poster image
  696. if(TMDB_id !==0 && TMDB_id!=="error"){
  697. if(POSTER_img.src !== ""){
  698. thread.children[0].className="search-project";
  699. thread.children[0].style.cssText="";
  700. let dd=document.createElement("dd");
  701. dd.append(POSTER_img);
  702. thread.children[0].children[0].before(dd);
  703. }else{
  704. thread.children[0].className="search-project";
  705. thread.children[0].style.cssText="";
  706. let label_img = document.createElement('label');
  707. label_img.innerText = "Missing";
  708. label_img.style.color = "firebrick";
  709. let dd=document.createElement("dd");
  710. dd.append(label_img);
  711. thread.children[0].children[0].before(dd);
  712. }
  713. }
  714.  
  715. //YT Link
  716. if(TMDB_title !==0){
  717. YT_link.href = YT_trailer_url;
  718. YT_link.append(YT_img);
  719. thread_row.firstChild.before(YT_link);
  720. }
  721. //TMDB Link
  722. if(TMDB_id !==0 && TMDB_id!=="error"){
  723. if(content==="movie" || content==="movie_cartoon"|| content==="movie_anime") TMDB_link.href = 'https://www.themoviedb.org/movie/' + TMDB_id;
  724. if(content==="tv" || content==="tv_cartoon"|| content==="serie_anime") TMDB_link.href = 'https://www.themoviedb.org/tv/' + TMDB_id;
  725. TMDB_link.append(TMDB_img);
  726. thread_row.firstChild.before(TMDB_link);
  727. }
  728. //Season Count
  729. if(content==="tv" && Seasonscount!==0){
  730. Seasons_label.innerText=Seasonscount;
  731. thread_row.append(Seasons_label);
  732. }
  733. //IMDB Link
  734. if(OMDB_info!=='error' && OMDB_info!==0){
  735. if(IMDB_rating!==0) {IMDB_link.innerText = IMDB_rating.substring(0, IMDB_rating.length - 3);} else {IMDB_link.innerText="N/A"}
  736. IMDB_link.href = `https://www.imdb.com/title/${IMDB_id}/`;
  737. thread_row.append(IMDB_img,IMDB_link);
  738. }
  739. //MAL Link
  740. /*
  741. if(MAL_info!=='error' && MAL_info!==0){
  742. if(MAL_score!==0) {MAL_link.innerText = MAL_score;} else {MAL_link.innerText="N/A"}
  743. MAL_link.href = MAL_url;
  744. thread.children[0].children[2].append(MAL_img, MAL_link);
  745. }*/
  746. //RT Link
  747. if(RT_info!=='error' && RT_info!==0){
  748. if(RT_rating!==0) {RT_link.innerText = RT_rating;} else {RT_link.innerText ="N/A";}
  749. RT_link.href = `https://www.rottentomatoes.com${RT_url_delta}/`;
  750. if(RT_cert===0) {thread_row.append(RT_img,RT_link);}
  751. if(RT_cert==='fresh') {thread_row.append(RT_fresh_img,RT_link);}
  752. if(RT_cert==='rotten') {RT_link.style.color="yellowgreen"; thread_row.append(RT_rotten_img,RT_link);}
  753. }
  754. //Awards
  755. if(Awards!==0){
  756. AWARDS_link.innerText = Awards;
  757. AWARDS_link.href = "https://www.imdb.com/title/"+IMDB_id+"/awards/"
  758. thread_row.append(AWARDS_img,AWARDS_link);
  759. }
  760. //providers
  761. if(TMDB_providers !== "error"){
  762. let tr = document.createElement('div');
  763.  
  764. let streaming_link = document.createElement('a');
  765. if(content==="movie" || content==="movie_cartoon"|| content==="movie_anime") streaming_link.href="https://www.themoviedb.org/movie/"+ TMDB_id+"/watch?locale="+country;
  766. if(content==="tv" || content==="tv_cartoon"|| content==="serie_anime") streaming_link.href="https://www.themoviedb.org/tv/"+ TMDB_id+"/watch?locale="+country
  767. streaming_link.innerText = "Streaming:"
  768. streaming_link.style.color = "salmon";
  769. tr.append(streaming_link);
  770.  
  771. for(let provider of TMDB_providers){
  772. let provider_image = document.createElement('img');
  773. provider_image.style.height='16px';
  774. provider_image.style.width='16px';
  775. provider_image.style.marginLeft = '8px';
  776. provider_image.style.marginTop = '4px';
  777. //provider_image.style.marginBottom = '8px';
  778. provider_image.style.borderRadius = '3px';
  779. provider_image.src = 'https://image.tmdb.org/t/p/w185/' + provider["provider_logo"];
  780. tr.append(provider_image);
  781. }
  782. thread_block.append(tr);
  783. }
  784.  
  785.  
  786. }else{ //if no content found in TMDB
  787. let thread_row = thread.children[0].children[0].children[0].children[0].children[0].children[0];
  788. if(String(thread_row.children[0].href).includes("unread")) thread_row.removeChild(thread_row.children[0]);
  789.  
  790. let error_message = document.createElement("label");
  791. error_message.style.color="firebrick";
  792. error_message.style.marginLeft = '4px';
  793. error_message.innerText = "ERR: Title Misspelled/Not Found"
  794. thread_row.append(error_message);
  795. }
  796.  
  797. //reset all data
  798. thread_title_year=0; OMDB_info=0; RT_info=0; TMDB_id=0; IMDB_id=0; IMDB_title=0; IMDB_year=0; RT_url_delta=0; IMDB_rating=0; RT_rating=0; RT_cert=0; Awards=0, Seasonscount=0;
  799. }
  800.  
  801. }
  802.  
  803. //loop titles
  804.  
  805.  
  806.  
  807.  
  808. }
  809.  
  810. main();