mirror of
https://github.com/openeggbert/youtubedl-frontend.git
synced 2025-03-14 21:23:27 +01:00
Renamed to youtubedl-frontend. Added many improvements
This commit is contained in:
parent
7318598d8d
commit
c4dc2f650f
30
pom.xml
30
pom.xml
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
archivebox-youtube-helper: Tool generating html pages for Archive Box.
|
||||
youtubedl-frontend: Tool generating html pages for Archive Box.
|
||||
Copyright (C) 2024 the original author or authors.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
@ -29,12 +29,12 @@
|
||||
</parent>
|
||||
|
||||
<groupId>org.nanoboot.tools</groupId>
|
||||
<artifactId>archivebox-youtube-helper</artifactId>
|
||||
<artifactId>youtubedl-frontend</artifactId>
|
||||
<version>0.0.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>archivebox-youtube-helper</name>
|
||||
<description>archivebox-youtube-helper</description>
|
||||
<name>youtubedl-frontend</name>
|
||||
<description>youtubedl-frontend</description>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
@ -82,7 +82,7 @@
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>org.nanoboot.archiveboxyoutubehelper.Main</mainClass>
|
||||
<mainClass>org.nanoboot.youtubedlfrontend.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
@ -187,6 +187,21 @@
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.17.1</version>
|
||||
</dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>com.github.jai-imageio</groupId>
|
||||
<artifactId>jai-imageio-core</artifactId>
|
||||
<version>1.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.jai-imageio</groupId>
|
||||
<artifactId>jai-imageio-jpeg2000</artifactId>
|
||||
<version>1.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sejda.imageio</groupId>
|
||||
<artifactId>webp-imageio</artifactId>
|
||||
<version>0.1.6</version>
|
||||
</dependency>-->
|
||||
|
||||
</dependencies>
|
||||
|
||||
@ -201,6 +216,11 @@
|
||||
<name>nanoboot-snapshots-repository</name>
|
||||
<url>https://maven.nanoboot.org/snapshots</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>AsposeJavaAPI</id>
|
||||
<name>Aspose Java API</name>
|
||||
<url>https://repository.aspose.com/repo/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// archiveboxyoutubehelper:
|
||||
// youtubedlfrontend:
|
||||
// Copyright (C) 2024 the original author or authors.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
@ -17,7 +17,7 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module archiveboxyoutubehelper {
|
||||
module youtubedlfrontend {
|
||||
requires lombok;
|
||||
requires org.apache.logging.log4j;
|
||||
requires org.json;
|
||||
@ -25,4 +25,5 @@ module archiveboxyoutubehelper {
|
||||
requires humble.video.noarch;
|
||||
requires humble.video.all;
|
||||
requires com.fasterxml.jackson.databind;
|
||||
requires java.desktop;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// archivebox-youtube-helper: Tool generating html pages for Archive Box.
|
||||
// youtubedl-frontend: Tool generating html pages for Archive Box.
|
||||
// Copyright (C) 2024 the original author or authors.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
@ -16,7 +16,7 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
package org.nanoboot.archiveboxyoutubehelper;
|
||||
package org.nanoboot.youtubedlfrontend;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -37,48 +37,111 @@ import java.util.Map;
|
||||
public class Main {
|
||||
|
||||
private static int iii = 0;
|
||||
private static int videoNumberPerRow = 0;
|
||||
public static final boolean ALWAYS_COMPUTE_METADATA = false;
|
||||
public static final int VIDEOS_PER_ROW = 4;
|
||||
private static int THUMBNAIL_WIDTH = 250;
|
||||
private static int internalStaticVariableVideoNumberPerRow = 0;
|
||||
public static boolean argAlwaysGenerateMetadata = true;
|
||||
public static boolean argAlwaysGenerateHtmlFiles = true;
|
||||
public static int argVideosPerRow = 4;
|
||||
public static int THUMBNAIL_WIDTH = 250;
|
||||
public static String argVideo;
|
||||
public static String argChannel;
|
||||
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
System.out.println("archiveboxyoutubehelper - HTML generator\n");
|
||||
System.out.println("youtubedlfrontend - HTML generator\n");
|
||||
|
||||
args = "/rv/blupi/archivebox --_video UDpsz1yIwiw --always-generate-metadata 1 --always-generate-html-files 1 --videos-per-row 4".split(" ");
|
||||
//args = "/rv/databig/youtube --_video UDpsz1yIwiw --always-generate-metadata 1 --always-generate-html-files 1 --videos-per-row 4".split(" ");
|
||||
|
||||
if (args.length == 0) {
|
||||
args = new String[]{"/rv/blupi/archivebox"
|
||||
//, "--video", "gPU_onaTzXs"
|
||||
};
|
||||
}
|
||||
if (args.length < 1) {
|
||||
System.err.println("At least one argument is expected, but the count of arguments is: " + args.length + ".");
|
||||
System.exit(1);
|
||||
}
|
||||
argVideo = "";
|
||||
argChannel = "";
|
||||
if(args.length > 1) {
|
||||
for(int i = 1;i<args.length;i++) {
|
||||
String s = args[i];
|
||||
if(s.equals("--video")) {
|
||||
if (args.length > 0) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String arg = args[i];
|
||||
if (i == 0 && !arg.startsWith(TWO_DASHES)) {
|
||||
continue;
|
||||
}
|
||||
if (arg.equals("--video")) {
|
||||
i++;
|
||||
if(i >= args.length) {
|
||||
throw new ArchiveBoxYoutubeHelperException("Fatal error: missing value for --video");
|
||||
if (i >= args.length) {
|
||||
throw new YoutubedlFrontendException("Fatal error: missing value for --video");
|
||||
}
|
||||
argVideo = args[i];
|
||||
}
|
||||
if(s.equals("--channel")) {
|
||||
if (arg.equals("--channel")) {
|
||||
i++;
|
||||
if(i >= args.length) {
|
||||
throw new ArchiveBoxYoutubeHelperException("Fatal error: missing value for --channel");
|
||||
if (i >= args.length) {
|
||||
throw new YoutubedlFrontendException("Fatal error: missing value for --channel");
|
||||
}
|
||||
argChannel = args[i];
|
||||
}
|
||||
|
||||
if (arg.equals("--videos-per-row")) {
|
||||
i++;
|
||||
if (i >= args.length) {
|
||||
throw new YoutubedlFrontendException("Fatal error: missing value for --videos-per-row");
|
||||
}
|
||||
argVideosPerRow = Integer.parseInt(args[i]);
|
||||
if (argVideosPerRow < 2) {
|
||||
argVideosPerRow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (arg.equals("--always-generate-metadata")) {
|
||||
i++;
|
||||
if (i >= args.length) {
|
||||
throw new YoutubedlFrontendException("Fatal error: missing value for --always-generate-metadata");
|
||||
}
|
||||
String s = args[i];
|
||||
switch (s) {
|
||||
case "1":
|
||||
argAlwaysGenerateMetadata = true;
|
||||
break;
|
||||
case "true":
|
||||
argAlwaysGenerateMetadata = true;
|
||||
break;
|
||||
case "0":
|
||||
argAlwaysGenerateMetadata = false;
|
||||
break;
|
||||
case "false":
|
||||
argAlwaysGenerateMetadata = false;
|
||||
break;
|
||||
default:
|
||||
throw new YoutubedlFrontendException("Invalid value for --always-generate-metadata");
|
||||
};
|
||||
}
|
||||
|
||||
if (arg.equals("--always-generate-html-files")) {
|
||||
i++;
|
||||
if (i >= args.length) {
|
||||
throw new YoutubedlFrontendException("Fatal error: missing value for --always-generate-html-files");
|
||||
}
|
||||
String s = args[i];
|
||||
switch (s) {
|
||||
case "1":
|
||||
argAlwaysGenerateHtmlFiles = true;
|
||||
break;
|
||||
case "true":
|
||||
argAlwaysGenerateHtmlFiles = true;
|
||||
break;
|
||||
case "0":
|
||||
argAlwaysGenerateHtmlFiles = false;
|
||||
break;
|
||||
case "false":
|
||||
argAlwaysGenerateHtmlFiles = false;
|
||||
break;
|
||||
default:
|
||||
throw new YoutubedlFrontendException("Invalid value for --always-generate-html-files");
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File archiveBoxRootDirectory = new File(args[0]);
|
||||
String workingDirectory = args.length > 0 && !args[0].startsWith(TWO_DASHES) ? args[0] : new File(".").getAbsolutePath();
|
||||
|
||||
File archiveBoxRootDirectory = new File(workingDirectory);
|
||||
File archiveBoxArchiveDirectory = new File(archiveBoxRootDirectory, "archive");
|
||||
int i = 0;
|
||||
List<YoutubeVideo> youtubeVideos = new ArrayList<>();
|
||||
@ -90,13 +153,13 @@ public class Main {
|
||||
continue;
|
||||
}
|
||||
YoutubeVideo youtubeVideo = new YoutubeVideo(mediaDirectory);
|
||||
if(!Main.argVideo.isBlank() && !youtubeVideo.getId().equals(Main.argVideo)) {
|
||||
continue;
|
||||
}
|
||||
if(!argVideo.isBlank() && !youtubeVideo.getId().equals(argVideo)) {
|
||||
if (!Main.argVideo.isBlank() && !youtubeVideo.getId().equals(Main.argVideo)) {
|
||||
continue;
|
||||
}
|
||||
if(!argChannel.isBlank() && !youtubeVideo.getChannelId().equals(argChannel)) {
|
||||
if (!argVideo.isBlank() && !youtubeVideo.getId().equals(argVideo)) {
|
||||
continue;
|
||||
}
|
||||
if (!argChannel.isBlank() && !youtubeVideo.getChannelId().equals(argChannel)) {
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
@ -121,14 +184,18 @@ public class Main {
|
||||
YoutubeVideo previousVideo = null;
|
||||
YoutubeVideo nextVideo = null;
|
||||
YoutubeVideo currentVideo = null;
|
||||
for(int j = 0; j<youtubeVideos.size(); j++) {
|
||||
for (int j = 0; j < youtubeVideos.size(); j++) {
|
||||
previousVideo = currentVideo;
|
||||
currentVideo = youtubeVideos.get(j);
|
||||
if(j < (youtubeVideos.size() - 1)) {
|
||||
nextVideo = youtubeVideos.get(j+1);
|
||||
if (j < (youtubeVideos.size() - 1)) {
|
||||
nextVideo = youtubeVideos.get(j + 1);
|
||||
}
|
||||
if (previousVideo != null) {
|
||||
currentVideo.setPreviousVideoId(previousVideo.getId());
|
||||
}
|
||||
if (nextVideo != null) {
|
||||
currentVideo.setNextVideoId(nextVideo.getId());
|
||||
}
|
||||
if(previousVideo != null) currentVideo.setPreviousVideoId(previousVideo.getId());
|
||||
if(nextVideo != null) currentVideo.setNextVideoId(nextVideo.getId());
|
||||
}
|
||||
Map<String, String> channelUrls = new HashMap<>();
|
||||
List<String> channels = new ArrayList<>();
|
||||
@ -173,21 +240,24 @@ public class Main {
|
||||
|
||||
channels.forEach(c -> {
|
||||
sb.append("<h1>").append(c).append("</h1>\n");
|
||||
sb.append("<div style=\"max-width:").append((Main.THUMBNAIL_WIDTH + 20) * Main.VIDEOS_PER_ROW).append("px\"><a href =\"").append(channelUrls.get(c)).append("\">").append(channelUrls.get(c)).append("</a><div class=\"videos\">");
|
||||
sb.append("<div style=\"max-width:").append((Main.THUMBNAIL_WIDTH + 20) * Main.argVideosPerRow).append("px\"><a href =\"").append(channelUrls.get(c)).append("\">").append(channelUrls.get(c)).append("</a><div class=\"videos\">");
|
||||
iii = 0;
|
||||
videoNumberPerRow = 0;
|
||||
internalStaticVariableVideoNumberPerRow = 0;
|
||||
sb.append("<table>\n");
|
||||
youtubeVideos.stream().filter(v -> c.equals(v.getChannelName())).forEach(z -> {
|
||||
iii++;
|
||||
if (videoNumberPerRow == 0) {
|
||||
if (internalStaticVariableVideoNumberPerRow == 0) {
|
||||
sb.append("<tr>");
|
||||
}
|
||||
videoNumberPerRow++;
|
||||
internalStaticVariableVideoNumberPerRow++;
|
||||
sb.append("<td><div class=\"box\"><table style=\"margin:5px;max-width:")
|
||||
.append(THUMBNAIL_WIDTH)
|
||||
.append("px;\">\n<tr><td><a href=\"videos/" + z.getId() + ".html\" target=\"_blank\"><img src=\"archive/");
|
||||
sb.append(z.getSnapshot());
|
||||
sb.append("/media/thumbnail.jpg\" width=\"")
|
||||
sb
|
||||
.append("/media/mini-thumbnail.")
|
||||
.append(z.getMiniThumbnailFormat())
|
||||
.append("\" width=\"")
|
||||
.append(THUMBNAIL_WIDTH)
|
||||
.append("\"></a></td></tr>\n");
|
||||
sb.append("<tr><td><b style=\"font-size:90%;\">").append(z.getTitle()).append("</b></td></tr>\n");
|
||||
@ -199,14 +269,14 @@ public class Main {
|
||||
.append("</td></tr>\n");
|
||||
z.setNumber(iii);
|
||||
sb.append("</table></div></td>\n");
|
||||
if (videoNumberPerRow == VIDEOS_PER_ROW) {
|
||||
if (internalStaticVariableVideoNumberPerRow == argVideosPerRow) {
|
||||
sb.append("<tr>");
|
||||
videoNumberPerRow = 0;
|
||||
internalStaticVariableVideoNumberPerRow = 0;
|
||||
}
|
||||
File videoHtmlFile = new File(videosDirectory, z.getId() + ".html");
|
||||
// if(videoHtmlFile.exists()) {
|
||||
//
|
||||
// }
|
||||
if(!videoHtmlFile.exists() || argAlwaysGenerateHtmlFiles) {
|
||||
|
||||
|
||||
{
|
||||
StringBuilder sb2 = new StringBuilder("""
|
||||
<!DOCTYPE html>
|
||||
@ -214,8 +284,8 @@ public class Main {
|
||||
<head>
|
||||
<link rel="icon" type="image/x-icon" href="../favicon.ico" sizes="16x16">
|
||||
<title>"""
|
||||
+z.getTitle() +
|
||||
"""
|
||||
+ z.getTitle()
|
||||
+ """
|
||||
</title>
|
||||
<style>
|
||||
body {padding:20px;}
|
||||
@ -230,54 +300,78 @@ public class Main {
|
||||
);
|
||||
String finalUrl = "https://www.youtube.com/watch?v=" + z.getId();
|
||||
|
||||
sb2.append("<input type=\"text\" id=\"youtube_url\" name=\"youtube_url\" size=\"60\" width=\"60\" style=\"margint-bottom:20px;margin-right:10px;font-size:110%;padding:5px;\" value=\"" + finalUrl + "\"><br><br>");
|
||||
sb2.append("<a target=\"_blank\" href=\"").append(finalUrl).append("\">");
|
||||
sb2.append(finalUrl).append("</a>").append("<br>");
|
||||
sb2.append("<input type=\"text\" id=\"youtube_url\" name=\"youtube_url\" size=\"60\" width=\"60\" style=\"margint-bottom:20px;margin-right:10px;font-size:110%;padding:5px;\" value=\"" + finalUrl + "\"><br>\n<br>\n");
|
||||
sb2.append("<a target=\"_blank\" href=\"").append(finalUrl).append("\">");
|
||||
sb2.append(finalUrl).append("</a>").append("<br>\n");
|
||||
String videoLocalUrl = "";
|
||||
try {
|
||||
videoLocalUrl = "file:///" + archiveBoxRootDirectory.getAbsolutePath() + "/archive/" + z.getSnapshot() + "/media/" + URLEncoder.encode(z.getVideoFileName(), StandardCharsets.UTF_8.toString()).replace("+", "%20");
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
throw new ArchiveBoxYoutubeHelperException(ex.getMessage());
|
||||
throw new YoutubedlFrontendException(ex.getMessage());
|
||||
}
|
||||
if(!z.getVideoFileName().endsWith(".mkv")) {
|
||||
try {
|
||||
sb2.append("<video src=\"");
|
||||
|
||||
sb2.append("../archive/" + z.getSnapshot() + "/media/" + URLEncoder.encode(z.getVideoFileName(), StandardCharsets.UTF_8.toString()).replace("+", "%20"));
|
||||
sb2.append("""
|
||||
" controls width=\"800\">
|
||||
Your browser does not support the video tag.
|
||||
</video><br>
|
||||
""");
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
throw new YoutubedlFrontendException(ex.getMessage());
|
||||
}
|
||||
} else {
|
||||
sb2.append("<a target=\"_blank\" href=\"").append(videoLocalUrl).append("\">");
|
||||
|
||||
|
||||
sb2.append("<img style=\"margin:10px;width:600px;\" src=\"../archive/")
|
||||
.append(z.getSnapshot())
|
||||
.append("/media/thumbnail.jpg\"></a><br>");
|
||||
.append("/media/thumbnail.")
|
||||
.append(z.getThumbnailFormat())
|
||||
.append("\"></a><br>\n");
|
||||
}
|
||||
sb2.append("<span style=\"font-size:160%;font-weight:bold;\">").append(z.getTitle()).append("</span>");
|
||||
sb2.append("<br><br>");
|
||||
sb2.append("<br>\n<br>\n");
|
||||
sb2.append("#").append(z.getNumber()).append(" ");
|
||||
if(z.getPreviousVideoId() != null) sb2.append("<a href=\"./").append(z.getPreviousVideoId()).append(".html\">");
|
||||
if (z.getPreviousVideoId() != null) {
|
||||
sb2.append("<a href=\"./").append(z.getPreviousVideoId()).append(".html\">");
|
||||
}
|
||||
sb2.append("Back");
|
||||
if(z.getPreviousVideoId() != null) sb2.append("</a>");
|
||||
if (z.getPreviousVideoId() != null) {
|
||||
sb2.append("</a>");
|
||||
}
|
||||
sb2.append(" ");
|
||||
if(z.getNextVideoId()!= null) sb2.append("<a href=\"./").append(z.getNextVideoId()).append(".html\">");
|
||||
if (z.getNextVideoId() != null) {
|
||||
sb2.append("<a href=\"./").append(z.getNextVideoId()).append(".html\">");
|
||||
}
|
||||
sb2.append("Next");
|
||||
if(z.getNextVideoId() != null) sb2.append("</a>");
|
||||
if (z.getNextVideoId() != null) {
|
||||
sb2.append("</a>");
|
||||
}
|
||||
sb2.append(" ");
|
||||
sb2.append("<br>");
|
||||
sb2.append("<br>\n");
|
||||
sb2.append("<pre style=\"white-space: pre-wrap; border:1px solid black;max-width:600px;padding:10px;min-height:50px;\">");
|
||||
sb2.append(z.getDescription().isBlank() ? "No description" : z.getDescription());
|
||||
sb2.append("</pre>");
|
||||
sb2.append("<h2>Comments</h2>");
|
||||
z.getComments().forEach(co -> {
|
||||
|
||||
|
||||
// private String id, parentId, text, author;
|
||||
// private int timestamp;
|
||||
sb2.append("<div style=\"margin-left:")
|
||||
.append(co.dotCount() * 50)
|
||||
.append("px;\">");
|
||||
sb2.append("<div style=\"margin-left:")
|
||||
.append(co.dotCount() * 50)
|
||||
.append("px;\">");
|
||||
sb2.append("<h3>").append(co.getAuthor()).append("</h3>");
|
||||
|
||||
|
||||
sb2.append("<span style=\"color:grey;font-size:80%;\">")
|
||||
|
||||
.append(Utils.DATE_FORMAT.format(new Date(co.getTimestamp() * 1000))).append("</span><br>");
|
||||
.append(Utils.DATE_FORMAT.format(new Date(co.getTimestamp() * 1000))).append("</span><br>\n");
|
||||
sb2.append("<span style=\"color:grey;font-size:80%;\">")
|
||||
.append(co.getId() + " " + co.getParentId()).append("</span><br>");
|
||||
.append(co.getId() + " " + co.getParentId()).append("</span><br>\n");
|
||||
sb2.append("<pre style=\"white-space: pre-wrap;border:1px solid black;max-width:600px;padding:10px;min-height:50px;\">").append(co.getText()).append("</pre>");
|
||||
sb2.append("</div>");
|
||||
});
|
||||
|
||||
|
||||
// private String id;
|
||||
//
|
||||
// private String title;
|
||||
@ -292,18 +386,17 @@ sb2.append("<div style=\"margin-left:")
|
||||
// private String description;
|
||||
// private String thumbnail;
|
||||
// private List<YoutubeComment> comments = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
sb2.append("</body></html>");
|
||||
Utils.writeTextToFile(sb2.toString(), videoHtmlFile);
|
||||
String singleVideo = sb2.toString();
|
||||
//singleVideo.replace("<br>\n", "<br>\n\n");
|
||||
Utils.writeTextToFile(singleVideo, videoHtmlFile);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
if (videoNumberPerRow < VIDEOS_PER_ROW) {
|
||||
if (internalStaticVariableVideoNumberPerRow < argVideosPerRow) {
|
||||
sb.append("<tr>");
|
||||
}
|
||||
sb.append("<table>\n");
|
||||
sb.append("</table>\n");
|
||||
sb.append("</div></div>");
|
||||
});
|
||||
sb.append("""
|
||||
@ -317,5 +410,6 @@ sb2.append("<div style=\"margin-left:")
|
||||
System.out.println("[Warning] Snapshots without videos:");
|
||||
YoutubeVideo.missingYoutubeVideos.forEach(s -> System.out.println(s));
|
||||
}
|
||||
private static final String TWO_DASHES = "--";
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// archivebox-youtube-helper: Tool generating html pages for Archive Box.
|
||||
// youtubedl-frontend: Tool generating html pages for Archive Box.
|
||||
// Copyright (C) 2024 the original author or authors.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
@ -16,7 +16,7 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
package org.nanoboot.archiveboxyoutubehelper;
|
||||
package org.nanoboot.youtubedlfrontend;
|
||||
|
||||
import dev.mccue.guava.hash.Hashing;
|
||||
import java.io.BufferedReader;
|
||||
@ -99,7 +99,7 @@ public class Utils {
|
||||
return result;//.substring(0, result.length() - 1);
|
||||
}
|
||||
|
||||
public static void copyFile(File originalFile, File copiedFile) throws ArchiveBoxYoutubeHelperException {
|
||||
public static void copyFile(File originalFile, File copiedFile) throws YoutubedlFrontendException {
|
||||
Path originalPath = originalFile.toPath();
|
||||
Path copied = new File(copiedFile, originalFile.getName()).toPath();
|
||||
|
||||
@ -107,7 +107,7 @@ public class Utils {
|
||||
Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
throw new ArchiveBoxYoutubeHelperException("Copying file failed: " + originalFile.getAbsolutePath());
|
||||
throw new YoutubedlFrontendException("Copying file failed: " + originalFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ public class Utils {
|
||||
fileWriter = new FileWriter(file);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
throw new ArchiveBoxYoutubeHelperException("Writing to file failed: " + file.getName(), ex);
|
||||
throw new YoutubedlFrontendException("Writing to file failed: " + file.getName(), ex);
|
||||
}
|
||||
PrintWriter printWriter = new PrintWriter(fileWriter);
|
||||
printWriter.print(text);
|
||||
@ -131,7 +131,7 @@ public class Utils {
|
||||
try {
|
||||
return new String(Files.readAllBytes(Paths.get(file.getAbsolutePath())));
|
||||
} catch (IOException ex) {
|
||||
throw new ArchiveBoxYoutubeHelperException("Reading file failed: " + file.getName(), ex);
|
||||
throw new YoutubedlFrontendException("Reading file failed: " + file.getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ public class Utils {
|
||||
InputStream inputStream = clazz.getResourceAsStream(fileName);
|
||||
return readFromInputStream(inputStream);
|
||||
} catch (IOException ex) {
|
||||
throw new ArchiveBoxYoutubeHelperException("Reading file failed: " + fileName, ex);
|
||||
throw new YoutubedlFrontendException("Reading file failed: " + fileName, ex);
|
||||
}
|
||||
|
||||
}
|
||||
@ -164,7 +164,7 @@ public class Utils {
|
||||
return dev.mccue.guava.io.Files.hash(file, Hashing.sha512()).toString();
|
||||
} catch (IOException ex) {
|
||||
System.err.println(ex.getMessage());
|
||||
throw new ArchiveBoxYoutubeHelperException(ex.getMessage());
|
||||
throw new YoutubedlFrontendException(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
||||
*/
|
||||
package org.nanoboot.archiveboxyoutubehelper;
|
||||
package org.nanoboot.youtubedlfrontend;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
@ -2,7 +2,7 @@
|
||||
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
||||
*/
|
||||
package org.nanoboot.archiveboxyoutubehelper;
|
||||
package org.nanoboot.youtubedlfrontend;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@ -21,6 +21,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import javax.imageio.ImageIO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@ -50,6 +51,7 @@ public class YoutubeVideo implements Comparable<YoutubeVideo> {
|
||||
private long timestamp;
|
||||
private String description;
|
||||
private String thumbnail;
|
||||
private String miniThumbnail;
|
||||
private List<YoutubeComment> comments = new ArrayList<>();
|
||||
private String previousVideoId = null;
|
||||
private String nextVideoId = null;
|
||||
@ -60,7 +62,7 @@ public class YoutubeVideo implements Comparable<YoutubeVideo> {
|
||||
|
||||
public YoutubeVideo(File mediaDirectory) throws InterruptedException, IOException {
|
||||
File metadataFile = new File(mediaDirectory, "metadata");
|
||||
if (!Main.ALWAYS_COMPUTE_METADATA && metadataFile.exists()) {
|
||||
if (!Main.argAlwaysGenerateMetadata && metadataFile.exists()) {
|
||||
|
||||
YoutubeVideo yv = new YoutubeVideo();
|
||||
//new ObjectMapper().readValue(Utils.readTextFromFile(metadataFile), YoutubeVideo.class);
|
||||
@ -86,6 +88,7 @@ public class YoutubeVideo implements Comparable<YoutubeVideo> {
|
||||
timestamp = Long.parseLong(properties.getProperty("timestamp"));
|
||||
description = properties.getProperty("description");
|
||||
thumbnail = properties.getProperty("thumbnail");
|
||||
miniThumbnail = properties.getProperty("miniThumbnail");
|
||||
comments = new ArrayList<>();
|
||||
JSONArray ja = new JSONArray(properties.getProperty("comments"));
|
||||
ja.forEach(o -> {
|
||||
@ -96,7 +99,7 @@ public class YoutubeVideo implements Comparable<YoutubeVideo> {
|
||||
comments.add(new ObjectMapper().readValue(toString, YoutubeComment.class));
|
||||
} catch (JsonProcessingException ex) {
|
||||
|
||||
throw new ArchiveBoxYoutubeHelperException(ex.getMessage());
|
||||
throw new YoutubedlFrontendException(ex.getMessage());
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -119,17 +122,82 @@ public class YoutubeVideo implements Comparable<YoutubeVideo> {
|
||||
if (thumbnail == null) {
|
||||
thumbnail = "";
|
||||
}
|
||||
File thumbnailFile = new File(mediaDirectory, "thumbnail.jpg");
|
||||
if (!thumbnailFile.exists() && thumbnail != null) {
|
||||
try (BufferedInputStream in = new BufferedInputStream(new URL(thumbnail).openStream()); FileOutputStream fileOutputStream = new FileOutputStream(thumbnailFile.getAbsolutePath())) {
|
||||
byte dataBuffer[] = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
|
||||
fileOutputStream.write(dataBuffer, 0, bytesRead);
|
||||
JSONArray thumbnails = jsonObject.getJSONArray("thumbnails");
|
||||
for (int i = 0; i < thumbnails.length(); i++) {
|
||||
JSONObject o = (JSONObject) thumbnails.get(i);
|
||||
if (!o.has("width")) {
|
||||
continue;
|
||||
} else {
|
||||
int width = o.getInt("width");
|
||||
if (width < (((double)Main.THUMBNAIL_WIDTH) * 0.8d)) {
|
||||
continue;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getMessage());
|
||||
miniThumbnail = o.getString("url");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File thumbnailFile = new File(mediaDirectory, "thumbnail." + getThumbnailFormat());
|
||||
File miniThumbnailFile = new File(mediaDirectory, "mini-thumbnail." + getMiniThumbnailFormat());
|
||||
|
||||
// new File(mediaDirectory, "thumbnail.jpg").delete();
|
||||
// new File(mediaDirectory, "mini-thumbnail.jpg").delete();
|
||||
// new File(mediaDirectory, "thumbnail.webp").delete();
|
||||
// new File(mediaDirectory, "mini-thumbnail.webp").delete();
|
||||
|
||||
if (thumbnail != null) {
|
||||
if (!thumbnailFile.exists()) {
|
||||
try (BufferedInputStream in = new BufferedInputStream(new URL(thumbnail).openStream()); FileOutputStream fileOutputStream = new FileOutputStream(thumbnailFile.getAbsolutePath())) {
|
||||
byte dataBuffer[] = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
|
||||
fileOutputStream.write(dataBuffer, 0, bytesRead);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
if (!miniThumbnailFile.exists()) {
|
||||
try (BufferedInputStream in = new BufferedInputStream(new URL(miniThumbnail).openStream()); FileOutputStream fileOutputStream = new FileOutputStream(miniThumbnailFile.getAbsolutePath())) {
|
||||
byte dataBuffer[] = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
|
||||
fileOutputStream.write(dataBuffer, 0, bytesRead);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
// for (String s : ImageIO.getReaderFormatNames()) {
|
||||
// System.out.println(s);
|
||||
// }
|
||||
//if(!miniThumbnailFile.exists()) {
|
||||
|
||||
//String miniThumbnailFileAbsolutePath = miniThumbnailFile.getAbsolutePath();
|
||||
// String formatName = miniThumbnailFileAbsolutePath.substring(miniThumbnailFileAbsolutePath
|
||||
// .lastIndexOf(".") + 1);
|
||||
// BufferedImage inputImage = ImageIO.read(thumbnailFile);
|
||||
// if(inputImage == null) {
|
||||
//
|
||||
// }
|
||||
// int thumbnailWidth = inputImage.getWidth();
|
||||
// int thumbnailHeight = inputImage.getHeight();
|
||||
// double heightWidthRatio = ((double) thumbnailHeight) / ((double) thumbnailWidth);
|
||||
// int miniThumbnailWidth = Main.THUMBNAIL_WIDTH;
|
||||
// int miniThumbnailHeight = (int) (heightWidthRatio * ((double) Main.THUMBNAIL_WIDTH));
|
||||
//
|
||||
// BufferedImage outputImage = new BufferedImage(miniThumbnailWidth,
|
||||
// miniThumbnailHeight, inputImage.getType());
|
||||
//
|
||||
// Graphics2D g2d = outputImage.createGraphics();
|
||||
// g2d.drawImage(inputImage, 0, 0, miniThumbnailWidth, miniThumbnailHeight, null);
|
||||
// g2d.dispose();
|
||||
//
|
||||
//
|
||||
//
|
||||
// ImageIO.write(outputImage, formatName, new File(miniThumbnailFileAbsolutePath));
|
||||
//}
|
||||
}
|
||||
//
|
||||
Optional<File> descriptionFile = files.stream().filter(f -> f.getName().endsWith(".description")).findFirst();
|
||||
@ -198,6 +266,7 @@ public class YoutubeVideo implements Comparable<YoutubeVideo> {
|
||||
properties.put("timestamp", String.valueOf(timestamp));
|
||||
properties.put("description", description);
|
||||
properties.put("thumbnail", thumbnail);
|
||||
properties.put("minithumbnail", miniThumbnail);
|
||||
properties.put("comments", new JSONArray(comments).toString());
|
||||
if (previousVideoId != null) {
|
||||
properties.put("previousVideoId", previousVideoId);
|
||||
@ -225,6 +294,32 @@ public class YoutubeVideo implements Comparable<YoutubeVideo> {
|
||||
|
||||
}
|
||||
|
||||
public String getThumbnailFormat() {
|
||||
return getExtensionFromUrl(thumbnail);
|
||||
}
|
||||
|
||||
public String getMiniThumbnailFormat() {
|
||||
return getExtensionFromUrl(miniThumbnail);
|
||||
}
|
||||
private String getExtensionFromUrl(String url) {
|
||||
String result = url.substring(url
|
||||
.lastIndexOf(".") + 1);
|
||||
int questionMarkIndex = 0;
|
||||
for(int i = 0;i<result.length();i++) {
|
||||
char ch = result.charAt(i);
|
||||
if(ch != '?') {
|
||||
continue;
|
||||
} else {
|
||||
questionMarkIndex = i;
|
||||
}
|
||||
}
|
||||
if(questionMarkIndex > 0) {
|
||||
result = result.substring(0, questionMarkIndex);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretty prints a timestamp (in {@link Global.NO_PTS} units) into a string.
|
||||
*
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// archivebox-youtube-helper: Tool generating html pages for Archive Box.
|
||||
// youtubedl-frontend: Tool generating html pages for Archive Box.
|
||||
// Copyright (C) 2024 the original author or authors.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
@ -17,19 +17,19 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package org.nanoboot.archiveboxyoutubehelper;
|
||||
package org.nanoboot.youtubedlfrontend;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:robertvokac@nanoboot.org">Robert Vokac</a>
|
||||
* @since 0.0.0
|
||||
*/
|
||||
public class ArchiveBoxYoutubeHelperException extends RuntimeException {
|
||||
public class YoutubedlFrontendException extends RuntimeException {
|
||||
|
||||
public ArchiveBoxYoutubeHelperException(String msg) {
|
||||
public YoutubedlFrontendException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public ArchiveBoxYoutubeHelperException(String msg, Exception e) {
|
||||
public YoutubedlFrontendException(String msg, Exception e) {
|
||||
super(msg, e);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user