Automatic Lemmy Post creation using jnovel rss feeds only on new chapter

This commit is contained in:
Neshura 2023-06-19 00:26:50 +02:00
parent c1eba780d1
commit 17283a9d9b
Signed by: Neshura
GPG key ID: B6983AAA6B9A7A6C
5 changed files with 2573 additions and 0 deletions

1785
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

17
Cargo.toml Normal file
View file

@ -0,0 +1,17 @@
[package]
name = "ascendance-of-a-bookworm-bot"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chrono = "0.4.26"
lemmy_api_common = "0.17.4"
lemmy_db_schema = "0.17.4"
once_cell = "1.18.0"
reqwest = { version = "0.11.18", features = ["blocking", "json"] }
serde = "1.0.164"
serde_derive = "1.0.164"
serde_json = "1.0.97"
url = "2.4.0"

411
jnovel-example.json Normal file
View file

@ -0,0 +1,411 @@
{
"version": "https://jsonfeed.org/version/1",
"title": "Ascendance of a Bookworm",
"home_page_url": "https://j-novel.club/series/ascendance-of-a-bookworm",
"description": "A young woman who loves books dies and is reborn in another world as Myne, a sickly child from a poor family. Worst of all, there are almost no books in this world! So Myne decides that she'll just have to make her own and become a librarian.",
"author": {
"name": "J-Novel Club"
},
"items": [
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-6",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-6",
"title": "Ascendance of a Bookworm: Part 5 Volume 5 Part 6",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 5 Part 6 (available for subscribers)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-64872b31036804ff1be232c8/bookworm5.5-cover-400.jpg",
"date_published": "2023-06-12T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-5",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-5",
"title": "Ascendance of a Bookworm: Part 5 Volume 5 Part 5",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 5 Part 5 (available for subscribers)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-647df642f839a63a784c8b24/bookworm5.5-cover-400.jpg",
"date_published": "2023-06-05T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-4",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-4",
"title": "Ascendance of a Bookworm: Part 5 Volume 5 Part 4",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 5 Part 4 (available for subscribers)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-6474c52538f2134856b56bbe/bookworm5.5-cover-400.jpg",
"date_published": "2023-05-29T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-3",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-3",
"title": "Ascendance of a Bookworm: Part 5 Volume 5 Part 3",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 5 Part 3 (available for subscribers)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-646b844e036804ff1be23118/bookworm5.5-cover-400.jpg",
"date_published": "2023-05-22T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-2",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-2",
"title": "Ascendance of a Bookworm: Part 5 Volume 5 Part 2",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 5 Part 2 (available for subscribers)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-64624ef7a2ea846d6b3f5307/bookworm5.5-cover-400.jpg",
"date_published": "2023-05-15T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-1",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-5-part-1",
"title": "Ascendance of a Bookworm: Part 5 Volume 5 Part 1",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 5 Part 1 (free)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-64594c97cabacabb2c498bfb/bookworm5.5-cover-400.jpg",
"date_published": "2023-05-08T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-8",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-8",
"title": "Ascendance of a Bookworm: Part 5 Volume 4 Part 8",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 4 Part 8 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-64400ee2bbfa9b9015a3b4c2/bookworm5.4-cover-400.jpg",
"date_published": "2023-05-01T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-7",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-7",
"title": "Ascendance of a Bookworm: Part 5 Volume 4 Part 7",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 4 Part 7 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-64400e5f6f9feb2622ff757a/bookworm5.4-cover-400.jpg",
"date_published": "2023-04-24T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-6",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-6",
"title": "Ascendance of a Bookworm: Part 5 Volume 4 Part 6",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 4 Part 6 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-643d5c02bbfa9b9015a3b46a/bookworm5.4-cover-400.jpg",
"date_published": "2023-04-17T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-5",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-5",
"title": "Ascendance of a Bookworm: Part 5 Volume 4 Part 5",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 4 Part 5 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-64342367f2df38506778bf87/bookworm5.4-cover-400.jpg",
"date_published": "2023-04-10T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-4",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-4",
"title": "Ascendance of a Bookworm: Part 5 Volume 4 Part 4",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 4 Part 4 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-642b04fc89f12f4d2bf611ac/bookworm5.4-cover-400.jpg",
"date_published": "2023-04-03T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-3",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-3",
"title": "Ascendance of a Bookworm: Part 5 Volume 4 Part 3",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 4 Part 3 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-6421b4627686c3cd55fc00aa/bookworm5.4-cover-400.jpg",
"date_published": "2023-03-27T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-2",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-2",
"title": "Ascendance of a Bookworm: Part 5 Volume 4 Part 2",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 4 Part 2 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-64188110e9be8e3e55d5c6a5/bookworm5.4-cover-400.jpg",
"date_published": "2023-03-20T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-1",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-4-part-1",
"title": "Ascendance of a Bookworm: Part 5 Volume 4 Part 1",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 4 Part 1 (free)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-640f67a67877a2862d88758b/bookworm5.4-cover-400.jpg",
"date_published": "2023-03-13T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-10",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-10",
"title": "Ascendance of a Bookworm: Part 5 Volume 3 Part 10",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 3 Part 10 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63f5f58e785e215d51f3969e/bookworm5.3-cover-400.jpg",
"date_published": "2023-03-06T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-9",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-9",
"title": "Ascendance of a Bookworm: Part 5 Volume 3 Part 9",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 3 Part 9 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63f5f49fd69a89450c0cf2d4/bookworm5.3-cover-400.jpg",
"date_published": "2023-02-27T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-8",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-8",
"title": "Ascendance of a Bookworm: Part 5 Volume 3 Part 8",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 3 Part 8 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63f3efb20179968f16229033/bookworm5.3-cover-400.jpg",
"date_published": "2023-02-20T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-7",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-7",
"title": "Ascendance of a Bookworm: Part 5 Volume 3 Part 7",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 3 Part 7 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63ea88e2d67ef0a916a929ca/bookworm5.3-cover-400.jpg",
"date_published": "2023-02-13T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-6",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-6",
"title": "Ascendance of a Bookworm: Part 5 Volume 3 Part 6",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 3 Part 6 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63e14f6c2f6ef88b59e0cc3d/bookworm5.3-cover-400.jpg",
"date_published": "2023-02-06T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-5",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-5",
"title": "Ascendance of a Bookworm: Part 5 Volume 3 Part 5",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 3 Part 5 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63d817bc552bedd02ef0f2d2/bookworm5.3-cover-400.jpg",
"date_published": "2023-01-30T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-4",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-4",
"title": "Ascendance of a Bookworm: Part 5 Volume 3 Part 4",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 3 Part 4 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63cef187c1f813e8051c11f6/bookworm5.3-cover-400.jpg",
"date_published": "2023-01-23T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-3",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-3",
"title": "Ascendance of a Bookworm: Part 5 Volume 3 Part 3",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 3 Part 3 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63c5c96cfcd981160ed7f4b9/bookworm5.3-cover-400.jpg",
"date_published": "2023-01-16T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-2",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-2",
"title": "Ascendance of a Bookworm: Part 5 Volume 3 Part 2",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 3 Part 2 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63bc72e9482b67ed0f4e130f/bookworm5.3-cover-400.jpg",
"date_published": "2023-01-09T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-1",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-3-part-1",
"title": "Ascendance of a Bookworm: Part 5 Volume 3 Part 1",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 3 Part 1 (free)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63af316e41fdb4b16fa9f3b5/bookworm5.3-cover-400.jpg",
"date_published": "2023-01-02T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-8",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-8",
"title": "Ascendance of a Bookworm: Part 5 Volume 2 Part 8",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 2 Part 8 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63971a23811dc9950fe219ad/bookworm5.2-cover-400.jpg",
"date_published": "2022-12-26T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-7",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-7",
"title": "Ascendance of a Bookworm: Part 5 Volume 2 Part 7",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 2 Part 7 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-639719efa6449c0010fb311e/bookworm5.2-cover-400.jpg",
"date_published": "2022-12-19T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-6",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-6",
"title": "Ascendance of a Bookworm: Part 5 Volume 2 Part 6",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 2 Part 6 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-6397050a75e261ab0f505a6b/bookworm5.2-cover-400.jpg",
"date_published": "2022-12-12T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-5",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-5",
"title": "Ascendance of a Bookworm: Part 5 Volume 2 Part 5",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 2 Part 5 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-638e67708fc63f8c3f1a524a/bookworm5.2-cover-400.jpg",
"date_published": "2022-12-05T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-4",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-4",
"title": "Ascendance of a Bookworm: Part 5 Volume 2 Part 4",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 2 Part 4 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-6384ed590517e1e171e6c551/bookworm5.2-cover-400.jpg",
"date_published": "2022-11-28T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-3",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-3",
"title": "Ascendance of a Bookworm: Part 5 Volume 2 Part 3",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 2 Part 3 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-637b9c13449c28d01bb4b4cd/bookworm5.2-cover-400.jpg",
"date_published": "2022-11-21T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-2",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-2",
"title": "Ascendance of a Bookworm: Part 5 Volume 2 Part 2",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 2 Part 2 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63729a99563cdce739e17427/bookworm5.2-cover-400.jpg",
"date_published": "2022-11-14T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-1",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-2-part-1",
"title": "Ascendance of a Bookworm: Part 5 Volume 2 Part 1",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 2 Part 1 (free)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-636942940f70ce58739b2844/bookworm5.2-cover-400.jpg",
"date_published": "2022-11-07T22:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-8",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-8",
"title": "Ascendance of a Bookworm: Part 5 Volume 1 Part 8",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 1 Part 8 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-634dbbabb2895e4e5862a45e/bookworm5.1-cover-400.jpg",
"date_published": "2022-10-31T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-7",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-7",
"title": "Ascendance of a Bookworm: Part 5 Volume 1 Part 7",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 1 Part 7 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-634dbb87a25e943074d2ede9/bookworm5.1-cover-400.jpg",
"date_published": "2022-10-24T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-6",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-6",
"title": "Ascendance of a Bookworm: Part 5 Volume 1 Part 6",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 1 Part 6 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-634dbab44f712abf7c52d3a0/bookworm5.1-cover-400.jpg",
"date_published": "2022-10-17T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-5",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-5",
"title": "Ascendance of a Bookworm: Part 5 Volume 1 Part 5",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 1 Part 5 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-63443bda3b3c7e893a05596b/bookworm5.1-cover-400.jpg",
"date_published": "2022-10-10T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-4",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-4",
"title": "Ascendance of a Bookworm: Part 5 Volume 1 Part 4",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 1 Part 4 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-633b2f6c95d05f661f46b179/bookworm5.1-cover-400.jpg",
"date_published": "2022-10-03T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-3",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-3",
"title": "Ascendance of a Bookworm: Part 5 Volume 1 Part 3",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 1 Part 3 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-6331af2e6d287a7b7268489d/bookworm5.1-cover-400.jpg",
"date_published": "2022-09-26T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-2",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-2",
"title": "Ascendance of a Bookworm: Part 5 Volume 1 Part 2",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 1 Part 2 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-6328d459853da3577cbdd6f9/bookworm5.1-cover-400.jpg",
"date_published": "2022-09-19T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-1",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-5-volume-1-part-1",
"title": "Ascendance of a Bookworm: Part 5 Volume 1 Part 1",
"summary": "Read Ascendance of a Bookworm: Part 5 Volume 1 Part 1 (free)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-631f9aed59b60299586f0b29/bookworm5.1-cover-400.jpg",
"date_published": "2022-09-12T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-8",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-8",
"title": "Ascendance of a Bookworm: Part 4 Volume 9 Part 8",
"summary": "Read Ascendance of a Bookworm: Part 4 Volume 9 Part 8 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-6303e4666164ffe71fb3039c/bookworm4.9-cover-400.jpg",
"date_published": "2022-09-05T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-7",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-7",
"title": "Ascendance of a Bookworm: Part 4 Volume 9 Part 7",
"summary": "Read Ascendance of a Bookworm: Part 4 Volume 9 Part 7 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-6303e45cbfd3ac0620743003/bookworm4.9-cover-400.jpg",
"date_published": "2022-08-29T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-6",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-6",
"title": "Ascendance of a Bookworm: Part 4 Volume 9 Part 6",
"summary": "Read Ascendance of a Bookworm: Part 4 Volume 9 Part 6 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-6303e3df95d05f661f46ae31/bookworm4.9-cover-400.jpg",
"date_published": "2022-08-22T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-5",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-5",
"title": "Ascendance of a Bookworm: Part 4 Volume 9 Part 5",
"summary": "Read Ascendance of a Bookworm: Part 4 Volume 9 Part 5 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-62fa9d2e3690f46d54265b03/bookworm4.9-cover-400.jpg",
"date_published": "2022-08-15T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-4",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-4",
"title": "Ascendance of a Bookworm: Part 4 Volume 9 Part 4",
"summary": "Read Ascendance of a Bookworm: Part 4 Volume 9 Part 4 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-62f16bb8a9f787ca5446a1b8/bookworm4.9-cover-400.jpg",
"date_published": "2022-08-08T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-3",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-3",
"title": "Ascendance of a Bookworm: Part 4 Volume 9 Part 3",
"summary": "Read Ascendance of a Bookworm: Part 4 Volume 9 Part 3 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-62e792b17d8cd29c54d666b6/bookworm4.9-cover-400.jpg",
"date_published": "2022-08-01T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-2",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-2",
"title": "Ascendance of a Bookworm: Part 4 Volume 9 Part 2",
"summary": "Read Ascendance of a Bookworm: Part 4 Volume 9 Part 2 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-62def2b5de7f5911540ea23e/bookworm4.9-cover-400.jpg",
"date_published": "2022-07-25T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-1",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-9-part-1",
"title": "Ascendance of a Bookworm: Part 4 Volume 9 Part 1",
"summary": "Read Ascendance of a Bookworm: Part 4 Volume 9 Part 1 (free)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-62d599c27d8cd29c54d665d5/bookworm4.9-cover-400.jpg",
"date_published": "2022-07-18T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-8-part-8",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-8-part-8",
"title": "Ascendance of a Bookworm: Part 4 Volume 8 Part 8",
"summary": "Read Ascendance of a Bookworm: Part 4 Volume 8 Part 8 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-62bb698fd440cc5d411b50b1/bookworm4.8-cover-400.jpg",
"date_published": "2022-07-11T21:00:00Z"
},
{
"id": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-8-part-7",
"url": "https://j-novel.club/read/ascendance-of-a-bookworm-part-4-volume-8-part-7",
"title": "Ascendance of a Bookworm: Part 4 Volume 8 Part 7",
"summary": "Read Ascendance of a Bookworm: Part 4 Volume 8 Part 7 (expired)",
"image": "https://d2dq7ifhe7bu0f.cloudfront.net/Part-62ba0e44cbbd90be7aca1380/bookworm4.8-cover-400.jpg",
"date_published": "2022-07-04T21:00:00Z"
}
]
}

