-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for issue #4652: Add Find Unlinked Files Filter based on Date #7846
Merged
Merged
Changes from all commits
Commits
Show all changes
67 commits
Select commit
Hold shift + click to select a range
afd9ba6
Display last edited date along with filename
gliargovas 3d5c737
Create DateRange object
gliargovas 318e79d
Add ExternalFilesDateViewModel
gliargovas 59d5bfd
Add getDisplayTextWithEditDate method
gliargovas aed71d4
Create File Date Combobox
gdrosos be11dab
Fix typo
gdrosos 3b9d286
Add Functionality of FileDateCombo box
gdrosos 3f7aa41
Add ViewModel Functionality for the Last Edited Filter
gdrosos cb303c5
Modify Unlinked Files Crawler to support Last Edited Filter
gdrosos 04962f0
Add FileFilterUtils.java
gliargovas c6625bf
Add "Last Edited:" to l10n package
gliargovas ec54bc3
add External File Sorter Class
gdrosos c099ce0
Add FileSortViewModel
gliargovas e6e15d5
Add Sort by combo box
gliargovas 1e9ec13
Add fileSortCombo view side code
gliargovas 639aa8e
Add sort by date functionality methods
gliargovas 291d645
Add View Model implementation for sort by date field
gdrosos ba7116e
Add Sort Support to Crawler
gdrosos 87c0111
Rename filteredFiles variable in Crawler
gdrosos 7cc1c50
Add "Sort by:" to en localiztion properties
gliargovas 4b3038e
Fix syntax error
gliargovas 7a53d2e
Fix typo in File Filter Utils
gdrosos 18b6df6
Fix incorrect reverse sorting method call
gliargovas 757a8a7
Convert days to months in isDuringLastMonth method
gdrosos 22aef66
Add Unit Tests for isDuring methods in FileFilterUtils
gdrosos f49a0ae
Improve code quality of FileFilterUtilsTest
gdrosos 07d5174
make variables of FileFilterUtilsTest final
gdrosos 6791053
Leave new line to all files
gdrosos 02017c3
Update Changelog
gdrosos 7fcfff6
Merge branch 'main' into fix-for-issue-4652
gdrosos 91235b4
Improve code quality according to Codacy Code Analysis
gdrosos e191344
Merge branch 'fix-for-issue-4652' of https://github.com/gdrosos/jabre…
gdrosos 076f1db
Further improve code quality according to Codacy Code Analysis
gdrosos 1e6cca7
Minor Code quality improvement
gdrosos 66db608
Fix Typo
gdrosos 0998abd
Use Logger to log exceptions
gdrosos fde0180
Use method reference operator
gdrosos 7d83221
Use localization to show localized strings
gdrosos 87d6b9f
Apply suggested changes from Codacy
aad00fc
Revert "Use method reference operator
"
gdrosos 998d52d
Add unlinked files filter fields localisation
gliargovas 6a02336
Merge branch 'fix-for-issue-4652' of https://github.com/gdrosos/jabre…
gliargovas 425c258
Fix typo
gliargovas 482212d
Use meaningful names in lambda expressions
gliargovas 234943a
Refactor code to use DateRange enum instead of strings
gliargovas 4f812a9
Remove wrongly commited code
gliargovas e949db9
Use ExternalFileSorter Enums instead of Strings
gdrosos 7295535
Ensure the code passes LocalizationConsistencyTests
gdrosos 9b001f6
Add tests for FileFilterUtils sort methods
gliargovas ccd8e92
Fix code format issues
gliargovas c2c7ae6
Update FileFilterUtilsTests with minor fixes
gdrosos bd9dbf7
Add negative sort tests and improve code format
gliargovas 1a58342
Use Path.of() instead of Paths.get()
gliargovas 08f0f19
Fix FileFilterUtilsTest code format
gliargovas 4db03ee
Add documentation to UnlinkedFilesCrawler and FileFilterUtils
gliargovas 3825ee9
Add comment descriptions to FileFilterUtilsTest
gliargovas 7762cb9
Replace minusMonths() and minusYears() with minusDays()
gliargovas 6e721c5
Use TempDir at Unit Tests
gdrosos a495c16
Remove the use of java.io.File
gliargovas a6f91c0
Use streams for sort tests
gliargovas 5136b1f
Remove unused imports
gliargovas 0b459a6
Use enums directly for filter and sort fields
gliargovas 226010b
Remove redundant default cases from FileFilterUtils.java
gliargovas 1e2f8c4
replace DateRange enums with values() method
gdrosos 3334398
Replace ExternalFileSorter enums with values() method in UnlinkedFile…
gdrosos 4ae48a1
Place the correct order in DateTime enums
gdrosos 4a00080
Make sure a value is returned when an IOException occurs in getFileTi…
gdrosos File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.jabref.gui.externalfiles; | ||
|
||
import org.jabref.logic.l10n.Localization; | ||
|
||
public enum DateRange { | ||
ALL_TIME(Localization.lang("All time")), | ||
YEAR(Localization.lang("Last year")), | ||
MONTH(Localization.lang("Last month")), | ||
WEEK(Localization.lang("Last week")), | ||
DAY(Localization.lang("Last day")); | ||
|
||
private final String dateRange; | ||
|
||
DateRange(String dateRange) { | ||
this.dateRange = dateRange; | ||
} | ||
|
||
public String getDateRange() { | ||
return dateRange; | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/org/jabref/gui/externalfiles/ExternalFileSorter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package org.jabref.gui.externalfiles; | ||
|
||
import org.jabref.logic.l10n.Localization; | ||
|
||
public enum ExternalFileSorter { | ||
DEFAULT(Localization.lang("Default")), | ||
DATE_ASCENDING(Localization.lang("Newest first")), | ||
DATE_DESCENDING(Localization.lang("Oldest first")); | ||
|
||
private final String sorter; | ||
|
||
ExternalFileSorter(String sorter) { | ||
this.sorter = sorter; | ||
} | ||
|
||
public String getSorter() { | ||
return sorter; | ||
} | ||
} |
112 changes: 112 additions & 0 deletions
112
src/main/java/org/jabref/gui/externalfiles/FileFilterUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package org.jabref.gui.externalfiles; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.attribute.FileTime; | ||
import java.time.LocalDateTime; | ||
import java.time.ZoneId; | ||
import java.util.Comparator; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class FileFilterUtils { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(FileFilterUtils.class); | ||
|
||
/* Returns the last edited time of a file as LocalDateTime. */ | ||
public static LocalDateTime getFileTime(Path path) { | ||
FileTime lastEditedTime = null; | ||
try { | ||
lastEditedTime = Files.getLastModifiedTime(path); | ||
} catch (IOException e) { | ||
LOGGER.error("Could not retrieve file time", e); | ||
return LocalDateTime.now(); | ||
} | ||
LocalDateTime localDateTime = lastEditedTime | ||
.toInstant() | ||
.atZone(ZoneId.systemDefault()) | ||
.toLocalDateTime(); | ||
return localDateTime; | ||
} | ||
|
||
/* Returns true if a file with a specific path | ||
* was edited during the last 24 hours. */ | ||
public boolean isDuringLastDay(LocalDateTime fileEditTime) { | ||
LocalDateTime NOW = LocalDateTime.now(ZoneId.systemDefault()); | ||
return fileEditTime.isAfter(NOW.minusHours(24)); | ||
} | ||
|
||
/* Returns true if a file with a specific path | ||
* was edited during the last 7 days. */ | ||
public boolean isDuringLastWeek(LocalDateTime fileEditTime) { | ||
LocalDateTime NOW = LocalDateTime.now(ZoneId.systemDefault()); | ||
return fileEditTime.isAfter(NOW.minusDays(7)); | ||
} | ||
|
||
/* Returns true if a file with a specific path | ||
* was edited during the last 30 days. */ | ||
public boolean isDuringLastMonth(LocalDateTime fileEditTime) { | ||
LocalDateTime NOW = LocalDateTime.now(ZoneId.systemDefault()); | ||
return fileEditTime.isAfter(NOW.minusDays(30)); | ||
} | ||
|
||
/* Returns true if a file with a specific path | ||
* was edited during the last 365 days. */ | ||
public boolean isDuringLastYear(LocalDateTime fileEditTime) { | ||
LocalDateTime NOW = LocalDateTime.now(ZoneId.systemDefault()); | ||
return fileEditTime.isAfter(NOW.minusDays(365)); | ||
} | ||
|
||
/* Returns true if a file is edited in the time margin specified by the given filter. */ | ||
public static boolean filterByDate(Path path, DateRange filter) { | ||
FileFilterUtils fileFilter = new FileFilterUtils(); | ||
LocalDateTime fileTime = FileFilterUtils.getFileTime(path); | ||
boolean isInDateRange = switch (filter) { | ||
case DAY -> fileFilter.isDuringLastDay(fileTime); | ||
case WEEK -> fileFilter.isDuringLastWeek(fileTime); | ||
case MONTH -> fileFilter.isDuringLastMonth(fileTime); | ||
case YEAR -> fileFilter.isDuringLastYear(fileTime); | ||
case ALL_TIME -> true; | ||
}; | ||
return isInDateRange; | ||
} | ||
|
||
/* Sorts a list of Path objects according to the last edited date | ||
* of their corresponding files, from newest to oldest. */ | ||
public List<Path> sortByDateAscending(List<Path> files) { | ||
return files.stream() | ||
.sorted(Comparator.comparingLong(file -> FileFilterUtils.getFileTime(file) | ||
.atZone(ZoneId.systemDefault()) | ||
.toInstant() | ||
.toEpochMilli())) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
/* Sorts a list of Path objects according to the last edited date | ||
* of their corresponding files, from oldest to newest. */ | ||
public List<Path> sortByDateDescending(List<Path> files) { | ||
return files.stream() | ||
.sorted(Comparator.comparingLong(file -> -FileFilterUtils.getFileTime(file) | ||
.atZone(ZoneId.systemDefault()) | ||
.toInstant() | ||
.toEpochMilli())) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
/* Sorts a list of Path objects according to the last edited date | ||
* the order depends on the specified sorter type. */ | ||
public static List<Path> sortByDate(List<Path> files, ExternalFileSorter sortType) { | ||
FileFilterUtils fileFilter = new FileFilterUtils(); | ||
List<Path> sortedFiles = switch (sortType) { | ||
case DEFAULT -> files; | ||
case DATE_ASCENDING -> fileFilter.sortByDateDescending(files); | ||
case DATE_DESCENDING -> fileFilter.sortByDateAscending(files); | ||
}; | ||
return sortedFiles; | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IntelliJ complains here, that toInstant may throw a NPE. This seems possible, since you don't return when a IOException occurs. Is that something we should think about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @calixtus , so maybe we need to place the code in a try catch-block to handle the NPE or in the same try catch block so when an IO Exception occurs the toInstant() method call is omited.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, there must be a value returned from this method... Which one, if getLastModifiedTime fails?
Today? null?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, sorry you are right, we will return LocalDateTime.now() when an IOException occurs