Skip to content

Commit a6820b3

Browse files
committed
Article app (with Wallabag support)
First version of built-in Wallabag support. There are a number of things that aren't quite there yet: * The long-press menu on an entry doesn't actually do anything. This needs to be implemented. * Related: starring/archiving/removing isn't implemented yet. * There's no download progress, there should be some progress indicator. * There's currently nothing that prevents two syncs from running at the same time (and messing with each other). * All articles are always downloaded. Ideally, only new unread articles would be downloaded. * The epubs downloaded from Wallabag aren't great, and are missing important features like blockquotes. We might want to create our own by converting them from HTML to custom epubs.
1 parent 68c3c28 commit a6820b3

File tree

19 files changed

+2132
-43
lines changed

19 files changed

+2132
-43
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
/libs
77
/bin
88
/Settings.toml
9+
/.articles
910
/.metadata.json
1011
/.reading-states
1112
/.fat32-epoch

Cargo.lock

Lines changed: 120 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/core/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,6 @@ rand_core = "0.6.4"
3939
rand_xoshiro = "0.6.0"
4040
percent-encoding = "2.3.1"
4141
chrono = { version = "0.4.38", features = ["serde", "clock"], default-features = false }
42+
ureq = { version = "3.0.12", features = ["cookies"] }
43+
http = "1.3.1"
44+
url = "2.5.4"

crates/core/src/articles/mod.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
pub mod wallabag;
2+
3+
use chrono::NaiveDateTime;
4+
use serde::{Deserialize, Serialize};
5+
use std::{
6+
collections::BTreeSet,
7+
fs::{self, File},
8+
io::Error,
9+
os::unix::fs::MetadataExt,
10+
path::PathBuf,
11+
};
12+
13+
use crate::{
14+
metadata::{FileInfo, Info},
15+
settings::ArticleList,
16+
};
17+
18+
pub const ARTICLES_DIR: &str = ".articles";
19+
20+
#[derive(Serialize, Deserialize)]
21+
pub struct ArticleIndex {
22+
pub articles: Vec<Article>,
23+
}
24+
25+
#[derive(Serialize, Deserialize, Clone)]
26+
pub struct Article {
27+
pub id: u64,
28+
pub title: String,
29+
pub domain: String,
30+
pub authors: Vec<String>,
31+
pub format: String,
32+
pub language: String,
33+
pub reading_time: u32,
34+
pub added: NaiveDateTime,
35+
pub starred: bool,
36+
pub archived: bool,
37+
}
38+
39+
impl Article {
40+
fn path(&self) -> PathBuf {
41+
std::path::absolute(PathBuf::from(format!(
42+
"{}/article-{}.{}",
43+
ARTICLES_DIR, self.id, self.format
44+
)))
45+
.unwrap()
46+
}
47+
48+
pub fn file(&self) -> FileInfo {
49+
let path = self.path();
50+
let size = match fs::metadata(&path) {
51+
Ok(metadata) => metadata.size(),
52+
Err(_err) => 0,
53+
};
54+
FileInfo {
55+
path: path,
56+
kind: self.format.to_owned(),
57+
size: size,
58+
}
59+
}
60+
61+
pub fn info(&self) -> Info {
62+
Info {
63+
title: self.title.to_owned(),
64+
subtitle: self.domain.to_owned(),
65+
author: self.authors.join(", "),
66+
year: "".to_string(),
67+
language: self.language.to_owned(),
68+
publisher: "".to_string(),
69+
series: "".to_string(),
70+
edition: "".to_string(),
71+
volume: "".to_string(),
72+
number: "".to_string(),
73+
identifier: "".to_string(),
74+
categories: BTreeSet::new(),
75+
file: self.file(),
76+
reader: None,
77+
reader_info: None,
78+
toc: None,
79+
added: self.added,
80+
}
81+
}
82+
}
83+
84+
pub fn read_index(article_list: ArticleList) -> Result<Vec<Article>, Error> {
85+
let file = File::open(ARTICLES_DIR.to_owned() + "/index.json")?;
86+
let index: ArticleIndex = serde_json::from_reader(file)?;
87+
88+
Ok(index
89+
.articles
90+
.into_iter()
91+
.filter(|article| match article_list {
92+
ArticleList::Unread => !article.archived,
93+
ArticleList::Starred => article.starred,
94+
ArticleList::Archive => article.archived,
95+
})
96+
.collect())
97+
}

0 commit comments

Comments
 (0)