changeset 7543:fc9daba984c0

- issue2551103 - add pragma 'display_protected' to roundup-admin. If setting is true, print protected attributes like id, activity, actor... when using display or specification subcommands.
author John Rouillard <rouilj@ieee.org>
date Thu, 13 Jul 2023 23:47:43 -0400
parents 3b67f0e7fe48
children 4c90a57c89e3
files CHANGES.txt roundup/admin.py test/test_admin.py
diffstat 3 files changed, 84 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES.txt	Thu Jul 13 20:16:44 2023 -0400
+++ b/CHANGES.txt	Thu Jul 13 23:47:43 2023 -0400
@@ -12,6 +12,16 @@
 Roundup 2.0 supports Python 3.4 and later. Roundup 2.1.0 supports
 python 3.6 or newer (3.4/3.5 might work, but they are not tested).
 
+2024-XX-YY 2.4.0
+
+Fixed:
+
+Features:
+
+- issue2551103 - add pragma 'display_protected' to roundup-admin. If
+  true, print protected attributes like id, activity, actor...
+  when using display or specification subcommands. (John Rouillard)
+
 2023-07-13 2.3.0
 
 Fixed:
--- a/roundup/admin.py	Thu Jul 13 20:16:44 2023 -0400
+++ b/roundup/admin.py	Thu Jul 13 23:47:43 2023 -0400
@@ -114,7 +114,8 @@
         }
         self.settings_help = {
             'display_protected':
-            _("Have 'display designator' show protected fields: creator. NYI"),
+            _("Have 'display designator' show protected fields: "
+              "creator, id etc."),
 
             'indexer_backend':
             _("Set indexer to use when running 'reindex' NYI"),
@@ -522,10 +523,18 @@
             cl = self.get_class(classname)
 
             # display the values
-            keys = sorted(cl.properties)
+            normal_props = sorted(cl.properties)
+            if self.settings['display_protected']:
+                keys = sorted(cl.getprops())
+            else:
+                keys = normal_props
+
             for key in keys:
                 value = cl.get(nodeid, key)
-                print(_('%(key)s: %(value)s') % locals())
+                # prepend * for protected propeties else just indent
+                # with space.
+                protected = "*" if key not in normal_props else ' '
+                print(_('%(protected)s%(key)s: %(value)s') % locals())
 
     def do_export(self, args, export_files=True):
         ''"""Usage: export [[-]class[,class]] export_dir
@@ -1479,6 +1488,19 @@
          will show all settings and their current values. If verbose
          is enabled hidden settings and descriptions will be shown.
         """
+        """
+          The following are to be implemented:
+
+           indexer - Not Implemented - set indexer to use for
+                     reindex.  Use when changing indexer backends.
+
+           exportfiles={true|false} - Not Implemented - If true
+                    (default) export/import db tables and files. If
+                    False, export/import just database tables, not
+                    files. Use for faster database migration.
+                    Replaces exporttables/importtables with
+                    exportfiles=false then export/import
+        """
 
         if len(args) < 1:
             raise UsageError(_('Not enough arguments supplied'))
@@ -1798,8 +1820,12 @@
 
         # get the key property
         keyprop = cl.getkey()
-        for key in cl.properties:
-            value = cl.properties[key]
+        if self.settings['display_protected']:
+            properties = cl.getprops()
+        else:
+            properties = cl.properties
+        for key in properties:
+            value = properties[key]
             if keyprop == key:
                 sys.stdout.write(_('%(key)s: %(value)s (key property)\n') %
                                  locals())
--- a/test/test_admin.py	Thu Jul 13 20:16:44 2023 -0400
+++ b/test/test_admin.py	Thu Jul 13 23:47:43 2023 -0400
@@ -1032,6 +1032,26 @@
         expected = 'Error: Internal error: pragma can not handle values of type: float'
         self.assertIn(expected, out)
 
+
+        # -----
+        inputs = iter(["pragma display_protected=yes",
+                       "display user1",
+                       "quit"])
+        AdminTool.my_input = lambda _self, _prompt: next(inputs)
+
+        self.install_init()
+        self.admin=AdminTool()
+        sys.argv=['main', '-i', self.dirname]
+
+        with captured_output() as (out, err):
+            ret = self.admin.main()
+
+        out = out.getvalue().strip()
+        
+        print(ret)
+        expected = '\n*creation: '
+        self.assertIn(expected, out)
+
         # -----
         AdminTool.my_input = orig_input
 
@@ -1479,6 +1499,7 @@
                 'timezone: <roundup.hyperdb.String>',
                 'password: <roundup.hyperdb.Password>',
             ]
+
             
         with captured_output() as (out, err):
             sys.argv=['main', '-i', self.dirname, 'specification', 'user']
@@ -1488,6 +1509,28 @@
         print(outlist)
         self.assertEqual(sorted(outlist), sorted(spec))
 
+        # -----
+        inputs = iter(["pragma display_protected=1", "spec user", "quit"])
+        AdminTool.my_input = lambda _self, _prompt: next(inputs)
+
+        self.install_init()
+        self.admin=AdminTool()
+        sys.argv=['main', '-i', self.dirname]
+
+        with captured_output() as (out, err):
+            ret = self.admin.main()
+
+        # strip greeting and help text lines
+        outlist = out.getvalue().strip().split('\n')[2:]
+        
+        protected = [ 'id: <roundup.hyperdb.String>',
+                      'creation: <roundup.hyperdb.Date>',
+                      'activity: <roundup.hyperdb.Date>',
+                      'creator: <roundup.hyperdb.Link to "user">',
+                      'actor: <roundup.hyperdb.Link to "user">']
+        print(outlist)
+        self.assertEqual(sorted(outlist), sorted(spec + protected))
+
     def testRetireRestore(self):
         ''' Note the tests will fail if you run this under pdb.
             the context managers capture the pdb prompts and this screws

Roundup Issue Tracker: http://roundup-tracker.org/