Browse Source

change orgs to use id numbers as their table key and function input param

MisterE123 3 years ago
parent
commit
419fc84822

+ 11 - 11
modpol/DOCS/orgs

@@ -4,7 +4,7 @@ they are *not* just a message in a table anymore... they have a timestamp and mo
 ===============
 
 
-Orgs are stored in modpol.orgs by the key 'org_name'
+Orgs are stored in modpol.orgs by the key 'org_id', a unique integer
 
 Old ledgers of deleted orgs are stored in modpol.old_ledgers, 
 if preserve records is enabled
@@ -36,8 +36,8 @@ 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
+Function: modpol.record(org_id, msg, type)
+-- Params: strings msg, type, org_id (number)
 -- Outputs:
 -- "msg" specifies an event and/or status message.
 -- "org" specifies an "org" name.
@@ -52,8 +52,8 @@ Function: modpol.record(org_name, msg, type)
 
 --==oo888888888888888888888888888888oo==--
 
-Function: modpol.add_org(org_name, members, parent, properties)
--- Params:   string name, table members, string parent, table properties
+Function: modpol.add_org(org_id, members, parent, properties)
+-- Params:   org)id (number), table members, string parent, table properties
 -- Parent must be an existing org, defaults to 'instance', properties 
 -- are arbitrary properties to initialize the org with
 
@@ -75,8 +75,8 @@ Function: modpol.add_org(org_name, members, parent, properties)
 
 --==oo888888888888888888888888888888oo==--
 
--- Function: modpol.remove_org(org_name, reason)
--- Params:   string name, opt string reason
+-- Function: modpol.remove_org(org_id, reason)
+-- Params:   org_id (number), opt string reason
 -- Output:
 --
 -- This function removes an "org".  It returns a boolean
@@ -114,8 +114,8 @@ Function: modpol.reset_orgs()
 
 --==oo888888888888888888888888888888oo==--
 
-Function: modpol.add_member(org_name, member)
--- Params: org_name (string), member (string)
+Function: modpol.add_member(org_id, member)
+-- Params: org_id (number), member (string)
 -- Output:
 -- Adds the specified member to the specified org
 -- Returns a boolean success indicator and
@@ -124,14 +124,14 @@ Function: modpol.add_member(org_name, member)
 --==oo888888888888888888888888888888oo==--
 
 Function: modpol.is_member
--- Params: org (string), member (string)
+-- Params: org (number), member (string)
 -- Output: boolean, or nil and error message if not applicable. (org nonexistent)
 
 
 --==oo888888888888888888888888888888oo==--
 
 Function: modpol.remove_member
--- Params: org (string), member (string)
+-- Params: org (number), member (string)
 -- Output:
 -- Removes the specified member from the specified org
 -- Returns confirmation or error message

+ 166 - 80
modpol/orgs/orgs.lua

@@ -6,29 +6,58 @@
 -- ===================================================================
 -- preserve records -- if true, will store org ledgers when they are closed, for later reference.
 local preserve_records = true
+
+-- policies assigned to any org can go here
 modpol.default_org_policies = modpol.default_org_policies or {}
 
 
--- initiate the table of orgs
 
-modpol.orgs = {} 
+-- initiate the table of orgs, if it doesnt already exist from storage!
+modpol.orgs = modpol.orgs or {} 
+
+
+
 if preserve_records then
-   modpol.old_ledgers = {} -- a backup of all legders of all closed orgs.
+   modpol.old_ledgers = modpol.old_ledgers or {} -- a backup of all legders of all closed orgs.
 end
 
 
