From 5d3dad6f7f63f467c00217ca742744bd185f6415 Mon Sep 17 00:00:00 2001 From: Cleiton Felipe de Moraes Date: Thu, 30 Apr 2020 19:24:37 -0300 Subject: [PATCH] Add feature sentiment analysis --- .../Resources/Resource.designer.cs | 1 + .../TravelMonkey.Android.csproj | 86 +++++++++----- src/TravelMonkey.iOS/TravelMonkey.iOS.csproj | 79 +++++++++---- src/TravelMonkey.sln | 56 +++++---- src/TravelMonkey/ApiKeys.cs | 14 ++- src/TravelMonkey/ColorConstants.cs | 22 ++++ src/TravelMonkey/EmojiConstants.cs | 13 ++ src/TravelMonkey/Services/SentimentService.cs | 50 ++++++++ src/TravelMonkey/TravelMonkey.csproj | 9 +- .../SentimentResultPageViewModel.cs | 111 ++++++++++++++++++ src/TravelMonkey/Views/MainPage.xaml | 9 ++ src/TravelMonkey/Views/MainPage.xaml.cs | 5 + .../Views/SentimentResultPage.xaml | 36 ++++++ .../Views/SentimentResultPage.xaml.cs | 38 ++++++ 14 files changed, 444 insertions(+), 85 deletions(-) create mode 100644 src/TravelMonkey/ColorConstants.cs create mode 100644 src/TravelMonkey/EmojiConstants.cs create mode 100644 src/TravelMonkey/Services/SentimentService.cs create mode 100644 src/TravelMonkey/ViewModels/SentimentResultPageViewModel.cs create mode 100644 src/TravelMonkey/Views/SentimentResultPage.xaml create mode 100644 src/TravelMonkey/Views/SentimentResultPage.xaml.cs diff --git a/src/TravelMonkey.Android/Resources/Resource.designer.cs b/src/TravelMonkey.Android/Resources/Resource.designer.cs index 5e6cbf4..15832c1 100644 --- a/src/TravelMonkey.Android/Resources/Resource.designer.cs +++ b/src/TravelMonkey.Android/Resources/Resource.designer.cs @@ -2,6 +2,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. diff --git a/src/TravelMonkey.Android/TravelMonkey.Android.csproj b/src/TravelMonkey.Android/TravelMonkey.Android.csproj index 4b9a5ab..e606195 100644 --- a/src/TravelMonkey.Android/TravelMonkey.Android.csproj +++ b/src/TravelMonkey.Android/TravelMonkey.Android.csproj @@ -1,4 +1,4 @@ - + Debug @@ -53,6 +53,9 @@ + + 4.0.0 + @@ -93,63 +96,84 @@ - - + + + + - - + + + + - - + + + + - - + + + + - - + + + + - - + + + + - - + + + + - - + + + + - - + + + + - - + + + + - - + + + + - - + + + + - - - - + {04991790-FBB2-415A-9531-268B4193DB3E} TravelMonkey - - + + \ No newline at end of file diff --git a/src/TravelMonkey.iOS/TravelMonkey.iOS.csproj b/src/TravelMonkey.iOS/TravelMonkey.iOS.csproj index 479887f..38d53b8 100644 --- a/src/TravelMonkey.iOS/TravelMonkey.iOS.csproj +++ b/src/TravelMonkey.iOS/TravelMonkey.iOS.csproj @@ -75,24 +75,60 @@ false - - - - - - - - - - - - - - - - - - + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + @@ -103,6 +139,9 @@ + + 4.0.0 + @@ -129,7 +168,5 @@ - - - + \ No newline at end of file diff --git a/src/TravelMonkey.sln b/src/TravelMonkey.sln index 222f516..2773034 100644 --- a/src/TravelMonkey.sln +++ b/src/TravelMonkey.sln @@ -1,57 +1,65 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30011.22 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TravelMonkey.Android", "TravelMonkey.Android\TravelMonkey.Android.csproj", "{A06A377B-F901-4238-88BD-A92726C715C2}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TravelMonkey.iOS", "TravelMonkey.iOS\TravelMonkey.iOS.csproj", "{8C00CCB8-214B-4B88-8042-4C8D31284CD3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TravelMonkey", "TravelMonkey\TravelMonkey.csproj", "{04991790-FBB2-415A-9531-268B4193DB3E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TravelMonkey", "TravelMonkey\TravelMonkey.csproj", "{04991790-FBB2-415A-9531-268B4193DB3E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - Debug|iPhoneSimulator = Debug|iPhoneSimulator - Release|iPhoneSimulator = Release|iPhoneSimulator Debug|iPhone = Debug|iPhone + Debug|iPhoneSimulator = Debug|iPhoneSimulator + Release|Any CPU = Release|Any CPU Release|iPhone = Release|iPhone + Release|iPhoneSimulator = Release|iPhoneSimulator EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {A06A377B-F901-4238-88BD-A92726C715C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A06A377B-F901-4238-88BD-A92726C715C2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A06A377B-F901-4238-88BD-A92726C715C2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A06A377B-F901-4238-88BD-A92726C715C2}.Release|Any CPU.Build.0 = Release|Any CPU - {A06A377B-F901-4238-88BD-A92726C715C2}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {A06A377B-F901-4238-88BD-A92726C715C2}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {A06A377B-F901-4238-88BD-A92726C715C2}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {A06A377B-F901-4238-88BD-A92726C715C2}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {A06A377B-F901-4238-88BD-A92726C715C2}.Debug|Any CPU.Deploy.0 = Debug|Any CPU {A06A377B-F901-4238-88BD-A92726C715C2}.Debug|iPhone.ActiveCfg = Debug|Any CPU {A06A377B-F901-4238-88BD-A92726C715C2}.Debug|iPhone.Build.0 = Debug|Any CPU + {A06A377B-F901-4238-88BD-A92726C715C2}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {A06A377B-F901-4238-88BD-A92726C715C2}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {A06A377B-F901-4238-88BD-A92726C715C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A06A377B-F901-4238-88BD-A92726C715C2}.Release|Any CPU.Build.0 = Release|Any CPU {A06A377B-F901-4238-88BD-A92726C715C2}.Release|iPhone.ActiveCfg = Release|Any CPU {A06A377B-F901-4238-88BD-A92726C715C2}.Release|iPhone.Build.0 = Release|Any CPU + {A06A377B-F901-4238-88BD-A92726C715C2}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {A06A377B-F901-4238-88BD-A92726C715C2}.Release|iPhoneSimulator.Build.0 = Release|Any CPU {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator - {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator - {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Release|Any CPU.Build.0 = Release|iPhoneSimulator - {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Debug|iPhone.ActiveCfg = Debug|iPhone {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Debug|iPhone.Build.0 = Debug|iPhone + {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator + {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator + {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator + {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Release|Any CPU.Build.0 = Release|iPhoneSimulator {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Release|iPhone.ActiveCfg = Release|iPhone {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Release|iPhone.Build.0 = Release|iPhone + {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator + {8C00CCB8-214B-4B88-8042-4C8D31284CD3}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator {04991790-FBB2-415A-9531-268B4193DB3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {04991790-FBB2-415A-9531-268B4193DB3E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {04991790-FBB2-415A-9531-268B4193DB3E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {04991790-FBB2-415A-9531-268B4193DB3E}.Release|Any CPU.Build.0 = Release|Any CPU - {04991790-FBB2-415A-9531-268B4193DB3E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {04991790-FBB2-415A-9531-268B4193DB3E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {04991790-FBB2-415A-9531-268B4193DB3E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {04991790-FBB2-415A-9531-268B4193DB3E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU {04991790-FBB2-415A-9531-268B4193DB3E}.Debug|iPhone.ActiveCfg = Debug|Any CPU {04991790-FBB2-415A-9531-268B4193DB3E}.Debug|iPhone.Build.0 = Debug|Any CPU + {04991790-FBB2-415A-9531-268B4193DB3E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {04991790-FBB2-415A-9531-268B4193DB3E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {04991790-FBB2-415A-9531-268B4193DB3E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {04991790-FBB2-415A-9531-268B4193DB3E}.Release|Any CPU.Build.0 = Release|Any CPU {04991790-FBB2-415A-9531-268B4193DB3E}.Release|iPhone.ActiveCfg = Release|Any CPU {04991790-FBB2-415A-9531-268B4193DB3E}.Release|iPhone.Build.0 = Release|Any CPU + {04991790-FBB2-415A-9531-268B4193DB3E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {04991790-FBB2-415A-9531-268B4193DB3E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {97E4151C-8E27-4626-9979-1DF3B0700197} EndGlobalSection EndGlobal diff --git a/src/TravelMonkey/ApiKeys.cs b/src/TravelMonkey/ApiKeys.cs index 82c4dd3..f1f6cd7 100644 --- a/src/TravelMonkey/ApiKeys.cs +++ b/src/TravelMonkey/ApiKeys.cs @@ -2,13 +2,15 @@ { public static class ApiKeys { - #warning You need to set up your API keys. - public static string ComputerVisionApiKey = ""; - public static string TranslationsApiKey = ""; - public static string BingImageSearch = ""; + //#warning You need to set up your API keys. + public static string ComputerVisionApiKey = "d8401cb58e5e417ebb12b5eaebe02620"; + public static string TranslationsApiKey = "71e2c2b0bf2148aa911ec2949669f153"; + public static string BingImageSearch = "2d4288fd604942f29c193fd2f48a1ac0"; + public static string SentimentApiKey = "4ffe47d6c6a14d0baf88faa0d3cede22"; // Change this to the Azure Region you are using - public static string ComputerVisionEndpoint = "https://westeurope.api.cognitive.microsoft.com/"; - public static string TranslationsEndpoint = "https://api.cognitive.microsofttranslator.com/"; + public static string ComputerVisionEndpoint = "https://brazilsouth.api.cognitive.microsoft.com/"; + public static string TranslationsEndpoint = "https://api.cognitive.microsoft.com/"; + public static string SentimentEndpoint = "https://brazilsouth.api.cognitive.microsoft.com/"; } } \ No newline at end of file diff --git a/src/TravelMonkey/ColorConstants.cs b/src/TravelMonkey/ColorConstants.cs new file mode 100644 index 0000000..4688b56 --- /dev/null +++ b/src/TravelMonkey/ColorConstants.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xamarin.Forms; + +namespace TravelMonkey +{ + public class ColorConstants + { + public static Color DefaultBackgroundColor => Color.FromHex("#FFF"); + + public static Color EmotionColor9 => Color.FromHex("#29EB94"); + public static Color EmotionColor8 => Color.FromHex("#31C774"); + public static Color EmotionColor7 => Color.FromHex("#2E9C5F"); + public static Color EmotionColor6 => Color.FromHex("#208946"); + public static Color EmotionColor5 => Color.FromHex("#3D81DF"); + public static Color EmotionColor4 => Color.FromHex("#CC2C66"); + public static Color EmotionColor3 => Color.FromHex("#CB3359"); + public static Color EmotionColor2 => Color.FromHex("#B01C41"); + public static Color EmotionColor1 => Color.FromHex("#7F1437"); + } +} diff --git a/src/TravelMonkey/EmojiConstants.cs b/src/TravelMonkey/EmojiConstants.cs new file mode 100644 index 0000000..ea0f845 --- /dev/null +++ b/src/TravelMonkey/EmojiConstants.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TravelMonkey +{ + public class EmojiConstants + { + public const string SadFaceEmoji = "😢"; + public const string NeutralFaceEmoji = "\U0001F610"; + public const string HappyFaceEmoji = "\U0001F603"; + } +} diff --git a/src/TravelMonkey/Services/SentimentService.cs b/src/TravelMonkey/Services/SentimentService.cs new file mode 100644 index 0000000..4469cd2 --- /dev/null +++ b/src/TravelMonkey/Services/SentimentService.cs @@ -0,0 +1,50 @@ +using Microsoft.Azure.CognitiveServices.Language.TextAnalytics; +using Microsoft.Azure.CognitiveServices.Language.TextAnalytics.Models; +using Microsoft.Rest; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace TravelMonkey.Services +{ + public class SentimentService + { + public async Task sentimentAnalysis(ITextAnalyticsClient client, string text) + { + var result = await client.SentimentAsync(text, "en"); + return result; + } + + public TextAnalyticsClient authenticateClient() + { + ApiKeySentimentServiceClientCredentials credentials = new ApiKeySentimentServiceClientCredentials(); + TextAnalyticsClient client = new TextAnalyticsClient(credentials) + { + Endpoint = ApiKeys.SentimentEndpoint + }; + return client; + } + } + public class ApiKeySentimentServiceClientCredentials : ServiceClientCredentials + { + private readonly string apiKey; + + public ApiKeySentimentServiceClientCredentials() + { + this.apiKey = ApiKeys.SentimentApiKey; + } + + public override Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + request.Headers.Add("Ocp-Apim-Subscription-Key", this.apiKey); + return base.ProcessHttpRequestAsync(request, cancellationToken); + } + } +} diff --git a/src/TravelMonkey/TravelMonkey.csproj b/src/TravelMonkey/TravelMonkey.csproj index de0691b..3f1ad36 100644 --- a/src/TravelMonkey/TravelMonkey.csproj +++ b/src/TravelMonkey/TravelMonkey.csproj @@ -11,6 +11,7 @@ + @@ -22,11 +23,8 @@ - - - @@ -51,4 +49,9 @@ Code + + + MSBuild:UpdateDesignTimeXaml + + \ No newline at end of file diff --git a/src/TravelMonkey/ViewModels/SentimentResultPageViewModel.cs b/src/TravelMonkey/ViewModels/SentimentResultPageViewModel.cs new file mode 100644 index 0000000..2bdff69 --- /dev/null +++ b/src/TravelMonkey/ViewModels/SentimentResultPageViewModel.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Text; +using TravelMonkey.Services; +using Xamarin.Forms; + +namespace TravelMonkey.ViewModels +{ + public class SentimentResultPageViewModel : BaseViewModel + { + private readonly SentimentService sentimentService = new SentimentService(); + + #region Fields + string _emojiLabelText = string.Empty; + string _userInputEntryText = string.Empty; + Color _backgroundColor = ColorConstants.DefaultBackgroundColor; + #endregion + + #region Properties + public string EmojiLabelText + { + get => _emojiLabelText; + set => Set(ref _emojiLabelText, value); + } + + public string UserInputEntryText + { + get => _userInputEntryText; + set + { + Set(ref _userInputEntryText, value); + //GetSentiment(); + } + } + + public Color BackgroundColor + { + get => _backgroundColor; + set => Set(ref _backgroundColor, value); + } + #endregion + + + public Command SentimentTextCommand => new Command(() => + { + GetSentiment(); + }); + + private async void GetSentiment() + { + var client = sentimentService.authenticateClient(); + var result = await sentimentService.sentimentAnalysis(client, UserInputEntryText.ToString()); + + if (result.Score == null) + MessagingCenter.Send(this, "Oops something went wrong here. :("); + + SetEmoji(result.Score); + SetBackgroundColor(result.Score); + } + + void SetEmoji(double? result) + { + switch (result) + { + case double number when (number < 0.4): + EmojiLabelText = EmojiConstants.SadFaceEmoji; + break; + case double number when (number >= 0.4 && number <= 0.6): + EmojiLabelText = EmojiConstants.NeutralFaceEmoji; + break; + case double number when (number > 0.6): + EmojiLabelText = EmojiConstants.HappyFaceEmoji; + break; + } + } + + void SetBackgroundColor(double? result) + { + switch (result) + { + case double number when (number <= 0.1): + BackgroundColor = ColorConstants.EmotionColor1; + break; + case double number when (number > 0.1 && number <= 0.2): + BackgroundColor = ColorConstants.EmotionColor2; + break; + case double number when (number > 0.2 && number <= 0.3): + BackgroundColor = ColorConstants.EmotionColor3; + break; + case double number when (number > 0.3 && number <= 0.4): + BackgroundColor = ColorConstants.EmotionColor4; + break; + case double number when (number > 0.4 && number <= 0.6): + BackgroundColor = ColorConstants.EmotionColor5; + break; + case double number when (number > 0.6 && number <= 0.7): + BackgroundColor = ColorConstants.EmotionColor6; + break; + case double number when (number > 0.7 && number <= 0.8): + BackgroundColor = ColorConstants.EmotionColor7; + break; + case double number when (number > 0.8 && number <= 0.9): + BackgroundColor = ColorConstants.EmotionColor8; + break; + case double number when (number > 0.9): + BackgroundColor = ColorConstants.EmotionColor9; + break; + } + } + } +} diff --git a/src/TravelMonkey/Views/MainPage.xaml b/src/TravelMonkey/Views/MainPage.xaml index ee8eb69..5177b2e 100644 --- a/src/TravelMonkey/Views/MainPage.xaml +++ b/src/TravelMonkey/Views/MainPage.xaml @@ -74,6 +74,15 @@ + + + diff --git a/src/TravelMonkey/Views/MainPage.xaml.cs b/src/TravelMonkey/Views/MainPage.xaml.cs index 8b2b41f..0c3b039 100644 --- a/src/TravelMonkey/Views/MainPage.xaml.cs +++ b/src/TravelMonkey/Views/MainPage.xaml.cs @@ -36,6 +36,11 @@ private async void AddNewPicture_Tapped(object sender, EventArgs e) await Navigation.PushModalAsync(new AddPicturePage()); } + private async void TextSentiment_Tapped(object sender, EventArgs e) + { + await Navigation.PushModalAsync(new SentimentResultPage()); + } + private async void Entry_Completed(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(TranslateTextEntry.Text)) diff --git a/src/TravelMonkey/Views/SentimentResultPage.xaml b/src/TravelMonkey/Views/SentimentResultPage.xaml new file mode 100644 index 0000000..e50b5fe --- /dev/null +++ b/src/TravelMonkey/Views/SentimentResultPage.xaml @@ -0,0 +1,36 @@ + + + + + + + + + +