Skip to content

Commit

Permalink
Use Path in the download helper classes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Isira-Seneviratne committed Aug 5, 2023
1 parent b18ae90 commit 1a1fa7c
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All @@ -14,21 +15,27 @@
import org.schabi.newpipe.settings.NewPipeSettings;
import org.schabi.newpipe.util.FilePickerActivityHelper;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static android.provider.DocumentsContract.Document.COLUMN_DISPLAY_NAME;
import static android.provider.DocumentsContract.Root.COLUMN_DOCUMENT_ID;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;

public class StoredDirectoryHelper {
private static final String TAG = StoredDirectoryHelper.class.getSimpleName();
public static final int PERMISSION_FLAGS = Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION;

private File ioTree;
private Path ioTree;
private DocumentFile docTree;

private Context context;
Expand All @@ -40,7 +47,7 @@ public StoredDirectoryHelper(@NonNull final Context context, @NonNull final Uri
this.tag = tag;

if (ContentResolver.SCHEME_FILE.equalsIgnoreCase(path.getScheme())) {
this.ioTree = new File(URI.create(path.toString()));
ioTree = Paths.get(URI.create(path.toString()));
return;
}

Expand All @@ -64,13 +71,17 @@ public StoredFileHelper createFile(final String filename, final String mime) {
}

public StoredFileHelper createUniqueFile(final String name, final String mime) {
final ArrayList<String> matches = new ArrayList<>();
final List<String> matches = new ArrayList<>();
final String[] filename = splitFilename(name);
final String lcFilename = filename[0].toLowerCase();
final String lcFileName = filename[0].toLowerCase();

if (docTree == null) {
for (final File file : ioTree.listFiles()) {
addIfStartWith(matches, lcFilename, file.getName());
try (Stream<Path> stream = Files.list(ioTree)) {
matches.addAll(stream.map(path -> path.getFileName().toString().toLowerCase())
.filter(fileName -> fileName.startsWith(lcFileName))
.collect(Collectors.toList()));
} catch (final IOException e) {
Log.e(TAG, "Exception while traversing " + ioTree, e);
}
} else {
// warning: SAF file listing is very slow
Expand All @@ -82,10 +93,10 @@ public StoredFileHelper createUniqueFile(final String name, final String mime) {
final ContentResolver cr = context.getContentResolver();

try (Cursor cursor = cr.query(docTreeChildren, projection, selection,
new String[]{lcFilename}, null)) {
new String[]{lcFileName}, null)) {
if (cursor != null) {
while (cursor.moveToNext()) {
addIfStartWith(matches, lcFilename, cursor.getString(0));
addIfStartWith(matches, lcFileName, cursor.getString(0));
}
}
}
Expand All @@ -112,7 +123,7 @@ public StoredFileHelper createUniqueFile(final String name, final String mime) {
Collections.sort(matches, String::compareTo);

for (int i = 1; i < 1000; i++) {
if (Collections.binarySearch(matches, makeFileName(lcFilename, i, filename[1])) < 0) {
if (Collections.binarySearch(matches, makeFileName(lcFileName, i, filename[1])) < 0) {
return createFile(makeFileName(filename[0], i, filename[1]), mime, true);
}
}
Expand Down Expand Up @@ -141,11 +152,11 @@ private StoredFileHelper createFile(final String filename, final String mime,
}

public Uri getUri() {
return docTree == null ? Uri.fromFile(ioTree) : docTree.getUri();
return docTree == null ? Uri.fromFile(ioTree.toFile()) : docTree.getUri();
}

public boolean exists() {
return docTree == null ? ioTree.exists() : docTree.exists();
return docTree == null ? Files.exists(ioTree) : docTree.exists();
}

/**
Expand All @@ -169,7 +180,9 @@ public boolean isDirect() {
*/
public boolean mkdirs() {
if (docTree == null) {
return ioTree.exists() || ioTree.mkdirs();
// TODO: Use Files.createDirectories() when AGP 8.1 is available:
// https://issuetracker.google.com/issues/282544786
return Files.exists(ioTree) || ioTree.toFile().mkdirs();
}

if (docTree.exists()) {
Expand Down Expand Up @@ -206,16 +219,16 @@ public String getTag() {

public Uri findFile(final String filename) {
if (docTree == null) {
final File res = new File(ioTree, filename);
return res.exists() ? Uri.fromFile(res) : null;
final Path res = ioTree.resolve(filename);
return Files.exists(res) ? Uri.fromFile(res.toFile()) : null;
}

final DocumentFile res = findFileSAFHelper(context, docTree, filename);
return res == null ? null : res.getUri();
}

public boolean canWrite() {
return docTree == null ? ioTree.canWrite() : docTree.canWrite();
return docTree == null ? Files.isWritable(ioTree) : docTree.canWrite();
}

/**
Expand All @@ -230,14 +243,14 @@ public boolean isInvalidSafStorage() {
@NonNull
@Override
public String toString() {
return (docTree == null ? Uri.fromFile(ioTree) : docTree.getUri()).toString();
return (docTree == null ? Uri.fromFile(ioTree.toFile()) : docTree.getUri()).toString();
}

////////////////////
// Utils
///////////////////

private static void addIfStartWith(final ArrayList<String> list, @NonNull final String base,
private static void addIfStartWith(final List<String> list, @NonNull final String base,
final String str) {
if (isNullOrEmpty(str)) {
return;
Expand All @@ -259,7 +272,7 @@ private static String[] splitFilename(@NonNull final String filename) {
}

private static String makeFileName(final String name, final int idx, final String ext) {
return name.concat(" (").concat(String.valueOf(idx)).concat(")").concat(ext);
return name + "(" + idx + ")" + ext;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import us.shandian.giga.io.FileStream;
import us.shandian.giga.io.FileStreamSAF;
Expand All @@ -36,7 +39,7 @@ public class StoredFileHelper implements Serializable {

private transient DocumentFile docFile;
private transient DocumentFile docTree;
private transient File ioFile;
private transient Path ioPath;
private transient Context context;

protected String source;
Expand All @@ -49,7 +52,8 @@ public class StoredFileHelper implements Serializable {

public StoredFileHelper(final Context context, final Uri uri, final String mime) {
if (FilePickerActivityHelper.isOwnFileUri(context, uri)) {
ioFile = Utils.getFileForUri(uri);
final File ioFile = Utils.getFileForUri(uri);
ioPath = ioFile.toPath();
source = Uri.fromFile(ioFile).toString();
} else {
docFile = DocumentFile.fromSingleUri(context, uri);
Expand Down Expand Up @@ -100,26 +104,18 @@ public StoredFileHelper(@Nullable final Uri parent, final String filename, final
this.srcType = this.docFile.getType();
}

StoredFileHelper(final File location, final String filename, final String mime)
StoredFileHelper(final Path location, final String filename, final String mime)
throws IOException {
this.ioFile = new File(location, filename);
ioPath = location.resolve(filename);

if (this.ioFile.exists()) {
if (!this.ioFile.isFile() && !this.ioFile.delete()) {
throw new IOException("The filename is already in use by non-file entity "
+ "and cannot overwrite it");
}
} else {
if (!this.ioFile.createNewFile()) {
throw new IOException("Cannot create the file");
}
}
Files.deleteIfExists(ioPath);
Files.createFile(ioPath);

this.source = Uri.fromFile(this.ioFile).toString();
this.sourceTree = Uri.fromFile(location).toString();
source = Uri.fromFile(ioPath.toFile()).toString();
sourceTree = Uri.fromFile(location.toFile()).toString();

this.srcName = ioFile.getName();
this.srcType = mime;
srcName = ioPath.getFileName().toString();
srcType = mime;
}

public StoredFileHelper(final Context context, @Nullable final Uri parent,
Expand All @@ -129,7 +125,7 @@ public StoredFileHelper(final Context context, @Nullable final Uri parent,

if (path.getScheme() == null
|| path.getScheme().equalsIgnoreCase(ContentResolver.SCHEME_FILE)) {
this.ioFile = new File(URI.create(this.source));
this.ioPath = Paths.get(URI.create(this.source));
} else {
final DocumentFile file = DocumentFile.fromSingleUri(context, path);

Expand Down Expand Up @@ -187,7 +183,7 @@ public SharpStream getStream() throws IOException {
assertValid();

if (docFile == null) {
return new FileStream(ioFile);
return new FileStream(ioPath.toFile());
} else {
return new FileStreamSAF(context.getContentResolver(), docFile.getUri());
}
Expand All @@ -211,7 +207,7 @@ public boolean isInvalid() {
public Uri getUri() {
assertValid();

return docFile == null ? Uri.fromFile(ioFile) : docFile.getUri();
return docFile == null ? Uri.fromFile(ioPath.toFile()) : docFile.getUri();
}

public Uri getParentUri() {
Expand All @@ -233,7 +229,12 @@ public boolean delete() {
return true;
}
if (docFile == null) {
return ioFile.delete();
try {
return Files.deleteIfExists(ioPath);
} catch (final IOException e) {
Log.e(TAG, "Exception while deleting " + ioPath, e);
return false;
}
}

final boolean res = docFile.delete();
Expand All @@ -252,21 +253,30 @@ public boolean delete() {
public long length() {
assertValid();

return docFile == null ? ioFile.length() : docFile.length();
if (docFile == null) {
try {
return Files.size(ioPath);
} catch (final IOException e) {
Log.e(TAG, "Exception while getting the size of " + ioPath, e);
return 0;
}
} else {
return docFile.length();
}
}

public boolean canWrite() {
if (source == null) {
return false;
}
return docFile == null ? ioFile.canWrite() : docFile.canWrite();
return docFile == null ? Files.isWritable(ioPath) : docFile.canWrite();
}

public String getName() {
if (source == null) {
return srcName;
} else if (docFile == null) {
return ioFile.getName();
return ioPath.getFileName().toString();
}

final String name = docFile.getName();
Expand All @@ -287,20 +297,19 @@ public String getTag() {
}

public boolean existsAsFile() {
if (source == null || (docFile == null && ioFile == null)) {
if (source == null || (docFile == null && ioPath == null)) {
if (DEBUG) {
Log.d(TAG, "existsAsFile called but something is null: source = ["
+ (source == null ? "null => storage is invalid" : source)
+ "], docFile = [" + (docFile == null ? "null" : docFile)
+ "], ioFile = [" + (ioFile == null ? "null" : ioFile) + "]");
+ "], docFile = [" + docFile + "], ioPath = [" + ioPath + "]");
}
return false;
}

// WARNING: DocumentFile.exists() and DocumentFile.isFile() methods are slow
// docFile.isVirtual() means it is non-physical?
return docFile == null
? (ioFile.exists() && ioFile.isFile())
? Files.isRegularFile(ioPath)
: (docFile.exists() && docFile.isFile());
}

Expand All @@ -310,8 +319,10 @@ public boolean create() {

if (docFile == null) {
try {
result = ioFile.createNewFile();
Files.createFile(ioPath);
result = true;
} catch (final IOException e) {
Log.e(TAG, "Exception while creating " + ioPath, e);
return false;
}
} else if (docTree == null) {
Expand All @@ -332,7 +343,8 @@ public boolean create() {
}

if (result) {
source = (docFile == null ? Uri.fromFile(ioFile) : docFile.getUri()).toString();
source = (docFile == null ? Uri.fromFile(ioPath.toFile()) : docFile.getUri())
.toString();
srcName = getName();
srcType = getType();
}
Expand All @@ -352,7 +364,7 @@ public void invalidate() {

docTree = null;
docFile = null;
ioFile = null;
ioPath = null;
context = null;
}

Expand Down Expand Up @@ -383,7 +395,7 @@ public boolean equals(final StoredFileHelper storage) {
}

if (this.isDirect()) {
return this.ioFile.getPath().equalsIgnoreCase(storage.ioFile.getPath());
return this.ioPath.equals(storage.ioPath);
}

return DocumentsContract.getDocumentId(this.docFile.getUri())
Expand Down

0 comments on commit 1a1fa7c

Please sign in to comment.