Ostatnio aktywny 1741105227

melanie zrewidował ten Gist 1741105227. Przejdź do rewizji

Brak zmian

melanie zrewidował ten Gist 1741105203. Przejdź do rewizji

Brak zmian

melanie zrewidował ten Gist 1732922313. Przejdź do rewizji

Brak zmian

melanie zrewidował ten Gist 1732918400. Przejdź do rewizji

1 file changed, 131 insertions

lastfm-weekly-report.ts(stworzono plik)

@@ -0,0 +1,131 @@
1 + const LASTFM_API_KEY = process.env.FEED_LASTFM_API_KEY || "";
2 + const LASTFM_USERNAME = process.env.FEED_LASTFM_USERNAME || "";
3 + const LASTFM_API = "https://ws.audioscrobbler.com/2.0/";
4 +
5 + function formatItem({
6 + artist,
7 + image,
8 + name,
9 + playcount,
10 + url,
11 + }: {
12 + artist: { "#text": string };
13 + image?: { "#text": string }[];
14 + name: string;
15 + playcount: string;
16 + url: string;
17 + }) {
18 + return {
19 + name: artist ? `${name} by ${artist?.["#text"]}` : name,
20 + image: image ? image?.at(-1)?.["#text"] : undefined,
21 + playcount,
22 + url,
23 + };
24 + }
25 +
26 + function epochToIso(epoch: string) {
27 + const date = new Date(Number.parseInt(epoch) * 1000);
28 + return date?.toISOString();
29 + }
30 +
31 + function isoToYearAndWeek(iso: string) {
32 + const date = new Date(iso);
33 + const year = date.getFullYear();
34 + const firstOfYear = new Date(year, 0, 1);
35 + const daysSinceFirstOfYear = Math.floor(
36 + (+date - +firstOfYear) / (24 * 60 * 60 * 1000),
37 + );
38 + const week = Math.ceil((date.getDay() + 1 + daysSinceFirstOfYear) / 7);
39 + return {
40 + week,
41 + year,
42 + };
43 + }
44 +
45 + function listToHTML(
46 + arr: {
47 + name: string;
48 + playcount: string;
49 + url: string;
50 + }[],
51 + ) {
52 + return arr
53 + .map(
54 + ({ name, playcount, url }) =>
55 + `<li><a href="${url}">${name}</a> (${playcount} plays)</li>`,
56 + )
57 + .join("");
58 + }
59 +
60 + async function lastFm(method = "") {
61 + const data = await fetch(
62 + `${LASTFM_API}?method=${method}&api_key=${LASTFM_API_KEY}&format=json&user=${LASTFM_USERNAME}`,
63 + );
64 + return await data.json();
65 + }
66 +
67 + async function getWeeklyChartList(limit = 5) {
68 + const data = await lastFm("user.getWeeklyChartList");
69 + return data?.weeklychartlist?.chart?.slice(limit * -1);
70 + }
71 +
72 + async function getWeeklyTrackChart(to: string, from: string, limit = 5) {
73 + const data = await lastFm(`user.getWeeklyTrackChart&from=${from}&to=${to}`);
74 + return data?.weeklytrackchart?.track?.slice(0, limit)?.map(formatItem);
75 + }
76 +
77 + async function getWeeklyAlbumChart(to: string, from: string, limit = 5) {
78 + const data = await lastFm(`user.getWeeklyAlbumChart&from=${from}&to=${to}`);
79 + return data?.weeklyalbumchart?.album?.slice(0, limit)?.map(formatItem);
80 + }
81 +
82 + async function getWeeklyArtistChart(to: string, from: string, limit = 5) {
83 + const data = await lastFm(`user.getWeeklyArtistChart&from=${from}&to=${to}`);
84 + return data?.weeklyartistchart?.artist?.slice(0, limit)?.map(formatItem);
85 + }
86 +
87 + async function buildReport() {
88 + const output = [];
89 + const weeks = await getWeeklyChartList();
90 + for (const week of weeks) {
91 + output.push({
92 + to: week.to,
93 + from: week.from,
94 + tracks: await getWeeklyTrackChart(week.to, week.from),
95 + albums: await getWeeklyAlbumChart(week.to, week.from),
96 + artists: await getWeeklyArtistChart(week.to, week.from),
97 + });
98 + }
99 + return output;
100 + }
101 +
102 + export default async function buildFeedItems() {
103 + const data = await buildReport();
104 + return data
105 + .map(({ to, from, tracks, albums, artists }) => {
106 + const trackList = listToHTML(tracks);
107 + const albumList = listToHTML(albums);
108 + const artistList = listToHTML(artists);
109 + const toIso = epochToIso(to);
110 + const fromIso = epochToIso(from);
111 + const { week, year } = isoToYearAndWeek(fromIso);
112 +
113 + if (!trackList && !albumList && !artistList) {
114 + return;
115 + }
116 +
117 + return {
118 + content_html: [
119 + artistList ? `<h2>Top Artists</h2><ol>${artistList}</ol>` : "",
120 + albumList ? `<h2>Top Albums</h2><ol>${albumList}</ol>` : "",
121 + trackList ? `<h2>Top Tracks</h2><ol>${trackList}</ol>` : "",
122 + ].join(""),
123 + date_published: toIso,
124 + id: `last.fm-${from}-${to}`,
125 + title: "weekly last.fm report",
126 + url: `https://www.last.fm/user/ZicklePop/listening-report/year/${year}/week/${week}`,
127 + tags: ["last.fm"],
128 + };
129 + })
130 + .filter((o) => !!o);
131 + }
Nowsze Starsze