Offline login implemented

This commit is contained in:
Caesar2011
2018-07-08 15:54:44 +02:00
parent b49a3d01da
commit d353353d3a
10 changed files with 162 additions and 118 deletions

View File

@@ -75,16 +75,16 @@ public class MainActivity extends AppCompatActivity
getGoogleAuth().getLoginState(credentials -> {
if (credentials == null || credentials.getUsername() == null || credentials.getPassword() == null) {
MainActivity.this.getKVV().endUpdate();
changeLoginState(null);
toLogoutState();
return;
}
MainActivity.this.getKVV().login(credentials.getUsername(), credentials.getPassword(), success -> {
MainActivity.this.getKVV().endUpdate();
changeLoginState(credentials);
toLoginState(credentials);
}, error -> {
log.e(error);
MainActivity.this.getKVV().endUpdate();
changeLoginState(null);
toLogoutState();
});
});
});
@@ -149,7 +149,7 @@ public class MainActivity extends AppCompatActivity
if (credentials != null) {
MainActivity.this.getGoogleAuth().deleteLoginState(credentials.getUsername(), credentials.getPassword());
}
MainActivity.this.changeLoginState(null);
MainActivity.this.toLogoutState();
});
break;
}
@@ -187,56 +187,60 @@ public class MainActivity extends AppCompatActivity
return this.mKVV;
}
private void changeLoginState(Credentials credentials) {
log.d("change login state");
private void toLoginState(Credentials credentials) {
if (credentials == null) {
log.d("null");
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragcontainer, LoginFragment.newInstance());
fragmentTransaction.commit();
findViewById(R.id.app_bar_layout).setVisibility(View.VISIBLE);
NavigationView navigationView = findViewById(R.id.nav_view);
View header = navigationView.getHeaderView(0);
header.findViewById(R.id.imageView).setVisibility(View.GONE);
header.findViewById(R.id.login_name).setVisibility(View.GONE);
header.findViewById(R.id.login_page).setVisibility(View.VISIBLE);
navigationView.getMenu().clear();
navigationView.inflateMenu(R.menu.activity_main_drawer);
toLogoutState();
} else {
log.d(credentials.getUsername());
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragcontainer, ModulesFragment.newInstance());
fragmentTransaction.commit();
findViewById(R.id.app_bar_layout).setVisibility(View.VISIBLE);
final NavigationView navigationView = findViewById(R.id.nav_view);
View header = navigationView.getHeaderView(0);
header.findViewById(R.id.imageView).setVisibility(View.VISIBLE);
header.findViewById(R.id.login_name).setVisibility(View.VISIBLE);
header.findViewById(R.id.login_page).setVisibility(View.GONE);
navigationView.getMenu().clear();
navigationView.inflateMenu(R.menu.activity_main_drawer_login);
navigationView.setCheckedItem(R.id.nav_modules);
getKVV().getModuleList(success -> {
log.d("Modules.get", success.size());
//SubMenu moduleMenu = navigationView.getMenu().findItem(R.id.nav_modules).getSubMenu();
int i = 0;
for (Iterator<Modules.Module> it = success.latestSemesterIterator(); it.hasNext(); ) {
Modules.Module module = it.next();
MenuItem menuItem = navigationView.getMenu().add(Menu.NONE, Menu.NONE, 101 + i, module.title);
final int finalI = i;
menuItem.setOnMenuItemClickListener(item -> {
onModulesFragmentInteraction(finalI);
return false;
});
i++;
}
}, error -> log.d("Modules.error", error));
toLoginState(credentials.getUsername());
}
}
private void toLogoutState() {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragcontainer, LoginFragment.newInstance());
fragmentTransaction.commit();
findViewById(R.id.app_bar_layout).setVisibility(View.VISIBLE);
NavigationView navigationView = findViewById(R.id.nav_view);
View header = navigationView.getHeaderView(0);
header.findViewById(R.id.imageView).setVisibility(View.GONE);
header.findViewById(R.id.login_name).setVisibility(View.GONE);
header.findViewById(R.id.login_page).setVisibility(View.VISIBLE);
navigationView.getMenu().clear();
navigationView.inflateMenu(R.menu.activity_main_drawer);
}
private void toLoginState(String username) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragcontainer, ModulesFragment.newInstance());
fragmentTransaction.commit();
findViewById(R.id.app_bar_layout).setVisibility(View.VISIBLE);
final NavigationView navigationView = findViewById(R.id.nav_view);
View header = navigationView.getHeaderView(0);
header.findViewById(R.id.imageView).setVisibility(View.VISIBLE);
header.findViewById(R.id.login_name).setVisibility(View.VISIBLE);
header.findViewById(R.id.login_page).setVisibility(View.GONE);
navigationView.getMenu().clear();
navigationView.inflateMenu(R.menu.activity_main_drawer_login);
navigationView.setCheckedItem(R.id.nav_modules);
getKVV().getModuleList(success -> {
log.d("Modules.get", success.size());
//SubMenu moduleMenu = navigationView.getMenu().findItem(R.id.nav_modules).getSubMenu();
int i = 0;
for (Iterator<Modules.Module> it = success.latestSemesterIterator(); it.hasNext(); ) {
Modules.Module module = it.next();
MenuItem menuItem = navigationView.getMenu().add(Menu.NONE, Menu.NONE, 101 + i, module.title);
final int finalI = i;
menuItem.setOnMenuItemClickListener(item -> {
onModulesFragmentInteraction(finalI);
return false;
});
i++;
}
}, error -> log.e("Modules.error", error));
}
@@ -248,8 +252,8 @@ public class MainActivity extends AppCompatActivity
@Override
public void onLoginFragmentInteraction(Credentials credentials) {
changeLoginState(credentials);
public void onLoginFragmentInteraction(String username) {
toLoginState(username);
}
@Override

View File

@@ -8,13 +8,17 @@ import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import java.io.IOException;
import de.sebse.fuplanner.MainActivity;
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.services.GoogleAuth.Credentials;
import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth;
import de.sebse.fuplanner.services.KVV.KVV;
import de.sebse.fuplanner.services.KVV.types.Modules;
import de.sebse.fuplanner.tools.logging.Logger;
/**
@@ -26,11 +30,6 @@ import de.sebse.fuplanner.tools.logging.Logger;
* create an instance of this fragment.
*/
public class LoginFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
// TODO: Rename and change types of parameters
private OnLoginFragmentInteractionListener mListener;
private Logger log = new Logger(this);
@@ -44,7 +43,6 @@ public class LoginFragment extends Fragment {
*
* @return A new instance of fragment LoginFragment.
*/
// TODO: Rename and change types and number of parameters
public static LoginFragment newInstance() {
LoginFragment fragment = new LoginFragment();
Bundle args = new Bundle();
@@ -61,47 +59,57 @@ public class LoginFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_login, container, false);
View btn_login = v.findViewById(R.id.btn_login);
if (btn_login != null) {
btn_login.setOnClickListener(view -> {
final ProgressDialog progressDialog = new ProgressDialog(LoginFragment.this.getContext(),
R.style.FUTheme_Dialog);
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Authenticating...");
progressDialog.show();
EditText input_usr = ((View) view.getParent()).findViewById(R.id.input_username);
EditText input_pwd = ((View) view.getParent()).findViewById(R.id.input_password);
if (input_usr != null) {
if (input_pwd != null) {
if (LoginFragment.this.getActivity() == null) {
log.e("Login fragment has no activity!");
return;
}
final String username = input_usr.getText().toString();
final String password = input_pwd.getText().toString();
final KVV kvv = ((MainActivity) LoginFragment.this.getActivity()).getKVV();
final GoogleAuth gauth = ((MainActivity) LoginFragment.this.getActivity()).getGoogleAuth();
kvv.login(username, password, success -> {
progressDialog.dismiss();
log.d("success", success.toString());
gauth.setLoginState(username, password);
if (LoginFragment.this.mListener != null) {
Credentials cred = new Credentials(username, password);
LoginFragment.this.mListener.onLoginFragmentInteraction(cred);
}
}, error -> {
progressDialog.dismiss();
log.e("error", error);
});
}
try {
Context context = getContext();
if (context != null) {
Modules modules = Modules.load(context);
if (modules != null) {
Button offline_btn = v.findViewById(R.id.btn_offline);
offline_btn.setVisibility(View.VISIBLE);
offline_btn.setText(v.getResources().getString(R.string.enter_offline_mode, modules.getUsername()));
offline_btn.setOnClickListener(v1 -> mListener.onLoginFragmentInteraction(modules.getUsername()));
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
View btn_login = v.findViewById(R.id.btn_login);
btn_login.setOnClickListener(view -> {
final ProgressDialog progressDialog = new ProgressDialog(LoginFragment.this.getContext(),
R.style.FUTheme_Dialog);
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Authenticating...");
progressDialog.show();
EditText input_usr = ((View) view.getParent()).findViewById(R.id.input_username);
EditText input_pwd = ((View) view.getParent()).findViewById(R.id.input_password);
if (input_usr != null) {
if (input_pwd != null) {
if (LoginFragment.this.getActivity() == null) {
log.e("Login fragment has no activity!");
return;
}
String username = input_usr.getText().toString();
String password = input_pwd.getText().toString();
KVV kvv = ((MainActivity) getActivity()).getKVV();
GoogleAuth gauth = ((MainActivity) getActivity()).getGoogleAuth();
kvv.login(username, password, success -> {
progressDialog.dismiss();
gauth.setLoginState(username, password);
if (mListener != null)
mListener.onLoginFragmentInteraction(username);
}, error -> {
progressDialog.dismiss();
log.e("Error on KVV login!", error);
});
}
}
});
return v;
}
@@ -135,7 +143,6 @@ public class LoginFragment extends Fragment {
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnLoginFragmentInteractionListener {
// TODO: Update argument type and name
void onLoginFragmentInteraction(Credentials credentials);
void onLoginFragmentInteraction(String username);
}
}

View File

@@ -10,6 +10,7 @@ import java.util.HashMap;
import de.sebse.fuplanner.services.KVV.types.LoginToken;
import de.sebse.fuplanner.services.KVV.types.Modules;
import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
@@ -23,8 +24,10 @@ public class KVV {
private boolean isUpdating;
private ArrayList<LastTokenCallback> updatingList;
private HashMap<String, Object> addons = new HashMap<>();
private Logger log = new Logger(this);
public KVV(Context context) {
log.d("new kvv");
this.context = context;
this.isUpdating = false;
this.updatingList = new ArrayList<>();
@@ -42,7 +45,7 @@ public class KVV {
lastToken = null;
KVVModuleList modules = (KVVModuleList) addons.get("modules");
if (modules != null) {
modules.deleteModules(this.context);
modules.deleteModulesOffline(this.context);
}
addons.clear();
}
@@ -118,7 +121,7 @@ public class KVV {
private<T> NetworkCallback<T> saveOnCallback(KVVModuleList modules, NetworkCallback<T> callback){
return (success -> {
try {
modules.saveModules(this.context);
modules.saveModulesOffline(this.context);
} catch (IOException e) {
e.printStackTrace();
}

View File

@@ -46,7 +46,7 @@ public class KVVModuleList extends HTTPService {
this.token = token;
try {
Modules modules = Modules.load(context);
if (modules.getUsername().equals(token.getUsername()))
if (token == null || modules.getUsername().equals(token.getUsername()))
this.moduleList = modules;
} catch (IOException e) {
e.printStackTrace();
@@ -75,7 +75,11 @@ public class KVVModuleList extends HTTPService {
});
}
public void getModuleListUpgrade(final NetworkCallback<Modules> callback, final NetworkErrorCallback errorCallback) {
private void getModuleListUpgrade(final NetworkCallback<Modules> callback, final NetworkErrorCallback errorCallback) {
if (token == null) {
errorCallback.onError(new NetworkError(101105, 500, "Currently running in offline mode!"));
return;
}
get("https://kvv.imp.fu-berlin.de/direct/site.json", token.getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
@@ -117,12 +121,12 @@ public class KVVModuleList extends HTTPService {
}, error -> errorCallback.onError(new NetworkError(101104, error.networkResponse.statusCode, "Cannot get module list!")));
}
public void deleteModules(Context context) {
public void deleteModulesOffline(Context context) {
if (this.moduleList != null)
this.moduleList.delete(context);
}
public void saveModules(Context context) throws IOException {
public void saveModulesOffline(Context context) throws IOException {
if (this.moduleList != null)
this.moduleList.save(context);
}
@@ -139,11 +143,11 @@ public class KVVModuleList extends HTTPService {
public 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 int items = 4;
final AtomicInteger items = new AtomicInteger(0);
NetworkCallback<Modules.Module> successCb = success -> {
returns.getAndIncrement();
callback.onResponse(Pair.create(module, false));
if (returns.get() == items) {
if (returns.get() == items.get()) {
callback.onResponse(Pair.create(module, true));
if (lastError.get() != null)
errorCallback.onError(lastError.get());
@@ -152,7 +156,7 @@ public class KVVModuleList extends HTTPService {
NetworkErrorCallback errorCb = error -> {
lastError.set(error);
returns.getAndIncrement();
if (returns.get() == items) {
if (returns.get() == items.get()) {
callback.onResponse(Pair.create(module, true));
if (lastError.get() != null)
errorCallback.onError(lastError.get());
@@ -164,8 +168,7 @@ public class KVVModuleList extends HTTPService {
() -> this.getAnnouncements(module, successCb, errorCb, forceRefresh),
() -> this.getGradebook(module, successCb, errorCb, forceRefresh)
};
//noinspection ConstantConditions
if (methods.length != items) throw new AssertionError();
items.set(methods.length);
for (Runnable method: methods) {
method.run();
}
@@ -192,7 +195,10 @@ public class KVVModuleList extends HTTPService {
}
private void getAnnouncementsUpgrade(String ID, final NetworkCallback<ArrayList<Announcement>> callback, final NetworkErrorCallback errorCallback) {
//log.d("SITE GET URL", String.format("https://kvv.imp.fu-berlin.de/direct/announcement/site/%s.json?n=999999&d=999999999", ID));
if (token == null) {
errorCallback.onError(new NetworkError(101204, 500, "Currently running in offline mode!"));
return;
}
get(String.format("https://kvv.imp.fu-berlin.de/direct/announcement/site/%s.json?n=999999&d=999999999", ID), token.getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
@@ -243,6 +249,10 @@ public class KVVModuleList extends HTTPService {
}
private void getAssignmentsUpgrade(String ID, final NetworkCallback<AssignmentList> callback, final NetworkErrorCallback errorCallback) {
if (token == null) {
errorCallback.onError(new NetworkError(101304, 500, "Currently running in offline mode!"));
return;
}
get(String.format("https://kvv.imp.fu-berlin.de/direct/assignment/site/%s.json", ID), token.getCookies(), response ->{
String body = response.getParsed();
if (body == null) {
@@ -277,7 +287,7 @@ public class KVVModuleList extends HTTPService {
assignments.add(0, new Assignment(id, title, dueTime, gradebookItemName, gradeScale, urls));
}
} catch (JSONException e) {
errorCallback.onError(new NetworkError(101306, 403, "Cannot parse announcements!"));
errorCallback.onError(new NetworkError(101302, 403, "Cannot parse announcements!"));
return;
}
callback.onResponse(assignments);
@@ -307,7 +317,10 @@ public class KVVModuleList extends HTTPService {
}
private void getEventsUpgrade(String ID, final NetworkCallback<EventList> callback, final NetworkErrorCallback errorCallback) {
//https://kvv.imp.fu-berlin.de/direct/calendar/site/91c6e9cc-58eb-486d-ab99-a22a40997d1b.json
if (token == null) {
errorCallback.onError(new NetworkError(101404, 500, "Currently running in offline mode!"));
return;
}
get(String.format("https://kvv.imp.fu-berlin.de/direct/calendar/site/%s.json", ID), token.getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
@@ -358,6 +371,10 @@ public class KVVModuleList extends HTTPService {
}
private void getGradebookUpgrade(String ID, final NetworkCallback<ArrayList<Gradebook>> callback, final NetworkErrorCallback errorCallback) {
if (token == null) {
errorCallback.onError(new NetworkError(101104, 500, "Currently running in offline mode!"));
return;
}
get(String.format("https://kvv.imp.fu-berlin.de/direct/gradebook/site/%s.json", ID ), token.getCookies(), response ->{
String body = response.getParsed();
if (body == null) {
@@ -370,22 +387,20 @@ public class KVVModuleList extends HTTPService {
JSONArray sites = json.getJSONArray("assignments");
for (int i = 0; i < sites.length(); i++) {
//log.d("gradebook FOUND!", i);
JSONObject site = sites.getJSONObject(i);
String grade = site.optString("grade", null);
String itemName = site.optString("itemName", null);
double maxPoints = site.optDouble("points", -1);
//log.d("Gradebook:",itemName, grade, maxPoints);
gradebook.add(0, new Gradebook(itemName, grade, maxPoints));
}
}catch (JSONException e) {
errorCallback.onError(new NetworkError(101504, 403, "Cannot parse gradebook for announcements!"));
errorCallback.onError(new NetworkError(101502, 403, "Cannot parse gradebook for announcements!"));
return;
}
callback.onResponse(gradebook);
}, error -> errorCallback.onError(new NetworkError(101505, error.networkResponse.statusCode, "Cannot get gradebook for assignments!")));
}, error -> errorCallback.onError(new NetworkError(101503, error.networkResponse.statusCode, "Cannot get gradebook for assignments!")));
}

View File

@@ -48,13 +48,22 @@
<android.support.v7.widget.AppCompatButton
android:id="@+id/btn_login"
android:layout_width="fill_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:text="@string/log_in"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/btn_offline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:visibility="gone"/>
</LinearLayout>
</ScrollView>

View File

@@ -34,4 +34,5 @@
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="enter_offline_mode">Enter Offline Mode (%1$s)</string>
</resources>