Merge branch 'master' of github.com:Plume-org/Plume
This commit is contained in:
commit
b0e70a42a9
137
Cargo.lock
generated
137
Cargo.lock
generated
@ -71,14 +71,6 @@ dependencies = [
|
|||||||
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ansi_term"
|
|
||||||
version = "0.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "antidote"
|
name = "antidote"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -97,16 +89,6 @@ dependencies = [
|
|||||||
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "atty"
|
|
||||||
version = "0.2.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
@ -231,20 +213,6 @@ dependencies = [
|
|||||||
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap"
|
|
||||||
version = "2.31.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colored"
|
name = "colored"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
@ -253,22 +221,6 @@ dependencies = [
|
|||||||
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "comrak"
|
|
||||||
version = "0.2.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"entities 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"typed-arena 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cookie"
|
name = "cookie"
|
||||||
version = "0.11.0-dev"
|
version = "0.11.0-dev"
|
||||||
@ -400,11 +352,6 @@ dependencies = [
|
|||||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "entities"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "error-chain"
|
name = "error-chain"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@ -1008,7 +955,6 @@ dependencies = [
|
|||||||
"bcrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bcrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"comrak 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1019,6 +965,7 @@ dependencies = [
|
|||||||
"hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rocket 0.4.0-dev (git+https://github.com/SergioBenitez/Rocket?rev=df7111143e466c18d1f56377a8d9530a5a306aba)",
|
"rocket 0.4.0-dev (git+https://github.com/SergioBenitez/Rocket?rev=df7111143e466c18d1f56377a8d9530a5a306aba)",
|
||||||
"rocket_codegen 0.4.0-dev (git+https://github.com/SergioBenitez/Rocket?rev=df7111143e466c18d1f56377a8d9530a5a306aba)",
|
"rocket_codegen 0.4.0-dev (git+https://github.com/SergioBenitez/Rocket?rev=df7111143e466c18d1f56377a8d9530a5a306aba)",
|
||||||
@ -1070,6 +1017,14 @@ dependencies = [
|
|||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pulldown-cmark"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
@ -1134,14 +1089,6 @@ name = "redox_syscall"
|
|||||||
version = "0.1.37"
|
version = "0.1.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_termios"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
@ -1474,11 +1421,6 @@ name = "string_cache_shared"
|
|||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strsim"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "0.11.11"
|
version = "0.11.11"
|
||||||
@ -1587,24 +1529,6 @@ dependencies = [
|
|||||||
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "termion"
|
|
||||||
version = "1.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "textwrap"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thread_local"
|
name = "thread_local"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
@ -1786,24 +1710,11 @@ name = "traitobject"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "twoway"
|
|
||||||
version = "0.1.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typeable"
|
name = "typeable"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "typed-arena"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
@ -1848,11 +1759,6 @@ name = "unicode-segmentation"
|
|||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-width"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.0.4"
|
version = "0.0.4"
|
||||||
@ -1863,11 +1769,6 @@ name = "unicode-xid"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode_categories"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unidecode"
|
name = "unidecode"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@ -1919,11 +1820,6 @@ name = "vcpkg"
|
|||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vec_map"
|
|
||||||
version = "0.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
@ -1996,11 +1892,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45"
|
"checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45"
|
||||||
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
|
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
|
||||||
"checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477"
|
"checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477"
|
||||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
|
||||||
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
||||||
"checksum array_tool 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f8cb5d814eb646a863c4f24978cff2880c4be96ad8cde2c0f0678732902e271"
|
"checksum array_tool 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f8cb5d814eb646a863c4f24978cff2880c4be96ad8cde2c0f0678732902e271"
|
||||||
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
||||||
"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
|
|
||||||
"checksum backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe525f66f42d207968308ee86bc2dd60aa5fab535b22e616323a173d097d8e"
|
"checksum backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe525f66f42d207968308ee86bc2dd60aa5fab535b22e616323a173d097d8e"
|
||||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
||||||
"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
|
"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
|
||||||
@ -2017,9 +1911,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8b9d2900f78631a5876dc5d6c9033ede027253efcd33dd36b1309fc6cab97ee0"
|
"checksum cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8b9d2900f78631a5876dc5d6c9033ede027253efcd33dd36b1309fc6cab97ee0"
|
||||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||||
"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6"
|
"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6"
|
||||||
"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
|
|
||||||
"checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
|
"checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
|
||||||
"checksum comrak 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "053b26c8ce23b4c505a9479beace98f95899e0bf5c5255cf0219e9b0f48cf6ea"
|
|
||||||
"checksum cookie 0.11.0-dev (git+https://github.com/alexcrichton/cookie-rs?rev=0365a18)" = "<none>"
|
"checksum cookie 0.11.0-dev (git+https://github.com/alexcrichton/cookie-rs?rev=0365a18)" = "<none>"
|
||||||
"checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67"
|
"checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67"
|
||||||
"checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d"
|
"checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d"
|
||||||
@ -2034,7 +1926,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a70de3c590ce18df70743cace1cf12565637a0b26fd8b04ef10c7d33fdc66cdc"
|
"checksum dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a70de3c590ce18df70743cace1cf12565637a0b26fd8b04ef10c7d33fdc66cdc"
|
||||||
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
||||||
"checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d"
|
"checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d"
|
||||||
"checksum entities 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca"
|
|
||||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||||
"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
|
"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
|
||||||
"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
|
"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
|
||||||
@ -2110,6 +2001,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0"
|
"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0"
|
||||||
"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
|
"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
|
||||||
"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
|
"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
|
||||||
|
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
|
||||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||||
"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
|
"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
|
||||||
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
|
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
|
||||||
@ -2118,7 +2010,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
|
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
|
||||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||||
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
|
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
|
||||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
|
||||||
"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb"
|
"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb"
|
||||||
"checksum regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bd90079345f4a4c3409214734ae220fd773c6f2e8a543d07370c6c1c369cfbfb"
|
"checksum regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bd90079345f4a4c3409214734ae220fd773c6f2e8a543d07370c6c1c369cfbfb"
|
||||||
"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a"
|
"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a"
|
||||||
@ -2155,7 +2046,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
|
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
|
||||||
"checksum string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35293b05cf1494e8ddd042a7df6756bf18d07f42d234f32e71dce8a7aabb0191"
|
"checksum string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35293b05cf1494e8ddd042a7df6756bf18d07f42d234f32e71dce8a7aabb0191"
|
||||||
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
||||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
|
||||||
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
||||||
"checksum syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97c05b8ebc34ddd6b967994d5c6e9852fa92f8b82b3858c39451f97346dcce5"
|
"checksum syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97c05b8ebc34ddd6b967994d5c6e9852fa92f8b82b3858c39451f97346dcce5"
|
||||||
"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
|
"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
|
||||||
@ -2167,8 +2057,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||||
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
|
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
|
||||||
"checksum tera 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e815b67d44c26feb06630011fb58b5b243f4e9585aac1ed0592c5795de64cd75"
|
"checksum tera 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e815b67d44c26feb06630011fb58b5b243f4e9585aac1ed0592c5795de64cd75"
|
||||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
|
||||||
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
|
|
||||||
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
|
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
|
||||||
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
|
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
|
||||||
"checksum tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be15ef40f675c9fe66e354d74c73f3ed012ca1aa14d65846a33ee48f1ae8d922"
|
"checksum tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be15ef40f675c9fe66e354d74c73f3ed012ca1aa14d65846a33ee48f1ae8d922"
|
||||||
@ -2185,9 +2073,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a"
|
"checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a"
|
||||||
"checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9"
|
"checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9"
|
||||||
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
|
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
|
||||||
"checksum twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1"
|
|
||||||
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
|
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
|
||||||
"checksum typed-arena 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5934776c3ac1bea4a9d56620d6bf2d483b20d394e49581db40f187e1118ff667"
|
|
||||||
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
||||||
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
|
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
|
||||||
"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
|
"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
|
||||||
@ -2195,10 +2081,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||||
"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f"
|
"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f"
|
||||||
"checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946"
|
"checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946"
|
||||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
|
||||||
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
"checksum unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
|
||||||
"checksum unidecode 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "402bb19d8e03f1d1a7450e2bd613980869438e0666331be3e073089124aa1adc"
|
"checksum unidecode 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "402bb19d8e03f1d1a7450e2bd613980869438e0666331be3e073089124aa1adc"
|
||||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||||
"checksum untrusted 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70afa43c8c5d23a53a3c39ec9b56232c5badc19f6bb5ad529c1d6448a7241365"
|
"checksum untrusted 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70afa43c8c5d23a53a3c39ec9b56232c5badc19f6bb5ad529c1d6448a7241365"
|
||||||
@ -2207,7 +2091,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||||||
"checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22"
|
"checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22"
|
||||||
"checksum vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ed0f6789c8a85ca41bbc1c9d175422116a9869bd1cf31bb08e1493ecce60380"
|
"checksum vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ed0f6789c8a85ca41bbc1c9d175422116a9869bd1cf31bb08e1493ecce60380"
|
||||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
|
||||||
"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
|
"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
|
||||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||||
"checksum webfinger 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "27a4e6d1de7050af8beb026c02bcef5340ec1f3af6d4a02248b7990908baa3ff"
|
"checksum webfinger 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "27a4e6d1de7050af8beb026c02bcef5340ec1f3af6d4a02248b7990908baa3ff"
|
||||||
|
@ -9,7 +9,6 @@ array_tool = "1.0"
|
|||||||
base64 = "0.9"
|
base64 = "0.9"
|
||||||
bcrypt = "0.2"
|
bcrypt = "0.2"
|
||||||
colored = "1.6"
|
colored = "1.6"
|
||||||
comrak = "0.2"
|
|
||||||
dotenv = "*"
|
dotenv = "*"
|
||||||
failure = "0.1"
|
failure = "0.1"
|
||||||
failure_derive = "0.1"
|
failure_derive = "0.1"
|
||||||
@ -19,6 +18,7 @@ hex = "0.3"
|
|||||||
hyper = "*"
|
hyper = "*"
|
||||||
lazy_static = "*"
|
lazy_static = "*"
|
||||||
openssl = "0.10.6"
|
openssl = "0.10.6"
|
||||||
|
pulldown-cmark = { version = "0.1.2", default-features = false }
|
||||||
reqwest = "0.8"
|
reqwest = "0.8"
|
||||||
rpassword = "2.0"
|
rpassword = "2.0"
|
||||||
serde = "*"
|
serde = "*"
|
||||||
|
2
migrations/2018-06-20-175532_create_mentions/down.sql
Normal file
2
migrations/2018-06-20-175532_create_mentions/down.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
DROP TABLE mentions;
|
7
migrations/2018-06-20-175532_create_mentions/up.sql
Normal file
7
migrations/2018-06-20-175532_create_mentions/up.sql
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
-- Your SQL goes here
|
||||||
|
CREATE TABLE mentions (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
mentioned_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL,
|
||||||
|
post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE,
|
||||||
|
comment_id INTEGER REFERENCES comments(id) ON DELETE CASCADE
|
||||||
|
)
|
@ -0,0 +1,2 @@
|
|||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
ALTER TABLE mentions DROP COLUMN ap_url;
|
2
migrations/2018-06-20-194538_add_mentions_ap_url/up.sql
Normal file
2
migrations/2018-06-20-194538_add_mentions_ap_url/up.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
-- Your SQL goes here
|
||||||
|
ALTER TABLE mentions ADD COLUMN ap_url VARCHAR NOT NULL DEFAULT '';
|
3
po/en.po
3
po/en.po
@ -280,3 +280,6 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "You are not author in this blog."
|
msgid "You are not author in this blog."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "{{ data }} mentioned you."
|
||||||
|
msgstr ""
|
||||||
|
3
po/fr.po
3
po/fr.po
@ -279,3 +279,6 @@ msgstr "Vous n'avez pas les droits."
|
|||||||
|
|
||||||
msgid "You are not author in this blog."
|
msgid "You are not author in this blog."
|
||||||
msgstr "Vous n'êtes pas auteur dans ce blog."
|
msgstr "Vous n'êtes pas auteur dans ce blog."
|
||||||
|
|
||||||
|
msgid "{{ data }} mentioned you."
|
||||||
|
msgstr ""
|
||||||
|
4
po/pl.po
4
po/pl.po
@ -285,5 +285,9 @@ msgstr ""
|
|||||||
msgid "You are not author in this blog."
|
msgid "You are not author in this blog."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
|
msgid "{{ data }} mentioned you."
|
||||||
|
msgstr "{{ data }} skomentował Twój artykuł"
|
||||||
|
|
||||||
#~ msgid "Logowanie"
|
#~ msgid "Logowanie"
|
||||||
#~ msgstr "Zaloguj się"
|
#~ msgstr "Zaloguj się"
|
||||||
|
@ -275,3 +275,6 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "You are not author in this blog."
|
msgid "You are not author in this blog."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "{{ data }} mentioned you."
|
||||||
|
msgstr ""
|
||||||
|
@ -40,8 +40,8 @@ pub trait FromActivity<T: Object>: Sized {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Notify<T: Object> {
|
pub trait Notify {
|
||||||
fn notify(conn: &PgConnection, act: T, actor: Id);
|
fn notify(&self, conn: &PgConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Deletable {
|
pub trait Deletable {
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
use diesel::{
|
use diesel::{
|
||||||
pg::PgConnection,
|
pg::PgConnection,
|
||||||
r2d2::{ConnectionManager, Pool, PooledConnection}
|
r2d2::{ConnectionManager, PooledConnection}
|
||||||
};
|
};
|
||||||
use rocket::{Request, State, Outcome, http::Status, request::{self, FromRequest}};
|
use rocket::{Request, State, Outcome, http::Status, request::{self, FromRequest}};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use setup::PgPool;
|
||||||
|
|
||||||
// From rocket documentation
|
// From rocket documentation
|
||||||
|
|
||||||
// Connection request guard type: a wrapper around an r2d2 pooled connection.
|
// Connection request guard type: a wrapper around an r2d2 pooled connection.
|
||||||
@ -17,7 +19,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for DbConn {
|
|||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
||||||
let pool = request.guard::<State<Pool<ConnectionManager<PgConnection>>>>()?;
|
let pool = request.guard::<State<PgPool>>()?;
|
||||||
match pool.get() {
|
match pool.get() {
|
||||||
Ok(conn) => Outcome::Success(DbConn(conn)),
|
Ok(conn) => Outcome::Success(DbConn(conn)),
|
||||||
Err(_) => Outcome::Failure((Status::ServiceUnavailable, ()))
|
Err(_) => Outcome::Failure((Status::ServiceUnavailable, ()))
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#![feature(plugin, custom_derive, decl_macro, iterator_find_map)]
|
#![feature(plugin, custom_derive, decl_macro, iterator_find_map, iterator_flatten)]
|
||||||
#![plugin(rocket_codegen)]
|
#![plugin(rocket_codegen)]
|
||||||
|
|
||||||
extern crate activitypub;
|
extern crate activitypub;
|
||||||
@ -8,7 +8,6 @@ extern crate base64;
|
|||||||
extern crate bcrypt;
|
extern crate bcrypt;
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate colored;
|
extern crate colored;
|
||||||
extern crate comrak;
|
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate failure_derive;
|
extern crate failure_derive;
|
||||||
@ -23,6 +22,7 @@ extern crate dotenv;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
extern crate openssl;
|
extern crate openssl;
|
||||||
|
extern crate pulldown_cmark;
|
||||||
extern crate reqwest;
|
extern crate reqwest;
|
||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
extern crate rocket_contrib;
|
extern crate rocket_contrib;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use activitypub::{
|
use activitypub::{
|
||||||
activity::Create,
|
activity::Create,
|
||||||
object::Note
|
link,
|
||||||
|
object::{Note, properties::ObjectProperties}
|
||||||
};
|
};
|
||||||
use chrono;
|
use chrono;
|
||||||
use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods, dsl::any};
|
use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods, dsl::any};
|
||||||
@ -14,6 +15,7 @@ use activity_pub::{
|
|||||||
use models::{
|
use models::{
|
||||||
get_next_id,
|
get_next_id,
|
||||||
instance::Instance,
|
instance::Instance,
|
||||||
|
mentions::Mention,
|
||||||
notifications::*,
|
notifications::*,
|
||||||
posts::Post,
|
posts::Post,
|
||||||
users::User
|
users::User
|
||||||
@ -84,6 +86,16 @@ impl FromActivity<Note> for Comment {
|
|||||||
fn from_activity(conn: &PgConnection, note: Note, actor: Id) -> Comment {
|
fn from_activity(conn: &PgConnection, note: Note, actor: Id) -> Comment {
|
||||||
let previous_url = note.object_props.in_reply_to.clone().unwrap().as_str().unwrap().to_string();
|
let previous_url = note.object_props.in_reply_to.clone().unwrap().as_str().unwrap().to_string();
|
||||||
let previous_comment = Comment::find_by_ap_url(conn, previous_url.clone());
|
let previous_comment = Comment::find_by_ap_url(conn, previous_url.clone());
|
||||||
|
|
||||||
|
// save mentions
|
||||||
|
if let Some(serde_json::Value::Array(tags)) = note.object_props.tag.clone() {
|
||||||
|
for tag in tags.into_iter() {
|
||||||
|
serde_json::from_value::<link::Mention>(tag)
|
||||||
|
.map(|m| Mention::from_activity(conn, m, Id::new(note.clone().object_props.clone().url_string().unwrap_or(String::from("")))))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let comm = Comment::insert(conn, NewComment {
|
let comm = Comment::insert(conn, NewComment {
|
||||||
content: SafeString::new(¬e.object_props.content_string().unwrap()),
|
content: SafeString::new(¬e.object_props.content_string().unwrap()),
|
||||||
spoiler_text: note.object_props.summary_string().unwrap_or(String::from("")),
|
spoiler_text: note.object_props.summary_string().unwrap_or(String::from("")),
|
||||||
@ -95,28 +107,22 @@ impl FromActivity<Note> for Comment {
|
|||||||
author_id: User::from_url(conn, actor.clone().into()).unwrap().id,
|
author_id: User::from_url(conn, actor.clone().into()).unwrap().id,
|
||||||
sensitive: false // "sensitive" is not a standard property, we need to think about how to support it with the activitypub crate
|
sensitive: false // "sensitive" is not a standard property, we need to think about how to support it with the activitypub crate
|
||||||
});
|
});
|
||||||
Comment::notify(conn, note, actor);
|
comm.notify(conn);
|
||||||
comm
|
comm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Notify<Note> for Comment {
|
impl Notify for Comment {
|
||||||
fn notify(conn: &PgConnection, note: Note, _actor: Id) {
|
fn notify(&self, conn: &PgConnection) {
|
||||||
match Comment::find_by_ap_url(conn, note.object_props.id_string().unwrap()) {
|
for author in self.get_post(conn).get_authors(conn) {
|
||||||
Some(comment) => {
|
Notification::insert(conn, NewNotification {
|
||||||
for author in comment.clone().get_post(conn).get_authors(conn) {
|
title: "{{ data }} commented your article".to_string(),
|
||||||
let comment = comment.clone();
|
data: Some(self.get_author(conn).display_name.clone()),
|
||||||
Notification::insert(conn, NewNotification {
|
content: Some(self.get_post(conn).title),
|
||||||
title: "{{ data }} commented your article".to_string(),
|
link: self.ap_url.clone(),
|
||||||
data: Some(comment.get_author(conn).display_name.clone()),
|
user_id: author.id
|
||||||
content: Some(comment.get_post(conn).title),
|
});
|
||||||
link: comment.ap_url,
|
}
|
||||||
user_id: author.id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => println!("Couldn't find comment by AP id, to create a new notification")
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,15 +62,15 @@ impl FromActivity<FollowAct> for Follow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Notify<FollowAct> for Follow {
|
impl Notify for Follow {
|
||||||
fn notify(conn: &PgConnection, follow: FollowAct, actor: Id) {
|
fn notify(&self, conn: &PgConnection) {
|
||||||
let follower = User::from_url(conn, actor.into()).unwrap();
|
let follower = User::get(conn, self.follower_id).unwrap();
|
||||||
Notification::insert(conn, NewNotification {
|
Notification::insert(conn, NewNotification {
|
||||||
title: "{{ data }} started following you".to_string(),
|
title: "{{ data }} started following you".to_string(),
|
||||||
data: Some(follower.display_name.clone()),
|
data: Some(follower.display_name.clone()),
|
||||||
content: None,
|
content: None,
|
||||||
link: Some(follower.ap_url),
|
link: Some(follower.ap_url),
|
||||||
user_id: User::from_url(conn, follow.follow_props.object_link::<Id>().unwrap().into()).unwrap().id
|
user_id: self.following_id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ impl Like {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FromActivity<activity::Like> for Like {
|
impl FromActivity<activity::Like> for Like {
|
||||||
fn from_activity(conn: &PgConnection, like: activity::Like, actor: Id) -> Like {
|
fn from_activity(conn: &PgConnection, like: activity::Like, _actor: Id) -> Like {
|
||||||
let liker = User::from_url(conn, like.like_props.actor.as_str().unwrap().to_string());
|
let liker = User::from_url(conn, like.like_props.actor.as_str().unwrap().to_string());
|
||||||
let post = Post::find_by_ap_url(conn, like.like_props.object.as_str().unwrap().to_string());
|
let post = Post::find_by_ap_url(conn, like.like_props.object.as_str().unwrap().to_string());
|
||||||
let res = Like::insert(conn, NewLike {
|
let res = Like::insert(conn, NewLike {
|
||||||
@ -85,15 +85,15 @@ impl FromActivity<activity::Like> for Like {
|
|||||||
user_id: liker.unwrap().id,
|
user_id: liker.unwrap().id,
|
||||||
ap_url: like.object_props.id_string().unwrap_or(String::from(""))
|
ap_url: like.object_props.id_string().unwrap_or(String::from(""))
|
||||||
});
|
});
|
||||||
Like::notify(conn, like, actor);
|
res.notify(conn);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Notify<activity::Like> for Like {
|
impl Notify for Like {
|
||||||
fn notify(conn: &PgConnection, like: activity::Like, actor: Id) {
|
fn notify(&self, conn: &PgConnection) {
|
||||||
let liker = User::from_url(conn, actor.into()).unwrap();
|
let liker = User::get(conn, self.user_id).unwrap();
|
||||||
let post = Post::find_by_ap_url(conn, like.like_props.object_link::<Id>().unwrap().into()).unwrap();
|
let post = Post::get(conn, self.post_id).unwrap();
|
||||||
for author in post.get_authors(conn) {
|
for author in post.get_authors(conn) {
|
||||||
let post = post.clone();
|
let post = post.clone();
|
||||||
Notification::insert(conn, NewNotification {
|
Notification::insert(conn, NewNotification {
|
||||||
|
113
src/models/mentions.rs
Normal file
113
src/models/mentions.rs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
use activitypub::link;
|
||||||
|
use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods};
|
||||||
|
|
||||||
|
use activity_pub::{Id, inbox::Notify};
|
||||||
|
use models::{
|
||||||
|
comments::Comment,
|
||||||
|
notifications::*,
|
||||||
|
posts::Post,
|
||||||
|
users::User
|
||||||
|
};
|
||||||
|
use schema::mentions;
|
||||||
|
|
||||||
|
#[derive(Queryable, Identifiable)]
|
||||||
|
pub struct Mention {
|
||||||
|
pub id: i32,
|
||||||
|
pub mentioned_id: i32,
|
||||||
|
pub post_id: Option<i32>,
|
||||||
|
pub comment_id: Option<i32>,
|
||||||
|
pub ap_url: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable)]
|
||||||
|
#[table_name = "mentions"]
|
||||||
|
pub struct NewMention {
|
||||||
|
pub mentioned_id: i32,
|
||||||
|
pub post_id: Option<i32>,
|
||||||
|
pub comment_id: Option<i32>,
|
||||||
|
pub ap_url: String
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mention {
|
||||||
|
insert!(mentions, NewMention);
|
||||||
|
get!(mentions);
|
||||||
|
find_by!(mentions, find_by_ap_url, ap_url as String);
|
||||||
|
list_by!(mentions, list_for_user, mentioned_id as i32);
|
||||||
|
list_by!(mentions, list_for_post, post_id as i32);
|
||||||
|
|
||||||
|
pub fn get_mentioned(&self, conn: &PgConnection) -> Option<User> {
|
||||||
|
User::get(conn, self.mentioned_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_post(&self, conn: &PgConnection) -> Option<Post> {
|
||||||
|
self.post_id.and_then(|id| Post::get(conn, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_comment(&self, conn: &PgConnection) -> Option<Comment> {
|
||||||
|
self.post_id.and_then(|id| Comment::get(conn, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_activity(conn: &PgConnection, ment: String) -> link::Mention {
|
||||||
|
let user = User::find_by_fqn(conn, ment.clone());
|
||||||
|
println!("building act : {} -> {:?}", ment, user);
|
||||||
|
let mut mention = link::Mention::default();
|
||||||
|
mention.link_props.set_href_string(user.clone().map(|u| u.ap_url).unwrap_or(String::new())).expect("Error setting mention's href");
|
||||||
|
mention.link_props.set_name_string(format!("@{}", ment)).expect("Error setting mention's name");
|
||||||
|
mention
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_activity(&self, conn: &PgConnection) -> link::Mention {
|
||||||
|
let user = self.get_mentioned(conn);
|
||||||
|
let mut mention = link::Mention::default();
|
||||||
|
mention.link_props.set_href_string(user.clone().map(|u| u.ap_url).unwrap_or(String::new())).expect("Error setting mention's href");
|
||||||
|
mention.link_props.set_name_string(user.map(|u| format!("@{}", u.get_fqn(conn))).unwrap_or(String::new())).expect("Error setting mention's name");
|
||||||
|
mention
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_activity(conn: &PgConnection, ment: link::Mention, inside: Id) -> Option<Self> {
|
||||||
|
let ap_url = ment.link_props.href_string().unwrap();
|
||||||
|
let mentioned = User::find_by_ap_url(conn, ap_url).unwrap();
|
||||||
|
|
||||||
|
if let Some(post) = Post::find_by_ap_url(conn, inside.clone().into()) {
|
||||||
|
let res = Mention::insert(conn, NewMention {
|
||||||
|
mentioned_id: mentioned.id,
|
||||||
|
post_id: Some(post.id),
|
||||||
|
comment_id: None,
|
||||||
|
ap_url: ment.link_props.href_string().unwrap_or(String::new())
|
||||||
|
});
|
||||||
|
res.notify(conn);
|
||||||
|
Some(res)
|
||||||
|
} else {
|
||||||
|
if let Some(comment) = Comment::find_by_ap_url(conn, inside.into()) {
|
||||||
|
let res = Mention::insert(conn, NewMention {
|
||||||
|
mentioned_id: mentioned.id,
|
||||||
|
post_id: None,
|
||||||
|
comment_id: Some(comment.id),
|
||||||
|
ap_url: ment.link_props.href_string().unwrap_or(String::new())
|
||||||
|
});
|
||||||
|
res.notify(conn);
|
||||||
|
Some(res)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Notify for Mention {
|
||||||
|
fn notify(&self, conn: &PgConnection) {
|
||||||
|
let author = self.get_comment(conn)
|
||||||
|
.map(|c| c.get_author(conn).display_name.clone())
|
||||||
|
.unwrap_or(self.get_post(conn).unwrap().get_authors(conn)[0].display_name.clone());
|
||||||
|
|
||||||
|
self.get_mentioned(conn).map(|m| {
|
||||||
|
Notification::insert(conn, NewNotification {
|
||||||
|
title: "{{ data }} mentioned you.".to_string(),
|
||||||
|
data: Some(author),
|
||||||
|
content: None,
|
||||||
|
link: Some(self.get_post(conn).map(|p| p.ap_url).unwrap_or_else(|| self.get_comment(conn).unwrap().ap_url.unwrap_or(String::new()))),
|
||||||
|
user_id: m.id
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,18 @@ macro_rules! find_by {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! list_by {
|
||||||
|
($table:ident, $fn:ident, $($col:ident as $type:ident),+) => {
|
||||||
|
/// Try to find a $table with a given $col
|
||||||
|
pub fn $fn(conn: &PgConnection, $($col: $type),+) -> Vec<Self> {
|
||||||
|
$table::table
|
||||||
|
$(.filter($table::$col.eq($col)))+
|
||||||
|
.load::<Self>(conn)
|
||||||
|
.expect("Error loading $table by $col")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! get {
|
macro_rules! get {
|
||||||
($table:ident) => {
|
($table:ident) => {
|
||||||
pub fn get(conn: &PgConnection, id: i32) -> Option<Self> {
|
pub fn get(conn: &PgConnection, id: i32) -> Option<Self> {
|
||||||
@ -53,6 +65,7 @@ pub mod comments;
|
|||||||
pub mod follows;
|
pub mod follows;
|
||||||
pub mod instance;
|
pub mod instance;
|
||||||
pub mod likes;
|
pub mod likes;
|
||||||
|
pub mod mentions;
|
||||||
pub mod notifications;
|
pub mod notifications;
|
||||||
pub mod post_authors;
|
pub mod post_authors;
|
||||||
pub mod posts;
|
pub mod posts;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use activitypub::{
|
use activitypub::{
|
||||||
activity::Create,
|
activity::Create,
|
||||||
|
link,
|
||||||
object::{Article, properties::ObjectProperties}
|
object::{Article, properties::ObjectProperties}
|
||||||
};
|
};
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
@ -9,13 +10,13 @@ use serde_json;
|
|||||||
use BASE_URL;
|
use BASE_URL;
|
||||||
use activity_pub::{
|
use activity_pub::{
|
||||||
PUBLIC_VISIBILTY, ap_url, Id, IntoId,
|
PUBLIC_VISIBILTY, ap_url, Id, IntoId,
|
||||||
actor::Actor,
|
|
||||||
inbox::FromActivity
|
inbox::FromActivity
|
||||||
};
|
};
|
||||||
use models::{
|
use models::{
|
||||||
blogs::Blog,
|
blogs::Blog,
|
||||||
instance::Instance,
|
instance::Instance,
|
||||||
likes::Like,
|
likes::Like,
|
||||||
|
mentions::Mention,
|
||||||
post_authors::PostAuthor,
|
post_authors::PostAuthor,
|
||||||
reshares::Reshare,
|
reshares::Reshare,
|
||||||
users::User
|
users::User
|
||||||
@ -144,6 +145,8 @@ impl Post {
|
|||||||
let mut to = self.get_receivers_urls(conn);
|
let mut to = self.get_receivers_urls(conn);
|
||||||
to.push(PUBLIC_VISIBILTY.to_string());
|
to.push(PUBLIC_VISIBILTY.to_string());
|
||||||
|
|
||||||
|
let mentions = Mention::list_for_post(conn, self.id).into_iter().map(|m| m.to_activity(conn)).collect::<Vec<link::Mention>>();
|
||||||
|
|
||||||
let mut article = Article::default();
|
let mut article = Article::default();
|
||||||
article.object_props = ObjectProperties {
|
article.object_props = ObjectProperties {
|
||||||
name: Some(serde_json::to_value(self.title.clone()).unwrap()),
|
name: Some(serde_json::to_value(self.title.clone()).unwrap()),
|
||||||
@ -151,7 +154,7 @@ impl Post {
|
|||||||
attributed_to: Some(serde_json::to_value(self.get_authors(conn).into_iter().map(|x| x.ap_url).collect::<Vec<String>>()).unwrap()),
|
attributed_to: Some(serde_json::to_value(self.get_authors(conn).into_iter().map(|x| x.ap_url).collect::<Vec<String>>()).unwrap()),
|
||||||
content: Some(serde_json::to_value(self.content.clone()).unwrap()),
|
content: Some(serde_json::to_value(self.content.clone()).unwrap()),
|
||||||
published: Some(serde_json::to_value(self.creation_date).unwrap()),
|
published: Some(serde_json::to_value(self.creation_date).unwrap()),
|
||||||
tag: Some(serde_json::to_value(Vec::<serde_json::Value>::new()).unwrap()),
|
tag: Some(serde_json::to_value(mentions).unwrap()),
|
||||||
url: Some(serde_json::to_value(self.compute_id(conn)).unwrap()),
|
url: Some(serde_json::to_value(self.compute_id(conn)).unwrap()),
|
||||||
to: Some(serde_json::to_value(to).unwrap()),
|
to: Some(serde_json::to_value(to).unwrap()),
|
||||||
cc: Some(serde_json::to_value(Vec::<serde_json::Value>::new()).unwrap()),
|
cc: Some(serde_json::to_value(Vec::<serde_json::Value>::new()).unwrap()),
|
||||||
@ -184,6 +187,15 @@ impl Post {
|
|||||||
|
|
||||||
impl FromActivity<Article> for Post {
|
impl FromActivity<Article> for Post {
|
||||||
fn from_activity(conn: &PgConnection, article: Article, _actor: Id) -> Post {
|
fn from_activity(conn: &PgConnection, article: Article, _actor: Id) -> Post {
|
||||||
|
// save mentions
|
||||||
|
if let Some(serde_json::Value::Array(tags)) = article.object_props.tag.clone() {
|
||||||
|
for tag in tags.into_iter() {
|
||||||
|
serde_json::from_value::<link::Mention>(tag)
|
||||||
|
.map(|m| Mention::from_activity(conn, m, Id::new(article.clone().object_props.clone().url_string().unwrap_or(String::from("")))))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Post::insert(conn, NewPost {
|
Post::insert(conn, NewPost {
|
||||||
blog_id: 0, // TODO
|
blog_id: 0, // TODO
|
||||||
slug: String::from(""), // TODO
|
slug: String::from(""), // TODO
|
||||||
|
@ -73,7 +73,7 @@ impl Reshare {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FromActivity<Announce> for Reshare {
|
impl FromActivity<Announce> for Reshare {
|
||||||
fn from_activity(conn: &PgConnection, announce: Announce, actor: Id) -> Reshare {
|
fn from_activity(conn: &PgConnection, announce: Announce, _actor: Id) -> Reshare {
|
||||||
let user = User::from_url(conn, announce.announce_props.actor.as_str().unwrap().to_string());
|
let user = User::from_url(conn, announce.announce_props.actor.as_str().unwrap().to_string());
|
||||||
let post = Post::find_by_ap_url(conn, announce.announce_props.object.as_str().unwrap().to_string());
|
let post = Post::find_by_ap_url(conn, announce.announce_props.object.as_str().unwrap().to_string());
|
||||||
let reshare = Reshare::insert(conn, NewReshare {
|
let reshare = Reshare::insert(conn, NewReshare {
|
||||||
@ -81,15 +81,15 @@ impl FromActivity<Announce> for Reshare {
|
|||||||
user_id: user.unwrap().id,
|
user_id: user.unwrap().id,
|
||||||
ap_url: announce.object_props.id_string().unwrap_or(String::from(""))
|
ap_url: announce.object_props.id_string().unwrap_or(String::from(""))
|
||||||
});
|
});
|
||||||
Reshare::notify(conn, announce, actor);
|
reshare.notify(conn);
|
||||||
reshare
|
reshare
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Notify<Announce> for Reshare {
|
impl Notify for Reshare {
|
||||||
fn notify(conn: &PgConnection, announce: Announce, actor: Id) {
|
fn notify(&self, conn: &PgConnection) {
|
||||||
let actor = User::from_url(conn, actor.into()).unwrap();
|
let actor = User::get(conn, self.user_id).unwrap();
|
||||||
let post = Post::find_by_ap_url(conn, announce.announce_props.object_link::<Id>().unwrap().into()).unwrap();
|
let post = self.get_post(conn).unwrap();
|
||||||
for author in post.get_authors(conn) {
|
for author in post.get_authors(conn) {
|
||||||
let post = post.clone();
|
let post = post.clone();
|
||||||
Notification::insert(conn, NewNotification {
|
Notification::insert(conn, NewNotification {
|
||||||
|
@ -47,7 +47,7 @@ use safe_string::SafeString;
|
|||||||
|
|
||||||
pub const AUTH_COOKIE: &'static str = "user_id";
|
pub const AUTH_COOKIE: &'static str = "user_id";
|
||||||
|
|
||||||
#[derive(Queryable, Identifiable, Serialize, Deserialize, Clone)]
|
#[derive(Queryable, Identifiable, Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
@ -89,7 +89,7 @@ impl User {
|
|||||||
get!(users);
|
get!(users);
|
||||||
find_by!(users, find_by_email, email as String);
|
find_by!(users, find_by_email, email as String);
|
||||||
find_by!(users, find_by_name, username as String, instance_id as i32);
|
find_by!(users, find_by_name, username as String, instance_id as i32);
|
||||||
|
find_by!(users, find_by_ap_url, ap_url as String);
|
||||||
|
|
||||||
pub fn grant_admin_rights(&self, conn: &PgConnection) {
|
pub fn grant_admin_rights(&self, conn: &PgConnection) {
|
||||||
diesel::update(self)
|
diesel::update(self)
|
||||||
@ -419,23 +419,15 @@ impl APActor for User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn from_url(conn: &PgConnection, url: String) -> Option<User> {
|
fn from_url(conn: &PgConnection, url: String) -> Option<User> {
|
||||||
let in_db = users::table.filter(users::ap_url.eq(url.clone()))
|
User::find_by_ap_url(conn, url.clone()).or_else(|| {
|
||||||
.limit(1)
|
// The requested user was not in the DB
|
||||||
.load::<User>(conn)
|
// We try to fetch it if it is remote
|
||||||
.expect("Error loading user by AP url")
|
if Url::parse(url.as_ref()).unwrap().host_str().unwrap() != BASE_URL.as_str() {
|
||||||
.into_iter().nth(0);
|
Some(User::fetch_from_url(conn, url).unwrap())
|
||||||
match in_db {
|
} else {
|
||||||
Some(u) => Some(u),
|
None
|
||||||
None => {
|
|
||||||
// The requested user was not in the DB
|
|
||||||
// We try to fetch it if it is remote
|
|
||||||
if Url::parse(url.as_ref()).unwrap().host_str().unwrap() != BASE_URL.as_str() {
|
|
||||||
Some(User::fetch_from_url(conn, url).unwrap())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use rocket::{
|
|||||||
use rocket_contrib::Template;
|
use rocket_contrib::Template;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
|
||||||
use activity_pub::{broadcast, inbox::Inbox};
|
use activity_pub::{broadcast, inbox::Inbox, inbox::Notify};
|
||||||
use db_conn::DbConn;
|
use db_conn::DbConn;
|
||||||
use models::{
|
use models::{
|
||||||
blogs::Blog,
|
blogs::Blog,
|
||||||
@ -55,6 +55,7 @@ fn create_response(blog_name: String, slug: String, query: Option<CommentQuery>,
|
|||||||
let blog = Blog::find_by_fqn(&*conn, blog_name.clone()).unwrap();
|
let blog = Blog::find_by_fqn(&*conn, blog_name.clone()).unwrap();
|
||||||
let post = Post::find_by_slug(&*conn, slug.clone(), blog.id).unwrap();
|
let post = Post::find_by_slug(&*conn, slug.clone(), blog.id).unwrap();
|
||||||
let form = data.get();
|
let form = data.get();
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
let (new_comment, id) = NewComment::build()
|
let (new_comment, id) = NewComment::build()
|
||||||
.content(form.content.clone())
|
.content(form.content.clone())
|
||||||
@ -67,6 +68,20 @@ fn create_response(blog_name: String, slug: String, query: Option<CommentQuery>,
|
|||||||
let instance = Instance::get_local(&*conn).unwrap();
|
let instance = Instance::get_local(&*conn).unwrap();
|
||||||
instance.received(&*conn, serde_json::to_value(new_comment.clone()).expect("JSON serialization error"));
|
instance.received(&*conn, serde_json::to_value(new_comment.clone()).expect("JSON serialization error"));
|
||||||
broadcast(&*conn, &user, new_comment, user.get_followers(&*conn));
|
broadcast(&*conn, &user, new_comment, user.get_followers(&*conn));
|
||||||
|
=======
|
||||||
|
let comment = Comment::insert(&*conn, NewComment {
|
||||||
|
content: SafeString::new(&form.content.clone()),
|
||||||
|
in_response_to_id: query.responding_to,
|
||||||
|
post_id: post.id,
|
||||||
|
author_id: user.id,
|
||||||
|
ap_url: None, // TODO: set it
|
||||||
|
sensitive: false,
|
||||||
|
spoiler_text: "".to_string()
|
||||||
|
});
|
||||||
|
comment.notify(&*conn);
|
||||||
|
|
||||||
|
broadcast(&*conn, &user, comment.create_activity(&*conn), user.get_followers(&*conn));
|
||||||
|
>>>>>>> dbdcbe71049e181c1c7649169c0153b3c9d81ad8
|
||||||
|
|
||||||
Redirect::to(format!("/~/{}/{}/#comment-{}", blog_name, slug, id))
|
Redirect::to(format!("/~/{}/{}/#comment-{}", blog_name, slug, id))
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use rocket::response::{Redirect, Flash};
|
use rocket::response::{Redirect, Flash};
|
||||||
|
|
||||||
use activity_pub::{broadcast, IntoId, inbox::Notify};
|
use activity_pub::{broadcast, inbox::Notify};
|
||||||
use db_conn::DbConn;
|
use db_conn::DbConn;
|
||||||
use models::{
|
use models::{
|
||||||
blogs::Blog,
|
blogs::Blog,
|
||||||
@ -23,8 +23,8 @@ fn create(blog: String, slug: String, user: User, conn: DbConn) -> Redirect {
|
|||||||
ap_url: "".to_string()
|
ap_url: "".to_string()
|
||||||
});
|
});
|
||||||
like.update_ap_url(&*conn);
|
like.update_ap_url(&*conn);
|
||||||
|
like.notify(&*conn);
|
||||||
|
|
||||||
likes::Like::notify(&*conn, like.into_activity(&*conn), user.clone().into_id());
|
|
||||||
broadcast(&*conn, &user, like.into_activity(&*conn), user.get_followers(&*conn));
|
broadcast(&*conn, &user, like.into_activity(&*conn), user.get_followers(&*conn));
|
||||||
} else {
|
} else {
|
||||||
let like = likes::Like::find_by_user_on_post(&*conn, user.id, post.id).unwrap();
|
let like = likes::Like::find_by_user_on_post(&*conn, user.id, post.id).unwrap();
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
use comrak::{markdown_to_html, ComrakOptions};
|
|
||||||
use heck::KebabCase;
|
use heck::KebabCase;
|
||||||
use rocket::request::Form;
|
use rocket::request::Form;
|
||||||
use rocket::response::{Redirect, Flash};
|
use rocket::response::{Redirect, Flash};
|
||||||
use rocket_contrib::Template;
|
use rocket_contrib::Template;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
|
||||||
use activity_pub::{broadcast, context, activity_pub, ActivityPub};
|
use activity_pub::{broadcast, context, activity_pub, ActivityPub, Id};
|
||||||
use db_conn::DbConn;
|
use db_conn::DbConn;
|
||||||
use models::{
|
use models::{
|
||||||
blogs::*,
|
blogs::*,
|
||||||
comments::Comment,
|
comments::Comment,
|
||||||
|
mentions::Mention,
|
||||||
post_authors::*,
|
post_authors::*,
|
||||||
posts::*,
|
posts::*,
|
||||||
users::User
|
users::User
|
||||||
};
|
};
|
||||||
use utils;
|
|
||||||
use safe_string::SafeString;
|
use safe_string::SafeString;
|
||||||
|
use utils;
|
||||||
|
|
||||||
#[get("/~/<blog>/<slug>", rank = 4)]
|
#[get("/~/<blog>/<slug>", rank = 4)]
|
||||||
fn details(blog: String, slug: String, conn: DbConn, user: Option<User>) -> Template {
|
fn details(blog: String, slug: String, conn: DbConn, user: Option<User>) -> Template {
|
||||||
@ -88,19 +88,7 @@ fn create(blog_name: String, data: Form<NewPostForm>, user: User, conn: DbConn)
|
|||||||
if slug == "new" || Post::find_by_slug(&*conn, slug.clone(), blog.id).is_some() {
|
if slug == "new" || Post::find_by_slug(&*conn, slug.clone(), blog.id).is_some() {
|
||||||
Redirect::to(uri!(new: blog = blog_name))
|
Redirect::to(uri!(new: blog = blog_name))
|
||||||
} else {
|
} else {
|
||||||
let content = markdown_to_html(form.content.to_string().as_ref(), &ComrakOptions{
|
let (content, mentions) = utils::md_to_html(form.content.to_string().as_ref());
|
||||||
smart: true,
|
|
||||||
safe: true,
|
|
||||||
ext_strikethrough: true,
|
|
||||||
ext_tagfilter: true,
|
|
||||||
ext_table: true,
|
|
||||||
ext_autolink: true,
|
|
||||||
ext_tasklist: true,
|
|
||||||
ext_superscript: true,
|
|
||||||
ext_header_ids: Some("title".to_string()),
|
|
||||||
ext_footnotes: true,
|
|
||||||
..ComrakOptions::default()
|
|
||||||
});
|
|
||||||
|
|
||||||
let post = Post::insert(&*conn, NewPost {
|
let post = Post::insert(&*conn, NewPost {
|
||||||
blog_id: blog.id,
|
blog_id: blog.id,
|
||||||
@ -117,6 +105,10 @@ fn create(blog_name: String, data: Form<NewPostForm>, user: User, conn: DbConn)
|
|||||||
author_id: user.id
|
author_id: user.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for m in mentions.into_iter() {
|
||||||
|
Mention::from_activity(&*conn, Mention::build_activity(&*conn, m), Id::new(post.compute_id(&*conn)));
|
||||||
|
}
|
||||||
|
|
||||||
let act = post.create_activity(&*conn);
|
let act = post.create_activity(&*conn);
|
||||||
broadcast(&*conn, &user, act, user.get_followers(&*conn));
|
broadcast(&*conn, &user, act, user.get_followers(&*conn));
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use rocket::response::{Redirect, Flash};
|
use rocket::response::{Redirect, Flash};
|
||||||
|
|
||||||
use activity_pub::{broadcast, IntoId, inbox::Notify};
|
use activity_pub::{broadcast, inbox::Notify};
|
||||||
use db_conn::DbConn;
|
use db_conn::DbConn;
|
||||||
use models::{
|
use models::{
|
||||||
blogs::Blog,
|
blogs::Blog,
|
||||||
@ -23,8 +23,8 @@ fn create(blog: String, slug: String, user: User, conn: DbConn) -> Redirect {
|
|||||||
ap_url: "".to_string()
|
ap_url: "".to_string()
|
||||||
});
|
});
|
||||||
reshare.update_ap_url(&*conn);
|
reshare.update_ap_url(&*conn);
|
||||||
|
reshare.notify(&*conn);
|
||||||
|
|
||||||
Reshare::notify(&*conn, reshare.into_activity(&*conn), user.clone().into_id());
|
|
||||||
broadcast(&*conn, &user, reshare.into_activity(&*conn), user.get_followers(&*conn));
|
broadcast(&*conn, &user, reshare.into_activity(&*conn), user.get_followers(&*conn));
|
||||||
} else {
|
} else {
|
||||||
let reshare = Reshare::find_by_user_on_post(&*conn, user.id, post.id).unwrap();
|
let reshare = Reshare::find_by_user_on_post(&*conn, user.id, post.id).unwrap();
|
||||||
|
@ -71,16 +71,17 @@ fn dashboard_auth() -> Flash<Redirect> {
|
|||||||
#[get("/@/<name>/follow")]
|
#[get("/@/<name>/follow")]
|
||||||
fn follow(name: String, conn: DbConn, user: User) -> Redirect {
|
fn follow(name: String, conn: DbConn, user: User) -> Redirect {
|
||||||
let target = User::find_by_fqn(&*conn, name.clone()).unwrap();
|
let target = User::find_by_fqn(&*conn, name.clone()).unwrap();
|
||||||
follows::Follow::insert(&*conn, follows::NewFollow {
|
let f = follows::Follow::insert(&*conn, follows::NewFollow {
|
||||||
follower_id: user.id,
|
follower_id: user.id,
|
||||||
following_id: target.id
|
following_id: target.id
|
||||||
});
|
});
|
||||||
|
f.notify(&*conn);
|
||||||
|
|
||||||
let mut act = Follow::default();
|
let mut act = Follow::default();
|
||||||
act.follow_props.set_actor_link::<Id>(user.clone().into_id()).unwrap();
|
act.follow_props.set_actor_link::<Id>(user.clone().into_id()).unwrap();
|
||||||
act.follow_props.set_object_object(user.into_activity(&*conn)).unwrap();
|
act.follow_props.set_object_object(user.into_activity(&*conn)).unwrap();
|
||||||
act.object_props.set_id_string(format!("{}/follow/{}", user.ap_url, target.ap_url)).unwrap();
|
act.object_props.set_id_string(format!("{}/follow/{}", user.ap_url, target.ap_url)).unwrap();
|
||||||
|
|
||||||
follows::Follow::notify(&*conn, act.clone(), user.clone().into_id());
|
|
||||||
broadcast(&*conn, &user, act, vec![target]);
|
broadcast(&*conn, &user, act, vec![target]);
|
||||||
Redirect::to(uri!(details: name = name))
|
Redirect::to(uri!(details: name = name))
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,16 @@ table! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
mentions (id) {
|
||||||
|
id -> Int4,
|
||||||
|
mentioned_id -> Int4,
|
||||||
|
post_id -> Nullable<Int4>,
|
||||||
|
comment_id -> Nullable<Int4>,
|
||||||
|
ap_url -> Varchar,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
table! {
|
table! {
|
||||||
notifications (id) {
|
notifications (id) {
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
@ -137,6 +147,9 @@ joinable!(comments -> posts (post_id));
|
|||||||
joinable!(comments -> users (author_id));
|
joinable!(comments -> users (author_id));
|
||||||
joinable!(likes -> posts (post_id));
|
joinable!(likes -> posts (post_id));
|
||||||
joinable!(likes -> users (user_id));
|
joinable!(likes -> users (user_id));
|
||||||
|
joinable!(mentions -> comments (comment_id));
|
||||||
|
joinable!(mentions -> posts (post_id));
|
||||||
|
joinable!(mentions -> users (mentioned_id));
|
||||||
joinable!(notifications -> users (user_id));
|
joinable!(notifications -> users (user_id));
|
||||||
joinable!(post_authors -> posts (post_id));
|
joinable!(post_authors -> posts (post_id));
|
||||||
joinable!(post_authors -> users (author_id));
|
joinable!(post_authors -> users (author_id));
|
||||||
@ -152,6 +165,7 @@ allow_tables_to_appear_in_same_query!(
|
|||||||
follows,
|
follows,
|
||||||
instances,
|
instances,
|
||||||
likes,
|
likes,
|
||||||
|
mentions,
|
||||||
notifications,
|
notifications,
|
||||||
post_authors,
|
post_authors,
|
||||||
posts,
|
posts,
|
||||||
|
@ -12,7 +12,7 @@ use db_conn::DbConn;
|
|||||||
use models::instance::*;
|
use models::instance::*;
|
||||||
use models::users::*;
|
use models::users::*;
|
||||||
|
|
||||||
type PgPool = Pool<ConnectionManager<PgConnection>>;
|
pub type PgPool = Pool<ConnectionManager<PgConnection>>;
|
||||||
|
|
||||||
/// Initializes a database pool.
|
/// Initializes a database pool.
|
||||||
fn init_pool() -> Option<PgPool> {
|
fn init_pool() -> Option<PgPool> {
|
||||||
|
50
src/utils.rs
50
src/utils.rs
@ -1,5 +1,6 @@
|
|||||||
use gettextrs::gettext;
|
use gettextrs::gettext;
|
||||||
use heck::CamelCase;
|
use heck::CamelCase;
|
||||||
|
use pulldown_cmark::{Event, Parser, Options, Tag, html};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
http::uri::Uri,
|
http::uri::Uri,
|
||||||
response::{Redirect, Flash}
|
response::{Redirect, Flash}
|
||||||
@ -18,3 +19,52 @@ pub fn make_actor_id(name: String) -> String {
|
|||||||
pub fn requires_login(message: &str, url: Uri) -> Flash<Redirect> {
|
pub fn requires_login(message: &str, url: Uri) -> Flash<Redirect> {
|
||||||
Flash::new(Redirect::to(Uri::new(format!("/login?m={}", gettext(message.to_string())))), "callback", url.as_str())
|
Flash::new(Redirect::to(Uri::new(format!("/login?m={}", gettext(message.to_string())))), "callback", url.as_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns (HTML, mentions)
|
||||||
|
pub fn md_to_html(md: &str) -> (String, Vec<String>) {
|
||||||
|
let parser = Parser::new_ext(md, Options::all());
|
||||||
|
|
||||||
|
let (parser, mentions): (Vec<Vec<Event>>, Vec<Vec<String>>) = parser.map(|evt| match evt {
|
||||||
|
Event::Text(txt) => {
|
||||||
|
let (evts, _, _, _, new_mentions) = txt.chars().fold((vec![], false, String::new(), 0, vec![]), |(mut events, in_mention, text_acc, n, mut mentions), c| {
|
||||||
|
if in_mention {
|
||||||
|
if (c.is_alphanumeric() || c == '@' || c == '.' || c == '-' || c == '_') && (n < (txt.chars().count() - 1)) {
|
||||||
|
(events, in_mention, text_acc + c.to_string().as_ref(), n + 1, mentions)
|
||||||
|
} else {
|
||||||
|
let mention = text_acc + c.to_string().as_ref();
|
||||||
|
let short_mention = mention.clone();
|
||||||
|
let short_mention = short_mention.splitn(1, '@').nth(0).unwrap_or("");
|
||||||
|
let link = Tag::Link(format!("/@/{}/", mention).into(), short_mention.to_string().into());
|
||||||
|
|
||||||
|
mentions.push(mention);
|
||||||
|
events.push(Event::Start(link.clone()));
|
||||||
|
events.push(Event::Text(format!("@{}", short_mention).into()));
|
||||||
|
events.push(Event::End(link));
|
||||||
|
|
||||||
|
(events, false, c.to_string(), n + 1, mentions)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if c == '@' {
|
||||||
|
events.push(Event::Text(text_acc.into()));
|
||||||
|
(events, true, String::new(), n + 1, mentions)
|
||||||
|
} else {
|
||||||
|
if n >= (txt.chars().count() - 1) { // Add the text after at the end, even if it is not followed by a mention.
|
||||||
|
events.push(Event::Text((text_acc.clone() + c.to_string().as_ref()).into()))
|
||||||
|
}
|
||||||
|
(events, in_mention, text_acc + c.to_string().as_ref(), n + 1, mentions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
(evts, new_mentions)
|
||||||
|
},
|
||||||
|
_ => (vec![evt], vec![])
|
||||||
|
}).unzip();
|
||||||
|
let parser = parser.into_iter().flatten();
|
||||||
|
let mentions = mentions.into_iter().flatten().map(|m| String::from(m.trim()));
|
||||||
|
|
||||||
|
// TODO: fetch mentionned profiles in background, if needed
|
||||||
|
|
||||||
|
let mut buf = String::new();
|
||||||
|
html::push_html(&mut buf, parser);
|
||||||
|
(buf, mentions.collect())
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user