Move jnovel module into fetchers module
This commit is contained in:
parent
ba3110da0e
commit
6bd7369ecc
1 changed files with 148 additions and 129 deletions
|
@ -1,12 +1,15 @@
|
||||||
use crate::jnovel::PartInfo::{NoParts, Part};
|
use crate::{write_error, HTTP_CLIENT, lemmy};
|
||||||
use crate::jnovel::PostInfo::{Chapter, Volume};
|
|
||||||
use crate::{write_error, HTTP_CLIENT};
|
|
||||||
use chrono::{DateTime, Duration, Utc};
|
use chrono::{DateTime, Duration, Utc};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ops::Sub;
|
use std::ops::Sub;
|
||||||
|
use async_trait::async_trait;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
use crate::fetchers::Fetcher;
|
||||||
|
use crate::fetchers::jnovel::JPostInfo::{Chapter, Volume};
|
||||||
|
use crate::fetchers::jnovel::PartInfo::{NoParts, Part};
|
||||||
|
use crate::lemmy::{PostInfo, PostInfoInner};
|
||||||
|
|
||||||
static PAST_DAYS_ELIGIBLE: u8 = 4;
|
static PAST_DAYS_ELIGIBLE: u8 = 4;
|
||||||
|
|
||||||
|
@ -54,27 +57,21 @@ pub(crate) struct Cover {
|
||||||
pub(crate) struct VolumeDetail {
|
pub(crate) struct VolumeDetail {
|
||||||
pub(crate) title: String,
|
pub(crate) title: String,
|
||||||
pub(crate) slug: String,
|
pub(crate) slug: String,
|
||||||
pub(crate) number: u8,
|
number: u8,
|
||||||
pub(crate) publishing: String,
|
publishing: String,
|
||||||
#[serde(alias = "shortDescription")]
|
#[serde(alias = "shortDescription")]
|
||||||
pub(crate) short_description: String,
|
short_description: String,
|
||||||
pub(crate) cover: Cover,
|
cover: Cover,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub(crate) struct ChapterDetail {
|
pub(crate) struct ChapterDetail {
|
||||||
pub(crate) title: String,
|
pub(crate) title: String,
|
||||||
pub(crate) slug: String,
|
pub(crate) slug: String,
|
||||||
pub(crate) launch: String,
|
launch: String,
|
||||||
pub(crate) cover: Option<Cover>,
|
pub(crate) cover: Option<Cover>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub(crate) struct LemmyPostInfo {
|
|
||||||
pub(crate) title: String,
|
|
||||||
pub(crate) url: Url,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub(crate) enum PartInfo {
|
pub(crate) enum PartInfo {
|
||||||
NoParts,
|
NoParts,
|
||||||
|
@ -137,19 +134,19 @@ impl PartialOrd for PartInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) enum PostInfo {
|
pub(crate) enum JPostInfo {
|
||||||
Chapter {
|
Chapter {
|
||||||
part: PartInfo,
|
part: PartInfo,
|
||||||
lemmy_info: LemmyPostInfo,
|
lemmy_info: PostInfoInner,
|
||||||
},
|
},
|
||||||
Volume {
|
Volume {
|
||||||
part: PartInfo,
|
part: PartInfo,
|
||||||
description: String,
|
description: String,
|
||||||
lemmy_info: LemmyPostInfo,
|
lemmy_info: PostInfoInner,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PostInfo {
|
impl JPostInfo {
|
||||||
pub(crate) fn get_part_info(&self) -> PartInfo {
|
pub(crate) fn get_part_info(&self) -> PartInfo {
|
||||||
match self {
|
match self {
|
||||||
Chapter {
|
Chapter {
|
||||||
|
@ -160,15 +157,17 @@ impl PostInfo {
|
||||||
} => *part_info,
|
} => *part_info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_lemmy_info(&self) -> LemmyPostInfo {
|
impl PostInfo for JPostInfo {
|
||||||
|
fn get_info(&self) -> PostInfoInner {
|
||||||
match self {
|
match self {
|
||||||
Chapter { lemmy_info, .. } => lemmy_info.clone(),
|
Chapter { lemmy_info, .. } => lemmy_info.clone(),
|
||||||
Volume { lemmy_info, .. } => lemmy_info.clone(),
|
Volume { lemmy_info, .. } => lemmy_info.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_description(&self) -> Option<String> {
|
fn get_description(&self) -> Option<String> {
|
||||||
match self {
|
match self {
|
||||||
Chapter { .. } => None,
|
Chapter { .. } => None,
|
||||||
Volume { description, .. } => Some(description.clone()),
|
Volume { description, .. } => Some(description.clone()),
|
||||||
|
@ -176,7 +175,7 @@ impl PostInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for PostInfo {
|
impl PartialEq for JPostInfo {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
let self_part = match self {
|
let self_part = match self {
|
||||||
Chapter { part, .. } => part,
|
Chapter { part, .. } => part,
|
||||||
|
@ -192,7 +191,7 @@ impl PartialEq for PostInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for PostInfo {
|
impl PartialOrd for JPostInfo {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
if self.gt(other) {
|
if self.gt(other) {
|
||||||
Some(Ordering::Greater)
|
Some(Ordering::Greater)
|
||||||
|
@ -240,9 +239,26 @@ impl PartialOrd for PostInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn check_feed(series_slug: &str, series_has_parts: bool) -> Result<Vec<PostInfo>, ()> {
|
pub(crate) struct JFetcherOptions {
|
||||||
|
series_slug: String,
|
||||||
|
series_has_parts: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JFetcherOptions {
|
||||||
|
pub(crate) fn new(series_slug: String, series_has_parts: bool) -> Self {
|
||||||
|
JFetcherOptions {
|
||||||
|
series_slug,
|
||||||
|
series_has_parts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Fetcher for JFetcherOptions {
|
||||||
|
type Return = JPostInfo;
|
||||||
|
async fn check_feed(&self) -> Result<Vec<Self::Return>, ()> {
|
||||||
let response = match HTTP_CLIENT
|
let response = match HTTP_CLIENT
|
||||||
.get(api_url!() + "/series/" + series_slug + "/volumes?format=json")
|
.get(api_url!() + "/series/" + self.series_slug.as_str() + "/volumes?format=json")
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
@ -272,20 +288,20 @@ pub(crate) async fn check_feed(series_slug: &str, series_has_parts: bool) -> Res
|
||||||
volume_brief_data.volumes.reverse(); // Makes breaking out of the volume loop easier
|
volume_brief_data.volumes.reverse(); // Makes breaking out of the volume loop easier
|
||||||
|
|
||||||
// If no parts just use 0 as Part indicator as no Series with Parts has a Part 0
|
// If no parts just use 0 as Part indicator as no Series with Parts has a Part 0
|
||||||
let mut volume_map: HashMap<u8, PostInfo> = HashMap::new();
|
let mut volume_map: HashMap<u8, JPostInfo> = HashMap::new();
|
||||||
let mut prepub_map: HashMap<u8, PostInfo> = HashMap::new();
|
let mut prepub_map: HashMap<u8, JPostInfo> = HashMap::new();
|
||||||
|
|
||||||
for volume in volume_brief_data.volumes.iter() {
|
for volume in volume_brief_data.volumes.iter() {
|
||||||
let publishing_date = DateTime::parse_from_rfc3339(&volume.publishing).unwrap();
|
let publishing_date = DateTime::parse_from_rfc3339(&volume.publishing).unwrap();
|
||||||
if publishing_date < Utc::now().sub(Duration::days(PAST_DAYS_ELIGIBLE as i64)) {
|
if publishing_date < Utc::now().sub(Duration::days(PAST_DAYS_ELIGIBLE as i64)) {
|
||||||
match series_has_parts {
|
match self.series_has_parts {
|
||||||
true => continue,
|
true => continue,
|
||||||
false => break,
|
false => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let new_part_info: PartInfo;
|
let new_part_info: PartInfo;
|
||||||
|
|
||||||
if series_has_parts {
|
if self.series_has_parts {
|
||||||
let mut part_number: Option<u8> = None;
|
let mut part_number: Option<u8> = None;
|
||||||
let splits: Vec<&str> = volume.slug.split('-').collect();
|
let splits: Vec<&str> = volume.slug.split('-').collect();
|
||||||
for (index, split) in splits.clone().into_iter().enumerate() {
|
for (index, split) in splits.clone().into_iter().enumerate() {
|
||||||
|
@ -311,11 +327,12 @@ pub(crate) async fn check_feed(series_slug: &str, series_has_parts: bool) -> Res
|
||||||
}
|
}
|
||||||
|
|
||||||
let post_url = format!(
|
let post_url = format!(
|
||||||
"{}/series/{series_slug}#volume-{}",
|
"{}/series/{}#volume-{}",
|
||||||
jnc_base_url!(),
|
jnc_base_url!(),
|
||||||
|
self.series_slug.as_str(),
|
||||||
volume.number
|
volume.number
|
||||||
);
|
);
|
||||||
let post_details = LemmyPostInfo {
|
let post_details = lemmy::PostInfoInner {
|
||||||
title: volume.title.clone(),
|
title: volume.title.clone(),
|
||||||
url: Url::parse(&post_url).unwrap(),
|
url: Url::parse(&post_url).unwrap(),
|
||||||
};
|
};
|
||||||
|
@ -356,14 +373,16 @@ pub(crate) async fn check_feed(series_slug: &str, series_has_parts: bool) -> Res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut result_vec: Vec<PostInfo> = volume_map.values().cloned().collect();
|
let mut result_vec: Vec<JPostInfo> = volume_map.values().cloned().collect();
|
||||||
let mut prepub_vec: Vec<PostInfo> = prepub_map.values().cloned().collect();
|
let mut prepub_vec: Vec<JPostInfo> = prepub_map.values().cloned().collect();
|
||||||
result_vec.append(&mut prepub_vec);
|
result_vec.append(&mut prepub_vec);
|
||||||
|
|
||||||
Ok(result_vec)
|
Ok(result_vec)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_latest_prepub(volume_slug: &str) -> Result<Option<LemmyPostInfo>, ()> {
|
|
||||||
|
async fn get_latest_prepub(volume_slug: &str) -> Result<Option<lemmy::PostInfoInner>, ()> {
|
||||||
let response = match HTTP_CLIENT
|
let response = match HTTP_CLIENT
|
||||||
.get(api_url!() + "/volumes/" + volume_slug + "/parts?format=json")
|
.get(api_url!() + "/volumes/" + volume_slug + "/parts?format=json")
|
||||||
.send()
|
.send()
|
||||||
|
@ -394,7 +413,7 @@ async fn get_latest_prepub(volume_slug: &str) -> Result<Option<LemmyPostInfo>, (
|
||||||
};
|
};
|
||||||
volume_prepub_parts_data.parts.reverse(); // Makes breaking out of the parts loop easier
|
volume_prepub_parts_data.parts.reverse(); // Makes breaking out of the parts loop easier
|
||||||
|
|
||||||
let mut post_details: Option<LemmyPostInfo> = None;
|
let mut post_details: Option<lemmy::PostInfoInner> = None;
|
||||||
|
|
||||||
for prepub_part in volume_prepub_parts_data.parts.iter() {
|
for prepub_part in volume_prepub_parts_data.parts.iter() {
|
||||||
let publishing_date = DateTime::parse_from_rfc3339(&prepub_part.launch).unwrap();
|
let publishing_date = DateTime::parse_from_rfc3339(&prepub_part.launch).unwrap();
|
||||||
|
@ -405,7 +424,7 @@ async fn get_latest_prepub(volume_slug: &str) -> Result<Option<LemmyPostInfo>, (
|
||||||
}
|
}
|
||||||
|
|
||||||
let post_url = format!("{}/read/{}", jnc_base_url!(), prepub_part.slug);
|
let post_url = format!("{}/read/{}", jnc_base_url!(), prepub_part.slug);
|
||||||
post_details = Some(LemmyPostInfo {
|
post_details = Some(lemmy::PostInfoInner {
|
||||||
title: prepub_part.title.clone(),
|
title: prepub_part.title.clone(),
|
||||||
url: Url::parse(&post_url).unwrap(),
|
url: Url::parse(&post_url).unwrap(),
|
||||||
});
|
});
|
Loading…
Reference in a new issue