Radish alpha
r
rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5
Radicle web interface
Radicle
Git
http: Modify payloads fields
Sebastian Martinez committed 1 year ago
commit c798e5d4e919ed37e85283a8b8ba2ccd0d1540be
parent 868f7b1
3 files changed +247 -254
modified radicle-httpd/src/api.rs
@@ -1,3 +1,4 @@
+
use std::collections::BTreeMap;
use std::sync::Arc;
use std::time::Duration;

@@ -6,11 +7,12 @@ use axum::http::Method;
use axum::response::{IntoResponse, Json};
use axum::routing::get;
use axum::Router;
+
use radicle::identity::doc::PayloadId;
use radicle::issue::cache::Issues as _;
use radicle::patch::cache::Patches as _;
use radicle::storage::git::Repository;
use serde::{Deserialize, Serialize};
-
use serde_json::json;
+
use serde_json::{json, Value};
use tower_http::cors::{self, CorsLayer};

use radicle::cob::{issue, patch, Author};
@@ -52,7 +54,6 @@ impl Context {
        repo: &R,
        doc: DocAt,
    ) -> Result<repo::Info, error::Error> {
-
        let (_, head) = repo.head()?;
        let DocAt { doc, .. } = doc;
        let rid = repo.id();

@@ -62,19 +63,33 @@ impl Context {
            .into_iter()
            .map(|did| json::author(&Author::new(did), aliases.alias(did.as_key())))
            .collect::<Vec<_>>();
-
        let issues = self.profile.issues(repo)?.counts()?;
-
        let patches = self.profile.patches(repo)?.counts()?;
        let db = &self.profile.database()?;
        let seeding = db.count(&rid).unwrap_or_default();

+
        let payloads: BTreeMap<PayloadId, Value> = doc.payload.into_iter()
+
            .filter_map(|(id, payload)| match id  {
+
                id if id == PayloadId::project() => {
+
                    let Ok((_, head)) = repo.head() else {
+
                        return None
+
                    };
+
                    let (Ok(patches), Ok(issues)) = (self.profile.patches(repo), self.profile.issues(repo)) else {
+
                        return None
+
                    };
+
                    let (Ok(patches), Ok(issues)) = (patches.counts(), issues.counts()) else {
+
                        return None
+
                    };
+

+
                    Some((id, json!({ "data": payload, "meta": { "head": head, "issues": issues, "patches": patches } } )))
+
                },
+
                _ => Some((id, json!({ "data": payload })))
+
              })
+
            .collect();
+

        Ok(repo::Info {
-
            payload: doc.payload,
+
            payloads,
            delegates,
            threshold: doc.threshold,
            visibility: doc.visibility,
-
            head,
-
            issues,
-
            patches,
            rid,
            seeding,
        })
@@ -233,8 +248,7 @@ mod search {
    #[derive(Serialize, Deserialize, Eq, Debug)]
    pub struct SearchResult {
        pub rid: RepoId,
-
        #[serde(flatten)]
-
        pub payload: BTreeMap<PayloadId, Payload>,
+
        pub payloads: BTreeMap<PayloadId, Payload>,
        pub delegates: NonEmpty<serde_json::Value>,
        pub seeds: usize,
        #[serde(skip)]
@@ -267,7 +281,7 @@ mod search {

            Some(SearchResult {
                rid: info.rid,
-
                payload: info.doc.payload,
+
                payloads: info.doc.payload,
                delegates,
                seeds,
                index,
@@ -306,23 +320,17 @@ mod repo {
    use serde::Serialize;
    use serde_json::Value;

-
    use radicle::cob;
-
    use radicle::git::Oid;
-
    use radicle::identity::doc::{Payload, PayloadId};
+
    use radicle::identity::doc::PayloadId;
    use radicle::identity::{RepoId, Visibility};

    /// Repos info.
    #[derive(Serialize)]
    #[serde(rename_all = "camelCase")]
    pub struct Info {
-
        #[serde(flatten)]
-
        pub payload: BTreeMap<PayloadId, Payload>,
+
        pub payloads: BTreeMap<PayloadId, Value>,
        pub delegates: Vec<Value>,
        pub threshold: usize,
        pub visibility: Visibility,
-
        pub head: Oid,
-
        pub patches: cob::patch::PatchCounts,
-
        pub issues: cob::issue::IssueCounts,
        pub rid: RepoId,
        pub seeding: usize,
    }
modified radicle-httpd/src/api/v1/delegates.rs
@@ -3,17 +3,11 @@ use axum::response::IntoResponse;
use axum::routing::get;
use axum::{Json, Router};

-
use radicle::cob::Author;
use radicle::identity::Did;
-
use radicle::issue::cache::Issues as _;
-
use radicle::node::routing::Store;
-
use radicle::node::AliasStore;
-
use radicle::patch::cache::Patches as _;
-
use radicle::storage::{ReadRepository, ReadStorage};
+
use radicle::storage::ReadStorage;

use crate::api::error::Error;
-
use crate::api::repo::Info;
-
use crate::api::{json, Context, PaginationQuery, RepoQuery};
+
use crate::api::{Context, PaginationQuery, RepoQuery};
use crate::axum_extra::{Path, Query};

pub fn router(ctx: Context) -> Router {
@@ -37,7 +31,6 @@ async fn delegates_repos_handler(
    let page = page.unwrap_or(0);
    let per_page = per_page.unwrap_or(10);
    let storage = &ctx.profile.storage;
-
    let db = &ctx.profile.database()?;
    let pinned = &ctx.profile.config.web.pinned;
    let mut repos = match show {
        RepoQuery::All => storage
@@ -59,48 +52,14 @@ async fn delegates_repos_handler(
            if !id.doc.delegates.iter().any(|d| *d == delegate) {
                return None;
            }
-
            let Ok(repo) = storage.repository(id.rid) else {
+
            let Ok((repo, doc)) = ctx.repo(id.rid) else {
                return None;
            };
-
            let Ok((_, head)) = repo.head() else {
+
            let Ok(repo_info) = ctx.repo_info(&repo, doc) else {
                return None;
            };
-
            let Ok(_payload) = id.doc.project() else {
-
                return None;
-
            };
-
            let Ok(issues) = ctx.profile.issues(&repo) else {
-
                return None;
-
            };
-
            let Ok(issues) = issues.counts() else {
-
                return None;
-
            };
-
            let Ok(patches) = ctx.profile.patches(&repo) else {
-
                return None;
-
            };
-
            let Ok(patches) = patches.counts() else {
-
                return None;
-
            };
-

-
            let aliases = ctx.profile.aliases();
-
            let delegates = id
-
                .doc
-
                .delegates
-
                .into_iter()
-
                .map(|did| json::author(&Author::new(did), aliases.alias(did.as_key())))
-
                .collect::<Vec<_>>();
-
            let seeding = db.count(&id.rid).unwrap_or_default();

-
            Some(Info {
-
                payload: id.doc.payload,
-
                delegates,
-
                threshold: id.doc.threshold,
-
                visibility: id.doc.visibility,
-
                head,
-
                issues,
-
                patches,
-
                rid: id.rid,
-
                seeding,
-
            })
+
            Some(repo_info)
        })
        .skip(page * per_page)
        .take(per_page)
@@ -141,10 +100,27 @@ mod routes {
            response.json().await,
            json!([
              {
-
                "xyz.radicle.project": {
-
                  "defaultBranch": "master",
-
                  "description": "Rad repository for tests",
-
                  "name": "hello-world",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "data": {
+
                      "defaultBranch": "master",
+
                      "description": "Rad repository for tests",
+
                      "name": "hello-world",
+
                    },
+
                    "meta": {
+
                      "head": HEAD,
+
                      "patches": {
+
                        "open": 1,
+
                        "draft": 0,
+
                        "archived": 0,
+
                        "merged": 0,
+
                      },
+
                      "issues": {
+
                        "open": 1,
+
                        "closed": 0,
+
                      },
+
                    }
+
                  }
                },
                "delegates": [
                  {
@@ -156,25 +132,31 @@ mod routes {
                "visibility": {
                  "type": "public"
                },
-
                "head": HEAD,
-
                "patches": {
-
                  "open": 1,
-
                  "draft": 0,
-
                  "archived": 0,
-
                  "merged": 0,
-
                },
-
                "issues": {
-
                  "open": 1,
-
                  "closed": 0,
-
                },
                "rid": RID,
                "seeding": 1,
              },
              {
-
                "xyz.radicle.project": {
-
                  "defaultBranch": "master",
-
                  "description": "Rad repository for sorting",
-
                  "name": "again-hello-world",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "data": {
+
                      "defaultBranch": "master",
+
                      "description": "Rad repository for sorting",
+
                      "name": "again-hello-world",
+
                    },
+
                    "meta": {
+
                      "head": "344dcd184df5bf37aab6c107fa9371a1c5b3321a",
+
                      "patches": {
+
                        "open": 0,
+
                        "draft": 0,
+
                        "archived": 0,
+
                        "merged": 0,
+
                      },
+
                      "issues": {
+
                        "open": 0,
+
                        "closed": 0,
+
                      },
+
                    }
+
                  }
                },
                "delegates": [
                  {
@@ -186,17 +168,6 @@ mod routes {
                "visibility": {
                  "type": "public"
                },
-
                "head": "344dcd184df5bf37aab6c107fa9371a1c5b3321a",
-
                "patches": {
-
                  "open": 0,
-
                  "draft": 0,
-
                  "archived": 0,
-
                  "merged": 0,
-
                },
-
                "issues": {
-
                  "open": 0,
-
                  "closed": 0,
-
                },
                "rid": "rad:z4GypKmh1gkEfmkXtarcYnkvtFUfE",
                "seeding": 1,
              }
@@ -223,10 +194,27 @@ mod routes {
            response.json().await,
            json!([
              {
-
                "xyz.radicle.project": {
-
                  "defaultBranch": "master",
-
                  "description": "Rad repository for tests",
-
                  "name": "hello-world",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "data": {
+
                      "defaultBranch": "master",
+
                      "description": "Rad repository for tests",
+
                      "name": "hello-world",
+
                    },
+
                    "meta": {
+
                      "head": HEAD,
+
                      "patches": {
+
                        "open": 1,
+
                        "draft": 0,
+
                        "archived": 0,
+
                        "merged": 0,
+
                      },
+
                      "issues": {
+
                        "open": 1,
+
                        "closed": 0,
+
                      },
+
                    }
+
                  }
                },
                "delegates": [
                  {
@@ -238,25 +226,31 @@ mod routes {
                "visibility": {
                  "type": "public"
                },
-
                "head": HEAD,
-
                "patches": {
-
                  "open": 1,
-
                  "draft": 0,
-
                  "archived": 0,
-
                  "merged": 0,
-
                },
-
                "issues": {
-
                  "open": 1,
-
                  "closed": 0,
-
                },
                "rid": RID,
                "seeding": 1,
              },
              {
-
                "xyz.radicle.project": {
-
                  "defaultBranch": "master",
-
                  "description": "Rad repository for sorting",
-
                  "name": "again-hello-world",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "data": {
+
                      "defaultBranch": "master",
+
                      "description": "Rad repository for sorting",
+
                      "name": "again-hello-world",
+
                    },
+
                    "meta": {
+
                      "head": "344dcd184df5bf37aab6c107fa9371a1c5b3321a",
+
                      "patches": {
+
                        "open": 0,
+
                        "draft": 0,
+
                        "archived": 0,
+
                        "merged": 0,
+
                      },
+
                      "issues": {
+
                        "open": 0,
+
                        "closed": 0,
+
                      },
+
                    }
+
                  }
                },
                "delegates": [
                  {
@@ -268,17 +262,6 @@ mod routes {
                "visibility": {
                  "type": "public"
                },
-
                "head": "344dcd184df5bf37aab6c107fa9371a1c5b3321a",
-
                "patches": {
-
                  "open": 0,
-
                  "draft": 0,
-
                  "archived": 0,
-
                  "merged": 0,
-
                },
-
                "issues": {
-
                  "open": 0,
-
                  "closed": 0,
-
                },
                "rid": "rad:z4GypKmh1gkEfmkXtarcYnkvtFUfE",
                "seeding": 1,
              }
modified radicle-httpd/src/api/v1/repos.rs
@@ -11,9 +11,8 @@ use radicle_surf::{diff, Glob, Oid, Repository};
use serde::{Deserialize, Serialize};
use serde_json::json;

-
use radicle::cob::{issue::cache::Issues as _, patch::cache::Patches as _, Author};
+
use radicle::cob::{issue::cache::Issues as _, patch::cache::Patches as _};
use radicle::identity::RepoId;
-
use radicle::node::routing::Store;
use radicle::node::{AliasStore, NodeId};
use radicle::storage::{ReadRepository, ReadStorage, RemoteRepository};

@@ -66,7 +65,6 @@ async fn repo_root_handler(
        _ => 10,
    });
    let storage = &ctx.profile.storage;
-
    let db = &ctx.profile.database()?;
    let pinned = &ctx.profile.config.web.pinned;
    let policies = ctx.profile.policies()?;

@@ -90,47 +88,14 @@ async fn repo_root_handler(
            if !policies.is_seeding(&info.rid).unwrap_or_default() {
                return None;
            }
-
            let Ok(repo) = storage.repository(info.rid) else {
-
                return None;
-
            };
-
            let Ok((_, head)) = repo.head() else {
-
                return None;
-
            };
-
            let Ok(_payload) = info.doc.project() else {
-
                return None;
-
            };
-
            let Ok(issues) = ctx.profile.issues(&repo) else {
+
            let Ok((repo, doc)) = ctx.repo(info.rid) else {
                return None;
            };
-
            let Ok(issues) = issues.counts() else {
+
            let Ok(repo_info) = ctx.repo_info(&repo, doc) else {
                return None;
            };
-
            let Ok(patches) = ctx.profile.patches(&repo) else {
-
                return None;
-
            };
-
            let Ok(patches) = patches.counts() else {
-
                return None;
-
            };
-
            let aliases = ctx.profile.aliases();
-
            let delegates = info
-
                .doc
-
                .delegates
-
                .into_iter()
-
                .map(|did| api::json::author(&Author::new(did), aliases.alias(did.as_key())))
-
                .collect::<Vec<_>>();
-
            let seeding = db.count(&info.rid).unwrap_or_default();
-

-
            Some(api::repo::Info {
-
                payload: info.doc.payload,
-
                delegates,
-
                head,
-
                threshold: info.doc.threshold,
-
                visibility: info.doc.visibility,
-
                issues,
-
                patches,
-
                rid: info.rid,
-
                seeding,
-
            })
+

+
            Some(repo_info)
        })
        .skip(page * per_page)
        .take(per_page)
@@ -201,7 +166,8 @@ async fn history_handler(
    Path(rid): Path<RepoId>,
    Query(qs): Query<CommitsQueryString>,
) -> impl IntoResponse {
-
    let (repo, doc) = ctx.repo(rid)?;
+
    let (repo, _) = ctx.repo(rid)?;
+
    let (_, head) = repo.head()?;
    let CommitsQueryString {
        since,
        until,
@@ -217,7 +183,7 @@ async fn history_handler(

    let sha = match parent {
        Some(commit) => commit,
-
        None => ctx.repo_info(&repo, doc)?.head.to_string(),
+
        None => head.to_string(),
    };
    let repo = Repository::open(repo.path())?;

@@ -732,10 +698,27 @@ mod routes {
            response.json().await,
            json!([
              {
-
                "xyz.radicle.project": {
-
                  "defaultBranch": "master",
-
                  "description": "Rad repository for tests",
-
                  "name": "hello-world",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "data": {
+
                      "defaultBranch": "master",
+
                      "description": "Rad repository for tests",
+
                      "name": "hello-world",
+
                    },
+
                    "meta": {
+
                      "head": HEAD,
+
                      "patches": {
+
                        "open": 1,
+
                        "draft": 0,
+
                        "archived": 0,
+
                        "merged": 0,
+
                      },
+
                      "issues": {
+
                        "open": 1,
+
                        "closed": 0,
+
                      },
+
                    }
+
                  }
                },
                "delegates": [
                  {
@@ -747,25 +730,31 @@ mod routes {
                "visibility": {
                  "type": "public"
                },
-
                "head": HEAD,
-
                "patches": {
-
                  "open": 1,
-
                  "draft": 0,
-
                  "archived": 0,
-
                  "merged": 0,
-
                },
-
                "issues": {
-
                  "open": 1,
-
                  "closed": 0,
-
                },
                "rid": RID,
                "seeding": 1,
              },
              {
-
                "xyz.radicle.project": {
-
                  "defaultBranch": "master",
-
                  "description": "Rad repository for sorting",
-
                  "name": "again-hello-world",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "data": {
+
                      "defaultBranch": "master",
+
                      "description": "Rad repository for sorting",
+
                      "name": "again-hello-world",
+
                    },
+
                    "meta": {
+
                      "head": "344dcd184df5bf37aab6c107fa9371a1c5b3321a",
+
                      "patches": {
+
                        "open": 0,
+
                        "draft": 0,
+
                        "archived": 0,
+
                        "merged": 0,
+
                      },
+
                      "issues": {
+
                        "open": 0,
+
                        "closed": 0,
+
                      },
+
                    }
+
                  }
                },
                "delegates": [
                  {
@@ -777,17 +766,6 @@ mod routes {
                "visibility": {
                  "type": "public"
                },
-
                "head": "344dcd184df5bf37aab6c107fa9371a1c5b3321a",
-
                "patches": {
-
                  "open": 0,
-
                  "draft": 0,
-
                  "archived": 0,
-
                  "merged": 0,
-
                },
-
                "issues": {
-
                  "open": 0,
-
                  "closed": 0,
-
                },
                "rid": "rad:z4GypKmh1gkEfmkXtarcYnkvtFUfE",
                "seeding": 1,
              },
@@ -805,10 +783,27 @@ mod routes {
            response.json().await,
            json!([
              {
-
                "xyz.radicle.project": {
-
                  "defaultBranch": "master",
-
                  "description": "Rad repository for tests",
-
                  "name": "hello-world",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "data": {
+
                      "defaultBranch": "master",
+
                      "description": "Rad repository for tests",
+
                      "name": "hello-world",
+
                    },
+
                    "meta": {
+
                      "head": HEAD,
+
                      "patches": {
+
                        "open": 1,
+
                        "draft": 0,
+
                        "archived": 0,
+
                        "merged": 0,
+
                      },
+
                      "issues": {
+
                        "open": 1,
+
                        "closed": 0,
+
                      },
+
                    }
+
                  }
                },
                "delegates": [
                  {
@@ -820,25 +815,31 @@ mod routes {
                "visibility": {
                  "type": "public"
                },
-
                "head": HEAD,
-
                "patches": {
-
                  "open": 1,
-
                  "draft": 0,
-
                  "archived": 0,
-
                  "merged": 0,
-
                },
-
                "issues": {
-
                  "open": 1,
-
                  "closed": 0,
-
                },
                "rid": RID,
                "seeding": 1,
              },
              {
-
                "xyz.radicle.project": {
-
                  "name": "again-hello-world",
-
                  "description": "Rad repository for sorting",
-
                  "defaultBranch": "master",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "data": {
+
                      "name": "again-hello-world",
+
                      "description": "Rad repository for sorting",
+
                      "defaultBranch": "master",
+
                    },
+
                    "meta": {
+
                      "head": "344dcd184df5bf37aab6c107fa9371a1c5b3321a",
+
                      "patches": {
+
                        "open": 0,
+
                        "draft": 0,
+
                        "archived": 0,
+
                        "merged": 0,
+
                      },
+
                      "issues": {
+
                        "open": 0,
+
                        "closed": 0,
+
                      },
+
                    }
+
                  }
                },
                "delegates": [
                  {
@@ -850,17 +851,6 @@ mod routes {
                "visibility": {
                  "type": "public"
                },
-
                "head": "344dcd184df5bf37aab6c107fa9371a1c5b3321a",
-
                "patches": {
-
                  "open": 0,
-
                  "draft": 0,
-
                  "archived": 0,
-
                  "merged": 0,
-
                },
-
                "issues": {
-
                  "open": 0,
-
                  "closed": 0,
-
                },
                "rid": "rad:z4GypKmh1gkEfmkXtarcYnkvtFUfE",
                "seeding": 1,
              },
@@ -878,10 +868,27 @@ mod routes {
        assert_eq!(
            response.json().await,
            json!({
-
                "xyz.radicle.project": {
-
                 "defaultBranch": "master",
-
                 "description": "Rad repository for tests",
-
                 "name": "hello-world",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "data": {
+
                      "defaultBranch": "master",
+
                      "description": "Rad repository for tests",
+
                      "name": "hello-world",
+
                    },
+
                    "meta": {
+
                      "head": HEAD,
+
                      "patches": {
+
                        "open": 1,
+
                        "draft": 0,
+
                        "archived": 0,
+
                        "merged": 0,
+
                      },
+
                      "issues": {
+
                        "open": 1,
+
                        "closed": 0,
+
                      },
+
                    }
+
                  }
                },
               "delegates": [
                 {
@@ -893,17 +900,6 @@ mod routes {
               "visibility": {
                 "type": "public"
               },
-
               "head": HEAD,
-
               "patches": {
-
                 "open": 1,
-
                 "draft": 0,
-
                 "archived": 0,
-
                 "merged": 0,
-
               },
-
               "issues": {
-
                 "open": 1,
-
                 "closed": 0,
-
               },
               "rid": RID,
               "seeding": 1,
            })
@@ -921,10 +917,12 @@ mod routes {
            response.json().await,
            json!([
              {
-
                "xyz.radicle.project": {
-
                  "name": "hello-world",
-
                  "description": "Rad repository for tests",
-
                  "defaultBranch": "master",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "name": "hello-world",
+
                    "description": "Rad repository for tests",
+
                    "defaultBranch": "master",
+
                  }
                },
                "rid": "rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp",
                "delegates": [
@@ -936,10 +934,12 @@ mod routes {
                "seeds": 1,
              },
              {
-
                "xyz.radicle.project": {
-
                  "name": "again-hello-world",
-
                  "description": "Rad repository for sorting",
-
                  "defaultBranch": "master",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "name": "again-hello-world",
+
                    "description": "Rad repository for sorting",
+
                    "defaultBranch": "master",
+
                  },
                },
                "rid": "rad:z4GypKmh1gkEfmkXtarcYnkvtFUfE",
                "delegates": [
@@ -966,10 +966,12 @@ mod routes {
            json!([
              {
                "rid": "rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp",
-
                "xyz.radicle.project": {
-
                  "defaultBranch": "master",
-
                  "description": "Rad repository for tests",
-
                  "name": "hello-world",
+
                "payloads": {
+
                  "xyz.radicle.project": {
+
                    "defaultBranch": "master",
+
                    "description": "Rad repository for tests",
+
                    "name": "hello-world",
+
                  },
                },
                "delegates": [
                  {