Skip to content

Commit c0a8690

Browse files
authored
Merge pull request #217 from kaczmarkiewiczp/dev
Revamped Serve dialog
2 parents 18990ab + 40668d6 commit c0a8690

File tree

9 files changed

+332
-51
lines changed

9 files changed

+332
-51
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package ca.pkay.rcloneexplorer.Dialogs;
2+
3+
import android.app.Dialog;
4+
import android.content.Context;
5+
import android.content.DialogInterface;
6+
import android.os.Bundle;
7+
import android.support.annotation.NonNull;
8+
import android.support.annotation.Nullable;
9+
import android.support.design.widget.TextInputLayout;
10+
import android.support.v4.app.DialogFragment;
11+
import android.support.v4.app.FragmentActivity;
12+
import android.support.v7.app.AlertDialog;
13+
import android.view.LayoutInflater;
14+
import android.view.View;
15+
import android.widget.CheckBox;
16+
import android.widget.EditText;
17+
import android.widget.RadioGroup;
18+
19+
import ca.pkay.rcloneexplorer.R;
20+
import ca.pkay.rcloneexplorer.Rclone;
21+
22+
public class ServeDialog extends DialogFragment {
23+
24+
private Context context;
25+
private boolean isDarkTheme;
26+
private Callback callback;
27+
private RadioGroup protocol;
28+
private CheckBox allowRemoteAccess;
29+
private EditText user;
30+
private EditText password;
31+
32+
public interface Callback {
33+
void onServeOptionsSelected(int protocol, boolean allowRemoteAccess, String user, String password);
34+
}
35+
36+
@NonNull
37+
@Override
38+
public Dialog onCreateDialog(Bundle savedInstanceState) {
39+
if (getParentFragment() != null) {
40+
callback = (Callback) getParentFragment();
41+
}
42+
43+
if (savedInstanceState != null) {
44+
isDarkTheme = savedInstanceState.getBoolean("isDarkTheme");
45+
}
46+
47+
AlertDialog.Builder builder;
48+
if (isDarkTheme) {
49+
builder = new AlertDialog.Builder(context, R.style.DarkDialogTheme);
50+
} else {
51+
builder = new AlertDialog.Builder(context);
52+
}
53+
54+
LayoutInflater layoutInflater = ((FragmentActivity)context).getLayoutInflater();
55+
View view = layoutInflater.inflate(R.layout.dialog_serve, null);
56+
57+
protocol = view.findViewById(R.id.radio_group_protocol);
58+
allowRemoteAccess = view.findViewById(R.id.checkbox_allow_remote_access);
59+
user = view.findViewById(R.id.edit_text_user);
60+
password = view.findViewById(R.id.edit_text_password);
61+
62+
((TextInputLayout) view.findViewById(R.id.text_input_layout_user)).setHint("Username");
63+
((TextInputLayout) view.findViewById(R.id.text_input_layout_password)).setHint("Password");
64+
65+
builder.setTitle(R.string.serve_dialog_title);
66+
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
67+
@Override
68+
public void onClick(DialogInterface dialog, int which) {
69+
sendCallback();
70+
}
71+
});
72+
73+
builder.setNegativeButton(R.string.cancel, null);
74+
75+
builder.setView(view);
76+
77+
return builder.show();
78+
}
79+
80+
@Override
81+
public void onSaveInstanceState(Bundle outState) {
82+
super.onSaveInstanceState(outState);
83+
outState.putBoolean("isDarkTheme", isDarkTheme);
84+
outState.putInt("protocol", protocol.getCheckedRadioButtonId());
85+
outState.putBoolean("allowRemoteAccess", allowRemoteAccess.isChecked());
86+
if (!user.getText().toString().trim().isEmpty()) {
87+
outState.putString("user", user.getText().toString());
88+
}
89+
if (!password.getText().toString().trim().isEmpty()) {
90+
outState.putString("password", password.getText().toString());
91+
}
92+
}
93+
94+
@Override
95+
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
96+
super.onViewStateRestored(savedInstanceState);
97+
if (savedInstanceState == null) {
98+
return;
99+
}
100+
101+
allowRemoteAccess.setChecked(savedInstanceState.getBoolean("allowRemoteAccess", false));
102+
String savedUser = savedInstanceState.getString("user");
103+
if (savedUser != null) {
104+
user.setText(savedUser);
105+
}
106+
107+
String savedPassword = savedInstanceState.getString("password");
108+
if (savedPassword != null) {
109+
password.setText(savedPassword);
110+
}
111+
112+
int savedProtocol = savedInstanceState.getInt("protocol", -1);
113+
if (savedProtocol == R.id.radio_http || savedProtocol == R.id.radio_webdav) {
114+
protocol.check(savedProtocol);
115+
}
116+
}
117+
118+
@Override
119+
public void onAttach(Context context) {
120+
super.onAttach(context);
121+
this.context = context;
122+
123+
if (context instanceof Callback) {
124+
callback = (Callback) context;
125+
}
126+
}
127+
128+
public ServeDialog setDarkTheme(boolean isDarkTheme) {
129+
this.isDarkTheme = isDarkTheme;
130+
return this;
131+
}
132+
133+
private void sendCallback() {
134+
int selectedProtocolId = protocol.getCheckedRadioButtonId();
135+
int selectedProtocol;
136+
switch (selectedProtocolId) {
137+
case R.id.radio_webdav:
138+
selectedProtocol = Rclone.SERVE_PROTOCOL_WEBDAV;
139+
break;
140+
case R.id.radio_http:
141+
default:
142+
selectedProtocol = Rclone.SERVE_PROTOCOL_HTTP;
143+
break;
144+
}
145+
146+
callback.onServeOptionsSelected(selectedProtocol, allowRemoteAccess.isChecked(), user.getText().toString(), password.getText().toString());
147+
}
148+
}