178
src/config/mod.rs Normal file
View file

@ -0,0 +1,178 @@
use std::{fs::{self, OpenOptions}, path::Path, io::Write};
use lemmy_api_common::sensitive::Sensitive;
use serde_derive::{Deserialize, Serialize};
macro_rules! pub_struct {
($name:ident {$($field:ident: $t:ty,)*}) => {
#[derive(Serialize, Deserialize, Clone)]
pub(crate) struct $name {
$(pub(crate) $field: $t), *
}
}
}
// Secrets structs
pub_struct!(Secrets {
lemmy: LemmyLogin,
reddit: RedditLogin,
});
impl Secrets {
pub(crate) fn load() -> Secrets {
let file_contents = match fs::read_to_string("secrets.json") {
Ok(data) => data,
Err(e) => panic!("ERROR: secrets.json could not be read:\n\n{:#?}", e),
};
let config_parse: Secrets = match serde_json::from_str(&file_contents) {
Ok(data) => data,
Err(e) => panic!("ERROR: secrets.json could not be parsed:\n\n{:#?}", e),
};
return config_parse;
}
}
#[derive(Serialize, Deserialize, Clone)]
pub(crate) struct LemmyLogin {
pub(crate) username: String,
password: String
}
impl LemmyLogin {
pub(crate) fn get_username(&self) -> Sensitive<String> {
return Sensitive::new(self.username.clone());
}
pub(crate) fn get_password(&self) -> Sensitive<String> {
return Sensitive::new(self.password.clone())
}
}
#[derive(Serialize, Deserialize, Clone)]
pub(crate) struct RedditLogin {
pub(crate) app_id: String,
app_secret: String,
refresh_token: String,
redirect_uri: String,
}
// Config structs
pub_struct!(Config {
reddit_config: RedditConfig,
feeds: Vec<FeedSetting>,
});
impl Config {
pub(crate) fn load() -> Config {
let file_contents = match fs::read_to_string("config.json") {
Ok(data) => data,
Err(e) => panic!("ERROR: config.json could not be read:\n\n{:#?}", e),
};
let config_parse: Config = match serde_json::from_str(&file_contents) {
Ok(data) => data,
Err(e) => panic!("ERROR: config.json could not be parsed:\n\n{:#?}", e),
};
return config_parse;
}
}
pub_struct!(RedditConfig {
user_agent: String,
subreddit: String,
});
pub_struct!(FeedSetting {
feed_url: String,
communities: FeedCommunities,
reddit: FeedRedditSettings,
});
pub_struct!(FeedCommunities {
chapter: LemmyCommunities,
volume: LemmyCommunities,
});
#[derive(Serialize, Deserialize, Clone)]
#[allow(non_camel_case_types)]
pub(crate) enum LemmyCommunities {
aobwebnovel,
aobprepub,
aoblightnovel,
aobmanga,
aobanime
}
pub_struct!(FeedRedditSettings {
enabled: bool,
flair: String,
});
// Posts structs
pub_struct!(PrevPost {
title: String,
last_post_url: String,
});
impl PrevPost {
pub(crate) fn load() -> Vec<PrevPost> {
let history;
if Path::new("posts.json").exists() {
let file_contents = match fs::read_to_string("posts.json") {
Ok(data) => data,
Err(e) => panic!("ERROR: secrets.json could not be read:\n\n{:#?}", e),
};
if file_contents.len() > 0 {
let history_parse: Vec<PrevPost> = match serde_json::from_str(&file_contents) {
Ok(data) => data,
Err(e) => panic!("ERROR: secrets.json could not be parsed:\n\n{:#?}", e),
};
history = history_parse;
}
else {
history = [].to_vec()
}
}
else {
let _ = fs::File::create("posts.json");
history = [].to_vec()
}
return history;
}
pub(crate) fn save(data: &Vec<PrevPost>) {
let mut file = OpenOptions::new().read(true).write(true).create(true).open("posts.json").unwrap();
let json_data = serde_json::to_string_pretty(&data).unwrap();
write!(&mut file, "{}", json_data).unwrap();
}
}
// RSS Feed Structs
pub_struct!(FeedData {
version: String,
title: String,
home_page_url: String,
description: String,
author: FeedAuthor,
items: Vec<FeedEntry>,
});
pub_struct!(FeedAuthor {
name: String,
});
pub_struct!(FeedEntry {
id: String,
url: String,
title: String,
summary: String,
image: Option<String>,
date_published: String,
});

