Releases: tonymushah/mangadex-api
v4.2.0
What's Changed
- Fix mangadex input types cover upload by @tonymushah in #442
- Update Rust crate serde_qs to v1 by @renovate[bot] and @tonymushah in #426
Full Changelog: v4.1.0...v4.2.0
mangadex-api v4.1.0
mangadex-api v4.1.0
- update
reqwestto 0.13 (no real rust code changes, just some cargo toml change).
mangadex-api-types-rust v1.0.1
- some clippy lint fixes
mangadex-api v4.0.0
In a nutshell
mangadex-api-types::Errorhas been moved tomangadex-api::error::Errorallowingtypesandschemasto be more lightweight (in term of dependencies)- removed
mutli-thread,... and other similar features. We now useArc<tokio::sync::RwLock>forHttpClientRef - removed
legacy-auth,legacy-user,... since these endpoint doesn't work anymore. - the
oauthfeature is now enabled by default. - all structures and enums for types and schemas are now
non_exhaustiveby default,non_exhaustivefeature flag also removed. - most of the non_exhaustive types also implement
Defaultnow for clarity. - Added
MangaSortOrder::Rating - Support for upload term policy: _this is set to
falseby default but it istruefor the input type one. - we use
rust-tlsby default (thanks to @j1nxie) GET /manga/{id}/recommendationendpoint support- Unavailable chapters support
- an experimental WASM test crate has been added: it works but I don't recommend using it in browsers environment since the result WASM file might often reach ~900kB. I only recommend using this crate in your back-end.
Crates released
- mangadex-api 4.0.0
- mangadex-api-types-rust 1.0.0
- mangadex-api-schemas-rust 1.0.0
- mangadex-api-input-types 1.0.0
Github change log
- Update Rust crate uuid to 1.8 by @renovate[bot] in #184
- Update Rust crate reqwest to 0.12 by @renovate[bot] in #185
- Update Rust crate bytes to 1.6 by @renovate[bot] in #187
- V3.3.0 cargo update by @tonymushah in #193
- Added
namicomiby @tonymushah in #194 - 188 remove legacy account feature by @tonymushah in #195
- 190 add the legacy user delete for delete userid and post userdeletecode by @tonymushah in #196
- Update Rust crate tokio to 1.37 by @renovate[bot] in #197
- fixed module error by @tonymushah in #198
- 191 add the post uploadcheck approval required endpoint by @tonymushah in #199
- fix: Send only auth token when auth is required by @tonymushah in #200
- Bump h2 from 0.4.3 to 0.4.4 by @dependabot[bot] in #202
- Update Rust crate serde_qs to 0.13 by @renovate[bot] in #203
- Bump rustls from 0.22.2 to 0.22.4 by @dependabot[bot] in #205
- V3.3.0 by @tonymushah in #206
- some import fixes by @tonymushah in #207
- Update Rust crate anyhow to 1.0.82 by @renovate[bot] in #208
- Update Rust crate async-graphql to 7.0.3 by @renovate[bot] in #209
- Update Rust crate async-stream to 0.3.5 by @renovate[bot] in #210
- Update Rust crate clap to 4.5.4 by @renovate[bot] in #211
- Update Rust crate fake to 2.9.2 by @renovate[bot] in #213
- Update Rust crate color-print to 0.3.6 by @renovate[bot] in #212
- Update Rust crate serde to v1.0.203 by @renovate[bot] in #232
- Update Rust crate anyhow to v1.0.86 by @renovate[bot] in #233
- Update Rust crate thiserror to v1.0.61 by @renovate[bot] in #234
- Update Rust crate tokio to v1.38.0 by @renovate[bot] in #235
- Update Rust crate async-graphql to v7.0.6 by @renovate[bot] in #237
- Update Rust crate clap to v4.5.6 by @renovate[bot] in #236
- Update Rust crate url to v2.5.1 by @renovate[bot] in #239
- Update Rust crate clap to v4.5.7 by @renovate[bot] in #238
- Update Rust crate reqwest to v0.12.5 by @renovate[bot] in #241
- Update Rust crate serde to v1.0.204 by @renovate[bot] in #246
- Update Rust crate uuid to v1.10.0 by @renovate[bot] in #243
- Update Rust crate clap to v4.5.9 by @renovate[bot] in #245
- Bump zerovec from 0.10.2 to 0.10.4 by @dependabot[bot] in #247
- Bump zerovec-derive from 0.10.2 to 0.10.3 by @dependabot[bot] in #248
- Update Rust crate tokio to v1.38.1 by @renovate[bot] in #252
- Update Rust crate bytes to v1.6.1 by @renovate[bot] in #250
- Update Rust crate async-graphql to v7.0.7 by @renovate[bot] in #251
- Update Rust crate url to v2.5.2 by @renovate[bot] in #242
- Update Rust crate thiserror to v1.0.62 by @renovate[bot] in #249
- Update Rust crate serde_json to v1.0.120 by @renovate[bot] in #244
- Update Rust crate wiremock to v0.6.1 by @renovate[bot] in #254
- Update Rust crate thiserror to v1.0.63 by @renovate[bot] in #253
- Bump openssl from 0.10.64 to 0.10.66 by @dependabot[bot] in #255
- Update Rust crate tokio to v1.39.1 by @renovate[bot] in #256
- Update Rust crate clap to v4.5.11 by @renovate[bot] in #257
- Update Rust crate tokio to v1.39.2 by @renovate[bot] in #258
- Update Rust crate clap to v4.5.15 by @renovate[bot] in #261
- Update Rust crate serde to v1.0.205 by @renovate[bot] in #262
- Update Rust crate clap to v4.5.16 by @renovate[bot] in #264
- Update Rust crate serde to v1.0.208 by @renovate[bot] in #263
- Bump quinn-proto from 0.11.3 to 0.11.8 by @dependabot[bot] in #268
- Update Rust crate serde to v1.0.209 by @renovate[bot] in #267
- Update Rust crate serde_json to v1.0.128 by @renovate[bot] in #259
- Update Rust crate reqwest to v0.12.7 by @renovate[bot] in #266
- Update Rust crate tokio to v1.40.0 by @renovate[bot] in #265
- Update language.rs by @tonymushah in #280
- feat: add reference expansion for custom lists by @j1nxie in #281
- Add auth to auth required endpoints by @tonymushah in #282
- 283 add settings template objects by @tonymushah in #292
- 293 update languages for site update 16th of nov 2024 by @tonymushah in #294
- Update Rust crate fake to v3 by @renovate[bot] in #287
- Update Rust crate thiserror to v2 by @renovate[bot] in #288
- Update Rust crate tokio to v1.41.1 by @renovate[bot] in #277
- more cargo updates by @tonymushah in #297
- V3.4.0 realease chore by @tonymushah in #298
- fix: doc build fail by @tonymushah in #299
- Bump rustls from 0.23.17 to 0.23.18 by @dependabot[bot] in #301
- Update workspace uuid dependency from "1.8" to "1" by @tonymushah in #308
- Bump ring from 0.17.8 to 0.17.13 by @dependabot[bot] in #311
- Bump openssl from 0.10.68 to 0.10.70 by @dependabot[bot] in #310
- Update Rust crate tokio-stream to v0.1.17 by @renovate[bot] in #309
- Update Rust crate tokio to v1.44.1 by @renovate[bot] in #305
- Bump tokio from 1.44.1 to 1.44.2 by @dependabot[bot] in #316
- Feat with auth custom lists by @tonymushah in #317
- 318 de bloat schema and types crates by @tonymushah in https://github.com/tonymushah/man...
mangadex v3.2.0 minor changes
mangadex-api v3.2 is here
Hello everyone!
I'm here to give you some changes logs about this realease:
derive_builderupgraded to v0.20 #172- Added
JPlang (it's already published on the0.7.2patch) #180 - Fixed Serialization for
IncludeFuturePages,IncludeExternalUrl,IncludeFuturePublishAt,IncludeFutureUpdateswhich will serialize to1for includes and0for excludes
Quick crate version overview
| Crate | Version |
|---|---|
mangadex-api |
3.2 |
mangadex-api-types-rust |
0.8 |
mangadex-api-schema-rust |
0.8 |
mangadex-api-input-types |
0.4 |
That's it!
Have a nice day everyone!
mangadex v3.0.1 Patches
mangadex-api-types-rust v0.6.1
- Added
Language::get_langsto get an array of all local language - Added
Tag::get_all_tagsto get an array of all local tags
mangadex-api-schema-rust v0.6.1
- Added
mangadex-api-types-rust::Tagconversion toApiObjectNoRelationship<TagAttributes> - Fixed
Relationshipconversion handler forArtist,Creator,Member,Leader
mangadex-api v3.0.1
- Implemented
send()toUnFollowCustomListBuilder
Happy Christmas everyone! 🎅🎅
I hope you're enjoying your Christmas Eve well.
`mangadex-api` v3 is here 🥳
Hello everyone,
I'm very happy and excited to announce to you:
The Release of mangadex-api v3
along with mangadex-api-types/schema-rust v0.6
First,
As mentioned in v3 annoucement, 3/4 (or maybe half) of the feature goal was added.
1- The custom_list_v2 feature for mangadex-api:
It's the support of the subscription system, announced in August 2023. (Ref: here).
There might be some missing endpoint in this feature (like /subscription,...) because it's not deployed yet on api.mangadex.org but on api.mangadex.dev (their public dev environment).
Even if it's not deployed yet, i want to make it stable in v3.1, so stay tuned for that.
2- The upload stabilization :
A days ago, i got the time to try and test the upload endpoints.
It works and the chapter chapter got uploaded to the Official "Test" Manga (the uploaded chapter is here), but it somehow contains some bugs (ref here)
Some discord note
The test/example code is available in mangadex-api/examples/upload.rs
3- mangadex_api_schema_rust::v5::Relationship can now convert to mangadex_api_schema_rust::ApiObjectNoRelationships
I added some TryFrom implementation to Relationship.
This allow you to not add a lot of boilerplate code that does the same thing (converting a relationship to ApiObject 😵💫)
Note: This converstion only support :
- ApiObjectNoRelationships<AuthorAttributes>
- ApiObjectNoRelationships<ChapterAttributes>
- ApiObjectNoRelationships<CoverAttributes>
- ApiObjectNoRelationships<CustomListAttributes>
- ApiObjectNoRelationships<MangaAttributes>
- ApiObjectNoRelationships<ScanlationGroupAttributes>`
- ApiObjectNoRelationships<TagAttributes>
- ApiObjectNoRelationships<UserAttributes>
4- tokio-multi-thread and rw-mutli-thread feature for mangadex-api
Sometimes, in a really big project, you often need a good concurent program.
To satisfy this demand, I added the rw-mutli-thread feature. Instead of using the futures::lock::Mutex in the multi-thread, it'll use tokio::sync::RwLock.
Note that all invoked requests the client data. Only login and refresh_token (for both legacy-auth and oauth) write the client data.
And tokio-multi-thread is just use tokio::sync::Mutex instead of
5- oauth feature (enabled by default)
A few weeks ago, Mangadex introduced personal-clients, the official (and also simple 😂) way for 3rd party software and SDK to support authentification with the OAuth introduced last year.
There is a simple demo on the README but there is also a few examples at mangadex-api/examples:
6- the new syntax
As mentioned in the v3 annoucement, the SDK will got the breaking change feature.
Quick reminder:
if we have an endpoint like this:
PUT /manga/{id}
parameters
title: LocalizedString
version: int
authors: string[] (uuid)
year: int
the invocation should be like this:
/// I assume that you already declared a `MangaDexClient` somewhere.
client.
// /manga/{id}
.manga()
.id(/* Some manga Id here */)
// the HTTP method
.put()
// Parameters
.version(3_u32)
.title(/* some LocalizedString here */)
.year(2023)
.authors(vec![Uuid::new_v4()])
// Send the request
.send()
.await?In previous versions, you often need to build the request first, but now it's not required.
7- utils feature
The type alias DownloadElement have been changed from (String, Option<Bytes>) to (String, Result<Bytes>) where the String is for the filename and the Result<Bytes> is for the image bytes.
I also added a new module upload for upload utilities.
8- RateLimit handling
Please refer to #26 for more details
That's (maybe) it! 🙂
If you want to use the new mangadex-api v3,
Just update your Cargo.toml
# ...
# Types and schemas are always required
mangadex-api-types-rust = "0.6"
mangadex-api-schema-rust = "0.6"
mangadex-api = { version = "3.0.0", feature = ["mutli-thread"]}
# Please note that `oauth` is enabled by defaultThanks for your amazing support
See you in next versions.
@tonymushah
`utils` features Annoucement (MangadexApi 2.1.0)
Hello everybody,
After the realease of special-eureka, i made some testing (mostly reading 😅) but i had some limitations that annoys me when using this SDK.
The first thing is the (non serialization of the types and schemas) but now it`s fixed :
mangadex-api-types-rust 0.3.4has two feature flags :non_exhaustive(enabled by default) that enable#[non_exhaustive]for enums andspectafor thespecta. Useful for the ones who is building a typesafetauriapp.mangadex-api-schema 0.3.2has three features flags :non_exhaustive(enabled by default) that enable#[non_exhaustive]for structs and schemas ,spectafor thespecta, andserializethat enable serde serialization
The second thing is the new features flags :
legacy-authandlegacy-accountfor the old Mangadex login system. Since 5.9.0, Mangadex switched to OAuth for their login system. These involve theMangaDexClient::auth()andMangaDexClient::account()removed by default.utilsfor some utilities that i already imagined.
The utils features
For now, this allows you to download chapters and cover much faster.
I mean code faster.
When enabled, this unlock the new function in the client : MangaDexClient::download() allows you to download chapters and cover images
Examples :
Retrieving chapter pages
Old way
// Imports used for downloading the pages to a file.
// They are not used because we're just printing the raw bytes.
// use std::fs::File;
// use std::io::Write;
use reqwest::Url;
use uuid::Uuid;
use mangadex_api::v5::MangaDexClient;
# async fn run() -> anyhow::Result<()> {
let client = MangaDexClient::default();
let chapter_id = Uuid::new_v4();
let at_home = client
.at_home()
.server()
.chapter_id(&chapter_id)
.build()?
.send()
.await?;
let http_client = reqwest::Client::new();
// Original quality. Use `.data.attributes.data_saver` for smaller, compressed images.
let page_filenames = at_home.chapter.data;
for filename in page_filenames {
// If using the data-saver option, use "/data-saver/" instead of "/data/" in the URL.
let page_url = at_home
.base_url
.join(&format!(
"/{quality_mode}/{chapter_hash}/{page_filename}",
quality_mode = "data",
chapter_hash = at_home.chapter.hash,
page_filename = filename
))
.unwrap();
let res = http_client.get(page_url).send().await?;
// The data should be streamed rather than downloading the data all at once.
let bytes = res.bytes().await?;
// This is where you would download the file but for this example,
// we're just printing the raw data.
// let mut file = File::create(&filename)?;
// let _ = file.write_all(&bytes);
println!("Chunk: {:?}", bytes);
}
# Ok(())
# }The new way
use crate::{utils::download::chapter::DownloadMode, MangaDexClient};
use anyhow::{Ok, Result};
/// used for file exporting
use std::{
fs::{create_dir_all, File},
io::Write,
};
/// It's from this manga called [`The Grim Reaper Falls In Love With A Human`](https://mangadex.org/title/be2efc56-1669-4e42-9f27-3bd232bca8ea/the-grim-reaper-falls-in-love-with-a-human)
///
/// [Chapter 1 English](https://mangadex.org/chapter/2b4e39a5-fba0-4055-a176-8b7e19faacdb) by [`Kredim`](https://mangadex.org/group/0b870e54-c75f-4d2e-8068-c40f939135fd/kredim)
#[tokio::main]
async fn main() -> Result<()> {
let output_dir = "your-output-dir";
let client = MangaDexClient::default();
let chapter_id = uuid::Uuid::parse_str("32b229f6-e9bf-41a0-9694-63c11191704c")?;
let chapter_files = client
/// We use the download builder
.download()
/// Chapter id (accept uuid::Uuid)
.chapter(chapter_id)
/// You also use `DownloadMode::Normal` if you want some the original quality
///
/// Default : Normal
.mode(DownloadMode::DataSaver)
/// Enable the [`The MangaDex@Home report`](https://api.mangadex.org/docs/retrieving-chapter/#the-mangadexhome-report-endpoint) if true
///
/// Default : false
.report(true)
/// Something that i don`t really know about
///
/// More details at : https://api.mangadex.org/docs/retrieving-chapter/#basics
.force_port_443(false)
.build()?
.execute()
.await?;
create_dir_all(format!("{}{}", output_dir, chapter_id))?;
for (filename, bytes) in chapter_files {
let mut file: File =
File::create(format!("{}{}/{}", output_dir, chapter_id, filename))?;
file.write_all(&bytes)?;
}
Ok(())
}Much more cleaner !
Retrieving cover image
Old way
// Imports used for downloading the cover to a file.
// They are not used because we're just printing the raw bytes.
// use std::fs::File;
// use std::io::Write;
use reqwest::Url;
use uuid::Uuid;
use mangadex_api::types::RelationshipType;
use mangadex_api::v5::MangaDexClient;
use mangadex_api::CDN_URL;
# async fn run() -> anyhow::Result<()> {
let client = MangaDexClient::default();
let manga_id = Uuid::new_v4();
let manga = client
.manga()
.get()
.manga_id(&manga_id)
.build()?
.send()
.await?;
let cover_id = manga
.data
.relationships
.iter()
.find(|related| related.type_ == RelationshipType::CoverArt)
.expect("no cover art found for manga")
.id;
let cover = client
.cover()
.get()
.cover_id(&cover_id)
.build()?
.send()
.await?;
// This uses the best quality image.
// To use smaller, thumbnail-sized images, append any of the following:
//
// - .512.jpg
// - .256.jpg
//
// For example, "https://uploads.mangadex.org/covers/8f3e1818-a015-491d-bd81-3addc4d7d56a/4113e972-d228-4172-a885-cb30baffff97.jpg.512.jpg"
let cover_url = Url::parse(&format!(
"{}/covers/{}/{}",
CDN_URL, manga_id, cover.data.attributes.file_name
))
.unwrap();
let http_client = reqwest::Client::new();
let res = http_client.get(cover_url).send().await?;
// The data should be streamed rather than downloading the data all at once.
let bytes = res.bytes().await?;
// This is where you would download the file but for this example, we're just printing the raw data.
// let mut file = File::create(&filename)?;
// let _ = file.write_all(&bytes);
println!("Chunk: {:?}", bytes);
# Ok(())
# }The new way
Via a cover id.
use anyhow::Result;
use uuid::Uuid;
use crate::MangaDexClient;
use std::{io::Write, fs::File};
/// Download the volume 2 cover of [Lycoris Recoil](https://mangadex.org/title/9c21fbcd-e22e-4e6d-8258-7d580df9fc45/lycoris-recoil)
#[tokio::main]
async fn main() -> Result<()>{
let cover_id : Uuid = Uuid::parse_str("0bc12ff4-3cec-4244-8582-965b8be496ea")?;
let client : MangaDexClient = MangaDexClient::default();
let (filename, bytes) = client.download().cover().build()?.via_cover_id(cover_id).await?;
let mut file = File::create(format!("{}/{}", "your-output-dir", filename))?;
file.write_all(&bytes)?;
Ok(())
}Via a manga id.
use anyhow::Result;
use uuid::Uuid;
use crate::MangaDexClient;
use std::{io::Write, fs::File};
/// Download the [Kimi tte Watashi no Koto Suki Nandesho?](https://mangadex.org/title/f75c2845-0241-4e69-87c7-b93575b532dd/kimi-tte-watashi-no-koto-suki-nandesho) cover
///
/// For test... of course :3
#[tokio::main]
async fn main() -> Result<()>{
let manga_id : Uuid = Uuid::parse_str("f75c2845-0241-4e69-87c7-b93575b532dd")?;
let client : MangaDexClient = MangaDexClient::default();
let (filename, bytes) = client
.download()
.cover()
/// you can use
///
/// ```rust
/// .quality(CoverQuality::Size512)
/// ``` for 512
/// or
/// ```rust
/// .quality(CoverQuality::Size256)
/// ``` for 256
.build()?.via_manga_id(manga_id).await?;
let mut file = File::create(format!("{}/{}", "test-outputs/covers", filename))?;
file.write_all(&bytes)?;
Ok(())
}Much more cleaner this way.
That's all for today.
If you have a suggestion or a request, just open an issue.