diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesEvents.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesEvents.java index 60583f4..e9f24d0 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesEvents.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesEvents.java @@ -23,6 +23,8 @@ import de.sebse.fuplanner.tools.network.NetworkErrorCallback; public class ModulesEvents extends PartModules { + private ModulesEventsNumber mEventNumbers; + ModulesEvents(Login login, ModulesList list, Context context) { super(login, list, context); } @@ -116,29 +118,20 @@ public class ModulesEvents extends PartModules { callback.onResponse(new EventList()); return; } - super.head(String.format("https://www.fu-berlin.de/vv/de/search?utf8=✓&query=%s", module.lvNumber.iterator().next()), null, response -> { - String location = response.getHeaders().get("Location"); - if (location == null) { + eventNumbers().getVVNumber(module.lvNumber.iterator().next(), vvNumber -> { + if (vvNumber.equals("")) { // Events not available callback.onResponse(new EventList()); //errorCallback.onError(new NetworkError(101410, 403, "Cannot get events!")); return; } - String group; - try { - group = Regex.regex("lv/([0-9]+)\\?", location); - } catch (NoSuchFieldException e) { - errorCallback.onError(new NetworkError(101410, 400, "Cannot get events!")); - e.printStackTrace(); - return; - } // 462854, 465661, 462126, 463782, 437050, 433843, 471614, 464205 //String[] tests = {"462854", "465661", "462126", "463782", "437050", "433843", "471614", "464205"}; //String[] tests = {"461459", "424564", "459494", "429737", "463765", "476477", "464082", "459577", "459743", "464318", "449358", "454327", "461784", "468081", "485919"}; - //group = tests[new Random().nextInt(tests.length)]; - //log.d("LAAAAAAST", group); - //group = "462126"; - super.get(String.format("https://www.fu-berlin.de/vv/de/lv/%s", group), null, response1 -> { + //vvNumber = tests[new Random().nextInt(tests.length)]; + //log.d("LAAAAAAST", vvNumber); + //vvNumber = "462126"; + super.get(String.format("https://www.fu-berlin.de/vv/de/lv/%s", vvNumber), null, response1 -> { String body = response1.getParsed(); if (body == null) { errorCallback.onError(new NetworkError(101411, 400, "Cannot get events!")); @@ -183,7 +176,13 @@ public class ModulesEvents extends PartModules { } callback.onResponse(events); }, error -> errorCallback.onError(new NetworkError(101415, error.networkResponse.statusCode, "Cannot get events!"))); - }, error -> errorCallback.onError(new NetworkError(101413, error.networkResponse.statusCode, "Cannot get events!"))); + }, errorCallback); }, errorCallback); } + + private ModulesEventsNumber eventNumbers() { + if (mEventNumbers == null) + mEventNumbers = new ModulesEventsNumber(getContext()); + return mEventNumbers; + } } diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesEventsNumber.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesEventsNumber.java new file mode 100644 index 0000000..9ae23c8 --- /dev/null +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesEventsNumber.java @@ -0,0 +1,72 @@ +package de.sebse.fuplanner.services.kvv; + +import android.content.Context; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashSet; + +import de.sebse.fuplanner.services.kvv.types.CacheBBEventNumber; +import de.sebse.fuplanner.services.kvv.types.CacheLecturer; +import de.sebse.fuplanner.services.kvv.types.Lecturer; +import de.sebse.fuplanner.tools.Regex; +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; + +class ModulesEventsNumber extends HTTPService { + private final CacheBBEventNumber mStorage; + + ModulesEventsNumber(Context context) { + super(context); + CacheBBEventNumber storage = null; + try { + storage = CacheBBEventNumber.load(context); + } catch (IOException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + if (storage == null) { + mStorage = new CacheBBEventNumber(); + } else { + mStorage = storage; + } + } + + void getVVNumber(String lvNumber, NetworkCallback callback, NetworkErrorCallback errorCallback) { + String vvNumber = mStorage.getVVNumber(lvNumber); + if (vvNumber != null) { + callback.onResponse(vvNumber); + return; + } + + super.head(String.format("https://www.fu-berlin.de/vv/de/search?utf8=✓&query=%s", lvNumber), null, response -> { + String location = response.getHeaders().get("Location"); + if (location == null) { + // Events not available + callback.onResponse(""); + //errorCallback.onError(new NetworkError(101410, 403, "Cannot get events!")); + return; + } + try { + String group = Regex.regex("lv/([0-9]+)\\?", location); + mStorage.setVVNumber(lvNumber, vvNumber); + try { + mStorage.save(getContext()); + } catch (IOException e) { + e.printStackTrace(); + } + callback.onResponse(group); + } catch (NoSuchFieldException e) { + errorCallback.onError(new NetworkError(102201, 400, "Cannot get events!")); + e.printStackTrace(); + } + }, error -> errorCallback.onError(new NetworkError(102202, error.networkResponse.statusCode, "Error retrieving lecturer!"))); + } +} diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java index 5ec4aed..1183158 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java @@ -203,6 +203,10 @@ public class ModulesList extends HTTPService { return; } final int[] latch = {memberships.length()}; + if (latch[0] == 0) { + successCallback.onResponse(modules); + return; + } for (int i = 0; i < memberships.length(); i++) { try { JSONObject membership = memberships.getJSONObject(i); @@ -338,7 +342,7 @@ public class ModulesList extends HTTPService { HashSet lvNumberSet = new HashSet<>(); boolean found = false; try { - Matcher match = Regex.match("[A-Za-z0-9]*_([A-Za-z0-9]*)_([A-Za-z0-9]*)_([0-9]{2}[0-9]{2}?)([WS]+)", json.getString("courseId")); + Matcher match = Regex.match("[A-Za-z0-9]*_([A-Za-z0-9]*)_([A-Za-z0-9]*)_([0-9]{2,})([WS]+)", json.getString("courseId")); type = match.group(1); lvNumber = match.group(2); semYear = match.group(3); @@ -352,6 +356,7 @@ public class ModulesList extends HTTPService { } } } catch (NoSuchFieldException | NumberFormatException e) { + log.e(e); type = "Projekt"; } if (!found) { diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheBBEventNumber.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheBBEventNumber.java new file mode 100644 index 0000000..e45905e --- /dev/null +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheBBEventNumber.java @@ -0,0 +1,78 @@ +package de.sebse.fuplanner.services.kvv.types; + +import android.content.Context; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.HashMap; + +public class CacheBBEventNumber implements Serializable { + private transient static final long RESAVE_TIMER = 1000L * 60 * 60 * 24 * 30; + private static final String FILE_NAME = "BBEventNumberStorageSaving"; + private static final String FILE_NAME_TIMESTAMP = "BBEventNumberStorageSavingTimestamp"; + private transient long mLastTimestamp = 0; + + private HashMap mBBEventNumbers = new HashMap<>(); + private HashMap mBBEventNumbersRefresh = new HashMap<>(); + + public static CacheBBEventNumber load(Context context) throws IOException, ClassNotFoundException { + FileInputStream fis = context.openFileInput(FILE_NAME); + ObjectInputStream is = new ObjectInputStream(fis); + Object readObject = is.readObject(); + if (!(readObject instanceof CacheBBEventNumber)) + return null; + CacheBBEventNumber storage = (CacheBBEventNumber) readObject; + is.close(); + fis.close(); + + fis = context.openFileInput(FILE_NAME_TIMESTAMP); + is = new ObjectInputStream(fis); + storage.mLastTimestamp = is.readLong(); + is.close(); + fis.close(); + + return storage; + } + + public boolean isNewerVersionInStorage(Context context) throws IOException { + FileInputStream fis = context.openFileInput(FILE_NAME_TIMESTAMP); + ObjectInputStream is = new ObjectInputStream(fis); + boolean result = this.mLastTimestamp < is.readLong(); + is.close(); + fis.close(); + return result; + } + + public void save(Context context) throws IOException { + FileOutputStream fos = context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE); + ObjectOutputStream os = new ObjectOutputStream(fos); + os.writeObject(this); + os.close(); + fos.close(); + + fos = context.openFileOutput(FILE_NAME_TIMESTAMP, Context.MODE_PRIVATE); + os = new ObjectOutputStream(fos); + this.mLastTimestamp = System.currentTimeMillis(); + os.writeLong(this.mLastTimestamp); + os.close(); + fos.close(); + } + + public void setVVNumber(String lvNumber, String vvNumber) { + mBBEventNumbers.put(lvNumber, vvNumber); + mBBEventNumbersRefresh.put(lvNumber, System.currentTimeMillis()); + } + + public String getVVNumber(String lvNumber) { + if (!mBBEventNumbersRefresh.containsKey(lvNumber)) + return null; + //noinspection ConstantConditions + if (mBBEventNumbersRefresh.get(lvNumber) + RESAVE_TIMER < System.currentTimeMillis()) + return null; + return mBBEventNumbers.get(lvNumber); + } +}