using System; using System.Collections.Generic; using System.Linq; using Luticate2.Utils.Dbo.Basic; using Luticate2.Utils.Dbo.PaginatedRequest; using Luticate2.Utils.Dbo.Result; using Microsoft.Extensions.Logging; using VDS.RDF.Nodes; using VDS.RDF.Query; using WebApiWebSem.Dbo.Articles; using WebApiWebSem.Dbo.ArticlesFields; namespace WebApiWebSem.DataAccess { public class DbPediaDataAccess { private readonly SparqlRemoteEndpoint _sparqlRemoteEndpoint; private readonly ILogger _logger; protected string Prefixes = @" PREFIX owl: PREFIX xsd: PREFIX rdfs: PREFIX rdf: PREFIX foaf: PREFIX dc: PREFIX : PREFIX dbpedia2: PREFIX dbpedia: PREFIX skos: PREFIX dbpedia-owl: "; public DbPediaDataAccess(SparqlRemoteEndpoint sparqlRemoteEndpoint, ILogger logger) { _sparqlRemoteEndpoint = sparqlRemoteEndpoint; _logger = logger; } protected string Escape(string str)//TODO { return str.Replace('\'', ' ').Replace('"', ' '); } protected LuResult Query(string query) { _logger.LogInformation(query); try { var results = _sparqlRemoteEndpoint.QueryWithResultSet(query); return LuResult.Ok(results); } catch (Exception e) { return LuResult.Error(LuStatus.BackendError, e); } } protected ArticlesDbo ModelToDbo(SparqlResult result) { var dbo = new ArticlesDbo { Fields = new List() }; foreach (var variable in result.Variables) { string data = null; var v = result[variable]; if (v != null) { data = v.AsValuedNode().AsString(); } if (variable == "id") { dbo.Id = data.Split('/').Last(); } else if (variable == "abstract") { dbo.Text = data; } else if (variable == "pictureUrl") { dbo.PictureUrl = data; } else if (variable == "pictureDesc") { dbo.PictureCaption = data; } else { if (data != null) { dbo.Fields.Add(new ArticlesFieldsDbo { Property = variable, Type = "text/plain", Value = data }); } } } return dbo; } public LuResult> GetMultiple(LuPaginatedRequestDbo request) { var type = ArticlesDataAccess.GetFilterType(request.Filter); string querySelect = null; string queryWhereId = null; string queryWhereVars = null; if (type == "home") { querySelect = "?id ?abstract ?pictureUrl ?pictureDesc"; queryWhereId = @"?id foaf:isPrimaryTopicOf wikipedia-en:World_War_II ."; queryWhereVars = @" OPTIONAL { ?id dbo:abstract ?abstract FILTER(lang(?abstract) = 'en') } OPTIONAL { ?id foaf:depiction ?pictureUrl } OPTIONAL { ?id dbpedia-owl:depictionDescription ?pictureDesc } BIND ((?abstract) AS ?search)"; } else if (type == "persons") { querySelect = "?id ?abstract ?pictureUrl ?pictureDesc (MIN(?name) AS ?name) (str(?birthDate) AS ?birthDate) (str(?deathDate) AS ?deathDate)"; queryWhereId = @"?id rdf:type dbo:Person ; ?type dbr:World_War_II ."; queryWhereVars = @" ?id dbp:name ?name . OPTIONAL { ?id dbo:abstract ?abstract FILTER(lang(?abstract) = 'en') } OPTIONAL { ?id foaf:depiction ?pictureUrl } OPTIONAL { ?id dbpedia-owl:depictionDescription ?pictureDesc } OPTIONAL { ?id dbp:birthDate ?birthDate } OPTIONAL { ?id dbp:deathDate ?deathDate } FILTER (lang(?name) = 'en') BIND (CONCAT(?name) AS ?search)"; } else if (type == "locations") { querySelect = "?id ?name ?abstract ?pictureUrl ?pictureDesc (str(MIN(?date) as ?date) as ?date) (group_concat(distinct ?combatant;separator=', ') as ?combatant) (group_concat(distinct ?commanderName;separator=', ') as ?commander)"; queryWhereId = @"?ww foaf:isPrimaryTopicOf wikipedia-en:World_War_II ; dbo:place ?id."; queryWhereVars = @" ?id foaf:name ?name . OPTIONAL { ?id dbo:abstract ?abstract FILTER(lang(?abstract) = 'en') } OPTIONAL { ?id foaf:depiction ?pictureUrl } OPTIONAL { ?id dbpedia-owl:depictionDescription ?pictureDesc } OPTIONAL { ?id dbo:date ?date } OPTIONAL { ?id dbp:combatant ?combatant } OPTIONAL { ?id dbp:commander ?commanderName } FILTER (lang(?name) = 'en') BIND (CONCAT(?name) AS ?search)"; } else if (type == "countries") { querySelect = "?id (MIN(?name) as ?name) ?abstract ?pictureUrl ?pictureDesc "; queryWhereId = @"?id a ; ?type dbr:World_War_II ."; queryWhereVars = @" ?id foaf:name ?name . OPTIONAL { ?id dbo:abstract ?abstract FILTER(lang(?abstract) = 'en') } OPTIONAL { ?id foaf:depiction ?pictureUrl } OPTIONAL { ?id dbpedia-owl:depictionDescription ?pictureDesc } FILTER (lang(?name) = 'en') BIND (CONCAT(?name) AS ?search)"; } var filter = $"FILTER regex(?search, '{request.Filter.Query}', 'i')"; var count = Query(string.Format(@"{0} SELECT (COUNT(?id) AS ?count) WHERE {{ SELECT DISTINCT {1} WHERE {{ {2} {3} {4} }} }} ", Prefixes, querySelect, queryWhereId, queryWhereVars, filter)); if (!count) { return count.To>(); } var res = Query(string.Format(@"{0} SELECT DISTINCT {1} WHERE {{ {2} {3} {4} }} ORDER BY {5} LIMIT {6} OFFSET {7}", Prefixes, querySelect, queryWhereId, queryWhereVars, filter, request.OrderBy.ToDbPediaModel(), request.PerPage, request.Page * request.PerPage)); if (!res) { return res.To>(); } var results = new LuPaginatedDbo { Count = count.Data.Results.First()["count"].AsValuedNode().AsInteger(), Data = res.Data.Results.Select(ModelToDbo).Select(dbo => { dbo.Type = type; return dbo; }).ToList() }; return LuResult>.Ok(results); } } }