Skip to content

Commit

Permalink
feat(serve): support contributors.txt
Browse files Browse the repository at this point in the history
  • Loading branch information
fiji-flo committed Nov 18, 2024
1 parent 2a7c039 commit 5dfe87a
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 36 deletions.
48 changes: 24 additions & 24 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ version = "0.0.20"
edition = "2021"
license = "MPL-2.0"
authors = [
"Florian Dieminger <[email protected]>",
"The MDN Engineering Team <[email protected]>",
"Florian Dieminger <[email protected]>",
"The MDN Engineering Team <[email protected]>",
]
homepage = "https://github.com/mdn/rari"
repository = "https://github.com/mdn/rari"
Expand All @@ -30,27 +30,27 @@ codegen-units = 1
[workspace]
resolver = "2"
members = [
"crates/rari-data",
"crates/rari-utils",
"crates/rari-deps",
"crates/rari-types",
"crates/rari-templ-func",
"crates/rari-md",
"crates/rari-doc",
"crates/rari-linter",
"crates/rari-tools",
"crates/css-syntax",
"crates/css-syntax-types",
"crates/css-definition-syntax",
"crates/diff-test",
"crates/rari-data",
"crates/rari-utils",
"crates/rari-deps",
"crates/rari-types",
"crates/rari-templ-func",
"crates/rari-md",
"crates/rari-doc",
"crates/rari-linter",
"crates/rari-tools",
"crates/css-syntax",
"crates/css-syntax-types",
"crates/css-definition-syntax",
"crates/diff-test",
]

[workspace.package]
edition = "2021"
license = "MPL-2.0"
authors = [
"Florian Dieminger <[email protected]>",
"The MDN Engineering Team <[email protected]>",
"Florian Dieminger <[email protected]>",
"The MDN Engineering Team <[email protected]>",
]
rust-version = "1.81"

Expand Down Expand Up @@ -81,10 +81,10 @@ html-escape = "0.2"
ignore = "0.4"
rayon = "1"
reqwest = { version = "0.12", default-features = false, features = [
"blocking",
"json",
"rustls-tls",
"gzip",
"blocking",
"json",
"rustls-tls",
"gzip",
] }
indoc = "2"
base64 = "0.22"
Expand All @@ -108,9 +108,9 @@ anyhow.workspace = true
dashmap.workspace = true

self_update = { version = "0.41", default-features = false, features = [
"rustls",
"compression-flate2",
"compression-zip-deflate",
"rustls",
"compression-flate2",
"compression-zip-deflate",
] }
clap = { version = "4.5.1", features = ["derive"] }
clap-verbosity-flag = "2"
Expand Down
53 changes: 49 additions & 4 deletions crates/rari-cli/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ use std::str::FromStr;
use std::sync::atomic::AtomicU64;
use std::sync::Arc;

use axum::body::Body;
use axum::extract::{Path, Request, State};
use axum::http::StatusCode;
use axum::http::{header, StatusCode};
use axum::response::{IntoResponse, Response};
use axum::routing::get;
use axum::{Json, Router};
use rari_doc::cached_readers::wiki_histories;
use rari_doc::contributors::contributors_txt;
use rari_doc::error::DocError;
use rari_doc::issues::{to_display_issues, InMemoryLayer};
use rari_doc::pages::json::BuiltPage;
Expand All @@ -28,14 +31,23 @@ struct SearchItem {
title: String,
url: String,
}

async fn handler(state: State<Arc<InMemoryLayer>>, req: Request) -> Response<Body> {
if req.uri().path().ends_with("/contributors.txt") {
get_contributors_handler(req).await.into_response()
} else {
get_json_handler(state, req).await.into_response()
}
}

