package org.geogebra.common.move.ggtapi.models; import java.util.HashMap; import java.util.Map; import java.util.TreeSet; import org.geogebra.common.move.ggtapi.models.json.JSONArray; import org.geogebra.common.move.ggtapi.models.json.JSONObject; import org.geogebra.common.util.debug.Log; /** * For Generating a JSON String for specific GeoGebratube API Requests * * @author Matthias Meisinger */ public class MaterialRequest implements Request { enum Task { fetch; } public enum Fields { id, title, type, description, timestamp, author, author_id, url, url_direct, language, thumbnail, featured, likes, width, height, instructions_pre, instructions_post, ggbBase64, toolbar, menubar, inputbar, modified, visibility, favorite, is3d, spreadsheet, cas, graphics2, constprot, propcalc, dataanalysis, funcinsp, macro, sharing_key, preview_url, elemcnt_applet; } public enum Filters { id, title, search, type, description, timestamp, author, author_url, language, featured, likes, inbook, inws, author_id; } public enum Order { id, title, type, description, timestamp, author, language, featured, likes, relevance; } public enum Type { asc, desc; } private static final String api = "1.1.0"; private Task task = Task.fetch; public Fields[] fields = new Fields[] { Fields.id, Fields.title, Fields.type, Fields.timestamp, Fields.author, Fields.author_id, Fields.url, Fields.url_direct, Fields.thumbnail, Fields.featured, Fields.likes, Fields.modified, Fields.visibility, Fields.favorite, Fields.sharing_key }; public Filters[] filters = { Filters.search }; public Map<Filters, String> filterMap = new HashMap<Filters, String>(); public Order by = Order.relevance; public Type type = Type.desc; public int limit = GeoGebraTubeAPI.STANDARD_RESULT_QUANTITY; private JSONObject requestJSON = new JSONObject(); private JSONObject apiJSON = new JSONObject(); private JSONObject taskJSON = new JSONObject(); private JSONObject fieldsJSON = new JSONObject(); private JSONArray fieldJSON = new JSONArray(); private JSONObject filtersJSON = new JSONObject(); private JSONArray filterJSON = new JSONArray(); private JSONObject orderJSON = new JSONObject(); private JSONObject limitJSON = new JSONObject(); private final AuthenticationModel model; private final ClientInfo client; public TreeSet<Filters> negFilters = new TreeSet<Filters>(); /** * Constructor for a Featured Materials Request */ public MaterialRequest(ClientInfo client) { this.client = client; this.model = client.getModel(); } /** * Constructor for a Search Request * * @param query * search term or #id */ public MaterialRequest(String query, ClientInfo client) { this(client); this.filterMap.put(Filters.type, "ggb"); if (query != null && query.startsWith("#")) { this.filters = new Filters[] { Filters.id }; this.filterMap.put(Filters.id, query.substring(1)); this.by = Order.timestamp; } else { this.filters = new Filters[] { Filters.search }; this.filterMap.put(Filters.search, query); } } /** * Constructor for a Request by ID * * @param filters * @param by */ public static MaterialRequest forId(String id, ClientInfo client) { MaterialRequest mr = new MaterialRequest(client); mr.fields = Fields.values(); mr.by = Order.id; mr.filters = new Filters[] { Filters.id }; mr.filterMap.put(Filters.type, "ggb"); mr.filterMap.put(Filters.id, id + ""); return mr; } @Override public String toJSONString(ClientInfo client) { try { this.apiJSON.put("-api", MaterialRequest.api); this.taskJSON.put("-type", this.task.toString()); for (int i = 0; i < this.fields.length; i++) { JSONObject current = new JSONObject(); current.put("-name", this.fields[i].toString()); this.fieldJSON.put(current); } this.fieldsJSON.put("field", this.fieldJSON); for (int i = 0; i < this.filters.length; i++) { JSONObject current = new JSONObject(); current.put("-name", this.filters[i].toString()); if (this.negFilters.contains(filters[i])) { current.put("-comp", "neq"); } if (this.filterMap.get(this.filters[i]) != null) { current.put("#text", this.filterMap.get(this.filters[i])); } this.filterJSON.put(current); } this.filtersJSON.put("field", this.filterJSON); this.orderJSON.put("-by", this.by.toString()); this.orderJSON.put("-type", this.type.toString()); this.limitJSON.put("-num", String.valueOf(this.limit)); this.taskJSON.put("fields", this.fieldsJSON); this.taskJSON.put("filters", this.filtersJSON); this.taskJSON.put("order", this.orderJSON); this.taskJSON.put("limit", this.limitJSON); if (this.model != null && model.isLoggedIn()) { JSONObject login = new JSONObject(); login.put("-token", model.getLoginToken()); this.apiJSON.put("login", login); } if (this.client != null) { JSONObject clientJSON = new JSONObject(); clientJSON.put("-id", client.getId()); clientJSON.put("-width", client.getWidth() + ""); clientJSON.put("-height", client.getHeight() + ""); clientJSON.put("-type", client.getType()); clientJSON.put("-language", client.getLanguage()); this.apiJSON.put("client", clientJSON); } this.apiJSON.put("task", this.taskJSON); this.requestJSON.put("request", this.apiJSON); return this.requestJSON.toString(); } catch (Exception e) { Log.debug("problem building request: " + e.getMessage()); return null; } } public static MaterialRequest forUser(int userId, ClientInfo client) { MaterialRequest req = new MaterialRequest(client); req.filters = new Filters[] { Filters.author_url, Filters.type }; req.filterMap.put(Filters.type, "link"); req.negFilters.add(Filters.type); req.filterMap.put(Filters.author_url, userId + ""); req.by = Order.relevance; return req; } public static MaterialRequest forCurrentUser(ClientInfo client) { MaterialRequest req = new MaterialRequest(client); req.filters = new Filters[] { Filters.type }; req.filterMap.put(Filters.type, "link"); req.negFilters.add(Filters.type); req.by = Order.relevance; return req; } public static MaterialRequest forCurrentUserGgb(ClientInfo client) { MaterialRequest req = new MaterialRequest(client); req.filters = new Filters[] { Filters.type }; req.filterMap.put(Filters.type, "ggb"); req.by = Order.relevance; return req; } public static MaterialRequest forFeatured(ClientInfo client) { MaterialRequest req = new MaterialRequest(client); req.filters = new Filters[] { Filters.featured, Filters.type }; req.filterMap.put(Filters.type, "link"); req.negFilters.add(Filters.type); req.filterMap.put(Filters.featured, "true"); req.type = Type.desc; return req; } public static MaterialRequest forFeaturedGgb(ClientInfo client) { MaterialRequest req = new MaterialRequest(client); req.filters = new Filters[] { Filters.featured, Filters.type }; req.filterMap.put(Filters.type, "ggb"); req.filterMap.put(Filters.featured, "true"); req.type = Type.desc; return req; } public static MaterialRequest searchGgb(ClientInfo client, String query) { MaterialRequest req = new MaterialRequest(client); req.filters = new Filters[] { Filters.search, Filters.type }; req.filterMap.put(Filters.search, query); req.filterMap.put(Filters.type, "ggb"); return req; } public static MaterialRequest forBook(int id, ClientInfo client) { MaterialRequest req = new MaterialRequest(client); req.filters = new Filters[] { Filters.inbook, Filters.type }; req.filterMap.put(Filters.type, "link"); req.negFilters.add(Filters.type); req.filterMap.put(Filters.inbook, id + ""); req.by = Order.timestamp; req.type = Type.desc; return req; } public static MaterialRequest forWorksheet(int id, ClientInfo client) { MaterialRequest req = new MaterialRequest(client); req.filters = new Filters[] { Filters.inws, Filters.type }; req.fields = Fields.values(); req.filterMap.put(Filters.type, "link"); req.negFilters.add(Filters.type); req.filterMap.put(Filters.inws, id + ""); req.by = Order.timestamp; req.type = Type.desc; return req; } public int getUserId() { return model.getUserId(); } }