Advertisement
usamimi2323

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

Nov 10th, 2024 (edited)
133
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 9.65 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. // タイトル比較の前処理
  79. function tN(str)
  80. //function  truncateName(str)
  81. {
  82.     return str
  83.         .replace(/\[[^\]]+\]/g,'')                          // 括弧で括られた文字列除去
  84.         .replace(/\([^\)]+\)/g, '')                         // 括弧で括られた文字列除去
  85.         .replace(/【[^】]+】/g,'')                           // 括弧で括られた文字列除去
  86.         .replace(/~[^~]+~/,'')                            // サブタイトル除去
  87.         .replace(/~([^ \d\.]+\b)( [^ \d\.]+\b)*/,'')      // サブタイトル除去
  88.         .replace(/\b([-ー―-])[^\d\.]+\1\b/,'')         // サブタイトル除去
  89.         .replace('[@@]COMIC +','')                            // 不要文字列除去
  90.         .replace(/\b0+(\d+)\b/g, '$1')                      // 0パディング除去
  91.         .replace(/第(\d+([-+,_ ]\d+)*)巻/,'$1')               // 数字と間の記号のみに修正
  92.         .replace(/全(\d+)巻/,'1-$1')                      // 数字と間の記号のみに修正
  93.         .replace(/\bzen(\d+)/,'1-$1')                       // 数字と間の記号のみに修正
  94.         .replace(/\bv(\d+)/g,'$1')                          // 数字と間の記号のみに修正
  95.         .replace(/\u0073hit|ra\u0070e/gi, '')               // turbobit用NGワード除去
  96.         .replace(/×/g,'x')                                 // 作者名結合文字×をxに変更(タイポでxとなっていることがよくあるため、そちらに統一)
  97.         .replace(/[_  ]/g,'')                             // 区切り文字除去(除去するタイミングは最後近くで)
  98.         .replace(/([!?#$%&+@、。!?#$%&+@、。])/g,'')    // 不要記号除去
  99. }
  100.  
  101.  
  102. function isAutoCreatedFolderName(n)
  103. {
  104.     return n=='様々なファイル'||n=='任意'||n=='Folder'||n=='永続オフライン'||n=='オフラインファイル'
  105. }
  106. function getFileParts(f)
  107. {
  108.     const r = (f||'').match(/^(.+)(\.part\d+|\.mp3|\.zip|\.rar|\.tar|\.epub)?(\.[\da-z]{2,6})$/i);
  109.     return (r && !/^\d+$/.test(r[3]))?[r[1]||'',r[2]||'',r[3]||'']:[f||'','',''];
  110. }
  111. function getFileSpec(f){return (getFileParts(f))[0]}
  112. function getFileSpecFull(f){const x=getFileParts(f);return x[0]+x[1];}
  113. function getExt(f){return (getFileParts())[2]}
  114. function getExtFull(f){const x=getFileParts(f);return x[1]+x[2];}
  115.  
  116. function comicNumbering(str)
  117. {
  118.     return (isNaN(str)||str.length==2)?str:(str.length==1)?('0'+str):str.replace(/^0+(\d\d)$/,'$1');
  119. }
  120. function replaceNums(str)
  121. {
  122.     return str.replace(/\d+/g,function(x){return comicNumbering(x);})
  123. }
  124. function K(k){return Object.keys(k)}
  125.  
  126.  
  127.  
  128. function mergePackagesWithSameTitle_for_crawledLink(c_link)
  129. {
  130.     // 開始時に少し待機、JD自体が重い時のエラー予防
  131.     const interval = 1*100;
  132.     var limitcount = 50;
  133.     while(limitcount-- > 0)
  134.         if (sleep(interval) || c_link.package && c_link.package.name)
  135.             break;
  136.     if (c_link.package===null || c_link.package.name===null)
  137.         return;
  138.    
  139.     const crawledLink_name_crafted  = tN(getFileSpec(c_link.name));
  140.    
  141.     var i=0;
  142.     var UUIDs = [], matched_names = [];
  143.    
  144.     //
  145.     // 新規リンクの名前とマッチしたリンクのUUIDを取得
  146.     // マッチしたパッケージ名とリンク名を取得
  147.     //
  148.     getAllCrawledPackages().forEach(function(p)
  149.     {
  150.         // 自動作成されたパッケージでは個々のリンク名を比較
  151.         if (isAutoCreatedFolderName(p.name))
  152.             p.downloadLinks.forEach(function(l)
  153.             {
  154.                 if (isTargetFileExt(l.name)
  155.                     && crawledLink_name_crafted == tN(getFileSpec(l.name)))
  156.                     matched_names.push(getFileSpec(l.name)),
  157.                     UUIDs.push(l.UUID)
  158.             });
  159.         // 自動作成されたパッケージでなければパッケージ名を比較
  160.         else if (crawledLink_name_crafted == tN(p.name))
  161.             // 指定拡張子以外のリンクが含まれていれば除外
  162.             if (! p.downloadLinks.some(function(l){return !isTargetFileExt(l.name)}))
  163.                 matched_names.push(p.name),
  164.                 UUIDs = UUIDs.concat(p.downloadLinks.map(function(l){return l.UUID}));
  165.     });
  166.     // マッチしたものが2つ以上なければ終了
  167.     if ((matched_names.length) <= 1)
  168.         return;
  169.    
  170.     var final_package_name = '';
  171.     // パッケージ名取得のため、まずDLの方からマッチング
  172.     if (!getAllFilePackages().some(
  173.         function(p){return (crawledLink_name_crafted == tN(p.name)) && (final_package_name = p.name)}))
  174.     {
  175.         // DLの方に無い場合
  176.        
  177.         var final_author = '', final_category = '';
  178.         var authors = {}, categorys = {};
  179.        
  180.         function incKey(o,k){k in o?o[k]++:(o[k]=1)};
  181.         function setCategoryAndAuthor(name_str, category_dict, author_dict)
  182.         {
  183.             var r = name_str.match(/^(?:\(([^\)]+)\) *)?(?:\[([^\]]+)\] *)?/)
  184.             if (!r) return;
  185.             r[1] && incKey(category_dict,r[1]);
  186.             r[2] && incKey(author_dict,  r[2]);
  187.         }
  188.        
  189.         matched_names.forEach(function(n){setCategoryAndAuthor(n,categorys,authors)});
  190.        
  191.         // 採用する作者名を取得
  192.         // 英数のみ以外がある場合、英数のみのものは除外
  193.         if (K(authors).length)
  194.         {
  195. //          var tmp1 = K(authors).sort(function(a,b){return authors[b]-authors[a]});    // 該当数順
  196.             var tmp1 = K(authors).sort(function(a,b){return b.length - a.length});      // 作者名の長さ順
  197.             var tmp2 = tmp1.filter(function(k){return ! /^[- _\.a-z\d]+$/i.test(k)});
  198.             if (tmp2.length)
  199.             {
  200.                 final_author = tmp2[0];
  201.                 // 除外すべき英数のみ作者名の名前がある
  202.                 if (tmp1.length != tmp2.length)
  203.                     matched_names = matched_names.filter(function(n){
  204.                         return ! /^(?:\([^\)]+\) *)?\[[- _\.a-z\d]+\]/i.test(n)});
  205.             }
  206.             else
  207.                 final_author = tmp1[0];
  208.         }
  209.         if (K(categorys).length)
  210.             category_list.some(function(c){return (c in categorys) && (final_category = c)});
  211.        
  212.         // パッケージ名を選出
  213.         // "(category) [authors] title..."
  214.         // "[authors] title..."
  215.         var final_package_names = matched_names.filter(function(n){return /^\(([^\)]+)\) \[([^\]]+)\] .+/.test(n)})
  216.                             || matched_names.filter(function(n){return /^\[([^\]]+)\] .+/.test(n)});
  217.         if (0==final_package_names.length) return;//***
  218.        
  219.         final_package_name = final_package_names[0];
  220.         if (final_author)
  221.             final_package_name = final_package_name.replace(/^(\([^\)]+\))? *\[[^\]]+\] */,
  222.                 function(m,m1){return (m1?(m1+' '):'')+'['+ final_author+'] '});
  223.         if (final_category)
  224.             final_package_name = final_package_name.replace(/^(\([^\)]+\))? */, '('+final_category+') ');
  225.     }
  226.    
  227.     callAPI('linkgrabberv2', 'movetoNewPackage', UUIDs, null, final_package_name, null);
  228. }
  229.  
  230. function waitForLinkCrawling(timeout_msec)
  231. {
  232.     const polling_interval = 100;
  233.     const timeout_min = polling_interval;
  234.     const timeout_max = 5*60*1000;
  235.     timeout_msec || (timeout_msec = timeout_max);
  236.     var trycount = Math.max(Math.min(timeout_msec,timeout_max),timeout_min)
  237.                     /polling_interval;
  238.     while(trycount-- > 0)
  239.     {
  240.         if (! callAPI("linkcrawler","isCrawling")
  241.             && ! callAPI("linkgrabberv2","isCollecting"))
  242.             return true;
  243.         sleep(polling_interval);
  244.     }
  245.     return false;
  246. }
  247.  
  248.  
  249.  
  250. disablePermissionChecks();
  251.  
  252. if (isTargetFileExt(crawledLink.name))
  253. {
  254.     // 取得できるjobがnullなので、jobが終えたかを個別で検知できない
  255.     waitForLinkCrawling();
  256.    
  257.     const lock_key = "JD2.similar_title.lock";
  258.     var glock = getModifyLock(lock_key);
  259.     glock.writeLock();
  260.     try {
  261.         mergePackagesWithSameTitle_for_crawledLink(crawledLink);
  262.     }
  263.     finally
  264.     {
  265.         glock.writeUnlock();
  266.         glock = null;
  267.     }
  268. }
  269.  
  270.  
  271.  
Advertisement
Comments
Add Comment
Please, Sign In to add comment
Advertisement