<commit_before>package io.github.manami.gui.controller;

import com.google.common.collect.Streams;

import org.controlsfx.control.Notifications;

import java.nio.file.Path;
import java.util.HashSet;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import io.github.manami.Main;
import io.github.manami.cache.Cache;
import io.github.manami.core.Manami;
import io.github.manami.core.services.RecommendationsRetrievalService;
import io.github.manami.core.services.ServiceRepository;
import io.github.manami.core.services.events.AdvancedProgressState;
import io.github.manami.core.services.events.ProgressState;
import io.github.manami.dto.entities.Anime;
import io.github.manami.dto.entities.InfoLink;
import io.github.manami.dto.entities.MinimalEntry;
import io.github.manami.gui.utility.AnimeTableBuilder;
import io.github.manami.gui.utility.ImageCache;
import io.github.manami.gui.wrapper.MainControllerWrapper;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.Tab;
import javafx.scene.control.TableView;
import javafx.scene.layout.HBox;

import static io.github.manami.core.config.Config.NOTIFICATION_DURATION;
import static io.github.manami.gui.utility.DialogLibrary.JSON_FILTER;
import static io.github.manami.gui.utility.DialogLibrary.showExportDialog;


public class RecommendationsController implements Observer {

    public static final String RECOMMENDATIONS_TAB_TITLE = "Recommendations";

    private final ServiceRepository serviceRepo = Main.CONTEXT.getBean(ServiceRepository.class);
    private final ImageCache imageCache = Main.CONTEXT.getBean(ImageCache.class);
    private final Manami app = Main.CONTEXT.getBean(Manami.class);
    private final Cache cache = Main.CONTEXT.getBean(Cache.class);
    private final Set<InfoLink> containedEntries = new HashSet<>();

    @FXML
    private TableView<Anime> contentTable;

    @FXML
    private HBox hBoxProgress;

    @FXML
    private ProgressBar progressBar;

    @FXML
    private Label lblProgress;

    @FXML
    private Button btnStart;

    @FXML
    private Button btnExport;

    private Tab tab;
    private RecommendationsRetrievalService service;


    /**
     * Called from FXML when creating the Object.
     *
     * @since 2.4.0
     */
    public void initialize() {
        new AnimeTableBuilder<>(contentTable)
                .withPicture(imageCache::loadPicture)
                .withTitleSortable(false)
                .withAddToWatchListButton(true)
                .withAddToFilterListButton(true)
                .withRemoveButton(true)
                .withListChangedEvent((a) -> {
                    Platform.runLater(() -> tab.setText(String.format("Filter List (%s)", contentTable.getItems().size())));
                    return null;
                });
    }


    public void export() {
        final Path file = showExportDialog(Main.CONTEXT.getBean(MainControllerWrapper.class).getMainStage(), JSON_FILTER);
        app.exportList(contentTable.getItems(), file);
    }


    private void showProgressControls(final boolean value) {
        Platform.runLater(() -> {
            hBoxProgress.setVisible(value);
            btnStart.setVisible(!value);
        });
    }


    public void start() {
        service = new RecommendationsRetrievalService(app, cache, this);
        showProgressControls(true);
        contentTable.getItems().clear();
        serviceRepo.startService(service);
    }


    /**
     * Stops the service if necessary and resets the GUI.
     *
     * @since 2.4.0
     */
    public void cancel() {
        if (service != null) {
            service.cancel();
        }

        clear();
    }


