|
|
@ -26,6 +26,8 @@ import java.io.InputStream; |
|
|
|
import java.util.*; |
|
|
|
import java.util.*; |
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
|
|
|
|
import java.util.regex.Matcher; |
|
|
|
|
|
|
|
import java.util.regex.Pattern; |
|
|
|
|
|
|
|
|
|
|
|
@Service |
|
|
|
@Service |
|
|
|
public class AliYunDriverClientService { |
|
|
|
public class AliYunDriverClientService { |
|
|
@ -34,6 +36,7 @@ public class AliYunDriverClientService { |
|
|
|
private static String rootPath = "/"; |
|
|
|
private static String rootPath = "/"; |
|
|
|
private static int chunkSize = 10485760; // 10MB
|
|
|
|
private static int chunkSize = 10485760; // 10MB
|
|
|
|
private TFile rootTFile = null; |
|
|
|
private TFile rootTFile = null; |
|
|
|
|
|
|
|
private final Pattern shareNamePatten = Pattern.compile("^.*!(?<shareId>[a-zA-Z0-9]{11})(?>$|:(?<password>[a-zA-Z0-9]{4})$)"); |
|
|
|
|
|
|
|
|
|
|
|
private static Cache<String, Set<TFile>> tFilesCache = Caffeine.newBuilder() |
|
|
|
private static Cache<String, Set<TFile>> tFilesCache = Caffeine.newBuilder() |
|
|
|
.initialCapacity(128) |
|
|
|
.initialCapacity(128) |
|
|
@ -51,10 +54,10 @@ public class AliYunDriverClientService { |
|
|
|
AliYunDriverFileSystemStore.setBean(this); |
|
|
|
AliYunDriverFileSystemStore.setBean(this); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Set<TFile> getTFiles(String nodeId) { |
|
|
|
public Set<TFile> getTFiles(String nodeId, String shareId, String sharePassword) { |
|
|
|
Set<TFile> tFiles = tFilesCache.get(nodeId, key -> { |
|
|
|
Set<TFile> tFiles = tFilesCache.get(shareId + ":" + nodeId, key -> { |
|
|
|
// 获取真实的文件列表
|
|
|
|
// 获取真实的文件列表
|
|
|
|
return getTFiles2(nodeId); |
|
|
|
return getTFiles2(nodeId, shareId, sharePassword); |
|
|
|
}); |
|
|
|
}); |
|
|
|
Set<TFile> all = new LinkedHashSet<>(tFiles); |
|
|
|
Set<TFile> all = new LinkedHashSet<>(tFiles); |
|
|
|
// 获取上传中的文件列表
|
|
|
|
// 获取上传中的文件列表
|
|
|
@ -63,11 +66,12 @@ public class AliYunDriverClientService { |
|
|
|
return all; |
|
|
|
return all; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Set<TFile> getTFiles2(String nodeId) { |
|
|
|
private Set<TFile> getTFiles2(String nodeId, String shareId, String sharePassword) { |
|
|
|
List<TFile> tFileList = fileListFromApi(nodeId, null, new ArrayList<>()); |
|
|
|
List<TFile> tFileList = fileListFromApi(nodeId, null, new ArrayList<>(), shareId, sharePassword); |
|
|
|
tFileList.sort(Comparator.comparing(TFile::getUpdated_at).reversed()); |
|
|
|
tFileList.sort(Comparator.comparing(TFile::getUpdated_at).reversed()); |
|
|
|
Set<TFile> tFileSets = new LinkedHashSet<>(); |
|
|
|
Set<TFile> tFileSets = new LinkedHashSet<>(); |
|
|
|
for (TFile tFile : tFileList) { |
|
|
|
for (TFile tFile : tFileList) { |
|
|
|
|
|
|
|
tFile.setShare_password(sharePassword); |
|
|
|
if (!tFileSets.add(tFile)) { |
|
|
|
if (!tFileSets.add(tFile)) { |
|
|
|
LOGGER.info("当前目录下{} 存在同名文件:{},文件大小:{}", nodeId, tFile.getName(), tFile.getSize()); |
|
|
|
LOGGER.info("当前目录下{} 存在同名文件:{},文件大小:{}", nodeId, tFile.getName(), tFile.getSize()); |
|
|
|
} |
|
|
|
} |
|
|
@ -76,22 +80,32 @@ public class AliYunDriverClientService { |
|
|
|
return tFileSets; |
|
|
|
return tFileSets; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private List<TFile> fileListFromApi(String nodeId, String marker, List<TFile> all) { |
|
|
|
private List<TFile> fileListFromApi(String nodeId, String marker, List<TFile> all, String shareId, String sharePassword) { |
|
|
|
FileListRequest listQuery = new FileListRequest(); |
|
|
|
FileListRequest listQuery = new FileListRequest(); |
|
|
|
listQuery.setMarker(marker); |
|
|
|
listQuery.setMarker(marker); |
|
|
|
listQuery.setLimit(100); |
|
|
|
listQuery.setLimit(100); |
|
|
|
listQuery.setOrder_by("updated_at"); |
|
|
|
listQuery.setOrder_by("updated_at"); |
|
|
|
listQuery.setOrder_direction("DESC"); |
|
|
|
listQuery.setOrder_direction("DESC"); |
|
|
|
listQuery.setDrive_id(client.getDriveId()); |
|
|
|
|
|
|
|
listQuery.setParent_file_id(nodeId); |
|
|
|
listQuery.setParent_file_id(nodeId); |
|
|
|
String json = client.post("/file/list", listQuery); |
|
|
|
if (shareId != null){ |
|
|
|
TFileListResult<TFile> tFileListResult = JsonUtil.readValue(json, new TypeReference<TFileListResult<TFile>>() { |
|
|
|
listQuery.setShare_id(shareId); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
|
|
|
|
listQuery.setDrive_id(client.getDriveId()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
String json; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
json = client.post("/file/list", listQuery, shareId, sharePassword); |
|
|
|
|
|
|
|
} catch (WebdavException e){ |
|
|
|
|
|
|
|
// 无法获取列表可能是 shareId 已经失效,与其报错不如返回空,特别是使用 dav 挂载时候,报错会导致 IO 错误无法删除目录
|
|
|
|
|
|
|
|
e.printStackTrace(); |
|
|
|
|
|
|
|
return Collections.emptyList(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
TFileListResult<TFile> tFileListResult = JsonUtil.readValue(json, new TypeReference<TFileListResult<TFile>>() {}); |
|
|
|
all.addAll(tFileListResult.getItems()); |
|
|
|
all.addAll(tFileListResult.getItems()); |
|
|
|
if (!StringUtils.hasLength(tFileListResult.getNext_marker())) { |
|
|
|
if (!StringUtils.hasLength(tFileListResult.getNext_marker())) { |
|
|
|
return all; |
|
|
|
return all; |
|
|
|
} |
|
|
|
} |
|
|
|
return fileListFromApi(nodeId, tFileListResult.getNext_marker(), all); |
|
|
|
return fileListFromApi(nodeId, tFileListResult.getNext_marker(), all, shareId, sharePassword); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -213,7 +227,7 @@ public class AliYunDriverClientService { |
|
|
|
TFile tFile = getTFileByPath(sourcePath); |
|
|
|
TFile tFile = getTFileByPath(sourcePath); |
|
|
|
RenameRequest renameRequest = new RenameRequest(); |
|
|
|
RenameRequest renameRequest = new RenameRequest(); |
|
|
|
renameRequest.setDrive_id(client.getDriveId()); |
|
|
|
renameRequest.setDrive_id(client.getDriveId()); |
|
|
|
renameRequest.setFile_id(tFile.getFile_id()); |
|
|
|
renameRequest.setFile_id(tFile.getOrigin_file_id() != null ? tFile.getOrigin_file_id() : tFile.getFile_id()); |
|
|
|
renameRequest.setName(newName); |
|
|
|
renameRequest.setName(newName); |
|
|
|
client.post("/file/update", renameRequest); |
|
|
|
client.post("/file/update", renameRequest); |
|
|
|
clearCache(); |
|
|
|
clearCache(); |
|
|
@ -227,7 +241,7 @@ public class AliYunDriverClientService { |
|
|
|
TFile targetTFile = getTFileByPath(targetPath); |
|
|
|
TFile targetTFile = getTFileByPath(targetPath); |
|
|
|
MoveRequest moveRequest = new MoveRequest(); |
|
|
|
MoveRequest moveRequest = new MoveRequest(); |
|
|
|
moveRequest.setDrive_id(client.getDriveId()); |
|
|
|
moveRequest.setDrive_id(client.getDriveId()); |
|
|
|
moveRequest.setFile_id(sourceTFile.getFile_id()); |
|
|
|
moveRequest.setFile_id(sourceTFile.getOrigin_file_id() != null ? sourceTFile.getOrigin_file_id() : sourceTFile.getFile_id()); |
|
|
|
moveRequest.setTo_parent_file_id(targetTFile.getFile_id()); |
|
|
|
moveRequest.setTo_parent_file_id(targetTFile.getFile_id()); |
|
|
|
client.post("/file/move", moveRequest); |
|
|
|
client.post("/file/move", moveRequest); |
|
|
|
clearCache(); |
|
|
|
clearCache(); |
|
|
@ -241,7 +255,7 @@ public class AliYunDriverClientService { |
|
|
|
} |
|
|
|
} |
|
|
|
RemoveRequest removeRequest = new RemoveRequest(); |
|
|
|
RemoveRequest removeRequest = new RemoveRequest(); |
|
|
|
removeRequest.setDrive_id(client.getDriveId()); |
|
|
|
removeRequest.setDrive_id(client.getDriveId()); |
|
|
|
removeRequest.setFile_id(tFile.getFile_id()); |
|
|
|
removeRequest.setFile_id(tFile.getOrigin_file_id() != null ? tFile.getOrigin_file_id() : tFile.getFile_id()); |
|
|
|
client.post("/recyclebin/trash", removeRequest); |
|
|
|
client.post("/recyclebin/trash", removeRequest); |
|
|
|
clearCache(); |
|
|
|
clearCache(); |
|
|
|
} |
|
|
|
} |
|
|
@ -283,6 +297,7 @@ public class AliYunDriverClientService { |
|
|
|
|
|
|
|
|
|
|
|
public Response download(String path, HttpServletRequest request, long size ) { |
|
|
|
public Response download(String path, HttpServletRequest request, long size ) { |
|
|
|
TFile file = getTFileByPath(path); |
|
|
|
TFile file = getTFileByPath(path); |
|
|
|
|
|
|
|
if (file.getShare_id() == null){ |
|
|
|
DownloadRequest downloadRequest = new DownloadRequest(); |
|
|
|
DownloadRequest downloadRequest = new DownloadRequest(); |
|
|
|
downloadRequest.setDrive_id(client.getDriveId()); |
|
|
|
downloadRequest.setDrive_id(client.getDriveId()); |
|
|
|
downloadRequest.setFile_id(file.getFile_id()); |
|
|
|
downloadRequest.setFile_id(file.getFile_id()); |
|
|
@ -290,6 +305,17 @@ public class AliYunDriverClientService { |
|
|
|
Object url = JsonUtil.getJsonNodeValue(json, "url"); |
|
|
|
Object url = JsonUtil.getJsonNodeValue(json, "url"); |
|
|
|
LOGGER.debug("{} url = {}", path, url); |
|
|
|
LOGGER.debug("{} url = {}", path, url); |
|
|
|
return client.download(url.toString(), request, size); |
|
|
|
return client.download(url.toString(), request, size); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
DownloadRequest downloadRequest = new DownloadRequest(); |
|
|
|
|
|
|
|
downloadRequest.setFile_id(file.getFile_id()); |
|
|
|
|
|
|
|
downloadRequest.setShare_id(file.getShare_id()); |
|
|
|
|
|
|
|
downloadRequest.setShareToken(client.readShareToken(file.getShare_id(), file.getShare_password())); |
|
|
|
|
|
|
|
downloadRequest.setExpire_sec(600); |
|
|
|
|
|
|
|
String json = client.post("/file/get_share_link_download_url", downloadRequest, file.getShare_id(), file.getShare_password()); |
|
|
|
|
|
|
|
Object url = JsonUtil.getJsonNodeValue(json, "url"); |
|
|
|
|
|
|
|
LOGGER.debug("{} url = {}", path, url); |
|
|
|
|
|
|
|
return client.download(url.toString(), request, size); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private TFile getNodeIdByPath2(String path) { |
|
|
|
private TFile getNodeIdByPath2(String path) { |
|
|
@ -304,7 +330,7 @@ public class AliYunDriverClientService { |
|
|
|
if (tFile == null ) { |
|
|
|
if (tFile == null ) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
return getNodeIdByParentId(tFile.getFile_id(), pathInfo.getName()); |
|
|
|
return getNodeIdByParentId(tFile.getFile_id(), pathInfo.getName(), tFile.getShare_id(), tFile.getShare_password()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -343,14 +369,31 @@ public class AliYunDriverClientService { |
|
|
|
return rootTFile; |
|
|
|
return rootTFile; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private TFile getNodeIdByParentId(String parentId, String name) { |
|
|
|
private TFile getShareRootTFile(String shareId, String name, String originFileId, String sharePassword){ |
|
|
|
Set<TFile> tFiles = getTFiles(parentId); |
|
|
|
TFile rootTFile = new TFile(); |
|
|
|
|
|
|
|
rootTFile.setName(name); |
|
|
|
|
|
|
|
rootTFile.setFile_id("root"); |
|
|
|
|
|
|
|
rootTFile.setCreated_at(new Date()); |
|
|
|
|
|
|
|
rootTFile.setUpdated_at(new Date()); |
|
|
|
|
|
|
|
rootTFile.setType("folder"); |
|
|
|
|
|
|
|
rootTFile.setShare_id(shareId); |
|
|
|
|
|
|
|
rootTFile.setOrigin_file_id(originFileId); |
|
|
|
|
|
|
|
rootTFile.setShare_password(sharePassword); |
|
|
|
|
|
|
|
return rootTFile; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private TFile getNodeIdByParentId(String parentId, String name, String shareId, String sharePassword) { |
|
|
|
|
|
|
|
Set<TFile> tFiles = getTFiles(parentId, shareId, sharePassword); |
|
|
|
for (TFile tFile : tFiles) { |
|
|
|
for (TFile tFile : tFiles) { |
|
|
|
if (tFile.getName().equals(name)) { |
|
|
|
if (tFile.getName().equals(name)) { |
|
|
|
|
|
|
|
Matcher matcher = shareNamePatten.matcher(name); |
|
|
|
|
|
|
|
if (matcher.find()){ |
|
|
|
|
|
|
|
return getShareRootTFile(matcher.group("shareId"), name, tFile.getFile_id(), matcher.group("password")); |
|
|
|
|
|
|
|
} else { |
|
|
|
return tFile; |
|
|
|
return tFile; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|