+-- this counter will increment every time a new org is created, and the current value will be used as the org id
+-- we set it to 1 for init, and then run through all existing orgs and take only the greatest... which we then add 1 to.
+-- this ensures a unique id for each org.
+modpol.id_counter = 1
+if #modpol.orgs > 0 then
+   for id,org in pairs(modpol.orgs) do
+      if id > modpol.id_counter then
+         modpol.id_counter = id
+      end
+      
+   end
+   for id,ledg in pairs(modpol.old_ledgers) do
+      if id > modpol.id_counter then
+         modpol.id_counter = id
+      end
+   end
+   modpol.id_counter = modpol.id_counter +1
+end
+         
+
+
+
 --define the template of a ledger entry
 modpol.ledger_entry_temp = {
    timestamp = '',
    entrytype = nil,
    action_msg = '',
    org_name = nil,
+   org_id = nil,
 }
 
 
 -- define the basic template of an org.
 
 modpol.org_temp = {
+   id = nil,
    name = nil,
    policies = {},
    members = {},
@@ -42,19 +71,22 @@ modpol.org_temp = {
 
 -- ===================================================================
 -- Function: modpol.create_ledger_entry
--- Params: strings action_msg, org_name, type
+-- Params: strings: action_msg,  type, number: org_id
 -- Outputs:
 -- returns a ledger entry table, with a timestamp
--- This function accepts a message and an optional org_name and type specification
+-- This function accepts a message and an optional org_id and type specification
 -- and returns a valid ledger entry table
 
-modpol.create_ledger_entry = function(action_msg, org_name, entry_type)
+modpol.create_ledger_entry = function(action_msg, org_id, 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
+   if org_id and type(org_id) == 'number' and modpol.orgs [org_id] then
+      entry.org_id = org_id
+      if modpol.orgs[org_id].name then
+         entry.org_name = modpol.orgs[org_id].name
+      end
    end
    if entry_type and type(entry_type) == 'string' then
       entry.entrytype = entry_type
@@ -66,35 +98,54 @@ end
 
 -- ===================================================================
 -- Function: modpol.record
--- Params: strings msg, org, type
+-- Params: strings msg, type, number org_id
 -- Outputs:
 -- "msg" specifies an event and/or status message.
--- "org" specifies an "org" name.
+-- "org" specifies an "org" id.
 -- "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, type)
+modpol.record = function (org_id, msg, type)
 
-   local entry = modpol.create_ledger_entry(msg,org_name,type)
+   local entry = modpol.create_ledger_entry(msg, org_id, type)
                                 -- Record in global ledger
    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 modpol.orgs [org_id] ~= nil then
+        local org_ledger =  modpol.orgs [org_id]["ledger"]
         if    org_ledger == nil then
-            modpol.orgs [org_name]["ledger"] = { entry }
+            modpol.orgs [org_id]["ledger"] = { entry }
         else
-            modpol.orgs [org_name]["ledger"] =
-                table.insert (org_ledger, entry)
+            modpol.orgs [org_id]["ledger"] = table.insert (org_ledger, entry)
         end
     end
 
     modpol.store_data()         -- Copy data to disk
 end
 
+-- ===================================================================
+-- Function: modpol.get_org_id_by_name(org_name)
+-- Params:   org_name
+
+-- Output: an org id or nil
+--
+modpol.get_org_id_by_name = function(org_name)
+   local id = nil
+   for org_id,org in pairs(modpol.orgs) do
+      if org.name == org_name then
+         id = org_id
+      end
+   end
+   return id
+end
+
+
+
+
+
 -- ===================================================================
 -- Function: modpol.add_org
 -- Params:   string name, table members, string parent, table properties
@@ -115,54 +166,78 @@ end
 -- properties defaults to an empty table. Use it to initialize the org 
 -- with arbitrary properties
 
-modpol.add_org = function(org_name, members, parent, properties)
+modpol.add_org = function(org_name, members, parent_id, properties)
     local str
 
     if modpol.ocutil.str_empty (org_name) then
         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"
+    if parent_id and not modpol.orgs[parent_id] then 
+      return false,"Error: Parent_id must be a valid existing org id"
     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
+    modpol.ocutil.log ("Attempting to add new org " .. org_name)
+    
+    if modpol.get_org_id_by_name(org_name) ~= nil then
         str = "Error: Org " .. org_name .. " already exists"
         modpol.ocutil.log (str)
         return false,str
     end
 
-    local parent_org = parent or 'instance'
-    local props = properties or {}
+    local org_id = modpol.id_counter
+    modpol.id_counter = modpol.id_counter + 1
 
-   
-    -- 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}
+
+    -- the instance will have a parent of nil if it is the instance. 
+    -- otherwise, it will have a parent of instance's id if not otherwise defined
+    local parent_org_id = nil
+    
+
+    if parent_id and not(modpol.get_org_id_by_name('instance') == org_id) then
+      parent_org_id = parent_id
     end
 
-    local msg = "New org: " .. org_name ..
-        " (" .. table.concat (members, ", ") .. ")"
+    if not parent_id and not(modpol.get_org_id_by_name('instance') == org_id) then
+      parent_org_id = modpol.get_org_id_by_name('instance')
+   end
+
+
+
+   local props = properties or {}
+
+
+   -- actually add the org
+   local org = modpol.org_temp
+   local default_policies = modpol.default_org_policies or {}
+   org.id = org_id
+   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_id
+   org.properties = props
+   org.policies = default_policies
+
+   modpol.orgs [org_id] = org
+
+   --record the child org in the parent's children table
+   if parent_org_id then
+
+      if modpol.orgs[parent_org_id].children then
+         table.insert(modpol.orgs[parent_org_id].children, org_id)
+      else
+         modpol.orgs[parent_org_id].children = {org_id}
+      end
+   end
+
+   local msg = "New org: " .. org_name .. " ["..org_id.."], parent =  ".. dump(parent_org_id)..", members = "..
+      " (" .. table.concat (members, ", ") .. ")"
 
-   modpol.record (org_name, msg, 'org_init')
+   modpol.record (org_id, msg, 'org_init')
    return true, msg
 end
 
@@ -171,7 +246,7 @@ end
 
 -- ===================================================================
 -- Function: modpol.remove_org
--- Params:   string name, opt string reason
+-- Params:   number id, opt string reason
 -- Output:
 --
 -- This function removes an "org".  It returns a boolean
@@ -179,51 +254,58 @@ end
 -- 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
+-- and stores the ledger in modpol.old_ledgers
 
 
--- The string parameter specifies the "org" name.
+-- The number parameter specifies the "org" id.
 --
 -- The reason is an optional string to additionally include in the 
 -- log as reason for removal
 
-modpol.remove_org = function (org_name, reason)
+modpol.remove_org = function (org_id, 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"
+   if not type(org_id) == 'number' or not modpol.orgs[org_id] then
+      str = "Error: Specify an existing org id to remove"
+      modpol.ocutil.log (str)
+      return false,str
    end
-
+   local org_name = modpol.orgs[org_id]
    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
+   local msg = 'Removing org '..org_name ..' ['..org_id..'], reason: '.. reason
+
+   modpol.ocutil.log (msg)
 
+      
    -- 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
+      modpol.old_ledgers[org_id] = modpol.orgs[org_id].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
+   if modpol.orgs[org_id].children and #modpol.orgs[org_id].children > 0 then
+      for _,child_name in pairs(modpol.orgs[org_id].children) do
+         --this is recursion. If it gets to be a problem, we will need a separate function      
+         modpol.remove_org(child_name, 'remove parent org') 
       end
    end
 
-   modpol.orgs[org_name] = nil
+   --also remove references to this org in parent orgs
+   if modpol.orgs[org_id].parent then
+      local parent_id = modpol.orgs[org_id].parent
+      modpol.orgs[parent_id].children[org_id] = nil
+   end
+
+   modpol.orgs[org_id] = nil
+
+   modpol.record (org_id, msg, 'org_remove')
 
   
   return true,msg
@@ -247,10 +329,11 @@ end
 modpol.list_orgs  = function()
     local outbuf = ""
     local str
-    for org_name, org_data in pairs (modpol.orgs) do
+    for org_id, org_data in pairs (modpol.orgs) do
                                 -- Process next "org"
                                 -- Build string version of member list
         local memcat = org_data ["members"]
+        local org_name = org_data ["name"].."["..org_id.."]"
         if  modpol.ocutil.str_empty (memcat) then
               memcat = "(empty)"
         else
@@ -273,10 +356,10 @@ 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
+      for id, 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)
+         table.insert(old_ledger,modpol.create_ledger_entry('Removing org '.. id, id, 'org_purge'))
+         modpol.old_ledgers[id] = old_ledger
       end
    end
    modpol.orgs = {}
@@ -288,7 +371,7 @@ end
 
 -- ===================================================================
 -- Function: modpol.add_member
--- Params: org (string), member (string)
+-- Params: org_id (number), member (string)
 -- Output:
 -- Adds the specified member to the specified org
 -- Returns a boolean success indicator and
@@ -297,18 +380,20 @@ end
 
 -- 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
+modpol.add_member = function(org_id, member)
+   
+   if (modpol.orgs[org_id] == 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_name,member) then
+      local org_name = modpol.orgs [org_id].name
+      if modpol.is_member(org_id,member) then
          return false,"Error: " .. member .. " is already a member of " .. org_name
       else
-         table.insert(modpol.orgs[org_name]["members"], member)
-         local message = member .. " added to org " .. org_name
-         modpol.record(org_name, message, 'add_member')
+         table.insert(modpol.orgs[org_id]["members"], member)
+         local message = member .. " added to org " .. org_name .. " ["..org_id.."]"
+         modpol.record(org_id, message, 'add_member')
          return true,message
       end
    end
@@ -316,7 +401,7 @@ end
 
 -- ===================================================================
 -- Function: modpol.is_member
--- Params: org (string), member (string)
+-- Params: org (number), member (string)
 -- Output: Boolean depending on membership or nil/error message
 
 modpol.is_member = function(org, member)
@@ -340,7 +425,7 @@ end
 
 -- ===================================================================
 -- Function: modpol.remove_member
--- Params: org (string), member (string)
+-- Params: org (number), member (string)
 -- Output:
 -- Removes the specified member from the specified org
 -- Returns confirmation or error message
@@ -358,9 +443,10 @@ function modpol.remove_member(org, member)
                
                modpol.orgs[org]["members"][value] = nil  
                
-               -- TODO: add callbacks here --
+               -- TODO: add callbacks here, for such as revoking privs, etc --
+
                message = member .. " removed from org " .. org
-               modpol.record(org_name, message, 'remove_member')
+               modpol.record(org, message, 'remove_member')
                return true, message
             end
          end

+ 44 - 2
modpol/storage/storage-local.lua

@@ -9,6 +9,7 @@
 modpol.datadir     = modpol.topdir  .. "/data"
 modpol.file_ledger = modpol.datadir .. "/ledger.dat"
 modpol.file_orgs   = modpol.datadir .. "/orgs.dat"
+modpol.file_old_ledgers   = modpol.datadir .. "/old_ledgers.dat"
 
 os.execute ("mkdir -p " .. modpol.datadir)
 
@@ -43,8 +44,7 @@ end
 
 local store_orgs = function()
     local ok =  modpol.ocutil.file_write (modpol.file_orgs,
-modpol.serpent.dump (modpol.orgs))
-
+    modpol.serpent.dump (modpol.orgs))
     if    ok ~= true then
         modpol.ocutil.fatal_error ("store_data: orgs")
     end
@@ -55,12 +55,32 @@ modpol.serpent.dump (modpol.orgs))
     modpol.ocutil.log (nn .. " orgs stored to disk")
 end
 
