Merge pull request 'POS_Sprint_5' (#7) from POS_Sprint_5 into develop

Reviewed-on: #7
This commit is contained in:
Wojciech Przybyła 2021-01-14 20:00:41 +01:00
commit 8c97d210bc
24 changed files with 1216 additions and 720 deletions

View File

@ -14,6 +14,7 @@ using System.Net;
using System.Linq; using System.Linq;
using System.IO; using System.IO;
using Newtonsoft.Json; using Newtonsoft.Json;
using Klient.Droid.Modules;
namespace Klient.Droid namespace Klient.Droid
{ {
@ -48,7 +49,7 @@ namespace Klient.Droid
if (string.IsNullOrWhiteSpace(new NetworkCredential("", Password).Password)) if (string.IsNullOrWhiteSpace(new NetworkCredential("", Password).Password))
{ {
FindViewById<TextView>(Resource.Id.ErrorLogIn).Text = "Hasło musi mieć od 3 do 12 znaków!"; FindViewById<TextView>(Resource.Id.ErrorLogIn).Text = "Hasło nie może być puste ani zawierać spacji!";
FindViewById<EditText>(Resource.Id.Password).Text = ""; FindViewById<EditText>(Resource.Id.Password).Text = "";
} }
else else
@ -97,12 +98,12 @@ namespace Klient.Droid
if (Login.Length < 3 || Login.Length > 12) if (Login.Length < 3 || Login.Length > 12)
{ {
FindViewById<TextView>(Resource.Id.ErrorRegister).Text = "Login musi mięć od 3 do 12 znaków!"; FindViewById<TextView>(Resource.Id.ErrorRegister).Text = "Login musi mieć od 3 do 12 znaków!";
FindViewById<EditText>(Resource.Id.NewPassword).Text = ""; FindViewById<EditText>(Resource.Id.NewPassword).Text = "";
FindViewById<EditText>(Resource.Id.RepeatPassword).Text = ""; FindViewById<EditText>(Resource.Id.RepeatPassword).Text = "";
} }
else if (new NetworkCredential("", Password).Password.Length < 8 || new NetworkCredential("", Password).Password.Length > 20) else if (new NetworkCredential("", Password).Password.Length < 8 || new NetworkCredential("", Password).Password.Length > 20 || string.IsNullOrWhiteSpace(new NetworkCredential("", Password).Password))
{ {
FindViewById<TextView>(Resource.Id.ErrorRegister).Text = "Hasło musi mieć od 8 do 20 znaków!"; FindViewById<TextView>(Resource.Id.ErrorRegister).Text = "Hasło musi mieć od 8 do 20 znaków!";
FindViewById<EditText>(Resource.Id.NewPassword).Text = ""; FindViewById<EditText>(Resource.Id.NewPassword).Text = "";
@ -151,12 +152,17 @@ namespace Klient.Droid
} }
} }
[Java.Interop.Export("HelpLoginScreen")] [Java.Interop.Export("GoToProfile")]
public void GoBackToProfile(View v)
{
SetContentView(Resource.Layout.ekranProfil);
}
[Java.Interop.Export("GoToRegister")]
public void HelpLoginScreen(View v) public void HelpLoginScreen(View v)
{ {
SetContentView(Resource.Layout.ekranRejestracji); SetContentView(Resource.Layout.ekranRejestracji);
} }
[Java.Interop.Export("SignInMainScreen")] [Java.Interop.Export("SignInMainScreen")]
public void MainScreenSignIn(View v) public void MainScreenSignIn(View v)
{ {
@ -169,7 +175,7 @@ namespace Klient.Droid
SetContentView(Resource.Layout.ekranRejestracji); SetContentView(Resource.Layout.ekranRejestracji);
} }
[Java.Interop.Export("about")] [Java.Interop.Export("HelpLoginScreen")]
public void MainScreenAbout(View v) public void MainScreenAbout(View v)
{ {
SetContentView(Resource.Layout.ekranInformacji); SetContentView(Resource.Layout.ekranInformacji);
@ -225,7 +231,31 @@ namespace Klient.Droid
var response = await client.PostAsync("http://10.0.2.2:5001/api/Image/Process", formDataContent); var response = await client.PostAsync("http://10.0.2.2:5001/api/Image/Process", formDataContent);
if(response.StatusCode == HttpStatusCode.OK) if(response.StatusCode == HttpStatusCode.OK)
{ {
var jsonString = await response.Content.ReadAsStringAsync();
dynamic jsonObject = JsonConvert.DeserializeObject(jsonString);
FindViewById<TextView>(Resource.Id.ErrorPhoto).Text = "Przesłano zdjęcie!"; FindViewById<TextView>(Resource.Id.ErrorPhoto).Text = "Przesłano zdjęcie!";
SetContentView(Resource.Layout.ekranZLinkami);
var second_response = await client.GetAsync("http://10.0.2.2:5001/api/Search", jsonObject.response);
if(second_response.StatusCode == HttpStatusCode.OK)
{
var second_jsonString = await response.Content.ReadAsStringAsync();
dynamic second_jsonObject = JsonConvert.DeserializeObject(second_jsonString);
List<SearchResult> fullLink = JsonConvert.DeserializeObject<List<SearchResult>>(second_jsonObject);
int end = 10;
if (fullLink.Count < 10) end = fullLink.Count;
for (int i = 0; i < end; i++)
{
FindViewById<TextView>(Resource.Id.links).Text = FindViewById<TextView>(Resource.Id.links).Text + fullLink[i].Title + ": " + fullLink[i].Link + "\n\n";
}
}
else
{
FindViewById<TextView>(Resource.Id.links).Text = "Coś poszło nie tak!";
}
} }
else else
{ {
@ -291,5 +321,30 @@ namespace Klient.Droid
FindViewById<TextView>(Resource.Id.NullValueProfile).Text = msg; FindViewById<TextView>(Resource.Id.NullValueProfile).Text = msg;
} }
} }
[Java.Interop.Export("GetHistory")]
public async void GetUserHistory(View v)
{
SetContentView(Resource.Layout.ekranHistorii);
var response = await client.GetAsync("http://10.0.2.2:5001/api/History");
if (response.StatusCode == HttpStatusCode.OK)
{
var jsonString = await response.Content.ReadAsStringAsync();
dynamic jsonObject = JsonConvert.DeserializeObject(jsonString);
List<string> history = JsonConvert.DeserializeObject<List<string>>(jsonObject.history);
int end = 10;
int temp;
if (history.Count < 10) end = history.Count;
for (int i = 0; i < end; i++)
{
temp = i + 1;
FindViewById<TextView>(Resource.Id.history).Text = FindViewById<TextView>(Resource.Id.history).Text + "\n" + temp + ". " + history[i];
}
}
else
{
FindViewById<TextView>(Resource.Id.history).Text = "Coś poszło nie tak!";
}
}
} }
} }