    @Override
    public void update(final Observable observable, final Object object) {
        if (object == null) {
            return;
        }

        if (object instanceof AdvancedProgressState) {
            final AdvancedProgressState state = (AdvancedProgressState) object;
            final int done = state.getDone();
            final int all = state.getTodo();
            final double percent = ((done * 100.00) / all) / 100.00;

            if (state.getAnime() != null) {
                Anime anime = (Anime) object;

                if (!containedEntries.contains(anime.getInfoLink())) {
                    containedEntries.add(anime.getInfoLink());
                    contentTable.getItems().add(anime);
                }

                Platform.runLater(() -> {
                    progressBar.setProgress(percent);<commit_msg>Fixed updating recommendations table<commit_after>package io.github.manami.gui.controller;

import com.google.common.collect.Streams;

import org.controlsfx.control.Notifications;

import java.nio.file.Path;
import java.util.HashSet;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import io.github.manami.Main;
import io.github.manami.cache.Cache;
import io.github.manami.core.Manami;
import io.github.manami.core.services.RecommendationsRetrievalService;
import io.github.manami.core.services.ServiceRepository;
import io.github.manami.core.services.events.AdvancedProgressState;
import io.github.manami.core.services.events.ProgressState;
import io.github.manami.dto.entities.Anime;
import io.github.manami.dto.entities.InfoLink;
import io.github.manami.dto.entities.MinimalEntry;
import io.github.manami.gui.utility.AnimeTableBuilder;
import io.github.manami.gui.utility.ImageCache;
import io.github.manami.gui.wrapper.MainControllerWrapper;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.Tab;
import javafx.scene.control.TableView;
import javafx.scene.layout.HBox;

import static io.github.manami.core.config.Config.NOTIFICATION_DURATION;
import static io.github.manami.gui.utility.DialogLibrary.JSON_FILTER;
import static io.github.manami.gui.utility.DialogLibrary.showExportDialog;


public class RecommendationsController implements Observer {

    public static final String RECOMMENDATIONS_TAB_TITLE = "Recommendations";

    private final ServiceRepository serviceRepo = Main.CONTEXT.getBean(ServiceRepository.class);
    private final ImageCache imageCache = Main.CONTEXT.getBean(ImageCache.class);
    private final Manami app = Main.CONTEXT.getBean(Manami.class);
    private final Cache cache = Main.CONTEXT.getBean(Cache.class);
    private final Set<InfoLink> containedEntries = new HashSet<>();

    @FXML
    private TableView<Anime> contentTable;

    @FXML
    private HBox hBoxProgress;

    @FXML
    private ProgressBar progressBar;

    @FXML
    private Label lblProgress;

    @FXML
    private Button btnStart;

    @FXML
    private Button btnExport;

    private Tab tab;
    private RecommendationsRetrievalService service;


    /**
     * Called from FXML when creating the Object.
     *
     * @since 2.4.0
     */
    public void initialize() {
        new AnimeTableBuilder<>(contentTable)
                .withPicture(imageCache::loadPicture)
                .withTitleSortable(false)
                .withAddToWatchListButton(true)
                .withAddToFilterListButton(true)
                .withRemoveButton(true)
                .withListChangedEvent((a) -> {
                    Platform.runLater(() -> tab.setText(String.format("Filter List (%s)", contentTable.getItems().size())));
                    return null;
                });
    }


    public void export() {
        final Path file = showExportDialog(Main.CONTEXT.getBean(MainControllerWrapper.class).getMainStage(), JSON_FILTER);
        app.exportList(contentTable.getItems(), file);
    }


    private void showProgressControls(final boolean value) {
        Platform.runLater(() -> {
            hBoxProgress.setVisible(value);
            btnStart.setVisible(!value);
        });
    }


    public void start() {
        service = new RecommendationsRetrievalService(app, cache, this);
        showProgressControls(true);
        contentTable.getItems().clear();
        serviceRepo.startService(service);
    }


    /**
     * Stops the service if necessary and resets the GUI.
     *
     * @since 2.4.0
     */
    public void cancel() {
        if (service != null) {
            service.cancel();
        }

        clear();
    }


    @Override
    public void update(final Observable observable, final Object object) {
        if (object == null) {
            return;
        }

        if (object instanceof AdvancedProgressState) {
            final AdvancedProgressState state = (AdvancedProgressState) object;
            final int done = state.getDone();
            final int all = state.getTodo();
            final double percent = ((done * 100.00) / all) / 100.00;

            if (state.getAnime() != null) {
                Anime anime = state.getAnime();

                if (!containedEntries.contains(anime.getInfoLink())) {
                    containedEntries.add(anime.getInfoLink());
                    contentTable.getItems().add(anime);
                }

                Platform.runLater(() -> {
                    progressBar.setProgress(percent);
{'fraction_non_alphanumeric': 0.1028137370279234, 'fraction_numerical': 0.0034235583609714348, 'mean_word_length': 2.828009828009828, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3319463', 'n_tokens_mistral': 2706, 'n_tokens_neox': 2577, 'n_words': 519}