Skip to content
queries.py 4.79 KiB
Newer Older
Franziska Koehn's avatar
Franziska Koehn committed
"""
:Author: Franziska Koehn
:Created: 2015/01/13

This module includes functions around sending and defining queries.
"""

Franziska Koehn's avatar
Franziska Koehn committed
from threading import Lock
requests_lock = Lock()

Franziska Koehn's avatar
Franziska Koehn committed
    """Returns all applicable methods for creating a query."""
Franziska Koehn's avatar
Franziska Koehn committed
    """Returns all applicable Operators for creating a query."""
Franziska Koehn's avatar
Franziska Koehn committed
#TODO download_async and download as one function???

def download_async(result, host, creds, rest, dest_folder='', cb=(lambda *_: None), cb_args=()):
Franziska Koehn's avatar
Franziska Koehn committed
    """
    Downloads file by using threads (So the GUI will not be bocked while downloading).

    **Parameters**
        :result: resultset, from which will be downloaded
        :host: address of host
        :creds: credentials (including user-name and -password)
        :rest: REST-API definition
        :dest_folder: folder where the downloaded files will be saved
        :cb: function for moving spinners
        :cb_args: args for function cb
    """
Franziska Koehn's avatar
Franziska Koehn committed
    from threading import Thread
    download_thread = Thread(target=download, args=(result, host, creds, rest, dest_folder, cb, cb_args))
Franziska Koehn's avatar
Franziska Koehn committed
    download_thread.start()
    return download_thread
Franziska Koehn's avatar
Franziska Koehn committed

def download(result, host, creds, rest, dest_folder='', cb=(lambda *_: None), cb_args=()):
Franziska Koehn's avatar
Franziska Koehn committed
    """
    Downloads a file.

    **Parameters**
        :result: resultset, from which will be downloaded
        :host: address of host
        :creds: credentials (including user-name and -password)
        :rest: REST-API definition
        :dest_folder: folder where the downloaded files will be saved
        :cb: function for moving spinners
        :cb_args: args for function cb
    """

Franziska Koehn's avatar
Franziska Koehn committed
    requests_lock.acquire()

    import re
    import os

    names=[]
    def subfunc(f):
        key = f.group(0).strip("{}")
        r = result[key]
        names.append(r)
        return r
    ret = re.sub('\{\w+\}', subfunc, rest)

    path = os.path.join(dest_folder, '-'.join(names))
    url = "%s%s" % (host, ret)

    download_file(url, creds, path)
Franziska Koehn's avatar
Franziska Koehn committed
    requests_lock.release()
    cb(*cb_args)
def download_file(url, creds, path):
Franziska Koehn's avatar
Franziska Koehn committed
    """
    Downloads a file.

    **Parameters**
        :url: host/REST-API with filled values
        :creds: credentials (including user-name and -password)
        :path: folder where the downloaded files will be saved
    """

    import requests
    from base64 import b64encode
    from requests.auth import HTTPBasicAuth

    if not path.endswith(".zip"):
        path += ".zip"
        with open(path, 'wb') as handle:
            response = requests.get(url, stream=True, auth=HTTPBasicAuth(user, passw))
            if not response.ok:
                raise ValueError(response.status_code)
            for block in response.iter_content(1024):
                if not block:
                    break
                handle.write(block)
    except IOError as e:
        print "Error writing file %s, %s" % (path, e)
    except ValueError as e:
        print "Error downloading file %s, Status Code %s" % (url, e)


def search_for(host, root_element, constraints, search_fields, user, passw):
Franziska Koehn's avatar
Franziska Koehn committed
    """
    Does a search for given values. raises xsa -Exceptions

    **Parameters**
        :host: host-address
        :root_element: root-element of search
        :constraints: constraints of query
        :search_fields: fields which will be returned from server
        :user: user-name
        :passw:user-password
    """
    import xsa.errors as xsa_errors

    from pyxnat.core import errors
    from httplib2 import ServerNotFoundError
    from httplib import ResponseNotReady

    from tempfile import mkdtemp
    from pyxnat import Interface
        central = Interface(server=host,
                            user=user,
                            password=passw,
                            cachedir=tmp_dir)
    except IndexError as e:
Franziska Koehn's avatar
Franziska Koehn committed
        raise xsa_errors.ServerNotFoundError("Server not found, check your host-address.")
    result = []

    try:
        result =  central.select(root_element,search_fields).where(constraints)
    except errors.DatabaseError as e:
        if '401' in str(e):
            raise xsa_errors.UnauthorizedError("Unauthorizied attempt. Check your User and Password")
    except ServerNotFoundError:
        raise xsa_errors.ServerNotFoundError("Server not found, check your host-address.")
    except ResponseNotReady:
        raise xsa_errors.ResponseNotReady("Please check your Host-Address")

    if result == []:
        raise xsa_errors.QueryError("Please check your query.")

    try:
        central.disonnect()
    except AttributeError:
        print "can\'t close connection (wrong pyxnat version?)"

    try:
        from shutil import rmtree
        rmtree(tmp_dir)
    except:
        pass