diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
deleted file mode 100644
index ac93b0d..0000000
--- a/.idea/deploymentTargetDropDown.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index 731677a..8c0539e 100644
--- a/README.md
+++ b/README.md
@@ -19,10 +19,12 @@ Current feature list
* File upload
* File download
* pdf file reader using user provided pdf.js server
+* file sharing links
+* get object info
+* get bucket info
Planned feature list
-* file sharing links
* better interface for uploads and downloads
This app is a work in progress, so it have some bugs that need to be fixed
diff --git a/app/build.gradle b/app/build.gradle
index b094678..0c24d0b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,8 +9,8 @@ android {
applicationId "asgardius.page.s3manager"
minSdk 24
targetSdk 33
- versionCode 14
- versionName "0.1.12"
+ versionCode 15
+ versionName "0.1.13"
setProperty("archivesBaseName", "s3-manager-$versionName")
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 894774b..1a20301 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -19,6 +19,14 @@
android:supportsRtl="true"
android:theme="@style/Theme.AsgardiusS3Manager"
tools:targetApi="31">
+
+
+
diff --git a/app/src/main/java/asgardius/page/s3manager/BucketSelect.java b/app/src/main/java/asgardius/page/s3manager/BucketSelect.java
index 60e4e28..2bf5ce2 100644
--- a/app/src/main/java/asgardius/page/s3manager/BucketSelect.java
+++ b/app/src/main/java/asgardius/page/s3manager/BucketSelect.java
@@ -165,6 +165,8 @@ public class BucketSelect extends AppCompatActivity {
//System.out.println(file);
//Toast.makeText(BucketSelect.this, intent.getData().toString(), Toast.LENGTH_SHORT).show();
+ } else if (menuItem.getTitle() == getResources().getString(R.string.object_info)) {
+ objectInfo(Name.get(position).toString());
} else if (menuItem.getTitle() == getResources().getString(R.string.file_del)) {
//Toast.makeText(BucketSelect.this, getResources().getString(R.string.pending_feature), Toast.LENGTH_SHORT).show();
delete(prefix + Name.get(position).toString());
@@ -288,6 +290,19 @@ public class BucketSelect extends AppCompatActivity {
startActivity(intent);
}
+ private void objectInfo(String bucket) {
+
+ Intent intent = new Intent(this, ObjectInfo.class);
+ //treelevel ++;
+ intent.putExtra("endpoint", endpoint);
+ intent.putExtra("username", username);
+ intent.putExtra("password", password);
+ intent.putExtra("bucket", bucket);
+ intent.putExtra("region", location);
+ startActivity(intent);
+
+ }
+
private void newBucket() {
Intent intent = new Intent(this, CreateBucket.class);
intent.putExtra("endpoint", endpoint);
diff --git a/app/src/main/java/asgardius/page/s3manager/ObjectInfo.java b/app/src/main/java/asgardius/page/s3manager/ObjectInfo.java
new file mode 100644
index 0000000..ffbc132
--- /dev/null
+++ b/app/src/main/java/asgardius/page/s3manager/ObjectInfo.java
@@ -0,0 +1,147 @@
+package asgardius.page.s3manager;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.regions.Region;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.AmazonS3Client;
+import com.amazonaws.services.s3.S3ClientOptions;
+import com.amazonaws.services.s3.model.Bucket;
+import com.amazonaws.services.s3.model.ListObjectsRequest;
+import com.amazonaws.services.s3.model.ObjectListing;
+import com.amazonaws.services.s3.model.S3ObjectSummary;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ObjectInfo extends AppCompatActivity {
+ String username, password, endpoint, bucket, object, location;
+ Region region;
+ S3ClientOptions s3ClientOptions;
+ AWSCredentials myCredentials;
+ AmazonS3 s3client;
+ ProgressBar simpleProgressBar;
+ TextView filesize, filesizeinfo, objectcount;
+ boolean isobject, isfolder;
+ long totalSize = 0;
+ int totalItems = 0;
+ ListObjectsRequest orequest;
+ long KiB, MiB, GiB;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_object_info);
+ KiB = 1024;
+ MiB = 1024 * KiB;
+ GiB = 1024 * MiB;
+ simpleProgressBar = (ProgressBar) findViewById(R.id.simpleProgressBar);
+ filesize = (TextView) findViewById(R.id.size);
+ filesizeinfo = (TextView) findViewById(R.id.size_info);
+ objectcount = (TextView) findViewById(R.id.object_count);
+ endpoint = getIntent().getStringExtra("endpoint");
+ username = getIntent().getStringExtra("username");
+ password = getIntent().getStringExtra("password");
+ bucket = getIntent().getStringExtra("bucket");
+ location = getIntent().getStringExtra("region");
+ object = getIntent().getStringExtra("object");
+ if (object == null) {
+ getSupportActionBar().setTitle(bucket+"/");
+ } else {
+ getSupportActionBar().setTitle(bucket+"/"+object);
+ }
+ region = Region.getRegion(location);
+ s3ClientOptions = S3ClientOptions.builder().build();
+ myCredentials = new BasicAWSCredentials(username, password);
+ try {
+ s3client = new AmazonS3Client(myCredentials, region);
+ } catch (Exception e) {
+ Toast.makeText(getApplicationContext(),getResources().getString(R.string.media_list_fail), Toast.LENGTH_SHORT).show();
+ }
+ s3client.setEndpoint(endpoint);
+ if (!endpoint.contains(getResources().getString(R.string.aws_endpoint))) {
+ s3ClientOptions.setPathStyleAccess(true);
+ }
+ s3client.setS3ClientOptions(s3ClientOptions);
+ Thread getInfo = new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ //Your code goes here
+ if (object == null) {
+ isobject = false;
+ orequest = new ListObjectsRequest().withBucketName(bucket).withMaxKeys(8000);
+ } else {
+ isobject = true;
+ if (object.endsWith("/")) {
+ isfolder = true;
+ } else {
+ isfolder = false;
+ }
+ orequest = new ListObjectsRequest().withBucketName(bucket).withPrefix(object).withMaxKeys(8000);
+ }
+ ObjectListing result = s3client.listObjects(orequest);
+ do {
+ for (S3ObjectSummary objectSummary : result.getObjectSummaries()) {
+ totalSize += objectSummary.getSize();
+ totalItems++;
+ }
+ result = s3client.listNextBatchOfObjects (result);
+ } while (result.isTruncated());
+
+
+ runOnUiThread(new Runnable() {
+
+ @Override
+ public void run() {
+ if (isobject) {
+ if (isfolder) {
+ filesizeinfo.setText(getResources().getString(R.string.folder_size));
+ objectcount.setText(totalItems+" "+getResources().getString(R.string.file_count));
+ } else {
+ filesizeinfo.setText(getResources().getString(R.string.file_size));
+ }
+ } else {
+ filesizeinfo.setText(getResources().getString(R.string.bucket_size));
+ objectcount.setText(totalItems+" "+getResources().getString(R.string.file_count));
+ }
+ if (totalSize >= GiB) {
+ filesize.setText(Long.toString(totalSize/GiB)+" GiB");
+ } else if (totalSize >= MiB) {
+ filesize.setText(Long.toString(totalSize/MiB)+" MiB");
+ } else if (totalSize >= KiB) {
+ filesize.setText(Long.toString(totalSize/KiB)+" KiB");
+ } else {
+ filesize.setText(Long.toString(totalSize)+" Bytes");
+ }
+ simpleProgressBar.setVisibility(View.INVISIBLE);
+ }
+ });
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ runOnUiThread(new Runnable() {
+
+ @Override
+ public void run() {
+ Toast.makeText(getApplicationContext(),getResources().getString(R.string.media_list_fail), Toast.LENGTH_SHORT).show();
+ }
+ });
+ //Toast.makeText(getApplicationContext(),getResources().getString(R.string.media_list_fail), Toast.LENGTH_SHORT).show();
+ finish();
+ }
+ }
+ });
+ getInfo.start();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/asgardius/page/s3manager/ObjectSelect.java b/app/src/main/java/asgardius/page/s3manager/ObjectSelect.java
index 1a56cc6..a65f095 100644
--- a/app/src/main/java/asgardius/page/s3manager/ObjectSelect.java
+++ b/app/src/main/java/asgardius/page/s3manager/ObjectSelect.java
@@ -306,6 +306,8 @@ public class ObjectSelect extends AppCompatActivity {
if (menuItem.getTitle() == getResources().getString(R.string.upload_file_here)) {
//Toast.makeText(ObjectSelect.this, getResources().getString(R.string.pending_feature), Toast.LENGTH_SHORT).show();
upload();
+ } else if (menuItem.getTitle() == getResources().getString(R.string.object_info)) {
+ objectInfo(prefix + Name.get(position).toString());
} else if (menuItem.getTitle() == getResources().getString(R.string.file_del)) {
if (Name.size() == 1 && treelevel >= 1) {
Toast.makeText(ObjectSelect.this, getResources().getString(R.string.only_item_onlist), Toast.LENGTH_SHORT).show();
@@ -335,8 +337,10 @@ public class ObjectSelect extends AppCompatActivity {
} else if (menuItem.getTitle() == getResources().getString(R.string.upload_file_here)) {
//Toast.makeText(ObjectSelect.this, getResources().getString(R.string.pending_feature), Toast.LENGTH_SHORT).show();
upload();
- } else if (menuItem.getTitle() == getResources().getString(R.string.file_share)) {
+ } else if (menuItem.getTitle() == getResources().getString(R.string.create_link)) {
share(prefix + Name.get(position).toString());
+ } else if (menuItem.getTitle() == getResources().getString(R.string.object_info)) {
+ objectInfo(prefix + Name.get(position).toString());
} else if (menuItem.getTitle() == getResources().getString(R.string.file_del)) {
if (menuItem.getTitle() == getResources().getString(R.string.file_del)) {
if (Name.size() == 1 && treelevel >= 1) {
@@ -418,6 +422,20 @@ public class ObjectSelect extends AppCompatActivity {
}
+ private void objectInfo(String object) {
+
+ Intent intent = new Intent(this, ObjectInfo.class);
+ //treelevel ++;
+ intent.putExtra("endpoint", endpoint);
+ intent.putExtra("username", username);
+ intent.putExtra("password", password);
+ intent.putExtra("bucket", bucket);
+ intent.putExtra("object", object);
+ intent.putExtra("region", location);
+ startActivity(intent);
+
+ }
+
private void delete(String object, boolean folder) {
AlertDialog.Builder builder = new AlertDialog.Builder(ObjectSelect.this);
builder.setCancelable(true);
diff --git a/app/src/main/java/asgardius/page/s3manager/Share.java b/app/src/main/java/asgardius/page/s3manager/Share.java
index 9f46d39..d46e657 100644
--- a/app/src/main/java/asgardius/page/s3manager/Share.java
+++ b/app/src/main/java/asgardius/page/s3manager/Share.java
@@ -31,7 +31,7 @@ public class Share extends AppCompatActivity {
Calendar mycal;
EditText datepick, monthpick, yearpick, hourpick, minutepick;
int date, month, year, hour, minute;
- Button share;
+ Button share, external;
public static String URLify(String str) {
str = str.trim();
@@ -73,6 +73,7 @@ public class Share extends AppCompatActivity {
hourpick = (EditText)findViewById(R.id.Hour);
minutepick = (EditText)findViewById(R.id.Minute);
share = (Button)findViewById(R.id.share);
+ external = (Button)findViewById(R.id.open_in);
endpoint = getIntent().getStringExtra("endpoint");
username = getIntent().getStringExtra("username");
password = getIntent().getStringExtra("password");
@@ -97,31 +98,55 @@ public class Share extends AppCompatActivity {
public void onClick(View view) {
//buttonaction
try {
- date = Integer.parseInt(datepick.getText().toString());
- month = Integer.parseInt(monthpick.getText().toString());
- year = Integer.parseInt(yearpick.getText().toString());
- hour = Integer.parseInt(hourpick.getText().toString());
- minute = Integer.parseInt(minutepick.getText().toString());
- mycal.set(Calendar.YEAR, year);
- mycal.set(Calendar.MONTH, month-1);
- mycal.set(Calendar.DATE, date);
- mycal.set(Calendar.HOUR, hour);
- mycal.set(Calendar.MINUTE, minute);
- mycal.set(Calendar.SECOND, 0);
- Date expiration = mycal.getTime();
- //System.out.println(expiration);
- GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket, object).withExpiration(expiration);
- URL objectURL = s3client.generatePresignedUrl(request);
- //System.out.println(URLify(objectURL.toString()));
- Intent shareIntent = new Intent(Intent.ACTION_SEND);
- shareIntent.setType("text/plain");
- shareIntent.putExtra(Intent.EXTRA_TEXT, URLify(objectURL.toString()));
- startActivity(Intent.createChooser(shareIntent, "choose one"));
+ if (datepick.getText().toString().equals("") || monthpick.getText().toString().equals("") ||
+ yearpick.getText().toString().equals("") || hourpick.getText().toString().equals("") ||
+ minutepick.getText().toString().equals("")) {
+ Toast.makeText(getApplicationContext(),getResources().getString(R.string.null_expiration_date), Toast.LENGTH_SHORT).show();
+ } else {
+ date = Integer.parseInt(datepick.getText().toString());
+ month = Integer.parseInt(monthpick.getText().toString());
+ year = Integer.parseInt(yearpick.getText().toString());
+ hour = Integer.parseInt(hourpick.getText().toString());
+ minute = Integer.parseInt(minutepick.getText().toString());
+ mycal.set(Calendar.YEAR, year);
+ mycal.set(Calendar.MONTH, month-1);
+ mycal.set(Calendar.DATE, date);
+ mycal.set(Calendar.HOUR, hour);
+ mycal.set(Calendar.MINUTE, minute);
+ mycal.set(Calendar.SECOND, 0);
+ Date expiration = mycal.getTime();
+ //System.out.println(expiration);
+ GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket, object).withExpiration(expiration);
+ URL objectURL = s3client.generatePresignedUrl(request);
+ //System.out.println(URLify(objectURL.toString()));
+ Intent shareIntent = new Intent(Intent.ACTION_SEND);
+ shareIntent.setType("text/plain");
+ shareIntent.putExtra(Intent.EXTRA_TEXT, URLify(objectURL.toString()));
+ startActivity(Intent.createChooser(shareIntent, "choose one"));
+ }
} catch (Exception e) {
Toast.makeText(getApplicationContext(),getResources().getString(R.string.invalid_expiration_date), Toast.LENGTH_SHORT).show();
}
}
});
+ external.setOnClickListener(new View.OnClickListener(){
+ @Override
+ public void onClick(View view) {
+ //buttonaction
+ try {
+ GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket, object);
+ URL objectURL = s3client.generatePresignedUrl(request);
+ //System.out.println(URLify(objectURL.toString()));
+ Intent shareIntent = new Intent(Intent.ACTION_SEND);
+ shareIntent.setType("text/plain");
+ shareIntent.putExtra(Intent.EXTRA_TEXT, URLify(objectURL.toString()));
+ startActivity(Intent.createChooser(shareIntent, "choose one"));
+ } catch (Exception e) {
+ Toast.makeText(getApplicationContext(),getResources().getString(R.string.invalid_expiration_date), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ });
}
}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_object_info.xml b/app/src/main/res/layout/activity_object_info.xml
new file mode 100644
index 0000000..4a8f6c1
--- /dev/null
+++ b/app/src/main/res/layout/activity_object_info.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_share.xml b/app/src/main/res/layout/activity_share.xml
index 27942ff..aba7813 100644
--- a/app/src/main/res/layout/activity_share.xml
+++ b/app/src/main/res/layout/activity_share.xml
@@ -112,7 +112,15 @@
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
- android:text="@string/create_link"
+ android:text="@string/file_share"
+ tools:ignore="MissingConstraints" />
+
+
diff --git a/app/src/main/res/menu/bucket_menu.xml b/app/src/main/res/menu/bucket_menu.xml
index 3c3e897..047028e 100644
--- a/app/src/main/res/menu/bucket_menu.xml
+++ b/app/src/main/res/menu/bucket_menu.xml
@@ -9,6 +9,10 @@
android:id="@+id/newbucket"
android:title="@string/create_bucket" />
+
+
diff --git a/app/src/main/res/menu/folder_menu.xml b/app/src/main/res/menu/folder_menu.xml
index 1e64433..a5f1e60 100644
--- a/app/src/main/res/menu/folder_menu.xml
+++ b/app/src/main/res/menu/folder_menu.xml
@@ -5,6 +5,10 @@
android:id="@+id/upload_file"
android:title="@string/upload_file_here" />
+
+
diff --git a/app/src/main/res/menu/object_menu.xml b/app/src/main/res/menu/object_menu.xml
index 056673d..d8e0549 100644
--- a/app/src/main/res/menu/object_menu.xml
+++ b/app/src/main/res/menu/object_menu.xml
@@ -11,7 +11,11 @@
+ android:title="@string/create_link" />
+
+
- Hora de expiración
Crear enlace al archivo
La fecha de caducidad debe ser inferior a 7 días
+ Tamaño del archivo
+ Propiedades
+ Abir en
+ Tamaño de la carpeta
+ Tamaño del bucket
+ Archivos
+ Debe establecer una fecha de expiración para compartir archivos
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 41aeab3..e0b8061 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -18,12 +18,14 @@
YYYY
Create file link
Expiration date must be at most 7 days
+ You must set an expiration date to share files
Local database is corrupted. Please reinstall this app
This feature is not implemented yet
Set new bucket name
Bucket name
A bucket name is required
Share file
+ Open in
Download file
Download in progress
File downloaded successfully
@@ -39,6 +41,11 @@
Retry
Download failed
Success
+ Properties
+ File Size
+ Folder Size
+ Bucket Size
+ Files
Create new bucket
Bucket created successfully
Upload file in current folder