diff options
| author | Kali Kaneko <kali@leap.se> | 2013-08-26 21:54:13 +0200 | 
|---|---|---|
| committer | Kali Kaneko <kali@leap.se> | 2013-08-26 21:54:13 +0200 | 
| commit | 4c5fcefcb0205727aed5ef59cd18b0dd263c4cfd (patch) | |
| tree | 74faa509c3ef691cfd6c3272d0881ee6970743c2 | |
| parent | 9070d74a47158f5749c5e16b8d9d9e62a55d07df (diff) | |
| parent | 4a124f94730775b97afc49b48ccfa0206459190f (diff) | |
Merge tag '0.3.1' into debian-0.3.1
Tag leap.common version 0.3.1
Conflicts:
	pkg/requirements.pip
	src/leap/common/events/events_pb2.py
| -rw-r--r-- | .gitattributes | 1 | ||||
| -rw-r--r-- | CHANGELOG | 11 | ||||
| -rw-r--r-- | MANIFEST.in | 1 | ||||
| -rw-r--r-- | README.rst | 1 | ||||
| -rw-r--r-- | pkg/__init__.py | 0 | ||||
| -rw-r--r-- | pkg/requirements.pip | 8 | ||||
| -rw-r--r-- | pkg/utils.py | 84 | ||||
| -rw-r--r-- | setup.py | 27 | ||||
| -rw-r--r-- | src/leap/common/__init__.py | 4 | ||||
| -rw-r--r-- | src/leap/common/_version.py | 203 | ||||
| -rw-r--r-- | src/leap/common/events/Makefile | 2 | ||||
| -rw-r--r-- | src/leap/common/events/events.proto | 29 | ||||
| -rw-r--r-- | src/leap/common/events/events_pb2.py | 911 | ||||
| -rw-r--r-- | src/leap/common/events/server.py | 28 | ||||
| -rw-r--r-- | versioneer.py | 669 | 
15 files changed, 1565 insertions, 414 deletions
| diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dd8fe59 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +src/leap/common/_version.py export-subst @@ -1,3 +1,14 @@ +0.3.1 Aug 23: +  o Add libssl-dev requirement for pyOpenSSL. +  o Make the server ping call be async inside events' +    ensure_server. Fixes #3355. +  o Requirements in setup are taken from requirements.pip +  o Updated requirements. +  o Add IMAP_UNREAD_MAIL event. +  o Add events for SMTP relay signaling. Closes #3464. +  o Add events for imap and keymanager notifications. Closes: #3480 +  o Add versioneer to handle versioning. +  0.3.0 Aug 9:    o OSX: Fix problem with path prefix not returning the correct      value. Fixes #3273. diff --git a/MANIFEST.in b/MANIFEST.in index 84a01ef..3ba80ca 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,2 @@  include src/leap/common/testing/*.pem +include versioneer.py @@ -16,6 +16,7 @@ A collection of shared utils used by the several python LEAP subprojects.  Library dependencies  --------------------  * ``protobuf-compiler`` +* ``libssl-dev``  Python dependencies  ------------------- diff --git a/pkg/__init__.py b/pkg/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pkg/__init__.py diff --git a/pkg/requirements.pip b/pkg/requirements.pip new file mode 100644 index 0000000..9617d92 --- /dev/null +++ b/pkg/requirements.pip @@ -0,0 +1,8 @@ +jsonschema  #<=0.8 -- are we done with this conflict? +pyxdg +protobuf>=2.4.1 +protobuf.socketrpc +pyopenssl +python-dateutil + +#autopep8 -- ??? diff --git a/pkg/utils.py b/pkg/utils.py new file mode 100644 index 0000000..deace14 --- /dev/null +++ b/pkg/utils.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +# utils.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. + +""" +Utils to help in the setup process +""" + +import os +import re +import sys + + +def get_reqs_from_files(reqfiles): +    """ +    Returns the contents of the top requirement file listed as a +    string list with the lines + +    @param reqfiles: requirement files to parse +    @type reqfiles: list of str +    """ +    for reqfile in reqfiles: +        if os.path.isfile(reqfile): +            return open(reqfile, 'r').read().split('\n') + + +def parse_requirements(reqfiles=['requirements.txt', +                                 'requirements.pip', +                                 'pkg/requirements.pip']): +    """ +    Parses the requirement files provided. + +    Checks the value of LEAP_VENV_SKIP_PYSIDE to see if it should +    return PySide as a dep or not. Don't set, or set to 0 if you want +    to install it through pip. + +    @param reqfiles: requirement files to parse +    @type reqfiles: list of str +    """ + +    requirements = [] +    skip_pyside = os.getenv("LEAP_VENV_SKIP_PYSIDE", "0") != "0" +    for line in get_reqs_from_files(reqfiles): +        # -e git://foo.bar/baz/master#egg=foobar +        if re.match(r'\s*-e\s+', line): +            pass +            # do not try to do anything with externals on vcs +            #requirements.append(re.sub(r'\s*-e\s+.*#egg=(.*)$', r'\1', +                                #line)) +        # http://foo.bar/baz/foobar/zipball/master#egg=foobar +        elif re.match(r'\s*https?:', line): +            requirements.append(re.sub(r'\s*https?:.*#egg=(.*)$', r'\1', +                                line)) +        # -f lines are for index locations, and don't get used here +        elif re.match(r'\s*-f\s+', line): +            pass + +        # argparse is part of the standard library starting with 2.7 +        # adding it to the requirements list screws distro installs +        elif line == 'argparse' and sys.version_info >= (2, 7): +            pass +        elif line == 'PySide' and skip_pyside: +            pass +        # do not include comments +        elif line.lstrip().startswith('#'): +            pass +        else: +            if line != '': +                requirements.append(line) + +    return requirements @@ -19,20 +19,14 @@ setup file for leap.common  """  from setuptools import setup, find_packages -# XXX parse pkg/requirements.pip -requirements = [ -    "jsonschema", -    "pyxdg", -    'protobuf', -    'protobuf.socketrpc', -    "PyOpenSSL", -    "python-dateutil", -    "PyCrypto", -] +from pkg import utils +parsed_reqs = utils.parse_requirements() -#dependency_links = [ -    #"https://protobuf-socket-rpc.googlecode.com/files/protobuf.socketrpc-1.3.2.tar.gz#egg=protobuf.socketrpc" -#] +import versioneer +versioneer.versionfile_source = 'src/leap/common/_version.py' +versioneer.versionfile_build = 'leap/common/_version.py' +versioneer.tag_prefix = ''  # tags are like 1.2.0 +versioneer.parentdir_prefix = 'leap.common-'  tests_requirements = [      'mock', @@ -54,9 +48,8 @@ trove_classifiers = [  setup(      name='leap.common', -    # If you change version, do it also in -    # src/leap/common/__init__.py -    version='0.3.0', +    version=versioneer.get_version(), +    cmdclass=versioneer.get_cmdclass(),      url='https://leap.se/',      license='GPLv3+',      author='The LEAP Encryption Access Project', @@ -73,7 +66,7 @@ setup(      #packages=find_packages('src', exclude=['leap.common.tests']),      packages=find_packages('src'),      test_suite='leap.common.tests', -    install_requires=requirements, +    install_requires=parsed_reqs,      #dependency_links=dependency_links,      tests_require=tests_requirements,      include_package_data=True diff --git a/src/leap/common/__init__.py b/src/leap/common/__init__.py index 3946fe8..5619900 100644 --- a/src/leap/common/__init__.py +++ b/src/leap/common/__init__.py @@ -16,4 +16,6 @@ except ImportError:  __all__ = ["certs", "check", "files", "events"] -__version__ = "0.3.0" +from ._version import get_versions +__version__ = get_versions()['version'] +del get_versions diff --git a/src/leap/common/_version.py b/src/leap/common/_version.py new file mode 100644 index 0000000..597e2e4 --- /dev/null +++ b/src/leap/common/_version.py @@ -0,0 +1,203 @@ + +IN_LONG_VERSION_PY = True +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (build by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. Generated by +# versioneer-0.7+ (https://github.com/warner/python-versioneer) + +# these strings will be replaced by git during git-archive +git_refnames = "$Format:%d$" +git_full = "$Format:%H$" + + +import subprocess +import sys + +def run_command(args, cwd=None, verbose=False): +    try: +        # remember shell=False, so use git.cmd on windows, not just git +        p = subprocess.Popen(args, stdout=subprocess.PIPE, cwd=cwd) +    except EnvironmentError: +        e = sys.exc_info()[1] +        if verbose: +            print("unable to run %s" % args[0]) +            print(e) +        return None +    stdout = p.communicate()[0].strip() +    if sys.version >= '3': +        stdout = stdout.decode() +    if p.returncode != 0: +        if verbose: +            print("unable to run %s (error)" % args[0]) +        return None +    return stdout + + +import sys +import re +import os.path + +def get_expanded_variables(versionfile_source): +    # the code embedded in _version.py can just fetch the value of these +    # variables. When used from setup.py, we don't want to import +    # _version.py, so we do it with a regexp instead. This function is not +    # used from _version.py. +    variables = {} +    try: +        f = open(versionfile_source,"r") +        for line in f.readlines(): +            if line.strip().startswith("git_refnames ="): +                mo = re.search(r'=\s*"(.*)"', line) +                if mo: +                    variables["refnames"] = mo.group(1) +            if line.strip().startswith("git_full ="): +                mo = re.search(r'=\s*"(.*)"', line) +                if mo: +                    variables["full"] = mo.group(1) +        f.close() +    except EnvironmentError: +        pass +    return variables + +def versions_from_expanded_variables(variables, tag_prefix, verbose=False): +    refnames = variables["refnames"].strip() +    if refnames.startswith("$Format"): +        if verbose: +            print("variables are unexpanded, not using") +        return {} # unexpanded, so not in an unpacked git-archive tarball +    refs = set([r.strip() for r in refnames.strip("()").split(",")]) +    # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of +    # just "foo-1.0". If we see a "tag: " prefix, prefer those. +    TAG = "tag: " +    tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) +    if not tags: +        # Either we're using git < 1.8.3, or there really are no tags. We use +        # a heuristic: assume all version tags have a digit. The old git %d +        # expansion behaves like git log --decorate=short and strips out the +        # refs/heads/ and refs/tags/ prefixes that would let us distinguish +        # between branches and tags. By ignoring refnames without digits, we +        # filter out many common branch names like "release" and +        # "stabilization", as well as "HEAD" and "master". +        tags = set([r for r in refs if re.search(r'\d', r)]) +        if verbose: +            print("discarding '%s', no digits" % ",".join(refs-tags)) +    if verbose: +        print("likely tags: %s" % ",".join(sorted(tags))) +    for ref in sorted(tags): +        # sorting will prefer e.g. "2.0" over "2.0rc1" +        if ref.startswith(tag_prefix): +            r = ref[len(tag_prefix):] +            if verbose: +                print("picking %s" % r) +            return { "version": r, +                     "full": variables["full"].strip() } +    # no suitable tags, so we use the full revision id +    if verbose: +        print("no suitable tags, using full revision id") +    return { "version": variables["full"].strip(), +             "full": variables["full"].strip() } + +def versions_from_vcs(tag_prefix, versionfile_source, verbose=False): +    # this runs 'git' from the root of the source tree. That either means +    # someone ran a setup.py command (and this code is in versioneer.py, so +    # IN_LONG_VERSION_PY=False, thus the containing directory is the root of +    # the source tree), or someone ran a project-specific entry point (and +    # this code is in _version.py, so IN_LONG_VERSION_PY=True, thus the +    # containing directory is somewhere deeper in the source tree). This only +    # gets called if the git-archive 'subst' variables were *not* expanded, +    # and _version.py hasn't already been rewritten with a short version +    # string, meaning we're inside a checked out source tree. + +    try: +        here = os.path.abspath(__file__) +    except NameError: +        # some py2exe/bbfreeze/non-CPython implementations don't do __file__ +        return {} # not always correct + +    # versionfile_source is the relative path from the top of the source tree +    # (where the .git directory might live) to this file. Invert this to find +    # the root from __file__. +    root = here +    if IN_LONG_VERSION_PY: +        for i in range(len(versionfile_source.split("/"))): +            root = os.path.dirname(root) +    else: +        root = os.path.dirname(here) +    if not os.path.exists(os.path.join(root, ".git")): +        if verbose: +            print("no .git in %s" % root) +        return {} + +    GIT = "git" +    if sys.platform == "win32": +        GIT = "git.cmd" +    stdout = run_command([GIT, "describe", "--tags", "--dirty", "--always"], +                         cwd=root) +    if stdout is None: +        return {} +    if not stdout.startswith(tag_prefix): +        if verbose: +            print("tag '%s' doesn't start with prefix '%s'" % (stdout, tag_prefix)) +        return {} +    tag = stdout[len(tag_prefix):] +    stdout = run_command([GIT, "rev-parse", "HEAD"], cwd=root) +    if stdout is None: +        return {} +    full = stdout.strip() +    if tag.endswith("-dirty"): +        full += "-dirty" +    return {"version": tag, "full": full} + + +def versions_from_parentdir(parentdir_prefix, versionfile_source, verbose=False): +    if IN_LONG_VERSION_PY: +        # We're running from _version.py. If it's from a source tree +        # (execute-in-place), we can work upwards to find the root of the +        # tree, and then check the parent directory for a version string. If +        # it's in an installed application, there's no hope. +        try: +            here = os.path.abspath(__file__) +        except NameError: +            # py2exe/bbfreeze/non-CPython don't have __file__ +            return {} # without __file__, we have no hope +        # versionfile_source is the relative path from the top of the source +        # tree to _version.py. Invert this to find the root from __file__. +        root = here +        for i in range(len(versionfile_source.split("/"))): +            root = os.path.dirname(root) +    else: +        # we're running from versioneer.py, which means we're running from +        # the setup.py in a source tree. sys.argv[0] is setup.py in the root. +        here = os.path.abspath(sys.argv[0]) +        root = os.path.dirname(here) + +    # Source tarballs conventionally unpack into a directory that includes +    # both the project name and a version string. +    dirname = os.path.basename(root) +    if not dirname.startswith(parentdir_prefix): +        if verbose: +            print("guessing rootdir is '%s', but '%s' doesn't start with prefix '%s'" % +                  (root, dirname, parentdir_prefix)) +        return None +    return {"version": dirname[len(parentdir_prefix):], "full": ""} + +tag_prefix = "" +parentdir_prefix = "leap.common-" +versionfile_source = "src/leap/common/_version.py" + +def get_versions(default={"version": "unknown", "full": ""}, verbose=False): +    variables = { "refnames": git_refnames, "full": git_full } +    ver = versions_from_expanded_variables(variables, tag_prefix, verbose) +    if not ver: +        ver = versions_from_vcs(tag_prefix, versionfile_source, verbose) +    if not ver: +        ver = versions_from_parentdir(parentdir_prefix, versionfile_source, +                                      verbose) +    if not ver: +        ver = default +    return ver + diff --git a/src/leap/common/events/Makefile b/src/leap/common/events/Makefile index 4f73dea..5b7e60d 100644 --- a/src/leap/common/events/Makefile +++ b/src/leap/common/events/Makefile @@ -25,7 +25,7 @@ all: events_pb2.py  %_pb2.py: %.proto  	$(PROTOC) --python_out=./ $< -	autopep8 --in-place --aggressive $@ +#	autopep8 --in-place --aggressive $@  clean:  	rm -f *_pb2.py diff --git a/src/leap/common/events/events.proto b/src/leap/common/events/events.proto index b844f42..2708b93 100644 --- a/src/leap/common/events/events.proto +++ b/src/leap/common/events/events.proto @@ -34,6 +34,35 @@ enum Event {    UPDATER_NEW_UPDATES = 11;    UPDATER_DONE_UPDATING = 12;    RAISE_WINDOW = 13; +  SMTP_SERVICE_STARTED = 14; +  SMTP_SERVICE_FAILED_TO_START = 15; +  SMTP_RECIPIENT_ACCEPTED_ENCRYPTED = 16; +  SMTP_RECIPIENT_ACCEPTED_UNENCRYPTED = 17; +  SMTP_RECIPIENT_REJECTED = 18; +  SMTP_START_ENCRYPT_AND_SIGN = 19; +  SMTP_END_ENCRYPT_AND_SIGN = 20; +  SMTP_START_SIGN = 21; +  SMTP_END_SIGN = 22; +  SMTP_SEND_MESSAGE_START = 23; +  SMTP_SEND_MESSAGE_SUCCESS = 24; +  SMTP_SEND_MESSAGE_ERROR = 25; +  SMTP_CONNECTION_LOST = 26; +  IMAP_SERVICE_STARTED = 30; +  IMAP_SERVICE_FAILED_TO_START = 31; +  IMAP_CLIENT_LOGIN = 32; +  IMAP_FETCHED_INCOMING = 33; +  IMAP_MSG_PROCESSING = 34; +  IMAP_MSG_DECRYPTED = 35; +  IMAP_MSG_SAVED_LOCALLY = 36; +  IMAP_MSG_DELETED_INCOMING = 37; +  IMAP_UNHANDLED_ERROR = 38; +  IMAP_UNREAD_MAIL = 39; +  KEYMANAGER_LOOKING_FOR_KEY = 40; +  KEYMANAGER_KEY_FOUND = 41; +  KEYMANAGER_KEY_NOT_FOUND = 42; +  KEYMANAGER_STARTED_KEY_GENERATION = 43; +  KEYMANAGER_FINISHED_KEY_GENERATION = 44; +  KEYMANAGER_DONE_UPLOADING_KEYS = 45;  } diff --git a/src/leap/common/events/events_pb2.py b/src/leap/common/events/events_pb2.py index e25c7da..6151714 100644 --- a/src/leap/common/events/events_pb2.py +++ b/src/leap/common/events/events_pb2.py @@ -9,74 +9,191 @@ from google.protobuf import descriptor_pb2  # @@protoc_insertion_point(imports) +  DESCRIPTOR = descriptor.FileDescriptor( -    name='events.proto', -    package='leap.common.events', -    serialized_pb='\n\x0c\x65vents.proto\x12\x12leap.common.events\"\x97\x01\n\rSignalRequest\x12(\n\x05\x65vent\x18\x01 \x02(\x0e\x32\x19.leap.common.events.Event\x12\x0f\n\x07\x63ontent\x18\x02 \x02(\t\x12\x12\n\nmac_method\x18\x03 \x02(\t\x12\x0b\n\x03mac\x18\x04 \x02(\x0c\x12\x12\n\nenc_method\x18\x05 \x01(\t\x12\x16\n\x0e\x65rror_occurred\x18\x06 \x01(\x08\"j\n\x0fRegisterRequest\x12(\n\x05\x65vent\x18\x01 \x02(\x0e\x32\x19.leap.common.events.Event\x12\x0c\n\x04port\x18\x02 \x02(\x05\x12\x12\n\nmac_method\x18\x03 \x02(\t\x12\x0b\n\x03mac\x18\x04 \x02(\x0c\"l\n\x11UnregisterRequest\x12(\n\x05\x65vent\x18\x01 \x02(\x0e\x32\x19.leap.common.events.Event\x12\x0c\n\x04port\x18\x02 \x02(\x05\x12\x12\n\nmac_method\x18\x03 \x02(\t\x12\x0b\n\x03mac\x18\x04 \x02(\x0c\"\r\n\x0bPingRequest\"\x82\x01\n\rEventResponse\x12\x38\n\x06status\x18\x01 \x02(\x0e\x32(.leap.common.events.EventResponse.Status\x12\x0e\n\x06result\x18\x02 \x01(\t\"\'\n\x06Status\x12\x06\n\x02OK\x10\x01\x12\n\n\x06UNAUTH\x10\x02\x12\t\n\x05\x45RROR\x10\x03*\xe7\x02\n\x05\x45vent\x12\x15\n\x11\x43LIENT_SESSION_ID\x10\x01\x12\x0e\n\nCLIENT_UID\x10\x02\x12\x19\n\x15SOLEDAD_CREATING_KEYS\x10\x03\x12\x1e\n\x1aSOLEDAD_DONE_CREATING_KEYS\x10\x04\x12\x1a\n\x16SOLEDAD_UPLOADING_KEYS\x10\x05\x12\x1f\n\x1bSOLEDAD_DONE_UPLOADING_KEYS\x10\x06\x12\x1c\n\x18SOLEDAD_DOWNLOADING_KEYS\x10\x07\x12!\n\x1dSOLEDAD_DONE_DOWNLOADING_KEYS\x10\x08\x12\x1c\n\x18SOLEDAD_NEW_DATA_TO_SYNC\x10\t\x12\x1a\n\x16SOLEDAD_DONE_DATA_SYNC\x10\n\x12\x17\n\x13UPDATER_NEW_UPDATES\x10\x0b\x12\x19\n\x15UPDATER_DONE_UPDATING\x10\x0c\x12\x10\n\x0cRAISE_WINDOW\x10\r2\xdd\x02\n\x13\x45ventsServerService\x12J\n\x04ping\x12\x1f.leap.common.events.PingRequest\x1a!.leap.common.events.EventResponse\x12R\n\x08register\x12#.leap.common.events.RegisterRequest\x1a!.leap.common.events.EventResponse\x12V\n\nunregister\x12%.leap.common.events.UnregisterRequest\x1a!.leap.common.events.EventResponse\x12N\n\x06signal\x12!.leap.common.events.SignalRequest\x1a!.leap.common.events.EventResponse2\xb1\x01\n\x13\x45ventsClientService\x12J\n\x04ping\x12\x1f.leap.common.events.PingRequest\x1a!.leap.common.events.EventResponse\x12N\n\x06signal\x12!.leap.common.events.SignalRequest\x1a!.leap.common.events.EventResponseB\x03\x90\x01\x01') +  name='events.proto', +  package='leap.common.events', +  serialized_pb='\n\x0c\x65vents.proto\x12\x12leap.common.events\"\x97\x01\n\rSignalRequest\x12(\n\x05\x65vent\x18\x01 \x02(\x0e\x32\x19.leap.common.events.Event\x12\x0f\n\x07\x63ontent\x18\x02 \x02(\t\x12\x12\n\nmac_method\x18\x03 \x02(\t\x12\x0b\n\x03mac\x18\x04 \x02(\x0c\x12\x12\n\nenc_method\x18\x05 \x01(\t\x12\x16\n\x0e\x65rror_occurred\x18\x06 \x01(\x08\"j\n\x0fRegisterRequest\x12(\n\x05\x65vent\x18\x01 \x02(\x0e\x32\x19.leap.common.events.Event\x12\x0c\n\x04port\x18\x02 \x02(\x05\x12\x12\n\nmac_method\x18\x03 \x02(\t\x12\x0b\n\x03mac\x18\x04 \x02(\x0c\"l\n\x11UnregisterRequest\x12(\n\x05\x65vent\x18\x01 \x02(\x0e\x32\x19.leap.common.events.Event\x12\x0c\n\x04port\x18\x02 \x02(\x05\x12\x12\n\nmac_method\x18\x03 \x02(\t\x12\x0b\n\x03mac\x18\x04 \x02(\x0c\"\r\n\x0bPingRequest\"\x82\x01\n\rEventResponse\x12\x38\n\x06status\x18\x01 \x02(\x0e\x32(.leap.common.events.EventResponse.Status\x12\x0e\n\x06result\x18\x02 \x01(\t\"\'\n\x06Status\x12\x06\n\x02OK\x10\x01\x12\n\n\x06UNAUTH\x10\x02\x12\t\n\x05\x45RROR\x10\x03*\xc0\t\n\x05\x45vent\x12\x15\n\x11\x43LIENT_SESSION_ID\x10\x01\x12\x0e\n\nCLIENT_UID\x10\x02\x12\x19\n\x15SOLEDAD_CREATING_KEYS\x10\x03\x12\x1e\n\x1aSOLEDAD_DONE_CREATING_KEYS\x10\x04\x12\x1a\n\x16SOLEDAD_UPLOADING_KEYS\x10\x05\x12\x1f\n\x1bSOLEDAD_DONE_UPLOADING_KEYS\x10\x06\x12\x1c\n\x18SOLEDAD_DOWNLOADING_KEYS\x10\x07\x12!\n\x1dSOLEDAD_DONE_DOWNLOADING_KEYS\x10\x08\x12\x1c\n\x18SOLEDAD_NEW_DATA_TO_SYNC\x10\t\x12\x1a\n\x16SOLEDAD_DONE_DATA_SYNC\x10\n\x12\x17\n\x13UPDATER_NEW_UPDATES\x10\x0b\x12\x19\n\x15UPDATER_DONE_UPDATING\x10\x0c\x12\x10\n\x0cRAISE_WINDOW\x10\r\x12\x18\n\x14SMTP_SERVICE_STARTED\x10\x0e\x12 \n\x1cSMTP_SERVICE_FAILED_TO_START\x10\x0f\x12%\n!SMTP_RECIPIENT_ACCEPTED_ENCRYPTED\x10\x10\x12\'\n#SMTP_RECIPIENT_ACCEPTED_UNENCRYPTED\x10\x11\x12\x1b\n\x17SMTP_RECIPIENT_REJECTED\x10\x12\x12\x1f\n\x1bSMTP_START_ENCRYPT_AND_SIGN\x10\x13\x12\x1d\n\x19SMTP_END_ENCRYPT_AND_SIGN\x10\x14\x12\x13\n\x0fSMTP_START_SIGN\x10\x15\x12\x11\n\rSMTP_END_SIGN\x10\x16\x12\x1b\n\x17SMTP_SEND_MESSAGE_START\x10\x17\x12\x1d\n\x19SMTP_SEND_MESSAGE_SUCCESS\x10\x18\x12\x1b\n\x17SMTP_SEND_MESSAGE_ERROR\x10\x19\x12\x18\n\x14SMTP_CONNECTION_LOST\x10\x1a\x12\x18\n\x14IMAP_SERVICE_STARTED\x10\x1e\x12 \n\x1cIMAP_SERVICE_FAILED_TO_START\x10\x1f\x12\x15\n\x11IMAP_CLIENT_LOGIN\x10 \x12\x19\n\x15IMAP_FETCHED_INCOMING\x10!\x12\x17\n\x13IMAP_MSG_PROCESSING\x10\"\x12\x16\n\x12IMAP_MSG_DECRYPTED\x10#\x12\x1a\n\x16IMAP_MSG_SAVED_LOCALLY\x10$\x12\x1d\n\x19IMAP_MSG_DELETED_INCOMING\x10%\x12\x18\n\x14IMAP_UNHANDLED_ERROR\x10&\x12\x14\n\x10IMAP_UNREAD_MAIL\x10\'\x12\x1e\n\x1aKEYMANAGER_LOOKING_FOR_KEY\x10(\x12\x18\n\x14KEYMANAGER_KEY_FOUND\x10)\x12\x1c\n\x18KEYMANAGER_KEY_NOT_FOUND\x10*\x12%\n!KEYMANAGER_STARTED_KEY_GENERATION\x10+\x12&\n\"KEYMANAGER_FINISHED_KEY_GENERATION\x10,\x12\"\n\x1eKEYMANAGER_DONE_UPLOADING_KEYS\x10-2\xdd\x02\n\x13\x45ventsServerService\x12J\n\x04ping\x12\x1f.leap.common.events.PingRequest\x1a!.leap.common.events.EventResponse\x12R\n\x08register\x12#.leap.common.events.RegisterRequest\x1a!.leap.common.events.EventResponse\x12V\n\nunregister\x12%.leap.common.events.UnregisterRequest\x1a!.leap.common.events.EventResponse\x12N\n\x06signal\x12!.leap.common.events.SignalRequest\x1a!.leap.common.events.EventResponse2\xb1\x01\n\x13\x45ventsClientService\x12J\n\x04ping\x12\x1f.leap.common.events.PingRequest\x1a!.leap.common.events.EventResponse\x12N\n\x06signal\x12!.leap.common.events.SignalRequest\x1a!.leap.common.events.EventResponseB\x03\x90\x01\x01')  _EVENT = descriptor.EnumDescriptor( -    name='Event', -    full_name='leap.common.events.Event', -    filename=None, -    file=DESCRIPTOR, -    values=[ -        descriptor.EnumValueDescriptor( -            name='CLIENT_SESSION_ID', index=0, number=1, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='CLIENT_UID', index=1, number=2, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='SOLEDAD_CREATING_KEYS', index=2, number=3, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='SOLEDAD_DONE_CREATING_KEYS', index=3, number=4, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='SOLEDAD_UPLOADING_KEYS', index=4, number=5, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='SOLEDAD_DONE_UPLOADING_KEYS', index=5, number=6, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='SOLEDAD_DOWNLOADING_KEYS', index=6, number=7, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='SOLEDAD_DONE_DOWNLOADING_KEYS', index=7, number=8, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='SOLEDAD_NEW_DATA_TO_SYNC', index=8, number=9, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='SOLEDAD_DONE_DATA_SYNC', index=9, number=10, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='UPDATER_NEW_UPDATES', index=10, number=11, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='UPDATER_DONE_UPDATING', index=11, number=12, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='RAISE_WINDOW', index=12, number=13, -            options=None, -            type=None), -    ], -    containing_type=None, -    options=None, -    serialized_start=557, -    serialized_end=916, +  name='Event', +  full_name='leap.common.events.Event', +  filename=None, +  file=DESCRIPTOR, +  values=[ +    descriptor.EnumValueDescriptor( +      name='CLIENT_SESSION_ID', index=0, number=1, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='CLIENT_UID', index=1, number=2, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SOLEDAD_CREATING_KEYS', index=2, number=3, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SOLEDAD_DONE_CREATING_KEYS', index=3, number=4, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SOLEDAD_UPLOADING_KEYS', index=4, number=5, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SOLEDAD_DONE_UPLOADING_KEYS', index=5, number=6, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SOLEDAD_DOWNLOADING_KEYS', index=6, number=7, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SOLEDAD_DONE_DOWNLOADING_KEYS', index=7, number=8, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SOLEDAD_NEW_DATA_TO_SYNC', index=8, number=9, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SOLEDAD_DONE_DATA_SYNC', index=9, number=10, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='UPDATER_NEW_UPDATES', index=10, number=11, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='UPDATER_DONE_UPDATING', index=11, number=12, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='RAISE_WINDOW', index=12, number=13, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_SERVICE_STARTED', index=13, number=14, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_SERVICE_FAILED_TO_START', index=14, number=15, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_RECIPIENT_ACCEPTED_ENCRYPTED', index=15, number=16, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_RECIPIENT_ACCEPTED_UNENCRYPTED', index=16, number=17, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_RECIPIENT_REJECTED', index=17, number=18, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_START_ENCRYPT_AND_SIGN', index=18, number=19, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_END_ENCRYPT_AND_SIGN', index=19, number=20, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_START_SIGN', index=20, number=21, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_END_SIGN', index=21, number=22, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_SEND_MESSAGE_START', index=22, number=23, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_SEND_MESSAGE_SUCCESS', index=23, number=24, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_SEND_MESSAGE_ERROR', index=24, number=25, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='SMTP_CONNECTION_LOST', index=25, number=26, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='IMAP_SERVICE_STARTED', index=26, number=30, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='IMAP_SERVICE_FAILED_TO_START', index=27, number=31, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='IMAP_CLIENT_LOGIN', index=28, number=32, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='IMAP_FETCHED_INCOMING', index=29, number=33, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='IMAP_MSG_PROCESSING', index=30, number=34, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='IMAP_MSG_DECRYPTED', index=31, number=35, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='IMAP_MSG_SAVED_LOCALLY', index=32, number=36, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='IMAP_MSG_DELETED_INCOMING', index=33, number=37, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='IMAP_UNHANDLED_ERROR', index=34, number=38, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='IMAP_UNREAD_MAIL', index=35, number=39, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='KEYMANAGER_LOOKING_FOR_KEY', index=36, number=40, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='KEYMANAGER_KEY_FOUND', index=37, number=41, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='KEYMANAGER_KEY_NOT_FOUND', index=38, number=42, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='KEYMANAGER_STARTED_KEY_GENERATION', index=39, number=43, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='KEYMANAGER_FINISHED_KEY_GENERATION', index=40, number=44, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='KEYMANAGER_DONE_UPLOADING_KEYS', index=41, number=45, +      options=None, +      type=None), +  ], +  containing_type=None, +  options=None, +  serialized_start=557, +  serialized_end=1773,  ) @@ -93,393 +210,411 @@ SOLEDAD_DONE_DATA_SYNC = 10  UPDATER_NEW_UPDATES = 11  UPDATER_DONE_UPDATING = 12  RAISE_WINDOW = 13 +SMTP_SERVICE_STARTED = 14 +SMTP_SERVICE_FAILED_TO_START = 15 +SMTP_RECIPIENT_ACCEPTED_ENCRYPTED = 16 +SMTP_RECIPIENT_ACCEPTED_UNENCRYPTED = 17 +SMTP_RECIPIENT_REJECTED = 18 +SMTP_START_ENCRYPT_AND_SIGN = 19 +SMTP_END_ENCRYPT_AND_SIGN = 20 +SMTP_START_SIGN = 21 +SMTP_END_SIGN = 22 +SMTP_SEND_MESSAGE_START = 23 +SMTP_SEND_MESSAGE_SUCCESS = 24 +SMTP_SEND_MESSAGE_ERROR = 25 +SMTP_CONNECTION_LOST = 26 +IMAP_SERVICE_STARTED = 30 +IMAP_SERVICE_FAILED_TO_START = 31 +IMAP_CLIENT_LOGIN = 32 +IMAP_FETCHED_INCOMING = 33 +IMAP_MSG_PROCESSING = 34 +IMAP_MSG_DECRYPTED = 35 +IMAP_MSG_SAVED_LOCALLY = 36 +IMAP_MSG_DELETED_INCOMING = 37 +IMAP_UNHANDLED_ERROR = 38 +IMAP_UNREAD_MAIL = 39 +KEYMANAGER_LOOKING_FOR_KEY = 40 +KEYMANAGER_KEY_FOUND = 41 +KEYMANAGER_KEY_NOT_FOUND = 42 +KEYMANAGER_STARTED_KEY_GENERATION = 43 +KEYMANAGER_FINISHED_KEY_GENERATION = 44 +KEYMANAGER_DONE_UPLOADING_KEYS = 45  _EVENTRESPONSE_STATUS = descriptor.EnumDescriptor( -    name='Status', -    full_name='leap.common.events.EventResponse.Status', -    filename=None, -    file=DESCRIPTOR, -    values=[ -        descriptor.EnumValueDescriptor( -            name='OK', index=0, number=1, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='UNAUTH', index=1, number=2, -            options=None, -            type=None), -        descriptor.EnumValueDescriptor( -            name='ERROR', index=2, number=3, -            options=None, -            type=None), -    ], -    containing_type=None, -    options=None, -    serialized_start=515, -    serialized_end=554, +  name='Status', +  full_name='leap.common.events.EventResponse.Status', +  filename=None, +  file=DESCRIPTOR, +  values=[ +    descriptor.EnumValueDescriptor( +      name='OK', index=0, number=1, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='UNAUTH', index=1, number=2, +      options=None, +      type=None), +    descriptor.EnumValueDescriptor( +      name='ERROR', index=2, number=3, +      options=None, +      type=None), +  ], +  containing_type=None, +  options=None, +  serialized_start=515, +  serialized_end=554,  )  _SIGNALREQUEST = descriptor.Descriptor( -    name='SignalRequest', -    full_name='leap.common.events.SignalRequest', -    filename=None, -    file=DESCRIPTOR, -    containing_type=None, -    fields=[ -        descriptor.FieldDescriptor( -            name='event', full_name='leap.common.events.SignalRequest.event', index=0, -            number=1, type=14, cpp_type=8, label=2, -            has_default_value=False, default_value=1, -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='content', full_name='leap.common.events.SignalRequest.content', index=1, -            number=2, type=9, cpp_type=9, label=2, -            has_default_value=False, default_value=unicode("", "utf-8"), -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='mac_method', full_name='leap.common.events.SignalRequest.mac_method', index=2, -            number=3, type=9, cpp_type=9, label=2, -            has_default_value=False, default_value=unicode("", "utf-8"), -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='mac', full_name='leap.common.events.SignalRequest.mac', index=3, -            number=4, type=12, cpp_type=9, label=2, -            has_default_value=False, default_value="", -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='enc_method', full_name='leap.common.events.SignalRequest.enc_method', index=4, -            number=5, type=9, cpp_type=9, label=1, -            has_default_value=False, default_value=unicode("", "utf-8"), -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='error_occurred', full_name='leap.common.events.SignalRequest.error_occurred', index=5, -            number=6, type=8, cpp_type=7, label=1, -            has_default_value=False, default_value=False, -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -    ], -    extensions=[ -    ], -    nested_types=[], -    enum_types=[ -    ], -    options=None, -    is_extendable=False, -    extension_ranges=[], -    serialized_start=37, -    serialized_end=188, +  name='SignalRequest', +  full_name='leap.common.events.SignalRequest', +  filename=None, +  file=DESCRIPTOR, +  containing_type=None, +  fields=[ +    descriptor.FieldDescriptor( +      name='event', full_name='leap.common.events.SignalRequest.event', index=0, +      number=1, type=14, cpp_type=8, label=2, +      has_default_value=False, default_value=1, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='content', full_name='leap.common.events.SignalRequest.content', index=1, +      number=2, type=9, cpp_type=9, label=2, +      has_default_value=False, default_value=unicode("", "utf-8"), +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='mac_method', full_name='leap.common.events.SignalRequest.mac_method', index=2, +      number=3, type=9, cpp_type=9, label=2, +      has_default_value=False, default_value=unicode("", "utf-8"), +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='mac', full_name='leap.common.events.SignalRequest.mac', index=3, +      number=4, type=12, cpp_type=9, label=2, +      has_default_value=False, default_value="", +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='enc_method', full_name='leap.common.events.SignalRequest.enc_method', index=4, +      number=5, type=9, cpp_type=9, label=1, +      has_default_value=False, default_value=unicode("", "utf-8"), +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='error_occurred', full_name='leap.common.events.SignalRequest.error_occurred', index=5, +      number=6, type=8, cpp_type=7, label=1, +      has_default_value=False, default_value=False, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +  ], +  extensions=[ +  ], +  nested_types=[], +  enum_types=[ +  ], +  options=None, +  is_extendable=False, +  extension_ranges=[], +  serialized_start=37, +  serialized_end=188,  )  _REGISTERREQUEST = descriptor.Descriptor( -    name='RegisterRequest', -    full_name='leap.common.events.RegisterRequest', -    filename=None, -    file=DESCRIPTOR, -    containing_type=None, -    fields=[ -        descriptor.FieldDescriptor( -            name='event', full_name='leap.common.events.RegisterRequest.event', index=0, -            number=1, type=14, cpp_type=8, label=2, -            has_default_value=False, default_value=1, -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='port', full_name='leap.common.events.RegisterRequest.port', index=1, -            number=2, type=5, cpp_type=1, label=2, -            has_default_value=False, default_value=0, -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='mac_method', full_name='leap.common.events.RegisterRequest.mac_method', index=2, -            number=3, type=9, cpp_type=9, label=2, -            has_default_value=False, default_value=unicode("", "utf-8"), -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='mac', full_name='leap.common.events.RegisterRequest.mac', index=3, -            number=4, type=12, cpp_type=9, label=2, -            has_default_value=False, default_value="", -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -    ], -    extensions=[ -    ], -    nested_types=[], -    enum_types=[ -    ], -    options=None, -    is_extendable=False, -    extension_ranges=[], -    serialized_start=190, -    serialized_end=296, +  name='RegisterRequest', +  full_name='leap.common.events.RegisterRequest', +  filename=None, +  file=DESCRIPTOR, +  containing_type=None, +  fields=[ +    descriptor.FieldDescriptor( +      name='event', full_name='leap.common.events.RegisterRequest.event', index=0, +      number=1, type=14, cpp_type=8, label=2, +      has_default_value=False, default_value=1, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='port', full_name='leap.common.events.RegisterRequest.port', index=1, +      number=2, type=5, cpp_type=1, label=2, +      has_default_value=False, default_value=0, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='mac_method', full_name='leap.common.events.RegisterRequest.mac_method', index=2, +      number=3, type=9, cpp_type=9, label=2, +      has_default_value=False, default_value=unicode("", "utf-8"), +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='mac', full_name='leap.common.events.RegisterRequest.mac', index=3, +      number=4, type=12, cpp_type=9, label=2, +      has_default_value=False, default_value="", +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +  ], +  extensions=[ +  ], +  nested_types=[], +  enum_types=[ +  ], +  options=None, +  is_extendable=False, +  extension_ranges=[], +  serialized_start=190, +  serialized_end=296,  )  _UNREGISTERREQUEST = descriptor.Descriptor( -    name='UnregisterRequest', -    full_name='leap.common.events.UnregisterRequest', -    filename=None, -    file=DESCRIPTOR, -    containing_type=None, -    fields=[ -        descriptor.FieldDescriptor( -            name='event', full_name='leap.common.events.UnregisterRequest.event', index=0, -            number=1, type=14, cpp_type=8, label=2, -            has_default_value=False, default_value=1, -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='port', full_name='leap.common.events.UnregisterRequest.port', index=1, -            number=2, type=5, cpp_type=1, label=2, -            has_default_value=False, default_value=0, -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='mac_method', full_name='leap.common.events.UnregisterRequest.mac_method', index=2, -            number=3, type=9, cpp_type=9, label=2, -            has_default_value=False, default_value=unicode("", "utf-8"), -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='mac', full_name='leap.common.events.UnregisterRequest.mac', index=3, -            number=4, type=12, cpp_type=9, label=2, -            has_default_value=False, default_value="", -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -    ], -    extensions=[ -    ], -    nested_types=[], -    enum_types=[ -    ], -    options=None, -    is_extendable=False, -    extension_ranges=[], -    serialized_start=298, -    serialized_end=406, +  name='UnregisterRequest', +  full_name='leap.common.events.UnregisterRequest', +  filename=None, +  file=DESCRIPTOR, +  containing_type=None, +  fields=[ +    descriptor.FieldDescriptor( +      name='event', full_name='leap.common.events.UnregisterRequest.event', index=0, +      number=1, type=14, cpp_type=8, label=2, +      has_default_value=False, default_value=1, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='port', full_name='leap.common.events.UnregisterRequest.port', index=1, +      number=2, type=5, cpp_type=1, label=2, +      has_default_value=False, default_value=0, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='mac_method', full_name='leap.common.events.UnregisterRequest.mac_method', index=2, +      number=3, type=9, cpp_type=9, label=2, +      has_default_value=False, default_value=unicode("", "utf-8"), +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='mac', full_name='leap.common.events.UnregisterRequest.mac', index=3, +      number=4, type=12, cpp_type=9, label=2, +      has_default_value=False, default_value="", +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +  ], +  extensions=[ +  ], +  nested_types=[], +  enum_types=[ +  ], +  options=None, +  is_extendable=False, +  extension_ranges=[], +  serialized_start=298, +  serialized_end=406,  )  _PINGREQUEST = descriptor.Descriptor( -    name='PingRequest', -    full_name='leap.common.events.PingRequest', -    filename=None, -    file=DESCRIPTOR, -    containing_type=None, -    fields=[ -    ], -    extensions=[ -    ], -    nested_types=[], -    enum_types=[ -    ], -    options=None, -    is_extendable=False, -    extension_ranges=[], -    serialized_start=408, -    serialized_end=421, +  name='PingRequest', +  full_name='leap.common.events.PingRequest', +  filename=None, +  file=DESCRIPTOR, +  containing_type=None, +  fields=[ +  ], +  extensions=[ +  ], +  nested_types=[], +  enum_types=[ +  ], +  options=None, +  is_extendable=False, +  extension_ranges=[], +  serialized_start=408, +  serialized_end=421,  )  _EVENTRESPONSE = descriptor.Descriptor( -    name='EventResponse', -    full_name='leap.common.events.EventResponse', -    filename=None, -    file=DESCRIPTOR, -    containing_type=None, -    fields=[ -        descriptor.FieldDescriptor( -            name='status', full_name='leap.common.events.EventResponse.status', index=0, -            number=1, type=14, cpp_type=8, label=2, -            has_default_value=False, default_value=1, -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -        descriptor.FieldDescriptor( -            name='result', full_name='leap.common.events.EventResponse.result', index=1, -            number=2, type=9, cpp_type=9, label=1, -            has_default_value=False, default_value=unicode("", "utf-8"), -            message_type=None, enum_type=None, containing_type=None, -            is_extension=False, extension_scope=None, -            options=None), -    ], -    extensions=[ -    ], -    nested_types=[], -    enum_types=[ -        _EVENTRESPONSE_STATUS, -    ], -    options=None, -    is_extendable=False, -    extension_ranges=[], -    serialized_start=424, -    serialized_end=554, +  name='EventResponse', +  full_name='leap.common.events.EventResponse', +  filename=None, +  file=DESCRIPTOR, +  containing_type=None, +  fields=[ +    descriptor.FieldDescriptor( +      name='status', full_name='leap.common.events.EventResponse.status', index=0, +      number=1, type=14, cpp_type=8, label=2, +      has_default_value=False, default_value=1, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    descriptor.FieldDescriptor( +      name='result', full_name='leap.common.events.EventResponse.result', index=1, +      number=2, type=9, cpp_type=9, label=1, +      has_default_value=False, default_value=unicode("", "utf-8"), +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +  ], +  extensions=[ +  ], +  nested_types=[], +  enum_types=[ +    _EVENTRESPONSE_STATUS, +  ], +  options=None, +  is_extendable=False, +  extension_ranges=[], +  serialized_start=424, +  serialized_end=554,  )  _SIGNALREQUEST.fields_by_name['event'].enum_type = _EVENT  _REGISTERREQUEST.fields_by_name['event'].enum_type = _EVENT  _UNREGISTERREQUEST.fields_by_name['event'].enum_type = _EVENT  _EVENTRESPONSE.fields_by_name['status'].enum_type = _EVENTRESPONSE_STATUS -_EVENTRESPONSE_STATUS.containing_type = _EVENTRESPONSE +_EVENTRESPONSE_STATUS.containing_type = _EVENTRESPONSE;  DESCRIPTOR.message_types_by_name['SignalRequest'] = _SIGNALREQUEST  DESCRIPTOR.message_types_by_name['RegisterRequest'] = _REGISTERREQUEST  DESCRIPTOR.message_types_by_name['UnregisterRequest'] = _UNREGISTERREQUEST  DESCRIPTOR.message_types_by_name['PingRequest'] = _PINGREQUEST  DESCRIPTOR.message_types_by_name['EventResponse'] = _EVENTRESPONSE -  class SignalRequest(message.Message): -    __metaclass__ = reflection.GeneratedProtocolMessageType -    DESCRIPTOR = _SIGNALREQUEST - -    # @@protoc_insertion_point(class_scope:leap.common.events.SignalRequest) +  __metaclass__ = reflection.GeneratedProtocolMessageType +  DESCRIPTOR = _SIGNALREQUEST +  # @@protoc_insertion_point(class_scope:leap.common.events.SignalRequest)  class RegisterRequest(message.Message): -    __metaclass__ = reflection.GeneratedProtocolMessageType -    DESCRIPTOR = _REGISTERREQUEST - -    # @@protoc_insertion_point(class_scope:leap.common.events.RegisterRequest) +  __metaclass__ = reflection.GeneratedProtocolMessageType +  DESCRIPTOR = _REGISTERREQUEST +  # @@protoc_insertion_point(class_scope:leap.common.events.RegisterRequest)  class UnregisterRequest(message.Message): -    __metaclass__ = reflection.GeneratedProtocolMessageType -    DESCRIPTOR = _UNREGISTERREQUEST - -    # @@protoc_insertion_point(class_scope:leap.common.events.UnregisterRequest) +  __metaclass__ = reflection.GeneratedProtocolMessageType +  DESCRIPTOR = _UNREGISTERREQUEST +  # @@protoc_insertion_point(class_scope:leap.common.events.UnregisterRequest)  class PingRequest(message.Message): -    __metaclass__ = reflection.GeneratedProtocolMessageType -    DESCRIPTOR = _PINGREQUEST - -    # @@protoc_insertion_point(class_scope:leap.common.events.PingRequest) +  __metaclass__ = reflection.GeneratedProtocolMessageType +  DESCRIPTOR = _PINGREQUEST +  # @@protoc_insertion_point(class_scope:leap.common.events.PingRequest)  class EventResponse(message.Message): -    __metaclass__ = reflection.GeneratedProtocolMessageType -    DESCRIPTOR = _EVENTRESPONSE +  __metaclass__ = reflection.GeneratedProtocolMessageType +  DESCRIPTOR = _EVENTRESPONSE -    # @@protoc_insertion_point(class_scope:leap.common.events.EventResponse) +  # @@protoc_insertion_point(class_scope:leap.common.events.EventResponse)  _EVENTSSERVERSERVICE = descriptor.ServiceDescriptor( -    name='EventsServerService', -    full_name='leap.common.events.EventsServerService', -    file=DESCRIPTOR, +  name='EventsServerService', +  full_name='leap.common.events.EventsServerService', +  file=DESCRIPTOR, +  index=0, +  options=None, +  serialized_start=1776, +  serialized_end=2125, +  methods=[ +  descriptor.MethodDescriptor( +    name='ping', +    full_name='leap.common.events.EventsServerService.ping',      index=0, +    containing_service=None, +    input_type=_PINGREQUEST, +    output_type=_EVENTRESPONSE,      options=None, -    serialized_start=919, -    serialized_end=1268, -    methods=[ -        descriptor.MethodDescriptor( -            name='ping', -            full_name='leap.common.events.EventsServerService.ping', -            index=0, -            containing_service=None, -            input_type=_PINGREQUEST, -            output_type=_EVENTRESPONSE, -            options=None, -        ), -        descriptor.MethodDescriptor( -            name='register', -            full_name='leap.common.events.EventsServerService.register', -            index=1, -            containing_service=None, -            input_type=_REGISTERREQUEST, -            output_type=_EVENTRESPONSE, -            options=None, -        ), -        descriptor.MethodDescriptor( -            name='unregister', -            full_name='leap.common.events.EventsServerService.unregister', -            index=2, -            containing_service=None, -            input_type=_UNREGISTERREQUEST, -            output_type=_EVENTRESPONSE, -            options=None, -        ), -        descriptor.MethodDescriptor( -            name='signal', -            full_name='leap.common.events.EventsServerService.signal', -            index=3, -            containing_service=None, -            input_type=_SIGNALREQUEST, -            output_type=_EVENTRESPONSE, -            options=None, -        ), -    ]) - +  ), +  descriptor.MethodDescriptor( +    name='register', +    full_name='leap.common.events.EventsServerService.register', +    index=1, +    containing_service=None, +    input_type=_REGISTERREQUEST, +    output_type=_EVENTRESPONSE, +    options=None, +  ), +  descriptor.MethodDescriptor( +    name='unregister', +    full_name='leap.common.events.EventsServerService.unregister', +    index=2, +    containing_service=None, +    input_type=_UNREGISTERREQUEST, +    output_type=_EVENTRESPONSE, +    options=None, +  ), +  descriptor.MethodDescriptor( +    name='signal', +    full_name='leap.common.events.EventsServerService.signal', +    index=3, +    containing_service=None, +    input_type=_SIGNALREQUEST, +    output_type=_EVENTRESPONSE, +    options=None, +  ), +])  class EventsServerService(service.Service): -    __metaclass__ = service_reflection.GeneratedServiceType -    DESCRIPTOR = _EVENTSSERVERSERVICE - - +  __metaclass__ = service_reflection.GeneratedServiceType +  DESCRIPTOR = _EVENTSSERVERSERVICE  class EventsServerService_Stub(EventsServerService): -    __metaclass__ = service_reflection.GeneratedServiceStubType -    DESCRIPTOR = _EVENTSSERVERSERVICE +  __metaclass__ = service_reflection.GeneratedServiceStubType +  DESCRIPTOR = _EVENTSSERVERSERVICE  _EVENTSCLIENTSERVICE = descriptor.ServiceDescriptor( -    name='EventsClientService', -    full_name='leap.common.events.EventsClientService', -    file=DESCRIPTOR, +  name='EventsClientService', +  full_name='leap.common.events.EventsClientService', +  file=DESCRIPTOR, +  index=1, +  options=None, +  serialized_start=2128, +  serialized_end=2305, +  methods=[ +  descriptor.MethodDescriptor( +    name='ping', +    full_name='leap.common.events.EventsClientService.ping', +    index=0, +    containing_service=None, +    input_type=_PINGREQUEST, +    output_type=_EVENTRESPONSE, +    options=None, +  ), +  descriptor.MethodDescriptor( +    name='signal', +    full_name='leap.common.events.EventsClientService.signal',      index=1, +    containing_service=None, +    input_type=_SIGNALREQUEST, +    output_type=_EVENTRESPONSE,      options=None, -    serialized_start=1271, -    serialized_end=1448, -    methods=[ -        descriptor.MethodDescriptor( -            name='ping', -            full_name='leap.common.events.EventsClientService.ping', -            index=0, -            containing_service=None, -            input_type=_PINGREQUEST, -            output_type=_EVENTRESPONSE, -            options=None, -        ), -        descriptor.MethodDescriptor( -            name='signal', -            full_name='leap.common.events.EventsClientService.signal', -            index=1, -            containing_service=None, -            input_type=_SIGNALREQUEST, -            output_type=_EVENTRESPONSE, -            options=None, -        ), -    ]) - +  ), +])  class EventsClientService(service.Service): -    __metaclass__ = service_reflection.GeneratedServiceType -    DESCRIPTOR = _EVENTSCLIENTSERVICE - - +  __metaclass__ = service_reflection.GeneratedServiceType +  DESCRIPTOR = _EVENTSCLIENTSERVICE  class EventsClientService_Stub(EventsClientService): -    __metaclass__ = service_reflection.GeneratedServiceStubType -    DESCRIPTOR = _EVENTSCLIENTSERVICE +  __metaclass__ = service_reflection.GeneratedServiceStubType +  DESCRIPTOR = _EVENTSCLIENTSERVICE  # @@protoc_insertion_point(module_scope) diff --git a/src/leap/common/events/server.py b/src/leap/common/events/server.py index 59f3454..861cb4f 100644 --- a/src/leap/common/events/server.py +++ b/src/leap/common/events/server.py @@ -77,18 +77,32 @@ def ensure_server(port=SERVER_PORT):          s.connect(('localhost', port))          s.close()          # port is taken, check if there's a server running there -        response = ping(port) -        if response is not None and response.status == proto.EventResponse.OK: -            logger.info('A server is already running on port %d.', port) -            return None -        # port is taken, and not by an events server -        logger.info('Port %d is taken by something not an events server.', port) -        raise PortAlreadyTaken(port) +        ping(port, +             reqcbk=lambda req, res: process_ping(port, req, res), +             timeout=10)      except socket.error:          # port is available, run a server          logger.info('Launching server on port %d.', port)          return EventsServerDaemon.ensure(port) +def process_ping(port, request, response): +    """ +    Response callback for the ping event. + +    :param port: Port that is trying to be used +    :type port: int +    :param request: Ping request made +    :type request: proto.PingRequest +    :param response: Response from the event +    :type response: proto.EventResponse +    """ +    if response is not None and response.status == proto.EventResponse.OK: +        logger.info('A server is already running on port %d.', port) +        return +    # port is taken, and not by an events server +    logger.info('Port %d is taken by something not an events server.', port) +    raise PortAlreadyTaken(port) +  def ping(port=SERVER_PORT, reqcbk=None, timeout=1000):      """ diff --git a/versioneer.py b/versioneer.py new file mode 100644 index 0000000..34e4807 --- /dev/null +++ b/versioneer.py @@ -0,0 +1,669 @@ +#! /usr/bin/python + +"""versioneer.py + +(like a rocketeer, but for versions) + +* https://github.com/warner/python-versioneer +* Brian Warner +* License: Public Domain +* Version: 0.7+ + +This file helps distutils-based projects manage their version number by just +creating version-control tags. + +For developers who work from a VCS-generated tree (e.g. 'git clone' etc), +each 'setup.py version', 'setup.py build', 'setup.py sdist' will compute a +version number by asking your version-control tool about the current +checkout. The version number will be written into a generated _version.py +file of your choosing, where it can be included by your __init__.py + +For users who work from a VCS-generated tarball (e.g. 'git archive'), it will +compute a version number by looking at the name of the directory created when +te tarball is unpacked. This conventionally includes both the name of the +project and a version number. + +For users who work from a tarball built by 'setup.py sdist', it will get a +version number from a previously-generated _version.py file. + +As a result, loading code directly from the source tree will not result in a +real version. If you want real versions from VCS trees (where you frequently +update from the upstream repository, or do new development), you will need to +do a 'setup.py version' after each update, and load code from the build/ +directory. + +You need to provide this code with a few configuration values: + + versionfile_source: +    A project-relative pathname into which the generated version strings +    should be written. This is usually a _version.py next to your project's +    main __init__.py file. If your project uses src/myproject/__init__.py, +    this should be 'src/myproject/_version.py'. This file should be checked +    in to your VCS as usual: the copy created below by 'setup.py +    update_files' will include code that parses expanded VCS keywords in +    generated tarballs. The 'build' and 'sdist' commands will replace it with +    a copy that has just the calculated version string. + + versionfile_build: +    Like versionfile_source, but relative to the build directory instead of +    the source directory. These will differ when your setup.py uses +    'package_dir='. If you have package_dir={'myproject': 'src/myproject'}, +    then you will probably have versionfile_build='myproject/_version.py' and +    versionfile_source='src/myproject/_version.py'. + + tag_prefix: a string, like 'PROJECTNAME-', which appears at the start of all +             VCS tags. If your tags look like 'myproject-1.2.0', then you +             should use tag_prefix='myproject-'. If you use unprefixed tags +             like '1.2.0', this should be an empty string. + + parentdir_prefix: a string, frequently the same as tag_prefix, which +                   appears at the start of all unpacked tarball filenames. If +                   your tarball unpacks into 'myproject-1.2.0', this should +                   be 'myproject-'. + +To use it: + + 1: include this file in the top level of your project + 2: make the following changes to the top of your setup.py: +     import versioneer +     versioneer.versionfile_source = 'src/myproject/_version.py' +     versioneer.versionfile_build = 'myproject/_version.py' +     versioneer.tag_prefix = '' # tags are like 1.2.0 +     versioneer.parentdir_prefix = 'myproject-' # dirname like 'myproject-1.2.0' + 3: add the following arguments to the setup() call in your setup.py: +     version=versioneer.get_version(), +     cmdclass=versioneer.get_cmdclass(), + 4: run 'setup.py update_files', which will create _version.py, and will +    modify your __init__.py to define __version__ (by calling a function +    from _version.py) + 5: modify your MANIFEST.in to include versioneer.py + 6: add both versioneer.py and the generated _version.py to your VCS +""" + +import os, sys, re +from distutils.core import Command +from distutils.command.sdist import sdist as _sdist +from distutils.command.build import build as _build + +versionfile_source = None +versionfile_build = None +tag_prefix = None +parentdir_prefix = None + +VCS = "git" +IN_LONG_VERSION_PY = False + + +LONG_VERSION_PY = ''' +IN_LONG_VERSION_PY = True +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (build by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. Generated by +# versioneer-0.7+ (https://github.com/warner/python-versioneer) + +# these strings will be replaced by git during git-archive +git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s" +git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s" + + +import subprocess +import sys + +def run_command(args, cwd=None, verbose=False): +    try: +        # remember shell=False, so use git.cmd on windows, not just git +        p = subprocess.Popen(args, stdout=subprocess.PIPE, cwd=cwd) +    except EnvironmentError: +        e = sys.exc_info()[1] +        if verbose: +            print("unable to run %%s" %% args[0]) +            print(e) +        return None +    stdout = p.communicate()[0].strip() +    if sys.version >= '3': +        stdout = stdout.decode() +    if p.returncode != 0: +        if verbose: +            print("unable to run %%s (error)" %% args[0]) +        return None +    return stdout + + +import sys +import re +import os.path + +def get_expanded_variables(versionfile_source): +    # the code embedded in _version.py can just fetch the value of these +    # variables. When used from setup.py, we don't want to import +    # _version.py, so we do it with a regexp instead. This function is not +    # used from _version.py. +    variables = {} +    try: +        f = open(versionfile_source,"r") +        for line in f.readlines(): +            if line.strip().startswith("git_refnames ="): +                mo = re.search(r'=\s*"(.*)"', line) +                if mo: +                    variables["refnames"] = mo.group(1) +            if line.strip().startswith("git_full ="): +                mo = re.search(r'=\s*"(.*)"', line) +                if mo: +                    variables["full"] = mo.group(1) +        f.close() +    except EnvironmentError: +        pass +    return variables + +def versions_from_expanded_variables(variables, tag_prefix, verbose=False): +    refnames = variables["refnames"].strip() +    if refnames.startswith("$Format"): +        if verbose: +            print("variables are unexpanded, not using") +        return {} # unexpanded, so not in an unpacked git-archive tarball +    refs = set([r.strip() for r in refnames.strip("()").split(",")]) +    # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of +    # just "foo-1.0". If we see a "tag: " prefix, prefer those. +    TAG = "tag: " +    tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) +    if not tags: +        # Either we're using git < 1.8.3, or there really are no tags. We use +        # a heuristic: assume all version tags have a digit. The old git %%d +        # expansion behaves like git log --decorate=short and strips out the +        # refs/heads/ and refs/tags/ prefixes that would let us distinguish +        # between branches and tags. By ignoring refnames without digits, we +        # filter out many common branch names like "release" and +        # "stabilization", as well as "HEAD" and "master". +        tags = set([r for r in refs if re.search(r'\d', r)]) +        if verbose: +            print("discarding '%%s', no digits" %% ",".join(refs-tags)) +    if verbose: +        print("likely tags: %%s" %% ",".join(sorted(tags))) +    for ref in sorted(tags): +        # sorting will prefer e.g. "2.0" over "2.0rc1" +        if ref.startswith(tag_prefix): +            r = ref[len(tag_prefix):] +            if verbose: +                print("picking %%s" %% r) +            return { "version": r, +                     "full": variables["full"].strip() } +    # no suitable tags, so we use the full revision id +    if verbose: +        print("no suitable tags, using full revision id") +    return { "version": variables["full"].strip(), +             "full": variables["full"].strip() } + +def versions_from_vcs(tag_prefix, versionfile_source, verbose=False): +    # this runs 'git' from the root of the source tree. That either means +    # someone ran a setup.py command (and this code is in versioneer.py, so +    # IN_LONG_VERSION_PY=False, thus the containing directory is the root of +    # the source tree), or someone ran a project-specific entry point (and +    # this code is in _version.py, so IN_LONG_VERSION_PY=True, thus the +    # containing directory is somewhere deeper in the source tree). This only +    # gets called if the git-archive 'subst' variables were *not* expanded, +    # and _version.py hasn't already been rewritten with a short version +    # string, meaning we're inside a checked out source tree. + +    try: +        here = os.path.abspath(__file__) +    except NameError: +        # some py2exe/bbfreeze/non-CPython implementations don't do __file__ +        return {} # not always correct + +    # versionfile_source is the relative path from the top of the source tree +    # (where the .git directory might live) to this file. Invert this to find +    # the root from __file__. +    root = here +    if IN_LONG_VERSION_PY: +        for i in range(len(versionfile_source.split("/"))): +            root = os.path.dirname(root) +    else: +        root = os.path.dirname(here) +    if not os.path.exists(os.path.join(root, ".git")): +        if verbose: +            print("no .git in %%s" %% root) +        return {} + +    GIT = "git" +    if sys.platform == "win32": +        GIT = "git.cmd" +    stdout = run_command([GIT, "describe", "--tags", "--dirty", "--always"], +                         cwd=root) +    if stdout is None: +        return {} +    if not stdout.startswith(tag_prefix): +        if verbose: +            print("tag '%%s' doesn't start with prefix '%%s'" %% (stdout, tag_prefix)) +        return {} +    tag = stdout[len(tag_prefix):] +    stdout = run_command([GIT, "rev-parse", "HEAD"], cwd=root) +    if stdout is None: +        return {} +    full = stdout.strip() +    if tag.endswith("-dirty"): +        full += "-dirty" +    return {"version": tag, "full": full} + + +def versions_from_parentdir(parentdir_prefix, versionfile_source, verbose=False): +    if IN_LONG_VERSION_PY: +        # We're running from _version.py. If it's from a source tree +        # (execute-in-place), we can work upwards to find the root of the +        # tree, and then check the parent directory for a version string. If +        # it's in an installed application, there's no hope. +        try: +            here = os.path.abspath(__file__) +        except NameError: +            # py2exe/bbfreeze/non-CPython don't have __file__ +            return {} # without __file__, we have no hope +        # versionfile_source is the relative path from the top of the source +        # tree to _version.py. Invert this to find the root from __file__. +        root = here +        for i in range(len(versionfile_source.split("/"))): +            root = os.path.dirname(root) +    else: +        # we're running from versioneer.py, which means we're running from +        # the setup.py in a source tree. sys.argv[0] is setup.py in the root. +        here = os.path.abspath(sys.argv[0]) +        root = os.path.dirname(here) + +    # Source tarballs conventionally unpack into a directory that includes +    # both the project name and a version string. +    dirname = os.path.basename(root) +    if not dirname.startswith(parentdir_prefix): +        if verbose: +            print("guessing rootdir is '%%s', but '%%s' doesn't start with prefix '%%s'" %% +                  (root, dirname, parentdir_prefix)) +        return None +    return {"version": dirname[len(parentdir_prefix):], "full": ""} + +tag_prefix = "%(TAG_PREFIX)s" +parentdir_prefix = "%(PARENTDIR_PREFIX)s" +versionfile_source = "%(VERSIONFILE_SOURCE)s" + +def get_versions(default={"version": "unknown", "full": ""}, verbose=False): +    variables = { "refnames": git_refnames, "full": git_full } +    ver = versions_from_expanded_variables(variables, tag_prefix, verbose) +    if not ver: +        ver = versions_from_vcs(tag_prefix, versionfile_source, verbose) +    if not ver: +        ver = versions_from_parentdir(parentdir_prefix, versionfile_source, +                                      verbose) +    if not ver: +        ver = default +    return ver + +''' + + +import subprocess +import sys + +def run_command(args, cwd=None, verbose=False): +    try: +        # remember shell=False, so use git.cmd on windows, not just git +        p = subprocess.Popen(args, stdout=subprocess.PIPE, cwd=cwd) +    except EnvironmentError: +        e = sys.exc_info()[1] +        if verbose: +            print("unable to run %s" % args[0]) +            print(e) +        return None +    stdout = p.communicate()[0].strip() +    if sys.version >= '3': +        stdout = stdout.decode() +    if p.returncode != 0: +        if verbose: +            print("unable to run %s (error)" % args[0]) +        return None +    return stdout + + +import sys +import re +import os.path + +def get_expanded_variables(versionfile_source): +    # the code embedded in _version.py can just fetch the value of these +    # variables. When used from setup.py, we don't want to import +    # _version.py, so we do it with a regexp instead. This function is not +    # used from _version.py. +    variables = {} +    try: +        f = open(versionfile_source,"r") +        for line in f.readlines(): +            if line.strip().startswith("git_refnames ="): +                mo = re.search(r'=\s*"(.*)"', line) +                if mo: +                    variables["refnames"] = mo.group(1) +            if line.strip().startswith("git_full ="): +                mo = re.search(r'=\s*"(.*)"', line) +                if mo: +                    variables["full"] = mo.group(1) +        f.close() +    except EnvironmentError: +        pass +    return variables + +def versions_from_expanded_variables(variables, tag_prefix, verbose=False): +    refnames = variables["refnames"].strip() +    if refnames.startswith("$Format"): +        if verbose: +            print("variables are unexpanded, not using") +        return {} # unexpanded, so not in an unpacked git-archive tarball +    refs = set([r.strip() for r in refnames.strip("()").split(",")]) +    # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of +    # just "foo-1.0". If we see a "tag: " prefix, prefer those. +    TAG = "tag: " +    tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) +    if not tags: +        # Either we're using git < 1.8.3, or there really are no tags. We use +        # a heuristic: assume all version tags have a digit. The old git %d +        # expansion behaves like git log --decorate=short and strips out the +        # refs/heads/ and refs/tags/ prefixes that would let us distinguish +        # between branches and tags. By ignoring refnames without digits, we +        # filter out many common branch names like "release" and +        # "stabilization", as well as "HEAD" and "master". +        tags = set([r for r in refs if re.search(r'\d', r)]) +        if verbose: +            print("discarding '%s', no digits" % ",".join(refs-tags)) +    if verbose: +        print("likely tags: %s" % ",".join(sorted(tags))) +    for ref in sorted(tags): +        # sorting will prefer e.g. "2.0" over "2.0rc1" +        if ref.startswith(tag_prefix): +            r = ref[len(tag_prefix):] +            if verbose: +                print("picking %s" % r) +            return { "version": r, +                     "full": variables["full"].strip() } +    # no suitable tags, so we use the full revision id +    if verbose: +        print("no suitable tags, using full revision id") +    return { "version": variables["full"].strip(), +             "full": variables["full"].strip() } + +def versions_from_vcs(tag_prefix, versionfile_source, verbose=False): +    # this runs 'git' from the root of the source tree. That either means +    # someone ran a setup.py command (and this code is in versioneer.py, so +    # IN_LONG_VERSION_PY=False, thus the containing directory is the root of +    # the source tree), or someone ran a project-specific entry point (and +    # this code is in _version.py, so IN_LONG_VERSION_PY=True, thus the +    # containing directory is somewhere deeper in the source tree). This only +    # gets called if the git-archive 'subst' variables were *not* expanded, +    # and _version.py hasn't already been rewritten with a short version +    # string, meaning we're inside a checked out source tree. + +    try: +        here = os.path.abspath(__file__) +    except NameError: +        # some py2exe/bbfreeze/non-CPython implementations don't do __file__ +        return {} # not always correct + +    # versionfile_source is the relative path from the top of the source tree +    # (where the .git directory might live) to this file. Invert this to find +    # the root from __file__. +    root = here +    if IN_LONG_VERSION_PY: +        for i in range(len(versionfile_source.split("/"))): +            root = os.path.dirname(root) +    else: +        root = os.path.dirname(here) +    if not os.path.exists(os.path.join(root, ".git")): +        if verbose: +            print("no .git in %s" % root) +        return {} + +    GIT = "git" +    if sys.platform == "win32": +        GIT = "git.cmd" +    stdout = run_command([GIT, "describe", "--tags", "--dirty", "--always"], +                         cwd=root) +    if stdout is None: +        return {} +    if not stdout.startswith(tag_prefix): +        if verbose: +            print("tag '%s' doesn't start with prefix '%s'" % (stdout, tag_prefix)) +        return {} +    tag = stdout[len(tag_prefix):] +    stdout = run_command([GIT, "rev-parse", "HEAD"], cwd=root) +    if stdout is None: +        return {} +    full = stdout.strip() +    if tag.endswith("-dirty"): +        full += "-dirty" +    return {"version": tag, "full": full} + + +def versions_from_parentdir(parentdir_prefix, versionfile_source, verbose=False): +    if IN_LONG_VERSION_PY: +        # We're running from _version.py. If it's from a source tree +        # (execute-in-place), we can work upwards to find the root of the +        # tree, and then check the parent directory for a version string. If +        # it's in an installed application, there's no hope. +        try: +            here = os.path.abspath(__file__) +        except NameError: +            # py2exe/bbfreeze/non-CPython don't have __file__ +            return {} # without __file__, we have no hope +        # versionfile_source is the relative path from the top of the source +        # tree to _version.py. Invert this to find the root from __file__. +        root = here +        for i in range(len(versionfile_source.split("/"))): +            root = os.path.dirname(root) +    else: +        # we're running from versioneer.py, which means we're running from +        # the setup.py in a source tree. sys.argv[0] is setup.py in the root. +        here = os.path.abspath(sys.argv[0]) +        root = os.path.dirname(here) + +    # Source tarballs conventionally unpack into a directory that includes +    # both the project name and a version string. +    dirname = os.path.basename(root) +    if not dirname.startswith(parentdir_prefix): +        if verbose: +            print("guessing rootdir is '%s', but '%s' doesn't start with prefix '%s'" % +                  (root, dirname, parentdir_prefix)) +        return None +    return {"version": dirname[len(parentdir_prefix):], "full": ""} + +import sys + +def do_vcs_install(versionfile_source, ipy): +    GIT = "git" +    if sys.platform == "win32": +        GIT = "git.cmd" +    run_command([GIT, "add", "versioneer.py"]) +    run_command([GIT, "add", versionfile_source]) +    run_command([GIT, "add", ipy]) +    present = False +    try: +        f = open(".gitattributes", "r") +        for line in f.readlines(): +            if line.strip().startswith(versionfile_source): +                if "export-subst" in line.strip().split()[1:]: +                    present = True +        f.close() +    except EnvironmentError: +        pass     +    if not present: +        f = open(".gitattributes", "a+") +        f.write("%s export-subst\n" % versionfile_source) +        f.close() +        run_command([GIT, "add", ".gitattributes"]) +     + +SHORT_VERSION_PY = """ +# This file was generated by 'versioneer.py' (0.7+) from +# revision-control system data, or from the parent directory name of an +# unpacked source archive. Distribution tarballs contain a pre-generated copy +# of this file. + +version_version = '%(version)s' +version_full = '%(full)s' +def get_versions(default={}, verbose=False): +    return {'version': version_version, 'full': version_full} + +""" + +DEFAULT = {"version": "unknown", "full": "unknown"} + +def versions_from_file(filename): +    versions = {} +    try: +        f = open(filename) +    except EnvironmentError: +        return versions +    for line in f.readlines(): +        mo = re.match("version_version = '([^']+)'", line) +        if mo: +            versions["version"] = mo.group(1) +        mo = re.match("version_full = '([^']+)'", line) +        if mo: +            versions["full"] = mo.group(1) +    f.close() +    return versions + +def write_to_version_file(filename, versions): +    f = open(filename, "w") +    f.write(SHORT_VERSION_PY % versions) +    f.close() +    print("set %s to '%s'" % (filename, versions["version"])) + + +def get_best_versions(versionfile, tag_prefix, parentdir_prefix, +                      default=DEFAULT, verbose=False): +    # returns dict with two keys: 'version' and 'full' +    # +    # extract version from first of _version.py, 'git describe', parentdir. +    # This is meant to work for developers using a source checkout, for users +    # of a tarball created by 'setup.py sdist', and for users of a +    # tarball/zipball created by 'git archive' or github's download-from-tag +    # feature. + +    variables = get_expanded_variables(versionfile_source) +    if variables: +        ver = versions_from_expanded_variables(variables, tag_prefix) +        if ver: +            if verbose: print("got version from expanded variable %s" % ver) +            return ver + +    ver = versions_from_file(versionfile) +    if ver: +        if verbose: print("got version from file %s %s" % (versionfile, ver)) +        return ver + +    ver = versions_from_vcs(tag_prefix, versionfile_source, verbose) +    if ver: +        if verbose: print("got version from git %s" % ver) +        return ver + +    ver = versions_from_parentdir(parentdir_prefix, versionfile_source, verbose) +    if ver: +        if verbose: print("got version from parentdir %s" % ver) +        return ver + +    if verbose: print("got version from default %s" % ver) +    return default + +def get_versions(default=DEFAULT, verbose=False): +    assert versionfile_source is not None, "please set versioneer.versionfile_source" +    assert tag_prefix is not None, "please set versioneer.tag_prefix" +    assert parentdir_prefix is not None, "please set versioneer.parentdir_prefix" +    return get_best_versions(versionfile_source, tag_prefix, parentdir_prefix, +                             default=default, verbose=verbose) +def get_version(verbose=False): +    return get_versions(verbose=verbose)["version"] + +class cmd_version(Command): +    description = "report generated version string" +    user_options = [] +    boolean_options = [] +    def initialize_options(self): +        pass +    def finalize_options(self): +        pass +    def run(self): +        ver = get_version(verbose=True) +        print("Version is currently: %s" % ver) + + +class cmd_build(_build): +    def run(self): +        versions = get_versions(verbose=True) +        _build.run(self) +        # now locate _version.py in the new build/ directory and replace it +        # with an updated value +        target_versionfile = os.path.join(self.build_lib, versionfile_build) +        print("UPDATING %s" % target_versionfile) +        os.unlink(target_versionfile) +        f = open(target_versionfile, "w") +        f.write(SHORT_VERSION_PY % versions) +        f.close() + +class cmd_sdist(_sdist): +    def run(self): +        versions = get_versions(verbose=True) +        self._versioneer_generated_versions = versions +        # unless we update this, the command will keep using the old version +        self.distribution.metadata.version = versions["version"] +        return _sdist.run(self) + +    def make_release_tree(self, base_dir, files): +        _sdist.make_release_tree(self, base_dir, files) +        # now locate _version.py in the new base_dir directory (remembering +        # that it may be a hardlink) and replace it with an updated value +        target_versionfile = os.path.join(base_dir, versionfile_source) +        print("UPDATING %s" % target_versionfile) +        os.unlink(target_versionfile) +        f = open(target_versionfile, "w") +        f.write(SHORT_VERSION_PY % self._versioneer_generated_versions) +        f.close() + +INIT_PY_SNIPPET = """ +from ._version import get_versions +__version__ = get_versions()['version'] +del get_versions +""" + +class cmd_update_files(Command): +    description = "modify __init__.py and create _version.py" +    user_options = [] +    boolean_options = [] +    def initialize_options(self): +        pass +    def finalize_options(self): +        pass +    def run(self): +        ipy = os.path.join(os.path.dirname(versionfile_source), "__init__.py") +        print(" creating %s" % versionfile_source) +        f = open(versionfile_source, "w") +        f.write(LONG_VERSION_PY % {"DOLLAR": "$", +                                   "TAG_PREFIX": tag_prefix, +                                   "PARENTDIR_PREFIX": parentdir_prefix, +                                   "VERSIONFILE_SOURCE": versionfile_source, +                                   }) +        f.close() +        try: +            old = open(ipy, "r").read() +        except EnvironmentError: +            old = "" +        if INIT_PY_SNIPPET not in old: +            print(" appending to %s" % ipy) +            f = open(ipy, "a") +            f.write(INIT_PY_SNIPPET) +            f.close() +        else: +            print(" %s unmodified" % ipy) +        do_vcs_install(versionfile_source, ipy) + +def get_cmdclass(): +    return {'version': cmd_version, +            'update_files': cmd_update_files, +            'build': cmd_build, +            'sdist': cmd_sdist, +            } | 
