|
|
@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletRequest; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.util.*; |
|
|
|
import java.util.*; |
|
|
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.regex.Matcher; |
|
|
|
import java.util.regex.Matcher; |
|
|
|
import java.util.regex.Pattern; |
|
|
|
import java.util.regex.Pattern; |
|
|
@ -35,7 +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 Pattern sharePatten = Pattern.compile("^.*卍([a-zA-Z0-9]{11})$"); |
|
|
|
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) |
|
|
@ -53,10 +54,10 @@ public class AliYunDriverClientService { |
|
|
|
AliYunDriverFileSystemStore.setBean(this); |
|
|
|
AliYunDriverFileSystemStore.setBean(this); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Set<TFile> getTFiles(String nodeId, String shareId) { |
|
|
|
public Set<TFile> getTFiles(String nodeId, String shareId, String sharePassword) { |
|
|
|
Set<TFile> tFiles = tFilesCache.get(shareId + ":" + nodeId, key -> { |
|
|
|
Set<TFile> tFiles = tFilesCache.get(shareId + ":" + nodeId, key -> { |
|
|
|
// 获取真实的文件列表
|
|
|
|
// 获取真实的文件列表
|
|
|
|
return getTFiles2(nodeId, shareId); |
|
|
|
return getTFiles2(nodeId, shareId, sharePassword); |
|
|
|
}); |
|
|
|
}); |
|
|
|
Set<TFile> all = new LinkedHashSet<>(tFiles); |
|
|
|
Set<TFile> all = new LinkedHashSet<>(tFiles); |
|
|
|
// 获取上传中的文件列表
|
|
|
|
// 获取上传中的文件列表
|
|
|
@ -65,11 +66,12 @@ public class AliYunDriverClientService { |
|
|
|
return all; |
|
|
|
return all; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Set<TFile> getTFiles2(String nodeId, String shareId) { |
|
|
|
private Set<TFile> getTFiles2(String nodeId, String shareId, String sharePassword) { |
|
|
|
List<TFile> tFileList = fileListFromApi(nodeId, null, new ArrayList<>(), shareId); |
|
|
|
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()); |
|
|
|
} |
|
|
|
} |
|
|
@ -78,7 +80,7 @@ public class AliYunDriverClientService { |
|
|
|
return tFileSets; |
|
|
|
return tFileSets; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private List<TFile> fileListFromApi(String nodeId, String marker, List<TFile> all, String shareId) { |
|
|
|
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); |
|
|
@ -90,14 +92,20 @@ public class AliYunDriverClientService { |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
listQuery.setDrive_id(client.getDriveId()); |
|
|
|
listQuery.setDrive_id(client.getDriveId()); |
|
|
|
} |
|
|
|
} |
|
|
|
String json = client.post("/file/list", listQuery, shareId); |
|
|
|
String json; |
|
|
|
TFileListResult<TFile> tFileListResult = JsonUtil.readValue(json, new TypeReference<TFileListResult<TFile>>() { |
|
|
|
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, shareId); |
|
|
|
return fileListFromApi(nodeId, tFileListResult.getNext_marker(), all, shareId, sharePassword); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -219,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(); |
|
|
@ -233,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(); |
|
|
@ -247,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(); |
|
|
|
} |
|
|
|
} |
|
|
@ -301,9 +309,9 @@ public class AliYunDriverClientService { |
|
|
|
DownloadRequest downloadRequest = new DownloadRequest(); |
|
|
|
DownloadRequest downloadRequest = new DownloadRequest(); |
|
|
|
downloadRequest.setFile_id(file.getFile_id()); |
|
|
|
downloadRequest.setFile_id(file.getFile_id()); |
|
|
|
downloadRequest.setShare_id(file.getShare_id()); |
|
|
|
downloadRequest.setShare_id(file.getShare_id()); |
|
|
|
downloadRequest.setShareToken(client.readShareToken(file.getShare_id())); |
|
|
|
downloadRequest.setShareToken(client.readShareToken(file.getShare_id(), file.getShare_password())); |
|
|
|
downloadRequest.setExpire_sec(600); |
|
|
|
downloadRequest.setExpire_sec(600); |
|
|
|
String json = client.post("/file/get_share_link_download_url", downloadRequest, file.getShare_id()); |
|
|
|
String json = client.post("/file/get_share_link_download_url", downloadRequest, file.getShare_id(), file.getShare_password()); |
|
|
|
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); |
|
|
@ -322,11 +330,7 @@ public class AliYunDriverClientService { |
|
|
|
if (tFile == null ) { |
|
|
|
if (tFile == null ) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
Matcher matcher = sharePatten.matcher(pathInfo.getName()); |
|
|
|
return getNodeIdByParentId(tFile.getFile_id(), pathInfo.getName(), tFile.getShare_id(), tFile.getShare_password()); |
|
|
|
if (matcher.find()){ |
|
|
|
|
|
|
|
return getShareRootTFile(matcher.group(1), pathInfo.getName()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return getNodeIdByParentId(tFile.getFile_id(), tFile.getShare_id(), pathInfo.getName()); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -365,7 +369,7 @@ public class AliYunDriverClientService { |
|
|
|
return rootTFile; |
|
|
|
return rootTFile; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private TFile getShareRootTFile(String shareId, String name){ |
|
|
|
private TFile getShareRootTFile(String shareId, String name, String originFileId, String sharePassword){ |
|
|
|
TFile rootTFile = new TFile(); |
|
|
|
TFile rootTFile = new TFile(); |
|
|
|
rootTFile.setName(name); |
|
|
|
rootTFile.setName(name); |
|
|
|
rootTFile.setFile_id("root"); |
|
|
|
rootTFile.setFile_id("root"); |
|
|
@ -373,16 +377,23 @@ public class AliYunDriverClientService { |
|
|
|
rootTFile.setUpdated_at(new Date()); |
|
|
|
rootTFile.setUpdated_at(new Date()); |
|
|
|
rootTFile.setType("folder"); |
|
|
|
rootTFile.setType("folder"); |
|
|
|
rootTFile.setShare_id(shareId); |
|
|
|
rootTFile.setShare_id(shareId); |
|
|
|
|
|
|
|
rootTFile.setOrigin_file_id(originFileId); |
|
|
|
|
|
|
|
rootTFile.setShare_password(sharePassword); |
|
|
|
return rootTFile; |
|
|
|
return rootTFile; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private TFile getNodeIdByParentId(String parentId, String shareId, String name) { |
|
|
|
private TFile getNodeIdByParentId(String parentId, String name, String shareId, String sharePassword) { |
|
|
|
Set<TFile> tFiles = getTFiles(parentId, shareId); |
|
|
|
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; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|