summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2012-08-07 01:53:26 -0500
committerDan McGee <dan@archlinux.org>2012-08-07 03:17:46 -0500
commit2cb15547b0d3dfee46f3d51341bebd0b1251c0f9 (patch)
treeb0d23afaff0cb3b8447fb28452db004008ff79ea
parent7d9ed0b881bd05878e7a54f785c2551bc6e336d6 (diff)
Add ctypes-based wrapper to ALPM vercmp API
This will allow us to do some additional stuff on systems that have libalpm available; namely we can use the version comparison logic it provides to do smarter filtering etc. of fields that use comparsion operations. Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r--packages/alpm.py68
1 files changed, 68 insertions, 0 deletions
diff --git a/packages/alpm.py b/packages/alpm.py
new file mode 100644
index 00000000..a7f4c3b5
--- /dev/null
+++ b/packages/alpm.py
@@ -0,0 +1,68 @@
+import ctypes
+from ctypes.util import find_library
+import operator
+
+
+def load_alpm(name=None):
+ # Load the alpm library and set up some of the functions we might use
+ if name == None:
+ name = find_library('alpm')
+ try:
+ alpm = ctypes.cdll.LoadLibrary(name)
+ except OSError:
+ return None
+ alpm.alpm_version.argtypes = ()
+ alpm.alpm_version.restype = ctypes.c_char_p
+ alpm.alpm_pkg_vercmp.argtypes = (ctypes.c_char_p, ctypes.c_char_p)
+ alpm.alpm_pkg_vercmp.restype = ctypes.c_int
+ return alpm
+
+
+ALPM = load_alpm()
+
+class AlpmAPI(object):
+ OPERATOR_MAP = {
+ '=': operator.eq,
+ '==': operator.eq,
+ '!=': operator.ne,
+ '<': operator.lt,
+ '<=': operator.le,
+ '>': operator.gt,
+ '>=': operator.ge,
+ }
+
+ def __init__(self):
+ self.alpm = ALPM
+ self.available = ALPM is not None
+
+ def version(self):
+ if not self.available:
+ return None
+ return ALPM.alpm_version()
+
+ def vercmp(self, ver1, ver2):
+ if not self.available:
+ return None
+ return ALPM.alpm_pkg_vercmp(str(ver1), str(ver2))
+
+ def compare_versions(self, ver1, oper, ver2):
+ func = self.OPERATOR_MAP.get(oper, None)
+ if func is None:
+ raise Exception("Invalid operator %s specified" % oper)
+ if not self.available:
+ return None
+ res = self.vercmp(ver1, ver2)
+ return func(res, 0)
+
+
+def main():
+ api = AlpmAPI()
+ print api.version()
+ print api.vercmp(1, 2)
+ print api.compare_versions(1, '<', 2)
+
+
+if __name__ == '__main__':
+ main()
+
+# vim: set ts=4 sw=4 et: