mirror of
https://github.com/openeggbert/youtubedl-frontend.git
synced 2025-03-25 17:17:46 +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"?>
|
<?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.
|
Copyright (C) 2024 the original author or authors.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
@ -29,12 +29,12 @@
|
|||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.nanoboot.tools</groupId>
|
<groupId>org.nanoboot.tools</groupId>
|
||||||
<artifactId>archivebox-youtube-helper</artifactId>
|
<artifactId>youtubedl-frontend</artifactId>
|
||||||
<version>0.0.0-SNAPSHOT</version>
|
<version>0.0.0-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>archivebox-youtube-helper</name>
|
<name>youtubedl-frontend</name>
|
||||||
<description>archivebox-youtube-helper</description>
|
<description>youtubedl-frontend</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
@ -82,7 +82,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifest>
|
<manifest>
|
||||||
<mainClass>org.nanoboot.archiveboxyoutubehelper.Main</mainClass>
|
<mainClass>org.nanoboot.youtubedlfrontend.Main</mainClass>
|
||||||
</manifest>
|
</manifest>
|
||||||
</archive>
|
</archive>
|
||||||
<descriptorRefs>
|
<descriptorRefs>
|
||||||
@ -187,6 +187,21 @@
|
|||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>2.17.1</version>
|
<version>2.17.1</version>
|
||||||
</dependency>
|
</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>
|
</dependencies>
|
||||||
|
|
||||||
@ -201,6 +216,11 @@
|
|||||||
<name>nanoboot-snapshots-repository</name>
|
<name>nanoboot-snapshots-repository</name>
|
||||||
<url>https://maven.nanoboot.org/snapshots</url>
|
<url>https://maven.nanoboot.org/snapshots</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>AsposeJavaAPI</id>
|
||||||
|
<name>Aspose Java API</name>
|
||||||
|
<url>https://repository.aspose.com/repo/</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<pluginRepositories>
|
<pluginRepositories>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// archiveboxyoutubehelper:
|
// youtubedlfrontend:
|
||||||
// Copyright (C) 2024 the original author or authors.
|
// Copyright (C) 2024 the original author or authors.
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// 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.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
module archiveboxyoutubehelper {
|
module youtubedlfrontend {
|
||||||
requires lombok;
|
requires lombok;
|
||||||
requires org.apache.logging.log4j;
|
requires org.apache.logging.log4j;
|
||||||
requires org.json;
|
requires org.json;
|
||||||
@ -25,4 +25,5 @@ module archiveboxyoutubehelper {
|
|||||||
requires humble.video.noarch;
|
requires humble.video.noarch;
|
||||||
requires humble.video.all;
|
requires humble.video.all;
|
||||||
requires com.fasterxml.jackson.databind;
|
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.
|
// Copyright (C) 2024 the original author or authors.
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// 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
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// 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.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -37,48 +37,111 @@ import java.util.Map;
|
|||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
private static int iii = 0;
|
private static int iii = 0;
|
||||||
private static int videoNumberPerRow = 0;
|
private static int internalStaticVariableVideoNumberPerRow = 0;
|
||||||
public static final boolean ALWAYS_COMPUTE_METADATA = false;
|
public static boolean argAlwaysGenerateMetadata = true;
|
||||||
public static final int VIDEOS_PER_ROW = 4;
|
public static boolean argAlwaysGenerateHtmlFiles = true;
|
||||||
private static int THUMBNAIL_WIDTH = 250;
|
public static int argVideosPerRow = 4;
|
||||||
|
public static int THUMBNAIL_WIDTH = 250;
|
||||||
public static String argVideo;
|
public static String argVideo;
|
||||||
public static String argChannel;
|
public static String argChannel;
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, InterruptedException {
|
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) {
|
if (args.length < 1) {
|
||||||
System.err.println("At least one argument is expected, but the count of arguments is: " + args.length + ".");
|
System.err.println("At least one argument is expected, but the count of arguments is: " + args.length + ".");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
argVideo = "";
|
argVideo = "";
|
||||||
argChannel = "";
|
argChannel = "";
|
||||||
if(args.length > 1) {
|
if (args.length > 0) {
|
||||||
for(int i = 1;i<args.length;i++) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
String s = args[i];
|
String arg = args[i];
|
||||||
if(s.equals("--video")) {
|
if (i == 0 && !arg.startsWith(TWO_DASHES)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (arg.equals("--video")) {
|
||||||
i++;
|
i++;
|
||||||
if(i >= args.length) {
|
if (i >= args.length) {
|
||||||
throw new ArchiveBoxYoutubeHelperException("Fatal error: missing value for --video");
|
throw new YoutubedlFrontendException("Fatal error: missing value for --video");
|
||||||
}
|
}
|
||||||
argVideo = args[i];
|
argVideo = args[i];
|
||||||
}
|
}
|
||||||
if(s.equals("--channel")) {
|
if (arg.equals("--channel")) {
|
||||||
i++;
|
i++;
|
||||||
if(i >= args.length) {
|
if (i >= args.length) {
|
||||||
throw new ArchiveBoxYoutubeHelperException("Fatal error: missing value for --channel");
|
throw new YoutubedlFrontendException("Fatal error: missing value for --channel");
|
||||||
}
|
}
|
||||||
argChannel = args[i];
|
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");
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
String workingDirectory = args.length > 0 && !args[0].startsWith(TWO_DASHES) ? args[0] : new File(".").getAbsolutePath();
|
||||||
File archiveBoxRootDirectory = new File(args[0]);
|
|
||||||
|
File archiveBoxRootDirectory = new File(workingDirectory);
|
||||||
File archiveBoxArchiveDirectory = new File(archiveBoxRootDirectory, "archive");
|
File archiveBoxArchiveDirectory = new File(archiveBoxRootDirectory, "archive");
|
||||||
int i = 0;
|
int i = 0;
|
||||||
List<YoutubeVideo> youtubeVideos = new ArrayList<>();
|
List<YoutubeVideo> youtubeVideos = new ArrayList<>();
|
||||||
@ -90,13 +153,13 @@ public class Main {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
YoutubeVideo youtubeVideo = new YoutubeVideo(mediaDirectory);
|
YoutubeVideo youtubeVideo = new YoutubeVideo(mediaDirectory);
|
||||||
if(!Main.argVideo.isBlank() && !youtubeVideo.getId().equals(Main.argVideo)) {
|
if (!Main.argVideo.isBlank() && !youtubeVideo.getId().equals(Main.argVideo)) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(!argVideo.isBlank() && !youtubeVideo.getId().equals(argVideo)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(!argChannel.isBlank() && !youtubeVideo.getChannelId().equals(argChannel)) {
|
if (!argVideo.isBlank() && !youtubeVideo.getId().equals(argVideo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!argChannel.isBlank() && !youtubeVideo.getChannelId().equals(argChannel)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@ -121,14 +184,18 @@ public class Main {
|
|||||||
YoutubeVideo previousVideo = null;
|
YoutubeVideo previousVideo = null;
|
||||||
YoutubeVideo nextVideo = null;
|
YoutubeVideo nextVideo = null;
|
||||||
YoutubeVideo currentVideo = null;
|
YoutubeVideo currentVideo = null;
|
||||||
for(int j = 0; j<youtubeVideos.size(); j++) {
|
for (int j = 0; j < youtubeVideos.size(); j++) {
|
||||||
previousVideo = currentVideo;
|
previousVideo = currentVideo;
|
||||||
currentVideo = youtubeVideos.get(j);
|
currentVideo = youtubeVideos.get(j);
|
||||||
if(j < (youtubeVideos.size() - 1)) {
|
if (j < (youtubeVideos.size() - 1)) {
|
||||||
nextVideo = youtubeVideos.get(j+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<>();
|
Map<String, String> channelUrls = new HashMap<>();
|
||||||
List<String> channels = new ArrayList<>();
|
List<String> channels = new ArrayList<>();
|
||||||
@ -173,21 +240,24 @@ public class Main {
|
|||||||
|
|
||||||
channels.forEach(c -> {
|
channels.forEach(c -> {
|
||||||
sb.append("<h1>").append(c).append("</h1>\n");
|
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;
|
iii = 0;
|
||||||
videoNumberPerRow = 0;
|
internalStaticVariableVideoNumberPerRow = 0;
|
||||||
sb.append("<table>\n");
|
sb.append("<table>\n");
|
||||||
youtubeVideos.stream().filter(v -> c.equals(v.getChannelName())).forEach(z -> {
|
youtubeVideos.stream().filter(v -> c.equals(v.getChannelName())).forEach(z -> {
|
||||||
iii++;
|
iii++;
|
||||||
if (videoNumberPerRow == 0) {
|
if (internalStaticVariableVideoNumberPerRow == 0) {
|
||||||
sb.append("<tr>");
|
sb.append("<tr>");
|
||||||
}
|
}
|
||||||
videoNumberPerRow++;
|
internalStaticVariableVideoNumberPerRow++;
|
||||||
sb.append("<td><div class=\"box\"><table style=\"margin:5px;max-width:")
|
sb.append("<td><div class=\"box\"><table style=\"margin:5px;max-width:")
|
||||||
.append(THUMBNAIL_WIDTH)
|
.append(THUMBNAIL_WIDTH)
|
||||||
.append("px;\">\n<tr><td><a href=\"videos/" + z.getId() + ".html\" target=\"_blank\"><img src=\"archive/");
|
.append("px;\">\n<tr><td><a href=\"videos/" + z.getId() + ".html\" target=\"_blank\"><img src=\"archive/");
|
||||||
sb.append(z.getSnapshot());
|
sb.append(z.getSnapshot());
|
||||||
sb.append("/media/thumbnail.jpg\" width=\"")
|
sb
|
||||||
|
.append("/media/mini-thumbnail.")
|
||||||
|
.append(z.getMiniThumbnailFormat())
|
||||||
|
.append("\" width=\"")
|
||||||
.append(THUMBNAIL_WIDTH)
|
.append(THUMBNAIL_WIDTH)
|
||||||
.append("\"></a></td></tr>\n");
|
.append("\"></a></td></tr>\n");
|
||||||
sb.append("<tr><td><b style=\"font-size:90%;\">").append(z.getTitle()).append("</b></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");
|
.append("</td></tr>\n");
|
||||||
z.setNumber(iii);
|
z.setNumber(iii);
|
||||||
sb.append("</table></div></td>\n");
|
sb.append("</table></div></td>\n");
|
||||||
if (videoNumberPerRow == VIDEOS_PER_ROW) {
|
if (internalStaticVariableVideoNumberPerRow == argVideosPerRow) {
|
||||||
sb.append("<tr>");
|
sb.append("<tr>");
|
||||||
videoNumberPerRow = 0;
|
internalStaticVariableVideoNumberPerRow = 0;
|
||||||
}
|
}
|
||||||
File videoHtmlFile = new File(videosDirectory, z.getId() + ".html");
|
File videoHtmlFile = new File(videosDirectory, z.getId() + ".html");
|
||||||
// if(videoHtmlFile.exists()) {
|
if(!videoHtmlFile.exists() || argAlwaysGenerateHtmlFiles) {
|
||||||
//
|
|
||||||
// }
|
|
||||||
{
|
{
|
||||||
StringBuilder sb2 = new StringBuilder("""
|
StringBuilder sb2 = new StringBuilder("""
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@ -214,8 +284,8 @@ public class Main {
|
|||||||
<head>
|
<head>
|
||||||
<link rel="icon" type="image/x-icon" href="../favicon.ico" sizes="16x16">
|
<link rel="icon" type="image/x-icon" href="../favicon.ico" sizes="16x16">
|
||||||
<title>"""
|
<title>"""
|
||||||
+z.getTitle() +
|
+ z.getTitle()
|
||||||
"""
|
+ """
|
||||||
</title>
|
</title>
|
||||||
<style>
|
<style>
|
||||||
body {padding:20px;}
|
body {padding:20px;}
|
||||||
@ -230,54 +300,78 @@ public class Main {
|
|||||||
);
|
);
|
||||||
String finalUrl = "https://www.youtube.com/watch?v=" + z.getId();
|
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("<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("<a target=\"_blank\" href=\"").append(finalUrl).append("\">");
|
||||||
sb2.append(finalUrl).append("</a>").append("<br>");
|
sb2.append(finalUrl).append("</a>").append("<br>\n");
|
||||||
String videoLocalUrl = "";
|
String videoLocalUrl = "";
|
||||||
try {
|
try {
|
||||||
videoLocalUrl = "file:///" + archiveBoxRootDirectory.getAbsolutePath() + "/archive/" + z.getSnapshot() + "/media/" + URLEncoder.encode(z.getVideoFileName(), StandardCharsets.UTF_8.toString()).replace("+", "%20");
|
videoLocalUrl = "file:///" + archiveBoxRootDirectory.getAbsolutePath() + "/archive/" + z.getSnapshot() + "/media/" + URLEncoder.encode(z.getVideoFileName(), StandardCharsets.UTF_8.toString()).replace("+", "%20");
|
||||||
} catch (UnsupportedEncodingException ex) {
|
} 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("<a target=\"_blank\" href=\"").append(videoLocalUrl).append("\">");
|
||||||
|
|
||||||
sb2.append("<img style=\"margin:10px;width:600px;\" src=\"../archive/")
|
sb2.append("<img style=\"margin:10px;width:600px;\" src=\"../archive/")
|
||||||
.append(z.getSnapshot())
|
.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("<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(" ");
|
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");
|
sb2.append("Back");
|
||||||
if(z.getPreviousVideoId() != null) sb2.append("</a>");
|
if (z.getPreviousVideoId() != null) {
|
||||||
|
sb2.append("</a>");
|
||||||
|
}
|
||||||
sb2.append(" ");
|
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");
|
sb2.append("Next");
|
||||||
if(z.getNextVideoId() != null) sb2.append("</a>");
|
if (z.getNextVideoId() != null) {
|
||||||
|
sb2.append("</a>");
|
||||||
|
}
|
||||||
sb2.append(" ");
|
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("<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(z.getDescription().isBlank() ? "No description" : z.getDescription());
|
||||||
sb2.append("</pre>");
|
sb2.append("</pre>");
|
||||||
sb2.append("<h2>Comments</h2>");
|
sb2.append("<h2>Comments</h2>");
|
||||||
z.getComments().forEach(co -> {
|
z.getComments().forEach(co -> {
|
||||||
|
|
||||||
// private String id, parentId, text, author;
|
// private String id, parentId, text, author;
|
||||||
// private int timestamp;
|
// private int timestamp;
|
||||||
sb2.append("<div style=\"margin-left:")
|
sb2.append("<div style=\"margin-left:")
|
||||||
.append(co.dotCount() * 50)
|
.append(co.dotCount() * 50)
|
||||||
.append("px;\">");
|
.append("px;\">");
|
||||||
sb2.append("<h3>").append(co.getAuthor()).append("</h3>");
|
sb2.append("<h3>").append(co.getAuthor()).append("</h3>");
|
||||||
|
|
||||||
sb2.append("<span style=\"color:grey;font-size:80%;\">")
|
sb2.append("<span style=\"color:grey;font-size:80%;\">")
|
||||||
|
.append(Utils.DATE_FORMAT.format(new Date(co.getTimestamp() * 1000))).append("</span><br>\n");
|
||||||
.append(Utils.DATE_FORMAT.format(new Date(co.getTimestamp() * 1000))).append("</span><br>");
|
|
||||||
sb2.append("<span style=\"color:grey;font-size:80%;\">")
|
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("<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>");
|
sb2.append("</div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
// private String id;
|
// private String id;
|
||||||
//
|
//
|
||||||
// private String title;
|
// private String title;
|
||||||
@ -292,18 +386,17 @@ sb2.append("<div style=\"margin-left:")
|
|||||||
// private String description;
|
// private String description;
|
||||||
// private String thumbnail;
|
// private String thumbnail;
|
||||||
// private List<YoutubeComment> comments = new ArrayList<>();
|
// private List<YoutubeComment> comments = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sb2.append("</body></html>");
|
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("<tr>");
|
||||||
}
|
}
|
||||||
sb.append("<table>\n");
|
sb.append("</table>\n");
|
||||||
sb.append("</div></div>");
|
sb.append("</div></div>");
|
||||||
});
|
});
|
||||||
sb.append("""
|
sb.append("""
|
||||||
@ -317,5 +410,6 @@ sb2.append("<div style=\"margin-left:")
|
|||||||
System.out.println("[Warning] Snapshots without videos:");
|
System.out.println("[Warning] Snapshots without videos:");
|
||||||
YoutubeVideo.missingYoutubeVideos.forEach(s -> System.out.println(s));
|
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.
|
// Copyright (C) 2024 the original author or authors.
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// 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
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// 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 dev.mccue.guava.hash.Hashing;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
@ -99,7 +99,7 @@ public class Utils {
|
|||||||
return result;//.substring(0, result.length() - 1);
|
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 originalPath = originalFile.toPath();
|
||||||
Path copied = new File(copiedFile, originalFile.getName()).toPath();
|
Path copied = new File(copiedFile, originalFile.getName()).toPath();
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ public class Utils {
|
|||||||
Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
ex.printStackTrace();
|
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);
|
fileWriter = new FileWriter(file);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
ex.printStackTrace();
|
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 printWriter = new PrintWriter(fileWriter);
|
||||||
printWriter.print(text);
|
printWriter.print(text);
|
||||||
@ -131,7 +131,7 @@ public class Utils {
|
|||||||
try {
|
try {
|
||||||
return new String(Files.readAllBytes(Paths.get(file.getAbsolutePath())));
|
return new String(Files.readAllBytes(Paths.get(file.getAbsolutePath())));
|
||||||
} catch (IOException ex) {
|
} 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);
|
InputStream inputStream = clazz.getResourceAsStream(fileName);
|
||||||
return readFromInputStream(inputStream);
|
return readFromInputStream(inputStream);
|
||||||
} catch (IOException ex) {
|
} 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();
|
return dev.mccue.guava.io.Files.hash(file, Hashing.sha512()).toString();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
System.err.println(ex.getMessage());
|
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/Licenses/license-default.txt to change this license
|
||||||
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
* 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.ArrayList;
|
||||||
import java.util.Collections;
|
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/Licenses/license-default.txt to change this license
|
||||||
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
* 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.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
@ -21,6 +21,7 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -50,6 +51,7 @@ public class YoutubeVideo implements Comparable<YoutubeVideo> {
|
|||||||
private long timestamp;
|
private long timestamp;
|
||||||
private String description;
|
private String description;
|
||||||
private String thumbnail;
|
private String thumbnail;
|
||||||
|
private String miniThumbnail;
|
||||||
private List<YoutubeComment> comments = new ArrayList<>();
|
private List<YoutubeComment> comments = new ArrayList<>();
|
||||||
private String previousVideoId = null;
|
private String previousVideoId = null;
|
||||||
private String nextVideoId = null;
|
private String nextVideoId = null;
|
||||||
@ -60,7 +62,7 @@ public class YoutubeVideo implements Comparable<YoutubeVideo> {
|
|||||||
|
|
||||||
public YoutubeVideo(File mediaDirectory) throws InterruptedException, IOException {
|
public YoutubeVideo(File mediaDirectory) throws InterruptedException, IOException {
|
||||||
File metadataFile = new File(mediaDirectory, "metadata");
|
File metadataFile = new File(mediaDirectory, "metadata");
|
||||||
if (!Main.ALWAYS_COMPUTE_METADATA && metadataFile.exists()) {
|
if (!Main.argAlwaysGenerateMetadata && metadataFile.exists()) {
|
||||||
|
|
||||||
YoutubeVideo yv = new YoutubeVideo();
|
YoutubeVideo yv = new YoutubeVideo();
|
||||||
//new ObjectMapper().readValue(Utils.readTextFromFile(metadataFile), YoutubeVideo.class);
|
//new ObjectMapper().readValue(Utils.readTextFromFile(metadataFile), YoutubeVideo.class);
|
||||||
@ -86,6 +88,7 @@ public class YoutubeVideo implements Comparable<YoutubeVideo> {
|
|||||||
timestamp = Long.parseLong(properties.getProperty("timestamp"));
|
timestamp = Long.parseLong(properties.getProperty("timestamp"));
|
||||||
description = properties.getProperty("description");
|
description = properties.getProperty("description");
|
||||||
thumbnail = properties.getProperty("thumbnail");
|
thumbnail = properties.getProperty("thumbnail");
|
||||||
|
miniThumbnail = properties.getProperty("miniThumbnail");
|
||||||
comments = new ArrayList<>();
|
comments = new ArrayList<>();
|
||||||
JSONArray ja = new JSONArray(properties.getProperty("comments"));
|
JSONArray ja = new JSONArray(properties.getProperty("comments"));
|
||||||
ja.forEach(o -> {
|
ja.forEach(o -> {
|
||||||
@ -96,7 +99,7 @@ public class YoutubeVideo implements Comparable<YoutubeVideo> {
|
|||||||
comments.add(new ObjectMapper().readValue(toString, YoutubeComment.class));
|
comments.add(new ObjectMapper().readValue(toString, YoutubeComment.class));
|
||||||
} catch (JsonProcessingException ex) {
|
} 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) {
|
if (thumbnail == null) {
|
||||||
thumbnail = "";
|
thumbnail = "";
|
||||||
}
|
}
|
||||||
File thumbnailFile = new File(mediaDirectory, "thumbnail.jpg");
|
JSONArray thumbnails = jsonObject.getJSONArray("thumbnails");
|
||||||
if (!thumbnailFile.exists() && thumbnail != null) {
|
for (int i = 0; i < thumbnails.length(); i++) {
|
||||||
try (BufferedInputStream in = new BufferedInputStream(new URL(thumbnail).openStream()); FileOutputStream fileOutputStream = new FileOutputStream(thumbnailFile.getAbsolutePath())) {
|
JSONObject o = (JSONObject) thumbnails.get(i);
|
||||||
byte dataBuffer[] = new byte[1024];
|
if (!o.has("width")) {
|
||||||
int bytesRead;
|
continue;
|
||||||
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
|
} else {
|
||||||
fileOutputStream.write(dataBuffer, 0, bytesRead);
|
int width = o.getInt("width");
|
||||||
|
if (width < (((double)Main.THUMBNAIL_WIDTH) * 0.8d)) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
miniThumbnail = o.getString("url");
|
||||||
System.out.println(e.getMessage());
|
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();
|
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("timestamp", String.valueOf(timestamp));
|
||||||
properties.put("description", description);
|
properties.put("description", description);
|
||||||
properties.put("thumbnail", thumbnail);
|
properties.put("thumbnail", thumbnail);
|
||||||
|
properties.put("minithumbnail", miniThumbnail);
|
||||||
properties.put("comments", new JSONArray(comments).toString());
|
properties.put("comments", new JSONArray(comments).toString());
|
||||||
if (previousVideoId != null) {
|
if (previousVideoId != null) {
|
||||||
properties.put("previousVideoId", previousVideoId);
|
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.
|
* 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.
|
// Copyright (C) 2024 the original author or authors.
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// 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.
|
// 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>
|
* @author <a href="mailto:robertvokac@nanoboot.org">Robert Vokac</a>
|
||||||
* @since 0.0.0
|
* @since 0.0.0
|
||||||
*/
|
*/
|
||||||
public class ArchiveBoxYoutubeHelperException extends RuntimeException {
|
public class YoutubedlFrontendException extends RuntimeException {
|
||||||
|
|
||||||
public ArchiveBoxYoutubeHelperException(String msg) {
|
public YoutubedlFrontendException(String msg) {
|
||||||
super(msg);
|
super(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArchiveBoxYoutubeHelperException(String msg, Exception e) {
|
public YoutubedlFrontendException(String msg, Exception e) {
|
||||||
super(msg, e);
|
super(msg, e);
|
||||||
}
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user