anime quality, https

This commit is contained in:
Jon Dough
2024-03-29 06:38:52 +00:00
parent 96da42f1cf
commit ddf88ed2fc
8 changed files with 72 additions and 40 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text eol=lf

4
.gitignore vendored
View File

@@ -4,4 +4,6 @@ static_assets
favourites_info.json
*.js
package-lock.json
build
build
*.key
*.cert

2
.torrc
View File

@@ -1,4 +1,4 @@
HiddenServiceDir ./tor/hidden_service
HiddenServicePort 80 0.0.0.0:8043
ContactInfo Billy Bob <billybob@example.com>

View File

@@ -4,6 +4,8 @@ Most of the code is a modification of [hedgeblog](https://github.com/jetstream0/
Since TOR is pretty slow to download large files (eg, videos), the videos are streamed so load time isn't as bad as one might expect (HTTP protocol is amazing, browsers are amazing).
Optionally, this site can be run locally or on the regular web with HTTP(S).
# Running
After first cloning or downloading the repository:

View File

@@ -1,5 +1,5 @@
import * as path from 'path';
import { readdirSync } from 'fs';
import { readdirSync, existsSync } from 'fs';
import { Renderer } from './ryuji.js';
import { Builder } from './saki.js';
import _favourites_info from './favourites_info.json';
@@ -23,21 +23,21 @@ interface DirectoryVars {
chapters: string[]; //name of all the chapters
}
interface AnimeVars {
interface ListingVars {
listing: Listing;
chapter: string;
next_chapter?: string | boolean;
prev_chapter?: string | boolean;
}
type MusicVars = AnimeVars;
type MusicVars = ListingVars;
interface MangaVars {
listing: Listing;
chapter: string;
interface AnimeVars extends ListingVars {
higher_quality_available: boolean;
};
interface MangaVars extends ListingVars {
images: string[]; //file names of all the images in the chapter
next_chapter?: string | boolean;
prev_chapter?: string | boolean;
}
const favourites_info: Record<string, FavouritesInfo> = _favourites_info;
@@ -92,48 +92,45 @@ let manga_pages_count: number = 0;
for (let i = 0; i < listings.length; i++) {
const listing: Listing = listings[i];
directory_serve_paths.push(`/${listing.type}/${listing.name}`);
const chapters: string[] = readdirSync(path.join(__dirname, `/static_assets/${listing.type}_assets/${listing.name}`), { withFileTypes: true }).map((d) => d.name.replace(".mp4", "").replace(".mp3", ""));
const chapters: string[] = readdirSync(path.join(__dirname, `/static_assets/${listing.type}_assets/${listing.name}`), { withFileTypes: true }).map((d) => d.name.replace(".mp4", "").replace(".mp3", "")).filter(
(chapter: string) =>
!(listing.type === "anime" && chapter.endsWith("_higher_quality"))
); //filter out the higher quality anime videos, we want those to be on the same page as the low quality (select quality with dropdown), not listed as a separate episode
directory_vars.push({
listing,
chapters,
});
if (listing.type === "anime") {
for (let j = 0; j < chapters.length; j++) {
const chapter: string = chapters[j];
anime_serve_paths.push(`/${listing.type}/${listing.name}/${chapter}`);
for (let j = 0; j < chapters.length; j++) {
const chapter: string = chapters[j];
const base = {
listing,
chapter,
next_chapter: chapters[j + 1] ? chapters[j + 1] : false,
prev_chapter: j > 0 ? chapters[j - 1] : false,
};
const serve_path = `/${listing.type}/${listing.name}/${chapter}`;
if (listing.type === "anime") {
anime_serve_paths.push(serve_path);
anime_vars.push({
listing,
chapter,
next_chapter: chapters[j + 1] ? chapters[j + 1] : false,
prev_chapter: j > 0 ? chapters[j - 1] : false,
...base,
higher_quality_available: existsSync(path.join(__dirname, `/static_assets/${listing.type}_assets/${listing.name}`, `${chapter}_higher_quality.mp4`)),
});
}
} else if (listing.type === "manga") {
for (let j = 0; j < chapters.length; j++) {
const chapter: string = chapters[j];
manga_serve_paths.push(`/${listing.type}/${listing.name}/${chapter}`);
} else if (listing.type === "manga") {
manga_serve_paths.push(serve_path);
const images: string[] = readdirSync(path.join(__dirname, `/static_assets/${listing.type}_assets/${listing.name}/${chapter}`), { withFileTypes: true }).map((d) => d.name);
manga_pages_count += images.length;
manga_vars.push({
listing,
chapter,
...base,
images,
next_chapter: chapters[j + 1] ? chapters[j + 1] : false,
prev_chapter: j > 0 ? chapters[j - 1] : false,
});
}
} else if (listing.type === "music") {
for (let j = 0; j < chapters.length; j++) {
const chapter: string = chapters[j];
} else if (listing.type === "music") {
music_serve_paths.push(serve_path);
songs.push(`${listing.name}/${chapter}`);
music_serve_paths.push(`/${listing.type}/${listing.name}/${chapter}`);
music_vars.push({
listing,
chapter,
next_chapter: chapters[j + 1] ? chapters[j + 1] : false,
prev_chapter: j > 0 ? chapters[j - 1] : false,
...base,
});
}
//
}
}

14
host.ts
View File

@@ -1,4 +1,5 @@
import { createServer } from 'http';
import { createServer as createServerHttps } from 'https';
import * as path from 'path';
import { existsSync, readFileSync, statSync, createReadStream } from 'fs';
import { createHash } from 'crypto';
@@ -16,7 +17,7 @@ function get_password(date: Date = new Date()): string {
const port: number = 8043;
const stream_chunk_size: number = 2 * 1024 * 1024; //2 MiB
createServer((req, res) => {
const request_handler = (req, res) => {
const todays_password: string = get_password();
let req_path: string;
if (req.url.includes("..")) {
@@ -162,6 +163,15 @@ createServer((req, res) => {
}
//end response
return res.end();
}).listen(port);
};
if (process.argv[2] === "--https") {
createServerHttps({
key: readFileSync("server.key"),
cert: readFileSync("server.cert"),
}, request_handler).listen(port + 1);
console.log(`Hosting HTTPS on port ${port + 1}`);
}
createServer(request_handler).listen(port);
console.log(`Hosting on port ${port}`);

View File

@@ -7,6 +7,7 @@
"compile": "tsc -p .",
"build": "node build.js",
"host": "node host.js",
"host-https": "node host.js --https",
"start": "npm run compile && npm run build && npm run host"
},
"repository": {

View File

@@ -24,7 +24,26 @@
<div id="main">
<div class="anime">
<h2 style="margin: 0;">[[ listing.name ]] [[ chapter ]]</h2>
<video src="/anime_assets/[[ listing.name ]]/[[ chapter ]].mp4" controls></video>
<video id="video" src="/anime_assets/[[ listing.name ]]/[[ chapter ]].mp4" controls></video>
<br/>
[[ if:higher_quality_available ]]
<label for="quality">Choose quality:</label>
<select id="quality" onchange="quality_change()">
<option selected value="low">Low/Regular Quality</option>
<option value="high">Higher Quality</option>
</select>
<script>
function quality_change() {
let video = document.getElementById("video");
if (document.getElementById("quality").value === "low") {
video.src = "/anime_assets/[[ listing.name ]]/[[ chapter ]].mp4";
} else if (document.getElementById("quality").value === "high") {
video.src = "/anime_assets/[[ listing.name ]]/[[ chapter ]]_higher_quality.mp4";
}
}
quality_change();
</script>
[[ endif ]]
[[ component:nav ]]
</div>
</div>