diff --git a/backend/api/views.py b/backend/api/views.py index 1f5ceae..94d9f9d 100644 --- a/backend/api/views.py +++ b/backend/api/views.py @@ -247,6 +247,7 @@ class FileFilterView(APIView): professor_id = request.query_params.get("professor") course_id = request.query_params.get("course") semester_id = request.query_params.get("semester") + peer_id = request.query_params.get("peer_id") # Check if provided filter IDs exist if topic_id and not Topic.objects.filter(id=topic_id).exists(): @@ -269,6 +270,11 @@ class FileFilterView(APIView): {"error": f"Semester with id {semester_id} does not exist"}, status=status.HTTP_400_BAD_REQUEST, ) + if peer_id and not PeerUser.objects.filter(id=peer_id).exists(): + return Response( + {"error": f"Peer with id {peer_id} does not exist"}, + status=status.HTTP_400_BAD_REQUEST, + ) # Start with the base queryset queryset = File.objects.all() @@ -282,16 +288,20 @@ class FileFilterView(APIView): queryset = queryset.filter(course__id=course_id) if semester_id: queryset = queryset.filter(semester__id=semester_id) + queryset = queryset.annotate( upvote_count=Count("upvotes"), downvote_count=Count("downvotes") ).order_by(F("downvote_count") - F("upvote_count")) # Filter files based on active peers in the past hour - active_peer_ids = PeerUser.objects.filter( - last_poll__gte=timezone.now() - timedelta(hours=1) - ).values_list("id", flat=True) - queryset = queryset.filter(peer_users__in=active_peer_ids).distinct() + if peer_id: + queryset = queryset.filter(peer_users__in=peer_id) + else: + active_peer_ids = PeerUser.objects.filter( + last_poll__gte=timezone.now() - timedelta(hours=1) + ).values_list("id", flat=True) + queryset = queryset.filter(peer_users__in=active_peer_ids).distinct() serializer = FileSerializer(queryset, many=True) # Loop through each serialized file to sort its peer_users diff --git a/file_peer/peer_service.py b/file_peer/peer_service.py index 8014ed4..ef66322 100644 --- a/file_peer/peer_service.py +++ b/file_peer/peer_service.py @@ -83,6 +83,13 @@ def request_file(): print("Error:", error) return error, response.status_code +@app.route("/files", methods=["GET"]) +def list_files(): + files = os.listdir("./uploads") + newFiles = [] + for file in files: + newFiles.append(file.split("_")[1]) + return {"files": newFiles}, 200 @app.route("/request-tests", methods=["GET"]) def request_test_(): diff --git a/frontend/src/screens/RegisterFile.tsx b/frontend/src/screens/RegisterFile.tsx index 78fab0a..f2f763d 100644 --- a/frontend/src/screens/RegisterFile.tsx +++ b/frontend/src/screens/RegisterFile.tsx @@ -1,22 +1,48 @@ import "../styles/RegisterFile.css"; -import { RegisteredFile } from "../types/types"; +import { RegisteredFile, Status } from "../types/types"; import { useState, useEffect } from "react"; +import { getAuthHeaders } from "../utils/getAuthHeaders"; export default function RegisterFile() { + const [serverFiles, setServerFiles] = useState([]); const [registeredFiles, setRegisteredFiles] = useState([]); useEffect(() => { - fetchRegisteredFiles(); + fetchServerFiles(); }, []) - const fetchRegisteredFiles = () => { - return - fetch("http://localhost:5000/files") // replace with local api endpoint + + useEffect(() => { + fetch(`http://localhost:8080/files`, { + method: 'GET', + }) .then(response => response.json()) .then(data => { - setRegisteredFiles(data); + const files: string[] = data.files + setRegisteredFiles( + serverFiles.map((file) => { + if (files.includes(file.filename)) { + file.status = Status.HOSTED; + return file; + } + file.status = Status.PRIVATE; + return file; + }) + ) }) - .catch(error => console.error(error)); + }, [serverFiles]) + + const fetchServerFiles = () => { + fetch(`http://localhost:8000/api/files/filter?peer_id=1`, { + method: 'GET', + headers: getAuthHeaders() + }) // replace with local api endpoint + .then(response => response.json()) + .then(data => { + setServerFiles(data) + }) + .catch(error => console.error(error)); } + const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); // handle file upload diff --git a/frontend/src/screens/Results.tsx b/frontend/src/screens/Results.tsx index 29415cb..2bc6a72 100644 --- a/frontend/src/screens/Results.tsx +++ b/frontend/src/screens/Results.tsx @@ -3,6 +3,7 @@ import { useLocation, useNavigate } from 'react-router-dom'; import styles from '../styles/Results.module.css'; // Make sure this path is correct import { getAuthHeaders } from '../utils/getAuthHeaders'; import { File } from '../types/types'; +import { Link } from 'react-router-dom'; const Results: React.FC = () => { const [files, setFiles] = useState([]); @@ -113,7 +114,7 @@ function DownloadButton({ file }: { file: File }) { <> { success === true ? -

Downloaded!

: + Downloaded! : } diff --git a/frontend/src/types/types.ts b/frontend/src/types/types.ts index 2d7d0ee..da7f1f9 100644 --- a/frontend/src/types/types.ts +++ b/frontend/src/types/types.ts @@ -38,7 +38,7 @@ export interface File { downvotes: number[]; } -enum Status { +export enum Status { HOSTED = "HOSTED", PRIVATE = 'PRIVATE', }