From d4718ac120d2daab96ba1338f95c551fb1f448e0 Mon Sep 17 00:00:00 2001 From: heimoshuiyu Date: Mon, 13 Dec 2021 07:07:43 +0800 Subject: [PATCH] Add: support select ramdom files by tag --- pkg/api/api.go | 1 + pkg/api/handle_get_random_files.go | 26 +++++++ pkg/database/method.go | 22 ++++++ pkg/database/sql_stmt.go | 106 ++++++++++++++++------------ web/src/component/GetRandomFiles.js | 70 +++++++++++++++++- 5 files changed, 178 insertions(+), 47 deletions(-) diff --git a/pkg/api/api.go b/pkg/api/api.go index cc81fdc..3bdda2d 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -72,6 +72,7 @@ func NewAPI(config Config) (*API, error) { apiMux.HandleFunc("/search_folders", api.HandleSearchFolders) apiMux.HandleFunc("/get_files_in_folder", api.HandleGetFilesInFolder) apiMux.HandleFunc("/get_random_files", api.HandleGetRandomFiles) + apiMux.HandleFunc("/get_random_files_with_tag", api.HandleGetRandomFilesWithTag) apiMux.HandleFunc("/get_file_stream", api.HandleGetFileStream) apiMux.HandleFunc("/get_ffmpeg_config_list", api.HandleGetFfmpegConfigs) apiMux.HandleFunc("/feedback", api.HandleFeedback) diff --git a/pkg/api/handle_get_random_files.go b/pkg/api/handle_get_random_files.go index a164376..f7eefa8 100644 --- a/pkg/api/handle_get_random_files.go +++ b/pkg/api/handle_get_random_files.go @@ -23,3 +23,29 @@ func (api *API) HandleGetRandomFiles(w http.ResponseWriter, r *http.Request) { log.Println("[api] Get random files") json.NewEncoder(w).Encode(getRandomFilesResponse) } + +type GetRandomFilesWithTagRequest struct { + ID int64 `json:"id"` +} + +func (api *API) HandleGetRandomFilesWithTag(w http.ResponseWriter, r *http.Request) { + req := &GetRandomFilesWithTagRequest{} + err := json.NewDecoder(r.Body).Decode(req) + if err != nil { + api.HandleError(w, r, err) + return + } + + files, err := api.Db.GetRandomFilesWithTag(req.ID, 10) + if err != nil { + api.HandleError(w, r, err) + return + } + + getRandomFilesResponse := &GetRandomFilesResponse{ + Files: &files, + } + + log.Println("[api] Get random files with tag", req.ID) + json.NewEncoder(w).Encode(getRandomFilesResponse) +} diff --git a/pkg/database/method.go b/pkg/database/method.go index 9083d85..e6542a5 100644 --- a/pkg/database/method.go +++ b/pkg/database/method.go @@ -35,6 +35,28 @@ func (database *Database) GetRandomFiles(limit int64) ([]File, error) { return files, nil } +func (database *Database) GetRandomFilesWithTag(tagID, limit int64) ([]File, error) { + rows, err := database.stmt.getRandomFilesWithTag.Query(tagID, limit) + if err != nil { + return nil, err + } + defer rows.Close() + files := make([]File, 0) + for rows.Next() { + file := File{ + Db: database, + } + err = rows.Scan(&file.ID, &file.Folder_id, &file.Filename, &file.Foldername, &file.Filesize) + if err != nil { + return nil, err + } + files = append(files, file) + log.Println("[db] GetRandomFilesWithTag", file.ID, file.Filename, file.Foldername, file.Filesize) + } + log.Println("[db] GetRandomFilesWithTag", files) + return files, nil +} + func (database *Database) GetFilesInFolder(folder_id int64, limit int64, offset int64) ([]File, error) { rows, err := database.stmt.getFilesInFolder.Query(folder_id, limit, offset) if err != nil { diff --git a/pkg/database/sql_stmt.go b/pkg/database/sql_stmt.go index 0afbbb0..9e9d50a 100644 --- a/pkg/database/sql_stmt.go +++ b/pkg/database/sql_stmt.go @@ -158,6 +158,15 @@ JOIN folders ON files.folder_id = folders.id ORDER BY RANDOM() LIMIT ?;` +var getRandomFilesWithTagQuery = `SELECT +files.id, files.folder_id, files.filename, folders.foldername, files.filesize +FROM file_has_tag +JOIN files ON file_has_tag.file_id = files.id +JOIN folders ON files.folder_id = folders.id +WHERE file_has_tag.tag_id = ? +ORDER BY RANDOM() +LIMIT ?;` + var insertFeedbackQuery = `INSERT INTO feedbacks (time, feedback, header) VALUES (?, ?, ?);` @@ -236,51 +245,52 @@ ORDER BY reviews.created_at ;` type Stmt struct { - initFilesTable *sql.Stmt - initFoldersTable *sql.Stmt - initFeedbacksTable *sql.Stmt - initUsersTable *sql.Stmt - initAvatarsTable *sql.Stmt - initTagsTable *sql.Stmt - initFileHasTag *sql.Stmt - initLikesTable *sql.Stmt - initReviewsTable *sql.Stmt - initPlaybacksTable *sql.Stmt - initLogsTable *sql.Stmt - initTmpfsTable *sql.Stmt - insertFolder *sql.Stmt - insertFile *sql.Stmt - findFolder *sql.Stmt - findFile *sql.Stmt - searchFiles *sql.Stmt - getFolder *sql.Stmt - dropFiles *sql.Stmt - dropFolder *sql.Stmt - getFile *sql.Stmt - searchFolders *sql.Stmt - getFilesInFolder *sql.Stmt - getRandomFiles *sql.Stmt - insertFeedback *sql.Stmt - insertUser *sql.Stmt - countUser *sql.Stmt - countAdmin *sql.Stmt - getUser *sql.Stmt - getUserById *sql.Stmt - getAnonymousUser *sql.Stmt - insertTag *sql.Stmt - getTag *sql.Stmt - getTags *sql.Stmt - updateTag *sql.Stmt - putTagOnFile *sql.Stmt - getTagsOnFile *sql.Stmt - deleteTagOnFile *sql.Stmt - updateFoldername *sql.Stmt - insertReview *sql.Stmt - getReviewsOnFile *sql.Stmt - getReview *sql.Stmt - updateReview *sql.Stmt - deleteReview *sql.Stmt - getReviewsByUser *sql.Stmt + initFilesTable *sql.Stmt + initFoldersTable *sql.Stmt + initFeedbacksTable *sql.Stmt + initUsersTable *sql.Stmt + initAvatarsTable *sql.Stmt + initTagsTable *sql.Stmt + initFileHasTag *sql.Stmt + initLikesTable *sql.Stmt + initReviewsTable *sql.Stmt + initPlaybacksTable *sql.Stmt + initLogsTable *sql.Stmt + initTmpfsTable *sql.Stmt + insertFolder *sql.Stmt + insertFile *sql.Stmt + findFolder *sql.Stmt + findFile *sql.Stmt + searchFiles *sql.Stmt + getFolder *sql.Stmt + dropFiles *sql.Stmt + dropFolder *sql.Stmt + getFile *sql.Stmt + searchFolders *sql.Stmt + getFilesInFolder *sql.Stmt + getRandomFiles *sql.Stmt + getRandomFilesWithTag *sql.Stmt + insertFeedback *sql.Stmt + insertUser *sql.Stmt + countUser *sql.Stmt + countAdmin *sql.Stmt + getUser *sql.Stmt + getUserById *sql.Stmt + getAnonymousUser *sql.Stmt + insertTag *sql.Stmt + getTag *sql.Stmt + getTags *sql.Stmt + updateTag *sql.Stmt + putTagOnFile *sql.Stmt + getTagsOnFile *sql.Stmt + deleteTagOnFile *sql.Stmt + updateFoldername *sql.Stmt + insertReview *sql.Stmt + getReviewsOnFile *sql.Stmt + getReview *sql.Stmt + updateReview *sql.Stmt + deleteReview *sql.Stmt + getReviewsByUser *sql.Stmt } func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) { @@ -482,6 +492,12 @@ func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) { return nil, err } + // init getRandomFilesWithTag + stmt.getRandomFilesWithTag, err = sqlConn.Prepare(getRandomFilesWithTagQuery) + if err != nil { + return nil, err + } + // init insertFeedback stmt.insertFeedback, err = sqlConn.Prepare(insertFeedbackQuery) if err != nil { diff --git a/web/src/component/GetRandomFiles.js b/web/src/component/GetRandomFiles.js index 2d38807..9f5eeae 100644 --- a/web/src/component/GetRandomFiles.js +++ b/web/src/component/GetRandomFiles.js @@ -4,8 +4,10 @@ import FilesTable from "./FilesTable"; function GetRandomFiles(props) { const [files, setFiles] = useState([]); const [isLoading, setIsLoading] = useState(false); + const [tags, setTags] = useState([]); + const [selectedTag, setSelectedTag] = useState(""); - function refresh(setFiles) { + function getRandomFiles() { setIsLoading(true); fetch("/api/v1/get_random_files") .then((response) => response.json()) @@ -20,15 +22,79 @@ function GetRandomFiles(props) { }); } + function getRandomFilesWithTag() { + setIsLoading(true); + fetch("/api/v1/get_random_files_with_tag", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + id: parseInt(selectedTag), + }), + }) + .then((response) => response.json()) + .then((data) => { + if (data.error) { + alert(data.error); + } else { + setFiles(data.files); + } + }) + .catch((error) => { + alert("get_random_files_with_tag error: " + error); + }) + .finally(() => { + setIsLoading(false); + }); + } + + function refresh() { + if (selectedTag === "") { + getRandomFiles(); + } else { + getRandomFilesWithTag(); + } + } + + function getTags() { + fetch("/api/v1/get_tags") + .then((response) => response.json()) + .then((data) => { + setTags(data.tags); + }) + .catch((error) => { + alert("get_tags error: " + error); + }); + } + useEffect(() => { - refresh(setFiles); + getTags(); }, []); + + useEffect(() => { + refresh(); + }, [selectedTag]); + return (
+