182
src/main.rs Normal file
View file

@ -0,0 +1,182 @@
use chrono::Utc;
use config::{Config, PrevPost, Secrets};
use lemmy_api_common::{
person::{Login, LoginResponse},
post::{CreatePost, GetPosts, GetPostsResponse},
sensitive::Sensitive,
};
use lemmy_db_schema::{
newtypes::{CommunityId, LanguageId},
ListingType, SortType,
};
use once_cell::sync::Lazy;
use reqwest::{blocking::Client, StatusCode};
use std::{thread::sleep, time};
use url::Url;
use crate::config::FeedData;
mod config;
pub static CLIENT: Lazy<Client> = Lazy::new(|| {
let client = Client::builder()
.timeout(time::Duration::from_secs(30))
.connect_timeout(time::Duration::from_secs(30))
.build()
.expect("build client");
client
});
struct Bot {
secrets: Secrets,
config: Config,
post_history: Vec<PrevPost>,
auth: Sensitive<String>,
}
impl Bot {
pub(crate) fn new() -> Bot {
Bot {
secrets: Secrets::load(),
config: Config::load(),
post_history: PrevPost::load(),
auth: Sensitive::new("".to_string()),
}
}
pub(crate) fn login(&mut self) {
let login_params = Login {
username_or_email: self.secrets.lemmy.get_username(),
password: self.secrets.lemmy.get_password(),
};
let res = CLIENT
.post("https://lemmy.neshweb.net/api/v3/user/login")
.json(&login_params)
.send()
.unwrap();
if res.status() == StatusCode::OK {
let data: &LoginResponse = &res.json().unwrap();
let jwt = data.jwt.clone().expect("JWT Token could not be acquired");
self.auth = jwt;
} else {
println!("Error Code: {:?}", res.status());
panic!("JWT Token could not be acquired");
}
}
pub(crate) fn post(&mut self, post_data: CreatePost) {
let res = CLIENT
.post("https://lemmy.neshweb.net/api/v3/post")
.json(&post_data)
.send()
.unwrap();
}
}
fn list_posts(auth: &Sensitive<String>) -> GetPostsResponse {
let params = GetPosts {
type_: Some(ListingType::Local),
sort: Some(SortType::New),
auth: Some(auth.clone()),
..Default::default()
};
let res = CLIENT
.get("https://lemmy.neshweb.net/api/v3/post/list")
.query(&params)
.send()
.unwrap()
.text()
.unwrap();
return serde_json::from_str(&res).unwrap();
}
fn main() {
// Get all needed auth tokens at the start
let mut old = Utc::now().time();
let mut this = Bot::new();
println!("{}", this.secrets.lemmy.username);
this.login();
// Create empty eTag list
println!("TODO: Etag list");
// Enter a loop (not for debugging)
loop {
let start = Utc::now();
print!("\x1B[2J\x1B[1;1H");
println!("Started loop at {} {}", start.format("%H:%M:%S"), start.timezone());
if start.time() - old > chrono::Duration::seconds(6) {
old = start.time();
this.config = Config::load();
}
// Start the polling process
// Get all feed URLs (use cache)
let mut post_queue: Vec<CreatePost> = vec![];
this.config.feeds.iter().for_each(|feed| {
let res = CLIENT
.get(feed.feed_url.clone())
.send()
.unwrap()
.text()
.unwrap();
let data: FeedData = serde_json::from_str(&res).unwrap();
let mut prev_post_idx: Option<usize> = None;
let mut do_post = true;
this.post_history
.iter()
.enumerate()
.for_each(|(idx, post)| {
if &post.last_post_url == &data.items[0].url {
do_post = false;
} else if &post.title == &data.title {
prev_post_idx = Some(idx);
}
});
if do_post {
let item = &data.items[0];
let new_post = CreatePost {
name: item.title.clone(),
community_id: CommunityId(3), // TODO get community id by using community name at the start, save it in a list, planned refresh once a day
url: Some(Url::parse(&item.url).unwrap()),
body: Some(
"[Reddit](https://reddit.com)\n\n[Discord](https://discord.com)".into(),
),
honeypot: None,
nsfw: Some(false),
language_id: Some(LanguageId(0)), // TODO get English language id by api (at the start)
auth: this.auth.clone(),
};
post_queue.push(new_post);
match prev_post_idx {
Some(idx) => {
this.post_history[idx].title = data.title;
this.post_history[idx].last_post_url = item.url.clone();
}
None => this.post_history.push(PrevPost {
title: data.title,
last_post_url: item.url.clone(),
}),
}
}
sleep(time::Duration::from_millis(100)); // Should prevent dos-ing J-Novel servers
});
PrevPost::save(&this.post_history);
post_queue.iter().for_each(|post| {
println!("Posted: {}", post.name);
this.post(post.clone());
});
while Utc::now().time() - start.time() < chrono::Duration::seconds(60) {
sleep(time::Duration::from_secs(10));
}
}
}