From 31824f0ff7a242cf25e2cdc59cc5ddfa6addc00d Mon Sep 17 00:00:00 2001 From: Oliver Kopp <1366654+koppor@users.noreply.github.com> Date: Wed, 22 Jun 2022 22:55:52 +0200 Subject: [PATCH 01/13] Remove obsolete closing bracket --- .gitpod.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile index 86a0be3410e..007108a0f49 100644 --- a/.gitpod.Dockerfile +++ b/.gitpod.Dockerfile @@ -5,4 +5,4 @@ FROM gitpod/workspace-full # All available versions can be listed using sdk ls java # More information about SDKMAN available at https://github.com/sdkman/sdkman-cli#sdkman-cli RUN bash -c ". /home/gitpod/.sdkman/bin/sdkman-init.sh \ - && sdk install java 18.0.1.1-open)" + && sdk install java 18.0.1.1-open" From 5f2c4f992d751c78268792af97b56334aa79903d Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Wed, 22 Jun 2022 21:23:40 +0000 Subject: [PATCH 02/13] Fix extension name --- .gitpod.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.yml b/.gitpod.yml index ca3b96bdf76..14f9d5faf56 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -5,4 +5,4 @@ tasks: vscode: extensions: - redhat.java - - vscjava + - vscjava.vscode-java-pack From b56ad72e305b5ba53c598d6ef8b93a884afbb610 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Thu, 23 Jun 2022 06:54:08 +0000 Subject: [PATCH 03/13] Add gradle support --- .gitpod.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitpod.yml b/.gitpod.yml index 14f9d5faf56..e8a063cab8e 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -5,4 +5,7 @@ tasks: vscode: extensions: - redhat.java - - vscjava.vscode-java-pack + - richardwillis.vscode-gradle + - vscjava.vscode-java-debug + - kiteco.kite + - DavidAnson.vscode-markdownlint From 3c2aae97bffdb44ccb064dba20ab26e03cf181f2 Mon Sep 17 00:00:00 2001 From: Oliver Kopp <1366654+koppor@users.noreply.github.com> Date: Thu, 23 Jun 2022 09:25:26 +0200 Subject: [PATCH 04/13] Add IntelliJ plugins to Gitpod configuration --- .gitpod.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitpod.yml b/.gitpod.yml index e8a063cab8e..a0aa262ea90 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -2,6 +2,11 @@ image: file: .gitpod.Dockerfile tasks: - init: ./gradlew assemble +jetbrains: + intellij: + plugins: + - CheckStyle-IDEA + - zielu.gittoolbox vscode: extensions: - redhat.java From 0c96007c0a7e7cb317fb6296e180bfe3caa46c9f Mon Sep 17 00:00:00 2001 From: linsui <36977733+linsui@users.noreply.github.com> Date: Thu, 23 Jun 2022 18:53:27 +0000 Subject: [PATCH 05/13] Pass the data as a string (#8923) closes https://github.com/JabRef/jabref/issues/8922 --- buildres/linux/jabrefHost.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildres/linux/jabrefHost.py b/buildres/linux/jabrefHost.py index aedf2d81580..557768fc9f6 100755 --- a/buildres/linux/jabrefHost.py +++ b/buildres/linux/jabrefHost.py @@ -74,7 +74,7 @@ def send_message(message): def add_jabref_entry(data): """Send string via cli as literal to preserve special characters""" - cmd = str(JABREF_PATH).split() + ["--importBibtex", r"{}".format(data)] + cmd = str(JABREF_PATH).split() + ["--importBibtex", r"'{}'".format(data)] logging.info("Try to execute command {}".format(cmd)) response = subprocess.check_output(cmd, stderr=subprocess.STDOUT) logging.info("Called JabRef and got: {}".format(response)) From 92e4cb28078ed743b40b70ab7325b3d4c1b68947 Mon Sep 17 00:00:00 2001 From: Oliver Kopp <1366654+koppor@users.noreply.github.com> Date: Sat, 25 Jun 2022 22:48:29 +0200 Subject: [PATCH 06/13] Link to new board (and refine text) Co-authored-by: ThiloteE <73715071+ThiloteE@users.noreply.github.com> --- docs/teaching.md | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/docs/teaching.md b/docs/teaching.md index 52a3a14a1f4..fdf628d7073 100644 --- a/docs/teaching.md +++ b/docs/teaching.md @@ -15,27 +15,31 @@ By using JabRef as training object in exercises and labs, students can level-up ## How to integrate JabRef in your class -1. Get in touch with the JabRef team to discuss details. We offer email, skype, [gitter.im](https://gitter.im/JabRef/jabref), discord. Get in touch with [@koppor](https://github.com/koppor/) to find the right channel and to start forming the success of your course. -2. Choose tasks from one of the following boards. Write a comment on each issue so that it can be reserved for your course. - * Candidates for university projects: [https://github.com/JabRef/jabref/projects/9](https://github.com/JabRef/jabref/projects/9) - * This board categorizes in small, medium, and large features - * Feature Board: [https://github.com/JabRef/jabref/projects/7](https://github.com/JabRef/jabref/projects/7) - * This is a general feature board. Recommended, if the board above is empty or you did not find something suitable - * Bug Board: [https://github.com/JabRef/jabref/projects/5](https://github.com/JabRef/jabref/projects/5) - * This is an excellent board to find issues training the maintenance knowledge which is essential for industry work - * General "good first issues". The JabRef team tags issues as [good first issues](https://github.com/jabref/jabref/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) to indicate open tasks offering a good start into the JabRef code. These issues are more a list of random bugs and features. For a more structured comparison of the opened tasks, we recommend the project boards listed above. - * Be aware that the difficulty of bugs and feature vary. A task should be chosen with care. The JabRef team can help here: The majority of the team has experiences in teaching +1. Choose task from the board [Candidates for university projects](https://github.com/orgs/JabRef/projects/3/views/3). + There, new functionality is categorized in small, medium, and large effort. + Morevoer, categorization on the main focus (UI, logic, or both), + implementation effort, testing effort, and "issue understanding effort". + The latter category is important, because some issues are "quick wins" and others need thorough thinking. + In general, all issues of JabRef are free to take. + Be aware that the difficulty of bugs and feature vary. + For the brave, the [Bug Board](https://github.com/JabRef/jabref/projects/5) or the [Feature Board](https://github.com/JabRef/jabref/projects/7) provide other issue sources. + Especially for Master students, these are excellent boards to find issues that train maintenance knowledge (which is essential for industry work). +2. Get in touch with the JabRef team to reserve issues for your student group and possibly to discuss details. We offer email, skype, [gitter.im](https://gitter.im/JabRef/jabref), discord. Get in touch with [@koppor](https://github.com/koppor/) to find the right channel and to start forming the success of your course. 3. Schedule tasks with students -4. Code reviews by JabRef maintainers -5. Students address feedback and learn more about good coding practices by incoporating feedback -6. Students update their pull request -7. Pull request is merged +4. Students implement code +5. Students review other student's code (recommended: students of a previous year's project review current year's project code) +6. Students address review feedback +7. Students submit pull request +8. Code reviews by JabRef maintainers +9. Students address feedback and learn more about good coding practices by incoporating feedback +10. Students update their pull request +11. Pull request is merged -For a near-to-perfect preparation and effect of the course, we ask you to get in touch with us **four weeks** in advance. Then, the JabRef team can a) learn about the starting skill level of the students, b) the aimed skill level at the end of the course, c) the amount of time the students are given to learn about and contribute to JabRef, d) check the [feature board](https://github.com/JabRef/jabref/projects/7) for appropriate tasks (and fill it as needed), e) recommend appropriate features. +For a near-to-perfect preparation and effect of the course, we ask you to get in touch with us **four weeks** in advance. Then, the JabRef team can a) learn about the starting skill level of the students, b) the aimed skill level at the end of the course, c) the amount of time the students are given to learn about and contribute to JabRef, d) check the [Candidates for university projects](https://github.com/orgs/JabRef/projects/3/views/3) for appropriate tasks (and fill it as needed), e) recommend appropriate features. -It is also possible to just direct students to our [Contribution Guide](https://github.com/JabRef/jabref/blob/master/CONTRIBUTING.md#contributing-guide). The learning effect may be lower as the time of the students has to be spent to a) learn about JabRef and b) select an appropriate issue. +It is also possible to just direct students to our [Contribution Guide](https://devdocs.jabref.org/contributing.html#contribute-code). The learning effect may be lower as the time of the students has to be spent to a) learn about JabRef and b) select an appropriate issue. -Since a huge fraction of software costs is spent on [software maintenance](https://en.wikipedia.org/wiki/Software\_maintenance), adding new features also educates in that aspect: perfective maintenance[1](teaching.md#LientzSwanson) is trained. When fixing bugs, corrective maintenance[2](teaching.md#LientzSwanson) is trained. +Since a huge fraction of software costs is spent on [software maintenance](https://en.wikipedia.org/wiki/Software\_maintenance), adding new features also educates in that aspect: perfective maintenance[1](teaching.md#LientzSwanson) is trained. When fixing bugs, corrective maintenance [2](teaching.md#LientzSwanson) is trained. ## Process for contributions From 5990776e1ff00916e6638c32524841a8ef86ea54 Mon Sep 17 00:00:00 2001 From: Christoph Date: Mon, 27 Jun 2022 20:42:16 +0200 Subject: [PATCH 07/13] Try to make reproducible builds (#8925) * remove lov4j snapshot from test * lock deps and use jitpack for commit hash * add gradle lockfile * remove lockfile. Can still be added later --- build.gradle | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 413e9c6f29f..8e56620aca1 100644 --- a/build.gradle +++ b/build.gradle @@ -81,7 +81,7 @@ repositories { mavenLocal() mavenCentral() maven { url 'https://oss.sonatype.org/content/groups/public' } - maven { url 'https://repository.apache.org/snapshots' } + maven { url 'https://jitpack.io' } } configurations { @@ -95,6 +95,10 @@ configurations { } } +dependencyLocking { + lockAllConfigurations() +} + javafx { version = "18" modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.web', 'javafx.swing' ] @@ -166,7 +170,7 @@ dependencies { // JavaFX stuff implementation 'org.kordamp.ikonli:ikonli-javafx:12.3.1' implementation 'org.kordamp.ikonli:ikonli-materialdesign2-pack:12.3.1' - implementation 'de.saxsys:mvvmfx-validation:1.9.0-SNAPSHOT' + implementation 'com.github.sialcasa.mvvmFX:mvvmfx-validation:f195849ca9' //jitpack implementation 'de.saxsys:mvvmfx:1.8.0' implementation 'com.tobiasdiez:easybind:2.2' implementation 'org.fxmisc.flowless:flowless:0.6.10' @@ -208,15 +212,13 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2' testImplementation 'org.junit.platform:junit-platform-launcher:1.8.2' - testRuntimeOnly group: 'org.apache.logging.log4j', name: 'log4j-core', version: '3.0.0-SNAPSHOT' - testRuntimeOnly group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '3.0.0-SNAPSHOT' testImplementation 'org.mockito:mockito-core:4.6.1' testImplementation 'org.xmlunit:xmlunit-core:2.9.0' testImplementation 'org.xmlunit:xmlunit-matchers:2.9.0' testRuntimeOnly 'com.tngtech.archunit:archunit-junit5-engine:0.23.1' testImplementation 'com.tngtech.archunit:archunit-junit5-api:0.23.1' - testImplementation "org.testfx:testfx-core:4.0.17-alpha-SNAPSHOT" - testImplementation "org.testfx:testfx-junit5:4.0.17-alpha-SNAPSHOT" + testImplementation "org.testfx:testfx-core:4.0.16-alpha" + testImplementation "org.testfx:testfx-junit5:4.0.16-alpha" testImplementation "org.hamcrest:hamcrest-library:2.2" checkstyle 'com.puppycrawl.tools:checkstyle:10.1' From 2d1591711e52d18e52ff36ac7d882fb62ffc2bac Mon Sep 17 00:00:00 2001 From: Prashant Singh Date: Tue, 28 Jun 2022 06:42:06 +0930 Subject: [PATCH 08/13] Find Unlinked files should ignore Thumbs.db, etc (#8800) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christoph Co-authored-by: ThiloteE <73715071+ThiloteE@users.noreply.github.com> Co-authored-by: “zhaoqingying123“ <710870305@qq.com> Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com> Co-authored-by: Oliver Kopp --- CHANGELOG.md | 1 + .../gui/externalfiles/ChainedFilters.java | 35 ++++++++++ .../gui/externalfiles/FileFilterUtils.java | 30 +++++---- .../externalfiles/GitIgnoreFileFilter.java | 66 +++++++++++++++++++ .../externalfiles/UnlinkedFilesCrawler.java | 66 +++++++++++++------ .../externalfiles/UnlinkedPDFFileFilter.java | 1 - .../jabref/gui/util/FileNodeViewModel.java | 18 +++++ .../externalfiles/FileFilterUtilsTest.java | 63 ++++++++++++++---- .../GitIgnoreFileFilterTest.java | 50 ++++++++++++++ .../UnlinkedFilesCrawlerTest.java | 38 +++++++++++ 10 files changed, 323 insertions(+), 45 deletions(-) create mode 100644 src/main/java/org/jabref/gui/externalfiles/ChainedFilters.java create mode 100644 src/main/java/org/jabref/gui/externalfiles/GitIgnoreFileFilter.java create mode 100644 src/test/java/org/jabref/gui/externalfiles/GitIgnoreFileFilterTest.java create mode 100644 src/test/java/org/jabref/gui/externalfiles/UnlinkedFilesCrawlerTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bad6edb909..dea34f011c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We added a fetcher for [Biodiversity Heritage Library](https://www.biodiversitylibrary.org/). [8539](https://github.com/JabRef/jabref/issues/8539) - We added support for multiple messages in the snackbar. [#7340](https://github.com/JabRef/jabref/issues/7340) +- We added an extra option in the 'Find Unlinked Files' dialog view to ignore unnecessary files like Thumbs.db, DS_Store, etc. [koppor#373](https://github.com/koppor/jabref/issues/373) - JabRef now writes log files. Linux: `$home/.cache/jabref/logs/version`, Windows: `%APPDATA%\..\Local\harawata\jabref\version\logs`, Mac: `Users/.../Library/Logs/jabref/version` - We added an importer for Citavi backup files, support ".ctv5bak" and ".ctv6bak" file formats. [#8322](https://github.com/JabRef/jabref/issues/8322) diff --git a/src/main/java/org/jabref/gui/externalfiles/ChainedFilters.java b/src/main/java/org/jabref/gui/externalfiles/ChainedFilters.java new file mode 100644 index 00000000000..4162c9c674f --- /dev/null +++ b/src/main/java/org/jabref/gui/externalfiles/ChainedFilters.java @@ -0,0 +1,35 @@ +package org.jabref.gui.externalfiles; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Path; +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Chains the given filters - if ALL of them accept, the result is also accepted + */ +public class ChainedFilters implements DirectoryStream.Filter { + + private static final Logger LOGGER = LoggerFactory.getLogger(ChainedFilters.class); + + private DirectoryStream.Filter[] filters; + + public ChainedFilters(DirectoryStream.Filter... filters) { + this.filters = filters; + } + + @Override + public boolean accept(Path entry) throws IOException { + return Arrays.stream(filters).allMatch(filter -> { + try { + return filter.accept(entry); + } catch (IOException e) { + LOGGER.error("Could not apply filter", e); + return true; + } + }); + } +} diff --git a/src/main/java/org/jabref/gui/externalfiles/FileFilterUtils.java b/src/main/java/org/jabref/gui/externalfiles/FileFilterUtils.java index 28e1f20929a..6c9e48d13e3 100644 --- a/src/main/java/org/jabref/gui/externalfiles/FileFilterUtils.java +++ b/src/main/java/org/jabref/gui/externalfiles/FileFilterUtils.java @@ -16,10 +16,10 @@ 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; + FileTime lastEditedTime; try { lastEditedTime = Files.getLastModifiedTime(path); } catch (IOException e) { @@ -33,28 +33,28 @@ public static LocalDateTime getFileTime(Path path) { return localDateTime; } - /* Returns true if a file with a specific path + /* 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 + /* 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 + /* 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 + /* 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()); @@ -75,8 +75,10 @@ public static boolean filterByDate(Path path, DateRange filter) { return isInDateRange; } - /* Sorts a list of Path objects according to the last edited date - * of their corresponding files, from newest to oldest. */ + /** + * Sorts a list of Path objects according to the last edited date + * of their corresponding files, from newest to oldest. + */ public List sortByDateAscending(List files) { return files.stream() .sorted(Comparator.comparingLong(file -> FileFilterUtils.getFileTime(file) @@ -86,8 +88,10 @@ public List sortByDateAscending(List files) { .collect(Collectors.toList()); } - /* Sorts a list of Path objects according to the last edited date - * of their corresponding files, from oldest to newest. */ + /** + * Sorts a list of Path objects according to the last edited date + * of their corresponding files, from oldest to newest. + */ public List sortByDateDescending(List files) { return files.stream() .sorted(Comparator.comparingLong(file -> -FileFilterUtils.getFileTime(file) @@ -97,8 +101,10 @@ public List sortByDateDescending(List files) { .collect(Collectors.toList()); } - /* Sorts a list of Path objects according to the last edited date - * the order depends on the specified sorter type. */ + /** + * Sorts a list of Path objects according to the last edited date + * the order depends on the specified sorter type. + */ public static List sortByDate(List files, ExternalFileSorter sortType) { FileFilterUtils fileFilter = new FileFilterUtils(); List sortedFiles = switch (sortType) { diff --git a/src/main/java/org/jabref/gui/externalfiles/GitIgnoreFileFilter.java b/src/main/java/org/jabref/gui/externalfiles/GitIgnoreFileFilter.java new file mode 100644 index 00000000000..64f01de977b --- /dev/null +++ b/src/main/java/org/jabref/gui/externalfiles/GitIgnoreFileFilter.java @@ -0,0 +1,66 @@ +package org.jabref.gui.externalfiles; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static java.util.function.Predicate.not; + +public class GitIgnoreFileFilter implements DirectoryStream.Filter { + + private static final Logger LOGGER = LoggerFactory.getLogger(GitIgnoreFileFilter.class); + + private Set gitIgnorePatterns; + + public GitIgnoreFileFilter(Path path) { + Path currentPath = path; + while ((currentPath != null) && !Files.exists(currentPath.resolve(".gitignore"))) { + currentPath = currentPath.getParent(); + } + if (currentPath == null) { + // we did not find any gitignore, lets use the default + gitIgnorePatterns = Set.of(".git", ".DS_Store", "desktop.ini", "Thumbs.db").stream() + // duplicate code as below + .map(line -> "glob:" + line) + .map(matcherString -> FileSystems.getDefault().getPathMatcher(matcherString)) + .collect(Collectors.toSet()); + } else { + Path gitIgnore = currentPath.resolve(".gitignore"); + try { + Set plainGitIgnorePatternsFromGitIgnoreFile = Files.readAllLines(gitIgnore).stream() + .map(line -> line.trim()) + .filter(not(String::isEmpty)) + .filter(line -> !line.startsWith("#")) + // convert to Java syntax for Glob patterns + .map(line -> "glob:" + line) + .map(matcherString -> FileSystems.getDefault().getPathMatcher(matcherString)) + .collect(Collectors.toSet()); + gitIgnorePatterns = new HashSet<>(plainGitIgnorePatternsFromGitIgnoreFile); + // we want to ignore ".gitignore" itself + gitIgnorePatterns.add(FileSystems.getDefault().getPathMatcher("glob:.gitignore")); + } catch (IOException e) { + LOGGER.info("Could not read .gitignore from {}", gitIgnore, e); + gitIgnorePatterns = Set.of(); + } + } + } + + @Override + public boolean accept(Path path) throws IOException { + // We assume that git does not stop at a patern, but tries all. We implement that behavior + return gitIgnorePatterns.stream().noneMatch(filter -> + // we need this one for "*.png" + filter.matches(path.getFileName()) || + // we need this one for "**/*.png" + filter.matches(path)); + } +} diff --git a/src/main/java/org/jabref/gui/externalfiles/UnlinkedFilesCrawler.java b/src/main/java/org/jabref/gui/externalfiles/UnlinkedFilesCrawler.java index 53ebad10fc5..ef26c177a25 100644 --- a/src/main/java/org/jabref/gui/externalfiles/UnlinkedFilesCrawler.java +++ b/src/main/java/org/jabref/gui/externalfiles/UnlinkedFilesCrawler.java @@ -66,52 +66,76 @@ protected FileNodeViewModel call() throws IOException { * 'state' must be set to 1, to keep the recursion running. When the states value changes, the method will resolve * its recursion and return what it has saved so far. *
- * The files are filtered according to the {@link DateRange} filter value + * The files are filtered according to the {@link DateRange} filter value * and then sorted according to the {@link ExternalFileSorter} value. * + * @param unlinkedPDFFileFilter contains a BibDatabaseContext which is used to determine whether the file is linked + * + * @return FileNodeViewModel containing the data of the current directory and all subdirectories * @throws IOException if directory is not a directory or empty */ - private FileNodeViewModel searchDirectory(Path directory, UnlinkedPDFFileFilter fileFilter) throws IOException { + FileNodeViewModel searchDirectory(Path directory, UnlinkedPDFFileFilter unlinkedPDFFileFilter) throws IOException { // Return null if the directory is not valid. if ((directory == null) || !Files.isDirectory(directory)) { throw new IOException(String.format("Invalid directory for searching: %s", directory)); } - FileNodeViewModel parent = new FileNodeViewModel(directory); - Map> fileListPartition; + FileNodeViewModel fileNodeViewModelForCurrentDirectory = new FileNodeViewModel(directory); - try (Stream filesStream = StreamSupport.stream(Files.newDirectoryStream(directory, fileFilter).spliterator(), false)) { - fileListPartition = filesStream.collect(Collectors.partitioningBy(Files::isDirectory)); + // Map from isDirectory (true/false) to full path + // Result: Contains only files not matching the filter (i.e., PDFs not linked and files not ignored) + // Filters: + // 1. UnlinkedPDFFileFilter + // 2. GitIgnoreFilter + ChainedFilters filters = new ChainedFilters(unlinkedPDFFileFilter, new GitIgnoreFileFilter(directory)); + Map> directoryAndFilePartition; + try (Stream filesStream = StreamSupport.stream(Files.newDirectoryStream(directory, filters).spliterator(), false)) { + directoryAndFilePartition = filesStream.collect(Collectors.partitioningBy(Files::isDirectory)); } catch (IOException e) { - LOGGER.error(String.format("%s while searching files: %s", e.getClass().getName(), e.getMessage())); - return parent; + LOGGER.error("Error while searching files", e); + return fileNodeViewModelForCurrentDirectory; } + List subDirectories = directoryAndFilePartition.get(true); + List files = directoryAndFilePartition.get(false); - List subDirectories = fileListPartition.get(true); - List files = new ArrayList<>(fileListPartition.get(false)); - int fileCount = 0; + // at this point, only unlinked PDFs AND unignored files are contained - for (Path subDirectory : subDirectories) { - FileNodeViewModel subRoot = searchDirectory(subDirectory, fileFilter); + // initially, we find no files at all + int fileCountOfSubdirectories = 0; + // now we crawl into the found subdirectories first (!) + for (Path subDirectory : subDirectories) { + FileNodeViewModel subRoot = searchDirectory(subDirectory, unlinkedPDFFileFilter); if (!subRoot.getChildren().isEmpty()) { - fileCount += subRoot.getFileCount(); - parent.getChildren().add(subRoot); + fileCountOfSubdirectories += subRoot.getFileCount(); + fileNodeViewModelForCurrentDirectory.getChildren().add(subRoot); } } + // now we have the data of all subdirectories + // it is stored in fileNodeViewModelForCurrentDirectory.getChildren() + + // now we handle the files in the current directory + // filter files according to last edited date. - List filteredFiles = new ArrayList(); + // Note that we do not use the "StreamSupport.stream" filtering functionality, because refactoring the code to that would lead to more code + List resultingFiles = new ArrayList<>(); for (Path path : files) { if (FileFilterUtils.filterByDate(path, dateFilter)) { - filteredFiles.add(path); + resultingFiles.add(path); } } + // sort files according to last edited date. - filteredFiles = FileFilterUtils.sortByDate(filteredFiles, sorter); - parent.setFileCount(filteredFiles.size() + fileCount); - parent.getChildren().addAll(filteredFiles.stream() + resultingFiles = FileFilterUtils.sortByDate(resultingFiles, sorter); + + // the count of all files is the count of the found files in current directory plus the count of all files in the subdirectories + fileNodeViewModelForCurrentDirectory.setFileCount(resultingFiles.size() + fileCountOfSubdirectories); + + // create and add FileNodeViewModel to the FileNodeViewModel for the current directory + fileNodeViewModelForCurrentDirectory.getChildren().addAll(resultingFiles.stream() .map(FileNodeViewModel::new) .collect(Collectors.toList())); - return parent; + + return fileNodeViewModelForCurrentDirectory; } } diff --git a/src/main/java/org/jabref/gui/externalfiles/UnlinkedPDFFileFilter.java b/src/main/java/org/jabref/gui/externalfiles/UnlinkedPDFFileFilter.java index 0cdb7263263..0532801d222 100644 --- a/src/main/java/org/jabref/gui/externalfiles/UnlinkedPDFFileFilter.java +++ b/src/main/java/org/jabref/gui/externalfiles/UnlinkedPDFFileFilter.java @@ -32,7 +32,6 @@ public UnlinkedPDFFileFilter(DirectoryStream.Filter fileFilter, BibDatabas @Override public boolean accept(Path pathname) throws IOException { - if (Files.isDirectory(pathname)) { return true; } else { diff --git a/src/main/java/org/jabref/gui/util/FileNodeViewModel.java b/src/main/java/org/jabref/gui/util/FileNodeViewModel.java index 2c7d4e1a103..2410ad4b67c 100644 --- a/src/main/java/org/jabref/gui/util/FileNodeViewModel.java +++ b/src/main/java/org/jabref/gui/util/FileNodeViewModel.java @@ -7,6 +7,7 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; +import java.util.Objects; import javafx.beans.property.ReadOnlyListWrapper; import javafx.collections.FXCollections; @@ -94,4 +95,21 @@ public String toString() { this.children, this.fileCount); } + + @Override + public int hashCode() { + return Objects.hash(children, fileCount, path); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof FileNodeViewModel)) { + return false; + } + FileNodeViewModel other = (FileNodeViewModel) obj; + return Objects.equals(children, other.children) && (fileCount == other.fileCount) && Objects.equals(path, other.path); + } } diff --git a/src/test/java/org/jabref/gui/externalfiles/FileFilterUtilsTest.java b/src/test/java/org/jabref/gui/externalfiles/FileFilterUtilsTest.java index a6888ab8d3a..9af4b1364bb 100755 --- a/src/test/java/org/jabref/gui/externalfiles/FileFilterUtilsTest.java +++ b/src/test/java/org/jabref/gui/externalfiles/FileFilterUtilsTest.java @@ -5,7 +5,9 @@ import java.nio.file.attribute.FileTime; import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import org.junit.jupiter.api.BeforeEach; @@ -64,20 +66,20 @@ public void isDuringLastYearPositiveTest() { @Nested class SortingTests { - private List files = new ArrayList(); - private List expectedSortByDateAscending = new ArrayList(); - private List expectedSortByDateDescending = new ArrayList(); - private List wrongOrder = new ArrayList(); + private final List files = new ArrayList<>(); + private final List expectedSortByDateAscending = new ArrayList<>(); + private final List expectedSortByDateDescending = new ArrayList<>(); + private final List wrongOrder = new ArrayList<>(); /* Initialize the directory and files used in the sorting tests, and change their last edited dates. */ @BeforeEach public void setUp(@TempDir Path tempDir) throws Exception { - + Path firstPath = tempDir.resolve("firstFile.pdf"); Path secondPath = tempDir.resolve("secondFile.pdf"); Path thirdPath = tempDir.resolve("thirdFile.pdf"); Path fourthPath = tempDir.resolve("fourthFile.pdf"); - + Files.createFile(firstPath); Files.createFile(secondPath); Files.createFile(thirdPath); @@ -88,19 +90,19 @@ public void setUp(@TempDir Path tempDir) throws Exception { Files.setLastModifiedTime(secondPath, FileTime.fromMillis(5)); Files.setLastModifiedTime(thirdPath, FileTime.fromMillis(1)); Files.setLastModifiedTime(fourthPath, FileTime.fromMillis(2)); - + // fill the list to be sorted by the tests. files.add(firstPath); files.add(secondPath); files.add(thirdPath); files.add(fourthPath); - + // fill the expected values lists. expectedSortByDateAscending.add(thirdPath.toString()); expectedSortByDateAscending.add(fourthPath.toString()); expectedSortByDateAscending.add(secondPath.toString()); expectedSortByDateAscending.add(firstPath.toString()); - + expectedSortByDateDescending.add(firstPath.toString()); expectedSortByDateDescending.add(secondPath.toString()); expectedSortByDateDescending.add(fourthPath.toString()); @@ -111,7 +113,7 @@ public void setUp(@TempDir Path tempDir) throws Exception { wrongOrder.add(thirdPath.toString()); wrongOrder.add(fourthPath.toString()); } - + @Test public void sortByDateAscendingPositiveTest() { List sortedPaths = fileFilterUtils @@ -131,7 +133,7 @@ public void sortByDateAscendingNegativeTest() { .collect(Collectors.toList()); assertNotEquals(sortedPaths, wrongOrder); } - + @Test public void sortByDateDescendingPositiveTest() { List sortedPaths = fileFilterUtils @@ -152,4 +154,43 @@ public void testSortByDateDescendingNegativeTest() { assertNotEquals(sortedPaths, wrongOrder); } } + + @Nested + class filteringTests { + private final List files = new ArrayList<>(); + private final List targetFiles = new ArrayList<>(); + private final Set ignoreFileSet = new HashSet<>(); + + @BeforeEach + public void setUp(@TempDir Path tempDir) throws Exception { + ignoreFileSet.add(".DS_Store"); + ignoreFileSet.add("Thumbs.db"); + + Path firstPath = tempDir.resolve("firstFile.pdf"); + Path secondPath = tempDir.resolve("secondFile.pdf"); + Path thirdPath = tempDir.resolve("thirdFile.pdf"); + Path fourthPath = tempDir.resolve("fourthFile.pdf"); + Path fifthPath = tempDir.resolve(".DS_Store"); + Path sixthPath = tempDir.resolve("Thumbs.db"); + + Files.createFile(firstPath); + Files.createFile(secondPath); + Files.createFile(thirdPath); + Files.createFile(fourthPath); + Files.createFile(fifthPath); + Files.createFile(sixthPath); + + files.add(firstPath); + files.add(secondPath); + files.add(thirdPath); + files.add(fourthPath); + files.add(fifthPath); + files.add(sixthPath); + + targetFiles.add(firstPath); + targetFiles.add(secondPath); + targetFiles.add(thirdPath); + targetFiles.add(fourthPath); + } + } } diff --git a/src/test/java/org/jabref/gui/externalfiles/GitIgnoreFileFilterTest.java b/src/test/java/org/jabref/gui/externalfiles/GitIgnoreFileFilterTest.java new file mode 100644 index 00000000000..2504ffb55b7 --- /dev/null +++ b/src/test/java/org/jabref/gui/externalfiles/GitIgnoreFileFilterTest.java @@ -0,0 +1,50 @@ +package org.jabref.gui.externalfiles; + +import java.nio.file.Files; +import java.nio.file.Path; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class GitIgnoreFileFilterTest { + + @Test + public void checkSimpleGitIgnore(@TempDir Path dir) throws Exception { + Files.writeString(dir.resolve(".gitignore"), """ + *.png + """); + GitIgnoreFileFilter gitIgnoreFileFilter = new GitIgnoreFileFilter(dir); + assertFalse(gitIgnoreFileFilter.accept(dir.resolve("test.png"))); + } + + @Test + public void checkSimpleGitIgnoreWithAllowing(@TempDir Path dir) throws Exception { + Files.writeString(dir.resolve(".gitignore"), """ + !*.png + """); + GitIgnoreFileFilter gitIgnoreFileFilter = new GitIgnoreFileFilter(dir); + assertTrue(gitIgnoreFileFilter.accept(dir.resolve("test.png"))); + } + + @Test + public void checkSimpleGitIgnoreWithOverwritingDefs(@TempDir Path dir) throws Exception { + Files.writeString(dir.resolve(".gitignore"), """ + !*.png + *.png + """); + GitIgnoreFileFilter gitIgnoreFileFilter = new GitIgnoreFileFilter(dir); + assertFalse(gitIgnoreFileFilter.accept(dir.resolve("test.png"))); + } + + @Test + public void checkDirectoryGitIgnore(@TempDir Path dir) throws Exception { + Files.writeString(dir.resolve(".gitignore"), """ + **/*.png + """); + GitIgnoreFileFilter gitIgnoreFileFilter = new GitIgnoreFileFilter(dir); + assertFalse(gitIgnoreFileFilter.accept(dir.resolve("test.png"))); + } +} diff --git a/src/test/java/org/jabref/gui/externalfiles/UnlinkedFilesCrawlerTest.java b/src/test/java/org/jabref/gui/externalfiles/UnlinkedFilesCrawlerTest.java new file mode 100644 index 00000000000..3d53ae3ef59 --- /dev/null +++ b/src/test/java/org/jabref/gui/externalfiles/UnlinkedFilesCrawlerTest.java @@ -0,0 +1,38 @@ +package org.jabref.gui.externalfiles; + +import java.nio.file.Files; +import java.nio.file.Path; + +import org.jabref.gui.util.FileNodeViewModel; +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.preferences.FilePreferences; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class UnlinkedFilesCrawlerTest { + + @Test + public void minimalGitIgnore(@TempDir Path testRoot) throws Exception { + Files.writeString(testRoot.resolve(".gitignore"), """ + *.png + """); + Path subDir = testRoot.resolve("subdir"); + Files.createDirectories(subDir); + Files.createFile(subDir.resolve("test.png")); + + UnlinkedPDFFileFilter unlinkedPDFFileFilter = mock(UnlinkedPDFFileFilter.class); + when(unlinkedPDFFileFilter.accept(any(Path.class))).thenReturn(true); + + UnlinkedFilesCrawler unlinkedFilesCrawler = new UnlinkedFilesCrawler(testRoot, unlinkedPDFFileFilter, DateRange.ALL_TIME, ExternalFileSorter.DEFAULT, mock(BibDatabaseContext.class), mock(FilePreferences.class)); + + FileNodeViewModel fileNodeViewModel = unlinkedFilesCrawler.searchDirectory(testRoot, unlinkedPDFFileFilter); + + assertEquals(new FileNodeViewModel(testRoot), fileNodeViewModel); + } +} From 586d3e40d1f53cdf5f8bec9eba75ba1ca0a7a724 Mon Sep 17 00:00:00 2001 From: Victor Daniel Manfrini Pires Date: Mon, 27 Jun 2022 18:13:20 -0300 Subject: [PATCH 09/13] Fix for Dark theme not readable (#8929) * changed background color entry-selected (#7927) * chaged color summary text select active/inactive (#7927) * resolved threads (#7927) * update CHANGELOG Co-authored-by: euEmica Co-authored-by: Victor Daniel --- CHANGELOG.md | 1 + src/main/java/org/jabref/gui/Base.css | 3 +++ src/main/java/org/jabref/gui/Dark.css | 3 +++ .../java/org/jabref/gui/importer/ImportEntriesDialog.css | 9 +++++++-- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dea34f011c6..7fe899c63bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve ### Changed +- Change in the color of the selection entries and the color of the summary in the Import Entries Dialog. [#7927](https://github.com/JabRef/jabref/issues/7927) - We upgraded to Lucene 9.2 for the fulltext search. Thus, the now created search index cannot be read from older versions of JabRef anylonger. ⚠️ JabRef will recreate the index in a new folder for new files and this will take a long time for a huge library. diff --git a/src/main/java/org/jabref/gui/Base.css b/src/main/java/org/jabref/gui/Base.css index 3a25f9afc25..188182d5151 100644 --- a/src/main/java/org/jabref/gui/Base.css +++ b/src/main/java/org/jabref/gui/Base.css @@ -98,6 +98,9 @@ -jr-drag-target: -jr-purple; -jr-drag-target-hover: derive(-jr-purple, 80%); + -js-summary-text-color: #000000; + -js-summary-text-color-selected: #000000; + /* Here are redefinitions of the default properties of modena. They should in principle all be derived from the above colors. Goal should be to make as few as possible direct color-changes to elements and only do this for diff --git a/src/main/java/org/jabref/gui/Dark.css b/src/main/java/org/jabref/gui/Dark.css index e1de8084646..adaa1cd1a83 100644 --- a/src/main/java/org/jabref/gui/Dark.css +++ b/src/main/java/org/jabref/gui/Dark.css @@ -55,6 +55,9 @@ -jr-drag-target: -jr-accent; -jr-drag-target-hover: -jr-accent; + + -js-summary-text-color: derive(-fx-light-text-color, 70%); + -js-summary-text-color-selected: derive( -fx-dark-text-color, 70%); } #previewBody { diff --git a/src/main/java/org/jabref/gui/importer/ImportEntriesDialog.css b/src/main/java/org/jabref/gui/importer/ImportEntriesDialog.css index 5adbe79d227..03251b85b89 100644 --- a/src/main/java/org/jabref/gui/importer/ImportEntriesDialog.css +++ b/src/main/java/org/jabref/gui/importer/ImportEntriesDialog.css @@ -11,10 +11,15 @@ /*-fx-padding: 0.5em 0em 0.5em 0em;*/ } -.list-cell { +.list-cell .summary > Text { -fx-padding: 0.5em 0 1em 0.5em; + -fx-fill: -js-summary-text-color; } .list-cell:entry-selected { - -fx-background-color: derive(-jr-selected, 60%); + -fx-background-color: derive(-jr-selected, 35%); +} + +.list-cell:entry-selected .summary > Text { + -fx-fill: js-summary-text-color-selected; } From 92b7d7ab86bf5f5c0c3cd0af35edcabd5e4584b4 Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 29 Jun 2022 09:41:24 +0200 Subject: [PATCH 10/13] Show pdf icon for mime type in maintable (#8935) Fixes #8930 --- CHANGELOG.md | 4 +++- .../java/org/jabref/gui/maintable/columns/FileColumn.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fe899c63bd..98b3a24c19e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,8 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve ### Changed -- Change in the color of the selection entries and the color of the summary in the Import Entries Dialog. [#7927](https://github.com/JabRef/jabref/issues/7927) +- The file column in the main table now shows the corresponding defined icon for the linked file [8930](https://github.com/JabRef/jabref/issues/8930). +- We improved the color of the selected entries and the color of the summary in the Import Entries Dialog in the dark theme. [#7927](https://github.com/JabRef/jabref/issues/7927) - We upgraded to Lucene 9.2 for the fulltext search. Thus, the now created search index cannot be read from older versions of JabRef anylonger. ⚠️ JabRef will recreate the index in a new folder for new files and this will take a long time for a huge library. @@ -37,6 +38,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve ### Fixed +- We fixed an issue where linked files with the filetype "application/pdf" in an entry were not shown with the correct PDF-Icon in the main table [8930](https://github.com/JabRef/jabref/issues/8930) - We fixed an issue where "open folder" for linked files did not open the folder and did not select the file unter certain Linux desktop environments [#8679](https://github.com/JabRef/jabref/issues/8679), [#8849](https://github.com/JabRef/jabref/issues/8849) - We fixed an issue where the content of a big shared database library is not shown [#8788](https://github.com/JabRef/jabref/issues/8788) - We fixed the unnecessary horizontal scroll bar in group panel [#8467](https://github.com/JabRef/jabref/issues/8467) diff --git a/src/main/java/org/jabref/gui/maintable/columns/FileColumn.java b/src/main/java/org/jabref/gui/maintable/columns/FileColumn.java index c963ed87b23..c325637af32 100644 --- a/src/main/java/org/jabref/gui/maintable/columns/FileColumn.java +++ b/src/main/java/org/jabref/gui/maintable/columns/FileColumn.java @@ -147,7 +147,7 @@ private Node createFileIcon(List linkedFiles) { if (linkedFiles.size() > 1) { return IconTheme.JabRefIcons.FILE_MULTIPLE.getGraphicNode(); } else if (linkedFiles.size() == 1) { - return externalFileTypes.fromLinkedFile(linkedFiles.get(0), false) + return externalFileTypes.fromLinkedFile(linkedFiles.get(0), true) .map(ExternalFileType::getIcon) .orElse(IconTheme.JabRefIcons.FILE) .getGraphicNode(); From ffe166348a625e7ee36f94dc8123d6f7b9fca46b Mon Sep 17 00:00:00 2001 From: github actions Date: Fri, 1 Jul 2022 02:55:57 +0000 Subject: [PATCH 11/13] Squashed 'buildres/csl/csl-styles/' changes from e740261c4c..3d3573c8db MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 3d3573c8db Update centre-de-recherche-sur-les-civilisations-de-l-asie-orientale.csl (#5988) 5de0fbe8c5 Update society-of-biblical-literature-fullnote-bibliography.csl (#5913) 04b6c7a07f Create revue-internationale-durbanisme.csl (#5974) 4a5bfe2174 Update biological-reviews.csl (#6116) 957b2bc04d Update harvard-cite-them-right-no-et-al.csl (#6115) e836a6cb6b Update harvard-university-of-bath.csl (#6011) b4a8dd7468 Update and rename harvard-cite-them-right.csl to harvard-cite-them-ri… (#6113) a198884a93 Update twentieth-century-music.csl (#6110) 81c161937a Update archaeonautica.csl (#5928) fc46f1d5f0 Bump actions/cache from 2 to 3 (#6112) fab57ed46a Bump actions/checkout from 2 to 3 (#6111) 519d594f1a [don't merge] chore: Included githubactions in the dependabot config (#6109) a8aa8984f5 Update universidade-estadual-de-alagoas-uneal-abnt.csl (#5915) 6191640505 Update isnad-dipnotlu.csl (#5909) d65a6ac3cb Update isnad-metinici.csl (#5910) 830d3379ab Update technische-universitat-dresden-linguistik.csl (#6097) 81adc43b03 Update american-society-for-horticultural-science.csl (#6089) b7676235c9 Create south-african-law-journal.csl (#6092) 215e1e9e3e Create journal-of-lithic-studies.csl (#6080) 0740f8cf11 Create eunomia-revista-en-cultura-de-la-legalidad.csl (#6095) f93c809060 Create endocrine-journal.csl (#6086) 3fdeb51ded Revert "chore: Set permissions for GitHub actions (#6096)" (#6108) 35ebd1e265 chore: Set permissions for GitHub actions (#6096) 1cb875893e Create journal-fur-medienlinguistik (#6100) f4b5f7fbbf Update unified-style-sheet-for-linguistics.csl (#6098) c3f856a260 Update advanced-materials.csl (#6103) d1e7576807 Bump diffy from 3.4.0 to 3.4.2 (#6107) 9e5e7ab030 Fix Dev Dynamics (#6099) 72345207d6 Add CSL style for the journal Developmental Dynamics (#6093) ba8db055a2 Create independent style for vox-sanguinis.csl (#6085) 845dee0a3b Create meta.csl (#6088) 684bc3ab52 Update universite-du-quebec-a-montreal.csl (#6087) 3602c18c16 Up-date & re-title pour-reussir/dionne (#6043) 0cc6e825d0 Fix Mainz Geography cfc4cec596 Add DOI and fix printing author names in Population and Économie et statistique (#6079) 14e8b1d5c0 Update journal-of-neuroimaging.csl (#6084) 2c0e1f1772 Update isnad-dipnotlu.csl (#6081) 02fdb9bbf5 Merge pull request #6082 from denismaier/patch-ube-muwi-note 93093784c9 removes default-locale git-subtree-dir: buildres/csl/csl-styles git-subtree-split: 3d3573c8dbd71679d241b74ba3f64033c9a63713 --- .github/dependabot.yml | 6 + .github/workflows/merge.yaml | 8 +- .github/workflows/sheldon.yaml | 8 +- Gemfile.lock | 2 +- advanced-materials.csl | 10 +- ...ican-society-for-horticultural-science.csl | 48 +- archaeonautica.csl | 13 +- biological-reviews.csl | 6 +- ...-les-civilisations-de-l-asie-orientale.csl | 29 +- dependent/advanced-theory-and-simulations.csl | 15 + dependent/vox-sanguinis.csl | 16 - developmental-dynamics.csl | 280 +++++ economie-et-statistique.csl | 197 +-- endocrine-journal.csl | 126 ++ ...mia-revista-en-cultura-de-la-legalidad.csl | 197 +++ harvard-cite-them-right-11th-edition.csl | 318 +++++ harvard-cite-them-right-no-et-al.csl | 15 +- harvard-cite-them-right.csl | 13 +- harvard-university-of-bath.csl | 1117 +++++++++-------- isnad-dipnotlu.csl | 41 +- isnad-metinici.csl | 27 +- journal-fur-medienlinguistik.csl | 206 +++ journal-of-lithic-studies.csl | 193 +++ journal-of-neuroimaging.csl | 4 +- meta.csl | 938 ++++++++++++++ population.csl | 197 +-- pour-reussir-note.csl | 1012 ++++++++++----- revue-internationale-durbanisme.csl | 183 +++ ...lical-literature-fullnote-bibliography.csl | 68 +- south-african-law-journal.csl | 519 ++++++++ technische-universitat-dresden-linguistik.csl | 40 +- twentieth-century-music.csl | 9 +- unified-style-sheet-for-linguistics.csl | 26 +- universidade-estadual-de-alagoas-abnt.csl | 45 +- ...rn-institut-fur-musikwissenschaft-note.csl | 2 +- universitat-mainz-geographisches-institut.csl | 2 +- universite-du-quebec-a-montreal.csl | 4 +- vox-sanguinis.csl | 178 +++ 38 files changed, 4892 insertions(+), 1226 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 dependent/advanced-theory-and-simulations.csl delete mode 100644 dependent/vox-sanguinis.csl create mode 100644 developmental-dynamics.csl create mode 100644 endocrine-journal.csl create mode 100644 eunomia-revista-en-cultura-de-la-legalidad.csl create mode 100644 harvard-cite-them-right-11th-edition.csl create mode 100644 journal-fur-medienlinguistik.csl create mode 100644 journal-of-lithic-studies.csl create mode 100644 meta.csl create mode 100644 revue-internationale-durbanisme.csl create mode 100644 south-african-law-journal.csl create mode 100644 vox-sanguinis.csl diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000..5ace4600a1f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/merge.yaml b/.github/workflows/merge.yaml index 4c9a02df776..0a0d9db955e 100644 --- a/.github/workflows/merge.yaml +++ b/.github/workflows/merge.yaml @@ -19,9 +19,9 @@ jobs: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" DISTRIBUTION_UPDATER_TOKEN: "${{ secrets.DISTRIBUTION_UPDATER_TOKEN }}" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 if: github.event_name == 'push' - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 if: github.event_name == 'workflow_dispatch' with: fetch-depth: 0 @@ -30,7 +30,7 @@ jobs: id: release run: echo ::set-output name=branch::v1.0.2 - name: Checkout release branch - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: ref: ${{ steps.release.outputs.branch }} path: './release' @@ -63,7 +63,7 @@ jobs: ruby-version: 3.0.2 - name: but use cache to speed that up if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && (steps.update.outputs.updated == 'true' || steps.update.outputs.deleted == 'true')) - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: vendor/bundle key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} diff --git a/.github/workflows/sheldon.yaml b/.github/workflows/sheldon.yaml index eef83fd496c..9bf525949f1 100644 --- a/.github/workflows/sheldon.yaml +++ b/.github/workflows/sheldon.yaml @@ -15,17 +15,17 @@ jobs: # labels to a PR # https://securitylab.github.com/research/github-actions-preventing-pwn-requests - name: Checkout repo for OWNER TEST - uses: actions/checkout@v2 + uses: actions/checkout@v3 if: contains(github.event.pull_request.labels.*.name, 'safe to test') with: ref: ${{ github.event.pull_request.head.ref }} # otherwise, checkout the current master, and the pr to the subdirectory 'pull-request' - name: Checkout base repo for pull-request test - uses: actions/checkout@v2 + uses: actions/checkout@v3 if: "! contains(github.event.pull_request.labels.*.name, 'safe to test')" - name: Checkout pull-request - uses: actions/checkout@v2 + uses: actions/checkout@v3 if: "! contains(github.event.pull_request.labels.*.name, 'safe to test')" with: repository: ${{ github.event.pull_request.head.repo.full_name }} @@ -54,7 +54,7 @@ jobs: with: ruby-version: 3.0.2 - name: but use cache to speed that up - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: vendor/bundle key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} diff --git a/Gemfile.lock b/Gemfile.lock index e7c7f102fa9..dde35577b7f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -33,7 +33,7 @@ GEM csl-styles (2.0.0) csl (~> 2.0) diff-lcs (1.5.0) - diffy (3.4.0) + diffy (3.4.2) dotenv (2.7.6) erubis (2.7.0) faraday (1.8.0) diff --git a/advanced-materials.csl b/advanced-materials.csl index 621c6d9d34b..8ade35d119e 100644 --- a/advanced-materials.csl +++ b/advanced-materials.csl @@ -5,7 +5,7 @@ http://www.zotero.org/styles/advanced-materials - + Jimmy Lawrence jimmymisc@gmail.com @@ -16,13 +16,13 @@ 0935-9648 1521-4095 A style for Wiley's Advanced Materials - 2012-09-27T22:06:38+00:00 + 2022-06-22T14:43:19+00:00 This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License - - - - - - - - - + @@ -106,10 +101,6 @@ - - - - @@ -173,13 +164,13 @@ + + + - - - @@ -188,15 +179,21 @@ + + + + + + - + - - + + @@ -217,7 +214,6 @@ - diff --git a/archaeonautica.csl b/archaeonautica.csl index 1340f1c0021..9c1e0ff16d5 100644 --- a/archaeonautica.csl +++ b/archaeonautica.csl @@ -16,8 +16,7 @@ 0154-1854 2117-6973 - Style conçu pour la revue Archaeonautica. L’archéologie maritime et navale de la - préhistoire à l’époque contemporaine. Centre Camille Jullian, CNRS + Style conçu pour la revue Archaeonautica. L’archéologie maritime et navale de la préhistoire à l’époque contemporaine. Centre Camille Jullian, CNRS 2020-05-10T04:06:42+00:00 This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License @@ -80,7 +79,7 @@ - - + diff --git a/meta.csl b/meta.csl new file mode 100644 index 00000000000..843a260b514 --- /dev/null +++ b/meta.csl @@ -0,0 +1,938 @@ + + diff --git a/population.csl b/population.csl index 4a650687147..3e75caa2912 100644 --- a/population.csl +++ b/population.csl @@ -1,5 +1,5 @@ - diff --git a/pour-reussir-note.csl b/pour-reussir-note.csl index 884c78ffe94..4cc02a54b98 100644 --- a/pour-reussir-note.csl +++ b/pour-reussir-note.csl @@ -1,19 +1,25 @@ - diff --git a/society-of-biblical-literature-fullnote-bibliography.csl b/society-of-biblical-literature-fullnote-bibliography.csl index 3078db2f8e0..99eaa04018a 100644 --- a/society-of-biblical-literature-fullnote-bibliography.csl +++ b/society-of-biblical-literature-fullnote-bibliography.csl @@ -33,7 +33,7 @@ Society of Biblical Literature format with full notes and bibliography - 2022-05-27T18:39:17+00:00 + 2022-06-29T13:58:51+00:00 This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License @@ -113,11 +113,11 @@ - + @@ -382,7 +382,7 @@ - + @@ -675,7 +675,16 @@ - + + + + + + + + + + @@ -791,7 +800,15 @@ @@ -841,9 +858,9 @@ - + - + @@ -926,11 +943,10 @@ - + - @@ -991,12 +1007,15 @@ + - - - + - + + + + + @@ -1011,12 +1030,15 @@ + - - - + - + + + + + @@ -1072,14 +1094,16 @@ - - + + + + - + @@ -1115,6 +1139,7 @@ + @@ -1138,7 +1163,6 @@ - @@ -1168,6 +1192,7 @@ + @@ -1188,7 +1213,6 @@ - diff --git a/south-african-law-journal.csl b/south-african-law-journal.csl new file mode 100644 index 00000000000..66e89063c64 --- /dev/null +++ b/south-african-law-journal.csl @@ -0,0 +1,519 @@ + + diff --git a/technische-universitat-dresden-linguistik.csl b/technische-universitat-dresden-linguistik.csl index 19301d851e8..beb06a7e4b7 100644 --- a/technische-universitat-dresden-linguistik.csl +++ b/technische-universitat-dresden-linguistik.csl @@ -6,7 +6,7 @@ http://www.zotero.org/styles/technische-universitat-dresden-linguistik - + Simon Meier-Vieracker https://tu-dresden.de/gsw/slk/germanistik/al @@ -16,7 +16,7 @@ Zitierstil entsprechend den Vorgaben der linguistischen Professuren am Institut für Germanistik der Technischen Universität Dresden. Der Stil orientiert sich an den Richtlinien von 'Deutsche Sprache: Zeitschrift für Theorie Praxis Dokumentation', hg. vom IDS Mannheim - 2021-07-19T08:34:39+00:00 + 2022-06-23T08:36:06+00:00 This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License @@ -51,14 +51,14 @@ - + @@ -81,7 +81,7 @@ - + @@ -113,6 +113,28 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -133,12 +155,11 @@ - + - @@ -150,17 +171,16 @@ - + - - + diff --git a/twentieth-century-music.csl b/twentieth-century-music.csl index b137c2c870c..2565ea626d3 100644 --- a/twentieth-century-music.csl +++ b/twentieth-century-music.csl @@ -6,6 +6,7 @@ + Patrick O'Brien @@ -14,7 +15,7 @@ 1478-5722 1478-5730 - 2018-01-16T09:37:56+00:00 + 2022-06-26T15:04:55+00:00 This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License @@ -410,7 +411,11 @@ -