diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 01a68bf..0000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: java - -install: true - -jdk: - - openjdk8 - -notifications: - email: false - -script: - - export TZ=Asia/Shanghai - - mvn cobertura:cobertura - -after_success: - - bash <(curl -s https://codecov.io/bash) -t c590f330-6d1e-4baf-9cbe-e376c11cd96f \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index aae9bb5..0000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,128 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity -and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the - overall community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or - advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email - address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -admin@zhouzifei.com. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series -of actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within -the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct -enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. diff --git a/docs/README.md b/docs/README.md index d7c3690..fe35451 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,9 +1,9 @@ -# simpleFS初认识 +# Fork目的 +因为发现原仓库更新已不活跃(上次更新已是半年前)提交的pr都未合并,故fork出来,并修复部分bug,并添加了部分功能。 +# simpleFS +它是一个小型整合型的工具类,带有整合(阿里云,七牛云,又拍云,腾讯云,华为云,~~百度云~~,本地上传)OSS上传,短信发送(阿里云,腾讯云,七牛云),文件加工类,它可以让我们脱离繁琐的开发流程,让开发变得**So easy!**。 -> 如你所见,它是一个小型整合型的工具类,带有整合(阿里云,七牛云,又拍云,腾讯云,华为云,~~百度云~~,本地上传)OSS上传,短信发送(阿里云,腾讯云,七牛云),文件加工类,,它可以让我们脱离繁琐的开发流程,让开发变得**So easy!**. - -# 支持站点 -------------------------------- +# 支持平台 | 站点 | 文件上传 | 分片上传 | 断点续传 | 文件下载 | 文件删除 | | :--: | :--: | :--: | :--: | :--: | :--: | @@ -32,7 +32,8 @@ | **其它兼容 S3 协议的平台** |✔|✖|✖|✔|✔| # 快速开始 -## 安装方式 + +## 1、安装 ### 依赖包方式引入 @@ -72,15 +73,19 @@ > ``` ### 源码安装方式引入 +拉取代码 ```shell -git clone https://gitee.com/zifeiZhou/simpleFS.git(Gitee) -git clone https://github.com/shengdingbox/simpleFS.git(Github) +git clone https://gitee.com/zifeiZhou/simpleFS.git(国内,版本较为落后) +git clone https://github.com/shengdingbox/simpleFS.git(默认) +``` +编译构建 +```shell mvn clean install ``` -## 配置存储配置信息 -### 阿里云oss配置 +## 2、配置 + - `application.yml`方式 ```yaml @@ -121,9 +126,9 @@ simple-fs: qiniu: access-key: 七牛云授权AK secret-key: 七牛云授权SK - endpoint: 七牛云地域 domain-url: 七牛云访问地址 bucket-name: 七牛云空间名称 + region: 七牛云地域 upai: user-name: 又拍云用户名 pass-word: 又拍云密码 @@ -153,7 +158,7 @@ simple-fs.oss.endpoint=地域 simple-fs.oss.domain-url=图片外网地址 simple-fs.oss.bucket-name=空间名称 ``` -启动配置类赋值 +- 启动配置类赋值 ```java import com.zhouzifei.tool.config.OssFileProperties; @@ -182,46 +187,32 @@ public class OssConfig { } ``` -` - - - - - - - - - - - - - - - - - +## 开发 - - - - - - -获取ApiClient对象 +- 初始化 ```java - @Autowired - FileProperties fileProperties; - - BaseFileUploader uploader = new BaseFileUploader(); - ApiClient apiClient = uploader.getApiClient(fileProperties); +@Autowired +private SimpleFsProperties simpleFsProperties; + +FileUploader uploader = FileUploader.builder() + .simpleFsProperties(simpleFsProperties) + .progressListener(progressListener) + .domainUrl(domainUrl) + .accessKey(accessKey) + .secretKey(secretKey) + .region(region) + .bucketName(bucketName) + .storageType(storageType) + .build(); + +ApiClient apiClient = uploader.execute(); ``` - 文件上传 ```java -VirtualFile uploadFile(MultipartFile file); -VirtualFile uploadFile(File file); -VirtualFile uploadFile(InputStream is, String fileName); +VirtualFile virtualFile = apiClient.uploadFile(file, TEST_OBJECT_NAME); + ``` - 文件下载 ```java @@ -235,37 +226,101 @@ VirtualFile multipartUpload(File file); ```java boolean removeFile(String key); ``` -### m3u8下载类 + +- 文件上传最佳实践 ```java -public class M3u8DownloadUtil { - public static void main(String[] args) { - M3u8DTO m3u8Download = M3u8DTO.builder() - .m3u8Url("下载地址") - .fileName("下载完的文件名,不带后缀") - .filePath("下载后的地址") - .retryCount("重试次数") - .threadCount("线程数") - .timeout("超时时间").build(); - M3u8DownloadFactory.M3u8Download instance = M3u8DownloadFactory.getInstance(m3u8Download); - instance.runDownloadTask();//开始下载 - M3u8DownloadFactory.destroy();//销毁实例 +package com.zhouzifei.oss; + +import com.zhouzifei.tool.config.QiniuFileProperties; +import com.zhouzifei.tool.config.SimpleFsProperties; +import com.zhouzifei.tool.consts.StorageTypeConst; +import com.zhouzifei.tool.dto.VirtualFile; +import com.zhouzifei.tool.listener.ProgressListener; +import com.zhouzifei.tool.service.ApiClient; +import com.zhouzifei.tool.service.FileUploader; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.util.ResourceUtils; + +import java.io.FileInputStream; + +@SpringBootApplication(scanBasePackages = "com.zhouzifei.*") +@SpringBootTest +@ActiveProfiles("oss") +public class OssTemplateTest { + + @Autowired + private SimpleFsProperties simpleFsProperties; + + /** + * 测试用文件名,该文件在测试资源文件夹下 + */ + private static final String TEST_OBJECT_NAME = "test.txt"; + + @Test + @SneakyThrows + public void test() { + System.out.println(simpleFsProperties); + ProgressListener progressListener = new ProgressListener() { + @Override + public void start(String s) { + System.out.println("开始上传"); + } + + @Override + public void process(int i, int i1) { + System.out.println("i=" + i); + System.out.println("i1=" + i1); + } + + @Override + public void end(VirtualFile virtualFile) { + System.out.println("上传完成"); + System.out.println(virtualFile); + + } + }; + QiniuFileProperties qiniuFileProperties = simpleFsProperties.getQiniu(); + System.out.println(qiniuFileProperties); + + String domainUrl = qiniuFileProperties.getDomainUrl(); + String accessKey = qiniuFileProperties.getAccessKey(); + String secretKey = qiniuFileProperties.getSecretKey(); + String region = qiniuFileProperties.getRegion(); + String bucketName = qiniuFileProperties.getBucketName(); + String storageType = StorageTypeConst.QINIUYUN.getStorageType(); + + FileUploader uploader = FileUploader.builder() + .simpleFsProperties(simpleFsProperties) + .progressListener(progressListener) + .domainUrl(domainUrl) + .accessKey(accessKey) + .secretKey(secretKey) + .region(region) + .bucketName(bucketName) + .storageType(storageType) + .build(); + + ApiClient apiClient = uploader.execute(); + + + FileInputStream file = new FileInputStream(ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + TEST_OBJECT_NAME)); + + VirtualFile virtualFile = apiClient.uploadFile(file, TEST_OBJECT_NAME); + System.out.println(virtualFile.getFullFilePath()); + System.out.println(virtualFile.getFileHash()); + + } + } -``` -## 特别鸣谢 -- `spring-boot-demo` 深度学习并实战 spring boot 的项目: [https://github.com/xkcoding/spring-boot-demo](https://github.com/xkcoding/spring-boot-demo) -- `腾讯云COS`免费空间50G,免费流量10G/月 [https://cloud.tencent.com/product/cos](https://cloud.tencent.com/product/cos) -- `七牛云`免费空间10G,免费流量10G/月,免费GET100万次/月[https://www.qiniu.com/prices](https://www.qiniu.com/prices) -- `又拍云`免费空间10G,免费流量15G/月(非开通就有,需要额外申请又拍云联盟,限时1年)[https://www.upyun.com/league](https://www.upyun.com/league) -- `网易云`免费空间50G,免费流量20G/月(目前发现最慷慨的一家)[https://www.163yun.com/nos/free](https://www.163yun.com/nos/free) -- `青云`免费空间10G,免费流量1G/月,另外注意没有免费请求额度[https://www.qingcloud.com/pricing-standard](https://www.qingcloud.com/pricing-standard) -- `阿里云`免费空间40G,免费流量10G/月 (限定新用户、限时6个月)[https://www.aliyun.com/product/oss](https://www.aliyun.com/product/oss) -- `FASTDFS`一个开源的轻量级分布式文件系统[https://github.com/happyfish100/fastdfs/wiki/](https://github.com/happyfish100/fastdfs/wiki/) -- `FASTDFS`一个开源的轻量级分布式文件系统[https://github.com/happyfish100/fastdfs/wiki/](https://github.com/happyfish100/fastdfs/wiki/) +``` -## 在线文档 -- http://docs.zhouzifei.com/ diff --git a/package.json b/package.json deleted file mode 100644 index a6960ed..0000000 --- a/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "my-project", - "scripts": { - "start": "docsify start . -c ssr.config.js", - "deploy": "now -p" - }, - "files": [ - "docs" - ], - "docsify": { - "config": { - "basePath": "https://docsify.js.org/", - "loadSidebar": false, - "loadNavbar": false, - "coverpage": true, - "name": "docsify" - } - } -} \ No newline at end of file diff --git a/pom.xml b/pom.xml index c5029bb..8008104 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ 1.2.83 3.13.2 4.6.0 - 7.2.19 + 7.17.0 1.15.3 2.4.2.1-RELEASE 1.18.12 @@ -210,7 +210,7 @@ - + - + org.sonatype.plugins diff --git a/src/main/java/com/zhouzifei/tool/config/QiniuFileProperties.java b/src/main/java/com/zhouzifei/tool/config/QiniuFileProperties.java index 4bcceb8..baf0284 100644 --- a/src/main/java/com/zhouzifei/tool/config/QiniuFileProperties.java +++ b/src/main/java/com/zhouzifei/tool/config/QiniuFileProperties.java @@ -16,8 +16,8 @@ @ConfigurationProperties(prefix = "simple-fs.qiniu") public class QiniuFileProperties extends FileProperties{ private String domainUrl; - private String endpoint; private String bucketName; private String accessKey; private String secretKey; + private String region; } diff --git a/src/main/java/com/zhouzifei/tool/fileClient/QiniuApiClient.java b/src/main/java/com/zhouzifei/tool/fileClient/QiniuApiClient.java index b04021a..d8782e8 100644 --- a/src/main/java/com/zhouzifei/tool/fileClient/QiniuApiClient.java +++ b/src/main/java/com/zhouzifei/tool/fileClient/QiniuApiClient.java @@ -3,13 +3,12 @@ import com.alibaba.fastjson.JSON; import com.qiniu.common.QiniuException; -import com.qiniu.common.Region; import com.qiniu.http.Response; import com.qiniu.storage.BucketManager; import com.qiniu.storage.Configuration; +import com.qiniu.storage.Region; import com.qiniu.storage.UploadManager; import com.qiniu.storage.model.DefaultPutRet; -import com.qiniu.storage.model.FileInfo; import com.qiniu.util.Auth; import com.zhouzifei.tool.common.ServiceException; import com.zhouzifei.tool.config.FileProperties; @@ -37,10 +36,12 @@ public class QiniuApiClient extends BaseApiClient { private BucketManager bucketManager; private Auth auth; + private Configuration cfg; public QiniuApiClient() { super("七牛云"); } + public QiniuApiClient(FileProperties fileProperties) { super("七牛云"); init(fileProperties); @@ -48,7 +49,8 @@ public QiniuApiClient(FileProperties fileProperties) { @Override public QiniuApiClient init(FileProperties fileProperties) { - final QiniuFileProperties qiniuFileProperties = (QiniuFileProperties)fileProperties; + + final QiniuFileProperties qiniuFileProperties = (QiniuFileProperties) fileProperties; this.accessKey = qiniuFileProperties.getAccessKey(); this.secretKey = qiniuFileProperties.getSecretKey(); this.bucketName = qiniuFileProperties.getBucketName(); @@ -59,7 +61,22 @@ public QiniuApiClient init(FileProperties fileProperties) { || StringUtils.isNullOrEmpty(bucketName)) { throw new ServiceException("[" + this.storageType + "]尚未配置七牛云,文件上传功能暂时不可用!"); } + if (StringUtils.isEmpty(qiniuFileProperties.getRegion())) { + cfg = new Configuration(Region.autoRegion()); + } else { + String zone = qiniuFileProperties.getRegion(); + Region region = new Region.Builder() + .region(zone) + .accUpHost("up-" + zone + ".qiniup.com") + .iovipHost("iovip-" + zone + ".qiniuio.com") + .rsHost("rs-" + zone + ".qiniuapi.com") + .rsfHost("rsf-" + zone + ".qiniuapi.com") + .apiHost("api.qiniuapi.com") + .build(); + cfg = new Configuration(region); + } auth = Auth.create(accessKey, secretKey); + bucketManager = new BucketManager(auth, cfg); return this; } @@ -76,7 +93,6 @@ public String uploadInputStream(InputStream is, String fileName) { //Zone.zone1:华北 //Zone.zone2:华南 //Zone.zoneNa0:北美 - Configuration cfg = new Configuration(Region.autoRegion()); UploadManager uploadManager = new UploadManager(cfg); try { String upToken = auth.uploadToken(this.bucketName); @@ -107,27 +123,28 @@ public boolean removeFile(String key) { throw new ServiceException("[" + this.storageType + "]删除文件发生异常:" + r.toString()); } } + @Override public VirtualFile multipartUpload(InputStream inputStream, MetaDataRequest metaDataRequest) { return null; } @Override - public List fileList(FileListRequesr fileListRequesr){ + public List fileList(FileListRequesr fileListRequesr) { return null; } @Override public boolean exists(String fileName) { - try { - FileInfo stat = bucketManager.stat(bucketName,this.domainUrl + fileName); + /* try { + FileInfo stat = bucketManager.stat(bucketName, fileName); if (stat != null && stat.md5 != null) { return true; } } catch (QiniuException e) { throw new ServiceException("查询文件是否存在失败!" + e.code() + "," + e.response.toString()); - } - return false; + }*/ + return true; } @Override