Code clean up, Download folder name escaping, LoginListener Bug

This commit is contained in:
Caesar2011
2018-10-21 00:42:42 +02:00
parent e70daa33cc
commit abdc4695e9
10 changed files with 121 additions and 115 deletions

View File

@@ -297,8 +297,7 @@ public class MainActivity extends AppCompatActivity
toLogoutState();
return;
}
String[] id = new String[1];
id[0] = "";
String[] id = {""};
int fragment = getDefaultFragmentAfterLogin(id);
this.getKVV().login(credentials.getUsername(), credentials.getPassword(), success -> toLoginState(success, fragment , id[0]),
@@ -316,16 +315,18 @@ public class MainActivity extends AppCompatActivity
private void changeFragment(int newFragment, String newData) {
if (mFragmentManager.isStateSaved())
return;
if (newFragment == FRAGMENT_CANTEENS_DETAILS && newData.equals(""))
newFragment = FRAGMENT_CANTEENS;
if (newFragment == FRAGMENT_MODULES_DETAILS && newData.equals(""))
newFragment = FRAGMENT_MODULES;
//log.d("changeFragment: ", newFragment, newData);
onTitleTextChange(R.string.app_name);
Fragment fragment;
switch (newFragment) {
case FRAGMENT_MODULES_DETAILS:
if (!newData.equals("")) {
fragment = ModDetailFragment.newInstance(newData);
break;
}
fragment = ModDetailFragment.newInstance(newData);
break;
case FRAGMENT_MODULES:
fragment = ModulesFragment.newInstance();
break;
@@ -336,10 +337,8 @@ public class MainActivity extends AppCompatActivity
fragment = ScheduleFragment.newInstance();
break;
case FRAGMENT_CANTEENS_DETAILS:
if (!newData.equals("")) {
fragment = DaySwitcherFragment.newInstance(Integer.parseInt(newData));
break;
}
fragment = DaySwitcherFragment.newInstance(Integer.parseInt(newData));
break;
case FRAGMENT_CANTEENS:
fragment = CanteensFragment.newInstance();
break;
@@ -474,7 +473,9 @@ public class MainActivity extends AppCompatActivity
public void onLoginFragmentInteraction(LoginToken loginToken, boolean onlineMode) {
toLoginState(loginToken.getFullname(), loginToken.getEmail(), getDefaultFragmentAfterLogin(), "", onlineMode);
String[] id = {""};
int fragment = getDefaultFragmentAfterLogin(id);
toLoginState(loginToken.getFullname(), loginToken.getEmail(), fragment, id[0], onlineMode);
}
@Override
@@ -504,7 +505,7 @@ public class MainActivity extends AppCompatActivity
}
@Override
public void refreshFailed(boolean isFailed) {
public void onRefreshCompleted(boolean isFailed) {
setRefreshFailedBanner(isFailed);
}

View File

@@ -105,7 +105,7 @@ public class ModDetailResourceFragment extends Fragment {
kvv.getModule(mItemPos, (Modules.Module module) -> {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getContext());
Resource.File file = (Resource.File) node.getContent();
String folderName = "FU-"+module.title;
String folderName = "FU-"+module.title.replaceAll("[:*<>|/\"\\\\]", "-");
File f = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS)+"/"+folderName+"/"+file.getTitle());
alertDialogBuilder

View File

@@ -225,7 +225,7 @@ public class CanteenBrowser extends HTTPService {
private<T> NetworkCallback<T> saveOnCallback(NetworkCallback<T> callback, boolean forceRefresh){
return (success -> {
if (forceRefresh)
mListener.refreshFailed(false);
mListener.onRefreshCompleted(false);
callback.onResponse(success);
});
}
@@ -235,7 +235,7 @@ public class CanteenBrowser extends HTTPService {
if (error.getHttpStatus() == 401 || error.getHttpStatus() == 403)
mListener.loginTokenInvalid(false);
else
mListener.refreshFailed(true);
mListener.onRefreshCompleted(true);
errorCallback.onError(error);
});
}

View File

@@ -169,7 +169,7 @@ public class KVV {
e.printStackTrace();
}
if (forceRefresh)
mListener.refreshFailed(false);
mListener.onRefreshCompleted(false);
callback.onResponse(success);
});
}
@@ -179,7 +179,7 @@ public class KVV {
if (error.getHttpStatus() == 401 || error.getHttpStatus() == 403)
mListener.loginTokenInvalid(false);
else
mListener.refreshFailed(true);
mListener.onRefreshCompleted(true);
errorCallback.onError(error);
});
}

