Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 67 additions & 32 deletions Client/Program.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System.Drawing;
using System.Drawing.Text;
using System.Reflection;
using TagsCloudContainer.Configuration;
using TagsCloudContainer.PointGenerators;
using TagsCloudContainer.TextProviders;
using TagsCloudContainer;
using Autofac;
using NPOI.SS.Util.CellWalk;

namespace Client
{
Expand All @@ -14,42 +16,70 @@ static void Main()
{
var config = new Config();

ConfigureSupportedReadingFormats(config);
ConfigureFileSource(config);
ConfigureCloudView(config);
ConfigureColor(config);
ConfigurePathToSave(config);
ConfigureStartPoint(config);
ConfigureFont(config);
ConfigureApp(config)
.OnFail(error => Console.WriteLine($"Ошибка конфигурирования: {error}"))
.Then(Run);
}

private static void Run(Config config)
{
var container = DependencyInjection.BuildContainer(config);
using var scope = container.BeginLifetimeScope();
scope.Resolve<PictureMaker>().DrawPicture();
Console.WriteLine($"результат сохранен в {config.PicturePath}");
scope.Resolve<PictureMaker>().DrawPicture()
.OnFail(error => Console.WriteLine($"Ошибка обработки: {error}"))
.Then(a => Console.WriteLine($"результат сохранен в {config.PicturePath}"));
}

private static Result<Config> ConfigureApp(Config config)
{
return ConfigureSupportedReadingFormats(config).AsResult()
.Then(ConfigureFileSource)
.Then(ConfigureCloudView)
.Then(ConfigureColor)
.Then(ConfigurePathToSave)
.Then(ConfigureStartPoint)
.Then(ConfigureFont);
}

private static void ConfigureSupportedReadingFormats(Config config)
private static Config ConfigureSupportedReadingFormats(Config config)
{
Console.WriteLine("Поддерживаются следующие форматы файлов для чтения:");
var textProviders = FindImplemetations<ITextProvider>();
foreach (var point in textProviders)
Console.WriteLine("\t" + point.Key);
config.SupportedReadingFormats = textProviders;
return config;
}

private static Result<Config> ConfigureFont(Config config)
{
Console.WriteLine("Введите размер шрифта");
if (!int.TryParse(Console.ReadLine(), out var fontSize))
return Result.Fail<Config>("invalid fontSize");

Console.WriteLine("Введите название шрифта");
var fontName = Console.ReadLine();
if (!CheckFont(fontName))
return Result.Fail<Config>("invalid fontName");
config.Font = new Font(fontName, fontSize);
return Result.Ok(config);
}

private static void ConfigureFont(Config config)
private static bool CheckFont(string fontName)
{
config.Font = new Font("arial", 12);
var fontCollection = new InstalledFontCollection();
return fontCollection.Families.Any(
f => f.Name.Equals(fontName, StringComparison.InvariantCultureIgnoreCase));
}

private static void ConfigurePathToSave(Config config)
private static Config ConfigurePathToSave(Config config)
{
Console.WriteLine("Введите полный путь и название файла для сохранения");
var inp = Console.ReadLine();
var inp = ReadValue("Введите полный путь и название файла для сохранения");
config.PicturePath = inp.Length == 0 ? "1.bmp" : inp;
return config;
}

private static void ConfigureStartPoint(Config config)
private static Result<Config> ConfigureStartPoint(Config config)
{
Console.WriteLine("Введите координаты центра поля для рисования" +
"\n При некорректном вводе координаты центра составят ( 1000, 1000)");
Expand All @@ -58,14 +88,19 @@ private static void ConfigureStartPoint(Config config)
if (int.TryParse(xLine, out var xResult) &&
int.TryParse(yLine, out var yResult))
config.StartPoint = new Point(xResult, yResult);
config.StartPoint = new Point(1000, 1000);
else
config.StartPoint = new Point(1000, 1000);
return Result.Ok(config);
}

private static void ConfigureFileSource(Config config)
private static Result<Config> ConfigureFileSource(Config config)
{
Console.WriteLine("Введите имя файла источника тэгов");
var inp = Console.ReadLine();
var inp = ReadValue("Введите имя файла источника тэгов");
if ((inp.Length != 0) &&
!config.SupportedReadingFormats.TryGetValue(Path.GetExtension(inp), out var textProvider))
return Result.Fail<Config>("wrong file format for text source");
config.FilePath = inp.Length == 0 ? @"TestFile.txt" : inp;
return Result.Ok(config);
}

private static string GetLabel(RainbowColors color)
Expand All @@ -76,7 +111,7 @@ private static string GetLabel(RainbowColors color)
return attribute.LabelText;
}

