Page MenuHomePhabricator

D8983.diff
No OneTemporary

D8983.diff

diff --git a/services/reports/Cargo.lock b/services/reports/Cargo.lock
--- a/services/reports/Cargo.lock
+++ b/services/reports/Cargo.lock
@@ -1508,6 +1508,28 @@
"regex-automata 0.1.10",
]
+[[package]]
+name = "maud"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0bab19cef8a7fe1c18a43e881793bfc9d4ea984befec3ae5bd0415abf3ecf00"
+dependencies = [
+ "itoa",
+ "maud_macros",
+]
+
+[[package]]
+name = "maud_macros"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0be95d66c3024ffce639216058e5bae17a83ecaf266ffc6e4d060ad447c9eed2"
+dependencies = [
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
[[package]]
name = "memchr"
version = "2.5.0"
@@ -1775,6 +1797,30 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
[[package]]
name = "proc-macro2"
version = "1.0.66"
@@ -1890,6 +1936,7 @@
"derive_more",
"hex",
"http",
+ "maud",
"num-derive",
"num-traits",
"once_cell",
diff --git a/services/reports/Cargo.toml b/services/reports/Cargo.toml
--- a/services/reports/Cargo.toml
+++ b/services/reports/Cargo.toml
@@ -20,6 +20,7 @@
derive_more = "0.99"
hex = "0.4"
http = "0.2"
+maud = "0.25"
num-traits = "0.2"
num-derive = "0.4"
once_cell = "1.17"
diff --git a/services/reports/src/email/config.rs b/services/reports/src/email/config.rs
--- a/services/reports/src/email/config.rs
+++ b/services/reports/src/email/config.rs
@@ -9,7 +9,7 @@
#[derive(Clone, Debug, Hash, Eq, PartialEq, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum MailingGroup {
- ErrorsReports,
+ ErrorReports,
InconsistencyReports,
MediaReports,
}
@@ -18,7 +18,7 @@
fn from(value: &ReportType) -> Self {
use ReportType::*;
match value {
- ErrorReport => Self::ErrorsReports,
+ ErrorReport => Self::ErrorReports,
MediaMission => Self::MediaReports,
ThreadInconsistency | EntryInconsistency | UserInconsistency => {
Self::InconsistencyReports
@@ -37,7 +37,7 @@
pub postmark_token: String,
/// E-mail that is used as a sender
pub sender_email: String,
- /// Receiver e-mails for report types
+ /// Recipient e-mails for report types
pub mailing_groups: HashMap<MailingGroup, String>,
}
@@ -111,6 +111,21 @@
mailing_groups: HashMap::new(),
});
+ #[test]
+ fn parse_args_disabled() {
+ // should return none when config exists but is disabled
+ let mut args = EmailArgs {
+ config_content: Some(EXAMPLE_CFG.clone()),
+ config_file: None,
+ };
+ let cfg = args.parse().expect("failed to parse");
+ assert!(cfg.is_some());
+
+ args.config_content.as_mut().unwrap().disabled = true;
+ let cfg = args.parse().expect("failed to parse");
+ assert!(cfg.is_none());
+ }
+
#[test]
fn parse_args_priority() {
// direct content should have higher priority than file
diff --git a/services/reports/src/email/mod.rs b/services/reports/src/email/mod.rs
--- a/services/reports/src/email/mod.rs
+++ b/services/reports/src/email/mod.rs
@@ -1 +1,2 @@
pub mod config;
+mod template;
diff --git a/services/reports/src/email/template/html_layout.rs b/services/reports/src/email/template/html_layout.rs
new file mode 100644
--- /dev/null
+++ b/services/reports/src/email/template/html_layout.rs
@@ -0,0 +1,89 @@
+use maud::{html, Markup, PreEscaped, DOCTYPE};
+
+pub fn render_page(body: Markup) -> String {
+ let markup = html! {
+ (DOCTYPE)
+ html lang="en" {
+ head {
+ meta charset="utf-8";
+ style { (PreEscaped(CSS)) }
+ }
+ body {
+ (body)
+ }
+ }
+ };
+
+ markup.into_string()
+}
+
+const CSS: &str = r#"
+body {
+ font-family: Arial, sans-serif;
+ margin: 0;
+ padding: 20px;
+ color: #333;
+ line-height: 1.5;
+}
+
+h2 {
+ font-size: 24px;
+ color: #222;
+ margin: 0 0 10px;
+ padding: 0;
+}
+
+h3 {
+ font-size: 18px;
+ color: #444;
+ margin: 0 0 8px;
+ padding: 0;
+}
+
+h4 {
+ font-size: 16px;
+ color: #555;
+ margin: 0;
+ padding: 0;
+}
+
+p {
+ margin: 0 0 10px;
+ padding: 0;
+}
+
+b {
+ font-weight: bold;
+}
+
+em {
+ font-style: italic;
+}
+
+code {
+ background-color: #f0f0f0;
+ padding: 2px 4px;
+ border-radius: 2px;
+ font-family: monospace;
+}
+
+pre {
+ background-color: #f0f0f0;
+ padding: 10px;
+ font-family: monospace;
+ overflow: auto;
+}
+
+ul {
+ margin: 0 0 10px 20px;
+ padding: 0;
+}
+
+a {
+ color: #007bff;
+ text-decoration: none;
+}
+a:hover {
+ text-decoration: underline;
+}
+"#;
diff --git a/services/reports/src/email/template/mod.rs b/services/reports/src/email/template/mod.rs
new file mode 100644
--- /dev/null
+++ b/services/reports/src/email/template/mod.rs
@@ -0,0 +1,58 @@
+use maud::{html, Markup, Render};
+
+use crate::report_types::*;
+
+mod html_layout;
+
+pub fn render_email_for_report(
+ report_input: &ReportInput,
+ report_id: &ReportID,
+ user_id: Option<&str>,
+) -> String {
+ html_layout::render_page(message_body_for_report(
+ report_input,
+ report_id,
+ user_id,
+ ))
+}
+
+fn message_body_for_report(
+ report: &ReportInput,
+ report_id: &ReportID,
+ user_id: Option<&str>,
+) -> Markup {
+ let user = user_id.unwrap_or("N/A");
+ let platform = &report.platform_details;
+ let time = report
+ .time
+ .unwrap_or_default()
+ .format("%d/%m/%y %H:%M:%S")
+ .to_string();
+
+ html! {
+ ul {
+ li { "User ID: " b { (user) } }
+ li { "Platform: " (platform) }
+ li { "Time: " b { (time) } }
+ li { "Report ID: " b { (report_id) } }
+ }
+ }
+}
+
+impl Render for PlatformDetails {
+ fn render(&self) -> Markup {
+ let code_version = self
+ .code_version
+ .map(|it| it.to_string())
+ .unwrap_or("N/A".into());
+ html! {
+ b { (self.platform) } ", code version: " b { (code_version) }
+ }
+ }
+}
+
+impl Render for ReportID {
+ fn render(&self) -> Markup {
+ html! { (self.as_str()) }
+ }
+}
diff --git a/services/reports/src/report_types.rs b/services/reports/src/report_types.rs
--- a/services/reports/src/report_types.rs
+++ b/services/reports/src/report_types.rs
@@ -41,6 +41,23 @@
UserInconsistency = 4,
}
+impl ReportType {
+ pub fn is_error(&self) -> bool {
+ matches!(self, Self::ErrorReport)
+ }
+ pub fn is_media_mission(&self) -> bool {
+ matches!(self, Self::MediaMission)
+ }
+ pub fn is_inconsistency(&self) -> bool {
+ matches!(
+ self,
+ ReportType::ThreadInconsistency
+ | ReportType::EntryInconsistency
+ | ReportType::UserInconsistency
+ )
+ }
+}
+
/// Report platform
#[derive(Clone, Debug, Serialize, Deserialize, Display)]
#[serde(rename_all = "lowercase")]
@@ -56,8 +73,8 @@
#[serde(rename_all = "camelCase")]
pub struct PlatformDetails {
pub platform: ReportPlatform,
- code_version: Option<u16>,
- state_version: Option<u16>,
+ pub code_version: Option<u16>,
+ pub state_version: Option<u16>,
}
/// Input report payload - this is the JSON we receive from clients

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 23, 3:54 AM (18 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2568003
Default Alt Text
D8983.diff (7 KB)

Event Timeline