Skip to content

Commit

Permalink
adds importservice and movie repository
Browse files Browse the repository at this point in the history
  • Loading branch information
jemayn committed Nov 8, 2023
1 parent 07030e9 commit fb25803
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 5 deletions.
5 changes: 3 additions & 2 deletions TwentyFourDays.Persistence/Composer.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using TwentyFourDays.Persistence.DbContexts;
using TwentyFourDays.Persistence.Migrations;
using TwentyFourDays.Persistence.Repositories;
using TwentyFourDays.Persistence.Services;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
Expand All @@ -22,5 +22,6 @@ public void Compose(IUmbracoBuilder builder)
builder.AddNotificationAsyncHandler<UmbracoApplicationStartedNotification, MovieMigration>();

builder.Services.AddTransient<MoviesImportService>();
builder.Services.AddTransient<MovieRepository>();
}
}
49 changes: 49 additions & 0 deletions TwentyFourDays.Persistence/Repositories/MovieRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using TwentyFourDays.Persistence.DbContexts;
using TwentyFourDays.Persistence.Models;
using Umbraco.Cms.Persistence.EFCore.Scoping;

namespace TwentyFourDays.Persistence.Repositories;

public class MovieRepository
{
private readonly IEFCoreScopeProvider<MovieContext> _scopeProvider;

public MovieRepository(IEFCoreScopeProvider<MovieContext> scopeProvider)
{
_scopeProvider = scopeProvider;
}

public async Task Insert(Movie movie)
{
using var scope = _scopeProvider.CreateScope();

await scope.ExecuteWithContextAsync<Task>(async db =>
{
var moviesFromDb = db.Movies.ToList();

var movieExists = moviesFromDb.FirstOrDefault(x => x.Id == movie.Id);

if (movieExists is not null)
{
return;
}

var movieGenresFromDb = db.MovieGenres.ToList();
var movieGenreList = new List<MovieGenre>();

foreach (var movieGenre in movie.Genres)
{
// If a genre of the same name already exists then we just use that as to not have duplicates
var exists = movieGenresFromDb.FirstOrDefault(x => x.Name == movieGenre.Name);
movieGenreList.Add(exists ?? movieGenre);
}

movie.Genres = movieGenreList;

db.Movies.Add(movie);
await db.SaveChangesAsync();
});

scope.Complete();
}
}
101 changes: 98 additions & 3 deletions TwentyFourDays.Persistence/Services/MoviesImportService.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,109 @@
namespace TwentyFourDays.Persistence.Services;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OfficeOpenXml;
using TwentyFourDays.Persistence.Models;
using TwentyFourDays.Persistence.Repositories;
using Umbraco.Cms.Core.Extensions;

namespace TwentyFourDays.Persistence.Services;

public class MoviesImportService
{
public MoviesImportService()
private readonly ILogger<MoviesImportService> _logger;
private readonly IHostEnvironment _hostEnvironment;
private readonly MovieRepository _movieRepository;

public MoviesImportService(ILogger<MoviesImportService> logger, IHostEnvironment hostEnvironment, MovieRepository movieRepository)
{

_logger = logger;
_hostEnvironment = hostEnvironment;
_movieRepository = movieRepository;
}

public async Task Import()
{
_logger.LogInformation("Starting movies import");
var excelPath = Path.Combine(_hostEnvironment.MapPathContentRoot(Umbraco.Cms.Core.Constants.SystemDirectories.Data), "chatgpt-25-christmas-movies.xlsx");

if (!File.Exists(excelPath))
{
_logger.LogError($"Couldn't find movies file on path: {excelPath}");
return;
}

// Adapted from https://www.c-sharpcorner.com/article/using-epplus-to-import-and-export-data-in-asp-net-core/
await using var fileStream = File.Open(excelPath, FileMode.Open);

using var package = new ExcelPackage(fileStream);

var worksheet = package.Workbook.Worksheets.FirstOrDefault();
if (worksheet is null)
{
_logger.LogError("Couldn't find worksheet");
return;
}

var movies = MapMoviesFromExcel(worksheet);

foreach (var movie in movies)
{
await _movieRepository.Insert(movie);
}

_logger.LogInformation("Import complete");
}

private static IEnumerable<Movie> MapMoviesFromExcel(ExcelWorksheet worksheet)
{
var dealers = new List<Movie>();
var rowCount = worksheet.Dimension.Rows;

// Starts on row 2 as row 1 are headers
for (var row = 2; row <= rowCount; row++)
{
var name = worksheet.Cells[row, 1].Value?.ToString()?.Trim() ?? "";
int.TryParse(worksheet.Cells[row, 2].Value?.ToString()?.Trim(), out var releaseYear);
var genres = GetGenres(worksheet.Cells[row, 3].Value?.ToString()?.Trim());
var mainActor = worksheet.Cells[row, 4].Value?.ToString()?.Trim() ?? "";

dealers.Add(new Movie
{
Name = name,
ReleaseYear = releaseYear,
Genres = genres,
MainActor = mainActor
});
}

return dealers;
}

private static List<MovieGenre> GetGenres(string? value)
{
var movieGenres = new List<MovieGenre>();

if (string.IsNullOrWhiteSpace(value))
{
return movieGenres;
}

var genres = value.Split(',');

foreach (var genre in genres)
{
var trimmedGenre = genre.Trim();

if (string.IsNullOrWhiteSpace(trimmedGenre))
{
continue;
}

movieGenres.Add(new MovieGenre
{
Name = trimmedGenre
});
}

return movieGenres;
}
}
20 changes: 20 additions & 0 deletions TwentyFourDays/TestController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using TwentyFourDays.Persistence.Services;
using Umbraco.Cms.Web.Common.Controllers;

namespace TwentyFourDays;

public class TestController : UmbracoApiController
{
private readonly MoviesImportService _moviesImportService;

public TestController(MoviesImportService moviesImportService)
{
_moviesImportService = moviesImportService;
}

public async Task TestImport()
{
await _moviesImportService.Import();
}

}
4 changes: 4 additions & 0 deletions TwentyFourDays/TwentyFourDays.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
<ProjectReference Include="..\TwentyFourDays.Persistence\TwentyFourDays.Persistence.csproj" />
</ItemGroup>

<ItemGroup>
<None Include="umbraco\Data\chatgpt-25-christmas-movies.xlsx" />
</ItemGroup>

<PropertyGroup>
<!-- Razor files are needed for the backoffice to work correctly -->
<CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory>
Expand Down

0 comments on commit fb25803

Please sign in to comment.