public void Running_the_script_and_exiting_the_process_does_not_raise_an_event_which_gives_the_arhcipelago_data_when_there_was_no_data()
        {
            // Given
            CreateMockFactory();
            _mockProcessWrapper.Setup(m => m.Start());
            _mockProcessWrapper.Setup(m => m.WaitForExit(It.IsAny <int>())).Returns(false);

            List <Tuple <string, double> > emptyArchipelagoData = new List <Tuple <string, double> >(); // no data

            _mockJsonReader.Setup(m => m.GetArchipelagoDataFromDirectory(It.IsAny <string>())).Returns(emptyArchipelagoData);
            _mockJsonReader.Setup(m => m.RemoveJsonFilesFromDirectory(It.IsAny <string>()));

            var scriptRunner = new PythonScriptRunner("scriptDirectory", "pythonExeLocation");

            int actualFinishedEventHandlerCallCount = 0;

            scriptRunner.FinishedEventHandler += (sender, eventArgs) =>
            {
                actualFinishedEventHandlerCallCount++;
            };

            // When
            scriptRunner.Go();

            // fake process saying that it has finished
            _mockProcessWrapper.Raise(m => m.Exited += null, EventArgs.Empty);

            // Then
            int expectedFinishedEventHandlerCallCount = 0;

            Assert.AreEqual(expectedFinishedEventHandlerCallCount, actualFinishedEventHandlerCallCount);
        }
        public void Running_checks_for_exit_happening_before_adding_exit_delegate_to_exit_event_handler()
        {
            // Given
            CreateMockFactory();
            _mockProcessWrapper.Setup(m => m.Start());
            // this should force the script to read the json
            _mockProcessWrapper.Setup(m => m.WaitForExit(It.IsAny <int>())).Returns(true);

            List <Tuple <string, double> > archipelagoData = new List <Tuple <string, double> >();

            archipelagoData.Add(new Tuple <string, double>("branch name 1", 10));
            archipelagoData.Add(new Tuple <string, double>("branch name 2", 20));
            archipelagoData.Add(new Tuple <string, double>("branch name 3", 30));
            _mockJsonReader.Setup(m => m.GetArchipelagoDataFromDirectory(It.IsAny <string>())).Returns(archipelagoData);
            _mockJsonReader.Setup(m => m.RemoveJsonFilesFromDirectory(It.IsAny <string>()));

            var scriptRunner = new PythonScriptRunner("scriptDirectory", "pythonExeLocation");

            int actualFinishedEventHandlerCallCount = 0;

            scriptRunner.FinishedEventHandler += (sender, eventArgs) =>
            {
                actualFinishedEventHandlerCallCount++;
            };

            // When
            scriptRunner.Go();

            // not faking the process saying that it has finished

            // Then
            int expectedFinishedEventHandlerCallCount = 1;

            Assert.AreEqual(expectedFinishedEventHandlerCallCount, actualFinishedEventHandlerCallCount);
        }
        public async Task <IResult <IReadOnlyCollection <byte> > > HandleAsync(GetHeatMapCommand command)
        {
            var validationResult = await IsValidAsync(command);

            if (validationResult.HasFailed())
            {
                return(validationResult.Map <IReadOnlyCollection <byte> >());
            }

            var userId     = command.UserId ?? command.CurrentUserId;
            var gamesCount = await _dataContext.Users.Where(x => x.Id == userId).Select(x => x.Games).CountAsync();

            var existingActualHeatMap = await _dataContext.GeneratedHeatMaps
                                        .AsNoTracking()
                                        .FirstOrDefaultAsync(x => x.UserId == userId && x.GeneratedAt > DateTime.Now.AddDays(-1));

            if (existingActualHeatMap != null && existingActualHeatMap.GamesCount == gamesCount)
            {
                return(existingActualHeatMap.HeatMap.ToList().ToSuccessfulResult());
            }

            PythonScriptRunner.RunScript("PythonScripts/heatmap.py", userId.ToString());

            var fileInfo = new FileInfo("heatplot.png");

            var data = new byte[fileInfo.Length];

            await using (var fs = fileInfo.OpenRead())
            {
                fs.Read(data, 0, data.Length);
            }

            fileInfo.Delete();

            _dataContext.GeneratedHeatMaps.Add(new GeneratedHeatmap
            {
                HeatMap     = data,
                UserId      = userId,
                GeneratedAt = DateTime.Now,
                GamesCount  = gamesCount
            });

            await _dataContext.SaveChangesAsync();

            return(data.ToList().ToSuccessfulResult());
        }
        protected override void OnStart(string[] args)
        {
            base.OnStart(args);
            initializeFiles();

            watchdog = new Thread(new ThreadStart(Watchdog));
            watchdog.IsBackground = true;
            watchdog.Start();
            if (logsProcessor == null)
            {
                logsProcessor = new Thread(new ThreadStart(Data2Csv.processLogs));
                logsProcessor.Start();
            }

            // Update prediction funftion
            new Thread(updatePrediction).Start();

            PythonScriptRunner.StartRInstances_SeparateProcess(BasePath + "Mlscript.py");

            initDataService();
        }
        public void Running_the_script_and_exiting_the_process_raises_an_event_which_gives_the_arhcipelago_data()
        {
            // Given
            CreateMockFactory();
            _mockProcessWrapper.Setup(m => m.Start());
            _mockProcessWrapper.Setup(m => m.WaitForExit(It.IsAny <int>())).Returns(false);

            List <Tuple <string, double> > expectedArchipelagoData = new List <Tuple <string, double> >();

            expectedArchipelagoData.Add(new Tuple <string, double>("branch name 1", 10));
            expectedArchipelagoData.Add(new Tuple <string, double>("branch name 2", 20));
            expectedArchipelagoData.Add(new Tuple <string, double>("branch name 3", 30));
            _mockJsonReader.Setup(m => m.GetArchipelagoDataFromDirectory(It.IsAny <string>())).Returns(expectedArchipelagoData);
            _mockJsonReader.Setup(m => m.RemoveJsonFilesFromDirectory(It.IsAny <string>()));

            var scriptRunner = new PythonScriptRunner("scriptDirectory", "pythonExeLocation");

            List <Tuple <string, double> > actualArchipelagoData = new List <Tuple <string, double> >();

            scriptRunner.FinishedEventHandler += (sender, eventArgs) =>
            {
                actualArchipelagoData = eventArgs.ArchipelagoData;
            };

            // When
            scriptRunner.Go();

            // fake process saying that it has finished
            _mockProcessWrapper.Raise(m => m.Exited += null, EventArgs.Empty);

            // Then
            for (var i = 0; i < actualArchipelagoData.Count; i++)
            {
                var expected = expectedArchipelagoData[i];
                var actual   = actualArchipelagoData[i];

                Assert.AreEqual(expected, actual);
            }
        }
        public void Json_files_are_deleted_after_a_run_completes()
        {
            // Given
            CreateMockFactory();
            _mockProcessWrapper.Setup(m => m.Start());
            _mockProcessWrapper.Setup(m => m.WaitForExit(It.IsAny <int>())).Returns(true);

            var actualRemoveJsonFilesFromDirectoryCallCount = 0;

            _mockJsonReader.Setup(m => m.RemoveJsonFilesFromDirectory(It.IsAny <string>())).Callback(() =>
            {
                actualRemoveJsonFilesFromDirectoryCallCount++;
            });

            var scriptRunner = new PythonScriptRunner("scriptDirectory", "pythonExeLocation");

            // When
            scriptRunner.Go();

            // Then
            var expectedRemoveJsonFilesFromDirectoryCallCount = 1;

            Assert.AreEqual(expectedRemoveJsonFilesFromDirectoryCallCount, actualRemoveJsonFilesFromDirectoryCallCount);
        }
        public void Running_twice_without_completing_the_first_one_does_not_create_the_process_again()
        {
            // Given
            CreateMockFactory();

            int actualStartCalledCount = 0;

            _mockProcessWrapper.Setup(m => m.Start()).Callback(() =>
            {
                actualStartCalledCount++;
            });
            _mockProcessWrapper.Setup(m => m.WaitForExit(It.IsAny <int>())).Returns(false);

            var scriptRunner = new PythonScriptRunner("scriptDirectory", "pythonExeLocation");

            // When
            scriptRunner.Go();
            scriptRunner.Go(); // should do nothing

            // Then
            int expectedStartCalledCount = 1;

            Assert.AreEqual(expectedStartCalledCount, actualStartCalledCount);
        }
        public async Task <IResult <IReadOnlyCollection <GameWithImageResponse> > > HandleAsync(GetRecommendedGamesCommand command)
        {
            var validationResult = await IsValidAsync(command);

            if (validationResult.HasFailed())
            {
                return(validationResult.Map <IReadOnlyCollection <GameWithImageResponse> >());
            }

            var userId = command.UserId ?? command.CurrentUserId;

            var yesterday = DateTime.Now.AddDays(-1);
            var existingActualRecommendation = await _dataContext.GamesRecommendations
                                               .AsNoTracking()
                                               .Include(x => x.RecommendedGames)
                                               .FirstOrDefaultAsync(x => x.UserId == userId && x.GeneratedAt > yesterday);

            if (existingActualRecommendation != null && existingActualRecommendation.RecommendedGames.Count > 0)
            {
                var recommendedGamesIds = existingActualRecommendation.RecommendedGames.Select(x => x.GameId);
                var games = await _dataContext.Games
                            .Include(x => x.CoverGameImage)
                            .Where(x => recommendedGamesIds.Contains(x.Id))
                            .ToListAsync();

                return(games.Select(x => new GameWithImageResponse
                {
                    Category = x.GameCategory,
                    Id = x.Id,
                    ImageBytes = x.CoverGameImage.Data.ToList(),
                    Title = x.Name
                })
                       .ToList()
                       .ToSuccessfulResult());
            }

            PythonScriptRunner.RunScript("PythonScripts/recommender.py", userId.ToString());

            var lines = File.ReadAllLines("PythonScripts/list_of_games.txt");

            var recommendedGames = new List <Game>();

            foreach (var line in lines)
            {
                var game = await _dataContext.Games
                           .Include(x => x.CoverGameImage)
                           .SingleOrDefaultAsync(x => x.Name == line);

                if (game != null)
                {
                    recommendedGames.Add(game);
                }
            }

            var gamesRecommendation = new GamesRecommendation
            {
                GeneratedAt      = DateTime.Now,
                UserId           = userId,
                RecommendedGames = recommendedGames
                                   .Select(x => new RecommendationEntry {
                    Game = x
                }).ToList()
            };

            _dataContext.GamesRecommendations.Add(gamesRecommendation);
            await _dataContext.SaveChangesAsync();

            return(recommendedGames.Select(x => new GameWithImageResponse
            {
                Category = x.GameCategory,
                Id = x.Id,
                ImageBytes = x.CoverGameImage.Data.ToList(),
                Title = x.Name
            })
                   .ToList()
                   .ToSuccessfulResult());
        }