Blackboard Resources (no links)

This commit is contained in:
Caesar2011
2019-02-01 01:50:04 +01:00
parent 35bb4e1629
commit 7f6e794fc8
7 changed files with 238 additions and 27 deletions

View File

@@ -24,6 +24,7 @@ import de.sebse.fuplanner.services.kvv.types.Resource;
import de.sebse.fuplanner.tools.MainActivityListener;
import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.ui.treeview.DirectoryNodeBinder;
import de.sebse.fuplanner.tools.ui.treeview.DocumentNodeBinder;
import de.sebse.fuplanner.tools.ui.treeview.FileNodeBinder;
import de.sebse.fuplanner.tools.ui.treeview.TreeNode;
import de.sebse.fuplanner.tools.ui.treeview.TreeViewAdapter;
@@ -81,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()));
adapter = new ModDetailResourceAdapter(Arrays.asList(new FileNodeBinder(), new DirectoryNodeBinder(), new DocumentNodeBinder()));
adapter.setOnTreeNodeListener(new TreeViewAdapter.OnTreeNodeListener() {
@Override
public boolean onClick(TreeNode node, RecyclerView.ViewHolder holder) {

View File

@@ -14,6 +14,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import de.sebse.fuplanner.services.kvv.types.Modules;
import de.sebse.fuplanner.services.kvv.types.Resource;
@@ -126,8 +127,81 @@ public class ModulesResources extends PartModules<ArrayList<Resource>> {
@Override
protected void upgradeBB(String ID, NetworkCallback<ArrayList<Resource>> callback, NetworkErrorCallback errorCallback) {
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenBB() == null || !mLogin.getLoginTokenBB().isAvailable()) {
errorCallback.onError(new NetworkError(101614, 500, "Currently running in offline mode!"));
return;
}
getRescourceFolder(String.format("https://lms.fu-berlin.de/learn/api/public/v1/courses/%s/contents/", ID), ID, false, callback, errorCallback);
//callback.onResponse(new ArrayList<>());
}
private void getRescourceFolder(String url, String ID, boolean subRequest, NetworkCallback<ArrayList<Resource>> callback, NetworkErrorCallback errorCallback) {
if (mLogin.getLoginTokenBB() == null) {
errorCallback.onError(new NetworkError(101610, 500, "Cannot get resources!"));
return;
}
get(url, mLogin.getLoginTokenBB().getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(101611, 403, "No resources retrieved!"));
return;
}
ArrayList<Resource> resources = new ArrayList<>();
JSONArray sites;
try {
JSONObject json = new JSONObject(body);
sites = json.getJSONArray("results");
} catch (JSONException e) {
e.printStackTrace();
errorCallback.onError(new NetworkError(101612, 400, "Cannot parse resources!"));
return;
}
final int[] latch = {sites.length()};
for (int i = 0; i < sites.length(); i++) {
try {
JSONObject resource = sites.getJSONObject(i);
String resid = resource.getString("id");
String title = resource.getString("title");
String created = resource.getString("created");
String content = resource.getJSONObject("contentHandler").getString("id");
long createdDate = UtilsDate.stringToMillis(created, "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
if (content.equals("resource/x-bb-folder")) {
Resource.Folder folder = new Resource.Folder("", title, createdDate, "", true, "");
resources.add(folder);
getRescourceFolder(String.format("https://lms.fu-berlin.de/learn/api/public/v1/courses/%s/contents/%s/children", ID, resid), ID, true, response1 -> {
for (Resource resource1 : response1) {
folder.add(resource1);
}
if (--latch[0] == 0) callback.onResponse(resources);
}, errorCallback);
} 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);
}
} catch (JSONException e) {
log.e(new NetworkError(101615, 400, "Cannot parse resources!"));
e.printStackTrace();
log.e("ID:", i, "JSON:", sites);
return;
}
}
}, error -> {
if (!subRequest || error.networkResponse.statusCode != 403) {
errorCallback.onError(new NetworkError(101613, error.networkResponse.statusCode, "Cannot get resources!"));
} else {
callback.onResponse(new ArrayList<>());
}
});
}

View File

