Skip to content

Commit

Permalink
Merge pull request #217 from kaczmarkiewiczp/dev
Browse files Browse the repository at this point in the history
Revamped Serve dialog
  • Loading branch information
patrykcoding authored Sep 20, 2018
2 parents 18990ab + 40668d6 commit c0a8690
Show file tree
Hide file tree
Showing 9 changed files with 332 additions and 51 deletions.
148 changes: 148 additions & 0 deletions app/src/main/java/ca/pkay/rcloneexplorer/Dialogs/ServeDialog.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package ca.pkay.rcloneexplorer.Dialogs;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioGroup;

import ca.pkay.rcloneexplorer.R;
import ca.pkay.rcloneexplorer.Rclone;

public class ServeDialog extends DialogFragment {

private Context context;
private boolean isDarkTheme;
private Callback callback;
private RadioGroup protocol;
private CheckBox allowRemoteAccess;
private EditText user;
private EditText password;

public interface Callback {
void onServeOptionsSelected(int protocol, boolean allowRemoteAccess, String user, String password);
}

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
if (getParentFragment() != null) {
callback = (Callback) getParentFragment();
}

if (savedInstanceState != null) {
isDarkTheme = savedInstanceState.getBoolean("isDarkTheme");
}

AlertDialog.Builder builder;
if (isDarkTheme) {
builder = new AlertDialog.Builder(context, R.style.DarkDialogTheme);
} else {
builder = new AlertDialog.Builder(context);
}

LayoutInflater layoutInflater = ((FragmentActivity)context).getLayoutInflater();
View view = layoutInflater.inflate(R.layout.dialog_serve, null);

protocol = view.findViewById(R.id.radio_group_protocol);
allowRemoteAccess = view.findViewById(R.id.checkbox_allow_remote_access);
user = view.findViewById(R.id.edit_text_user);
password = view.findViewById(R.id.edit_text_password);

((TextInputLayout) view.findViewById(R.id.text_input_layout_user)).setHint("Username");
((TextInputLayout) view.findViewById(R.id.text_input_layout_password)).setHint("Password");

builder.setTitle(R.string.serve_dialog_title);
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
sendCallback();
}
});

builder.setNegativeButton(R.string.cancel, null);

builder.setView(view);

return builder.show();
}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("isDarkTheme", isDarkTheme);
outState.putInt("protocol", protocol.getCheckedRadioButtonId());
outState.putBoolean("allowRemoteAccess", allowRemoteAccess.isChecked());
if (!user.getText().toString().trim().isEmpty()) {
outState.putString("user", user.getText().toString());
}
if (!password.getText().toString().trim().isEmpty()) {
outState.putString("password", password.getText().toString());
}
}

@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
if (savedInstanceState == null) {
return;
}

allowRemoteAccess.setChecked(savedInstanceState.getBoolean("allowRemoteAccess", false));
String savedUser = savedInstanceState.getString("user");
if (savedUser != null) {
user.setText(savedUser);
}

String savedPassword = savedInstanceState.getString("password");
if (savedPassword != null) {
password.setText(savedPassword);
}

int savedProtocol = savedInstanceState.getInt("protocol", -1);
if (savedProtocol == R.id.radio_http || savedProtocol == R.id.radio_webdav) {
protocol.check(savedProtocol);
}
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;

if (context instanceof Callback) {
callback = (Callback) context;
}
}

public ServeDialog setDarkTheme(boolean isDarkTheme) {
this.isDarkTheme = isDarkTheme;
return this;
}

