Преглед на файлове

Merge branch 'modules-as-actions' of https://gitlab.com/medlabboulder/modpol into modules-as-actions

Nathan Schneider преди 2 години
родител
ревизия
ddf4c72fc8

+ 2 - 0
modpol/api.lua

@@ -15,5 +15,7 @@ dofile (localdir .. "/interactions/interactions.lua")
 --modules
 dofile (localdir .. "/modules/join_org.lua")
 dofile (localdir .. "/modules/join_org_class.lua")
+dofile (localdir .. "/modules/join_org_consent.lua")
+dofile (localdir .. "/modules/consent.lua")
 dofile (localdir .. "/modules/remove_org.lua")
 dofile (localdir .. "/modules/child_org.lua")

+ 42 - 0
modpol/modules/consent.lua

@@ -0,0 +1,42 @@
+
+
+Consent = {}
+
+Consent.setup = {
+    name = "Consent",
+    slug = "consent",
+    desc = "Other modules can use to implement consent based decision making",
+    votes = 0
+}
+
+Consent.config = {
+    prompt = "Would you like to approve this action?",
+    votes_required = 1
+}
+
+function Consent:initiate(result)
+    self.result = result
+    for id, member in pairs(self.org.members) do
+        self.org:add_pending_action(self.id, member, "callback")
+    end
+end
+
+function Consent:callback(member)
+    modpol.interactions.binary_poll_user(
+        member,
+        self.config.prompt,
+        function (resp)
+            if resp == "Yes" then
+                self.votes = self.votes + 1
+            end
+            
+            if self.votes >= self.config.votes_required then
+                self.result()
+                self.org:wipe_pending_actions(self.id)
+            end
+        end
+    )
+end
+
+
+modpol.modules.consent = Consent

+ 5 - 17
modpol/modules/join_org_class.lua

@@ -2,22 +2,12 @@
 -- Module that enables a user to join an org
 
 JoinOrg = {}
-JoinOrg_mt = { __index = JoinOrg }
 
-
-function JoinOrg.create(initiator, org, id)
-    local inst = {
-        name = "Join an org",
-        desc = "Initiator chooses an org to become a member of. Nothing happens if they are already in an org.",
-        initiator = initiator,
-        org = org,
-        id = id,
-        votes_yes = 0
-    }
-    setmetatable(inst, JoinOrg_mt)
-    return inst
-
-end
+JoinOrg.setup = {
+    name = "Join an org",
+    desc = "Initiator chooses an org to become a member of. Nothing happens if they are already in an org.",
+    votes_yes = 0
+}
 
 function JoinOrg:initiate(result)
     modpol.interactions.binary_poll_user(
@@ -33,8 +23,6 @@ function JoinOrg:initiate(result)
         end
     )
 
-    
-
     if result then result() end
 
 end

+ 30 - 0
modpol/modules/join_org_consent.lua

@@ -0,0 +1,30 @@
+
+
+JoinOrg = {}
+
+JoinOrg.setup = {
+    name = "Join an org",
+    slug = "join_org_consent",
+    desc = "Consent based join org module"
+}
+
+function JoinOrg:initiate() 
+    self.org:call_module(
+        "consent", 
+        self.initiator, 
+        {
+            prompt = "Allow " .. self.initiator .. " to join?",
+            votes_required = 1
+        },
+        function () 
+            self:complete()
+        end
+    )
+end
+
+function JoinOrg:complete()
+    self.org:add_member(self.initiator)
+    print("Added " .. self.initiator .. " to the org!")
+end
+
+modpol.modules.join_org_consent = JoinOrg

+ 39 - 0
modpol/modules/template.lua

