Skip to content

Commit

Permalink
Merge pull request #287 from mregni/dev
Browse files Browse the repository at this point in the history
New beta release
  • Loading branch information
mregni authored Jan 21, 2019
2 parents e915c77 + 23b8b32 commit 3de77ee
Show file tree
Hide file tree
Showing 43 changed files with 1,121 additions and 808 deletions.
4 changes: 3 additions & 1 deletion .bettercodehub.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ exclude:
- /EmbyStat.Common/Models/.*
- /EmbyStat.Common/Constants.cs
- /EmbyStat.Common/Converters/.*
- /EmbyStat.Controllers/ViewModels/.*
- /EmbyStat.Controllers/ViewModels/.*
- /EmbyStat.Controllers/MapProfiles.cs
- /EmbyStat.DI/DIExtentions.cs
- /EmbyStat.Repositories/ApplicationDbContext.cs
- /EmbyStat.Repositories/DatabaseInitializer.cs
- /EmbyStat.Repositories/Migrations/.*
- /EmbyStat.Web/ClientApp/.*
Expand Down
8 changes: 8 additions & 0 deletions EmbyStat.Controllers/JobController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ public async Task<IActionResult> FireMediaSync()
return Ok();
}

[HttpGet]
[Route("mediasync")]
public IActionResult IsFireMediaSyncRunning()
{
var job = _jobService.GetById(Constants.JobIds.MediaSyncId);
return Ok(_mapper.Map<JobViewModel>(job));
}

[HttpPost]
[Route("smallsync/fire")]
public async Task<IActionResult> FireSmallSync()
Expand Down
13 changes: 11 additions & 2 deletions EmbyStat.Jobs/BaseJob.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using AutoMapper.Mappers;
using EmbyStat.Common.Exceptions;
using EmbyStat.Common.Hubs;
using EmbyStat.Common.Models.Entities;
Expand Down Expand Up @@ -42,10 +43,14 @@ public async Task Execute()
await RunJob();
PostJobExecution();
}
catch (WizardNotFinishedException e)
{
LogWarning(e.Message);
}
catch (Exception e)
{
Log.Error(e, "Error while running job");
FailExecution();
FailExecution(string.Empty);
throw;
}
}
Expand Down Expand Up @@ -79,10 +84,14 @@ private void PostJobExecution()
: $"Job finished after {Math.Ceiling(runTime)} minutes.");
}

private void FailExecution()
private void FailExecution(string message)
{
State = JobState.Failed;
_jobRepository.EndJob(Id, DateTime.UtcNow, State);
if (!string.IsNullOrWhiteSpace(message))
{
LogError(message);
}
SendLogProgressToFront(100);
}

Expand Down
82 changes: 46 additions & 36 deletions EmbyStat.Jobs/Jobs/Sync/MediaSyncJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,33 +232,38 @@ private async Task ProcessShows(List<Collection> rootItems, CancellationToken ca
{
j++;
LogProgress(Math.Floor(33 + 36 / ((double)shows.Count / j * (rootItems.Count / (double)(i + 1)))));
var rawSeasons = await GetSeasonsFromEmby(show.Id, cancellationToken);
await ProcessShow(show, rootItem, j, shows.Count, cancellationToken);
}
cancellationToken.ThrowIfCancellationRequested();
}
}

var episodes = new List<Episode>();
var seasonLinks = new List<Tuple<string, string>>();
foreach (var season in rawSeasons)
{
var eps = await GetEpisodesFromEmby(season.Id, cancellationToken);
eps.ForEach(x => x.Collections.Add(new MediaCollection { CollectionId = rootItem.Id }));
episodes.AddRange(eps);
private async Task ProcessShow(Show show, Collection rootItem, int index, int showCount, CancellationToken cancellationToken)
{
var rawSeasons = await GetSeasonsFromEmby(show.Id, cancellationToken);

seasonLinks.AddRange(eps.Select(x => new Tuple<string, string>(season.Id, x.Id)));
}
var episodes = new List<Episode>();
var seasonLinks = new List<Tuple<string, string>>();
foreach (var season in rawSeasons)
{
var eps = await GetEpisodesFromEmby(season.Id, cancellationToken);
eps.ForEach(x => x.Collections.Add(new MediaCollection { CollectionId = rootItem.Id }));
episodes.AddRange(eps);

LogInformation($"Processing show ({j}/{shows.Count}) {show.Name} with {rawSeasons.Count} seasons and {episodes.Count} episodes");
seasonLinks.AddRange(eps.Select(x => new Tuple<string, string>(season.Id, x.Id)));
}

var groupedEpisodes = episodes.GroupBy(x => x.Id).Select(x => new { Episode = episodes.First(y => y.Id == x.Key) });
LogInformation($"Processing show ({index}/{showCount}) {show.Name} with {rawSeasons.Count} seasons and {episodes.Count} episodes");

_showRepository.AddRange(groupedEpisodes.Select(x => x.Episode).ToList());
var groupedEpisodes = episodes.GroupBy(x => x.Id).Select(x => new { Episode = episodes.First(y => y.Id == x.Key) });

var seasons = rawSeasons.Select(x => ShowHelper.ConvertToSeason(x, seasonLinks.Where(y => y.Item1 == x.Id))).ToList();
seasons.ForEach(x => x.Collections.Add(new MediaCollection { CollectionId = rootItem.Id }));
_showRepository.AddRange(seasons);
_showRepository.AddRange(groupedEpisodes.Select(x => x.Episode).ToList());

cancellationToken.ThrowIfCancellationRequested();
}
cancellationToken.ThrowIfCancellationRequested();
}
var seasons = rawSeasons.Select(x => ShowHelper.ConvertToSeason(x, seasonLinks.Where(y => y.Item1 == x.Id))).ToList();
seasons.ForEach(x => x.Collections.Add(new MediaCollection { CollectionId = rootItem.Id }));
_showRepository.AddRange(seasons);