app/src/main/java/ca/pkay/rcloneexplorer/FilePicker.java

+4
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,10 @@ private ArrayList<String> getStorageDirectories() {
508508
File[] extFiles = getExternalMediaDirs();
509509
String internalStorage = storageDirectories.get(0);
510510
for (File f : extFiles) {
511+
if (f == null) {
512+
continue;
513+
}
514+
511515
if (!f.getAbsolutePath().startsWith(internalStorage)) {
512516
storageDirectories.add(f.getAbsolutePath());
513517
}

app/src/main/java/ca/pkay/rcloneexplorer/Fragments/FileExplorerFragment.java

+34-29
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import ca.pkay.rcloneexplorer.Dialogs.InputDialog;
6363
import ca.pkay.rcloneexplorer.Dialogs.LinkDialog;
6464
import ca.pkay.rcloneexplorer.Dialogs.LoadingDialog;
65+
import ca.pkay.rcloneexplorer.Dialogs.ServeDialog;
6566
import ca.pkay.rcloneexplorer.Dialogs.SortDialog;
6667
import ca.pkay.rcloneexplorer.FileComparators;
6768
import ca.pkay.rcloneexplorer.Dialogs.FilePropertiesDialog;
@@ -90,7 +91,8 @@ public class FileExplorerFragment extends Fragment implements FileExplorerRecy
9091
OpenAsDialog.OnClickListener,
9192
InputDialog.OnPositive,
9293
GoToDialog.Callbacks,
93-
SortDialog.OnClickListener {
94+
SortDialog.OnClickListener,
95+
ServeDialog.Callback {
9496

9597
private static final String ARG_REMOTE = "remote_param";
9698
private static final String SHARED_PREFS_SORT_ORDER = "ca.pkay.rcexplorer.sort_order";
@@ -593,34 +595,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
593595
recyclerViewAdapter.toggleSelectAll();
594596
return true;
595597
case R.id.action_serve:
596-
String[] serveOptions = new String[] {"HTTP", "Webdav"};
597-
AlertDialog.Builder builder = new AlertDialog.Builder(context);
598-
builder.setItems(serveOptions, new DialogInterface.OnClickListener() {
599-
@Override
600-
public void onClick(DialogInterface dialog, int which) {
601-
Intent intent = new Intent(getContext(), StreamingService.class);
602-
switch (which) {
603-
case 0: // HTTP
604-
intent.putExtra(StreamingService.SERVE_PATH_ARG, directoryObject.getCurrentPath());
605-
intent.putExtra(StreamingService.REMOTE_ARG, remote);
606-
intent.putExtra(StreamingService.SERVE_PROTOCOL, StreamingService.SERVE_HTTP);
607-
intent.putExtra(StreamingService.SHOW_NOTIFICATION_TEXT, true);
608-
break;
609-
case 1: // Webdav
610-
intent.putExtra(StreamingService.SERVE_PATH_ARG, directoryObject.getCurrentPath());
611-
intent.putExtra(StreamingService.REMOTE_ARG, remote);
612-
intent.putExtra(StreamingService.SERVE_PROTOCOL, StreamingService.SERVE_WEBDAV);
613-
intent.putExtra(StreamingService.SHOW_NOTIFICATION_TEXT, true);
614-
break;
615-
default:
616-
return;
617-
}
618-
context.startService(intent);
619-
}
620-
});
621-
builder.setTitle(R.string.pick_a_protocol);
622-
builder.show();
623-
598+
serve();
624599
return true;
625600
case R.id.action_empty_trash:
626601
emptyTrash();
@@ -650,6 +625,36 @@ public void onClick(DialogInterface dialog, int which) {
650625
}
651626
}
652627

628+
private void serve() {
629+
ServeDialog serveDialog = new ServeDialog();
630+
serveDialog.setDarkTheme(isDarkTheme);
631+
serveDialog.show(getChildFragmentManager(), "serve dialog");
632+
}
633+
634+
// serve callback
635+
@Override
636+
public void onServeOptionsSelected(int protocol, boolean allowRemoteAccess, String user, String password) {
637+
Intent intent = new Intent(getContext(), StreamingService.class);
638+
intent.putExtra(StreamingService.SERVE_PATH_ARG, directoryObject.getCurrentPath());
639+
intent.putExtra(StreamingService.REMOTE_ARG, remote);
640+
intent.putExtra(StreamingService.SHOW_NOTIFICATION_TEXT, true);
641+
intent.putExtra(StreamingService.ALLOW_REMOTE_ACCESS, allowRemoteAccess);
642+
intent.putExtra(StreamingService.AUTHENTICATION_USERNAME, user);
643+
intent.putExtra(StreamingService.AUTHENTICATION_PASSWORD, password);
644+
645+
switch (protocol) {
646+
case Rclone.SERVE_PROTOCOL_HTTP: // HTTP
647+
intent.putExtra(StreamingService.SERVE_PROTOCOL, StreamingService.SERVE_HTTP);
648+
break;
649+
case Rclone.SERVE_PROTOCOL_WEBDAV: // Webdav
650+
intent.putExtra(StreamingService.SERVE_PROTOCOL, StreamingService.SERVE_WEBDAV);
651+
break;
652+
default:
653+
return;
654+
}
655+
context.startService(intent);
656+
}
657+
653658
private void emptyTrash() {
654659
AlertDialog.Builder builder;
655660

app/src/main/java/ca/pkay/rcloneexplorer/Rclone.java

+32-18
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@
3333

3434
public class Rclone {
3535

36-
public static int SYNC_DIRECTION_LOCAL_TO_REMOTE = 1;
37-
public static int SYNC_DIRECTION_REMOTE_TO_LOCAL = 2;
36+
public static final int SYNC_DIRECTION_LOCAL_TO_REMOTE = 1;
37+
public static final int SYNC_DIRECTION_REMOTE_TO_LOCAL = 2;
38+
public static final int SERVE_PROTOCOL_HTTP = 1;
39+
public static final int SERVE_PROTOCOL_WEBDAV = 2;
3840
private Context context;
3941
private String rclone;
4042
private String rcloneConf;
@@ -353,37 +355,49 @@ public String obscure(String pass) {
353355
}
354356
}
355357

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

362-
try {
363-
return Runtime.getRuntime().exec(command);
364-
} catch (IOException e) {
365-
e.printStackTrace();
366-
return null;
363+
String commandProtocol = protocol == SERVE_PROTOCOL_HTTP ? "http" : "webdav";
364+
String address;
365+
if (allowRemoteAccess) {
366+
address = ":" + String.valueOf(port);
367+
} else {
368+
address = "127.0.0.1:" + String.valueOf(port);
367369
}
368-
}
369-
370-
public Process serveWebdav(RemoteItem remote, String servePath, int port) {
371-
String remoteName = remote.getName();
372-
String localRemotePath = (remote.isRemoteType(RemoteItem.LOCAL)) ? Environment.getExternalStorageDirectory().getAbsolutePath() + "/" : "";
373-
String path = (servePath.compareTo("//" + remoteName) == 0) ? remoteName + ":" + localRemotePath : remoteName + ":" + localRemotePath + servePath;
374-
String[] command = createCommandWithOptions("serve", "webdav", "--addr", ":" + String.valueOf(port), path);
375-
376370
String cachePath = context.getCacheDir().getAbsolutePath();
377371
String[] environmentalVariables = {"TMPDIR=" + cachePath}; // this is a fix for #199
378372

373+
String[] command;
374+
375+
if (user == null && password != null) {
376+
command = createCommandWithOptions("serve", commandProtocol, "--addr", address, path, "--pass", password);
377+
} else if (user != null && password == null) {
378+
command = createCommandWithOptions("serve", commandProtocol, "--addr", address, path, "--user", user);
379+
} else if (user != null) {
380+
command = createCommandWithOptions("serve", commandProtocol, "--addr", address, path, "--user", user, "--pass", password);
381+
} else {
382+
command = createCommandWithOptions("serve", commandProtocol, "--addr", address, path);
383+
}
384+
379385
try {
380-
return Runtime.getRuntime().exec(command, environmentalVariables);
386+
if (protocol == SERVE_PROTOCOL_WEBDAV) {
387+
return Runtime.getRuntime().exec(command, environmentalVariables);
388+
} else {
389+
return Runtime.getRuntime().exec(command);
390+
}
381391
} catch (IOException e) {
382392
e.printStackTrace();
383393
return null;
384394
}
385395
}
386396

397+
public Process serve(int protocol, int port, boolean localhostOnly, RemoteItem remote, String servePath) {
398+
return serve(protocol, port, localhostOnly, null, null, remote, servePath);
399+
}
400+
387401
public Process sync(RemoteItem remoteItem, String remote, String localPath, int syncDirection) {
388402
String[] command;
389403
String remoteName = remoteItem.getName();

app/src/main/java/ca/pkay/rcloneexplorer/RemoteConfig/DriveConfig.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ private void scopeSet(int selectedScope) {
240240
break;
241241
}
242242

243-
scope.setText("scrope: \"" + scopeString + "\"");
243+
scope.setText("scope: \"" + scopeString + "\"");
244244
}
245245

246246
private void setUpRemote() {

app/src/main/java/ca/pkay/rcloneexplorer/Services/StreamingService.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ public class StreamingService extends IntentService {
2323
public static final String REMOTE_ARG = "ca.pkay.rcexplorer.streaming_service.arg2";
2424
public static final String SHOW_NOTIFICATION_TEXT = "ca.pkay.rcexplorer.streaming_service.arg3";
2525
public static final String SERVE_PROTOCOL = "ca.pkay.rcexplorer.serve_protocol";
26+
public static final String ALLOW_REMOTE_ACCESS = "ca.pkay.rcexplorer.allow_remote_access";
27+
public static final String AUTHENTICATION_USERNAME = "ca.pkay.rcexplorer.username";
28+
public static final String AUTHENTICATION_PASSWORD = "ca.pkay.rcexplorer.password";
2629
public static final int SERVE_HTTP = 11;
2730
public static final int SERVE_WEBDAV = 12;
2831
private final String CHANNEL_ID = "ca.pkay.rcexplorer.streaming_channel";
@@ -54,6 +57,9 @@ protected void onHandleIntent(@Nullable Intent intent) {
5457
final RemoteItem remote = intent.getParcelableExtra(REMOTE_ARG);
5558
final Boolean showNotificationText = intent.getBooleanExtra(SHOW_NOTIFICATION_TEXT, false);
5659
final int protocol = intent.getIntExtra(SERVE_PROTOCOL, SERVE_HTTP);
60+
final Boolean allowRemoteAccess = intent.getBooleanExtra(ALLOW_REMOTE_ACCESS, false);
61+
final String authenticationUsername = intent.getStringExtra(AUTHENTICATION_USERNAME);
62+
final String authenticationPassword = intent.getStringExtra(AUTHENTICATION_PASSWORD);
5763

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

8288
switch (protocol) {
8389
case SERVE_WEBDAV:
84-
runningProcess = rclone.serveWebdav(remote, servePath, 8080);
90+
runningProcess = rclone.serve(Rclone.SERVE_PROTOCOL_WEBDAV, 8080, allowRemoteAccess, authenticationUsername, authenticationPassword, remote, servePath);
8591
break;
8692
case SERVE_HTTP:
8793
default:
88-
runningProcess = rclone.serveHttp(remote, servePath, 8080);
94+
runningProcess = rclone.serve(Rclone.SERVE_PROTOCOL_HTTP, 8080, allowRemoteAccess, authenticationUsername, authenticationPassword, remote, servePath);
8995
break;
9096
}
9197

app/src/main/java/ca/pkay/rcloneexplorer/Services/ThumbnailsLoadingService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ protected void onHandleIntent(@Nullable Intent intent) {
3030
}
3131

3232
RemoteItem remote = intent.getParcelableExtra(REMOTE_ARG);
33-
process = rclone.serveHttp(remote, "", 29170);
33+
process = rclone.serve(Rclone.SERVE_PROTOCOL_HTTP, 29170, true, remote, "");
3434
if (process != null) {
3535
try {
3636
process.waitFor();

0 commit comments

Comments
 (0)