View File

@ -0,0 +1,20 @@
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Klient.Droid.Modules
{
public class SearchResult
{
public string Title { get; set; }
public string Link { get; set; }
public string Snippet { get; set; }
}
}

View File

@ -73,6 +73,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="MainActivity.cs" /> <Compile Include="MainActivity.cs" />
<Compile Include="Modules\SearchResult.cs" />
<Compile Include="Resources\Resource.designer.cs" /> <Compile Include="Resources\Resource.designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
@ -98,7 +99,6 @@
<AndroidResource Include="Resources\mipmap-xxxhdpi\launcher_foreground.png" /> <AndroidResource Include="Resources\mipmap-xxxhdpi\launcher_foreground.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Modules\" />
<Folder Include="Resources\drawable-hdpi\" /> <Folder Include="Resources\drawable-hdpi\" />
<Folder Include="Resources\drawable-xhdpi\" /> <Folder Include="Resources\drawable-xhdpi\" />
<Folder Include="Resources\drawable-xxhdpi\" /> <Folder Include="Resources\drawable-xxhdpi\" />
@ -150,10 +150,30 @@
</AndroidResource> </AndroidResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<AndroidResourceAnalysisConfig Include="Resources\layout\ekranInformacji.xml"> <AndroidResourceAnalysisConfig Include="Resources\layout\ekranPomocRejestracja.xml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</AndroidResourceAnalysisConfig> </AndroidResourceAnalysisConfig>
</ItemGroup> </ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\ekranPomocZdjecie.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\ekranHistorii.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\ekranInformacji.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\ekranZLinkami.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<ProjectExtensions> <ProjectExtensions>
<VisualStudio> <VisualStudio>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffbdd7f0">
<Button
android:text="Back"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backHistory"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ff0b31c8"
android:textColor="#fffcfcfc"
android:gravity="center"
android:onClick="GoToProfile" />
<TextView
android:text="Poszukiwacz 2021"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text3"
android:textColor="#ff000000"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
<TextView
android:text="Historia wyszukiwań"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/HistoryTitle"
android:textStyle="bold"
android:layout_centerHorizontal="true"
android:textSize="30dp"
android:paddingTop="5dp"
android:textColor="#ff000000" />
<TextView
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history"
android:layout_below="@+id/HistoryTitle"
android:textColor="#ff000000" />
</RelativeLayout>