async fn get_json_handler(
State(memory_layer): State<Arc<InMemoryLayer>>,
req: Request,
) -> Result<Json<BuiltPage>, AppError> {
let url = req.uri().path();
let req_id = REQ_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let span = span!(Level::WARN, "serve", req = req_id);
let _enter1 = span.enter();
let url = req.uri().path();
let mut json = get_json(url)?;
if let BuiltPage::Doc(json_doc) = &mut json {
let m = memory_layer.get_events();
Expand Down Expand Up @@ -66,6 +78,38 @@ fn get_json(url: &str) -> Result<BuiltPage, DocError> {
Ok(json)
}

async fn get_contributors_handler(req: Request) -> impl IntoResponse {
let url = req.uri().path();
match get_contributors(url.strip_suffix("/contributors.txt").unwrap_or(url)) {
Ok(contributors_txt_str) => (
StatusCode::OK,
[(header::CONTENT_TYPE, "text/plain")],
contributors_txt_str,
)
.into_response(),
Err(e) => {
tracing::error!("error generating contributors.txt for {url}: {e:?}");
(StatusCode::INTERNAL_SERVER_ERROR).into_response()
}
}
}

fn get_contributors(url: &str) -> Result<String, AppError> {
let page = Page::from_url_with_fallback(url)?;
let json = page.build()?;
let github_file_url = if let BuiltPage::Doc(ref doc) = json {
&doc.doc.source.github_url
} else {
""
};
let wiki_histories = wiki_histories();
let wiki_history = wiki_histories
.get(&page.locale())
.and_then(|wh| wh.get(page.slug()));
let contributors_txt_str = contributors_txt(wiki_history, github_file_url);
Ok(contributors_txt_str)
}

async fn get_search_index_handler(
Path(locale): Path<String>,
) -> Result<Json<Vec<SearchItem>>, AppError> {
Expand Down Expand Up @@ -118,10 +162,11 @@ fn get_search_index(locale: Locale) -> Result<Vec<SearchItem>, DocError> {
Ok(out)
}

#[derive(Debug)]
struct AppError(anyhow::Error);

impl IntoResponse for AppError {
fn into_response(self) -> Response {
fn into_response(self) -> Response<Body> {
(StatusCode::INTERNAL_SERVER_ERROR, error!("🤷: {}", self.0)).into_response()
}
}
Expand All @@ -142,7 +187,7 @@ pub fn serve(memory_layer: InMemoryLayer) -> Result<(), anyhow::Error> {
.block_on(async {
let app = Router::new()
.route("/:locale/search-index.json", get(get_search_index_handler))
.fallback(get_json_handler)
.fallback(handler)
.with_state(Arc::new(memory_layer));

let listener = tokio::net::TcpListener::bind("0.0.0.0:8083").await.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion crates/rari-doc/src/cached_readers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ pub fn contributor_spotlight_files() -> Cow<'static, UrlToPageMap> {
///
/// - Panics if the translated content root or individual directory names are invalid.
/// - Panics if the `_wikihistory.json` file is missing or contains malformed JSON.
pub(crate) fn wiki_histories() -> Cow<'static, WikiHistories> {
pub fn wiki_histories() -> Cow<'static, WikiHistories> {
fn gather() -> Result<WikiHistories, DocError> {
let mut map = HashMap::new();
if let Some(ctr) = content_translated_root() {
Expand Down
11 changes: 4 additions & 7 deletions crates/rari-doc/src/contributors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use rari_types::locale::Locale;
use serde::Deserialize;

#[derive(Clone, Debug, Deserialize)]
pub(crate) struct WikiHistoryEntry {
pub struct WikiHistoryEntry {
pub contributors: Vec<String>,
}

pub(crate) type WikiHistory = HashMap<String, WikiHistoryEntry>;
pub(crate) type WikiHistories = HashMap<Locale, WikiHistory>;
pub type WikiHistory = HashMap<String, WikiHistoryEntry>;
pub type WikiHistories = HashMap<Locale, WikiHistory>;

/// Generates a contributors text report summarizing commit history and original Wiki contributors.
///
Expand Down Expand Up @@ -61,10 +61,7 @@ pub(crate) type WikiHistories = HashMap<Locale, WikiHistory>;
/// // # Contributors by commit history
/// // https://github.com/user/repo/commits/main/file.txt
/// ```
pub(crate) fn contributors_txt(
wiki_history: Option<&WikiHistoryEntry>,
github_file_url: &str,
) -> String {
pub fn contributors_txt(wiki_history: Option<&WikiHistoryEntry>, github_file_url: &str) -> String {
let mut out = String::new();
out.extend([
"# Contributors by commit history\n",
Expand Down

0 comments on commit 5dfe87a

Please sign in to comment.