Skip to content

Commit

Permalink
Merge pull request #1011 from NYPL-Simplified/russellc/clear-expired-…
Browse files Browse the repository at this point in the history
…oa-books

Add expiration for open access books
  • Loading branch information
russellcullen authored Dec 11, 2023
2 parents 336ea92 + 00aedb8 commit 0657a2b
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.nypl.simplified.books.controller

import com.io7m.jfunctional.Some
import org.joda.time.DateTime
import org.librarysimplified.http.api.LSHTTPClientType
import org.librarysimplified.http.api.LSHTTPResponseStatus
import org.nypl.simplified.accounts.api.AccountAuthenticationCredentials
Expand All @@ -23,6 +24,7 @@ import org.nypl.simplified.feeds.api.FeedLoading
import org.nypl.simplified.opds.core.OPDSAvailabilityRevoked
import org.nypl.simplified.opds.core.OPDSFeedParserType
import org.nypl.simplified.opds.core.OPDSParseException
import org.nypl.simplified.opds.core.getOrNull
import org.nypl.simplified.patron.api.PatronUserProfile
import org.nypl.simplified.patron.api.PatronUserProfileParsersType
import org.nypl.simplified.profiles.api.ProfileID
Expand Down Expand Up @@ -64,12 +66,14 @@ class BookSyncTask(
val providerAuth = provider.authentication
if (providerAuth == AccountProviderAuthenticationDescription.Anonymous) {
this.logger.debug("account does not support syncing")
this.removeExpiredBooks(account)
return this.taskRecorder.finishSuccess(Unit)
}

val credentials = account.loginState.credentials
if (credentials == null) {
this.logger.debug("no credentials, aborting!")
this.removeExpiredBooks(account)
return this.taskRecorder.finishSuccess(Unit)
}

Expand Down Expand Up @@ -115,6 +119,28 @@ class BookSyncTask(
}
}

private fun removeExpiredBooks(account: AccountType) {
val bookDatabase = account.bookDatabase
val existing = bookDatabase.books()

for (existingId in existing) {
try {
this.logger.debug("[{}] checking for deletion", existingId.brief())
val dbEntry = bookDatabase.entry(existingId)
val avail = dbEntry.book.entry.availability
val endDate = avail.endDate.getOrNull() ?: continue

if (endDate <= DateTime.now()) {
this.logger.debug("[{}] deleting", existingId.brief())
bookRegistry.clearFor(existingId)
dbEntry.delete()
}
} catch (x: Throwable) {
this.logger.error("[{}]: unable to delete entry: ", existingId, x)
}
}
}

private fun fetchPatronUserProfile(
account: AccountType,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

Expand Down Expand Up @@ -280,11 +281,7 @@ private void tryConsumeAcquisitions(
final OPDSAcquisition acquisition = new OPDSAcquisition(v, href, type, indirects);
entry_builder.addAcquisition(acquisition);

if (v == Relation.ACQUISITION_OPEN_ACCESS) {
entry_builder.setAvailability(OPDSAvailabilityOpenAccess.get(revoke));
} else {
tryAvailability(entry_builder, link, revoke);
}
tryAvailability(entry_builder, link, revoke);
break;
}
}
Expand Down Expand Up @@ -653,6 +650,8 @@ private OPDSAvailabilityType inferAvailability(
return OPDSAvailabilityLoanable.get();
} else if (Relation.ACQUISITION_GENERIC.getUri().toString().equals(rel)) {
return OPDSAvailabilityLoaned.get(start_date, end_date, revoke);
} else if (Relation.ACQUISITION_OPEN_ACCESS.getUri().toString().equals(rel)) {
return OPDSAvailabilityOpenAccess.get(revoke, end_date);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ data class OPDSAvailabilityOpenAccess private constructor(
* @return The revocation link, if any
*/

val revoke: OptionType<URI>
val revoke: OptionType<URI>,
private val endDate: OptionType<DateTime>
) : OPDSAvailabilityType {

val endDateOrNull: DateTime?
Expand All @@ -30,7 +31,7 @@ data class OPDSAvailabilityOpenAccess private constructor(
*/

override fun getEndDate(): OptionType<DateTime> {
return Option.none()
return this.endDate
}

override fun toString(): String {
Expand All @@ -57,10 +58,12 @@ data class OPDSAvailabilityOpenAccess private constructor(
*/

@JvmStatic
@JvmOverloads
operator fun get(
revoke: OptionType<URI>
revoke: OptionType<URI>,
endDate: OptionType<DateTime> = Option.none(),
): OPDSAvailabilityOpenAccess {
return OPDSAvailabilityOpenAccess(revoke)
return OPDSAvailabilityOpenAccess(revoke, endDate)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import one.irradia.mime.api.MIMEType;
Expand Down Expand Up @@ -176,7 +177,9 @@ private static OPDSAvailabilityType parseAvailability(
node, "open_access");
final OptionType<URI> in_revoke =
JSONParserUtilities.getURIOptional(n, "revoke");
return OPDSAvailabilityOpenAccess.get(in_revoke);
final OptionType<DateTime> in_end_date =
JSONParserUtilities.getTimestampOptional(n, "end_date");
return OPDSAvailabilityOpenAccess.get(in_revoke, in_end_date);
}

if (node.has("revoked")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ public ObjectNode onOpenAccess(final OPDSAvailabilityOpenAccess a) {
oh.put("revoke", uri.toString());
return Unit.unit();
});
a.getEndDate().map(t -> {
oh.put("end_date", fmt.print(t));
return Unit.unit();
});
o.set("open_access", oh);
return o;
}
Expand Down

0 comments on commit 0657a2b

Please sign in to comment.