cancellationToken.ThrowIfCancellationRequested();
}

private async Task SyncMissingEpisodes(DateTime? lastUpdateFromTvdb, string tvdbApiKey, CancellationToken cancellationToken)
Expand Down Expand Up @@ -297,27 +302,12 @@ private async Task GetMissingEpisodesFromTvdb(IEnumerable<Show> shows, Cancellat
LogProgress(Math.Floor(66 + 33 / (showCount / i)));
LogInformation($"Processing {show.Name}");

var neededEpisodeCount = 0;
var seasons = _showRepository.GetAllSeasonsForShow(show.Id).ToList();
var episodes = _showRepository.GetAllEpisodesForShow(show.Id, true).ToList();

try
{
var tvdbEpisodes = await _tvdbClient.GetEpisodes(show.TVDB, cancellationToken);

foreach (var episode in tvdbEpisodes)
{
var season = seasons.SingleOrDefault(x => x.IndexNumber == episode.SeasonIndex);
if (IsEpisodeMissing(episodes, season, episode))
{
neededEpisodeCount++;
}
}

LogInformation($"Found {neededEpisodeCount} missing episodes for show {show.Name}");
show.TvdbSynced = true;
show.MissingEpisodesCount = neededEpisodeCount;
_showRepository.UpdateShow(show);
await ProgressMissingEpisodes(show, seasons, episodes, cancellationToken);
}
catch (Exception e)
{
Expand All @@ -328,6 +318,26 @@ private async Task GetMissingEpisodesFromTvdb(IEnumerable<Show> shows, Cancellat
}
}

private async Task ProgressMissingEpisodes(Show show, List<Season> seasons, List<Episode> episodes, CancellationToken cancellationToken)
{
var neededEpisodeCount = 0;
var tvdbEpisodes = await _tvdbClient.GetEpisodes(show.TVDB, cancellationToken);

foreach (var episode in tvdbEpisodes)
{
var season = seasons.SingleOrDefault(x => x.IndexNumber == episode.SeasonIndex);
if (IsEpisodeMissing(episodes, season, episode))
{
neededEpisodeCount++;
}
}

LogInformation($"Found {neededEpisodeCount} missing episodes for show {show.Name}");
show.TvdbSynced = true;
show.MissingEpisodesCount = neededEpisodeCount;
_showRepository.UpdateShow(show);
}

private bool IsEpisodeMissing(List<Episode> localEpisodes, Season season, VirtualEpisode tvdbEpisode)
{
if (season == null)
Expand Down
1 change: 1 addition & 0 deletions EmbyStat.Jobs/Jobs/Sync/SmallSyncJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class SmallSyncJob : BaseJob, ISmallSyncJob
public SmallSyncJob(IJobHubHelper hubHelper, IJobRepository jobRepository, IConfigurationService configurationService, IEmbyService embyService) : base(hubHelper, jobRepository, configurationService)
{
_embyService = embyService;
Title = jobRepository.GetById(Id).Title;
}

public sealed override Guid Id => Constants.JobIds.SmallSyncId;
Expand Down
55 changes: 32 additions & 23 deletions EmbyStat.Repositories/MovieRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,8 @@ public void AddOrUpdate(Movie movie)
{
using (var context = new ApplicationDbContext())
{
var peopleToDelete = new List<string>();
foreach (var person in movie.ExtraPersons)
{
var temp = context.People.AsNoTracking().SingleOrDefault(x => x.Id == person.PersonId);
if (temp == null)
{
Log.Warning($"{Constants.LogPrefix.MediaSyncJob}\tWe couldn't find the person with Id {person.PersonId} for movie ({movie.Id}) {movie.Name} in our database. This is because Emby didn't return the actor when we queried the people for the parent id. As a fix we will remove the person from the movie now.");
peopleToDelete.Add(person.PersonId);
}
}
peopleToDelete.ForEach(x => movie.ExtraPersons.Remove(movie.ExtraPersons.SingleOrDefault(y => y.PersonId == x)));

var genresToDelete = new List<string>();
foreach (var genre in movie.MediaGenres)
{
var temp = context.Genres.AsNoTracking().SingleOrDefault(x => x.Id == genre.GenreId);
if (temp == null)
{
Log.Warning($"{Constants.LogPrefix.MediaSyncJob}\tWe couldn't find the genre with Id {genre.GenreId} for movie ({movie.Id}) {movie.Name} in our database. This is because Emby didn't return the genre when we queried the genres for the parent id. As a fix we will remove the genre from the movie now.");
genresToDelete.Add(genre.GenreId);
}
}
genresToDelete.ForEach(x => movie.MediaGenres.Remove(movie.MediaGenres.SingleOrDefault(y => y.GenreId == x)));
RemovePeopleWithoutLink(context, movie);
RemoveGenreWithoutLink(context, movie);

var dbMovie = context.Movies.Include(x => x.Collections).SingleOrDefault(x => x.Id == movie.Id);
if (dbMovie == null)
Expand All @@ -58,6 +37,36 @@ public void AddOrUpdate(Movie movie)
}
}

private void RemovePeopleWithoutLink(ApplicationDbContext context, Movie movie)
{
var peopleToDelete = new List<string>();
foreach (var person in movie.ExtraPersons)
{
var temp = context.People.AsNoTracking().SingleOrDefault(x => x.Id == person.PersonId);
if (temp == null)
{
Log.Warning($"{Constants.LogPrefix.MediaSyncJob}\tWe couldn't find the person with Id {person.PersonId} for movie ({movie.Id}) {movie.Name} in our database. This is because Emby didn't return the actor when we queried the people for the parent id. As a fix we will remove the person from the movie now.");
peopleToDelete.Add(person.PersonId);
}
}
peopleToDelete.ForEach(x => movie.ExtraPersons.Remove(movie.ExtraPersons.SingleOrDefault(y => y.PersonId == x)));
}

public void RemoveGenreWithoutLink(ApplicationDbContext context, Movie movie)
{
var genresToDelete = new List<string>();
foreach (var genre in movie.MediaGenres)
{
var temp = context.Genres.AsNoTracking().SingleOrDefault(x => x.Id == genre.GenreId);
if (temp == null)
{
Log.Warning($"{Constants.LogPrefix.MediaSyncJob}\tWe couldn't find the genre with Id {genre.GenreId} for movie ({movie.Id}) {movie.Name} in our database. This is because Emby didn't return the genre when we queried the genres for the parent id. As a fix we will remove the genre from the movie now.");
genresToDelete.Add(genre.GenreId);
}
}
genresToDelete.ForEach(x => movie.MediaGenres.Remove(movie.MediaGenres.SingleOrDefault(y => y.GenreId == x)));
}

public int GetTotalPersonByType(List<string> collections, PersonType type)
{
using (var context = new ApplicationDbContext())
Expand Down
41 changes: 21 additions & 20 deletions EmbyStat.Services/ShowService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,28 +147,9 @@ public List<ShowCollectionRow> GetCollectionRows(IEnumerable<string> collectionI
}
else
{
stats = new List<ShowCollectionRow>();
var shows = _showRepository.GetAllShows(collectionIds);

foreach (var show in shows)
{
var episodeCount = _showRepository.GetEpisodeCountForShow(show.Id);
var totalEpisodeCount = _showRepository.GetEpisodeCountForShow(show.Id, true);
var specialCount = totalEpisodeCount - episodeCount;
var seasonCount = _showRepository.GetSeasonCountForShow(show.Id);

stats.Add(new ShowCollectionRow
{
Title = show.Name,
SortName = show.SortName,
Episodes = episodeCount,
Seasons = seasonCount,
Specials = specialCount,
MissingEpisodes = show.MissingEpisodesCount,
PremiereDate = show.PremiereDate,
Status = show.Status == "Continuing"
});
}
stats = shows.Select(CreateShowCollectionRow).ToList();

var json = JsonConvert.SerializeObject(stats);
_statisticsRepository.AddStatistic(json, DateTime.UtcNow, StatisticType.ShowCollected, collectionIds);
Expand All @@ -177,6 +158,26 @@ public List<ShowCollectionRow> GetCollectionRows(IEnumerable<string> collectionI
return stats;
}

private ShowCollectionRow CreateShowCollectionRow(Show show)
{
var episodeCount = _showRepository.GetEpisodeCountForShow(show.Id);
var totalEpisodeCount = _showRepository.GetEpisodeCountForShow(show.Id, true);
var specialCount = totalEpisodeCount - episodeCount;
var seasonCount = _showRepository.GetSeasonCountForShow(show.Id);

return new ShowCollectionRow
{
Title = show.Name,
SortName = show.SortName,
Episodes = episodeCount,
Seasons = seasonCount,
Specials = specialCount,
MissingEpisodes = show.MissingEpisodesCount,
PremiereDate = show.PremiereDate,
Status = show.Status == "Continuing"
};
}

public bool ShowTypeIsPresent()
{
return _showRepository.Any();
Expand Down
7 changes: 5 additions & 2 deletions EmbyStat.Web/ClientApp/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ import { SyncGuard } from './shared/guards/sync.guard';

const routes: Routes = [{ path: '', component: DashboardOverviewComponent },
{ path: 'configuration', component: ConfigurationOverviewComponent },
{ path: 'configuration/:tab', component: ConfigurationOverviewComponent },
{ path: 'plugin', component: PluginOverviewComponent },
{ path: 'server', component: ServerOverviewComponent },
{ path: 'wizard', component: WizardOverviewComponent },
{ path: 'jobs', component: JobsOverviewComponent },
{ path: 'movie', component: MovieOverviewComponent, canActivate: [SyncGuard] },
{ path: 'show', component: ShowOverviewComponent, canActivate: [SyncGuard] },
{ path: 'movies', component: MovieOverviewComponent, canActivate: [SyncGuard] },
{ path: 'movies/:tab', component: MovieOverviewComponent, canActivate: [SyncGuard] },
{ path: 'shows', component: ShowOverviewComponent, canActivate: [SyncGuard] },
{ path: 'shows/:tab', component: ShowOverviewComponent, canActivate: [SyncGuard] },
{ path: 'logs', component: LogsOverviewComponent },
{ path: 'about', component: AboutOverviewComponent },
{ path: '**', redirectTo: '' }];
Expand Down
16 changes: 1 addition & 15 deletions EmbyStat.Web/ClientApp/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Subscription } from 'rxjs/Subscription';
import * as signalR from '@aspnet/signalr';

import { ConfigurationFacade } from './configuration/state/facade.configuration';
import { WizardStateService } from './wizard/services/wizard-state.service';
import { JobSocketService } from './shared/services/job-socket.service';
import { SideBarService } from './shared/services/side-bar.service';
import { Job } from './jobs/models/job';
Expand All @@ -22,15 +21,13 @@ export class AppComponent implements OnInit, OnDestroy {
private mediaMatcher: MediaQueryList = matchMedia(`(max-width: ${SMALL_WIDTH_BREAKPOINT}px)`);
private configChangedSub: Subscription;
private configLoadSub: Subscription;
private wizardStateSub: Subscription;
openMenu = true;

constructor(
private zone: NgZone,
private configurationFacade: ConfigurationFacade,
private translate: TranslateService,
private router: Router,
private wizardStateService: WizardStateService,
private jobSocketService: JobSocketService,
private sideBarService: SideBarService) {
this.mediaMatcher.addListener(mql => zone.run(() => this.mediaMatcher = mql));
Expand Down Expand Up @@ -65,19 +62,12 @@ export class AppComponent implements OnInit, OnDestroy {
this.configLoadSub = this.configurationFacade.getConfiguration().subscribe(config => {
if (!config.wizardFinished) {
this.router.navigate(['/wizard']);
this.openMenu = false;
}
});

this.wizardStateSub = this.wizardStateService.finished.subscribe(finished => {
if (finished) {
this.openMenu = true;
this.router.navigate(['']);
}
});

this.configChangedSub = this.configurationFacade.configuration$.subscribe(config => {
this.translate.use(config.language);
console.log("lang changed");
});
}

Expand All @@ -89,10 +79,6 @@ export class AppComponent implements OnInit, OnDestroy {
if (this.configLoadSub !== undefined) {
this.configLoadSub.unsubscribe();
}

if (this.wizardStateSub !== undefined) {
this.wizardStateSub.unsubscribe();
}
}

isScreenSmall(): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ <h2>{{'CONFIGURATION.SETTINGS' | translate}}</h2>
</div>
</div>
<div class="content">
<mat-tab-group>
<mat-tab-group [selectedIndex]="selected">
<mat-tab label="{{'COMMON.GENERAL' | translate | capitalizeFirst}}">
<div class="configuration__tab-content">
<app-configuration-general></app-configuration-general>
Expand Down
Loading

0 comments on commit 3de77ee

Please sign in to comment.