View File

@ -18,7 +18,8 @@
android:id="@+id/title" android:id="@+id/title"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:textSize="50dp" android:textSize="50dp"
android:textStyle="bold" /> android:textStyle="bold"
android:textColor="#ff000000" />
<TextView <TextView
android:text="Poszukiwacz jest aplikacją mobilną pozwalającą na wyszukiwanie w Internece stron zawierających schematy i tutoriale na podstawie treści zadania. \n Jednocześnie pomaga w nauce, jaki i przyśpiesza proces dokonywania researchu danych. " android:text="Poszukiwacz jest aplikacją mobilną pozwalającą na wyszukiwanie w Internece stron zawierających schematy i tutoriale na podstawie treści zadania. \n Jednocześnie pomaga w nauce, jaki i przyśpiesza proces dokonywania researchu danych. "
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
@ -27,7 +28,8 @@
android:id="@+id/textView1" android:id="@+id/textView1"
android:layout_below="@id/title" android:layout_below="@id/title"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:gravity="center_horizontal" /> android:gravity="center_horizontal"
android:textColor="#ff373737" />
<TextView <TextView
android:text="Poszukiwacz 2021" android:text="Poszukiwacz 2021"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
@ -55,3 +57,5 @@
</RelativeLayout> </RelativeLayout>

View File

@ -60,17 +60,6 @@
android:text="Zaloguj" android:text="Zaloguj"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:foregroundGravity="center" /> android:foregroundGravity="center" />
<Button
android:text="?"
android:layout_width="35.0dp"
android:layout_height="35.0dp"
android:id="@+id/help"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#ff0b31c8"
android:textColor="#fffcfcfc"
android:gravity="center"
android:onClick="HelpLoginScreen" />
<Button <Button
android:text="Back" android:text="Back"
android:layout_width="38.5dp" android:layout_width="38.5dp"

View File

@ -21,7 +21,6 @@
android:layout_marginLeft="75dp" android:layout_marginLeft="75dp"
android:onClick="LoadFromFolder" /> android:onClick="LoadFromFolder" />
<TextView <TextView
android:text="Poszukiwacz 2021"
android:text="Poszukiwacz 2021" android:text="Poszukiwacz 2021"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -57,13 +56,13 @@
android:text="?" android:text="?"
android:layout_width="35.0dp" android:layout_width="35.0dp"
android:layout_height="35.0dp" android:layout_height="35.0dp"
android:id="@+id/helpRegister" android:id="@+id/helpPhoto"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:background="#ff0b31c8" android:background="#ff0b31c8"
android:textColor="#fffcfcfc" android:textColor="#fffcfcfc"
android:gravity="center" android:gravity="center"
android:onClick="HelpRegisterScreen" /> android:onClick="HelpPhoto" />
<ImageButton <ImageButton
android:src="@drawable/obraz3" android:src="@drawable/obraz3"
android:layout_width="63.5dp" android:layout_width="63.5dp"

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffbdd7f0">
<TextView
android:text="Login powinien składać się z 3 do 12 znaków!"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/loginTip"
android:paddingTop="20dp"
android:textColor="#ff000000" />
<TextView
android:text="Hasło musi się składać z 8 do 20 znaków!"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/passwordTip"
android:layout_below="@+id/loginTip"
android:paddingTop="10dp"
android:textColor="#ff000000" />
<TextView
android:text="To jest pomoc \n w rejestracji \n co miałem \n napisac"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView1"
android:textColor="#ffb1d5f8"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true" /> <TextView
android:text="Poszukiwacz 2021"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text1"
android:textColor="#ff000000"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" /> <Button
android:text="Back"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backRegisterHelp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ff0b31c8"
android:textColor="#fffcfcfc"
android:gravity="center"
android:onClick="GoToRegister" /> </RelativeLayout>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffbdd7f0">
<TextView
android:text="Poszukiwacz 2021"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text1"
android:textColor="#ff000000"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
<Button
android:text="Back"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backPomocZdjecie"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ff0b31c8"
android:textColor="#fffcfcfc"
android:gravity="center"
android:onClick="GoToPoLogowaniu" />
<TextView
android:text="W celu załadowania zdjęcia z pamięci telefonu \nwybierz ikonę folderu, w celu zrobnienia zdjęcia \nwybierz ikonę aparatu i postępuj jak przy robieniu zdjęcia. \nNa następnym ekranie zostanie wyświtlony \npodgląd załadowanego zdjęcia."
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView1" />
</RelativeLayout>

