mirror of
https://github.com/BradNut/personal-website-sveltekit
synced 2025-09-08 23:20:18 +00:00
Adding fetch bandcamp albums and showing them on the main home page, also caching response.
This commit is contained in:
parent
a0bebf3f5a
commit
0f5248bee0
9 changed files with 163 additions and 6 deletions
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"Bandcamp",
|
||||||
"bradleyshellnut",
|
"bradleyshellnut",
|
||||||
"iconify",
|
"iconify",
|
||||||
"Mullvad",
|
"Mullvad",
|
||||||
|
|
|
||||||
90
src/lib/components/bandcamp/index.svelte
Normal file
90
src/lib/components/bandcamp/index.svelte
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { Album } from "$root/lib/types/album";
|
||||||
|
|
||||||
|
|
||||||
|
export let albums: Album[];
|
||||||
|
const displayAlbums =
|
||||||
|
albums?.length > 6 ? albums.slice(0, 6) : albums;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2>Currently listening to:</h2>
|
||||||
|
<div class="albumsStyles">
|
||||||
|
{#each displayAlbums as album}
|
||||||
|
<div>
|
||||||
|
<figure>
|
||||||
|
<a
|
||||||
|
title={`Link to ${album.title} by ${album.artist}`}
|
||||||
|
target="_blank"
|
||||||
|
href={album.url}
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={`https://images.weserv.nl/?url=${encodeURIComponent(
|
||||||
|
album.artwork
|
||||||
|
)}&w=230&h=230`}
|
||||||
|
alt={`Album art for ${album.title}`}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</figure>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
href={album.url}
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
<h3>{album.title.length > 20 ? `${album.title.slice(0, 20)}...` : album.title}</h3>
|
||||||
|
<h3>by {album.artist}</h3>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
.albumsStyles {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(auto, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
@media (max-width: 1000px) {
|
||||||
|
grid-template-columns: repeat(2, minmax(150px, 1fr));
|
||||||
|
img {
|
||||||
|
width: 230px;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 575px) {
|
||||||
|
height: 500px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 12px;
|
||||||
|
}
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: var(--lightGrey) var(--darkGrey);
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: var(--darkGrey);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color: var(--lightGrey);
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 3px solid var(--darkGrey);
|
||||||
|
}
|
||||||
|
grid-template-columns: minmax(230px, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.albumStyles {
|
||||||
|
display: grid;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
@media (max-width: 550px) {
|
||||||
|
grid-template-columns: 0.75fr 0.75fr;
|
||||||
|
font-size: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
6
src/lib/types/album.ts
Normal file
6
src/lib/types/album.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
export type Album = {
|
||||||
|
url: string;
|
||||||
|
artwork: string;
|
||||||
|
title: string;
|
||||||
|
artist: string;
|
||||||
|
};
|
||||||
40
src/lib/util/fetchBandcampAlbums.ts
Normal file
40
src/lib/util/fetchBandcampAlbums.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
// import * as htmlparser2 from 'htmlparser2';
|
||||||
|
import scrapeIt from 'scrape-it';
|
||||||
|
import type { Album } from '../types/album';
|
||||||
|
|
||||||
|
export async function fetchBandcampAlbums() {
|
||||||
|
try {
|
||||||
|
const { data } = await scrapeIt('https://bandcamp.com/royvalentine', {
|
||||||
|
collectionItems: {
|
||||||
|
listItem: '.collection-item-container',
|
||||||
|
data: {
|
||||||
|
url: {
|
||||||
|
selector: '.collection-title-details > a.item-link',
|
||||||
|
attr: 'href'
|
||||||
|
},
|
||||||
|
artwork: {
|
||||||
|
selector: 'div.collection-item-art-container a img',
|
||||||
|
attr: 'src'
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
selector: 'span.item-link-alt > div.collection-item-title'
|
||||||
|
},
|
||||||
|
artist: {
|
||||||
|
selector: 'span.item-link-alt > div.collection-item-artist'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const albums: Album[] = data?.collectionItems || [];
|
||||||
|
console.log(`Albums ${JSON.stringify(albums)}`);
|
||||||
|
|
||||||
|
if (albums && albums?.length > 0) {
|
||||||
|
return albums;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/routes/+page.server.ts
Normal file
12
src/routes/+page.server.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import type { PageServerLoad } from './lib/$types';
|
||||||
|
import { fetchBandcampAlbums } from '$root/lib/util/fetchBandcampAlbums';
|
||||||
|
|
||||||
|
export const load: PageServerLoad = async ({ setHeaders }) => {
|
||||||
|
const albums = await fetchBandcampAlbums();
|
||||||
|
setHeaders({
|
||||||
|
'cache-control': 'max-age=43200'
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
albums
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import SEO from '$root/lib/components/SEO.svelte';
|
import type { PageData } from './$types';
|
||||||
|
import Bandcamp from '$lib/components/bandcamp/index.svelte';
|
||||||
|
import SEO from '$lib/components/SEO.svelte';
|
||||||
|
import type { Album } from '$root/lib/types/album';
|
||||||
|
|
||||||
// export let data: PageData;
|
export let data: PageData;
|
||||||
|
let albums: Album[];
|
||||||
|
$: ({ albums } = data);
|
||||||
|
|
||||||
const userNames = {
|
const userNames = {
|
||||||
github: 'BradNut',
|
github: 'BradNut',
|
||||||
linkedIn: 'bradley-shellnut',
|
linkedIn: 'bradley-shellnut',
|
||||||
|
|
@ -57,7 +63,7 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="social-info">
|
<div class="social-info">
|
||||||
<!-- <Bandcamp /> -->
|
<Bandcamp {albums} />
|
||||||
<!-- <Articles /> -->
|
<!-- <Articles /> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ export async function fetchArticlesApi(
|
||||||
articles.push({
|
articles.push({
|
||||||
tags,
|
tags,
|
||||||
title: article.title,
|
title: article.title,
|
||||||
url: article.url,
|
url: new URL(article.url),
|
||||||
hashed_url: article.hashed_url,
|
hashed_url: article.hashed_url,
|
||||||
reading_time: article.reading_time,
|
reading_time: article.reading_time,
|
||||||
preview_picture: article.preview_picture,
|
preview_picture: article.preview_picture,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
aria-label={`Link to ${article.title}`}
|
aria-label={`Link to ${article.title}`}
|
||||||
href={article.url.href}
|
href={article.url}
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
{article.title}
|
{article.title}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@
|
||||||
import shellnutArchitectWebsiteBlurred from "$lib/assets/images/Mark_Shellnut_Architect.png?w=100&png&blur=10";
|
import shellnutArchitectWebsiteBlurred from "$lib/assets/images/Mark_Shellnut_Architect.png?w=100&png&blur=10";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<SEO title="Portfolio" />
|
<svelte:head>
|
||||||
|
<title>Portfolio | Bradley Shellnut</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
<h1>Portfolio!</h1>
|
<h1>Portfolio!</h1>
|
||||||
<div class="portfolioTabStyles">
|
<div class="portfolioTabStyles">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue