From c7eaaf710d0963396bd1658bebe7fc36a0deb80b Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 17 Oct 2012 05:35:43 +0900 Subject: added skeleton for generic client wizard flow --- src/leap/util/dicts.py | 258 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 src/leap/util/dicts.py (limited to 'src/leap/util') diff --git a/src/leap/util/dicts.py b/src/leap/util/dicts.py new file mode 100644 index 00000000..d8177973 --- /dev/null +++ b/src/leap/util/dicts.py @@ -0,0 +1,258 @@ +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. + +try: + from thread import get_ident as _get_ident +except ImportError: + from dummy_thread import get_ident as _get_ident + +try: + from _abcoll import KeysView, ValuesView, ItemsView +except ImportError: + pass + + +class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running={}): + 'od.__repr__() <==> repr(od)' + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) -- cgit v1.2.3 From 8118056a244ca74d16380ad26a70e3da40e7e401 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 9 Nov 2012 11:21:40 +0900 Subject: connect page merged into regvalidation. Flow nearly working with fake provider, except for authentication. --- src/leap/util/web.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/leap/util/web.py (limited to 'src/leap/util') diff --git a/src/leap/util/web.py b/src/leap/util/web.py new file mode 100644 index 00000000..6ddf4b21 --- /dev/null +++ b/src/leap/util/web.py @@ -0,0 +1,18 @@ +""" +web related utilities +""" + + +def get_https_domain_and_port(full_domain): + """ + returns a tuple with domain and port + from a full_domain string that can + contain a colon + """ + domain_split = full_domain.split(':') + _len = len(domain_split) + if _len == 1: + domain, port = full_domain, 443 + if _len == 2: + domain, port = domain_split + return domain, port -- cgit v1.2.3 From 8fd77ba036cb78c81939bbfce312b12cdc90d881 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 9 Nov 2012 18:13:32 +0900 Subject: working version of the fake provider. wizard can now be completely tested against this. --- src/leap/util/web.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src/leap/util') diff --git a/src/leap/util/web.py b/src/leap/util/web.py index 6ddf4b21..b2aef058 100644 --- a/src/leap/util/web.py +++ b/src/leap/util/web.py @@ -3,16 +3,37 @@ web related utilities """ +class UsageError(Exception): + """ """ + + def get_https_domain_and_port(full_domain): """ returns a tuple with domain and port from a full_domain string that can contain a colon """ + if full_domain is None: + return None, None + + https_sch = "https://" + http_sch = "http://" + + if full_domain.startswith(https_sch): + full_domain = full_domain.lstrip(https_sch) + elif full_domain.startswith(http_sch): + raise UsageError( + "cannot be called with a domain " + "that begins with 'http://'") + domain_split = full_domain.split(':') _len = len(domain_split) if _len == 1: domain, port = full_domain, 443 - if _len == 2: + elif _len == 2: domain, port = domain_split + else: + raise UsageError( + "must be called with one only parameter" + "in the form domain[:port]") return domain, port -- cgit v1.2.3 From d24c7328fa845737dbb83d512e4b3f287634c4cc Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 14 Nov 2012 00:33:05 +0900 Subject: make tests pass + pep8 They were breaking mainly because I did not bother to have a pass over them to change the PROVIDER settings from the branding case. All good now, although much testing is yet needed and some refactor could be used. long live green tests! --- src/leap/util/dicts.py | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'src/leap/util') diff --git a/src/leap/util/dicts.py b/src/leap/util/dicts.py index d8177973..001ca96b 100644 --- a/src/leap/util/dicts.py +++ b/src/leap/util/dicts.py @@ -1,4 +1,5 @@ -# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Backport of OrderedDict() class that runs +# on Python 2.4, 2.5, 2.6, 2.7 and pypy. # Passes Python2.7's test suite and incorporates all the latest updates. try: @@ -17,9 +18,11 @@ class OrderedDict(dict): # An inherited dict maps keys to values. # The inherited dict provides __getitem__, __len__, __contains__, and get. # The remaining methods are order-aware. - # Big-O running times for all methods are the same as for regular dictionaries. + # Big-O running times for all methods are the same as for regular + # dictionaries. - # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The internal self.__map dictionary maps keys to links in a doubly + # linked list. # The circular doubly linked list starts and ends with a sentinel element. # The sentinel element never gets deleted (this simplifies the algorithm). # Each link is stored as a list of length three: [PREV, NEXT, KEY]. @@ -42,8 +45,9 @@ class OrderedDict(dict): def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' - # Setting a new item creates a new link which goes at the end of the linked - # list, and the inherited dictionary is updated with the new key/value pair. + # Setting a new item creates a new link which goes at the end + # of the linked list, and the inherited dictionary is updated + # with the new key/value pair. if key not in self: root = self.__root last = root[0] @@ -53,7 +57,8 @@ class OrderedDict(dict): def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which is - # then removed by updating the links in the predecessor and successor nodes. + # then removed by updating the links in the predecessor and successor + # nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) link_prev[1] = link_next @@ -89,8 +94,8 @@ class OrderedDict(dict): def popitem(self, last=True): '''od.popitem() -> (k, v), return and remove a (key, value) pair. - Pairs are returned in LIFO order if last is true or FIFO order if false. - + Pairs are returned in LIFO order if last is true or FIFO order if + false. ''' if not self: raise KeyError('dictionary is empty') @@ -142,11 +147,13 @@ class OrderedDict(dict): '''od.update(E, **F) -> None. Update od from dict/iterable E and F. If E is a dict instance, does: for k in E: od[k] = E[k] - If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): + od[k] = E[k] Or if E is an iterable of items, does: for k, v in E: od[k] = v - In either case, this is followed by: for k, v in F.items(): od[k] = v - + In either case, this is followed by: for k, v in F.items(): + od[k] = v ''' + if len(args) > 2: raise TypeError('update() takes at most 2 positional ' 'arguments (%d given)' % (len(args),)) @@ -169,13 +176,16 @@ class OrderedDict(dict): for key, value in kwds.items(): self[key] = value - __update = update # let subclasses override update without breaking __init__ + __update = update # let subclasses override update + # without breaking __init__ __marker = object() def pop(self, key, default=__marker): - '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. - If key is not found, d is returned if given, otherwise KeyError is raised. + '''od.pop(k[,d]) -> v + remove specified key and return the corresponding value. + If key is not found, d is returned if given, + otherwise KeyError is raised. ''' if key in self: @@ -232,12 +242,12 @@ class OrderedDict(dict): return d def __eq__(self, other): - '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + '''od.__eq__(y) <==> od==y. + Comparison to another OD is order-sensitive while comparison to a regular mapping is order-insensitive. - ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return len(self) == len(other) and self.items() == other.items() return dict.__eq__(self, other) def __ne__(self, other): -- cgit v1.2.3 From 53fa2c134ab2c96376276aa1c0ed74db0aaba218 Mon Sep 17 00:00:00 2001 From: kali Date: Mon, 10 Dec 2012 23:20:09 +0900 Subject: get cipher config from eip-service --- src/leap/util/misc.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/leap/util/misc.py (limited to 'src/leap/util') diff --git a/src/leap/util/misc.py b/src/leap/util/misc.py new file mode 100644 index 00000000..3c26892b --- /dev/null +++ b/src/leap/util/misc.py @@ -0,0 +1,16 @@ +""" +misc utils +""" + + +class ImproperlyConfigured(Exception): + """ + """ + + +def null_check(value, value_name): + try: + assert value is not None + except AssertionError: + raise ImproperlyConfigured( + "%s parameter cannot be None" % value_name) -- cgit v1.2.3 From 04d423e2a89034dfb86fe305108162fd2a696079 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 12 Dec 2012 03:29:31 +0900 Subject: tests for openvpn options and make the rest of tests pass after some changes in this branch (dirtyness in config files) --- src/leap/util/fileutil.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/leap/util') diff --git a/src/leap/util/fileutil.py b/src/leap/util/fileutil.py index aef4cfe0..820ffe46 100644 --- a/src/leap/util/fileutil.py +++ b/src/leap/util/fileutil.py @@ -93,6 +93,11 @@ def mkdir_p(path): raise +def mkdir_f(path): + folder, fname = os.path.split(path) + mkdir_p(folder) + + def check_and_fix_urw_only(_file): """ test for 600 mode and try -- cgit v1.2.3 From 490cde9c33039c2c5b16d929d6f8bb8e8f06f430 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 5 Dec 2012 23:50:08 +0900 Subject: tests for firstrun/wizard --- src/leap/util/web.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/leap/util') diff --git a/src/leap/util/web.py b/src/leap/util/web.py index b2aef058..15de0561 100644 --- a/src/leap/util/web.py +++ b/src/leap/util/web.py @@ -13,6 +13,7 @@ def get_https_domain_and_port(full_domain): from a full_domain string that can contain a colon """ + full_domain = unicode(full_domain) if full_domain is None: return None, None -- cgit v1.2.3 From b0c3c9194447f20306111a31ee5a6d4828fed158 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 21 Dec 2012 07:43:16 +0900 Subject: readme typos, updated translation docs --- src/leap/util/translations.py | 58 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/leap/util/translations.py (limited to 'src/leap/util') diff --git a/src/leap/util/translations.py b/src/leap/util/translations.py new file mode 100644 index 00000000..c06aa947 --- /dev/null +++ b/src/leap/util/translations.py @@ -0,0 +1,58 @@ +import inspect + +from PyQt4.QtCore import QCoreApplication + +""" +here I could not do all that I wanted. +the context is not getting passed to the xml file. +Looks like pylupdate4 is somehow a hack that does not +parse too well the python ast. +I guess we could generate the xml for ourselves as a last recourse. +""" + +# XXX BIG NOTE: +# RESIST the temptation to get the translate function +# more compact, or have the Context argument passed as a variable +# It HAS to be explicit due to how the pylupdate parser +# works. + + +qtTranslate = QCoreApplication.translate + + +class LEAPTr: + pass + + +def translate(*args): + """ + translate(Context, text, comment) + """ + print 'translating...' + klsname = None + try: + # get class value from instance + # using live object inspection + prev_frame = inspect.stack()[1][0] + self = inspect.getargvalues(prev_frame).locals.get('self') + if self: + # XXX will this work with QObject wrapper?? + if isinstance(LEAPTr, self) and hasattr(self, 'tr'): + print "we got a self in base class" + return self.tr(*args) + + # Trying to get the class name + # but this is useless, the parser + # has already got the context. + klsname = self.__class__.__name__ + print 'KLSNAME -- ', klsname + except: + print 'error getting stack frame' + + if klsname: + nargs = (klsname,) + args + return qtTranslate(*nargs) + + else: + nargs = ('default', ) + args + return qtTranslate(*nargs) -- cgit v1.2.3 From ec0fc05e3918782dbb29f9f6901c0de22419134d Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 21 Dec 2012 10:28:46 +0900 Subject: magic translatable objects --- src/leap/util/tests/test_translations.py | 22 ++++++++++++++++ src/leap/util/translations.py | 43 +++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 src/leap/util/tests/test_translations.py (limited to 'src/leap/util') diff --git a/src/leap/util/tests/test_translations.py b/src/leap/util/tests/test_translations.py new file mode 100644 index 00000000..794daeba --- /dev/null +++ b/src/leap/util/tests/test_translations.py @@ -0,0 +1,22 @@ +import unittest + +from leap.util import translations + + +class TrasnlationsTestCase(unittest.TestCase): + """ + tests for translation functions and classes + """ + + def setUp(self): + self.trClass = translations.LEAPTranslatable + + def test_trasnlatable(self): + tr = self.trClass({"en": "house", "es": "casa"}) + eq = self.assertEqual + eq(tr.tr(to="es"), "casa") + eq(tr.tr(to="en"), "house") + + +if __name__ == "__main__": + unittest.main() diff --git a/src/leap/util/translations.py b/src/leap/util/translations.py index c06aa947..14b8c020 100644 --- a/src/leap/util/translations.py +++ b/src/leap/util/translations.py @@ -1,6 +1,10 @@ import inspect +import logging from PyQt4.QtCore import QCoreApplication +from PyQt4.QtCore import QLocale + +logger = logging.getLogger(__name__) """ here I could not do all that I wanted. @@ -20,15 +24,12 @@ I guess we could generate the xml for ourselves as a last recourse. qtTranslate = QCoreApplication.translate -class LEAPTr: - pass - - -def translate(*args): +def translate(*args, **kwargs): """ + our magic function. translate(Context, text, comment) """ - print 'translating...' + #print 'translating...' klsname = None try: # get class value from instance @@ -37,7 +38,7 @@ def translate(*args): self = inspect.getargvalues(prev_frame).locals.get('self') if self: # XXX will this work with QObject wrapper?? - if isinstance(LEAPTr, self) and hasattr(self, 'tr'): + if isinstance(LEAPTranslatable, self) and hasattr(self, 'tr'): print "we got a self in base class" return self.tr(*args) @@ -45,9 +46,10 @@ def translate(*args): # but this is useless, the parser # has already got the context. klsname = self.__class__.__name__ - print 'KLSNAME -- ', klsname + #print 'KLSNAME -- ', klsname except: - print 'error getting stack frame' + logger.error('error getting stack frame') + #print 'error getting stack frame' if klsname: nargs = (klsname,) + args @@ -56,3 +58,26 @@ def translate(*args): else: nargs = ('default', ) + args return qtTranslate(*nargs) + + +class LEAPTranslatable(dict): + """ + An extended dict that implements a .tr method + so it can be translated on the fly by our + magic translate method + """ + + try: + locale = str(QLocale.system().name()).split('_')[0] + except: + logger.warning("could not get system locale!") + print "could not get system locale!" + locale = "en" + + def tr(self, to=None): + if not to: + to = self.locale + _tr = self.get(to, None) + if not _tr: + _tr = self.get("en", None) + return _tr -- cgit v1.2.3 From 4ad663b935fa1845d426dde99a8272942b620e11 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 2 Jan 2013 18:06:13 +0900 Subject: initial OSX packaging --- src/leap/util/leap_argparse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/util') diff --git a/src/leap/util/leap_argparse.py b/src/leap/util/leap_argparse.py index 2f996a31..5b0775cc 100644 --- a/src/leap/util/leap_argparse.py +++ b/src/leap/util/leap_argparse.py @@ -37,5 +37,5 @@ Launches main LEAP Client""", epilog=epilog) def init_leapc_args(): parser = build_parser() - opts = parser.parse_args() + opts, unknown = parser.parse_known_args() return parser, opts -- cgit v1.2.3 From 93d5a8cd1ec55c725d5931d86989ea11ac2db844 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 9 Jan 2013 04:20:15 +0900 Subject: fix provider label translation --- src/leap/util/translations.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/leap/util') diff --git a/src/leap/util/translations.py b/src/leap/util/translations.py index 14b8c020..80daa10d 100644 --- a/src/leap/util/translations.py +++ b/src/leap/util/translations.py @@ -17,7 +17,7 @@ I guess we could generate the xml for ourselves as a last recourse. # XXX BIG NOTE: # RESIST the temptation to get the translate function # more compact, or have the Context argument passed as a variable -# It HAS to be explicit due to how the pylupdate parser +# Its name HAS to be explicit due to how the pylupdate parser # works. @@ -29,18 +29,19 @@ def translate(*args, **kwargs): our magic function. translate(Context, text, comment) """ - #print 'translating...' + if len(args) == 1: + obj = args[0] + if isinstance(obj, LEAPTranslatable) and hasattr(obj, 'tr'): + return obj.tr() + klsname = None try: # get class value from instance # using live object inspection prev_frame = inspect.stack()[1][0] - self = inspect.getargvalues(prev_frame).locals.get('self') + locals_ = inspect.getargvalues(prev_frame).locals + self = locals_.get('self') if self: - # XXX will this work with QObject wrapper?? - if isinstance(LEAPTranslatable, self) and hasattr(self, 'tr'): - print "we got a self in base class" - return self.tr(*args) # Trying to get the class name # but this is useless, the parser @@ -49,7 +50,6 @@ def translate(*args, **kwargs): #print 'KLSNAME -- ', klsname except: logger.error('error getting stack frame') - #print 'error getting stack frame' if klsname: nargs = (klsname,) + args -- cgit v1.2.3 From 239a95a65055a5b7128894faf30938496382fbe1 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 9 Jan 2013 05:39:28 +0900 Subject: fix exception i18n --- src/leap/util/translations.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/leap/util') diff --git a/src/leap/util/translations.py b/src/leap/util/translations.py index 80daa10d..d782cfe4 100644 --- a/src/leap/util/translations.py +++ b/src/leap/util/translations.py @@ -51,13 +51,14 @@ def translate(*args, **kwargs): except: logger.error('error getting stack frame') - if klsname: + if klsname and len(args) == 1: nargs = (klsname,) + args return qtTranslate(*nargs) else: - nargs = ('default', ) + args - return qtTranslate(*nargs) + #nargs = ('default', ) + args + #import pdb4qt; pdb4qt.set_trace() + return qtTranslate(*args) class LEAPTranslatable(dict): -- cgit v1.2.3 From ade0eded09176fd687d1ee30724468c048d15065 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 11 Jan 2013 09:16:49 +0900 Subject: fix for missing cacert bundle frozen app cannot find requests cacert bundle. added to Resources to get us going. --- src/leap/util/certs.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/leap/util/certs.py (limited to 'src/leap/util') diff --git a/src/leap/util/certs.py b/src/leap/util/certs.py new file mode 100644 index 00000000..304db08a --- /dev/null +++ b/src/leap/util/certs.py @@ -0,0 +1,17 @@ +import os +import logging + +logger = logging.getLogger(__name__) + + +def get_mac_cabundle(): + # hackaround bundle error + # XXX this needs a better fix! + f = os.path.split(__file__)[0] + sep = os.path.sep + f_ = sep.join(f.split(sep)[:-2]) + verify = os.path.join(f_, 'cacert.pem') + #logger.error('VERIFY PATH = %s' % verify) + exists = os.path.isfile(verify) + #logger.error('do exist? %s', exists) + return verify -- cgit v1.2.3 From d6c8cb0f12e8924820c296a8114a7899f61e5180 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 17 Jan 2013 05:54:16 +0900 Subject: (osx) detect which interface is traffic going thru --- src/leap/util/certs.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/leap/util') diff --git a/src/leap/util/certs.py b/src/leap/util/certs.py index 304db08a..f0f790e9 100644 --- a/src/leap/util/certs.py +++ b/src/leap/util/certs.py @@ -14,4 +14,5 @@ def get_mac_cabundle(): #logger.error('VERIFY PATH = %s' % verify) exists = os.path.isfile(verify) #logger.error('do exist? %s', exists) - return verify + if exists: + return verify -- cgit v1.2.3 From 6e9c63f47b98fbfcd3a5104fbfa5cc9d9ffe5143 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 17 Jan 2013 07:31:59 +0900 Subject: osx fixed already running instance check --- src/leap/util/misc.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/leap/util') diff --git a/src/leap/util/misc.py b/src/leap/util/misc.py index 3c26892b..aa3ebe25 100644 --- a/src/leap/util/misc.py +++ b/src/leap/util/misc.py @@ -1,6 +1,9 @@ """ misc utils """ +import psutil + +from leap.base.constants import OPENVPN_BIN class ImproperlyConfigured(Exception): @@ -14,3 +17,20 @@ def null_check(value, value_name): except AssertionError: raise ImproperlyConfigured( "%s parameter cannot be None" % value_name) + +def get_openvpn_pids(): + # binary name might change + + openvpn_pids = [] + for p in psutil.process_iter(): + try: + # XXX Not exact! + # Will give false positives. + # we should check that cmdline BEGINS + # with openvpn or with our wrapper + # (pkexec / osascript / whatever) + if OPENVPN_BIN in ' '.join(p.cmdline): + openvpn_pids.append(p.pid) + except psutil.error.AccessDenied: + pass + return openvpn_pids -- cgit v1.2.3 From 6fb952397573f4bc90f4cd9e72b49fcf6256e95c Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 17 Jan 2013 08:07:45 +0900 Subject: localize exit country if we can only if we can find the geoip database, which comes with geoip-database in debian. we will have to think more about this in the future but it's nice to have now for testing. --- src/leap/util/__init__.py | 9 +++++++++ src/leap/util/geo.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/leap/util/geo.py (limited to 'src/leap/util') diff --git a/src/leap/util/__init__.py b/src/leap/util/__init__.py index e69de29b..a70a9a8b 100644 --- a/src/leap/util/__init__.py +++ b/src/leap/util/__init__.py @@ -0,0 +1,9 @@ +import logging +logger = logging.getLogger(__name__) + +try: + import pygeoip + HAS_GEOIP = True +except ImportError: + logger.debug('PyGeoIP not found. Disabled Geo support.') + HAS_GEOIP = False diff --git a/src/leap/util/geo.py b/src/leap/util/geo.py new file mode 100644 index 00000000..54b29596 --- /dev/null +++ b/src/leap/util/geo.py @@ -0,0 +1,32 @@ +""" +experimental geo support. +not yet a feature. +in debian, we rely on the (optional) geoip-database +""" +import os +import platform + +from leap.util import HAS_GEOIP + +GEOIP = None + +if HAS_GEOIP: + import pygeoip # we know we can :) + + GEOIP_PATH = None + + if platform.system() == "Linux": + PATH = "/usr/share/GeoIP/GeoIP.dat" + if os.path.isfile(PATH): + GEOIP_PATH = PATH + GEOIP = pygeoip.GeoIP(GEOIP_PATH, pygeoip.MEMORY_CACHE) + + +def get_country_name(ip): + if not GEOIP: + return + try: + country = GEOIP.country_name_by_addr(ip) + except pygeoip.GeoIPError: + country = None + return country if country else "-" -- cgit v1.2.3 From ff59da55ef9a176b36cef19d67e7ec363bf5d739 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 24 Jan 2013 02:30:00 +0900 Subject: wizard rephrasing & punctuation --- src/leap/util/translations.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/leap/util') diff --git a/src/leap/util/translations.py b/src/leap/util/translations.py index d782cfe4..f55c8fba 100644 --- a/src/leap/util/translations.py +++ b/src/leap/util/translations.py @@ -56,8 +56,6 @@ def translate(*args, **kwargs): return qtTranslate(*nargs) else: - #nargs = ('default', ) + args - #import pdb4qt; pdb4qt.set_trace() return qtTranslate(*args) -- cgit v1.2.3 From 9cdc193c587631986e579c1ba37a8b982be01238 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 24 Jan 2013 18:47:41 +0900 Subject: all tests green again plus: * added soledad test requirements * removed soledad from run_tests run (+1K tests failing) * added option to run All tests to run_tests script * pep8 cleanup --- src/leap/util/misc.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/leap/util') diff --git a/src/leap/util/misc.py b/src/leap/util/misc.py index aa3ebe25..d869a1ba 100644 --- a/src/leap/util/misc.py +++ b/src/leap/util/misc.py @@ -17,7 +17,8 @@ def null_check(value, value_name): except AssertionError: raise ImproperlyConfigured( "%s parameter cannot be None" % value_name) - + + def get_openvpn_pids(): # binary name might change -- cgit v1.2.3 From 173e532c810d16bcef8f3009bc9203eed9604c87 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 30 Jan 2013 05:26:15 +0900 Subject: comment out unused arguments in the arg parser --- src/leap/util/leap_argparse.py | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'src/leap/util') diff --git a/src/leap/util/leap_argparse.py b/src/leap/util/leap_argparse.py index 5b0775cc..3412a72c 100644 --- a/src/leap/util/leap_argparse.py +++ b/src/leap/util/leap_argparse.py @@ -6,16 +6,13 @@ def build_parser(): all the options for the leap arg parser Some of these could be switched on only if debug flag is present! """ - epilog = "Copyright 2012 The Leap Project" + epilog = "Copyright 2012 The LEAP Encryption Access Project" parser = argparse.ArgumentParser(description=""" -Launches main LEAP Client""", epilog=epilog) +Launches the LEAP Client""", epilog=epilog) parser.add_argument('-d', '--debug', action="store_true", - help='launches in debug mode') - parser.add_argument('-c', '--config', metavar="CONFIG FILE", nargs='?', - action="store", dest="config_file", - type=argparse.FileType('r'), - help='optional config file') - parser.add_argument('--logfile', metavar="LOG FILE", nargs='?', + help=("Launches client in debug mode, writing debug" + "info to stdout")) + parser.add_argument('-l', '--logfile', metavar="LOG FILE", nargs='?', action="store", dest="log_file", #type=argparse.FileType('w'), help='optional log file') @@ -23,15 +20,21 @@ Launches main LEAP Client""", epilog=epilog) type=int, action="store", dest="openvpn_verb", help='verbosity level for openvpn logs [1-6]') - parser.add_argument('-l', '--no-provider-checks', - action="store_true", default=False, - help="skips download of provider config files. gets " - "config from local files only. Will fail if cannot " - "find any") - parser.add_argument('-k', '--no-ca-verify', - action="store_true", default=False, - help="(insecure). Skips verification of the server " - "certificate used in TLS handshake.") + + # Not in use, we might want to reintroduce them. + #parser.add_argument('-i', '--no-provider-checks', + #action="store_true", default=False, + #help="skips download of provider config files. gets " + #"config from local files only. Will fail if cannot " + #"find any") + #parser.add_argument('-k', '--no-ca-verify', + #action="store_true", default=False, + #help="(insecure). Skips verification of the server " + #"certificate used in TLS handshake.") + #parser.add_argument('-c', '--config', metavar="CONFIG FILE", nargs='?', + #action="store", dest="config_file", + #type=argparse.FileType('r'), + #help='optional config file') return parser -- cgit v1.2.3