diff --git a/cms/evidence-types.jsonld b/cms/evidence-types.jsonld new file mode 100644 index 00000000..9c9320b2 --- /dev/null +++ b/cms/evidence-types.jsonld @@ -0,0 +1,371 @@ +{ + "@graph" : [ { + "@id" : "mas_evidence_types:Audit%20reports", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Audit reports" + } + }, { + "@id" : "mas_evidence_types:CONCEPT-Evidence_type", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "prefLabel" : { + "@language" : "en", + "@value" : "Evidence type" + } + }, { + "@id" : "mas_evidence_types:CONCEPT-Guidance_and_advice", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Evidence_type", + "prefLabel" : { + "@language" : "en", + "@value" : "Guidance and advice" + } + }, { + "@id" : "mas_evidence_types:Care%20pathways", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Care pathways" + } + }, { + "@id" : "mas_evidence_types:Commissioning%20guides", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Guidance_and_advice", + "prefLabel" : { + "@language" : "en", + "@value" : "Commissioning guides" + } + }, { + "@id" : "mas_evidence_types:Drug%20best%20practice%20guidance", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Guidance_and_advice", + "prefLabel" : { + "@language" : "en", + "@value" : "Drug best practice guidance" + } + }, { + "@id" : "mas_evidence_types:Drug%20costs", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Drug costs" + } + }, { + "@id" : "mas_evidence_types:Drug%20horizon%20scanning", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Drug horizon scanning" + } + }, { + "@id" : "mas_evidence_types:Drug%20prescribing", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Guidance_and_advice", + "prefLabel" : { + "@language" : "en", + "@value" : "Drug prescribing" + } + }, { + "@id" : "mas_evidence_types:Drug%20regulatory%20and%20marketing", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Drug regulatory and marketing" + } + }, { + "@id" : "mas_evidence_types:Drug%2Fmedicines%20management", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Drug/medicines management" + } + }, { + "@id" : "mas_evidence_types:Effective%20practice%20examples", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Effective practice examples" + } + }, { + "@id" : "mas_evidence_types:Evidence%20summaries", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Evidence%20summary", + "prefLabel" : { + "@language" : "en", + "@value" : "Evidence summaries" + } + }, { + "@id" : "mas_evidence_types:Evidence%20summary", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Evidence_type", + "prefLabel" : { + "@language" : "en", + "@value" : "Evidence summary" + } + }, { + "@id" : "mas_evidence_types:Evidence%20updates", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Evidence%20summary", + "prefLabel" : { + "@language" : "en", + "@value" : "Evidence updates" + } + }, { + "@id" : "mas_evidence_types:Evidence-based%20management%20reports", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Evidence-based management reports" + } + }, { + "@id" : "mas_evidence_types:Eyes%20on%20evidence%20commentaries", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Evidence%20summary", + "prefLabel" : { + "@language" : "en", + "@value" : "Eyes on evidence commentaries" + } + }, { + "@id" : "mas_evidence_types:Guidance", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Guidance_and_advice", + "prefLabel" : { + "@language" : "en", + "@value" : "Guidance" + } + }, { + "@id" : "mas_evidence_types:Health%20technology%20assessments", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Systematic%20review", + "prefLabel" : { + "@language" : "en", + "@value" : "Health technology assessments" + } + }, { + "@id" : "mas_evidence_types:Implementation%20support%20tools", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Implementation support tools" + } + }, { + "@id" : "mas_evidence_types:Learning%20materials", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Learning materials" + } + }, { + "@id" : "mas_evidence_types:MAS_evidence_type", + "@type" : "http://www.w3.org/2004/02/skos/core#ConceptScheme", + "hasTopConcept" : "mas_evidence_types:CONCEPT-Evidence_type", + "prefLabel" : { + "@language" : "en", + "@value" : "MAS evidence type" + } + }, { + "@id" : "mas_evidence_types:Media%20and%20commentaries", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Evidence_type", + "prefLabel" : { + "@language" : "en", + "@value" : "Media and commentaries" + } + }, { + "@id" : "mas_evidence_types:Medicines%20Q%20%26%20A", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Evidence%20summary", + "prefLabel" : { + "@language" : "en", + "@value" : "Medicines Q & A" + } + }, { + "@id" : "mas_evidence_types:Medicines%20evidence%20commentaries", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Evidence%20summary", + "prefLabel" : { + "@language" : "en", + "@value" : "Medicines evidence commentaries" + } + }, { + "@id" : "mas_evidence_types:Ongoing%20or%20unpublished%20research", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Primary%20research", + "prefLabel" : { + "@language" : "en", + "@value" : "Ongoing or unpublished research" + } + }, { + "@id" : "mas_evidence_types:Other%20economic%20evaluations", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Other economic evaluations" + } + }, { + "@id" : "mas_evidence_types:Other%20evidence", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Evidence_type", + "prefLabel" : { + "@language" : "en", + "@value" : "Other evidence" + } + }, { + "@id" : "mas_evidence_types:Other%20primary%20research", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Primary%20research", + "prefLabel" : { + "@language" : "en", + "@value" : "Other primary research" + } + }, { + "@id" : "mas_evidence_types:Patient%20decision%20aids", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Patient decision aids" + } + }, { + "@id" : "mas_evidence_types:Patient%20information", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Patient information" + } + }, { + "@id" : "mas_evidence_types:Policy", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Evidence_type", + "prefLabel" : { + "@language" : "en", + "@value" : "Policy" + } + }, { + "@id" : "mas_evidence_types:Population%20intelligence", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Population intelligence" + } + }, { + "@id" : "mas_evidence_types:Population%20needs%20assessment", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Population needs assessment" + } + }, { + "@id" : "mas_evidence_types:Primary%20research", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Evidence_type", + "prefLabel" : { + "@language" : "en", + "@value" : "Primary research" + } + }, { + "@id" : "mas_evidence_types:Quality%20measures", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Other%20evidence", + "prefLabel" : { + "@language" : "en", + "@value" : "Quality measures" + } + }, { + "@id" : "mas_evidence_types:Randomised%20controlled%20trials", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Primary%20research", + "prefLabel" : { + "@language" : "en", + "@value" : "Randomised controlled trials" + } + }, { + "@id" : "mas_evidence_types:Safety%20alerts", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Evidence_type", + "prefLabel" : { + "@language" : "en", + "@value" : "Safety alerts" + } + }, { + "@id" : "mas_evidence_types:Systematic%20review", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:CONCEPT-Evidence_type", + "prefLabel" : { + "@language" : "en", + "@value" : "Systematic review" + } + }, { + "@id" : "mas_evidence_types:Systematic%20reviews", + "@type" : "http://www.w3.org/2004/02/skos/core#Concept", + "broader" : "mas_evidence_types:Systematic%20review", + "prefLabel" : { + "@language" : "en", + "@value" : "Systematic reviews" + } + }, { + "@id" : "urn:x-evn-master:mas_evidence_types", + "@type" : "owl:Ontology", + "status" : "metadata:UnderDevelopmentStatus", + "defaultNamespace" : "http://nice.org.uk/MAS/evidence_type/", + "newInstancesUserCannotModifyURI" : "0", + "comment" : "A list of evidence types includes in the Medicines Awareness Service", + "label" : "MAS evidence types", + "imports" : [ "http://topbraid.org/skos.shapes", "http://topbraid.org/imported" ] + } ], + "@context" : { + "prefLabel" : { + "@id" : "http://www.w3.org/2004/02/skos/core#prefLabel" + }, + "broader" : { + "@id" : "http://www.w3.org/2004/02/skos/core#broader", + "@type" : "@id" + }, + "imports" : { + "@id" : "http://www.w3.org/2002/07/owl#imports", + "@type" : "@id" + }, + "status" : { + "@id" : "http://topbraid.org/metadata#status", + "@type" : "@id" + }, + "label" : { + "@id" : "http://www.w3.org/2000/01/rdf-schema#label" + }, + "newInstancesUserCannotModifyURI" : { + "@id" : "http://topbraid.org/teamwork#newInstancesUserCannotModifyURI", + "@type" : "http://www.w3.org/2001/XMLSchema#boolean" + }, + "comment" : { + "@id" : "http://www.w3.org/2000/01/rdf-schema#comment" + }, + "defaultNamespace" : { + "@id" : "http://topbraid.org/swa#defaultNamespace" + }, + "hasTopConcept" : { + "@id" : "http://www.w3.org/2004/02/skos/core#hasTopConcept", + "@type" : "@id" + }, + "metadata" : "http://topbraid.org/metadata#", + "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "owl" : "http://www.w3.org/2002/07/owl#", + "teamwork" : "http://topbraid.org/teamwork#", + "mas_evidence_types" : "http://nice.org.uk/MAS/evidence_type/", + "rdfs" : "http://www.w3.org/2000/01/rdf-schema#" + } +} diff --git a/cms/models/EvidenceType.js b/cms/models/EvidenceType.js index d67e5084..99560cf8 100644 --- a/cms/models/EvidenceType.js +++ b/cms/models/EvidenceType.js @@ -1,4 +1,22 @@ -const keystone = require("keystone"); +const keystone = require("keystone"), + fs = require("fs"), + path = require("path"); + +// Load the JSONLD for evidence types on application load +// so we don't have to hit the file system again and again +let evidenceTypesJsonLd; +fs.readFile( + path.resolve(__dirname, "../evidence-types.jsonld"), + "UTF-8", + function(err, contents) { + if (err) { + loggger.error(err); + throw err; + } + + evidenceTypesJsonLd = JSON.parse(contents); + } +); const Types = keystone.Field.Types; @@ -12,12 +30,7 @@ const EvidenceType = new keystone.List("EvidenceType", { EvidenceType.add({ title: { type: String, required: true }, key: { type: String, required: true }, - oldEPiServerId: { - label: "Old EPiServer ID", - type: Types.Number, - required: false - } -}); + oldEPiServerId: { label: "Old EPiServer ID", type: Types.Number, required: false }}); EvidenceType.relationship({ ref: "Item", @@ -25,6 +38,20 @@ EvidenceType.relationship({ refPath: "evidenceType" }); +EvidenceType.schema.virtual("broaderTitle").get(function() { + const key = this.key, + evidenceTypes = evidenceTypesJsonLd["@graph"], + concept = evidenceTypes.find(e => e["@id"] === key); + + // Assume only 2 levels + const broaderConcept = evidenceTypes.find(e => e["@id"] === concept.broader); + + if(broaderConcept.broader) + return broaderConcept.prefLabel["@value"]; + else + return concept.prefLabel["@value"]; +}); + EvidenceType.defaultColumns = "title, oldEPiServerId, key"; EvidenceType.register(); diff --git a/cms/models/Item.js b/cms/models/Item.js index 3b63fbc0..0437a049 100644 --- a/cms/models/Item.js +++ b/cms/models/Item.js @@ -165,6 +165,7 @@ Item.schema.post("save", async function(doc, next) { .model.findById(doc._id) .populate("source") .populate("evidenceType") + .populate("speciality") .exec(); } catch (err) { logger.error("An error occurred finding item: ", err.message); diff --git a/cms/routes/api/items.js b/cms/routes/api/items.js index 589cbf66..6ed816ff 100644 --- a/cms/routes/api/items.js +++ b/cms/routes/api/items.js @@ -1,14 +1,18 @@ -const keystone = require("keystone"), - Items = keystone.list("Item"); +var keystone = require("keystone"), + Items = keystone.list("Item"), + _ = require("lodash"); const log4js = require("log4js"), logger = log4js.getLogger(); exports.single = function(req, res, next) { + + Items.model .findById(req.params.itemId) .populate("source") .populate("evidenceType") + .populate("speciality") .exec(function(err, item) { if (err) { logger.error(`Error getting item with id ${req.params.itemId}`, err); @@ -21,7 +25,26 @@ exports.single = function(req, res, next) { return res.notfound("Item not found", notFoundMsg, true); } - res.json(item); + const obj = _.pick(item, [ + "_id", + "updatedAt", + "createdAt", + "slug", + "shortSummary", + "source._id", + "source.title", + "url", + "title", + "comment", + "publicationDate", + "resourceLinks", + "speciality", + "evidenceType._id", + "evidenceType.title", + "evidenceType.key", + "evidenceType.broaderTitle"]); + + return res.json(obj); }); }; @@ -34,6 +57,7 @@ exports.list = function(req, res) { .find() .populate("source") .populate("evidenceType") + .populate("speciality") .exec(function(err, items) { if (err) { logger.error(`Failed to get list of items`, err); diff --git a/lambda/MAS.Tests/UnitTests/DailyEmailTests.cs b/lambda/MAS.Tests/UnitTests/DailyEmailTests.cs new file mode 100644 index 00000000..fbb1d11d --- /dev/null +++ b/lambda/MAS.Tests/UnitTests/DailyEmailTests.cs @@ -0,0 +1,138 @@ +using MAS.Models; +using MAS.Tests.Infrastructure; +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Xunit; + +namespace MAS.Tests.UnitTests +{ + public class DailyEmailTests : TestBase + { + Item exampleItem = new Item() + { + Id = "123", + Title = "Some Title", + Slug = "abc", + ShortSummary = "Some short summary", + ResourceLinks = "", + Comment = "", + Speciality = new List + { + new Speciality() + { + Key = "1a", + Title = "Some speciality", + + } + }, + EvidenceType = new EvidenceType() + { + Key = "1b", + Title = "Some evidence type" + }, + Source = new Source() + { + Id = "1c", + Title = "Some source" + } + }; + Item exampleItem2 = new Item() + { + Id = "123", + Title = "Some Title", + Slug = "abc", + ShortSummary = "Some short summary", + ResourceLinks = "", + Comment = "", + Speciality = new List + { + new Speciality() + { + Key = "1a", + Title = "Some speciality 2", + + } + }, + EvidenceType = new EvidenceType() + { + Key = "1c", + Title = "Some evidence type 2" + }, + Source = new Source() + { + Id = "1c", + Title = "Some source" + } + }; + + [Fact] + public void CanCreateSingleItemEmail() + { + var email = new DailyEmail() + { + Items = new List() + { + exampleItem + } + }; + + var expectedHtml = "
Some evidence type
Some Title
Some source
Some speciality
Some short summary
SPS Comment
"; + email.HTML.ShouldBe(expectedHtml); + + } + + [Fact] + public void CanCreateEmailWithTwoItemsSharingEvidenceType() + { + var email = new DailyEmail() + { + Items = new List() + { + exampleItem, + exampleItem + } + }; + + var expectedHtml = "
Some evidence type
Some Title
Some source
Some speciality
Some short summary
SPS Comment
Some Title
Some source
Some speciality
Some short summary
SPS Comment
"; + email.HTML.ShouldBe(expectedHtml); + + } + + [Fact] + public void CanCreateEmailWithTwoItemsDifferentEvidenceType() + { + var email = new DailyEmail() + { + Items = new List() + { + exampleItem, + exampleItem2 + } + }; + + var expectedHtml = "
Some evidence type
Some Title
Some source
Some speciality
Some short summary
SPS Comment
Some evidence type 2
Some Title
Some source
Some speciality 2
Some short summary
SPS Comment
"; + email.HTML.ShouldBe(expectedHtml); + + } + + [Fact] + public void ItemsWithManySpecialitiesRenderCorrectly() + { + exampleItem.Speciality.Add(new Speciality() { Key = "abcd", Title = "Another speciality" }); + var email = new DailyEmail() + { + Items = new List() + { + exampleItem + } + }; + + var expectedHtml = "
Some evidence type
Some Title
Some source
Some speciality | Another speciality
Some short summary
SPS Comment
"; + email.HTML.ShouldBe(expectedHtml); + + } + } +} diff --git a/lambda/MAS/Controllers/MailController.cs b/lambda/MAS/Controllers/MailController.cs index d9ea13a4..5521597e 100644 --- a/lambda/MAS/Controllers/MailController.cs +++ b/lambda/MAS/Controllers/MailController.cs @@ -25,7 +25,7 @@ public async Task PutMailAsync() { var items = await _contentService.GetItemsAsync(); - var body = _mailService.CreateEmailBody(items); + var body = _mailService.CreateDailyEmailBody(items); var subject = "MAS Email"; var previewText = "This MAS email was created " + DateTime.Now.ToShortDateString(); diff --git a/lambda/MAS/Models/DailyEmail.cs b/lambda/MAS/Models/DailyEmail.cs new file mode 100644 index 00000000..5f7d56a5 --- /dev/null +++ b/lambda/MAS/Models/DailyEmail.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MAS.Models +{ + public class DailyEmail + { + public List Items { get; set; } + + public List> GroupedItems + { + get + { + return Items.GroupBy(x => x.EvidenceType.Title).ToList(); + } + } + + + public string HTML + { + get + { + var body = new StringBuilder(); + + foreach (var group in GroupedItems) + { + string specInEvidenceType = String.Join(',', group.SelectMany(x => x.Speciality.Select(y => y.Title))); + body.Append("*|INTERESTED:Daily specialities of interest:" + specInEvidenceType + "|*"); + body.Append("
"); + + var evidenceType = group.Key; + body.Append("" + evidenceType + ""); + + foreach (var item in group) + { + string itemSpecList = String.Join(',', item.Speciality.Select(x => x.Title)); + body.Append("*|INTERESTED:Daily specialities of interest:" + itemSpecList + "|*"); + + body.Append("
"); + body.Append(item.Title); + body.Append("
"); + body.Append(item.Source.Title); + body.Append("
"); + body.Append(String.Join(" | ", item.Speciality.Select(x => x.Title))); + body.Append("
"); + body.Append(item.ShortSummary); + body.Append("
"); + body.Append("SPS Comment"); + body.Append("
"); + + body.Append("*|END:INTERESTED|*"); + } + + body.Append("
"); + body.Append("*|END:INTERESTED|*"); + } + + return body.ToString(); + } + } + } +} diff --git a/lambda/MAS/Models/Item.cs b/lambda/MAS/Models/Item.cs index 4dfc11a6..b0aa4343 100644 --- a/lambda/MAS/Models/Item.cs +++ b/lambda/MAS/Models/Item.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace MAS.Models @@ -7,6 +8,8 @@ public class Item { [JsonProperty("_id"), Required, JsonRequired] public string Id { get; set; } + [JsonProperty("slug")] + public string Slug { get; set; } [Required, JsonRequired] public string Slug { get; set; } [Required, JsonRequired] @@ -15,6 +18,8 @@ public class Item public Source Source { get; set; } [Required, JsonRequired] public EvidenceType EvidenceType { get; set; } + [JsonProperty("speciality")] + public List Speciality { get; set; } public string ShortSummary { get; set; } public string Comment { get; set; } public string ResourceLinks { get; set; } diff --git a/lambda/MAS/Models/Speciality.cs b/lambda/MAS/Models/Speciality.cs new file mode 100644 index 00000000..37b04f15 --- /dev/null +++ b/lambda/MAS/Models/Speciality.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MAS.Models +{ + public class Speciality + { + public string Title { get; set; } + + public string Key { get; set; } + } +} diff --git a/lambda/MAS/Services/MailService.cs b/lambda/MAS/Services/MailService.cs index aa7ab767..26e7a722 100644 --- a/lambda/MAS/Services/MailService.cs +++ b/lambda/MAS/Services/MailService.cs @@ -8,13 +8,14 @@ using System.Collections.Generic; using System.Text; using System.Threading.Tasks; +using System.Linq; namespace MAS.Services { public interface IMailService { Task CreateAndSendCampaignAsync(string subject, string previewText, string body); - string CreateEmailBody(IEnumerable item); + string CreateDailyEmailBody(IEnumerable item); } public class MailService: IMailService @@ -73,21 +74,10 @@ public async Task CreateAndSendCampaignAsync(string subject, string prev } - public string CreateEmailBody(IEnumerable items) + public string CreateDailyEmailBody(IEnumerable items) { - var body = new StringBuilder(); - - foreach (var item in items) - { - body.Append(item.Source.Title); - body.Append("
"); - body.Append(item.Title); - body.Append("
"); - body.Append(item.ShortSummary); - body.Append("


"); - } - - return body.ToString(); + var dailyEmail = new DailyEmail() { Items = items.ToList() }; + return dailyEmail.HTML; } } } diff --git a/lambda/MAS/Services/S3Service.cs b/lambda/MAS/Services/S3Service.cs new file mode 100644 index 00000000..6459eeb3 --- /dev/null +++ b/lambda/MAS/Services/S3Service.cs @@ -0,0 +1,82 @@ +using Amazon.Lambda.Core; +using Amazon.S3; +using Amazon.S3.Model; +using MAS.Configuration; +using MAS.Models; +using Microsoft.Extensions.Logging; +using System; +using System.Text; +using System.Threading.Tasks; + +namespace MAS.Services +{ + public interface IS3Service + { + Task WriteToS3(Item item); + } + public class S3Service : IS3Service + { + private readonly IAmazonS3 _amazonS3; + private readonly ILogger _logger; + + public S3Service(IAmazonS3 amazonS3, ILogger logger) + { + _amazonS3 = amazonS3; + _logger = logger; + } + + public async Task WriteToS3(Item item) + { + PutObjectRequest request = new PutObjectRequest() + { + BucketName = AppSettings.AWSConfig.BucketName, + Key = item.Id + ".txt", + ContentBody = CreateContentBody(item) + }; + + try + { + var response = await _amazonS3.PutObjectAsync(request); + return response; + } + catch (Exception e) + { + _logger.LogError($"Failed to write to S3 - exception: {e.Message}"); + throw new Exception($"Failed to write to S3 - exception: {e.Message}"); + } + + } + + private string CreateContentBody(Item item) + { + var contentBody = new StringBuilder(); + contentBody.Append("Title: "); + contentBody.Append(item.Title); + contentBody.Append(Environment.NewLine); + + contentBody.Append("Short Summary: "); + contentBody.Append(item.ShortSummary); + contentBody.Append(Environment.NewLine); + + contentBody.Append("Source: "); + contentBody.Append(item.Source.Title); + contentBody.Append(Environment.NewLine); + + contentBody.Append("Evidence Type: "); + contentBody.Append(item.EvidenceType.Title); + contentBody.Append(Environment.NewLine); + + contentBody.Append("UKMI Comment: "); + contentBody.Append(item.UKMiComment); + contentBody.Append(Environment.NewLine); + + if (item.ResourceLinks != null) + { + contentBody.Append("Resource Links: "); + contentBody.Append(item.ResourceLinks); + } + + return contentBody.ToString(); + } + } +}