tangled
alpha
login
or
join now
t1c.dev
/
rocksky
forked from
rocksky.app/rocksky
2
fork
atom
A decentralized music tracking and discovery platform built on AT Protocol 🎵
2
fork
atom
overview
issues
pulls
pipelines
[scrobbler] avoid duplicate scrobbles
tsiry-sandratraina.com
9 months ago
c1f1c815
f9bda895
+68
-9
5 changed files
expand all
collapse all
unified
split
crates
scrobbler
src
repo
mod.rs
spotify_account.rs
scrobbler.rs
rockskyweb
src
components
ScrobblesAreaChart
ScrobblesAreaChart.tsx
pages
profile
library
albums
Albums.tsx
+1
crates/scrobbler/src/repo/mod.rs
···
1
1
pub mod album;
2
2
pub mod api_key;
3
3
pub mod artist;
4
4
+
pub mod spotify_account;
4
5
pub mod spotify_token;
5
6
pub mod track;
6
7
pub mod user;
+26
crates/scrobbler/src/repo/spotify_account.rs
···
1
1
+
use anyhow::Error;
2
2
+
use sqlx::{Pool, Postgres};
3
3
+
4
4
+
use crate::xata::spotify_account::SpotifyAccount;
5
5
+
6
6
+
pub async fn get_spotify_account(
7
7
+
pool: &Pool<Postgres>,
8
8
+
did: &str,
9
9
+
) -> Result<Option<SpotifyAccount>, Error> {
10
10
+
let results: Vec<SpotifyAccount> = sqlx::query_as(
11
11
+
r#"
12
12
+
SELECT * FROM spotify_accounts
13
13
+
LEFT JOIN users ON spotify_accounts.user_id = users.xata_id
14
14
+
WHERE users.did = $1
15
15
+
"#,
16
16
+
)
17
17
+
.bind(did)
18
18
+
.fetch_all(pool)
19
19
+
.await?;
20
20
+
21
21
+
if results.len() == 0 {
22
22
+
return Ok(None);
23
23
+
}
24
24
+
25
25
+
Ok(Some(results[0].clone()))
26
26
+
}
+25
crates/scrobbler/src/scrobbler.rs
···
489
489
);
490
490
return Ok(());
491
491
}
492
492
+
493
493
+
let spotify_user = repo::spotify_account::get_spotify_account(pool, &did).await?;
494
494
+
if let Some(spotify_user) = spotify_user {
495
495
+
if cache.get(&format!("{}:current", spotify_user.email))?.is_some() {
496
496
+
println!(
497
497
+
"{} {} - {}, currently scrobbling, skipping",
498
498
+
"Currently scrobbling: ".yellow(),
499
499
+
artist,
500
500
+
track
501
501
+
);
502
502
+
return Ok(());
503
503
+
}
504
504
+
}
505
505
+
506
506
+
if cache.get(&format!("nowplaying:{}", did))?.is_some() {
507
507
+
println!(
508
508
+
"{} {} - {}, currently scrobbling, skipping",
509
509
+
"Currently scrobbling: ".yellow(),
510
510
+
artist,
511
511
+
track
512
512
+
);
513
513
+
return Ok(());
514
514
+
}
515
515
+
516
516
+
492
517
// set cache for 5 seconds to avoid duplicate scrobbles
493
518
cache.setex(
494
519
&format!("listenbrainz:cache:{}:{}:{}", artist, track, did),
+6
-9
rockskyweb/src/components/ScrobblesAreaChart/ScrobblesAreaChart.tsx
···
13
13
}: TooltipProps<number, string>) => {
14
14
if (active && payload && payload.length) {
15
15
return (
16
16
-
<div
17
17
-
style={{
18
18
-
backgroundColor: "white",
19
19
-
padding: "5px",
20
20
-
border: "1px solid #ccc",
21
21
-
}}
22
22
-
>
23
23
-
<span style={{ color: "#808080" }}>
16
16
+
<div className="bg-[#fff] border-[1px] border-[#ccc] p-[5px]">
17
17
+
<span className="text-[#808080]">
24
18
{dayjs(label).format("dddd DD MMMM YYYY")}:
25
19
</span>
26
26
-
<span> {numeral(payload[0].value).format("0,0")}</span>
20
20
+
<span className="text-[#710de4]">
21
21
+
{" "}
22
22
+
{numeral(payload[0].value).format("0,0")}
23
23
+
</span>
27
24
</div>
28
25
);
29
26
}
+10
rockskyweb/src/pages/profile/library/albums/Albums.tsx
···
135
135
},
136
136
},
137
137
},
138
138
+
TableEmptyMessage: {
139
139
+
style: {
140
140
+
backgroundColor: "var(--color-background)",
141
141
+
},
142
142
+
},
143
143
+
Table: {
144
144
+
style: {
145
145
+
backgroundColor: "var(--color-background)",
146
146
+
},
147
147
+
},
138
148
}}
139
149
>
140
150
<TableBuilderColumn header="Name">