Merge pull request 'develop' (#10) from develop into master

Reviewed-on: #10
This commit is contained in:
Wojciech Przybyła 2021-01-27 18:32:18 +01:00
commit 74df2904b2
87 changed files with 18456 additions and 7317 deletions

View File

@ -1,11 +1,11 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio Version 16
VisualStudioVersion = 15.0.28307.1300 VisualStudioVersion = 16.0.30717.126
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Klient.Android", "Klient\Klient.Android\Klient.Android.csproj", "{8FF60786-AD97-4373-9B4D-6EF28BE7C2A2}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Poszukiwacz", "Klient\Klient.Android\Poszukiwacz.csproj", "{8FF60786-AD97-4373-9B4D-6EF28BE7C2A2}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Klient", "Klient\Klient\Klient.csproj", "{46672F33-450A-4DD4-BA9F-C15E88C20AC8}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Klient", "Klient\Klient\Klient.csproj", "{46672F33-450A-4DD4-BA9F-C15E88C20AC8}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -6,20 +6,471 @@ using Android.Runtime;
using Android.Views; using Android.Views;
using Android.Widget; using Android.Widget;
using Android.OS; using Android.OS;
using Xamarin.Essentials;
using System.Net.Http;
using System.Collections.Generic;
using System.Security;
using System.Net;
using System.Linq;
using Newtonsoft.Json;
using Klient.Droid.Modules;
using Android.Provider;
using Android.Content;
using Android.Graphics;
using Newtonsoft.Json.Linq;
using Com.Xamarin.Formsviewgroup;
using Android.Icu.Text;
using System.IO;
using Android.Media;
using System.Threading.Tasks;
using Java.IO;
using System.Net.Http.Headers;
namespace Klient.Droid namespace Klient.Droid
{ {
[Activity(Label = "Klient", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] [Activity(Label = "Klient", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{ {
Bitmap bitmap;
ByteArrayContent fileContent;
public static int PickImageId = 1000;
private static readonly HttpClient client = new HttpClient();
public static Android.Content.Intent photo;
public string savedLogin = "";
public string savedName = "";
public string savedSurname = "";
public string savedEmail = "";
private string userId = "";
private string userToken = "";
protected override void OnCreate(Bundle savedInstanceState) protected override void OnCreate(Bundle savedInstanceState)
{ {
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState); base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.SetVmPolicy(builder.Build());
LoadApplication(new App()); LoadApplication(new App());
SetContentView(Resource.Layout.ekranStartowy);
}
[Java.Interop.Export("SignIn")]
async public void SignIn(Android.Views.View v)
{
var Login = FindViewById<EditText>(Resource.Id.Login).Text;
SecureString Password = new NetworkCredential("", FindViewById<EditText>(Resource.Id.Password).Text).SecurePassword;
if (string.IsNullOrWhiteSpace(new NetworkCredential("", Password).Password))
{
FindViewById<TextView>(Resource.Id.ErrorLogIn).Text = "Hasło nie może być puste ani zawierać spacji!";
FindViewById<EditText>(Resource.Id.Password).Text = "";
}
else
{
var values = new Dictionary<string, string>
{
{ "login", Login },
{ "password", new NetworkCredential("", Password).Password }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://10.0.2.2:5001/api/User/SignIn", content);
if (response.StatusCode == HttpStatusCode.OK)
{
var jsonString = await response.Content.ReadAsStringAsync();
dynamic jsonObject = JsonConvert.DeserializeObject(jsonString);
SetContentView(Resource.Layout.ekranPoLogowaniu);
savedLogin = jsonObject.user.login;
savedName = jsonObject.user.name;
savedEmail = jsonObject.user.email;
savedSurname = jsonObject.user.surname;
userId = jsonObject.user.id;
userToken = jsonObject.jwt.token;
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", userToken);
}
else
{
string msg = await response.Content.ReadAsStringAsync();
FindViewById<TextView>(Resource.Id.ErrorLogIn).Text = msg;
FindViewById<EditText>(Resource.Id.Password).Text = "";
}
}
}
[Java.Interop.Export("HelpLoginScreen")]
public void GoToAboutScreen(View v)
{
SetContentView(Resource.Layout.ekranInformacji);
}
[Java.Interop.Export("SignUp")]
async public void SignUp(View v)
{
var Name = FindViewById<EditText>(Resource.Id.Name).Text;
var Surname = FindViewById<EditText>(Resource.Id.Surname).Text;
var Email = FindViewById<EditText>(Resource.Id.Email).Text;
var Login = FindViewById<EditText>(Resource.Id.NewLogin).Text;
SecureString Password = new NetworkCredential("", FindViewById<EditText>(Resource.Id.NewPassword).Text).SecurePassword;
SecureString Password2 = new NetworkCredential("", FindViewById<EditText>(Resource.Id.RepeatPassword).Text).SecurePassword;
if (Login.Length < 3 || Login.Length > 12)
{
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.RepeatPassword).Text = "";
}
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<EditText>(Resource.Id.NewPassword).Text = "";
FindViewById<EditText>(Resource.Id.RepeatPassword).Text = "";
}
else if (new NetworkCredential("", Password).Password != new NetworkCredential("", Password2).Password)
{
FindViewById<TextView>(Resource.Id.ErrorRegister).Text = "Hasła muszą być identyczne!";
FindViewById<EditText>(Resource.Id.NewPassword).Text = "";
FindViewById<EditText>(Resource.Id.RepeatPassword).Text = "";
}
else if(string.IsNullOrEmpty(FindViewById<EditText>(Resource.Id.NewLogin).Text) || string.IsNullOrEmpty(FindViewById<EditText>(Resource.Id.Email).Text) || string.IsNullOrEmpty(FindViewById<EditText>(Resource.Id.NewPassword).Text) || string.IsNullOrEmpty(FindViewById<EditText>(Resource.Id.RepeatPassword).Text) || string.IsNullOrEmpty(FindViewById<EditText>(Resource.Id.Name).Text) || string.IsNullOrEmpty(FindViewById<EditText>(Resource.Id.Surname).Text))
{
FindViewById<TextView>(Resource.Id.ErrorRegister).Text = "Wartości nie mogą być puste!";
FindViewById<EditText>(Resource.Id.NewPassword).Text = "";
FindViewById<EditText>(Resource.Id.RepeatPassword).Text = "";
}
else
{
var values = new Dictionary<string, string>
{
{ "email", Email },
{ "name", Name },
{ "surname", Surname },
{ "login", Login },
{ "password", new NetworkCredential("", Password).Password }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://10.0.2.2:5001/api/User/Register", content);
var responseString = await response.Content.ReadAsStringAsync();
if (response.StatusCode == HttpStatusCode.OK) SetContentView(Resource.Layout.ekranLogowania);
else
{
string msg = await response.Content.ReadAsStringAsync();
FindViewById<TextView>(Resource.Id.ErrorRegister).Text = msg;
FindViewById<EditText>(Resource.Id.Password).Text = "";
FindViewById<EditText>(Resource.Id.RepeatPassword).Text = "";
}
}
}
[Java.Interop.Export("HelpRegisterScreen")]
public void GoToRegisterHelp(View v)
{
SetContentView(Resource.Layout.ekranPomocRejestracja);
}
[Java.Interop.Export("GoToProfile")]
public void GoBackToProfile(View v)
{
SetContentView(Resource.Layout.ekranProfil);
}
[Java.Interop.Export("GoToRegister")]
public void HelpLoginScreen(View v)
{
SetContentView(Resource.Layout.ekranRejestracji);
}
[Java.Interop.Export("SignInMainScreen")]
public void MainScreenSignIn(View v)
{
SetContentView(Resource.Layout.ekranLogowania);
}
[Java.Interop.Export("SignUpMainScreen")]
public void MainScreenSignUp(View v)
{
SetContentView(Resource.Layout.ekranRejestracji);
}
[Java.Interop.Export("GoToMainScreenFromInformation")]
public void GoToMainScreenFromInformation(View v)
{
SetContentView(Resource.Layout.ekranStartowy);
}
[Java.Interop.Export("LoadFromFolder")]
public void LoadFile(View v)
{
Intent = new Android.Content.Intent();
Intent.SetType("image/*");
Intent.SetAction(Android.Content.Intent.ActionGetContent);
StartActivityForResult(Android.Content.Intent.CreateChooser(Intent, "Select Picture"), PickImageId);
}
[Java.Interop.Export("LoadFromCamera")]
public void LoadFromCamera(View v)
{
Intent intent = new Intent(MediaStore.ActionImageCapture);
StartActivityForResult(intent, 0);
}
[Java.Interop.Export("GoToStart")]
public void GoToStart(View v)
{
SetContentView(Resource.Layout.ekranStartowy);
}
[Java.Interop.Export("GoToPoLogowaniu")]
public void GoToPoLogowaniu(View v)
{
SetContentView(Resource.Layout.ekranPoLogowaniu);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Android.Content.Intent data)
{
SetContentView(Resource.Layout.ekranPoZdjeciu);
FindViewById<TextView>(Resource.Id.ErrorPhoto).Text = "";
if (requestCode == 0)
{
photo = data;
base.OnActivityResult(requestCode, resultCode, data);
if (data != null)
{
bitmap = (Bitmap)data.Extras.Get("data");
byte[] bitmapData;
var stream = new MemoryStream();
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 60, stream);
bitmapData = stream.ToArray();
fileContent = new ByteArrayContent(bitmapData);
FindViewById<ImageView>(Resource.Id.Preview).SetImageBitmap(bitmap);
}
else SetContentView(Resource.Layout.ekranPoLogowaniu);
}
else if(requestCode == PickImageId)
{
if(data == null) SetContentView(Resource.Layout.ekranPoLogowaniu);
else
{
Android.Net.Uri uri = data.Data;
photo = data;
FindViewById<ImageView>(Resource.Id.Preview).SetImageURI(uri);
}
}
else if(data == null)
{
SetContentView(Resource.Layout.ekranPoLogowaniu);
}
}
[Java.Interop.Export("SendPhoto")]
async public void UploadPhoto(View v)
{
if(photo.Data == null)
{
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "image",
FileName = Guid.NewGuid().ToString()
};
string boundary = "---8d0f01e6b3b5dafaaadaad";
MultipartFormDataContent formDataContent = new MultipartFormDataContent(boundary);
formDataContent.Add(fileContent);
var response = await client.PostAsync("http://10.0.2.2:5001/api/Image/Process", formDataContent);
if (response.StatusCode == HttpStatusCode.OK)
{
var jsonString = await response.Content.ReadAsStringAsync();
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/{jsonString}");
if (second_response.StatusCode == HttpStatusCode.OK)
{
var second_jsonString = await response.Content.ReadAsStringAsync();
List<SearchResult> fullLink = JsonConvert.DeserializeObject<List<SearchResult>>(second_jsonString);
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 + ": \n" + fullLink[i].link + "\n\n";
}
}
else
{
FindViewById<TextView>(Resource.Id.links).Text = "Coś poszło nie tak!";
}
}
else
{
string msg = await response.Content.ReadAsStringAsync();
FindViewById<TextView>(Resource.Id.ErrorPhoto).Text = msg;
}
}
using(var imageStream = ContentResolver.OpenInputStream(photo.Data))
using(var stramContent = new StreamContent(imageStream))
using(var byteArrayContent = new ByteArrayContent(await stramContent.ReadAsByteArrayAsync()))
using(var formDataContent = new MultipartFormDataContent())
{
formDataContent.Add(byteArrayContent, "image", Guid.NewGuid() + ".jpg");
foreach (var content in formDataContent)
{
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentResolver.GetType(photo.Data));
break;
}
var response = await client.PostAsync("http://10.0.2.2:5001/api/Image/Process", formDataContent);
if(response.StatusCode == HttpStatusCode.OK)
{
var jsonString = await response.Content.ReadAsStringAsync();
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/{jsonString}");
if(second_response.StatusCode == HttpStatusCode.OK)
{
var second_jsonString = await second_response.Content.ReadAsStringAsync();
List<SearchResult> fullLink = JsonConvert.DeserializeObject<List<SearchResult>>(second_jsonString);
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
{
string msg = await response.Content.ReadAsStringAsync();
FindViewById<TextView>(Resource.Id.ErrorPhoto).Text = msg;
}
}
}
[Java.Interop.Export("GoToProfil")]
public void GoToProfile(View v)
{
SetContentView(Resource.Layout.ekranProfil);
FindViewById<EditText>(Resource.Id.ChangeName).Text = savedName;
FindViewById<EditText>(Resource.Id.ChangeSurname).Text = savedSurname;
FindViewById<EditText>(Resource.Id.ChangeEmail).Text = savedEmail;
FindViewById<TextView>(Resource.Id.ProfilPageLogin).Text = savedLogin;
}
[Java.Interop.Export("Save")]
public async void SaveChanges(View v)
{
var Name = FindViewById<EditText>(Resource.Id.ChangeName).Text;
var Surname = FindViewById<EditText>(Resource.Id.ChangeSurname).Text;
var Email = FindViewById<EditText>(Resource.Id.ChangeEmail).Text;
if (string.IsNullOrEmpty(Name))
{
Name = savedName;
}
if (string.IsNullOrEmpty(Email))
{
Email = savedEmail;
}
if (string.IsNullOrEmpty(Surname))
{
Surname = savedSurname;
}
var values = new Dictionary<string, string>
{
{ "id", userId },
{ "email", Email },
{ "name", Name },
{ "surname", Surname },
{ "login", savedLogin }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://10.0.2.2:5001/api/User/Update", content);
if (response.StatusCode == HttpStatusCode.OK)
{
FindViewById<TextView>(Resource.Id.NullValueProfile).Text = "Zapisano!";
var jsonString = await response.Content.ReadAsStringAsync();
dynamic jsonObject = JsonConvert.DeserializeObject(jsonString);
savedLogin = jsonObject.login;
savedName = jsonObject.name;
savedEmail = jsonObject.email;
savedSurname = jsonObject.surname;
}
else
{
string msg = await response.Content.ReadAsStringAsync();
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);
var hs = (JArray)jsonObject.history;
List<string> history = hs.ToObject<List<string>>();
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
{
string msg = await response.Content.ReadAsStringAsync();
FindViewById<TextView>(Resource.Id.HistoryError).Text = msg;
}
}
[Java.Interop.Export("HelpPhoto")]
public void GotToHelpPhoto(View v)
{
SetContentView(Resource.Layout.ekranPomocZdjecie);
}
[Java.Interop.Export("LogOut")]
public void LogOut(View v)
{
SetContentView(Resource.Layout.ekranStartowy);
} }
} }
} }

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

@ -8,7 +8,7 @@
<TemplateGuid>{c9e5eea5-ca05-42a1-839b-61506e0a37df}</TemplateGuid> <TemplateGuid>{c9e5eea5-ca05-42a1-839b-61506e0a37df}</TemplateGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<RootNamespace>Klient.Droid</RootNamespace> <RootNamespace>Klient.Droid</RootNamespace>
<AssemblyName>Klient.Android</AssemblyName> <AssemblyName>Poszukiwacz</AssemblyName>
<AndroidApplication>True</AndroidApplication> <AndroidApplication>True</AndroidApplication>
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile> <AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
<AndroidResgenClass>Resource</AndroidResgenClass> <AndroidResgenClass>Resource</AndroidResgenClass>
@ -16,7 +16,7 @@
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix> <MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix> <MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk> <AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v8.1</TargetFrameworkVersion> <TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType> <AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
<NuGetPackageImportStamp> <NuGetPackageImportStamp>
</NuGetPackageImportStamp> </NuGetPackageImportStamp>
@ -30,6 +30,13 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AndroidLinkMode>None</AndroidLinkMode> <AndroidLinkMode>None</AndroidLinkMode>
<AotAssemblies>false</AotAssemblies>
<EnableLLVM>false</EnableLLVM>
<AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
<BundleAssemblies>false</BundleAssemblies>
<MandroidI18n />
<Debugger>Xamarin</Debugger>
<AndroidSupportedAbis />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@ -42,22 +49,32 @@
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime> <AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Mono.Android" /> <Reference Include="Mono.Android" />
<Reference Include="Mono.Android.Export" />
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Xamarin.Forms" Version="3.4.0.1008975" /> <PackageReference Include="Newtonsoft.Json">
<PackageReference Include="Xamarin.Android.Support.Design" Version="27.0.2.1" /> <Version>12.0.3</Version>
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="27.0.2.1" /> </PackageReference>
<PackageReference Include="Xamarin.Android.Support.v4" Version="27.0.2.1" /> <PackageReference Include="Xamarin.Essentials">
<PackageReference Include="Xamarin.Android.Support.v7.CardView" Version="27.0.2.1" /> <Version>1.5.3.2</Version>
<PackageReference Include="Xamarin.Android.Support.v7.MediaRouter" Version="27.0.2.1" /> </PackageReference>
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1687" />
<PackageReference Include="Xamarin.Android.Support.Design" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.v4" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.v7.CardView" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.v7.MediaRouter" Version="28.0.0.3" />
</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>
@ -67,8 +84,6 @@
<None Include="Properties\AndroidManifest.xml" /> <None Include="Properties\AndroidManifest.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<AndroidResource Include="Resources\layout\Tabbar.axml" />
<AndroidResource Include="Resources\layout\Toolbar.axml" />
<AndroidResource Include="Resources\values\styles.xml" /> <AndroidResource Include="Resources\values\styles.xml" />
<AndroidResource Include="Resources\values\colors.xml" /> <AndroidResource Include="Resources\values\colors.xml" />
<AndroidResource Include="Resources\mipmap-anydpi-v26\icon.xml" /> <AndroidResource Include="Resources\mipmap-anydpi-v26\icon.xml" />
@ -85,12 +100,10 @@
<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\" />
<Folder Include="Resources\drawable-xxxhdpi\" /> <Folder Include="Resources\drawable-xxxhdpi\" />
<Folder Include="Resources\drawable\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Klient\Klient.csproj"> <ProjectReference Include="..\Klient\Klient.csproj">
@ -98,5 +111,83 @@
<Name>Klient</Name> <Name>Klient</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\ekranLogowania.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\ekranRejestracji.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\ekranStartowy.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\ekranPoLogowaniu.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\Obraz2.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\Obraz1.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\ekranPoZdjeciu.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\Obraz3.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\ekranProfil.xml">
<SubType>Designer</SubType>
</AndroidResource>
</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>
<ItemGroup>
<AndroidResource Include="Resources\layout\ekranPomocRejestracja.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\Obraz4.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\xml\file_paths.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\Obraz8.png" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties TriggeredFromHotReload="False" />
</VisualStudio>
</ProjectExtensions>
</Project> </Project>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.Klient.Android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.Klient.Android" android:installLocation="internalOnly">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" /> <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="27" />
<application android:label="Klient.Android"></application> <application android:label="Klient.Android" android:usesCleartextTraffic="true" android:theme="@style/Base.Theme.AppCompat.Light.DarkActionBar" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest> </manifest>

View File

@ -15,6 +15,7 @@ using Android.App;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: Application(Theme = "@style/Base.Theme.AppCompat.Light.DarkActionBar")]
// Version information for an assembly consists of the following four values: // Version information for an assembly consists of the following four values:
// //

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.TabLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabIndicatorColor="@android:color/white"
app:tabGravity="fill"
app:tabMode="fixed" />

View File

@ -1,9 +0,0 @@
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

View File

@ -0,0 +1,69 @@
<?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">
<ImageButton
android:src="@drawable/obraz4"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backHistory"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ffbdd7f0"
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/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/HistoryError"
android:textColor="#ff000000"
android:paddingBottom="35dp"
android:focusableInTouchMode="true"
android:isScrollContainer="true"
android:fadeScrollbars="true"
android:scrollbars="vertical"
android:verticalScrollbarPosition="right"
android:scrollIndicators="right"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:textIsSelectable="true"
android:paddingTop="10dp"/>
<TextView
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/HistoryError"
android:layout_below="@+id/HistoryTitle"
android:textColor="#ffff0000"
android:layout_centerInParent="true"
android:paddingTop="10dp" />
</RelativeLayout>

View File

@ -0,0 +1,60 @@
<?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"
android:paddingTop="30dp">
<TextView
android:text="Poszukiwacz"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/title"
android:layout_centerHorizontal="true"
android:textSize="50dp"
android:textStyle="bold"
android:textColor="#ff000000" />
<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:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView1"
android:layout_below="@id/title"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:textColor="#ff373737" />
<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" />
<ImageButton
android:src="@drawable/obraz4"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backInformation"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ffbdd7f0"
android:gravity="center"
android:onClick="GoToMainScreenFromInformation" />
</RelativeLayout>

View File

@ -0,0 +1,92 @@
<?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"
>
<android.support.design.widget.TextInputLayout
android:id="@+id/LayoutLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:hint="Login">
<EditText
android:layout_width="204.0dp"
android:layout_height="58.0dp"
android:id="@+id/Login"
android:layout_alignParentStart="false"
android:minWidth="25px"
android:minHeight="25px"
android:layout_centerInParent="false"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:inputType="text"
android:textColor="#ff000000"
android:textColorHint="#ff6c6767" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/LayoutPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
android:layout_below="@+id/LayoutLogin"
android:layout_centerHorizontal="true"
app:passwordToggleTint="@android:color/darker_gray"
android:hint="Hasło"
android:gravity="left">
<EditText
android:layout_width="204.0dp"
android:layout_height="58.0dp"
android:id="@+id/Password"
android:layout_centerHorizontal="true"
android:layout_below="@+id/Login"
android:inputType="none|textPassword"
android:textColor="#ff000000"
android:textColorHint="#ff6c6767" />
</android.support.design.widget.TextInputLayout>
<Button
android:layout_width="100.5dp"
android:layout_height="50dp"
android:id="@+id/In"
android:layout_below="@id/LayoutPassword"
android:layout_alignParentRight="false"
android:gravity="center"
android:onClick="SignIn"
android:text="Zaloguj"
android:layout_centerHorizontal="true"
android:foregroundGravity="center" />
<ImageButton
android:src="@drawable/obraz4"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backLogowanie"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ffbdd7f0"
android:gravity="center"
android:onClick="GoToStart"/>
<TextView
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ErrorLogIn"
android:textColor="#ffd60000"
android:layout_below="@id/In"
android:layout_centerHorizontal="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" />
</RelativeLayout>

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffbdd7f0">
<ImageButton
android:src="@drawable/Obraz1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="80px"
android:minHeight="80px"
android:id="@+id/LoadFromFolder"
android:contentDescription="Wybieranie z pliku"
android:background="#ffbdd7f0"
android:layout_below="@+id/text5"
android:layout_alignParentRight="false"
android:layout_centerHorizontal="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="75dp"
android:onClick="LoadFromFolder" />
<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="Załaduj zdjęcie"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text5"
android:layout_centerHorizontal="true"
android:layout_marginVertical="100dp"
android:textSize="45dp"
android:textColor="#ff000000"
android:gravity="center" />
<ImageButton
android:src="@drawable/obraz2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/LoadFromCamera"
android:contentDescription="Zrób zdjęcie"
android:background="#ffbdd7f0"
android:layout_centerHorizontal="true"
android:layout_below="@+id/text5"
android:layout_alignParentRight="true"
android:layout_marginRight="75dp"
android:onClick="LoadFromCamera" />
<Button
android:text="?"
android:layout_width="35.0dp"
android:layout_height="35.0dp"
android:id="@+id/helpPhoto"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#ff0b31c8"
android:textColor="#fffcfcfc"
android:gravity="center"
android:onClick="HelpPhoto" />
<ImageButton
android:src="@drawable/obraz3"
android:layout_width="63.5dp"
android:layout_height="70.5dp"
android:background="#ffbdd7f0"
android:id="@+id/Profile"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:onClick="GoToProfil"/>
</RelativeLayout>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffbdd7f0">
<ImageView
android:src="@android:drawable/ic_menu_gallery"
android:layout_width="match_parent"
android:layout_height="217.5dp"
android:minWidth="100px"
android:minHeight="100px"
android:id="@+id/Preview" />
<Button
android:text="Wyślij zdjęcie"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/SendPhoto"
android:onClick="SendPhoto"
android:layout_below="@id/Preview" />
<TextView
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ErrorPhoto"
android:layout_centerHorizontal="true"
android:layout_below="@id/SendPhoto"
android:textColor="#ffd60000" />
<ImageButton
android:src="@drawable/obraz4"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backZdjecie"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ffbdd7f0"
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,59 @@
<?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" />
<ImageButton
android:src="@drawable/obraz4"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backRegisterHelp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ffbdd7f0"
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" />
<ImageButton
android:src="@drawable/obraz4"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backPomocZdjecie"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ffbdd7f0"
android:gravity="center"
android:onClick="GoToPoLogowaniu" />
<TextView
android:text="W celu załadowania zdjęcia z pamięci telefonu \nwybierz ikonę folderu, w celu zrobienia 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"
android:textColor="#ff000000" />
</RelativeLayout>

View File

@ -0,0 +1,132 @@
<?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">
<TextView
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ProfilPageLogin"
android:layout_centerHorizontal="true"
android:textStyle="bold"
android:textSize="30dp" />
<android.support.design.widget.TextInputLayout
android:id="@+id/LayoutNameC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/ProfilPageLogin"
android:hint="Imie"
android:layout_alignParentLeft="true">
<android.support.design.widget.TextInputEditText
android:layout_width="204.0dp"
android:layout_height="58.0dp"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/ChangeName"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:capitalize="words"
android:textColorHint="#ff6c6767"
android:textColor="#ff000000"
android:inputType="none|textPersonName" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/LayoutSurnameC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:hint="Nazwisko"
android:layout_below="@id/LayoutNameC"
android:layout_alignParentLeft="true">
<android.support.design.widget.TextInputEditText
android:layout_width="204.0dp"
android:layout_height="58.0dp"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/ChangeSurname"
android:textColorHint="#ff6c6767"
android:textColor="#ff000000"
android:inputType="none|textPersonName" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/LayoutEmailC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:hint="Adres email"
android:layout_below="@id/LayoutSurnameC"
android:layout_alignParentLeft="true">
<android.support.design.widget.TextInputEditText
android:layout_width="204.0dp"
android:layout_height="58.0dp"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/ChangeEmail"
android:textColorHint="#ff6c6767"
android:textColor="#ff000000"
android:inputType="none|textEmailAddress" />
</android.support.design.widget.TextInputLayout>
<Button
android:text="Zapisz"
android:layout_width="100.5dp"
android:layout_height="50dp"
android:id="@+id/Save"
android:layout_below="@id/LayoutEmailC"
android:layout_centerHorizontal="true"
android:foregroundGravity="center"
android:gravity="center"
android:onClick="Save"/>
<TextView
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/NullValueProfile"
android:layout_centerHorizontal="true"
android:layout_below="@id/Save"
android:textColor="#ffd60000" />
<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" />
<ImageButton
android:src="@drawable/obraz4"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backProfil"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ffbdd7f0"
android:gravity="center"
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" />
<ImageButton
android:src="@drawable/obraz8"
android:layout_width="35.0dp"
android:layout_height="35.0dp"
android:background="#ffbdd7f0"
android:id="@+id/LogOut"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:onClick="LogOut" />
</RelativeLayout>

View File

@ -0,0 +1,177 @@
<?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">
<android.support.design.widget.TextInputLayout
android:id="@+id/LayoutName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:hint="Imie"
android:layout_alignParentLeft="true">
<android.support.design.widget.TextInputEditText
android:layout_width="204.0dp"
android:layout_height="58.0dp"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/Name"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:capitalize="words"
android:textColorHint="#ff6c6767"
android:textColor="#ff000000"
android:inputType="none|textPersonName" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/LayoutSurname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:hint="Nazwisko"
android:layout_below="@id/LayoutName"
android:layout_alignParentLeft="true">
<android.support.design.widget.TextInputEditText
android:layout_width="204.0dp"
android:layout_height="58.0dp"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/Surname"
android:textColorHint="#ff6c6767"
android:layout_below="@id/Name"
android:textColor="#ff000000"
android:inputType="none|textPersonName" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/LayoutEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:hint="Adres email"
android:layout_below="@id/LayoutSurname"
android:layout_alignParentLeft="true">
<android.support.design.widget.TextInputEditText
android:layout_width="204.0dp"
android:layout_height="58.0dp"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/Email"
android:textColorHint="#ff6c6767"
android:textColor="#ff000000"
android:inputType="none|textEmailAddress" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/LayoutNewPassword1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
app:passwordToggleTint="@android:color/darker_gray"
android:layout_centerHorizontal="true"
android:hint="Hasło"
android:layout_below="@id/LayoutEmail"
android:layout_alignParentLeft="true">
<android.support.design.widget.TextInputEditText
android:layout_width="204.0dp"
android:layout_height="58.0dp"
android:minWidth="25px"
android:minHeight="25px"
android:textColor="#ff000000"
android:textColorHint="#ff6c6767"
android:id="@+id/NewPassword"
android:inputType="none|textPassword" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/LayoutNewPassword2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:hint="Powtórz hasło"
app:passwordToggleEnabled="true"
app:passwordToggleTint="@android:color/darker_gray"
android:layout_below="@id/LayoutNewPassword1"
android:layout_alignParentLeft="true">
<android.support.design.widget.TextInputEditText
android:layout_width="204.0dp"
android:layout_height="58.0dp"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/RepeatPassword"
android:inputType="none|textPassword"
android:textColor="#ff000000"
android:textColorHint="#ff6c6767" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/LayoutNewLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:hint="Login"
android:layout_below="@id/LayoutNewPassword2"
android:layout_alignParentLeft="true">
<android.support.design.widget.TextInputEditText
android:layout_width="204.0dp"
android:layout_height="58.0dp"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/NewLogin"
android:textColor="#ff000000"
android:layout_below="@+id/Surname" />
</android.support.design.widget.TextInputLayout>
<Button
android:text=" Załóż \n konto"
android:layout_width="100.5dp"
android:layout_height="50dp"
android:id="@+id/SignUp"
android:autoSizeTextType="uniform"
android:gravity="center"
android:layout_below="@id/LayoutNewLogin"
android:layout_alignParentRight="false"
android:foregroundGravity="center"
android:layout_centerHorizontal="true"
android:onClick="SignUp" />
<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=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ErrorRegister"
android:textColor="#ffd60000"
android:layout_below="@id/SignUp"
android:layout_centerHorizontal="true" />
<Button
android:text="?"
android:layout_width="35.0dp"
android:layout_height="35.0dp"
android:id="@+id/helpRegister"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#ff0b31c8"
android:textColor="#fffcfcfc"
android:gravity="center"
android:onClick="HelpRegisterScreen" />
<ImageButton
android:src="@drawable/obraz4"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backRejestracja"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ffbdd7f0"
android:gravity="center"
android:onClick="GoToStart" />
</RelativeLayout>

View File

@ -0,0 +1,61 @@
<?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"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/text4"
android:layout_centerHorizontal="true"
android:textColor="#ff000000"
android:textStyle="bold"
android:textSize="45dp"
android:layout_marginVertical="100dp" />
<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="?"
android:layout_width="25.0dp"
android:layout_height="25.0dp"
android:id="@+id/about"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#ff0b31c8"
android:textColor="#fffcfcfc"
android:gravity="center"
android:onClick="HelpLoginScreen" />
<Button
android:text="Zaloguj"
android:layout_width="200.0dp"
android:layout_height="70.0dp"
android:id="@+id/SignInMainScreen"
android:layout_alignParentLeft="false"
android:layout_centerInParent="true"
android:onClick="SignInMainScreen" />
<Button
android:text="Stwórz konto"
android:layout_width="200.0dp"
android:layout_height="50.0dp"
android:id="@+id/SignUpMainScreen"
android:layout_centerInParent="true"
android:layout_below="@+id/SignInMainScreen"
android:layout_marginVertical="15dp"
android:onClick="SignUpMainScreen" />
</RelativeLayout>

View File

@ -0,0 +1,70 @@
<?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/LinkError"
android:textColor="#ff393939"
android:linksClickable="true"
android:autoLink="web"
android:fadeScrollbars="true"
android:scrollbars="vertical"
android:verticalScrollbarPosition="right"
android:scrollIndicators="right"
android:paddingBottom="35dp"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:isScrollContainer="true"
android:textIsSelectable="true"
android:focusableInTouchMode="true"
android:paddingTop="10dp" />
<TextView
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/linkTitle"
android:id="@+id/LinkError"
android:textColor="#ffff0000"
android:layout_centerInParent="true"
android:paddingTop="10dp" />
<ImageButton
android:src="@drawable/obraz4"
android:layout_width="38.5dp"
android:layout_height="35.0dp"
android:id="@+id/backToSendPhoto"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#ffbdd7f0"
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

@ -4,7 +4,7 @@
<style name="MainTheme" parent="MainTheme.Base"> <style name="MainTheme" parent="MainTheme.Base">
</style> </style>
<!-- Base theme applied no matter what API --> <!-- Base theme applied no matter what API -->
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar"> <style name="MainTheme.Base" parent="Theme.AppCompat">
<!--If you are using revision 22.1 please use just windowNoTitle. Without android:--> <!--If you are using revision 22.1 please use just windowNoTitle. Without android:-->
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
<!--We will be using the toolbar so no need to show ActionBar--> <!--We will be using the toolbar so no need to show ActionBar-->
@ -20,6 +20,7 @@
<!-- You can also set colorControlNormal, colorControlActivated <!-- You can also set colorControlNormal, colorControlActivated
colorControlHighlight and colorSwitchThumbNormal. --> colorControlHighlight and colorSwitchThumbNormal. -->
<item name="windowActionModeOverlay">true</item> <item name="windowActionModeOverlay">true</item>
<item name="android:textColorHint">#ff000000</item>
<item name="android:datePickerDialogTheme">@style/AppCompatDialogStyle</item> <item name="android:datePickerDialogTheme">@style/AppCompatDialogStyle</item>
</style> </style>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="my_images"
path="path" />
</paths>

View File

@ -10,6 +10,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Xamarin.Forms" Version="3.4.0.1008975" /> <PackageReference Include="Xamarin.Essentials" Version="1.5.3.2" />
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1687" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "5.0.1",
"commands": [
"dotnet-ef"
]
}
}
}

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

