mirror of
https://github.com/zfile-dev/zfile.git
synced 2025-04-19 05:34:52 +00:00
添加缓存支持, 添加搜索功能.
This commit is contained in:
@@ -2,9 +2,11 @@ package im.zhaojun;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableCaching
|
||||
@EnableAspectJAutoProxy(exposeProxy = true)
|
||||
public class ZfileApplication {
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ public class AliyunService implements FileService {
|
||||
fileItem.setSize(s.getSize());
|
||||
fileItem.setTime(s.getLastModified());
|
||||
fileItem.setType(FileTypeEnum.FILE);
|
||||
fileItem.setPath(path);
|
||||
fileItemList.add(fileItem);
|
||||
}
|
||||
|
||||
@@ -86,6 +87,7 @@ public class AliyunService implements FileService {
|
||||
FileItem fileItem = new FileItem();
|
||||
fileItem.setName(commonPrefix.substring(path.length(), commonPrefix.length() - 1));
|
||||
fileItem.setType(FileTypeEnum.FOLDER);
|
||||
fileItem.setPath(path);
|
||||
fileItemList.add(fileItem);
|
||||
}
|
||||
|
||||
@@ -104,4 +106,9 @@ public class AliyunService implements FileService {
|
||||
return URLUtil.complateUrl(domain, path);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum getStorageTypeEnum() {
|
||||
return StorageTypeEnum.ALIYUN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package im.zhaojun.common.config;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.caffeine.CaffeineCache;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.cache.support.SimpleCacheManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
public class CaffeineConfiguration {
|
||||
|
||||
@Value("${zfile.cache.timeout}")
|
||||
private Long timeout;
|
||||
|
||||
public static final String CACHE_NAME = "zfile";
|
||||
|
||||
/**
|
||||
* 个性化配置缓存
|
||||
*/
|
||||
@Bean
|
||||
public CacheManager cacheManager() {
|
||||
SimpleCacheManager manager = new SimpleCacheManager();
|
||||
ArrayList<CaffeineCache> caches = new ArrayList<>();
|
||||
caches.add(new CaffeineCache(CACHE_NAME,
|
||||
Caffeine.newBuilder().recordStats()
|
||||
.expireAfterWrite(timeout, TimeUnit.SECONDS)
|
||||
.build())
|
||||
);
|
||||
manager.setCaches(caches);
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KeyGenerator keyGenerator() {
|
||||
return new KeyGenerator() {
|
||||
@Override
|
||||
public Object generate(Object target, Method method, Object... params) {
|
||||
char separator = ':';
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
// 类名
|
||||
strBuilder.append(target.getClass().getSimpleName());
|
||||
strBuilder.append(separator);
|
||||
// 方法名
|
||||
strBuilder.append(method.getName());
|
||||
strBuilder.append(separator);
|
||||
// 参数值
|
||||
for (Object object : params) {
|
||||
strBuilder.append(object).append(",");
|
||||
}
|
||||
return strBuilder.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,8 @@
|
||||
package im.zhaojun.common.config;
|
||||
|
||||
import im.zhaojun.aliyun.service.AliyunService;
|
||||
import im.zhaojun.common.enums.StorageTypeEnum;
|
||||
import im.zhaojun.common.exception.UnknownStorageTypeException;
|
||||
import im.zhaojun.common.service.FileService;
|
||||
import im.zhaojun.ftp.service.FtpService;
|
||||
import im.zhaojun.huawei.service.HuaweiService;
|
||||
import im.zhaojun.local.service.LocalService;
|
||||
import im.zhaojun.qiniu.service.QiniuService;
|
||||
import im.zhaojun.tencent.TencentService;
|
||||
import im.zhaojun.upyun.service.UpYunService;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -32,18 +26,22 @@ public class StorageTypeFactory implements ApplicationContextAware {
|
||||
storageTypeEnumFileServiceMap = act.getBeansOfType(FileService.class);
|
||||
}
|
||||
|
||||
public static <T extends FileService> T getTrafficMode(StorageTypeEnum type) {
|
||||
String beanName = "";
|
||||
switch (type) {
|
||||
case UPYUN: beanName = applicationContext.getBeanNamesForType(UpYunService.class)[0]; break;
|
||||
case QINIU: beanName = applicationContext.getBeanNamesForType(QiniuService.class)[0]; break;
|
||||
case HUAWEI: beanName = applicationContext.getBeanNamesForType(HuaweiService.class)[0]; break;
|
||||
case FTP: beanName = applicationContext.getBeanNamesForType(FtpService.class)[0]; break;
|
||||
case ALIYUN: beanName = applicationContext.getBeanNamesForType(AliyunService.class)[0]; break;
|
||||
case LOCAL: beanName = applicationContext.getBeanNamesForType(LocalService.class)[0]; break;
|
||||
case TENCENT: beanName = applicationContext.getBeanNamesForType(TencentService.class)[0]; break;
|
||||
public static FileService getTrafficMode(StorageTypeEnum type) {
|
||||
FileService result = null;
|
||||
for (FileService fileService : storageTypeEnumFileServiceMap.values()) {
|
||||
if (fileService.getStorageTypeEnum() == type) {
|
||||
result = fileService;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (T) storageTypeEnumFileServiceMap.get(beanName);
|
||||
|
||||
if (result == null) {
|
||||
throw new UnknownStorageTypeException(type.getDescription());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package im.zhaojun.common.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.cache.RedisCacheWriter;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@Configuration
|
||||
public class ZfileCacheConfiguration {
|
||||
|
||||
@Value("${zfile.cache.timeout}")
|
||||
private Long timeout;
|
||||
|
||||
public static final String CACHE_NAME = "zfile";
|
||||
|
||||
/**
|
||||
* 个性化配置缓存
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "spring.cache.type", havingValue = "caffeine")
|
||||
public CaffeineCacheManager caffeineCacheManager() {
|
||||
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
|
||||
caffeineCacheManager.setCacheNames(Collections.singletonList(CACHE_NAME));
|
||||
return caffeineCacheManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KeyGenerator keyGenerator() {
|
||||
return (target, method, params) -> {
|
||||
char separator = ':';
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
|
||||
// 类名
|
||||
strBuilder.append(target.getClass().getSimpleName());
|
||||
strBuilder.append(separator);
|
||||
|
||||
// 方法名
|
||||
strBuilder.append(method.getName());
|
||||
strBuilder.append(separator);
|
||||
|
||||
// 参数值
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (i == params.length - 1) {
|
||||
strBuilder.append(params[i]);
|
||||
} else {
|
||||
strBuilder.append(params[i]).append(",");
|
||||
}
|
||||
}
|
||||
return strBuilder.toString();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "spring.cache.type", havingValue = "redis")
|
||||
public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
|
||||
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
|
||||
GenericJackson2JsonRedisSerializer jsonRedisSerializer
|
||||
= new GenericJackson2JsonRedisSerializer();
|
||||
RedisSerializationContext.SerializationPair<Object> pair
|
||||
= RedisSerializationContext.SerializationPair.fromSerializer(jsonRedisSerializer);
|
||||
RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
|
||||
return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package im.zhaojun.common.controller;
|
||||
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import im.zhaojun.common.config.StorageTypeFactory;
|
||||
import im.zhaojun.common.enums.FileTypeEnum;
|
||||
@@ -7,16 +8,17 @@ import im.zhaojun.common.enums.StorageTypeEnum;
|
||||
import im.zhaojun.common.model.FileItem;
|
||||
import im.zhaojun.common.model.ResultBean;
|
||||
import im.zhaojun.common.model.SiteConfig;
|
||||
import im.zhaojun.common.model.SystemConfig;
|
||||
import im.zhaojun.common.service.FileService;
|
||||
import im.zhaojun.common.service.SystemConfigService;
|
||||
import im.zhaojun.common.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -24,10 +26,12 @@ import java.util.List;
|
||||
@RestController
|
||||
public class FileController {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FileController.class);
|
||||
|
||||
private FileService fileService;
|
||||
|
||||
@Resource
|
||||
private SystemConfigService configService;
|
||||
private SystemConfigService systemConfigService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public ResultBean list(String path, String sortBy, boolean descending) throws Exception {
|
||||
@@ -87,8 +91,8 @@ public class FileController {
|
||||
*/
|
||||
@GetMapping("/getConfig")
|
||||
public ResultBean getConfig(String path) throws Exception {
|
||||
SiteConfig config = fileService.getConfig(URLUtil.decode(path));
|
||||
config.setSystemConfig(configService.getSystemConfig());
|
||||
SiteConfig config = fileService.getConfig(URLUtil.decode(StringUtils.removeDuplicateSeparator("/" + path + "/")));
|
||||
config.setSystemConfig(systemConfigService.getSystemConfig());
|
||||
return ResultBean.successData(config);
|
||||
}
|
||||
|
||||
@@ -98,8 +102,11 @@ public class FileController {
|
||||
@PostConstruct
|
||||
@GetMapping("/updateStorageStrategy")
|
||||
public ResultBean updateConfig() {
|
||||
StorageTypeEnum storageStrategy = configService.getSystemConfig().getStorageStrategy();
|
||||
SystemConfig systemConfig = systemConfigService.getSystemConfig();
|
||||
StorageTypeEnum storageStrategy = systemConfig.getStorageStrategy();
|
||||
fileService = StorageTypeFactory.getTrafficMode(storageStrategy);
|
||||
log.info("当前启用存储类型: {}", storageStrategy.getDescription());
|
||||
initSearchCache();
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
@@ -118,4 +125,29 @@ public class FileController {
|
||||
public ResultBean getAudioInfo(String url) throws Exception {
|
||||
return ResultBean.success(fileService.getAudioInfo(url));
|
||||
}
|
||||
|
||||
@GetMapping("/search")
|
||||
public ResultBean search(@RequestParam("path") String name) throws Exception {
|
||||
return ResultBean.success(fileService.search(name));
|
||||
}
|
||||
|
||||
private void initSearchCache() {
|
||||
StorageTypeEnum storageStrategy = systemConfigService.getSystemConfig().getStorageStrategy();
|
||||
FileService fileService = StorageTypeFactory.getTrafficMode(storageStrategy);
|
||||
|
||||
ThreadUtil.execute(() -> {
|
||||
try {
|
||||
long startTime = System.currentTimeMillis();
|
||||
log.info("初始化 {} 文件列表", storageStrategy.getDescription());
|
||||
List<FileItem> fileItemList = fileService.selectAllFileList();
|
||||
long endTime = System.currentTimeMillis();
|
||||
log.info("完成 {} 缓存, 共缓存了 {} 个文件夹, 使用时间 {} 秒",
|
||||
storageStrategy.getDescription(),
|
||||
fileItemList.size(),
|
||||
(endTime - startTime) / 1000);
|
||||
} catch (Exception e) {
|
||||
log.info("初始化 " + storageStrategy.getDescription() + " 文件列表异常", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package im.zhaojun.common.exception;
|
||||
|
||||
/**
|
||||
* 未知的存储类型异常
|
||||
*/
|
||||
public class UnknownStorageTypeException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -4853756482605773655L;
|
||||
|
||||
public UnknownStorageTypeException() {
|
||||
}
|
||||
|
||||
public UnknownStorageTypeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public UnknownStorageTypeException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public UnknownStorageTypeException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public UnknownStorageTypeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ public class FileItem implements Serializable {
|
||||
private Date time;
|
||||
private Long size;
|
||||
private FileTypeEnum type;
|
||||
private String path;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
@@ -43,4 +44,12 @@ public class FileItem implements Serializable {
|
||||
public void setType(FileTypeEnum type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,18 @@ import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import im.zhaojun.common.config.CaffeineConfiguration;
|
||||
import com.mpatric.mp3agic.ID3v1;
|
||||
import com.mpatric.mp3agic.ID3v2;
|
||||
import com.mpatric.mp3agic.Mp3File;
|
||||
import im.zhaojun.common.config.ZfileCacheConfiguration;
|
||||
import im.zhaojun.common.enums.FileTypeEnum;
|
||||
import im.zhaojun.common.enums.StorageTypeEnum;
|
||||
import im.zhaojun.common.model.AudioInfo;
|
||||
import im.zhaojun.common.model.FileItem;
|
||||
import im.zhaojun.common.model.ImageInfo;
|
||||
import im.zhaojun.common.model.SiteConfig;
|
||||
import im.zhaojun.common.util.StringUtils;
|
||||
import org.springframework.aop.framework.AopContext;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
@@ -19,12 +24,14 @@ import org.springframework.cache.annotation.Cacheable;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@CacheConfig(cacheNames = CaffeineConfiguration.CACHE_NAME, keyGenerator = "keyGenerator")
|
||||
@CacheConfig(cacheNames = ZfileCacheConfiguration.CACHE_NAME, keyGenerator = "keyGenerator")
|
||||
public interface FileService {
|
||||
|
||||
@Cacheable
|
||||
@@ -39,9 +46,12 @@ public interface FileService {
|
||||
*/
|
||||
@Cacheable
|
||||
default SiteConfig getConfig(String path) throws Exception {
|
||||
path = StringUtils.removeLastSeparator(path);
|
||||
SiteConfig siteConfig = new SiteConfig();
|
||||
for (FileItem fileItem : fileList(StringUtils.removeDuplicateSeparator("/" + path + "/"))) {
|
||||
FileService fileService = (FileService) AopContext.currentProxy();
|
||||
|
||||
List<FileItem> fileItemList = fileService.fileList(path);
|
||||
path = StringUtils.removeLastSeparator(path);
|
||||
for (FileItem fileItem : fileItemList) {
|
||||
if ("readme.md".equalsIgnoreCase(fileItem.getName())) {
|
||||
siteConfig.setFooter(getTextContent(path + "/" + fileItem.getName()));
|
||||
} else if ("header.md".equalsIgnoreCase(fileItem.getName())) {
|
||||
@@ -83,4 +93,73 @@ public interface FileService {
|
||||
BufferedImage sourceImg = ImageIO.read(inputStream);
|
||||
return new ImageInfo(sourceImg.getWidth(), sourceImg.getHeight());
|
||||
}
|
||||
|
||||
default AudioInfo getAudioInfo(String url) throws Exception {
|
||||
// String query = new URL(URLUtil.decode(url)).getQuery();
|
||||
// url = url.replace(query, URLUtil.encode(query));
|
||||
File file = new File(System.getProperty("user.home") + "/zfile/tmp/audio/" + UUID.fastUUID());
|
||||
FileUtil.mkParentDirs(file);
|
||||
HttpUtil.downloadFile(url, file);
|
||||
Mp3File mp3file = new Mp3File(file);
|
||||
ID3v1 audioTag = null;
|
||||
AudioInfo audioInfo = new AudioInfo();
|
||||
|
||||
if (mp3file.hasId3v1Tag()) {
|
||||
audioTag = mp3file.getId3v1Tag();
|
||||
audioInfo.setCover("/shikwasa/audio.png");
|
||||
} else if (mp3file.hasId3v2Tag()) {
|
||||
ID3v2 id3v2Tag = mp3file.getId3v2Tag();
|
||||
audioInfo.setCover("data:" + id3v2Tag.getAlbumImageMimeType() + ";base64," + Base64.encode(id3v2Tag.getAlbumImage()));
|
||||
audioTag = id3v2Tag;
|
||||
} else {
|
||||
}
|
||||
|
||||
if (audioTag == null) {
|
||||
audioInfo.setTitle("未知歌曲");
|
||||
audioInfo.setArtist("未知");
|
||||
} else {
|
||||
audioInfo.setTitle(audioTag.getTitle());
|
||||
audioInfo.setArtist(audioTag.getArtist());
|
||||
}
|
||||
audioInfo.setSrc(url);
|
||||
file.deleteOnExit();
|
||||
return audioInfo;
|
||||
}
|
||||
|
||||
|
||||
default List<FileItem> search(String name) throws Exception {
|
||||
List<FileItem> result = new ArrayList<>();
|
||||
|
||||
List<FileItem> fileItemList = selectAllFileList();
|
||||
for (FileItem fileItem : fileItemList) {
|
||||
if (fileItem.getName().contains(name)) {
|
||||
result.add(fileItem);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
default List<FileItem> selectAllFileList() throws Exception {
|
||||
List<FileItem> result = new ArrayList<>();
|
||||
|
||||
String path = "/";
|
||||
|
||||
FileService currentFileService = (FileService) AopContext.currentProxy();
|
||||
List<FileItem> fileItemList = currentFileService.fileList(path);
|
||||
ArrayDeque<FileItem> queue = new ArrayDeque<>(fileItemList);
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
FileItem fileItem = queue.pop();
|
||||
result.add(fileItem);
|
||||
if (fileItem.getType() == FileTypeEnum.FOLDER) {
|
||||
String filePath = StringUtils.removeDuplicateSeparator("/" + fileItem.getPath() + "/" + fileItem.getName() + "/");
|
||||
queue.addAll(currentFileService.fileList(filePath));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
StorageTypeEnum getStorageTypeEnum();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package im.zhaojun.common.service;
|
||||
|
||||
import im.zhaojun.common.config.StorageTypeFactory;
|
||||
import im.zhaojun.common.enums.StorageTypeEnum;
|
||||
import im.zhaojun.common.model.SystemConfig;
|
||||
import im.zhaojun.common.repository.SystemConfigRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -15,4 +17,11 @@ public class SystemConfigService {
|
||||
public SystemConfig getSystemConfig() {
|
||||
return systemConfigRepository.findFirstBy();
|
||||
}
|
||||
}
|
||||
|
||||
public FileService getCurrentFileService() {
|
||||
SystemConfig systemConfig = getSystemConfig();
|
||||
StorageTypeEnum storageStrategy = systemConfig.getStorageStrategy();
|
||||
return StorageTypeFactory.getTrafficMode(storageStrategy);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package im.zhaojun.common.util;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Lazy(false)
|
||||
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
|
||||
|
||||
private static ApplicationContext applicationContext = null;
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(SpringContextHolder.class);
|
||||
|
||||
/**
|
||||
* 取得存储在静态变量中的 ApplicationContext.
|
||||
*/
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从静态变量 applicationContext 中取得 Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getBean(String name) {
|
||||
return (T) applicationContext.getBean(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从静态变量 applicationContext 中取得 Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
public static <T> T getBean(Class<T> requiredType) {
|
||||
return applicationContext.getBean(requiredType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除 SpringContextHolder 中的 ApplicationContext 为 Null.
|
||||
*/
|
||||
public static void clearHolder() {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
|
||||
}
|
||||
logger.info("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
|
||||
applicationContext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现 DisposableBean 接口, 在 Context 关闭时清理静态变量.
|
||||
*/
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
SpringContextHolder.clearHolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -61,6 +61,7 @@ public class FtpService implements FileService {
|
||||
fileItem.setSize(ftpFile.getSize());
|
||||
fileItem.setTime(ftpFile.getTimestamp().getTime());
|
||||
fileItem.setType(ftpFile.isDirectory() ? FileTypeEnum.FOLDER : FileTypeEnum.FILE);
|
||||
fileItem.setPath(path);
|
||||
fileItemList.add(fileItem);
|
||||
}
|
||||
return fileItemList;
|
||||
@@ -70,4 +71,9 @@ public class FtpService implements FileService {
|
||||
public String getDownloadUrl(String path) {
|
||||
return URLUtil.complateUrl(domain, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum getStorageTypeEnum() {
|
||||
return StorageTypeEnum.FTP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ public class HuaweiService implements FileService {
|
||||
fileItem.setSize(metadata.getContentLength());
|
||||
fileItem.setTime(metadata.getLastModified());
|
||||
fileItem.setType(FileTypeEnum.FILE);
|
||||
fileItem.setPath(path);
|
||||
fileItemList.add(fileItem);
|
||||
}
|
||||
|
||||
@@ -86,6 +87,7 @@ public class HuaweiService implements FileService {
|
||||
FileItem fileItem = new FileItem();
|
||||
fileItem.setName(commonPrefix.substring(0, commonPrefix.length() - 1));
|
||||
fileItem.setType(FileTypeEnum.FOLDER);
|
||||
fileItem.setPath(path);
|
||||
fileItemList.add(fileItem);
|
||||
}
|
||||
|
||||
@@ -102,4 +104,9 @@ public class HuaweiService implements FileService {
|
||||
URL url = new URL(res.getSignedUrl());
|
||||
return URLUtil.complateUrl(domain, url.getFile());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum getStorageTypeEnum() {
|
||||
return StorageTypeEnum.HUAWEI;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,15 @@
|
||||
package im.zhaojun.local.service;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.mpatric.mp3agic.ID3v2;
|
||||
import com.mpatric.mp3agic.Mp3File;
|
||||
import im.zhaojun.common.enums.FileTypeEnum;
|
||||
import im.zhaojun.common.enums.StorageTypeEnum;
|
||||
import im.zhaojun.common.model.AudioInfo;
|
||||
import im.zhaojun.common.model.FileItem;
|
||||
import im.zhaojun.common.model.ImageInfo;
|
||||
import im.zhaojun.common.model.StorageConfig;
|
||||
@@ -62,6 +68,7 @@ public class LocalService implements FileService {
|
||||
fileItem.setSize(f.length());
|
||||
fileItem.setName(f.getName());
|
||||
fileItemList.add(fileItem);
|
||||
fileItem.setPath(path);
|
||||
}
|
||||
|
||||
return fileItemList;
|
||||
@@ -95,6 +102,25 @@ public class LocalService implements FileService {
|
||||
return FileUtil.readUtf8String(StringUtils.concatPath(filePath, URLUtil.decode(path)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioInfo getAudioInfo(String url) throws Exception {
|
||||
String query = new URL(URLUtil.decode(url)).getQuery();
|
||||
url = url.replace(query, URLUtil.encode(query));
|
||||
File file = new File(System.getProperty("user.home") + "/zfile/tmp/audio/" + UUID.fastUUID());
|
||||
FileUtil.mkParentDirs(file);
|
||||
HttpUtil.downloadFile(url, file);
|
||||
Mp3File mp3file = new Mp3File(file);
|
||||
ID3v2 audioTag = mp3file.getId3v2Tag();
|
||||
String imageMimeType = audioTag.getAlbumImageMimeType();
|
||||
AudioInfo audioInfo = new AudioInfo();
|
||||
audioInfo.setArtist(audioTag.getArtist());
|
||||
audioInfo.setTitle(audioTag.getTitle());
|
||||
audioInfo.setCover("data:" + imageMimeType + ";base64," + Base64.encode(audioTag.getAlbumImage()));
|
||||
audioInfo.setSrc(url);
|
||||
file.deleteOnExit();
|
||||
return audioInfo;
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
@@ -102,4 +128,9 @@ public class LocalService implements FileService {
|
||||
public void setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum getStorageTypeEnum() {
|
||||
return StorageTypeEnum.LOCAL;
|
||||
}
|
||||
}
|
||||
@@ -86,6 +86,7 @@ public class QiniuService implements FileService {
|
||||
fileItem.setSize(item.fsize);
|
||||
fileItem.setTime(new Date(item.putTime / 1000));
|
||||
fileItem.setType(FileTypeEnum.FILE);
|
||||
fileItem.setPath(path);
|
||||
fileItemList.add(fileItem);
|
||||
}
|
||||
|
||||
@@ -95,6 +96,7 @@ public class QiniuService implements FileService {
|
||||
FileItem fileItem = new FileItem();
|
||||
fileItem.setName(commonPrefix.substring(0, commonPrefix.length() - 1));
|
||||
fileItem.setType(FileTypeEnum.FOLDER);
|
||||
fileItem.setPath(path);
|
||||
fileItemList.add(fileItem);
|
||||
}
|
||||
|
||||
@@ -109,4 +111,9 @@ public class QiniuService implements FileService {
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum getStorageTypeEnum() {
|
||||
return StorageTypeEnum.QINIU;
|
||||
}
|
||||
}
|
||||
@@ -81,6 +81,7 @@ public class TencentService implements FileService {
|
||||
fileItem.setSize(s.getSize());
|
||||
fileItem.setTime(s.getLastModified());
|
||||
fileItem.setType(FileTypeEnum.FILE);
|
||||
fileItem.setPath(path);
|
||||
fileItemList.add(fileItem);
|
||||
}
|
||||
|
||||
@@ -88,6 +89,7 @@ public class TencentService implements FileService {
|
||||
FileItem fileItem = new FileItem();
|
||||
fileItem.setName(commonPrefix.substring(path.length(), commonPrefix.length() - 1));
|
||||
fileItem.setType(FileTypeEnum.FOLDER);
|
||||
fileItem.setPath(path);
|
||||
fileItemList.add(fileItem);
|
||||
}
|
||||
|
||||
@@ -100,4 +102,9 @@ public class TencentService implements FileService {
|
||||
URL url = cosClient.generatePresignedUrl(bucketName, path, expirationDate);
|
||||
return URLUtil.complateUrl(domain, url.getFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum getStorageTypeEnum() {
|
||||
return StorageTypeEnum.TENCENT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package im.zhaojun.upyun.service;
|
||||
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import com.UpYun;
|
||||
import com.upyun.UpException;
|
||||
import im.zhaojun.common.enums.FileTypeEnum;
|
||||
import im.zhaojun.common.enums.StorageTypeEnum;
|
||||
import im.zhaojun.common.model.FileItem;
|
||||
@@ -12,7 +11,6 @@ import im.zhaojun.common.service.StorageConfigService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -45,10 +43,9 @@ public class UpYunService implements FileService {
|
||||
upYun = new UpYun(bucketName, username, password);
|
||||
}
|
||||
|
||||
public List<FileItem> fileList(String path) throws IOException, UpException {
|
||||
public List<FileItem> fileList(String path) throws Exception {
|
||||
ArrayList<FileItem> fileItems = new ArrayList<>();
|
||||
|
||||
List<UpYun.FolderItem> folderItems = upYun.readDir(path, null);
|
||||
List<UpYun.FolderItem> folderItems = upYun.readDir(URLUtil.encode(path), null);
|
||||
|
||||
if (folderItems != null) {
|
||||
for (UpYun.FolderItem folderItem : folderItems) {
|
||||
@@ -56,6 +53,7 @@ public class UpYunService implements FileService {
|
||||
fileItem.setName(folderItem.name);
|
||||
fileItem.setSize(folderItem.size);
|
||||
fileItem.setTime(folderItem.date);
|
||||
fileItem.setPath(path);
|
||||
|
||||
if ("Folder".equals(folderItem.type)) {
|
||||
fileItem.setType(FileTypeEnum.FOLDER);
|
||||
@@ -73,4 +71,8 @@ public class UpYunService implements FileService {
|
||||
return URLUtil.complateUrl(domain, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageTypeEnum getStorageTypeEnum() {
|
||||
return StorageTypeEnum.UPYUN;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user