Skip to content

Commit c3b5a5c

Browse files
add getChildren function to handle pagination
1 parent 3a8b416 commit c3b5a5c

File tree

1 file changed

+46
-30
lines changed

1 file changed

+46
-30
lines changed

DriveBackup/src/main/java/ratismal/drivebackup/uploaders/onedrive/OneDriveUploader.java

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@
2323
import java.io.File;
2424
import java.io.IOException;
2525
import java.io.RandomAccessFile;
26+
import java.util.ArrayList;
2627
import java.util.Arrays;
28+
import java.util.Comparator;
2729
import java.util.Iterator;
30+
import java.util.List;
2831
import java.util.concurrent.TimeUnit;
2932

3033
import static ratismal.drivebackup.config.Localization.intl;
@@ -336,19 +339,7 @@ private FQID getRootFolder(@NotNull String folder) throws IOException, GraphApiE
336339
*/
337340
@Nullable
338341
private FQID getFolder(@NotNull FQID root, @NotNull String folder) throws IOException, GraphApiErrorException {
339-
Request request = new Request.Builder()
340-
.addHeader("Authorization", "Bearer " + accessToken)
341-
.url("https://graph.microsoft.com/v1.0/drives/" + root.driveId + "/items/" + root.itemId + "/children")
342-
.build();
343-
JSONArray children;
344-
try (Response response = DriveBackup.httpClient.newCall(request).execute()) {
345-
if (!response.isSuccessful()) {
346-
throw new GraphApiErrorException(response);
347-
}
348-
children = new JSONObject(response.body().string()).getJSONArray("value");
349-
}
350-
for (int i = 0; i < children.length(); i++) {
351-
JSONObject childItem = children.getJSONObject(i);
342+
for (JSONObject childItem : getChildren(root, "?select=name,id,parentReference,remoteItem")) {
352343
String folderName = childItem.getString("name"); // TODO filter non folders
353344
if (folder.equals(folderName)) {
354345
if (childItem.has("remoteItem")) {
@@ -359,10 +350,45 @@ private FQID getFolder(@NotNull FQID root, @NotNull String folder) throws IOExce
359350
return new FQID(driveId, itemId);
360351
}
361352
}
362-
// TODO handle @odata.nextLink
363353
return null;
364354
}
365355

356+
/**
357+
* gets all children for a given folder
358+
* @param folder to query
359+
* @param queryParams line like "?$select=name"
360+
* @throws IOException on request execution failure
361+
* @throws GraphApiErrorException if the children could not be retrieved
362+
* @throws JSONException if the response does not contain the expected items
363+
*/
364+
@NotNull
365+
private List<JSONObject> getChildren(@NotNull FQID folder, @NotNull String queryParams) throws IOException, GraphApiErrorException {
366+
ArrayList<JSONObject> allChildren = new ArrayList<>();
367+
String targetUrl = "https://graph.microsoft.com/v1.0/me/drives/" + folder.driveId
368+
+ "/items/" + folder.itemId + "/children" + queryParams;
369+
while (true) {
370+
Request request = new Request.Builder()
371+
.addHeader("Authorization", "Bearer " + accessToken)
372+
.url(targetUrl)
373+
.build();
374+
try (Response response = DriveBackup.httpClient.newCall(request).execute()) {
375+
if (!response.isSuccessful()) {
376+
throw new GraphApiErrorException(response);
377+
}
378+
JSONObject parsedResponse = new JSONObject(response.body().string());
379+
JSONArray someChildren = parsedResponse.getJSONArray("value");
380+
allChildren.ensureCapacity(parsedResponse.getInt("@odata.count"));
381+
for (int i = 0; i < someChildren.length(); i++) {
382+
allChildren.add(someChildren.getJSONObject(i));
383+
}
384+
if (!parsedResponse.has("@odata.nextLink")) {
385+
return allChildren;
386+
}
387+
targetUrl = parsedResponse.getString("@odata.nextLink");
388+
}
389+
}
390+
}
391+
366392
/**
367393
* moves an item to the recycle bin
368394
*
@@ -499,31 +525,21 @@ private void pruneBackups(@NotNull FQID parent) throws IOException, GraphApiErro
499525
if (fileLimit == -1) {
500526
return;
501527
}
502-
Request childItemRequest = new Request.Builder()
503-
.addHeader("Authorization", "Bearer " + accessToken)
504-
.url("https://graph.microsoft.com/v1.0/drives/" + parent.driveId + "/items/" + parent.itemId + "/children?sort_by=createdDateTime")
505-
.build();
506-
JSONArray items;
507-
try (Response childItemResponse = DriveBackup.httpClient.newCall(childItemRequest).execute()) {
508-
if (!childItemResponse.isSuccessful()) {
509-
throw new GraphApiErrorException(childItemResponse);
510-
}
511-
items = new JSONObject(childItemResponse.body().string()).getJSONArray("value");
512-
}
513-
if(fileLimit >= items.length()) { // TODO filter non backup files (folders & files not created by plugin)
528+
List<JSONObject> childItems = getChildren(parent, "?$select=id,createdDateTime");
529+
if(fileLimit >= childItems.size()) {
514530
return;
515531
}
516532
logger.info(
517533
intl("backup-method-limit-reached"),
518-
"file-count", String.valueOf(items.length()),
534+
"file-count", String.valueOf(childItems.size()),
519535
"upload-method", getName(),
520536
"file-limit", String.valueOf(fileLimit));
521-
int itemsToDelete = items.length() - fileLimit;
537+
childItems.sort(Comparator.comparing(item -> item.getString("createdDateTime")));
538+
int itemsToDelete = childItems.size() - fileLimit;
522539
for (int i = 0; i < itemsToDelete; i++) {
523-
String itemId = items.getJSONObject(i).getString("id");
540+
String itemId = childItems.get(i).getString("id");
524541
recycleItem(parent.driveId, itemId);
525542
}
526-
// TODO handle @odata.nextLink
527543
}
528544

529545
/**

0 commit comments

Comments
 (0)