View File

@ -94,7 +94,6 @@
android:layout_below="@id/Save" android:layout_below="@id/Save"
android:textColor="#ffd60000" /> android:textColor="#ffd60000" />
<TextView <TextView
android:text="Poszukiwacz 2021"
android:text="Poszukiwacz 2021" android:text="Poszukiwacz 2021"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -114,4 +113,12 @@
android:textColor="#fffcfcfc" android:textColor="#fffcfcfc"
android:gravity="center" android:gravity="center"
android:onClick="GoToPoLogowaniu" /> android:onClick="GoToPoLogowaniu" />
<Button
android:text="Historia"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/GetHistory"
android:layout_below="@id/Save"
android:translationY="45dp"
android:onClick="GetHistory" />
</RelativeLayout> </RelativeLayout>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffbdd7f0">
<TextView
android:text="Proponowane materiały"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/linkTitle"
android:textStyle="bold"
android:layout_centerHorizontal="true"
android:translationY="5dp"
android:textColor="#ff000000" />
<TextView
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/links"
android:layout_below="@+id/linkTitle"
android:textColor="#ff393939"
android:linksClickable="true"
android:autoLink="web" />
<Button
android:text="Back"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backToSendPhoto"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ff0b31c8"
android:textColor="#fffcfcfc"
android:gravity="center"
android:onClick="GoToPoLogowaniu" />
<TextView
android:text="Poszukiwacz 2021"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text1"
android:textColor="#ff000000"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>

View File

@ -0,0 +1,28 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Serwer.Infrastructure.Services;
using System;
using System.Threading.Tasks;
namespace Serwer.Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class HistoryController: ControllerBase
{
private readonly IHistoryService _historyService;
public HistoryController(IHistoryService historyService)
{
_historyService = historyService;
}
[Authorize]
[HttpGet()]
public async Task<IActionResult> Get()
{
var id = User.Identity.Name;
var history = await _historyService.GetAsync(Guid.Parse(id));
return Ok(history);
}
}
}

View File

@ -23,7 +23,8 @@ namespace Serwer.Api.Controllers
[HttpGet("{query}")] [HttpGet("{query}")]
public async Task<IActionResult> Search(string query) public async Task<IActionResult> Search(string query)
{ {
var results = await _searchService.Search(query); var id = User.Identity.Name;
var results = await _searchService.Search(Guid.Parse(id), query);
return Ok(results); return Ok(results);
} }
} }

View File

@ -89,8 +89,10 @@ namespace Serwer.Api
services.AddSingleton<IMapper>(AutoMapperConfig.Initialize()); services.AddSingleton<IMapper>(AutoMapperConfig.Initialize());
services.AddSingleton<IJwtHandler, JwtHandler>(sp => new JwtHandler(jwtSettings)); services.AddSingleton<IJwtHandler, JwtHandler>(sp => new JwtHandler(jwtSettings));
services.AddScoped<IUserRepository, UserRepository>(); services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IHistoryRepository, HistoryRepository>();
services.AddScoped<IImageHandler, ImageHandler>(); services.AddScoped<IImageHandler, ImageHandler>();
services.AddScoped<IUserService, UserService>(); services.AddScoped<IUserService, UserService>();
services.AddScoped<IHistoryService, HistoryService>();
services.AddScoped<ISearchService, SearchService>(); services.AddScoped<ISearchService, SearchService>();
} }

