XZise has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/247482

Change subject: [FEAT] cache: Separate commands
......................................................................

[FEAT] cache: Separate commands

Instead of having everything in one command and to play with `and` to only
execute part of the command, this is providing three separate commands to
filter for entries, output something depending on them and to do an action
afterwards.

The filter command only needs to return a boolean for an entry. The output
command can either return None to suppress the default output, similar to
before. If it returns anything else it'll print that result. And at the moment
only the delete action is supported and that as an option and not using code
like the other two.

Additionally it supports to only define a function name and it'll call it
automatically with the entry as the first positional parameter.

It adds two utility output functions to easier see what each cache entry is
actually doing.

Change-Id: I7b8fc283555a6d35719e47d28ff1becfbd07baf7
---
M scripts/maintenance/cache.py
1 file changed, 97 insertions(+), 24 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/pywikibot/core 
refs/changes/82/247482/1

diff --git a/scripts/maintenance/cache.py b/scripts/maintenance/cache.py
index 8aa15b0..14188a1 100755
--- a/scripts/maintenance/cache.py
+++ b/scripts/maintenance/cache.py
@@ -5,29 +5,43 @@
 
 Syntax:
 
-    python pwb.py cache [-password] [-delete] [-c "..."] [dir ...]
+    python pwb.py cache [-password] [-delete] [-c "..."] [-o "..."] [dir ...]
 
 If no directory are specified, it will detect the API caches.
 
 If no command is specified, it will print the filename of all entries.
 If only -delete is specified, it will delete all entries.
 
-The option '-c' must be followed by a command in python syntax.
+-delete           Delete each command filtered. If that option is set the
+                  default output will be nothing.
+
+-c                Filter command in python syntax. It must evaulate to True to
+                  output anything.
+
+-o                Output command which is output when the filter evaluated to
+                  True. If it returns None it won't output anything.
 
 Example commands:
   Print the filename of any entry with 'wikidata' in the key:
 
-    entry if "wikidata" in entry._uniquedescriptionstr() else None
+    -c "wikidata" in entry._uniquedescriptionstr()
 
   Customised output if the site code is 'ar':
 
-    entry.site.code == "ar" and print("%s" % entry._uniquedescriptionstr())
+    -c entry.site.code == "ar"
+    -o uniquedesc(entry)
 
   Or the state of the login
-    entry.site._loginstatus == LoginStatus.NOT_ATTEMPTED and \
-print("%s" % entry._uniquedescriptionstr())
 
-  These functions can be used as a command:
+    -c entry.site._loginstatus == LoginStatus.NOT_ATTEMPTED
+    -o uniquedesc(entry)
+
+  If the function only uses one parameter for the entry it can be omitted:
+
+    -c has_password
+    -o uniquedesc
+
+Available filter commands:
     has_password(entry)
     is_logout(entry)
     empty_response(entry)
@@ -39,9 +53,13 @@
   There are helper functions which can be part of a command:
     older_than(entry, interval)
     newer_than(entry, interval)
+
+Available output commands:
+
+    uniquedesc(entry)
 """
 #
-# (C) Pywikibot team, 2014
+# (C) Pywikibot team, 2014-2015
 #
 # Distributed under the terms of the MIT license.
 #
@@ -182,7 +200,8 @@
         os.remove(self._cachefile_path())
 
 
-def process_entries(cache_path, func, use_accesstime=None):
+def process_entries(cache_path, func, use_accesstime=None, output_func=None,
+                    action_func=None):
     """
     Check the contents of the cache.
 
@@ -251,8 +270,30 @@
             pywikibot.exception(e, tb=True)
             continue
 
-        func(entry)
+        if func(entry):
+            if output_func:
+                output = output_func(entry)
+                if output is not None:
+                    pywikibot.output(output)
+            if action_func:
+                action_func(entry)
 
+
+def _parse_command(command, name):
+    obj = globals().get(command)
+    if callable(obj):
+        return obj
+    else:
+        try:
+            return eval('lambda entry: ' + command)
+        except:
+            pywikibot.exception()
+            pywikibot.error('Can not compile {0} command: '
+                            '{1}'.format(name, command))
+            return None
+
+
+# Filter commands
 
 def has_password(entry):
     """Entry has a password in the entry."""
@@ -306,15 +347,39 @@
         return entry
 
 
+# Output commands
+
+def uniquedesc(entry):
+    """Return the unique description string."""
+    return entry._uniquedescriptionstr()
+
+
+def parameters(entry):
+    """Return a pretty formatted parameters list."""
+    lines = ''
+    for key, items in sorted(entry._params.items()):
+        lines += '{0}={1}\n'.format(key, ', '.join(items))
+    return lines
+
+
 def main():
+    def output_itself(entry):
+        return entry
+
+    def filter_none(entry):
+        return True
+
     local_args = pywikibot.handleArgs()
     cache_paths = None
     delete = False
     command = None
+    output = None
 
     for arg in local_args:
         if command == '':
             command = arg
+        elif output == '':
+            output = arg
         elif arg == '-delete':
             delete = True
         elif arg == '-password':
@@ -324,13 +389,16 @@
                 pywikibot.error('Only one command may be executed.')
                 exit(1)
             command = ''
+        elif arg == '-o':
+            if output:
+                pywikibot.error('Only one output may be defined.')
+                exit(1)
+            output = ''
         else:
             if not cache_paths:
                 cache_paths = [arg]
             else:
                 cache_paths.append(arg)
-
-    func = None
 
     if not cache_paths:
         cache_paths = ['apicache', 'tests/apicache']
@@ -346,26 +414,31 @@
                 os.path.join(os.path.expanduser('~/.pywikibot'), 'apicache')]
 
     if delete:
-        action_func = lambda entry: entry._delete()
+        action_func = CacheEntry._delete
+        output_func = None
     else:
-        action_func = lambda entry: pywikibot.output(entry)
+        action_func = None
+
+    if output:
+        output_func = _parse_command(output, 'output')
+        if output_func is None:
+            return False
+    elif not action_func:
+        output_func = output_itself
 
     if command:
-        try:
-            command_func = eval('lambda entry: ' + command)
-        except:
-            pywikibot.exception()
-            pywikibot.error(u'Can not compile command: %s' % command)
-            exit(1)
-
-        func = lambda entry: command_func(entry) and action_func(entry)
+        filter_func = _parse_command(command, 'filter')
+        if filter_func is None:
+            return False
     else:
-        func = action_func
+        filter_func = filter_none
 
     for cache_path in cache_paths:
         if len(cache_paths) > 1:
             pywikibot.output(u'Processing %s' % cache_path)
-        process_entries(cache_path, func)
+        process_entries(cache_path, filter_func, output_func=output_func,
+                        action_func=action_func)
+
 
 if __name__ == '__main__':
     main()

-- 
To view, visit https://gerrit.wikimedia.org/r/247482
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I7b8fc283555a6d35719e47d28ff1becfbd07baf7
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to