Profiles: Add open+close report date range queries

This commit is contained in:
asonix 2021-02-04 21:03:43 -06:00
parent 5940264ffd
commit 426726286d
3 changed files with 144 additions and 36 deletions

View file

@ -58,7 +58,11 @@ impl Outbound for ReportCreated {
}
fn inboxes(&self, ctx: &Context) -> Result<Vec<Url>, Error> {
let report = ctx.store.reports.by_id(self.report_id)?;
let report = ctx
.store
.reports
.by_id(self.report_id)?
.req("report by id")?;
let server_id = server_from_report(&report, ctx)?;
@ -73,7 +77,11 @@ impl Outbound for ReportCreated {
}
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let report = ctx.store.reports.by_id(self.report_id)?;
let report = ctx
.store
.reports
.by_id(self.report_id)?
.req("report by id")?;
let server_id = server_from_report(&report, ctx)?;
let actor_id = ctx
.apub

View file

@ -180,45 +180,133 @@ impl Store {
Ok(report)
}
pub fn all(&self) -> impl DoubleEndedIterator<Item = Uuid> {
self.created_open_report
.iter()
pub fn open_reports(&self) -> impl DoubleEndedIterator<Item = Uuid> {
let start: &[u8] = &[];
self.open_reports_date_range(start..).rev()
}
pub fn closed_reports(&self) -> impl DoubleEndedIterator<Item = Uuid> {
let start: &[u8] = &[];
self.closed_reports_date_range(start..).rev()
}
pub fn open_reports_newer_than<'a>(
&'a self,
id: Uuid,
) -> impl DoubleEndedIterator<Item = Uuid> + 'a {
self.report_created
.get(id.as_bytes())
.ok()
.and_then(|opt| opt)
.and_then(date_from_ivec)
.into_iter()
.flat_map(move |created| {
self.open_reports_date_range(created_open_reports_bound(created)..)
})
}
pub fn open_reports_older_than<'a>(
&'a self,
id: Uuid,
) -> impl DoubleEndedIterator<Item = Uuid> + 'a {
self.report_created
.get(id.as_bytes())
.ok()
.and_then(|opt| opt)
.and_then(date_from_ivec)
.into_iter()
.flat_map(move |created| {
self.open_reports_date_range(..created_open_reports_bound(created))
})
.rev()
}
pub fn closed_reports_newer_than<'a>(
&'a self,
id: Uuid,
) -> impl DoubleEndedIterator<Item = Uuid> + 'a {
self.report_resolved
.get(id.as_bytes())
.ok()
.and_then(|opt| opt)
.and_then(date_from_ivec)
.into_iter()
.flat_map(move |resolved| {
self.closed_reports_date_range(resolved_resolved_reports_bound(resolved)..)
})
}
pub fn closed_reports_older_than<'a>(
&'a self,
id: Uuid,
) -> impl DoubleEndedIterator<Item = Uuid> + 'a {
self.report_resolved
.get(id.as_bytes())
.ok()
.and_then(|opt| opt)
.and_then(date_from_ivec)
.into_iter()
.flat_map(move |resolved| {
self.closed_reports_date_range(..resolved_resolved_reports_bound(resolved))
})
.rev()
}
fn closed_reports_date_range<K>(
&self,
range: impl std::ops::RangeBounds<K>,
) -> impl DoubleEndedIterator<Item = Uuid>
where
K: AsRef<[u8]>,
{
self.resolved_resolved_report
.range(range)
.values()
.filter_map(|res| res.ok())
.filter_map(uuid_from_ivec)
}
pub fn by_id(&self, id: Uuid) -> Result<Report, StoreError> {
fn open_reports_date_range<K>(
&self,
range: impl std::ops::RangeBounds<K>,
) -> impl DoubleEndedIterator<Item = Uuid>
where
K: AsRef<[u8]>,
{
self.created_open_report
.range(range)
.values()
.filter_map(|res| res.ok())
.filter_map(uuid_from_ivec)
}
pub fn by_id(&self, id: Uuid) -> Result<Option<Report>, StoreError> {
let reporter_kind = self
.report_reporter_kind
.get(id.as_bytes())?
.and_then(reporter_kind_from_ivec)
.ok_or_else(|| StoreError::Missing)?;
let reporter_opt = match reporter_kind {
ReporterKind::Profile => self.report_profile.get(id.as_bytes())?,
ReporterKind::Server => self.report_server.get(id.as_bytes())?,
};
.and_then(reporter_kind_from_ivec);
let reporter = reporter_opt
.and_then(uuid_from_ivec)
.ok_or_else(|| StoreError::Missing)?;
let reporter_opt = match reporter_kind {
Some(ReporterKind::Profile) => self.report_profile.get(id.as_bytes())?,
Some(ReporterKind::Server) => self.report_server.get(id.as_bytes())?,
None => None,
};
let reporter = reporter_opt.and_then(uuid_from_ivec);
let kind = self
.report_kind
.get(id.as_bytes())?
.and_then(kind_from_ivec)
.ok_or_else(|| StoreError::Missing)?;
.and_then(kind_from_ivec);
let reported_item_opt = match kind {
ReportKind::Profile => self.report_reported_profile.get(id.as_bytes())?,
ReportKind::Submission => self.report_reported_submission.get(id.as_bytes())?,
ReportKind::Comment => self.report_reported_comment.get(id.as_bytes())?,
ReportKind::Post => self.report_reported_post.get(id.as_bytes())?,
Some(ReportKind::Profile) => self.report_reported_profile.get(id.as_bytes())?,
Some(ReportKind::Submission) => self.report_reported_submission.get(id.as_bytes())?,
Some(ReportKind::Comment) => self.report_reported_comment.get(id.as_bytes())?,
Some(ReportKind::Post) => self.report_reported_post.get(id.as_bytes())?,
None => None,
};
let reported_item = reported_item_opt
.and_then(uuid_from_ivec)
.ok_or_else(|| StoreError::Missing)?;
let reported_item = reported_item_opt.and_then(uuid_from_ivec);
let note = self.report_note.get(id.as_bytes())?.map(string_from_ivec);
@ -235,17 +323,21 @@ impl Store {
.get(id.as_bytes())?
.and_then(date_from_ivec);
Ok(Report {
id,
reporter,
reporter_kind,
reported_item,
kind,
note,
resolved,
resolution,
forwarded,
})
let optionable = move || -> Option<Report> {
Some(Report {
id,
reporter: reporter?,
reporter_kind: reporter_kind?,
reported_item: reported_item?,
kind: kind?,
note,
resolved,
resolution,
forwarded,
})
};
Ok((optionable)())
}
pub(crate) fn forwarded(&self, report_id: Uuid) -> Result<Option<DateTime<Utc>>, StoreError> {
@ -371,6 +463,10 @@ fn created_open_reports_key(created_at: DateTime<Utc>, report_id: Uuid) -> Strin
format!("/created/{}/report/{}", created_at.to_rfc3339(), report_id)
}
fn created_open_reports_bound(created_at: DateTime<Utc>) -> String {
format!("/created/{}/report/", created_at.to_rfc3339())
}
fn resolved_resolved_reports_key(resolved_at: DateTime<Utc>, report_id: Uuid) -> String {
format!(
"/resolved/{}/report/{}",
@ -378,3 +474,7 @@ fn resolved_resolved_reports_key(resolved_at: DateTime<Utc>, report_id: Uuid) ->
report_id
)
}
fn resolved_resolved_reports_bound(resolved_at: DateTime<Utc>) -> String {
format!("/resolved/{}/report/", resolved_at.to_rfc3339())
}

View file

@ -64,7 +64,7 @@ impl Viewer {
Ok(true)
}
(Viewer::Server(viewer_id), StoredRecords::Report(report_id)) => {
let report = ctx.store.reports.by_id(report_id)?;
let report = ctx.store.reports.by_id(report_id)?.req("report by id")?;
let server_id = item_server_for_report(&report, ctx)?;
if *viewer_id == server_id {