fork download
  1.  
  2. // スレッド内の表示されているすべてのレスに含まれる、キャッシュ済みの画像を保存します。
  3. // 同じリンクが複数あった場合もすべて保存します。
  4. // レス表示: ${SCRIPT:Frw} SaveImages.js
  5.  
  6. var options = {
  7. // 保存先のディレクトリを指定
  8. // 空文字列の場合は、<v2c.saveDir>/userdata/imagesに保存されます。
  9. saveDirectory: "",
  10. // {0}: レス番号, {1}: レス内の画像index, {2}: 画像のファイル名
  11. fileNameFormatString: "{0}_{1}_{2}"
  12. };
  13.  
  14. var util = (function() {
  15. var scriptName = "SaveImages.js";
  16.  
  17. var format_ = function(formatString, args) {
  18. if(!formatString || typeof formatString !== "string")
  19. throw "引数 formatString を指定してください。";
  20.  
  21. return formatString.replace(/\{(\d)\}/g, function(m, c) {
  22. return args[parseInt(c)];
  23. });
  24. };
  25. return {
  26. println: function(formatString /*, ...*/) {
  27. var message = format_(formatString, Array.prototype.slice.call(arguments, 1));
  28. v2c.println("[" + scriptName + "] " + message);
  29. },
  30. format: function(formatString /*, ...*/) {
  31. return format_(formatString, Array.prototype.slice.call(arguments, 1));
  32. }
  33. };
  34. })();
  35.  
  36. function getFilteredResponses() {
  37. var thread = v2c.context.thread;
  38. return Array.map(v2c.context.filteredResIndex, function(x) { return thread.getRes(x); });
  39. }
  40.  
  41. function repeat(s, count) {
  42. return new Array(count + 1).join(s);
  43. }
  44. function padLeft(x, ch, count) {
  45. return (repeat(ch, count) + x).slice(-count);
  46. }
  47.  
  48. function formatFileName(resIndex, n, count, original) {
  49. return util.format(options.fileNameFormatString,
  50. padLeft(resIndex, '0', 4),
  51. padLeft(n, '0', String(count).length),
  52. original);
  53. }
  54.  
  55. function escape(s) {
  56. return ('' + s).replace(/(?:\\|\/|\:|\*|\?|\"|<|>|\|)/g, '_');
  57. }
  58.  
  59. var th = v2c.context.thread;
  60. var saveDirectoryRoot = options.saveDirectory
  61. || v2c.saveDir.getPath() + "/userdata/images";
  62. var saveDirectory = new java.io.File(saveDirectoryRoot,
  63. util.format("{0}/[{1}] {2}", th.board.key, th.key, escape(th.title)));
  64.  
  65. var images = getFilteredResponses()
  66. .reduce(function(a, x) {
  67. var imageLinks = x.links.filter(function(x) {
  68. return x.type_IMAGE && x.imageCacheFile;
  69. });
  70.  
  71. return a.concat(imageLinks.map(function(link, i) {
  72. var originalName = java.nio.file.Paths.get(link.url.getPath()).getFileName();
  73.  
  74. return {
  75. res: x,
  76. imageIndex: i,
  77. imageLink: link,
  78. fileName: formatFileName(x.number, i + 1, imageLinks.length, originalName)
  79. };
  80. }));
  81. }, []);
  82.  
  83. if(0 < images.length) {
  84. if(!saveDirectory.exists()) {
  85. if(!saveDirectory.mkdirs())
  86. throw '保存先ディレクトリの作成に失敗しました。';
  87. }
  88.  
  89. images.forEach(function(x) {
  90. var destFile = new java.io.File(saveDirectory, x.fileName);
  91. var path = destFile.getPath();
  92. if(destFile.exists()) {
  93. util.println("既にファイルが存在するため、この項目を無視します: {0}", path);
  94. return;
  95. }
  96.  
  97. if(!v2c.copyFile(x.imageLink.imageCacheFile, path)) {
  98. util.println("保存に失敗しました: {0}", path);
  99. return;
  100. }
  101.  
  102. //util.println("保存しました: {0}", path);
  103. });
  104.  
  105. v2c.context.setStatusBarText("[SaveImages.js] 完了しました。");
  106. } else {
  107. v2c.context.setStatusBarText("[SaveImages.js] このスレッドにはキャッシュ済みの画像はありません。");
  108. }
Runtime error #stdin #stdout #stderr 0.47s 382976KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
js: uncaught JavaScript runtime exception: ReferenceError: "v2c" is not defined.