Advertisement
usamimi2323

JDownloader2 EventScript - 新規リンク登録時に同一タイトルでグループ化するスクリプト

Nov 10th, 2024 (edited)
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 8.55 KB | Source Code | 0 0
  1. //
  2. // JDownloader2 EventScript - 新規リンク登録時に同一タイトルでグループ化するスクリプト
  3. //
  4. // 【概要】
  5. //
  6. // 新規リンク登録時に名前の文字列内にある括弧を無視して
  7. // グループ化してパッケージに移動する
  8. //
  9. // 【説明】
  10. //
  11. // JDにURLを登録する際、カテゴリや作者名が違ったり無かったりすれば、
  12. // 同じタイトルであってもグループ化されず、別のパッケージに登録される。
  13. //
  14. // このスクリプトでは、リンクやパッケージの名前の()内、[]内を無視し
  15. // 他の部分が一致すれば一つのパッケージにグループ化します。
  16. // (カテゴリ名や作者名を無視する)
  17. //
  18. // 書庫ファイルや電子書籍ファイル、動画ファイルのみグループ化します
  19. // (zip,rar,cbz,cbr,pdf,epub,azw3,mp4,mkv,webm,avi,wmv)
  20. //
  21. // ※JDに登録する際に、常に命名規則に則った
  22. //  名前付けをしていることが前提
  23. //
  24. //  例:"(カテゴリ) [作者名] タイトル... .rar"
  25. //
  26. // ※意図しない動作になった場合を考え
  27. //  このスクリプトではリンク名のリネームは行わない
  28. //  パッケージ名変更とリンクの移動のみ行います
  29. //
  30. //
  31. // 【使い方】
  32. //
  33. // 『Synchronous execution of script』 OFF
  34. //   Synchronous(同期)をオフ、
  35. //   !!!非同期にしておかないとイベント時にJDが固まる!!!
  36. //
  37. // 『Trigger』 A new link has been added (ON_NEW_LINK)
  38. //
  39. //
  40.  
  41. /*
  42.  
  43. 新規に追加されたリンクの名前に基づいて
  44. 既存のパッケージ名、もしくはリンク名(※)の
  45. タイトル部分が同一であれば
  46. それらを含めてグループ化、つまり一つのパッケージにまとめる
  47.  
  48. 最終パッケージ名
  49. 作者名(英数のみ)よりも作者名(英数以外含む)を優先して採用
  50. カテゴリはパッケージとリンクの名前から列挙し
  51. 優先順位に従って採用(category_listのリスト昇順)
  52.  
  53.  
  54. ※ 既存のリンクが対象となるのは
  55.   自動生成されたパッケージ内のリンクのみ
  56.  
  57. */
  58.  
  59. const category_list = [
  60.     '18禁アニメ',
  61.     '同人アニメ',
  62.     '同人CG集',
  63.     '同人誌',
  64.     '成年コミック',
  65.     '一般小説',
  66.     '一般コミック・少女',
  67.     '一般コミック',
  68.     '一般書籍'
  69. ];
  70.  
  71. ///////////////////////////////////////////////////////////////////////////
  72.  
  73. function isTargetFileExt(n)
  74. {
  75.     return /(?:^[^\.]+$)|(?:\.(?:rar|zip|7z|cbz|cbr|pdf|epub|azw3|mp4|mkv|webm|avi|wmv)$)/i.test(n);
  76. }
  77.  
  78. function isAutoCreatedFolderName(n)
  79. {
  80.     return n=='様々なファイル'||n=='任意'||n=='Folder'||n=='永続オフライン'||n=='オフラインファイル'
  81. }
  82. function getFileParts(f)
  83. {
  84.     var r = f.match(/^(.+)(\.part\d+|\.mp3|\.zip|\.rar|\.tar|\.epub)?(\.[\da-z]{2,6})$/i);
  85.     return r?[r[1]||'',r[2]||'',r[3]||'']:[f,'',''];
  86. }
  87. function getFileSpec(f){return (getFileParts(f))[0]}
  88. function getFileSpecFull(f){const x=getFileParts(f);return x[0]+x[1];}
  89. function getExt(f){return (getFileParts())[2]}
  90. function getExtFull(f){const x=getFileParts(f);return x[1]+x[2];}
  91.  
  92. function comicNumbering(str)
  93. {
  94.     return (isNaN(str)||str.length==2)?str:(str.length==1)?('0'+str):str.replace(/^0+(\d\d)$/,'$1');
  95. }
  96. function replaceNums(str)
  97. {
  98.     return str.replace(/\d+/g,function(x){return comicNumbering(x);})
  99. }
  100. function K(k){return Object.keys(k)}
  101.  
  102.  
  103. //function  truncateName(str)
  104. function  tN(str)
  105. {
  106.     return str
  107.         .replace(/\[[^\]]+\]/g,'')
  108.         .replace(/\([^\)]+\)/g, '')
  109.         .replace(/【[^】]+】/g,'')
  110.         .replace(/~[^~]+~/,'')
  111.         .replace(/~([^ \d\.]+\b)( [^ \d\.]+\b)*/,'')
  112.         .replace(/\b([-ー―-])[^\d\.]+\1\b/,'')
  113.         .replace('[@@]COMIC ','')
  114.         .replace(/全(\d+)巻/,function(m,m1){return '第01-'+comicNumbering(m1)+'巻'})
  115. //      .replace(/zen(\d+)/,function(m,m1){return (m1.length==1?m1:'01-'+comicNumbering(m1))})
  116. //      .replace(/\bv(\d+)/,'$1')
  117.         .replace(/\u0073hit|ra\u0070e/gi, '')       //for turbobit
  118.         .replace(/[_ ]/g,'')
  119.         .replace(/×/g,'x')
  120.         .replace(/([!?#$%&+@、。!?#$%&+@、。])/g,'')
  121. }
  122.  
  123. function mergePackagesWithSameTitle_for_crawledLink(c_link)
  124. {
  125.     // 開始時に少し待機、JD自体が重い時のエラー予防
  126.     const interval = 1*100;
  127.     var limitcount = 50;
  128.     while(limitcount-- > 0)
  129.         if (sleep(interval) || c_link.package && c_link.package.name)
  130.             break;
  131.     if (c_link.package===null || c_link.package.name===null)
  132.         return;
  133.    
  134.     const crawledLink_name_crafted  = tN(getFileSpec(c_link.name));
  135.    
  136.     var i=0;
  137.     var UUIDs = [], matched_names = [];
  138.    
  139.     //
  140.     // 新規リンクの名前とマッチしたリンクのUUIDを取得
  141.     // マッチしたパッケージ名とリンク名を取得
  142.     //
  143.     getAllCrawledPackages().forEach(function(p)
  144.     {
  145.         // 自動作成されたパッケージでは個々のリンク名を比較
  146.         if (isAutoCreatedFolderName(p.name))
  147.             p.downloadLinks.forEach(function(l)
  148.             {
  149.                 if (isTargetFileExt(l.name)
  150.                     && crawledLink_name_crafted == tN(getFileSpec(l.name)))
  151.                     matched_names.push(getFileSpec(l.name)),
  152.                     UUIDs.push(l.UUID)
  153.             });
  154.         // 自動作成されたパッケージでなければパッケージ名を比較
  155.         else if (crawledLink_name_crafted == tN(p.name))
  156.             // 指定拡張子以外のリンクが含まれていれば除外
  157.             if (! p.downloadLinks.some(function(l){return !isTargetFileExt(l.name)}))
  158.                 matched_names.push(p.name),
  159.                 UUIDs = Array.prototype.concat(UUIDs, p.downloadLinks.map(function(l){return l.UUID}));
  160.     });
  161.     // マッチしたものが2つ以上なければ終了
  162.     if ((matched_names.length) <= 1)
  163.         return;
  164.    
  165.     var final_author = '', final_category = '';
  166.     var authors = {}, categorys = {};
  167.    
  168.     function incKey(o,k){k in o?o[k]++:(o[k]=1)};
  169.     function setCategoryAndAuthor(name_str, category_dict, author_dict)
  170.     {
  171.         var r = name_str.match(/^(?:\(([^\)]+)\) *)?(?:\[([^\]]+)\] *)?/)
  172.         if (!r) return;
  173.         r[1] && incKey(category_dict,r[1]);
  174.         r[2] && incKey(author_dict,  r[2]);
  175.     }
  176.    
  177.     matched_names.forEach(function(n){setCategoryAndAuthor(n,categorys,authors)});
  178.  
  179.     // 採用する作者名を取得
  180.     // 英数のみ以外がある場合、英数のみのものは除外
  181.     if (K(authors).length)
  182.     {
  183. //      var tmp1 = K(authors).sort(function(a,b){return authors[b]-authors[a]});    // 該当数順
  184.         var tmp1 = K(authors).sort(function(a,b){return b.length - a.length});      // 作者名の長さ順
  185.         var tmp2 = tmp1.filter(function(k){return ! /^[- _\.a-z\d]+$/i.test(k)});
  186.         if (tmp2.length)
  187.         {
  188.             final_author = tmp2[0];
  189.             // 除外すべき英数のみ作者名の名前がある
  190.             if (tmp1.length != tmp2.length)
  191.                 matched_names = matched_names.filter(function(n){
  192.                     return ! /^(?:\([^\)]+\) *)?\[[- _\.a-z\d]+\]/i.test(n)});
  193.         }
  194.         else
  195.             final_author = tmp1[0];
  196.     }
  197.     if (K(categorys).length)
  198.         category_list.some(function(c){return (c in categorys) && (final_category = c)});
  199.    
  200.     // パッケージ名を選出
  201.     // "(category) [authors] title..."
  202.     // "[authors] title..."
  203.     var dest_package_names = matched_names.filter(function(n){return /^\(([^\)]+)\) \[([^\]]+)\] .+/.test(n)})
  204.                         || matched_names.filter(function(n){return /^\[([^\]]+)\] .+/.test(n)});
  205.     if (0==dest_package_names.length) return;//***
  206.     var dest_package_name = dest_package_names[0];
  207.     if (final_author)
  208.         dest_package_name = dest_package_name.replace(/^(\([^\)]+\))? *\[[^\]]+\] */,
  209.             function(m,m1){return (m1?(m1+' '):'')+'['+ final_author+'] '});
  210.     if (final_category)
  211.         dest_package_name = dest_package_name.replace(/^(\([^\)]+\))? */, '('+final_category+') ');
  212.    
  213.     callAPI('linkgrabberv2', 'movetoNewPackage', UUIDs, null, dest_package_name, null);
  214. }
  215.  
  216. function waitForLinkCrawling(timeout_msec)
  217. {
  218.     const polling_interval = 100;
  219.     const timeout_min = polling_interval;
  220.     const timeout_max = 5*60*1000;
  221.     timeout_msec || (timeout_msec = timeout_max);
  222.     var trycount = Math.max(Math.min(timeout_msec,timeout_max),timeout_min)
  223.                     /polling_interval;
  224.     while(trycount-- > 0)
  225.         if (! callAPI("linkcrawler","isCrawling")
  226.             && ! callAPI("linkgrabberv2","isCollecting"))
  227.             return true;
  228.     return false;
  229. }
  230.  
  231.  
  232.  
  233. disablePermissionChecks();
  234.  
  235. if (isTargetFileExt(crawledLink.name))
  236. {
  237.     // 取得できるjobがnullなので、jobが終えたかを個別で検知できない
  238.     waitForLinkCrawling();
  239.    
  240.     const lock_key = "JD2.similar_title.lock";
  241.     var glock = getModifyLock(lock_key);
  242.     glock.writeLock();
  243.     try {
  244.         mergePackagesWithSameTitle_for_crawledLink(crawledLink);
  245.     }
  246.     finally
  247.     {
  248.         glock.writeUnlock();
  249.         glock = null;
  250.     }
  251. }
  252.  
  253.  
  254.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement