pkar.lua 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #!/usr/bin/lua
  2. local cli = require "cli"
  3. local json = require "cjson"
  4. local plpath = require "pl.path"
  5. local nsm = require "volksdata.namespace"
  6. local term = require "volksdata.term"
  7. local triple = require "volksdata.triple"
  8. local graph = require "volksdata.graph"
  9. local pkar = require "pocket_archive"
  10. local cmdoc = require "pocket_archive.cmdoc"
  11. local model = require "pocket_archive.model"
  12. local pres = require "pocket_archive.presentation"
  13. local repo = require "pocket_archive.repo"
  14. local sub = require "pocket_archive.submission"
  15. cli.locale "en_US" -- TODO set with multilingual support.
  16. io.output(io.stdout)
  17. init = cli.command {
  18. "Initialize a new Pocket Archive store.",
  19. function(args)
  20. io.write("WARNING! This will WIPE all your archive and web data!\n")
  21. io.write("Enter 'yes' if you know what you are doing: ")
  22. local a = io.read()
  23. if a == "yes" then
  24. io.write("Alright, you asked for it.\n")
  25. repo.reset_store()
  26. sub.reset_ores()
  27. pres.reset_site()
  28. else io.write("Chicken out.\n")
  29. end
  30. end
  31. }
  32. list = cli.command {
  33. "List all resource IDs.",
  34. function()
  35. for s in repo.gr:unique_terms(triple.POS_S):iter() do
  36. print(nsm.denormalize_uri(s.data))
  37. end
  38. end,
  39. }
  40. deposit = cli.command {
  41. "Deposit a package.",
  42. cli.positional "path" { "Path of the laundry list file." },
  43. cli.flag "c,cleanup" {
  44. "Remove laundry list and SIP after successful submission.",
  45. type = cli.boolean,
  46. },
  47. function(args)
  48. sub.deposit(args.path, args.cleanup)
  49. end
  50. }
  51. remove = cli.command {
  52. "Remove a list of resources.",
  53. cli.positional "path" {
  54. "Path of the delete list file or input stream. It must contain \z
  55. one ID per line, in the short URI format (`par:<ID>'). If not \z
  56. provided or `-', it is set to standard input.",
  57. type = cli.string,
  58. default = "-",
  59. },
  60. cli.flag "m,members" {
  61. "Remove the resource members recursively.",
  62. type = cli.boolean,
  63. default = false,
  64. },
  65. function(args)
  66. if args.path == "-" then args.path = nil end
  67. local ct = 0
  68. for id in io.lines(args.path) do
  69. if #id > 0 then -- skip blank lines.
  70. io.write("Deleting: " .. id .. "\n")
  71. local del_ids = repo.remove(id, args.members)
  72. for _ in pairs(del_ids) do ct = ct + 1 end
  73. end
  74. end
  75. io.write("Deleted " .. ct .. " resources.\n")
  76. end
  77. }
  78. gen_site = cli.command {
  79. "Generate a static site from the archive.",
  80. function(args) pres.generate_site() end
  81. }
  82. dump_res = cli.command {
  83. "Generate an RDF representation of a resource.",
  84. cli.positional "id" {
  85. "ID of the resource, prefixed by `par:`",
  86. type = cli.string,
  87. },
  88. cli.flag "f,format" {
  89. "RDF format. `nt` and `ttl` are available.",
  90. type = cli.string,
  91. default = "ttl",
  92. },
  93. cli.flag "o,output" {
  94. "Output file. If not specified, output to stdout.",
  95. type = cli.string,
  96. default = io.stdout,
  97. },
  98. function(args)
  99. local s = term.new_iriref_ns(args.id)
  100. io.output(args.output)
  101. for chunk in repo.serialize_rsrc(s, args.format) do
  102. io.write(chunk)
  103. end
  104. io.close() -- This will fail for io.stdout, but it's OK.
  105. if args.output ~= io.stdout then
  106. print("File written to ", args.output)
  107. end
  108. end,
  109. }
  110. dump_ll = cli.command {
  111. "Generate a laundry list for a stored resource or a whole submission.",
  112. cli.positional "id" {
  113. "ID of the resource, prefixed by `par:`",
  114. type = cli.string,
  115. },
  116. cli.flag "o,output" {
  117. "Output file. If not specified, output to stdout.",
  118. type = cli.string,
  119. default = io.stdout,
  120. },
  121. function(args)
  122. local s = term.new_iriref_ns(args.id)
  123. io.output(args.output)
  124. if args.id:find("^sub:") then
  125. -- Dump whole submission.
  126. --[[
  127. local co = coroutine.create(pres.generate_sub_ll)
  128. while true do
  129. local r, res = coroutine.resume(co, s)
  130. if not r then break end
  131. if res then io.write(res) end
  132. end
  133. --]]
  134. io.write(pres.generate_sub_ll(s))
  135. else
  136. -- One resource only.
  137. io.write(pres.generate_res_ll(s))
  138. end
  139. io.close() -- This will fail for io.stdout, but it's OK.
  140. if args.output ~= io.stdout then
  141. print("File written to ", args.output)
  142. end
  143. end
  144. }
  145. dump_archive = cli.command {
  146. "Generate a RDF representation of the full archive.",
  147. cli.positional "path" {
  148. "Destination file path.",
  149. type = cli.string,
  150. },
  151. cli.flag "f,format" {
  152. "RDF serialization format. One of `ttl` [default], `nt`.",
  153. type = cli.string,
  154. default = "ttl",
  155. },
  156. function(args)
  157. repo.dump(args.path, args.format)
  158. print ("File written to ", args.path)
  159. end,
  160. }
  161. list_ctypes = cli.command {
  162. "List all content types.",
  163. function(args)
  164. for tname in pairs(model.types) do
  165. io.write(tname)
  166. io.write("\n")
  167. end
  168. end,
  169. }
  170. dump_schema = cli.command {
  171. "Generate a structured representation ofa content type schema as JSON.",
  172. cli.positional "ctype" {
  173. "Content type name.",
  174. type = cli.string,
  175. },
  176. function(args)
  177. local schema = model.types[args.ctype]
  178. if not schema then
  179. print("No such content type: ", ctype)
  180. return 1
  181. end
  182. io.write(json.encode(schema))
  183. io.write("\n")
  184. end,
  185. }
  186. gen_cmdoc = cli.command {
  187. "Generate a static website with content model documentation.",
  188. function(args)
  189. cmdoc.generate_doc()
  190. io.write("Documentation generated at " .. cmdoc.out_dir .. "\n")
  191. end,
  192. }
  193. cli.program {
  194. "Pocket Archive command line interface.",
  195. }