@ -0,0 +1,39 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Serwer.Infrastructure.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace Serwer.Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ImageController : ControllerBase
{
private readonly IImageHandler _imageService;
public ImageController(IImageHandler imageService)
{
_imageService = imageService;
}
[Authorize]
[HttpPost("Process")]
public async Task<IActionResult> Process([FromForm]IFormFile image)
{
if(image == null)
{
return NotFound();
}
using (var memoryStream = new MemoryStream())
{
await image.CopyToAsync(memoryStream);
var response = await _imageService.Process(image.Name, image.ContentType, memoryStream.ToArray());
return Ok(response);
}
}
}
}

View File

@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Serwer.Infrastructure.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Serwer.Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SearchController : ControllerBase
{
private readonly ISearchService _searchService;
public SearchController(ISearchService searchService)
{
_searchService = searchService;
}
[Authorize]
[HttpGet("{query}")]
public async Task<IActionResult> Search(string query)
{
var id = User.Identity.Name;
var results = await _searchService.Search(Guid.Parse(id), query);
return Ok(results);
}
}
}

View File

@ -0,0 +1,53 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Serwer.Infrastructure.DTO;
using Serwer.Infrastructure.Services;
using Serwer.Infrastructure.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Serwer.Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
private readonly IUserService _userService;
public UserController(IUserService userService)
{
_userService = userService;
}
[HttpPost("Register")]
public async Task<IActionResult> Register([FromForm]RegisterModel request)
{
await _userService.RegisterAsync(request.Email, request.Name, request.Surname, request.Login, request.Password);
return Ok();
}
[HttpPost("SignIn")]
public async Task<IActionResult> SignIn([FromForm]SignInModel request)
{
var user = await _userService.SignInAsync(request.Login, request.Password);
return Ok(user);
}
[Authorize]
[HttpPost("Update")]
public async Task<IActionResult> Update([FromForm]UpdateUserModel request)
{
var user = await _userService.UpdateAsync(request);
return Ok(user);
}
[HttpGet("Test")]
public IActionResult Test()
{
return NoContent();
}
}
}

