mirror of
https://github.com/matrix-org/matrix-hookshot.git
synced 2025-03-10 13:17:08 +00:00
Use rss
crate for RSS feed parsing (#709)
* Refactor annoying type difference * Add rss * Add support for parsing RSS feeds * Add rss lib * Add Cargo project * Lint rust * changelog * Add support for new fields
This commit is contained in:
parent
97ff9f2e3a
commit
eda6fc8c26
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"rust-analyzer.linkedProjects": [
|
||||
"./Cargo.toml"
|
||||
]
|
||||
}
|
429
Cargo.lock
generated
429
Cargo.lock
generated
@ -4,18 +4,37 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
version = "0.7.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
name = "atom_syndication"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
checksum = "ca96cb38e3d8236f1573a84bbc55e130bd1ae07df770e36d0cf221ea7a50e36c"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"derive_builder",
|
||||
"diligent-date-parser",
|
||||
"never",
|
||||
"quick-xml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c70beb79cbb5ce9c4f8e20849978f34225931f665bb49efa6982875a4d5facb3"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
@ -46,9 +65,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.7.3"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f"
|
||||
checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
@ -56,6 +75,22 @@ version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "contrast"
|
||||
version = "0.1.0"
|
||||
@ -68,18 +103,87 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.21"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa"
|
||||
checksum = "dd4056f63fce3b82d852c3da92b08ea59959890813a7f4ce9c0ff85b10cf301b"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
|
||||
dependencies = [
|
||||
"derive_builder_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_core"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_macro"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -92,12 +196,35 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
name = "diligent-date-parser"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||
checksum = "f6cf7fe294274a222363f84bcb63cdea762979a0443b4cf1f4f8fd17c86b1182"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[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 = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
@ -117,33 +244,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.3"
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.1"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
name = "libloading"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matrix-hookshot"
|
||||
@ -156,6 +286,7 @@ dependencies = [
|
||||
"napi-build",
|
||||
"napi-derive",
|
||||
"rgb",
|
||||
"rss",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
@ -175,22 +306,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "napi"
|
||||
version = "2.0.2"
|
||||
version = "2.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4cfe7fef533df6323a5aa17d75cb162850f2b045adabb9922bfbd234426a1bb"
|
||||
checksum = "556470a21074b55be8adee5f27ca04389cfdaca323a28b4b0e9c15466de94731"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"ctor",
|
||||
"lazy_static",
|
||||
"napi-derive",
|
||||
"napi-sys",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -201,51 +333,71 @@ checksum = "ebd4419172727423cf30351406c54f6cc1b354a2cfb4f1dba3e6cd07f6d5522b"
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive"
|
||||
version = "2.0.4"
|
||||
version = "2.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fb47b1f5f021abe96fcb84e7977f46c0aa645904c18cdb7b3a031e61899bf48"
|
||||
checksum = "af2ac63101a19228b0881694cac07468d642fd10e4f943a9c9feebeebf1a4787"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"napi-derive-backend",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive-backend"
|
||||
version = "1.0.21"
|
||||
version = "1.0.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "487c39117657211e9bf93acade9363eac61ceead142e4906d15ff08d29fa448d"
|
||||
checksum = "0e32b5bc4d803e40b783b0aa3fe488eac8711cfaa4c5c9915293dfd3d0b99925"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn",
|
||||
"semver",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-sys"
|
||||
version = "2.1.0"
|
||||
version = "2.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a385494dac3c52cbcacb393bb3b42669e7db8ab240c7ad5115f549eb061f2cc"
|
||||
checksum = "166b5ef52a3ab5575047a9fe8d4a030cdd0f63c96f071cd6907674453b07bae3"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "never"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.9.0"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
@ -255,33 +407,43 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5c1a97b1bc42b1d550bfb48d4262153fe400a12bab1511821736f7eac76d7e2"
|
||||
dependencies = [
|
||||
"encoding_rs",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.14"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
|
||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.6"
|
||||
version = "1.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
|
||||
checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@ -290,47 +452,65 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.26"
|
||||
version = "0.6.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.31"
|
||||
version = "0.8.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a374af9a0e5fdcdd98c1c7b64f05004f9ea2555b6c75f211daa81268a3c50f1"
|
||||
checksum = "20ec2d3e3fc7a92ced357df9cebd5a10b6fb2aa1ee797bf7e9ce2f17dffc8f59"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.9"
|
||||
name = "rss"
|
||||
version = "2.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||
checksum = "aa1ec965a5f5ec71e16106b35df21861c4014ace848c6b75720816925552936d"
|
||||
dependencies = [
|
||||
"atom_syndication",
|
||||
"derive_builder",
|
||||
"never",
|
||||
"quick-xml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.132"
|
||||
version = "1.0.160"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008"
|
||||
checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.132"
|
||||
version = "1.0.160"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276"
|
||||
checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.73"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5"
|
||||
checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@ -338,109 +518,110 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.84"
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcf316d5356ed6847742d036f8a39c3b8435cac10bd528a4bd461928a6ab34d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.5.1"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
|
||||
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.15.0"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.7"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.19"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.2"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.29.0"
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aac7fef12f4b59cd0a29339406cc9203ab44e440ddff6b3f5a41455349fa9cf3"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_msvc",
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.29.0"
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d027175d00b01e0cbeb97d6ab6ebe03b12330a35786cbaca5252b1c4bf5d9b"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.29.0"
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8793f59f7b8e8b01eda1a652b2697d87b93097198ae85f823b969ca5b89bba58"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8602f6c418b67024be2996c512f5f995de3ba417f4c75af68401ab8756796ae4"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d615f419543e0bd7d2b3323af0d86ff19cbc4f816e6453f36a2c2ce889c354"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11d95421d9ed3672c280884da53201a5c46b7b2765ca6faf34b0d71cf34a3561"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
@ -17,7 +17,7 @@ contrast = "0"
|
||||
rgb = "0"
|
||||
md-5 = "0.8.0"
|
||||
hex = "0.4.3"
|
||||
|
||||
rss = "2.0.3"
|
||||
|
||||
[build-dependencies]
|
||||
napi-build = "1"
|
||||
|
1
changelog.d/709.misc
Normal file
1
changelog.d/709.misc
Normal file
@ -0,0 +1 @@
|
||||
Switch to using Rust for parsing RSS feeds.
|
@ -2,7 +2,7 @@
|
||||
import { Appservice, Intent, IRichReplyMetadata, StateEvent } from "matrix-bot-sdk";
|
||||
import { BotCommands, botCommand, compileBotCommands, HelpFunction } from "../BotCommands";
|
||||
import { CommentProcessor } from "../CommentProcessor";
|
||||
import { FormatUtil } from "../FormatUtil";
|
||||
import { FormatUtil, LooseMinimalGitHubRepo } from "../FormatUtil";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { Connection, IConnection, IConnectionState, InstantiateConnectionOpts, ProvisionConnectionOpts } from "./IConnection";
|
||||
import { GetConnectionsResponseItem } from "../provisioning/api";
|
||||
@ -25,7 +25,7 @@ import { GitHubIssueConnection } from "./GithubIssue";
|
||||
import { BridgeConfigGitHub } from "../Config/Config";
|
||||
import { ApiError, ErrCode, ValidatorApiError } from "../api";
|
||||
import { PermissionCheckFn } from ".";
|
||||
import { GitHubRepoMessageBody, MinimalGitHubIssue, MinimalGitHubRepo } from "../libRs";
|
||||
import { GitHubRepoMessageBody, MinimalGitHubIssue } from "../libRs";
|
||||
import Ajv, { JSONSchemaType } from "ajv";
|
||||
import { HookFilter } from "../HookFilter";
|
||||
import { GitHubGrantChecker } from "../Github/GrantChecker";
|
||||
@ -637,7 +637,7 @@ export class GitHubRepoConnection extends CommandConnection<GitHubRepoConnection
|
||||
const issueNumber = result?.[1];
|
||||
|
||||
if (issueNumber) {
|
||||
let issue: MinimalGitHubIssue & { repository?: MinimalGitHubRepo, pull_request?: unknown, state: string };
|
||||
let issue: MinimalGitHubIssue & { repository?: LooseMinimalGitHubRepo, pull_request?: unknown, state: string };
|
||||
try {
|
||||
issue = (await octokit.issues.get({
|
||||
repo: this.state.repo,
|
||||
|
@ -23,12 +23,19 @@ export interface ILabel {
|
||||
description?: string
|
||||
}
|
||||
|
||||
export type LooseMinimalGitHubRepo = {
|
||||
id: number,
|
||||
full_name: string,
|
||||
html_url: string,
|
||||
description?: string|null,
|
||||
}
|
||||
|
||||
export class FormatUtil {
|
||||
public static formatIssueRoomName(issue: MinimalGitHubIssue, repository: { full_name: string}) {
|
||||
return emoji.emojify(`${repository.full_name}#${issue.number}: ${issue.title}`);
|
||||
}
|
||||
|
||||
public static formatRepoRoomName(repo: MinimalGitHubRepo) {
|
||||
public static formatRepoRoomName(repo: LooseMinimalGitHubRepo) {
|
||||
return emoji.emojify(repo.description ? `${repo.full_name}: ${repo.description}` : repo.full_name);
|
||||
}
|
||||
|
||||
@ -40,24 +47,30 @@ export class FormatUtil {
|
||||
return `${repo.html_url}`;
|
||||
}
|
||||
|
||||
public static getPartialBodyForGithubRepo(repo: MinimalGitHubRepo) {
|
||||
public static getPartialBodyForGithubRepo(repo: LooseMinimalGitHubRepo) {
|
||||
if (!repo.id || !repo.html_url || !repo.full_name) {
|
||||
throw Error('Missing keys in repo object');
|
||||
}
|
||||
return getPartialBodyForGithubRepo(repo);
|
||||
return getPartialBodyForGithubRepo({
|
||||
...repo,
|
||||
description: repo.description ?? undefined,
|
||||
});
|
||||
}
|
||||
|
||||
public static getPartialBodyForGithubIssue(repo: MinimalGitHubRepo, issue: MinimalGitHubIssue) {
|
||||
public static getPartialBodyForGithubIssue(repo: LooseMinimalGitHubRepo, issue: MinimalGitHubIssue) {
|
||||
if (!repo.id || !repo.html_url || !repo.full_name) {
|
||||
throw Error('Missing keys in repo object');
|
||||
}
|
||||
if (!issue.html_url || !issue.id || !issue.number || !issue.title) {
|
||||
throw Error('Missing keys in issue object');
|
||||
}
|
||||
return getPartialBodyForGithubIssue(repo, issue);
|
||||
return getPartialBodyForGithubIssue({
|
||||
...repo,
|
||||
description: repo.description ?? undefined,
|
||||
}, issue);
|
||||
}
|
||||
|
||||
public static getPartialBodyForGitHubPR(repo: MinimalGitHubRepo, issue: IMinimalPR) {
|
||||
public static getPartialBodyForGitHubPR(repo: LooseMinimalGitHubRepo, issue: IMinimalPR) {
|
||||
return {
|
||||
...FormatUtil.getPartialBodyForGithubRepo(repo),
|
||||
"external_url": issue.html_url,
|
||||
@ -72,7 +85,7 @@ export class FormatUtil {
|
||||
|
||||
|
||||
public static getPartialBodyForComment(comment: {id: number, html_url: string},
|
||||
repo?: MinimalGitHubRepo,
|
||||
repo?: LooseMinimalGitHubRepo,
|
||||
issue?: MinimalGitHubIssue) {
|
||||
return {
|
||||
...(issue && repo ? FormatUtil.getPartialBodyForGithubIssue(repo, issue) : undefined),
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { MatrixClient, MatrixError } from "matrix-bot-sdk";
|
||||
import { MatrixError } from "matrix-bot-sdk";
|
||||
import { BridgeConfigFeeds } from "../Config/Config";
|
||||
import { ConnectionManager } from "../ConnectionManager";
|
||||
import { FeedConnection } from "../Connections";
|
||||
@ -13,6 +13,7 @@ import UserAgent from "../UserAgent";
|
||||
import { randomUUID } from "crypto";
|
||||
import { StatusCodes } from "http-status-codes";
|
||||
import { FormatUtil } from "../FormatUtil";
|
||||
import { FeedItem, parseRSSFeed } from "../libRs";
|
||||
|
||||
const log = new Logger("FeedReader");
|
||||
|
||||
@ -86,8 +87,8 @@ const accountDataSchema = {
|
||||
const ajv = new Ajv();
|
||||
const validateAccountData = ajv.compile<AccountData>(accountDataSchema);
|
||||
|
||||
function isNonEmptyString(input: any): input is string {
|
||||
return input && typeof input === 'string';
|
||||
function isNonEmptyString(input: unknown): input is string {
|
||||
return Boolean(input) && typeof input === 'string';
|
||||
}
|
||||
|
||||
function stripHtml(input: string): string {
|
||||
@ -108,11 +109,6 @@ function shuffle<T>(array: T[]): T[] {
|
||||
return array;
|
||||
}
|
||||
|
||||
interface FeedItem {
|
||||
title?: string;
|
||||
link?: string;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export class FeedReader {
|
||||
private static buildParser(): Parser {
|
||||
@ -131,7 +127,6 @@ export class FeedReader {
|
||||
url: string,
|
||||
headers: Record<string, string>,
|
||||
timeoutMs: number,
|
||||
parser: Parser = FeedReader.buildParser(),
|
||||
httpClient = axios,
|
||||
): Promise<{ response: AxiosResponse, feed: Parser.Output<FeedItem> }> {
|
||||
const response = await httpClient.get(url, {
|
||||
@ -142,7 +137,11 @@ export class FeedReader {
|
||||
// We don't want to wait forever for the feed.
|
||||
timeout: timeoutMs,
|
||||
});
|
||||
const feed = await parser.parseString(response.data);
|
||||
|
||||
if (typeof response.data !== "string") {
|
||||
throw Error('Unexpected response type');
|
||||
}
|
||||
const feed = parseRSSFeed(response.data);
|
||||
return { response, feed };
|
||||
}
|
||||
|
||||
@ -151,16 +150,16 @@ export class FeedReader {
|
||||
* @param item A feed item.
|
||||
* @returns Return either a link to the item, or null.
|
||||
*/
|
||||
private static parseLinkFromItem(item: {guid?: string, link?: string}) {
|
||||
private static parseLinkFromItem(item: FeedItem) {
|
||||
if (item.link) {
|
||||
return item.link;
|
||||
}
|
||||
if (item.guid) {
|
||||
if (item.id && item.idIsPermalink) {
|
||||
try {
|
||||
// The feed librray doesn't give us attributes (needs isPermaLink), so we're not really sure if this a URL or not.
|
||||
// Parse it and see.
|
||||
// https://validator.w3.org/feed/docs/rss2.html#ltguidgtSubelementOfLtitemgt
|
||||
const url = new URL(item.guid);
|
||||
const url = new URL(item.id);
|
||||
return url.toString();
|
||||
} catch (ex) {
|
||||
return null;
|
||||
@ -298,7 +297,6 @@ export class FeedReader {
|
||||
},
|
||||
// We don't want to wait forever for the feed.
|
||||
this.config.pollTimeoutSeconds * 1000,
|
||||
this.parser,
|
||||
this.httpClient,
|
||||
);
|
||||
|
||||
@ -327,7 +325,7 @@ export class FeedReader {
|
||||
for (const item of feed.items) {
|
||||
// Find the first guid-like that looks like a string.
|
||||
// Some feeds have a nasty habit of leading a empty tag there, making us parse it as garbage.
|
||||
const guid = [item.guid, item.id, item.link, item.title].find(isNonEmptyString);
|
||||
const guid = [item.id, item.link, item.title].find(isNonEmptyString);
|
||||
if (!guid) {
|
||||
log.error(`Could not determine guid for entry in ${url}, skipping`);
|
||||
continue;
|
||||
@ -352,7 +350,7 @@ export class FeedReader {
|
||||
title: isNonEmptyString(item.title) ? stripHtml(item.title) : null,
|
||||
pubdate: item.pubDate ?? null,
|
||||
summary: item.summary ?? null,
|
||||
author: item.creator ?? null,
|
||||
author: item.author ?? null,
|
||||
link: FeedReader.parseLinkFromItem(item),
|
||||
fetchKey
|
||||
};
|
||||
|
1
src/feeds/mod.rs
Normal file
1
src/feeds/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod parser;
|
65
src/feeds/parser.rs
Normal file
65
src/feeds/parser.rs
Normal file
@ -0,0 +1,65 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use napi::bindgen_prelude::{Error as JsError, Status};
|
||||
use rss::{Channel, Error as RssError};
|
||||
|
||||
#[derive(Serialize, Debug, Deserialize)]
|
||||
#[napi(object)]
|
||||
pub struct FeedItem {
|
||||
pub title: Option<String>,
|
||||
pub link: Option<String>,
|
||||
pub id: Option<String>,
|
||||
pub id_is_permalink: bool,
|
||||
pub pubdate: Option<String>,
|
||||
pub summary: Option<String>,
|
||||
pub author: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Deserialize)]
|
||||
#[napi(object)]
|
||||
pub struct JsRssChannel {
|
||||
pub title: String,
|
||||
pub items: Vec<FeedItem>,
|
||||
}
|
||||
#[napi(js_name = "parseRSSFeed")]
|
||||
pub fn js_parse_rss_feed(xml: String) -> Result<JsRssChannel, JsError> {
|
||||
fn map_item_value(original: &str) -> String {
|
||||
original.to_string()
|
||||
}
|
||||
|
||||
Channel::from_str(&xml)
|
||||
.map(|channel| JsRssChannel {
|
||||
title: channel.title().to_string(),
|
||||
items: channel
|
||||
.items()
|
||||
.iter()
|
||||
.map(|item| FeedItem {
|
||||
title: item.title().map(map_item_value),
|
||||
link: item.link().map(map_item_value),
|
||||
id: item.guid().map(|f| f.value().to_string()),
|
||||
id_is_permalink: item.guid().map_or(false, |f| f.is_permalink()),
|
||||
pubdate: item.pub_date().map(map_item_value),
|
||||
summary: item.description().map(map_item_value),
|
||||
author: item.author().map(map_item_value),
|
||||
})
|
||||
.collect(),
|
||||
})
|
||||
.map_err(|op| match op {
|
||||
RssError::Utf8(err) => JsError::new(
|
||||
Status::Unknown,
|
||||
format!("An error while converting bytes to UTF8. {}'", err).to_string(),
|
||||
),
|
||||
RssError::Xml(err) => JsError::new(
|
||||
Status::Unknown,
|
||||
format!("XML parsing error. {}", err).to_string(),
|
||||
),
|
||||
RssError::InvalidStartTag => JsError::new(
|
||||
Status::Unknown,
|
||||
format!("The input didn't begin with an opening <rss> tag.").to_string(),
|
||||
),
|
||||
err => JsError::new(
|
||||
Status::Unknown,
|
||||
format!("Unknown error trying to parse feed parse feed '{}'", err).to_string(),
|
||||
),
|
||||
})
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
pub mod Config;
|
||||
pub mod Github;
|
||||
pub mod Jira;
|
||||
pub mod feeds;
|
||||
pub mod format_util;
|
||||
|
||||
#[macro_use]
|
||||
|
Loading…
x
Reference in New Issue
Block a user