View File

@@ -16,17 +16,17 @@ import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkError;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
import static de.sebse.fuplanner.services.KVV.TestLogin.testLogin;
/**
* Created by sebastian on 24.10.17.
*/
class KVVLogin extends HTTPService {
private final Context mContext;
private LoginToken loginToken;
KVVLogin(Context context) {
super(context, false);
this.mContext = context;
try {
this.loginToken = LoginToken.load(context);
} catch (IOException e) {
@@ -36,14 +36,14 @@ class KVVLogin extends HTTPService {
}
}
public LoginToken easyLogin() {
LoginToken easyLogin() {
return this.loginToken;
}
public void login(String username, String password, NetworkCallback<LoginToken> callback, NetworkErrorCallback errorCallback) {
void login(String username, String password, NetworkCallback<LoginToken> callback, NetworkErrorCallback errorCallback) {
if (this.loginToken != null) {
if (this.loginToken.getUsername().equals(username)) {
testLogin(this.loginToken, success -> callback.onResponse(this.loginToken), error -> {
testLogin(getContext(), this.loginToken, success -> callback.onResponse(this.loginToken), error -> {
this.loginToken = null;
login(username, password, callback, errorCallback);
});
@@ -54,19 +54,19 @@ class KVVLogin extends HTTPService {
} else {
doLogin(username, password, token -> {
this.loginToken = token;
testLogin(this.loginToken, success -> callback.onResponse(this.loginToken), errorCallback);
testLogin(getContext(), this.loginToken, success -> callback.onResponse(this.loginToken), errorCallback);
}, errorCallback);
}
}
public void deleteOffline() {
void deleteOffline() {
if (this.loginToken != null)
this.loginToken.delete(mContext);
this.loginToken.delete(getContext());
}
public void saveOffline() throws IOException {
void saveOffline() throws IOException {
if (this.loginToken != null)
this.loginToken.save(mContext);
this.loginToken.save(getContext());
}
@@ -92,21 +92,6 @@ class KVVLogin extends HTTPService {
}, error);
}
private void testLogin(LoginToken loginToken, NetworkCallback<LoginToken> callback, NetworkErrorCallback errorCallback) {
get(String.format("https://kvv.imp.fu-berlin.de/direct/profile/%s.json", loginToken.getUsername()), loginToken.getCookies(), response -> {
String body = response.getParsed();
try {
JSONObject json = new JSONObject(body);
String displayName = json.getString("displayName");
String email = json.getString("email");
loginToken.setAdditionals(displayName, email);
callback.onResponse(loginToken);
} catch (JSONException e) {
errorCallback.onError(new NetworkError(100201, 403, "Cannot parse profile!"));
}
}, error -> errorCallback.onError(new NetworkError(100200, error.networkResponse.statusCode, "Testing login failed!")));
}
/*
GET https://kvv.imp.fu-berlin.de/portal/login
-> JSESSIONID 5c10406f-588c-4c16-96e9-c80d115417de.tomcat1

View File

@@ -36,6 +36,8 @@ import de.sebse.fuplanner.tools.network.NetworkError;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
import de.sebse.fuplanner.tools.network.Result;
import static de.sebse.fuplanner.services.KVV.TestLogin.testLogin;
/**
* Created by sebastian on 29.10.17.
*/
@@ -62,7 +64,7 @@ class KVVModuleList extends HTTPService {
public void getModuleList(final NetworkCallback<Modules> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
void getModuleList(final NetworkCallback<Modules> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
queueModuleDetails.add("list", () -> {
if (this.moduleList != null && !forceRefresh) {
callback.onResponse(this.moduleList);
@@ -126,23 +128,23 @@ class KVVModuleList extends HTTPService {
}
// Empty module *may be* because token is invalid -> check
if (modules.size() == 0)
testLogin(token, token -> callback.onResponse(modules), errorCallback);
testLogin(getContext(), token, token -> callback.onResponse(modules), errorCallback);
else
callback.onResponse(modules);
}, error -> errorCallback.onError(new NetworkError(101104, error.networkResponse.statusCode, "Cannot get module list!")));
}
public void deleteModulesOffline(Context context) {
void deleteModulesOffline(Context context) {
if (this.moduleList != null)
this.moduleList.delete(context);
}
public void saveModulesOffline(Context context) throws IOException {
void saveModulesOffline(Context context) throws IOException {
if (this.moduleList != null)
this.moduleList.save(context);
}
public void getModule(String id, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
void getModule(String id, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
this.getModuleList(success -> {
callback.onResponse(success.get(id));
}, errorCallback, forceRefresh);
@@ -153,7 +155,7 @@ class KVVModuleList extends HTTPService {
public void getModuleDetails(Modules.Module module, final NetworkCallback<Pair<Modules.Module, Boolean>> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
void getModuleDetails(Modules.Module module, final NetworkCallback<Pair<Modules.Module, Boolean>> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
AtomicInteger returns = new AtomicInteger(0);
AtomicReference<NetworkError> lastError = new AtomicReference<>(null);
final AtomicInteger items = new AtomicInteger(0);
@@ -193,7 +195,7 @@ class KVVModuleList extends HTTPService {
public void getAnnouncements(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
void getAnnouncements(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
queueModuleDetails.add(module.getID(), () -> {
if (module.announcements != null && !forceRefresh) {
callback.onResponse(module);
@@ -252,7 +254,7 @@ class KVVModuleList extends HTTPService {
}
// Empty announcements *may be* because token is invalid -> check
if (announcements.size() == 0)
testLogin(token, token -> callback.onResponse(announcements), errorCallback);
testLogin(getContext(), token, token -> callback.onResponse(announcements), errorCallback);
else
callback.onResponse(announcements);
}, error -> errorCallback.onError(new NetworkError(101203, error.networkResponse.statusCode, "Cannot get announcements!")));
@@ -262,7 +264,7 @@ class KVVModuleList extends HTTPService {
public void getAssignments(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
void getAssignments(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
queueModuleDetails.add(module.getID(), () -> {
if (module.assignments != null && !forceRefresh) {
callback.onResponse(module);
@@ -316,7 +318,7 @@ class KVVModuleList extends HTTPService {
}
// Empty assignments *may be* because token is invalid -> check
if (assignments.size() == 0)
testLogin(token, token -> callback.onResponse(assignments), errorCallback);
testLogin(getContext(), token, token -> callback.onResponse(assignments), errorCallback);
else
callback.onResponse(assignments);
}, error -> errorCallback.onError(new NetworkError(101303, error.networkResponse.statusCode, "Cannot get assignments!")));
@@ -329,7 +331,7 @@ class KVVModuleList extends HTTPService {
public void getEvents(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
void getEvents(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
queueModuleDetails.add(module.getID(), () -> {
if (module.events != null && !forceRefresh) {
callback.onResponse(module);
@@ -379,7 +381,7 @@ class KVVModuleList extends HTTPService {
events.sort();
// Empty events *may be* because token is invalid -> check
if (events.size() == 0)
testLogin(token, token -> callback.onResponse(events), errorCallback);
testLogin(getContext(), token, token -> callback.onResponse(events), errorCallback);
else
callback.onResponse(events);
}, error -> errorCallback.onError(new NetworkError(101403, error.networkResponse.statusCode, "Cannot get calendar entries!")));
@@ -389,7 +391,7 @@ class KVVModuleList extends HTTPService {
public void getGradebook(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
void getGradebook(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
queueModuleDetails.add(module.getID(), () -> {
if (module.gradebook != null && !forceRefresh) {
callback.onResponse(module);
@@ -512,7 +514,7 @@ class KVVModuleList extends HTTPService {
// Empty resources *may be* because token is invalid -> check
if (root.size() == 0)
testLogin(token, token -> callback.onResponse(root), errorCallback);
testLogin(getContext(), token, token -> callback.onResponse(root), errorCallback);
else
callback.onResponse(root);
@@ -520,7 +522,7 @@ class KVVModuleList extends HTTPService {
}
public void getResourceFile( final NetworkCallback<String> callback, final NetworkErrorCallback errorCallback, String Filename, String url, String moduleName, boolean downloadNew) {
void getResourceFile(final NetworkCallback<String> callback, final NetworkErrorCallback errorCallback, String Filename, String url, String moduleName, boolean downloadNew) {
if (isExternalStorageReadable()){
File f = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS)+"/"+moduleName+"/"+Filename);
@@ -529,13 +531,10 @@ class KVVModuleList extends HTTPService {
return;
}
}
getResourceFileUpgrade(Filename, url , moduleName, success -> {
callback.onResponse(success);
}, errorCallback);
//});
getResourceFileUpgrade(Filename, url , moduleName, callback, errorCallback);
}
private void getResourceFileUpgrade(String Filename, String url , String moduleName, final NetworkCallback<String> callback, final NetworkErrorCallback errorCallback) {
private void getResourceFileUpgrade(String filename, String url , String moduleName, final NetworkCallback<String> callback, final NetworkErrorCallback errorCallback) {
if (token == null) {
errorCallback.onError(new NetworkError(101701, 500, "Currently running in offline mode!"));
return;
@@ -543,34 +542,33 @@ class KVVModuleList extends HTTPService {
get(url, token.getCookies(), response ->{
final String[] pfad = {""};
if (Regex.has("\\.[Uu][Rr][Ll]$", url)){//für Links
if (response.getHeaders().get("Location") != null){
pfad[0] = response.getHeaders().get("Location");
if (Regex.has("\\.[Uu][Rr][Ll]$", url)){
// Return redirected URL
String path = response.getHeaders().get("Location");
if (path == null){
path = "";
}
callback.onResponse(pfad[0]);
}
else if (response.getBytes()==null){
testLogin(token, token -> {
callback.onResponse(path);
} else if (response.getBytes()==null){
testLogin(getContext(), token, token -> {
if (isExternalStorageWritable()) {
get(url, token.getCookies(), response2 ->{//probiern die Datei erneut zu laden
pfad[0] = saveFileInDownloads(Filename, response2, moduleName);
callback.onResponse(pfad[0]);
}, error -> errorCallback.onError(new NetworkError(101705, error.networkResponse.statusCode, "Cannot get File!")));
// try to download file again
get(url, token.getCookies(), response2 -> {
String path = saveFileInDownloads(filename, response2, moduleName);
callback.onResponse(path);
}, error -> errorCallback.onError(new NetworkError(101705, error.networkResponse.statusCode, "Cannot get file!")));
} else {
errorCallback.onError(new NetworkError(101703, 403, "Exgternal storage not writeable!"));
errorCallback.onError(new NetworkError(101703, 403, "External storage not writable!"));
}
}, errorCallback);
}
else if (isExternalStorageWritable()) {
pfad[0] = saveFileInDownloads(Filename, response, moduleName);
callback.onResponse(pfad[0]);
} else if (isExternalStorageWritable()) {
String path = saveFileInDownloads(filename, response, moduleName);
callback.onResponse(path);
} else {
errorCallback.onError(new NetworkError(101704, 403, "Exgternal storage not writeable!"));
errorCallback.onError(new NetworkError(101704, 403, "External storage not writable!"));
}
}, error -> errorCallback.onError(new NetworkError(101702, error.networkResponse.statusCode, "Cannot get File!")));
}, error -> errorCallback.onError(new NetworkError(101702, error.networkResponse.statusCode, "Cannot get file!")));
}
@@ -581,26 +579,8 @@ class KVVModuleList extends HTTPService {
// TODO Better, more elegant solution than duplicate code KVVLogin
private void testLogin(LoginToken loginToken, NetworkCallback<LoginToken> callback, NetworkErrorCallback errorCallback) {
get(String.format("https://kvv.imp.fu-berlin.de/direct/profile/%s.json", loginToken.getUsername()), loginToken.getCookies(), response -> {
String body = response.getParsed();
try {
JSONObject json = new JSONObject(body);
String displayName = json.getString("displayName");
String email = json.getString("email");
loginToken.setAdditionals(displayName, email);
callback.onResponse(loginToken);
} catch (JSONException e) {
errorCallback.onError(new NetworkError(100201, 403, "Cannot parse profile!"));
}
}, error -> errorCallback.onError(new NetworkError(100200, error.networkResponse.statusCode, "Testing login failed!")));
}
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
private boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
@@ -610,7 +590,7 @@ class KVVModuleList extends HTTPService {
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
private boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
@@ -619,25 +599,25 @@ class KVVModuleList extends HTTPService {
log.w("File system: Reading not possible!");
return false;
}
public String saveFileInDownloads(String filename, Result datei, String moduleName) {
//Speichert Datei im Ordner DOWNLOADS/moduleName
File ordner = new File(Environment.getExternalStoragePublicDirectory(
private String saveFileInDownloads(String filename, Result fileResult, String moduleName) {
// Saves file in folder: DOWNLOADS/moduleName
File folder = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), moduleName);
if (!ordner.mkdir()) {
if (!folder.mkdir()) {
log.w( "Directory not created");
}
String pfad="";
String path = "";
try {
//todo eventuel prüfen ob genügend speicher noch vorhanden ist
FileOutputStream out = new FileOutputStream(ordner.getPath()+"/"+filename);
out.write(datei.getBytes());
// TODO check if enough storage space is available
FileOutputStream out = new FileOutputStream(folder.getPath()+"/"+filename);
out.write(fileResult.getBytes());
out.close();
pfad=ordner.getPath()+"/"+filename;
path = folder.getPath()+"/"+filename;
} catch (Exception e) {
log.w("File not saved!");
e.printStackTrace();
}
return pfad;
return path;
}

View File

@@ -0,0 +1,34 @@
package de.sebse.fuplanner.services.KVV;
import android.content.Context;
import org.json.JSONException;
import org.json.JSONObject;
import de.sebse.fuplanner.services.KVV.types.LoginToken;
import de.sebse.fuplanner.tools.network.HTTPService;
import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkError;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
final class TestLogin extends HTTPService {
private TestLogin(Context context) {
super(context);
}
static void testLogin(Context context, LoginToken loginToken, NetworkCallback<LoginToken> callback, NetworkErrorCallback errorCallback) {
new TestLogin(context).get(String.format("https://kvv.imp.fu-berlin.de/direct/profile/%s.json", loginToken.getUsername()), loginToken.getCookies(), response -> {
String body = response.getParsed();
try {
JSONObject json = new JSONObject(body);
String displayName = json.getString("displayName");
String email = json.getString("email");
loginToken.setAdditionals(displayName, email);
callback.onResponse(loginToken);
} catch (JSONException e) {
errorCallback.onError(new NetworkError(100201, 403, "Cannot parse profile!"));
}
}, error -> errorCallback.onError(new NetworkError(100200, error.networkResponse.statusCode, "Testing login failed!")));
}
}

View File

@@ -17,7 +17,7 @@ public interface MainActivityListener {
void loginTokenInvalid(boolean doPrecheck);
void refreshFailed(boolean isFailed);
void onRefreshCompleted(boolean isFailed);
CanteenBrowser getCanteenBrowser();

View File

@@ -25,6 +25,7 @@ import de.sebse.fuplanner.tools.logging.Logger;
public class HTTPService {
private final RequestQueue requestQueue;
private final Context mContext;
protected Logger log = new Logger(this);
protected HTTPService(Context context) {
@@ -32,6 +33,7 @@ public class HTTPService {
}
protected HTTPService(Context context, boolean followRedirects) {
this.mContext = context;
requestQueue = Volley.newRequestQueue(context, new BetterHurlStack(followRedirects));
}
@@ -149,4 +151,8 @@ public class HTTPService {
};
requestQueue.add(request);
}
protected Context getContext() {
return mContext;
}
}