View File

@ -33,7 +33,7 @@ namespace Serwer.Core.Domain
{ {
if (string.IsNullOrWhiteSpace(email)) if (string.IsNullOrWhiteSpace(email))
{ {
throw new Exception("Email cannot be empty"); throw new Exception("Email nie może być pusty.");
} }
if (Email == email) if (Email == email)
{ {
@ -48,7 +48,7 @@ namespace Serwer.Core.Domain
{ {
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
{ {
throw new Exception("Name cannot be empty"); throw new Exception("Imię nie może być puste.");
} }
if (Name == name) if (Name == name)
{ {
@ -63,7 +63,7 @@ namespace Serwer.Core.Domain
{ {
if (string.IsNullOrWhiteSpace(surname)) if (string.IsNullOrWhiteSpace(surname))
{ {
throw new Exception("Surname cannot be empty"); throw new Exception("Nazwisko nie może być puste.");
} }
if (Surname == surname) if (Surname == surname)
{ {
@ -78,7 +78,7 @@ namespace Serwer.Core.Domain
{ {
if (string.IsNullOrWhiteSpace(login)) if (string.IsNullOrWhiteSpace(login))
{ {
throw new Exception("Login cannot be empty"); throw new Exception("Login nie może być pusty.");
} }
if (Login == login) if (Login == login)
{ {
@ -93,7 +93,7 @@ namespace Serwer.Core.Domain
{ {
if (string.IsNullOrWhiteSpace(password)) if (string.IsNullOrWhiteSpace(password))
{ {
throw new Exception("Password cannot be empty"); throw new Exception("Hasło nie może być puste.");
} }
if (Password == password) if (Password == password)
{ {

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Core.Domain
{
public class UserHistory
{
private readonly ISet<string> _history;
public User User { get; protected set; }
public List<string> History
{
get
{
return _history.Select(x => x).ToList();
}
}
public UserHistory(User user)
{
User = user;
_history = new HashSet<string>();
}
public void Add(string query)
{
_history.Add(query);
}
}
}

View File

@ -0,0 +1,15 @@
using Serwer.Core.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Core.Repositories
{
public interface IHistoryRepository
{
Task AddAsync(User user, string query);
Task<UserHistory> GetAsync(User user);
}
}

View File

@ -0,0 +1,31 @@
using Serwer.Core.Domain;
using Serwer.Core.Repositories;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Repositories
{
public class HistoryRepository: IHistoryRepository
{
private static ISet<UserHistory> _history = new HashSet<UserHistory>();
public async Task AddAsync(User user, string query)
{
var history = _history.FirstOrDefault(x => x.User.Id == user.Id);
if(history == null)
{
history = new UserHistory(user);
}
history.Add(query);
await Task.FromResult(_history.Add(history));
}
public async Task<UserHistory> GetAsync(User user)
{
var history = _history.FirstOrDefault(x => x.User.Id == user.Id);
return await Task.FromResult(history);
}
}
}

View File

@ -0,0 +1,32 @@
using Serwer.Core.Domain;
using Serwer.Core.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Services
{
public class HistoryService: IHistoryService
{
private readonly IHistoryRepository _historyRepository;
private readonly IUserRepository _userRepository;
public HistoryService(IHistoryRepository historyRepository, IUserRepository userRepository)
{
_historyRepository = historyRepository;
_userRepository = userRepository;
}
public async Task<UserHistory> GetAsync(Guid userId)
{
var user = await _userRepository.GetAsync(userId);
if(user == null)
{
throw new Exception("Coś poszło nie tak.");
}
var history = await _historyRepository.GetAsync(user);
return history;
}
}
}

View File

@ -0,0 +1,14 @@
using Serwer.Core.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Services
{
public interface IHistoryService
{
Task<UserHistory> GetAsync(Guid userId);
}
}

View File

@ -8,6 +8,6 @@ namespace Serwer.Infrastructure.Services
{ {
public interface ISearchService public interface ISearchService
{ {
Task<IList<SearchResultDTO>> Search(string query); Task<IList<SearchResultDTO>> Search(Guid userId, string query);
} }
} }

View File

@ -1,6 +1,7 @@
using Google.Apis.Customsearch.v1; using Google.Apis.Customsearch.v1;
using Google.Apis.Services; using Google.Apis.Services;
using Newtonsoft.Json; using Newtonsoft.Json;
using Serwer.Core.Repositories;
using Serwer.Infrastructure.DTO; using Serwer.Infrastructure.DTO;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -15,14 +16,25 @@ namespace Serwer.Infrastructure.Services
public class SearchService : ISearchService public class SearchService : ISearchService
{ {
private readonly IImageHandler _imageHandler; private readonly IImageHandler _imageHandler;
private readonly IHistoryRepository _historyRepository;
private readonly IUserRepository _userRepository;
private const string apiKey = "AIzaSyCagG6QyQyBuJNb1YDuK25qSzoC0Rrjo0c"; private const string apiKey = "AIzaSyCagG6QyQyBuJNb1YDuK25qSzoC0Rrjo0c";
private const string searchEngineId = "17b946686537c46e3"; private const string searchEngineId = "17b946686537c46e3";
public SearchService(IImageHandler imageHandler) public SearchService(IImageHandler imageHandler, IHistoryRepository historyRepository, IUserRepository userRepository)
{ {
_imageHandler = imageHandler; _imageHandler = imageHandler;
_historyRepository = historyRepository;
_userRepository = userRepository;
} }
public async Task<IList<SearchResultDTO>> Search(string query) public async Task<IList<SearchResultDTO>> Search(Guid userId, string query)
{ {
var user = await _userRepository.GetAsync(userId);
if(user == null)
{
throw new Exception("Coś poszło nie tak.");
}
await _historyRepository.AddAsync(user, query);
WebRequest webRequest = WebRequest.Create($"https://www.googleapis.com/customsearch/v1?key={apiKey}&cx={searchEngineId}&q={query}"); WebRequest webRequest = WebRequest.Create($"https://www.googleapis.com/customsearch/v1?key={apiKey}&cx={searchEngineId}&q={query}");
using (var stream = new StreamReader(webRequest.GetResponse().GetResponseStream())) using (var stream = new StreamReader(webRequest.GetResponse().GetResponseStream()))
{ {

View File

@ -29,7 +29,7 @@ namespace Serwer.Infrastructure.Services
{ {
if(await _userRepository.GetAsync(login) != null) if(await _userRepository.GetAsync(login) != null)
{ {
throw new Exception($"User with login: {login} already exists."); throw new Exception($"Użytkownik z loginem: {login} już istnieje.");
} }
var user = new User(Guid.NewGuid(), email, name, surname, login, password); var user = new User(Guid.NewGuid(), email, name, surname, login, password);
await _userRepository.AddAsync(user); await _userRepository.AddAsync(user);
@ -40,11 +40,11 @@ namespace Serwer.Infrastructure.Services
var user = await _userRepository.GetAsync(login); var user = await _userRepository.GetAsync(login);
if(user == null) if(user == null)
{ {
throw new Exception("User not found."); throw new Exception("Nie znaleziono użytkownika.");
} }
if(user.Password != password) if(user.Password != password)
{ {
throw new Exception("Incorrect password."); throw new Exception("Hasło niepoprawne.");
} }
var jwt = _jwtHandler.CreateToken(user.Id); var jwt = _jwtHandler.CreateToken(user.Id);
@ -61,12 +61,12 @@ namespace Serwer.Infrastructure.Services
var user = await _userRepository.GetAsync(userModel.Id); var user = await _userRepository.GetAsync(userModel.Id);
if(user == null) if(user == null)
{ {
throw new Exception("User not found."); throw new Exception("Nie znaleziono użytkownika.");
} }
var userLoginTaken = await _userRepository.GetAsync(userModel.Login); var userLoginTaken = await _userRepository.GetAsync(userModel.Login);
if(userLoginTaken != null && userLoginTaken.Id != user.Id) if(userLoginTaken != null && userLoginTaken.Id != user.Id)
{ {
throw new Exception("User login taken."); throw new Exception("Login jest już zajęty.");
} }
var newUser = new User(user.Id, userModel.Email, userModel.Name, userModel.Surname, userModel.Login, user.Password); var newUser = new User(user.Id, userModel.Email, userModel.Name, userModel.Surname, userModel.Login, user.Password);