package app.controllers; import app.annotations.enums.CollectStages; import app.annotations.interfaces.*; import app.entities.SearchFilter; import app.entities.db.DbFile; import app.repositories.FilePSRepository; import app.repositories.FileRepository; import app.services.ProfileService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.InputStreamResource; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLConnection; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.sql.Timestamp; import java.time.Instant; import java.util.UUID; @RestController @RequestMapping(FileController.endpoint) public class FileController { public static final String endpoint = "api/file"; private final Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private FileRepository fileRepository; @Autowired private FilePSRepository filePSRepository; @Autowired private ProfileService profileService; @GetMapping("/edit/{uuid}") @CheckWebAccess @CheckPermitionFlag(flag = "z") @CollectStatistic(stage = CollectStages.COMBINED) public ResponseEntity getDbFile(@PathVariable String uuid) { DbFile dbFile = fileRepository.findById(UUID.fromString(uuid)).orElse(null); if (dbFile == null) return ResponseEntity.notFound().build(); return ResponseEntity.ok(dbFile); } @PostMapping("/edit") @CheckWebAccess @CheckPermitionFlag(flag = "z") @CollectStatistic(stage = CollectStages.COMBINED) public ResponseEntity editDbFile(@RequestBody DbFile dbFileEdited) { DbFile dbFile = fileRepository.findById(dbFileEdited.getId()).orElse(null); if (dbFile == null) return ResponseEntity.notFound().build(); dbFile.setTags(dbFileEdited.getTags()); fileRepository.save(dbFile); return ResponseEntity.ok().build(); } @PostMapping @CheckWebAccess @CheckPermitionFlag(flag = "z") @CollectStatistic(stage = CollectStages.COMBINED) public ResponseEntity upload(@CookieValue(value = "steam64") String steam64, @RequestParam("file") MultipartFile multipartFile, @RequestParam(value = "tags", required = false) String tags) throws IOException { if (multipartFile.isEmpty() || multipartFile.getSize() == 0L) return ResponseEntity.noContent().build(); UUID uuid = UUID.randomUUID(); Timestamp timestamp = Timestamp.from(Instant.now()); DbFile dbFile = new DbFile(); dbFile.setUploader(steam64); dbFile.setFilename(multipartFile.getOriginalFilename()); dbFile.setFilesize(multipartFile.getSize()); dbFile.setData(multipartFile.getBytes()); dbFile.setTimestamp(timestamp); dbFile.setId(uuid); dbFile.setTags(tags); dbFile.setDeleted(false); fileRepository.save(dbFile); return ResponseEntity.ok(uuid.toString()); } @GetMapping("/{uuid}") public ResponseEntity download(@PathVariable String uuid) throws UnsupportedEncodingException { DbFile dbFile = fileRepository.findById(UUID.fromString(uuid)).orElse(null); if (dbFile == null) return ResponseEntity.notFound().build(); MediaType mediaType = MediaType.APPLICATION_OCTET_STREAM; try { mediaType = MediaType.valueOf(URLConnection.guessContentTypeFromName(dbFile.getFilename())); } catch (Exception ignored) {} HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodeFileName(dbFile.getFilename())); headers.add(HttpHeaders.CACHE_CONTROL,"max-age="+(60*60*24*30)); return ResponseEntity.ok() .headers(headers) .contentLength(dbFile.getFilesize()) .contentType(mediaType) .body(new InputStreamResource(new ByteArrayInputStream(dbFile.getData()))); } @PostMapping("/search") @CheckWebAccess @CheckPermitionFlag(flag = "z") @CollectStatistic(stage = CollectStages.COMBINED) public Page getFiles(Pageable pageable, @RequestBody(required = false) SearchFilter searchFilter) { if (searchFilter == null) searchFilter = new SearchFilter(); String steam64_ids = searchFilter.getAccountsSteam64(profileService); return filePSRepository.getFiles(pageable, steam64_ids.isEmpty(), steam64_ids, searchFilter.getBeginUnixTime(), searchFilter.getEndUnixTime()); } private static String encodeFileName(String fileName) throws UnsupportedEncodingException { return URLEncoder.encode(fileName, StandardCharsets.UTF_8).replace("+", "%20"); } public String getUrl(String tags) { logger.info("Search " + tags + " in files"); DbFile dbFile = fileRepository.getDbFilesByTag(tags); if (dbFile == null) throw new RuntimeException("Cannot find: " + tags); logger.info("Search {} end with success", tags); return endpoint+"/"+dbFile.getId(); } public String getUrlWithNameAndTag(String filename, String tag) { logger.info("Search {} with tag: {} in files", filename, tag); DbFile dbFile = fileRepository.getDbFileByFilenameAndTag(filename + ".%", tag); if (dbFile == null) throw new RuntimeException("Cannot find: " + filename); logger.info("Search {} with tag: {} end with success", filename, tag); return endpoint+"/"+dbFile.getId(); } }