+-- ===================================================================
+-- This function stores "old_ledgers" data to disk.
+
+local store_old_ledgers = function()
+
+    local ok =  modpol.ocutil.file_write (modpol.file_old_ledgers,
+    modpol.serpent.dump (modpol.old_ledgers))
+
+
+    if    ok ~= true then
+        modpol.ocutil.fatal_error ("store_data: orgs")
+    end
+
+    local nn  = modpol.ocutil.table_length (modpol.old_ledgers)
+    local str = "entries"
+    if nn == 1 then str = "entry" end
+    modpol.ocutil.log (nn .. " orgs stored to disk")
+end
+
 -- ===================================================================
 -- This function stores data to disk.
 
 modpol.store_data = function()
     store_ledger()
     store_orgs()
+    store_old_ledgers()
 end
 
 -- ===================================================================
@@ -105,12 +125,34 @@ local load_orgs   = function()
     end
 end
 
+-- ===================================================================
+-- This function loads "old_ledgers" data from disk.
+
+local load_old_ledgers   = function()
+    local obj =  modpol.ocutil.file_read (modpol.file_old_ledgers )
+    if    obj ~= nil then
+        local func, err = load (obj)
+        if err then
+            modpol.ocutil.fatal_error ("load_data: orgs"   )
+        end
+        modpol.orgs = func()
+
+        local nn  = modpol.ocutil.table_length (modpol.file_old_ledgers)
+        local str = "entries"
+        if nn == 1 then str = "entry" end
+        modpol.ocutil.log (nn .. " orgs loaded from disk")
+    else
+        modpol.ocutil.log ("No stored old ledgers data found")
+    end
+end
+
 -- ===================================================================
 -- This function loads stored data from disk.
 
 modpol.load_storage = function()
     load_ledger()
     load_orgs()
