rework orgs. Add various properties to orgs. Make all org functions return success boolean as well as error/success string message.
This commit is contained in:
parent
4f53e801c4
commit
d646a4a8dd
50
modpol/DOCS/ledgers
Normal file
50
modpol/DOCS/ledgers
Normal file
@ -0,0 +1,50 @@
|
||||
Ledger
|
||||
**************************
|
||||
|
||||
a legder is a table of records that holds the history of an org, and of modpol itself.
|
||||
|
||||
its structure is a table of legder entries.
|
||||
|
||||
Every org has one, starting with the entry recording its creation.
|
||||
|
||||
Ledger Entry
|
||||
**************************
|
||||
a legder entry is a table with the following properties:
|
||||
|
||||
timestamp = nil,
|
||||
entrytype = nil,
|
||||
action_msg = '',
|
||||
|
||||
the timestamp will hold the output of os.time at the moment the entry was created.
|
||||
|
||||
the entrytype is optional; it can hold an identifier of the kind of entry it is (e.g. 'org_init', 'new_user', etc etc.)
|
||||
|
||||
action_msg is the record output itself.
|
||||
|
||||
|
||||
|
||||
Entrytypes
|
||||
**************************
|
||||
|
||||
These are the entrytypes that modpol uses. Each additional module should document whatever entrytypes it adds.
|
||||
|
||||
'org_init'
|
||||
type used when an org is created
|
||||
|
||||
'org_purge'
|
||||
type used when all orgs are purged. -- will only be found in the main modpol ledger.
|
||||
|
||||
'org_remove'
|
||||
type used when removing an individual org
|
||||
|
||||
'add_member'
|
||||
type used when adding a member to an org
|
||||
|
||||
'remove_member'
|
||||
type used when removing a member from an org
|
||||
|
||||
|
||||
|
||||
Old orgs
|
||||
**************************
|
||||
when an org is removed, its ledger is stored in modpol.old_legders = {} Note that multiple ledgers may exist here with the same org name.
|
137
modpol/DOCS/orgs
Normal file
137
modpol/DOCS/orgs
Normal file
@ -0,0 +1,137 @@
|
||||
== Dev note ===
|
||||
*note, see doc ledgers for info about org ledgers.
|
||||
they are *not* just a message in a table anymore... they have a timestamp and more.
|
||||
===============
|
||||
|
||||
|
||||
Orgs are stored in modpol.orgs by the key 'org_name'
|
||||
|
||||
Old ledgers of deleted orgs are stored in modpol.old_ledgers,
|
||||
if preserve records is enabled
|
||||
|
||||
An org is a table with the following properties:
|
||||
|
||||
{
|
||||
name = '', -- a unique name...
|
||||
this is a reference to the key used to store the org table. Changing this does not change the org name.
|
||||
policies = {}, -- a table to store the org's policies
|
||||
members = {}, -- a table that contains the member names
|
||||
or the org, in no particular order (TKTK: maybe change it so that members have a name:properties table?)
|
||||
ledger = {}, -- a table of ledger entries. See the ledger docs
|
||||
parent = nil, -- the name of the org that spawned this org.
|
||||
removing a parent org removes its children
|
||||
children = {}, -- a table of strings of org names of child orgs
|
||||
properties = { -- good for modules to store arbitrary info about the org here.
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
|
||||
API functions for orgs
|
||||
======================
|
||||
|
||||
a local variable setting 'preserve_records' determines whether
|
||||
to store old ledgers when an org is deleted. It is set to true.
|
||||
It would be possible to extend this to a settings file later.
|
||||
|
||||
--==oo888888888888888888888888888888oo==--
|
||||
Function: modpol.record(org_name, msg, type)
|
||||
-- Params: strings msg, org, type
|
||||
-- Outputs:
|
||||
-- "msg" specifies an event and/or status message.
|
||||
-- "org" specifies an "org" name.
|
||||
-- "type" -- optional type of legder entry. Could be e.g. 'election_result', 'add_member', etc
|
||||
|
||||
|
||||
-- This function adds the message to a global ledger and, if "org"
|
||||
-- specifies a valid "org", to an "org"-specific ledger. Both the mem-
|
||||
-- ory-resident and on-disk copies of the data structures used are up-
|
||||
-- dated.
|
||||
-- the type input is used to be able to search ledgers for specific events
|
||||
|
||||
--==oo888888888888888888888888888888oo==--
|
||||
|
||||
Function: modpol.add_org(org_name, members, parent, properties)
|
||||
-- Params: string name, table members, string parent, table properties
|
||||
-- Parent must be an existing org, defaults to 'instance', properties
|
||||
-- are arbitrary properties to initialize the org with
|
||||
|
||||
-- Output:
|
||||
-- This function creates an "org". It returns a boolean success indicator and
|
||||
-- either an error message starting with "Error:" or a success message.
|
||||
--
|
||||
--
|
||||
-- The string parameter specifies the "org" name.
|
||||
--
|
||||
-- The members table should be an integer-indexed array of member
|
||||
-- names.
|
||||
|
||||
-- parent should be nil or a valid existing org name. If nil, defaults to
|
||||
-- 'instance'
|
||||
|
||||
-- properties defaults to an empty table. Use it to initialize the org
|
||||
-- with arbitrary properties
|
||||
|
||||
--==oo888888888888888888888888888888oo==--
|
||||
|
||||
-- Function: modpol.remove_org(org_name, reason)
|
||||
-- Params: string name, opt string reason
|
||||
-- Output:
|
||||
--
|
||||
-- This function removes an "org". It returns a boolean
|
||||
-- success indicator and either an error message
|
||||
-- starting with "Error:" or a success message. It also recursively
|
||||
-- removes all child orgs, with 'remove parent org' as reason. If
|
||||
-- preserve_records is enabled, it logs the removal in the org ledger,
|
||||
-- and stores the ledger in modpol.old_legders
|
||||
--
|
||||
-- The string parameter specifies the "org" name.
|
||||
--
|
||||
-- The reason is an optional string to additionally include in the
|
||||
-- log as reason for removal
|
||||
|
||||
--==oo888888888888888888888888888888oo==--
|
||||
|
||||
Function: modpol.list_orgs()
|
||||
-- Params: None
|
||||
-- Output:
|
||||
-- This function returns a text-format list of "orgs". The list shows
|
||||
-- one "org" per line in the following format:
|
||||
-- org_name (member, member, ...)
|
||||
-- If there are no "orgs", the output is an empty string.
|
||||
|
||||
--==oo888888888888888888888888888888oo==--
|
||||
|
||||
|
||||
Function: modpol.reset_orgs()
|
||||
-- Params: None
|
||||
-- Removes all orgs and recreates blank org "instance" with all
|
||||
-- current users
|
||||
-- returns confirmation message
|
||||
-- if preserve_records is enabled, stores all org ledgers
|
||||
-- in modpol.old_ledgers
|
||||
|
||||
--==oo888888888888888888888888888888oo==--
|
||||
|
||||
Function: modpol.add_member(org_name, member)
|
||||
-- Params: org_name (string), member (string)
|
||||
-- Output:
|
||||
-- Adds the specified member to the specified org
|
||||
-- Returns a boolean success indicator and
|
||||
-- either a confirmation or error message
|
||||
|
||||
--==oo888888888888888888888888888888oo==--
|
||||
|
||||
Function: modpol.is_member
|
||||
-- Params: org (string), member (string)
|
||||
-- Output: boolean, or nil and error message if not applicable. (org nonexistent)
|
||||
|
||||
|
||||
--==oo888888888888888888888888888888oo==--
|
||||
|
||||
Function: modpol.remove_member
|
||||
-- Params: org (string), member (string)
|
||||
-- Output:
|
||||
-- Removes the specified member from the specified org
|
||||
-- Returns confirmation or error message
|
@ -1,30 +1,94 @@
|
||||
|
||||
-- ===================================================================
|
||||
-- /orgs.lua
|
||||
-- Org-related functions for Modular Politics
|
||||
-- Called by modpol/modpol/api.lua
|
||||
-- ===================================================================
|
||||
-- preserve records -- if true, will store org ledgers when they are closed, for later reference.
|
||||
local preserve_records = true
|
||||
modpol.default_org_policies = modpol.default_org_policies or {}
|
||||
|
||||
|
||||
-- initiate the table of orgs
|
||||
|
||||
modpol.orgs = {}
|
||||
if preserve_records then
|
||||
modpol.old_ledgers = {} -- a backup of all legders of all closed orgs.
|
||||
end
|
||||
|
||||
|
||||
--define the template of a ledger entry
|
||||
modpol.ledger_entry_temp = {
|
||||
timestamp = '',
|
||||
entrytype = nil,
|
||||
action_msg = '',
|
||||
org_name = nil,
|
||||
}
|
||||
|
||||
|
||||
-- define the basic template of an org.
|
||||
|
||||
modpol.org_temp = {
|
||||
name = nil,
|
||||
policies = {},
|
||||
members = {},
|
||||
ledger = {},
|
||||
parent = nil,
|
||||
children = {},
|
||||
properties = {},
|
||||
old_names = {},
|
||||
|
||||
}
|
||||
|
||||
-- ===================================================================
|
||||
-- Function: modpol.create_ledger_entry
|
||||
-- Params: strings action_msg, org_name, type
|
||||
-- Outputs:
|
||||
-- returns a ledger entry table, with a timestamp
|
||||
-- This function accepts a message and an optional org_name and type specification
|
||||
-- and returns a valid ledger entry table
|
||||
|
||||
modpol.create_ledger_entry = function(action_msg, org_name, entry_type)
|
||||
local entry = modpol.ledger_entry_temp
|
||||
if action_msg and type(action_msg) == 'string' then
|
||||
entry.action_msg = action_msg
|
||||
end
|
||||
if org_name and type(org_name) == 'string' and modpol.orgs [org_name] then
|
||||
entry.org_name = org_name
|
||||
end
|
||||
if entry_type and type(entry_type) == 'string' then
|
||||
entry.entrytype = entry_type
|
||||
end
|
||||
entry.timestamp = os.time()
|
||||
return entry
|
||||
end
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Function: modpol.record
|
||||
-- Params: strings msg, org
|
||||
-- Params: strings msg, org, type
|
||||
-- Outputs:
|
||||
-- "msg" specifies an event and/or status message.
|
||||
-- "org" specifies an "org" name.
|
||||
-- "type" -- optional type of legder entry. Could be e.g. 'election_result', 'add_member', etc
|
||||
-- This function adds the message to a global ledger and, if "org"
|
||||
-- specifies a valid "org", to an "org"-specific ledger. Both the mem-
|
||||
-- ory-resident and on-disk copies of the data structures used are up-
|
||||
-- dated.
|
||||
|
||||
modpol.record = function (org_name, msg)
|
||||
modpol.record = function (org_name, msg, type)
|
||||
|
||||
local entry = modpol.create_ledger_entry(msg,org_name,type)
|
||||
-- Record in global ledger
|
||||
table.insert (modpol.ledger, msg)
|
||||
table.insert (modpol.ledger, entry)
|
||||
-- Record in "org"-specific ledger
|
||||
if modpol.orgs [org_name] ~= nil then
|
||||
local org_ledger = modpol.orgs [org_name]["ledger"]
|
||||
if org_ledger == nil then
|
||||
modpol.orgs [org_name]["ledger"] = { msg }
|
||||
modpol.orgs [org_name]["ledger"] = { entry }
|
||||
else
|
||||
modpol.orgs [org_name]["ledger"] =
|
||||
table.insert (org_ledger, msg)
|
||||
table.insert (org_ledger, entry)
|
||||
end
|
||||
end
|
||||
|
||||
@ -33,39 +97,144 @@ end
|
||||
|
||||
-- ===================================================================
|
||||
-- Function: modpol.add_org
|
||||
-- Params: string name, table members
|
||||
-- Params: string name, table members, string parent, table properties
|
||||
|
||||
-- Output:
|
||||
--
|
||||
-- This function creates an "org". It returns either an error message
|
||||
-- starting with "-!-" or a success message.
|
||||
-- This function creates an "org". It returns a boolean success indicator and
|
||||
-- either an error message starting with "Error:" or a success message.
|
||||
--
|
||||
-- The string parameter specifies the "org" name.
|
||||
--
|
||||
-- The specified table should be an integer-indexed array of member
|
||||
-- The members table should be an integer-indexed array of member
|
||||
-- names.
|
||||
|
||||
modpol.add_org = function (org_name, members)
|
||||
-- parent should be nil or a valid existing org name. If nil, defaults to
|
||||
-- 'instance'
|
||||
|
||||
-- properties defaults to an empty table. Use it to initialize the org
|
||||
-- with arbitrary properties
|
||||
|
||||
modpol.add_org = function(org_name, members, parent, properties)
|
||||
local str
|
||||
|
||||
if modpol.ocutil.str_empty (org_name) then
|
||||
return "Error: Org needs a name"
|
||||
return false,"Error: Org needs a name"
|
||||
end
|
||||
|
||||
if parent and not modpol.orgs[parent] then
|
||||
return false,"Error: Parent must be a valid org"
|
||||
end
|
||||
|
||||
if properties and not type(properties) == 'table' then
|
||||
return false,"Error: Properties must be a table"
|
||||
end
|
||||
|
||||
modpol.ocutil.log ("Adding org " .. org_name)
|
||||
if modpol.orgs [org_name] ~= nil then
|
||||
str = "Error: Org " .. org_name .. " already exists"
|
||||
modpol.ocutil.log (str)
|
||||
return str
|
||||
return false,str
|
||||
end
|
||||
|
||||
local parent_org = parent or 'instance'
|
||||
local props = properties or {}
|
||||
|
||||
|
||||
-- actually add the org
|
||||
local org = modpol.org_temp
|
||||
local default_policies = modpol.default_org_policies or {}
|
||||
org.name = org_name -- do not change this without the proper api function. This is only a reference, not the only place this is recorded.
|
||||
org.members = members
|
||||
org.parent = parent_org
|
||||
org.properties = props
|
||||
org.policies = default_policies
|
||||
|
||||
modpol.orgs [org_name] = org
|
||||
|
||||
--record the child org in the parent's children table
|
||||
if modpol.orgs[parent_org].children then
|
||||
table.insert(modpol.orgs[parent_org].children, org_name)
|
||||
else
|
||||
modpol.orgs[parent].children = {org_name}
|
||||
end
|
||||
|
||||
modpol.orgs [org_name] = { members=members }
|
||||
local msg = "New org: " .. org_name ..
|
||||
" (" .. table.concat (members, ", ") .. ")"
|
||||
|
||||
modpol.record (org_name, msg)
|
||||
return msg
|
||||
modpol.record (org_name, msg, 'org_init')
|
||||
return true, msg
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Function: modpol.remove_org
|
||||
-- Params: string name, opt string reason
|
||||
-- Output:
|
||||
--
|
||||
-- This function removes an "org". It returns a boolean
|
||||
-- success indicator and either an error message
|
||||
-- starting with "Error:" or a success message. It also recursively
|
||||
-- removes all child orgs, with 'remove parent org' as reason. If
|
||||
-- preserve_records is enabled, it logs the removal in the org ledger,
|
||||
-- and stores the ledger in modpol.old_legders
|
||||
|
||||
|
||||
-- The string parameter specifies the "org" name.
|
||||
--
|
||||
-- The reason is an optional string to additionally include in the
|
||||
-- log as reason for removal
|
||||
|
||||
modpol.remove_org = function (org_name, reason)
|
||||
local str
|
||||
if not reason then reason = '' end
|
||||
if modpol.ocutil.str_empty (org_name) then
|
||||
return false,"Error: Specify an org name to remove"
|
||||
end
|
||||
|
||||
if org_name == 'instance' then
|
||||
return false,"Error: You cannot remove instance"
|
||||
end
|
||||
|
||||
modpol.ocutil.log ("Removing org " .. org_name)
|
||||
if modpol.orgs [org_name] == nil then
|
||||
str = "Error: Cannot remove non-existant org " .. org_name
|
||||
modpol.ocutil.log (str)
|
||||
return false,str
|
||||
end
|
||||
|
||||
--log msg
|
||||
local msg = 'Removing org '..org_name ..', reason: '.. reason
|
||||
|
||||
-- actually remove the org
|
||||
modpol.record (org_name, msg, 'org_remove')
|
||||
|
||||
-- TODO: if callbacks are implemented, do so here --
|
||||
if preserve_records then
|
||||
modpol.old_ledgers = modpol.orgs[org_name].ledger
|
||||
end
|
||||
|
||||
-- also remove all children
|
||||
if modpol.orgs[org_name].children and #modpol.orgs[org_name].children > 0 then
|
||||
for _,child_name in pairs(modpol.orgs[org_name].children) do
|
||||
modpol.remove_org(child_name, 'remove parent org') --this is recursion. If it gets to be a problem, we will need a separate function
|
||||
end
|
||||
end
|
||||
|
||||
modpol.orgs[org_name] = nil
|
||||
|
||||
|
||||
return true,msg
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Function: modpol.list_orgs
|
||||
-- Params: None
|
||||
@ -102,9 +271,17 @@ end
|
||||
|
||||
modpol.reset_orgs = function()
|
||||
local users = modpol.list_users()
|
||||
--store the ledgers in modpol.old_ledgers, and note that each org was closed in each record.
|
||||
if preserve_records then
|
||||
for name, org in pairs(modpol.orgs) do
|
||||
local old_ledger = org.ledger
|
||||
table.insert(old_ledger,modpol.create_ledger_entry('Removing org '.. name, name, 'org_purge'))
|
||||
table.insert(modpol.old_ledgers, org.ledger)
|
||||
end
|
||||
end
|
||||
modpol.orgs = {}
|
||||
local message = "Orgs purged"
|
||||
modpol.record(nil, message)
|
||||
modpol.record(nil, message, 'org_purge')
|
||||
modpol.add_org("instance", users)
|
||||
return message
|
||||
end
|
||||
@ -114,19 +291,25 @@ end
|
||||
-- Params: org (string), member (string)
|
||||
-- Output:
|
||||
-- Adds the specified member to the specified org
|
||||
-- Returns confirmation or error message
|
||||
-- Returns a boolean success indicator and
|
||||
-- either a confirmation or error message
|
||||
|
||||
modpol.add_member = function(org, member)
|
||||
if (modpol.orgs[org] == nil) then
|
||||
return "Error: No such org"
|
||||
|
||||
-- TODO, check that member is a user, if the org_name is not instance
|
||||
|
||||
modpol.add_member = function(org_name, member)
|
||||
if (modpol.orgs[org_name] == nil) then
|
||||
return false,"Error: No such org"
|
||||
elseif type(member) ~= 'string' then
|
||||
return false,"Error: member is wrong type"
|
||||
else
|
||||
if modpol.is_member(org,member) then
|
||||
return "Error: " .. member .. " is already a member of " .. org
|
||||
if modpol.is_member(org_name,member) then
|
||||
return false,"Error: " .. member .. " is already a member of " .. org_name
|
||||
else
|
||||
table.insert(modpol.orgs[org]["members"], member)
|
||||
local message = member .. " added to org " .. org
|
||||
modpol.record(message, org)
|
||||
return message
|
||||
table.insert(modpol.orgs[org_name]["members"], member)
|
||||
local message = member .. " added to org " .. org_name
|
||||
modpol.record(org_name, message, 'add_member')
|
||||
return true,message
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -165,22 +348,26 @@ end
|
||||
function modpol.remove_member(org, member)
|
||||
local message = "Error: No such org"
|
||||
if (modpol.orgs[org] == nil) then
|
||||
return nil, message
|
||||
return false, message
|
||||
else
|
||||
local member_table = modpol.orgs[org]["members"]
|
||||
if member_table then
|
||||
for index, value in pairs(member_table) do
|
||||
if value == member then
|
||||
-- match found, set to nil
|
||||
value = nil
|
||||
|
||||
modpol.orgs[org]["members"][value] = nil
|
||||
|
||||
-- TODO: add callbacks here --
|
||||
message = member .. " removed from org " .. org
|
||||
return message
|
||||
modpol.record(org_name, message, 'remove_member')
|
||||
return true, message
|
||||
end
|
||||
end
|
||||
end
|
||||
-- no match found (or org has no members)
|
||||
message = member .. " not found in org " .. org
|
||||
return nil, message
|
||||
return false, message
|
||||
end
|
||||
end
|
||||
|
||||
@ -189,6 +376,13 @@ end
|
||||
-- rename_org(old_name, new_name)
|
||||
-- Renames an org
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- POLICIES
|
||||
-- Each policy is a table with a string for a key. Contents:
|
||||
|
@ -16,8 +16,8 @@ regchat = minetest.register_chatcommand
|
||||
chat_table = {
|
||||
privs = {} ,
|
||||
func = function (user, param)
|
||||
local result = modpol.add_org (param, { user })
|
||||
return true, result
|
||||
local success, message = modpol.add_org (param, { user })
|
||||
return true, message
|
||||
end
|
||||
}
|
||||
regchat ("addorg" , chat_table)
|
||||
@ -59,7 +59,7 @@ minetest.register_chatcommand(
|
||||
"joinorg", {
|
||||
privs = {},
|
||||
func = function(user, param)
|
||||
local result = modpol.add_member(param, user)
|
||||
local success, result = modpol.add_member(param, user)
|
||||
return true, result
|
||||
end,
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user