private void sendCallback() {
int selectedProtocolId = protocol.getCheckedRadioButtonId();
int selectedProtocol;
switch (selectedProtocolId) {
case R.id.radio_webdav:
selectedProtocol = Rclone.SERVE_PROTOCOL_WEBDAV;
break;
case R.id.radio_http:
default:
selectedProtocol = Rclone.SERVE_PROTOCOL_HTTP;
break;
}

callback.onServeOptionsSelected(selectedProtocol, allowRemoteAccess.isChecked(), user.getText().toString(), password.getText().toString());
}
}
4 changes: 4 additions & 0 deletions app/src/main/java/ca/pkay/rcloneexplorer/FilePicker.java
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,10 @@ private ArrayList<String> getStorageDirectories() {
File[] extFiles = getExternalMediaDirs();
String internalStorage = storageDirectories.get(0);
for (File f : extFiles) {
if (f == null) {
continue;
}

if (!f.getAbsolutePath().startsWith(internalStorage)) {
storageDirectories.add(f.getAbsolutePath());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import ca.pkay.rcloneexplorer.Dialogs.InputDialog;
import ca.pkay.rcloneexplorer.Dialogs.LinkDialog;
import ca.pkay.rcloneexplorer.Dialogs.LoadingDialog;
import ca.pkay.rcloneexplorer.Dialogs.ServeDialog;
import ca.pkay.rcloneexplorer.Dialogs.SortDialog;
import ca.pkay.rcloneexplorer.FileComparators;
import ca.pkay.rcloneexplorer.Dialogs.FilePropertiesDialog;
Expand Down Expand Up @@ -90,7 +91,8 @@ public class FileExplorerFragment extends Fragment implements FileExplorerRecy
OpenAsDialog.OnClickListener,
InputDialog.OnPositive,
GoToDialog.Callbacks,
SortDialog.OnClickListener {
SortDialog.OnClickListener,
ServeDialog.Callback {

private static final String ARG_REMOTE = "remote_param";
private static final String SHARED_PREFS_SORT_ORDER = "ca.pkay.rcexplorer.sort_order";
Expand Down Expand Up @@ -593,34 +595,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
recyclerViewAdapter.toggleSelectAll();
return true;
case R.id.action_serve:
String[] serveOptions = new String[] {"HTTP", "Webdav"};
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setItems(serveOptions, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(getContext(), StreamingService.class);
switch (which) {
case 0: // HTTP
intent.putExtra(StreamingService.SERVE_PATH_ARG, directoryObject.getCurrentPath());
intent.putExtra(StreamingService.REMOTE_ARG, remote);
intent.putExtra(StreamingService.SERVE_PROTOCOL, StreamingService.SERVE_HTTP);
intent.putExtra(StreamingService.SHOW_NOTIFICATION_TEXT, true);
break;
case 1: // Webdav
intent.putExtra(StreamingService.SERVE_PATH_ARG, directoryObject.getCurrentPath());
intent.putExtra(StreamingService.REMOTE_ARG, remote);
intent.putExtra(StreamingService.SERVE_PROTOCOL, StreamingService.SERVE_WEBDAV);
intent.putExtra(StreamingService.SHOW_NOTIFICATION_TEXT, true);
break;
default:
return;
}
context.startService(intent);
}
});
builder.setTitle(R.string.pick_a_protocol);
builder.show();

serve();
return true;
case R.id.action_empty_trash:
emptyTrash();
Expand Down Expand Up @@ -650,6 +625,36 @@ public void onClick(DialogInterface dialog, int which) {
}
}

private void serve() {
ServeDialog serveDialog = new ServeDialog();
serveDialog.setDarkTheme(isDarkTheme);
serveDialog.show(getChildFragmentManager(), "serve dialog");
}

// serve callback
@Override
public void onServeOptionsSelected(int protocol, boolean allowRemoteAccess, String user, String password) {
Intent intent = new Intent(getContext(), StreamingService.class);
intent.putExtra(StreamingService.SERVE_PATH_ARG, directoryObject.getCurrentPath());
intent.putExtra(StreamingService.REMOTE_ARG, remote);
intent.putExtra(StreamingService.SHOW_NOTIFICATION_TEXT, true);
intent.putExtra(StreamingService.ALLOW_REMOTE_ACCESS, allowRemoteAccess);
intent.putExtra(StreamingService.AUTHENTICATION_USERNAME, user);
intent.putExtra(StreamingService.AUTHENTICATION_PASSWORD, password);

switch (protocol) {
case Rclone.SERVE_PROTOCOL_HTTP: // HTTP
intent.putExtra(StreamingService.SERVE_PROTOCOL, StreamingService.SERVE_HTTP);
break;
case Rclone.SERVE_PROTOCOL_WEBDAV: // Webdav
intent.putExtra(StreamingService.SERVE_PROTOCOL, StreamingService.SERVE_WEBDAV);
break;
default:
return;
}
context.startService(intent);
}

private void emptyTrash() {
AlertDialog.Builder builder;

Expand Down
50 changes: 32 additions & 18 deletions app/src/main/java/ca/pkay/rcloneexplorer/Rclone.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@

public class Rclone {

public static int SYNC_DIRECTION_LOCAL_TO_REMOTE = 1;
public static int SYNC_DIRECTION_REMOTE_TO_LOCAL = 2;
public static final int SYNC_DIRECTION_LOCAL_TO_REMOTE = 1;
public static final int SYNC_DIRECTION_REMOTE_TO_LOCAL = 2;
public static final int SERVE_PROTOCOL_HTTP = 1;
public static final int SERVE_PROTOCOL_WEBDAV = 2;
private Context context;
private String rclone;
private String rcloneConf;
Expand Down Expand Up @@ -353,37 +355,49 @@ public String obscure(String pass) {
}
}

public Process serveHttp(RemoteItem remote, String servePath, int port) {
public Process serve(int protocol, int port, boolean allowRemoteAccess, String user, String password, RemoteItem remote, String servePath) {
String remoteName = remote.getName();
String localRemotePath = (remote.isRemoteType(RemoteItem.LOCAL)) ? Environment.getExternalStorageDirectory().getAbsolutePath() + "/" : "";
String path = (servePath.compareTo("//" + remoteName) == 0) ? remoteName + ":" + localRemotePath : remoteName + ":" + localRemotePath + servePath;
String[] command = createCommandWithOptions("serve", "http", "--addr", ":" + String.valueOf(port), path);

try {
return Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
return null;
String commandProtocol = protocol == SERVE_PROTOCOL_HTTP ? "http" : "webdav";
String address;
if (allowRemoteAccess) {
address = ":" + String.valueOf(port);
} else {
address = "127.0.0.1:" + String.valueOf(port);
}
}

public Process serveWebdav(RemoteItem remote, String servePath, int port) {
String remoteName = remote.getName();
String localRemotePath = (remote.isRemoteType(RemoteItem.LOCAL)) ? Environment.getExternalStorageDirectory().getAbsolutePath() + "/" : "";
String path = (servePath.compareTo("//" + remoteName) == 0) ? remoteName + ":" + localRemotePath : remoteName + ":" + localRemotePath + servePath;
String[] command = createCommandWithOptions("serve", "webdav", "--addr", ":" + String.valueOf(port), path);

String cachePath = context.getCacheDir().getAbsolutePath();
String[] environmentalVariables = {"TMPDIR=" + cachePath}; // this is a fix for #199

String[] command;

if (user == null && password != null) {
command = createCommandWithOptions("serve", commandProtocol, "--addr", address, path, "--pass", password);
} else if (user != null && password == null) {
command = createCommandWithOptions("serve", commandProtocol, "--addr", address, path, "--user", user);
} else if (user != null) {
command = createCommandWithOptions("serve", commandProtocol, "--addr", address, path, "--user", user, "--pass", password);
} else {
command = createCommandWithOptions("serve", commandProtocol, "--addr", address, path);
}

try {
return Runtime.getRuntime().exec(command, environmentalVariables);
if (protocol == SERVE_PROTOCOL_WEBDAV) {
return Runtime.getRuntime().exec(command, environmentalVariables);
} else {
return Runtime.getRuntime().exec(command);
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
}

public Process serve(int protocol, int port, boolean localhostOnly, RemoteItem remote, String servePath) {
return serve(protocol, port, localhostOnly, null, null, remote, servePath);
}

public Process sync(RemoteItem remoteItem, String remote, String localPath, int syncDirection) {
String[] command;
String remoteName = remoteItem.getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ private void scopeSet(int selectedScope) {
break;
}

scope.setText("scrope: \"" + scopeString + "\"");
scope.setText("scope: \"" + scopeString + "\"");
}

private void setUpRemote() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public class StreamingService extends IntentService {
public static final String REMOTE_ARG = "ca.pkay.rcexplorer.streaming_service.arg2";
public static final String SHOW_NOTIFICATION_TEXT = "ca.pkay.rcexplorer.streaming_service.arg3";
public static final String SERVE_PROTOCOL = "ca.pkay.rcexplorer.serve_protocol";
public static final String ALLOW_REMOTE_ACCESS = "ca.pkay.rcexplorer.allow_remote_access";
public static final String AUTHENTICATION_USERNAME = "ca.pkay.rcexplorer.username";
public static final String AUTHENTICATION_PASSWORD = "ca.pkay.rcexplorer.password";
public static final int SERVE_HTTP = 11;
public static final int SERVE_WEBDAV = 12;
private final String CHANNEL_ID = "ca.pkay.rcexplorer.streaming_channel";
Expand Down Expand Up @@ -54,6 +57,9 @@ protected void onHandleIntent(@Nullable Intent intent) {
final RemoteItem remote = intent.getParcelableExtra(REMOTE_ARG);
final Boolean showNotificationText = intent.getBooleanExtra(SHOW_NOTIFICATION_TEXT, false);
final int protocol = intent.getIntExtra(SERVE_PROTOCOL, SERVE_HTTP);
final Boolean allowRemoteAccess = intent.getBooleanExtra(ALLOW_REMOTE_ACCESS, false);
final String authenticationUsername = intent.getStringExtra(AUTHENTICATION_USERNAME);
final String authenticationPassword = intent.getStringExtra(AUTHENTICATION_PASSWORD);

Intent foregroundIntent = new Intent(this, StreamingService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, foregroundIntent, 0);
Expand Down Expand Up @@ -81,11 +87,11 @@ protected void onHandleIntent(@Nullable Intent intent) {

switch (protocol) {
case SERVE_WEBDAV:
runningProcess = rclone.serveWebdav(remote, servePath, 8080);
runningProcess = rclone.serve(Rclone.SERVE_PROTOCOL_WEBDAV, 8080, allowRemoteAccess, authenticationUsername, authenticationPassword, remote, servePath);
break;
case SERVE_HTTP:
default:
runningProcess = rclone.serveHttp(remote, servePath, 8080);
runningProcess = rclone.serve(Rclone.SERVE_PROTOCOL_HTTP, 8080, allowRemoteAccess, authenticationUsername, authenticationPassword, remote, servePath);
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected void onHandleIntent(@Nullable Intent intent) {
}

RemoteItem remote = intent.getParcelableExtra(REMOTE_ARG);
process = rclone.serveHttp(remote, "", 29170);
process = rclone.serve(Rclone.SERVE_PROTOCOL_HTTP, 29170, true, remote, "");
if (process != null) {
try {
process.waitFor();
Expand Down
Loading

0 comments on commit c0a8690

Please sign in to comment.