Initial backend commit

This commit is contained in:
Max W. 2024-02-03 14:40:43 +01:00
parent 1b2fa0e9af
commit 01b33d11e9
10 changed files with 274 additions and 4 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@ build/
!**/src/main/**/build/
!**/src/test/**/build/
/src/main/resources/static/
/temp-filestore/
### STS ###
.apt_generated

View File

@ -29,6 +29,7 @@ dependencies {
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'com.rethinkdb:rethinkdb-driver:2.4.4'
}
tasks.named('test') {

View File

@ -13,5 +13,6 @@ public class MvcConfig implements WebMvcConfigurer {
registry.addViewController("/download").setViewName("forward:/index.html");
registry.addViewController("/upload").setViewName("forward:/index.html");
registry.addViewController("/credits").setViewName("forward:/index.html");
}
}

View File

@ -0,0 +1,18 @@
package de.w665.sharepulse.db;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Getter
@Configuration
public class RethinkDBConfig {
@Value("${rethinkdb.host}")
private String host;
@Value("${rethinkdb.port}")
private int port;
@Value("${rethinkdb.database}")
private String database;
}

View File

@ -0,0 +1,72 @@
package de.w665.sharepulse.db;
import com.rethinkdb.RethinkDB;
import com.rethinkdb.gen.exc.ReqlOpFailedError;
import com.rethinkdb.net.Connection;
import com.rethinkdb.net.Result;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@Slf4j
@Service
public class RethinkDBService {
private static final RethinkDB r = RethinkDB.r;
private Connection connection;
private final RethinkDBConfig config;
public RethinkDBService(RethinkDBConfig config) {
this.config = config;
}
@PostConstruct
public void initialize() {
connection = r.connection().hostname(config.getHost()).port(config.getPort()).connect();
log.info("Connected to RethinkDB at " + config.getHost() + ":" + config.getPort() + " on database " + config.getDatabase());
//rethinkdb check if database exists
/*Result<Object> result = r.dbList().run(connection);
List<String> databases = new ArrayList<>();
Object db = result.first();
ArrayList<String> dbList = (ArrayList<String>) db;
databases.addAll(dbList);
if (!databases.contains("sharepulse")) {
r.dbCreate("sharepulse").run(connection);
log.info("Database 'sharepulse' created successfully.");
} else {
log.info("Database 'sharepulse' already exists. No action needed.");
}*/
try {
r.dbCreate(config.getDatabase()).run(connection).stream();
log.info("Database " + config.getDatabase() + " created");
} catch (ReqlOpFailedError e) {
log.info("Database " + config.getDatabase() + " already exists. Error: " + e.getClass().getSimpleName());
}
// Additional initialization, like ensuring the database and tables exist
}
@PreDestroy
public void close() {
if (connection != null) {
connection.close();
}
}
// Example method to insert data into a specific table
public void insertData(String tableName, Object data) {
r.db(config.getDatabase()).table(tableName).insert(data).run(connection);
}
}

View File

@ -0,0 +1,20 @@
package de.w665.sharepulse.model;
import lombok.*;
import java.util.Date;
@Getter
@Setter
@ToString
@NoArgsConstructor
public class FileUpload {
private String fileId;
private String fileName;
private long fileSize;
private boolean singleDownload;
private Date uploadDate;
private String uploadedByIpAddress;
private long downloadCount;
private String fileDescription;
}

View File

@ -1,15 +1,39 @@
package de.w665.sharepulse.rest.mappings;
import de.w665.sharepulse.rest.ApiRestController;
import de.w665.sharepulse.service.FileService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@Slf4j
@RestController
public class Upload extends ApiRestController {
private final FileService fileService;
@Autowired
public Upload(FileService fileService) {
this.fileService = fileService;
}
// Currently testing
@GetMapping("/upload")
public String getUpload() {
return "Upload works";
@PostMapping("/upload")
public ResponseEntity<String> getUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
if (file.isEmpty()) {
log.debug("User tried to upload an empty file. IP: " + request.getRemoteAddr());
return new ResponseEntity<>("Please select a file to upload.", HttpStatus.NOT_ACCEPTABLE);
}
fileService.processUploadedFile(file, request.getRemoteAddr());
log.debug("User uploaded file " + file.getOriginalFilename() + " from IP " + request.getRemoteAddr() + " successfully.");
return new ResponseEntity<>("File " + file.getOriginalFilename() + " uploaded successfully", HttpStatus.OK);
}
}

View File

@ -0,0 +1,34 @@
package de.w665.sharepulse.service;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.Date;
@Service
public class FileIdService {
private static int dailyCounter = 0;
private static String lastDate = "";
// Not safe to use
public static synchronized String generateId() {
String today = new SimpleDateFormat("yyMMdd").format(new Date());
if (!today.equals(lastDate)) {
dailyCounter = 0;
lastDate = today;
}
String counterEncoded = Integer.toString(++dailyCounter, 36).toUpperCase();
return today + counterEncoded;
}
public String generateNewUniqueId() {
return generateId();
}
}

View File

@ -0,0 +1,80 @@
package de.w665.sharepulse.service;
import de.w665.sharepulse.model.FileUpload;
import jakarta.annotation.PostConstruct;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
@Slf4j
@Service
public class FileService {
private final FileIdService fileIdService;
@Value("${sharepulse.temp-filestore-path}")
private String tempDirPath;
@Autowired
public FileService(FileIdService fileIdService) {
this.fileIdService = fileIdService;
}
public void processUploadedFile(MultipartFile file, String uploaderIp) {
String fileId = fileIdService.generateNewUniqueId();
FileUpload fileUpload = new FileUpload();
fileUpload.setFileId(fileId);
fileUpload.setFileName(file.getOriginalFilename());
fileUpload.setFileSize(file.getSize());
fileUpload.setSingleDownload(false);
fileUpload.setUploadDate(new Date());
fileUpload.setUploadedByIpAddress(uploaderIp);
fileUpload.setDownloadCount(0);
fileUpload.setFileDescription("fileDescription");
System.out.println(fileUpload.toString());
// TODO: rename file to fileID
Path path = Paths.get(getTempDirPath() + File.separator + fileId);
try {
Files.write(path, file.getBytes());
log.debug("File " + file.getOriginalFilename() + " written to " + path.getFileName());
} catch (IOException e) {
e.printStackTrace();
}
}
// create a folder
@PostConstruct
public void createFolder() {
Path path = Paths.get(getTempDirPath());
log.debug("Creating directory " + path.getFileName());
try {
if (!Files.exists(path)) {
Files.createDirectory(path);
log.debug("Directory created");
} else {
log.debug("Directory already exists");
}
} catch (IOException e) {
e.printStackTrace();
}
}
private String getTempDirPath() {
return System.getProperty("user.dir") + tempDirPath;
}
}

View File

@ -1,5 +1,24 @@
# Application config
sharepulse.temp-filestore-path=/temp-filestore
# Static path
spring.web.resources.static-locations=classpath:/static/browser/
# Rest API path prefix
spring.data.rest.base-path=/api/v1
# Upload size overwrite
spring.servlet.multipart.max-file-size=1GB
spring.servlet.multipart.max-request-size=1GB
# Logging
logging.level.de.w665.sharepulse=DEBUG
# Database
rethinkdb.host=localhost
rethinkdb.port=28015
rethinkdb.database=sharepulse
# Miscellaneous
server.port=80
spring.application.name=sharepulse