View File

@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
namespace Serwer.Api.Framework
{
public class ExceptionHandlerMiddleware
{
private readonly RequestDelegate _next;
public ExceptionHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
var statusCode = HttpStatusCode.BadRequest;
context.Response.StatusCode = (int)statusCode;
return context.Response.WriteAsync($"Błąd: {exception.Message}");
}
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Serwer.Api
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseUrls("http://localhost:5001");
});
}
}

View File

@ -0,0 +1,113 @@
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_dependencyType": "appService.windows"
},
"parameters": {
"resourceGroupName": {
"type": "string",
"defaultValue": "PixBlocksAdditionResourceGroup",
"metadata": {
"description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking."
}
},
"resourceGroupLocation": {
"type": "string",
"defaultValue": "centralus",
"metadata": {
"description": "Location of the resource group. Resource groups could have different location than resources, however by default we use API versions from latest hybrid profile which support all locations for resource types we support."
}
},
"resourceName": {
"type": "string",
"defaultValue": "PixBlocksAddition",
"metadata": {
"description": "Name of the main resource to be created by this template."
}
},
"resourceLocation": {
"type": "string",
"defaultValue": "[parameters('resourceGroupLocation')]",
"metadata": {
"description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there."
}
}
},
"variables": {
"appServicePlan_name": "[concat('Plan', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
"appServicePlan_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/serverFarms/', variables('appServicePlan_name'))]"
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"name": "[parameters('resourceGroupName')]",
"location": "[parameters('resourceGroupLocation')]",
"apiVersion": "2019-10-01"
},
{
"type": "Microsoft.Resources/deployments",
"name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
"resourceGroup": "[parameters('resourceGroupName')]",
"apiVersion": "2019-10-01",
"dependsOn": [
"[parameters('resourceGroupName')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"location": "[parameters('resourceLocation')]",
"name": "[parameters('resourceName')]",
"type": "Microsoft.Web/sites",
"apiVersion": "2015-08-01",
"tags": {
"[concat('hidden-related:', variables('appServicePlan_ResourceId'))]": "empty"
},
"dependsOn": [
"[variables('appServicePlan_ResourceId')]"
],
"kind": "app",
"properties": {
"name": "[parameters('resourceName')]",
"kind": "app",
"httpsOnly": true,
"reserved": false,
"serverFarmId": "[variables('appServicePlan_ResourceId')]",
"siteConfig": {
"metadata": [
{
"name": "CURRENT_STACK",
"value": "dotnetcore"
}
]
}
},
"identity": {
"type": "SystemAssigned"
}
},
{
"location": "[parameters('resourceLocation')]",
"name": "[variables('appServicePlan_name')]",
"type": "Microsoft.Web/serverFarms",
"apiVersion": "2015-08-01",
"sku": {
"name": "S1",
"tier": "Standard",
"family": "S",
"size": "S1"
},
"properties": {
"name": "[variables('appServicePlan_name')]"
}
}
]
}
}
}
]
}

