package local.epul4a.fotosharing.controller; import local.epul4a.fotosharing.dto.CommentaireDTO; import local.epul4a.fotosharing.dto.PartageDTO; import local.epul4a.fotosharing.dto.PhotoDTO; import local.epul4a.fotosharing.service.CommentaireService; import local.epul4a.fotosharing.service.PartageService; import local.epul4a.fotosharing.service.PhotoService; import local.epul4a.fotosharing.service.UtilisateurService; import org.springframework.core.io.Resource; import org.springframework.data.domain.Page; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @Controller public class PhotoController { private final PhotoService photoService; private final CommentaireService commentaireService; private final PartageService partageService; private final UtilisateurService utilisateurService; public PhotoController( PhotoService photoService, CommentaireService commentaireService, PartageService partageService, UtilisateurService utilisateurService ) { this.photoService = photoService; this.commentaireService = commentaireService; this.partageService = partageService; this.utilisateurService = utilisateurService; } /* ========================== UPLOAD ========================== */ @GetMapping("/upload") public String uploadForm() { return "upload"; } @PostMapping("/upload") public String doUpload(@RequestParam("file") MultipartFile file, @RequestParam(value = "visibilite", defaultValue = "PRIVATE") String visibilite, Authentication auth, Model model) { try { photoService.store(file, visibilite, auth.getName()); return "redirect:/mes-photos"; } catch (Exception ex) { model.addAttribute("error", ex.getMessage()); return "upload"; } } /* ========================== RAW IMAGE ========================== */ @GetMapping("/photo/{id}/raw") public ResponseEntity rawPhoto(@PathVariable Long id) { PhotoDTO photo = photoService.getPhotoById(id); if (photo == null) return ResponseEntity.notFound().build(); Resource r = photoService.loadAsResource(photo.getUuidFichier()); if (!r.exists()) return ResponseEntity.notFound().build(); return ResponseEntity.ok() .contentType(MediaType.IMAGE_JPEG) // simplifiable, ou détecté dans service .body(r); } /* ========================== MES PHOTOS ========================== */ @GetMapping("/mes-photos") public String mesPhotos( @RequestParam(defaultValue = "0") int pagePrivees, @RequestParam(defaultValue = "0") int pagePubliques, @RequestParam(defaultValue = "0") int pagePartagees, @RequestParam(defaultValue = "0") int pageMesPartagees, Authentication auth, Model model) { String email = auth.getName(); model.addAttribute("photosPrivees", photoService.listPrivatePhotos(email, pagePrivees, 12)); model.addAttribute("photosPubliques", photoService.listPublicPhotos(email, pagePubliques, 12)); model.addAttribute("photosPartagees", photoService.listSharedWith(email, pagePartagees, 12)); model.addAttribute("mesPhotosPartagees", photoService.listSharedPhotos(email, pageMesPartagees, 12)); model.addAttribute("pagePrivees", pagePrivees); model.addAttribute("pagePubliques", pagePubliques); model.addAttribute("pagePartagees", pagePartagees); model.addAttribute("pageMesPartagees", pageMesPartagees); return "mes-photos"; } /* ========================== GALERIE ========================== */ @GetMapping("/galerie") public String galerie(@RequestParam(defaultValue = "0") int page, Model model) { Page photosPage = photoService.listPublic(page, 12); model.addAttribute("photosPage", photosPage); model.addAttribute("currentPage", page); return "galerie"; } /* ========================== DETAIL PHOTO ========================== */ @GetMapping("/photo/{id}") @PreAuthorize("@securityService.canAccessPhoto(authentication, #id)") public String viewPhoto(@PathVariable Long id, @RequestParam(defaultValue = "0") int page, Authentication auth, Model model) { PhotoDTO photo = photoService.getPhotoById(id); if (photo == null) return "redirect:/galerie"; model.addAttribute("photo", photo); Page commentaires = commentaireService.listByPhoto(id, page, 10); model.addAttribute("commentairesPage", commentaires); model.addAttribute("currentPage", page); String currentUser = (auth != null ? auth.getName() : null); boolean canComment = partageService.canComment(id, currentUser); boolean canAdmin = partageService.canAdmin(id, currentUser); model.addAttribute("canComment", canComment); model.addAttribute("canAdmin", canAdmin); model.addAttribute("currentUser", currentUser); model.addAttribute("partages", partageService.getPartagesForPhoto(id)); return "photo-detail"; } /* ========================== COMMENTAIRES ========================== */ @PostMapping("/photo/{id}/comment") public String addComment(@PathVariable Long id, @RequestParam String contenu, Authentication auth) { commentaireService.addComment(id, auth.getName(), contenu); return "redirect:/photo/" + id; } /* ========================== PARTAGE PHOTO ========================== */ @PostMapping("/photo/{id}/share") @PreAuthorize("@securityService.canAccessPhoto(authentication, #id)") public String sharePhoto(@PathVariable Long id, @RequestParam String email, @RequestParam String permission, Authentication auth) { try { partageService.share(id, email, permission, auth.getName()); return "redirect:/photo/" + id + "?shared=ok"; } catch (RuntimeException ex) { return "redirect:/photo/" + id + "?error=" + URLEncoder.encode(ex.getMessage(), StandardCharsets.UTF_8); } } @GetMapping("/photo/{id}/unshare/{email}") public String unshare(@PathVariable Long id, @PathVariable String email) { partageService.unshare(id, email); return "redirect:/photo/" + id; } /* ========================== MAJ MODE PARTAGE ========================== */ @PostMapping("/photo/{id}/share/update") @PreAuthorize("@securityService.canAccessPhoto(authentication, #id)") public String updateShare( @PathVariable Long id, @RequestParam String email, @RequestParam String permission, Authentication auth ) { partageService.updatePermission(id, email, permission, auth.getName()); return "redirect:/photo/" + id; } }