private static void ConfigureColor(Config config)
private static Config ConfigureColor(Config config)
{
Console.WriteLine("Выборите цвет из возможных:");
var colors = Enum.GetValues(typeof(RainbowColors))
Expand All @@ -86,8 +121,8 @@ private static void ConfigureColor(Config config)
foreach (var color in colors)
Console.WriteLine("\t" + color.Key);

Console.WriteLine("В случае неправильного ввода - цвет будет выбираться случайным образом");
var inp = Console.ReadLine().ToLower();
var inp = ReadValue("В случае неправильного ввода - цвет будет выбираться случайным образом")
.ToLower();
if (colors.TryGetValue(inp, out var colorName))
{
config.Color = Color.FromName(colorName.ToString());
Expand All @@ -96,9 +131,10 @@ private static void ConfigureColor(Config config)
else
Console.WriteLine("Цвет будет выбираться случайно");

return config;
}

private static void ConfigureCloudView(Config config)
private static Result<Config> ConfigureCloudView(Config config)
{
Console.WriteLine("Выберите внешний вид облака из возможных:");
var pointGenerators = FindImplemetations<IPointGenerator>();
Expand All @@ -107,14 +143,13 @@ private static void ConfigureCloudView(Config config)
Console.WriteLine("Введите, соблюдая орфографию");
var pointGenerator = Console.ReadLine().ToLower();
if (pointGenerators.TryGetValue(pointGenerator, out var pointGeneratorName))
config.PointGenerator = pointGeneratorName;
else
{
Console.WriteLine("Такой формы не предусмотрено");
ConfigureCloudView(config);
config.PointGenerator = pointGeneratorName;
return Result.Ok(config);
}
return Result.Fail<Config>("Такой формы не предусмотрено");
}

private static Dictionary<string, Type> FindImplemetations<T>()
{
var assembly = Assembly.LoadFrom("TagsCloudContainer.dll");
Expand All @@ -123,11 +158,11 @@ private static Dictionary<string, Type> FindImplemetations<T>()
.Where(t => type.IsAssignableFrom(t) && !t.IsInterface)
.ToDictionary(x => x.GetCustomAttribute<LabelAttribute>().LabelText.ToLower(), x => x);
}
private static string? ReadValue(string? argName = null)

private static string ReadValue(string? argName = null)
{
Console.Write($"{argName ?? ""}: ");
return Console.ReadLine();
}
}
}
}
2 changes: 1 addition & 1 deletion TagsCloudContainer.Tests/CloudLayoutShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void PutNextRectangle_ShouldKeepEnteredSize()
{
var layout = new CloudLayout(new Point(5, 5), new ArchemedianSpiral());
var enteredSize = new Size(3, 4);
var returnedSize = layout.PutNextRectangle(enteredSize).Size;
var returnedSize = layout.PutNextRectangle(enteredSize).GetValueOrThrow().Size;

returnedSize.Should().BeEquivalentTo(enteredSize);
}
Expand Down
39 changes: 39 additions & 0 deletions TagsCloudContainer.Tests/RegexParserShould.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using FluentAssertions;
using TagsCloudContainer.StringParsers;

namespace TagsCloudContainer.Tests;

[TestFixture]
public class RegexParserShould
{
private RegexParser _parser;

[SetUp]
public void Setup()
{
_parser = new RegexParser();
}

[Test]
public void ReturnsOnlyWords()
{
var input = "This parser should -+- parse all #words, except any *symbols";

var result = _parser.GetWordsFromString(input);
var expected = new [] {"This", "parser", "should", "parse", "all", "words", "except", "any", "symbols"};

result.IsSuccess.Should().BeTrue();
result.GetValueOrThrow().ToList().Select(w => w.Value).Should().BeEquivalentTo(expected);
}

[Test]
public void ReturnsNoWordsIfEmptyInput()
{
var input = "";

var result = _parser.GetWordsFromString(input);

result.Error.Should().Be("Input cannot be empty");
}
}

