diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3ea891c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+################################################################################
+# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
+################################################################################
+
+/Sources/Exercicio.PrincipaisPalavras.Application/obj
+/Sources/Exercicio.PrincipaisPalavras.Infra.HttpService/bin/Debug/netcoreapp2.2
+/Sources/Exercicio.PrincipaisPalavras.Infra.HttpService/obj
+/Sources/Exercicio.PrincipaisPalavras.Service/bin/Debug/netcoreapp2.2
+/Sources/Exercicio.PrincipaisPalavras.Application/bin/Debug/netcoreapp2.2
+/Sources/Exercicio.PrincipaisPalavras.Service/obj
+/Sources/Exercicio.PrincipaisPalavras.Test/bin/Debug/netcoreapp2.2
+/Sources/Exercicio.PrincipaisPalavras.Test/obj
+/Sources/Exercicio.PrincipaisPalavras.WebApi/bin/Debug/netcoreapp2.2
+/Sources/Exercicio.PrincipaisPalavras.WebApi/obj
+/Sources/.vs/Exercicio.PrincipaisPalavras/v15/Server/sqlite3
+/Sources/.vs/Exercicio.PrincipaisPalavras/v15
+/.vs
diff --git a/Sources/.vs/config/applicationhost.config b/Sources/.vs/config/applicationhost.config
new file mode 100644
index 0000000..c65464e
--- /dev/null
+++ b/Sources/.vs/config/applicationhost.config
@@ -0,0 +1,996 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Sources/Exercicio.PrincipaisPalavras.Application/BlogMinutoSeguro/BlogMinutoSeguroApp.cs b/Sources/Exercicio.PrincipaisPalavras.Application/BlogMinutoSeguro/BlogMinutoSeguroApp.cs
new file mode 100644
index 0000000..b9581b3
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Application/BlogMinutoSeguro/BlogMinutoSeguroApp.cs
@@ -0,0 +1,38 @@
+using Exercicio.PrincipaisPalavras.Application.BlogMinutoSeguro.Interfaces;
+using Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro;
+using Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro.Interfaces;
+using Exercicio.PrincipaisPalavras.Service.Core;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Exercicio.PrincipaisPalavras.Application.BlogMinutoSeguro
+{
+ public class BlogMinutoSeguroApp : IBlogMinutoSeguroApp
+ {
+ private readonly IBlogMinutoSeguroService _blogMinutoSeguroService = null;
+
+ public BlogMinutoSeguroApp(IBlogMinutoSeguroService blogMinutoSeguroService)
+ {
+ _blogMinutoSeguroService = blogMinutoSeguroService;
+ }
+
+ public async Task> ObterPrincipaisPalavrasAsync()
+ {
+ var response = new Response();
+
+ var conteudo = await _blogMinutoSeguroService.ObterConteudoFeedAsync();
+
+ if (string.IsNullOrEmpty(conteudo))
+ {
+ response.RasonPhrase = "Conteudo da página não encontrado";
+ return response;
+ }
+
+ response.AddContent(new FeedNoticia(conteudo));
+
+ return response;
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Application/BlogMinutoSeguro/Interfaces/IBlogMinutoSeguroApp.cs b/Sources/Exercicio.PrincipaisPalavras.Application/BlogMinutoSeguro/Interfaces/IBlogMinutoSeguroApp.cs
new file mode 100644
index 0000000..4d6c507
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Application/BlogMinutoSeguro/Interfaces/IBlogMinutoSeguroApp.cs
@@ -0,0 +1,14 @@
+using Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro;
+using Exercicio.PrincipaisPalavras.Service.Core;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Exercicio.PrincipaisPalavras.Application.BlogMinutoSeguro.Interfaces
+{
+ public interface IBlogMinutoSeguroApp
+ {
+ Task> ObterPrincipaisPalavrasAsync();
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Application/Exercicio.PrincipaisPalavras.Application.csproj b/Sources/Exercicio.PrincipaisPalavras.Application/Exercicio.PrincipaisPalavras.Application.csproj
new file mode 100644
index 0000000..fbfdfe7
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Application/Exercicio.PrincipaisPalavras.Application.csproj
@@ -0,0 +1,11 @@
+
+
+
+ netcoreapp2.2
+
+
+
+
+
+
+
diff --git a/Sources/Exercicio.PrincipaisPalavras.Infra.HttpService/BlogMinutoSeguroHttpService.cs b/Sources/Exercicio.PrincipaisPalavras.Infra.HttpService/BlogMinutoSeguroHttpService.cs
new file mode 100644
index 0000000..6c8fac3
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Infra.HttpService/BlogMinutoSeguroHttpService.cs
@@ -0,0 +1,28 @@
+using Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro.Interfaces;
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Exercicio.PrincipaisPalavras.Infra.HttpService
+{
+ public class BlogMinutoSeguroHttpService : HttpClientBase, IBlogMinutoSeguroService
+ {
+ private const string uriBlogFeed = "blog/feed";
+
+ public BlogMinutoSeguroHttpService(): base("http://www.minutoseguros.com.br", "*/*")
+ {
+ }
+
+ public Task ObterConteudoFeedAsync()
+ {
+ return GetStringAsync(uriBlogFeed);
+ }
+
+ public HttpResponseMessage ObterConteudoFeedSync()
+ {
+ return GetSync(uriBlogFeed);
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Infra.HttpService/Exercicio.PrincipaisPalavras.Infra.HttpService.csproj b/Sources/Exercicio.PrincipaisPalavras.Infra.HttpService/Exercicio.PrincipaisPalavras.Infra.HttpService.csproj
new file mode 100644
index 0000000..fbfdfe7
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Infra.HttpService/Exercicio.PrincipaisPalavras.Infra.HttpService.csproj
@@ -0,0 +1,11 @@
+
+
+
+ netcoreapp2.2
+
+
+
+
+
+
+
diff --git a/Sources/Exercicio.PrincipaisPalavras.Infra.HttpService/HttpClientBase.cs b/Sources/Exercicio.PrincipaisPalavras.Infra.HttpService/HttpClientBase.cs
new file mode 100644
index 0000000..ed96163
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Infra.HttpService/HttpClientBase.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Exercicio.PrincipaisPalavras.Infra.HttpService
+{
+ public abstract class HttpClientBase
+ {
+ protected readonly HttpClient _httpClient;
+
+ private readonly string _mediaTypeAccept;
+
+ public HttpClientBase(string url) : this(url, "text/html")
+ {
+ }
+
+ public HttpClientBase(string url, string mediaTypeAccept, Int64 timeOut = 3000, bool useDefaultCredentials = false)
+ {
+ _mediaTypeAccept = mediaTypeAccept;
+
+ _httpClient = CreateHttpClienWithHandler(new Uri(url), timeOut, useDefaultCredentials);
+ }
+
+ public virtual HttpResponseMessage GetSync(string uri)
+ {
+ return GetAsync(uri).GetAwaiter().GetResult();
+ }
+
+ public virtual Task GetAsync(string uri)
+ {
+ return _httpClient.GetAsync(uri);
+ }
+
+ public virtual Task GetAsync(string uri, CancellationToken cancellationToken)
+ {
+ return _httpClient.GetAsync(uri, cancellationToken);
+ }
+
+ public virtual async Task GetStringAsync(string uri)
+ {
+ var response = await _httpClient.GetAsync(uri);
+
+ return await response.Content.ReadAsStringAsync();
+ }
+
+ public virtual HttpClient CreateHttpClienWithHandler(Uri baseAddress, Int64 timeOut, bool useDefaultCredentials)
+ {
+ var http = new HttpClient(CreateHttpClientHandler(useDefaultCredentials))
+ {
+ BaseAddress = baseAddress,
+ Timeout = TimeSpan.FromMilliseconds(timeOut)
+ };
+
+ http.DefaultRequestHeaders.Add("Accept", _mediaTypeAccept);
+ http.DefaultRequestHeaders.Add("Accept-Language", "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7");
+ http.DefaultRequestHeaders.Add("Postman-Token", "92defd03-997e-4a76-8bf6-d4c27689e476");
+ http.DefaultRequestHeaders.Add("User-Agent", "PostmanRuntime/7.15.0");
+
+ return http;
+ }
+
+ protected virtual HttpClientHandler CreateHttpClientHandler(bool useDefaultCredentials)
+ {
+ var coockies = new CookieCollection();
+
+ //coockies.Add(new Cookie("incap_ses_1239_1762536", "RY6beEc+lihW77u1ItAxEWXWJV0AAAAA/4NFHU9GK80fr01ssMIhiA==", "/", ".minutoseguros.com.br"));
+ coockies.Add(new Cookie("incap_ses_789_1762536", "LWoDSNgCST0CoTOiTxjzCkgoJl0AAAAAzKQZySUBf72Km8CnA2FPdQ==", "/", ".minutoseguros.com.br"));
+ coockies.Add(new Cookie("nlbi_1762536", "BvZVWkGzJQARObmQFqUGpAAAAADbKfc7jgu9TyKpDoCmRn9N", "/", ".minutoseguros.com.br"));
+ coockies.Add(new Cookie("visid_incap_1762536", "0zVL0xC1TCyNtyOxkUAeqvvqJV0AAAAAQUIPAAAAAADgSdmxvVk57tSOLKmrglhv", "/", ".minutoseguros.com.br"));
+
+ var coockieContaniner = new CookieContainer();
+ coockieContaniner.Add(coockies);
+
+ return new HttpClientHandler()
+ {
+ AllowAutoRedirect = true,
+ UseDefaultCredentials = useDefaultCredentials,
+ AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate,
+ UseCookies = true,
+ CookieContainer = coockieContaniner
+ };
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/FeedNoticia.cs b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/FeedNoticia.cs
new file mode 100644
index 0000000..d52ad6d
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/FeedNoticia.cs
@@ -0,0 +1,41 @@
+using Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro.Helper;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro
+{
+ public class FeedNoticia
+ {
+ public List Topicos { get; private set; }
+ public string HtmlContent { get; private set; }
+
+ public FeedNoticia(string htmlContent)
+ {
+ CarregarInformacoesTopico(htmlContent);
+ }
+
+ public void CarregarInformacoesTopico(string html)
+ {
+ var htmlTopicos = html.Split("- ");
+
+ if (htmlTopicos.Any())
+ {
+ Topicos = new List
(htmlTopicos.Count() - 1);
+
+ for (int i = 0; i < htmlTopicos.Length; i++)
+ {
+ if (i > 0)
+ {
+ var obj = new Topico(htmlTopicos[i]);
+ obj.CarregarInformacoesTopico();
+
+ Topicos.Add(obj);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/Helper/RegexPatternHelper.cs b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/Helper/RegexPatternHelper.cs
new file mode 100644
index 0000000..96c121e
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/Helper/RegexPatternHelper.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro.Helper
+{
+ public class RegexPatternHelper
+ {
+ public static string TagsWithContent(string [] content)
+ {
+ string strPattern = string.Empty;
+
+ for (int i = 0; i < content.Length; i++)
+ {
+ if (i == 0)
+ strPattern = $"<{content[i]}>\\s*(.+?)\\s*{content[i]}>";
+ else
+ strPattern += $"|<{content[i]}>\\s*(.+?)\\s*{content[i]}>";
+ }
+
+ return strPattern;
+ }
+
+ public static string BeetweenSpace(string[] content)
+ {
+ string strPattern = string.Empty;
+
+ for (int i = 0; i < content.Length; i++)
+ {
+ if (i == 0)
+ strPattern = $"\\s{content[i]}\\s";
+ else
+ strPattern += $"|\\s{content[i]}\\s";
+ }
+
+ return strPattern;
+ }
+
+ public static string Words(string initial, string length)
+ {
+ return "\\w{" + initial + "," + length + "}";
+ }
+
+ public static string Tags()
+ {
+ return @"<[^>]*>";
+ }
+
+ public static string Links()
+ {
+ return @"http[^\s]+";
+ }
+
+ public static string Number()
+ {
+ return @"\d+";
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/Interfaces/IBlogMinutoSeguroService.cs b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/Interfaces/IBlogMinutoSeguroService.cs
new file mode 100644
index 0000000..329e01c
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/Interfaces/IBlogMinutoSeguroService.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro.Interfaces
+{
+ public interface IBlogMinutoSeguroService
+ {
+ Task ObterConteudoFeedAsync();
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/PalavraPrincipal.cs b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/PalavraPrincipal.cs
new file mode 100644
index 0000000..f936237
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/PalavraPrincipal.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro
+{
+ public class PalavraPrincipal
+ {
+ public PalavraPrincipal(string nome, int qtd)
+ {
+ Nome = nome;
+ Qtd = qtd;
+ }
+
+ public string Nome { get; private set; }
+
+ public int Qtd { get; private set; }
+
+ public void AdicionarQtd()
+ {
+ Qtd++;
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/Topico.cs b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/Topico.cs
new file mode 100644
index 0000000..3eb91f5
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/Topico.cs
@@ -0,0 +1,86 @@
+using Exercicio.PrincipaisPalavras.Service.Core.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro
+{
+ public class Topico
+ {
+ private string _strHtml = string.Empty;
+ public string Titulo { get; set; }
+ public int QtdPalavras { get; set; }
+ public List PalavraPrincipals { get; set; }
+
+ public Topico(string htmlTopico)
+ {
+ _strHtml = htmlTopico;
+
+ ObterTítulo();
+ RemoverConteudoTags();
+ RemoverTags();
+ RemoverLinks();
+
+ RemoverArtigos();
+ RemoverPreposicoes();
+
+ //RemoverNumeros();
+ }
+
+ public string ObterStrHtml()
+ {
+ return _strHtml;
+ }
+
+ private void ObterTítulo()
+ {
+ Titulo = _strHtml.Beetween("", " ");
+ }
+
+ public void CarregarInformacoesTopico()
+ {
+ var matches = Regex.Matches(_strHtml, TopicoPattern.ObterPatternWords(), RegexOptions.Compiled);
+
+ QtdPalavras = matches.Count;
+
+ PalavraPrincipals = matches.GroupBy(x => x.Value).Select(grp =>
+ new PalavraPrincipal(grp.Key, grp.Count())).OrderByDescending(p => p.Qtd).Take(10).ToList();
+ }
+
+ #region PrivateMethods
+
+ private void RemoverArtigos()
+ {
+ _strHtml = Regex.Replace(_strHtml, TopicoPattern.ObterPatternArtigos(), " ", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ }
+
+ private void RemoverPreposicoes()
+ {
+ _strHtml = Regex.Replace(_strHtml, TopicoPattern.ObterPatternPreposicoes(), " ", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ }
+
+ private void RemoverConteudoTags()
+ {
+ _strHtml = Regex.Replace(_strHtml, TopicoPattern.ObterPatternConteudo(), " ", RegexOptions.Compiled);
+ }
+
+ private void RemoverTags()
+ {
+ _strHtml = Regex.Replace(_strHtml, TopicoPattern.ObterPatternTags(), " ", RegexOptions.Compiled);
+ }
+
+ private void RemoverLinks()
+ {
+ _strHtml = Regex.Replace(_strHtml, TopicoPattern.ObterPatternLinks(), " ", RegexOptions.Compiled);
+ }
+
+ private void RemoverNumeros()
+ {
+ _strHtml = Regex.Replace(_strHtml, TopicoPattern.ObterPatternNumerico(), "", RegexOptions.Compiled);
+ }
+
+ #endregion
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/TopicoPattern.cs b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/TopicoPattern.cs
new file mode 100644
index 0000000..3b49f2f
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Service/BlogMinutoSeguro/TopicoPattern.cs
@@ -0,0 +1,105 @@
+using Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro.Helper;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro
+{
+ public class TopicoPattern
+ {
+ private static string _patternConteudo;
+ private static string _patternTags;
+ private static string _patternLinks;
+ private static string _patternWords;
+ private static string _patternArtigos;
+ private static string _patternPreposicoes;
+
+ private static string _patternNumerico;
+
+ public static string ObterPatternConteudo()
+ {
+ if (!string.IsNullOrEmpty(_patternConteudo)) return _patternConteudo;
+
+ _patternConteudo = RegexPatternHelper.TagsWithContent(ObterTags());
+
+ return _patternConteudo;
+ }
+
+ public static string ObterPatternTags()
+ {
+ if (!string.IsNullOrEmpty(_patternTags)) return _patternTags;
+
+ _patternTags = RegexPatternHelper.Tags();
+
+ return _patternTags;
+ }
+
+ public static string ObterPatternLinks()
+ {
+ if (!string.IsNullOrEmpty(_patternLinks)) return _patternLinks;
+
+ _patternLinks = RegexPatternHelper.Links();
+
+ return _patternLinks;
+ }
+
+ public static string ObterPatternWords()
+ {
+ if (!string.IsNullOrEmpty(_patternWords)) return _patternWords;
+
+ _patternWords = RegexPatternHelper.Words("4", string.Empty);
+
+ return _patternWords;
+ }
+
+ public static string ObterPatternArtigos()
+ {
+ if (!string.IsNullOrEmpty(_patternArtigos)) return _patternArtigos;
+
+ _patternArtigos = RegexPatternHelper.BeetweenSpace(ObterArtigos());
+
+ return _patternArtigos;
+ }
+
+ public static string ObterPatternPreposicoes()
+ {
+ if (!string.IsNullOrEmpty(_patternPreposicoes)) return _patternPreposicoes;
+
+ _patternPreposicoes = RegexPatternHelper.BeetweenSpace(ObterPreposicoes());
+
+ return _patternPreposicoes;
+ }
+
+ public static string ObterPatternNumerico()
+ {
+ if (!string.IsNullOrEmpty(_patternNumerico)) return _patternNumerico;
+
+ _patternNumerico = RegexPatternHelper.Number();
+
+ return _patternNumerico;
+ }
+
+ public static string [] ObterArtigos()
+ {
+ string[] artigos = { "a", "o", "as", "os", "um", "uns", "uma", "uma" };
+
+ return artigos;
+ }
+
+ public static string [] ObterPreposicoes()
+ {
+ string [] preposicoes = { "ao", "aos", "aonde", "àquele", "ante", "após", "até", "com", "como", "conforme", "contra", "da", "das", "de", "do", "dos"
+ , "desde", "em", "entre", "para", "por", "perante", "sem", "sob", "sobre", "trás", "duma", "disto", "nas", "num", "nessa", "pelo", "pelos", "pela","pelas", "durante", "exceto"
+ , "feito", "fora", "senão", "visto" };
+
+ return preposicoes;
+ }
+
+ public static string[] ObterTags()
+ {
+ string[] _tagsContent = { "link", "lastBuildDate", "lastBuildDate", "language", "link", "sy:updatePeriod", "sy:updateFrequency", "generator" };
+
+ return _tagsContent;
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Service/Core/Extensions/StringExtension.cs b/Sources/Exercicio.PrincipaisPalavras.Service/Core/Extensions/StringExtension.cs
new file mode 100644
index 0000000..6e906a8
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Service/Core/Extensions/StringExtension.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Exercicio.PrincipaisPalavras.Service.Core.Extensions
+{
+ public static class StringExtension
+ {
+ public static string Beetween(this string content, string startsWith, string endsWith)
+ {
+ var cropStart = content.IndexOf(startsWith, StringComparison.Ordinal);
+ var cropped = content.Substring(cropStart);
+ var cropEnd = cropped.IndexOf(endsWith, StringComparison.Ordinal);
+ var cleaned = cropped.Substring(0, cropEnd).Substring(startsWith.Length);
+ return cleaned;
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Service/Core/Response.cs b/Sources/Exercicio.PrincipaisPalavras.Service/Core/Response.cs
new file mode 100644
index 0000000..c48a7ed
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Service/Core/Response.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Exercicio.PrincipaisPalavras.Service.Core
+{
+ public class Response
+ {
+ public T Content { get; private set; }
+
+ public string RasonPhrase { get; set; }
+
+ public bool IsValid => string.IsNullOrEmpty(RasonPhrase);
+
+ public void AddContent(T input)
+ {
+ Content = input;
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Service/Exercicio.PrincipaisPalavras.Service.csproj b/Sources/Exercicio.PrincipaisPalavras.Service/Exercicio.PrincipaisPalavras.Service.csproj
new file mode 100644
index 0000000..c16c6d5
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Service/Exercicio.PrincipaisPalavras.Service.csproj
@@ -0,0 +1,7 @@
+
+
+
+ netcoreapp2.2
+
+
+
diff --git a/Sources/Exercicio.PrincipaisPalavras.Test/Exercicio.PrincipaisPalavras.Test.csproj b/Sources/Exercicio.PrincipaisPalavras.Test/Exercicio.PrincipaisPalavras.Test.csproj
new file mode 100644
index 0000000..4d331c0
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Test/Exercicio.PrincipaisPalavras.Test.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp2.2
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sources/Exercicio.PrincipaisPalavras.Test/Extensions/BlogMinutoSeguroServiceMoqExtensions.cs b/Sources/Exercicio.PrincipaisPalavras.Test/Extensions/BlogMinutoSeguroServiceMoqExtensions.cs
new file mode 100644
index 0000000..15d6463
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Test/Extensions/BlogMinutoSeguroServiceMoqExtensions.cs
@@ -0,0 +1,77 @@
+using Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro.Interfaces;
+using Moq;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Exercicio.PrincipaisPalavras.Test.Extensions
+{
+ public static class BlogMinutoSeguroServiceMoqExtensions
+ {
+ public static Mock ObterConteudoFeed_Topico(this Mock mock)
+ {
+ mock.Setup(c => c.ObterConteudoFeedAsync())
+ .Returns(Task.FromResult(ObterTexto()));
+
+ return mock;
+ }
+
+ public static string ObterTexto()
+ {
+ return @"-
+
O valor do seguro dos carros mais vendidos do Brasil em junho
+ https://www.minutoseguros.com.br/blog/seguro-dos-carros-mais-vendidos-brasil-junho-2/
+ https://www.minutoseguros.com.br/blog/seguro-dos-carros-mais-vendidos-brasil-junho-2/#respond
+ Fri, 05 Jul 2019 15:36:21 +0000
+
+
+
+
+
+
+
+ http://www.minutoseguros.com.br/blog/?p=24470
+ Única mudança na lista dos carros mais vendidos em comparação ao mês passado é a saída do Corolla e a entrada do Compass; com 34% de aumento nas vendas, Argo, da FIAT, é o veículo que mais ascendeu e Kwid mantém-se na quarta posição
+ O post O valor do seguro dos carros mais vendidos do Brasil em junho apareceu primeiro em Blog Minuto Seguros .
+ ]]>
+ A Minuto Seguros, uma das principais corretoras do País e líder no segmento de seguros online, acaba de realizar um estudo com base na lista divulgada pela Fenabrave (Federação Nacional da Distribuição de Veículos Automotores) com o seguro dos carros mais vendidos no Brasil em junho.
+ O Onix , da Chevrolet, apesar de manter-se na liderança de mercado teve uma queda de 12% em relação ao mês de maio. O principal modelo da GM saiu de 22.279 unidades para 19.500, em junho. Já O HB20 foi outro modelo que teve queda nas vendas em junho: 19% a menos que o último mês, quando caiu de 10.111 unidades para 8.147. É o segundo mês consecutivo de quedas do hatch da Hyundai que, apesar disso, mantém o posto de segundo carro mais vendido do Brasil no ano.
+
+ O KA, apesar de ter apresentado queda comparativamente a maio, ultrapassou o HB20 no ranking mensal de mais vendidos com as 8.398 unidades vendidas. Comparativamente ao mês de maio, o KA caiu 14% as suas comercializações. Em junho ele chegou ao número de 8.398, mas em maio ele já havia alcançado 9.484 vendas. Por mais um mês, o quinto consecutivo, as vendas de HB20 e KA não superaram a totalidade de vendas do Onix: 19.500 contra 16.545 dos dois modelos.
+ COTE O SEGURO DOS MAIS VENDIDOS
+ Em junho, o preço médio do seguro do Onix, entre as cinco capitais cotadas, foi de R$1.777 para o público masculino. Em comparação ao mês de maio, houve uma leve subida do preço médio do hatch da Chevrolet: cerca de 2%. A variação é baixa e mostra que, pelo menos entre os meses, houve certa estabilização do preço do seguro.
+ Preço do seguro Onix para mulheres
+ Sobre o perfil feminino para o seguro do Onix, o preço médio nas cinco capitais é de R$1.722. A diferença de valores, em comparação ao mês passado, apresenta outra elevação nos valores, dessa vez, mais perceptível: 8%. Na comparação com os homens, as mulheres pagam menos no valor do seguro do Onix. O valor para elas é, em média, R$55 mais barato do que para eles.
+ O Onix, em 2019, no primeiro semestre do ano já vendeu mais de 100 mil carros. Ao total já foram 117.001 até o último dia de junho. Em 2018, nos seis primeiros meses do ano, o hatch da Chevrolet havia vendido 89.261 unidades. O crescimento nas vendas do Onix, ano versus ano, é de 31%. Para efeito de comparação, o Onix só foi ter mais de 100 mil unidades vendidas em 2018 no mês de julho.
+ Apenas uma mudança na lista: sai Corolla entra Compass
+ No mês de junho, a única mudança ficou por conta da saída do Corolla e a entrada do Compass. O SUV da Jeep ficou com a 10ª colocação e 5.080 unidades vendidas. Essa, inclusive, foi a primeira vez que o Jeep Compass entrou na lista dos carros mais vendidos do Brasil em 2019. Em 2018, por exemplo, o modelo era figura mais constante na lista juntamente com o Renegade. Com relação ao preço do seguro do Compass, o SUV ficou com a maior média, tanto para os homens, quanto para as mulheres. Os valores foram R$3.858 e R$3.459, respectivamente.
+
+ O Kwid , da Renault, mostra, por mais um mês, que consolidou-se entre as preferências automotivas brasileiras. Dessa vez, por 265 unidades, ele não passou o HB20 e entrou no TOP3 dos mais vendidos do mês. O mini SUV ficou manteve a quarta posição com a venda de 7.882 unidades. Mesmo com esse bom mês de vendas, comparado a maio, as vendas do Kwid tiveram queda de 9%. Mas, algo que não mudou foi que o mini SUV da Renault manteve o posto de menor média do preço do seguro, tanto para homens, quanto para mulheres. Para o público masculino o valor médio foi de R$1.741 nas cinco capitais cotadas, já para o público feminino, R$1.542.
+
+ O HB20 está com 2.348 comercializações de vantagem para o Ford KA até o sexto mês do ano. A disputa acirrada pelo posto de segundo carro mais vendido do Brasil parece que vai ser apertada até o final do ano. O KA está consolidado no terceiro lugar e parece que não será incomodado pelo Kwid até o final do ano – a menos que haja alguma surpresa.
+ Preço do seguro da lista dos mais vendidos
+ Os valores do seguro para o HB20 parecem ter estabilizado nos últimos meses, com poucas alterações, tanto para baixo quanto para cima. Se em maio o valor médio para assegurar o carro era R$2.096, em junho, subiu levemente para R$2.159, cerca de 3%. Para as mulheres, o cenário se repete, com poucas alterações: se em maio o preço médio entre as cinco capitais era de R$1.940, em junho subiu para R$2.088, menos de R$150.
+ O Ford KA, terceiro carro mais vendido do Brasil e segundo carro mais vendido em junho, comercializou 8.398 carros no sexto mês do ano. O preço médio do seguro do KA para os homens foi de R$2.004. Isso significou um aumento de quase 10% comparado ao último mês, quando o preço estava R$1.826. Já para as mulheres, o valor médio foi de R$1.711, R$106 mais caro o do que no último mês, representando um aumento de 6,6%. É o segundo mês consecutivo que o preço do seguro do KA aumenta nas mesmas proporções para as mulheres no valor médio das cinco capitais.
+ O Kwid tomou para si o posto de preço do seguro médio mais barato entre os veículos mais vendidos do Brasil. Nos quatro primeiros meses do ano, o posto foi do KA, que depois passou para o Onix e agora chegou ao Kwid. Para mulheres, o valor foi de R$1.542 e para homens, de R$1.741.
+ Análise do preço do seguro dos carros mais vendidos
+ A somatória dos 10 carros mais vendidos do Brasil teve a primeira queda do ano, após cinco meses de crescentes. Em janeiro foram 70.889, em fevereiro 71.694. Em março, o número bateu 76.039 unidades, em abril foram 83.238 e, agora em maio, 89.095. No entanto, em junho, o número caiu para 80.611, o número mais baixo desde março. Esse dado explica, basicamente, a queda nas vendas dos principais modelos.
+ O preço do seguro médio desses 10 veículos ficou no valor de R$2.361 para os homens e de R$2.189 para as mulheres. Para ambos os sexos houve aumento nos valores, 10% para as mulheres e 6,8% para os homens. O aumento no valor médio dos carros mais vendidos aconteceu pela entrada do Compass na lista, que historicamente tem um preço de seguro mais caro por dois fatores: preço de Tabela FIPE alto e manutenção mais cara por conta das peças.
+ Para realizar o estudo, a Minuto Seguros considerou como perfil um condutor homem e uma condutora mulher, de 35 anos, ambos casados. Foram avaliados os preços dos seguros em cinco capitais (São Paulo, Rio de Janeiro, Belo Horizonte, Curitiba e Maceió).
+ Quem paga menos pelo seguro do carro?
+ Dentro destes perfis mencionados, o preço do seguro para o Kwid é o que apresenta a menor diferença entre as capitais cotadas para homens. O valor mais alto está no Rio de Janeiro com R$1.911 e o menor em São Paulo, por R$1.397, uma distância de R$514. No contraponto de diferença de valores, ainda citando o público masculino, o HB20 é que tem a maior diferença entre estados: R$1.558. A mais alta no Rio de Janeiro, R$3.185, e a menor em Belo Horizonte, com R$1.627.
+ Para os homens, São Paulo foi a cidade com seguro mais barato para oito dos dez veículos. Nos seguros com valores mais altos, o Rio de Janeiro é a cidade que detém os maiores preços: sete dos dez modelos. O preço médio do seguro para homens, em São Paulo, cidade com menor custo, para os 10 carros mais vendidos é de R$1.892. Já no Rio de Janeiro, o preço médio foi de R$2.905.
+ Análise do seguro – público feminino
+ Agora, falando no perfil feminino, o Kwid também foi o que apresentou a menor diferença entre as capitais cotadas, com uma diferença de R$503, do valor mais alto, que está no Rio de Janeiro, com R$1.767, para o mais baixo, que está em Belo Horizonte, com R$1.264. Falando agora sobre a distância de valores mais alta, o Renegade ficou com a maior: R$1.798. A maior no Rio de Janeiro, com R$4.263 e a menor, também em Belo Horizonte, com R$2.465.
+ No âmbito do público feminino, São Paulo e Belo Horizonte foram as cidades com o seguro mais barato: cinco modelos para cada um. Já os valores maiores estão concentrados no Rio de Janeiro com nove dos dez delos concentrados lá. O preço médio do seguro em São Paulo e Belo Horizonte, para as mulheres, ficou com R$1.805 e R$1.916, respectivamente. Já no Rio de Janeiro, o preço médio foi de R$2.844.
+ TABELAS COM OS VALORES DO SEGURO DOS CARROS MAIS VENDIDOS EM JUNHO
+
+
+ O post O valor do seguro dos carros mais vendidos do Brasil em junho apareceu primeiro em Blog Minuto Seguros .
+ ]]>
+ https://www.minutoseguros.com.br/blog/seguro-dos-carros-mais-vendidos-brasil-junho-2/feed/
+ 0
+ ";
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.Test/TopicoTest.cs b/Sources/Exercicio.PrincipaisPalavras.Test/TopicoTest.cs
new file mode 100644
index 0000000..af5d573
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.Test/TopicoTest.cs
@@ -0,0 +1,91 @@
+using Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro;
+using Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro.Interfaces;
+using Exercicio.PrincipaisPalavras.Test.Extensions;
+using Moq;
+using System.Linq;
+using Xunit;
+
+namespace Exercicio.PrincipaisPalavras.Test
+{
+ public class TopicoTest
+ {
+ private readonly Mock _blogMinutoSeguroService = null;
+
+ public TopicoTest()
+ {
+ _blogMinutoSeguroService = new Mock().ObterConteudoFeed_Topico();
+ }
+
+ [Fact]
+ public void Verificar_Conteudo_Titulo()
+ {
+ var html = _blogMinutoSeguroService.Object.ObterConteudoFeedAsync().Result;
+
+ var topico = new Topico(html);
+
+ Assert.NotEmpty(topico.Titulo);
+ Assert.True(!topico.Titulo.Contains("<") || !topico.Titulo.Contains(">"));
+ }
+
+ [Fact]
+ public void Verificar_Remocao_de_Tags_Titulo()
+ {
+ var html = _blogMinutoSeguroService.Object.ObterConteudoFeedAsync().Result;
+
+ var strHtml = new Topico(html).ObterStrHtml();
+
+ Assert.NotEmpty(strHtml);
+ Assert.True(!strHtml.Contains("link"));
+ Assert.True(!strHtml.Contains("lastBuildDate"));
+ Assert.True(!strHtml.Contains("language"));
+ Assert.True(!strHtml.Contains("sy:"));
+ Assert.True(!strHtml.Contains("generator"));
+ }
+
+ [Fact]
+ public void Verificar_Palavras_Artigo()
+ {
+ var html = _blogMinutoSeguroService.Object.ObterConteudoFeedAsync().Result;
+
+ var strHtml = new Topico(html).ObterStrHtml();
+
+ Assert.NotEmpty(strHtml);
+ Assert.DoesNotMatch(TopicoPattern.ObterPatternArtigos(), strHtml);
+ }
+
+ [Fact]
+ public void Verificar_Palavras_Preposicoes()
+ {
+ var html = _blogMinutoSeguroService.Object.ObterConteudoFeedAsync().Result;
+
+ var strHtml = new Topico(html).ObterStrHtml();
+
+ Assert.NotEmpty(strHtml);
+ Assert.DoesNotMatch(TopicoPattern.ObterPatternPreposicoes(), strHtml);
+ }
+
+ [Fact]
+ public void Verificar_Qtd_Palavras()
+ {
+ var html = _blogMinutoSeguroService.Object.ObterConteudoFeedAsync().Result;
+
+ var obj = new Topico(html);
+ obj.CarregarInformacoesTopico();
+
+ Assert.True(obj.QtdPalavras > 0);
+ }
+
+ [Fact]
+ public void Verificar_Palavras_Principais()
+ {
+ var html = _blogMinutoSeguroService.Object.ObterConteudoFeedAsync().Result;
+
+ var obj = new Topico(html);
+ obj.CarregarInformacoesTopico();
+
+ Assert.NotNull(obj.PalavraPrincipals);
+ Assert.True(obj.PalavraPrincipals.Any());
+ Assert.True(obj.PalavraPrincipals.Count == 10);
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.WebApi/Controllers/BlogMinutoSeguroController.cs b/Sources/Exercicio.PrincipaisPalavras.WebApi/Controllers/BlogMinutoSeguroController.cs
new file mode 100644
index 0000000..0a2f313
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.WebApi/Controllers/BlogMinutoSeguroController.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Exercicio.PrincipaisPalavras.Application.BlogMinutoSeguro.Interfaces;
+using Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro;
+using Exercicio.PrincipaisPalavras.Service.Core;
+using Exercicio.PrincipaisPalavras.WebApi.Core;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Exercicio.PrincipaisPalavras.WebApi.Controllers
+{
+ [Route("api/blogMinutoSeguro")]
+ [ApiController]
+ public class BlogMinutoSeguroController : WebApiControllerBase
+ {
+ private readonly IBlogMinutoSeguroApp _blogMinutoSeguroApp = null;
+
+ public BlogMinutoSeguroController(IBlogMinutoSeguroApp blogMinutoSeguroApp)
+ {
+ _blogMinutoSeguroApp = blogMinutoSeguroApp;
+ }
+
+ [HttpGet]
+ [Route("ObterPrincipaisPalavras")]
+ public async Task GetAsync()
+ {
+ return Reply(await _blogMinutoSeguroApp.ObterPrincipaisPalavrasAsync());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/Exercicio.PrincipaisPalavras.WebApi/Core/WebApiControllerBase.cs b/Sources/Exercicio.PrincipaisPalavras.WebApi/Core/WebApiControllerBase.cs
new file mode 100644
index 0000000..65b8aad
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.WebApi/Core/WebApiControllerBase.cs
@@ -0,0 +1,20 @@
+using Exercicio.PrincipaisPalavras.Service.Core;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Exercicio.PrincipaisPalavras.WebApi.Core
+{
+ public class WebApiControllerBase : ControllerBase
+ {
+ public ActionResult Reply(Response response)
+ {
+ if (response.IsValid)
+ return Ok(response);
+
+ return BadRequest(response.RasonPhrase);
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.WebApi/Exercicio.PrincipaisPalavras.WebApi.csproj b/Sources/Exercicio.PrincipaisPalavras.WebApi/Exercicio.PrincipaisPalavras.WebApi.csproj
new file mode 100644
index 0000000..3c00783
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.WebApi/Exercicio.PrincipaisPalavras.WebApi.csproj
@@ -0,0 +1,19 @@
+
+
+
+ netcoreapp2.2
+ InProcess
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sources/Exercicio.PrincipaisPalavras.WebApi/Exercicio.PrincipaisPalavras.WebApi.csproj.user b/Sources/Exercicio.PrincipaisPalavras.WebApi/Exercicio.PrincipaisPalavras.WebApi.csproj.user
new file mode 100644
index 0000000..2dbec45
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.WebApi/Exercicio.PrincipaisPalavras.WebApi.csproj.user
@@ -0,0 +1,13 @@
+
+
+
+ ApiControllerEmptyScaffolder
+ root/Controller
+ 600
+ True
+ False
+ True
+
+ False
+
+
\ No newline at end of file
diff --git a/Sources/Exercicio.PrincipaisPalavras.WebApi/Program.cs b/Sources/Exercicio.PrincipaisPalavras.WebApi/Program.cs
new file mode 100644
index 0000000..5551ff4
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.WebApi/Program.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+
+namespace Exercicio.PrincipaisPalavras.WebApi
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ CreateWebHostBuilder(args).Build().Run();
+ }
+
+ public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
+ WebHost.CreateDefaultBuilder(args)
+ .UseStartup();
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.WebApi/Properties/launchSettings.json b/Sources/Exercicio.PrincipaisPalavras.WebApi/Properties/launchSettings.json
new file mode 100644
index 0000000..3bc9934
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.WebApi/Properties/launchSettings.json
@@ -0,0 +1,30 @@
+{
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:51302",
+ "sslPort": 0
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "api/blogMinutoSeguro",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "Exercicio.PrincipaisPalavras.WebApi": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "api/blogMinutoSeguro",
+ "applicationUrl": "http://localhost:5000",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/Exercicio.PrincipaisPalavras.WebApi/Startup.cs b/Sources/Exercicio.PrincipaisPalavras.WebApi/Startup.cs
new file mode 100644
index 0000000..d2de489
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.WebApi/Startup.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Exercicio.PrincipaisPalavras.Application.BlogMinutoSeguro;
+using Exercicio.PrincipaisPalavras.Application.BlogMinutoSeguro.Interfaces;
+using Exercicio.PrincipaisPalavras.Infra.HttpService;
+using Exercicio.PrincipaisPalavras.Service.BlogMinutoSeguro.Interfaces;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace Exercicio.PrincipaisPalavras.WebApi
+{
+ public class Startup
+ {
+ public Startup(IConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ public IConfiguration Configuration { get; }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
+
+ //Http Services
+ services.AddSingleton();
+
+ //Application
+ services.AddSingleton();
+ }
+
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseMvc();
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.WebApi/appsettings.Development.json b/Sources/Exercicio.PrincipaisPalavras.WebApi/appsettings.Development.json
new file mode 100644
index 0000000..e203e94
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.WebApi/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ }
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.WebApi/appsettings.json b/Sources/Exercicio.PrincipaisPalavras.WebApi/appsettings.json
new file mode 100644
index 0000000..def9159
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.WebApi/appsettings.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/Sources/Exercicio.PrincipaisPalavras.sln b/Sources/Exercicio.PrincipaisPalavras.sln
new file mode 100644
index 0000000..e34f94d
--- /dev/null
+++ b/Sources/Exercicio.PrincipaisPalavras.sln
@@ -0,0 +1,66 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.705
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1 - Host", "1 - Host", "{5D47A049-D7E2-4FA2-800E-0CE14C0E617C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3 - Service", "3 - Service", "{03597842-B3C4-4D77-AA37-383AE9A63B5D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4 - Infra", "4 - Infra", "{560F5E76-29CE-4429-B40E-604E8577C3FC}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5 - Test", "5 - Test", "{F8BEF237-9829-49D7-A8F7-9BD75F92F20A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exercicio.PrincipaisPalavras.Infra.HttpService", "Exercicio.PrincipaisPalavras.Infra.HttpService\Exercicio.PrincipaisPalavras.Infra.HttpService.csproj", "{C6C28AED-A9C9-4882-814F-23BFAA178C2F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exercicio.PrincipaisPalavras.Service", "Exercicio.PrincipaisPalavras.Service\Exercicio.PrincipaisPalavras.Service.csproj", "{320E318D-FCC8-4F05-AC33-1F4C529D2361}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exercicio.PrincipaisPalavras.WebApi", "Exercicio.PrincipaisPalavras.WebApi\Exercicio.PrincipaisPalavras.WebApi.csproj", "{839FD6C2-E5B4-47F2-B0CD-77A0F8C96BA3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exercicio.PrincipaisPalavras.Test", "Exercicio.PrincipaisPalavras.Test\Exercicio.PrincipaisPalavras.Test.csproj", "{E6C53FE8-74C8-4E77-9A86-950AD4119763}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2 - Application", "2 - Application", "{2CAAB892-B7ED-439A-9E64-85997AA22B99}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exercicio.PrincipaisPalavras.Application", "Exercicio.PrincipaisPalavras.Application\Exercicio.PrincipaisPalavras.Application.csproj", "{0BBED86C-C154-43CC-9CCA-4FCB9BFDDE93}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C6C28AED-A9C9-4882-814F-23BFAA178C2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6C28AED-A9C9-4882-814F-23BFAA178C2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6C28AED-A9C9-4882-814F-23BFAA178C2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6C28AED-A9C9-4882-814F-23BFAA178C2F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {320E318D-FCC8-4F05-AC33-1F4C529D2361}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {320E318D-FCC8-4F05-AC33-1F4C529D2361}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {320E318D-FCC8-4F05-AC33-1F4C529D2361}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {320E318D-FCC8-4F05-AC33-1F4C529D2361}.Release|Any CPU.Build.0 = Release|Any CPU
+ {839FD6C2-E5B4-47F2-B0CD-77A0F8C96BA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {839FD6C2-E5B4-47F2-B0CD-77A0F8C96BA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {839FD6C2-E5B4-47F2-B0CD-77A0F8C96BA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {839FD6C2-E5B4-47F2-B0CD-77A0F8C96BA3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E6C53FE8-74C8-4E77-9A86-950AD4119763}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E6C53FE8-74C8-4E77-9A86-950AD4119763}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E6C53FE8-74C8-4E77-9A86-950AD4119763}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E6C53FE8-74C8-4E77-9A86-950AD4119763}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0BBED86C-C154-43CC-9CCA-4FCB9BFDDE93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0BBED86C-C154-43CC-9CCA-4FCB9BFDDE93}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0BBED86C-C154-43CC-9CCA-4FCB9BFDDE93}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0BBED86C-C154-43CC-9CCA-4FCB9BFDDE93}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C6C28AED-A9C9-4882-814F-23BFAA178C2F} = {560F5E76-29CE-4429-B40E-604E8577C3FC}
+ {320E318D-FCC8-4F05-AC33-1F4C529D2361} = {03597842-B3C4-4D77-AA37-383AE9A63B5D}
+ {839FD6C2-E5B4-47F2-B0CD-77A0F8C96BA3} = {5D47A049-D7E2-4FA2-800E-0CE14C0E617C}
+ {E6C53FE8-74C8-4E77-9A86-950AD4119763} = {F8BEF237-9829-49D7-A8F7-9BD75F92F20A}
+ {0BBED86C-C154-43CC-9CCA-4FCB9BFDDE93} = {2CAAB892-B7ED-439A-9E64-85997AA22B99}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {FC385AB2-659A-40BB-BC09-D8B48E71FB18}
+ EndGlobalSection
+EndGlobal