Son aktivite 1732922313

melanie's Avatar melanie bu gisti düzenledi 1732922313. Düzenlemeye git

Değişiklik yok

melanie's Avatar melanie bu gisti düzenledi 1732918400. Düzenlemeye git

1 file changed, 131 insertions

lastfm-weekly-report.ts(dosya oluşturuldu)

@@ -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 + }
Daha yeni Daha eski