Skip to content

Commit

Permalink
Basic functionality added (JabRef#10418)
Browse files Browse the repository at this point in the history
  • Loading branch information
ExrosZ-Alt committed Oct 17, 2024
1 parent 707e3c0 commit 9f895f5
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 22 deletions.
11 changes: 10 additions & 1 deletion src/main/java/org/jabref/gui/LibraryTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import org.jabref.gui.maintable.MainTable;
import org.jabref.gui.maintable.MainTableDataModel;
import org.jabref.gui.preferences.GuiPreferences;
import org.jabref.gui.preferences.entry.EntryTabViewModel;
import org.jabref.gui.undo.CountingUndoManager;
import org.jabref.gui.undo.NamedCompound;
import org.jabref.gui.undo.RedoAction;
Expand Down Expand Up @@ -1212,6 +1213,9 @@ public LibraryTabContainer getLibraryTabContainer() {
return tabContainer;
}

/**
* Takes an entry and increments the number of times it has been viewed by 1.
*/
private void incrementViewCount(BibEntry entry) {
MVStore mvStore = PopularityGroup.getMVStore();
synchronized (mvStore) {
Expand All @@ -1222,11 +1226,16 @@ private void incrementViewCount(BibEntry entry) {
String uniqueKey = PopularityGroup.getUniqueKeyForEntry(entry);
long lastViewTime = lastViewTimestamps.getOrDefault(uniqueKey, 0L);

if (currentTime - lastViewTime >= 3600000) { // 3600000 milliseconds in one hour
if (currentTime - lastViewTime >= 3600000 && EntryTabViewModel.trackViewsProperty().get()) { // 3600000 milliseconds in one hour
int currentCount = viewCounts.getOrDefault(uniqueKey, 0);
viewCounts.put(uniqueKey, currentCount + 1);
lastViewTimestamps.put(uniqueKey, currentTime);
mvStore.commit(); // Save changes

// Debugging, remove when all good
System.out.println("BibEntry: " + entry);
System.out.println("UniqueKey: " + uniqueKey);
System.out.println(PopularityGroup.getEntryViewCount(entry));
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/org/jabref/gui/groups/GroupDialogView.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ public class GroupDialogView extends BaseDialog<AbstractGroup> {
@FXML private ComboBox<String> timePeriodCombo;
@FXML private ComboBox<Integer> maxEntriesCombo;


private final EnumMap<GroupHierarchyType, String> hierarchyText = new EnumMap<>(GroupHierarchyType.class);
private final EnumMap<GroupHierarchyType, String> hierarchyToolTip = new EnumMap<>(GroupHierarchyType.class);

Expand Down Expand Up @@ -203,13 +202,15 @@ public void initialize() {
searchRadioButton.selectedProperty().bindBidirectional(viewModel.typeSearchProperty());
autoRadioButton.selectedProperty().bindBidirectional(viewModel.typeAutoProperty());
texRadioButton.selectedProperty().bindBidirectional(viewModel.typeTexProperty());
popularityButton.selectedProperty().bindBidirectional(viewModel.typePopularityProperty());
popularityButton.disableProperty().bind(viewModel.trackViewsEnabledProperty().not());

timePeriodCombo.setItems(FXCollections.observableArrayList("Last week", "Last month", "Last year", "All time"));
maxEntriesCombo.setItems(FXCollections.observableArrayList(10, 20, 50, 100, 999));

timePeriodCombo.visibleProperty().bind(popularityButton.selectedProperty());
maxEntriesCombo.visibleProperty().bind(popularityButton.selectedProperty());
timePeriodCombo.valueProperty().bindBidirectional(viewModel.timePeriodProperty());
maxEntriesCombo.valueProperty().bindBidirectional(viewModel.maxEntriesProperty());
timePeriodCombo.setItems(FXCollections.observableArrayList("Last week", "Last month", "Last year", "All time"));
maxEntriesCombo.setItems(FXCollections.observableArrayList(10, 20, 50, 100, 999));

keywordGroupSearchTerm.textProperty().bindBidirectional(viewModel.keywordGroupSearchTermProperty());
keywordGroupSearchField.textProperty().bindBidirectional(viewModel.keywordGroupSearchFieldProperty());
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ListProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleObjectProperty;
Expand Down Expand Up @@ -47,6 +48,7 @@
import org.jabref.model.groups.ExplicitGroup;
import org.jabref.model.groups.GroupHierarchyType;
import org.jabref.model.groups.GroupTreeNode;
import org.jabref.model.groups.PopularityGroup;
import org.jabref.model.groups.RegexKeywordGroup;
import org.jabref.model.groups.SearchGroup;
import org.jabref.model.groups.TexGroup;
Expand Down Expand Up @@ -99,6 +101,9 @@ public class GroupDialogViewModel {

private final StringProperty texGroupFilePathProperty = new SimpleStringProperty("");

private final Property<Integer> maxEntriesProperty = new SimpleObjectProperty<>();
private final StringProperty timePeriodProperty = new SimpleStringProperty();

private Validator nameValidator;
private Validator nameContainsDelimiterValidator;
private Validator sameNameValidator;
Expand Down Expand Up @@ -371,6 +376,13 @@ public AbstractGroup resultConverter(ButtonType button) {
new DefaultAuxParser(new BibDatabase()),
fileUpdateMonitor,
currentDatabase.getMetaData());
} else if (typePopularityProperty.getValue()) {
resultingGroup = new PopularityGroup(
groupName,
groupHierarchySelectedProperty.getValue(),
currentDatabase.getEntries(),
maxEntriesProperty,
timePeriodProperty);
}

if (resultingGroup != null) {
Expand Down Expand Up @@ -583,6 +595,10 @@ public BooleanProperty typeTexProperty() {
return typeTexProperty;
}

public BooleanProperty typePopularityProperty() {
return typePopularityProperty;
}

public StringProperty keywordGroupSearchTermProperty() {
return keywordGroupSearchTermProperty;
}
Expand Down Expand Up @@ -650,4 +666,12 @@ private boolean groupOrSubgroupIsSearchGroup(GroupTreeNode groupTreeNode) {
public BooleanProperty trackViewsEnabledProperty() {
return EntryTabViewModel.trackViewsProperty();
}

public StringProperty timePeriodProperty() {
return timePeriodProperty;
}

public Property<Integer> maxEntriesProperty() {
return maxEntriesProperty;
}
}
7 changes: 6 additions & 1 deletion src/main/java/org/jabref/gui/preferences/entry/EntryTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
public class EntryTab extends AbstractPreferenceTabView<EntryTabViewModel> implements PreferencesTab {

@FXML public CheckBox trackViews;
@FXML private CheckBox enableViewTracking;

@FXML private TextField keywordSeparator;

Expand Down Expand Up @@ -70,11 +71,15 @@ public void initialize() {

addCreationDate.selectedProperty().bindBidirectional(viewModel.addCreationDateProperty());
addModificationDate.selectedProperty().bindBidirectional(viewModel.addModificationDateProperty());
trackViews.selectedProperty().bindBidirectional(viewModel.trackViewsProperty());
trackViews.selectedProperty().bindBidirectional(EntryTabViewModel.trackViewsProperty());
enableViewTracking.selectedProperty().bindBidirectional(EntryTabViewModel.analysisProperty());

trackViews.selectedProperty().addListener((observable, oldValue, newValue) -> {
viewModel.setTrackViewsEnabled(newValue);
});
enableViewTracking.selectedProperty().addListener((observable, oldValue, newValue) -> {
viewModel.setAnalysisEnabled(newValue);
});

ActionFactory actionFactory = new ActionFactory();
actionFactory.configureIconButton(StandardActions.HELP, new HelpAction(HelpFile.OWNER, dialogService, preferences.getExternalApplicationsPreferences()), markOwnerHelp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class EntryTabViewModel implements PreferenceTabViewModel {
private final StringProperty resolveStringsForFieldsProperty = new SimpleStringProperty("");
private final StringProperty nonWrappableFieldsProperty = new SimpleStringProperty("");

private static final BooleanProperty analysisProperty = new SimpleBooleanProperty();
private final BooleanProperty markOwnerProperty = new SimpleBooleanProperty();
private final StringProperty markOwnerNameProperty = new SimpleStringProperty("");
private final BooleanProperty markOwnerOverwriteProperty = new SimpleBooleanProperty();
Expand Down Expand Up @@ -69,8 +70,7 @@ public void storeSettings() {
ownerPreferences.setOverwriteOwner(markOwnerOverwriteProperty.getValue());

timestampPreferences.setAddCreationDate(addCreationDateProperty.getValue());
timestampPreferences.setAddModificationDate(addModificationDateProperty.getValue());
}
timestampPreferences.setAddModificationDate(addModificationDateProperty.getValue());}

public StringProperty keywordSeparatorProperty() {
return keywordSeparatorProperty;
Expand Down Expand Up @@ -116,11 +116,17 @@ public static BooleanProperty trackViewsProperty() {
return trackViewsProperty;
}

public boolean isTrackViewsEnabled() {
return trackViewsProperty.get();
}

public void setTrackViewsEnabled(boolean enabled) {
trackViewsProperty.set(enabled);
}

// Vew Analysis

public void setAnalysisEnabled(boolean enabled) {
analysisProperty.set(enabled);
}

public static BooleanProperty analysisProperty() {
return analysisProperty;
}
}
74 changes: 64 additions & 10 deletions src/main/java/org/jabref/model/groups/PopularityGroup.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package org.jabref.model.groups;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import javafx.beans.property.Property;
import javafx.beans.property.StringProperty;

import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.StandardField;

Expand All @@ -17,21 +22,35 @@
*/
public class PopularityGroup extends AbstractGroup {
private static MVStore mvStore;
private static List<BibEntry> data;
private final Property<Integer> maxEntriesProperty;
private final StringProperty timePeriodProperty;

public PopularityGroup(String name, GroupHierarchyType context) {
public PopularityGroup(String name, GroupHierarchyType context, List<BibEntry> entries, Property<Integer> integerProperty, StringProperty textProperty) {
super(name, context);
mvStore = getMVStore();
data = processPopularityGroup(entries, textProperty.getValue(), integerProperty.getValue());
this.maxEntriesProperty = integerProperty;
this.timePeriodProperty = textProperty;
}

public boolean contains(BibEntry entry) {
int viewCount = getEntryViewCount(entry);
return viewCount > 0;
int maxEntries = maxEntriesProperty.getValue();
if (viewCount > 0) {
for (int i = 0; i < Math.min(maxEntries, data.size()); i++) {
if (data.get(i).equals(entry)) {
return true;
}
}
}
return false;
}

@Override
@Override
public AbstractGroup deepCopy() {
// Create a copy of this popularity group with the same tracker and context
return new PopularityGroup(getName(), getHierarchicalContext());
// Create a copy of this popularity group with the same parameters
return new PopularityGroup(getName(), getHierarchicalContext(), data, maxEntriesProperty, timePeriodProperty);
}

@Override
Expand Down Expand Up @@ -66,11 +85,6 @@ public int hashCode() {
public static int getEntryViewCount(BibEntry entry) {
MVMap<String, Integer> viewCounts = mvStore.openMap("entryViewCounts");
String uniqueKey = getUniqueKeyForEntry(entry);

// Log the entry and unique key
System.out.println("BibEntry: " + entry);
System.out.println("UniqueKey: " + uniqueKey);

return viewCounts.getOrDefault(uniqueKey, 0);
}

Expand All @@ -89,4 +103,44 @@ public static synchronized MVStore getMVStore() {
}
return mvStore;
}

public List<BibEntry> processPopularityGroup(List<BibEntry> allEntries, String timePeriodCombo, Integer maxEntriesCombo) {
List<BibEntry> filteredEntries = new ArrayList<>();
long currentTime = System.currentTimeMillis();
long timeThreshold = getTimeThreshold(currentTime, timePeriodCombo);

for (BibEntry entry : allEntries) {
long lastViewTime = getLastViewTime(entry);
if (lastViewTime >= timeThreshold) {
filteredEntries.add(entry);
}
}

filteredEntries.sort((e1, e2) -> Integer.compare(PopularityGroup.getEntryViewCount(e2), PopularityGroup.getEntryViewCount(e1)));

if (filteredEntries.size() > maxEntriesCombo) {
filteredEntries = filteredEntries.subList(0, maxEntriesCombo);
}

return filteredEntries;
}

private long getTimeThreshold(long currentTime, String selectedTimePeriod) {
return switch (selectedTimePeriod) {
case "Last week" ->
currentTime - 7 * 24 * 60 * 60 * 1000L;
case "Last month" ->
currentTime - 30 * 24 * 60 * 60 * 1000L;
case "Last year" ->
currentTime - 365 * 24 * 60 * 60 * 1000L;
default -> // "All time"
0;
};
}

private long getLastViewTime(BibEntry entry) {
MVMap<String, Long> lastViewTimestamps = PopularityGroup.getMVStore().openMap("lastViewTimestamps");
String uniqueKey = PopularityGroup.getUniqueKeyForEntry(entry);
return lastViewTimestamps.getOrDefault(uniqueKey, 0L);
}
}

0 comments on commit 9f895f5

Please sign in to comment.