+    load_old_ledgers()
 end
 
 -- ===================================================================

+ 2 - 1
modpol_minetest/chatcommands/chatcommands.lua

@@ -59,7 +59,8 @@ minetest.register_chatcommand(
    "joinorg", {
       privs = {},
       func = function(user, param)
-         local success, result = modpol.add_member(param, user)
+         local org_id = modpol.get_org_id_by_name(param)
+         local success, result = modpol.add_member(org_id, user)
          return true, result
       end,
 })

+ 7 - 1
modpol_minetest/storage/storage-mod_storage.lua

@@ -18,11 +18,16 @@ modpol.load_storage = function()
    if (stored_orgs ~= nil) then
       modpol.orgs = stored_orgs
    end
-   -- load orgs
+   -- load ledger
    local stored_ledger = minetest.deserialize(mod_storage:get_string("ledger"))
    if (stored_ledger ~= nil) then
       modpol.ledger = stored_ledger
    end
+   -- load old_ledgers
+   local old_stored_ledgers = minetest.deserialize(mod_storage:get_string("old_ledgers"))
+   if (stored_ledger ~= nil) then
+      modpol.old_ledgers = old_stored_ledgers
+   end
 end
 
 -- Stores content of current orgs and ledger to mod_storage
@@ -31,4 +36,5 @@ modpol.store_data = function()
    -- write to storage
    mod_storage:set_string("orgs", minetest.serialize(modpol.orgs))
    mod_storage:set_string("ledger", minetest.serialize(modpol.ledger))
+   mod_storage:set_string("old_ledgers", minetest.serialize(modpol.old_ledgers))
 end