9 changes: 5 additions & 4 deletions TagsCloudContainer.Tests/TagGeneratorShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ public class TagGeneratorShould
[Test]
public void SetRightFontSize()
{
var processor = new TextProcessor.TextProcessor(
new TxtTextProvider(@"TextFile1.txt"), new RegexParser(), new ToLowerFilter(), new BoringWordFilter());
var words = processor.WordFrequencies();
var words = new Dictionary<Word, int>()
{
{new Word("a"), 3}
};
var generator = new TagGenerator.TagGenerator(new RandomColorProvider(), new System.Drawing.Font("arial", 12));
var result = generator.GenerateTags(words).First();
var result = generator.GenerateTags(words).GetValueOrThrow().First();

result.Font.Name.Should().Be("Arial");
result.Font.Size.Should().Be(36);
Expand Down
4 changes: 2 additions & 2 deletions TagsCloudContainer.Tests/TextProcessorShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public void Process()
var result = new TextProcessor.TextProcessor(
new TxtTextProvider(@"TextFile1.txt"), new RegexParser(), new ToLowerFilter(), new BoringWordFilter(), new ShortWordFilter()).WordFrequencies();

result.Count.Should().Be(3);
result.GetValueOrThrow().Count.Should().Be(3);

result.MaxBy(word => word.Value).Value.Should().Be(3);
result.GetValueOrThrow().MaxBy(word => word.Value).Value.Should().Be(3);
}
}
}
4 changes: 2 additions & 2 deletions TagsCloudContainer.Tests/TxtTextProviderShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ public void Setup()
[Test]
public void ThrowExceptionIfFileNotFounded()
{
Action act = () => _provider.ReadFile();
var result = _provider.ReadFile();

act.Should().Throw<FileNotFoundException>();
result.Error.Should().Be("File NotExisted.txt does not exist");
}
}
}
16 changes: 12 additions & 4 deletions TagsCloudContainer/CloudLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class CloudLayout
public readonly Size Size;
private readonly IEnumerable<Point> _points;
private List<Rectangle> Rectangles { get; set; }
private readonly Rectangle _frame;


public CloudLayout(Point center, IPointGenerator pointGenerator)
Expand All @@ -19,6 +20,7 @@ public CloudLayout(Point center, IPointGenerator pointGenerator)
Size = CountSize(center);
Rectangles = [];
_points = pointGenerator.GeneratePoints(Center);
_frame = new Rectangle(0, 0, Size.Width, Size.Height);
}

public CloudLayout(Size size, IPointGenerator pointGenerator)
Expand All @@ -27,6 +29,7 @@ public CloudLayout(Size size, IPointGenerator pointGenerator)
Center = FindCenter(size);
Rectangles = [];
_points = pointGenerator.GeneratePoints(Center);
_frame = new Rectangle(0, 0, Size.Width, Size.Height);
}


Expand All @@ -42,18 +45,23 @@ private static Point FindCenter(Size size)
return new Point(size.Width / 2, size.Height / 2);
}

public Rectangle PutNextRectangle(Size rectangleSize)
public Result<Rectangle> PutNextRectangle(Size rectangleSize)
{
foreach (var point in _points)
{
var supposed = new Rectangle(new Point(point.X - rectangleSize.Width / 2, point.Y - rectangleSize.Height / 2),
rectangleSize);
if (IntersectsWithAnyOther(supposed, Rectangles))
continue;
Rectangles.Add(supposed);
return supposed;
if (_frame.Contains(supposed))
{
Rectangles.Add(supposed);
return supposed;
}

return Result.Fail<Rectangle>("Вышли за границы рисунка");
}
throw new ArgumentException("Not Enough Points Generated");
return Result.Fail<Rectangle>("Not Enough Points Generated");
}

public static bool IntersectsWithAnyOther(Rectangle supposed, List<Rectangle> others)
Expand Down
5 changes: 2 additions & 3 deletions TagsCloudContainer/ColorProviders/ColorProvider.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using System.Drawing;
using System.Runtime.CompilerServices;

namespace TagsCloudContainer.ColorProviders;

public class ColorProvider : IColorProvider
{
[CompilerGenerated] private readonly Color _color;
private readonly Color _color;

public ColorProvider(Color color) => _color = color;

public Color GetColor() => _color;
public Result<Color> GetColor() => _color.AsResult();
}
2 changes: 1 addition & 1 deletion TagsCloudContainer/ColorProviders/IColorProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ namespace TagsCloudContainer.ColorProviders;

public interface IColorProvider
{
Color GetColor();
Result<Color> GetColor();
}
2 changes: 1 addition & 1 deletion TagsCloudContainer/ColorProviders/RandomColorProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace TagsCloudContainer.ColorProviders;

public class RandomColorProvider : IColorProvider
{
public Color GetColor()
public Result<Color> GetColor()
{
return Color.FromArgb(Random.Shared.Next(50, 255), Random.Shared.Next(0, 255), Random.Shared.Next(0, 255), Random.Shared.Next(0, 255));
}
Expand Down
Loading