@@ -0,0 +1,39 @@
+--- Template for modules
+-- function initiate and table setup are required as a base.
+-- @module Template
+Template = {}
+
+--- (Required): setup table containing name and description of the module
+-- @field name "Module Human-Readable Name"
+-- @field slug "Template" same as module name
+-- @field desc "Description of the module"
+Template.setup = {
+    name = "Module Human-Readable Name",
+    slug = "Template",
+    desc = "Description of the module"
+}
+
+--- (Optional): config for module 
+-- Defines the input parameters to the module initiate function.
+-- When calling a module from within another module,
+-- variables not defined in config will be ignored.
+-- Default values set in config can be overridden
+-- @field field_1 ex: votes_required, default = 5
+-- @field field_2 ex: voting_type, default = "majority"
+Template.config = {
+    field_1 = 5
+    field_2 = "majority"
+}
+
+--- (Required): initiate function
+-- Modules have access to the following instance variables:
+-- <li><code>self.org</code> (the org the module was called in),</li>
+-- <li><code>self.initiator</code> (the user that callced the module),</li>
+-- <li><code>self.id</code> (the process id of the module instance)</li>
+-- @function initiate
+function Template:initiate(config, result) 
+    -- call interaction functions here!
+
+    -- call result function 
+    if result then result() end
+end

+ 28 - 5
modpol/orgs/process.lua

@@ -1,6 +1,6 @@
-function modpol.orgs:call_module(module_name, initiator) 
+function modpol.orgs:call_module(module_name, initiator, config, result) 
     if not modpol.modules[module_name] then
-        modpol.ocutil.log('Error in ' .. self.name .. ':call_module -> module "' .. name .. '" not found')
+        modpol.ocutil.log('Error in ' .. self.name .. ':call_module -> module "' .. module_name .. '" not found')
         return
     end
 
@@ -22,11 +22,34 @@ function modpol.orgs:call_module(module_name, initiator)
     end
 
     local module = modpol.modules[module_name]
-    local new_process = module.create(initiator, self, index)
 
-    self.processes[index] = new_process
+    -- sets default values for undeclared config variables
+    if module.config then
+        for k, v in pairs(module.config) do
+            if config[k] == nil then
+                config[k] = v
+            end
+        end
+    end
 
-    self.processes[index]:initiate()
+    -- setting default params
+    local new_process = {
+        metatable = {__index = module},
+        initiator = initiator,
+        org = self,
+        id = index,
+        config = config
+    }
+    
+    -- copying default fields from setup
+    for k, v in pairs(module.setup) do
+        new_process[k] = v
+    end
+
+    setmetatable(new_process, new_process.metatable)
+
+    self.processes[index] = new_process
+    self.processes[index]:initiate(result)
 
     return index
 end

+ 0 - 31
modpol/tests/nested_functions.lua

@@ -1,31 +0,0 @@
-dofile("../modpol.lua")
-
-print('\nRemoving existing orgs')
-modpol.orgs.reset()
-
-print('\nCreating an org called "test_org"')
-test_org = modpol.instance:add_org('test_org', 'luke')
-
-print('\nAdding user "nathan" to test_org')
-test_org:add_member('nathan')
-
-print("\nOkay, let's start with requests. Setting up an org...")
-modpol.instance:add_org('test_org', 'luke')
-test_org:add_member('nathan')
-
-print('\nMaking consent the add_member policy')
-test_org:set_policy("add_member", "consent", false);
-
-print('\nMaking a request to add Josh')
-add_josh = {
-    user = "josh",
-    type = "add_member",
-    params = {"josh"}
-}
-request_id = test_org:make_request(add_josh)
-
-
-print('\nHave the two members vote on it')
-modpol.interactions.org_dashboard("nathan","test_org")
-modpol.interactions.org_dashboard("luke","test_org")
-

+ 13 - 0
modpol/tests/nested_module_test.lua

@@ -0,0 +1,13 @@
+dofile('../modpol.lua');
+
+modpol.orgs.reset()
+
+test_org = modpol.instance:add_org('test_org', 'luke')
+test_org:add_member('nathan')
+
+print(table.concat(test_org:list_members(), ", "))
+
+test_org:call_module(
+    "join_org_consent",
+    "paul"
+)