Java tutorial
/** * Copyright 2010 Steve Garon Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions and limitations under the * License. */ package org.jared.synodroid.ds.protocol.v32; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.jared.synodroid.ds.Synodroid; import org.jared.synodroid.ds.server.SimpleSynoServer; import org.jared.synodroid.ds.utils.SearchResult; import org.jared.synodroid.ds.utils.SortOrder; import org.jared.synodroid.ds.utils.Utils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.jared.synodroid.ds.data.Folder; import org.jared.synodroid.ds.data.SearchEngine; import org.jared.synodroid.ds.data.SharedDirectory; import org.jared.synodroid.ds.data.Task; import org.jared.synodroid.ds.data.TaskContainer; import org.jared.synodroid.ds.data.TaskDetail; import org.jared.synodroid.ds.data.TaskFile; import org.jared.synodroid.ds.data.TaskFilesContainer; import org.jared.synodroid.ds.data.TaskProperties; import org.jared.synodroid.ds.data.TaskStatus; import org.jared.synodroid.ds.protocol.DSHandler; import org.jared.synodroid.ds.protocol.DSMException; import org.jared.synodroid.ds.protocol.DownloadStationNotFound; import org.jared.synodroid.ds.protocol.MultipartBuilder; import org.jared.synodroid.ds.protocol.Part; import org.jared.synodroid.ds.protocol.QueryBuilder; import org.jared.synodroid.ds.protocol.StreamFactory; import android.net.Uri; import android.util.Log; /** * @author Stave Garon (steve.garon at gmail dot com) */ class DSHandlerDSM32 implements DSHandler { // DownloadManager constant declaration private static final String DM_URI_NEW = "/webman/modules/DownloadStation/dlm/downloadman.cgi"; private static final String TORRENT_INFO = "/webman/modules/DownloadStation/dlm/torrent_info.cgi"; private static final String INITDATA_URI = "/webman/initdata.cgi"; private static final String USER_SETTINGS = "/webman/usersettings.cgi"; private static final String SEARCH_URI = "/webman/modules/DownloadStation/dlm/btsearch.cgi"; private static final String FILE_URI = "/webman/modules/FileBrowser/file_share.cgi"; private static final String BOUNDARY = "-----------7dabb2d41348"; private static final int MAX_LOOP = 4; /* The Synology's server */ private SimpleSynoServer server; private boolean DEBUG; /** * The constructor * * @param serverP */ public DSHandlerDSM32(SimpleSynoServer serverP, boolean debug) { server = serverP; DEBUG = debug; } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.Protocol#getAllTask() */ public TaskContainer getAllTask(int startP, int limitP, String sortAttrP, boolean ascendingP) throws Exception { ArrayList<Task> result = new ArrayList<Task>(); TaskContainer container = new TaskContainer(result); // If we are logged on if (server.isConnected()) { QueryBuilder getAllRequest = new QueryBuilder().add("action", "getall"); getAllRequest.add("start", "" + startP); getAllRequest.add("limit", "" + limitP); getAllRequest.add("sort", sortAttrP.toLowerCase()); String asc = (ascendingP ? "ASC" : "DESC"); getAllRequest.add("dir", asc); // Execute JSONObject jso = null; synchronized (server) { jso = server.sendJSONRequest(DM_URI_NEW, getAllRequest.toString(), "GET"); } boolean success = jso.getBoolean("success"); // If request succeded if (success) { // Get the totals rates String totalUp = jso.getString("total_up"); String totalDown = jso.getString("total_down"); int totalTasks = jso.getInt("total"); container.setTotalUp(totalUp); container.setTotalDown(totalDown); container.setTotalTasks(totalTasks); JSONArray items = jso.getJSONArray("items"); for (int iLoop = 0; iLoop < items.length(); iLoop++) { JSONObject item = items.getJSONObject(iLoop); // Create the task item Task task = new Task(); task.fileName = item.getString("filename").trim(); task.taskId = item.getInt("task_id"); task.downloadRate = item.getString("current_rate").trim(); task.downloadSize = item.getString("current_size").trim(); String prog = item.getString("progress").trim(); int index = prog.indexOf("%"); // If a value could be found ('%' found) if (index != -1) { prog = prog.substring(0, index); try { task.downloadProgress = (int) Float.parseFloat(prog); } catch (NumberFormatException ex) { // Set to unknown task.downloadProgress = -1; } } // Set to unknown else { task.downloadProgress = -1; } task.status = item.getString("status"); task.eta = Utils.computeTimeLeft(item.getInt("timeleft")); task.totalSize = item.getString("total_size").trim(); task.uploadRate = item.getString("upload_rate").trim(); task.creator = item.getString("username").trim(); if (task.creator.equals("")) { task.creator = server.getUser(); } task.server = server; result.add(task); } } // Try to do something else { String reason = jso.getJSONObject("errno").getString("key"); throw new DSMException(reason); } } return container; } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#delete(org.jared.synodroid.ds.common.data.Task) */ public void delete(String taskids) throws Exception { // If we are logged on if (server.isConnected()) { try { QueryBuilder getAllRequest = new QueryBuilder().add("action", "delete").add("idList", taskids); // Execute synchronized (server) { server.sendJSONRequest(DM_URI_NEW, getAllRequest.toString(), "GET"); } } catch (Exception e) { if (DEBUG) Log.e(Synodroid.DS_TAG, "Not expected exception occured while deleting id:" + taskids, e); throw e; } } } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#clearAll() */ public void clearAll() throws Exception { // If we are logged on if (server.isConnected()) { try { QueryBuilder getAllRequest = new QueryBuilder().add("action", "clear").add("idList", ""); // Execute synchronized (server) { server.sendJSONRequest(DM_URI_NEW, getAllRequest.toString(), "GET"); } } catch (Exception e) { if (DEBUG) Log.e(Synodroid.DS_TAG, "Not expected exception occured while clearing tasks", e); throw e; } } } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#resume(org.jared.synodroid.ds.common.data.Task) */ public void resume(String taskids) throws Exception { // If we are logged on if (server.isConnected()) { QueryBuilder getAllRequest = new QueryBuilder().add("action", "resume").add("idList", taskids); // Execute synchronized (server) { server.sendJSONRequest(DM_URI_NEW, getAllRequest.toString(), "GET"); } } } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#resumeAll(List<org.jared. synodroid. common.data.Task>) */ public void resumeAll(List<Task> taskP) throws Exception { String taskids = ""; for (Task task : taskP) { if (task.status.equals(TaskStatus.TASK_PAUSED.toString())) { if (!taskids.equals("")) { taskids += ":"; } taskids += "" + task.taskId; } } resume(taskids); } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#stop(org.jared.synodroid.ds.common.data.Task) */ public void stop(String taskids) throws Exception { // If we are logged on if (server.isConnected()) { QueryBuilder getAllRequest = new QueryBuilder().add("action", "stop").add("idList", taskids); // Execute synchronized (server) { server.sendJSONRequest(DM_URI_NEW, getAllRequest.toString(), "GET"); } } } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#stopAll(List<org.jared.synodroid.ds . common.data.Task>) */ public void stopAll(List<Task> taskP) throws Exception { String taskids = ""; for (Task task : taskP) { if (task.status.equals(TaskStatus.TASK_DOWNLOADING.toString()) || task.status.equals(TaskStatus.TASK_PRE_SEEDING.toString()) || task.status.equals(TaskStatus.TASK_SEEDING.toString()) || task.status.equals(TaskStatus.TASK_HASH_CHECKING.toString()) || task.status.equals(TaskStatus.TASK_WAITING.toString())) { if (!taskids.equals("")) { taskids += ":"; } taskids += "" + task.taskId; } } stop(taskids); } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#getFiles(org.jared.synodroid.ds.common.data.Task) */ public TaskFilesContainer getFiles(Task taskP, int start, int limit) throws Exception { ArrayList<TaskFile> result = new ArrayList<TaskFile>(); TaskFilesContainer container = new TaskFilesContainer(result); // If we are logged on if (server.isConnected()) { QueryBuilder getAllRequest = new QueryBuilder().add("action", "list_file") .add("task_id", "" + taskP.taskId).add("start", "" + start).add("limit", "" + limit); // Execute JSONObject json = null; synchronized (server) { json = server.sendJSONRequest(TORRENT_INFO, getAllRequest.toString(), "GET"); } boolean success = json.getBoolean("success"); // If request succeded if (success) { JSONArray array = json.getJSONArray("items"); int totalFiles = json.getInt("total"); container.setTotalFiles(totalFiles); for (int iLoop = 0; iLoop < array.length(); iLoop++) { JSONObject obj = array.getJSONObject(iLoop); // Create the file TaskFile file = new TaskFile(); file.name = obj.getString("name"); file.filesize = obj.getString("size"); file.download = obj.getBoolean("wanted"); file.id = obj.getInt("index"); file.priority = obj.getString("priority"); result.add(file); } array.length(); } else { String reason = ""; if (json.has("reason")) { reason = json.getString("reason"); } else if (json.has("errno")) { JSONObject err = json.getJSONObject("errno"); reason = err.getString("key"); } throw new DSMException(reason); } } return container; } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#getDetails(org.jared.synodroid.ds.common.data.Task) */ public TaskDetail getDetails(Task taskP) throws Exception { TaskDetail result = new TaskDetail(); // If we are logged on if (server.isConnected()) { QueryBuilder getAllRequest = new QueryBuilder().add("action", "getone").add("taskid", "" + taskP.taskId) .add("update", "1"); // Execute JSONObject json = null; synchronized (server) { json = server.sendJSONRequest(DM_URI_NEW, getAllRequest.toString(), "GET"); } boolean success = json.getBoolean("success"); // If successful then build details list if (success) { JSONObject data = json.getJSONObject("data"); if (data.has("stime")) result.seedingDate = data.getString("stime"); if (data.has("totalpeer")) result.peersTotal = Utils.toLong(data.getString("totalpeer")); if (data.has("currpeer")) result.peersCurrent = Utils.toLong(data.getString("currpeer")); if (data.has("istorrent")) result.isTorrent = data.getBoolean("istorrent"); if (data.has("speed")) { Pattern p = Pattern.compile("(((\\d)*\\.(\\d)*) KB/s)"); Matcher m = p.matcher(data.getString("speed")); if (m.find() && m.groupCount() >= 2) { result.speedUpload = Utils.toDouble(m.group(2)); } if (m.find() && m.groupCount() >= 2) { result.speedDownload = Utils.toDouble(m.group(2)); } else { result.speedDownload = result.speedUpload; } } if (data.has("filename")) result.fileName = data.getString("filename"); if (data.has("username")) result.userName = data.getString("username"); if (data.has("totalpieces")) result.piecesTotal = Utils.toLong(data.getString("totalpieces")); if (data.has("transfered")) { Pattern p = Pattern.compile("((\\d*\\.\\d*)\\s[KMGT]B)"); Matcher m = p.matcher(data.getString("transfered")); if (m.find() && m.groupCount() >= 1) { result.bytesUploaded = Utils.fileSizeToBytes(m.group(1)); } // If you could find another matching group, it means downmload // informations are present if (m.find() && m.groupCount() >= 1) { result.bytesDownloaded = Utils.fileSizeToBytes(m.group(1)); } // Otherwise download informations were the first matching (no upload // information) else { result.bytesDownloaded = result.bytesUploaded; result.bytesUploaded = 0; } result.bytesRatio = 0; if (result.bytesDownloaded != 0) { result.bytesRatio = (int) (((float) result.bytesUploaded / (float) result.bytesDownloaded) * 100); } } if (data.has("seedelapsed")) result.seedingElapsed = data.getInt("seedelapsed"); if (data.has("isnzb")) result.isNZB = data.getBoolean("isnzb"); if (data.has("destination")) result.destination = data.getString("destination"); if (data.has(("url"))) result.url = data.getString("url"); if (data.has("ctime")) result.creationDate = data.getString("ctime"); if (data.has("status")) result.status = data.getString("status"); if (data.has("seeding_interval")) result.seedingInterval = data.getInt("seeding_interval"); if (data.has("currpieces")) result.piecesCurrent = Utils.toLong(data.getString("currpieces")); if (data.has("id")) result.taskId = data.getInt("id"); if (data.has("seeding_ratio")) result.seedingRatio = data.getInt("seeding_ratio"); if (data.has("filesize")) result.fileSize = Utils.fileSizeToBytes(data.getString("filesize")); if (data.has("seeders_leechers")) { Pattern p = Pattern.compile("(\\d+)(/)(\\d+)"); String v = data.getString("seeders_leechers"); Matcher m = p.matcher(v); if (m.find()) { if (m.groupCount() >= 1) result.seeders = Utils.toLong(m.group(1)); if (m.groupCount() >= 3) result.leechers = Utils.toLong(m.group(3)); } } } // Otherwise throw a exception else { String reason = ""; if (json.has("reason")) { reason = json.getString("reason"); } else if (json.has("errno")) { JSONObject err = json.getJSONObject("errno"); reason = err.getString("key"); } throw new DSMException(reason); } } return result; } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#upload(android.net.Uri) */ public void upload(Uri uriP) throws Exception { // If we are logged on if (server.isConnected()) { if (uriP.getPath() != null) { // Create the multipart MultipartBuilder builder = new MultipartBuilder(BOUNDARY, DEBUG); // The upload_type's part builder.addPart(new Part("upload_type").setContent("torrent".getBytes())); // The upload_type's part builder.addPart(new Part("desttext").setContent(getSharedDirectory(false).getBytes())); // The direction's part builder.addPart(new Part("direction").setContent("ASC".getBytes())); // The field's part builder.addPart(new Part("field").setContent("task_id".getBytes())); // The torrent's part Part filePart = new Part("torrent"); filePart.addExtra("filename", uriP.getLastPathSegment()); if (uriP.getPath().toLowerCase().endsWith("nzb")) { filePart.setContentType("application/octet-stream"); } else { filePart.setContentType("application/x-bittorrent"); } // Get the stream according to the Uri byte[] buffer = StreamFactory.getStream(uriP); // Set the content filePart.setContent(buffer); builder.addPart(filePart); // Execute JSONObject json; synchronized (server) { json = server.sendMultiPart(DM_URI_NEW, builder); } if (json != null) { boolean success = json.getBoolean("success"); // If successful then build details list if (!success) { String reason = ""; if (json.has("reason")) { reason = json.getString("reason"); } else if (json.has("errno")) { JSONObject err = json.getJSONObject("errno"); reason = err.getString("key"); } throw new DSMException(reason); } } } } } public void uploadUrl(Uri uriP, String uname, String pass) throws Exception { // If we are logged on if (server.isConnected()) { if (uriP.toString() != null) { String urls = "[\"" + uriP.toString() + "\"]"; // Create the builder QueryBuilder builder = new QueryBuilder().add("urls", urls).add("action", "add_url_task") .add("desttext", getSharedDirectory(true)); if (uname != null && pass != null) { builder.add("dlauth", "on"); builder.add("dluser", uname); builder.add("dlpass", pass); } // Execute JSONObject json = null; synchronized (server) { json = server.sendJSONRequest(DM_URI_NEW, builder.toString(), "POST"); } boolean success = json.getBoolean("success"); if (!success) { String reason = ""; if (json.has("reason")) { reason = json.getString("reason"); } else if (json.has("errno")) { JSONObject err = json.getJSONObject("errno"); reason = err.getString("key"); } throw new DSMException(reason); } } } } public String getMultipartUri() { return DM_URI_NEW; } public String getBoundary() { return BOUNDARY; } public byte[] generateMultipart(Uri uriP, String shared) throws Exception { if (uriP.getPath() != null) { // Create the multipart MultipartBuilder builder = new MultipartBuilder(BOUNDARY, DEBUG); // The upload_type's part builder.addPart(new Part("upload_type").setContent("torrent".getBytes())); // The upload_type's part builder.addPart(new Part("desttext").setContent(shared.getBytes())); // The direction's part builder.addPart(new Part("direction").setContent("ASC".getBytes())); // The field's part builder.addPart(new Part("field").setContent("task_id".getBytes())); // The torrent's part Part filePart = new Part("torrent"); filePart.addExtra("filename", uriP.getLastPathSegment()); if (uriP.getPath().toLowerCase().endsWith("nzb")) { filePart.setContentType("application/octet-stream"); } else { filePart.setContentType("application/x-bittorrent"); } // Get the stream according to the Uri byte[] buffer = StreamFactory.getStream(uriP); // Set the content filePart.setContent(buffer); builder.addPart(filePart); ByteArrayOutputStream baos = new ByteArrayOutputStream(); builder.writeData(baos); return baos.toByteArray(); } return null; } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#getTaskProperty(org.jared.synodroid.ds.common.data.Task) */ public TaskProperties getTaskProperty(Task taskP) throws Exception { // torrent_info.cgi?_dc=1299264441500&action=get_property&task_id=2001 QueryBuilder getPropReq = new QueryBuilder().add("action", "get_property").add("task_id", "" + taskP.taskId); TaskProperties output = new TaskProperties(); output.id = "" + taskP.taskId; JSONObject json = null; synchronized (server) { json = server.sendJSONRequest(TORRENT_INFO, getPropReq.toString(), "POST"); } boolean success = json.getBoolean("success"); // If not successful then throw an exception if (!success) { String reason = ""; if (json.has("reason")) { reason = json.getString("reason"); } else if (json.has("errno")) { JSONObject err = json.getJSONObject("errno"); reason = err.getString("key"); } throw new DSMException(reason); } else { try { if (json.has("ul_rate")) { output.ul_rate = json.getInt("ul_rate"); } if (json.has("dl_rate")) { output.dl_rate = json.getInt("dl_rate"); } if (json.has("max_peers")) { output.max_peers = json.getInt("max_peers"); } if (json.has("priority")) { output.priority = json.getInt("priority"); } if (json.has("seeding_ratio")) { output.seeding_ratio = json.getInt("seeding_ratio"); } if (json.has("seeding_interval")) { output.seeding_interval = json.getInt("seeding_interval"); } if (json.has("destination")) { output.destination = json.getString("destination"); } } catch (JSONException e) { } } return output; } public void setTaskProperty(final Task taskP, int ul_rate, int dl_rate, int priority, int max_peers, String destination, int seeding_ratio, int seeding_interval) throws Exception { // action=set_property // &task_ids=[2001] // &settings={"ext-comp-1434":"","ul_rate":5,"dl_rate":5,"priority":-1,"max_peers":100,"destination":"upload","seeding_ratio":25,"seeding_interval":90}' // Create the JSON request QueryBuilder updateTaskRequest = new QueryBuilder().add("action", "set_property").add("task_ids", "[" + taskP.taskId + "]"); JSONObject data = new JSONObject(); data.put("ext-comp-1434", ""); data.put("ul_rate", ul_rate); data.put("dl_rate", dl_rate); data.put("priority", priority); data.put("max_peers", max_peers); data.put("destination", destination); data.put("seeding_ratio", seeding_ratio); data.put("seeding_interval", seeding_interval); updateTaskRequest.add("settings", data.toString()); // Execute it to the server JSONObject json = null; synchronized (server) { json = server.sendJSONRequest(TORRENT_INFO, updateTaskRequest.toString(), "POST"); } boolean success = json.getBoolean("success"); // If not successful then throw an exception if (!success) { String reason = ""; if (json.has("reason")) { reason = json.getString("reason"); } else if (json.has("errno")) { JSONObject err = json.getJSONObject("errno"); reason = err.getString("key"); } throw new DSMException(reason); } } public void setFilePriority(final Task taskP, List<TaskFile> filesP, String priority) throws Exception { // action=set_files_priority&task_id=2001&priority=skip&indexes=%5B1%5D List<Integer> l_id = new ArrayList<Integer>(); for (TaskFile taskFile : filesP) { l_id.add(taskFile.id); } QueryBuilder updateSkipped = new QueryBuilder().add("action", "set_files_priority") .add("task_id", "" + taskP.taskId).add("priority", priority).add("indexes", l_id.toString()); // Execute it to the server JSONObject json = null; synchronized (server) { json = server.sendJSONRequest(TORRENT_INFO, updateSkipped.toString(), "POST"); } boolean success = json.getBoolean("success"); // If not successful then throw an exception if (!success) { String reason = ""; if (json.has("reason")) { reason = json.getString("reason"); } else if (json.has("errno")) { JSONObject err = json.getJSONObject("errno"); reason = err.getString("key"); } throw new DSMException(reason); } } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#updateTask(org.jared.synodroid.ds.common.data.Task, java.util.List, int, int) */ public void updateTask(Task taskP, List<TaskFile> filesP, int seedingRatioP, int seedingIntervalP) throws Exception { } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#enumSharedDirectory() */ public List<SharedDirectory> enumSharedDirectory() throws Exception { List<SharedDirectory> result = new ArrayList<SharedDirectory>(); // Create the JSON request QueryBuilder updateTaskRequest = new QueryBuilder().add("action", "enumshares"); // Execute it to the server JSONObject json = null; synchronized (server) { json = server.sendJSONRequest(DM_URI_NEW, updateTaskRequest.toString(), "GET"); } boolean success = json.getBoolean("success"); // If request succeded if (success) { JSONArray array = json.getJSONArray("items"); for (int iLoop = 0; iLoop < array.length(); iLoop++) { JSONObject obj = array.getJSONObject(iLoop); // Create the file SharedDirectory dir = new SharedDirectory(obj.getString("name")); dir.description = obj.getString("description"); result.add(dir); } } // If not successful then throw an exception else { String reason = ""; if (json.has("reason")) { reason = json.getString("reason"); } else if (json.has("errno")) { JSONObject err = json.getJSONObject("errno"); reason = err.getString("key"); } throw new DSMException(reason); } return result; } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#setSharedDirectory(java.lang .String) */ public void setSharedDirectory(Task taskP, String directoryP) throws Exception { // If we are logged on if (server.isConnected()) { if (taskP != null) { QueryBuilder setShared = new QueryBuilder().add("action", "set_destination") .add("task_ids", "[" + taskP.taskId + "]").add("destination", directoryP); // Execute synchronized (server) { server.sendJSONRequest(TORRENT_INFO, setShared.toString(), "POST"); } } else { QueryBuilder setShared = new QueryBuilder().add("action", "shareset").add("share", directoryP); // Execute synchronized (server) { server.sendJSONRequest(DM_URI_NEW, setShared.toString(), "POST"); } } } } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#getSharedDirectory() */ public String getSharedDirectory(boolean remap) throws Exception { String result = null; // If we are logged on if (server.isConnected()) { QueryBuilder getShared = new QueryBuilder().add("action", "shareget"); // Execute JSONObject json; synchronized (server) { try { json = server.sendJSONRequest(DM_URI_NEW, getShared.toString(), "GET"); } catch (FileNotFoundException ex) { if (remap) { if (server.DEBUG) Log.w(Synodroid.DS_TAG, "DSHandlerDSM32: Download station does not seem to be running."); throw new DownloadStationNotFound( "DSHanderDSM32: Download station does not seem to be running."); } else { throw ex; } } } boolean success = json.getBoolean("success"); // If request succeded if (success) { result = json.getString("shareName"); } // If not successful then throw an exception else { String reason = ""; if (json.has("reason")) { reason = json.getString("reason"); } else if (json.has("errno")) { JSONObject err = json.getJSONObject("errno"); reason = err.getString("key"); // Means that no shared directory has been set currently: don't throw an exception if (reason != null && reason.equals("download_error_user_removed")) { return ""; } } else if (json.has("disable_err")) { reason = json.getString("disable_err"); if (reason.equals("none") || reason.equals("sharenotfound")) { return ""; } } throw new DSMException(reason); } } return result; } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#getOriginalLink(org.jared .synodroid.common.data.Task) */ public StringBuffer getOriginalFile(Task taskP) throws Exception { StringBuffer result = null; // If we are logged on if (server.isConnected()) { QueryBuilder getOriginal = new QueryBuilder().add("action", "torrent").add("id", "" + taskP.taskId) .add("_rn", "" + System.currentTimeMillis()); // Execute synchronized (server) { String uri = DM_URI_NEW + "/" + taskP.originalLink; result = server.download(uri, getOriginal.toString()); } } return result; } /* * (non-Javadoc) * * @see org.jared.synodroid.ds.common.protocol.DSHandler#getOriginalLink(org.jared .synodroid.common.data.Task) */ public String buildOriginalFileString(int taskid) throws Exception { QueryBuilder getOriginal = new QueryBuilder().add("action", "torrent").add("id", "" + taskid).add("_rn", "" + System.currentTimeMillis()); return getOriginal.toString(); } public List<SearchEngine> getSearchEngines() throws Exception { List<SearchEngine> seList = new ArrayList<SearchEngine>(); // If we are logged on if (server.isConnected()) { // Execute JSONObject json = null; synchronized (server) { json = server.sendJSONRequest(INITDATA_URI, "", "GET"); } if (json != null) { JSONArray jsonArray = json.getJSONObject("UserSettings") .getJSONObject("SYNO.SDS.DownloadStation.Application").getJSONArray("btsearchplugins"); for (int i = 0; i < jsonArray.length(); i++) { SearchEngine se = new SearchEngine(); se.enabled = ((JSONObject) jsonArray.get(i)).getBoolean("enable"); se.name = ((JSONObject) jsonArray.get(i)).getString("name"); seList.add(se); } } } return seList; } public void setSearchEngines(List<SearchEngine> seList) throws Exception { JSONArray jArr = new JSONArray(); // If we are logged on if (server.isConnected()) { for (SearchEngine se : seList) { jArr.put(new JSONObject().put("enable", se.enabled).put("name", se.name)); } QueryBuilder qBuilder = new QueryBuilder().add("action", "apply").add("data", new JSONObject() .put("SYNO.SDS.DownloadStation.Application", new JSONObject().put("btsearchplugins", jArr)) .toString()); // Execute synchronized (server) { server.sendJSONRequest(USER_SETTINGS, qBuilder.toString(), "POST"); } } } public List<SearchResult> search(String query, SortOrder order, int start, int limit) throws Exception { List<SearchResult> results = new ArrayList<SearchResult>(); List<SearchEngine> seList = getSearchEngines(); String plugins = ""; for (SearchEngine se : seList) { if (se.enabled) { if (!plugins.equals("")) { plugins += ","; } plugins += se.name; } } QueryBuilder builder = new QueryBuilder().add("action", "search").add("query", query).add("plugins", plugins); JSONObject json = null; json = server.sendJSONRequest(SEARCH_URI, builder.toString(), "GET"); if (json != null) { if (server.DEBUG) Log.v(Synodroid.DS_TAG, "DSMSearch: Search query '" + query + "' queued for searching on the NAS."); if (json.getBoolean("success") && json.getBoolean("running")) { String taskid = json.getString("taskid"); boolean stop = false; QueryBuilder rBuilder = new QueryBuilder().add("start", String.valueOf(start)) .add("limit", String.valueOf(limit)).add("action", "query").add("dir", "DESC") .add("sort", order.equals(SortOrder.BySeeders) ? "seeds" : "date").add("taskid", taskid) .add("categories", "1").add("category", "_allcat_"); int loop = 0; while (!stop) { json = server.sendJSONRequest(SEARCH_URI, rBuilder.toString(), "GET"); if (json != null) { if (json.getBoolean("success")) { JSONArray items = new JSONArray(); boolean running = false; try { items = json.getJSONArray("items"); } catch (Exception e) { /*Do Nothing*/} try { running = json.getBoolean("running"); } catch (Exception e) { /*Do Nothing*/} if (!running || items.length() >= limit || loop == MAX_LOOP) { if (server.DEBUG) Log.i(Synodroid.DS_TAG, "DSMSearch: Found " + items.length() + " results from the search."); for (int i = 0; i < items.length(); i++) { JSONObject item = items.getJSONObject(i); SearchResult sr = new SearchResult(item.getInt("id"), item.getString("title"), item.getString("dlurl"), item.getString("page"), item.getString("size"), item.getString("date"), item.getInt("seeds"), item.getInt("leechs")); results.add(sr); } stop = true; } else { loop++; Thread.sleep(5000); if (server.DEBUG) Log.v(Synodroid.DS_TAG, "DSMSearch: Still running, not enough results and didn't reach max loop. Waiting 5 seconds for more results..."); } } else { loop++; Thread.sleep(5000); if (server.DEBUG) Log.v(Synodroid.DS_TAG, "DSMSearch: Success == False; Waiting 5 seconds for more results..."); } } else { stop = true; if (server.DEBUG) Log.w(Synodroid.DS_TAG, "DSMSearch: Search failed !!"); } } } } return results; } public List<Folder> getDirectoryListing(String srcPath) throws Exception { List<Folder> result = new ArrayList<Folder>(); String backPath = null; if (!srcPath.equals("fm_root")) { backPath = srcPath.substring(0, srcPath.lastIndexOf("/")); if (backPath.equals("remote")) { backPath = "fm_root"; } } // If we are logged on if (server.isConnected()) { QueryBuilder getDirectory = new QueryBuilder().add("action", "getshares").add("node", srcPath); // Execute JSONArray json; synchronized (server) { try { json = server.sendJSONRequestArray(FILE_URI, getDirectory.toString(), "GET"); } catch (Exception e) { Log.e(Synodroid.DS_TAG, "Directory Listing: Cannot go further in the directory.", e); json = new JSONArray(); } } if (backPath != null) result.add(new Folder(backPath, "..", backPath)); for (int i = 0; i < json.length(); i++) { if (!json.getJSONObject(i).getString("right").equals("RO")) { result.add(new Folder(json.getJSONObject(i).getString("id"), json.getJSONObject(i).getString("text"), json.getJSONObject(i).getString("spath"))); } } } return result; } }