Rewrite Version 3

This commit is contained in:
Neshura 2024-05-07 22:10:21 +02:00
parent aefceda628
commit 6520cc65a3
Signed by: Neshura
GPG key ID: B6983AAA6B9A7A6C
8 changed files with 715 additions and 481 deletions
src/fetchers

View file

@ -1,16 +1,13 @@
use crate::{HTTP_CLIENT, lemmy};
use crate::{HTTP_CLIENT};
use chrono::{DateTime, Duration, Utc};
use serde_derive::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::collections::HashMap;
use std::ops::Sub;
use async_trait::async_trait;
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};
use crate::fetchers::{FetcherTrait};
use crate::lemmy::{PartInfo, PostInfo, PostInfoInner, PostType};
use systemd_journal_logger::connected_to_journal;
use crate::lemmy::PartInfo::{NoParts, Part};
macro_rules! error {
($msg:tt) => {
@ -91,191 +88,31 @@ pub(crate) struct ChapterDetail {
pub(crate) cover: Option<Cover>,
}
#[derive(Debug, Copy, Clone)]
pub(crate) enum PartInfo {
NoParts,
Part(u8),
}
impl PartInfo {
pub(crate) fn as_u8(&self) -> u8 {
match self {
Part(number) => *number,
NoParts => 0,
}
}
pub(crate) fn as_string(&self) -> String {
self.as_u8().to_string()
}
}
impl PartialEq for PartInfo {
fn eq(&self, other: &Self) -> bool {
let self_numeric = self.as_u8();
let other_numeric = other.as_u8();
self_numeric == other_numeric
}
}
impl PartialOrd for PartInfo {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if self.gt(other) {
Some(Ordering::Greater)
} else if self.eq(other) {
Some(Ordering::Equal)
} else {
Some(Ordering::Less)
}
}
fn lt(&self, other: &Self) -> bool {
let self_numeric = self.as_u8();
let other_numeric = other.as_u8();
self_numeric < other_numeric
}
fn le(&self, other: &Self) -> bool {
!self.gt(other)
}
fn gt(&self, other: &Self) -> bool {
let self_numeric = self.as_u8();
let other_numeric = other.as_u8();
self_numeric > other_numeric
}
fn ge(&self, other: &Self) -> bool {
!self.lt(other)
}
}
#[derive(Debug, Clone)]
pub(crate) enum JPostInfo {
Chapter {
part: PartInfo,
lemmy_info: PostInfoInner,
},
Volume {
part: PartInfo,
description: String,
lemmy_info: PostInfoInner,
},
}
impl JPostInfo {
pub(crate) fn get_part_info(&self) -> PartInfo {
match self {
Chapter {
part: part_info, ..
} => *part_info,
Volume {
part: part_info, ..
} => *part_info,
}
}
}
impl PostInfo for JPostInfo {
fn get_info(&self) -> PostInfoInner {
match self {
Chapter { lemmy_info, .. } => lemmy_info.clone(),
Volume { lemmy_info, .. } => lemmy_info.clone(),
}
}
fn get_description(&self) -> Option<String> {
match self {
Chapter { .. } => None,
Volume { description, .. } => Some(description.clone()),
}
}
}
impl PartialEq for JPostInfo {
fn eq(&self, other: &Self) -> bool {
let self_part = match self {
Chapter { part, .. } => part,
Volume { part, .. } => part,
};
let other_part = match other {
Chapter { part, .. } => part,
Volume { part, .. } => part,
};
self_part.eq(other_part)
}
}
impl PartialOrd for JPostInfo {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if self.gt(other) {
Some(Ordering::Greater)
} else if self.eq(other) {
Some(Ordering::Equal)
} else {
Some(Ordering::Less)
}
}
fn lt(&self, other: &Self) -> bool {
let self_part = match self {
Chapter { part, .. } => part,
Volume { part, .. } => part,
};
let other_part = match other {
Chapter { part, .. } => part,
Volume { part, .. } => part,
};
self_part < other_part
}
fn le(&self, other: &Self) -> bool {
!self.gt(other)
}
fn gt(&self, other: &Self) -> bool {
let self_part = match self {
Chapter { part, .. } => part,
Volume { part, .. } => part,
};
let other_part = match other {
Chapter { part, .. } => part,
Volume { part, .. } => part,
};
self_part > other_part
}
fn ge(&self, other: &Self) -> bool {
!self.lt(other)
}
}
pub(crate) struct JFetcherOptions {
#[derive(Deserialize, Serialize, Debug, Clone)]
pub(crate) struct JNovelFetcher {
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
}
impl JNovelFetcher {
pub(crate) fn set_series(&mut self, series: String) {
self.series_slug = series;
}
pub(crate) fn set_part_option(&mut self, has_parts: bool) {
self.series_has_parts = has_parts;
}
}
#[async_trait]
impl Fetcher for JFetcherOptions {
type Return = JPostInfo;
async fn check_feed(&self) -> Result<Vec<Self::Return>, ()> {
impl FetcherTrait for JNovelFetcher {
fn new() -> Self {
JNovelFetcher {
series_slug: "".to_owned(),
series_has_parts: false
}
}
async fn check_feed(&self) -> Result<Vec<PostInfo>, ()> {
let response = match HTTP_CLIENT
.get(api_url!() + "/series/" + self.series_slug.as_str() + "/volumes?format=json")
.send()
@ -307,8 +144,8 @@ impl Fetcher for JFetcherOptions {
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
let mut volume_map: HashMap<u8, JPostInfo> = HashMap::new();
let mut prepub_map: HashMap<u8, JPostInfo> = HashMap::new();
let mut volume_map: HashMap<u8, PostInfo> = HashMap::new();
let mut prepub_map: HashMap<u8, PostInfo> = HashMap::new();
for volume in volume_brief_data.volumes.iter() {
let publishing_date = DateTime::parse_from_rfc3339(&volume.publishing).unwrap();
@ -351,14 +188,15 @@ impl Fetcher for JFetcherOptions {
self.series_slug.as_str(),
volume.number
);
let post_details = lemmy::PostInfoInner {
let post_details = PostInfoInner {
title: volume.title.clone(),
url: Url::parse(&post_url).unwrap(),
};
let new_post_info = Volume {
part: new_part_info,
description: volume.short_description.clone(),
let new_post_info = PostInfo {
post_type: Some(PostType::Volume),
part: Some(new_part_info),
description: Some(volume.short_description.clone()),
lemmy_info: post_details,
};
@ -376,9 +214,11 @@ impl Fetcher for JFetcherOptions {
}
if let Some(prepub_info) = get_latest_prepub(&volume.slug).await? {
let prepub_post_info = Chapter {
part: new_part_info,
let prepub_post_info = PostInfo {
post_type: Some(PostType::Chapter),
part: Some(new_part_info),
lemmy_info: prepub_info,
description: None,
};
prepub_map
@ -392,8 +232,8 @@ impl Fetcher for JFetcherOptions {
}
}
let mut result_vec: Vec<JPostInfo> = volume_map.values().cloned().collect();
let mut prepub_vec: Vec<JPostInfo> = prepub_map.values().cloned().collect();
let mut result_vec: Vec<PostInfo> = volume_map.values().cloned().collect();
let mut prepub_vec: Vec<PostInfo> = prepub_map.values().cloned().collect();
result_vec.append(&mut prepub_vec);
Ok(result_vec)
@ -401,7 +241,7 @@ impl Fetcher for JFetcherOptions {
}
async fn get_latest_prepub(volume_slug: &str) -> Result<Option<lemmy::PostInfoInner>, ()> {
async fn get_latest_prepub(volume_slug: &str) -> Result<Option<PostInfoInner>, ()> {
let response = match HTTP_CLIENT
.get(api_url!() + "/volumes/" + volume_slug + "/parts?format=json")
.send()
@ -432,7 +272,7 @@ async fn get_latest_prepub(volume_slug: &str) -> Result<Option<lemmy::PostInfoIn
};
volume_prepub_parts_data.parts.reverse(); // Makes breaking out of the parts loop easier
let mut post_details: Option<lemmy::PostInfoInner> = None;
let mut post_details: Option<PostInfoInner> = None;
for prepub_part in volume_prepub_parts_data.parts.iter() {
let publishing_date = DateTime::parse_from_rfc3339(&prepub_part.launch).unwrap();
@ -443,7 +283,7 @@ async fn get_latest_prepub(volume_slug: &str) -> Result<Option<lemmy::PostInfoIn
}
let post_url = format!("{}/read/{}", jnc_base_url!(), prepub_part.slug);
post_details = Some(lemmy::PostInfoInner {
post_details = Some(PostInfoInner {
title: prepub_part.title.clone(),
url: Url::parse(&post_url).unwrap(),
});