summaryrefslogtreecommitdiffstats
path: root/ext-plugins
diff options
context:
space:
mode:
authorJan Pokorný <jpokorny@redhat.com>2014-12-19 20:17:01 +0100
committerJan Pokorný <jpokorny@redhat.com>2015-01-09 10:21:23 +0100
commit34fc126b5ffd417d2cc601b81f7f976e2a5649ef (patch)
tree8f1f749d954c0e8f2df8ad57bbf25511b4cc5571 /ext-plugins
parent567e5686fc5713ba8163f42400fee9c9346851d6 (diff)
downloadclufter-34fc126b5ffd417d2cc601b81f7f976e2a5649ef.tar.gz
clufter-34fc126b5ffd417d2cc601b81f7f976e2a5649ef.tar.xz
clufter-34fc126b5ffd417d2cc601b81f7f976e2a5649ef.zip
formats/command: move to ext-plugins/lib-general/formats
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
Diffstat (limited to 'ext-plugins')
-rw-r--r--ext-plugins/lib-general/formats/command.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/ext-plugins/lib-general/formats/command.py b/ext-plugins/lib-general/formats/command.py
new file mode 100644
index 0000000..7d2b51b
--- /dev/null
+++ b/ext-plugins/lib-general/formats/command.py
@@ -0,0 +1,85 @@
+# -*- coding: UTF-8 -*-
+# Copyright 2014 Red Hat, Inc.
+# Part of clufter project
+# Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt)
+"""Format representing merged/isolated (1/2 levels) of single command to exec"""
+__author__ = "Jan Pokorný <jpokorny @at@ Red Hat .dot. com>"
+
+try:
+ from collections import OrderedDict
+except ImportError:
+ from ordereddict import OrderedDict
+from logging import getLogger
+
+log = getLogger(__name__)
+
+from ..format import SimpleFormat
+from ..protocol import Protocol
+from ..utils import head_tail
+from ..utils_func import apply_intercalate
+
+
+class command(SimpleFormat):
+ native_protocol = SEPARATED = Protocol('separated')
+ BYTESTRING = SimpleFormat.BYTESTRING
+ DICT = Protocol('dict')
+ MERGED = Protocol('merged')
+
+ @SimpleFormat.producing(BYTESTRING, chained=True)
+ def get_bytestring(self, *protodecl):
+ """Return command as canonical single string"""
+ # chained fallback
+ return ' '.join(self.MERGED(protect_safe=True))
+
+ @SimpleFormat.producing(SEPARATED, protect=True)
+ def get_separated(self, *protodecl):
+ ret = self.MERGED(protect_safe=True)
+ newret, acc = [], []
+ for i in ret:
+ if i.startswith('-') and i != '-':
+ if acc:
+ newret.append(tuple(acc))
+ acc = [i]
+ else:
+ acc.append(i)
+ # expect that, by convention, option takes at most a single argument
+ newret.extend(filter(bool, (tuple(acc[:2]), tuple(acc[2:]))))
+ return newret
+
+ @SimpleFormat.producing(MERGED, protect=True)
+ def get_merged(self, *protodecl):
+ # try to look (indirectly) if we have "separated" at hand first
+ if self.BYTESTRING in self._representations: # break the possible loop
+ from shlex import split
+ ret = split(self.BYTESTRING())
+ for i, lexeme in enumerate(ret[:]):
+ # heuristic(!) method to normalize: '-a=b' -> '-a', 'b'
+ if (lexeme.count('=') == 1 and
+ ('"' not in lexeme or lexeme.count('"') % 2) and
+ ("'" not in lexeme or lexeme.count("'") % 2)):
+ ret[i:i + 1] = lexeme.split('=')
+ elif self.DICT in self._representations: # break the possible loop (2)
+ d = self.DICT(protect_safe=True)
+ if not isinstance(d, OrderedDict):
+ log.warning("'{0}' format: not backed by OrderedDict".format(
+ self.__class__.name
+ ))
+ ret = [(k, v) for k, v in d.iteritems() if k != '__args__']
+ ret.extend(d.get('__args__', ()))
+ else:
+ ret = self.SEPARATED(protect_safe=True)
+ return apply_intercalate(ret)
+
+ @SimpleFormat.producing(DICT, protect=True)
+ # not a perfectly bijective mapping, this is a bit lossy representation,
+ # on the other hand, it canonicalize the notation when turned to other forms
+ def get_dict(self, *protodecl):
+ separated = self.SEPARATED()
+ separated.reverse()
+ ret = OrderedDict()
+ while separated:
+ head, tail = head_tail(separated.pop())
+ head = head if head.startswith('-') and head != '-' else '__args__'
+ acc = ret.setdefault(head, [])
+ acc.append(tail)
+ return ret