interactions.lua 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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_name (string)
  40. -- Output: Displays a menu of org-specific commands to the user
  41. function modpol.interactions.org_dashboard(user, org_name)
  42. local org = modpol.orgs.get_org(org_name)
  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. table.insert(org_modules, v.slug)
  61. end
  62. -- list pending actions
  63. local process_msg = #org.processes .. " total actions"
  64. if org.pending[user] then
  65. process_msg = process_msg .. " (" .. #org.pending[user] .. " pending)"
  66. else
  67. process_msg = process_msg .. " (0 pending)"
  68. end
  69. -- set up output
  70. print("Org: " .. org_name)
  71. print("Parent: " .. parent)
  72. print("Members: " .. table.concat(org.members, ", "))
  73. print("Children: " .. table.concat(children, ", "))
  74. print("Modules: " .. table.concat(org_modules, ", "))
  75. print("Actions: " .. process_msg)
  76. print()
  77. print("Commands: (M)odules, (A)ctions")
  78. local sel = io.read()
  79. print()
  80. if sel == 'm' or sel == 'M' then
  81. print("Type module name: ")
  82. local module_sel = io.read()
  83. print()
  84. local module_result = false
  85. for k,v in ipairs(org_modules) do
  86. if v == module_sel then
  87. module_result = true
  88. end
  89. end
  90. if module_result then
  91. org:call_module(module_sel, user)
  92. else
  93. print("Error: Module not found.")
  94. end
  95. elseif sel == 'a' or sel == 'A' then
  96. local processes = {}
  97. print("All processes: (* indicates pending action)")
  98. for k,v in ipairs(org.processes) do
  99. local active = ''
  100. if org.pending[user] then
  101. if org.pending[user][v.id] then
  102. active = '*'
  103. end
  104. end
  105. end
  106. print()
  107. print("Interact with which one?")
  108. local to_interact = io.read()
  109. local process = org.processes[tonumber(to_interact)]
  110. if not process then return end
  111. if org:has_pending_actions(user) then
  112. if org.pending[user][process.id] then
  113. org:interact(process.id, user)
  114. end
  115. end
  116. else
  117. print("Command not found")
  118. modpol.interactions.org_dashboard(user, org_name)
  119. end
  120. end
  121. -- Function: modpol.interactions.policy_dashboard
  122. -- input: user (string), org_id (int), policy (string)
  123. -- if policy is nil, enables creating a new policy
  124. -- output: opens a dashboard for viewing/editing policy details
  125. -- TODO
  126. -- Function: modpol.interactions.message
  127. -- input: user (string), message (string)
  128. -- output: prints message to CLI
  129. function modpol.interactions.message(user, message)
  130. print(user .. ": " .. message)
  131. end
  132. -- Function: modpol.interactions.text_query
  133. -- input: User (string), Query (string), func (function)
  134. -- func input: user input (string)
  135. -- output: Applies "func" to user input
  136. function modpol.interactions.text_query(user, query, func)
  137. print(user .. ": " .. query)
  138. answer = io.read()
  139. func(answer)
  140. end
  141. -- Function: dropdown_query
  142. -- input: user (string), label (string), options (table of strings), func(choice) (function)
  143. -- func input: choice (string)
  144. -- output: calls func on choice
  145. function modpol.interactions.dropdown_query(user, label, options, func)
  146. -- set up options
  147. local options_display = ""
  148. local options_number = 0
  149. for k,v in ipairs(options) do
  150. options_display = options_display .. k .. ". " ..
  151. options[k] .. "\n"
  152. options_number = options_number + 1
  153. end
  154. options_display = options_display .. "Select number:"
  155. if options_number == 0 then
  156. print("Error: No options given for dropdown")
  157. return nil
  158. end
  159. -- begin displaying
  160. print(user .. ": " .. label)
  161. print(options_display)
  162. -- read input and produce output
  163. local answer
  164. answer = io.read()
  165. answer = tonumber(answer)
  166. if answer then
  167. if answer >= 1 and answer <= options_number then
  168. print("Selection: " .. options[answer])
  169. func(options[answer])
  170. else
  171. print("Error: Not in dropdown range")
  172. return nil
  173. end
  174. else
  175. print("Error: Must be a number")
  176. return nil
  177. end
  178. end
  179. -- Function: modpol.binary_poll_user(user, question)
  180. -- Params: user (string), question (string), func (function)
  181. -- func input: user input (string: y/n)
  182. -- Output: Applies "func" to user input
  183. function modpol.interactions.binary_poll_user(user, question, func)
  184. local query = "Poll for " .. user .. " (y/n): ".. question
  185. local answer
  186. repeat
  187. print(query)
  188. answer = io.read()
  189. until answer == "y" or answer == "n"
  190. if answer == "y" then
  191. modpol.interactions.message(user, "Response recorded")
  192. func("Yes")
  193. elseif answer == "n" then
  194. modpol.interactions.message(user, "Response recorded")
  195. func("No")
  196. else
  197. modpol.interactions.message(user, "Error: invalid response")
  198. end
  199. end
  200. -- COMPLEX INTERACTIONS
  201. -- ====================
  202. -- Function: modpol.interactions.message_org
  203. -- input: initiator (string), org (number or string), message (string)
  204. -- output: broadcasts message to all org members
  205. function modpol.interactions.message_org(initiator, org, message)
  206. local this_org = modpol.orgs.get_org(org)
  207. local users = this_org:list_members()
  208. for k,v in ipairs(users) do
  209. modpol.interactions.message(v, message)
  210. end
  211. end
  212. -- Function: modpol.interactions.binary_poll_org
  213. -- input: initator (user string), org_id (number)
  214. -- output: gets question from initiator, asks all org members, broadcasts answers