@@ -62,6 +62,61 @@ public abstract class Resource implements Serializable {
return Objects.hashCode(getAuthor(), getContainer(), getModifiedDate(), getTitle(), getUrl());
}
public static class Document extends Resource implements LayoutItemType {
private final ArrayList<String> urls;
private final String body;
public Document(String author, String title, long modifiedDate, boolean visible, String container, String body) {
super(author, title, modifiedDate, "", visible, container);
this.body = body;
this.urls = new ArrayList<>();
}
@NonNull
@Override
public String toString() {
return "Resource{" +
"author='" + author + '\'' +
", modifiedDate=" + modifiedDate +
", title='" + title + '\'' +
", urls='" + urls.size() + '\'' +
", body='" + body + '\'' +
", urls='" + body + '\'' +
'}';
}
public String getBody() {
return body;
}
public void addUrl(String res){
urls.add(res);
}
public String getUrl(int id){
return urls.get(id);
}
public int size(){
return urls.size();
}
@Override
public TreeNode getTreeNode() {
return new TreeNode<>(this);
}
@Override
public @LayoutRes int getLayoutId() {
return R.layout.list_announcement_items;
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), this.getClass().getSimpleName());
}
}
public static class File extends Resource implements LayoutItemType {
private final String type;
@@ -91,6 +146,11 @@ public abstract class Resource implements Serializable {
public @LayoutRes int getLayoutId() {
return R.layout.item_file;
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), this.getClass().getSimpleName());
}
}
public static class Folder extends Resource implements LayoutItemType {
@@ -138,6 +198,11 @@ public abstract class Resource implements Serializable {
public @LayoutRes int getLayoutId() {
return R.layout.item_dir;
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), this.getClass().getSimpleName());
}
}
}

View File

@@ -64,12 +64,12 @@ public class ExpandableCardView extends CardView {
private int expandedHeight = 0;
private OnExpandedListener listener;
private final Logger log = new Logger(this);
private final OnClickListener defaultClickListener = v -> {
if(isExpanded()) collapse();
else expand();
};
private final Logger log = new Logger(this);
public ExpandableCardView(Context context) {
super(context);

View File

@@ -0,0 +1,67 @@
package de.sebse.fuplanner.tools.ui.treeview;
import android.view.View;
import android.widget.TextView;
import com.cunoraz.tagview.Tag;
import com.cunoraz.tagview.TagView;
import androidx.core.content.ContextCompat;
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.services.kvv.types.Resource;
import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.ui.cardview.ExpandableCardView;
/**
* Created by tlh on 2016/10/1 :)
*/
public class DocumentNodeBinder extends TreeViewBinder<DocumentNodeBinder.ViewHolder> {
@Override
public ViewHolder provideViewHolder(View itemView) {
return new ViewHolder(itemView);
}
@Override
public void bindView(ViewHolder holder, int position, TreeNode node) {
Resource.Document fileNode = (Resource.Document) node.getContent();
holder.title.setText(fileNode.getTitle());
holder.notes.setText(fileNode.getBody());
/*for (int i = 0, notesSize = fileNode.size(); i < notesSize; i++) {
String name = urlToName(fileNode.getUrl(i), i, holder.itemView.getResources());
Tag tag = new Tag(name);
tag.id = i;
tag.layoutColor = ContextCompat.getColor(holder.itemView.getContext(), R.color.colorFUBlue);
holder.mTagGroup.addTag(tag);
}
holder.mTagGroup.setOnTagClickListener((tag, i) -> {
String s = fileNode.getUrl(i);
if (s != null) {
String name = urlToName(s, i, holder.itemView.getResources());
requestInterface.request(name, s);
}
});*/
}
@Override
public int getLayoutId() {
return R.layout.list_announcement_items;
}
public class ViewHolder extends TreeViewBinder.ViewHolder {
final TextView title;
final TextView notes;
final ExpandableCardView card_view;
final TagView mTagGroup;
ViewHolder(View rootView) {
super(rootView);
this.card_view = rootView.findViewById(R.id.card_view);
this.title = this.card_view.getOuterView().findViewById(R.id.title);
this.notes = this.card_view.getInnerView().findViewById(R.id.notes);
this.mTagGroup = this.card_view.getInnerView().findViewById(R.id.tag_group);
}
}
}

View File

@@ -13,6 +13,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;
import de.sebse.fuplanner.tools.logging.Logger;
/**
* Created by tlh on 2016/10/1 :)
@@ -88,6 +89,7 @@ public class TreeViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
holder.itemView.setPadding(displayNodes.get(position).getHeight() * padding, 3, 3, 3);
if (!holder.itemView.hasOnClickListeners()) {
holder.itemView.setOnClickListener(v -> {
TreeNode selectedNode = displayNodes.get(holder.getLayoutPosition());
// Prevent multi-click during the short interval.
@@ -114,6 +116,7 @@ public class TreeViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
notifyItemRangeRemoved(positionStart, removeChildNodes(selectedNode, true));
}
});
}
for (TreeViewBinder viewBinder : viewBinders) {
if (viewBinder.getLayoutId() == displayNodes.get(position).getContent().getLayoutId())
//noinspection unchecked

View File

@@ -2,6 +2,7 @@
<de.sebse.fuplanner.tools.ui.cardview.ExpandableCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/tools"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/cardview_margin"