add a query arg to the List endpoint used to determine what page a child item is on
This commit is contained in:
parent
933670c63a
commit
6a5526ba3e
|
@ -2,6 +2,7 @@ package file
|
|||
|
||||
import (
|
||||
"crazyfs/api/helpers"
|
||||
"crazyfs/cacheitem"
|
||||
"crazyfs/config"
|
||||
"crazyfs/file"
|
||||
"crazyfs/responseitem"
|
||||
|
@ -10,6 +11,11 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
sortFolders = "folders"
|
||||
sortDefault = sortFolders
|
||||
)
|
||||
|
||||
func APIList(w http.ResponseWriter, r *http.Request) {
|
||||
if helpers.CheckInitialCrawl() {
|
||||
helpers.HandleRejectDuringInitialCrawl(w)
|
||||
|
@ -25,11 +31,11 @@ func APIList(w http.ResponseWriter, r *http.Request) {
|
|||
var err error
|
||||
|
||||
sortArg := r.URL.Query().Get("sort")
|
||||
var folderSorting string
|
||||
if sortArg == "default" || sortArg == "" {
|
||||
folderSorting = "default"
|
||||
} else if sortArg == "folders" {
|
||||
folderSorting = "folders"
|
||||
var sortType string
|
||||
if sortArg == sortDefault || sortArg == "" {
|
||||
sortType = sortDefault
|
||||
} else if sortArg == sortFolders {
|
||||
sortType = sortFolders
|
||||
} else {
|
||||
helpers.Return400Msg("folders arg must be 'default' (to not do any sorting) or 'first' (to sort the folders to the front of the list)", w)
|
||||
return
|
||||
|
@ -80,11 +86,6 @@ func APIList(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
// Create a copy of the cached Item, so we don't modify the Item in the cache
|
||||
item := responseitem.NewResponseItem(cacheItem)
|
||||
|
||||
response := map[string]interface{}{}
|
||||
|
||||
// Pagination
|
||||
var paginationLimit int
|
||||
if r.URL.Query().Get("limit") != "" {
|
||||
|
@ -102,17 +103,58 @@ func APIList(w http.ResponseWriter, r *http.Request) {
|
|||
paginationLimit = 100
|
||||
}
|
||||
|
||||
// Generate the listing.
|
||||
pageParam := r.URL.Query().Get("page")
|
||||
response := map[string]interface{}{}
|
||||
item, pages, responseError := generateListing(cacheItem, paginationLimit, sortType, pageParam)
|
||||
if responseError != "" {
|
||||
helpers.Return400Msg(responseError, w)
|
||||
return
|
||||
}
|
||||
|
||||
resolveItemName := r.URL.Query().Get("resolve")
|
||||
if resolveItemName != "" {
|
||||
var resolvedChild *responseitem.ResponseItem
|
||||
var resolvedChildPage int
|
||||
for i := range pages {
|
||||
for _, child := range pages[i] {
|
||||
if child.Name == resolveItemName {
|
||||
resolvedChild = child
|
||||
resolvedChildPage = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if resolvedChild != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if resolvedChild == nil {
|
||||
helpers.Return400Msg("failed to find item", w)
|
||||
return
|
||||
}
|
||||
item.Children = make([]*responseitem.ResponseItem, 1)
|
||||
item.Children[0] = resolvedChild
|
||||
response["resolved_page"] = resolvedChildPage
|
||||
}
|
||||
|
||||
if r.URL.Query().Get("page") != "" || resolveItemName != "" {
|
||||
response["total_pages"] = len(pages) + 1 // We add 1 to the count because arrays are zero-indexed.
|
||||
}
|
||||
|
||||
response["item"] = item
|
||||
helpers.WriteJsonResponse(response, true, w, r)
|
||||
}
|
||||
|
||||
func generateListing(cacheItem *cacheitem.Item, paginationLimit int, sortType string, pageParam string) (*responseitem.ResponseItem, [][]*responseitem.ResponseItem, string) {
|
||||
if sortType == "" {
|
||||
panic("sortType was an empty string")
|
||||
}
|
||||
|
||||
item := responseitem.NewResponseItem(cacheItem)
|
||||
totalItems := len(item.Children)
|
||||
totalPages := totalItems / paginationLimit
|
||||
if totalItems%paginationLimit != 0 {
|
||||
totalPages++
|
||||
}
|
||||
|
||||
if r.URL.Query().Get("page") != "" {
|
||||
response["total_pages"] = totalPages
|
||||
}
|
||||
|
||||
if folderSorting == "folders" {
|
||||
if sortType == sortFolders {
|
||||
var dirs, files []*responseitem.ResponseItem
|
||||
for _, child := range item.Children {
|
||||
if child.IsDir {
|
||||
|
@ -121,45 +163,43 @@ func APIList(w http.ResponseWriter, r *http.Request) {
|
|||
files = append(files, child)
|
||||
}
|
||||
}
|
||||
item.Children = make([]*responseitem.ResponseItem, len(item.Children))
|
||||
item.Children = append(dirs, files...)
|
||||
}
|
||||
|
||||
// Set the children to an empty array so that the JSON encoder doesn't return it as nil.
|
||||
var paginatedChildren []*responseitem.ResponseItem // this var will be either the full cacheitem list or a paginated list depending on the query args
|
||||
if item.Children != nil {
|
||||
paginatedChildren = item.Children
|
||||
} else {
|
||||
paginatedChildren = make([]*responseitem.ResponseItem, 0)
|
||||
}
|
||||
var pages [][]*responseitem.ResponseItem
|
||||
|
||||
pageParam := r.URL.Query().Get("page")
|
||||
var page int
|
||||
if pageParam != "" {
|
||||
page, err := strconv.Atoi(pageParam)
|
||||
if err != nil || page < 1 || page > totalPages {
|
||||
// Don't return an error, just truncate things
|
||||
page = totalPages
|
||||
pageInt, err := strconv.Atoi(pageParam)
|
||||
if err != nil || pageInt < 1 {
|
||||
return nil, nil, "invalid page number"
|
||||
}
|
||||
|
||||
start := (page - 1) * paginationLimit
|
||||
end := start + paginationLimit
|
||||
|
||||
if start >= 0 { // avoid segfaults
|
||||
if start > len(item.Children) {
|
||||
start = len(item.Children)
|
||||
}
|
||||
if end > len(item.Children) {
|
||||
end = len(item.Children)
|
||||
}
|
||||
paginatedChildren = paginatedChildren[start:end]
|
||||
if pageInt > totalPages {
|
||||
// Don't return an error, just set it to the max page number.
|
||||
pageInt = totalPages
|
||||
}
|
||||
pageInt--
|
||||
page = pageInt
|
||||
} else {
|
||||
page = 0
|
||||
}
|
||||
|
||||
for i := 0; i < len(item.Children); i += paginationLimit {
|
||||
end := i + paginationLimit
|
||||
if end > len(item.Children) {
|
||||
end = len(item.Children)
|
||||
}
|
||||
pages = append(pages, item.Children[i:end])
|
||||
}
|
||||
|
||||
paginatedChildren := pages[page]
|
||||
|
||||
// Erase the children of the children so we aren't displaying things recursively.
|
||||
for i := range paginatedChildren {
|
||||
paginatedChildren[i].Children = nil
|
||||
}
|
||||
|
||||
item.Children = paginatedChildren
|
||||
response["item"] = item
|
||||
helpers.WriteJsonResponse(response, true, w, r)
|
||||
return item, pages, ""
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue