Compare commits
16 Commits
Author | SHA1 | Date |
---|---|---|
Jacob Kiers | 9f815f3f9c | |
Jacob Kiers | 6cb35aae42 | |
Jacob Kiers | 7c5e971571 | |
Jacob Kiers | 0598026756 | |
Jacob Kiers | 4069d8ac31 | |
Jacob Kiers | 7407654e60 | |
Jacob Kiers | e7fd41ff95 | |
Jacob Kiers | c2d09621aa | |
Jacob Kiers | 9129f7e11b | |
Jacob Kiers | 71371cb3e1 | |
Jacob Kiers | f61e635721 | |
Jacob Kiers | d3e4c9e790 | |
Jacob Kiers | 3d7e5fc2cf | |
Jacob Kiers | 78049cf7b6 | |
Jacob Kiers | 3abec884c2 | |
Jacob Kiers | ea30a49901 |
|
@ -0,0 +1,3 @@
|
|||
[profile.release]
|
||||
lto = "thin"
|
||||
strip = true
|
|
@ -1,31 +1,26 @@
|
|||
local executableName = 'newsletter-to-web';
|
||||
local cross_image = 'img.kie.rs/jjkiers/rust-dind-cross:1.66-full';
|
||||
|
||||
local archs = [
|
||||
// { target: 'aarch64-unknown-linux-gnu', short: 'arm64-gnu' },
|
||||
{ target: 'aarch64-unknown-linux-musl', short: 'arm64-musl' },
|
||||
{ target: 'x86_64-pc-windows-gnu', short: 'windows' },
|
||||
// { target: 'x86_64-unknown-linux-gnu', short: 'amd64-gnu' },
|
||||
{ target: 'x86_64-unknown-linux-musl', short: 'amd64-musl' },
|
||||
];
|
||||
|
||||
local getStepName(arch) = 'Build for ' + arch.short;
|
||||
|
||||
local builtExecutableName(arch) = executableName + if std.startsWith(arch.short, 'windows') then '.exe' else '';
|
||||
local targetExecutableName(arch) = executableName + if std.startsWith(arch.short, 'windows') then '.exe' else '-' + arch.short;
|
||||
local builtExecutableName(arch) = executableName + if std.length(std.findSubstr(arch.short, 'windows')) > 0 then '.exe' else '';
|
||||
local targetExecutableName(arch) = executableName + '-' + arch.target + if std.length(std.findSubstr(arch.short, 'windows')) > 0 then '.exe' else '';
|
||||
|
||||
local add_build_steps() = [
|
||||
{
|
||||
name: getStepName(arch),
|
||||
image: 'img.kie.rs/jjkiers/rust-dind-cross:1.62-slim',
|
||||
image: cross_image,
|
||||
volumes: [
|
||||
{
|
||||
name: 'dockersock',
|
||||
path: '/var/run',
|
||||
},
|
||||
{
|
||||
name: 'rustup',
|
||||
path: '/usr/local/rustup',
|
||||
},
|
||||
],
|
||||
commands: [
|
||||
'echo Hello World from Jsonnet on ' + arch.target + '!',
|
||||
|
@ -51,13 +46,19 @@ local add_build_steps() = [
|
|||
steps:
|
||||
[{
|
||||
name: 'Wait for Docker',
|
||||
image: 'img.kie.rs/jjkiers/rust-dind-cross:1.65-slim',
|
||||
image: cross_image,
|
||||
commands: [
|
||||
'mkdir artifacts',
|
||||
'echo Using image: ' + cross_image,
|
||||
'while ! docker image ls; do sleep 1; done',
|
||||
'cargo --version',
|
||||
'rustc --version',
|
||||
'docker info',
|
||||
'docker pull hello-world:latest',
|
||||
'mkdir artifacts',
|
||||
],
|
||||
environment: {
|
||||
CROSS_REMOTE: true,
|
||||
},
|
||||
volumes: [{
|
||||
name: 'dockersock',
|
||||
path: '/var/run',
|
||||
|
@ -67,7 +68,7 @@ local add_build_steps() = [
|
|||
[
|
||||
{
|
||||
name: 'Show built artifacts',
|
||||
image: 'img.kie.rs/jjkiers/rust-dind-cross:1.62-slim',
|
||||
image: cross_image,
|
||||
commands: [
|
||||
'ls -lah artifacts',
|
||||
],
|
||||
|
@ -112,18 +113,6 @@ local add_build_steps() = [
|
|||
name: 'dockersock',
|
||||
temp: {},
|
||||
},
|
||||
{
|
||||
name: 'docker-storage',
|
||||
host: {
|
||||
path: '/srv/drone/docker-dind-rust',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'rustup',
|
||||
host: {
|
||||
path: '/srv/drone/rustup',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
image_pull_secrets: ['docker_private_repo'],
|
||||
|
|
21
CHANGELOG.md
21
CHANGELOG.md
|
@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.2.3] - 2022-12-29
|
||||
|
||||
### Added
|
||||
|
||||
* Added `update` subcommand to update to the latest version.
|
||||
|
||||
### Fixed
|
||||
|
||||
* Truncate feed file before writing, to prevent corruption from leftover data.
|
||||
* Ensure the feed file name is part of the self URL. This was still hardcoded to `feed.atom`.
|
||||
|
||||
## [0.2.2] - 2022-12-16
|
||||
|
||||
### Changed
|
||||
|
||||
* Updated build pipeline to generate much smaller binaries
|
||||
|
||||
## [0.2.1] - 2022-12-13
|
||||
|
||||
### Changed
|
||||
|
@ -22,4 +41,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Changed
|
||||
|
||||
* By default the name of the feed is now feed.xml instead of feed.atom.
|
||||
* By default, the name of the feed is now feed.xml instead of feed.atom.
|
||||
|
|
|
@ -29,14 +29,13 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
|||
[[package]]
|
||||
name = "atom_syndication"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21fb6a0b39c6517edafe46f8137e53c51742425a4dae1c73ee12264a37ad7541"
|
||||
source = "git+https://github.com/rust-syndication/atom?rev=5cf8d161e5e5af7d93cca8d2c117b7af879a99b7#5cf8d161e5e5af7d93cca8d2c117b7af879a99b7"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"derive_builder",
|
||||
"diligent-date-parser",
|
||||
"never",
|
||||
"quick-xml",
|
||||
"quick-xml 0.27.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -84,6 +83,12 @@ version = "3.11.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.77"
|
||||
|
@ -158,6 +163,19 @@ dependencies = [
|
|||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
version = "0.15.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5556015fe3aad8b968e5d4124980fbe2f6aaee7aeec6b749de1faaa2ca5d0a4c"
|
||||
dependencies = [
|
||||
"encode_unicode",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"unicode-width",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
|
@ -229,9 +247,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.12.4"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c"
|
||||
checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
|
@ -239,9 +257,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.12.4"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36"
|
||||
checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
|
@ -253,9 +271,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.12.4"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a"
|
||||
checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
|
@ -264,18 +282,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "derive_builder"
|
||||
version = "0.10.2"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d13202debe11181040ae9063d739fa32cfcaaebe2275fe387703460ae2365b30"
|
||||
checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
|
||||
dependencies = [
|
||||
"derive_builder_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_core"
|
||||
version = "0.10.2"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66e616858f6187ed828df7c64a6d71720d83767a7f19740b2d1b6fe6327b36e5"
|
||||
checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
|
@ -285,9 +303,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "derive_builder_macro"
|
||||
version = "0.10.2"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58a94ace95092c5acb1e97a7e846b310cfbd499652f72297da7493f618a98d73"
|
||||
checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn",
|
||||
|
@ -312,6 +330,12 @@ dependencies = [
|
|||
"chrono",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.31"
|
||||
|
@ -342,12 +366,78 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.6"
|
||||
|
@ -358,6 +448,31 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
|
@ -373,6 +488,77 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.23.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c"
|
||||
dependencies = [
|
||||
"http",
|
||||
"hyper",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.53"
|
||||
|
@ -403,6 +589,16 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imap"
|
||||
version = "2.4.1"
|
||||
|
@ -427,6 +623,37 @@ dependencies = [
|
|||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indicatif"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4295cbb7573c16d310e99e713cf9e75101eb190ab31fccd35f2d2691b4352b19"
|
||||
dependencies = [
|
||||
"console",
|
||||
"number_prefix",
|
||||
"portable-atomic",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.3"
|
||||
|
@ -437,6 +664,12 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.1"
|
||||
|
@ -449,6 +682,12 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.60"
|
||||
|
@ -522,6 +761,24 @@ version = "2.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "never"
|
||||
version = "0.1.0"
|
||||
|
@ -530,7 +787,7 @@ checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91"
|
|||
|
||||
[[package]]
|
||||
name = "newsletter-to-web"
|
||||
version = "0.2.0"
|
||||
version = "0.2.3"
|
||||
dependencies = [
|
||||
"atom_syndication",
|
||||
"base16ct",
|
||||
|
@ -539,6 +796,7 @@ dependencies = [
|
|||
"imap",
|
||||
"mail-parser",
|
||||
"rustls-connector",
|
||||
"self_update",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
|
@ -572,6 +830,22 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "number_prefix"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.16.0"
|
||||
|
@ -584,6 +858,30 @@ version = "6.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
|
@ -622,6 +920,15 @@ name = "quick-xml"
|
|||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffc053f057dd768a56f62cd7e434c42c831d296968997e9ac1f76ea7c2d14c41"
|
||||
dependencies = [
|
||||
"encoding_rs",
|
||||
"memchr",
|
||||
|
@ -636,6 +943,15 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.7.0"
|
||||
|
@ -653,6 +969,54 @@ version = "0.6.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"webpki-roots",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
|
@ -706,6 +1070,15 @@ dependencies = [
|
|||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55"
|
||||
dependencies = [
|
||||
"base64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
|
@ -728,6 +1101,58 @@ dependencies = [
|
|||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "self_update"
|
||||
version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c99e711a8a33bc7311c9aec68896c87c1f203edda4ca7345c75671b569ce871"
|
||||
dependencies = [
|
||||
"hyper",
|
||||
"indicatif",
|
||||
"log",
|
||||
"quick-xml 0.22.0",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"semver",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.91"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.6"
|
||||
|
@ -739,6 +1164,25 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
|
@ -768,6 +1212,20 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
|
@ -784,22 +1242,126 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.23.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"tokio",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
|
@ -812,18 +1374,45 @@ version = "0.7.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.83"
|
||||
|
@ -849,6 +1438,18 @@ dependencies = [
|
|||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.83"
|
||||
|
@ -994,3 +1595,12 @@ name = "windows_x86_64_msvc"
|
|||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "newsletter-to-web"
|
||||
version = "0.2.0"
|
||||
version = "0.2.3"
|
||||
edition = "2021"
|
||||
description = "Converts email newsletters to static HTML files"
|
||||
homepage = "https://code.kiers.eu/newsletter-to-web/newsletter-to-web"
|
||||
|
@ -19,3 +19,7 @@ imap = { version = "^2.4.1", default-features = false }
|
|||
mail-parser = "^0.8.0"
|
||||
rustls-connector = { version = "^0.16.1", default-features = false, features = [ "webpki-roots-certs", "quic" ] }
|
||||
sha2 = "^0.10.2"
|
||||
self_update = { version = "0.33.0", default-features = false, features = ["rustls"] }
|
||||
|
||||
[patch.crates-io]
|
||||
atom_syndication = { git = "https://github.com/rust-syndication/atom", rev = "5cf8d161e5e5af7d93cca8d2c117b7af879a99b7" }
|
||||
|
|
39
README.md
39
README.md
|
@ -1,6 +1,41 @@
|
|||
# Newsletter 2 Web
|
||||
# Newsletter to Web
|
||||
|
||||
Converts a newsletter to static HTML files.
|
||||
Converts a newsletter to and Atom feed and static HTML files.
|
||||
|
||||
## Usage
|
||||
|
||||
Get the latest release [from the releases page](https://code.kiers.eu/newsletter-to-web/newsletter-to-web/releases/latest).
|
||||
|
||||
### Getting help
|
||||
|
||||
For help, use
|
||||
|
||||
* `newsletter-to-web help`
|
||||
* `newsletter-to-web help <subcommand>`.
|
||||
|
||||
### Basic usage
|
||||
|
||||
First, download all messages from the IMAP mail server
|
||||
and store them in the `data/` directory:
|
||||
|
||||
```sh
|
||||
newsletter-to-web fetch-from-imap -s <imap.example.com> -u <email@example.com> -p <password>
|
||||
```
|
||||
|
||||
Then, convert them to an Atom feed, using
|
||||
`newsletters.example.com` as the base domain:
|
||||
|
||||
```sh
|
||||
newsletter-to-web --include-html build-feed newsletters.example.org
|
||||
```
|
||||
|
||||
This will put the output in the `output/` directory. The Atom
|
||||
feed will be in `output/feed.xml`, together with a very simple
|
||||
`index.html` file pointing to the feed. It will also add an HTML
|
||||
file for every email with the HTML content.
|
||||
|
||||
The feed will already contain the full HTML, so it can easily be
|
||||
read from a feed reader.
|
||||
|
||||
## Features
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
</section>
|
||||
<section>
|
||||
<h2>Recent Items</h2>
|
||||
<p>Last updated on <xsl:apply-templates select="atom:feed/atom:updated" /></p>
|
||||
<xsl:apply-templates select="atom:feed/atom:entry" />
|
||||
</section>
|
||||
</body>
|
||||
|
|
|
@ -50,4 +50,6 @@ pub(crate) enum Command {
|
|||
#[clap(value_parser, default_value = "output/")]
|
||||
directory: PathBuf,
|
||||
},
|
||||
/// Update to the latest version
|
||||
Update,
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
pub(crate) mod update;
|
|
@ -0,0 +1,17 @@
|
|||
use self_update::cargo_crate_version;
|
||||
use std::error::Error;
|
||||
|
||||
pub(crate) fn self_update() -> Result<(), Box<dyn Error>> {
|
||||
let backend = self_update::backends::gitea::Update::configure()
|
||||
.with_host("https://code.kiers.eu")
|
||||
.repo_owner("newsletter-to-web")
|
||||
.repo_name("newsletter-to-web")
|
||||
.bin_name("newsletter-to-web")
|
||||
.show_download_progress(true)
|
||||
.current_version(cargo_crate_version!())
|
||||
.build()?;
|
||||
|
||||
let status = backend.update()?;
|
||||
println!("Update status: `{}`!", status.version());
|
||||
Ok(())
|
||||
}
|
37
src/feed.rs
37
src/feed.rs
|
@ -2,6 +2,7 @@ use crate::Message;
|
|||
|
||||
use atom_syndication::{
|
||||
ContentBuilder, Entry, EntryBuilder, Feed, FeedBuilder, Generator, LinkBuilder, Person,
|
||||
WriteConfig,
|
||||
};
|
||||
use chrono::{DateTime, TimeZone, Utc};
|
||||
|
||||
|
@ -34,19 +35,13 @@ pub(crate) fn add_entry_to_feed(
|
|||
_ => "".to_string(),
|
||||
},
|
||||
},
|
||||
email: match &from.address {
|
||||
Some(e) => Some(e.to_string()),
|
||||
_ => None,
|
||||
},
|
||||
email: from.address.as_ref().map(|e| e.to_string()),
|
||||
uri: None,
|
||||
},
|
||||
title: parsed
|
||||
.subject()
|
||||
.expect("Expected a subject")
|
||||
.to_string(),
|
||||
title: parsed.subject().expect("Expected a subject").to_string(),
|
||||
content: Some(processed_html.clone()),
|
||||
id: url.clone(),
|
||||
published: Utc.timestamp_opt(date.to_timestamp(), 0).unwrap(), //(format!("{}{}", &date.to_iso8601(), "+00:00").as_str()).`unwrap(),
|
||||
published: Utc.timestamp_opt(date.to_timestamp(), 0).unwrap(),
|
||||
url: match include_html {
|
||||
true => url,
|
||||
false => "".to_string(),
|
||||
|
@ -57,10 +52,11 @@ pub(crate) fn add_entry_to_feed(
|
|||
feed.entries.push(entry);
|
||||
}
|
||||
|
||||
pub(crate) fn build_atom_feed(hostname: &String) -> Feed {
|
||||
pub(crate) fn build_atom_feed(hostname: &String, feed_file: &str) -> Feed {
|
||||
let feed_url = format!("https://{}/{}", hostname, feed_file);
|
||||
FeedBuilder::default()
|
||||
.title("JJKiers Newsletters")
|
||||
.id(format!("https://{}/feed.atom", hostname))
|
||||
.id(&feed_url)
|
||||
.link(
|
||||
LinkBuilder::default()
|
||||
.href(format!("https://{}/", hostname))
|
||||
|
@ -69,7 +65,7 @@ pub(crate) fn build_atom_feed(hostname: &String) -> Feed {
|
|||
)
|
||||
.link(
|
||||
LinkBuilder::default()
|
||||
.href(format!("https://{}/feed.atom", hostname))
|
||||
.href(&feed_url)
|
||||
.rel("self".to_string())
|
||||
.build(),
|
||||
)
|
||||
|
@ -81,6 +77,19 @@ pub(crate) fn build_atom_feed(hostname: &String) -> Feed {
|
|||
.build()
|
||||
}
|
||||
|
||||
pub(crate) fn write_feed<W: std::io::Write>(
|
||||
feed: Feed,
|
||||
mut out: W,
|
||||
) -> Result<W, atom_syndication::Error> {
|
||||
let _ = writeln!(out, r#"<?xml version="1.0"?>"#);
|
||||
let _ = writeln!(out, r#"<?xml-stylesheet href="feed.xsl" type="text/xsl"?>"#);
|
||||
let config = WriteConfig {
|
||||
write_document_declaration: false,
|
||||
..Default::default()
|
||||
};
|
||||
feed.write_with_config(out, config)
|
||||
}
|
||||
|
||||
//#[derive(Serialize, Deserialize, Debug)]
|
||||
pub(crate) struct Newsletter {
|
||||
id: String,
|
||||
|
@ -104,8 +113,8 @@ impl From<Newsletter> for Entry {
|
|||
|
||||
eb.title(post.title)
|
||||
.id(post.id)
|
||||
.published(Some(post.published.clone().into()))
|
||||
.author(post.author.into())
|
||||
.published(Some(post.published.into()))
|
||||
.author(post.author)
|
||||
.content(content);
|
||||
|
||||
if post.url.len() > 1 {
|
||||
|
|
95
src/main.rs
95
src/main.rs
|
@ -1,7 +1,7 @@
|
|||
#[warn(missing_docs)]
|
||||
#[doc = include_str!("../README.md")]
|
||||
|
||||
mod cli;
|
||||
mod command;
|
||||
mod feed;
|
||||
mod message;
|
||||
mod message_reader;
|
||||
|
@ -20,8 +20,8 @@ use std::{
|
|||
|
||||
pub(crate) use message::Message;
|
||||
|
||||
const INDEX_HTML: & 'static str = include_str!("../resources/index.html");
|
||||
const FEED_STYLESHEET: & 'static str = include_str!("../resources/feed.xsl");
|
||||
const INDEX_HTML: &str = include_str!("../resources/index.html");
|
||||
const FEED_STYLESHEET: &str = include_str!("../resources/feed.xsl");
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let cli = cli::Cli::parse();
|
||||
|
@ -41,7 +41,12 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
username.to_owned(),
|
||||
password.to_owned(),
|
||||
),
|
||||
cli::Command::BuildFeed { filename , hostname, include_html } => build_feed(&filename, hostname.to_owned(), *include_html),
|
||||
cli::Command::BuildFeed {
|
||||
filename,
|
||||
hostname,
|
||||
include_html,
|
||||
} => build_feed(filename, hostname, *include_html),
|
||||
cli::Command::Update => command::update::self_update(),
|
||||
_ => unimplemented!("This method is not yet implemented."),
|
||||
};
|
||||
|
||||
|
@ -56,7 +61,11 @@ fn create_directory<P: AsRef<Path>>(dir: P) -> Result<(), std::io::Error> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn build_feed(filename: &PathBuf, hostname: String, include_html: bool) -> Result<(), Box<dyn Error>> {
|
||||
fn build_feed(
|
||||
filename: &PathBuf,
|
||||
hostname: &String,
|
||||
include_html: bool,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let dir = filename.parent().ok_or(format!(
|
||||
"Could not get parent directory of {}",
|
||||
filename.display()
|
||||
|
@ -70,9 +79,15 @@ fn build_feed(filename: &PathBuf, hostname: String, include_html: bool) -> Resul
|
|||
|
||||
create_directory(dir)?;
|
||||
|
||||
let mut feed = feed::build_atom_feed(&hostname);
|
||||
let feed_file = filename
|
||||
.file_name()
|
||||
.expect("Feed path should have a file name")
|
||||
.to_str()
|
||||
.expect("Feed path should be printable.");
|
||||
|
||||
let mut reader = DataDirectoryMessageReader::new((&Path::new("data")).to_path_buf());
|
||||
let mut feed = feed::build_atom_feed(&hostname, feed_file);
|
||||
|
||||
let mut reader = DataDirectoryMessageReader::new(Path::new("data").to_path_buf());
|
||||
|
||||
for msg in reader.read_rfc822_messages() {
|
||||
let parsed = msg.get_parsed().expect("A parsed messsage.");
|
||||
|
@ -82,15 +97,12 @@ fn build_feed(filename: &PathBuf, hostname: String, include_html: bool) -> Resul
|
|||
msg.get_uid()
|
||||
))?;
|
||||
|
||||
let subject = match parsed.subject() {
|
||||
Some(subject) => subject,
|
||||
None => "No subject",
|
||||
};
|
||||
let subject = parsed.subject().unwrap_or("No subject");
|
||||
|
||||
println!(
|
||||
"Processing message {} from {} with subject {}",
|
||||
msg.get_uid(),
|
||||
date.to_string(),
|
||||
date,
|
||||
subject
|
||||
);
|
||||
|
||||
|
@ -98,26 +110,23 @@ fn build_feed(filename: &PathBuf, hostname: String, include_html: bool) -> Resul
|
|||
let processed_html = process_html(&html_body).expect("Could not process the HTML");
|
||||
|
||||
if include_html {
|
||||
let path : PathBuf = [dir, Path::new(&get_path(&parsed, &msg))].iter().collect();
|
||||
let path: PathBuf = [dir, Path::new(&get_path(&parsed, &msg))].iter().collect();
|
||||
write_file(&path, processed_html.as_bytes())?;
|
||||
}
|
||||
|
||||
feed::add_entry_to_feed(&mut feed, &msg, &processed_html, &hostname, include_html);
|
||||
}
|
||||
|
||||
if feed.entries.len() > 0 {
|
||||
if !feed.entries.is_empty() {
|
||||
feed.set_updated(Utc::now());
|
||||
println!("Writing feed to {}", filename.display());
|
||||
|
||||
// TODO: Ugly hack because atom_syndication crate does not support style sheets.
|
||||
let feed_str = feed.to_string().as_str().replace(">\n<feed", ">\n<?xml-stylesheet href=\"feed.xsl\" type=\"text/xsl\"?>\n<feed");
|
||||
let _ = write_file(filename, feed_str)?;
|
||||
let _ = write_file(dir.join("feed.xsl"), FEED_STYLESHEET)?;
|
||||
|
||||
// Another ugly hack, but I don't know how to do this better...
|
||||
let file_name = format!("{:?}", filename.file_name().unwrap()).replace('"', "");
|
||||
write_file(dir.join("index.html"), INDEX_HTML.replace("{FEED}", file_name.as_str()))?;
|
||||
|
||||
feed::write_feed(feed, open_file(filename).unwrap())?;
|
||||
write_file(dir.join("feed.xsl"), FEED_STYLESHEET)?;
|
||||
write_file(
|
||||
dir.join("index.html"),
|
||||
INDEX_HTML.replace("{FEED}", feed_file),
|
||||
)?;
|
||||
}
|
||||
|
||||
println!("Finished building the feed.");
|
||||
|
@ -136,12 +145,7 @@ fn fetch_from_imap(
|
|||
|
||||
print!("Getting mail from {} for mailbox {}", server, username);
|
||||
|
||||
let mut reader = ImapReader::new(
|
||||
String::from(server),
|
||||
port,
|
||||
String::from(username),
|
||||
String::from(password),
|
||||
);
|
||||
let mut reader = ImapReader::new(server, port, username, password);
|
||||
|
||||
for msg in reader.read_rfc822_messages() {
|
||||
let parsed = msg.get_parsed().ok_or(format!(
|
||||
|
@ -154,15 +158,12 @@ fn fetch_from_imap(
|
|||
msg.get_uid()
|
||||
))?;
|
||||
|
||||
let subject = match parsed.subject() {
|
||||
Some(subject) => subject,
|
||||
None => "No subject",
|
||||
};
|
||||
let subject = parsed.subject().unwrap_or("No subject");
|
||||
|
||||
println!(
|
||||
"Processing message {} from {} with subject {}",
|
||||
msg.get_uid(),
|
||||
date.to_string(),
|
||||
date,
|
||||
subject
|
||||
);
|
||||
|
||||
|
@ -182,8 +183,6 @@ fn fetch_from_imap(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn get_path(parsed: &ParsedMessage, msg: &Message) -> String {
|
||||
let date = parsed.date().expect("Could not extract date");
|
||||
let date_str = format!(
|
||||
|
@ -192,26 +191,32 @@ fn get_path(parsed: &ParsedMessage, msg: &Message) -> String {
|
|||
);
|
||||
|
||||
let hash = base16ct::lower::encode_string(&Sha256::digest(
|
||||
&parsed.body_html(0).expect("Expected a body").as_bytes(),
|
||||
parsed.body_html(0).expect("Expected a body").as_bytes(),
|
||||
));
|
||||
|
||||
let uid: i32 = msg.get_uid()
|
||||
let uid: i32 = msg
|
||||
.get_uid()
|
||||
.parse()
|
||||
.expect(&format!("Could not convert message id {} to an i32.", msg.get_uid()));
|
||||
.unwrap_or_else(|_| panic!("Could not convert message id {} to an i32.", msg.get_uid()));
|
||||
|
||||
format!("{:05}_{}_{}.html", uid, date_str, &hash).to_owned()
|
||||
format!("{:05}_{}_{}.html", uid, date_str, &hash)
|
||||
}
|
||||
|
||||
fn process_html(input: &str) -> Result<String, ()> {
|
||||
Ok(input.replace("src", "data-source"))
|
||||
}
|
||||
|
||||
fn write_file<P: Into<PathBuf>, D: AsRef<[u8]>>(html_path: P, data: D) -> Result<(), std::io::Error> {
|
||||
let path : PathBuf = html_path.into();
|
||||
fn open_file<P: Into<PathBuf>>(path: P) -> std::io::Result<std::fs::File> {
|
||||
OpenOptions::new()
|
||||
.write(true)
|
||||
.truncate(true)
|
||||
.create(true)
|
||||
.open(&path)
|
||||
.expect(format!("Could not open file '{}' for writing", &path.display()).as_str())
|
||||
.open(path.into())
|
||||
}
|
||||
|
||||
fn write_file<P: Into<PathBuf>, D: AsRef<[u8]>>(path: P, data: D) -> Result<(), std::io::Error> {
|
||||
let path: PathBuf = path.into();
|
||||
open_file(path.clone())
|
||||
.unwrap_or_else(|_| panic!("Could not open file '{}' for writing", &path.display()))
|
||||
.write_all(data.as_ref())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,4 +21,4 @@ impl Message {
|
|||
pub fn get_data(&self) -> &Vec<u8> {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ impl EmailReader for DataDirectoryMessageReader {
|
|||
Some(ext) => ext == "eml",
|
||||
None => false,
|
||||
})
|
||||
.map(|i| {
|
||||
.filter_map(|i| {
|
||||
let uid = i
|
||||
.path()
|
||||
.file_stem()
|
||||
|
@ -52,9 +52,9 @@ impl EmailReader for DataDirectoryMessageReader {
|
|||
.to_owned()
|
||||
.into_string()
|
||||
.expect("Could not convert filename to string.")
|
||||
.split("_")
|
||||
.split('_')
|
||||
.collect::<Vec<&str>>()[0]
|
||||
.trim_start_matches("0")
|
||||
.trim_start_matches('0')
|
||||
.to_string();
|
||||
|
||||
if let Ok(data) = std::fs::read(i.path()) {
|
||||
|
@ -63,8 +63,6 @@ impl EmailReader for DataDirectoryMessageReader {
|
|||
None
|
||||
}
|
||||
})
|
||||
.filter(|i| i.is_some())
|
||||
.map(|i| i.unwrap())
|
||||
.map(|i| Message::new(i.0, i.1));
|
||||
|
||||
let iter = items.collect::<Vec<Message>>().into_iter();
|
||||
|
|
Loading…
Reference in New Issue