Get article revisions from database during diff lookup.
Diffs for missing revisions now cause 404-errors
This commit is contained in:
parent
2e5b549ea8
commit
bfd2acda4f
2 changed files with 38 additions and 35 deletions
|
@ -1,20 +1,20 @@
|
||||||
use std::{self, fmt};
|
use std::fmt;
|
||||||
|
|
||||||
use diff;
|
use diff;
|
||||||
use futures::{self, Future};
|
use futures::{self, Future};
|
||||||
use futures::future::done;
|
use futures::future::{finished, done};
|
||||||
use hyper;
|
use hyper;
|
||||||
use hyper::header::ContentType;
|
use hyper::header::ContentType;
|
||||||
use hyper::server::*;
|
use hyper::server::*;
|
||||||
use serde_urlencoded;
|
use serde_urlencoded;
|
||||||
|
|
||||||
use mimes::*;
|
use mimes::*;
|
||||||
|
use models::ArticleRevision;
|
||||||
use site::Layout;
|
use site::Layout;
|
||||||
use state::State;
|
use state::State;
|
||||||
use web::{Resource, ResponseFuture};
|
use web::{Resource, ResponseFuture};
|
||||||
|
|
||||||
type BoxResource = Box<Resource + Sync + Send>;
|
type BoxResource = Box<Resource + Sync + Send>;
|
||||||
type Error = Box<std::error::Error + Send + Sync>;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DiffLookup {
|
pub struct DiffLookup {
|
||||||
|
@ -47,31 +47,35 @@ impl DiffLookup {
|
||||||
pub fn lookup(&self, article_id: u32, query: Option<&str>) -> Box<Future<Item=Option<BoxResource>, Error=::web::Error>> {
|
pub fn lookup(&self, article_id: u32, query: Option<&str>) -> Box<Future<Item=Option<BoxResource>, Error=::web::Error>> {
|
||||||
let state = self.state.clone();
|
let state = self.state.clone();
|
||||||
|
|
||||||
Box::new(done((|| -> Result<Option<BoxResource>, ::web::Error> {
|
Box::new(done(
|
||||||
let params: QueryParameters = serde_urlencoded::from_str(query.unwrap_or(""))?;
|
serde_urlencoded::from_str(query.unwrap_or(""))
|
||||||
|
.map_err(Into::into)
|
||||||
|
).and_then(move |params: QueryParameters| {
|
||||||
|
let from = state.get_article_revision(article_id as i32, params.from as i32);
|
||||||
|
let to = state.get_article_revision(article_id as i32, params.to as i32);
|
||||||
|
|
||||||
Ok(Some(Box::new(DiffResource::new(state, article_id, params.from, params.to))))
|
finished(state).join3(from, to)
|
||||||
}())))
|
}).and_then(move |(state, from, to)| {
|
||||||
|
match (from, to) {
|
||||||
|
(Some(from), Some(to)) =>
|
||||||
|
Ok(Some(Box::new(DiffResource::new(state, from, to)) as BoxResource)),
|
||||||
|
_ =>
|
||||||
|
Ok(None),
|
||||||
|
}
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DiffResource {
|
pub struct DiffResource {
|
||||||
state: State,
|
state: State,
|
||||||
article_id: u32,
|
from: ArticleRevision,
|
||||||
from: u32,
|
to: ArticleRevision,
|
||||||
to: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DiffResource {
|
impl DiffResource {
|
||||||
pub fn new(state: State, article_id: u32, from: u32, to: u32) -> Self {
|
pub fn new(state: State, from: ArticleRevision, to: ArticleRevision) -> Self {
|
||||||
Self { state, article_id, from, to }
|
assert_eq!(from.article_id, to.article_id);
|
||||||
}
|
Self { state, from, to }
|
||||||
|
|
||||||
fn query_args(&self) -> QueryParameters {
|
|
||||||
QueryParameters {
|
|
||||||
from: self.from.clone(),
|
|
||||||
to: self.to.clone(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +96,8 @@ impl Resource for DiffResource {
|
||||||
#[derive(BartDisplay)]
|
#[derive(BartDisplay)]
|
||||||
#[template = "templates/diff.html"]
|
#[template = "templates/diff.html"]
|
||||||
struct Template<'a> {
|
struct Template<'a> {
|
||||||
|
consecutive: bool,
|
||||||
|
article_id: u32,
|
||||||
title: &'a [Diff<char>],
|
title: &'a [Diff<char>],
|
||||||
lines: &'a [Diff<&'a str>],
|
lines: &'a [Diff<&'a str>],
|
||||||
}
|
}
|
||||||
|
@ -103,22 +109,18 @@ impl Resource for DiffResource {
|
||||||
added: Option<T>,
|
added: Option<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let from = self.state.get_article_revision(self.article_id as i32, self.from as i32);
|
|
||||||
let to = self.state.get_article_revision(self.article_id as i32, self.to as i32);
|
|
||||||
|
|
||||||
let head = self.head();
|
let head = self.head();
|
||||||
|
|
||||||
Box::new(head.join3(from, to)
|
Box::new(head
|
||||||
.and_then(move |(head, from, to)| {
|
.and_then(move |head| {
|
||||||
Ok(head
|
Ok(head
|
||||||
.with_body(Layout {
|
.with_body(Layout {
|
||||||
base: Some("../"), // Hmm, should perhaps accept `base` as argument
|
base: Some("../"), // Hmm, should perhaps accept `base` as argument
|
||||||
title: "Difference",
|
title: "Difference",
|
||||||
body: &Template {
|
body: &Template {
|
||||||
title: &diff::chars(
|
consecutive: self.to.revision - self.from.revision == 1,
|
||||||
from.as_ref().map(|x| &*x.title).unwrap_or(""),
|
article_id: self.from.article_id as u32,
|
||||||
to.as_ref().map(|x| &*x.title).unwrap_or("")
|
title: &diff::chars(&self.from.title, &self.to.title)
|
||||||
)
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|x| match x {
|
.map(|x| match x {
|
||||||
diff::Result::Left(x) => Diff { removed: Some(x), ..Default::default() },
|
diff::Result::Left(x) => Diff { removed: Some(x), ..Default::default() },
|
||||||
|
@ -126,10 +128,7 @@ impl Resource for DiffResource {
|
||||||
diff::Result::Right(x) => Diff { added: Some(x), ..Default::default() },
|
diff::Result::Right(x) => Diff { added: Some(x), ..Default::default() },
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
lines: &diff::lines(
|
lines: &diff::lines(&self.from.body, &self.to.body)
|
||||||
from.as_ref().map(|x| &*x.body).unwrap_or(""),
|
|
||||||
to.as_ref().map(|x| &*x.body).unwrap_or("")
|
|
||||||
)
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|x| match x {
|
.map(|x| match x {
|
||||||
diff::Result::Left(x) => Diff { removed: Some(x), ..Default::default() },
|
diff::Result::Left(x) => Diff { removed: Some(x), ..Default::default() },
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<header>
|
|
||||||
<h1>Difference</h1>
|
<div class="notice">
|
||||||
</header>
|
<p>
|
||||||
|
You are viewing the difference between two {{#consecutive?}}consecutive{{/consecutive}}
|
||||||
|
revisions of <a href="_by_id/{{article_id}}">this article</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<h1>{{#title}}{{#.removed}}<span class="removed">{{.}}</span>{{/.removed}}{{#.same}}{{.}}{{/.same}}{{#.added}}<span class="added">{{.}}</span>{{/.added}}{{/title}}</h1>
|
<h1>{{#title}}{{#.removed}}<span class="removed">{{.}}</span>{{/.removed}}{{#.same}}{{.}}{{/.same}}{{#.added}}<span class="added">{{.}}</span>{{/.added}}{{/title}}</h1>
|
||||||
|
|
Loading…
Reference in a new issue