Skip to content

Commit

Permalink
release 1.0.0.RC
Browse files Browse the repository at this point in the history
  • Loading branch information
BitInit committed May 2, 2019
1 parent 8ef19cf commit efbf759
Show file tree
Hide file tree
Showing 41 changed files with 246 additions and 37 deletions.
32 changes: 23 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
![logo](doc/image/logo_600_400.png)
## 介绍
`pnd`全名为`Personal Network Disk`,为了实现一个部署在家庭、寝室等私人生活中的网络存储空间,是一个具有从远程服务器后台下载到私人网盘、家庭文件共享、在线影视观看等功能的方便、快捷的生活助手。

前端页面:[https://github.com/BitInit/pnd-web](https://github.com/BitInit/pnd-web)

## 功能
- [x] 文件及文件夹:增/删//移动/复制
- [x] 大文件的分块上传,支持断点续传
- [ ] 文件下载 (开发中...)
- [ ] 影视在线观看
- [x] 文件及文件夹:增/删/重命名/移动/复制
- [x] 大文件的分块上传,支持文件上传的暂停/恢复;文件上传 md5 校验,如果系统存在该文件,可实现文件的秒传
- [x] 文件下载,部分视频的浏览器简单播放(临时功能)
- [ ] 视频在线播放 (开发中...)
- [ ] 远程资源后台下载
- [ ] ......

Expand All @@ -27,18 +28,31 @@ bin/startup.sh
# 浏览器访问:http://localhost:8989
```

### 直接下载安装包
待续...
### 直接下载二进制包
[选择最新的二进制包](https://github.com/BitInit/pnd/releases)

### docker

``` sh
docker pull bitinit/pnd

docker run -d -p 8989:8989 -v [YourOwnPath]:/pnd/data bitinit/pnd

# 浏览器访问:http://<ip>:8989
```

## 项目演示
#### 文件夹管理
文件夹创建、文件重命名、移动、删除

![folder](doc/folder_manage.gif)
![folder](doc/image/folder_manage.gif)

#### 大文件上传
#### 大文件分块上传
计算文件校验码,如果系统有该文件实现快速上传,如果没有就上传该大文件

![fileUpload](doc/file_upload.gif)
![fileUpload](doc/image/file_upload.gif)

#### 文件下载,部分视频简单播放
![fileDownload](doc/image/file_download.gif)

#### 其他功能 待续
2 changes: 1 addition & 1 deletion common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>site.bitinit.pnd</groupId>
<artifactId>pnd-all</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.0.RC</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>pnd-common</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ public static String formatDate(Date date, String format){
return f.format(date);
}



public static String uuid(){
return UUID.randomUUID().toString().replaceAll("-", "");
}
Expand Down
10 changes: 10 additions & 0 deletions distribution/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM openjdk:8-jre-alpine

WORKDIR /pnd
COPY . /pnd

RUN echo "Asia/Shanghai" > /etc/timezone

EXPOSE 8989
VOLUME /pnd/data
ENTRYPOINT ["bin/startup.sh"]
4 changes: 4 additions & 0 deletions distribution/assembly.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,9 @@
<source>../web/target/pnd-web.jar</source>
<outputDirectory>/lib/</outputDirectory>
</file>
<file>
<source>Dockerfile</source>
<destName>Dockerfile</destName>
</file>
</files>
</assembly>
8 changes: 4 additions & 4 deletions distribution/bin/startup.sh
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#!/usr/bin/env bash
#!/usr/bin/env sh

PND_HOME=`cd $(dirname $0)/..; pwd`

JAVA_OPTS="${JAVA_OPTS} -Dpnd.home=${PND_HOME}"
JAVA_OPTS="${JAVA_OPTS} -jar "${PND_HOME}/lib/pnd-web.jar""
JAVA_OPTS="${JAVA_OPTS} --spring.config.location=${PND_HOME}/conf/application.properties"

if [ ! -d "${PND_HOME}/logs" ]; then
mkdir ${PND_HOME}/logs
if [ ! -d "${PND_HOME}/data/logs" ]; then
mkdir -p ${PND_HOME}/data/logs
fi

#echo "nohup java ${JAVA_OPTS} > ${PND_HOME}/logs/pnd-start.log 2>&1 &"
#nohup java ${JAVA_OPTS} > ${PND_HOME}/logs/pnd-start.log 2>&1 &
#nohup java ${JAVA_OPTS} > ${PND_HOME}/data/logs/pnd-start.log 2>&1 < /dev/null
java ${JAVA_OPTS}
2 changes: 1 addition & 1 deletion distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>site.bitinit.pnd</groupId>
<artifactId>pnd-all</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.0.RC</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>pnd-distribution</artifactId>
Expand Down
Binary file removed doc/file_upload.gif
Binary file not shown.
Binary file added doc/image/file_download.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/image/file_upload.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file added doc/image/logo_600_400.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>site.bitinit.pnd</groupId>
<artifactId>pnd-all</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.0.RC</version>
<name>pnd-all</name>
<description>Personal Network Disk</description>
<packaging>pom</packaging>
Expand Down
2 changes: 1 addition & 1 deletion web/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>site.bitinit.pnd</groupId>
<artifactId>pnd-all</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.0.RC</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>pnd-web</artifactId>
Expand Down
2 changes: 2 additions & 0 deletions web/src/main/java/site/bitinit/pnd/PndApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
* @author john
*/
@SpringBootApplication
@EnableScheduling
public class PndApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void init(){
setDbMaxActive(Integer.parseInt(getEnvProperty(EnvironmentConstants.DB_MAX_ACTIVE, "20")));
setDbMaxIdle(Integer.parseInt(getEnvProperty(EnvironmentConstants.DB_MAX_IDLE, "50")));

setMaxConcurrentUploadNumbers(Integer.parseInt(getEnvProperty(EnvironmentConstants.MAX_CONCURRENT_UPLOAD_NUMBERS, "1")));
setMaxConcurrentUploadNumbers(Integer.parseInt(getEnvProperty(EnvironmentConstants.MAX_CONCURRENT_UPLOAD_NUMBERS, "3")));
setMaxFileUploadSize(getEnvProperty(EnvironmentConstants.MAX_FILE_UPLOAD_SIZE, "12MB"));
setMaxRequestSize(getEnvProperty(EnvironmentConstants.MAX_REQUEST_SIZE, "15MB"));
// 10MB
Expand Down
90 changes: 90 additions & 0 deletions web/src/main/java/site/bitinit/pnd/web/config/Scheduler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package site.bitinit.pnd.web.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import site.bitinit.pnd.web.dao.ResourceDao;
import site.bitinit.pnd.web.model.PndResource;
import site.bitinit.pnd.web.utils.PathUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
* @author: john
* @date: 2019/5/2
*/
@Component
public class Scheduler {

private static final Logger logger = LoggerFactory.getLogger(Scheduler.class);

@Autowired
private PathUtils pathUtils;
@Autowired
private ResourceDao resourceDao;
@Autowired
private TransactionTemplate transactionTemplate;

/**
* 每天凌晨 2 点执行脏数据清理
*/
@Scheduled(cron = "0 0 2 * * ?")
public void clearDirtyData(){
cleanResourceFile(cleanResourceTable());
}

/**
* 若清除资源表数据成功,再清理脏文件
* @param resources
*/
private void cleanResourceFile(List<PndResource> resources) {
resources.stream()
.filter(p -> shouldDelete(p))
.forEach(resource -> {
String subPath = resource.getPath() + File.separator + resource.getUuid();
String pathStr = pathUtils.getResourceAbsolutionPath(subPath);

File file = new File(pathStr);
if (file.exists()){
file.delete();
logger.info("clear resource {} success!", resource.getUuid());
}
});
}

/**
* 先通过事务清理资源表无效数据
* @return
*/
private List<PndResource> cleanResourceTable() {
return transactionTemplate.execute(transactionStatus -> {
List<PndResource> pndResources = resourceDao.findDirtyResources();
List<Long> deleteIds = new ArrayList<>();
pndResources.stream()
.filter(p -> shouldDelete(p))
.forEach(resource -> {
deleteIds.add(resource.getId());
});
resourceDao.deleteBatch(deleteIds);
return pndResources;
});
}

private boolean shouldDelete(PndResource resource){
if (System.currentTimeMillis() - resource.getGmtModified() >= RESOURCE_CLEAN_INTERVAL_TIME
|| resource.getLink() == 0){
return true;
}
return false;
}

/**
* 间隔时间 6h
*/
private static final long RESOURCE_CLEAN_INTERVAL_TIME = 6 * 3600 * 1000;
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public enum ResourceState {
fileTypeAccordingToSuffix.put(".flv", FileType.VIDEO);
fileTypeAccordingToSuffix.put(".rmvb", FileType.VIDEO);
fileTypeAccordingToSuffix.put(".avi", FileType.VIDEO);
fileTypeAccordingToSuffix.put(".mkv", FileType.PICTURE);
fileTypeAccordingToSuffix.put(".mkv", FileType.VIDEO);

// audio
fileTypeAccordingToSuffix.put(".mp3", FileType.AUDIO);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package site.bitinit.pnd.web.controller;

import org.apache.catalina.connector.ClientAbortException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import site.bitinit.pnd.common.ResponseEntity;
Expand All @@ -9,9 +15,11 @@
import site.bitinit.pnd.web.config.SystemConstants;
import site.bitinit.pnd.web.service.ResourceService;

import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Objects;

/**
* @author: john
Expand All @@ -21,6 +29,8 @@
@RequestMapping(SystemConstants.API_VERSION)
public class ResourceController {

private static final Logger logger = LoggerFactory.getLogger(ResourceController.class);

@Autowired
private ResourceService resourceService;

Expand Down Expand Up @@ -56,4 +66,28 @@ public ResponseEntity pauseFileUpload(String clientId, Long resourceId, String t
return ResponseUtils.ok("");
}

@GetMapping("/rs/{resourceId}")
public org.springframework.http.ResponseEntity<Resource> downloadFile(@PathVariable Long resourceId, String fileName, HttpServletRequest request) throws UnsupportedEncodingException {
Resource resource = resourceService.loadResource(resourceId);

String contentType = null;
try {
contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
if (Objects.isNull(contentType)){
contentType = "application/octet-stream";
}

return org.springframework.http.ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8"))
.body(resource);
}

@ExceptionHandler
public void clientAbortException(ClientAbortException e){
logger.warn("client cancelled file download {}", e.getMessage());
}
}
27 changes: 27 additions & 0 deletions web/src/main/java/site/bitinit/pnd/web/dao/ResourceDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
Expand Down Expand Up @@ -80,6 +81,32 @@ public int updateIndex(long id, long expected, long val){
return jdbcTemplate.update(sql, val, CommonUtils.formatDate(), id, expected);
}

public List<PndResource> findDirtyResources(){
String sql = "select " + RESOURCE_ALL_FIELDS + " from " + RESOURCE_TABLE_NAME + " where status = ? or (status = ? and link = ?)";
return daoUtils.queryForList(sql, RESOURCE_ROW_MAPPER, SystemConstants.ResourceState.pending.name(),
SystemConstants.ResourceState.succeeded.name(), 0);
}

public void delete(long resourceId){
String sql = "delete from " + RESOURCE_TABLE_NAME + " where id=?";
jdbcTemplate.update(sql, resourceId);
}

public void deleteBatch(List<Long> resourceIds){
String sql = "delete from " + RESOURCE_TABLE_NAME + " where id=?";
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
ps.setLong(1, resourceIds.get(i));
}

@Override
public int getBatchSize() {
return resourceIds.size();
}
});
}

public static final String RESOURCE_TABLE_NAME = " pnd_resource ";
private static final String RESOURCE_ALL_FIELDS = " id, size, path, uuid, gmt_create, gmt_modified, status, md5, link ";
private static final ResourceRowMapper RESOURCE_ROW_MAPPER = new ResourceRowMapper();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package site.bitinit.pnd.web.service;

import org.springframework.core.io.Resource;
import site.bitinit.pnd.web.config.SystemConstants;
import site.bitinit.pnd.web.controller.dto.ResourceConfigDto;
import site.bitinit.pnd.web.controller.dto.ResourceUploadResponseDto;
Expand Down Expand Up @@ -63,4 +64,5 @@ public interface ResourceService {
*/
void changeResourceState(String clientId, Long resourceId, String type);

Resource loadResource(Long resourceId);
}
Loading

0 comments on commit efbf759

Please sign in to comment.