mirror of
https://github.com/ilri/cgspace-java-helpers.git
synced 2025-07-05 22:11:45 +02:00
Compare commits
23 Commits
f0754ab419
...
v6.2
Author | SHA1 | Date | |
---|---|---|---|
c05a2e4f96
|
|||
cf2af393c0
|
|||
1f6ba4af67
|
|||
5ceaebaeae
|
|||
f3dcc6e261
|
|||
3eddbc3e22
|
|||
dbf59f784c
|
|||
0ffa4c8d37
|
|||
970d0c074e
|
|||
6b2b899957
|
|||
dfaa234a90
|
|||
f46e81b8cd
|
|||
dbd8721579
|
|||
a234b39064
|
|||
80a336f94d
|
|||
5ebf4930cf
|
|||
8e01595cc1
|
|||
8b3aac610d
|
|||
c2d7535d01
|
|||
b396fba043
|
|||
38a9cc5188
|
|||
16db38967b
|
|||
2604dc3cce
|
12
.github/workflows/maven.yml
vendored
12
.github/workflows/maven.yml
vendored
@ -12,13 +12,15 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 8
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 1.8
|
||||
java-version: 8
|
||||
distribution: 'temurin'
|
||||
cache: 'maven'
|
||||
- name: Build with Maven
|
||||
run: mvn -B package --file pom.xml
|
||||
|
10
CHANGELOG.md
10
CHANGELOG.md
@ -4,12 +4,20 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
## [6.2] - 2023-02-20
|
||||
### Updated
|
||||
- `iso_3166-1.json` from iso-codes 4.12.0, which updates the name for TR to "Türkiye"
|
||||
|
||||
## [6.1] - 2022-10-31
|
||||
### Updated
|
||||
- Update dependencies in `pom.xml`
|
||||
- `iso_3166-1.json` from iso-codes 4.11.0
|
||||
|
||||
### Changed
|
||||
- Java compiler and target from JDK 7 to JDK 8
|
||||
|
||||
### Added
|
||||
- New `FixLowQualityThumbnails` script to detect and remove more low-quality thumbnails
|
||||
|
||||
### Fixed
|
||||
- `FixJpgJpgThumbnails` and `FixLowQualityThumbnails` scripts not commiting changes when operating on a site, community, or collection
|
||||
|
16
README.md
16
README.md
@ -5,7 +5,7 @@ DSpace curation tasks and other Java-based helpers used on the [CGSpace](https:/
|
||||
- **FixJpgJpgThumbnails**: fix low-quality ".jpg.jpg" thumbnails by replacing them with their originals
|
||||
- **FixLowQualityThumbnails**: remove low-quality thumbnails when PDF bitstreams are present
|
||||
|
||||
Tested on DSpace 6.3. Read more about the [DSpace curation system](https://wiki.lyrasis.org/display/DSDOC5x/Curation+System).
|
||||
Tested on DSpace 6.3. Read more about the [DSpace curation system](https://wiki.lyrasis.org/display/DSDOC6x/Curation+System).
|
||||
|
||||
## Build and Install
|
||||
|
||||
@ -16,7 +16,7 @@ To use these curation tasks in a DSpace project add the following dependency to
|
||||
<dependency>
|
||||
<groupId>io.github.ilri.cgspace</groupId>
|
||||
<artifactId>cgspace-java-helpers</artifactId>
|
||||
<version>6.1-SNAPSHOT</version>
|
||||
<version>6.2</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
@ -32,7 +32,7 @@ $ mvn package
|
||||
Copy the resulting jar to the DSpace `lib` directory:
|
||||
|
||||
```console
|
||||
$ cp target/cgspace-java-helpers-6.1-SNAPSHOT.jar ~/dspace/lib/
|
||||
$ cp target/cgspace-java-helpers-6.2.jar ~/dspace/lib/
|
||||
```
|
||||
|
||||
## Configuration
|
||||
@ -44,6 +44,8 @@ Please refer to the appropriate README.md file:
|
||||
## TODO
|
||||
|
||||
- Add a curation task to normalize DOIs to "https://doi.org" format
|
||||
- Migrate from maven-deploy-plugin to nexus-staging-maven-plugin, see: https://central.sonatype.org/publish/publish-maven/#nexus-staging-maven-plugin-for-deployment-and-release
|
||||
- Stop using oss-parent, see: https://central.sonatype.org/publish/publish-maven/#create-a-ticket-with-sonatype
|
||||
|
||||
## Notes
|
||||
This project was initially created according to the [Maven Getting Started Guide](https://maven.apache.org/guides/getting-started/):
|
||||
@ -52,6 +54,14 @@ This project was initially created according to the [Maven Getting Started Guide
|
||||
$ mvn -B archetype:generate -DgroupId=io.github.ilri.cgspace -DartifactId=cgspace-java-helpers -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4
|
||||
```
|
||||
|
||||
To deploy a new `-SNAPSHOT` release to Maven Central (make sure OSSHRH credentials are in `~/.m2/settings.xml`):
|
||||
|
||||
```console
|
||||
$ mvn clean deploy
|
||||
```
|
||||
|
||||
See: <a href="https://central.sonatype.org/publish/publish-maven/#performing-a-snapshot-deployment">Performing a Snapshot Deployment</a>
|
||||
|
||||
## License
|
||||
This work is licensed under the [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html).
|
||||
|
||||
|
4
pom.xml
4
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>io.github.ilri.cgspace</groupId>
|
||||
<artifactId>cgspace-java-helpers</artifactId>
|
||||
<version>6.1-SNAPSHOT</version>
|
||||
<version>6.2</version>
|
||||
|
||||
<name>cgspace-java-helpers</name>
|
||||
<url>https://github.com/ilri/cgspace-java-helpers</url>
|
||||
@ -94,7 +94,7 @@
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>3.0.0</version>
|
||||
</plugin>
|
||||
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
||||
<plugin>
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
* Copyright (C) 2020 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package io.github.ilri.cgspace.ctasks;
|
||||
|
||||
@ -10,4 +10,4 @@ import java.util.List;
|
||||
|
||||
public class CGSpaceCountriesVocabulary extends CountriesVocabulary {
|
||||
List<Country> countries;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
* Copyright (C) 2020 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package io.github.ilri.cgspace.ctasks;
|
||||
|
||||
@ -11,26 +11,29 @@ import javax.annotation.Nullable;
|
||||
public class CountriesVocabulary {
|
||||
|
||||
class Country {
|
||||
private String name; //required
|
||||
private String common_name; //optional
|
||||
private String official_name; //optional
|
||||
private String cgspace_name; //optional
|
||||
private String numeric; //required Hmmmm need to cast this...
|
||||
private String alpha_2; //required
|
||||
private String alpha_3; //required
|
||||
private String name; // required
|
||||
private String common_name; // optional
|
||||
private String official_name; // optional
|
||||
private String cgspace_name; // optional
|
||||
private String numeric; // required Hmmmm need to cast this...
|
||||
private String alpha_2; // required
|
||||
private String alpha_3; // required
|
||||
|
||||
public Country(String name,
|
||||
@Nullable String common_name,
|
||||
@Nullable String official_name,
|
||||
@Nullable String cgspace_name,
|
||||
String numeric,
|
||||
String alpha_2,
|
||||
String alpha_3) {
|
||||
public Country(
|
||||
String name,
|
||||
@Nullable String common_name,
|
||||
@Nullable String official_name,
|
||||
@Nullable String cgspace_name,
|
||||
String numeric,
|
||||
String alpha_2,
|
||||
String alpha_3) {
|
||||
this.name = name;
|
||||
this.common_name = common_name;
|
||||
this.official_name = official_name;
|
||||
this.cgspace_name = cgspace_name;
|
||||
this.numeric = numeric; // fuuuuu this is a string and we can't cast to Integer because some values are zeropadded like "004"
|
||||
this.numeric =
|
||||
numeric; // fuuuuu this is a string and we can't cast to Integer because some
|
||||
// values are zeropadded like "004"
|
||||
this.alpha_2 = alpha_2;
|
||||
this.alpha_3 = alpha_3;
|
||||
}
|
||||
@ -63,4 +66,4 @@ public class CountriesVocabulary {
|
||||
return cgspace_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
* Copyright (C) 2020 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package io.github.ilri.cgspace.ctasks;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
@ -23,11 +24,11 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CountryCodeTagger extends AbstractCurationTask
|
||||
{
|
||||
public class CountryCodeTagger extends AbstractCurationTask {
|
||||
public class CountryCodeTaggerConfig {
|
||||
private final String isocodesJsonPath = "/io/github/ilri/cgspace/ctasks/iso_3166-1.json";
|
||||
private final String cgspaceCountriesJsonPath = "/io/github/ilri/cgspace/ctasks/cgspace-countries.json";
|
||||
private final String cgspaceCountriesJsonPath =
|
||||
"/io/github/ilri/cgspace/ctasks/cgspace-countries.json";
|
||||
private final String iso3166Field = taskProperty("iso3166.field");
|
||||
private final String iso3166Alpha2Field = taskProperty("iso3166-alpha2.field");
|
||||
private final boolean forceupdate = taskBooleanProperty("forceupdate", false);
|
||||
@ -57,17 +58,15 @@ public class CountryCodeTagger extends AbstractCurationTask
|
||||
}
|
||||
|
||||
@Override
|
||||
public int perform(DSpaceObject dso) throws IOException
|
||||
{
|
||||
public int perform(DSpaceObject dso) throws IOException {
|
||||
// gotta define this here so we can access it after the if context...
|
||||
CountryCodeTaggerResult alpha2Result = new CountryCodeTaggerResult();
|
||||
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
if (dso.getType() == Constants.ITEM) {
|
||||
// Load configuration
|
||||
CountryCodeTaggerConfig config = new CountryCodeTaggerConfig();
|
||||
|
||||
Item item = (Item)dso;
|
||||
Item item = (Item) dso;
|
||||
|
||||
try {
|
||||
alpha2Result = performAlpha2(item, config);
|
||||
@ -77,16 +76,18 @@ public class CountryCodeTagger extends AbstractCurationTask
|
||||
|
||||
setResult(alpha2Result.getResult());
|
||||
report(alpha2Result.getResult());
|
||||
}
|
||||
}
|
||||
|
||||
return alpha2Result.getStatus();
|
||||
return alpha2Result.getStatus();
|
||||
}
|
||||
|
||||
public CountryCodeTaggerResult performAlpha2(Item item, CountryCodeTaggerConfig config) throws IOException, SQLException {
|
||||
public CountryCodeTaggerResult performAlpha2(Item item, CountryCodeTaggerConfig config)
|
||||
throws IOException, SQLException {
|
||||
CountryCodeTaggerResult alpha2Result = new CountryCodeTaggerResult();
|
||||
String itemHandle = item.getHandle();
|
||||
|
||||
List<MetadataValue> itemCountries = itemService.getMetadataByMetadataString(item, config.iso3166Field);
|
||||
List<MetadataValue> itemCountries =
|
||||
itemService.getMetadataByMetadataString(item, config.iso3166Field);
|
||||
|
||||
// skip items that don't have country metadata
|
||||
if (itemCountries.size() == 0) {
|
||||
@ -95,36 +96,60 @@ public class CountryCodeTagger extends AbstractCurationTask
|
||||
} else {
|
||||
Gson gson = new Gson();
|
||||
|
||||
// TODO: convert to try: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream(config.isocodesJsonPath)));
|
||||
ISO3166CountriesVocabulary isocodesCountriesJson = gson.fromJson(reader, ISO3166CountriesVocabulary.class);
|
||||
// TODO: convert to try:
|
||||
// https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
|
||||
BufferedReader reader =
|
||||
new BufferedReader(
|
||||
new InputStreamReader(
|
||||
this.getClass().getResourceAsStream(config.isocodesJsonPath)));
|
||||
ISO3166CountriesVocabulary isocodesCountriesJson =
|
||||
gson.fromJson(reader, ISO3166CountriesVocabulary.class);
|
||||
reader.close();
|
||||
|
||||
reader = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream(config.cgspaceCountriesJsonPath)));
|
||||
CGSpaceCountriesVocabulary cgspaceCountriesJson = gson.fromJson(reader, CGSpaceCountriesVocabulary.class);
|
||||
reader =
|
||||
new BufferedReader(
|
||||
new InputStreamReader(
|
||||
this.getClass()
|
||||
.getResourceAsStream(config.cgspaceCountriesJsonPath)));
|
||||
CGSpaceCountriesVocabulary cgspaceCountriesJson =
|
||||
gson.fromJson(reader, CGSpaceCountriesVocabulary.class);
|
||||
reader.close();
|
||||
|
||||
// split the alpha2 country code field into schema, element, and qualifier so we can use it with item.addMetadata()
|
||||
// split the alpha2 country code field into schema, element, and qualifier so we can use
|
||||
// it with item.addMetadata()
|
||||
String[] iso3166Alpha2FieldParts = config.iso3166Alpha2Field.split("\\.");
|
||||
|
||||
if (config.forceupdate) {
|
||||
itemService.clearMetadata(Curator.curationContext(), item, iso3166Alpha2FieldParts[0], iso3166Alpha2FieldParts[1], iso3166Alpha2FieldParts[2], Item.ANY);
|
||||
itemService.clearMetadata(
|
||||
Curator.curationContext(),
|
||||
item,
|
||||
iso3166Alpha2FieldParts[0],
|
||||
iso3166Alpha2FieldParts[1],
|
||||
iso3166Alpha2FieldParts[2],
|
||||
Item.ANY);
|
||||
}
|
||||
|
||||
// check the item's country codes, if any
|
||||
List<MetadataValue> itemAlpha2CountryCodes = itemService.getMetadataByMetadataString(item, config.iso3166Alpha2Field);
|
||||
List<MetadataValue> itemAlpha2CountryCodes =
|
||||
itemService.getMetadataByMetadataString(item, config.iso3166Alpha2Field);
|
||||
|
||||
if (itemAlpha2CountryCodes.size() == 0) {
|
||||
List<String> newAlpha2Codes = new ArrayList<String>();
|
||||
for (MetadataValue itemCountry : itemCountries) {
|
||||
//check ISO 3166-1 countries
|
||||
// check ISO 3166-1 countries
|
||||
for (CountriesVocabulary.Country country : isocodesCountriesJson.countries) {
|
||||
if (itemCountry.getValue().equalsIgnoreCase(country.getName()) || itemCountry.getValue().equalsIgnoreCase(country.get_official_name()) || itemCountry.getValue().equalsIgnoreCase(country.get_common_name())) {
|
||||
if (itemCountry.getValue().equalsIgnoreCase(country.getName())
|
||||
|| itemCountry
|
||||
.getValue()
|
||||
.equalsIgnoreCase(country.get_official_name())
|
||||
|| itemCountry
|
||||
.getValue()
|
||||
.equalsIgnoreCase(country.get_common_name())) {
|
||||
newAlpha2Codes.add(country.getAlpha_2());
|
||||
}
|
||||
}
|
||||
|
||||
//check CGSpace countries
|
||||
// check CGSpace countries
|
||||
for (CountriesVocabulary.Country country : cgspaceCountriesJson.countries) {
|
||||
if (itemCountry.getValue().equalsIgnoreCase(country.getCgspace_name())) {
|
||||
newAlpha2Codes.add(country.getAlpha_2());
|
||||
@ -134,7 +159,14 @@ public class CountryCodeTagger extends AbstractCurationTask
|
||||
|
||||
if (newAlpha2Codes.size() > 0) {
|
||||
try {
|
||||
itemService.addMetadata(Curator.curationContext(), item, iso3166Alpha2FieldParts[0], iso3166Alpha2FieldParts[1], iso3166Alpha2FieldParts[2], "en_US", newAlpha2Codes);
|
||||
itemService.addMetadata(
|
||||
Curator.curationContext(),
|
||||
item,
|
||||
iso3166Alpha2FieldParts[0],
|
||||
iso3166Alpha2FieldParts[1],
|
||||
iso3166Alpha2FieldParts[2],
|
||||
"en_US",
|
||||
newAlpha2Codes);
|
||||
itemService.update(Curator.curationContext(), item);
|
||||
} catch (SQLException | AuthorizeException sqle) {
|
||||
config.log.debug(sqle.getMessage());
|
||||
@ -142,7 +174,11 @@ public class CountryCodeTagger extends AbstractCurationTask
|
||||
alpha2Result.setStatus(Curator.CURATE_ERROR);
|
||||
}
|
||||
|
||||
alpha2Result.setResult(itemHandle + ": added " + newAlpha2Codes.size() + " alpha2 country code(s)");
|
||||
alpha2Result.setResult(
|
||||
itemHandle
|
||||
+ ": added "
|
||||
+ newAlpha2Codes.size()
|
||||
+ " alpha2 country code(s)");
|
||||
} else {
|
||||
alpha2Result.setResult(itemHandle + ": no matching countries found");
|
||||
}
|
||||
@ -155,4 +191,4 @@ public class CountryCodeTagger extends AbstractCurationTask
|
||||
|
||||
return alpha2Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
* Copyright (C) 2020 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package io.github.ilri.cgspace.ctasks;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ISO3166CountriesVocabulary extends CountriesVocabulary {
|
||||
// support reading iso_3166-1.json from Debian's iso-codes package using SerializedName since our class needs to match the JSON exactly
|
||||
@SerializedName("3166-1") List<Country> countries;
|
||||
}
|
||||
// support reading iso_3166-1.json from Debian's iso-codes package using SerializedName since
|
||||
// our class needs to match the JSON exactly
|
||||
@SerializedName("3166-1")
|
||||
List<Country> countries;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ To use these curation tasks in a DSpace project add the following dependency to
|
||||
<dependency>
|
||||
<groupId>io.github.ilri.cgspace</groupId>
|
||||
<artifactId>cgspace-java-helpers</artifactId>
|
||||
<version>6.1-SNAPSHOT</version>
|
||||
<version>6.2</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
@ -30,7 +30,7 @@ $ mvn package
|
||||
Copy the resulting jar to the DSpace `lib` directory:
|
||||
|
||||
```
|
||||
$ cp target/cgspace-java-helpers-6.1-SNAPSHOT.jar ~/dspace/lib/
|
||||
$ cp target/cgspace-java-helpers-6.2.jar ~/dspace/lib/
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
@ -1,21 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
* Copyright (C) 2020 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package io.github.ilri.cgspace.scripts;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.*;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataValue;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.BundleService;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.handle.factory.HandleServiceFactory;
|
||||
import org.dspace.handle.service.HandleService;
|
||||
import org.dspace.content.service.BundleService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
@ -29,118 +35,142 @@ import java.util.List;
|
||||
* @since 5.1
|
||||
*/
|
||||
public class FixJpgJpgThumbnails {
|
||||
//note: static members belong to the class itself, not any one instance
|
||||
public static ItemService itemService = ContentServiceFactory.getInstance().getItemService();
|
||||
public static HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
|
||||
public static BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
|
||||
// note: static members belong to the class itself, not any one instance
|
||||
public static ItemService itemService = ContentServiceFactory.getInstance().getItemService();
|
||||
public static HandleService handleService =
|
||||
HandleServiceFactory.getInstance().getHandleService();
|
||||
public static BundleService bundleService =
|
||||
ContentServiceFactory.getInstance().getBundleService();
|
||||
|
||||
public static void main(String[] args) {
|
||||
String parentHandle = null;
|
||||
if (args.length >= 1) {
|
||||
parentHandle = args[0];
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
String parentHandle = null;
|
||||
if (args.length >= 1) {
|
||||
parentHandle = args[0];
|
||||
}
|
||||
|
||||
Context context = null;
|
||||
try {
|
||||
context = new Context();
|
||||
context.turnOffAuthorisationSystem();
|
||||
Context context = null;
|
||||
try {
|
||||
context = new Context();
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
if (StringUtils.isBlank(parentHandle)) {
|
||||
process(context, itemService.findAll(context));
|
||||
} else {
|
||||
DSpaceObject parent = handleService.resolveToObject(context, parentHandle);
|
||||
if (parent != null) {
|
||||
switch (parent.getType()) {
|
||||
case Constants.COLLECTION:
|
||||
process(context, itemService.findByCollection(context, (Collection) parent));
|
||||
break;
|
||||
case Constants.COMMUNITY:
|
||||
List<Collection> collections = ((Community) parent).getCollections();
|
||||
for (Collection collection : collections) {
|
||||
process(context, itemService.findAllByCollection(context, collection));
|
||||
}
|
||||
break;
|
||||
case Constants.SITE:
|
||||
process(context, itemService.findAll(context));
|
||||
break;
|
||||
case Constants.ITEM:
|
||||
processItem(context, (Item) parent);
|
||||
context.commit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException | AuthorizeException | IOException e) {
|
||||
e.printStackTrace(System.err);
|
||||
} finally {
|
||||
if (context != null && context.isValid()) {
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isBlank(parentHandle)) {
|
||||
process(context, itemService.findAll(context));
|
||||
} else {
|
||||
DSpaceObject parent = handleService.resolveToObject(context, parentHandle);
|
||||
if (parent != null) {
|
||||
switch (parent.getType()) {
|
||||
case Constants.SITE:
|
||||
process(context, itemService.findAll(context));
|
||||
context.commit();
|
||||
break;
|
||||
case Constants.COMMUNITY:
|
||||
List<Collection> collections = ((Community) parent).getCollections();
|
||||
for (Collection collection : collections) {
|
||||
process(
|
||||
context,
|
||||
itemService.findAllByCollection(context, collection));
|
||||
}
|
||||
context.commit();
|
||||
break;
|
||||
case Constants.COLLECTION:
|
||||
process(
|
||||
context,
|
||||
itemService.findByCollection(context, (Collection) parent));
|
||||
context.commit();
|
||||
break;
|
||||
case Constants.ITEM:
|
||||
processItem(context, (Item) parent);
|
||||
context.commit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException | AuthorizeException | IOException e) {
|
||||
e.printStackTrace(System.err);
|
||||
} finally {
|
||||
if (context != null && context.isValid()) {
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void process(Context context, Iterator<Item> items) throws SQLException, IOException, AuthorizeException {
|
||||
while (items.hasNext()) {
|
||||
Item item = items.next();
|
||||
processItem(context, item);
|
||||
itemService.update(context, item);
|
||||
}
|
||||
}
|
||||
private static void process(Context context, Iterator<Item> items)
|
||||
throws SQLException, IOException, AuthorizeException {
|
||||
while (items.hasNext()) {
|
||||
Item item = items.next();
|
||||
processItem(context, item);
|
||||
itemService.update(context, item);
|
||||
}
|
||||
}
|
||||
|
||||
private static void processItem(Context context, Item item) throws SQLException, AuthorizeException, IOException {
|
||||
// Some bitstreams like Infographics are large JPGs and put in the ORIGINAL bundle on purpose so we shouldn't
|
||||
// swap them.
|
||||
List<MetadataValue> itemTypes = itemService.getMetadataByMetadataString(item, "dcterms.type");
|
||||
boolean itemHasInfographic = false;
|
||||
for (MetadataValue itemType: itemTypes) {
|
||||
if (itemType.getValue().equals("Infographic")) {
|
||||
itemHasInfographic = true;
|
||||
}
|
||||
}
|
||||
private static void processItem(Context context, Item item)
|
||||
throws SQLException, AuthorizeException, IOException {
|
||||
// Some bitstreams like Infographics and Maps are large JPEGs and put in the ORIGINAL bundle
|
||||
// on purpose so we shouldn't
|
||||
// swap them.
|
||||
List<MetadataValue> itemTypes =
|
||||
itemService.getMetadataByMetadataString(item, "dcterms.type");
|
||||
for (MetadataValue itemType : itemTypes) {
|
||||
if (itemType.getValue().equals("Infographic") || itemType.getValue().equals("Map")) {
|
||||
System.out.println(
|
||||
item.getHandle() + ": item has an Infographic or Map, skipping.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
List<Bundle> thumbnailBundles = item.getBundles("THUMBNAIL");
|
||||
for (Bundle thumbnailBundle : thumbnailBundles) {
|
||||
List<Bitstream> thumbnailBundleBitstreams = thumbnailBundle.getBitstreams();
|
||||
for (Bitstream thumbnailBitstream : thumbnailBundleBitstreams) {
|
||||
String thumbnailName = thumbnailBitstream.getName();
|
||||
List<Bundle> thumbnailBundles = item.getBundles("THUMBNAIL");
|
||||
for (Bundle thumbnailBundle : thumbnailBundles) {
|
||||
List<Bitstream> thumbnailBundleBitstreams = thumbnailBundle.getBitstreams();
|
||||
for (Bitstream thumbnailBitstream : thumbnailBundleBitstreams) {
|
||||
String thumbnailName = thumbnailBitstream.getName();
|
||||
String thumbnailDescription = thumbnailBitstream.getDescription();
|
||||
|
||||
if (thumbnailName.toLowerCase().contains(".jpg.jpg")) {
|
||||
List<Bundle> originalBundles = item.getBundles("ORIGINAL");
|
||||
for (Bundle originalBundle : originalBundles) {
|
||||
List<Bitstream> originalBundleBitstreams = originalBundle.getBitstreams();
|
||||
// There is no point continuing if the thumbnail's description is empty or null
|
||||
if (StringUtils.isEmpty(thumbnailDescription)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Bitstream originalBitstream : originalBundleBitstreams) {
|
||||
String originalName = originalBitstream.getName();
|
||||
if (thumbnailName.toLowerCase().contains(".jpg.jpg")) {
|
||||
List<Bundle> originalBundles = item.getBundles("ORIGINAL");
|
||||
for (Bundle originalBundle : originalBundles) {
|
||||
List<Bitstream> originalBundleBitstreams = originalBundle.getBitstreams();
|
||||
|
||||
long originalBitstreamBytes = originalBitstream.getSize();
|
||||
for (Bitstream originalBitstream : originalBundleBitstreams) {
|
||||
String originalName = originalBitstream.getName();
|
||||
|
||||
/*
|
||||
- check if the original file name is the same as the thumbnail name minus the extra ".jpg"
|
||||
- check if the thumbnail description indicates it was automatically generated
|
||||
- check if the item has dc.type Infographic (JPG could be the "real" item!)
|
||||
- check if the original bitstream is less than ~100KiB
|
||||
- Note: in my tests there were 4022 items with ".jpg.jpg" thumbnails totaling 394549249
|
||||
bytes for an average of about 98KiB so ~100KiB seems like a good cut off
|
||||
*/
|
||||
if (
|
||||
originalName.equalsIgnoreCase(StringUtils.removeEndIgnoreCase(thumbnailName, ".jpg"))
|
||||
&& ("Generated Thumbnail".equals(thumbnailBitstream.getDescription()) || "IM Thumbnail".equals(thumbnailBitstream.getDescription()))
|
||||
&& !itemHasInfographic
|
||||
&& originalBitstreamBytes < 100000
|
||||
) {
|
||||
System.out.println(item.getHandle() + ": replacing " + thumbnailName + " with " + originalName);
|
||||
long originalBitstreamBytes = originalBitstream.getSize();
|
||||
|
||||
//add the original bitstream to the THUMBNAIL bundle
|
||||
bundleService.addBitstream(context, thumbnailBundle, originalBitstream);
|
||||
//remove the original bitstream from the ORIGINAL bundle
|
||||
originalBundle.removeBitstream(originalBitstream);
|
||||
//remove the JpgJpg bitstream from the THUMBNAIL bundle
|
||||
thumbnailBundle.removeBitstream(thumbnailBitstream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
- check if the original file name is the same as the thumbnail name minus the extra ".jpg"
|
||||
- check if the thumbnail description indicates it was automatically generated
|
||||
- check if the original bitstream is less than ~100KiB
|
||||
- Note: in my tests there were 4022 items with ".jpg.jpg" thumbnails totaling 394549249
|
||||
bytes for an average of about 98KiB so ~100KiB seems like a good cut off
|
||||
*/
|
||||
if (originalName.equalsIgnoreCase(
|
||||
StringUtils.removeEndIgnoreCase(thumbnailName, ".jpg"))
|
||||
&& ("Generated Thumbnail".equals(thumbnailDescription)
|
||||
|| "IM Thumbnail".equals(thumbnailDescription))
|
||||
&& originalBitstreamBytes < 100000) {
|
||||
System.out.println(
|
||||
item.getHandle()
|
||||
+ ": replacing "
|
||||
+ thumbnailName
|
||||
+ " with "
|
||||
+ originalName);
|
||||
|
||||
// add the original bitstream to the THUMBNAIL bundle
|
||||
bundleService.addBitstream(
|
||||
context, thumbnailBundle, originalBitstream);
|
||||
// remove the original bitstream from the ORIGINAL bundle
|
||||
originalBundle.removeBitstream(originalBitstream);
|
||||
// remove the JpgJpg bitstream from the THUMBNAIL bundle
|
||||
thumbnailBundle.removeBitstream(thumbnailBitstream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
* Copyright (C) 2022 Alan Orth
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package io.github.ilri.cgspace.scripts;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.*;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.BundleService;
|
||||
import org.dspace.content.service.ItemService;
|
||||
@ -71,10 +76,9 @@ public class FixLowQualityThumbnails {
|
||||
DSpaceObject parent = handleService.resolveToObject(context, parentHandle);
|
||||
if (parent != null) {
|
||||
switch (parent.getType()) {
|
||||
case Constants.COLLECTION:
|
||||
process(
|
||||
context,
|
||||
itemService.findByCollection(context, (Collection) parent));
|
||||
case Constants.SITE:
|
||||
process(context, itemService.findAll(context));
|
||||
context.commit();
|
||||
break;
|
||||
case Constants.COMMUNITY:
|
||||
List<Collection> collections = ((Community) parent).getCollections();
|
||||
@ -83,9 +87,13 @@ public class FixLowQualityThumbnails {
|
||||
context,
|
||||
itemService.findAllByCollection(context, collection));
|
||||
}
|
||||
context.commit();
|
||||
break;
|
||||
case Constants.SITE:
|
||||
process(context, itemService.findAll(context));
|
||||
case Constants.COLLECTION:
|
||||
process(
|
||||
context,
|
||||
itemService.findByCollection(context, (Collection) parent));
|
||||
context.commit();
|
||||
break;
|
||||
case Constants.ITEM:
|
||||
processItem(context, (Item) parent);
|
||||
@ -114,6 +122,8 @@ public class FixLowQualityThumbnails {
|
||||
|
||||
private static void processItem(Context context, Item item)
|
||||
throws SQLException, AuthorizeException, IOException {
|
||||
System.out.println("FixLowQualityThumbnails: processing item: " + item.getHandle());
|
||||
|
||||
// Set some state for the item before we iterate over the THUMBNAIL bundle
|
||||
boolean itemHasImThumbnail = false;
|
||||
|
||||
@ -154,7 +164,7 @@ public class FixLowQualityThumbnails {
|
||||
// ption will *always* be "Generated Thumbnail".
|
||||
if ("Generated Thumbnail".equals(thumbnailDescription)) {
|
||||
System.out.print("\u001b[33m");
|
||||
System.out.println("Deleting (" + item.getHandle() + "):");
|
||||
System.out.println("> Action: remove old thumbnail from THUMBNAIL bundle");
|
||||
System.out.println("> Name: »" + thumbnailName + "«");
|
||||
System.out.println("> Description: »" + thumbnailDescription + "«");
|
||||
System.out.print("\u001b[0m");
|
||||
@ -168,7 +178,7 @@ public class FixLowQualityThumbnails {
|
||||
} else if (thumbnailDescription.toLowerCase().contains("thumbnail")
|
||||
&& !"IM Thumbnail".equals(thumbnailDescription)) {
|
||||
System.out.print("\u001b[33m");
|
||||
System.out.println("Deleting (" + item.getHandle() + "):");
|
||||
System.out.println("> Action: remove manually uploaded thumbnail from THUMBNAIL bundle");
|
||||
System.out.println("> Name: »" + thumbnailName + "«");
|
||||
System.out.println("> Description: »" + thumbnailDescription + "«");
|
||||
System.out.print("\u001b[0m");
|
||||
@ -180,7 +190,7 @@ public class FixLowQualityThumbnails {
|
||||
// a thumbnail for a journal or a limited access item.
|
||||
} else {
|
||||
System.out.print("\u001b[34m");
|
||||
System.out.println("Skipping (" + item.getHandle() + "):");
|
||||
System.out.println("> Action: skip other thumbnail in THUMBNAIL bundle");
|
||||
System.out.println("> Name: »" + thumbnailName + "«");
|
||||
System.out.println("> Description: »" + thumbnailDescription + "«");
|
||||
System.out.print("\u001b[0m");
|
||||
@ -245,7 +255,7 @@ public class FixLowQualityThumbnails {
|
||||
&& (originalName.toLowerCase().contains("thumbnail")
|
||||
|| originalDescription.toLowerCase().contains("thumbnail"))) {
|
||||
System.out.print("\u001b[33m");
|
||||
System.out.println("Removing (" + item.getHandle() + "):");
|
||||
System.out.println("> Action: remove thumbnail from ORIGINAL bundle");
|
||||
System.out.println("> Name: »" + originalName + "«");
|
||||
System.out.println("> Description: »" + originalDescription + "«");
|
||||
System.out.print("\u001b[0m");
|
||||
@ -255,7 +265,7 @@ public class FixLowQualityThumbnails {
|
||||
|
||||
} else {
|
||||
System.out.print("\u001b[34m");
|
||||
System.out.println("Skipping (" + item.getHandle() + "):");
|
||||
System.out.println("> Action: skip other bitstream in ORIGINAL bundle");
|
||||
System.out.println("> Name: »" + originalName + "«");
|
||||
System.out.println("> Description: »" + originalDescription + "«");
|
||||
System.out.print("\u001b[0m");
|
||||
|
@ -15,7 +15,7 @@ To use these curation tasks in a DSpace project add the following dependency to
|
||||
<dependency>
|
||||
<groupId>io.github.ilri.cgspace</groupId>
|
||||
<artifactId>cgspace-java-helpers</artifactId>
|
||||
<version>6.1-SNAPSHOT</version>
|
||||
<version>6.2</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
@ -31,7 +31,7 @@ $ mvn package
|
||||
Copy the resulting jar to the DSpace `lib` directory:
|
||||
|
||||
```console
|
||||
$ cp target/cgspace-java-helpers-6.1-SNAPSHOT.jar ~/dspace/lib/
|
||||
$ cp target/cgspace-java-helpers-6.2.jar ~/dspace/lib/
|
||||
```
|
||||
|
||||
## Invocation
|
||||
|
@ -27,6 +27,7 @@
|
||||
{
|
||||
"alpha_2": "KP",
|
||||
"alpha_3": "PRK",
|
||||
"common_name": "North Korea",
|
||||
"name": "Korea, Democratic People's Republic of",
|
||||
"cgspace_name": "Korea, DPR",
|
||||
"numeric": "408",
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user