Skip to content

Commit 71c9438

Browse files
authored
Remove usages of surf (#873)
* docs: add info about pro version * feat(backend): return main website url * feat(frontend): display Ryot pro link in footer * fix(ts-utils): remove hoisted variables * fix(frontend): no-wrap for title * build(backend): upgrade deps * fix(backend): correct logic for exercise interacted * feat(backend): add new dep * feat(backend): new reqwest version of client * feat(backend): add json feature * feat(backend): switch to surf in anilist * build(backend): add file streaming deps * fix(backend): use reqwest for exporter * feat(backend): use reqwest in some places * fix(backend): don't queue notification when triggering test * feat(frontend): show in bold * feat(backend): remove all usages of surf * refactor(backend): change name of old function * build(backend): remove surf from deps * fix(frontend): do not pass as props * chore(frontend): do not display pro link * build(backend): bump version * fix(backend): add log to ABS importer * fix(frontend): better wordings * feat(backend): reduce interval for integration sync * docs: add info about sync interval * docs: add caveat for ABS
1 parent d1e223b commit 71c9438

39 files changed

+822
-1556
lines changed

Cargo.lock

+262-1,132
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ resolver = "2"
44

55
[workspace.dependencies]
66
anyhow = "=1.0.82"
7-
async-graphql = { version = "=7.0.5", features = [
7+
async-graphql = { version = "=7.0.6", features = [
88
"chrono",
99
"decimal",
1010
"log",

apps/backend/Cargo.toml

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ryot"
3-
version = "6.2.2"
3+
version = "6.2.3"
44
edition = "2021"
55
repository = "https://github.com/IgnisDa/ryot"
66
license = "GPL-3.0"
@@ -10,9 +10,9 @@ anyhow = { workspace = true }
1010
apalis = { version = "=0.5.3", features = ["cron", "limit"] }
1111
argon2 = "=0.6.0-pre.0"
1212
async-graphql = { workspace = true }
13-
async-graphql-axum = "=7.0.5"
13+
async-graphql-axum = "=7.0.6"
1414
async-trait = "=0.1.80"
15-
aws-sdk-s3 = { version = "=1.34.0", features = ["behavior-version-latest"] }
15+
aws-sdk-s3 = { version = "=1.36.0", features = ["behavior-version-latest"] }
1616
axum = { version = "=0.7.5", features = ["macros", "multipart"] }
1717
boilermates = "=0.3.0"
1818
cached = { version = "=0.51.4", features = ["disk_store"] }
@@ -30,13 +30,12 @@ derive_more = { version = "=1.0.0-beta.6", features = [
3030
"add_assign",
3131
], default-features = false }
3232
dotenvy = "=0.15.7"
33-
enum_meta = "=0.6.0"
33+
enum_meta = "=0.7.0"
3434
flate2 = "=1.0.30"
3535
futures = "=0.3.30"
3636
graphql_client = "=0.14.0"
3737
hashbag = "=0.1.12"
3838
http = "=1.1.0"
39-
http-types = "=2.12.0"
4039
isolang = { version = "=2.4.0", features = ["list_languages"] }
4140
itertools = "=0.13.0"
4241
jsonwebtoken = { version = "=9.3.0", default-features = false }
@@ -51,7 +50,12 @@ nanoid = { workspace = true }
5150
openidconnect = "=3.5.0"
5251
paginate = "=1.1.11"
5352
rand = "=0.9.0-alpha.1"
54-
regex = "=1.10.4"
53+
regex = "=1.10.5"
54+
# FIXME: Upgrade once https://github.com/seanmonstar/reqwest/pull/1620 is merged
55+
reqwest = { git = "https://github.com/thomasqueirozb/reqwest", branch = "base_url", features = [
56+
"json",
57+
"stream",
58+
] }
5559
rs-utils = { path = "../../libs/rs-utils" }
5660
rust_decimal = "=1.35.0"
5761
rust_decimal_macros = "=1.34.2"
@@ -68,10 +72,8 @@ serde-xml-rs = "=0.6.0"
6872
slug = "=0.1.5"
6973
strum = { workspace = true }
7074
struson = { version = "=0.5.0", features = ["serde"] }
71-
surf = { version = "=2.3.2", features = [
72-
"h1-client-rustls",
73-
], default-features = false }
7475
tokio = { version = "=1.38.0", features = ["full"] }
76+
tokio-util = { version = "=0.7.11", features = ["codec"] }
7577
tower = { version = "=0.4.13", features = ["buffer"] }
7678
tower-http = { version = "=0.5.2", features = ["catch-panic", "cors", "trace"] }
7779
tracing = { workspace = true }

apps/backend/src/exporter.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
use std::{collections::HashMap, fs::File, path::PathBuf, sync::Arc};
1+
use std::{collections::HashMap, path::PathBuf, sync::Arc};
22

33
use apalis::prelude::MessageQueue;
44
use async_graphql::{Context, Error, Object, Result, SimpleObject};
55
use chrono::{DateTime, Utc};
66
use nanoid::nanoid;
7+
use reqwest::{Body, Client};
78
use rs_utils::IsFeatureEnabled;
89
use sea_orm::prelude::DateTimeUtc;
910
use serde::{Deserialize, Serialize};
1011
use struson::writer::{JsonStreamWriter, JsonWriter};
12+
use tokio::fs::File;
13+
use tokio_util::codec::{BytesCodec, FramedRead};
1114

1215
use crate::{
1316
background::ApplicationJob, file_storage::FileStorageService,
@@ -99,7 +102,7 @@ impl ExporterService {
99102
}
100103
let started_at = Utc::now();
101104
let export_path = PathBuf::from(TEMP_DIR).join(format!("ryot-export-{}.json", nanoid!()));
102-
let file = File::create(&export_path).unwrap();
105+
let file = std::fs::File::create(&export_path).unwrap();
103106
let mut writer = JsonStreamWriter::new(file);
104107
writer.begin_object().unwrap();
105108
for export in to_export.iter() {
@@ -158,16 +161,20 @@ impl ExporterService {
158161
])),
159162
)
160163
.await;
161-
surf::put(url)
164+
let file = File::open(&export_path).await.unwrap();
165+
let stream = FramedRead::new(file, BytesCodec::new());
166+
let body = Body::wrap_stream(stream);
167+
let client = Client::new();
168+
client
169+
.put(url)
162170
.header("x-amz-meta-started_at", started_at.to_rfc2822())
163171
.header("x-amz-meta-ended_at", ended_at.to_rfc2822())
164172
.header(
165173
"x-amz-meta-exported",
166174
serde_json::to_string(&to_export).unwrap(),
167175
)
168-
.body_file(&export_path)
169-
.await
170-
.unwrap()
176+
.body(body)
177+
.send()
171178
.await
172179
.unwrap();
173180
Ok(true)

apps/backend/src/fitness/logic.rs

+1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ impl UserWorkoutInput {
149149
created_on: ActiveValue::Set(
150150
first_set_of_exercise_confirmed_at.unwrap_or(end_time),
151151
),
152+
exercise_num_times_interacted: ActiveValue::Set(Some(1)),
152153
..Default::default()
153154
};
154155
user_to_ex.insert(db).await.unwrap()

apps/backend/src/fitness/resolver.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,10 @@ impl ExerciseService {
331331
}
332332

333333
async fn get_all_exercises_from_dataset(&self) -> Result<Vec<GithubExercise>> {
334-
let data: Vec<GithubExercise> = surf::get(JSON_URL)
335-
.send()
334+
let data = reqwest::get(JSON_URL)
336335
.await
337336
.unwrap()
338-
.body_json()
337+
.json::<Vec<GithubExercise>>()
339338
.await
340339
.unwrap();
341340
Ok(data

apps/backend/src/importer/audiobookshelf.rs

+22-11
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ use anyhow::anyhow;
44
use async_graphql::Result;
55
use data_encoding::BASE64;
66
use database::{ImportSource, MediaLot, MediaSource};
7+
use reqwest::{
8+
header::{HeaderValue, AUTHORIZATION},
9+
Client,
10+
};
711
use sea_orm::DatabaseConnection;
812
use serde::{Deserialize, Serialize};
913
use serde_json::json;
10-
use surf::{http::headers::AUTHORIZATION, Client};
1114

1215
use crate::{
1316
importer::{ImportFailStep, ImportFailedItem, ImportResult},
@@ -48,13 +51,17 @@ where
4851
let mut failed_items = vec![];
4952
let client = get_base_http_client(
5053
&format!("{}/api/", input.api_url),
51-
vec![(AUTHORIZATION, format!("Bearer {}", input.api_key))],
54+
Some(vec![(
55+
AUTHORIZATION,
56+
HeaderValue::from_str(&format!("Bearer {}", input.api_key)).unwrap(),
57+
)]),
5258
);
53-
let libraries_resp: LibrariesListResponse = client
59+
let libraries_resp = client
5460
.get("libraries")
61+
.send()
5562
.await
5663
.map_err(|e| anyhow!(e))?
57-
.body_json()
64+
.json::<LibrariesListResponse>()
5865
.await
5966
.unwrap();
6067
for library in libraries_resp.libraries {
@@ -63,18 +70,20 @@ where
6370
if let Some(audiobookshelf_models::MediaType::Book) = library.media_type {
6471
query["filter"] = json!(format!("progress.{}", BASE64.encode(b"finished")));
6572
}
66-
let finished_items: ListResponse = client
73+
let finished_items = client
6774
.get(&format!("libraries/{}/items", library.id))
6875
.query(&query)
69-
.unwrap()
76+
.send()
7077
.await
7178
.map_err(|e| anyhow!(e))?
72-
.body_json()
79+
.json::<ListResponse>()
7380
.await
7481
.unwrap();
75-
for item in finished_items.results {
82+
let len = finished_items.results.len();
83+
for (idx, item) in finished_items.results.into_iter().enumerate() {
7684
let metadata = item.media.clone().unwrap().metadata;
7785
let title = metadata.title.clone();
86+
tracing::trace!("Importing item {:?} ({}/{})", title, idx + 1, len);
7887
let (identifier, lot, source, episodes) = if Some("epub".to_string())
7988
== item.media.as_ref().unwrap().ebook_format
8089
{
@@ -111,6 +120,7 @@ where
111120
let source = MediaSource::Itunes;
112121
let mut to_return = vec![];
113122
for episode in episodes {
123+
tracing::trace!("Importing episode {:?}", episode.title);
114124
let episode_details =
115125
get_item_details(&client, &item.id, Some(episode.id.unwrap()))
116126
.await?;
@@ -192,12 +202,13 @@ async fn get_item_details(
192202
if let Some(episode) = episode {
193203
query["episode"] = json!(episode);
194204
}
195-
let item: audiobookshelf_models::Item = client
205+
let item = client
196206
.get(&format!("items/{}", id))
197-
.query(&query)?
207+
.query(&query)
208+
.send()
198209
.await
199210
.map_err(|e| anyhow!(e))?
200-
.body_json()
211+
.json::<audiobookshelf_models::Item>()
201212
.await?;
202213
Ok(item)
203214
}

apps/backend/src/importer/jellyfin.rs

+28-23
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use async_graphql::Result;
22
use database::{MediaLot, MediaSource};
33
use enum_meta::HashMap;
4+
use reqwest::{
5+
header::{HeaderMap, HeaderValue, ACCEPT, AUTHORIZATION, USER_AGENT},
6+
Client, ClientBuilder,
7+
};
48
use sea_orm::prelude::DateTimeUtc;
59
use serde::{Deserialize, Serialize};
610
use serde_json::json;
7-
use surf::{
8-
http::headers::{ACCEPT, AUTHORIZATION, USER_AGENT},
9-
Client, Config, Url,
10-
};
1111

1212
use crate::{
1313
importer::{
@@ -16,7 +16,7 @@ use crate::{
1616
models::media::{
1717
ImportOrExportItemIdentifier, ImportOrExportMediaItem, ImportOrExportMediaItemSeen,
1818
},
19-
utils::USER_AGENT_STR,
19+
utils::{JSON, USER_AGENT_STR},
2020
};
2121

2222
static EMBY_HEADER_VALUE: &str =
@@ -74,26 +74,30 @@ struct AuthenticateResponse {
7474

7575
pub async fn import(input: DeployUrlAndKeyAndUsernameImportInput) -> Result<ImportResult> {
7676
let uri = format!("{}/Users/AuthenticateByName", input.api_url);
77-
let authenticate: AuthenticateResponse = surf::post(uri)
77+
let client = Client::new();
78+
let authenticate = client
79+
.post(uri)
7880
.header(AUTHORIZATION, EMBY_HEADER_VALUE)
79-
.body_json(&serde_json::json!({ "Username": input.username, "Pw": input.password }))
80-
.unwrap()
81+
.json(&serde_json::json!({ "Username": input.username, "Pw": input.password }))
82+
.send()
8183
.await
8284
.unwrap()
83-
.body_json()
85+
.json::<AuthenticateResponse>()
8486
.await
8587
.unwrap();
8688
tracing::debug!("Authenticated with token: {}", authenticate.access_token);
8789

88-
let client: Client = Config::new()
89-
.add_header(USER_AGENT, USER_AGENT_STR)
90-
.unwrap()
91-
.add_header(ACCEPT, "application/json")
92-
.unwrap()
93-
.add_header("X-Emby-Token", authenticate.access_token)
94-
.unwrap()
95-
.set_base_url(Url::parse(&input.api_url).unwrap().join("/").unwrap())
96-
.try_into()
90+
let mut headers = HeaderMap::new();
91+
headers.insert(USER_AGENT, HeaderValue::from_static(USER_AGENT_STR));
92+
headers.insert(ACCEPT, JSON.clone());
93+
headers.insert(
94+
"X-Emby-Token",
95+
HeaderValue::from_str(&authenticate.access_token).unwrap(),
96+
);
97+
let client: Client = ClientBuilder::new()
98+
.base_url(input.api_url + "/")
99+
.default_headers(headers)
100+
.build()
97101
.unwrap();
98102
let user_id = authenticate.user.id;
99103
tracing::debug!("Authenticated as user id: {}", user_id);
@@ -102,13 +106,13 @@ pub async fn import(input: DeployUrlAndKeyAndUsernameImportInput) -> Result<Impo
102106
let mut failed_items = vec![];
103107

104108
let query = json!({ "recursive": true, "IsPlayed": true, "fields": "ProviderIds" });
105-
let library_data: ItemsResponse = client
109+
let library_data = client
106110
.get(&format!("Users/{}/Items", user_id))
107111
.query(&query)
108-
.unwrap()
112+
.send()
109113
.await
110114
.unwrap()
111-
.body_json()
115+
.json::<ItemsResponse>()
112116
.await
113117
.unwrap();
114118

@@ -123,11 +127,12 @@ pub async fn import(input: DeployUrlAndKeyAndUsernameImportInput) -> Result<Impo
123127
if let Some(series_id) = item.series_id {
124128
let mut tmdb_id = series_id_to_tmdb_id.get(&series_id).cloned().flatten();
125129
if tmdb_id.is_none() {
126-
let details: ItemResponse = client
130+
let details = client
127131
.get(&format!("Items/{}", series_id))
132+
.send()
128133
.await
129134
.unwrap()
130-
.body_json()
135+
.json::<ItemResponse>()
131136
.await
132137
.unwrap();
133138
let insert_id = details.provider_ids.unwrap().tmdb;

0 commit comments

Comments
 (0)