diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailResourceFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailResourceFragment.java index b77347b..f589e2e 100644 --- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailResourceFragment.java +++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailResourceFragment.java @@ -34,7 +34,7 @@ import de.sebse.fuplanner.tools.ui.treeview.TreeViewAdapter; * Use the {@link ModDetailResourceFragment#newInstance} factory method to * create an instance of this fragment. */ -public class ModDetailResourceFragment extends Fragment { +public class ModDetailResourceFragment extends Fragment implements Download.OnDownloadRequestInterface { private static final String ARG_POSITION = "itemPosition"; private String mItemPos; @@ -82,7 +82,7 @@ public class ModDetailResourceFragment extends Fragment { RecyclerView recyclerView = view.findViewById(R.id.list); recyclerView.setLayoutManager(new LinearLayoutManager(context)); - adapter = new ModDetailResourceAdapter(Arrays.asList(new FileNodeBinder(), new DirectoryNodeBinder(), new DocumentNodeBinder())); + adapter = new ModDetailResourceAdapter(Arrays.asList(new FileNodeBinder(), new DirectoryNodeBinder(), new DocumentNodeBinder(this))); adapter.setOnTreeNodeListener(new TreeViewAdapter.OnTreeNodeListener() { @Override public boolean onClick(TreeNode node, RecyclerView.ViewHolder holder) { @@ -119,6 +119,17 @@ public class ModDetailResourceFragment extends Fragment { return view; } + @Override + public void request(String title, String url) { + if (mListener == null) + return; + mListener.getKVV().modules().list().find(mItemPos, (Modules.Module module) -> { + String folderName = "FU-"+module.title.replaceAll("[:*<>|/\"\\\\]", "-"); + folderName += "/Announcement"; + getDownload().openDownloadDialog(title, url, folderName); + }, log::e); + } + @Override public void onAttach(Context context) { super.onAttach(context); diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesResources.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesResources.java index a672b9b..04e7eae 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesResources.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesResources.java @@ -178,14 +178,43 @@ public class ModulesResources extends PartModules> { } else { String bodyText = resource.optString("body", ""); bodyText = String.valueOf(PartModules.fromHtml(bodyText)); - resources.add(new Resource.Document("", title, createdDate, true, "", bodyText)); - if (--latch[0] == 0) callback.onResponse(resources); + Resource.Document document = new Resource.Document("", title, createdDate, true, "", bodyText); + resources.add(document); + get(String.format("https://lms.fu-berlin.de/learn/api/public/v1/courses/%s/contents/%s/attachments", ID, resid), mLogin.getLoginTokenBB().getCookies(), response1 -> { + + String body1 = response1.getParsed(); + if (body1 == null) { + errorCallback.onError(new NetworkError(101617, 403, "No resource attachments retrieved!")); + return; + } + JSONArray attachments; + try { + JSONObject json = new JSONObject(body1); + attachments = json.getJSONArray("results"); + } catch (JSONException e) { + e.printStackTrace(); + errorCallback.onError(new NetworkError(101618, 400, "Cannot parse resource attachments!")); + return; + } + for (int j = 0; j < attachments.length(); j++) { + try { + JSONObject attachment = attachments.getJSONObject(j); + String attachid = attachment.getString("id"); + String attachname = attachment.getString("fileName"); + document.addUrl(String.format("https://lms.fu-berlin.de/learn/api/public/v1/courses/%s/contents/%s/attachments/%s/download", ID, resid, attachid), attachname); + } catch (JSONException e) { + log.e(new NetworkError(101619, 400, "Cannot parse resource attachments!")); + e.printStackTrace(); + log.e("ID:", j, "JSON:", attachments); + } + } + if (--latch[0] == 0) callback.onResponse(resources); + }, error -> errorCallback.onError(new NetworkError(101616, error.networkResponse.statusCode, "Cannot get resource attachments!"))); } } catch (JSONException e) { log.e(new NetworkError(101615, 400, "Cannot parse resources!")); e.printStackTrace(); log.e("ID:", i, "JSON:", sites); - return; } } }, error -> { @@ -238,7 +267,15 @@ public class ModulesResources extends PartModules> { } private void fileUpgrade(String filename, String url, String modulename, final NetworkCallback callback, final NetworkErrorCallback errorCallback) { - if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null) { + if (url.contains("lms.fu-berlin.de")) { + fileUpgradeBB(filename, url, modulename, callback, errorCallback); + } else { + fileUpgradeKVV(filename, url, modulename, callback, errorCallback); + } + } + + private void fileUpgradeKVV(String filename, String url, String modulename, final NetworkCallback callback, final NetworkErrorCallback errorCallback) { + if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null || !mLogin.getLoginTokenKVV().isAvailable()) { errorCallback.onError(new NetworkError(101604, 500, "Currently running in offline mode!")); return; } @@ -256,11 +293,52 @@ public class ModulesResources extends PartModules> { String path = saveFileInDownloads(filename, response.getBytes(), modulename); callback.onResponse(path); } else { - errorCallback.onError(new NetworkError(101704, 403, "External storage not writable!")); + errorCallback.onError(new NetworkError(101704, 400, "External storage not writable!")); } }, error -> errorCallback.onError(new NetworkError(101702, error.networkResponse.statusCode, "Cannot get file!"))); + } - + private void fileUpgradeBB(String filename, String url, String modulename, final NetworkCallback callback, final NetworkErrorCallback errorCallback) { + if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenBB() == null || !mLogin.getLoginTokenBB().isAvailable()) { + errorCallback.onError(new NetworkError(101615, 500, "Currently running in offline mode!")); + return; + } + get(url, mLogin.getLoginTokenBB().getCookies(), response -> { + if (response.getHeaders().containsKey("Location")) { + // Return redirected URL + String redirectUrl = response.getHeaders().get("Location"); + if (redirectUrl == null){ + redirectUrl = ""; + } + log.d("redirectUrl", redirectUrl); + get(redirectUrl, mLogin.getLoginTokenBB().getCookies(), response1 -> { + if (response1.getHeaders().containsKey("Location")) { + // Return redirected URL + String redirectUrl2 = response1.getHeaders().get("Location"); + if (redirectUrl2 == null) { + redirectUrl2 = ""; + } else { + redirectUrl2 = "https://lms.fu-berlin.de" + redirectUrl2; + } + log.d("redirectUrl2", redirectUrl2); + get(redirectUrl2, mLogin.getLoginTokenBB().getCookies(), response2 -> { + if (response2.getBytes() == null) { + errorCallback.onError(new NetworkError(101714, 400, "Cannot get file!")); + } else if (isExternalStorageWritable()) { + String path = saveFileInDownloads(filename, response2.getBytes(), modulename); + callback.onResponse(path); + } else { + errorCallback.onError(new NetworkError(101713, 400, "External storage not writable!")); + } + }, error -> errorCallback.onError(new NetworkError(101717, error.networkResponse.statusCode, "Cannot get file!"))); + } else { + errorCallback.onError(new NetworkError(101716, 400, "External storage not writable!")); + } + }, error -> errorCallback.onError(new NetworkError(101712, error.networkResponse.statusCode, "Cannot get file!"))); + } else { + errorCallback.onError(new NetworkError(101711, 400, "External storage not writable!")); + } + }, error -> errorCallback.onError(new NetworkError(101710, error.networkResponse.statusCode, "Cannot get file!"))); } @@ -293,7 +371,7 @@ public class ModulesResources extends PartModules> { // Saves file in folder: DOWNLOADS/moduleName File folder = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DOWNLOADS), moduleName); - if (!folder.mkdir()) { + if (!folder.mkdirs()) { log.w( "Directory not created"); } String path = ""; diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Resource.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Resource.java index 5de841c..7abc5df 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Resource.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Resource.java @@ -1,5 +1,7 @@ package de.sebse.fuplanner.services.kvv.types; +import android.util.Pair; + import com.google.android.gms.common.internal.Objects; import java.io.Serializable; @@ -63,7 +65,8 @@ public abstract class Resource implements Serializable { } public static class Document extends Resource implements LayoutItemType { - private final ArrayList urls; + + private final ArrayList urls; private final String body; public Document(String author, String title, long modifiedDate, boolean visible, String container, String body) { @@ -89,11 +92,11 @@ public abstract class Resource implements Serializable { return body; } - public void addUrl(String res){ - urls.add(res); + public void addUrl(String url, String name){ + urls.add(new DownloadFile(url, name)); } - public String getUrl(int id){ + public DownloadFile getUrl(int id){ return urls.get(id); } @@ -115,6 +118,16 @@ public abstract class Resource implements Serializable { public int hashCode() { return Objects.hashCode(super.hashCode(), this.getClass().getSimpleName()); } + + public class DownloadFile implements Serializable { + public final String url; + public final String name; + + public DownloadFile(String url, String name) { + this.url = url; + this.name = name; + } + } } public static class File extends Resource implements LayoutItemType { diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/ui/Download.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/ui/Download.java index 47b8898..bcc982d 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/ui/Download.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/ui/Download.java @@ -187,6 +187,8 @@ public class Download { private void fileOpen(File url){ Context context = contextInterface.get(); + log.d("fileOpen", context); + log.d("url", url.toString()); if (context == null) return; Uri uri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".my.provider", url); diff --git a/app/src/main/java/de/sebse/fuplanner/tools/ui/treeview/DocumentNodeBinder.java b/app/src/main/java/de/sebse/fuplanner/tools/ui/treeview/DocumentNodeBinder.java index b23a474..cbdf1a3 100644 --- a/app/src/main/java/de/sebse/fuplanner/tools/ui/treeview/DocumentNodeBinder.java +++ b/app/src/main/java/de/sebse/fuplanner/tools/ui/treeview/DocumentNodeBinder.java @@ -8,7 +8,10 @@ import com.cunoraz.tagview.TagView; import androidx.core.content.ContextCompat; import de.sebse.fuplanner.R; +import de.sebse.fuplanner.fragments.moddetails.ModDetailAnnounceFragment; import de.sebse.fuplanner.services.kvv.types.Resource; +import de.sebse.fuplanner.services.kvv.ui.Download; +import de.sebse.fuplanner.tools.UtilsDate; import de.sebse.fuplanner.tools.logging.Logger; import de.sebse.fuplanner.tools.ui.cardview.ExpandableCardView; @@ -17,6 +20,14 @@ import de.sebse.fuplanner.tools.ui.cardview.ExpandableCardView; */ public class DocumentNodeBinder extends TreeViewBinder { + + private Download.OnDownloadRequestInterface requestInterface; + + public DocumentNodeBinder(Download.OnDownloadRequestInterface requestInterface) { + super(); + this.requestInterface = requestInterface; + } + @Override public ViewHolder provideViewHolder(View itemView) { return new ViewHolder(itemView); @@ -26,22 +37,28 @@ public class DocumentNodeBinder extends TreeViewBinder { - String s = fileNode.getUrl(i); + String s = fileNode.getUrl(i).url; if (s != null) { - String name = urlToName(s, i, holder.itemView.getResources()); - requestInterface.request(name, s); + String name = fileNode.getUrl(i).name; + Logger log = new Logger(this); + //log.d(name); + //log.d(s); + this.requestInterface.request(name, s); } - });*/ + }); + holder.itemView.invalidate(); } @Override @@ -51,6 +68,7 @@ public class DocumentNodeBinder extends TreeViewBinder