Check-in by ben on 2024-10-05 22:44:03
Improve the display of user lists. Show item creator, title, etc
rather than the bare item id. Paginate list items. Add "back
link" to account that owns the list.
INSERTED DELETED
119 13 src/list/index.dcgi.m4
1 10 src/search/index.dcgi.m4
10 0 src/util.awk
130 23 TOTAL over 3 changed files
Index: src/list/index.dcgi.m4
==================================================================
--- src/list/index.dcgi.m4
+++ src/list/index.dcgi.m4
@@ -8,14 +8,27 @@
include(src/config.awk)
incl(src/api.awk)
incl(src/cgi.awk)
incl(src/util.awk)
-function main( acct, cmd, count, iaout, id, is_private, item_id,
- label, list_id, name, parts, url)
+function main( acct, client_url, cmd, count, creator, iaout, id,
+ is_private, items, label, list_id, name, name_slug, numfound,
+ page, pages, rows, query, title, type, url)
{
- count = split(search, parts, "/")
+ rows = 15
+ page = 1
+
+ # parse out page number
+ for (i in parts) {
+ if (parts[i] ~ /^rows[0-9][0-9]*$/) {
+ rows = substr(parts[i], 5)
+ } else if (parts[i] ~ /^page[0-9][0-9]*$/) {
+ page = substr(parts[i], 5)
+ }
+ }
+
+ split(search, parts, "/")
acct = parts[1]
list_id = parts[2]
print acct "'s Lists"
print ""
@@ -23,39 +36,131 @@
iaout = gettemp()
url = api_ssl_endpoint "/services/users/" acct "/lists/" list_id
api_request(url, "GET", iaout)
- # format list as a gopher directory (menu)
+ # fetch identifiers of list members
+
cmd = sprintf("%s <%s 2>&1", cmd_json2tsv, iaout)
FS = "\t"
- name = ""
- id = 0
+ id = ""
is_private = 0
- item_id = ""
+ name = ""
+ numfound = 0
+ query = ""
while ((cmd | getline) > 0) {
if ($1 == ".value.list_name" && $2 == "s") {
name = $3
- print "# List: " name
- id = 0
is_private = 0
} else if ($1 == ".value.is_private" && $2 == "b") {
if ($3 == "true") {
is_private = 1
}
} else if ($1 == ".value.members[].identifier" && $2 == "s") {
if (!is_private) {
- item_id = $3
- label = shorten_left(item_id, 60)
- printf "[1|%s|%s/details/%s|%s|%s]\n", label,
- cgipath, item_id, server, port
+ id = $3
+ numfound++
+ if (length(query) == 0) {
+ query = id
+ } else {
+ query = query "+OR+" id
+ }
+ }
+ }
+ }
+ close(cmd)
+ unlink(iaout)
+
+ # get metadata of list member items
+
+ name_slug = uri_encode(name)
+ gsub(/%20/, "-", name_slug)
+ client_url = api_ssl_endpoint "/details/" acct "/lists/" list_id \
+ "/" name_slug
+ url = api_ssl_endpoint "/services/search/beta/page_production/" \
+ "?user_query=identifier:(" query ")" \
+ "&hits_per_page=" rows \
+ "&page=" page \
+ "&aggregations=false" \
+ "&client_url=" client_url
+ api_request(url, "GET", iaout)
+
+ pages = int(numfound / rows)
+ if (numfound % rows != 0) {
+ pages++
+ }
+
+ # format as a gopher directory (menu)
+
+ printf "# List: %s, page %d of %d\n", name, page, pages
+ print ""
+
+ cmd = sprintf("%s <%s 2>&1", cmd_json2tsv, iaout)
+ FS = "\t"
+ count = 0
+ creator = ""
+ id = ""
+ title = ""
+ type = ""
+ while ((cmd | getline) > 0) {
+ if ($1 == ".response.body.hits.hits[].fields.creator[]" &&
+ $2 == "s" && length(creator) == 0)
+ {
+ creator = $3
+ } else if ($1 == ".response.body.hits.hits[].fields.identifier" &&
+ $2 == "s")
+ {
+ id = $3
+ } else if ($1 == ".response.body.hits.hits[].fields.mediatype" &&
+ $2 == "s")
+ {
+ type = $3
+ } else if ($1 == ".response.body.hits.hits[].fields.title" &&
+ $2 == "s")
+ {
+ title = $3
+ } else if ($1 == ".response.body.hits.hits[]._score" && $2 == "a") {
+ # the _score field happens to be toward the end of each item
+ if (length(title) > 0) {
+ if (length(creator) > 0) {
+ label = sprintf("[%s] %s by %s", mediatype[type], \
+ gph_encode(shorten(title, 40)), shorten(creator, 18))
+ } else {
+ label = sprintf("[%s] %s", mediatype[type], \
+ gph_encode(shorten(title, 58)))
+ }
+ printf "[1|%s|%s/details/%s|%s|%s]\n", label, cgipath, id,
+ server, port
+ count++
}
+ creator = ""
+ descr = ""
+ id = ""
+ type = ""
}
}
close(cmd)
+ # only show "page back" if the user is past page 1
+ if (page > 1) {
+ printf "[1|[<<] Page %d|%s/list/page%d/rows%d/%%09%s/%d|%s|%s]\n",
+ page - 1, cgipath, page - 1, rows,
+ acct, list_id, server, port
+ }
+
+ # only show "next page" if the current page is completely full
+ if (count == rows) {
+ printf "[1|[>>] Page %d|%s/list/page%d/rows%d/%%09%s/%d|%s|%s]\n",
+ page + 1, cgipath, page + 1, rows,
+ acct, list_id, server, port
+ }
+
+ print ""
+ printf "[1|Account %s|%s/account/%s|%s|%s]\n", acct, cgipath,
+ acct, server, port
+
print ""
printf "[1|PHAROS|%s|%s|%s]\n", cgipath, server, port
unlink(iaout)
exit 0
@@ -64,7 +169,8 @@
BEGIN {
config_init()
cgi_init()
uri_encode_init()
+ util_init()
main()
}
Index: src/search/index.dcgi.m4
==================================================================
--- src/search/index.dcgi.m4
+++ src/search/index.dcgi.m4
@@ -12,20 +12,10 @@
function main(search, cmd, count, creator, descr, field, fields, i, \
iaout, id, jsout, label, numfound, order, orders, page, rows, \
searchstr, title, type, url)
{
- mediatype["audio"] = "aud"
- mediatype["collection"] = "col"
- mediatype["data"] = "dat"
- mediatype["etree"] = "aud"
- mediatype["image"] = "img"
- mediatype["movies"] = "mov"
- mediatype["software"] = "bin"
- mediatype["texts"] = "txt"
- mediatype["web"] = "web"
-
rows = 15
page = 1
delete order
orders = 0
@@ -144,10 +134,11 @@
} else if ($1 == ".response.docs[].identifier" && $2 == "s") {
id = $3
} else if ($1 == ".response.docs[].mediatype" && $2 == "s") {
type = $3
} else if ($1 == ".response.docs[].title" && $2 == "s") {
+ # the title field happens to be toward the end of each item
title = $3
count++
if (length(creator) > 0) {
label = sprintf("[%s] %s by %s", mediatype[type], \
gph_encode(shorten(title, 40)), shorten(creator, 18))
Index: src/util.awk
==================================================================
--- src/util.awk
+++ src/util.awk
@@ -166,10 +166,20 @@
"Attribution-NonCommercial 4.0 International"
licenseurl["
https://creativecommons.org/licenses/by-nc-sa/4.0/"] = \
"Attribution-NonCommercial-ShareAlike 4.0 International"
licenseurl["
https://creativecommons.org/licenses/by-nc-nd/4.0/"] = \
"Attribution-NonCommercial-NoDerivs 4.0 International"
+
+ mediatype["audio"] = "aud"
+ mediatype["collection"] = "col"
+ mediatype["data"] = "dat"
+ mediatype["etree"] = "aud"
+ mediatype["image"] = "img"
+ mediatype["movies"] = "mov"
+ mediatype["software"] = "bin"
+ mediatype["texts"] = "txt"
+ mediatype["web"] = "web"
size_kb = 1024
size_mb = 1024 * 1024
size_gb = 1024 * 1024 * 1024
return