Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f0ca7ccde8 | |||
| 7fd1fe6d52 | |||
| 54c6d21fc5 | |||
| c031804464 | |||
| 5289fe872a | |||
| 7ea4acc289 | |||
| 6dbc043a7e | |||
| fb1668ede7 | |||
| 3d27e283ad | |||
| 4b205fa995 | |||
| e7126ae335 | |||
| b2312d7f1b |
+2
-46
@@ -1,46 +1,2 @@
|
|||||||
# Contributor Covenant Code of Conduct
|
You can read our Code of Conduct [here](https://docs.joinplu.me/organization/code-of-conduct).
|
||||||
|
By contributing to this repository, you agree to be bound by this Code of Conduct.
|
||||||
## Our Pledge
|
|
||||||
|
|
||||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, sexual identity and orientation, etc.
|
|
||||||
|
|
||||||
## Our Standards
|
|
||||||
|
|
||||||
Examples of behavior that contributes to creating a positive environment include:
|
|
||||||
|
|
||||||
* Using welcoming and inclusive language
|
|
||||||
* Being respectful of differing viewpoints and experiences
|
|
||||||
* Gracefully accepting constructive criticism
|
|
||||||
* Focusing on what is best for the community
|
|
||||||
* Showing empathy towards other community members
|
|
||||||
|
|
||||||
Examples of unacceptable behavior by participants include:
|
|
||||||
|
|
||||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
|
||||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
|
||||||
* Public or private harassment
|
|
||||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
|
||||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
|
||||||
|
|
||||||
## Our Responsibilities
|
|
||||||
|
|
||||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
|
||||||
|
|
||||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
|
|
||||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
|
||||||
|
|
||||||
## Enforcement
|
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at baptiste@gelez.xyz. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
|
||||||
|
|
||||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
|
||||||
|
|
||||||
## Attribution
|
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
|
||||||
|
|
||||||
[homepage]: http://contributor-covenant.org
|
|
||||||
[version]: http://contributor-covenant.org/version/1/4/
|
|
||||||
|
|||||||
Generated
+283
-69
@@ -131,10 +131,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomicwrites"
|
name = "atomicwrites"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -144,7 +144,7 @@ name = "atty"
|
|||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -164,7 +164,7 @@ dependencies = [
|
|||||||
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"debug-builders 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"debug-builders 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ dependencies = [
|
|||||||
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
"backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ version = "0.1.28"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -457,7 +457,7 @@ version = "0.6.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -578,10 +578,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ctrlc"
|
name = "ctrlc"
|
||||||
version = "3.1.2"
|
version = "3.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -876,7 +876,7 @@ version = "0.2.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -887,7 +887,7 @@ version = "1.0.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -914,7 +914,7 @@ name = "fs2"
|
|||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -932,7 +932,7 @@ name = "fsevent-sys"
|
|||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1104,7 +1104,7 @@ name = "hostname"
|
|||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1188,7 +1188,7 @@ dependencies = [
|
|||||||
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1238,7 +1238,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1246,7 +1246,7 @@ name = "inotify-sys"
|
|||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1254,7 +1254,7 @@ name = "iovec"
|
|||||||
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"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1308,6 +1308,40 @@ name = "lazycell"
|
|||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lber"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"nom 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ldap3"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lber 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"nom 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-uds-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lettre"
|
name = "lettre"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@@ -1352,7 +1386,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.55"
|
version = "0.2.58"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1435,7 +1469,7 @@ name = "memmap"
|
|||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1515,7 +1549,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1528,7 +1562,7 @@ dependencies = [
|
|||||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1547,6 +1581,16 @@ dependencies = [
|
|||||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio-uds"
|
||||||
|
version = "0.6.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miow"
|
name = "miow"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@@ -1589,7 +1633,7 @@ version = "0.2.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl 0.10.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl 0.10.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1606,7 +1650,7 @@ version = "0.2.33"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1617,25 +1661,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.11.0"
|
version = "0.14.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nix"
|
|
||||||
version = "0.13.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1644,6 +1676,11 @@ name = "nodrop"
|
|||||||
version = "0.1.13"
|
version = "0.1.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "4.2.3"
|
version = "4.2.3"
|
||||||
@@ -1664,7 +1701,7 @@ dependencies = [
|
|||||||
"fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1706,7 +1743,7 @@ name = "num_cpus"
|
|||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1728,7 +1765,7 @@ dependencies = [
|
|||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl-sys 0.9.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl-sys 0.9.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1744,7 +1781,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -1789,7 +1826,7 @@ name = "parking_lot_core"
|
|||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1801,7 +1838,7 @@ name = "parking_lot_core"
|
|||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1881,8 +1918,9 @@ dependencies = [
|
|||||||
"askama_escape 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"askama_escape 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"atom_syndication 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atom_syndication 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ctrlc 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"diesel 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"diesel 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"dotenv 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dotenv 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gettext 0.3.0 (git+https://github.com/Plume-org/gettext/?rev=294c54d74c699fbc66502b480a37cc66c1daa7f3)",
|
"gettext 0.3.0 (git+https://github.com/Plume-org/gettext/?rev=294c54d74c699fbc66502b480a37cc66c1daa7f3)",
|
||||||
@@ -1955,6 +1993,7 @@ dependencies = [
|
|||||||
"serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"shrinkwraprs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"shrinkwraprs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1994,6 +2033,7 @@ dependencies = [
|
|||||||
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ldap3 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"migrations_internals 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"migrations_internals 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl 0.10.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl 0.10.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"plume-api 0.3.0",
|
"plume-api 0.3.0",
|
||||||
@@ -2143,7 +2183,7 @@ name = "rand"
|
|||||||
version = "0.3.23"
|
version = "0.3.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2153,7 +2193,7 @@ version = "0.4.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -2166,7 +2206,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -2177,7 +2217,7 @@ version = "0.6.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -2232,7 +2272,7 @@ name = "rand_jitter"
|
|||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -2244,7 +2284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -2363,7 +2403,7 @@ dependencies = [
|
|||||||
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -2384,7 +2424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2476,7 +2516,7 @@ version = "3.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2582,6 +2622,11 @@ dependencies = [
|
|||||||
"variance 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"variance 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scoped-tls"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@@ -2599,7 +2644,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2695,11 +2740,21 @@ name = "siphasher"
|
|||||||
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 = "slab"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "0.6.9"
|
version = "0.6.9"
|
||||||
@@ -2880,12 +2935,17 @@ 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 = "take"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tantivy"
|
name = "tantivy"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomicwrites 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atomicwrites 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bitpacking 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitpacking 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -2953,7 +3013,7 @@ version = "3.0.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -2975,7 +3035,7 @@ name = "termion"
|
|||||||
version = "1.5.2"
|
version = "1.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -3002,28 +3062,33 @@ name = "time"
|
|||||||
version = "0.1.42"
|
version = "0.1.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "0.1.20"
|
version = "0.1.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-trace-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3036,6 +3101,34 @@ dependencies = [
|
|||||||
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-codec"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-core"
|
||||||
|
version = "0.1.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-current-thread"
|
name = "tokio-current-thread"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
@@ -3054,6 +3147,16 @@ dependencies = [
|
|||||||
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-fs"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-io"
|
name = "tokio-io"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
@@ -3064,6 +3167,23 @@ dependencies = [
|
|||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-proto"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-reactor"
|
name = "tokio-reactor"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
@@ -3082,6 +3202,14 @@ dependencies = [
|
|||||||
"tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-service"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-sync"
|
name = "tokio-sync"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@@ -3131,14 +3259,83 @@ dependencies = [
|
|||||||
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-tls"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-trace-core"
|
name = "tokio-trace-core"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-udp"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-uds"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-uds"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-uds-proto"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.4.10"
|
version = "0.4.10"
|
||||||
@@ -3466,7 +3663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum ascii_utils 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a"
|
"checksum ascii_utils 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a"
|
||||||
"checksum askama_escape 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "719b48039ffac1564f67d70162109ba9341125cee0096a540e478355b3c724a7"
|
"checksum askama_escape 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "719b48039ffac1564f67d70162109ba9341125cee0096a540e478355b3c724a7"
|
||||||
"checksum atom_syndication 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a9a7ab83635ff7a3b04856f4ad95324dccc9b947ab1e790fc5c769ee6d6f60c"
|
"checksum atom_syndication 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a9a7ab83635ff7a3b04856f4ad95324dccc9b947ab1e790fc5c769ee6d6f60c"
|
||||||
"checksum atomicwrites 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a3420b33cdefd3feb223dddc23739fc05cc034eb0f2be792c763e3d89e1eb6e3"
|
"checksum atomicwrites 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4e1aa99513c90202b4b04cfbe3c9d51dd914f2e26215a4caa76574b00bb6393"
|
||||||
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
||||||
"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
|
"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
|
||||||
"checksum backtrace 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "150ae7828afa7afb6d474f909d64072d21de1f3365b6e8ad8029bf7b1c6350a0"
|
"checksum backtrace 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "150ae7828afa7afb6d474f909d64072d21de1f3365b6e8ad8029bf7b1c6350a0"
|
||||||
@@ -3518,7 +3715,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
|
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
|
||||||
"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
|
"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
|
||||||
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
|
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
|
||||||
"checksum ctrlc 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5531b7f0698d9220b4729f8811931dbe0e91a05be2f7b3245fdc50dd856bae26"
|
"checksum ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7dfd2d8b4c82121dfdff120f818e09fc4380b0b7e17a742081a89b94853e87f"
|
||||||
"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
|
"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
|
||||||
"checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97"
|
"checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97"
|
||||||
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
|
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
|
||||||
@@ -3603,10 +3800,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
||||||
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
||||||
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||||
|
"checksum lber 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa172a35dd26774593b503d085735a189e322d16a2049b2739eb7f914b141b36"
|
||||||
|
"checksum ldap3 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dae98945f9023ddb484ec9cd9faffddabf18174e1f08bab360848a36ab4f8a80"
|
||||||
"checksum lettre 0.9.0 (git+https://github.com/lettre/lettre?rev=c988b1760ad8179d9e7f3fb8594d2b86cf2a0a49)" = "<none>"
|
"checksum lettre 0.9.0 (git+https://github.com/lettre/lettre?rev=c988b1760ad8179d9e7f3fb8594d2b86cf2a0a49)" = "<none>"
|
||||||
"checksum lettre_email 0.9.0 (git+https://github.com/lettre/lettre?rev=c988b1760ad8179d9e7f3fb8594d2b86cf2a0a49)" = "<none>"
|
"checksum lettre_email 0.9.0 (git+https://github.com/lettre/lettre?rev=c988b1760ad8179d9e7f3fb8594d2b86cf2a0a49)" = "<none>"
|
||||||
"checksum levenshtein_automata 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73a004f877f468548d8d0ac4977456a249d8fabbdb8416c36db163dfc8f2e8ca"
|
"checksum levenshtein_automata 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73a004f877f468548d8d0ac4977456a249d8fabbdb8416c36db163dfc8f2e8ca"
|
||||||
"checksum libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "42914d39aad277d9e176efbdad68acb1d5443ab65afe0e0e4f0d49352a950880"
|
"checksum libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319"
|
||||||
"checksum libsqlite3-sys 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd6457c70bbff456d9fe49deaba35ec47c3e598bf8d7950ff0575ceb7a8a6ad1"
|
"checksum libsqlite3-sys 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd6457c70bbff456d9fe49deaba35ec47c3e598bf8d7950ff0575ceb7a8a6ad1"
|
||||||
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
|
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
|
||||||
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||||
@@ -3629,15 +3828,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fe927a42e3807ef71defb191dc87d4e24479b221e67015fe38ae2b7b447bab"
|
"checksum miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fe927a42e3807ef71defb191dc87d4e24479b221e67015fe38ae2b7b447bab"
|
||||||
"checksum mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "049ba5ca2b63e837adeee724aa9e36b408ed593529dcc802aa96ca14bd329bdf"
|
"checksum mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "049ba5ca2b63e837adeee724aa9e36b408ed593529dcc802aa96ca14bd329bdf"
|
||||||
"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
|
"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
|
||||||
|
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
|
||||||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||||
"checksum multipart 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "136eed74cadb9edd2651ffba732b19a450316b680e4f48d6c79e905799e19d01"
|
"checksum multipart 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "136eed74cadb9edd2651ffba732b19a450316b680e4f48d6c79e905799e19d01"
|
||||||
"checksum murmurhash32 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d736ff882f0e85fe9689fb23db229616c4c00aee2b3ac282f666d8f20eb25d4a"
|
"checksum murmurhash32 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d736ff882f0e85fe9689fb23db229616c4c00aee2b3ac282f666d8f20eb25d4a"
|
||||||
"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
|
"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
|
||||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||||
"checksum new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30"
|
"checksum new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30"
|
||||||
"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17"
|
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
||||||
"checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b"
|
|
||||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||||
|
"checksum nom 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf51a729ecf40266a2368ad335a5fdde43471f545a967109cd62146ecf8b66ff"
|
||||||
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
||||||
"checksum notify 4.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ceb1a496a81dd6125f68ce772b41b83efe89a54d21768ed6d0c33c95832604e6"
|
"checksum notify 4.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ceb1a496a81dd6125f68ce772b41b83efe89a54d21768ed6d0c33c95832604e6"
|
||||||
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
||||||
@@ -3725,6 +3925,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339"
|
"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339"
|
||||||
"checksum scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a2ff3fc5223829be817806c6441279c676e454cc7da608faf03b0ccc09d3889"
|
"checksum scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a2ff3fc5223829be817806c6441279c676e454cc7da608faf03b0ccc09d3889"
|
||||||
"checksum scoped-pool 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "817a3a15e704545ce59ed2b5c60a5d32bda4d7869befb8b36667b658a6c00b43"
|
"checksum scoped-pool 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "817a3a15e704545ce59ed2b5c60a5d32bda4d7869befb8b36667b658a6c00b43"
|
||||||
|
"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
|
||||||
"checksum scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59a076157c1e2dc561d8de585151ee6965d910dd4dcb5dabb7ae3e83981a6c57"
|
"checksum scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59a076157c1e2dc561d8de585151ee6965d910dd4dcb5dabb7ae3e83981a6c57"
|
||||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||||
"checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2"
|
"checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2"
|
||||||
@@ -3739,7 +3940,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
|
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
|
||||||
"checksum shrinkwraprs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7d5f047b90b2ca2d1526ff73d67cba61f86f4cf9a8afddc99dd96702ded8e684"
|
"checksum shrinkwraprs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7d5f047b90b2ca2d1526ff73d67cba61f86f4cf9a8afddc99dd96702ded8e684"
|
||||||
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
|
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
|
||||||
|
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
||||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||||
|
"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
|
||||||
"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
|
"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
|
||||||
"checksum snap 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "95d697d63d44ad8b78b8d235bf85b34022a78af292c8918527c5f0cffdde7f43"
|
"checksum snap 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "95d697d63d44ad8b78b8d235bf85b34022a78af292c8918527c5f0cffdde7f43"
|
||||||
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
||||||
@@ -3760,6 +3963,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe"
|
"checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe"
|
||||||
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
||||||
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
|
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
|
||||||
|
"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5"
|
||||||
"checksum tantivy 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "67a63475a55950ad47573f881d912b8fab7f1f53a9cc2e036185efc92b471402"
|
"checksum tantivy 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "67a63475a55950ad47573f881d912b8fab7f1f53a9cc2e036185efc92b471402"
|
||||||
"checksum tantivy-fst 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16b22af5ff09b8897093287642a5aaee6f30eb496526ef83a8dd0f4c636ac367"
|
"checksum tantivy-fst 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16b22af5ff09b8897093287642a5aaee6f30eb496526ef83a8dd0f4c636ac367"
|
||||||
"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"
|
||||||
@@ -3769,17 +3973,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||||
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||||
"checksum tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "94a1f9396aec29d31bb16c24d155cfa144d1af91c40740125db3131bdaf76da8"
|
"checksum tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "ec2ffcf4bcfc641413fa0f1427bf8f91dfc78f56a6559cbf50e04837ae442a87"
|
||||||
"checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46"
|
"checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46"
|
||||||
|
"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f"
|
||||||
|
"checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71"
|
||||||
"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443"
|
"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443"
|
||||||
"checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e"
|
"checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e"
|
||||||
|
"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af"
|
||||||
"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926"
|
"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926"
|
||||||
|
"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389"
|
||||||
"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce"
|
"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce"
|
||||||
|
"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162"
|
||||||
"checksum tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5b2f843ffdf8d6e1f90bddd48da43f99ab071660cd92b7ec560ef3cdfd7a409a"
|
"checksum tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5b2f843ffdf8d6e1f90bddd48da43f99ab071660cd92b7ec560ef3cdfd7a409a"
|
||||||
"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119"
|
"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119"
|
||||||
"checksum tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72558af20be886ea124595ea0f806dd5703b8958e4705429dd58b3d8231f72f2"
|
"checksum tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72558af20be886ea124595ea0f806dd5703b8958e4705429dd58b3d8231f72f2"
|
||||||
"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e"
|
"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e"
|
||||||
"checksum tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "350c9edade9830dc185ae48ba45667a445ab59f6167ef6d0254ec9d2430d9dd3"
|
"checksum tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c"
|
||||||
|
"checksum tokio-trace-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9c8a256d6956f7cb5e2bdfe8b1e8022f1a09206c6c2b1ba00f3b746b260c613"
|
||||||
|
"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92"
|
||||||
|
"checksum tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "65ae5d255ce739e8537221ed2942e0445f4b3b813daebac1c0050ddaaa3587f9"
|
||||||
|
"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445"
|
||||||
|
"checksum tokio-uds-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93842f83f760d2a48eb54225f819d05549e69c481f56be4a1b1f51decf99da5b"
|
||||||
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
|
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
|
||||||
"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 try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ repository = "https://github.com/Plume-org/Plume"
|
|||||||
activitypub = "0.1.3"
|
activitypub = "0.1.3"
|
||||||
askama_escape = "0.1"
|
askama_escape = "0.1"
|
||||||
atom_syndication = "0.6"
|
atom_syndication = "0.6"
|
||||||
|
clap = "2.33"
|
||||||
colored = "1.8"
|
colored = "1.8"
|
||||||
dotenv = "0.14"
|
dotenv = "0.14"
|
||||||
gettext = { git = "https://github.com/Plume-org/gettext/", rev = "294c54d74c699fbc66502b480a37cc66c1daa7f3" }
|
gettext = { git = "https://github.com/Plume-org/gettext/", rev = "294c54d74c699fbc66502b480a37cc66c1daa7f3" }
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
<!--
|
|
||||||
If your issue is not purely technical, it should be debated on Loomio first
|
|
||||||
|
|
||||||
https://framavox.org/g/WK40YHMA/plume
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Plume version (and/or commit):
|
|
||||||
@@ -3,27 +3,53 @@
|
|||||||
Plume
|
Plume
|
||||||
</h1>
|
</h1>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://travis-ci.org/Plume-org/Plume"><img src="https://travis-ci.org/Plume-org/Plume.svg?branch=master" alt="Build status"></a>
|
<a href="https://github.com/Plume-org/Plume/"><img alt="CircleCI" src="https://img.shields.io/circleci/build/gh/Plume-org/Plume.svg"></a>
|
||||||
<a href="hhttps://codecov.io/gh/Plume-org/Plume"><img src="https://codecov.io/gh/Plume-org/Plume/branch/master/graph/badge.svg" alt="Code coverage"></a>
|
<a href="https://codecov.io/gh/Plume-org/Plume"><img src="https://codecov.io/gh/Plume-org/Plume/branch/master/graph/badge.svg" alt="Code coverage"></a>
|
||||||
|
<a title="Crowdin" target="_blank" href="https://crowdin.com/project/plume"><img src="https://d322cqt584bo4o.cloudfront.net/plume/localized.svg"></a>
|
||||||
|
<a href="https://hub.docker.com/r/plumeorg/plume"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/plumeorg/plume.svg"></a>
|
||||||
|
<a href="https://liberapay.com/Plume"><img alt="Liberapay patrons" src="https://img.shields.io/liberapay/patrons/Plume.svg"></a>
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://joinplu.me/">Website</a>
|
<a href="https://joinplu.me/">Website</a>
|
||||||
—
|
—
|
||||||
<a href="https://docs.joinplu.me/">Documentation</a>
|
<a href="https://docs.joinplu.me/">Documentation</a>
|
||||||
—
|
—
|
||||||
<a href="https://contribute.joinplu.me/">Contribute</a>
|
<a href="https://docs.joinplu.me/contribute">Contribute</a>
|
||||||
—
|
—
|
||||||
<a href="https://joinplu.me/#instances">Instances list</a>
|
<a href="https://joinplu.me/#instances">Instances list</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Plume is a federated blogging engine, based on ActivityPub. It uses the Rocket framework, and Diesel to interact with the database.
|
Plume is a **federated blogging engine**, based on *ActivityPub*. It is written in *Rust*, with the *Rocket* framework, and *Diesel* to interact with the database.
|
||||||
|
The front-end uses *Ructe* templates, *WASM* and *SCSS*.
|
||||||
|
|
||||||
It is not yet ready for production use, but we have all the basic features (account management, blogs, articles, comments, etc) and a basic federation.
|
## Features
|
||||||
|
|
||||||
Feel free to join our Matrix room: `#plume:disroot.org` to discuss about the project!
|
A lot of features are still missing, but what is already here should be quite stable. Current and planned features include:
|
||||||
|
|
||||||
We also have a [Loomio group](https://framavox.org/g/WK40YHMA/plume) to debate and vote and features. Feel free to join it to take part in Plume's decision process.
|
- **A blog-centric approach**: you can create as much blogs as you want with your account, to keep your different publications separated.
|
||||||
|
- **Media management**: you can upload pictures to illustrate your articles, but also audio files if you host a podcast, and manage them all from Plume.
|
||||||
|
- **Federation**: Plume is part of a network of interconnected websites called the Fediverse. Each of these websites (often called *instances*) have their own
|
||||||
|
rules and thematics, but they can all communicate with each other.
|
||||||
|
- **Collaborative writing**: invite other people to your blogs, and write articles together.
|
||||||
|
|
||||||
For more informations on the different ways to contribute, check out our [contribution page](https://contribute.joinplu.me). We are welcoming any kind of contribution, and you can probably find a way to help.
|
## Get involved
|
||||||
|
|
||||||
As we want the various spaces related to the project (GitHub, Matrix, Loomio, etc) to be as safe as possible for everyone, we adopted [a code of conduct](https://github.com/Plume-org/Plume/blob/master/CODE_OF_CONDUCT.md). Please read it and make sure you accept it before contributing.
|
If you want to have regular news about the project, the best place is probably [our blog](https://fediverse.blog/~/PlumeDev), or our Matrix room: [`#plume:disroot.org`](https://riot.im/app/#/room/#plume:disroot.org).
|
||||||
|
|
||||||
|
If you want to contribute more, a good first step is to read [our contribution guides](https://docs.joinplu.me/contribute). We accept all kind of contribution:
|
||||||
|
|
||||||
|
- [Back-end or front-end development](https://docs.joinplu.me/contribute/development/)
|
||||||
|
- [Translations](https://docs.joinplu.me/contribute/translations/)
|
||||||
|
- [Documentation](https://docs.joinplu.me/contribute/documentation/)
|
||||||
|
- UI and/or UX design (we don't have a dedicated guide yet, but [we can talk](https://docs.joinplu.me/contribute/discussion/) to see how we can work together!)
|
||||||
|
- [Taking part in discussions](https://docs.joinplu.me/contribute/discussion/)
|
||||||
|
- [Financial support](https://docs.joinplu.me/contribute/donations/)
|
||||||
|
|
||||||
|
But this list is not exhaustive and if you want to contribute differently you are welcome too!
|
||||||
|
|
||||||
|
As we want the various spaces related to the project (GitHub, Matrix, Loomio, etc) to be as safe as possible for everyone, we adopted [a code of conduct](https://docs.joinplu.me/organization/code-of-conduct). Please read it and make sure you accept it before contributing.
|
||||||
|
|
||||||
|
## Starting your own instance
|
||||||
|
|
||||||
|
We provide various way to install Plume: from source, with pre-built binaries, with Docker or with YunoHost.
|
||||||
|
For detailed explanations, please refer to [the documentation](https://docs.joinplu.me/installation/).
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
DROP TABLE password_reset_requests;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
CREATE TABLE password_reset_requests (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
email VARCHAR NOT NULL,
|
||||||
|
token VARCHAR NOT NULL,
|
||||||
|
expiration_date TIMESTAMP NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX password_reset_requests_token ON password_reset_requests (token);
|
||||||
|
CREATE UNIQUE INDEX password_reset_requests_email ON password_reset_requests (email);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
DROP TABLE password_reset_requests;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
CREATE TABLE password_reset_requests (
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
email VARCHAR NOT NULL,
|
||||||
|
token VARCHAR NOT NULL,
|
||||||
|
expiration_date DATETIME NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX password_reset_requests_token ON password_reset_requests (token);
|
||||||
|
CREATE UNIQUE INDEX password_reset_requests_email ON password_reset_requests (email);
|
||||||
@@ -25,7 +25,11 @@ fn main() {
|
|||||||
.subcommand(users::command());
|
.subcommand(users::command());
|
||||||
let matches = app.clone().get_matches();
|
let matches = app.clone().get_matches();
|
||||||
|
|
||||||
dotenv::dotenv().ok();
|
match dotenv::dotenv() {
|
||||||
|
Ok(path) => println!("Configuration read from {}", path.display()),
|
||||||
|
Err(ref e) if e.not_found() => eprintln!("no .env was found"),
|
||||||
|
e => e.map(|_| ()).unwrap(),
|
||||||
|
}
|
||||||
let conn = Conn::establish(CONFIG.database_url.as_str());
|
let conn = Conn::establish(CONFIG.database_url.as_str());
|
||||||
let _ = conn.as_ref().map(|conn| Instance::cache_local(conn));
|
let _ = conn.as_ref().map(|conn| Instance::cache_local(conn));
|
||||||
|
|
||||||
|
|||||||
+2
-10
@@ -109,16 +109,8 @@ fn new<'a>(args: &ArgMatches<'a>, conn: &Connection) {
|
|||||||
rpassword::read_password().expect("Couldn't read your password.")
|
rpassword::read_password().expect("Couldn't read your password.")
|
||||||
});
|
});
|
||||||
|
|
||||||
NewUser::new_local(
|
NewUser::new_local(conn, username, display_name, admin, &bio, email, &password)
|
||||||
conn,
|
.expect("Couldn't save new user");
|
||||||
username,
|
|
||||||
display_name,
|
|
||||||
admin,
|
|
||||||
&bio,
|
|
||||||
email,
|
|
||||||
User::hash_pass(&password).expect("Couldn't hash password"),
|
|
||||||
)
|
|
||||||
.expect("Couldn't save new user");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_password<'a>(args: &ArgMatches<'a>, conn: &Connection) {
|
fn reset_password<'a>(args: &ArgMatches<'a>, conn: &Connection) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ serde = "1.0"
|
|||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
shrinkwraprs = "0.2.1"
|
shrinkwraprs = "0.2.1"
|
||||||
|
tokio = "0.1.21"
|
||||||
|
|
||||||
[dependencies.chrono]
|
[dependencies.chrono]
|
||||||
features = ["serde"]
|
features = ["serde"]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use activitypub::{Activity, Link, Object};
|
use activitypub::{Activity, Link, Object};
|
||||||
use array_tool::vec::Uniq;
|
use array_tool::vec::Uniq;
|
||||||
use reqwest::ClientBuilder;
|
use reqwest::r#async::ClientBuilder;
|
||||||
use rocket::{
|
use rocket::{
|
||||||
http::Status,
|
http::Status,
|
||||||
request::{FromRequest, Request},
|
request::{FromRequest, Request},
|
||||||
@@ -8,6 +8,7 @@ use rocket::{
|
|||||||
Outcome,
|
Outcome,
|
||||||
};
|
};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
use tokio::prelude::*;
|
||||||
|
|
||||||
use self::sign::Signable;
|
use self::sign::Signable;
|
||||||
|
|
||||||
@@ -129,38 +130,36 @@ where
|
|||||||
.sign(sender)
|
.sign(sender)
|
||||||
.expect("activity_pub::broadcast: signature error");
|
.expect("activity_pub::broadcast: signature error");
|
||||||
|
|
||||||
|
let mut rt = tokio::runtime::current_thread::Runtime::new()
|
||||||
|
.expect("Error while initializing tokio runtime for federation");
|
||||||
|
let client = ClientBuilder::new()
|
||||||
|
.connect_timeout(std::time::Duration::from_secs(5))
|
||||||
|
.build()
|
||||||
|
.expect("Can't build client");
|
||||||
for inbox in boxes {
|
for inbox in boxes {
|
||||||
// TODO: run it in Sidekiq or something like that
|
|
||||||
let body = signed.to_string();
|
let body = signed.to_string();
|
||||||
let mut headers = request::headers();
|
let mut headers = request::headers();
|
||||||
headers.insert("Digest", request::Digest::digest(&body));
|
headers.insert("Digest", request::Digest::digest(&body));
|
||||||
let res = ClientBuilder::new()
|
rt.spawn(
|
||||||
.connect_timeout(Some(std::time::Duration::from_secs(5)))
|
client
|
||||||
.build()
|
.post(&inbox)
|
||||||
.and_then(|client| {
|
.headers(headers.clone())
|
||||||
client
|
.header(
|
||||||
.post(&inbox)
|
"Signature",
|
||||||
.headers(headers.clone())
|
request::signature(sender, &headers)
|
||||||
.header(
|
.expect("activity_pub::broadcast: request signature error"),
|
||||||
"Signature",
|
)
|
||||||
request::signature(sender, &headers)
|
.body(body)
|
||||||
.expect("activity_pub::broadcast: request signature error"),
|
.send()
|
||||||
)
|
.and_then(|r| r.into_body().concat2())
|
||||||
.body(body)
|
.map(move |response| {
|
||||||
.send()
|
println!("Successfully sent activity to inbox ({})", inbox);
|
||||||
});
|
println!("Response: \"{:?}\"\n", response)
|
||||||
match res {
|
})
|
||||||
Ok(mut r) => {
|
.map_err(|e| println!("Error while sending to inbox ({:?})", e)),
|
||||||
println!("Successfully sent activity to inbox ({})", inbox);
|
);
|
||||||
if let Ok(response) = r.text() {
|
|
||||||
println!("Response: \"{:?}\"\n\n", response)
|
|
||||||
} else {
|
|
||||||
println!("Error while reading response")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => println!("Error while sending to inbox ({:?})", e),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
rt.run().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Shrinkwrap, Clone, Serialize, Deserialize)]
|
#[derive(Shrinkwrap, Clone, Serialize, Deserialize)]
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ extern crate shrinkwraprs;
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
extern crate tokio;
|
||||||
|
|
||||||
pub mod activity_pub;
|
pub mod activity_pub;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ guid-create = "0.1"
|
|||||||
heck = "0.3.0"
|
heck = "0.3.0"
|
||||||
itertools = "0.8.0"
|
itertools = "0.8.0"
|
||||||
lazy_static = "*"
|
lazy_static = "*"
|
||||||
|
ldap3 = "0.6.1"
|
||||||
migrations_internals= "1.4.0"
|
migrations_internals= "1.4.0"
|
||||||
openssl = "0.10.22"
|
openssl = "0.10.22"
|
||||||
rocket = "0.4.0"
|
rocket = "0.4.0"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ pub struct Config {
|
|||||||
pub search_index: String,
|
pub search_index: String,
|
||||||
pub rocket: Result<RocketConfig, RocketError>,
|
pub rocket: Result<RocketConfig, RocketError>,
|
||||||
pub logo: LogoConfig,
|
pub logo: LogoConfig,
|
||||||
|
pub ldap: LdapConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -184,6 +185,27 @@ impl Default for LogoConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct LdapConfig {
|
||||||
|
pub url: Option<String>,
|
||||||
|
pub bind_dn: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LdapConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
let url = var("LDAP_URL").ok();
|
||||||
|
let bind_dn = var("LDAP_BIND_DN").ok();
|
||||||
|
if url.is_some() ^ bind_dn.is_some() {
|
||||||
|
panic!(
|
||||||
|
r#"Invalid configuration :
|
||||||
|
You must provide both LDAP_URL and LDAP_BIND_DN, or neither"#
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
LdapConfig { url, bind_dn }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref CONFIG: Config = Config {
|
pub static ref CONFIG: Config = Config {
|
||||||
base_url: var("BASE_URL").unwrap_or_else(|_| format!(
|
base_url: var("BASE_URL").unwrap_or_else(|_| format!(
|
||||||
@@ -199,5 +221,6 @@ lazy_static! {
|
|||||||
search_index: var("SEARCH_INDEX").unwrap_or_else(|_| "search_index".to_owned()),
|
search_index: var("SEARCH_INDEX").unwrap_or_else(|_| "search_index".to_owned()),
|
||||||
rocket: get_rocket_config(),
|
rocket: get_rocket_config(),
|
||||||
logo: LogoConfig::default(),
|
logo: LogoConfig::default(),
|
||||||
|
ldap: LdapConfig::default(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
use crate::CONFIG;
|
||||||
|
use ldap3::LdapConn;
|
||||||
|
use std::io;
|
||||||
|
use std::sync::{mpsc, Mutex};
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
|
type Message = (String, String, mpsc::Sender<io::Result<bool>>);
|
||||||
|
pub struct Ldap {
|
||||||
|
channel: mpsc::Sender<Message>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ldap {
|
||||||
|
pub fn get_shared() -> Self {
|
||||||
|
Ldap {
|
||||||
|
channel: CHANNEL.lock().unwrap().clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn connect(&self, username: String, password: String) -> LdapResult {
|
||||||
|
let (s, r) = mpsc::channel();
|
||||||
|
self.channel.send((username, password, s)).unwrap(); //we know the remote end was not closed
|
||||||
|
LdapResult { channel: r }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LdapResult {
|
||||||
|
channel: mpsc::Receiver<io::Result<bool>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LdapResult {
|
||||||
|
pub fn get(self) -> io::Result<bool> {
|
||||||
|
self.channel.recv().unwrap() //we know some message must have been send, be it an error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function loop indefinitelly, handling requests
|
||||||
|
fn handle(url: &str, bind_dn: &str, channel: mpsc::Receiver<Message>) {
|
||||||
|
let mut conn = LdapConn::new(url).expect("Error connecting to ldap server");
|
||||||
|
for (user, password, channel) in channel.iter() {
|
||||||
|
let res = conn
|
||||||
|
.simple_bind(&format!("uid={},{}", user, bind_dn), &password)
|
||||||
|
.map(|r| r.rc == 0);
|
||||||
|
let err = res.is_err();
|
||||||
|
channel.send(res).ok(); //we can't assume the other end did not drop it's handle
|
||||||
|
let err = conn.unbind().is_err() || err;
|
||||||
|
if err {
|
||||||
|
if let Ok(c) = LdapConn::new(url) {
|
||||||
|
conn = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ignore(channel: mpsc::Receiver<Message>) {
|
||||||
|
for (_user, _password, channel) in channel.iter() {
|
||||||
|
channel.send(Ok(false)).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref CHANNEL: Mutex<mpsc::Sender<Message>> = {
|
||||||
|
let (s, r) = mpsc::channel();
|
||||||
|
|
||||||
|
let builder = thread::Builder::new().name("ldap_handler".into());
|
||||||
|
builder
|
||||||
|
.spawn(move || {
|
||||||
|
if CONFIG.ldap.url.is_some() && CONFIG.ldap.bind_dn.is_some() {
|
||||||
|
handle(
|
||||||
|
CONFIG.ldap.url.as_ref().unwrap(),
|
||||||
|
CONFIG.ldap.bind_dn.as_ref().unwrap(),
|
||||||
|
r,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ignore(r);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
Mutex::new(s)
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ extern crate heck;
|
|||||||
extern crate itertools;
|
extern crate itertools;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
extern crate ldap3;
|
||||||
extern crate migrations_internals;
|
extern crate migrations_internals;
|
||||||
extern crate openssl;
|
extern crate openssl;
|
||||||
extern crate plume_api;
|
extern crate plume_api;
|
||||||
@@ -65,6 +66,7 @@ pub enum Error {
|
|||||||
Unauthorized,
|
Unauthorized,
|
||||||
Url,
|
Url,
|
||||||
Webfinger,
|
Webfinger,
|
||||||
|
Expired,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<bcrypt::BcryptError> for Error {
|
impl From<bcrypt::BcryptError> for Error {
|
||||||
@@ -362,11 +364,13 @@ pub mod follows;
|
|||||||
pub mod headers;
|
pub mod headers;
|
||||||
pub mod inbox;
|
pub mod inbox;
|
||||||
pub mod instance;
|
pub mod instance;
|
||||||
|
pub mod ldap;
|
||||||
pub mod likes;
|
pub mod likes;
|
||||||
pub mod medias;
|
pub mod medias;
|
||||||
pub mod mentions;
|
pub mod mentions;
|
||||||
pub mod migrations;
|
pub mod migrations;
|
||||||
pub mod notifications;
|
pub mod notifications;
|
||||||
|
pub mod password_reset_requests;
|
||||||
pub mod plume_rocket;
|
pub mod plume_rocket;
|
||||||
pub mod post_authors;
|
pub mod post_authors;
|
||||||
pub mod posts;
|
pub mod posts;
|
||||||
|
|||||||
@@ -0,0 +1,164 @@
|
|||||||
|
use chrono::{offset::Utc, Duration, NaiveDateTime};
|
||||||
|
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||||
|
use schema::password_reset_requests;
|
||||||
|
use {Connection, Error, Result};
|
||||||
|
|
||||||
|
#[derive(Clone, Identifiable, Queryable)]
|
||||||
|
pub struct PasswordResetRequest {
|
||||||
|
pub id: i32,
|
||||||
|
pub email: String,
|
||||||
|
pub token: String,
|
||||||
|
pub expiration_date: NaiveDateTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable)]
|
||||||
|
#[table_name = "password_reset_requests"]
|
||||||
|
pub struct NewPasswordResetRequest {
|
||||||
|
pub email: String,
|
||||||
|
pub token: String,
|
||||||
|
pub expiration_date: NaiveDateTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
const TOKEN_VALIDITY_HOURS: i64 = 2;
|
||||||
|
|
||||||
|
impl PasswordResetRequest {
|
||||||
|
pub fn insert(conn: &Connection, email: &str) -> Result<String> {
|
||||||
|
// first, delete other password reset tokens associated with this email:
|
||||||
|
let existing_requests =
|
||||||
|
password_reset_requests::table.filter(password_reset_requests::email.eq(email));
|
||||||
|
diesel::delete(existing_requests).execute(conn)?;
|
||||||
|
|
||||||
|
// now, generate a random token, set the expiry date,
|
||||||
|
// and insert it into the DB:
|
||||||
|
let token = plume_common::utils::random_hex();
|
||||||
|
let expiration_date = Utc::now()
|
||||||
|
.naive_utc()
|
||||||
|
.checked_add_signed(Duration::hours(TOKEN_VALIDITY_HOURS))
|
||||||
|
.expect("could not calculate expiration date");
|
||||||
|
let new_request = NewPasswordResetRequest {
|
||||||
|
email: email.to_owned(),
|
||||||
|
token: token.clone(),
|
||||||
|
expiration_date,
|
||||||
|
};
|
||||||
|
diesel::insert_into(password_reset_requests::table)
|
||||||
|
.values(new_request)
|
||||||
|
.execute(conn)
|
||||||
|
.map_err(Error::from)?;
|
||||||
|
|
||||||
|
Ok(token)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_by_token(conn: &Connection, token: &str) -> Result<Self> {
|
||||||
|
let token = password_reset_requests::table
|
||||||
|
.filter(password_reset_requests::token.eq(token))
|
||||||
|
.first::<Self>(conn)
|
||||||
|
.map_err(Error::from)?;
|
||||||
|
|
||||||
|
if token.expiration_date < Utc::now().naive_utc() {
|
||||||
|
return Err(Error::Expired);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(token)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_and_delete_by_token(conn: &Connection, token: &str) -> Result<Self> {
|
||||||
|
let request = Self::find_by_token(&conn, &token)?;
|
||||||
|
|
||||||
|
let filter =
|
||||||
|
password_reset_requests::table.filter(password_reset_requests::id.eq(request.id));
|
||||||
|
diesel::delete(filter).execute(conn)?;
|
||||||
|
|
||||||
|
Ok(request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use diesel::Connection;
|
||||||
|
use tests::db;
|
||||||
|
use users::tests as user_tests;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_insert_and_find_password_reset_request() {
|
||||||
|
let conn = db();
|
||||||
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
|
user_tests::fill_database(&conn);
|
||||||
|
let admin_email = "admin@example.com";
|
||||||
|
|
||||||
|
let token = PasswordResetRequest::insert(&conn, admin_email)
|
||||||
|
.expect("couldn't insert new request");
|
||||||
|
let request = PasswordResetRequest::find_by_token(&conn, &token)
|
||||||
|
.expect("couldn't retrieve request");
|
||||||
|
|
||||||
|
assert!(&token.len() > &32);
|
||||||
|
assert_eq!(&request.email, &admin_email);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_insert_delete_previous_password_reset_request() {
|
||||||
|
let conn = db();
|
||||||
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
|
user_tests::fill_database(&conn);
|
||||||
|
let admin_email = "admin@example.com";
|
||||||
|
|
||||||
|
PasswordResetRequest::insert(&conn, &admin_email).expect("couldn't insert new request");
|
||||||
|
PasswordResetRequest::insert(&conn, &admin_email)
|
||||||
|
.expect("couldn't insert second request");
|
||||||
|
|
||||||
|
let count = password_reset_requests::table.count().get_result(&*conn);
|
||||||
|
assert_eq!(Ok(1), count);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_find_password_reset_request_by_token_time() {
|
||||||
|
let conn = db();
|
||||||
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
|
user_tests::fill_database(&conn);
|
||||||
|
let admin_email = "admin@example.com";
|
||||||
|
let token = "abcdef";
|
||||||
|
let now = Utc::now().naive_utc();
|
||||||
|
|
||||||
|
diesel::insert_into(password_reset_requests::table)
|
||||||
|
.values((
|
||||||
|
password_reset_requests::email.eq(&admin_email),
|
||||||
|
password_reset_requests::token.eq(&token),
|
||||||
|
password_reset_requests::expiration_date.eq(now),
|
||||||
|
))
|
||||||
|
.execute(&*conn)
|
||||||
|
.expect("could not insert request");
|
||||||
|
|
||||||
|
match PasswordResetRequest::find_by_token(&conn, &token) {
|
||||||
|
Err(Error::Expired) => (),
|
||||||
|
_ => panic!("Received unexpected result finding expired token"),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_find_and_delete_password_reset_request() {
|
||||||
|
let conn = db();
|
||||||
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
|
user_tests::fill_database(&conn);
|
||||||
|
let admin_email = "admin@example.com";
|
||||||
|
|
||||||
|
let token = PasswordResetRequest::insert(&conn, &admin_email)
|
||||||
|
.expect("couldn't insert new request");
|
||||||
|
PasswordResetRequest::find_and_delete_by_token(&conn, &token)
|
||||||
|
.expect("couldn't find and delete request");
|
||||||
|
|
||||||
|
let count = password_reset_requests::table.count().get_result(&*conn);
|
||||||
|
assert_eq!(Ok(0), count);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -141,6 +141,15 @@ table! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
password_reset_requests (id) {
|
||||||
|
id -> Int4,
|
||||||
|
email -> Varchar,
|
||||||
|
token -> Varchar,
|
||||||
|
expiration_date -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
table! {
|
table! {
|
||||||
post_authors (id) {
|
post_authors (id) {
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
@@ -247,6 +256,7 @@ allow_tables_to_appear_in_same_query!(
|
|||||||
medias,
|
medias,
|
||||||
mentions,
|
mentions,
|
||||||
notifications,
|
notifications,
|
||||||
|
password_reset_requests,
|
||||||
post_authors,
|
post_authors,
|
||||||
posts,
|
posts,
|
||||||
reshares,
|
reshares,
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ use blogs::Blog;
|
|||||||
use db_conn::DbConn;
|
use db_conn::DbConn;
|
||||||
use follows::Follow;
|
use follows::Follow;
|
||||||
use instance::*;
|
use instance::*;
|
||||||
|
use ldap::Ldap;
|
||||||
use medias::Media;
|
use medias::Media;
|
||||||
use post_authors::PostAuthor;
|
use post_authors::PostAuthor;
|
||||||
use posts::Post;
|
use posts::Post;
|
||||||
@@ -333,17 +334,41 @@ impl User {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash_pass(pass: &str) -> Result<String> {
|
fn hash_pass(pass: &str) -> Result<String> {
|
||||||
bcrypt::hash(pass, 10).map_err(Error::from)
|
bcrypt::hash(pass, 10).map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn auth(&self, pass: &str) -> bool {
|
fn auth(&self, pass: &str) -> bool {
|
||||||
self.hashed_password
|
self.hashed_password
|
||||||
.clone()
|
.clone()
|
||||||
.map(|hashed| bcrypt::verify(pass, hashed.as_ref()).unwrap_or(false))
|
.map(|hashed| bcrypt::verify(pass, hashed.as_ref()).unwrap_or(false))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn connect(rocket: &PlumeRocket, name: &str, password: &str) -> Result<Self> {
|
||||||
|
let user = User::find_by_email(&*rocket.conn, &name)
|
||||||
|
.or_else(|_| User::find_by_fqn(&rocket, &name));
|
||||||
|
match user {
|
||||||
|
Ok(user) => {
|
||||||
|
let ldap_conn = Ldap::get_shared().connect(name.to_owned(), password.to_owned());
|
||||||
|
let local_conn = user.auth(password);
|
||||||
|
let ldap_conn = ldap_conn.get().unwrap_or(false);
|
||||||
|
if ldap_conn && local_conn {
|
||||||
|
user.clear_password(&rocket.conn).ok();
|
||||||
|
}
|
||||||
|
if ldap_conn || local_conn {
|
||||||
|
Ok(user)
|
||||||
|
} else {
|
||||||
|
Err(Error::NotFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
User::get(&rocket.conn, 1)?.auth(password);
|
||||||
|
Err(Error::NotFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reset_password(&self, conn: &Connection, pass: &str) -> Result<()> {
|
pub fn reset_password(&self, conn: &Connection, pass: &str) -> Result<()> {
|
||||||
diesel::update(self)
|
diesel::update(self)
|
||||||
.set(users::hashed_password.eq(User::hash_pass(pass)?))
|
.set(users::hashed_password.eq(User::hash_pass(pass)?))
|
||||||
@@ -351,6 +376,13 @@ impl User {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clear_password(&self, conn: &Connection) -> Result<()> {
|
||||||
|
diesel::update(self)
|
||||||
|
.set(users::hashed_password.eq::<Option<String>>(None))
|
||||||
|
.execute(conn)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_local_page(conn: &Connection, (min, max): (i32, i32)) -> Result<Vec<User>> {
|
pub fn get_local_page(conn: &Connection, (min, max): (i32, i32)) -> Result<Vec<User>> {
|
||||||
users::table
|
users::table
|
||||||
.filter(users::instance_id.eq(Instance::get_local()?.id))
|
.filter(users::instance_id.eq(Instance::get_local()?.id))
|
||||||
@@ -923,7 +955,7 @@ impl NewUser {
|
|||||||
is_admin: bool,
|
is_admin: bool,
|
||||||
summary: &str,
|
summary: &str,
|
||||||
email: String,
|
email: String,
|
||||||
password: String,
|
password: &str,
|
||||||
) -> Result<User> {
|
) -> Result<User> {
|
||||||
let (pub_key, priv_key) = gen_keypair();
|
let (pub_key, priv_key) = gen_keypair();
|
||||||
User::insert(
|
User::insert(
|
||||||
@@ -935,7 +967,7 @@ impl NewUser {
|
|||||||
summary: summary.to_owned(),
|
summary: summary.to_owned(),
|
||||||
summary_html: SafeString::new(&utils::md_to_html(&summary, None, false, None).0),
|
summary_html: SafeString::new(&utils::md_to_html(&summary, None, false, None).0),
|
||||||
email: Some(email),
|
email: Some(email),
|
||||||
hashed_password: Some(password),
|
hashed_password: Some(User::hash_pass(password)?),
|
||||||
instance_id: Instance::get_local()?.id,
|
instance_id: Instance::get_local()?.id,
|
||||||
ap_url: String::new(),
|
ap_url: String::new(),
|
||||||
public_key: String::from_utf8(pub_key).or(Err(Error::Signature))?,
|
public_key: String::from_utf8(pub_key).or(Err(Error::Signature))?,
|
||||||
@@ -964,7 +996,7 @@ pub(crate) mod tests {
|
|||||||
true,
|
true,
|
||||||
"Hello there, I'm the admin",
|
"Hello there, I'm the admin",
|
||||||
"admin@example.com".to_owned(),
|
"admin@example.com".to_owned(),
|
||||||
"invalid_admin_password".to_owned(),
|
"invalid_admin_password",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let user = NewUser::new_local(
|
let user = NewUser::new_local(
|
||||||
@@ -974,7 +1006,7 @@ pub(crate) mod tests {
|
|||||||
false,
|
false,
|
||||||
"Hello there, I'm no one",
|
"Hello there, I'm no one",
|
||||||
"user@example.com".to_owned(),
|
"user@example.com".to_owned(),
|
||||||
"invalid_user_password".to_owned(),
|
"invalid_user_password",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let other = NewUser::new_local(
|
let other = NewUser::new_local(
|
||||||
@@ -984,7 +1016,7 @@ pub(crate) mod tests {
|
|||||||
false,
|
false,
|
||||||
"Hello there, I'm someone else",
|
"Hello there, I'm someone else",
|
||||||
"other@example.com".to_owned(),
|
"other@example.com".to_owned(),
|
||||||
"invalid_other_password".to_owned(),
|
"invalid_other_password",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
vec![admin, user, other]
|
vec![admin, user, other]
|
||||||
@@ -1003,7 +1035,7 @@ pub(crate) mod tests {
|
|||||||
false,
|
false,
|
||||||
"Hello I'm a test",
|
"Hello I'm a test",
|
||||||
"test@example.com".to_owned(),
|
"test@example.com".to_owned(),
|
||||||
User::hash_pass("test_password").unwrap(),
|
"test_password",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -1109,7 +1141,7 @@ pub(crate) mod tests {
|
|||||||
false,
|
false,
|
||||||
"Hello I'm a test",
|
"Hello I'm a test",
|
||||||
"test@example.com".to_owned(),
|
"test@example.com".to_owned(),
|
||||||
User::hash_pass("test_password").unwrap(),
|
"test_password",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
+468
-498
File diff suppressed because it is too large
Load Diff
+434
-461
File diff suppressed because it is too large
Load Diff
+446
-476
File diff suppressed because it is too large
Load Diff
+468
-498
File diff suppressed because it is too large
Load Diff
+472
-502
File diff suppressed because it is too large
Load Diff
+411
-438
File diff suppressed because it is too large
Load Diff
+416
-443
File diff suppressed because it is too large
Load Diff
+466
-496
File diff suppressed because it is too large
Load Diff
+486
-516
File diff suppressed because it is too large
Load Diff
+471
-501
File diff suppressed because it is too large
Load Diff
+447
-474
File diff suppressed because it is too large
Load Diff
+436
-463
File diff suppressed because it is too large
Load Diff
+465
-495
File diff suppressed because it is too large
Load Diff
+475
-505
File diff suppressed because it is too large
Load Diff
+488
-518
File diff suppressed because it is too large
Load Diff
+467
-497
File diff suppressed because it is too large
Load Diff
+397
-417
@@ -73,11 +73,11 @@ msgid "Your blog information have been updated."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/comments.rs:97
|
# src/routes/comments.rs:97
|
||||||
msgid "Your comment has been posted."
|
msgid "Your comment have been posted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/comments.rs:172
|
# src/routes/comments.rs:172
|
||||||
msgid "Your comment has been deleted."
|
msgid "Your comment have been deleted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/instance.rs:134
|
# src/routes/instance.rs:134
|
||||||
@@ -109,7 +109,7 @@ msgid "You are not allowed to delete this media."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/medias.rs:163
|
# src/routes/medias.rs:163
|
||||||
msgid "Your avatar has been updated."
|
msgid "Your avatar have been updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/medias.rs:168
|
# src/routes/medias.rs:168
|
||||||
@@ -145,15 +145,11 @@ msgid "You are not allowed to publish on this blog."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:350
|
# src/routes/posts.rs:350
|
||||||
msgid "Your article has been updated."
|
msgid "Your article have been updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:532
|
# src/routes/posts.rs:532
|
||||||
msgid "Your article has been saved."
|
msgid "Your post have been saved."
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/routes/posts.rs:538
|
|
||||||
msgid "New article"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:572
|
# src/routes/posts.rs:572
|
||||||
@@ -161,7 +157,7 @@ msgid "You are not allowed to delete this article."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:597
|
# src/routes/posts.rs:597
|
||||||
msgid "Your article has been deleted."
|
msgid "Your article have been deleted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:602
|
# src/routes/posts.rs:602
|
||||||
@@ -212,152 +208,328 @@ msgstr ""
|
|||||||
msgid "You are now following {}."
|
msgid "You are now following {}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:254
|
# src/routes/user.rs:255
|
||||||
msgid "To subscribe to someone, you need to be logged in"
|
msgid "To subscribe to someone, you need to be logged in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:356
|
# src/routes/user.rs:357
|
||||||
msgid "To edit your profile, you need to be logged in"
|
msgid "To edit your profile, you need to be logged in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:398
|
# src/routes/user.rs:399
|
||||||
msgid "Your profile has been updated."
|
msgid "Your profile have been updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:425
|
# src/routes/user.rs:426
|
||||||
msgid "Your account has been deleted."
|
msgid "Your account have been deleted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:431
|
# src/routes/user.rs:432
|
||||||
msgid "You can't delete someone else's account."
|
msgid "You can't delete someone else's account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:503
|
# src/routes/user.rs:504
|
||||||
msgid "Registrations are closed on this instance."
|
msgid "Registrations are closed on this instance."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:527
|
# src/routes/user.rs:528
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid "Your account have been created. You just need to login before you can use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Internal server error"
|
msgid "Plume"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something broke on our side."
|
msgid "Menu"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Sorry about that. If you think this is a bug, please report it."
|
msgid "Search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "Dashboard"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Page not found"
|
msgid "Notifications"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We couldn't find this page."
|
msgid "Log Out"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The link that led you here may be broken."
|
msgid "My account"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The content you sent can't be processed."
|
msgid "Log In"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Maybe it was too long."
|
msgid "Register"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Invalid CSRF token"
|
msgid "About this instance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid "Source code"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles tagged \"{0}\""
|
msgid "Matrix room"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "There are currently no articles with such a tag"
|
msgid "Administration"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "Welcome to {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Create a blog"
|
msgid "Latest articles"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Your feed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Federated feed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Local feed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Administration of {0}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Instances"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Configuration"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Users"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Unblock"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Block"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Ban"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "All the articles of the Fediverse"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Articles from {}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to see here yet. Try subscribing to more people."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
# src/template_utils.rs:251
|
||||||
msgid "Title"
|
msgid "Name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/template_utils.rs:254
|
# src/template_utils.rs:254
|
||||||
msgid "Optional"
|
msgid "Optional"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Create blog"
|
msgid "Allow anyone to register here"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit \"{}\""
|
msgid "Short description"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Description"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Markdown syntax is supported"
|
msgid "Markdown syntax is supported"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid "Long description"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
# src/template_utils.rs:251
|
||||||
|
msgid "Default article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blog icon"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blog banner"
|
msgid "About {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Update blog"
|
msgid "Home to <em>{0}</em> people"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who wrote <em>{0}</em> articles"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "And are connected to <em>{0}</em> other instances"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Administred by"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Runs Plume {0}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Follow {}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Log in to follow"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enter your full username handle to follow"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Edit your account"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Your Profile"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Upload an avatar"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# src/template_utils.rs:251
|
||||||
|
msgid "Display name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# src/template_utils.rs:251
|
||||||
|
msgid "Email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Summary"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Update account"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Danger zone"
|
msgid "Danger zone"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be reversed."
|
msgid "Be very careful, any action taken here can't be cancelled."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Permanently delete this blog"
|
msgid "Delete your account"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{}'s icon"
|
msgid "Sorry, but as an admin, you can't leave your own instance."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit"
|
msgid "Your Dashboard"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "There's one author on this blog: "
|
msgid "Your Blogs"
|
||||||
msgid_plural "There are {0} authors on this blog: "
|
|
||||||
msgstr[0] ""
|
|
||||||
|
|
||||||
msgid "Latest articles"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "No posts to see here yet."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Search result(s) for \"{0}\""
|
msgid "Start a new blog"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Search result(s)"
|
msgid "Your Drafts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "No results for your query"
|
msgid "Your media"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "No more results for your query"
|
msgid "Go to your gallery"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Search"
|
msgid "Create your account"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Create an account"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# src/template_utils.rs:251
|
||||||
|
msgid "Username"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# src/template_utils.rs:251
|
||||||
|
msgid "Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# src/template_utils.rs:251
|
||||||
|
msgid "Password confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Articles"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Subscribers"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Subscriptions"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Atom feed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Recently boosted"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Admin"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "It is you"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Edit your profile"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Open on {0}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Unsubscribe"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Subscribe"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "{0}'s subscriptions"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "{0}'s subscribers"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Respond"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Are you sure?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete this comment"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "What is Plume?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Plume is a decentralized blogging engine."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Read the detailed rules"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "None"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No description"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "View all"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "By {0}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Draft"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Your query"
|
msgid "Your query"
|
||||||
@@ -370,6 +542,9 @@ msgstr ""
|
|||||||
msgid "Article title matching these words"
|
msgid "Article title matching these words"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Title"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
# src/template_utils.rs:339
|
# src/template_utils.rs:339
|
||||||
msgid "Subtitle matching these words"
|
msgid "Subtitle matching these words"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -434,6 +609,52 @@ msgstr ""
|
|||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Search result(s) for \"{0}\""
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Search result(s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No results for your query"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No more results for your query"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Reset your password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# src/template_utils.rs:251
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# src/template_utils.rs:251
|
||||||
|
msgid "Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Update password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Check your inbox!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# src/template_utils.rs:251
|
||||||
|
msgid "E-mail"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Send password reset link"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Log in"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# src/template_utils.rs:251
|
||||||
|
msgid "Username, or email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Interact with {}"
|
msgid "Interact with {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -492,6 +713,12 @@ msgstr ""
|
|||||||
msgid "Written by {0}"
|
msgid "Written by {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Edit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete this article"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "All rights reserved."
|
msgid "All rights reserved."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -521,12 +748,6 @@ msgstr ""
|
|||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Unsubscribe"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Subscribe"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -543,16 +764,120 @@ msgstr ""
|
|||||||
msgid "No comments yet. Be the first to react!"
|
msgid "No comments yet. Be the first to react!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Are you sure?"
|
msgid "Invalid CSRF token"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Page not found"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "We couldn't find this page."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "The link that led you here may be broken."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "The content you sent can't be processed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Maybe it was too long."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "You are not authorized."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Internal server error"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Something broke on our side."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Sorry about that. If you think this is a bug, please report it."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Edit \"{}\""
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Description"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Upload images"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Blog icon"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Blog banner"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Update blog"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Be very careful, any action taken here can't be reversed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Permanently delete this blog"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "New Blog"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Create a blog"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Create blog"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "{}'s icon"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "New article"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "There's one author on this blog: "
|
||||||
|
msgid_plural "There are {0} authors on this blog: "
|
||||||
|
msgstr[0] ""
|
||||||
|
|
||||||
|
msgid "No posts to see here yet."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Articles tagged \"{0}\""
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "There are currently no articles with such a tag"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "I'm from this instance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "I'm from another instance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# src/template_utils.rs:259
|
||||||
|
msgid "Example: user@plu.me"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Continue to your instance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Upload"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "You don't have any media yet."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Content warning: {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "Details"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -570,21 +895,6 @@ msgstr ""
|
|||||||
msgid "Send"
|
msgid "Send"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Your media"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Upload"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "You don't have any media yet."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Content warning: {0}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Details"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Media details"
|
msgid "Media details"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -599,333 +909,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Use as an avatar"
|
msgid "Use as an avatar"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Notifications"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Plume"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Menu"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Dashboard"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Log Out"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "My account"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Log In"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Register"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "About this instance"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Privacy policy"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Administration"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Documentation"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Source code"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Matrix room"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Your feed"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Federated feed"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Local feed"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Nothing to see here yet. Try subscribing to more people."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Articles from {}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "All the articles of the Fediverse"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Users"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Configuration"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Instances"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Ban"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Administration of {0}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
|
||||||
msgid "Name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Allow anyone to register here"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Short description"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Long description"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
|
||||||
msgid "Default article license"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Save these settings"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "About {0}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Runs Plume {0}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Home to <em>{0}</em> people"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Who wrote <em>{0}</em> articles"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "And are connected to <em>{0}</em> other instances"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Administred by"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Welcome to {}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Unblock"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Block"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Reset your password"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
|
||||||
msgid "New password"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
|
||||||
msgid "Confirmation"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Update password"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Log in"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
|
||||||
msgid "Username, or email"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
|
||||||
msgid "Password"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
|
||||||
msgid "E-mail"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Send password reset link"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Check your inbox!"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Admin"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "It is you"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Edit your profile"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Open on {0}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Follow {}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Log in to follow"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Enter your full username handle to follow"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Articles"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Subscribers"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Subscriptions"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Create your account"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Create an account"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
|
||||||
msgid "Username"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
|
||||||
msgid "Email"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
|
||||||
msgid "Password confirmation"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "{0}'s subscribers"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Edit your account"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Your Profile"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:251
|
|
||||||
msgid "Display name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Summary"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Update account"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be cancelled."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Delete your account"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Sorry, but as an admin, you can't leave your own instance."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Your Dashboard"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Your Blogs"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Start a new blog"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Your Drafts"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Go to your gallery"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Atom feed"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Recently boosted"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "What is Plume?"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Plume is a decentralized blogging engine."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "View all"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "None"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "No description"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "By {0}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Draft"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Respond"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Delete this comment"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "I'm from this instance"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "I'm from another instance"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# src/template_utils.rs:259
|
|
||||||
msgid "Example: user@plu.me"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Continue to your instance"
|
|
||||||
msgstr ""
|
|
||||||
|
|||||||
+462
-492
File diff suppressed because it is too large
Load Diff
+436
-463
File diff suppressed because it is too large
Load Diff
+430
-460
File diff suppressed because it is too large
Load Diff
+469
-499
File diff suppressed because it is too large
Load Diff
+414
-441
File diff suppressed because it is too large
Load Diff
+411
-438
File diff suppressed because it is too large
Load Diff
+2
-6
@@ -24,13 +24,9 @@ if [ $ARCH == "aarch64" -o $ARCH == "armv71" ] ; then
|
|||||||
apt-get install -y --no-install-recommends build-essential subversion ninja-build cmake
|
apt-get install -y --no-install-recommends build-essential subversion ninja-build cmake
|
||||||
mkdir -p /scratch/src
|
mkdir -p /scratch/src
|
||||||
cd /scratch/src
|
cd /scratch/src
|
||||||
# Pin LLVM to post 7.0.1 tag and pin to a known-good revision for Plume builds
|
svn co http://llvm.org/svn/llvm-project/llvm/tags/RELEASE_800/final/ llvm
|
||||||
svn co -r350977 http://llvm.org/svn/llvm-project/llvm/trunk/ llvm
|
|
||||||
cd /scratch/src/llvm/tools
|
cd /scratch/src/llvm/tools
|
||||||
# Pin lld to post 7.0.1 tag and pin to a known-good revision for Plume builds
|
svn co http://llvm.org/svn/llvm-project/lld/tags/RELEASE_800/final/ lld
|
||||||
svn co -r350975 http://llvm.org/svn/llvm-project/lld/trunk lld
|
|
||||||
#svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
|
|
||||||
#svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra
|
|
||||||
mkdir -p /scratch/build/arm
|
mkdir -p /scratch/build/arm
|
||||||
cd /scratch/build/arm
|
cd /scratch/build/arm
|
||||||
if [ "$ARCH" == "aarch64" ] ; then
|
if [ "$ARCH" == "aarch64" ] ; then
|
||||||
|
|||||||
+13
-23
@@ -62,30 +62,20 @@ pub fn oauth(
|
|||||||
let conn = &*rockets.conn;
|
let conn = &*rockets.conn;
|
||||||
let app = App::find_by_client_id(conn, &query.client_id)?;
|
let app = App::find_by_client_id(conn, &query.client_id)?;
|
||||||
if app.client_secret == query.client_secret {
|
if app.client_secret == query.client_secret {
|
||||||
if let Ok(user) = User::find_by_fqn(&rockets, &query.username) {
|
if let Ok(user) = User::connect(&rockets, &query.username, &query.password) {
|
||||||
if user.auth(&query.password) {
|
let token = ApiToken::insert(
|
||||||
let token = ApiToken::insert(
|
conn,
|
||||||
conn,
|
NewApiToken {
|
||||||
NewApiToken {
|
app_id: app.id,
|
||||||
app_id: app.id,
|
user_id: user.id,
|
||||||
user_id: user.id,
|
value: random_hex(),
|
||||||
value: random_hex(),
|
scopes: query.scopes.clone(),
|
||||||
scopes: query.scopes.clone(),
|
},
|
||||||
},
|
)?;
|
||||||
)?;
|
Ok(Json(json!({
|
||||||
Ok(Json(json!({
|
"token": token.value
|
||||||
"token": token.value
|
})))
|
||||||
})))
|
|
||||||
} else {
|
|
||||||
Ok(Json(json!({
|
|
||||||
"error": "Invalid credentials"
|
|
||||||
})))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Making fake password verification to avoid different
|
|
||||||
// response times that would make it possible to know
|
|
||||||
// if a username is registered or not.
|
|
||||||
User::get(conn, 1)?.auth(&query.password);
|
|
||||||
Ok(Json(json!({
|
Ok(Json(json!({
|
||||||
"error": "Invalid credentials"
|
"error": "Invalid credentials"
|
||||||
})))
|
})))
|
||||||
|
|||||||
+22
-1
@@ -5,6 +5,7 @@ extern crate activitypub;
|
|||||||
extern crate askama_escape;
|
extern crate askama_escape;
|
||||||
extern crate atom_syndication;
|
extern crate atom_syndication;
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
|
extern crate clap;
|
||||||
extern crate colored;
|
extern crate colored;
|
||||||
extern crate ctrlc;
|
extern crate ctrlc;
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
@@ -38,10 +39,12 @@ extern crate validator;
|
|||||||
extern crate validator_derive;
|
extern crate validator_derive;
|
||||||
extern crate webfinger;
|
extern crate webfinger;
|
||||||
|
|
||||||
|
use clap::App;
|
||||||
use diesel::r2d2::ConnectionManager;
|
use diesel::r2d2::ConnectionManager;
|
||||||
use plume_models::{
|
use plume_models::{
|
||||||
db_conn::{DbPool, PragmaForeignKey},
|
db_conn::{DbPool, PragmaForeignKey},
|
||||||
instance::Instance,
|
instance::Instance,
|
||||||
|
ldap::Ldap,
|
||||||
migrations::IMPORTED_MIGRATIONS,
|
migrations::IMPORTED_MIGRATIONS,
|
||||||
search::{Searcher as UnmanagedSearcher, SearcherError},
|
search::{Searcher as UnmanagedSearcher, SearcherError},
|
||||||
Connection, Error, CONFIG,
|
Connection, Error, CONFIG,
|
||||||
@@ -73,8 +76,13 @@ compile_i18n!();
|
|||||||
|
|
||||||
/// Initializes a database pool.
|
/// Initializes a database pool.
|
||||||
fn init_pool() -> Option<DbPool> {
|
fn init_pool() -> Option<DbPool> {
|
||||||
dotenv::dotenv().ok();
|
match dotenv::dotenv() {
|
||||||
|
Ok(path) => println!("Configuration read from {}", path.display()),
|
||||||
|
Err(ref e) if e.not_found() => eprintln!("no .env was found"),
|
||||||
|
e => e.map(|_| ()).unwrap(),
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = Ldap::get_shared(); // force initialization of lazy static
|
||||||
let manager = ConnectionManager::<Connection>::new(CONFIG.database_url.as_str());
|
let manager = ConnectionManager::<Connection>::new(CONFIG.database_url.as_str());
|
||||||
let pool = DbPool::builder()
|
let pool = DbPool::builder()
|
||||||
.connection_customizer(Box::new(PragmaForeignKey))
|
.connection_customizer(Box::new(PragmaForeignKey))
|
||||||
@@ -85,6 +93,19 @@ fn init_pool() -> Option<DbPool> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
App::new("Plume")
|
||||||
|
.bin_name("plume")
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.about("Plume backend server")
|
||||||
|
.after_help(
|
||||||
|
r#"
|
||||||
|
The plume command should be run inside the directory
|
||||||
|
containing the `.env` configuration file and `static` directory.
|
||||||
|
See https://docs.joinplu.me/installation/config
|
||||||
|
and https://docs.joinplu.me/installation/init for more info.
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.get_matches();
|
||||||
let dbpool = init_pool().expect("main: database pool initialization error");
|
let dbpool = init_pool().expect("main: database pool initialization error");
|
||||||
if IMPORTED_MIGRATIONS
|
if IMPORTED_MIGRATIONS
|
||||||
.is_pending(&dbpool.get().unwrap())
|
.is_pending(&dbpool.get().unwrap())
|
||||||
|
|||||||
+127
-124
@@ -16,7 +16,7 @@ use plume_models::{
|
|||||||
blog_authors::*, blogs::*, instance::Instance, medias::*, posts::Post, safe_string::SafeString,
|
blog_authors::*, blogs::*, instance::Instance, medias::*, posts::Post, safe_string::SafeString,
|
||||||
users::User, Connection, PlumeRocket,
|
users::User, Connection, PlumeRocket,
|
||||||
};
|
};
|
||||||
use routes::{errors::ErrorPage, Page};
|
use routes::{errors::ErrorPage, Page, RespondOrRedirect};
|
||||||
use template_utils::{IntoContext, Ructe};
|
use template_utils::{IntoContext, Ructe};
|
||||||
|
|
||||||
#[get("/~/<name>?<page>", rank = 2)]
|
#[get("/~/<name>?<page>", rank = 2)]
|
||||||
@@ -84,10 +84,7 @@ fn valid_slug(title: &str) -> Result<(), ValidationError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[post("/blogs/new", data = "<form>")]
|
#[post("/blogs/new", data = "<form>")]
|
||||||
pub fn create(
|
pub fn create(form: LenientForm<NewBlogForm>, rockets: PlumeRocket) -> RespondOrRedirect {
|
||||||
form: LenientForm<NewBlogForm>,
|
|
||||||
rockets: PlumeRocket,
|
|
||||||
) -> Result<Flash<Redirect>, Ructe> {
|
|
||||||
let slug = utils::make_actor_id(&form.title);
|
let slug = utils::make_actor_id(&form.title);
|
||||||
let conn = &*rockets.conn;
|
let conn = &*rockets.conn;
|
||||||
let intl = &rockets.intl.catalog;
|
let intl = &rockets.intl.catalog;
|
||||||
@@ -111,42 +108,43 @@ pub fn create(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
let blog = Blog::insert(
|
return render!(blogs::new(&rockets.to_context(), &*form, errors)).into();
|
||||||
&*conn,
|
|
||||||
NewBlog::new_local(
|
|
||||||
slug.clone(),
|
|
||||||
form.title.to_string(),
|
|
||||||
String::from(""),
|
|
||||||
Instance::get_local()
|
|
||||||
.expect("blog::create: instance error")
|
|
||||||
.id,
|
|
||||||
)
|
|
||||||
.expect("blog::create: new local error"),
|
|
||||||
)
|
|
||||||
.expect("blog::create: error");
|
|
||||||
|
|
||||||
BlogAuthor::insert(
|
|
||||||
&*conn,
|
|
||||||
NewBlogAuthor {
|
|
||||||
blog_id: blog.id,
|
|
||||||
author_id: user.id,
|
|
||||||
is_owner: true,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.expect("blog::create: author error");
|
|
||||||
|
|
||||||
Ok(Flash::success(
|
|
||||||
Redirect::to(uri!(details: name = slug.clone(), page = _)),
|
|
||||||
&i18n!(intl, "Your blog was successfully created!"),
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
Err(render!(blogs::new(&rockets.to_context(), &*form, errors)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let blog = Blog::insert(
|
||||||
|
&*conn,
|
||||||
|
NewBlog::new_local(
|
||||||
|
slug.clone(),
|
||||||
|
form.title.to_string(),
|
||||||
|
String::from(""),
|
||||||
|
Instance::get_local()
|
||||||
|
.expect("blog::create: instance error")
|
||||||
|
.id,
|
||||||
|
)
|
||||||
|
.expect("blog::create: new local error"),
|
||||||
|
)
|
||||||
|
.expect("blog::create: error");
|
||||||
|
|
||||||
|
BlogAuthor::insert(
|
||||||
|
&*conn,
|
||||||
|
NewBlogAuthor {
|
||||||
|
blog_id: blog.id,
|
||||||
|
author_id: user.id,
|
||||||
|
is_owner: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("blog::create: author error");
|
||||||
|
|
||||||
|
Flash::success(
|
||||||
|
Redirect::to(uri!(details: name = slug.clone(), page = _)),
|
||||||
|
&i18n!(intl, "Your blog was successfully created!"),
|
||||||
|
)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/~/<name>/delete")]
|
#[post("/~/<name>/delete")]
|
||||||
pub fn delete(name: String, rockets: PlumeRocket) -> Result<Flash<Redirect>, Ructe> {
|
pub fn delete(name: String, rockets: PlumeRocket) -> RespondOrRedirect {
|
||||||
let conn = &*rockets.conn;
|
let conn = &*rockets.conn;
|
||||||
let blog = Blog::find_by_fqn(&rockets, &name).expect("blog::delete: blog not found");
|
let blog = Blog::find_by_fqn(&rockets, &name).expect("blog::delete: blog not found");
|
||||||
|
|
||||||
@@ -158,19 +156,21 @@ pub fn delete(name: String, rockets: PlumeRocket) -> Result<Flash<Redirect>, Ruc
|
|||||||
{
|
{
|
||||||
blog.delete(&conn, &rockets.searcher)
|
blog.delete(&conn, &rockets.searcher)
|
||||||
.expect("blog::expect: deletion error");
|
.expect("blog::expect: deletion error");
|
||||||
Ok(Flash::success(
|
Flash::success(
|
||||||
Redirect::to(uri!(super::instance::index)),
|
Redirect::to(uri!(super::instance::index)),
|
||||||
i18n!(rockets.intl.catalog, "Your blog was deleted."),
|
i18n!(rockets.intl.catalog, "Your blog was deleted."),
|
||||||
))
|
)
|
||||||
|
.into()
|
||||||
} else {
|
} else {
|
||||||
// TODO actually return 403 error code
|
// TODO actually return 403 error code
|
||||||
Err(render!(errors::not_authorized(
|
render!(errors::not_authorized(
|
||||||
&rockets.to_context(),
|
&rockets.to_context(),
|
||||||
i18n!(
|
i18n!(
|
||||||
rockets.intl.catalog,
|
rockets.intl.catalog,
|
||||||
"You are not allowed to delete this blog."
|
"You are not allowed to delete this blog."
|
||||||
)
|
)
|
||||||
)))
|
))
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,104 +236,107 @@ pub fn update(
|
|||||||
name: String,
|
name: String,
|
||||||
form: LenientForm<EditForm>,
|
form: LenientForm<EditForm>,
|
||||||
rockets: PlumeRocket,
|
rockets: PlumeRocket,
|
||||||
) -> Result<Flash<Redirect>, Ructe> {
|
) -> RespondOrRedirect {
|
||||||
let conn = &*rockets.conn;
|
let conn = &*rockets.conn;
|
||||||
let intl = &rockets.intl.catalog;
|
let intl = &rockets.intl.catalog;
|
||||||
let mut blog = Blog::find_by_fqn(&rockets, &name).expect("blog::update: blog not found");
|
let mut blog = Blog::find_by_fqn(&rockets, &name).expect("blog::update: blog not found");
|
||||||
if rockets
|
if !rockets
|
||||||
.user
|
.user
|
||||||
.clone()
|
.clone()
|
||||||
.and_then(|u| u.is_author_in(&*conn, &blog).ok())
|
.and_then(|u| u.is_author_in(&*conn, &blog).ok())
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
{
|
{
|
||||||
let user = rockets
|
|
||||||
.user
|
|
||||||
.clone()
|
|
||||||
.expect("blogs::edit: User was None while it shouldn't");
|
|
||||||
form.validate()
|
|
||||||
.and_then(|_| {
|
|
||||||
if let Some(icon) = form.icon {
|
|
||||||
if !check_media(&*conn, icon, &user) {
|
|
||||||
let mut errors = ValidationErrors::new();
|
|
||||||
errors.add(
|
|
||||||
"",
|
|
||||||
ValidationError {
|
|
||||||
code: Cow::from("icon"),
|
|
||||||
message: Some(Cow::from(i18n!(
|
|
||||||
intl,
|
|
||||||
"You can't use this media as a blog icon."
|
|
||||||
))),
|
|
||||||
params: HashMap::new(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
return Err(errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(banner) = form.banner {
|
|
||||||
if !check_media(&*conn, banner, &user) {
|
|
||||||
let mut errors = ValidationErrors::new();
|
|
||||||
errors.add(
|
|
||||||
"",
|
|
||||||
ValidationError {
|
|
||||||
code: Cow::from("banner"),
|
|
||||||
message: Some(Cow::from(i18n!(
|
|
||||||
intl,
|
|
||||||
"You can't use this media as a blog banner."
|
|
||||||
))),
|
|
||||||
params: HashMap::new(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
return Err(errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
blog.title = form.title.clone();
|
|
||||||
blog.summary = form.summary.clone();
|
|
||||||
blog.summary_html = SafeString::new(
|
|
||||||
&utils::md_to_html(
|
|
||||||
&form.summary,
|
|
||||||
None,
|
|
||||||
true,
|
|
||||||
Some(Media::get_media_processor(
|
|
||||||
&conn,
|
|
||||||
blog.list_authors(&conn)
|
|
||||||
.expect("Couldn't get list of authors")
|
|
||||||
.iter()
|
|
||||||
.collect(),
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
.0,
|
|
||||||
);
|
|
||||||
blog.icon_id = form.icon;
|
|
||||||
blog.banner_id = form.banner;
|
|
||||||
blog.save_changes::<Blog>(&*conn)
|
|
||||||
.expect("Couldn't save blog changes");
|
|
||||||
Ok(Flash::success(
|
|
||||||
Redirect::to(uri!(details: name = name, page = _)),
|
|
||||||
i18n!(intl, "Your blog information have been updated."),
|
|
||||||
))
|
|
||||||
})
|
|
||||||
.map_err(|err| {
|
|
||||||
let medias = Media::for_user(&*conn, user.id).expect("Couldn't list media");
|
|
||||||
render!(blogs::edit(
|
|
||||||
&rockets.to_context(),
|
|
||||||
&blog,
|
|
||||||
medias,
|
|
||||||
&*form,
|
|
||||||
err
|
|
||||||
))
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// TODO actually return 403 error code
|
// TODO actually return 403 error code
|
||||||
Err(render!(errors::not_authorized(
|
return render!(errors::not_authorized(
|
||||||
&rockets.to_context(),
|
&rockets.to_context(),
|
||||||
i18n!(
|
i18n!(
|
||||||
rockets.intl.catalog,
|
rockets.intl.catalog,
|
||||||
"You are not allowed to edit this blog."
|
"You are not allowed to edit this blog."
|
||||||
)
|
)
|
||||||
)))
|
))
|
||||||
|
.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let user = rockets
|
||||||
|
.user
|
||||||
|
.clone()
|
||||||
|
.expect("blogs::edit: User was None while it shouldn't");
|
||||||
|
form.validate()
|
||||||
|
.and_then(|_| {
|
||||||
|
if let Some(icon) = form.icon {
|
||||||
|
if !check_media(&*conn, icon, &user) {
|
||||||
|
let mut errors = ValidationErrors::new();
|
||||||
|
errors.add(
|
||||||
|
"",
|
||||||
|
ValidationError {
|
||||||
|
code: Cow::from("icon"),
|
||||||
|
message: Some(Cow::from(i18n!(
|
||||||
|
intl,
|
||||||
|
"You can't use this media as a blog icon."
|
||||||
|
))),
|
||||||
|
params: HashMap::new(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return Err(errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(banner) = form.banner {
|
||||||
|
if !check_media(&*conn, banner, &user) {
|
||||||
|
let mut errors = ValidationErrors::new();
|
||||||
|
errors.add(
|
||||||
|
"",
|
||||||
|
ValidationError {
|
||||||
|
code: Cow::from("banner"),
|
||||||
|
message: Some(Cow::from(i18n!(
|
||||||
|
intl,
|
||||||
|
"You can't use this media as a blog banner."
|
||||||
|
))),
|
||||||
|
params: HashMap::new(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return Err(errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blog.title = form.title.clone();
|
||||||
|
blog.summary = form.summary.clone();
|
||||||
|
blog.summary_html = SafeString::new(
|
||||||
|
&utils::md_to_html(
|
||||||
|
&form.summary,
|
||||||
|
None,
|
||||||
|
true,
|
||||||
|
Some(Media::get_media_processor(
|
||||||
|
&conn,
|
||||||
|
blog.list_authors(&conn)
|
||||||
|
.expect("Couldn't get list of authors")
|
||||||
|
.iter()
|
||||||
|
.collect(),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.0,
|
||||||
|
);
|
||||||
|
blog.icon_id = form.icon;
|
||||||
|
blog.banner_id = form.banner;
|
||||||
|
blog.save_changes::<Blog>(&*conn)
|
||||||
|
.expect("Couldn't save blog changes");
|
||||||
|
Ok(Flash::success(
|
||||||
|
Redirect::to(uri!(details: name = name, page = _)),
|
||||||
|
i18n!(intl, "Your blog information have been updated."),
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.map_err(|err| {
|
||||||
|
let medias = Media::for_user(&*conn, user.id).expect("Couldn't list media");
|
||||||
|
render!(blogs::edit(
|
||||||
|
&rockets.to_context(),
|
||||||
|
&blog,
|
||||||
|
medias,
|
||||||
|
&*form,
|
||||||
|
err
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/~/<name>/outbox")]
|
#[get("/~/<name>/outbox")]
|
||||||
|
|||||||
+30
-30
@@ -13,7 +13,7 @@ use plume_models::{
|
|||||||
admin::Admin, comments::Comment, db_conn::DbConn, headers::Headers, instance::*, posts::Post,
|
admin::Admin, comments::Comment, db_conn::DbConn, headers::Headers, instance::*, posts::Post,
|
||||||
safe_string::SafeString, users::User, Error, PlumeRocket, CONFIG,
|
safe_string::SafeString, users::User, Error, PlumeRocket, CONFIG,
|
||||||
};
|
};
|
||||||
use routes::{errors::ErrorPage, rocket_uri_macro_static_files, Page};
|
use routes::{errors::ErrorPage, rocket_uri_macro_static_files, Page, RespondOrRedirect};
|
||||||
use template_utils::{IntoContext, Ructe};
|
use template_utils::{IntoContext, Ructe};
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
@@ -114,36 +114,36 @@ pub fn update_settings(
|
|||||||
_admin: Admin,
|
_admin: Admin,
|
||||||
form: LenientForm<InstanceSettingsForm>,
|
form: LenientForm<InstanceSettingsForm>,
|
||||||
rockets: PlumeRocket,
|
rockets: PlumeRocket,
|
||||||
) -> Result<Flash<Redirect>, Ructe> {
|
) -> RespondOrRedirect {
|
||||||
let conn = &*rockets.conn;
|
let conn = &*rockets.conn;
|
||||||
form.validate()
|
if let Err(e) = form.validate() {
|
||||||
.and_then(|_| {
|
let local_inst =
|
||||||
let instance =
|
Instance::get_local().expect("instance::update_settings: local instance error");
|
||||||
Instance::get_local().expect("instance::update_settings: local instance error");
|
render!(instance::admin(
|
||||||
instance
|
&rockets.to_context(),
|
||||||
.update(
|
local_inst,
|
||||||
conn,
|
form.clone(),
|
||||||
form.name.clone(),
|
e
|
||||||
form.open_registrations,
|
))
|
||||||
form.short_description.clone(),
|
.into()
|
||||||
form.long_description.clone(),
|
} else {
|
||||||
)
|
let instance =
|
||||||
.expect("instance::update_settings: save error");
|
Instance::get_local().expect("instance::update_settings: local instance error");
|
||||||
Ok(Flash::success(
|
instance
|
||||||
Redirect::to(uri!(admin)),
|
.update(
|
||||||
i18n!(rockets.intl.catalog, "Instance settings have been saved."),
|
conn,
|
||||||
))
|
form.name.clone(),
|
||||||
})
|
form.open_registrations,
|
||||||
.or_else(|e| {
|
form.short_description.clone(),
|
||||||
let local_inst =
|
form.long_description.clone(),
|
||||||
Instance::get_local().expect("instance::update_settings: local instance error");
|
)
|
||||||
Err(render!(instance::admin(
|
.expect("instance::update_settings: save error");
|
||||||
&rockets.to_context(),
|
Flash::success(
|
||||||
local_inst,
|
Redirect::to(uri!(admin)),
|
||||||
form.clone(),
|
i18n!(rockets.intl.catalog, "Instance settings have been saved."),
|
||||||
e
|
)
|
||||||
)))
|
.into()
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/admin/instances?<page>")]
|
#[get("/admin/instances?<page>")]
|
||||||
|
|||||||
+63
-64
@@ -38,76 +38,75 @@ pub fn upload(
|
|||||||
ct: &ContentType,
|
ct: &ContentType,
|
||||||
conn: DbConn,
|
conn: DbConn,
|
||||||
) -> Result<Redirect, status::BadRequest<&'static str>> {
|
) -> Result<Redirect, status::BadRequest<&'static str>> {
|
||||||
if ct.is_form_data() {
|
if !ct.is_form_data() {
|
||||||
let (_, boundary) = ct
|
return Ok(Redirect::to(uri!(new)));
|
||||||
.params()
|
}
|
||||||
.find(|&(k, _)| k == "boundary")
|
|
||||||
.ok_or_else(|| status::BadRequest(Some("No boundary")))?;
|
|
||||||
|
|
||||||
match Multipart::with_body(data.open(), boundary).save().temp() {
|
let (_, boundary) = ct
|
||||||
SaveResult::Full(entries) => {
|
.params()
|
||||||
let fields = entries.fields;
|
.find(|&(k, _)| k == "boundary")
|
||||||
|
.ok_or_else(|| status::BadRequest(Some("No boundary")))?;
|
||||||
|
|
||||||
let filename = fields
|
if let SaveResult::Full(entries) = Multipart::with_body(data.open(), boundary).save().temp() {
|
||||||
.get("file")
|
let fields = entries.fields;
|
||||||
.and_then(|v| v.iter().next())
|
|
||||||
.ok_or_else(|| status::BadRequest(Some("No file uploaded")))?
|
|
||||||
.headers
|
|
||||||
.filename
|
|
||||||
.clone();
|
|
||||||
// Remove extension if it contains something else than just letters and numbers
|
|
||||||
let ext = filename
|
|
||||||
.and_then(|f| {
|
|
||||||
f.rsplit('.')
|
|
||||||
.next()
|
|
||||||
.and_then(|ext| {
|
|
||||||
if ext.chars().any(|c| !c.is_alphanumeric()) {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(ext.to_lowercase())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map(|ext| format!(".{}", ext))
|
|
||||||
})
|
|
||||||
.unwrap_or_default();
|
|
||||||
let dest = format!("static/media/{}{}", GUID::rand().to_string(), ext);
|
|
||||||
|
|
||||||
match fields["file"][0].data {
|
let filename = fields
|
||||||
SavedData::Bytes(ref bytes) => fs::write(&dest, bytes)
|
.get("file")
|
||||||
.map_err(|_| status::BadRequest(Some("Couldn't save upload")))?,
|
.and_then(|v| v.iter().next())
|
||||||
SavedData::File(ref path, _) => {
|
.ok_or_else(|| status::BadRequest(Some("No file uploaded")))?
|
||||||
fs::copy(path, &dest)
|
.headers
|
||||||
.map_err(|_| status::BadRequest(Some("Couldn't copy upload")))?;
|
.filename
|
||||||
}
|
.clone();
|
||||||
_ => {
|
// Remove extension if it contains something else than just letters and numbers
|
||||||
return Ok(Redirect::to(uri!(new)));
|
let ext = filename
|
||||||
}
|
.and_then(|f| {
|
||||||
}
|
f.rsplit('.')
|
||||||
|
.next()
|
||||||
let has_cw = !read(&fields["cw"][0].data)
|
.and_then(|ext| {
|
||||||
.map(|cw| cw.is_empty())
|
if ext.chars().any(|c| !c.is_alphanumeric()) {
|
||||||
.unwrap_or(false);
|
|
||||||
let media = Media::insert(
|
|
||||||
&*conn,
|
|
||||||
NewMedia {
|
|
||||||
file_path: dest,
|
|
||||||
alt_text: read(&fields["alt"][0].data)?,
|
|
||||||
is_remote: false,
|
|
||||||
remote_url: None,
|
|
||||||
sensitive: has_cw,
|
|
||||||
content_warning: if has_cw {
|
|
||||||
Some(read(&fields["cw"][0].data)?)
|
|
||||||
} else {
|
|
||||||
None
|
None
|
||||||
},
|
} else {
|
||||||
owner_id: user.id,
|
Some(ext.to_lowercase())
|
||||||
},
|
}
|
||||||
)
|
})
|
||||||
.map_err(|_| status::BadRequest(Some("Error while saving media")))?;
|
.map(|ext| format!(".{}", ext))
|
||||||
Ok(Redirect::to(uri!(details: id = media.id)))
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
let dest = format!("static/media/{}{}", GUID::rand().to_string(), ext);
|
||||||
|
|
||||||
|
match fields["file"][0].data {
|
||||||
|
SavedData::Bytes(ref bytes) => fs::write(&dest, bytes)
|
||||||
|
.map_err(|_| status::BadRequest(Some("Couldn't save upload")))?,
|
||||||
|
SavedData::File(ref path, _) => {
|
||||||
|
fs::copy(path, &dest)
|
||||||
|
.map_err(|_| status::BadRequest(Some("Couldn't copy upload")))?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Ok(Redirect::to(uri!(new)));
|
||||||
}
|
}
|
||||||
SaveResult::Partial(_, _) | SaveResult::Error(_) => Ok(Redirect::to(uri!(new))),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let has_cw = !read(&fields["cw"][0].data)
|
||||||
|
.map(|cw| cw.is_empty())
|
||||||
|
.unwrap_or(false);
|
||||||
|
let media = Media::insert(
|
||||||
|
&*conn,
|
||||||
|
NewMedia {
|
||||||
|
file_path: dest,
|
||||||
|
alt_text: read(&fields["alt"][0].data)?,
|
||||||
|
is_remote: false,
|
||||||
|
remote_url: None,
|
||||||
|
sensitive: has_cw,
|
||||||
|
content_warning: if has_cw {
|
||||||
|
Some(read(&fields["cw"][0].data)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
owner_id: user.id,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.map_err(|_| status::BadRequest(Some("Error while saving media")))?;
|
||||||
|
Ok(Redirect::to(uri!(details: id = media.id)))
|
||||||
} else {
|
} else {
|
||||||
Ok(Redirect::to(uri!(new)))
|
Ok(Redirect::to(uri!(new)))
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-1
@@ -7,15 +7,51 @@ use rocket::{
|
|||||||
RawStr, Status,
|
RawStr, Status,
|
||||||
},
|
},
|
||||||
request::{self, FromFormValue, FromRequest, Request},
|
request::{self, FromFormValue, FromRequest, Request},
|
||||||
response::NamedFile,
|
response::{Flash, NamedFile, Redirect},
|
||||||
Outcome,
|
Outcome,
|
||||||
};
|
};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use template_utils::Ructe;
|
||||||
|
|
||||||
use plume_models::{posts::Post, Connection};
|
use plume_models::{posts::Post, Connection};
|
||||||
|
|
||||||
const ITEMS_PER_PAGE: i32 = 12;
|
const ITEMS_PER_PAGE: i32 = 12;
|
||||||
|
|
||||||
|
/// Special return type used for routes that "cannot fail", and instead
|
||||||
|
/// `Redirect`, or `Flash<Redirect>`, when we cannot deliver a `Ructe` Response
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
#[derive(Responder)]
|
||||||
|
pub enum RespondOrRedirect {
|
||||||
|
Response(Ructe),
|
||||||
|
FlashResponse(Flash<Ructe>),
|
||||||
|
Redirect(Redirect),
|
||||||
|
FlashRedirect(Flash<Redirect>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Ructe> for RespondOrRedirect {
|
||||||
|
fn from(response: Ructe) -> Self {
|
||||||
|
RespondOrRedirect::Response(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Flash<Ructe>> for RespondOrRedirect {
|
||||||
|
fn from(response: Flash<Ructe>) -> Self {
|
||||||
|
RespondOrRedirect::FlashResponse(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Redirect> for RespondOrRedirect {
|
||||||
|
fn from(redirect: Redirect) -> Self {
|
||||||
|
RespondOrRedirect::Redirect(redirect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Flash<Redirect>> for RespondOrRedirect {
|
||||||
|
fn from(redirect: Flash<Redirect>) -> Self {
|
||||||
|
RespondOrRedirect::FlashRedirect(redirect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Shrinkwrap, Copy, Clone, UriDisplayQuery)]
|
#[derive(Shrinkwrap, Copy, Clone, UriDisplayQuery)]
|
||||||
pub struct Page(i32);
|
pub struct Page(i32);
|
||||||
|
|
||||||
|
|||||||
+37
-28
@@ -26,7 +26,9 @@ use plume_models::{
|
|||||||
users::User,
|
users::User,
|
||||||
Error, PlumeRocket,
|
Error, PlumeRocket,
|
||||||
};
|
};
|
||||||
use routes::{comments::NewCommentForm, errors::ErrorPage, ContentLen, RemoteForm};
|
use routes::{
|
||||||
|
comments::NewCommentForm, errors::ErrorPage, ContentLen, RemoteForm, RespondOrRedirect,
|
||||||
|
};
|
||||||
use template_utils::{IntoContext, Ructe};
|
use template_utils::{IntoContext, Ructe};
|
||||||
|
|
||||||
#[get("/~/<blog>/<slug>?<responding_to>", rank = 4)]
|
#[get("/~/<blog>/<slug>?<responding_to>", rank = 4)]
|
||||||
@@ -40,17 +42,23 @@ pub fn details(
|
|||||||
let user = rockets.user.clone();
|
let user = rockets.user.clone();
|
||||||
let blog = Blog::find_by_fqn(&rockets, &blog)?;
|
let blog = Blog::find_by_fqn(&rockets, &blog)?;
|
||||||
let post = Post::find_by_slug(&*conn, &slug, blog.id)?;
|
let post = Post::find_by_slug(&*conn, &slug, blog.id)?;
|
||||||
if post.published
|
if !(post.published
|
||||||
|| post
|
|| post
|
||||||
.get_authors(&*conn)?
|
.get_authors(&*conn)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.any(|a| a.id == user.clone().map(|u| u.id).unwrap_or(0))
|
.any(|a| a.id == user.clone().map(|u| u.id).unwrap_or(0)))
|
||||||
{
|
{
|
||||||
let comments = CommentTree::from_post(&*conn, &post, user.as_ref())?;
|
return Ok(render!(errors::not_authorized(
|
||||||
|
&rockets.to_context(),
|
||||||
|
i18n!(rockets.intl.catalog, "This post isn't published yet.")
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
let previous = responding_to.and_then(|r| Comment::get(&*conn, r).ok());
|
let comments = CommentTree::from_post(&*conn, &post, user.as_ref())?;
|
||||||
|
|
||||||
Ok(render!(posts::details(
|
let previous = responding_to.and_then(|r| Comment::get(&*conn, r).ok());
|
||||||
|
|
||||||
|
Ok(render!(posts::details(
|
||||||
&rockets.to_context(),
|
&rockets.to_context(),
|
||||||
post.clone(),
|
post.clone(),
|
||||||
blog,
|
blog,
|
||||||
@@ -87,12 +95,6 @@ pub fn details(
|
|||||||
user.and_then(|u| u.is_following(&*conn, post.get_authors(&*conn).ok()?[0].id).ok()).unwrap_or(false),
|
user.and_then(|u| u.is_following(&*conn, post.get_authors(&*conn).ok()?[0].id).ok()).unwrap_or(false),
|
||||||
post.get_authors(&*conn)?[0].clone()
|
post.get_authors(&*conn)?[0].clone()
|
||||||
)))
|
)))
|
||||||
} else {
|
|
||||||
Ok(render!(errors::not_authorized(
|
|
||||||
&rockets.to_context(),
|
|
||||||
i18n!(rockets.intl.catalog, "This post isn't published yet.")
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/~/<blog>/<slug>", rank = 3)]
|
#[get("/~/<blog>/<slug>", rank = 3)]
|
||||||
@@ -219,7 +221,7 @@ pub fn update(
|
|||||||
cl: ContentLen,
|
cl: ContentLen,
|
||||||
form: LenientForm<NewPostForm>,
|
form: LenientForm<NewPostForm>,
|
||||||
rockets: PlumeRocket,
|
rockets: PlumeRocket,
|
||||||
) -> Result<Flash<Redirect>, Ructe> {
|
) -> RespondOrRedirect {
|
||||||
let conn = &*rockets.conn;
|
let conn = &*rockets.conn;
|
||||||
let b = Blog::find_by_fqn(&rockets, &blog).expect("post::update: blog error");
|
let b = Blog::find_by_fqn(&rockets, &blog).expect("post::update: blog error");
|
||||||
let mut post =
|
let mut post =
|
||||||
@@ -255,10 +257,11 @@ pub fn update(
|
|||||||
.expect("posts::update: is author in error")
|
.expect("posts::update: is author in error")
|
||||||
{
|
{
|
||||||
// actually it's not "Ok"…
|
// actually it's not "Ok"…
|
||||||
Ok(Flash::error(
|
Flash::error(
|
||||||
Redirect::to(uri!(super::blogs::details: name = blog, page = _)),
|
Redirect::to(uri!(super::blogs::details: name = blog, page = _)),
|
||||||
i18n!(&intl, "You are not allowed to publish on this blog."),
|
i18n!(&intl, "You are not allowed to publish on this blog."),
|
||||||
))
|
)
|
||||||
|
.into()
|
||||||
} else {
|
} else {
|
||||||
let (content, mentions, hashtags) = utils::md_to_html(
|
let (content, mentions, hashtags) = utils::md_to_html(
|
||||||
form.content.to_string().as_ref(),
|
form.content.to_string().as_ref(),
|
||||||
@@ -345,14 +348,15 @@ pub fn update(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Flash::success(
|
Flash::success(
|
||||||
Redirect::to(uri!(details: blog = blog, slug = new_slug, responding_to = _)),
|
Redirect::to(uri!(details: blog = blog, slug = new_slug, responding_to = _)),
|
||||||
i18n!(intl, "Your article has been updated."),
|
i18n!(intl, "Your article has been updated."),
|
||||||
))
|
)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let medias = Media::for_user(&*conn, user.id).expect("posts:update: medias error");
|
let medias = Media::for_user(&*conn, user.id).expect("posts:update: medias error");
|
||||||
Err(render!(posts::new(
|
render!(posts::new(
|
||||||
&rockets.to_context(),
|
&rockets.to_context(),
|
||||||
i18n!(intl, "Edit {0}"; &form.title),
|
i18n!(intl, "Edit {0}"; &form.title),
|
||||||
b,
|
b,
|
||||||
@@ -363,7 +367,8 @@ pub fn update(
|
|||||||
errors.clone(),
|
errors.clone(),
|
||||||
medias.clone(),
|
medias.clone(),
|
||||||
cl.0
|
cl.0
|
||||||
)))
|
))
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,7 +401,7 @@ pub fn create(
|
|||||||
form: LenientForm<NewPostForm>,
|
form: LenientForm<NewPostForm>,
|
||||||
cl: ContentLen,
|
cl: ContentLen,
|
||||||
rockets: PlumeRocket,
|
rockets: PlumeRocket,
|
||||||
) -> Result<Flash<Redirect>, Result<Ructe, ErrorPage>> {
|
) -> Result<RespondOrRedirect, ErrorPage> {
|
||||||
let conn = &*rockets.conn;
|
let conn = &*rockets.conn;
|
||||||
let blog = Blog::find_by_fqn(&rockets, &blog_name).expect("post::create: blog error");;
|
let blog = Blog::find_by_fqn(&rockets, &blog_name).expect("post::create: blog error");;
|
||||||
let slug = form.title.to_string().to_kebab_case();
|
let slug = form.title.to_string().to_kebab_case();
|
||||||
@@ -429,7 +434,8 @@ pub fn create(
|
|||||||
&rockets.intl.catalog,
|
&rockets.intl.catalog,
|
||||||
"You are not allowed to publish on this blog."
|
"You are not allowed to publish on this blog."
|
||||||
),
|
),
|
||||||
));
|
)
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let (content, mentions, hashtags) = utils::md_to_html(
|
let (content, mentions, hashtags) = utils::md_to_html(
|
||||||
@@ -530,10 +536,11 @@ pub fn create(
|
|||||||
Ok(Flash::success(
|
Ok(Flash::success(
|
||||||
Redirect::to(uri!(details: blog = blog_name, slug = slug, responding_to = _)),
|
Redirect::to(uri!(details: blog = blog_name, slug = slug, responding_to = _)),
|
||||||
i18n!(&rockets.intl.catalog, "Your article has been saved."),
|
i18n!(&rockets.intl.catalog, "Your article has been saved."),
|
||||||
))
|
)
|
||||||
|
.into())
|
||||||
} else {
|
} else {
|
||||||
let medias = Media::for_user(&*conn, user.id).expect("posts::create: medias error");
|
let medias = Media::for_user(&*conn, user.id).expect("posts::create: medias error");
|
||||||
Err(Ok(render!(posts::new(
|
Ok(render!(posts::new(
|
||||||
&rockets.to_context(),
|
&rockets.to_context(),
|
||||||
i18n!(rockets.intl.catalog, "New article"),
|
i18n!(rockets.intl.catalog, "New article"),
|
||||||
blog,
|
blog,
|
||||||
@@ -544,7 +551,8 @@ pub fn create(
|
|||||||
errors.clone(),
|
errors.clone(),
|
||||||
medias,
|
medias,
|
||||||
cl.0
|
cl.0
|
||||||
))))
|
))
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,14 +635,14 @@ pub fn remote_interact_post(
|
|||||||
blog_name: String,
|
blog_name: String,
|
||||||
slug: String,
|
slug: String,
|
||||||
remote: LenientForm<RemoteForm>,
|
remote: LenientForm<RemoteForm>,
|
||||||
) -> Result<Result<Ructe, Redirect>, ErrorPage> {
|
) -> Result<RespondOrRedirect, ErrorPage> {
|
||||||
let target = Blog::find_by_fqn(&rockets, &blog_name)
|
let target = Blog::find_by_fqn(&rockets, &blog_name)
|
||||||
.and_then(|blog| Post::find_by_slug(&rockets.conn, &slug, blog.id))?;
|
.and_then(|blog| Post::find_by_slug(&rockets.conn, &slug, blog.id))?;
|
||||||
if let Some(uri) = User::fetch_remote_interact_uri(&remote.remote)
|
if let Some(uri) = User::fetch_remote_interact_uri(&remote.remote)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|uri| rt_format!(uri, uri = target.ap_url).ok())
|
.and_then(|uri| rt_format!(uri, uri = target.ap_url).ok())
|
||||||
{
|
{
|
||||||
Ok(Err(Redirect::to(uri)))
|
Ok(Redirect::to(uri).into())
|
||||||
} else {
|
} else {
|
||||||
let mut errs = ValidationErrors::new();
|
let mut errs = ValidationErrors::new();
|
||||||
errs.add("remote", ValidationError {
|
errs.add("remote", ValidationError {
|
||||||
@@ -643,13 +651,14 @@ pub fn remote_interact_post(
|
|||||||
params: HashMap::new(),
|
params: HashMap::new(),
|
||||||
});
|
});
|
||||||
//could not get your remote url?
|
//could not get your remote url?
|
||||||
Ok(Ok(render!(posts::remote_interact(
|
Ok(render!(posts::remote_interact(
|
||||||
&rockets.to_context(),
|
&rockets.to_context(),
|
||||||
target,
|
target,
|
||||||
super::session::LoginForm::default(),
|
super::session::LoginForm::default(),
|
||||||
ValidationErrors::default(),
|
ValidationErrors::default(),
|
||||||
remote.clone(),
|
remote.clone(),
|
||||||
errs
|
errs
|
||||||
))))
|
))
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+68
-138
@@ -7,6 +7,7 @@ use rocket::{
|
|||||||
State,
|
State,
|
||||||
};
|
};
|
||||||
use rocket_i18n::I18n;
|
use rocket_i18n::I18n;
|
||||||
|
use routes::RespondOrRedirect;
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
@@ -16,10 +17,10 @@ use validator::{Validate, ValidationError, ValidationErrors};
|
|||||||
|
|
||||||
use mail::{build_mail, Mailer};
|
use mail::{build_mail, Mailer};
|
||||||
use plume_models::{
|
use plume_models::{
|
||||||
|
password_reset_requests::*,
|
||||||
users::{User, AUTH_COOKIE},
|
users::{User, AUTH_COOKIE},
|
||||||
Error, PlumeRocket, CONFIG,
|
Error, PlumeRocket, CONFIG,
|
||||||
};
|
};
|
||||||
use routes::errors::ErrorPage;
|
|
||||||
use template_utils::{IntoContext, Ructe};
|
use template_utils::{IntoContext, Ructe};
|
||||||
|
|
||||||
#[get("/login?<m>")]
|
#[get("/login?<m>")]
|
||||||
@@ -32,92 +33,63 @@ pub fn new(m: Option<String>, rockets: PlumeRocket) -> Ructe {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, FromForm, Validate)]
|
#[derive(Default, FromForm)]
|
||||||
pub struct LoginForm {
|
pub struct LoginForm {
|
||||||
#[validate(length(min = "1", message = "We need an email, or a username to identify you"))]
|
|
||||||
pub email_or_name: String,
|
pub email_or_name: String,
|
||||||
#[validate(length(min = "1", message = "Your password can't be empty"))]
|
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/login", data = "<form>")]
|
#[post("/login", data = "<form>")]
|
||||||
pub fn create(
|
pub fn create(
|
||||||
form: LenientForm<LoginForm>,
|
form: LenientForm<LoginForm>,
|
||||||
mut cookies: Cookies,
|
|
||||||
rockets: PlumeRocket,
|
rockets: PlumeRocket,
|
||||||
) -> Result<Flash<Redirect>, Ructe> {
|
mut cookies: Cookies,
|
||||||
|
) -> RespondOrRedirect {
|
||||||
let conn = &*rockets.conn;
|
let conn = &*rockets.conn;
|
||||||
let user = User::find_by_email(&*conn, &form.email_or_name)
|
|
||||||
.or_else(|_| User::find_by_fqn(&rockets, &form.email_or_name));
|
|
||||||
let mut errors = match form.validate() {
|
|
||||||
Ok(_) => ValidationErrors::new(),
|
|
||||||
Err(e) => e,
|
|
||||||
};
|
|
||||||
|
|
||||||
let user_id = if let Ok(user) = user {
|
let user_id = if let Ok(user) = User::connect(&rockets, &form.email_or_name, &form.password) {
|
||||||
if !user.auth(&form.password) {
|
user.id.to_string()
|
||||||
let mut err = ValidationError::new("invalid_login");
|
|
||||||
err.message = Some(Cow::from("Invalid username, or password"));
|
|
||||||
errors.add("email_or_name", err);
|
|
||||||
String::new()
|
|
||||||
} else {
|
|
||||||
user.id.to_string()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Fake password verification, only to avoid different login times
|
let mut errors = ValidationErrors::new();
|
||||||
// that could be used to see if an email adress is registered or not
|
|
||||||
User::get(&*conn, 1)
|
|
||||||
.map(|u| u.auth(&form.password))
|
|
||||||
.expect("No user is registered");
|
|
||||||
|
|
||||||
let mut err = ValidationError::new("invalid_login");
|
let mut err = ValidationError::new("invalid_login");
|
||||||
err.message = Some(Cow::from("Invalid username, or password"));
|
err.message = Some(Cow::from("Invalid username, or password"));
|
||||||
errors.add("email_or_name", err);
|
errors.add("email_or_name", err);
|
||||||
String::new()
|
return render!(session::login(&rockets.to_context(), None, &*form, errors)).into();
|
||||||
};
|
};
|
||||||
|
|
||||||
if errors.is_empty() {
|
cookies.add_private(
|
||||||
cookies.add_private(
|
Cookie::build(AUTH_COOKIE, user_id)
|
||||||
Cookie::build(AUTH_COOKIE, user_id)
|
.same_site(SameSite::Lax)
|
||||||
.same_site(SameSite::Lax)
|
.finish(),
|
||||||
.finish(),
|
);
|
||||||
);
|
let destination = rockets
|
||||||
let destination = rockets
|
.flash_msg
|
||||||
.flash_msg
|
.clone()
|
||||||
.clone()
|
.and_then(
|
||||||
.and_then(
|
|(name, msg)| {
|
||||||
|(name, msg)| {
|
if name == "callback" {
|
||||||
if name == "callback" {
|
Some(msg)
|
||||||
Some(msg)
|
} else {
|
||||||
} else {
|
None
|
||||||
None
|
}
|
||||||
}
|
},
|
||||||
},
|
)
|
||||||
)
|
.unwrap_or_else(|| "/".to_owned());
|
||||||
.unwrap_or_else(|| "/".to_owned());
|
|
||||||
|
|
||||||
let uri = Uri::parse(&destination)
|
if let Ok(uri) = Uri::parse(&destination).map(IntoOwned::into_owned) {
|
||||||
.map(IntoOwned::into_owned)
|
Flash::success(
|
||||||
.map_err(|_| {
|
|
||||||
render!(session::login(
|
|
||||||
&(conn, &rockets.intl.catalog, None, None),
|
|
||||||
None,
|
|
||||||
&*form,
|
|
||||||
errors
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(Flash::success(
|
|
||||||
Redirect::to(uri),
|
Redirect::to(uri),
|
||||||
i18n!(&rockets.intl.catalog, "You are now connected."),
|
i18n!(&rockets.intl.catalog, "You are now connected."),
|
||||||
))
|
)
|
||||||
|
.into()
|
||||||
} else {
|
} else {
|
||||||
Err(render!(session::login(
|
render!(session::login(
|
||||||
&rockets.to_context(),
|
&(conn, &rockets.intl.catalog, None, None),
|
||||||
None,
|
None,
|
||||||
&*form,
|
&*form,
|
||||||
errors
|
ValidationErrors::new()
|
||||||
)))
|
))
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,29 +136,17 @@ pub struct ResetForm {
|
|||||||
pub fn password_reset_request(
|
pub fn password_reset_request(
|
||||||
mail: State<Arc<Mutex<Mailer>>>,
|
mail: State<Arc<Mutex<Mailer>>>,
|
||||||
form: Form<ResetForm>,
|
form: Form<ResetForm>,
|
||||||
requests: State<Arc<Mutex<Vec<ResetRequest>>>>,
|
|
||||||
rockets: PlumeRocket,
|
rockets: PlumeRocket,
|
||||||
) -> Ructe {
|
) -> Ructe {
|
||||||
let mut requests = requests.lock().unwrap();
|
if User::find_by_email(&*rockets.conn, &form.email).is_ok() {
|
||||||
// Remove outdated requests (more than 1 day old) to avoid the list to grow too much
|
let token = PasswordResetRequest::insert(&*rockets.conn, &form.email)
|
||||||
requests.retain(|r| r.creation_date.elapsed().as_secs() < 24 * 60 * 60);
|
.expect("password_reset_request::insert: error");
|
||||||
|
|
||||||
if User::find_by_email(&*rockets.conn, &form.email).is_ok()
|
let url = format!("https://{}/password-reset/{}", CONFIG.base_url, token);
|
||||||
&& !requests.iter().any(|x| x.mail == form.email.clone())
|
|
||||||
{
|
|
||||||
let id = plume_common::utils::random_hex();
|
|
||||||
|
|
||||||
requests.push(ResetRequest {
|
|
||||||
mail: form.email.clone(),
|
|
||||||
id: id.clone(),
|
|
||||||
creation_date: Instant::now(),
|
|
||||||
});
|
|
||||||
|
|
||||||
let link = format!("https://{}/password-reset/{}", CONFIG.base_url, id);
|
|
||||||
if let Some(message) = build_mail(
|
if let Some(message) = build_mail(
|
||||||
form.email.clone(),
|
form.email.clone(),
|
||||||
i18n!(rockets.intl.catalog, "Password reset"),
|
i18n!(rockets.intl.catalog, "Password reset"),
|
||||||
i18n!(rockets.intl.catalog, "Here is the link to reset your password: {0}"; link),
|
i18n!(rockets.intl.catalog, "Here is the link to reset your password: {0}"; url),
|
||||||
) {
|
) {
|
||||||
if let Some(ref mut mail) = *mail.lock().unwrap() {
|
if let Some(ref mut mail) = *mail.lock().unwrap() {
|
||||||
mail.send(message.into())
|
mail.send(message.into())
|
||||||
@@ -199,17 +159,10 @@ pub fn password_reset_request(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/password-reset/<token>")]
|
#[get("/password-reset/<token>")]
|
||||||
pub fn password_reset_form(
|
pub fn password_reset_form(token: String, rockets: PlumeRocket) -> Result<Ructe, Ructe> {
|
||||||
token: String,
|
PasswordResetRequest::find_by_token(&*rockets.conn, &token)
|
||||||
requests: State<Arc<Mutex<Vec<ResetRequest>>>>,
|
.map_err(|err| password_reset_error_response(err, &rockets))?;
|
||||||
rockets: PlumeRocket,
|
|
||||||
) -> Result<Ructe, ErrorPage> {
|
|
||||||
requests
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.iter()
|
|
||||||
.find(|x| x.id == token.clone())
|
|
||||||
.ok_or(Error::NotFound)?;
|
|
||||||
Ok(render!(session::password_reset(
|
Ok(render!(session::password_reset(
|
||||||
&rockets.to_context(),
|
&rockets.to_context(),
|
||||||
&NewPasswordForm::default(),
|
&NewPasswordForm::default(),
|
||||||
@@ -239,56 +192,33 @@ fn passwords_match(form: &NewPasswordForm) -> Result<(), ValidationError> {
|
|||||||
#[post("/password-reset/<token>", data = "<form>")]
|
#[post("/password-reset/<token>", data = "<form>")]
|
||||||
pub fn password_reset(
|
pub fn password_reset(
|
||||||
token: String,
|
token: String,
|
||||||
requests: State<Arc<Mutex<Vec<ResetRequest>>>>,
|
|
||||||
form: Form<NewPasswordForm>,
|
form: Form<NewPasswordForm>,
|
||||||
rockets: PlumeRocket,
|
rockets: PlumeRocket,
|
||||||
) -> Result<Flash<Redirect>, Ructe> {
|
) -> Result<Flash<Redirect>, Ructe> {
|
||||||
form.validate()
|
form.validate()
|
||||||
.and_then(|_| {
|
.map_err(|err| render!(session::password_reset(&rockets.to_context(), &form, err)))?;
|
||||||
let mut requests = requests.lock().unwrap();
|
|
||||||
let req = requests
|
PasswordResetRequest::find_and_delete_by_token(&*rockets.conn, &token)
|
||||||
.iter()
|
.and_then(|request| User::find_by_email(&*rockets.conn, &request.email))
|
||||||
.find(|x| x.id == token.clone())
|
.and_then(|user| user.reset_password(&*rockets.conn, &form.password))
|
||||||
.ok_or_else(|| to_validation(0))?
|
.map_err(|err| password_reset_error_response(err, &rockets))?;
|
||||||
.clone();
|
|
||||||
if req.creation_date.elapsed().as_secs() < 60 * 60 * 2 {
|
Ok(Flash::success(
|
||||||
// Reset link is only valid for 2 hours
|
Redirect::to(uri!(
|
||||||
requests.retain(|r| *r != req);
|
new: m = _
|
||||||
let user = User::find_by_email(&*rockets.conn, &req.mail).map_err(to_validation)?;
|
)),
|
||||||
user.reset_password(&*rockets.conn, &form.password).ok();
|
i18n!(
|
||||||
Ok(Flash::success(
|
rockets.intl.catalog,
|
||||||
Redirect::to(uri!(
|
"Your password was successfully reset."
|
||||||
new: m = _
|
),
|
||||||
)),
|
))
|
||||||
i18n!(
|
|
||||||
rockets.intl.catalog,
|
|
||||||
"Your password was successfully reset."
|
|
||||||
),
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
Ok(Flash::error(
|
|
||||||
Redirect::to(uri!(
|
|
||||||
new: m = _
|
|
||||||
)),
|
|
||||||
i18n!(
|
|
||||||
rockets.intl.catalog,
|
|
||||||
"Sorry, but the link expired. Try again"
|
|
||||||
),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map_err(|err| render!(session::password_reset(&rockets.to_context(), &form, err)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_validation<T>(_: T) -> ValidationErrors {
|
fn password_reset_error_response(err: Error, rockets: &PlumeRocket) -> Ructe {
|
||||||
let mut errors = ValidationErrors::new();
|
match err {
|
||||||
errors.add(
|
Error::Expired => render!(session::password_reset_request_expired(
|
||||||
"",
|
&rockets.to_context()
|
||||||
ValidationError {
|
)),
|
||||||
code: Cow::from("server_error"),
|
_ => render!(errors::not_found(&rockets.to_context())),
|
||||||
message: Some(Cow::from("An unknown error occured")),
|
}
|
||||||
params: std::collections::HashMap::new(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
errors
|
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-11
@@ -25,14 +25,14 @@ use plume_models::{
|
|||||||
users::*,
|
users::*,
|
||||||
Error, PlumeRocket,
|
Error, PlumeRocket,
|
||||||
};
|
};
|
||||||
use routes::{errors::ErrorPage, Page, RemoteForm};
|
use routes::{errors::ErrorPage, Page, RemoteForm, RespondOrRedirect};
|
||||||
use template_utils::{IntoContext, Ructe};
|
use template_utils::{IntoContext, Ructe};
|
||||||
|
|
||||||
#[get("/me")]
|
#[get("/me")]
|
||||||
pub fn me(user: Option<User>) -> Result<Redirect, Flash<Redirect>> {
|
pub fn me(user: Option<User>) -> RespondOrRedirect {
|
||||||
match user {
|
match user {
|
||||||
Some(user) => Ok(Redirect::to(uri!(details: name = user.username))),
|
Some(user) => Redirect::to(uri!(details: name = user.username)).into(),
|
||||||
None => Err(utils::requires_login("", uri!(me))),
|
None => utils::requires_login("", uri!(me)).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ pub fn follow_not_connected(
|
|||||||
name: String,
|
name: String,
|
||||||
remote_form: Option<LenientForm<RemoteForm>>,
|
remote_form: Option<LenientForm<RemoteForm>>,
|
||||||
i18n: I18n,
|
i18n: I18n,
|
||||||
) -> Result<Result<Flash<Ructe>, Redirect>, ErrorPage> {
|
) -> Result<RespondOrRedirect, ErrorPage> {
|
||||||
let target = User::find_by_fqn(&rockets, &name)?;
|
let target = User::find_by_fqn(&rockets, &name)?;
|
||||||
if let Some(remote_form) = remote_form {
|
if let Some(remote_form) = remote_form {
|
||||||
if let Some(uri) = User::fetch_remote_interact_uri(&remote_form)
|
if let Some(uri) = User::fetch_remote_interact_uri(&remote_form)
|
||||||
@@ -207,7 +207,7 @@ pub fn follow_not_connected(
|
|||||||
.ok()
|
.ok()
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
Ok(Err(Redirect::to(uri)))
|
Ok(Redirect::to(uri).into())
|
||||||
} else {
|
} else {
|
||||||
let mut err = ValidationErrors::default();
|
let mut err = ValidationErrors::default();
|
||||||
err.add("remote",
|
err.add("remote",
|
||||||
@@ -217,7 +217,7 @@ pub fn follow_not_connected(
|
|||||||
params: HashMap::new(),
|
params: HashMap::new(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
Ok(Ok(Flash::new(
|
Ok(Flash::new(
|
||||||
render!(users::follow_remote(
|
render!(users::follow_remote(
|
||||||
&rockets.to_context(),
|
&rockets.to_context(),
|
||||||
target,
|
target,
|
||||||
@@ -228,10 +228,11 @@ pub fn follow_not_connected(
|
|||||||
)),
|
)),
|
||||||
"callback",
|
"callback",
|
||||||
uri!(follow: name = name).to_string(),
|
uri!(follow: name = name).to_string(),
|
||||||
)))
|
)
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(Ok(Flash::new(
|
Ok(Flash::new(
|
||||||
render!(users::follow_remote(
|
render!(users::follow_remote(
|
||||||
&rockets.to_context(),
|
&rockets.to_context(),
|
||||||
target,
|
target,
|
||||||
@@ -243,7 +244,8 @@ pub fn follow_not_connected(
|
|||||||
)),
|
)),
|
||||||
"callback",
|
"callback",
|
||||||
uri!(follow: name = name).to_string(),
|
uri!(follow: name = name).to_string(),
|
||||||
)))
|
)
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,7 +520,7 @@ pub fn create(
|
|||||||
false,
|
false,
|
||||||
"",
|
"",
|
||||||
form.email.to_string(),
|
form.email.to_string(),
|
||||||
User::hash_pass(&form.password).map_err(to_validation)?,
|
&form.password,
|
||||||
)
|
)
|
||||||
.map_err(to_validation)?;
|
.map_err(to_validation)?;
|
||||||
Ok(Flash::success(
|
Ok(Flash::success(
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ pub fn avatar(
|
|||||||
pub fn tabs(links: &[(&str, String, bool)]) -> Html<String> {
|
pub fn tabs(links: &[(&str, String, bool)]) -> Html<String> {
|
||||||
let mut res = String::from(r#"<div class="tabs">"#);
|
let mut res = String::from(r#"<div class="tabs">"#);
|
||||||
for (url, title, selected) in links {
|
for (url, title, selected) in links {
|
||||||
res.push_str(r#"<a href=""#);
|
res.push_str(r#"<a dir="auto" href=""#);
|
||||||
res.push_str(url);
|
res.push_str(url);
|
||||||
if *selected {
|
if *selected {
|
||||||
res.push_str(r#"" class="selected">"#);
|
res.push_str(r#"" class="selected">"#);
|
||||||
@@ -176,7 +176,7 @@ pub fn paginate_param(
|
|||||||
p
|
p
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
res.push_str(r#"<div class="pagination">"#);
|
res.push_str(r#"<div class="pagination" dir="auto">"#);
|
||||||
if page != 1 {
|
if page != 1 {
|
||||||
res.push_str(
|
res.push_str(
|
||||||
format!(
|
format!(
|
||||||
@@ -239,13 +239,13 @@ macro_rules! input {
|
|||||||
|
|
||||||
Html(format!(
|
Html(format!(
|
||||||
r#"
|
r#"
|
||||||
<label for="{name}">
|
<label for="{name}" dir="auto">
|
||||||
{label}
|
{label}
|
||||||
{optional}
|
{optional}
|
||||||
{details}
|
{details}
|
||||||
</label>
|
</label>
|
||||||
{error}
|
{error}
|
||||||
<input type="{kind}" id="{name}" name="{name}" value="{val}" {props}/>
|
<input type="{kind}" id="{name}" name="{name}" value="{val}" {props} dir="auto"/>
|
||||||
"#,
|
"#,
|
||||||
name = stringify!($name),
|
name = stringify!($name),
|
||||||
label = i18n!(cat, $label),
|
label = i18n!(cat, $label),
|
||||||
@@ -264,7 +264,7 @@ macro_rules! input {
|
|||||||
$err.errors().get(stringify!($name))
|
$err.errors().get(stringify!($name))
|
||||||
{
|
{
|
||||||
format!(
|
format!(
|
||||||
r#"<p class="error">{}</p>"#,
|
r#"<p class="error" dir="auto">{}</p>"#,
|
||||||
errs[0]
|
errs[0]
|
||||||
.message
|
.message
|
||||||
.clone()
|
.clone()
|
||||||
@@ -332,8 +332,8 @@ macro_rules! input {
|
|||||||
let cat = $catalog;
|
let cat = $catalog;
|
||||||
Html(format!(
|
Html(format!(
|
||||||
r#"
|
r#"
|
||||||
<label for="{name}">{label}</label>
|
<label for="{name}" dir="auto">{label}</label>
|
||||||
<input type="{kind}" id="{name}" name="{name}" {props}/>
|
<input type="{kind}" id="{name}" name="{name}" {props} dir="auto"/>
|
||||||
"#,
|
"#,
|
||||||
name = stringify!($name),
|
name = stringify!($name),
|
||||||
label = i18n!(cat, $label),
|
label = i18n!(cat, $label),
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ form input[type="submit"] {
|
|||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
|
overflow-y: scroll;
|
||||||
font-family: $lora;
|
font-family: $lora;
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
@@ -127,7 +127,7 @@ form.new-post {
|
|||||||
}
|
}
|
||||||
textarea {
|
textarea {
|
||||||
min-height: 20em;
|
min-height: 20em;
|
||||||
overflow-y: hidden;
|
overflow-y: scroll;
|
||||||
resize: none;
|
resize: none;
|
||||||
-webkit-appearance: textarea;
|
-webkit-appearance: textarea;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<link href='@Instance::get_local().unwrap().compute_box("~", &blog.fqn, "atom.xml")' rel='alternate' type='application/atom+xml'>
|
<link href='@Instance::get_local().unwrap().compute_box("~", &blog.fqn, "atom.xml")' rel='alternate' type='application/atom+xml'>
|
||||||
<link href='@blog.ap_url' rel='alternate' type='application/activity+json'>
|
<link href='@blog.ap_url' rel='alternate' type='application/activity+json'>
|
||||||
}, {
|
}, {
|
||||||
<a href="@uri!(blogs::details: name = &blog.fqn, page = _)">@blog.title</a>
|
<a href="@uri!(blogs::details: name = &blog.fqn, page = _)" dir="auto">@blog.title</a>
|
||||||
}, {
|
}, {
|
||||||
<div class="hidden">
|
<div class="hidden">
|
||||||
@for author in authors {
|
@for author in authors {
|
||||||
@@ -41,38 +41,38 @@
|
|||||||
}
|
}
|
||||||
<div class="h-card">
|
<div class="h-card">
|
||||||
<div class="user">
|
<div class="user">
|
||||||
<div class="flex wrap">
|
<div class="flex wrap" dir="auto">
|
||||||
<div class="avatar medium" style="background-image: url('@blog.icon_url(ctx.0)');" aria-label="@i18n!(ctx.1, "{}'s icon"; &blog.title)"></div>
|
<div class="avatar medium" style="background-image: url('@blog.icon_url(ctx.0)');" aria-label="@i18n!(ctx.1, "{}'s icon"; &blog.title)"></div>
|
||||||
<img class="hidden u-photo" src="@blog.icon_url(ctx.0)"/>
|
<img class="hidden u-photo" src="@blog.icon_url(ctx.0)"/>
|
||||||
|
|
||||||
<h1 class="grow flex vertical">
|
<h1 class="grow flex vertical">
|
||||||
<span class="p-name">@blog.title</span>
|
<span class="p-name">@blog.title</span>
|
||||||
<small>~@blog.fqn</small>
|
<small dir="auto">~@blog.fqn</small>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
@if ctx.2.clone().and_then(|u| u.is_author_in(ctx.0, &blog).ok()).unwrap_or(false) {
|
@if ctx.2.clone().and_then(|u| u.is_author_in(ctx.0, &blog).ok()).unwrap_or(false) {
|
||||||
<a href="@uri!(posts::new: blog = &blog.fqn)" class="button">@i18n!(ctx.1, "New article")</a>
|
<a href="@uri!(posts::new: blog = &blog.fqn)" class="button" dir="auto">@i18n!(ctx.1, "New article")</a>
|
||||||
<a href="@uri!(blogs::edit: name = &blog.fqn)" class="button">@i18n!(ctx.1, "Edit")</a>
|
<a href="@uri!(blogs::edit: name = &blog.fqn)" class="button" dir="auto">@i18n!(ctx.1, "Edit")</a>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<main class="user-summary">
|
<main class="user-summary" dir="auto">
|
||||||
<p>
|
<p>
|
||||||
@i18n!(ctx.1, "There's one author on this blog: ", "There are {0} authors on this blog: "; authors.len())
|
@i18n!(ctx.1, "There's one author on this blog: ", "There are {0} authors on this blog: "; authors.len())
|
||||||
@for (i, author) in authors.iter().enumerate() {@if i >= 1 {, }
|
@for (i, author) in authors.iter().enumerate() {@if i >= 1 {, }
|
||||||
<a class="author p-author" href="@uri!(user::details: name = &author.fqn)">@author.name()</a>}
|
<a class="author p-author" href="@uri!(user::details: name = &author.fqn)" dir="auto">@author.name()</a>}
|
||||||
</p>
|
</p>
|
||||||
@Html(blog.summary_html.clone())
|
@Html(blog.summary_html.clone())
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2>
|
<h2 dir="auto">
|
||||||
@i18n!(ctx.1, "Latest articles")
|
@i18n!(ctx.1, "Latest articles")
|
||||||
<small><a href="@uri!(blogs::atom_feed: name = &blog.fqn)" title="Atom feed">@icon!("rss")</a></small>
|
<small><a href="@uri!(blogs::atom_feed: name = &blog.fqn)" title="Atom feed">@icon!("rss")</a></small>
|
||||||
</h2>
|
</h2>
|
||||||
@if posts.is_empty() {
|
@if posts.is_empty() {
|
||||||
<p>@i18n!(ctx.1, "No posts to see here yet.")</p>
|
<p dir="auto">@i18n!(ctx.1, "No posts to see here yet.")</p>
|
||||||
}
|
}
|
||||||
<div class="cards">
|
<div class="cards">
|
||||||
@for article in posts {
|
@for article in posts {
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
@(ctx: BaseContext, form: &NewBlogForm, errors: ValidationErrors)
|
@(ctx: BaseContext, form: &NewBlogForm, errors: ValidationErrors)
|
||||||
|
|
||||||
@:base(ctx, i18n!(ctx.1, "New Blog"), {}, {}, {
|
@:base(ctx, i18n!(ctx.1, "New Blog"), {}, {}, {
|
||||||
<h1>@i18n!(ctx.1, "Create a blog")</h1>
|
<h1 dir="auto">@i18n!(ctx.1, "Create a blog")</h1>
|
||||||
<form method="post" action="@uri!(blogs::create)">
|
<form method="post" action="@uri!(blogs::create)">
|
||||||
@input!(ctx.1, title (text), "Title", form, errors, "required minlength=\"1\"")
|
@input!(ctx.1, title (text), "Title", form, errors, "required minlength=\"1\"")
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Create blog")"/>
|
<input type="submit" value="@i18n!(ctx.1, "Create blog")" dir="auto"/>
|
||||||
</form>
|
</form>
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<div class="comment u-comment h-cite" id="comment-@comm.id">
|
<div class="comment u-comment h-cite" id="comment-@comm.id">
|
||||||
<main class="content">
|
<main class="content">
|
||||||
<header>
|
<header>
|
||||||
<a class="author u-author h-card" href="@uri!(user::details: name = &author.fqn)">
|
<a class="author u-author h-card" href="@uri!(user::details: name = &author.fqn)" dir="auto">
|
||||||
@avatar(ctx.0, &author, Size::Small, true, ctx.1)
|
@avatar(ctx.0, &author, Size::Small, true, ctx.1)
|
||||||
<span class="display-name p-name">@author.name()</span>
|
<span class="display-name p-name">@author.name()</span>
|
||||||
<small>@author.fqn</small>
|
<small>@author.fqn</small>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
<div class="text p-content">
|
<div class="text p-content">
|
||||||
@if comm.sensitive {
|
@if comm.sensitive {
|
||||||
<details>
|
<details>
|
||||||
<summary>@comm.spoiler_text</summary>
|
<summary dir="auto">@comm.spoiler_text</summary>
|
||||||
}
|
}
|
||||||
@Html(&comm.content)
|
@Html(&comm.content)
|
||||||
@if comm.sensitive {
|
@if comm.sensitive {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
@if !articles.is_empty() {
|
@if !articles.is_empty() {
|
||||||
<div class="h-feed">
|
<div class="h-feed">
|
||||||
<h2><span class="p-name">@title</span> — <a href="@link">@i18n!(ctx.1, "View all")</a></h2>
|
<h2 dir="auto"><span class="p-name">@title</span> — <a href="@link">@i18n!(ctx.1, "View all")</a></h2>
|
||||||
<div class="cards">
|
<div class="cards">
|
||||||
@for article in articles {
|
@for article in articles {
|
||||||
@:post_card(ctx, article)
|
@:post_card(ctx, article)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
@(ctx: BaseContext, id: &str, title: String, optional: bool, medias: Vec<Media>, selected: Option<i32>)
|
@(ctx: BaseContext, id: &str, title: String, optional: bool, medias: Vec<Media>, selected: Option<i32>)
|
||||||
|
|
||||||
<label for="@id">
|
<label for="@id" dir="auto">
|
||||||
@title
|
@title
|
||||||
@if optional {
|
@if optional {
|
||||||
<small>@i18n!(ctx.1, "Optional")</small>
|
<small>@i18n!(ctx.1, "Optional")</small>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<option value="none" @if selected.is_none() { selected }>@i18n!(ctx.1, "None")</option>
|
<option value="none" @if selected.is_none() { selected }>@i18n!(ctx.1, "None")</option>
|
||||||
@for media in medias {
|
@for media in medias {
|
||||||
@if media.category() == MediaCategory::Image {
|
@if media.category() == MediaCategory::Image {
|
||||||
<option value="@media.id" @if selected.map(|c| c == media.id).unwrap_or(false) { selected }>
|
<option value="@media.id" @if selected.map(|c| c == media.id).unwrap_or(false) { selected } dir="auto">
|
||||||
@if !media.alt_text.is_empty() {
|
@if !media.alt_text.is_empty() {
|
||||||
@media.alt_text
|
@media.alt_text
|
||||||
} else {
|
} else {
|
||||||
@@ -22,4 +22,4 @@
|
|||||||
</option>
|
</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
@(ctx: BaseContext, instance: Instance, n_users: i64, n_articles: i64)
|
@(ctx: BaseContext, instance: Instance, n_users: i64, n_articles: i64)
|
||||||
|
|
||||||
<section class="split">
|
<section class="split" dir="auto">
|
||||||
<div class="presentation card">
|
<div class="presentation card">
|
||||||
<h2>@i18n!(ctx.1, "What is Plume?")</h2>
|
<h2>@i18n!(ctx.1, "What is Plume?")</h2>
|
||||||
<main>
|
<main>
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
@if article.cover_id.is_some() {
|
@if article.cover_id.is_some() {
|
||||||
<div class="cover" style="background-image: url('@Html(article.cover_url(ctx.0).unwrap_or_default())')"></div>
|
<div class="cover" style="background-image: url('@Html(article.cover_url(ctx.0).unwrap_or_default())')"></div>
|
||||||
}
|
}
|
||||||
<h3 class="p-name">
|
<h3 class="p-name" dir="auto">
|
||||||
<a class="u-url" href="@uri!(posts::details: blog = article.get_blog(ctx.0).unwrap().fqn, slug = &article.slug, responding_to = _)">
|
<a class="u-url" href="@uri!(posts::details: blog = article.get_blog(ctx.0).unwrap().fqn, slug = &article.slug, responding_to = _)">
|
||||||
@article.title
|
@article.title
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
<main>
|
<main>
|
||||||
<p class="p-summary">@article.subtitle</p>
|
<p class="p-summary" dir="auto">@article.subtitle</p>
|
||||||
</main>
|
</main>
|
||||||
<footer class="authors">
|
<footer class="authors">
|
||||||
@Html(i18n!(ctx.1, "By {0}"; format!(
|
@Html(i18n!(ctx.1, "By {0}"; format!(
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
@if article.cover_id.is_some() { style="background-image: url('@article.cover_url(ctx.0).unwrap_or_default()'" }
|
@if article.cover_id.is_some() { style="background-image: url('@article.cover_url(ctx.0).unwrap_or_default()'" }
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="article p-name">@article.title</h1>
|
<h1 class="article p-name" dir="auto">@article.title</h1>
|
||||||
<div class="article-info">
|
<div class="article-info" dir="auto">
|
||||||
<span class="author">
|
<span class="author">
|
||||||
@Html(i18n!(ctx.1, "Written by {0}"; format!("<a href=\"{}\">{}</a>",
|
@Html(i18n!(ctx.1, "Written by {0}"; format!("<a href=\"{}\">{}</a>",
|
||||||
uri!(user::details: name = &author.fqn),
|
uri!(user::details: name = &author.fqn),
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
—
|
—
|
||||||
<span class="date dt-published" datetime="@article.creation_date.format("%F %T")">@article.creation_date.format("%B %e, %Y")</span><a class="u-url" href="@article.ap_url"></a>
|
<span class="date dt-published" datetime="@article.creation_date.format("%F %T")">@article.creation_date.format("%B %e, %Y")</span><a class="u-url" href="@article.ap_url"></a>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="article p-summary">@article.subtitle</h2>
|
<h2 class="article p-summary" dir="auto">@article.subtitle</h2>
|
||||||
</div>
|
</div>
|
||||||
@if article.cover_id.is_some() {
|
@if article.cover_id.is_some() {
|
||||||
<div class="shadow"></div>
|
<div class="shadow"></div>
|
||||||
@@ -46,12 +46,12 @@
|
|||||||
}
|
}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<article class="e-content">
|
<article class="e-content" dir="auto">
|
||||||
@Html(&article.content)
|
@Html(&article.content)
|
||||||
</article>
|
</article>
|
||||||
<div class="article-meta">
|
<div class="article-meta">
|
||||||
<section class="split">
|
<section class="split">
|
||||||
<ul class="tags">
|
<ul class="tags" dir="auto">
|
||||||
@for tag in tags {
|
@for tag in tags {
|
||||||
@if !tag.is_hashtag {
|
@if !tag.is_hashtag {
|
||||||
<li><a class="p-category" href="@uri!(tags::tag: name = &tag.tag, page = _)">@tag.tag</a></li>
|
<li><a class="p-category" href="@uri!(tags::tag: name = &tag.tag, page = _)">@tag.tag</a></li>
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
<p class="right">
|
<p class="right" dir="auto">
|
||||||
@if article.license.is_empty() {
|
@if article.license.is_empty() {
|
||||||
@i18n!(ctx.1, "All rights reserved."; &article.license)
|
@i18n!(ctx.1, "All rights reserved."; &article.license)
|
||||||
} else {
|
} else {
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
</section>
|
</section>
|
||||||
}
|
}
|
||||||
<section class="banner">
|
<section class="banner">
|
||||||
<div class="flex p-author h-card user">
|
<div class="flex p-author h-card user" dir="auto">
|
||||||
@avatar(ctx.0, &author, Size::Medium, true, ctx.1)
|
@avatar(ctx.0, &author, Size::Medium, true, ctx.1)
|
||||||
<div class="grow">
|
<div class="grow">
|
||||||
<h2 class="p-name">
|
<h2 class="p-name">
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="comments">
|
<section class="comments" dir="auto">
|
||||||
<h2>@i18n!(ctx.1, "Comments")</h2>
|
<h2>@i18n!(ctx.1, "Comments")</h2>
|
||||||
|
|
||||||
@if ctx.2.is_some() {
|
@if ctx.2.is_some() {
|
||||||
@@ -143,7 +143,7 @@
|
|||||||
@if let Some(ref prev) = previous_comment {
|
@if let Some(ref prev) = previous_comment {
|
||||||
<input type="hidden" name="responding_to" value="@prev.id"/>
|
<input type="hidden" name="responding_to" value="@prev.id"/>
|
||||||
}
|
}
|
||||||
<textarea id="plume-editor" name="content">@comment_form.content</textarea>
|
<textarea id="plume-editor" name="content" dir="auto">@comment_form.content</textarea>
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Submit comment")" />
|
<input type="submit" value="@i18n!(ctx.1, "Submit comment")" />
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@
|
|||||||
@:comment(ctx, &comm, Some(&article.ap_url), &blog.fqn, &article.slug)
|
@:comment(ctx, &comm, Some(&article.ap_url), &blog.fqn, &article.slug)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
<p class="center">@i18n!(ctx.1, "No comments yet. Be the first to react!")</p>
|
<p class="center" dir="auto">@i18n!(ctx.1, "No comments yet. Be the first to react!")</p>
|
||||||
}
|
}
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
@(ctx: BaseContext, title: String, blog: Blog, editing: bool, form: &NewPostForm, is_draft: bool, article: Option<Post>, errors: ValidationErrors, medias: Vec<Media>, content_len: u64)
|
@(ctx: BaseContext, title: String, blog: Blog, editing: bool, form: &NewPostForm, is_draft: bool, article: Option<Post>, errors: ValidationErrors, medias: Vec<Media>, content_len: u64)
|
||||||
|
|
||||||
@:base(ctx, title.clone(), {}, {}, {
|
@:base(ctx, title.clone(), {}, {}, {
|
||||||
<h1 id="plume-editor-title">@title</h1>
|
<h1 id="plume-editor-title" dir="auto">@title</h1>
|
||||||
<div id="plume-editor" style="display: none;">
|
<div id="plume-editor" style="display: none;" dir="auto">
|
||||||
<header>
|
<header>
|
||||||
<button id="publish" class="button">@i18n!(ctx.1, "Publish")</button>
|
<button id="publish" class="button">@i18n!(ctx.1, "Publish")</button>
|
||||||
<p id="char-count">@content_len</p>
|
<p id="char-count">@content_len</p>
|
||||||
@@ -32,10 +32,10 @@
|
|||||||
@format!(r#"<p class="error">{}</p>"#, errs[0].message.clone().unwrap_or_else(|| Cow::from("Unknown error")))
|
@format!(r#"<p class="error">{}</p>"#, errs[0].message.clone().unwrap_or_else(|| Cow::from("Unknown error")))
|
||||||
}
|
}
|
||||||
|
|
||||||
<label for="editor-content">@i18n!(ctx.1, "Content")<small>@i18n!(ctx.1, "Markdown syntax is supported")</small></label>
|
<label for="editor-content" dir="auto">@i18n!(ctx.1, "Content")<small>@i18n!(ctx.1, "Markdown syntax is supported")</small></label>
|
||||||
<textarea id="editor-content" name="content" rows="20">@Html(&form.content)</textarea>
|
<textarea id="editor-content" name="content" rows="20" dir="auto">@Html(&form.content)</textarea>
|
||||||
<small id="editor-left">@content_len</small>
|
<small id="editor-left" dir="auto">@content_len</small>
|
||||||
<p>
|
<p dir="auto">
|
||||||
@i18n!(ctx.1, "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them.")
|
@i18n!(ctx.1, "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them.")
|
||||||
<a href="@uri!(medias::new)">@i18n!(ctx.1, "Upload media")</a>
|
<a href="@uri!(medias::new)">@i18n!(ctx.1, "Upload media")</a>
|
||||||
</p>
|
</p>
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
@:image_select(ctx, "cover", i18n!(ctx.1, "Illustration"), true, medias, form.cover)
|
@:image_select(ctx, "cover", i18n!(ctx.1, "Illustration"), true, medias, form.cover)
|
||||||
|
|
||||||
@if is_draft {
|
@if is_draft {
|
||||||
<label for="draft">
|
<label for="draft" dir="auto">
|
||||||
<input type="checkbox" name="draft" id="draft" checked>
|
<input type="checkbox" name="draft" id="draft" checked>
|
||||||
@i18n!(ctx.1, "This is a draft, don't publish it yet.")
|
@i18n!(ctx.1, "This is a draft, don't publish it yet.")
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
@(ctx: BaseContext, post: Post, login_form: LoginForm, login_errs: ValidationErrors, remote_form: RemoteForm, remote_errs: ValidationErrors)
|
@(ctx: BaseContext, post: Post, login_form: LoginForm, login_errs: ValidationErrors, remote_form: RemoteForm, remote_errs: ValidationErrors)
|
||||||
|
|
||||||
@:remote_interact_base(ctx, i18n!(ctx.1, "Interact with {}"; post.title.clone()), i18n!(ctx.1, "Log in to interact"), i18n!(ctx.1, "Enter your full username to interact"), {
|
@:remote_interact_base(ctx, i18n!(ctx.1, "Interact with {}"; post.title.clone()), i18n!(ctx.1, "Log in to interact"), i18n!(ctx.1, "Enter your full username to interact"), {
|
||||||
<h1>@i18n!(ctx.1, "Interact with {}"; post.title.clone())</h1>
|
<h1 dir="auto">@i18n!(ctx.1, "Interact with {}"; post.title.clone())</h1>
|
||||||
@:post_card(ctx, post)
|
@:post_card(ctx, post)
|
||||||
}, login_form, login_errs, remote_form, remote_errs)
|
}, login_form, login_errs, remote_form, remote_errs)
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
@use template_utils::*;
|
||||||
|
@use templates::base;
|
||||||
|
|
||||||
|
@(ctx: BaseContext)
|
||||||
|
|
||||||
|
@:base(ctx, i18n!(ctx.1, "Password reset"), {}, {}, {
|
||||||
|
<h1>@i18n!(ctx.1, "This token has expired")</h1>
|
||||||
|
<p>@i18n!(ctx.1, "Please start the process again by clicking") <a href="/password-reset">@i18n!(ctx.1, "here")</a>.</p>
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user