parent
f0bc470b75
commit
39a43c836d
@ -0,0 +1,66 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.common; |
||||||
|
|
||||||
|
import com.arialyy.aria.core.inf.AbsTarget; |
||||||
|
import com.arialyy.aria.core.inf.ITargetHandler; |
||||||
|
import com.arialyy.aria.util.CommonUtil; |
||||||
|
|
||||||
|
public abstract class BaseDelegate<TARGET extends AbsTarget> implements ITargetHandler { |
||||||
|
protected TARGET mTarget; |
||||||
|
protected final String TAG; |
||||||
|
|
||||||
|
public BaseDelegate(TARGET target) { |
||||||
|
mTarget = target; |
||||||
|
TAG = CommonUtil.getClassName(getClass()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void add() { |
||||||
|
mTarget.add(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void start() { |
||||||
|
mTarget.start(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void stop() { |
||||||
|
mTarget.stop(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void resume() { |
||||||
|
mTarget.resume(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void cancel() { |
||||||
|
mTarget.cancel(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void save() { |
||||||
|
mTarget.save(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void cancel(boolean removeFile) { |
||||||
|
mTarget.cancel(removeFile); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void reTry() { |
||||||
|
mTarget.reTry(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void reStart() { |
||||||
|
mTarget.reStart(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,88 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.common.ftp; |
||||||
|
|
||||||
|
import com.arialyy.aria.core.FtpUrlEntity; |
||||||
|
import com.arialyy.aria.core.inf.ITaskConfig; |
||||||
|
import java.net.Proxy; |
||||||
|
|
||||||
|
/** |
||||||
|
* fTP任务设置的信息,如:用户名、密码、端口等信息 |
||||||
|
*/ |
||||||
|
public class FtpTaskConfig implements ITaskConfig { |
||||||
|
|
||||||
|
/** |
||||||
|
* 账号和密码 |
||||||
|
*/ |
||||||
|
private FtpUrlEntity urlEntity; |
||||||
|
|
||||||
|
private Proxy proxy; |
||||||
|
|
||||||
|
/** |
||||||
|
* 字符编码,默认为"utf-8" |
||||||
|
*/ |
||||||
|
private String charSet = "utf-8"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传拦截器 |
||||||
|
*/ |
||||||
|
private IFtpUploadInterceptor uploadInterceptor; |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传到服务器文件的新文件名{@link FtpInterceptHandler#getNewFileName()} |
||||||
|
*/ |
||||||
|
private String newFileName; |
||||||
|
|
||||||
|
public String getNewFileName() { |
||||||
|
return newFileName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setNewFileName(String newFileName) { |
||||||
|
this.newFileName = newFileName; |
||||||
|
} |
||||||
|
|
||||||
|
public IFtpUploadInterceptor getUploadInterceptor() { |
||||||
|
return uploadInterceptor; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUploadInterceptor(IFtpUploadInterceptor uploadInterceptor) { |
||||||
|
this.uploadInterceptor = uploadInterceptor; |
||||||
|
} |
||||||
|
|
||||||
|
public FtpUrlEntity getUrlEntity() { |
||||||
|
return urlEntity; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUrlEntity(FtpUrlEntity urlEntity) { |
||||||
|
this.urlEntity = urlEntity; |
||||||
|
} |
||||||
|
|
||||||
|
public void setProxy(Proxy proxy) { |
||||||
|
this.proxy = proxy; |
||||||
|
} |
||||||
|
|
||||||
|
public Proxy getProxy() { |
||||||
|
return proxy; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCharSet() { |
||||||
|
return charSet; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCharSet(String charSet) { |
||||||
|
this.charSet = charSet; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,198 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.common.http; |
||||||
|
|
||||||
|
import com.arialyy.aria.core.common.RequestEnum; |
||||||
|
import com.arialyy.aria.core.inf.IHttpFileLenAdapter; |
||||||
|
import com.arialyy.aria.core.inf.ITaskConfig; |
||||||
|
import java.net.CookieManager; |
||||||
|
import java.net.Proxy; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Http任务设置的信息,如:cookie、请求参数 |
||||||
|
*/ |
||||||
|
public class HttpTaskConfig implements ITaskConfig { |
||||||
|
|
||||||
|
private CookieManager cookieManager; |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求参数 |
||||||
|
*/ |
||||||
|
private Map<String, String> params; |
||||||
|
|
||||||
|
/** |
||||||
|
* http 请求头 |
||||||
|
*/ |
||||||
|
private Map<String, String> headers = new HashMap<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 字符编码,默认为"utf-8" |
||||||
|
*/ |
||||||
|
private String charSet = "utf-8"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 网络请求类型 |
||||||
|
*/ |
||||||
|
private RequestEnum requestEnum = RequestEnum.GET; |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否使用服务器通过content-disposition传递的文件名,内容格式{@code attachment; filename="filename.jpg"} {@code true} |
||||||
|
* 使用 |
||||||
|
*/ |
||||||
|
private boolean useServerFileName = false; |
||||||
|
|
||||||
|
/** |
||||||
|
* 重定向链接 |
||||||
|
*/ |
||||||
|
private String redirectUrl = ""; |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否是chunk模式 |
||||||
|
*/ |
||||||
|
private boolean isChunked = false; |
||||||
|
/** |
||||||
|
* 文件上传需要的key |
||||||
|
*/ |
||||||
|
private String attachment; |
||||||
|
/** |
||||||
|
* 上传的文件类型 |
||||||
|
*/ |
||||||
|
private String contentType = "multipart/form-data"; |
||||||
|
private String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)"; |
||||||
|
|
||||||
|
private Proxy proxy; |
||||||
|
/** |
||||||
|
* 文件上传表单 |
||||||
|
*/ |
||||||
|
private Map<String, String> formFields = new HashMap<>(); |
||||||
|
|
||||||
|
private IHttpFileLenAdapter fileLenAdapter; |
||||||
|
|
||||||
|
public IHttpFileLenAdapter getFileLenAdapter() { |
||||||
|
return fileLenAdapter; |
||||||
|
} |
||||||
|
|
||||||
|
public void setFileLenAdapter(IHttpFileLenAdapter fileLenAdapter) { |
||||||
|
this.fileLenAdapter = fileLenAdapter; |
||||||
|
} |
||||||
|
|
||||||
|
public Map<String, String> getFormFields() { |
||||||
|
return formFields; |
||||||
|
} |
||||||
|
|
||||||
|
public void setFormFields(Map<String, String> formFields) { |
||||||
|
this.formFields = formFields; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAttachment() { |
||||||
|
return attachment; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAttachment(String attachment) { |
||||||
|
this.attachment = attachment; |
||||||
|
} |
||||||
|
|
||||||
|
public String getContentType() { |
||||||
|
return contentType; |
||||||
|
} |
||||||
|
|
||||||
|
public void setContentType(String contentType) { |
||||||
|
this.contentType = contentType; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUserAgent() { |
||||||
|
return userAgent; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUserAgent(String userAgent) { |
||||||
|
this.userAgent = userAgent; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isChunked() { |
||||||
|
return isChunked; |
||||||
|
} |
||||||
|
|
||||||
|
public void setChunked(boolean chunked) { |
||||||
|
isChunked = chunked; |
||||||
|
} |
||||||
|
|
||||||
|
public CookieManager getCookieManager() { |
||||||
|
return cookieManager; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCookieManager(CookieManager cookieManager) { |
||||||
|
this.cookieManager = cookieManager; |
||||||
|
} |
||||||
|
|
||||||
|
public Proxy getProxy() { |
||||||
|
return proxy; |
||||||
|
} |
||||||
|
|
||||||
|
public void setProxy(Proxy proxy) { |
||||||
|
this.proxy = proxy; |
||||||
|
} |
||||||
|
|
||||||
|
public Map<String, String> getHeaders() { |
||||||
|
return headers; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHeaders(Map<String, String> headers) { |
||||||
|
this.headers = headers; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCharSet() { |
||||||
|
return charSet; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCharSet(String charSet) { |
||||||
|
this.charSet = charSet; |
||||||
|
} |
||||||
|
|
||||||
|
public RequestEnum getRequestEnum() { |
||||||
|
return requestEnum; |
||||||
|
} |
||||||
|
|
||||||
|
public void setRequestEnum(RequestEnum requestEnum) { |
||||||
|
this.requestEnum = requestEnum; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isUseServerFileName() { |
||||||
|
return useServerFileName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUseServerFileName(boolean useServerFileName) { |
||||||
|
this.useServerFileName = useServerFileName; |
||||||
|
} |
||||||
|
|
||||||
|
public String getRedirectUrl() { |
||||||
|
return redirectUrl; |
||||||
|
} |
||||||
|
|
||||||
|
public void setRedirectUrl(String redirectUrl) { |
||||||
|
this.redirectUrl = redirectUrl; |
||||||
|
} |
||||||
|
|
||||||
|
public Map<String, String> getParams() { |
||||||
|
return params; |
||||||
|
} |
||||||
|
|
||||||
|
public void setParams(Map<String, String> params) { |
||||||
|
this.params = params; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,158 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.download; |
||||||
|
|
||||||
|
import android.support.annotation.CheckResult; |
||||||
|
import android.text.TextUtils; |
||||||
|
import com.arialyy.aria.core.inf.IGroupConfigHandler; |
||||||
|
import com.arialyy.aria.core.queue.DownloadGroupTaskQueue; |
||||||
|
import com.arialyy.aria.orm.DbEntity; |
||||||
|
import com.arialyy.aria.util.ALog; |
||||||
|
import com.arialyy.aria.util.CommonUtil; |
||||||
|
import java.io.File; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by lyy on 2019/4/9. |
||||||
|
* 下载组合任务功能 |
||||||
|
*/ |
||||||
|
abstract class AbsGroupConfigHandler<TARGET extends AbsDGTarget> implements IGroupConfigHandler { |
||||||
|
protected String TAG; |
||||||
|
private TARGET mTarget; |
||||||
|
private DGTaskWrapper mWrapper; |
||||||
|
/** |
||||||
|
* 组任务名 |
||||||
|
*/ |
||||||
|
private String mGroupHash; |
||||||
|
/** |
||||||
|
* 文件夹临时路径 |
||||||
|
*/ |
||||||
|
private String mDirPathTemp; |
||||||
|
/** |
||||||
|
* 是否需要修改路径 |
||||||
|
*/ |
||||||
|
private boolean needModifyPath = false; |
||||||
|
|
||||||
|
AbsGroupConfigHandler(TARGET target, DGTaskWrapper wrapper) { |
||||||
|
TAG = CommonUtil.getClassName(getClass()); |
||||||
|
mTarget = target; |
||||||
|
mWrapper = wrapper; |
||||||
|
setGroupHash(wrapper.getKey()); |
||||||
|
mTarget.setTaskWrapper(wrapper); |
||||||
|
if (getEntity() != null) { |
||||||
|
mDirPathTemp = getEntity().getDirPath(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean isRunning() { |
||||||
|
DownloadGroupTask task = DownloadGroupTaskQueue.getInstance().getTask(getEntity().getKey()); |
||||||
|
return task != null && task.isRunning(); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
TARGET setDirPath(String dirPath) { |
||||||
|
mDirPathTemp = dirPath; |
||||||
|
return mTarget; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 改变任务组文件夹路径,修改文件夹路径会将子任务所有路径更换 |
||||||
|
* |
||||||
|
* @param newDirPath 新的文件夹路径 |
||||||
|
*/ |
||||||
|
void reChangeDirPath(String newDirPath) { |
||||||
|
ALog.d(TAG, String.format("修改新路径为:%s", newDirPath)); |
||||||
|
List<DTaskWrapper> subTasks = mWrapper.getSubTaskWrapper(); |
||||||
|
if (subTasks != null && !subTasks.isEmpty()) { |
||||||
|
List<DownloadEntity> des = new ArrayList<>(); |
||||||
|
for (DTaskWrapper dte : subTasks) { |
||||||
|
DownloadEntity de = dte.getEntity(); |
||||||
|
String oldPath = de.getDownloadPath(); |
||||||
|
String newPath = newDirPath + "/" + de.getFileName(); |
||||||
|
File file = new File(oldPath); |
||||||
|
if (file.exists()) { |
||||||
|
file.renameTo(new File(newPath)); |
||||||
|
} |
||||||
|
de.setDownloadPath(newPath); |
||||||
|
des.add(de); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查并设置文件夹路径 |
||||||
|
* |
||||||
|
* @return {@code true} 合法 |
||||||
|
*/ |
||||||
|
@Override public boolean checkDirPath() { |
||||||
|
if (TextUtils.isEmpty(mDirPathTemp)) { |
||||||
|
ALog.e(TAG, "文件夹路径不能为null"); |
||||||
|
return false; |
||||||
|
} else if (!mDirPathTemp.startsWith("/")) { |
||||||
|
ALog.e(TAG, "文件夹路径【" + mDirPathTemp + "】错误"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
File file = new File(mDirPathTemp); |
||||||
|
if (file.isFile()) { |
||||||
|
ALog.e(TAG, "路径【" + mDirPathTemp + "】是文件,请设置文件夹路径"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (TextUtils.isEmpty(getEntity().getDirPath()) || !getEntity().getDirPath() |
||||||
|
.equals(mDirPathTemp)) { |
||||||
|
if (!file.exists()) { |
||||||
|
file.mkdirs(); |
||||||
|
} |
||||||
|
needModifyPath = true; |
||||||
|
getEntity().setDirPath(mDirPathTemp); |
||||||
|
ALog.i(TAG, String.format("文件夹路径改变,将更新文件夹路径为:%s", mDirPathTemp)); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public DownloadGroupEntity getEntity() { |
||||||
|
return mWrapper.getEntity(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean taskExists() { |
||||||
|
return DbEntity.checkDataExist(DownloadGroupEntity.class, "groupHash=?", mWrapper.getKey()); |
||||||
|
} |
||||||
|
|
||||||
|
DGTaskWrapper getTaskWrapper() { |
||||||
|
return mWrapper; |
||||||
|
} |
||||||
|
|
||||||
|
boolean isNeedModifyPath() { |
||||||
|
return needModifyPath; |
||||||
|
} |
||||||
|
|
||||||
|
String getDirPathTemp() { |
||||||
|
return mDirPathTemp; |
||||||
|
} |
||||||
|
|
||||||
|
TARGET getTarget() { |
||||||
|
return mTarget; |
||||||
|
} |
||||||
|
|
||||||
|
public String getGroupHash() { |
||||||
|
return mGroupHash; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGroupHash(String groupHash) { |
||||||
|
this.mGroupHash = groupHash; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,201 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.download; |
||||||
|
|
||||||
|
import android.text.TextUtils; |
||||||
|
import com.arialyy.aria.core.inf.ITargetHandler; |
||||||
|
import com.arialyy.aria.core.inf.IConfigHandler; |
||||||
|
import com.arialyy.aria.core.manager.TaskWrapperManager; |
||||||
|
import com.arialyy.aria.core.queue.DownloadTaskQueue; |
||||||
|
import com.arialyy.aria.orm.DbEntity; |
||||||
|
import com.arialyy.aria.util.ALog; |
||||||
|
import com.arialyy.aria.util.CheckUtil; |
||||||
|
import com.arialyy.aria.util.CommonUtil; |
||||||
|
import java.io.File; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by AriaL on 2019/4/5. |
||||||
|
* 普通下载任务通用功能处理 |
||||||
|
*/ |
||||||
|
class DNormalConfigHandler<TARGET extends AbsDTarget> implements IConfigHandler { |
||||||
|
private final String TAG = "DNormalDelegate"; |
||||||
|
private DownloadEntity mEntity; |
||||||
|
|
||||||
|
private TARGET mTarget; |
||||||
|
private String mNewUrl; |
||||||
|
/** |
||||||
|
* 设置的文件保存路径的临时变量 |
||||||
|
*/ |
||||||
|
private String mTempFilePath; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@code true}强制下载,不考虑文件路径是否被占用 |
||||||
|
*/ |
||||||
|
private boolean forceDownload = false; |
||||||
|
/** |
||||||
|
* 资源地址 |
||||||
|
*/ |
||||||
|
private String mUrl; |
||||||
|
|
||||||
|
DNormalConfigHandler(TARGET target, String url, String targetName) { |
||||||
|
this.mTarget = target; |
||||||
|
initTarget(url, targetName); |
||||||
|
} |
||||||
|
|
||||||
|
private void initTarget(String url, String targetName) { |
||||||
|
DTaskWrapper taskWrapper = |
||||||
|
TaskWrapperManager.getInstance().getHttpTaskWrapper(DTaskWrapper.class, url); |
||||||
|
mEntity = taskWrapper.getEntity(); |
||||||
|
|
||||||
|
mUrl = url; |
||||||
|
mTarget.setTargetName(targetName); |
||||||
|
mTarget.setTaskWrapper(taskWrapper); |
||||||
|
if (mEntity != null) { |
||||||
|
mTempFilePath = mEntity.getDownloadPath(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
TARGET updateUrl(String newUrl) { |
||||||
|
if (TextUtils.isEmpty(newUrl)) { |
||||||
|
ALog.e(TAG, "url更新失败,newUrl为null"); |
||||||
|
return mTarget; |
||||||
|
} |
||||||
|
if (mUrl.equals(newUrl)) { |
||||||
|
ALog.e(TAG, "url更新失败,新的下载url和旧的url一致"); |
||||||
|
return mTarget; |
||||||
|
} |
||||||
|
mNewUrl = newUrl; |
||||||
|
mTarget.getTaskWrapper().setRefreshInfo(true); |
||||||
|
return mTarget; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public DownloadEntity getEntity() { |
||||||
|
return mTarget.getEntity(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean taskExists() { |
||||||
|
return DbEntity.checkDataExist(DownloadEntity.class, "url=?", mUrl); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean isRunning() { |
||||||
|
DownloadTask task = DownloadTaskQueue.getInstance().getTask(mEntity.getKey()); |
||||||
|
return task != null && task.isRunning(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean checkEntity() { |
||||||
|
boolean b = checkUrl() && checkFilePath(); |
||||||
|
if (b) { |
||||||
|
mEntity.save(); |
||||||
|
} |
||||||
|
return b; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean checkFilePath() { |
||||||
|
String filePath = mTempFilePath; |
||||||
|
if (TextUtils.isEmpty(filePath)) { |
||||||
|
ALog.e(TAG, "下载失败,文件保存路径为null"); |
||||||
|
return false; |
||||||
|
} else if (!filePath.startsWith("/")) { |
||||||
|
ALog.e(TAG, "下载失败,文件保存路径【" + filePath + "】错误"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
File file = new File(filePath); |
||||||
|
if (file.isDirectory()) { |
||||||
|
if (mTarget.getTargetType() == ITargetHandler.D_HTTP) { |
||||||
|
ALog.e(TAG, "下载失败,保存路径【" + filePath + "】不能为文件夹,路径需要是完整的文件路径,如:/mnt/sdcard/game.zip"); |
||||||
|
return false; |
||||||
|
} else if (mTarget.getTargetType() == ITargetHandler.D_FTP) { |
||||||
|
filePath += mEntity.getFileName(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
// http文件名设置
|
||||||
|
if (TextUtils.isEmpty(mEntity.getFileName())) { |
||||||
|
mEntity.setFileName(file.getName()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//设置文件保存路径,如果新文件路径和旧文件路径不同,则修改路径
|
||||||
|
if (!filePath.equals(mEntity.getFilePath())) { |
||||||
|
// 检查路径冲突
|
||||||
|
if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) { |
||||||
|
if (!forceDownload) { |
||||||
|
ALog.e(TAG, "下载失败,保存路径【" + filePath + "】已经被其它任务占用,请设置其它保存路径"); |
||||||
|
return false; |
||||||
|
} else { |
||||||
|
ALog.w(TAG, "保存路径【" + filePath + "】已经被其它任务占用,当前任务将覆盖该路径的文件"); |
||||||
|
CommonUtil.delTaskRecord(filePath, 1); |
||||||
|
mTarget.setTaskWrapper( |
||||||
|
TaskWrapperManager.getInstance() |
||||||
|
.getHttpTaskWrapper(DTaskWrapper.class, mUrl)); |
||||||
|
} |
||||||
|
} |
||||||
|
File oldFile = new File(mEntity.getDownloadPath()); |
||||||
|
File newFile = new File(filePath); |
||||||
|
mEntity.setDownloadPath(filePath); |
||||||
|
mEntity.setFileName(newFile.getName()); |
||||||
|
// 如过使用Content-Disposition中的文件名,将不会执行重命名工作
|
||||||
|
if (mTarget.getTaskWrapper().asHttp().isUseServerFileName()) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
if (oldFile.exists()) { |
||||||
|
// 处理普通任务的重命名
|
||||||
|
CommonUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath()); |
||||||
|
ALog.i(TAG, String.format("将任务重命名为:%s", newFile.getName())); |
||||||
|
} else if (CommonUtil.blockTaskExists(oldFile.getPath())) { |
||||||
|
// 处理分块任务的重命名
|
||||||
|
CommonUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath()); |
||||||
|
ALog.i(TAG, String.format("将分块任务重命名为:%s", newFile.getName())); |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean checkUrl() { |
||||||
|
final String url = mEntity.getUrl(); |
||||||
|
if (TextUtils.isEmpty(url)) { |
||||||
|
ALog.e(TAG, "下载失败,url为null"); |
||||||
|
return false; |
||||||
|
} else if (!CheckUtil.checkUrlNotThrow(url)) { |
||||||
|
ALog.e(TAG, "下载失败,url【" + url + "】错误"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
int index = url.indexOf("://"); |
||||||
|
if (index == -1) { |
||||||
|
ALog.e(TAG, "下载失败,url【" + url + "】不合法"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (!TextUtils.isEmpty(mNewUrl)) { |
||||||
|
mEntity.setUrl(mNewUrl); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
void setForceDownload(boolean forceDownload) { |
||||||
|
this.forceDownload = forceDownload; |
||||||
|
} |
||||||
|
|
||||||
|
void setUrl(String url) { |
||||||
|
this.mUrl = url; |
||||||
|
} |
||||||
|
|
||||||
|
String getUrl() { |
||||||
|
return mUrl; |
||||||
|
} |
||||||
|
|
||||||
|
void setTempFilePath(String mTempFilePath) { |
||||||
|
this.mTempFilePath = mTempFilePath; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,91 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.download; |
||||||
|
|
||||||
|
import android.text.TextUtils; |
||||||
|
import com.arialyy.aria.core.FtpUrlEntity; |
||||||
|
import com.arialyy.aria.core.inf.AbsTaskWrapper; |
||||||
|
import com.arialyy.aria.util.ALog; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by lyy on 2017/4/9. |
||||||
|
* ftp文件夹下载功能代理 |
||||||
|
*/ |
||||||
|
class FtpDirConfigHandler extends AbsGroupConfigHandler<FtpDirDownloadTarget> { |
||||||
|
FtpDirConfigHandler(FtpDirDownloadTarget target, DGTaskWrapper wrapper) { |
||||||
|
super(target, wrapper); |
||||||
|
wrapper.setRequestType(AbsTaskWrapper.D_FTP_DIR); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean checkEntity() { |
||||||
|
boolean b = checkDirPath() && checkUrl(); |
||||||
|
if (b) { |
||||||
|
getEntity().save(); |
||||||
|
if (getTaskWrapper().getSubTaskWrapper() != null) { |
||||||
|
//初始化子项的登录信息
|
||||||
|
FtpUrlEntity tUrlEntity = getTaskWrapper().asFtp().getUrlEntity(); |
||||||
|
for (DTaskWrapper wrapper : getTaskWrapper().getSubTaskWrapper()) { |
||||||
|
FtpUrlEntity urlEntity = wrapper.asFtp().getUrlEntity(); |
||||||
|
urlEntity.needLogin = tUrlEntity.needLogin; |
||||||
|
urlEntity.account = tUrlEntity.account; |
||||||
|
urlEntity.user = tUrlEntity.user; |
||||||
|
urlEntity.password = tUrlEntity.password; |
||||||
|
// 处理ftps详细
|
||||||
|
if (tUrlEntity.isFtps) { |
||||||
|
urlEntity.isFtps = true; |
||||||
|
urlEntity.protocol = tUrlEntity.protocol; |
||||||
|
urlEntity.storePath = tUrlEntity.storePath; |
||||||
|
urlEntity.storePass = tUrlEntity.storePass; |
||||||
|
urlEntity.keyAlias = tUrlEntity.keyAlias; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (getTaskWrapper().asFtp().getUrlEntity().isFtps) { |
||||||
|
if (TextUtils.isEmpty(getTaskWrapper().asFtp().getUrlEntity().storePath)) { |
||||||
|
ALog.e(TAG, "证书路径为空"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (TextUtils.isEmpty(getTaskWrapper().asFtp().getUrlEntity().keyAlias)) { |
||||||
|
ALog.e(TAG, "证书别名为空"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return b; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查普通任务的下载地址 |
||||||
|
* |
||||||
|
* @return {@code true}地址合法 |
||||||
|
*/ |
||||||
|
private boolean checkUrl() { |
||||||
|
final String url = getGroupHash(); |
||||||
|
if (TextUtils.isEmpty(url)) { |
||||||
|
ALog.e(TAG, "下载失败,url为null"); |
||||||
|
return false; |
||||||
|
} else if (!url.startsWith("ftp")) { |
||||||
|
ALog.e(TAG, "下载失败,url【" + url + "】错误"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
int index = url.indexOf("://"); |
||||||
|
if (index == -1) { |
||||||
|
ALog.e(TAG, "下载失败,url【" + url + "】不合法"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,247 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.download; |
||||||
|
|
||||||
|
import android.support.annotation.CheckResult; |
||||||
|
import android.text.TextUtils; |
||||||
|
import com.arialyy.aria.core.common.RequestEnum; |
||||||
|
import com.arialyy.aria.orm.DbEntity; |
||||||
|
import com.arialyy.aria.util.ALog; |
||||||
|
import com.arialyy.aria.util.CommonUtil; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by lyy on 2019/4/9. |
||||||
|
* |
||||||
|
* http组合任务功能代理 |
||||||
|
*/ |
||||||
|
class HttpGroupConfigHandler extends AbsGroupConfigHandler<DownloadGroupTarget> { |
||||||
|
|
||||||
|
/** |
||||||
|
* 子任务下载地址, |
||||||
|
*/ |
||||||
|
private List<String> mUrls = new ArrayList<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 子任务文件名 |
||||||
|
*/ |
||||||
|
private List<String> mSubNameTemp = new ArrayList<>(); |
||||||
|
|
||||||
|
HttpGroupConfigHandler(DownloadGroupTarget target, DGTaskWrapper wrapper) { |
||||||
|
super(target, wrapper); |
||||||
|
mUrls.addAll(wrapper.getEntity().getUrls()); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
DownloadGroupTarget setGroupUrl(List<String> urls) { |
||||||
|
mUrls.clear(); |
||||||
|
mUrls.addAll(urls); |
||||||
|
return getTarget(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置子任务文件名,该方法必须在{@link #setDirPath(String)}之后调用,否则不生效 |
||||||
|
*/ |
||||||
|
@CheckResult |
||||||
|
DownloadGroupTarget setSubFileName(List<String> subTaskFileName) { |
||||||
|
if (subTaskFileName == null || subTaskFileName.isEmpty()) { |
||||||
|
ALog.w(TAG, "修改子任务的文件名失败:列表为null"); |
||||||
|
return getTarget(); |
||||||
|
} |
||||||
|
if (subTaskFileName.size() != getTaskWrapper().getSubTaskWrapper().size()) { |
||||||
|
ALog.w(TAG, "修改子任务的文件名失败:子任务文件名列表数量和子任务的数量不匹配"); |
||||||
|
return getTarget(); |
||||||
|
} |
||||||
|
mSubNameTemp.clear(); |
||||||
|
mSubNameTemp.addAll(subTaskFileName); |
||||||
|
return getTarget(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 更新组合任务下载地址 |
||||||
|
* |
||||||
|
* @param urls 新的组合任务下载地址列表 |
||||||
|
*/ |
||||||
|
@CheckResult |
||||||
|
DownloadGroupTarget updateUrls(List<String> urls) { |
||||||
|
if (urls == null || urls.isEmpty()) { |
||||||
|
throw new NullPointerException("下载地址列表为空"); |
||||||
|
} |
||||||
|
if (urls.size() != mUrls.size()) { |
||||||
|
throw new IllegalArgumentException("新下载地址数量和旧下载地址数量不一致"); |
||||||
|
} |
||||||
|
mUrls.clear(); |
||||||
|
mUrls.addAll(urls); |
||||||
|
String newHash = CommonUtil.getMd5Code(urls); |
||||||
|
setGroupHash(newHash); |
||||||
|
getEntity().setGroupHash(newHash); |
||||||
|
getEntity().update(); |
||||||
|
if (getEntity().getSubEntities() != null && !getEntity().getSubEntities().isEmpty()) { |
||||||
|
for (DownloadEntity de : getEntity().getSubEntities()) { |
||||||
|
de.setGroupHash(newHash); |
||||||
|
de.update(); |
||||||
|
} |
||||||
|
} |
||||||
|
return getTarget(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean checkEntity() { |
||||||
|
if (!checkDirPath()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (!checkSubName()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (!checkUrls()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (!getTaskWrapper().isUnknownSize() && getTaskWrapper().getEntity().getFileSize() == 0) { |
||||||
|
ALog.e(TAG, "组合任务必须设置文件文件大小,默认需要强制设置文件大小。如果无法获取到总长度,请调用#unknownSize()来标志该组合任务"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (getTaskWrapper().asHttp().getRequestEnum() == RequestEnum.POST) { |
||||||
|
for (DTaskWrapper subTask : getTaskWrapper().getSubTaskWrapper()) { |
||||||
|
subTask.asHttp().setRequestEnum(RequestEnum.POST); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (isNeedModifyPath()) { |
||||||
|
reChangeDirPath(getDirPathTemp()); |
||||||
|
} |
||||||
|
|
||||||
|
if (!mSubNameTemp.isEmpty()) { |
||||||
|
updateSingleSubFileName(); |
||||||
|
} |
||||||
|
saveEntity(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private void saveEntity() { |
||||||
|
getEntity().save(); |
||||||
|
DbEntity.saveAll(getEntity().getSubEntities()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 更新所有改动的子任务文件名 |
||||||
|
*/ |
||||||
|
private void updateSingleSubFileName() { |
||||||
|
List<DTaskWrapper> entities = getTaskWrapper().getSubTaskWrapper(); |
||||||
|
int i = 0; |
||||||
|
for (DTaskWrapper taskWrapper : entities) { |
||||||
|
if (i < mSubNameTemp.size()) { |
||||||
|
String newName = mSubNameTemp.get(i); |
||||||
|
DownloadEntity entity = taskWrapper.getEntity(); |
||||||
|
if (!newName.equals(entity.getFileName())) { |
||||||
|
String oldPath = getEntity().getDirPath() + "/" + entity.getFileName(); |
||||||
|
String newPath = getEntity().getDirPath() + "/" + newName; |
||||||
|
if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=? or isComplete='true'", |
||||||
|
newPath)) { |
||||||
|
ALog.w(TAG, String.format("更新文件名失败,路径【%s】已存在或文件已下载", newPath)); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
CommonUtil.modifyTaskRecord(oldPath, newPath); |
||||||
|
entity.setDownloadPath(newPath); |
||||||
|
entity.setFileName(newName); |
||||||
|
} |
||||||
|
} |
||||||
|
i++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查urls是否合法,并删除不合法的子任务 |
||||||
|
* |
||||||
|
* @return {@code true} 合法 |
||||||
|
*/ |
||||||
|
private boolean checkUrls() { |
||||||
|
if (mUrls.isEmpty()) { |
||||||
|
ALog.e(TAG, "下载失败,子任务下载列表为null"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
Set<String> repeated = new HashSet<>(); |
||||||
|
List<String> results = new ArrayList<>(); |
||||||
|
for (String url : mUrls) { |
||||||
|
if (!repeated.add(url)) { |
||||||
|
results.add(url); |
||||||
|
} |
||||||
|
} |
||||||
|
if (!results.isEmpty()) { |
||||||
|
ALog.e(TAG, String.format("组合任务中有url重复,重复的url:%s", Arrays.toString(results.toArray()))); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
Set<Integer> delItem = new HashSet<>(); |
||||||
|
|
||||||
|
int i = 0; |
||||||
|
for (String url : mUrls) { |
||||||
|
if (TextUtils.isEmpty(url)) { |
||||||
|
ALog.e(TAG, "子任务url为null,即将删除该子任务。"); |
||||||
|
delItem.add(i); |
||||||
|
continue; |
||||||
|
} else if (!url.startsWith("http")) { |
||||||
|
ALog.e(TAG, "子任务url【" + url + "】错误,即将删除该子任务。"); |
||||||
|
delItem.add(i); |
||||||
|
continue; |
||||||
|
} |
||||||
|
int index = url.indexOf("://"); |
||||||
|
if (index == -1) { |
||||||
|
ALog.e(TAG, "子任务url【" + url + "】不合法,即将删除该子任务。"); |
||||||
|
delItem.add(i); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
i++; |
||||||
|
} |
||||||
|
|
||||||
|
for (int index : delItem) { |
||||||
|
mUrls.remove(index); |
||||||
|
if (mSubNameTemp != null && !mSubNameTemp.isEmpty()) { |
||||||
|
mSubNameTemp.remove(index); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
getEntity().setGroupHash(CommonUtil.getMd5Code(mUrls)); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 如果用户设置了子任务文件名,检查子任务文件名 |
||||||
|
* |
||||||
|
* @return {@code true} 合法 |
||||||
|
*/ |
||||||
|
private boolean checkSubName() { |
||||||
|
if (mSubNameTemp == null || mSubNameTemp.isEmpty()) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
if (mUrls.size() != mSubNameTemp.size()) { |
||||||
|
ALog.e(TAG, "子任务文件名必须和子任务数量一致"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.download.m3u8; |
||||||
|
|
||||||
|
/** |
||||||
|
* m3u8直播参数设置 |
||||||
|
*/ |
||||||
|
public class M3U8LiveDelegate { |
||||||
|
|
||||||
|
M3U8LiveDelegate(M3U8Delegate delegate){ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置缓存目录 |
||||||
|
* @param cacheDir 缓存目录路径 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public M3U8LiveDelegate setCacheDir(String cacheDir){ |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.inf; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by lyy on 2019/4/5. |
||||||
|
* 普通任务配置处理 |
||||||
|
*/ |
||||||
|
public interface IConfigHandler { |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取实体 |
||||||
|
*/ |
||||||
|
AbsEntity getEntity(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 任务是否存在 |
||||||
|
* |
||||||
|
* @return {@code true}任务存在,{@code false} 任务不存在 |
||||||
|
*/ |
||||||
|
boolean taskExists(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 任务是否在执行 |
||||||
|
* |
||||||
|
* @return {@code true} 任务正在执行,{@code false} 任务没有执行 |
||||||
|
*/ |
||||||
|
boolean isRunning(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查下载实体,判断实体是否合法 合法标准为: |
||||||
|
* 1、下载路径不为null,并且下载路径是正常的http或ftp路径 |
||||||
|
* 2、保存路径不为null,并且保存路径是android文件系统路径 |
||||||
|
* 3、保存路径不能重复 |
||||||
|
* |
||||||
|
* @return {@code true}合法 |
||||||
|
*/ |
||||||
|
boolean checkEntity(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查并设置普通任务的文件保存路径 |
||||||
|
* |
||||||
|
* @return {@code true}保存路径合法 |
||||||
|
*/ |
||||||
|
boolean checkFilePath(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查普通任务的下载地址 |
||||||
|
* |
||||||
|
* @return {@code true}地址合法 |
||||||
|
*/ |
||||||
|
boolean checkUrl(); |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.inf; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by lyy on 2019/4/5. |
||||||
|
* 组合任务配置处理 |
||||||
|
*/ |
||||||
|
public interface IGroupConfigHandler { |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取实体 |
||||||
|
*/ |
||||||
|
AbsEntity getEntity(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 任务是否存在 |
||||||
|
* |
||||||
|
* @return {@code true}任务存在,{@code false} 任务不存在 |
||||||
|
*/ |
||||||
|
boolean taskExists(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 任务是否在执行 |
||||||
|
* |
||||||
|
* @return {@code true} 任务正在执行,{@code false} 任务没有执行 |
||||||
|
*/ |
||||||
|
boolean isRunning(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查实体是否合法 |
||||||
|
* |
||||||
|
* @return {@code true}合法 |
||||||
|
*/ |
||||||
|
boolean checkEntity(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查文件夹路径 |
||||||
|
* 1、文件夹路径不能为空 |
||||||
|
* 2、文件夹路径不能是文件 |
||||||
|
* |
||||||
|
* @return {@code true} 合法 |
||||||
|
*/ |
||||||
|
boolean checkDirPath(); |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.inf; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by AriaL on 2017/6/29. |
||||||
|
* 任务信息设置接口 |
||||||
|
*/ |
||||||
|
public interface ITaskConfig { |
||||||
|
|
||||||
|
} |
@ -0,0 +1,155 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* 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 com.arialyy.aria.core.upload; |
||||||
|
|
||||||
|
import android.text.TextUtils; |
||||||
|
import com.arialyy.aria.core.inf.AbsEntity; |
||||||
|
import com.arialyy.aria.core.common.ftp.IFtpUploadInterceptor; |
||||||
|
import com.arialyy.aria.core.inf.IConfigHandler; |
||||||
|
import com.arialyy.aria.core.manager.TaskWrapperManager; |
||||||
|
import com.arialyy.aria.core.queue.UploadTaskQueue; |
||||||
|
import com.arialyy.aria.orm.DbEntity; |
||||||
|
import com.arialyy.aria.util.ALog; |
||||||
|
import com.arialyy.aria.util.CheckUtil; |
||||||
|
import com.arialyy.aria.util.CommonUtil; |
||||||
|
import java.io.File; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Aria.Lao on 2019/4/5. |
||||||
|
* 普通上传任务通用功能处理 |
||||||
|
*/ |
||||||
|
class UNormalConfigHandler<TARGET extends AbsUploadTarget> implements IConfigHandler { |
||||||
|
private String TAG = "UNormalDelegate"; |
||||||
|
private UploadEntity mEntity; |
||||||
|
private TARGET mTarget; |
||||||
|
/** |
||||||
|
* 上传路径 |
||||||
|
*/ |
||||||
|
private String mTempUrl; |
||||||
|
|
||||||
|
UNormalConfigHandler(TARGET target, String filePath, String targetName) { |
||||||
|
mTarget = target; |
||||||
|
initTarget(filePath, targetName); |
||||||
|
} |
||||||
|
|
||||||
|
private void initTarget(String filePath, String targetName) { |
||||||
|
UTaskWrapper taskWrapper = |
||||||
|
TaskWrapperManager.getInstance().getHttpTaskWrapper(UTaskWrapper.class, filePath); |
||||||
|
mEntity = taskWrapper.getEntity(); |
||||||
|
File file = new File(filePath); |
||||||
|
mEntity.setFileName(file.getName()); |
||||||
|
mEntity.setFileSize(file.length()); |
||||||
|
mTarget.setTargetName(targetName); |
||||||
|
mTarget.setTaskWrapper(taskWrapper); |
||||||
|
mTempUrl = mEntity.getUrl(); |
||||||
|
} |
||||||
|
|
||||||
|
TARGET updateUrl(String newUrl) { |
||||||
|
mTempUrl = newUrl; |
||||||
|
return mTarget; |
||||||
|
} |
||||||
|
|
||||||
|
TARGET setUploadInterceptor(IFtpUploadInterceptor uploadInterceptor) { |
||||||
|
if (uploadInterceptor == null) { |
||||||
|
throw new NullPointerException("ftp拦截器为空"); |
||||||
|
} |
||||||
|
mTarget.getTaskWrapper().asFtp().setUploadInterceptor(uploadInterceptor); |
||||||
|
return mTarget; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public AbsEntity getEntity() { |
||||||
|
return mEntity; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean taskExists() { |
||||||
|
return DbEntity.checkDataExist(UploadEntity.class, "key=?", mEntity.getFilePath()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean isRunning() { |
||||||
|
UploadTask task = UploadTaskQueue.getInstance().getTask(mEntity.getKey()); |
||||||
|
return task != null && task.isRunning(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean checkEntity() { |
||||||
|
boolean b = checkUrl() && checkFilePath(); |
||||||
|
if (b) { |
||||||
|
mEntity.save(); |
||||||
|
} |
||||||
|
if (mTarget.getTaskWrapper().asFtp().getUrlEntity() != null && mTarget.getTaskWrapper() |
||||||
|
.asFtp() |
||||||
|
.getUrlEntity().isFtps) { |
||||||
|
if (TextUtils.isEmpty(mTarget.getTaskWrapper().asFtp().getUrlEntity().storePath)) { |
||||||
|
ALog.e(TAG, "证书路径为空"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (TextUtils.isEmpty(mTarget.getTaskWrapper().asFtp().getUrlEntity().keyAlias)) { |
||||||
|
ALog.e(TAG, "证书别名为空"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return b; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean checkFilePath() { |
||||||
|
String filePath = mEntity.getFilePath(); |
||||||
|
if (TextUtils.isEmpty(filePath)) { |
||||||
|
ALog.e(TAG, "上传失败,文件路径为null"); |
||||||
|
return false; |
||||||
|
} else if (!filePath.startsWith("/")) { |
||||||
|
ALog.e(TAG, "上传失败,文件路径【" + filePath + "】不合法"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
File file = new File(mEntity.getFilePath()); |
||||||
|
if (!file.exists()) { |
||||||
|
ALog.e(TAG, "上传失败,文件【" + filePath + "】不存在"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (file.isDirectory()) { |
||||||
|
ALog.e(TAG, "上传失败,文件【" + filePath + "】不能是文件夹"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean checkUrl() { |
||||||
|
|
||||||
|
final String url = mTempUrl; |
||||||
|
if (TextUtils.isEmpty(url)) { |
||||||
|
ALog.e(TAG, "上传失败,url为null"); |
||||||
|
return false; |
||||||
|
} else if (!CheckUtil.checkUrlNotThrow(url)) { |
||||||
|
ALog.e(TAG, "上传失败,url【" + url + "】错误"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
int index = url.indexOf("://"); |
||||||
|
if (index == -1) { |
||||||
|
ALog.e(TAG, "上传失败,url【" + url + "】不合法"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
mEntity.setUrl(url); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
void setTempUrl(String tempUrl) { |
||||||
|
this.mTempUrl = tempUrl; |
||||||
|
mTarget.getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(tempUrl)); |
||||||
|
} |
||||||
|
|
||||||
|
public String getTempUrl() { |
||||||
|
return mTempUrl; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue