Esempio n. 1
0
        public void MapGame(AggregatedGame game, VpdbRelease release, string fileId)
        {
            // update in case we didn't catch the last version.
            _vpdbManager.GetRelease(release.Id).Subscribe(updatedRelease => {
                _logger.Info("Mapping {0} to {1} ({2})", game, release, fileId);

                GetOrCreateMapping(game).Map(release, fileId);
            }, exception => _vpdbClient.HandleApiError(exception, "retrieving release details during linking"));
        }
Esempio n. 2
0
        public GameItemViewModel(Game game, IDependencyResolver resolver)
        {
            Game = game;

            _logger = resolver.GetService<ILogger>();
            _vpdbClient = resolver.GetService<IVpdbClient>();
            _gameManager = resolver.GetService<IGameManager>();
            _messageManager = resolver.GetService<IMessageManager>();
            var threadManager = resolver.GetService<IThreadManager>();

            // release identify
            IdentifyRelease = ReactiveCommand.CreateAsyncObservable(_ => _vpdbClient.Api.GetReleasesBySize(Game.FileSize, MatchThreshold).SubscribeOn(threadManager.WorkerScheduler));
            IdentifyRelease.Select(releases => releases
                .Select(release => new {release, release.Versions})
                .SelectMany(x => x.Versions.Select(version => new {x.release, version, version.Files}))
                .SelectMany(x => x.Files.Select(file => new GameResultItemViewModel(game, x.release, x.version, file, CloseResults)))
            ).Subscribe(x => {

                var releases = x as GameResultItemViewModel[] ?? x.ToArray();
                var numMatches = 0;
                _logger.Info("Found {0} releases for game to identify.", releases.Length);
                GameResultItemViewModel match = null;
                foreach (var vm in releases) {
                    if (game.Filename == vm.TableFile.Reference.Name && game.FileSize == vm.TableFile.Reference.Bytes) {
                        numMatches++;
                        match = vm;
                    }
                }
                _logger.Info("Found {0} identical match(es).", numMatches);

                // if file name and file size are identical, directly match.
                if (numMatches == 1 && match != null) {
                    _logger.Info("File name and size are equal to local release, linking.");
                    _gameManager.LinkRelease(match.Game, match.Release, match.TableFile.Reference.Id);
                    _messageManager.LogReleaseLinked(match.Game, match.Release, match.TableFile.Reference.Id);

                } else {
                    _logger.Info("View model updated with identified releases.");
                    IdentifiedReleases = releases;
                    HasExecuted = true;
                }
            }, exception => _vpdbClient.HandleApiError(exception, "identifying a game by file size"));

            //SyncToggled
            //	.Where(_ => Game.IsSynced && Game.HasRelease)
            //	.Subscribe(_ => { GameManager.Sync(Game); });

            // handle errors
            IdentifyRelease.ThrownExceptions.Subscribe(e => { _logger.Error(e, "Error matching game."); });

            // spinner
            IdentifyRelease.IsExecuting.ToProperty(this, vm => vm.IsExecuting, out _isExecuting);

            // result switch
            IdentifyRelease.Select(r => r.Count > 0).Subscribe(hasResults => { HasResults = hasResults; });

            // close button
            CloseResults.Subscribe(_ => { HasExecuted = false; });

            // identify button visibility
            this.WhenAny(
                vm => vm.HasExecuted,
                vm => vm.Game.HasRelease,
                vm => vm.IsExecuting,
                (hasExecuted, hasRelease, isExecuting) => !hasExecuted.Value && !hasRelease.Value && !isExecuting.Value
            ).ToProperty(this, vm => vm.ShowIdentifyButton, out _showIdentifyButton);
        }
Esempio n. 3
0
 public void HandleApiError(Exception e, string origin)
 {
     _vpdbClient.HandleApiError(e, origin);
 }
