Add: support select ramdom files by tag

This commit is contained in:
2021-12-13 07:07:43 +08:00
parent 7a10922ec4
commit d4718ac120
5 changed files with 178 additions and 47 deletions

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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 (?, ?, ?);`
@@ -260,6 +269,7 @@ type Stmt struct {
searchFolders *sql.Stmt
getFilesInFolder *sql.Stmt
getRandomFiles *sql.Stmt
getRandomFilesWithTag *sql.Stmt
insertFeedback *sql.Stmt
insertUser *sql.Stmt
countUser *sql.Stmt
@@ -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 {

View File

@@ -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 (
<div className="page">
<div className="search_toolbar">
<button className="refresh" onClick={() => refresh(setFiles)}>
{isLoading ? "Loading..." : "Refresh"}
</button>
<select
className="tag_select"
onChange={(event) => {
setSelectedTag(event.target.value);
}}
>
<option value="">All</option>
{tags.map((tag) => (
<option key={tag.id} value={tag.id}>
{tag.name}
</option>
))}
</select>
</div>
<FilesTable setPlayingFile={props.setPlayingFile} files={files} />
</div>