View File

@ -4,24 +4,25 @@
"windowsAuthentication": false, "windowsAuthentication": false,
"anonymousAuthentication": true, "anonymousAuthentication": true,
"iisExpress": { "iisExpress": {
"applicationUrl": "http://localhost:50287", "applicationUrl": "http://localhost:50760",
"sslPort": 44305 "sslPort": 44371
} }
}, },
"profiles": { "profiles": {
"IIS Express": { "IIS Express": {
"commandName": "IISExpress", "commandName": "IISExpress",
"launchBrowser": true, "launchBrowser": true,
"launchUrl": "api/values", "launchUrl": "swagger",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }
}, },
"Serwer": { "Serwer.Api": {
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true, "launchBrowser": true,
"launchUrl": "api/values", "launchUrl": "swagger",
"applicationUrl": "https://localhost:5001;http://localhost:5000", "applicationUrl": "http://localhost:5001;https://localhost:5000",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }

View File

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Content Remove="wwwroot\tessdata\eng.traineddata" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.0" NoWarn="NU1605" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="5.0.0" NoWarn="NU1605" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Serwer.Core\Serwer.Core.csproj" />
<ProjectReference Include="..\Serwer.Infrastructure\Serwer.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="wwwroot\tessdata\eng.traineddata" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Serwer.Api.Framework;
using Serwer.Core.Repositories;
using Serwer.Infrastructure.Mappers;
using Serwer.Infrastructure.Repositories;
using Serwer.Infrastructure.Services;
using Serwer.Infrastructure.Settings;
namespace Serwer.Api
{
public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
WebRootPath = env.WebRootPath;
}
public IConfiguration Configuration { get; }
protected string WebRootPath { get; set; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Serwer.Api", Version = "v1" });
var jwtSecurityScheme = new OpenApiSecurityScheme
{
Scheme = "bearer",
BearerFormat = "JWT",
Name = "JWT Authentication",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Description = "Put **_ONLY_** your JWT Bearer token on textbox below!",
Reference = new OpenApiReference
{
Id = JwtBearerDefaults.AuthenticationScheme,
Type = ReferenceType.SecurityScheme
}
};
c.AddSecurityDefinition(jwtSecurityScheme.Reference.Id, jwtSecurityScheme);
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{ jwtSecurityScheme, Array.Empty<string>() }
});
});
var hostEnviroment = new HostEnviroment { RootPath = WebRootPath };
var jwtSettings = new JwtSettings()
{
Issuer = "PoszukiwaczInc",
ExpiryMinutes = 120,
Key = "Fjjji0Hdsa4$JgrwIO1j678dCelgFymdo"
};
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(c =>
{
c.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Key)),
ValidIssuer = jwtSettings.Issuer,
ValidateAudience = false,
ValidateLifetime = true
};
});
services.AddSingleton<IHostEnviroment>(hostEnviroment);
services.AddSingleton<IMapper>(AutoMapperConfig.Initialize());
services.AddSingleton<IJwtHandler, JwtHandler>(sp => new JwtHandler(jwtSettings));
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IHistoryRepository, HistoryRepository>();
services.AddScoped<IImageHandler, ImageHandler>();
services.AddScoped<IUserService, UserService>();
services.AddScoped<IHistoryService, HistoryService>();
services.AddScoped<ISearchService, SearchService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseCors(builder =>
{
builder.AllowAnyHeader();
builder.AllowAnyMethod();
builder.AllowAnyOrigin();
});
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Serwer.Api v1"));
}
app.UseRouting();
app.UseMiddleware(typeof(ExceptionHandlerMiddleware));
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

