speed optimizations and stuff

This commit is contained in:
blank X 2020-10-25 22:27:15 +07:00
parent c515153d70
commit c1a6161fc2
3 changed files with 71 additions and 13 deletions

15
Cargo.lock generated
View File

@ -1102,6 +1102,7 @@ dependencies = [
"chrono",
"reqwest",
"rss",
"serde",
"serde_json",
"tokio",
"warp",
@ -1163,6 +1164,20 @@ name = "serde"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"

View File

@ -12,7 +12,8 @@ lto = true
[dependencies]
rss = "1.9.0"
warp = "0.2.5"
reqwest = "0.10.8"
chrono = "0.4.19"
serde_json = "1.0"
reqwest = "0.10.8"
serde = { version = "1.0.117", features = ["derive"] }
tokio = { version = "0.2.22", features = ["rt-core", "macros"] }

View File

@ -1,5 +1,6 @@
extern crate rss;
extern crate warp;
extern crate serde;
extern crate tokio;
extern crate chrono;
extern crate reqwest;
@ -8,6 +9,7 @@ use std::env;
use std::convert::Infallible;
use reqwest::Client;
use serde_json::json;
use serde::Deserialize;
use warp::{Filter, http::response};
use chrono::{Utc, DateTime, NaiveDateTime};
use rss::{Item, ItemBuilder, ChannelBuilder, GuidBuilder};
@ -31,6 +33,46 @@ const QUERY: &str = r#"query ($id: Int) {
}
}"#;
#[derive(Deserialize)]
struct Root {
pub data: Data
}
#[derive(Deserialize)]
#[serde(rename_all="PascalCase")]
struct Data {
pub media: Media
}
#[derive(Deserialize)]
#[serde(rename_all="camelCase")]
struct Media {
pub title: MediaTitle,
pub airing_schedule: AiringScheduleConnection,
pub episodes: Option<isize>,
pub site_url: String
}
#[derive(Deserialize)]
struct MediaTitle {
pub romaji: String,
pub english: Option<String>
}
#[derive(Deserialize)]
struct AiringScheduleConnection {
pub nodes: Vec<AiringSchedule>
}
#[derive(Deserialize)]
#[serde(rename_all="camelCase")]
struct AiringSchedule {
pub id: isize,
pub airing_at: i64,
pub time_until_airing: i64,
pub episode: isize
}
async fn give_response(anime_id: usize) -> Result<impl warp::Reply, Infallible> {
let json = json!({"query": QUERY, "variables": {"id": anime_id}});
let client = Client::new();
@ -41,7 +83,7 @@ async fn give_response(anime_id: usize) -> Result<impl warp::Reply, Infallible>
.send()
.await {
Ok(resp) => match resp.text().await {
Ok(resp) => match serde_json::from_str::<serde_json::Value>(&resp) {
Ok(resp) => match serde_json::from_str::<Root>(&resp) {
Ok(resp) => resp,
Err(err) => {
eprintln!("ERROR: {}", err);
@ -58,27 +100,27 @@ async fn give_response(anime_id: usize) -> Result<impl warp::Reply, Infallible>
return Ok(response::Builder::new().status(503).header("Content-Type", "type/plain").body(format!("503\n{}", err)));
}
};
let resp = &resp["data"]["Media"];
let title = resp["title"]["english"].as_str().unwrap_or(resp["title"]["romaji"].as_str().unwrap());
let mut items: Vec<Item> = Vec::new();
let mut pub_date = Utc::now().to_rfc2822();
let mut last_build_date = pub_date.clone();
for i in resp["airingSchedule"]["nodes"].as_array().unwrap() {
let i_date = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(i["airingAt"].as_i64().unwrap(), 0), Utc).to_rfc2822();
let resp = &resp.data.media;
let title = resp.title.english.as_ref().unwrap_or(&resp.title.romaji);
let mut items: Vec<Item> = Vec::with_capacity(resp.airing_schedule.nodes.len());
for i in &resp.airing_schedule.nodes {
let i_date = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(i.airing_at, 0), Utc).to_rfc2822();
pub_date = i_date.clone();
if i["timeUntilAiring"].as_i64().unwrap() > 0 {
if i.time_until_airing > 0 {
break;
}
last_build_date = i_date.clone();
let mut title = format!("{} - {}", title, i["episode"].as_u64().unwrap());
if i["episode"].as_u64().unwrap() == resp["episodes"].as_u64().unwrap_or(0) {
let mut title = format!("{} - {}", title, i.episode);
if Some(i.episode) == resp.episodes {
title.push_str(" END");
}
items.push(ItemBuilder::default()
.title(title)
.link(resp["siteUrl"].as_str().unwrap().to_string())
.link(resp.site_url.clone())
.pub_date(i_date)
.guid(GuidBuilder::default().permalink(false).value(format!("ran-{}-{}", anime_id, i["id"].as_u64().unwrap())).build().unwrap())
.guid(GuidBuilder::default().permalink(false).value(format!("ran-{}-{}", anime_id, i.id)).build().unwrap())
.build()
.unwrap()
);
@ -86,7 +128,7 @@ async fn give_response(anime_id: usize) -> Result<impl warp::Reply, Infallible>
items.reverse();
let channel = ChannelBuilder::default()
.title(title)
.link(resp["siteUrl"].as_str().unwrap())
.link(resp.site_url.clone())
.description(format!("Aired episodes of {}", title))
.pub_date(pub_date)
.last_build_date(last_build_date)