params) throws HttpRequestException {
- HttpRequest req = HttpRequest.delete(account.server + apiPath, params, false)
- .followRedirects(true)
- .connectTimeout(CONNECTION_TIMEOUT);
-
- req.header("Authorization", "Token " + account.token);
-
- return prepareHttpsCheck(req);
- }
-
- /**
- * Login into the server
- *
- * @return true if login success, false otherwise
- * @throws SeafException
- */
- private boolean realLogin(String passwd, String authToken, boolean rememberDevice) throws SeafException {
- boolean withAuthToken = false;
- HttpRequest req = null;
- try {
- req = prepareApiPostRequest("api2/auth-token/", false, null);
- // Log.d(DEBUG_TAG, "Login to " + account.server + "api2/auth-token/");
-
- if (!TextUtils.isEmpty(authToken)) {
- req.header("X-Seafile-OTP", authToken);
- withAuthToken = true;
- // Log.d(DEBUG_TAG, "authToken " + authToken);
- }
- if (!TextUtils.isEmpty(account.sessionKey)) {
- req.header("X-SEAFILE-S2FA", account.sessionKey);
- }
- if (rememberDevice) {
- req.header("X-SEAFILE-2FA-TRUST-DEVICE", 1);
- }
- req.form("username", account.email);
- req.form("password", passwd);
-
- String appVersion = "";
- Context context = SeadroidApplication.getAppContext();
- try {
- PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
- appVersion = pInfo.versionName;
- } catch (NameNotFoundException e) {
- // ignore
- }
-
- //TODO Secure.getString(context.getContentResolver(), Secure.ANDROID_ID); ?
- String deviceId = DeviceIdManager.getInstance().getOrSet();
-
- req.form("platform", "android");
- req.form("device_id", deviceId);
- req.form("device_name", Build.MODEL);
- req.form("client_version", appVersion);
- req.form("platform_version", Build.VERSION.RELEASE);
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK, withAuthToken);
- String sessionKey = req.header("x-seafile-s2fa");
- if (!TextUtils.isEmpty(sessionKey)) {
- account.sessionKey = sessionKey;
- }
- String contentAsString = new String(req.bytes(), "UTF-8");
- JSONObject obj = Utils.parseJsonObject(contentAsString);
- if (obj == null)
- return false;
- account.token = obj.getString("token");
- return true;
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (IOException e) {
- e.printStackTrace();
- throw SeafException.networkException;
- } catch (JSONException e) {
- throw SeafException.illFormatException;
- }
- }
-
- /**
- *
- * get Account info, which consists of three fields, usage, total and email.
- *
- * use GET to send HTTP request.
- *
- * @return
- * @throws SeafException
- */
- public String getAccountInfo() throws SeafException {
-
- String result;
- try {
- HttpRequest req = prepareApiGetRequest("api2/account/info/");
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
- result = new String(req.bytes(), "UTF-8");
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (IOException e) {
- throw SeafException.networkException;
- }
-
- return result;
- }
-
- public String getServerInfo() throws SeafException {
-
- String result;
- try {
- HttpRequest req = prepareApiGetRequest("api2/server-info/");
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
- result = new String(req.bytes(), "UTF-8");
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (IOException e) {
- throw SeafException.networkException;
- }
- return result;
- }
-
- public boolean doLogin(String passwd, String authToken, boolean rememberDevice) throws SeafException {
- try {
- return realLogin(passwd, authToken, rememberDevice);
- } catch (Exception e) {
- // do again
- return realLogin(passwd, authToken, rememberDevice);
- }
- }
-
- public String getRepos() throws SeafException {
- HttpRequest req = null;
- try {
- req = prepareApiGetRequest("api/v2.1/repos/");
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- String result = new String(req.bytes(), "UTF-8");
- return result;
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (IOException e) {
- throw SeafException.networkException;
- }
- }
-
- public String getEvents(int start, boolean useNewActivity) throws SeafException {
- String apiPath;
- try {
- Map params = Maps.newHashMap();
- if (useNewActivity) {
- apiPath = String.format("api/v2.1/activities/");
- if (start == 0) {
- start = 1;
- }
- params.put("page", start);
- } else {
- apiPath = String.format("api2/events/");
- params.put("start", start);
- }
-
- HttpRequest req = prepareApiGetRequest(apiPath, params);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- return new String(req.bytes(), "UTF-8");
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (IOException e) {
- throw SeafException.networkException;
- }
- }
-
- public String getHistoryChanges(String repoID, String commitId) throws SeafException {
- try {
- String apiPath = String.format("api2/repo_history_changes/%s/", repoID);
- Map params = Maps.newHashMap();
- params.put("commit_id", commitId);
- HttpRequest req = prepareApiGetRequest(apiPath, params);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- String result = new String(req.bytes(), "UTF-8");
-
- return result;
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (IOException e) {
- throw SeafException.networkException;
- }
- }
-
- public String getStarredFiles() throws SeafException {
- try {
- HttpRequest req = prepareApiGetRequest(ApiUrls.STAR_ITEMS);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- return new String(req.bytes(), "UTF-8");
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (IOException e) {
- throw SeafException.networkException;
- }
- }
-
- public String getAvatar(String email, int size) throws SeafException {
- try {
- String apiPath = String.format("api2/avatars/user/%s/resized/%d", email, size);
- HttpRequest req = prepareApiGetRequest(apiPath);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- String result = new String(req.bytes(), "UTF-8");
- return result;
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (IOException e) {
- throw SeafException.networkException;
- }
- }
-
- public String searchLibraries(String query, int page, int pageSize) throws SeafException {
-
- try {
- Map params = Maps.newHashMap();
- params.put("q", encodeUriComponent(query));
-
- if (pageSize < 0) {
- page = 20;
- }
- params.put("per_page", pageSize);
- params.put("page", page);
-
- HttpRequest req = prepareApiGetRequest("api2/search/", params);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
- String result = new String(req.bytes(), "UTF-8");
- return result;
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (IOException e) {
- throw SeafException.networkException;
- }
-
- }
-
private static String encodeUriComponent(String src) throws UnsupportedEncodingException {
return URLEncoder.encode(src, "UTF-8");
}
- /**
- * Get the contents of a directory.
- *
- * @param repoID
- * @param path
- * @return A non-null Pair of (dirID, content). If the local cache is up to date, the "content" is null.
- * @throws SeafException
- */
- public String getDirents(String repoID, String path) throws SeafException {
- try {
- String apiPath = String.format(ApiUrls.REPOS_DIR, repoID);
- Map params = Maps.newHashMap();
- params.put("p", encodeUriComponent(path));
-
- HttpRequest req = prepareApiGetRequest(apiPath, params);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- byte[] rawBytes = req.bytes();
- if (rawBytes == null) {
- throw SeafException.unknownException;
- }
- return new String(rawBytes, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw SeafException.encodingException;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (IOException e) {
- throw SeafException.networkException;
- }
- }
-
public Pair getDownloadLink(String repoID, String path, boolean isReUsed) throws SeafException {
try {
String apiPath = String.format("api2/repos/%s/file/", repoID);
@@ -464,890 +128,49 @@ public Pair getDownloadLink(String repoID, String path, boolean
}
}
- public String getBlockDownloadList(String repoID, String path) throws SeafException, IOException {
- try {
- String apiPath = String.format("api2/repos/%s/file/", repoID);
- Map params = Maps.newHashMap();
- params.put("p", encodeUriComponent(path));
- params.put("op", "downloadblks");
- HttpRequest req = prepareApiGetRequest(apiPath, params);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- String result = new String(req.bytes(), "UTF-8");
- return result;
- } catch (SeafException | IOException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
- /**
- * get file server link for downloading a block
- *
- * @param repoID
- * @param fileId
- * @param blockId
- * @return
- * @throws SeafException
- * @throws IOException
- */
- private String getBlockDownloadLink(String repoID, String fileId, String blockId) throws SeafException, IOException {
- try {
- String apiPath = String.format("api2/repos/%s/files/%s/blks/%s/download-link/", repoID, fileId, blockId);
- HttpRequest req = prepareApiGetRequest(apiPath, null);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- return new String(req.bytes(), "UTF-8");
- } catch (SeafException | IOException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
- /**
- * Get the latest version of the file from server
- *
- * @param repoID
- * @param fileBlocks
- * @param blockId
- * @param localPath
- * @param monitor
- * @return A two tuple of (fileID, file). If the local cached version is up to date, the returned file is null.
- */
- public Pair getBlock(String repoID,
- FileBlocks fileBlocks,
- String blockId,
- String localPath,
- long fileSize,
- ProgressMonitor monitor) throws SeafException, IOException, JSONException {
- String dlink = getBlockDownloadLink(repoID, fileBlocks.getFileId(), blockId).replaceAll("\"", "");
-
- File block = getBlockFromLink(dlink, fileBlocks, blockId, localPath, fileSize, monitor);
- if (block != null) {
- return new Pair<>(blockId, block);
- } else {
- throw SeafException.unknownException;
- }
+ public String getReUsedFileLink(String repoID, String path) throws SeafException {
+ //Setting up links can be reused
+ Pair ret = getDownloadLink(repoID, path, true);
+ return ret.first;
}
+ private void checkRequestResponseStatus(HttpRequest req, int expectedStatusCode) throws SeafException {
+ if (req.code() != expectedStatusCode) {
+ Log.d(DEBUG_TAG, "HTTP request failed : " + req.url() + ", " + req.code() + ", " + req.message());
- private File getFileFromLink(String dlink, String path, String localPath, String oid, ProgressMonitor monitor) throws SeafException {
- if (dlink == null)
- return null;
-
- File file = new File(localPath);
-
- try {
- int i = dlink.lastIndexOf('/');
- String quoted = dlink.substring(0, i) + "/" + URLEncoder.encode(dlink.substring(i + 1), "UTF-8");
-
- HttpRequest req = prepareApiFileGetRequest(quoted);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- if (monitor != null) {
- Long size = -1L;
- if (req.contentLength() > 0) {
- size = Long.valueOf(req.contentLength());
+ if (req.message() == null) {
+ throw SeafException.networkException;
+ } else if (req.code() == HttpURLConnection.HTTP_UNAUTHORIZED) {
+ String wiped = req.header("X-Seafile-Wiped");
+ if (wiped != null) {
+ throw SeafException.remoteWipedException;
} else {
- // The req.contentLength() returns an int, which has a max value of
- // 2GB. So if a file size exceeds 2GB, request.contentLength() would
- // return -1. In such case, we parse the content length from the raw
- // header string directly.
- //
- // See https://github.com/kevinsawicki/http-request/blob/http-request-5.6/lib/src/main/java/com/github/kevinsawicki/http/HttpRequest.java#L2519-L2521
- String contentLengthheader = req.header(HttpRequest.HEADER_CONTENT_LENGTH);
- // The server may not send us the "Content-Length" header in the
- // response, e.g. when the server is using chunked transfer encoding.
- if (contentLengthheader != null) {
- size = Long.parseLong(contentLengthheader);
- }
+ throw new SeafException(req.code(), req.message());
}
-
- if (size > 0) {
- monitor.onProgressNotify(size, false);
+ } else {
+ try {
+ String result = new String(req.bytes(), "UTF-8");
+ if (result != null && Utils.parseJsonObject(result) != null) {
+ JSONObject json = Utils.parseJsonObject(result);
+ if (json.has("detail")) {
+ throw new SeafException(req.code(), json.optString("detail"));
+ }
+ throw new SeafException(req.code(), json.optString("error_msg"));
+ } else {
+ throw new SeafException(req.code(), req.message());
+ }
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ throw new SeafException(req.code(), req.message());
}
- }
- File tmp = DataManager.createTempFile();
- // Log.d(DEBUG_TAG, "write to " + tmp.getAbsolutePath());
- if (monitor == null) {
- req.receive(tmp);
- } else {
- req.bufferSize(MonitoredFileOutputStream.BUFFER_SIZE);
- req.receive(new MonitoredFileOutputStream(tmp, monitor));
}
+ } else {
+ // Log.v(DEBUG_TAG, "HTTP request ok : " + req.url());
+ }
+ }
- if (!tmp.renameTo(file)) {
- Log.w(DEBUG_TAG, "Rename file error");
- return null;
- }
- return file;
- } catch (SeafException e) {
- throw e;
- } catch (UnsupportedEncodingException e) {
- throw SeafException.encodingException;
- } catch (IOException e) {
- e.printStackTrace();
- throw SeafException.networkException;
- } catch (HttpRequestException e) {
- if (e.getCause() instanceof MonitorCancelledException) {
- // Log.d(DEBUG_TAG, "download is cancelled");
- throw SeafException.userCancelledException;
- } else {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
- }
-
- private File getBlockFromLink(String dlink, FileBlocks fileBlocks, String blkId, String localPath, long fileSize, ProgressMonitor monitor) throws SeafException {
- if (dlink == null)
- return null;
-
- try {
-
- HttpRequest req = prepareApiFileGetRequest(dlink);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- if (monitor != null) {
- /*if (req.header(HttpRequest.HEADER_CONTENT_LENGTH) == null) {
- throw SeafException.illFormatException;
- }
- Long size = Long.parseLong(req.header(HttpRequest.HEADER_CONTENT_LENGTH));*/
- if (req.contentLength() > 0) {
- monitor.onProgressNotify(fileSize, true);
- }
- }
-
- File block = new File(localPath);
- // Log.d(DEBUG_TAG, "write to " + block.getAbsolutePath());
- if (monitor == null) {
- req.receive(block);
- } else {
- req.bufferSize(DataManager.BUFFER_SIZE);
- req.receive(new MonitoredFileOutputStream(fileBlocks, blkId, block, monitor));
- }
-
- return block;
-
- } catch (SeafException e) {
- throw e;
- } catch (UnsupportedEncodingException e) {
- throw SeafException.encodingException;
- } catch (IOException e) {
- e.printStackTrace();
- throw SeafException.networkException;
- } catch (HttpRequestException e) {
- if (e.getCause() instanceof MonitorCancelledException) {
- // Log.d(DEBUG_TAG, "download is cancelled");
- throw SeafException.userCancelledException;
- } else {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
- }
-
- public String getReUsedFileLink(String repoID, String path) throws SeafException {
- //Setting up links can be reused
- Pair ret = getDownloadLink(repoID, path, true);
- return ret.first;
- }
-
- /**
- * Get the latest version of the file from server
- *
- * @param repoID
- * @param path
- * @param localPath
- * @param cachedFileID The file id of the local cached version
- * @param monitor
- * @return A two tuple of (fileID, file). If the local cached version is up to date, the returned file is null.
- */
- public Pair getFile(String repoID, String path, String localPath, String cachedFileID, ProgressMonitor monitor) throws SeafException {
- Pair ret = getDownloadLink(repoID, path, false);
- String dlink = ret.first;
- String fileID = ret.second;
-
- if (fileID.equals(cachedFileID)) {
- // cache is valid
- // Log.d(DEBUG_TAG, String.format("file %s is cached", path));
- return new Pair(fileID, null);
- } else {
- /*Log.d(DEBUG_TAG,
- String.format("file %s will be downloaded from server, latest %s, local cache %s",
- path, fileID, cachedFileID != null ? cachedFileID : "null"));*/
-
- File file = getFileFromLink(dlink, path, localPath, fileID, monitor);
- if (file != null) {
- return new Pair(fileID, file);
- } else {
- throw SeafException.unknownException;
- }
- }
- }
-
- // get encrypted repo info
- public String getEncryptRepo(String repoID) throws SeafException {
- Response response = null;
- try {
- String url = account.server + "api2/repos/" + repoID;
- Request request = new Request.Builder()
- .url(url)
- .header("Authorization", "Token " + account.token)
- .build();
- response = new OkHttpClient().newCall(request).execute();
- if (response.code() == HttpURLConnection.HTTP_OK) {
- return response.body().string();
- } else {
- throw new SeafException(response.code(), response.message());
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return "";
- }
-
- // set password for an encrypted repo
- public boolean setPassword(String repoID, String passwd) throws SeafException {
- try {
- HttpRequest req = prepareApiPostRequest("api2/repos/" + repoID + "/", true, null);
-
- req.form("password", passwd);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
- return true;
- } catch (SeafException e) {
- Log.d(DEBUG_TAG, "Set Password err: " + e.getCode());
- throw e;
- } catch (Exception e) {
- Log.d(DEBUG_TAG, "Exception in setPassword ");
- e.printStackTrace();
- }
- return false;
- }
-
- public void createNewRepo(String repoName, String description, String password) throws SeafException {
- HttpRequest req = prepareApiPostRequest("api2/repos/", true, null);
- req.form("name", repoName);
-
- if (description.length() > 0) {
- req.form("desc", description);
- }
-
- if (password.length() > 0) {
- req.form("passwd", password);
- }
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
- }
-
- public Pair createNewDir(String repoID, String parentDir, String dirName) throws SeafException {
-
- HttpRequest req = null;
- try {
- String fullPath = Utils.pathJoin(parentDir, dirName);
- final String encodeUriComponent = encodeUriComponent(fullPath).replaceAll("\\+", "%20");
- Map params = Maps.newHashMap();
- params.put("p", encodeUriComponent);
- params.put("reloaddir", "true");
-
- req = prepareApiPostRequest("api2/repos/" + repoID + "/dir/", true, params, false);
-
- req.form("operation", "mkdir");
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- String newDirID = req.header("oid");
- if (newDirID == null) {
- return null;
- }
-
- String content = new String(req.bytes(), "UTF-8");
- if (content.length() == 0) {
- return null;
- }
-
- return new Pair(newDirID, content);
-
- } catch (SeafException e) {
- throw e;
- } catch (UnsupportedEncodingException e) {
- throw SeafException.encodingException;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
- public Pair createNewFile(String repoID, String parentDir, String fileName) throws SeafException {
-
- try {
- String fullPath = Utils.pathJoin(parentDir, fileName);
- final String encodeUriComponent = encodeUriComponent(fullPath).replaceAll("\\+", "%20");
- Map params = Maps.newHashMap();
- params.put("p", encodeUriComponent);
- params.put("reloaddir", "true");
-
- HttpRequest req = prepareApiPostRequest("api2/repos/" + repoID + "/file/", true, params, false);
-
- req.form("operation", "create");
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- String newDirID = req.header("oid");
- if (newDirID == null) {
- return null;
- }
-
- String content = new String(req.bytes(), "UTF-8");
- if (content.length() == 0) {
- return null;
- }
-
- return new Pair(newDirID, content);
- } catch (SeafException e) {
- throw e;
- } catch (UnsupportedEncodingException e) {
- throw SeafException.encodingException;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
-
- /**
- * Wrap a FileInputStream in a upload task. We publish the progress of the upload during the process, and if we detect the task has been cancelled by the user, we throw a {@link MonitorCancelledException} to indicate such a situation.
- */
- private class MonitoredFileInputStream extends InputStream {
- public static final int BUFFER_SIZE = 1024;
-
-
- private static final long PROGRESS_UPDATE_INTERVAL = 1000;
- private ProgressMonitor monitor;
- private InputStream src;
- private long bytesRead = 0;
- private long nextUpdate = System.currentTimeMillis() + PROGRESS_UPDATE_INTERVAL;
-
- public MonitoredFileInputStream(File file, ProgressMonitor monitor) throws IOException {
- this.src = new FileInputStream(file);
- this.monitor = monitor;
- }
-
- @Override
- public int read(byte[] buffer) throws IOException {
- int read = src.read(buffer);
- if (read != -1) {
- bytesRead += read;
- }
-
- checkMonitor();
-
- return read;
- }
-
- @Override
- public int read() throws IOException {
- int ret = src.read();
- if (ret != -1) {
- ++bytesRead;
- if (bytesRead % BUFFER_SIZE == 0) {
- checkMonitor();
- }
- }
-
- return ret;
- }
-
- @Override
- public void close() throws IOException {
- src.close();
- }
-
- private void checkMonitor() throws MonitorCancelledException {
- if (monitor.isCancelled() ||
- Thread.currentThread().isInterrupted()) {
- throw new MonitorCancelledException();
- }
-
- if (System.currentTimeMillis() > nextUpdate) {
- monitor.onProgressNotify(bytesRead, false);
- nextUpdate = System.currentTimeMillis() + PROGRESS_UPDATE_INTERVAL;
- }
- }
- }
-
- /**
- * Wrap a FileOutputStream in a download task. We publish the upload progress during the process, and if we detect the task has been cancelled by the user, we throw a {@link MonitorCancelledException} to indicate such a situation.
- */
- private class MonitoredFileOutputStream extends OutputStream {
- public static final int BUFFER_SIZE = 4096;
-
- private static final long PROGRESS_UPDATE_INTERVAL = 500;
- private ProgressMonitor monitor;
- private OutputStream dst;
- private long bytesWritten = 0;
- private long nextUpdate = System.currentTimeMillis() + PROGRESS_UPDATE_INTERVAL;
-
- private FileBlocks fileBlocks;
- private String blockId;
-
- public MonitoredFileOutputStream(File file, ProgressMonitor monitor) throws IOException {
- this.dst = new FileOutputStream(file);
- this.monitor = monitor;
- }
-
- public MonitoredFileOutputStream(FileBlocks fileBlocks, String blockId, File file, ProgressMonitor monitor) throws IOException {
- this.dst = new FileOutputStream(file);
- this.monitor = monitor;
- if (fileBlocks != null) {
- this.fileBlocks = fileBlocks;
- this.blockId = blockId;
- }
- }
-
- @Override
- public void write(byte[] buffer, int off, int len) throws IOException {
- dst.write(buffer, off, len);
- bytesWritten += len;
- checkMonitor();
- }
-
- @Override
- public void write(byte[] buffer) throws IOException {
- dst.write(buffer);
- bytesWritten += buffer.length;
- checkMonitor();
- }
-
- @Override
- public void write(int b) throws IOException {
- dst.write(b);
- ++bytesWritten;
- if (bytesWritten % BUFFER_SIZE == 0) {
- checkMonitor();
- }
- }
-
- @Override
- public void close() throws IOException {
- dst.close();
- }
-
- private void checkMonitor() throws MonitorCancelledException {
- if (monitor.isCancelled() ||
- Thread.currentThread().isInterrupted()) {
- throw new MonitorCancelledException();
- }
-
- if (System.currentTimeMillis() > nextUpdate) {
- if (fileBlocks != null) {
- fileBlocks.getBlock(blockId).finished = bytesWritten;
- monitor.onProgressNotify(fileBlocks.getFinished(), false);
- } else {
- monitor.onProgressNotify(bytesWritten, false);
- }
- nextUpdate = System.currentTimeMillis() + PROGRESS_UPDATE_INTERVAL;
- }
- }
- }
-
- private class MonitorCancelledException extends IOException {
- private static final long serialVersionUID = -1170466989781746232L;
-
- @Override
- public String toString() {
- return "the upload/download task has been cancelled";
- }
- }
-
- public void renameRepo(String repoID, String newName) throws SeafException {
- Map params = Maps.newHashMap();
- params.put("op", "rename");
-
- HttpRequest req = prepareApiPostRequest(String.format("api2/repos/%s/", repoID), true, params);
- req.form("repo_name", newName);
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
- }
-
- public void deleteRepo(String repoID) throws SeafException {
- try {
- HttpRequest req = prepareApiDeleteRequest(String.format("api2/repos/%s/", repoID), null);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
-
- public boolean deleteShareLink(String token) throws SeafException {
- try {
- HttpRequest req = prepareApiDeleteRequest(String.format("api/v2.1/share-links/%s/", token), null);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
- String result = new String(req.bytes(), "UTF-8");
- if (result != null && Utils.parseJsonObject(result) != null) {
- JSONObject obj = Utils.parseJsonObject(result);
- return obj.getBoolean("success");
- } else {
- throw SeafException.illFormatException;
- }
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (JSONException e) {
- e.printStackTrace();
- }
- return false;
- }
-
-
- public String getShareLink(String repoID, String path) throws SeafException {
- try {
- Map params = Maps.newHashMap();
- params.put("repo_id", repoID);
- params.put("path", path);
- HttpRequest req = prepareApiGetRequest("api/v2.1/share-links", params);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
- String result = new String(req.bytes(), "UTF-8");
- return result;
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (IOException e) {
- throw SeafException.networkException;
- }
- }
-
- public String getShareLink(String repoID, String path, String password, String days) throws SeafException {
- try {
- Map params = Maps.newHashMap();
- HttpRequest req = prepareApiPostRequest("api/v2.1/share-links/", true, params, false);
- req.form("repo_id", repoID);
- req.form("path", path);
- if (!TextUtils.isEmpty(password)) {
- req.form("password", password);
- }
- if (!TextUtils.isEmpty(days)) {
- req.form("expire_days", days);
- }
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
- String result = new String(req.bytes(), "UTF-8");
- if (result != null && Utils.parseJsonObject(result) != null) {
- JSONObject obj = Utils.parseJsonObject(result);
- return obj.getString("link");
- } else {
- throw SeafException.illFormatException;
- }
-
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (UnsupportedEncodingException e) {
- throw SeafException.illFormatException;
- } catch (JSONException e) {
- e.printStackTrace();
- throw SeafException.illFormatException;
- }
- }
-
- public void completeRemoteWipe(String token) throws SeafException {
- try {
- HttpRequest req = prepareApiPostRequest("api2/device-wiped/", true, null);
- req.form("token", token);
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_CREATED);
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
- public void star(String repoID, String path) throws SeafException {
- try {
- //api/v2.1/starred-items/
- HttpRequest req = prepareApiPostRequest("api2/starredfiles/", true, null);
-
- req.form("repo_id", repoID);
- req.form("p", path);
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_CREATED);
-
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
- public void starItems(String repoID, String path) throws SeafException {
- try {
- //api/v2.1/starred-items/
- HttpRequest req = prepareApiPostRequest(ApiUrls.STAR_ITEMS, true, null);
-
- req.form("repo_id", repoID);
- req.form("path", path);
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
- public void unstar(String repoID, String path) throws SeafException {
- try {
- Map params = Maps.newHashMap();
- params.put("repo_id", repoID);
- params.put("p", path);
- HttpRequest req = prepareApiDeleteRequest("api2/starredfiles/", params);
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
- public void unstarItems(String repoID, String path) throws SeafException {
- try {
- Map params = Maps.newHashMap();
- params.put("repo_id", repoID);
- params.put("path", path);
- HttpRequest req = prepareApiDeleteRequest(ApiUrls.STAR_ITEMS, params);
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
- public Pair rename(String repoID, String path, String newName, boolean isdir) throws SeafException {
- try {
- Map params = Maps.newHashMap();
- params.put("p", encodeUriComponent(path).replaceAll("\\+", "%20"));
- params.put("reloaddir", "true");
- String suffix = isdir ? "/dir/" : "/file/";
- HttpRequest req = prepareApiPostRequest("api2/repos/" + repoID + suffix, true, params);
-
- req.form("operation", "rename");
- req.form("newname", newName);
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- String newDirID = req.header("oid");
- if (newDirID == null) {
- return null;
- }
-
- String content = new String(req.bytes(), "UTF-8");
- if (content.length() == 0) {
- return null;
- }
-
- return new Pair(newDirID, content);
- } catch (SeafException e) {
- throw e;
- } catch (UnsupportedEncodingException e) {
- throw SeafException.encodingException;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
- public boolean delete(String repoID, String path, boolean isdir) throws SeafException {
- try {
- Map params = Maps.newHashMap();
- params.put("p", encodeUriComponent(path).replaceAll("\\+", "%20"));
- String suffix = isdir ? "/dir/" : "/file/";
- HttpRequest req = prepareApiDeleteRequest(ApiUrls.DELETE_FILE_OR_DIR + repoID + suffix, params);
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- String content = new String(req.bytes(), "UTF-8");
- if (content.length() == 0) {
- return false;
- }
-
- JSONObject jsonObject = new JSONObject(content);
- return jsonObject.optBoolean("success");
- } catch (SeafException e) {
- throw e;
- } catch (UnsupportedEncodingException e) {
- throw SeafException.encodingException;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (JSONException e) {
- throw SeafException.illFormatException;
- }
- }
-
- /**
- * Copy a file or multiple files, multiple file/folder names should be seperated by a ":".
- *
- * @param srcRepoId the source repo id
- * @param srcDir the source folder in src_repo
- * @param srcFn list of file/folder names to copy. Multiple file/folder names can be seperated by ":"
- * @param dstRepoId the destination repo id
- * @param dstDir the destination folder in dst_repo
- * @throws SeafException
- */
- public void copy(String srcRepoId, String srcDir, String srcFn, String dstRepoId, String dstDir) throws SeafException {
- try {
- Map params = Maps.newHashMap();
- params.put("p", encodeUriComponent(srcDir).replaceAll("\\+", "%20"));
-
- HttpRequest req = prepareApiPostRequest("api2/repos/" + srcRepoId + "/fileops/copy/", true, params);
-
- req.form("dst_repo", dstRepoId);
- req.form("dst_dir", dstDir);
- req.form("file_names", srcFn);
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- } catch (UnsupportedEncodingException e) {
- throw SeafException.encodingException;
- }
- }
-
- /**
- * Move multiple files
- *
- * @param srcRepoId the source repo id
- * @param srcDir the source folder in src_repo
- * @param srcFn list of file/folder names to move. Multiple file/folder names can be seperated by ":"
- * @param dstRepoId the destination repo id
- * @param dstDir the destination folder in dst_repo
- * @throws SeafException
- */
- public void move(String srcRepoId, String srcDir, String srcFn, String dstRepoId, String dstDir) throws SeafException {
- try {
- Map params = Maps.newHashMap();
- params.put("p", srcDir);
-
- HttpRequest req = prepareApiPostRequest("api2/repos/" + srcRepoId + "/fileops/move/", true, params);
-
- req.form("dst_repo", dstRepoId);
- req.form("dst_dir", dstDir);
- req.form("file_names", srcFn);
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- } catch (SeafException e) {
- throw e;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
- /**
- * Move a single file
- *
- * @param srcRepoId the source repo id
- * @param srcPath the source file path
- * @param dstRepoId the destination repo id
- * @param dstDir the destination folder in dst_repo
- * @return
- * @throws SeafException
- */
- public Pair move(String srcRepoId, String srcPath, String dstRepoId, String dstDir) throws SeafException {
- try {
- Map params = Maps.newHashMap();
- params.put("p", encodeUriComponent(srcPath).replaceAll("\\+", "%20"));
- params.put("reloaddir", "true");
- String suffix = "/file/";
- HttpRequest req = prepareApiPostRequest("api2/repos/" + srcRepoId + suffix, true, params);
-
- req.form("operation", "move");
- req.form("dst_repo", dstRepoId);
- req.form("dst_dir", dstDir);
-
- checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK);
-
- String newDirID = req.header("oid");
- if (newDirID == null) {
- return null;
- }
-
- String content = new String(req.bytes(), "UTF-8");
- if (content.length() == 0) {
- return null;
- }
-
- return new Pair(newDirID, content);
- } catch (SeafException e) {
- throw e;
- } catch (UnsupportedEncodingException e) {
- throw SeafException.encodingException;
- } catch (HttpRequestException e) {
- throw getSeafExceptionFromHttpRequestException(e);
- }
- }
-
- private void checkRequestResponseStatus(HttpRequest req, int expectedStatusCode) throws SeafException {
- if (req.code() != expectedStatusCode) {
- Log.d(DEBUG_TAG, "HTTP request failed : " + req.url() + ", " + req.code() + ", " + req.message());
-
- if (req.message() == null) {
- throw SeafException.networkException;
- } else if (req.code() == HttpURLConnection.HTTP_UNAUTHORIZED) {
- String wiped = req.header("X-Seafile-Wiped");
- if (wiped != null) {
- throw SeafException.remoteWipedException;
- } else {
- throw new SeafException(req.code(), req.message());
- }
- } else {
- try {
- String result = new String(req.bytes(), "UTF-8");
- if (result != null && Utils.parseJsonObject(result) != null) {
- JSONObject json = Utils.parseJsonObject(result);
- if (json.has("detail")) {
- throw new SeafException(req.code(), json.optString("detail"));
- }
- throw new SeafException(req.code(), json.optString("error_msg"));
- } else {
- throw new SeafException(req.code(), req.message());
- }
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- throw new SeafException(req.code(), req.message());
- }
-
- }
- } else {
- // Log.v(DEBUG_TAG, "HTTP request ok : " + req.url());
- }
- }
-
- private void checkRequestResponseStatus(HttpRequest req, int expectedStatusCode, boolean withAuthToken) throws SeafException {
- if (req.code() != expectedStatusCode) {
- Log.d(DEBUG_TAG, "HTTP request failed : " + req.url() + ", " + req.code() + ", " + req.message());
-
- if (req.message() == null) {
- throw SeafException.networkException;
- } else if (req.header("X-Seafile-OTP") != null && req.header("X-Seafile-OTP").equals("required")) {
- if (withAuthToken)
- throw SeafException.twoFactorAuthTokenInvalid;
- else
- throw SeafException.twoFactorAuthTokenMissing;
- } else {
- throw new SeafException(req.code(), req.message());
- }
- } else {
- // Log.v(DEBUG_TAG, "HTTP request ok : " + req.url());
- }
- }
private SeafException getSeafExceptionFromHttpRequestException(HttpRequestException e) {
if (e.getCause() instanceof SSLHandshakeException) {
diff --git a/app/src/main/res/layout/layout_frame_swipe_rv.xml b/app/src/main/res/layout/layout_frame_swipe_rv.xml
index f5f5d54a2..59739b80b 100644
--- a/app/src/main/res/layout/layout_frame_swipe_rv.xml
+++ b/app/src/main/res/layout/layout_frame_swipe_rv.xml
@@ -1,6 +1,5 @@