Skip to content

Commit 0657a2b

Browse files
Merge pull request #1011 from NYPL-Simplified/russellc/clear-expired-oa-books
Add expiration for open access books
2 parents 336ea92 + 00aedb8 commit 0657a2b

5 files changed

Lines changed: 45 additions & 10 deletions

File tree

simplified-books-controller/src/main/java/org/nypl/simplified/books/controller/BookSyncTask.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.nypl.simplified.books.controller
22

33
import com.io7m.jfunctional.Some
4+
import org.joda.time.DateTime
45
import org.librarysimplified.http.api.LSHTTPClientType
56
import org.librarysimplified.http.api.LSHTTPResponseStatus
67
import org.nypl.simplified.accounts.api.AccountAuthenticationCredentials
@@ -23,6 +24,7 @@ import org.nypl.simplified.feeds.api.FeedLoading
2324
import org.nypl.simplified.opds.core.OPDSAvailabilityRevoked
2425
import org.nypl.simplified.opds.core.OPDSFeedParserType
2526
import org.nypl.simplified.opds.core.OPDSParseException
27+
import org.nypl.simplified.opds.core.getOrNull
2628
import org.nypl.simplified.patron.api.PatronUserProfile
2729
import org.nypl.simplified.patron.api.PatronUserProfileParsersType
2830
import org.nypl.simplified.profiles.api.ProfileID
@@ -64,12 +66,14 @@ class BookSyncTask(
6466
val providerAuth = provider.authentication
6567
if (providerAuth == AccountProviderAuthenticationDescription.Anonymous) {
6668
this.logger.debug("account does not support syncing")
69+
this.removeExpiredBooks(account)
6770
return this.taskRecorder.finishSuccess(Unit)
6871
}
6972

7073
val credentials = account.loginState.credentials
7174
if (credentials == null) {
7275
this.logger.debug("no credentials, aborting!")
76+
this.removeExpiredBooks(account)
7377
return this.taskRecorder.finishSuccess(Unit)
7478
}
7579

@@ -115,6 +119,28 @@ class BookSyncTask(
115119
}
116120
}
117121

122+
private fun removeExpiredBooks(account: AccountType) {
123+
val bookDatabase = account.bookDatabase
124+
val existing = bookDatabase.books()
125+
126+
for (existingId in existing) {
127+
try {
128+
this.logger.debug("[{}] checking for deletion", existingId.brief())
129+
val dbEntry = bookDatabase.entry(existingId)
130+
val avail = dbEntry.book.entry.availability
131+
val endDate = avail.endDate.getOrNull() ?: continue
132+
133+
if (endDate <= DateTime.now()) {
134+
this.logger.debug("[{}] deleting", existingId.brief())
135+
bookRegistry.clearFor(existingId)
136+
dbEntry.delete()
137+
}
138+
} catch (x: Throwable) {
139+
this.logger.error("[{}]: unable to delete entry: ", existingId, x)
140+
}
141+
}
142+
}
143+
118144
private fun fetchPatronUserProfile(
119145
account: AccountType,
120146
) {

simplified-opds-core/src/main/java/org/nypl/simplified/opds/core/OPDSAcquisitionFeedEntryParser.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.net.URISyntaxException;
2222
import java.text.ParseException;
2323
import java.util.ArrayList;
24+
import java.util.Date;
2425
import java.util.List;
2526
import java.util.Objects;
2627

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

283-
if (v == Relation.ACQUISITION_OPEN_ACCESS) {
284-
entry_builder.setAvailability(OPDSAvailabilityOpenAccess.get(revoke));
285-
} else {
286-
tryAvailability(entry_builder, link, revoke);
287-
}
284+
tryAvailability(entry_builder, link, revoke);
288285
break;
289286
}
290287
}
@@ -653,6 +650,8 @@ private OPDSAvailabilityType inferAvailability(
653650
return OPDSAvailabilityLoanable.get();
654651
} else if (Relation.ACQUISITION_GENERIC.getUri().toString().equals(rel)) {
655652
return OPDSAvailabilityLoaned.get(start_date, end_date, revoke);
653+
} else if (Relation.ACQUISITION_OPEN_ACCESS.getUri().toString().equals(rel)) {
654+
return OPDSAvailabilityOpenAccess.get(revoke, end_date);
656655
}
657656
}
658657
}

simplified-opds-core/src/main/java/org/nypl/simplified/opds/core/OPDSAvailabilityOpenAccess.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ data class OPDSAvailabilityOpenAccess private constructor(
1515
* @return The revocation link, if any
1616
*/
1717

18-
val revoke: OptionType<URI>
18+
val revoke: OptionType<URI>,
19+
private val endDate: OptionType<DateTime>
1920
) : OPDSAvailabilityType {
2021

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

3233
override fun getEndDate(): OptionType<DateTime> {
33-
return Option.none()
34+
return this.endDate
3435
}
3536

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

5960
@JvmStatic
61+
@JvmOverloads
6062
operator fun get(
61-
revoke: OptionType<URI>
63+
revoke: OptionType<URI>,
64+
endDate: OptionType<DateTime> = Option.none(),
6265
): OPDSAvailabilityOpenAccess {
63-
return OPDSAvailabilityOpenAccess(revoke)
66+
return OPDSAvailabilityOpenAccess(revoke, endDate)
6467
}
6568
}
6669
}

simplified-opds-core/src/main/java/org/nypl/simplified/opds/core/OPDSJSONParser.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.net.URISyntaxException;
2323
import java.util.ArrayList;
2424
import java.util.Collections;
25+
import java.util.Date;
2526
import java.util.List;
2627

2728
import one.irradia.mime.api.MIMEType;
@@ -176,7 +177,9 @@ private static OPDSAvailabilityType parseAvailability(
176177
node, "open_access");
177178
final OptionType<URI> in_revoke =
178179
JSONParserUtilities.getURIOptional(n, "revoke");
179-
return OPDSAvailabilityOpenAccess.get(in_revoke);
180+
final OptionType<DateTime> in_end_date =
181+
JSONParserUtilities.getTimestampOptional(n, "end_date");
182+
return OPDSAvailabilityOpenAccess.get(in_revoke, in_end_date);
180183
}
181184

182185
if (node.has("revoked")) {

simplified-opds-core/src/main/java/org/nypl/simplified/opds/core/OPDSJSONSerializer.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ public ObjectNode onOpenAccess(final OPDSAvailabilityOpenAccess a) {
174174
oh.put("revoke", uri.toString());
175175
return Unit.unit();
176176
});
177+
a.getEndDate().map(t -> {
178+
oh.put("end_date", fmt.print(t));
179+
return Unit.unit();
180+
});
177181
o.set("open_access", oh);
178182
return o;
179183
}

0 commit comments

Comments
 (0)