interactions.lua 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. -- INTERACTIONS.LUA (CLI)
  2. -- User interaction functions for Modular Politics
  3. -- Called by modpol.lua
  4. modpol.interactions = {}
  5. -- DASHBOARDS
  6. -- ==========
  7. -- Function: modpol.interactions.dashboard(user)
  8. -- Params: user (string)
  9. -- Q: Should this return a menu of commands relevant to the specific user?
  10. -- Output: Displays a menu of commands to the user
  11. -- TKTK currently just prints all of modpol---needs major improvement
  12. function modpol.interactions.dashboard(user)
  13. -- adds user to root org if not already in it
  14. if not modpol.instance:has_member(user) then
  15. modpol.instance:add_member(user)
  16. end
  17. local all_users = modpol.instance:list_members()
  18. print('All orgs: (user orgs indicated by *)')
  19. for id, org in ipairs(modpol.orgs.array) do
  20. if type(org) == "table" then
  21. local indicator = ""
  22. if org:has_member(user) then indicator = "*" end
  23. print('['..id..'] '..indicator..org.name)
  24. end
  25. end
  26. print('All users: ' .. table.concat(all_users, ', '))
  27. print()
  28. print('Access which org id?')
  29. local sel = io.read()
  30. print()
  31. if modpol.orgs.array[tonumber(sel)] then
  32. local sel_org = modpol.orgs.array[tonumber(sel)].name
  33. modpol.interactions.org_dashboard(user, sel_org)
  34. else
  35. print("Org id not found.")
  36. end
  37. end
  38. -- Function: modpol.interactions.org_dashboard
  39. -- Params: user (string), org_string (string or id)
  40. -- Output: Displays a menu of org-specific commands to the user
  41. function modpol.interactions.org_dashboard(user, org_string)
  42. local org = modpol.orgs.get_org(org_string)
  43. if not org then return nil end
  44. -- identify parent
  45. local parent = ""
  46. if org.id == 1 then
  47. parent = "none"
  48. else
  49. parent = modpol.orgs.get_org(org.parent).name
  50. end
  51. -- identify children
  52. local children = {}
  53. for k,v in ipairs(org.children) do
  54. local this_child = modpol.orgs.get_org(v)
  55. table.insert(children, this_child.name)
  56. end
  57. -- list available modules
  58. local org_modules = {}
  59. for k,v in pairs(org.modules) do
  60. if not v.hide then
  61. table.insert(org_modules, v.slug)
  62. end
  63. end
  64. -- list pending
  65. local process_msg = #org.processes .. " total processes"
  66. if org.pending[user] then
  67. process_msg = process_msg .. " (" .. #org.pending[user] .. " pending)"
  68. else
  69. process_msg = process_msg .. " (0 pending)"
  70. end
  71. -- set up output
  72. print("Org: " .. org.name)
  73. print("Parent: " .. parent)
  74. print("Members: " .. table.concat(org.members, ", "))
  75. print("Children: " .. table.concat(children, ", "))
  76. print("Modules: " .. table.concat(org_modules, ", "))
  77. print("Pending: " .. process_msg)
  78. print()
  79. print("Commands: (M)odules, (P)ending")
  80. local sel = io.read()
  81. print()
  82. if sel == 'm' or sel == 'M' then
  83. print("Type module name: ")
  84. local module_sel = io.read()
  85. print()
  86. local module_result = false
  87. for k,v in ipairs(org_modules) do
  88. if v == module_sel then
  89. module_result = true
  90. end
  91. end
  92. if module_result then
  93. org:call_module(module_sel, user)
  94. else
  95. print("Error: Module not found.")
  96. end
  97. elseif sel == 'a' or sel == 'A' then
  98. local processes = {}
  99. print("All processes: (* indicates pending)")
  100. for k,v in ipairs(org.processes) do
  101. local active = ''
  102. if org.pending[user] then
  103. if org.pending[user][v.id] then
  104. active = '*'
  105. end
  106. end
  107. end
  108. print()
  109. print("Interact with which one?")
  110. local to_interact = io.read()
  111. local process = org.processes[tonumber(to_interact)]
  112. if not process then return end
  113. if org:has_pending_actions(user) then
  114. if org.pending[user][process.id] then
  115. org:interact(process.id, user)
  116. end
  117. end
  118. else
  119. print("Command not found")
  120. modpol.interactions.org_dashboard(user, org.name)
  121. end
  122. end
  123. -- Function: modpol.interactions.policy_dashboard
  124. -- input: user (string), org_id (int), policy (string)
  125. -- if policy is nil, enables creating a new policy
  126. -- output: opens a dashboard for viewing/editing policy details
  127. -- TODO
  128. -- Function: modpol.interactions.message
  129. -- input: user (string), message (string)
  130. -- output: prints message to CLI
  131. function modpol.interactions.message(user, message)
  132. print(user .. ": " .. message)
  133. end
  134. -- Function: modpol.interactions.text_query
  135. -- input: User (string), Query (string), func (function)
  136. -- func input: user input (string)
  137. -- output: Applies "func" to user input
  138. function modpol.interactions.text_query(user, query, func)
  139. print(user .. ": " .. query)
  140. answer = io.read()
  141. func(answer)
  142. end
  143. -- Function: dropdown_query
  144. -- input: user (string), label (string), options (table of strings), func(choice) (function)
  145. -- func input: choice (string)
  146. -- output: calls func on choice
  147. function modpol.interactions.dropdown_query(user, label, options, func)
  148. -- set up options
  149. local options_display = ""
  150. local options_number = 0
  151. for k,v in ipairs(options) do
  152. options_display = options_display .. k .. ". " ..
  153. options[k] .. "\n"
  154. options_number = options_number + 1
  155. end
  156. options_display = options_display .. "Select number:"
  157. if options_number == 0 then
  158. print("Error: No options given for dropdown")
  159. return nil
  160. end
  161. -- begin displaying
  162. print(user .. ": " .. label)
  163. print(options_display)
  164. -- read input and produce output
  165. local answer
  166. answer = io.read()
  167. answer = tonumber(answer)
  168. if answer then
  169. if answer >= 1 and answer <= options_number then
  170. print("Selection: " .. options[answer])
  171. func(options[answer])
  172. else
  173. print("Error: Not in dropdown range")
  174. return nil
  175. end
  176. else
  177. print("Error: Must be a number")
  178. return nil
  179. end
  180. end
  181. -- Function: modpol.binary_poll_user(user, question)
  182. -- Params: user (string), question (string), func (function)
  183. -- func input: user input (string: y/n)
  184. -- Output: Applies "func" to user input
  185. function modpol.interactions.binary_poll_user(user, question, func)
  186. local query = "Poll for " .. user .. " (y/n): ".. question
  187. local answer
  188. repeat
  189. print(query)
  190. answer = io.read()
  191. until answer == "y" or answer == "n"
  192. if answer == "y" then
  193. modpol.interactions.message(user, "Response recorded")
  194. func("Yes")
  195. elseif answer == "n" then
  196. modpol.interactions.message(user, "Response recorded")
  197. func("No")
  198. else
  199. modpol.interactions.message(user, "Error: invalid response")
  200. end
  201. end
  202. -- COMPLEX INTERACTIONS
  203. -- ====================
  204. -- Function: modpol.interactions.message_org
  205. -- input: initiator (string), org (number or string), message (string)
  206. -- output: broadcasts message to all org members
  207. function modpol.interactions.message_org(initiator, org, message)
  208. local this_org = modpol.orgs.get_org(org)
  209. local users = this_org:list_members()
  210. for k,v in ipairs(users) do
  211. modpol.interactions.message(v, message)
  212. end
  213. end
  214. -- Function: modpol.interactions.binary_poll_org
  215. -- input: initator (user string), org_id (number)
  216. -- output: gets question from initiator, asks all org members, broadcasts answers