Esempio n. 4
0
        public GameItemViewModel(AggregatedGame game, IDependencyResolver resolver)
        {
            Game = game;

            _logger          = resolver.GetService <ILogger>();
            _vpdbClient      = resolver.GetService <IVpdbClient>();
            _gameManager     = resolver.GetService <IGameManager>();
            _pinballXManager = resolver.GetService <IPinballXManager>();
            _messageManager  = resolver.GetService <IMessageManager>();
            var threadManager = resolver.GetService <IThreadManager>();

            game.WhenAnyValue(g => g.IsDownloading).ToProperty(this, vm => vm.IsDownloading, out _isDownloading);
            game.WhenAnyValue(g => g.IsQueued).ToProperty(this, vm => vm.IsQueued, out _isQueued);

            // release identify
            IdentifyRelease = ReactiveCommand.CreateFromObservable(() => _vpdbClient.Api.GetReleasesBySize(Game.FileSize, MatchThreshold).SubscribeOn(threadManager.WorkerScheduler));
            IdentifyRelease.Select(releases => releases
                                   .Select(release => new { release, release.Versions })
                                   .SelectMany(x => x.Versions.Select(version => new { x.release, version, version.Files }))
                                   .SelectMany(x => x.Files.Select(file => new GameResultItemViewModel(game, x.release, x.version, file, CloseResults)))
                                   ).Subscribe(x => {
                var releases   = x as GameResultItemViewModel[] ?? x.ToArray();
                var numMatches = 0;
                _logger.Info("Found {0} releases for game to identify.", releases.Length);
                GameResultItemViewModel match = null;
                foreach (var vm in releases)
                {
                    if (game.FileName == vm.TableFile.Reference.Name && game.FileSize == vm.TableFile.Reference.Bytes)
                    {
                        numMatches++;
                        match = vm;
                    }
                }
                _logger.Info("Found {0} identical match(es).", numMatches);

                // if file name and file size are identical, directly match.
                if (numMatches == 1 && match != null)
                {
                    _logger.Info("File name and size are equal to local release, linking.");
                    _gameManager.MapGame(match.Game, match.Release, match.TableFile.Reference.Id);
                    //_messageManager.LogReleaseLinked(match.Game, match.Release, match.TableFile.Reference.Id);
                }
                else
                {
                    _logger.Info("View model updated with identified releases.");
                    IdentifiedReleases = releases;
                    ShowResults        = true;
                }
            }, exception => _vpdbClient.HandleApiError(exception, "identifying a game by file size"));

            //var canSync = this.WhenAnyValue(x => x.Game.IsSynced, x => x.Game.HasRelease, (isSynced, hasRelease) => isSynced && hasRelease);
            //var canSync = this.WhenAnyValue(x => x.Game.Mapping.IsSynced, x => x.Game.MappedRelease, (isSynced, rls) => isSynced && rls != null);
            //SyncToggled = ReactiveCommand.Create(() => { _gameManager.Sync(Game); }, canSync);

            // handle errors
            IdentifyRelease.ThrownExceptions.Subscribe(e => { _logger.Error(e, "Error matching game."); });

            // result switch
            IdentifyRelease.Select(r => r.Count > 0).Subscribe(hasResults => { HasResults = hasResults; });

            // add to db button
            AddGame = ReactiveCommand.Create(() => _gameManager.AddGame(Game));

            // remove from db button
            RemoveGame = ReactiveCommand.Create(() => _pinballXManager.RemoveGame(Game.XmlGame));

            // close button
            CloseResults = ReactiveCommand.Create(() => { ShowResults = false; });

            // hide button
            HideGame = ReactiveCommand.Create(() => _gameManager.HideGame(Game));

            // unhide button
            UnHideGame = ReactiveCommand.Create(() => _gameManager.UnHideGame(Game));

            // download button
            DownloadMissing = ReactiveCommand.Create(() => _gameManager.DownloadGame(Game));

            // spinner
            IdentifyRelease.IsExecuting.ToProperty(this, vm => vm.IsExecuting, out _isExecuting);

            // global buttons hide
            this.WhenAnyValue(
                vm => vm.ShowResults,
                vm => vm.IsExecuting,
                vm => vm.IsDownloading,
                vm => vm.IsQueued,
                (showResults, isExecuting, isDownloading, isQueued) => !showResults && !isExecuting && !isDownloading && !isQueued
                ).ToProperty(this, vm => vm.ShowButtons, out _showButtons);

            // identify button visibility
            this.WhenAny(
                vm => vm.Game.HasLocalFile,
                vm => vm.Game.MappedTableFile,
                vm => vm.ShowButtons,
                (hasLocalFile, mappedFile, showButtons) => hasLocalFile.Value && mappedFile.Value == null && showButtons.Value
                ).ToProperty(this, vm => vm.ShowIdentifyButton, out _showIdentifyButton);

            // hide button visibility
            this.WhenAny(
                vm => vm.Game.Mapping,
                vm => vm.Game.HasLocalFile,
                vm => vm.Game.HasMappedRelease,
                vm => vm.Game.HasXmlGame,
                vm => vm.ShowButtons,
                (mapping, hasLocalFile, hasMappedRelease, hasXmlGame, showButtons) => (mapping.Value == null || !mapping.Value.IsHidden) && hasLocalFile.Value && !hasMappedRelease.Value && !hasXmlGame.Value && showButtons.Value
                ).ToProperty(this, vm => vm.ShowHideButton, out _showHideButton);

            // unhide button visibility
            this.WhenAny(
                vm => vm.Game.Mapping,
                vm => vm.ShowButtons,
                (mapping, showButtons) => mapping.Value != null && mapping.Value.IsHidden && showButtons.Value
                ).ToProperty(this, vm => vm.ShowUnHideButton, out _showUnHideButton);

            // add to db button visibility
            this.WhenAny(
                vm => vm.Game.HasLocalFile,
                vm => vm.Game.HasXmlGame,
                vm => vm.Game.MappedTableFile,
                vm => vm.ShowButtons,
                (hasLocalFile, hasXmlGame, mappedFile, showButtons) => hasLocalFile.Value && !hasXmlGame.Value && mappedFile.Value != null && showButtons.Value
                ).ToProperty(this, vm => vm.ShowAddToDbButton, out _showAddToDbButton);

            // remove from db button visibility
            this.WhenAny(
                vm => vm.Game.HasLocalFile,
                vm => vm.Game.HasXmlGame,
                vm => vm.ShowButtons,
                (hasLocalFile, hasXmlGame, showButtons) => !hasLocalFile.Value && hasXmlGame.Value && showButtons.Value
                ).ToProperty(this, vm => vm.ShowRemoveFromDbButton, out _showRemoveFromDbButton);

            // download button visibility
            this.WhenAny(
                vm => vm.Game.HasLocalFile,
                vm => vm.Game.MappedTableFile,
                vm => vm.ShowButtons,
                (hasLocalFile, mappedFile, showButtons) => !hasLocalFile.Value && mappedFile.Value != null && showButtons.Value
                ).ToProperty(this, vm => vm.ShowDownloadMissingButton, out _showDownloadMissingButton);

            // download progress
            this.WhenAnyValue(vm => vm.IsDownloading).Subscribe(isDownloading => {
                if (isDownloading)
                {
                    Game.MappedJob.WhenAnyValue(j => j.TransferPercent)
                    .Sample(TimeSpan.FromMilliseconds(300))
                    .Where(x => !Game.MappedJob.IsFinished)
                    .Subscribe(progress => {
                        // on main thread
                        System.Windows.Application.Current.Dispatcher.Invoke(() => {
                            DownloadPercent = progress;
                        });
                    });
                }
            });
        }