tangled
alpha
login
or
join now
rocksky.app
/
rocksky
96
fork
atom
A decentralized music tracking and discovery platform built on AT Protocol 🎵
rocksky.app
spotify
atproto
lastfm
musicbrainz
scrobbling
listenbrainz
96
fork
atom
overview
issues
7
pulls
pipelines
fix empty googledrive parent dir value
tsiry-sandratraina.com
8 months ago
94d5aaec
df763e3d
+84
-44
8 changed files
expand all
collapse all
unified
split
crates
dropbox
src
repo
dropbox_directory.rs
scan.rs
googledrive
src
repo
google_drive_directory.rs
google_drive_path.rs
scan.rs
raichu
src
lib.rs
scrobbler
src
scrobbler.rs
spotify
src
main.rs
+8
-8
crates/dropbox/src/repo/dropbox_directory.rs
···
1
-
use sqlx::{Pool, Postgres};
2
use crate::{types::file::Entry, xata::dropbox_diretory::DropboxDirectory};
0
3
4
pub async fn create_dropbox_directory(
5
pool: &Pool<Postgres>,
···
7
dropbox_id: &str,
8
parent_dir: &str,
9
) -> Result<(), sqlx::Error> {
10
-
let results: Vec<DropboxDirectory> = sqlx::query_as(
11
-
r#"
12
SELECT *
13
FROM dropbox_directories
14
WHERE dropbox_id = $1
···
21
.fetch_all(pool)
22
.await?;
23
24
-
let parent_id = results.first().map(|d| d.xata_id.clone());
25
26
-
sqlx::query(
27
-
r#"
28
INSERT INTO dropbox_directories (
29
dropbox_id,
30
name,
···
44
.execute(pool)
45
.await?;
46
47
-
Ok(())
48
-
}
···
0
1
use crate::{types::file::Entry, xata::dropbox_diretory::DropboxDirectory};
2
+
use sqlx::{Pool, Postgres};
3
4
pub async fn create_dropbox_directory(
5
pool: &Pool<Postgres>,
···
7
dropbox_id: &str,
8
parent_dir: &str,
9
) -> Result<(), sqlx::Error> {
10
+
let results: Vec<DropboxDirectory> = sqlx::query_as(
11
+
r#"
12
SELECT *
13
FROM dropbox_directories
14
WHERE dropbox_id = $1
···
21
.fetch_all(pool)
22
.await?;
23
24
+
let parent_id = results.first().map(|d| d.xata_id.clone());
25
26
+
sqlx::query(
27
+
r#"
28
INSERT INTO dropbox_directories (
29
dropbox_id,
30
name,
···
44
.execute(pool)
45
.await?;
46
47
+
Ok(())
48
+
}
+6
-2
crates/dropbox/src/scan.rs
···
22
consts::AUDIO_EXTENSIONS,
23
crypto::decrypt_aes_256_ctr,
24
repo::{
25
-
dropbox_directory::create_dropbox_directory, dropbox_path::create_dropbox_path, dropbox_token::{find_dropbox_refresh_token, find_dropbox_refresh_tokens}, track::get_track_by_hash
0
0
0
26
},
27
token::generate_token,
28
types::file::{Entry, EntryList},
···
291
let parent_path = Path::new(&path)
292
.parent()
293
.map(|p| p.to_string_lossy().to_string());
294
-
let status = create_dropbox_path(&pool, &entry, &track, &dropbox_id, parent_path).await;
0
295
println!("status: {:?}", status);
296
297
// TODO: publish file metadata to nats
···
22
consts::AUDIO_EXTENSIONS,
23
crypto::decrypt_aes_256_ctr,
24
repo::{
25
+
dropbox_directory::create_dropbox_directory,
26
+
dropbox_path::create_dropbox_path,
27
+
dropbox_token::{find_dropbox_refresh_token, find_dropbox_refresh_tokens},
28
+
track::get_track_by_hash,
29
},
30
token::generate_token,
31
types::file::{Entry, EntryList},
···
294
let parent_path = Path::new(&path)
295
.parent()
296
.map(|p| p.to_string_lossy().to_string());
297
+
let status =
298
+
create_dropbox_path(&pool, &entry, &track, &dropbox_id, parent_path).await;
299
println!("status: {:?}", status);
300
301
// TODO: publish file metadata to nats
+10
-13
crates/googledrive/src/repo/google_drive_directory.rs
···
1
-
use sqlx::{Pool, Postgres};
2
use crate::{types::file::File, xata::google_drive_directory::GoogleDriveDirectory};
0
3
4
pub async fn create_google_drive_directory(
5
pool: &Pool<Postgres>,
···
15
WHERE google_drive_id = $1
16
AND file_id = $2
17
LIMIT 1
18
-
"#
19
)
20
.bind(google_drive_id)
21
.bind(parent_id)
22
.fetch_all(pool)
23
.await?;
24
-
if results.is_empty() {
25
-
None
26
-
} else {
27
-
Some(results[0].clone())
28
-
}
29
} else {
30
None
31
};
···
35
format!("{}/{}", p.path.trim_end_matches('/'), file.name),
36
Some(p.xata_id),
37
),
38
-
None => (
39
-
format!("/{}", file.name),
40
-
None,
41
-
),
42
};
43
44
sqlx::query(
···
52
)
53
VALUES ($1, $2, $3, $4, $5)
54
ON CONFLICT DO NOTHING
55
-
"#
56
)
57
.bind(google_drive_id)
58
.bind(&file.name)
···
63
.await?;
64
65
Ok(())
66
-
}
···
0
1
use crate::{types::file::File, xata::google_drive_directory::GoogleDriveDirectory};
2
+
use sqlx::{Pool, Postgres};
3
4
pub async fn create_google_drive_directory(
5
pool: &Pool<Postgres>,
···
15
WHERE google_drive_id = $1
16
AND file_id = $2
17
LIMIT 1
18
+
"#,
19
)
20
.bind(google_drive_id)
21
.bind(parent_id)
22
.fetch_all(pool)
23
.await?;
24
+
if results.is_empty() {
25
+
None
26
+
} else {
27
+
Some(results[0].clone())
28
+
}
29
} else {
30
None
31
};
···
35
format!("{}/{}", p.path.trim_end_matches('/'), file.name),
36
Some(p.xata_id),
37
),
38
+
None => (format!("/{}", file.name), None),
0
0
0
39
};
40
41
sqlx::query(
···
49
)
50
VALUES ($1, $2, $3, $4, $5)
51
ON CONFLICT DO NOTHING
52
+
"#,
53
)
54
.bind(google_drive_id)
55
.bind(&file.name)
···
60
.await?;
61
62
Ok(())
63
+
}
+16
-9
crates/googledrive/src/repo/google_drive_path.rs
···
1
use sqlx::{Pool, Postgres};
2
3
-
use crate::{types::file::File, xata::{google_drive_directory::GoogleDriveDirectory, track::Track}};
0
0
0
4
5
pub async fn create_google_drive_path(
6
pool: &Pool<Postgres>,
···
9
google_drive_id: &str,
10
parent_dir: &str,
11
) -> Result<(), sqlx::Error> {
12
-
let parent_dir: Vec<GoogleDriveDirectory> = sqlx::query_as(
13
-
r#"
0
0
0
14
SELECT *
15
FROM google_drive_directories
16
WHERE google_drive_id = $1
17
AND file_id = $2
18
LIMIT 1
19
"#,
20
-
)
21
-
.bind(google_drive_id)
22
-
.bind(parent_dir)
23
-
.fetch_all(pool)
24
-
.await?;
25
26
-
let parent_dir = parent_dir.first().map(|d| d.clone().xata_id);
0
27
28
let result = sqlx::query(
29
r#"
···
1
use sqlx::{Pool, Postgres};
2
3
+
use crate::{
4
+
types::file::File,
5
+
xata::{google_drive_directory::GoogleDriveDirectory, track::Track},
6
+
};
7
8
pub async fn create_google_drive_path(
9
pool: &Pool<Postgres>,
···
12
google_drive_id: &str,
13
parent_dir: &str,
14
) -> Result<(), sqlx::Error> {
15
+
let parent_dir = if parent_dir.is_empty() {
16
+
None
17
+
} else {
18
+
let parent_dirs: Vec<GoogleDriveDirectory> = sqlx::query_as(
19
+
r#"
20
SELECT *
21
FROM google_drive_directories
22
WHERE google_drive_id = $1
23
AND file_id = $2
24
LIMIT 1
25
"#,
26
+
)
27
+
.bind(google_drive_id)
28
+
.bind(parent_dir)
29
+
.fetch_all(pool)
30
+
.await?;
31
32
+
parent_dirs.first().map(|d| d.xata_id.clone())
33
+
};
34
35
let result = sqlx::query(
36
r#"
+29
-6
crates/googledrive/src/scan.rs
···
21
consts::AUDIO_EXTENSIONS,
22
crypto::decrypt_aes_256_ctr,
23
repo::{
24
-
google_drive_directory::create_google_drive_directory, google_drive_path::create_google_drive_path, google_drive_token::{find_google_drive_refresh_token, find_google_drive_refresh_tokens}, track::get_track_by_hash
0
0
0
25
},
26
token::generate_token,
27
types::file::{File, FileList},
···
103
if file.mime_type == "application/vnd.google-apps.folder" {
104
println!("Scanning folder: {}", file.name.bright_green());
105
106
-
create_google_drive_directory(&pool, &file, &google_drive_id, parent_drive_file_id.as_deref()).await?;
0
0
0
0
0
0
107
108
// TODO: publish folder metadata to nats
109
···
296
match track {
297
Some(track) => {
298
println!("Track exists: {}", title.bright_green());
299
-
let status =
300
-
create_google_drive_path(&pool, &file, &track, &google_drive_id, &file_id).await?;
0
0
0
0
0
0
0
301
302
println!("status: {:?}", status);
303
// TODO: publish file metadata to nats
···
347
348
let track = get_track_by_hash(&pool, &hash).await?;
349
if let Some(track) = track {
350
-
let status =
351
-
create_google_drive_path(&pool, &file, &track, &google_drive_id, &file_id).await;
0
0
0
0
0
0
0
352
353
println!("status: {:?}", status);
354
···
21
consts::AUDIO_EXTENSIONS,
22
crypto::decrypt_aes_256_ctr,
23
repo::{
24
+
google_drive_directory::create_google_drive_directory,
25
+
google_drive_path::create_google_drive_path,
26
+
google_drive_token::{find_google_drive_refresh_token, find_google_drive_refresh_tokens},
27
+
track::get_track_by_hash,
28
},
29
token::generate_token,
30
types::file::{File, FileList},
···
106
if file.mime_type == "application/vnd.google-apps.folder" {
107
println!("Scanning folder: {}", file.name.bright_green());
108
109
+
create_google_drive_directory(
110
+
&pool,
111
+
&file,
112
+
&google_drive_id,
113
+
parent_drive_file_id.as_deref(),
114
+
)
115
+
.await?;
116
117
// TODO: publish folder metadata to nats
118
···
305
match track {
306
Some(track) => {
307
println!("Track exists: {}", title.bright_green());
308
+
let parent_drive_id = parent_drive_file_id.as_deref();
309
+
let status = create_google_drive_path(
310
+
&pool,
311
+
&file,
312
+
&track,
313
+
&google_drive_id,
314
+
parent_drive_id.unwrap_or(""),
315
+
)
316
+
.await?;
317
318
println!("status: {:?}", status);
319
// TODO: publish file metadata to nats
···
363
364
let track = get_track_by_hash(&pool, &hash).await?;
365
if let Some(track) = track {
366
+
let parent_drive_id = parent_drive_file_id.as_deref();
367
+
let status = create_google_drive_path(
368
+
&pool,
369
+
&file,
370
+
&track,
371
+
&google_drive_id,
372
+
parent_drive_id.unwrap_or(""),
373
+
)
374
+
.await;
375
376
println!("status: {:?}", status);
377
+1
-1
crates/raichu/src/lib.rs
···
5
use std::f32::consts::PI;
6
use std::io::Cursor;
7
use symphonia::core::audio::SampleBuffer;
8
-
use symphonia::core::codecs::{DecoderOptions, CODEC_TYPE_NULL};
9
use symphonia::core::formats::FormatOptions;
10
use symphonia::core::io::{MediaSource, MediaSourceStream};
11
use symphonia::core::meta::MetadataOptions;
···
5
use std::f32::consts::PI;
6
use std::io::Cursor;
7
use symphonia::core::audio::SampleBuffer;
8
+
use symphonia::core::codecs::{CODEC_TYPE_NULL, DecoderOptions};
9
use symphonia::core::formats::FormatOptions;
10
use symphonia::core::io::{MediaSource, MediaSourceStream};
11
use symphonia::core::meta::MetadataOptions;
+4
-2
crates/scrobbler/src/scrobbler.rs
···
492
493
let spotify_user = repo::spotify_account::get_spotify_account(pool, &did).await?;
494
if let Some(spotify_user) = spotify_user {
495
-
if cache.get(&format!("{}:current", spotify_user.email))?.is_some() {
0
0
0
496
println!(
497
"{} {} - {}, currently scrobbling, skipping",
498
"Currently scrobbling: ".yellow(),
···
512
);
513
return Ok(());
514
}
515
-
516
517
// set cache for 5 seconds to avoid duplicate scrobbles
518
cache.setex(
···
492
493
let spotify_user = repo::spotify_account::get_spotify_account(pool, &did).await?;
494
if let Some(spotify_user) = spotify_user {
495
+
if cache
496
+
.get(&format!("{}:current", spotify_user.email))?
497
+
.is_some()
498
+
{
499
println!(
500
"{} {} - {}, currently scrobbling, skipping",
501
"Currently scrobbling: ".yellow(),
···
515
);
516
return Ok(());
517
}
0
518
519
// set cache for 5 seconds to avoid duplicate scrobbles
520
cache.setex(
+10
-3
crates/spotify/src/main.rs
···
205
email.bright_green(),
206
e.to_string().bright_red()
207
);
208
-
match rt.block_on(nc.publish("rocksky.spotify.user", email.clone().into())) {
209
-
Ok(_) => {},
0
0
210
Err(e) => {
211
println!(
212
"{} Error publishing message to restart thread: {}",
···
697
&result.refresh_token,
698
&hex::decode(env::var("SPOTIFY_ENCRYPTION_KEY")?)?,
699
)?;
700
-
user_tokens.push((result.email.clone(), token, result.did.clone(), result.user_id.clone()));
0
0
0
0
0
701
}
702
703
Ok(user_tokens)
···
205
email.bright_green(),
206
e.to_string().bright_red()
207
);
208
+
match rt
209
+
.block_on(nc.publish("rocksky.spotify.user", email.clone().into()))
210
+
{
211
+
Ok(_) => {}
212
Err(e) => {
213
println!(
214
"{} Error publishing message to restart thread: {}",
···
699
&result.refresh_token,
700
&hex::decode(env::var("SPOTIFY_ENCRYPTION_KEY")?)?,
701
)?;
702
+
user_tokens.push((
703
+
result.email.clone(),
704
+
token,
705
+
result.did.clone(),
706
+
result.user_id.clone(),
707
+
));
708
}
709
710
Ok(user_tokens)