-
Notifications
You must be signed in to change notification settings - Fork 59
Document Processor Submission - Post completion #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
JJHH17
wants to merge
42
commits into
the-csharp-academy:main
Choose a base branch
from
JJHH17:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
d4e4486
Installed spectre console GUI package
JJHH17 ff1942b
Added initial program.cs class, includes spectre menu
JJHH17 85b2976
Added the system.config nuget package
JJHH17 91456d7
Installed the EF to SQL Server Nuget Package
JJHH17 dffc8f7
Created connection string and database values
JJHH17 67ed932
Created initial program model and DB Context
JJHH17 7812529
Installed entity framework design package for running migrations
JJHH17 30bdd0c
Createdmethods for adding new entries to db
JJHH17 e62370e
Resolved typo in connection string call
JJHH17 80ec3ad
Added method for printing entries to console
JJHH17 804101f
Added method for deleting entries
JJHH17 7ce04e4
Added method that seeds data from a csv file
JJHH17 64d19c8
Installed the CSV helper package
JJHH17 602bf11
Added string for export PDF file path location
JJHH17 56eb50f
Removed configuration for filepath which was unused
JJHH17 6f30e61
Added code to export data to a PDF via app
JJHH17 5b031f3
Added method for importing data via xls file
JJHH17 094fa4a
Added helper packages for xlsx processing and reading
JJHH17 c89e76b
Added method to read and seed xlsx files
JJHH17 97c2317
Added method to seed from XLS files
JJHH17 3a98ab0
Removed UserInterface and placed into its own class
JJHH17 bfb48bb
Added userInterface class
JJHH17 912ea61
added connection to dataseeding class
JJHH17 efb7376
Moved dataseeding mechanisms into their own class
JJHH17 7651931
Moved data seeding mechanism into its own class
JJHH17 f4d4031
Added data seeding into its own class
JJHH17 3339329
Added data export to its own class
JJHH17 1ed5b7a
Added support for exporting PDF
JJHH17 26494ab
Added reference to export menu
JJHH17 5c9def7
Added ability to export to CSV
JJHH17 7457379
Installed Cronos package, for cron/scheduling tasks
JJHH17 50794e3
Added code to export data to a csv every day at 9am, using the cronos…
JJHH17 05f886d
Added cronos package for report scheduling
JJHH17 1a3e7e4
Report automated generation now runs concurrently to the app UI
JJHH17 53d34c2
Added reference to azure blob connection string
JJHH17 04f38e1
Added azure blob package
JJHH17 2c8982d
Added container name reference to app.config
JJHH17 472022f
Added code to store to an Azure blob
JJHH17 07f8898
Removed unused using call in dataexport class
JJHH17 f72ecb5
Create README for Document Processor Application
JJHH17 28afb09
Enhance README with project details and usage instructions
JJHH17 7d15b0c
Update README with automated file export details
JJHH17 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
9 changes: 9 additions & 0 deletions
9
DocumentProcessor.JJHH17/DocumentProcessor.JJHH17/Configurations/App.config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| <?xml version="1.0" encoding="utf-8" ?> | ||
| <configuration> | ||
| <appSettings> | ||
| <add key="Server" value="localdb"/> | ||
| <add key="DatabaseName" value="documentProcessor"/> | ||
| <add key="AzureBlobConnectionString" value="NAMEHERE"/> | ||
| <add key="ContainerName" value="NAMEHERE"/> | ||
| </appSettings> | ||
| </configuration> |
108 changes: 108 additions & 0 deletions
108
DocumentProcessor.JJHH17/DocumentProcessor.JJHH17/DataExporting/DataExport.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| using CsvHelper; | ||
| using DocumentProcessor.JJHH17.Models; | ||
| using Spectre.Console; | ||
| using Azure.Storage.Blobs; | ||
| using System.Configuration; | ||
| using Azure.Storage.Blobs.Models; | ||
|
|
||
| namespace Document.Processor.JJHH17.DataExporting; | ||
|
|
||
| public class DataExport | ||
| { | ||
| enum ExportMenuOptions | ||
| { | ||
| PDF, | ||
| CSV, | ||
| AzureBlobStorage | ||
| } | ||
|
|
||
| public static void ExportMenu() | ||
| { | ||
| Console.Clear(); | ||
|
|
||
| AnsiConsole.MarkupLine("[bold yellow]Export Data to a given file type[/]"); | ||
| var choice = AnsiConsole.Prompt( | ||
| new SelectionPrompt<ExportMenuOptions>() | ||
| .Title("Select a file type to export to:") | ||
| .AddChoices(Enum.GetValues<ExportMenuOptions>())); | ||
| switch (choice) | ||
| { | ||
| case ExportMenuOptions.PDF: | ||
| CreateExportPDF(); | ||
| break; | ||
|
|
||
| case ExportMenuOptions.CSV: | ||
| CreateExportCsv(); | ||
| break; | ||
|
|
||
| case ExportMenuOptions.AzureBlobStorage: | ||
| CreateAzureBlobExport(); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| public static void CreateExportPDF() | ||
| { | ||
| using (var context = new PhoneBookContext()) | ||
| { | ||
| var entries = context.Phonebooks.ToList(); | ||
| using (var writer = new StreamWriter("ExportedPhonebook.pdf")) | ||
| using (var csv = new CsvWriter(writer, System.Globalization.CultureInfo.InvariantCulture)) | ||
| { | ||
| csv.WriteRecords(entries); | ||
| } | ||
| } | ||
| AnsiConsole.MarkupLine("[green]Data exported to ExportedPhonebook.pdf successfully![/]"); | ||
| AnsiConsole.MarkupLine("[green]You can find the CSV in 'CodeReviews.Console.DocumentProcessor\\DocumentProcessor.JJHH17\\DocumentProcessor.JJHH17\\bin\\Debug\\net8.0\\ExportedPhonebook.pdf\'[/]"); | ||
| } | ||
|
|
||
| public static void CreateExportCsv() | ||
| { | ||
| using (var context = new PhoneBookContext()) | ||
| { | ||
| var entries = context.Phonebooks.ToList(); | ||
| using (var writer = new StreamWriter("ExportedPhonebook.csv")) | ||
| using (var csv = new CsvWriter(writer, System.Globalization.CultureInfo.InvariantCulture)) | ||
| { | ||
| csv.WriteRecords(entries); | ||
| } | ||
| } | ||
|
|
||
| AnsiConsole.MarkupLine("[green]Data exported to ExportedPhonebook.csv successfully![/]"); | ||
| AnsiConsole.MarkupLine("[green]You can find the CSV in 'CodeReviews.Console.DocumentProcessor\\DocumentProcessor.JJHH17\\DocumentProcessor.JJHH17\\bin\\Debug\\net8.0\\ExportedPhonebook.csv\'[/]"); | ||
| } | ||
|
|
||
| public static async Task CreateAzureBlobExport() | ||
| { | ||
| var localCsv = "ExportedPhonebook.csv"; | ||
| if (!File.Exists(localCsv)) | ||
| { | ||
| AnsiConsole.MarkupLine("[yellow]CSV file not found. Creating CSV file first...[/]"); | ||
| CreateExportCsv(); | ||
| } | ||
|
|
||
| var connectionString = ConfigurationManager.AppSettings["AzureBlobConnectionString"]; | ||
| var containerName = ConfigurationManager.AppSettings["ContainerName"]; | ||
|
|
||
| if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(containerName)) | ||
| { | ||
| AnsiConsole.MarkupLine("[red]Azure Blob Storage connection string or container name is not configured properly. Please check in the app.config file.[/]"); | ||
| return; | ||
| } | ||
|
|
||
| var blobServiceClient = new BlobServiceClient(connectionString); | ||
| var containerClient = blobServiceClient.GetBlobContainerClient(containerName); | ||
| await containerClient.CreateIfNotExistsAsync(); | ||
|
|
||
| var blobClient = containerClient.GetBlobClient("ExportedPhonebook.csv"); | ||
| using var fileStream = File.OpenRead(localCsv); | ||
|
|
||
| var options = new BlobUploadOptions | ||
| { | ||
| HttpHeaders = new BlobHttpHeaders { ContentType = "text/csv" } | ||
| }; | ||
|
|
||
| await blobClient.UploadAsync(fileStream, options); | ||
| AnsiConsole.MarkupLine("[green]CSV file uploaded to Azure Blob Storage successfully![/]"); | ||
| } | ||
| } |
190 changes: 190 additions & 0 deletions
190
DocumentProcessor.JJHH17/DocumentProcessor.JJHH17/DataSeeding/DataSeeding.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,190 @@ | ||
| using DocumentProcessor.JJHH17.Models; | ||
| using ExcelDataReader; | ||
| using Spectre.Console; | ||
| using System.Data; | ||
|
|
||
| namespace Document.Processor.JJHH17.DataSeeding; | ||
|
|
||
| public class DataSeed | ||
| { | ||
| enum FileTypes | ||
| { | ||
| CSV, | ||
| XLS, | ||
| XLSX | ||
| } | ||
|
|
||
| public static void SeedOption() | ||
| { | ||
| Console.Clear(); | ||
| AnsiConsole.MarkupLine("[bold yellow]Seed Database via a given file type[/]"); | ||
|
|
||
| var choice = AnsiConsole.Prompt( | ||
| new SelectionPrompt<FileTypes>() | ||
| .Title("Select a file type to import from:") | ||
| .AddChoices(Enum.GetValues<FileTypes>())); | ||
|
|
||
| switch (choice) | ||
| { | ||
| case FileTypes.CSV: | ||
| SeedCSVData(); | ||
| break; | ||
| case FileTypes.XLS: | ||
| SeedXLSData(); | ||
| break; | ||
| case FileTypes.XLSX: | ||
| SeedXLSXData(); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| public static List<string[]> ReadFile(string filePath) | ||
| { | ||
| List<string[]> rows = new List<string[]>(); | ||
|
|
||
| try | ||
| { | ||
| string[] lines = File.ReadAllLines(filePath); | ||
|
|
||
| foreach (var line in lines) | ||
| { | ||
| var values = line.Split(','); | ||
| rows.Add(values); | ||
| } | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| AnsiConsole.MarkupLine($"[red]Error reading file: {ex.Message}[/]"); | ||
| Console.WriteLine("Press any key to return to the menu..."); | ||
| Console.ReadKey(); | ||
| } | ||
|
|
||
| return rows; | ||
| } | ||
|
|
||
| public static List<string[]> ReadExcel(string filePath) | ||
| { | ||
| System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); | ||
|
|
||
| using var stream = File.Open(filePath, FileMode.Open, FileAccess.Read); | ||
| using var reader = ExcelReaderFactory.CreateReader(stream); | ||
|
|
||
| var dataset = reader.AsDataSet(new ExcelDataSetConfiguration | ||
| { | ||
| ConfigureDataTable = _ => new ExcelDataTableConfiguration | ||
| { | ||
| UseHeaderRow = true | ||
| } | ||
| }); | ||
|
|
||
| var table = dataset.Tables[0]; | ||
| var rows = new List<string[]>(); | ||
|
|
||
| foreach (DataRow dr in table.Rows) | ||
| { | ||
| var name = dr["Name"].ToString()?.Trim(); | ||
| var email = dr["Email"].ToString()?.Trim(); | ||
| var phoneNumber = dr["PhoneNumber"].ToString()?.Trim(); | ||
|
|
||
| rows.Add(new string[] { name, email, phoneNumber }); | ||
| } | ||
|
|
||
| return rows; | ||
| } | ||
|
|
||
| public static void SeedCSVData() | ||
| { | ||
| try | ||
| { | ||
| string csvFilePath = "Import Data - Sheet1.csv"; | ||
| List<string[]> csvData = ReadFile(csvFilePath); | ||
|
|
||
| foreach (string[] row in csvData) | ||
| { | ||
| using (var context = new PhoneBookContext()) | ||
| { | ||
| var newEntry = new Phonebook | ||
| { | ||
| Name = row[0], | ||
| Email = row[1], | ||
| PhoneNumber = row[2] | ||
| }; | ||
| context.Phonebooks.Add(newEntry); | ||
| context.SaveChanges(); | ||
| } | ||
| } | ||
|
|
||
| AnsiConsole.MarkupLine("[green]Database seeded successfully from CSV![/]"); | ||
| Console.WriteLine("Press any key to return to the menu..."); | ||
| Console.ReadKey(); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| AnsiConsole.MarkupLine($"[red]Error reading CSV file: {ex.Message}[/]"); | ||
| Console.WriteLine("Press any key to return to the menu..."); | ||
| Console.ReadKey(); | ||
| } | ||
| } | ||
|
|
||
| public static void SeedXLSData() | ||
| { | ||
| try | ||
| { | ||
| string xlsFilePath = "Import Data - Sheet1.xls"; | ||
| var xlsData = ReadExcel(xlsFilePath); | ||
| using var context = new PhoneBookContext(); | ||
| foreach (var row in xlsData) | ||
| { | ||
| var newEntry = new Phonebook | ||
| { | ||
| Name = row[0], | ||
| Email = row[1], | ||
| PhoneNumber = row[2] | ||
| }; | ||
| context.Phonebooks.Add(newEntry); | ||
| } | ||
| context.SaveChanges(); | ||
| AnsiConsole.MarkupLine("[green]Database seeded successfully from XLS![/]"); | ||
| Console.WriteLine("Press any key to return to the menu..."); | ||
| Console.ReadKey(); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| AnsiConsole.MarkupLine($"[red]Error reading XLS file: {ex.Message}[/]"); | ||
| Console.WriteLine("Press any key to return to the menu..."); | ||
| Console.ReadKey(); | ||
| } | ||
| } | ||
|
|
||
| public static void SeedXLSXData() | ||
| { | ||
| try | ||
| { | ||
| string xlsxFilePath = "Import Data - Sheet1.xlsx"; | ||
| var xlsxData = ReadExcel(xlsxFilePath); | ||
|
|
||
| using var context = new PhoneBookContext(); | ||
| foreach (var row in xlsxData) | ||
| { | ||
| var newEntry = new Phonebook | ||
| { | ||
| Name = row[0], | ||
| Email = row[1], | ||
| PhoneNumber = row[2] | ||
| }; | ||
| context.Phonebooks.Add(newEntry); | ||
| } | ||
|
|
||
| context.SaveChanges(); | ||
| AnsiConsole.MarkupLine("[green]Database seeded successfully from XLSX![/]"); | ||
| Console.WriteLine("Press any key to return to the menu..."); | ||
| Console.ReadKey(); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| AnsiConsole.MarkupLine($"[red]Error reading XLSX file: {ex.Message}[/]"); | ||
| Console.WriteLine("Press any key to return to the menu..."); | ||
| Console.ReadKey(); | ||
| } | ||
| } | ||
| } |
30 changes: 30 additions & 0 deletions
30
DocumentProcessor.JJHH17/DocumentProcessor.JJHH17/DocumentProcessor.JJHH17.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFramework>net8.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Azure.Storage.Blobs" Version="12.26.0" /> | ||
| <PackageReference Include="Cronos" Version="0.11.1" /> | ||
| <PackageReference Include="CsvHelper" Version="33.1.0" /> | ||
| <PackageReference Include="ExcelDataReader" Version="3.8.0" /> | ||
| <PackageReference Include="ExcelDataReader.DataSet" Version="3.8.0" /> | ||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.9"> | ||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
| <PrivateAssets>all</PrivateAssets> | ||
| </PackageReference> | ||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.9" /> | ||
| <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.10" /> | ||
| <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.10" /> | ||
| <PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.10" /> | ||
| <PackageReference Include="Open-XML-SDK" Version="2.9.1" /> | ||
| <PackageReference Include="Spectre.Console" Version="0.52.0" /> | ||
| <PackageReference Include="Spectre.Console.Cli" Version="0.52.0" /> | ||
| <PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.9" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
26 changes: 26 additions & 0 deletions
26
DocumentProcessor.JJHH17/DocumentProcessor.JJHH17/Models/Phonebook.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| using System.Configuration; | ||
| using Microsoft.EntityFrameworkCore; | ||
|
|
||
| namespace DocumentProcessor.JJHH17.Models; | ||
|
|
||
| public class Phonebook | ||
| { | ||
| public int Id { get; set; } | ||
| public string Name { get; set; } | ||
| public string Email { get; set; } | ||
| public string PhoneNumber { get; set; } | ||
| } | ||
|
|
||
| public class PhoneBookContext : DbContext | ||
| { | ||
| private static readonly string server = ConfigurationManager.AppSettings["Server"]; | ||
| private static readonly string databaseInstance = ConfigurationManager.AppSettings["DatabaseName"]; | ||
| public static string connectionString = $@"Server=({server})\{databaseInstance};Integrated Security=true;"; | ||
|
|
||
| public DbSet<Phonebook> Phonebooks { get; set; } | ||
|
|
||
| protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) | ||
| { | ||
| optionsBuilder.UseSqlServer(connectionString); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟠 Separate Class
💡 This is not a Model, it is a DbContext. Move it to a different location that makes sense logically.