generated from nhcarrigan/template
feat(books,games,music): redirect to library.nhcarrigan.com
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 47s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 47s
Remove books.sh and songs.sh scripts, replacing the interactive library pages with simple redirects to the centralised library site.
This commit is contained in:
@@ -1,36 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Initialize an empty string to hold the list of books in JSON-like format
|
|
||||||
books=""
|
|
||||||
filecount=$(find "/mnt/c/Users/accou/Documents/iDrive/Cloud-Drive_accounts@nhcarrigan.com/Books" -type f | wc -l)
|
|
||||||
echo "Found $filecount files."
|
|
||||||
current=0
|
|
||||||
|
|
||||||
# Loop over each file found by find
|
|
||||||
while IFS= read -r -d $'\0' file; do
|
|
||||||
current=$((current + 1))
|
|
||||||
echo -ne "Processing $current/$filecount\r"
|
|
||||||
title=$(exiftool "$file" | grep "^Title\s*:" | cut -d ":" -f 2 | sed -e 's/^[[:space:]]*//')
|
|
||||||
author=$(exiftool "$file" | grep "^Creator\s*:" | cut -d ":" -f 2 | sed -e 's/^[[:space:]]*//')
|
|
||||||
|
|
||||||
if [ -z "$title" ]; then
|
|
||||||
# remove extension from the filename
|
|
||||||
title=$(basename "$file" | sed -e 's/\.[^.]*$//')
|
|
||||||
fi
|
|
||||||
if [ -z "$author" ]; then
|
|
||||||
author=$(exiftool "$file" | grep "^Author\s*:" | cut -d ":" -f 2 | sed -e 's/^[[:space:]]*//')
|
|
||||||
fi
|
|
||||||
if [ -z "$author" ]; then
|
|
||||||
author="Unknown Author"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# use jq to add the book to the list
|
|
||||||
books="$books$(jq -n --arg title "$title" --arg author "$author" '{title: $title, author: $author}'),"
|
|
||||||
done < <(find "/mnt/c/Users/accou/Documents/iDrive/Cloud-Drive_accounts@nhcarrigan.com/Books" -type f -print0)
|
|
||||||
|
|
||||||
# Remove trailing comma and add square brackets to complete the list
|
|
||||||
books="[${books%,}]"
|
|
||||||
|
|
||||||
# Write to ./books/books.json
|
|
||||||
echo "$books" > ./books/books.json
|
|
||||||
echo -ne "Done!\r"
|
|
||||||
+6
-105
@@ -4,114 +4,15 @@
|
|||||||
<title>Naomi's Book Library</title>
|
<title>Naomi's Book Library</title>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="description" content="An interactive explorer for the books Naomi reads." />
|
<meta name="description" content="Naomi's book library has moved to library.nhcarrigan.com." />
|
||||||
<script src="https://cdn.nhcarrigan.com/headers/index.js" async defer></script>
|
<script src="https://cdn.nhcarrigan.com/headers/index.js" async defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<h1>Naomi's Book Library</h1>
|
<h1>Naomi's Book Library</h1>
|
||||||
<section>
|
<section>
|
||||||
<p>An interactive explorer for the books Naomi reads.</p>
|
<p>This page has moved! You can find Naomi's book library at <a href="https://library.nhcarrigan.com">library.nhcarrigan.com</a>.</p>
|
||||||
<p id="count">Loading library...</p>
|
</section>
|
||||||
</section>
|
|
||||||
<div style="display: none;">
|
|
||||||
<span>Search Authors: </span>
|
|
||||||
<input type="text" id="author" />
|
|
||||||
</div>
|
|
||||||
<div style="display: none;">
|
|
||||||
<span>Search Titles: </span>
|
|
||||||
<input type="text" id="title" />
|
|
||||||
</div>
|
|
||||||
<div style="display: none;">
|
|
||||||
<button type="button" id="clear">Clear Filters</button>
|
|
||||||
</div>
|
|
||||||
<table id="books">
|
|
||||||
|
|
||||||
</table>
|
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
</html>
|
||||||
const authorQuery = document.getElementById('author');
|
|
||||||
const titleQuery = document.getElementById('title');
|
|
||||||
const resetButton = document.getElementById('clear');
|
|
||||||
const bookTable = document.getElementById('books');
|
|
||||||
const filterBooks = (author, title) => {
|
|
||||||
let result = [...bookList];
|
|
||||||
if(author) {
|
|
||||||
result = result.filter(book => book.author.toLowerCase().includes(author.toLowerCase()));
|
|
||||||
}
|
|
||||||
if(title) {
|
|
||||||
result = result.filter(book => book.title.toLowerCase().includes(title.toLowerCase()));
|
|
||||||
}
|
|
||||||
resetButton.parentElement.style.display = author || title ? "block" : "none";
|
|
||||||
document.getElementById('count').innerText = author || title ? `Filtered to ${result.length} books from ${bookList.length}.` : `Naomi currently has ${bookList.length} books.`;
|
|
||||||
updateTable(result);
|
|
||||||
}
|
|
||||||
const loadBooks = (books) => {
|
|
||||||
bookList.push(...books);
|
|
||||||
authorQuery.value = "";
|
|
||||||
titleQuery.value = "";
|
|
||||||
authorQuery.parentElement.style.display = "block";
|
|
||||||
titleQuery.parentElement.style.display = "block";
|
|
||||||
document.getElementById('count').innerText = `Naomi currently has ${books.length} books.`;
|
|
||||||
updateTable(books);
|
|
||||||
}
|
|
||||||
const updateTable = (books) => {
|
|
||||||
books = books.sort((a, b) => a.title.localeCompare(b.title));
|
|
||||||
bookTable.innerHTML = "";
|
|
||||||
const header = document.createElement('tr');
|
|
||||||
const authorHeader = document.createElement('th');
|
|
||||||
authorHeader.innerText = "Author";
|
|
||||||
const titleHeader = document.createElement('th');
|
|
||||||
titleHeader.innerText = "Title";
|
|
||||||
header.appendChild(titleHeader);
|
|
||||||
header.appendChild(authorHeader);
|
|
||||||
bookTable.appendChild(header);
|
|
||||||
books.forEach(book => {
|
|
||||||
const row = document.createElement('tr');
|
|
||||||
const author = document.createElement('td');
|
|
||||||
author.innerText = book.author;
|
|
||||||
const title = document.createElement('td');
|
|
||||||
title.innerText = book.title;
|
|
||||||
row.appendChild(title);
|
|
||||||
row.appendChild(author);
|
|
||||||
bookTable.appendChild(row);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const bookList = [];
|
|
||||||
fetch("./books.json").then(res => res.json()).then(data => loadBooks(data))
|
|
||||||
|
|
||||||
authorQuery?.addEventListener("input", (e) => filterBooks(e.target.value, titleQuery.value));
|
|
||||||
titleQuery?.addEventListener("input", (e) => filterBooks(authorQuery.value, e.target.value));
|
|
||||||
resetButton?.addEventListener("click", () => {
|
|
||||||
authorQuery.value = "";
|
|
||||||
titleQuery.value = "";
|
|
||||||
filterBooks("", "");
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
tr:nth-of-type(even) {
|
|
||||||
background-color: #db7093dd;
|
|
||||||
color: #ffefef;
|
|
||||||
}
|
|
||||||
input {
|
|
||||||
background:var(--foreground);
|
|
||||||
color:var(--background);
|
|
||||||
border:1px solid white;
|
|
||||||
border-radius:10px;
|
|
||||||
padding:.25rem
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
background:var(--foreground);
|
|
||||||
color:var(--background);
|
|
||||||
border:1px solid white;
|
|
||||||
border-radius:10px;
|
|
||||||
padding:.25rem;
|
|
||||||
cursor:url('https://cdn.nhcarrigan.com/cursors/pointer.cur'), pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</html>
|
|
||||||
|
|||||||
+3
-24
@@ -4,36 +4,15 @@
|
|||||||
<title>Games</title>
|
<title>Games</title>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="description" content="These are the various games we have developed!" />
|
<meta name="description" content="Naomi's game library has moved to library.nhcarrigan.com." />
|
||||||
<script src="https://cdn.nhcarrigan.com/headers/index.js" async defer></script>
|
<script src="https://cdn.nhcarrigan.com/headers/index.js" async defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<h1>Games</h1>
|
<h1>Games</h1>
|
||||||
<section>
|
<section>
|
||||||
<p>These are the various games we have developed.</p>
|
<p>This page has moved! You can find Naomi's game library at <a href="https://library.nhcarrigan.com">library.nhcarrigan.com</a>.</p>
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>Links</h2>
|
|
||||||
<p>
|
|
||||||
<a href="https://beccalia.nhcarrigan.com/">
|
|
||||||
🩵 Beccalia Series
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a href="https://goblin.nhcarrigan.com">
|
|
||||||
🩷 Ruu's Goblin Quest
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a href="https://loan.nhcarrigan.com">
|
|
||||||
🩵 Life of a Naomi
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We are currently on a hiatus from game development. But we may return in the future - be sure to join our Discord server so you don't miss any updates~!
|
|
||||||
</p>
|
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+6
-114
@@ -4,123 +4,15 @@
|
|||||||
<title>Naomi's Music Library</title>
|
<title>Naomi's Music Library</title>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="description" content="An interactive explorer for the music Naomi listens to." />
|
<meta name="description" content="Naomi's music library has moved to library.nhcarrigan.com." />
|
||||||
<script src="https://cdn.nhcarrigan.com/headers/index.js" async defer></script>
|
<script src="https://cdn.nhcarrigan.com/headers/index.js" async defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<h1>Naomi's Music Library</h1>
|
<h1>Naomi's Music Library</h1>
|
||||||
<section>
|
<section>
|
||||||
<p>An interactive explorer for the music Naomi listens to.</p>
|
<p>This page has moved! You can find Naomi's music library at <a href="https://library.nhcarrigan.com">library.nhcarrigan.com</a>.</p>
|
||||||
<p id="count">Loading library...</p>
|
</section>
|
||||||
</section>
|
|
||||||
<div style="display: none;">
|
|
||||||
<span>Search Artists: </span>
|
|
||||||
<input type="text" id="artist" />
|
|
||||||
</div>
|
|
||||||
<div style="display: none;">
|
|
||||||
<span>Search Titles: </span>
|
|
||||||
<input type="text" id="title" />
|
|
||||||
</div>
|
|
||||||
<div style="display: none;">
|
|
||||||
<button type="button" id="clear">Clear Filters</button>
|
|
||||||
</div>
|
|
||||||
<table id="songs">
|
|
||||||
|
|
||||||
</table>
|
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
</html>
|
||||||
const artistQuery = document.getElementById('artist');
|
|
||||||
const titleQuery = document.getElementById('title');
|
|
||||||
const resetButton = document.getElementById('clear');
|
|
||||||
const songTable = document.getElementById('songs');
|
|
||||||
const filterSongs = (artist, title) => {
|
|
||||||
let result = [...songList];
|
|
||||||
if(artist) {
|
|
||||||
result = result.filter(song => song.artist.toLowerCase().includes(artist.toLowerCase()));
|
|
||||||
}
|
|
||||||
if(title) {
|
|
||||||
result = result.filter(song => song.title.toLowerCase().includes(title.toLowerCase()));
|
|
||||||
}
|
|
||||||
resetButton.parentElement.style.display = artist || title ? "block" : "none";
|
|
||||||
document.getElementById('count').innerText = artist || title ? `Filtered to ${result.length} songs from ${songList.length}.` : `Naomi currently has ${songList.length} songs.`;
|
|
||||||
updateTable(result);
|
|
||||||
}
|
|
||||||
const loadSongs = (songs) => {
|
|
||||||
songList.push(...songs);
|
|
||||||
artistQuery.value = "";
|
|
||||||
titleQuery.value = "";
|
|
||||||
artistQuery.parentElement.style.display = "block";
|
|
||||||
titleQuery.parentElement.style.display = "block";
|
|
||||||
document.getElementById('count').innerText = `Naomi currently has ${songs.length} songs.`;
|
|
||||||
updateTable(songs);
|
|
||||||
}
|
|
||||||
const updateTable = (songs) => {
|
|
||||||
songs = songs.sort((a, b) => a.title.localeCompare(b.title));
|
|
||||||
songTable.innerHTML = "";
|
|
||||||
const header = document.createElement('tr');
|
|
||||||
const artistHeader = document.createElement('th');
|
|
||||||
artistHeader.innerText = "Artist";
|
|
||||||
const titleHeader = document.createElement('th');
|
|
||||||
titleHeader.innerText = "Title";
|
|
||||||
header.appendChild(titleHeader);
|
|
||||||
header.appendChild(artistHeader);
|
|
||||||
songTable.appendChild(header);
|
|
||||||
songs.forEach(song => {
|
|
||||||
const row = document.createElement('tr');
|
|
||||||
const artist = document.createElement('td');
|
|
||||||
artist.innerText = song.artist;
|
|
||||||
const title = document.createElement('td');
|
|
||||||
title.innerText = song.title;
|
|
||||||
row.appendChild(title);
|
|
||||||
row.appendChild(artist);
|
|
||||||
songTable.appendChild(row);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const songList = [];
|
|
||||||
fetch("./songs.json").then(res => res.json()).then(data => loadSongs(data))
|
|
||||||
|
|
||||||
artistQuery?.addEventListener("input", (e) => filterSongs(e.target.value, titleQuery.value));
|
|
||||||
titleQuery?.addEventListener("input", (e) => filterSongs(artistQuery.value, e.target.value));
|
|
||||||
resetButton?.addEventListener("click", () => {
|
|
||||||
artistQuery.value = "";
|
|
||||||
titleQuery.value = "";
|
|
||||||
filterSongs("", "");
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
table-layout: fixed;
|
|
||||||
}
|
|
||||||
tr:nth-of-type(even) {
|
|
||||||
background-color: var(--foreground);
|
|
||||||
color: var(--background);
|
|
||||||
}
|
|
||||||
input {
|
|
||||||
background:var(--foreground);
|
|
||||||
color:var(--background);
|
|
||||||
border:1px solid white;
|
|
||||||
border-radius:10px;
|
|
||||||
padding:.25rem
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
background:var(--foreground);
|
|
||||||
color:var(--background);
|
|
||||||
border:1px solid white;
|
|
||||||
border-radius:10px;
|
|
||||||
padding:.25rem;
|
|
||||||
cursor:url('https://cdn.nhcarrigan.com/cursors/pointer.cur'), pointer;
|
|
||||||
}
|
|
||||||
tr {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
td {
|
|
||||||
max-width: 50%;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</html>
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Initialize an empty string to hold the list of songs in JSON-like format
|
|
||||||
songs=""
|
|
||||||
filecount=$(find "/mnt/c/Users/accou/Music" -type f | wc -l)
|
|
||||||
echo "Found $filecount files."
|
|
||||||
current=0
|
|
||||||
|
|
||||||
# Loop over each file found by find
|
|
||||||
while IFS= read -r -d $'\0' file; do
|
|
||||||
current=$((current + 1))
|
|
||||||
echo -ne "Processing $current/$filecount\r"
|
|
||||||
title=$(mid3v2 -l "$file" | grep "TIT2\|TT2" | cut -d "=" -f 2)
|
|
||||||
artist=$(mid3v2 -l "$file" | grep "TPE1\|TP1" | cut -d "=" -f 2)
|
|
||||||
if [ -z "$title" ]; then
|
|
||||||
# remove .mp3 from the title
|
|
||||||
title=$(basename "$file" | sed -e 's/\.mp3//g')
|
|
||||||
fi
|
|
||||||
if [ -z "$artist" ]; then
|
|
||||||
artist="Unknown Artist"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# use jq to add the song to the list
|
|
||||||
songs="$songs$(jq -n --arg title "$title" --arg artist "$artist" '{title: $title, artist: $artist}'),"
|
|
||||||
done < <(find "/mnt/c/Users/accou/Music" -type f -print0)
|
|
||||||
|
|
||||||
# Remove trailing comma and add square brackets to complete the list
|
|
||||||
songs="[${songs%,}]"
|
|
||||||
|
|
||||||
# Write to ./music/songs.json
|
|
||||||
echo "$songs" > ./music/songs.json
|
|
||||||
echo -ne "Done!\r"
|
|
||||||
Reference in New Issue
Block a user