View File

@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

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 File
{
public string Name { get; protected set; }
public string ContentType { get; protected set; }
public byte[] Bytes { get; protected set; }
public long SizeBytes => Bytes.Length;
protected File()
{
}
protected File(string name, string contentType, byte[] bytes)
{
Name = name;
ContentType = contentType;
Bytes = bytes;
}
public static File Empty => new File();
public static File Create(string name, string contentType, byte[] bytes)
=> new File(name, contentType, bytes);
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Core.Domain
{
public class SearchResult
{
}
}

View File

@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Core.Domain
{
public class User
{
public Guid Id { get; protected set; }
public string Email { get; protected set; }
public string Name { get; protected set; }
public string Surname { get; protected set; }
public string Login { get; protected set; }
public string Password { get; protected set; }
public DateTime CreatedAt { get; protected set; }
public DateTime UpdatedAt { get; protected set; }
protected User() { }
public User(Guid id, string email, string name, string surname, string login, string password)
{
Id = id;
SetEmail(email);
SetName(name);
SetSurname(surname);
SetLogin(login);
SetPassword(password);
CreatedAt = DateTime.UtcNow;
}
public void SetEmail(string email)
{
if (string.IsNullOrWhiteSpace(email))
{
throw new Exception("Email nie może być pusty.");
}
if (Email == email)
{
return;
}
Email = email;
UpdatedAt = DateTime.UtcNow;
}
public void SetName(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new Exception("Imię nie może być puste.");
}
if (Name == name)
{
return;
}
Name = name;
UpdatedAt = DateTime.UtcNow;
}
public void SetSurname(string surname)
{
if (string.IsNullOrWhiteSpace(surname))
{
throw new Exception("Nazwisko nie może być puste.");
}
if (Surname == surname)
{
return;
}
Surname = surname;
UpdatedAt = DateTime.UtcNow;
}
public void SetLogin(string login)
{
if (string.IsNullOrWhiteSpace(login))
{
throw new Exception("Login nie może być pusty.");
}
if (Login == login)
{
return;
}
Login = login;
UpdatedAt = DateTime.UtcNow;
}
public void SetPassword(string password)
{
if (string.IsNullOrWhiteSpace(password))
{
throw new Exception("Hasło nie może być puste.");
}
if (Password == password)
{
return;
}
Password = password;
UpdatedAt = DateTime.UtcNow;
}
}
}

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,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Core.Repositories
{
public interface IRepository
{
}
}

