Browse Source

Do proper pagination with max_id/since_id

master
Puck Meerburg 1 year ago
parent
commit
ece09cf130
3 changed files with 50 additions and 5 deletions
  1. 1
    0
      Cargo.toml
  2. 48
    5
      src/collection.rs
  3. 1
    0
      src/lib.rs

+ 1
- 0
Cargo.toml View File

@@ -13,3 +13,4 @@ serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
jsonld = { path = "../jsonld-rs" }
url = "1.7"

+ 48
- 5
src/collection.rs View File

@@ -4,16 +4,17 @@ use futures::{
stream, Future, Stream,
};
use helpers::get_subelem;
use hyper::{Body, Method, Request, Response};
use hyper::{Body, Method, Request, Response, Uri};
use id;
use id::{decode, encode};
use jsonld::nodemap::{Entity, Pointer, Value};
use kroeg_server::ServerError;
use kroeg_tap::{Context, EntityStore, QueueStore, StoreItem};
use models::{Account, Emoji, Status};
use serde_json::{self, Value as JValue};

use models::Instance;
use statuses;
use std::collections::HashMap;
use url::form_urlencoded;

fn translate_one<T: EntityStore>(
item: Option<StoreItem>,
@@ -63,6 +64,46 @@ pub(crate) fn get_notifications<T: EntityStore, R: QueueStore>(
)))
}

fn get_cursor<T: EntityStore>(
uri: &Uri,
collection: &str,
store: T,
) -> impl Future<Item = (Option<String>, T), Error = (T::Error, T)> + Send {
let query = uri.query();
if let Some(query) = query {
let mut parsed = form_urlencoded::parse(query.as_bytes())
.into_owned()
.collect::<HashMap<_, _>>();
if let Some(cursor) = parsed.remove(&String::from("cursor")) {
return Either::B(future::ok((Some(cursor), store)));
}

if let Some(max_id) = parsed
.remove(&String::from("max_id"))
.and_then(|f| id::decode(&f))
{
return Either::A(Either::A(
store
.find_collection(collection.to_owned(), max_id)
.map(|(item, store)| (item.after, store)),
));
}

if let Some(since_id) = parsed
.remove(&String::from("since_id"))
.and_then(|f| id::decode(&f))
{
return Either::A(Either::B(
store
.find_collection(collection.to_owned(), since_id)
.map(|(item, store)| (item.before, store)),
));
}
}

Either::B(future::ok((None, store)))
}

pub(crate) fn get_timeline<T: EntityStore, R: QueueStore>(
context: Context,
store: T,
@@ -83,8 +124,10 @@ pub(crate) fn get_timeline<T: EntityStore, R: QueueStore>(
}

Box::new(
store
.read_collection("https://puckipedia.com/inbox".to_owned(), None, None)
get_cursor(request.uri(), "https://puckipedia.com/inbox", store)
.and_then(|(cursor, store)| {
store.read_collection("https://puckipedia.com/inbox".to_owned(), None, cursor)
})
.and_then(move |(pointer, store)| {
stream::iter_ok(pointer.items)
.fold((vec![], store), |(mut items, store), item| {

+ 1
- 0
src/lib.rs View File

@@ -9,6 +9,7 @@ extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate url;

use kroeg_server::router::Route;
use kroeg_server::KroegServiceBuilder;

Loading…
Cancel
Save