Channels! (work in progress)
This commit is contained in:
parent
ccd462b62a
commit
bee670ffa8
6 changed files with 175 additions and 9 deletions
82
index.js
82
index.js
|
@ -3,7 +3,8 @@ const express = require("express"),
|
|||
fs = require("fs"),
|
||||
ytdl = require("ytdl-core"),
|
||||
bodyParser = require("body-parser"),
|
||||
youtube = require("scrape-youtube")
|
||||
youtube = require("scrape-youtube"),
|
||||
ytExt = require("youtube-ext")
|
||||
|
||||
const PORT = process.env.PORT || 8080
|
||||
|
||||
|
@ -18,6 +19,7 @@ const searchCacheDur = (process.env.SEARCH_DUR || 24) * 3600000
|
|||
|
||||
const playerPath = path.join(resources, 'player.html')
|
||||
const searchPath = path.join(resources, 'searchPage.html')
|
||||
const channelPath = path.join(resources, 'channelPage.html')
|
||||
|
||||
const cssHeader = `<link rel="stylesheet" href="/mainStyle.css">`
|
||||
|
||||
|
@ -93,7 +95,6 @@ app.get("/search", async (req, res) => {
|
|||
var addedHTML = ""
|
||||
|
||||
var channels = results.channels
|
||||
|
||||
if (channels.length > 0) {
|
||||
|
||||
addedHTML += "<h2><br>Channels:</h2>"
|
||||
|
@ -120,11 +121,12 @@ app.get("/search", async (req, res) => {
|
|||
}
|
||||
}
|
||||
|
||||
addedHTML += "<h2><br>Videos:</h2>"
|
||||
if (videos.length > 0) {
|
||||
addedHTML += "<h2><br>Videos:</h2>"
|
||||
|
||||
for (let index = 0; index < videos.length; index++) {
|
||||
const result = videos[index];
|
||||
addedHTML += `
|
||||
for (let index = 0; index < videos.length; index++) {
|
||||
const result = videos[index];
|
||||
addedHTML += `
|
||||
<div class="col-xxl-4 col-sm-6 resultContainer">
|
||||
<div class="videoResult container-fluid row">
|
||||
<div class="col-lg-6 thumbparent">
|
||||
|
@ -149,6 +151,7 @@ app.get("/search", async (req, res) => {
|
|||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
res.send(html.replace("{RESULTS}", addedHTML))
|
||||
|
@ -178,6 +181,73 @@ app.get("/search", async (req, res) => {
|
|||
}
|
||||
})
|
||||
|
||||
app.get("/channel", async (req, res) => {
|
||||
var section = req.query.s || "videos"
|
||||
var channel = req.query.q || "UChcrBJNJLZucy3TPyGyAY2g"
|
||||
|
||||
var html = fs.readFileSync(channelPath).toString()
|
||||
|
||||
var info = await ytExt.channelInfo(channel, { includeVideos: true })
|
||||
|
||||
var videos = info.videos
|
||||
console.log(info)
|
||||
var addedHTML = ""
|
||||
if (section == "videos") {
|
||||
for (let index = 0; index < videos.length; index++) {
|
||||
const result = videos[index];
|
||||
if (result.title != undefined) {
|
||||
addedHTML += `
|
||||
<div class="col-xxl-4 col-sm-6 resultContainer">
|
||||
<div class="videoResult container-fluid row">
|
||||
<div class="col-lg-6 thumbparent">
|
||||
<a class="videoLink" href="/watch?v=${result.id}">
|
||||
<img class="thumbnail" src="${result.thumbnails[0].url}">
|
||||
<p style="display: block; text-align: left;">${result.duration.pretty}</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<a class="videoLink" href="/watch?v=${result.id}">
|
||||
<p style="font-size: 1.25rem;">${result.title || "No Title Found"}</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
} else {
|
||||
addedHTML = ""
|
||||
}
|
||||
|
||||
}
|
||||
} else if (section == "about") {
|
||||
addedHTML += `
|
||||
<div id="description">
|
||||
<h2>Description: <br></h2>
|
||||
<p>${info.description}</p>
|
||||
<p>Subscribers: ${info.subscribers.pretty}
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
if (addedHTML == "") {
|
||||
addedHTML = `<h2>Failed to load ${section}! Sorry... T^T<h2>`
|
||||
}
|
||||
|
||||
html = html.replace("{RESULTS}", addedHTML)
|
||||
|
||||
html = html.replace("{CHANNEL_NAME}", info.name)
|
||||
html = html.replace("{CHANNEL_DESC}", info.description)
|
||||
|
||||
for (let index = 0; index < 3; index++) {
|
||||
html = html.replace("{CHANNEL_ID}", info.id)
|
||||
|
||||
}
|
||||
|
||||
html = html.replace("{CHANNEL_PFP}", info.thumbnails[0].url)
|
||||
html = html.replace("{SUB_COUNT}", info.subscribers.pretty)
|
||||
|
||||
res.send(html)
|
||||
})
|
||||
|
||||
app.get("/video", async (req, res) => {
|
||||
var id = req.query.q || req.query.v
|
||||
var range = req.headers.range
|
||||
|
|
28
package-lock.json
generated
28
package-lock.json
generated
|
@ -12,9 +12,18 @@
|
|||
"body-parser": "^1.20.2",
|
||||
"express": "^4.18.2",
|
||||
"scrape-youtube": "^2.4.0",
|
||||
"youtube-ext": "^1.1.16",
|
||||
"ytdl-core": "^4.11.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz",
|
||||
"integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||
|
@ -699,6 +708,17 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "5.27.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.27.0.tgz",
|
||||
"integrity": "sha512-l3ydWhlhOJzMVOYkymLykcRRXqbUaQriERtR70B9LzNkZ4bX52Fc8wbTDneMiwo8T+AemZXvXaTx+9o5ROxrXg==",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
|
@ -723,6 +743,14 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/youtube-ext": {
|
||||
"version": "1.1.16",
|
||||
"resolved": "https://registry.npmjs.org/youtube-ext/-/youtube-ext-1.1.16.tgz",
|
||||
"integrity": "sha512-vyzHSwxlCAwqWUxZKJ/5g139BgnbmZFTy9I0nxDwqlbAh74dB1LjayCoB5BgLaaIkSMruEQwlf5bF+EeR235qA==",
|
||||
"dependencies": {
|
||||
"undici": "^5.26.3"
|
||||
}
|
||||
},
|
||||
"node_modules/ytdl-core": {
|
||||
"version": "4.11.5",
|
||||
"resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.11.5.tgz",
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"body-parser": "^1.20.2",
|
||||
"express": "^4.18.2",
|
||||
"scrape-youtube": "^2.4.0",
|
||||
"youtube-ext": "^1.1.16",
|
||||
"ytdl-core": "^4.11.5"
|
||||
}
|
||||
}
|
||||
|
|
51
resources/channelPage.html
Normal file
51
resources/channelPage.html
Normal file
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"
|
||||
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="./mainStyle.css">
|
||||
|
||||
<title>SimpleTube</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="titleBar" class="row container-fluid">
|
||||
<div class="col-6">
|
||||
<h1><a href="/">Simpletube</a></h1>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<form action="/search">
|
||||
<input type="text" placeholder="Search" name="q">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="channelBar" class="row container-fluid">
|
||||
<p>* Channels are still a work in progress.</p>
|
||||
<div class="col-sm-6">
|
||||
<img src="{CHANNEL_PFP}" class="pfp">
|
||||
<p>Subscribers: {SUB_COUNT}</p>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<h1>{CHANNEL_NAME}</h1>
|
||||
<p>{CHANNEL_DESC}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-6">
|
||||
<a class="videoLink channelLink" href="?q={CHANNEL_ID}&s=video">Videos</a>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<a class="videoLink channelLink" href="?q={CHANNEL_ID}&s=about">About</a>
|
||||
</div>
|
||||
</div>
|
||||
<main>
|
||||
<div class="container-fluid row" style="margin: 0; padding: 0;">
|
||||
{RESULTS}
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -25,7 +25,7 @@
|
|||
</div>
|
||||
<main>
|
||||
<h1>Welcome to SimpleTube</h1>
|
||||
<p>SimpleTube is a Youtube client that aims to be free of Javascript, as small as possible, and lack annoyances.
|
||||
<p>SimpleTube is a Youtube client that aims to be free and fast. (and have no ads!)
|
||||
<br>
|
||||
Currently SimpleTube does not have a trending tab or anything, so please use the search function at the top!
|
||||
<br>
|
||||
|
|
|
@ -124,7 +124,7 @@ p {
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
/* @media (max-width: 720px) {
|
||||
.resultContainer {
|
||||
max-width: 450px;
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ p {
|
|||
.resultContainer {
|
||||
max-width: 550px;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
.resultContainer {
|
||||
margin: 0 auto;
|
||||
|
@ -194,4 +194,20 @@ main {
|
|||
|
||||
hr {
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
#channelBar {
|
||||
background-color: rgb(15, 10, 25);
|
||||
border-bottom: 2px gray solid;
|
||||
padding: 20px;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.channelLink {
|
||||
color: white;
|
||||
font-size: 1.5rem;
|
||||
border: 2px white solid;
|
||||
display: inline-block;
|
||||
padding: 10px
|
||||
}
|
Loading…
Reference in a new issue