View File

@ -0,0 +1,19 @@
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 IUserRepository : IRepository
{
Task<User> GetAsync(Guid id);
Task<User> GetAsync(string login);
Task<IEnumerable<User>> GetAllAsync();
Task AddAsync(User user);
Task UpdateAsync(User user);
Task RemoveAsync(Guid id);
}
}

View File

@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.DTO
{
public class JwtDto
{
public Guid UserId { get; set; }
public string Token { get; set; }
public long Expires { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.DTO
{
public class SearchResultDTO
{
public string Title { get; set; }
public string Link { get; set; }
public string Snippet { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.DTO
{
public class SignedUserDto
{
public UserDto User { get; set; }
public JwtDto Jwt { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.DTO
{
public class UserDto
{
public Guid Id { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Login { get; set; }
public DateTime CreatedAt { get; protected set; }
public DateTime UpdatedAt { get; protected set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.DTO
{
public class UserHistoryDto
{
public List<string> History { get; set; }
public UserDto User { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Extentions
{
public static class Extentions
{
public static long ToTimestamp(this DateTime dateTime)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var time = dateTime.Ticks - epoch.Ticks;
return time / TimeSpan.TicksPerSecond;
}
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Framework
{
public class OCRResponseData
{
/// <summary>
/// Error message
/// </summary>
public string ErrorMessage { get; set; }
/// <summary>
/// Available pages
/// </summary>
public int AvailablePages { get; set; }
/// <summary>
/// OCRed text
/// </summary>
public List<List<string>> OCRText { get; set; }
/// <summary>
/// Output file1 URL
/// </summary>
public string OutputFileUrl { get; set; }
/// <summary>
/// Output file2 URL
/// </summary>
public string OutputFileUrl2 { get; set; }
/// <summary>
/// Output file3 URL
/// </summary>
public string OutputFileUrl3 { get; set; }
/// <summary>
/// Reserved
/// </summary>
public List<List<string>> Reserved { get; set; }
/// <summary>
/// OCRWords
/// </summary>
public List<List<OCRWSWord>> OCRWords { get; set; }
/// <summary>
/// Task description
/// </summary>
public string TaskDescription { get; set; }
/// <summary>
/// Constructor
/// </summary>
public OCRResponseData()
{
OCRText = new List<List<string>>();
Reserved = new List<List<string>>();
OCRWords = new List<List<OCRWSWord>>();
}
}
public class OCRWSWord
{
public int Top;
public int Left;
public int Height;
public int Width;
public string OCRWord;
}
}

View File

@ -0,0 +1,22 @@
using AutoMapper;
using Serwer.Core.Domain;
using Serwer.Infrastructure.DTO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Mappers
{
public static class AutoMapperConfig
{
public static IMapper Initialize()
=> new MapperConfiguration(cfg =>
{
cfg.CreateMap<User, UserDto>();
cfg.CreateMap<UserHistory, UserHistoryDto>();
})
.CreateMapper();
}
}

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,51 @@
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.Repositories
{
public class UserRepository : IUserRepository
{
private static ISet<User> _users = new HashSet<User>();
public async Task AddAsync(User user)
{
await Task.FromResult(_users.Add(user));
}
public async Task<IEnumerable<User>> GetAllAsync()
{
return await Task.FromResult(_users);
}
public async Task<User> GetAsync(Guid id)
{
return await Task.FromResult(_users.SingleOrDefault(x => x.Id == id));
}
public async Task<User> GetAsync(string login)
{
return await Task.FromResult(_users.SingleOrDefault(x => x.Login == login));
}
public async Task RemoveAsync(Guid id)
{
var user = await GetAsync(id);
_users.Remove(user);
}
public async Task UpdateAsync(User user)
{
var dbuser = await GetAsync(user.Id);
dbuser.SetEmail(user.Email);
dbuser.SetLogin(user.Login);
dbuser.SetName(user.Name);
dbuser.SetSurname(user.Surname);
dbuser.SetPassword(user.Password);
}
}
}

View File

@ -0,0 +1,36 @@
using AutoMapper;
using Serwer.Core.Domain;
using Serwer.Core.Repositories;
using Serwer.Infrastructure.DTO;
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;
private readonly IMapper _mapper;
public HistoryService(IHistoryRepository historyRepository, IUserRepository userRepository, IMapper mapper)
{
_historyRepository = historyRepository;
_userRepository = userRepository;
_mapper = mapper;
}
public async Task<UserHistoryDto> 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 _mapper.Map<UserHistoryDto>(history);
}
}
}

View File

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

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 IImageHandler
{
Task<string> Process(string name, string contentType, byte[] bytes);
}
}

View File

@ -0,0 +1,14 @@
using Serwer.Infrastructure.DTO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Services
{
public interface IJwtHandler
{
JwtDto CreateToken(Guid userId);
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Serwer.Infrastructure.DTO;
namespace Serwer.Infrastructure.Services
{
public interface ISearchService
{
Task<IList<SearchResultDTO>> Search(Guid userId, string query);
}
}

View File

@ -0,0 +1,17 @@
using Serwer.Infrastructure.DTO;
using Serwer.Infrastructure.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Services
{
public interface IUserService
{
Task RegisterAsync(string email, string name, string surname, string login, string password);
Task<SignedUserDto> SignInAsync(string login, string password);
Task<UserDto> UpdateAsync(UpdateUserModel userModel);
}
}

View File

@ -0,0 +1,85 @@
using Newtonsoft.Json;
using Serwer.Core.Domain;
using Serwer.Infrastructure.Framework;
using Serwer.Infrastructure.Settings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Tesseract;
namespace Serwer.Infrastructure.Services
{
public class ImageHandler : IImageHandler
{
private readonly ISet<File> _files = new HashSet<File>();
private readonly string _env;
public ImageHandler(IHostEnviroment hostEnviroment)
{
_env = hostEnviroment.RootPath;
}
public async Task<string> Process(string name, string contentType, byte[] bytes)
{
string license_code = "FC935C59-F248-48A3-9970-8A6BDB66FA86";
string user_name = "poszukiwacz";
string ocrURL = @"http://www.ocrwebservice.com/restservices/processDocument?gettext=true&outputformat=txt&language=polish";
byte[] uploadData = bytes;
HttpWebRequest request = CreateHttpRequest(ocrURL, user_name, license_code, "POST");
request.ContentLength = uploadData.Length;
// Send request
using (System.IO.Stream post = request.GetRequestStream())
{
post.Write(uploadData, 0, (int)uploadData.Length);
}
try
{
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Parse JSON response
string strJSON = new System.IO.StreamReader(response.GetResponseStream()).ReadToEnd();
OCRResponseData ocrResponse = JsonConvert.DeserializeObject<OCRResponseData>(strJSON);
return await Task.FromResult(ocrResponse.OCRText.First().First());
}
}
catch (WebException wex)
{
var x = string.Format("OCR API Error. HTTPCode:{0}", ((HttpWebResponse)wex.Response).StatusCode);
throw wex;
}
/*
var engine = new TesseractEngine(System.IO.Path.Combine(_env, "tessdata"),"eng+equ", EngineMode.Default);
var img = Pix.LoadFromMemory(bytes);
var res = engine.Process(img);
var txt = res.GetText();
return await Task.FromResult(txt);
*/
}
private static HttpWebRequest CreateHttpRequest(string address_url, string user_name, string license_code, string http_method)
{
Uri address = new Uri(address_url);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
byte[] authBytes = Encoding.UTF8.GetBytes(string.Format("{0}:{1}", user_name, license_code).ToCharArray());
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(authBytes);
request.Method = http_method;
request.Timeout = 600000;
// Specify Response format to JSON or XML (application/json or application/xml)
request.ContentType = "application/json";
return request;
}
}
}

View File

@ -0,0 +1,55 @@
using Microsoft.IdentityModel.Tokens;
using Serwer.Infrastructure.DTO;
using Serwer.Infrastructure.Extentions;
using Serwer.Infrastructure.Settings;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Services
{
public class JwtHandler: IJwtHandler
{
private readonly JwtSettings _settings;
public JwtHandler(JwtSettings settings)
{
_settings = settings;
}
public JwtDto CreateToken(Guid userId)
{
var now = DateTime.UtcNow;
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()),
new Claim(JwtRegisteredClaimNames.UniqueName, userId.ToString()),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, now.ToTimestamp().ToString(), ClaimValueTypes.Integer64)
};
var expires = now.AddMinutes(_settings.ExpiryMinutes);
var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_settings.Key)),
SecurityAlgorithms.HmacSha256);
var jwt = new JwtSecurityToken(
issuer: _settings.Issuer,
claims: claims,
notBefore: now,
expires: expires,
signingCredentials: signingCredentials
);
var token = new JwtSecurityTokenHandler().WriteToken(jwt);
return new JwtDto
{
UserId = userId,
Token = token,
Expires = expires.ToTimestamp()
};
}
}
}

View File

@ -0,0 +1,89 @@
using Google.Apis.Customsearch.v1;
using Google.Apis.Services;
using Newtonsoft.Json;
using Serwer.Core.Repositories;
using Serwer.Infrastructure.DTO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Services
{
public class SearchService : ISearchService
{
private readonly IImageHandler _imageHandler;
private readonly IHistoryRepository _historyRepository;
private readonly IUserRepository _userRepository;
private const string apiKey = "AIzaSyCagG6QyQyBuJNb1YDuK25qSzoC0Rrjo0c";
private const string searchEngineId = "17b946686537c46e3";
public SearchService(IImageHandler imageHandler, IHistoryRepository historyRepository, IUserRepository userRepository)
{
_imageHandler = imageHandler;
_historyRepository = historyRepository;
_userRepository = userRepository;
}
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);
var queries = query.Split('.').ToList();
if (queries.Count > 2)
{
var q0 = queries[0].Split(' ');
if (q0.Length < 3)
{
queries.RemoveAt(0);
}
if(queries.Last().Length < 5)
{
queries.RemoveAt(queries.Count - 1);
}
}
query = String.Join(".", queries);
var result = await sendRequest(query);
if(result.Count == 0)
{
result = await sendRequest(queries.Last());
}
return result;
}
private async Task<List<SearchResultDTO>> sendRequest(string 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()))
{
var response = await stream.ReadToEndAsync();
dynamic jsonData = JsonConvert.DeserializeObject(response);
var results = new List<SearchResultDTO>();
try
{
foreach (var item in jsonData.items)
{
results.Add(new SearchResultDTO
{
Title = item.title,
Link = item.link,
Snippet = item.snippet
});
}
return results;
}
catch(Exception)
{
return results;
}
}
}
}
}

View File

@ -0,0 +1,78 @@
using AutoMapper;
using Serwer.Core.Domain;
using Serwer.Core.Repositories;
using Serwer.Infrastructure.DTO;
using Serwer.Infrastructure.Mappers;
using Serwer.Infrastructure.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Services
{
public class UserService: IUserService
{
private readonly IUserRepository _userRepository;
private readonly IJwtHandler _jwtHandler;
private readonly IMapper _mapper;
public UserService(IUserRepository userRepository, IJwtHandler jwtHandler, IMapper mapper)
{
_userRepository = userRepository;
_jwtHandler = jwtHandler;
_mapper = mapper;
}
public async Task RegisterAsync(string email, string name, string surname, string login, string password)
{
if(await _userRepository.GetAsync(login) != null)
{
throw new Exception($"Użytkownik z loginem: {login} już istnieje.");
}
var user = new User(Guid.NewGuid(), email, name, surname, login, password);
await _userRepository.AddAsync(user);
}
public async Task<SignedUserDto> SignInAsync(string login, string password)
{
var user = await _userRepository.GetAsync(login);
if(user == null)
{
throw new Exception("Nie znaleziono użytkownika.");
}
if(user.Password != password)
{
throw new Exception("Hasło niepoprawne.");
}
var jwt = _jwtHandler.CreateToken(user.Id);
return new SignedUserDto()
{
User = _mapper.Map<UserDto>(user),
Jwt = _mapper.Map<JwtDto>(jwt)
};
}
public async Task<UserDto> UpdateAsync(UpdateUserModel userModel)
{
var user = await _userRepository.GetAsync(userModel.Id);
if(user == null)
{
throw new Exception("Nie znaleziono użytkownika.");
}
var userLoginTaken = await _userRepository.GetAsync(userModel.Login);
if(userLoginTaken != null && userLoginTaken.Id != user.Id)
{
throw new Exception("Login jest już zajęty.");
}
var newUser = new User(user.Id, userModel.Email, userModel.Name, userModel.Surname, userModel.Login, user.Password);
await _userRepository.UpdateAsync(newUser);
newUser = await _userRepository.GetAsync(user.Id);
return _mapper.Map<UserDto>(newUser);
}
}
}

View File

@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="Google.Apis.Customsearch.v1" Version="1.49.0.2084" />
<PackageReference Include="Google.Apis.CustomSearchAPI.v1" Version="1.49.0.2172" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.8.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.8.0" />
<PackageReference Include="Tesseract" Version="4.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Serwer.Core\Serwer.Core.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove="C:\Users\ppopo\.nuget\packages\tesseract\4.1.1\build\\..\x64\leptonica-1.80.0.dll" />
</ItemGroup>
<ItemGroup>
<None Remove="C:\Users\ppopo\.nuget\packages\tesseract\4.1.1\build\\..\x64\tesseract41.dll" />
</ItemGroup>
<ItemGroup>
<None Remove="C:\Users\ppopo\.nuget\packages\tesseract\4.1.1\build\\..\x86\leptonica-1.80.0.dll" />
</ItemGroup>
<ItemGroup>
<None Remove="C:\Users\ppopo\.nuget\packages\tesseract\4.1.1\build\\..\x86\tesseract41.dll" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Settings
{
public class HostEnviroment: IHostEnviroment
{
public string RootPath { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Settings
{
public interface IHostEnviroment
{
string RootPath { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.Settings
{
public class JwtSettings
{
public string Key { get; set; }
public string Issuer { get; set; }
public int ExpiryMinutes { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.ViewModels
{
public class RegisterModel
{
public string Email { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Login { get; set; }
public string Password { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.ViewModels
{
public class SignInModel
{
public string Login { get; set; }
public string Password { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serwer.Infrastructure.ViewModels
{
public class UpdateUserModel
{
public Guid Id { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Login { get; set; }
}
}

View File

@ -1,11 +1,22 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio Version 16
VisualStudioVersion = 15.0.28307.852 VisualStudioVersion = 16.0.30717.126
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serwer", "Serwer\Serwer.csproj", "{CCE1E4CC-EC14-46A3-BCC9-2CBD8F2284D6}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serwer.Tests", "Serwer.Tests\Serwer.Tests.csproj", "{4169F6FD-E08D-4329-BF87-A1411A9F1EF4}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serwer.Tests", "Serwer.Tests\Serwer.Tests.csproj", "{4169F6FD-E08D-4329-BF87-A1411A9F1EF4}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serwer.Core", "Serwer.Core\Serwer.Core.csproj", "{115E0BB1-FCC1-4E45-92B0-D3B6B4A3DA82}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serwer.Infrastructure", "Serwer.Infrastructure\Serwer.Infrastructure.csproj", "{523E9EE6-B8D9-4E08-A9A0-50D7F872C79C}"
ProjectSection(ProjectDependencies) = postProject
{115E0BB1-FCC1-4E45-92B0-D3B6B4A3DA82} = {115E0BB1-FCC1-4E45-92B0-D3B6B4A3DA82}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serwer.Api", "Serwer.Api\Serwer.Api.csproj", "{335159FF-5AB8-48E5-A04C-778A46058204}"
ProjectSection(ProjectDependencies) = postProject
{115E0BB1-FCC1-4E45-92B0-D3B6B4A3DA82} = {115E0BB1-FCC1-4E45-92B0-D3B6B4A3DA82}
{523E9EE6-B8D9-4E08-A9A0-50D7F872C79C} = {523E9EE6-B8D9-4E08-A9A0-50D7F872C79C}
EndProjectSection
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -13,14 +24,22 @@ Global
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CCE1E4CC-EC14-46A3-BCC9-2CBD8F2284D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCE1E4CC-EC14-46A3-BCC9-2CBD8F2284D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCE1E4CC-EC14-46A3-BCC9-2CBD8F2284D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCE1E4CC-EC14-46A3-BCC9-2CBD8F2284D6}.Release|Any CPU.Build.0 = Release|Any CPU
{4169F6FD-E08D-4329-BF87-A1411A9F1EF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4169F6FD-E08D-4329-BF87-A1411A9F1EF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4169F6FD-E08D-4329-BF87-A1411A9F1EF4}.Debug|Any CPU.Build.0 = Debug|Any CPU {4169F6FD-E08D-4329-BF87-A1411A9F1EF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4169F6FD-E08D-4329-BF87-A1411A9F1EF4}.Release|Any CPU.ActiveCfg = Release|Any CPU {4169F6FD-E08D-4329-BF87-A1411A9F1EF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4169F6FD-E08D-4329-BF87-A1411A9F1EF4}.Release|Any CPU.Build.0 = Release|Any CPU {4169F6FD-E08D-4329-BF87-A1411A9F1EF4}.Release|Any CPU.Build.0 = Release|Any CPU
{115E0BB1-FCC1-4E45-92B0-D3B6B4A3DA82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{115E0BB1-FCC1-4E45-92B0-D3B6B4A3DA82}.Debug|Any CPU.Build.0 = Debug|Any CPU
{115E0BB1-FCC1-4E45-92B0-D3B6B4A3DA82}.Release|Any CPU.ActiveCfg = Release|Any CPU
{115E0BB1-FCC1-4E45-92B0-D3B6B4A3DA82}.Release|Any CPU.Build.0 = Release|Any CPU
{523E9EE6-B8D9-4E08-A9A0-50D7F872C79C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{523E9EE6-B8D9-4E08-A9A0-50D7F872C79C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{523E9EE6-B8D9-4E08-A9A0-50D7F872C79C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{523E9EE6-B8D9-4E08-A9A0-50D7F872C79C}.Release|Any CPU.Build.0 = Release|Any CPU
{335159FF-5AB8-48E5-A04C-778A46058204}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{335159FF-5AB8-48E5-A04C-778A46058204}.Debug|Any CPU.Build.0 = Debug|Any CPU
{335159FF-5AB8-48E5-A04C-778A46058204}.Release|Any CPU.ActiveCfg = Release|Any CPU
{335159FF-5AB8-48E5-A04C-778A46058204}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -1,45 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Serwer.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}
// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}

View File

@ -1,24 +0,0 @@
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 Serwer
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}

View File

@ -1,13 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>
</Project>

View File

@ -1,48 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Serwer
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
}
}

View File

@ -1,9 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}

View File

@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}