<commit_before>#!/usr/local/bin/python3

"""
created_by:         Micah Halter
created_date:       2/28/2015
last_modified_by:   LZ
last_modified date: 3/5/2015
"""

# imports
import constants
import mysql.connector
from sql.user import User
from sql.mysql_connect_config import getConfig

# classes
class Topic(object):
    'Assessment object to hold attributes and functions for an assessment'

    def __init__(self, id, created, created_by, name, active):
        """
        self       - the topic in question
        id         - the id number of the topic 'self' in the database
        created    - the date when the topic 'self' was created
        created_by - the user that created the topic 'self'
        name       - the name of the topic 'self'
        active     - a bit specifying whether the topic is active

        this function acts as the constructor to define a new topic object
        """
        self.id         = id
        self.created    = created
        self.created_by = created_by
        self.name       = name
        self.active     = active

    @classmethod
    def noID(self, created_by, name, active):
        """
        the parameters correspond with the parameters in the constructor above

        returns a new assessment with the id parameter set as None and the other
        parameters as they are passed in

        this function acts as a second constructor where you have created a
        topic that has not yet been assigned an id from the database
        """
        return self(None, None, created_by, name, active)

    @classmethod
    def get(self, search="all", testActive=1):
        cnx = mysql.connector.connect(**getConfig())
        cursor = cnx.cursor()

        returnList = []
        query = ""
        if search == "all":
            query = ("SELECT * FROM topic")
        elif type(search) is int:
            query = ("SELECT * FROM topic WHERE id=%s" % (search))
        elif type(search) is str:
            query = ("SELECT * FROM topic WHERE (name LIKE '%%s%%')" % (search))
        elif str(type(search)) == "<class 'sql.user.User'>":
            query = ("SELECT * FROM topic WHERE created_by=%s" % (search.id))
        elif str(type(search)) == "<class 'sql.question.Question'>":
            query = ("SELECT t.* FROM question_topic AS qt "
                     "INNER JOIN topic AS t ON qt.topic_id=t.id "
                     "WHERE qt.question_id=%s"
                     % (search.id))
        elif str(type(search)) == "<class 'sql.assessment.Assessment'>":
            query = ("SELECT t.* FROM assessment_topic AS at "
                     "INNER JOIN topic AS t ON at.topic_id=t.id "
                     "WHERE at.assessment_id=%s"
                     % (search.id))

        query += (" WHERE active=%s;" if search == "all" else " AND active=%s;") % (testActive)

        cursor.execute(query)
        for (id, created, created_by, name, active) in cursor:
            user = User.get(created_by)[0]
            returnList.append(Topic(id, created, user, name, active))

        cnx.commit()
        cursor.close()
        cnx.close()

        return returnList

    def add(self):
        cnx = mysql.connector.connect(**getConfig())
        cursor = cnx.cursor()

        if self.id is None:
            insert = ("INSERT INTO topic (created_by, name, active) VALUES ('%s', %s, '%s', %s);" % (self.created, self.created_by.id, self.name, self.active))
            cursor.execute(insert)

            select = "SELECT LAST_INSERT_ID();"

            cursor.execute(select)

            for (id) in cursor:
                self.id = id

        cnx.commit()
        cursor.close()
        cnx.close()

    def update(self):
        cnx = mysql.connector.connect(**getConfig())
        cursor = cnx.cursor()

        if self.id is not None:
            update = ("UPDATE topic SET name='%s', active=%s" % (self.name, self.active))
            cursor.execute(update)

        cnx.commit()
        cursor.cloes()
        cnx.close()

    def activate(self, bool):
        cnx = mysql.connector.connect(**getConfig())
        cursor = cnx.cursor()

        if self.id is not None:
            self.active = int(bool)
            update = ("UPDATE topic SET active=%s WHERE id=%s" % (int(bool), self.id))
            cursor.execute(update)

            cnx.commit()
            cursor.close()
            cnx.close()

    def __eq__(self, other):
        """
        self  - the topic in question
        other - other topic that you are comparing 'self' to

        returns a boolean telling if the attributes of 'self'
        and 'other' are the same

        this function overrides the way python compares two topics
        and decides if they are equal instead of checking if they
        are the exact same object
        """
        return (
        self.id         == other.id         and
        self.created    == other.created    and
        self.created_by == other.created_by and
        self.name       == other.name       and
        self.active     == other.active
        ) if type(other) is Topic else False

    def __str__(self):
        """
        self - the topic in question

        returns a string that fully describes the assessment 'self'

        this function allows you to convert the topic object into
        a human-readable string for viewing the information in it
        """
        string = ""
        string += "id: "         +      str(self.id)         + "\n"
        string += "created: "    +      str(self.created)    + "\n"
        string += "created by: " +      str(self.created_by) + "\n"
        string += "active: "     + str(bool(self.active))    + "\n"
        string += "name: "       +          self.name        + "\n"
        string += "active: "       +    str(self.active)     + "\n"

        return string
    def toJson(self):
        data = {
        "id"        : self.id,
        "created"   : self.created,
        "createdBy": self.created_by,
        "name"      : self.name,
        "active"    : self.active
        }
        return json.dumps(data)

<commit_msg>fix json<commit_after>#!/usr/local/bin/python3

"""
created_by:         Micah Halter
created_date:       2/28/2015
last_modified_by:   LZ
last_modified date: 3/5/2015
"""

# imports
import constants
import json
import mysql.connector
from sql.user import User
from sql.mysql_connect_config import getConfig

# classes
class Topic(object):
    'Assessment object to hold attributes and functions for an assessment'

    def __init__(self, id, created, created_by, name, active):
        """
        self       - the topic in question
        id         - the id number of the topic 'self' in the database
        created    - the date when the topic 'self' was created
        created_by - the user that created the topic 'self'
        name       - the name of the topic 'self'
        active     - a bit specifying whether the topic is active

        this function acts as the constructor to define a new topic object
        """
        self.id         = id
        self.created    = created
        self.created_by = created_by
        self.name       = name
        self.active     = active

    @classmethod
    def noID(self, created_by, name, active):
        """
        the parameters correspond with the parameters in the constructor above

        returns a new assessment with the id parameter set as None and the other
        parameters as they are passed in

        this function acts as a second constructor where you have created a
        topic that has not yet been assigned an id from the database
        """
        return self(None, None, created_by, name, active)

    @classmethod
    def get(self, search="all", testActive=1):
        cnx = mysql.connector.connect(**getConfig())
        cursor = cnx.cursor()

        returnList = []
        query = ""
        if search == "all":
            query = ("SELECT * FROM topic")
        elif type(search) is int:
            query = ("SELECT * FROM topic WHERE id=%s" % (search))
        elif type(search) is str:
            query = ("SELECT * FROM topic WHERE (name LIKE '%%s%%')" % (search))
        elif str(type(search)) == "<class 'sql.user.User'>":
            query = ("SELECT * FROM topic WHERE created_by=%s" % (search.id))
        elif str(type(search)) == "<class 'sql.question.Question'>":
            query = ("SELECT t.* FROM question_topic AS qt "
                     "INNER JOIN topic AS t ON qt.topic_id=t.id "
                     "WHERE qt.question_id=%s"
                     % (search.id))
        elif str(type(search)) == "<class 'sql.assessment.Assessment'>":
            query = ("SELECT t.* FROM assessment_topic AS at "
                     "INNER JOIN topic AS t ON at.topic_id=t.id "
                     "WHERE at.assessment_id=%s"
                     % (search.id))

        query += (" WHERE active=%s;" if search == "all" else " AND active=%s;") % (testActive)

        cursor.execute(query)
        for (id, created, created_by, name, active) in cursor:
            user = User.get(created_by)[0]
            returnList.append(Topic(id, created, user, name, active))

        cnx.commit()
        cursor.close()
        cnx.close()

        return returnList

    def add(self):
        cnx = mysql.connector.connect(**getConfig())
        cursor = cnx.cursor()

        if self.id is None:
            insert = ("INSERT INTO topic (created_by, name, active) VALUES ('%s', %s, '%s', %s);" % (self.created, self.created_by.id, self.name, self.active))
            cursor.execute(insert)

            select = "SELECT LAST_INSERT_ID();"

            cursor.execute(select)

            for (id) in cursor:
                self.id = id

        cnx.commit()
        cursor.close()
        cnx.close()

    def update(self):
        cnx = mysql.connector.connect(**getConfig())
        cursor = cnx.cursor()

        if self.id is not None:
            update = ("UPDATE topic SET name='%s', active=%s" % (self.name, self.active))
            cursor.execute(update)

        cnx.commit()
        cursor.cloes()
        cnx.close()

    def activate(self, bool):
        cnx = mysql.connector.connect(**getConfig())
        cursor = cnx.cursor()

        if self.id is not None:
            self.active = int(bool)
            update = ("UPDATE topic SET active=%s WHERE id=%s" % (int(bool), self.id))
            cursor.execute(update)

            cnx.commit()
            cursor.close()
            cnx.close()

    def __eq__(self, other):
        """
        self  - the topic in question
        other - other topic that you are comparing 'self' to

        returns a boolean telling if the attributes of 'self'
        and 'other' are the same

        this function overrides the way python compares two topics
        and decides if they are equal instead of checking if they
        are the exact same object
        """
        return (
        self.id         == other.id         and
        self.created    == other.created    and
        self.created_by == other.created_by and
        self.name       == other.name       and
        self.active     == other.active
        ) if type(other) is Topic else False

    def __str__(self):
        """
        self - the topic in question

        returns a string that fully describes the assessment 'self'

        this function allows you to convert the topic object into
        a human-readable string for viewing the information in it
        """
        string = ""
        string += "id: "         +      str(self.id)         + "\n"
        string += "created: "    +      str(self.created)    + "\n"
        string += "created by: " +      str(self.created_by) + "\n"
        string += "active: "     + str(bool(self.active))    + "\n"
        string += "name: "       +          self.name        + "\n"
        string += "active: "       +    str(self.active)     + "\n"

        return string
    def toJson(self):
        data = {
        "id"        :     self.id,
        "created"   : str(self.created),
        "createdBy" :     self.created_by.toJson(),
        "name"      :     self.name,
        "active"    :     self.active
        }
        return json.dumps(data)

<|endoftext|>


<commit_before>from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
import importlib

_IMPORT_FAILED = "Could not import role profile '%s'"
_INCORRECT_ARGS = "USER_ROLES should be a list of strings and/or two-tuples"

def _import_class_from_string(class_path):
    """
    Given a string like 'foo.bar.Baz', returns the class it refers to.
    If the string is empty, return None, rather than raising an import error.
    """
    if not class_path:
        return None
    module_path, class_name = class_path.rsplit('.', 1)
    return getattr(importlib.import_module(module_path), class_name)

class Role(object):
    """
    A single role, eg as returned by `roles.moderator`.
    """
    def __init__(self, name):
        self.name = name

    def __unicode__(self):
        return self.name

class Roles(object):
    _roles_dict = None

    @property
    def roles_dict(self):
        """
        Load list style config into dict of {role_name: role_class}
        """
        if self._roles_dict is None:
            self._roles_dict = {}
            for item in self._config:
                if isinstance(item, basestring):
                    # An item like 'manager'
                    self._roles_dict[item] = None
                elif len(item) == 2:
                    # An item like ('manager', 'myapp.models.ManagerProfile')
                    #           or ('manager', '')
                    name, profile = item
                    try:
                        profile_class = _import_class_from_string(profile)
                    except:
                        raise ImproperlyConfigured(_IMPORT_FAILED, profile)
                    self._roles_dict[name] = profile_class
                else:
                    # Anything else
                    raise ImproperlyConfigured(_INCORRECT_ARGS)
        return self._roles_dict

    @property
    def choices(self):
        """
        Return a list of two-tuples of role names, suitable for use as the
        'choices' argument to a model field.
        """
        return [(role, role) for role in self.roles_dict.keys()]

    def __init__(self, config=None):
        """
        By default the Roles object will be created using configuration from
        the django settings file, but you can also set the configuration
        explicitly, for example, when testing.
        """
        self._config = config or getattr(settings, 'USER_ROLES', ())

    def __getattr__(self, name):
        """
        Handle custom properties for returning Role objects.
        For example: `roles.moderator`
        """
        if name in self.roles_dict.keys():
            return Role(name=name)
        else:
            raise AttributeError("No such role exists '%s'" % name)

roles = Roles()
<commit_msg>get `importlib` from `django.utils`, to support python 2.6<commit_after>from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils import importlib

_IMPORT_FAILED = "Could not import role profile '%s'"
_INCORRECT_ARGS = "USER_ROLES should be a list of strings and/or two-tuples"

def _import_class_from_string(class_path):
    """
    Given a string like 'foo.bar.Baz', returns the class it refers to.
    If the string is empty, return None, rather than raising an import error.
    """
    if not class_path:
        return None
    module_path, class_name = class_path.rsplit('.', 1)
    return getattr(importlib.import_module(module_path), class_name)

class Role(object):
    """
    A single role, eg as returned by `roles.moderator`.
    """
    def __init__(self, name):
        self.name = name

    def __unicode__(self):
        return self.name

class Roles(object):
    _roles_dict = None

    @property
    def roles_dict(self):
        """
        Load list style config into dict of {role_name: role_class}
        """
        if self._roles_dict is None:
            self._roles_dict = {}
            for item in self._config:
                if isinstance(item, basestring):
                    # An item like 'manager'
                    self._roles_dict[item] = None
                elif len(item) == 2:
                    # An item like ('manager', 'myapp.models.ManagerProfile')
                    #           or ('manager', '')
                    name, profile = item
                    try:
                        profile_class = _import_class_from_string(profile)
                    except:
                        raise ImproperlyConfigured(_IMPORT_FAILED, profile)
                    self._roles_dict[name] = profile_class
                else:
                    # Anything else
                    raise ImproperlyConfigured(_INCORRECT_ARGS)
        return self._roles_dict

    @property
    def choices(self):
        """
        Return a list of two-tuples of role names, suitable for use as the
        'choices' argument to a model field.
        """
        return [(role, role) for role in self.roles_dict.keys()]

    def __init__(self, config=None):
        """
        By default the Roles object will be created using configuration from
        the django settings file, but you can also set the configuration
        explicitly, for example, when testing.
        """
        self._config = config or getattr(settings, 'USER_ROLES', ())

    def __getattr__(self, name):
        """
        Handle custom properties for returning Role objects.
        For example: `roles.moderator`
        """
        if name in self.roles_dict.keys():
            return Role(name=name)
        else:
            raise AttributeError("No such role exists '%s'" % name)

roles = Roles()
<|endoftext|>


<commit_before>import os
import os.path
import time
import threading
import multiprocessing
import multiprocessing.pool

from boto.s3.connection import S3Connection
from boto.s3.key import Key

### S3 UPLOAD

def upload_directory(dirname, bucketname):
    upload_directory_to_bucket_by_name(dirname, "", bucketname)

def parallel_upload_directory(dirname, bucketname):
    parallel_upload_directory_to_bucket(dirname, "", bucketname)

def upload_directory_to_bucket_by_name(base, dirname, bucketname, bucketprefix=''):
    "Upload an entire directory to S3."

    aws_access_key = os.environ['AWS_ACCESS_KEY']
    aws_secret_key = os.environ['AWS_SECRET_KEY']

    s3     = S3Connection(aws_access_key, aws_secret_key)
    bucket = s3.get_bucket(bucketname)
    upload_directory_to_bucket(base, dirname, bucket, bucketprefix)

def upload_directory_to_bucket(base, dirname, bucket, bucketprefix=''):
    for f in os.listdir(os.path.join(base, dirname)):
        fname = os.path.join(dirname, f)
        if os.path.isdir(os.path.join(base, fname)):
            upload_directory_to_bucket(base, fname, bucket, bucketprefix)
        else:
            upload_file_to_bucket(base, fname, bucket, bucketprefix=bucketprefix)

def pool_upload(args):
    bucket_conns = threading.current_thread().local.bucket_conns
    bucket = bucket_conns[os.getpid()][args[2]]
    upload_file_to_bucket(args[0], args[1], bucket, bucketprefix=args[3])

def pool_init(bucketname):
    aws_access_key = os.environ['AWS_ACCESS_KEY']
    aws_secret_key = os.environ['AWS_SECRET_KEY']

    s3     = S3Connection(aws_access_key, aws_secret_key)
    bucket = s3.get_bucket(bucketname)

    try:
        tlocal = threading.current_thread().local
    except AttributeError:
        tlocal = threading.current_thread().local = threading.local()

    try:
        bucket_conns = tlocal.bucket_conns
    except AttributeError:
        bucket_conns = tlocal.bucket_conns = {}

    bucket_conns.setdefault(os.getpid(), {})[bucketname] = bucket

def parallel_upload_directory_to_bucket(base, dirname, bucket, bucketprefix=''):
    pool = multiprocessing.pool.ThreadPool(
            processes=32,
            initializer=pool_init,
            initargs=(bucket,))

    def walk_files(path):
        for root, dirs, files in os.walk(path):
            for f in files:
                yield os.path.join(root[len(path):], f)

    pool.map(pool_upload,
            ((base, f, bucket, bucketprefix) for f in walk_files(os.path.join(base, dirname))),
            10)

def upload_file_to_bucket_by_name(base, fname, bucketname, keyname=None, bucketprefix='', public=True, aws_access_key=None, aws_secret_key=None):
    "Upload a single file to S3."

    if aws_access_key is None:
        aws_access_key = os.environ['AWS_ACCESS_KEY']
    if aws_secret_key is None:
        aws_secret_key = os.environ['AWS_SECRET_KEY']

    s3     = S3Connection(aws_access_key, aws_secret_key)
    bucket = s3.get_bucket(bucketname)
    upload_file_to_bucket(
        base, fname, bucket, keyname=keyname, bucketprefix=bucketprefix,
        public=public)

def upload_file_to_bucket(base, fname, bucket, keyname=None, bucketprefix='', public=True):
    "Upload a single file to S3."

    TTL = 31536000      # one year

    print "Uploading %40.40s" % fname,
    while True:
        try:
            k = Key(bucket)
            if keyname is None:
                k.key = os.path.join(bucketprefix, fname)
            else:
                k.key = keyname
            k.set_contents_from_filename(
                os.path.join(base, fname),
                replace=True,
                headers={
                    'Cache-Control': 'max-age=%s' % TTL
                },
            )
            if public:
                k.set_acl('public-read')
            print "done."
            break
        except Exception, e:
            import traceback
            print "FAILED, retrying in 10."
            traceback.print_exc()
            time.sleep(10)
<commit_msg>Set the correct content Content-Type for fonts<commit_after>import os
import os.path
import time
import threading
import multiprocessing
import multiprocessing.pool

from boto.s3.connection import S3Connection
from boto.s3.key import Key

### S3 UPLOAD

def upload_directory(dirname, bucketname):
    upload_directory_to_bucket_by_name(dirname, "", bucketname)

def parallel_upload_directory(dirname, bucketname):
    parallel_upload_directory_to_bucket(dirname, "", bucketname)

def upload_directory_to_bucket_by_name(base, dirname, bucketname, bucketprefix=''):
    "Upload an entire directory to S3."

    aws_access_key = os.environ['AWS_ACCESS_KEY']
    aws_secret_key = os.environ['AWS_SECRET_KEY']

    s3     = S3Connection(aws_access_key, aws_secret_key)
    bucket = s3.get_bucket(bucketname)
    upload_directory_to_bucket(base, dirname, bucket, bucketprefix)

def upload_directory_to_bucket(base, dirname, bucket, bucketprefix=''):
    for f in os.listdir(os.path.join(base, dirname)):
        fname = os.path.join(dirname, f)
        if os.path.isdir(os.path.join(base, fname)):
            upload_directory_to_bucket(base, fname, bucket, bucketprefix)
        else:
            upload_file_to_bucket(base, fname, bucket, bucketprefix=bucketprefix)

def pool_upload(args):
    bucket_conns = threading.current_thread().local.bucket_conns
    bucket = bucket_conns[os.getpid()][args[2]]
    upload_file_to_bucket(args[0], args[1], bucket, bucketprefix=args[3])

def pool_init(bucketname):
    aws_access_key = os.environ['AWS_ACCESS_KEY']
    aws_secret_key = os.environ['AWS_SECRET_KEY']

    s3     = S3Connection(aws_access_key, aws_secret_key)
    bucket = s3.get_bucket(bucketname)

    try:
        tlocal = threading.current_thread().local
    except AttributeError:
        tlocal = threading.current_thread().local = threading.local()

    try:
        bucket_conns = tlocal.bucket_conns
    except AttributeError:
        bucket_conns = tlocal.bucket_conns = {}

    bucket_conns.setdefault(os.getpid(), {})[bucketname] = bucket

def parallel_upload_directory_to_bucket(base, dirname, bucket, bucketprefix=''):
    pool = multiprocessing.pool.ThreadPool(
            processes=32,
            initializer=pool_init,
            initargs=(bucket,))

    def walk_files(path):
        for root, dirs, files in os.walk(path):
            for f in files:
                yield os.path.join(root[len(path):], f)

    pool.map(pool_upload,
            ((base, f, bucket, bucketprefix) for f in walk_files(os.path.join(base, dirname))),
            10)

def upload_file_to_bucket_by_name(base, fname, bucketname, keyname=None, bucketprefix='', public=True, aws_access_key=None, aws_secret_key=None):
    "Upload a single file to S3."

    if aws_access_key is None:
        aws_access_key = os.environ['AWS_ACCESS_KEY']
    if aws_secret_key is None:
        aws_secret_key = os.environ['AWS_SECRET_KEY']

    s3     = S3Connection(aws_access_key, aws_secret_key)
    bucket = s3.get_bucket(bucketname)
    upload_file_to_bucket(
        base, fname, bucket, keyname=keyname, bucketprefix=bucketprefix,
        public=public)

def _get_extra_headers(path):
    _, extension = os.path.splitext(path)
    if extension == ".woff":
        yield "Content-Type", "application/x-font-woff"
    elif extension == ".ttf":
        yield "Content-Type", "font/truetype"
    elif extension == ".eot":
        yield "Content-Type", "application/vnd.ms-fontobject"
    elif extension == ".otf":
        yield "Content-Type", "font/opentype"

def upload_file_to_bucket(base, fname, bucket, keyname=None, bucketprefix='', public=True):
    "Upload a single file to S3."

    TTL = 31536000      # one year

    print "Uploading %40.40s" % fname,
    while True:
        try:
            k = Key(bucket)
            if keyname is None:
                k.key = os.path.join(bucketprefix, fname)
            else:
                k.key = keyname
            headers = {'Cache-Control': 'max-age=%s' % TTL}
            for header, value in _get_extra_headers(k.key):
                headers[header] = value
            k.set_contents_from_filename(
                os.path.join(base, fname),
                replace=True,
                headers=headers,
            )
            if public:
                k.set_acl('public-read')
            print "done."
            break
        except Exception, e:
            import traceback
            print "FAILED, retrying in 10."
            traceback.print_exc()
            time.sleep(10)
<|endoftext|>


<commit_before>import numpy as np
import pandas as pd

# Test data download requirements:
import requests
import os

URL_TEST_DATA = "https://raw.githubusercontent.com/open2c/cooltools/pileup-update/datasets/external_test_files.tsv"

def assign_supports(features, supports, labels=False, suffix=""):
    """
    Assign support regions to a table of genomic intervals.

    Parameters
    ----------
    features : DataFrame
        Dataframe with columns `chrom`, `start`, `end`
        or `chrom1`, `start1`, `end1`, `chrom2`, `start2`, `end2`
    supports : array-like
        Support areas

    """
    features = features.copy()
    supp_col = pd.Series(index=features.index, data=np.nan)

    c = "chrom" + suffix
    s = "start" + suffix
    e = "end" + suffix
    for col in (c, s, e):
        if col not in features.columns:
            raise ValueError(
                'Column "{}" not found in features data frame.'.format(col)
            )

    for i, region in enumerate(supports):
        # single-region support
        if len(region) in [3, 4]:
            sel = (features[c] == region[0]) & (features[e] > region[1])
            if region[2] is not None:
                sel &= features[s] < region[2]
        # paired-region support
        elif len(region) == 2:
            region1, region2 = region
            sel1 = (features[c] == region1[0]) & (features[e] > region1[1])
            if region1[2] is not None:
                sel1 &= features[s] < region1[2]
            sel2 = (features[c] == region2[0]) & (features[e] > region2[1])
            if region2[2] is not None:
                sel2 &= features[s] < region2[2]
            sel = sel1 | sel2
        supp_col.loc[sel] = i

    if labels:
        supp_col = supp_col.map(lambda i: supports[int(i)], na_action="ignore")

    return supp_col

def assign_regions_to_bins(bin_ids, regions_span):

    regions_binsorted = (
        regions_span[(regions_span["bin_start"] >= 0) & (regions_span["bin_end"] >= 0)]
        .sort_values(["bin_start", "bin_end"])
        .reset_index()
    )

    bin_reg_idx_lo = regions_span["bin_start"].searchsorted(bin_ids, "right") - 1
    bin_reg_idx_hi = regions_span["bin_end"].searchsorted(bin_ids, "right")
    mask_assigned = (bin_reg_idx_lo == bin_reg_idx_hi) & (bin_reg_idx_lo >= 0)

    region_ids = pd.array([pd.NA] * len(bin_ids))
    region_ids[mask_assigned] = regions_span["name"][bin_reg_idx_lo[mask_assigned]]

    return region_ids

def download_data(name="all", cache=True, data_dir=None):
    """

    Parameters
    ----------
    name : str
        Name of the dataset.
    cache : boolean, optional
        If True, try to load from the local cache first, and save to the cache
        if a download is required.
    data_dir : string, optional
        The directory where to cache data; default is defined by :func:`get_data_dir`.

    Returns
    -------
    Path to the last downloaded file.

    """

    def download_file(url, local_filename=None):
        if local_filename is None:
            local_filename = url.split('/')[-1]
        print('downloading:', url, 'as', local_filename)
        with requests.get(url, stream=True) as r:
            r.raise_for_status()
            with open(local_filename, 'wb') as f:
                for chunk in r.iter_content(chunk_size=8192):
                    f.write(chunk)
        return local_filename

    available_datasets = _get_datasets_info()
    available_keys = map(lambda x: x[0], available_datasets)

    if name in available_keys:
        keys = [name]
    elif name=="all":
        keys = available_keys
    else:
        raise Exception(
            """Dataset {key} is not available.
            Available datasets: {datasets}
            Use print_available_datasets() to see the details.
            """.format(key=name, datasets=','.join(available_keys)))

    data_dir = get_data_dir(data_dir)

    assert len(keys)>0 # Checking that test data file is parsed successfully
    downloaded = '' # Empty string that will be returned if the request was empty
    for key, url, local_filename in available_datasets:
        if not key in keys:
            continue

        file_path = os.path.join(data_dir, local_filename)
        if cache and os.path.exists(file_path):
            downloaded = file_path
            continue
        elif cache:
            print("Test dataset {} (file {}) is not in the cache directory {}".format(key, local_filename, data_dir))
        downloaded = download_file(url, file_path)

    return downloaded

def get_data_dir(data_dir=None):
    """
    Returns a path to cache directory for example datasets.

    This directory is then used by :func:`download_test_data`.

    By default, this function uses the location of cooltools as the home folder
    and stores the files under ./tests/data/external/ path there.

    Parameters
    ----------
    data_dir : str, optional
        Location of the home for test data storage

    Returns
    -------
    String with path to the folder with test data

    Notes
    -------
    Designed following seaborn download test data examples:
    https://github.com/mwaskom/seaborn/blob/4dd57d63e23e4628d8b7f41cdefdf64f7fefcf74/seaborn/utils.py#L427

    """

    if data_dir is None:
        data_dir = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', '..', 'datasets/'))

    data_dir = os.path.expanduser(data_dir)
    if not os.path.exists(data_dir):
        os.makedirs(data_dir)

    return os.path.join(data_dir, '')

def _get_datasets_info():
    """
    Reports all available datasets in URL_TEST_DATA

    Requires an internet connection.

    Returns
    -------

    A list of datasets: [key, url, local_filename]

    """

    url = URL_TEST_DATA
    datasets_metadata = requests.get(url, stream=True).iter_lines()
    datasets = []
    for line_metadata in datasets_metadata:
        line_metadata = line_metadata.decode("utf-8")
        if not line_metadata[0]=="#":
            datasets.append([line_metadata.split()[0], line_metadata.split()[2], line_metadata.split()[1]])

    return datasets

def print_available_datasets():
    """
    Prints all available test datasets in URL_TEST_DATA

    Requires an internet connection.

    """

    url = URL_TEST_DATA
    datasets_metadata = requests.get(url, stream=True).iter_lines()
    print("Available datasets:")
    for i, line_metadata in enumerate(datasets_metadata):
        if not line_metadata.decode("utf-8")[0]=="#":
            print("{0}) {1} : {4} \n  Downloaded from {3} \n  Stored as {2}".format(i, *line_metadata.decode("utf-8").split("\t")))
<commit_msg>Download API documentation improved<commit_after>import numpy as np
import pandas as pd

# Test data download requirements:
import requests
import os

URL_DATA = "https://raw.githubusercontent.com/open2c/cooltools/pileup-update/datasets/external_test_files.tsv"

def assign_supports(features, supports, labels=False, suffix=""):
    """
    Assign support regions to a table of genomic intervals.

    Parameters
    ----------
    features : DataFrame
        Dataframe with columns `chrom`, `start`, `end`
        or `chrom1`, `start1`, `end1`, `chrom2`, `start2`, `end2`
    supports : array-like
        Support areas

    """
    features = features.copy()
    supp_col = pd.Series(index=features.index, data=np.nan)

    c = "chrom" + suffix
    s = "start" + suffix
    e = "end" + suffix
    for col in (c, s, e):
        if col not in features.columns:
            raise ValueError(
                'Column "{}" not found in features data frame.'.format(col)
            )

    for i, region in enumerate(supports):
        # single-region support
        if len(region) in [3, 4]:
            sel = (features[c] == region[0]) & (features[e] > region[1])
            if region[2] is not None:
                sel &= features[s] < region[2]
        # paired-region support
        elif len(region) == 2:
            region1, region2 = region
            sel1 = (features[c] == region1[0]) & (features[e] > region1[1])
            if region1[2] is not None:
                sel1 &= features[s] < region1[2]
            sel2 = (features[c] == region2[0]) & (features[e] > region2[1])
            if region2[2] is not None:
                sel2 &= features[s] < region2[2]
            sel = sel1 | sel2
        supp_col.loc[sel] = i

    if labels:
        supp_col = supp_col.map(lambda i: supports[int(i)], na_action="ignore")

    return supp_col

def assign_regions_to_bins(bin_ids, regions_span):

    regions_binsorted = (
        regions_span[(regions_span["bin_start"] >= 0) & (regions_span["bin_end"] >= 0)]
        .sort_values(["bin_start", "bin_end"])
        .reset_index()
    )

    bin_reg_idx_lo = regions_span["bin_start"].searchsorted(bin_ids, "right") - 1
    bin_reg_idx_hi = regions_span["bin_end"].searchsorted(bin_ids, "right")
    mask_assigned = (bin_reg_idx_lo == bin_reg_idx_hi) & (bin_reg_idx_lo >= 0)

    region_ids = pd.array([pd.NA] * len(bin_ids))
    region_ids[mask_assigned] = regions_span["name"][bin_reg_idx_lo[mask_assigned]]

    return region_ids

def download_data(name="all", cache=True, data_dir=None):
    """

    Parameters
    ----------
    name : str
        Name of the dataset.
    cache : boolean, optional
        If True, try to load from the local cache first, and save to the cache
        if a download is required.
    data_dir : string, optional
        The directory where to cache data; default is defined by :func:`get_data_dir`.

    Returns
    -------
    Path to the last downloaded file.

    """

    def download_file(url, local_filename=None):
        if local_filename is None:
            local_filename = url.split('/')[-1]
        print('downloading:', url, 'as', local_filename)
        with requests.get(url, stream=True) as r:
            r.raise_for_status()
            with open(local_filename, 'wb') as f:
                for chunk in r.iter_content(chunk_size=8192):
                    f.write(chunk)
        return local_filename

    available_datasets = _get_datasets_info()
    available_keys = map(lambda x: x[0], available_datasets)

    if name in available_keys:
        keys = [name]
    elif name=="all":
        keys = available_keys
    else:
        raise Exception(
            """Dataset {key} is not available.
            Available datasets: {datasets}
            Use print_available_datasets() to see the details.
            """.format(key=name, datasets=','.join(available_keys)))

    data_dir = get_data_dir(data_dir)

    assert len(keys)>0 # Checking that test data file is parsed successfully
    downloaded = '' # Empty string that will be returned if the request was empty
    for key, url, local_filename in available_datasets:
        if not key in keys:
            continue

        file_path = os.path.join(data_dir, local_filename)
        if cache and os.path.exists(file_path):
            downloaded = file_path
            continue
        elif cache:
            print("Test dataset {} (file {}) is not in the cache directory {}".format(key, local_filename, data_dir))
        downloaded = download_file(url, file_path)

    return downloaded

def get_data_dir(data_dir=None):
    """
    Returns a path to cache directory for example datasets.

    This directory is then used by :func:`download_data`.

    By default, this function uses the location of cooltools as the home folder
    and stores the files under ./datasets/ path there.

    Parameters
    ----------
    data_dir : str, optional
        Location of the home for test data storage

    Returns
    -------
    String with path to the folder with test data

    Notes
    -------
    Designed following seaborn download test data examples:
    https://github.com/mwaskom/seaborn/blob/4dd57d63e23e4628d8b7f41cdefdf64f7fefcf74/seaborn/utils.py#L427

    """

    if data_dir is None:
        data_dir = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', '..', 'datasets/'))

    data_dir = os.path.expanduser(data_dir)
    if not os.path.exists(data_dir):
        os.makedirs(data_dir)

    return os.path.join(data_dir, '')

def _get_datasets_info():
    """
    Reports all available datasets in URL_DATA

    Requires an internet connection.

    Returns
    -------

    A list of datasets: [key, url, local_filename]

    """

    url = URL_DATA
    datasets_metadata = requests.get(url, stream=True).iter_lines()
    datasets = []
    for line_metadata in datasets_metadata:
        line_metadata = line_metadata.decode("utf-8")
        if not line_metadata[0]=="#":
            datasets.append([line_metadata.split()[0], line_metadata.split()[2], line_metadata.split()[1]])

    return datasets

def print_available_datasets():
    """
    Prints all available test datasets in URL_DATA

    Requires an internet connection.

    """

    url = URL_DATA
    datasets_metadata = requests.get(url, stream=True).iter_lines()
    print("Available datasets:")
    for i, line_metadata in enumerate(datasets_metadata):
        if not line_metadata.decode("utf-8")[0]=="#":
            print("{0}) {1} : {4} \n  Downloaded from {3} \n  Stored as {2}".format(i, *line_metadata.decode("utf-8").split("\t")))
<|endoftext|>


<commit_before>import random, math

def poisson_disk_sampling(bbox, pdf, n_iter=100, p_max=10000):
    '''
    A 3D version of Robert Bridson's algorithm, perhaps best illustrated by
    Mike Bostock's following D3.js animation:
    http://bl.ocks.org/mbostock/dbb02448b0f93e4c82c3

    Takes in a virtual 'bounding box' and a generator from which to sample,
    and purports to pack the space as tightly and randomly as possible,
    outputting the coordinates and radii of the corresponding circles.
    '''
    # subfunctions that use local namespace
    def outside():
        ''' checks if point center is within bounds '''
        return any(abs(c) > d/2. for c,d in zip([xj,yj,zj], bbox))

    def near():
        ''' checks if distance between two centers larger than radii'''
        for (xk, yk, zk), rk in zip(points, radii):
            radii_sum = r + rk
            # manhattan distance filter for distant points
            dist_mhtn = [abs(xj-xk), abs(yj-yk), abs(zj-zk)]
            if any(dm > radii_sum for dm in dist_mhtn):
                yield False
            else:
                dist_btwn = math.sqrt(sum(d**2 for d in dist_mhtn))
                yield radii_sum > dist_btwn

    points = [(0,0,0)]
    radii = [next(pdf)]
    available = [0]
    is3d = True if len(bbox)==3 else False

    while available and len(points) <= p_max:
        r = float(next(pdf))
        source = i = random.choice(available)
        xi, yi, zi = points[i]
        inner_r = min_dist = radii[i] + r
        outer_r = min_dist * 2

        for j in range(n_iter):
            # try a random point in the sampling space
            aj = random.random() * 2 * math.pi if is3d else 0
            bj = random.random() * 2 * math.pi
            rj = ( random.random()*(outer_r**3 - inner_r**3) + inner_r**3 )**(1./3.)

            xj = rj * math.cos(aj) * math.sin(bj) + xi
            yj = rj * math.cos(aj) * math.cos(bj) + yi
            zj = rj * math.sin(aj) + zi

            # bail of checks fail
            if outside() or any(near()):
                continue

            # if we got here the point is valid!
            available.append( len(points) )
            points.append( (xj, yj, zj) )
            radii.append( r )
            break

        else:
            # somewhat unknown python feature, think of it as "nobreak"
            # if we got here, it's because no new points were able to be
            # generated. this source is probably too crowded to have new
            # neighbors, so we stop considering it
            available.remove(i)

    return points, radii<commit_msg>Flipped angles for intuitiveness<commit_after>import random, math

def poisson_disk_sampling(bbox, pdf, n_iter=100, p_max=10000):
    '''
    A 3D version of Robert Bridson's algorithm, perhaps best illustrated by
    Mike Bostock's following D3.js animation:
    http://bl.ocks.org/mbostock/dbb02448b0f93e4c82c3

    Takes in a virtual 'bounding box' and a generator from which to sample,
    and purports to pack the space as tightly and randomly as possible,
    outputting the coordinates and radii of the corresponding circles.
    '''
    # subfunctions that use local namespace
    def outside():
        ''' checks if point center is within bounds '''
        return any(abs(c) > d/2. for c,d in zip([xj,yj,zj], bbox))

    def near():
        ''' checks if distance between two centers larger than radii'''
        for (xk, yk, zk), rk in zip(points, radii):
            radii_sum = r + rk
            # manhattan distance filter for distant points
            dist_mhtn = [abs(xj-xk), abs(yj-yk), abs(zj-zk)]
            if any(dm > radii_sum for dm in dist_mhtn):
                yield False
            else:
                dist_btwn = math.sqrt(sum(d**2 for d in dist_mhtn))
                yield radii_sum > dist_btwn

    points = [(0,0,0)]
    radii = [next(pdf)]
    available = [0]
    is3d = True if len(bbox)==3 else False

    while available and len(points) <= p_max:
        r = float(next(pdf))
        source = i = random.choice(available)
        xi, yi, zi = points[i]
        inner_r = min_dist = radii[i] + r
        outer_r = min_dist * 2

        for j in range(n_iter):
            # try a random point in the sampling space
            aj = random.random() * 2 * math.pi
            bj = random.random() * 2 * math.pi if is3d else 0
            rj = ( random.random()*(outer_r**3 - inner_r**3) + inner_r**3 )**(1./3.)

            xj = rj * math.cos(bj) * math.sin(aj) + xi
            yj = rj * math.cos(bj) * math.cos(aj) + yi
            zj = rj * math.sin(bj) + zi

            # bail of checks fail
            if outside() or any(near()):
                continue

            # if we got here the point is valid!
            available.append( len(points) )
            points.append( (xj, yj, zj) )
            radii.append( r )
            break

        else:
            # somewhat unknown python feature, think of it as "nobreak"
            # if we got here, it's because no new points were able to be
            # generated. this source is probably too crowded to have new
            # neighbors, so we stop considering it
            available.remove(i)

    return points, radii<|endoftext|>


<commit_before># coding: utf8

from enum import Enum

import abc
import copy

class OperatorType(Enum):
    AND = 'and'
    OR = 'or'
    XOR = 'xor'

class Entity(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def check(self, element, ref_position):
        pass

    @abc.abstractmethod
    def get_max_position(self):
        pass

    @abc.abstractmethod
    def get_min_position(self):
        pass

class ParsingEntity(Entity, metaclass=abc.ABCMeta):
    def __and__(self, other):
        if isinstance(self, ParsingEntity) and isinstance(other, ParsingEntity):
            parsing_operator = ParsingOperator(OperatorType.AND, self, other)
            return parsing_operator
        else:
            raise TypeError("Operands have to be ParsingEntity's subclasses")

    def __or__(self, other):
        if isinstance(self, ParsingEntity) and isinstance(other, ParsingEntity):
            parsing_operator = ParsingOperator(OperatorType.OR, self, other)
            return parsing_operator
        else:
            raise TypeError("Operands have to be ParsingEntity's subclasses")

    def __xor__(self, other):
        if isinstance(self, ParsingEntity) and isinstance(other, ParsingEntity):
            parsing_operator = ParsingOperator(OperatorType.XOR, self, other)
            return parsing_operator
        else:
            raise TypeError("Operands have to be ParsingEntity's subclasses")

    def __rshift__(self, other):
        if isinstance(self, ParsingEntity) and (isinstance(other, ParsingEntity) or other is None):
            parsing_block = ParsingBlock(self, other)
            return parsing_block
        else:
            raise TypeError("Operands have to be ParsingEntity's subclasses")

    @abc.abstractmethod
    def __eq__(self, other):
        pass

    def __ne__(self, other):
        return not self.__eq__(other)

    @abc.abstractmethod
    def __contains__(self, item):
        pass

    @abc.abstractmethod
    def __str__(self):
        pass

    @abc.abstractmethod
    def __repr__(self):
        self.__str__()

    @abc.abstractmethod
    def __copy__(self):
        pass

    @abc.abstractmethod
    def __deepcopy__(self, memodict={}):
        pass

class ParsingOperator(ParsingEntity):
    def __init__(self, operator_type, operand_a, operand_b):
        self.operatorType = operator_type
        self.operandA = operand_a
        self.operandB = operand_b

    def __eq__(self, other):
        if isinstance(other, ParsingOperator):
            if self.operatorType == other.operatorType and ((self.operandA == other.operandA and self.operandB == other.operandB) or (self.operandA == other.operandB and self.operandB == other.operandA)):
                return True
            else:
                return False
        else:
            return False

    def __contains__(self, item):
        if isinstance(item, ParsingEntity):
            if isinstance(item, ParsingCondition):
                if item in self.operandA or item in self.operandB:
                    return True
                else:
                    return False
            elif isinstance(item, ParsingOperator):
                if self.__eq__(item):
                    return True
                else:
                    if item in self.operandA or item in self.operandB:
                        return True
                    else:
                        return False
            else:
                TypeError("Unknown ParsingEntity's subclass")
        else:
            raise TypeError("Item have to be ParsingEntity's subclasses")

    def __str__(self):
        return 'ParsingOperator object'

    def __repr__(self):
        self.__str__()

    def __copy__(self):
        return ParsingOperator(self.operatorType, self.operandA, self.operandB)

    def __deepcopy__(self, memodict={}):
        return ParsingOperator(self.operatorType, copy.deepcopy(self.operandA), copy.deepcopy(self.operandB))

    def check(self, element, ref_position=0):
        if self.operatorType is OperatorType.AND:
            if self.operandA.check(element, ref_position) is True and self.operandB.check(element, ref_position) is True:
                return True
            else:
                return False
        elif self.operatorType is OperatorType.OR:
            if self.operandA.check(element, ref_position) is True or self.operandB.check(element, ref_position) is True:
                return True
            else:
                return False
        else:
            if (self.operandA.check(element, ref_position) is True) ^ (self.operandB.check(element, ref_position) is True):
                return True
            else:
                return False

    def get_max_position(self):
        operand_a = self.operandA.get_max_position()
        operand_b = self.operandB.get_max_position()

        if operand_a < 0 and operand_b < 0:
            return 0
        else:
            return max([operand_a, operand_b])

    def get_min_position(self):
        operand_a = self.operandA.get_min_position()
        operand_b = self.operandB.get_min_position()

        if operand_a > 0 and operand_b > 0:
            return 0
        else:
            return min([operand_a, operand_b])

class ParsingCondition(ParsingEntity):
    def __init__(self, character, rel_position=0):
        self.rel_position = rel_position
        self.character = character

    def __eq__(self, other):
        if isinstance(other, ParsingCondition):
            if self.rel_position == other.rel_position and self.character == other.character:
                return True
            else:
                return False
        else:
            return False

    def __contains__(self, item):
        self.__eq__(item)

    def __str__(self):
        return 'ParsingCondition object'

    def __repr__(self):
        self.__str__()

    def __copy__(self):
        return ParsingCondition(self.character, self.rel_position)

    def __deepcopy__(self, memodict={}):
        self.__copy__()

    def check(self, element, ref_position=0):
        element_size = len(element)
        if 0 <= ref_position < element_size:
            position = ref_position + self.rel_position
            if 0 <= position < element_size:
                if self.character in element[position]:
                    return True
                else:
                    return False
            else:
                raise IndexError('relative position out of range ( 0 <= ref_position + rel_position < len(element) )')
        else:
            raise IndexError('reference position out of range ( 0 <= ref_position < len(element) )')

    def get_min_position(self):
        if self.rel_position > 0:
            return 0
        else:
            return self.rel_position

    def get_max_position(self):
        if self.rel_position < 0:
            return 0
        else:
            return self.rel_position

class ParsingStructure(Entity):
    def __add__(self, other):
        if isinstance(self, ParsingStructure) and (isinstance(other, ParsingStructure) or other is None):
            parsing_pipeline = ParsingPipeline(self)
            if other is not None:
                parsing_pipeline.add_structure(other)
            return parsing_pipeline
        else:
            raise TypeError("Operands have to be ParsingStructure's subclasses")

    @abc.abstractmethod
    def check(self, element, ref_position):
        pass

    @abc.abstractmethod
    def get_max_position(self):
        pass

    @abc.abstractmethod
    def get_min_position(self):
        pass

class ParsingPipeline(ParsingStructure):
    def __init__(self, first_parsing_structure):
        self.arParsingStructure = list()
        self.arParsingStructure.append(first_parsing_structure)
        self.current_parsing_block_index = 0
        self.isEnded = False

    def check(self, element, ref_position=0):
        if not self.isEnded:
            result = self.arParsingStructure[self.current_parsing_block_index].check(element, ref_position)
            if result[1]:
                if self.current_parsing_block_index < len(self.arParsingStructure)-1:
                    self.current_parsing_block_index += 1
                else:
                    self.isEnded = True
            return result
        else:
            return None

    def get_min_position(self):
        ar_min_position = list()
        for parsing_structure in self.arParsingStructure:
            ar_min_position.append(parsing_structure.get_min_position())
        return min(ar_min_position)

    def get_max_position(self):
        ar_max_position = list()
        for parsing_structure in self.arParsingStructure:
            ar_max_position.append(parsing_structure.get_max_position())
        return max(ar_max_position)

    def add_structure(self, parsing_structure):
        if isinstance(parsing_structure, ParsingPipeline):
            self.arParsingStructure = self.arParsingStructure + parsing_structure.arParsingStructure
        elif isinstance(parsing_structure, ParsingBlock):
            self.arParsingStructure.append(parsing_structure)
        else:
            raise TypeError("Object to add have to be ParsingStructure's subclasses")

    def reset(self):
        self.current_parsing_block_index = 0
        self.isEnded = False

class ParsingBlock(ParsingStructure):
    def __init__(self, parser, border_condition):
        self.parser = parser
        self.borderCondition = border_condition

    def check(self, element, ref_position=0):
        parser_result = self.parser.check(element, ref_position)
        if self.borderCondition is not None:
            border_condition_result = self.borderCondition.check(element, ref_position)
        else:
            border_condition_result = False
        return parser_result, border_condition_result

    def get_min_position(self):
        if self.borderCondition is not None:
            return min([self.parser.get_min_position(), self.borderCondition.get_min_position()])
        else:
            return self.parser.get_min_position()

    def get_max_position(self):
        if self.borderCondition is not None:
            return max([self.parser.get_max_position(), self.borderCondition.get_max_position()])
        else:
            return self.parser.get_max_position()

class ParsingResult:
    def __init__(self, stream_class, read_method, write_method, return_method, args, kwargs, initial_character_index, final_character_index, ar_index):
        self.streamClass = stream_class
        self.readMethod = read_method
        self.writeMethod = write_method
        self.returnMethod = return_method
        self.arInput = {'args': args, 'kwargs': kwargs}
        self.initialCharacterIndex = initial_character_index
        self.finalCharacterIndex = final_character_index
        self.arIndex = ar_index

    def __add__(self, other):
        if isinstance(other, ParsingResult) and isinstance(self, ParsingResult):
            if ParsingResult.are_from_the_same_parsing(self, other):
                new_parsing_result = copy.deepcopy(self)
                for element in other.arIndex:
                    if element[0] not in new_parsing_result.arIndex or (len(element) == 3 and (element[0], None, element[2]) not in new_parsing_result.arIndex):
                        new_parsing_result.arIndex.append(element)
                new_parsing_result.arIndex.sort()
                return new_parsing_result
            else:
                ValueError("Operands have to come from the same parsing")
        else:
            TypeError("Operands have to be ParsingResult classes or subclasses")

    def __contains__(self, item):
        if isinstance(item, int):
            for element in self.arIndex:
                if element[0] == item:
                    return True
            return False
        elif isinstance(item, tuple):
            if len(item) == 2:
                for element in self.arIndex:
                    if element[0] == item[0] and element[1] == item[1]:
                        return True
                    return False
            elif len(item) == 3:
                if item[1] is not None:
                    for element in self.arIndex:
                        if len(element) == 3 and element[0] == item[0] and element[1] == item[1] and element[2] == item[2]:
                            return True
                    return False
                else:
                    for element in self.arIndex:
                        if len(element) == 3 and element[0] == item[0] and element[2] == item[2]:
                            return True
                    return False
            else:
                return False
        else:
            return False

    def __str__(self):
        return str({'Stream class': str(self.streamClass.__name__), 'Inputs': str(self.arInput),
                    'from': str(self.initialCharacterIndex), 'to': str(self.finalCharacterIndex),
                    'Index result': str(self.arIndex)})

    def __repr__(self):
        return 'Parsing result :' + '\n' + '   Stream class : ' + str(self.streamClass.__name__) + '\n' \
               + '   Inputs : ' + str(self.arInput) + '\n' + '   Parsed from character ' \
               + str(self.initialCharacterIndex) + ' to character ' + str(self.finalCharacterIndex) + '\n' \
               + '   Index result : ' + str(self.arIndex)

    def __copy__(self):
        return ParsingResult(self.streamClass, self.readMethod, self.writeMethod, self.returnMethod,
                             self.arInput['args'], self.arInput['kwargs'], self.initialCharacterIndex,
                             self.finalCharacterIndex, self.arIndex)

    def __deepcopy__(self, memodict={}):
        copy_ar_input = copy.deepcopy(self.arInput)
        copy_ar_index = copy.deepcopy(self.arIndex)
        return ParsingResult(self.streamClass, self.readMethod, self.writeMethod, self.returnMethod,
                             copy_ar_input['args'], copy_ar_input['kwargs'], self.initialCharacterIndex,
                             self.finalCharacterIndex, copy_ar_index)

    @staticmethod
    def are_from_the_same_parsing(parsing_result_a, parsing_result_b):
        if isinstance(parsing_result_a, ParsingResult) and isinstance(parsing_result_b, ParsingResult):
            return (parsing_result_a.streamClass == parsing_result_b.streamClass and
                    parsing_result_a.arInput['args'] == parsing_result_b.arInput['args'] and
                    parsing_result_a.arInput['kwargs'] == parsing_result_b.arInput['kwargs'] and
                    parsing_result_a.initialCharacterIndex == parsing_result_b.initialCharacterIndex and
                    parsing_result_a.finalCharacterIndex == parsing_result_b.finalCharacterIndex and
                    parsing_result_a.readMethod == parsing_result_b.readMethod and
                    parsing_result_a.writeMethod == parsing_result_b.writeMethod and
                    parsing_result_a.returnMethod == parsing_result_b.returnMethod)
        else:
            TypeError("Operands have to be ParsingResult classes or subclasses")

    def check_indexes(self):
        previous_index_value = -1
        for index in self.arIndex:
            if index[0] > previous_index_value:
                previous_index_value = index[0]
            else:
                raise ValueError('Indexes have to be sorted in ascending order')
            if len(index[1]) != 1 or not isinstance(index[1], str):
                raise TypeError("Indexes's characters have to be 'str' objects with a length of 1")

        return True
<commit_msg>Implement invert operator overloading<commit_after># coding: utf8

from enum import Enum

import abc
import copy

class OperatorType(Enum):
    AND = 'and'
    OR = 'or'
    XOR = 'xor'

class Entity(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def check(self, element, ref_position):
        pass

    @abc.abstractmethod
    def get_max_position(self):
        pass

    @abc.abstractmethod
    def get_min_position(self):
        pass

class ParsingEntity(Entity, metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def __init__(self):
        self.isNot = False

    def __and__(self, other):
        if isinstance(self, ParsingEntity) and isinstance(other, ParsingEntity):
            parsing_operator = ParsingOperator(OperatorType.AND, self, other)
            return parsing_operator
        else:
            raise TypeError("Operands have to be ParsingEntity's subclasses")

    def __or__(self, other):
        if isinstance(self, ParsingEntity) and isinstance(other, ParsingEntity):
            parsing_operator = ParsingOperator(OperatorType.OR, self, other)
            return parsing_operator
        else:
            raise TypeError("Operands have to be ParsingEntity's subclasses")

    def __xor__(self, other):
        if isinstance(self, ParsingEntity) and isinstance(other, ParsingEntity):
            parsing_operator = ParsingOperator(OperatorType.XOR, self, other)
            return parsing_operator
        else:
            raise TypeError("Operands have to be ParsingEntity's subclasses")

    def __rshift__(self, other):
        if isinstance(self, ParsingEntity) and (isinstance(other, ParsingEntity) or other is None):
            parsing_block = ParsingBlock(self, other)
            return parsing_block
        else:
            raise TypeError("Operands have to be ParsingEntity's subclasses")

    def __ne__(self, other):
        return not self.__eq__(other)

    def __invert__(self):
        result = copy.deepcopy(self)
        result.isNot = not result.isNot
        return result

    @abc.abstractmethod
    def __eq__(self, other):
        pass

    @abc.abstractmethod
    def __contains__(self, item):
        pass

    @abc.abstractmethod
    def __str__(self):
        pass

    @abc.abstractmethod
    def __repr__(self):
        self.__str__()

    @abc.abstractmethod
    def __copy__(self):
        pass

    @abc.abstractmethod
    def __deepcopy__(self, memodict={}):
        pass

class ParsingOperator(ParsingEntity):
    def __init__(self, operator_type, operand_a, operand_b):
        super(ParsingOperator, self).__init__()
        self.operatorType = operator_type
        self.operandA = operand_a
        self.operandB = operand_b

    def __eq__(self, other):
        if isinstance(other, ParsingOperator):
            if self.operatorType == other.operatorType and self.isNot == other.isNot and\
                    ((self.operandA == other.operandA and self.operandB == other.operandB)
                     or (self.operandA == other.operandB and self.operandB == other.operandA)):
                return True
            else:
                return False
        else:
            return False

    def __contains__(self, item):
        if isinstance(item, ParsingEntity):
            if isinstance(item, ParsingCondition):
                if item in self.operandA or item in self.operandB:
                    return True
                else:
                    return False
            elif isinstance(item, ParsingOperator):
                if self.__eq__(item):
                    return True
                else:
                    if item in self.operandA or item in self.operandB:
                        return True
                    else:
                        return False
            else:
                TypeError("Unknown ParsingEntity's subclass")
        else:
            raise TypeError("Item have to be ParsingEntity's subclasses")

    def __str__(self):
        return 'ParsingOperator object'

    def __repr__(self):
        return self.__str__()

    def __copy__(self):
        result = ParsingOperator(self.operatorType, self.operandA, self.operandB)
        result.isNot = self.isNot
        return result

    def __deepcopy__(self, memodict={}):
        result = ParsingOperator(self.operatorType, copy.deepcopy(self.operandA), copy.deepcopy(self.operandB))
        result.isNot = self.isNot
        return result

    def check(self, element, ref_position=0):
        if self.operatorType is OperatorType.AND:
            if self.operandA.check(element, ref_position) is True and self.operandB.check(element, ref_position) is True:
                result = True
            else:
                result = False
        elif self.operatorType is OperatorType.OR:
            if self.operandA.check(element, ref_position) is True or self.operandB.check(element, ref_position) is True:
                result = True
            else:
                result = False
        else:
            if (self.operandA.check(element, ref_position) is True) ^ (self.operandB.check(element, ref_position) is True):
                result = True
            else:
                result = False

        if self.isNot is False:
            return result
        else:
            return not result

    def get_max_position(self):
        operand_a = self.operandA.get_max_position()
        operand_b = self.operandB.get_max_position()

        if operand_a < 0 and operand_b < 0:
            return 0
        else:
            return max([operand_a, operand_b])

    def get_min_position(self):
        operand_a = self.operandA.get_min_position()
        operand_b = self.operandB.get_min_position()

        if operand_a > 0 and operand_b > 0:
            return 0
        else:
            return min([operand_a, operand_b])

class ParsingCondition(ParsingEntity):
    def __init__(self, character, rel_position=0):
        super(ParsingCondition, self).__init__()
        self.rel_position = rel_position
        self.character = character

    def __eq__(self, other):
        if isinstance(other, ParsingCondition):
            if self.rel_position == other.rel_position and self.character == other.character \
                    and self.isNot == other.isNot:
                return True
            else:
                return False
        else:
            return False

    def __contains__(self, item):
        return self.__eq__(item)

    def __str__(self):
        return 'ParsingCondition object'

    def __repr__(self):
        return self.__str__()

    def __copy__(self):
        result = ParsingCondition(self.character, self.rel_position)
        result.isNot = self.isNot
        return result

    def __deepcopy__(self, memodict={}):
        return self.__copy__()

    def check(self, element, ref_position=0):
        element_size = len(element)
        if 0 <= ref_position < element_size:
            position = ref_position + self.rel_position
            if 0 <= position < element_size:
                if self.character in element[position]:
                    result = True
                else:
                    result = False

                if self.isNot is False:
                    return result
                else:
                    return not result
            else:
                raise IndexError('relative position out of range ( 0 <= ref_position + rel_position < len(element) )')
        else:
            raise IndexError('reference position out of range ( 0 <= ref_position < len(element) )')

    def get_min_position(self):
        if self.rel_position > 0:
            return 0
        else:
            return self.rel_position

    def get_max_position(self):
        if self.rel_position < 0:
            return 0
        else:
            return self.rel_position

class ParsingStructure(Entity):
    def __add__(self, other):
        if isinstance(self, ParsingStructure) and (isinstance(other, ParsingStructure) or other is None):
            parsing_pipeline = ParsingPipeline(self)
            if other is not None:
                parsing_pipeline.add_structure(other)
            return parsing_pipeline
        else:
            raise TypeError("Operands have to be ParsingStructure's subclasses")

    @abc.abstractmethod
    def check(self, element, ref_position):
        pass

    @abc.abstractmethod
    def get_max_position(self):
        pass

    @abc.abstractmethod
    def get_min_position(self):
        pass

class ParsingPipeline(ParsingStructure):
    def __init__(self, first_parsing_structure):
        self.arParsingStructure = list()
        self.arParsingStructure.append(first_parsing_structure)
        self.current_parsing_block_index = 0
        self.isEnded = False

    def check(self, element, ref_position=0):
        if not self.isEnded:
            result = self.arParsingStructure[self.current_parsing_block_index].check(element, ref_position)
            if result[1]:
                if self.current_parsing_block_index < len(self.arParsingStructure)-1:
                    self.current_parsing_block_index += 1
                else:
                    self.isEnded = True
            return result
        else:
            return None

    def get_min_position(self):
        ar_min_position = list()
        for parsing_structure in self.arParsingStructure:
            ar_min_position.append(parsing_structure.get_min_position())
        return min(ar_min_position)

    def get_max_position(self):
        ar_max_position = list()
        for parsing_structure in self.arParsingStructure:
            ar_max_position.append(parsing_structure.get_max_position())
        return max(ar_max_position)

    def add_structure(self, parsing_structure):
        if isinstance(parsing_structure, ParsingPipeline):
            self.arParsingStructure = self.arParsingStructure + parsing_structure.arParsingStructure
        elif isinstance(parsing_structure, ParsingBlock):
            self.arParsingStructure.append(parsing_structure)
        else:
            raise TypeError("Object to add have to be ParsingStructure's subclasses")

    def reset(self):
        self.current_parsing_block_index = 0
        self.isEnded = False

class ParsingBlock(ParsingStructure):
    def __init__(self, parser, border_condition):
        self.parser = parser
        self.borderCondition = border_condition

    def check(self, element, ref_position=0):
        parser_result = self.parser.check(element, ref_position)
        if self.borderCondition is not None:
            border_condition_result = self.borderCondition.check(element, ref_position)
        else:
            border_condition_result = False
        return parser_result, border_condition_result

    def get_min_position(self):
        if self.borderCondition is not None:
            return min([self.parser.get_min_position(), self.borderCondition.get_min_position()])
        else:
            return self.parser.get_min_position()

    def get_max_position(self):
        if self.borderCondition is not None:
            return max([self.parser.get_max_position(), self.borderCondition.get_max_position()])
        else:
            return self.parser.get_max_position()

class ParsingResult:
    def __init__(self, stream_class, read_method, write_method, return_method, args, kwargs, initial_character_index, final_character_index, ar_index):
        self.streamClass = stream_class
        self.readMethod = read_method
        self.writeMethod = write_method
        self.returnMethod = return_method
        self.arInput = {'args': args, 'kwargs': kwargs}
        self.initialCharacterIndex = initial_character_index
        self.finalCharacterIndex = final_character_index
        self.arIndex = ar_index

    def __add__(self, other):
        if isinstance(other, ParsingResult) and isinstance(self, ParsingResult):
            if ParsingResult.are_from_the_same_parsing(self, other):
                new_parsing_result = copy.deepcopy(self)
                for element in other.arIndex:
                    if element[0] not in new_parsing_result.arIndex or (len(element) == 3 and (element[0], None, element[2]) not in new_parsing_result.arIndex):
                        new_parsing_result.arIndex.append(element)
                new_parsing_result.arIndex.sort()
                return new_parsing_result
            else:
                ValueError("Operands have to come from the same parsing")
        else:
            TypeError("Operands have to be ParsingResult classes or subclasses")

    def __contains__(self, item):
        if isinstance(item, int):
            for element in self.arIndex:
                if element[0] == item:
                    return True
            return False
        elif isinstance(item, tuple):
            if len(item) == 2:
                for element in self.arIndex:
                    if element[0] == item[0] and element[1] == item[1]:
                        return True
                    return False
            elif len(item) == 3:
                if item[1] is not None:
                    for element in self.arIndex:
                        if len(element) == 3 and element[0] == item[0] and element[1] == item[1] and element[2] == item[2]:
                            return True
                    return False
                else:
                    for element in self.arIndex:
                        if len(element) == 3 and element[0] == item[0] and element[2] == item[2]:
                            return True
                    return False
            else:
                return False
        else:
            return False

    def __str__(self):
        return str({'Stream class': str(self.streamClass.__name__), 'Inputs': str(self.arInput),
                    'from': str(self.initialCharacterIndex), 'to': str(self.finalCharacterIndex),
                    'Index result': str(self.arIndex)})

    def __repr__(self):
        return 'Parsing result :' + '\n' + '   Stream class : ' + str(self.streamClass.__name__) + '\n' \
               + '   Inputs : ' + str(self.arInput) + '\n' + '   Parsed from character ' \
               + str(self.initialCharacterIndex) + ' to character ' + str(self.finalCharacterIndex) + '\n' \
               + '   Index result : ' + str(self.arIndex)

    def __copy__(self):
        return ParsingResult(self.streamClass, self.readMethod, self.writeMethod, self.returnMethod,
                             self.arInput['args'], self.arInput['kwargs'], self.initialCharacterIndex,
                             self.finalCharacterIndex, self.arIndex)

    def __deepcopy__(self, memodict={}):
        copy_ar_input = copy.deepcopy(self.arInput)
        copy_ar_index = copy.deepcopy(self.arIndex)
        return ParsingResult(self.streamClass, self.readMethod, self.writeMethod, self.returnMethod,
                             copy_ar_input['args'], copy_ar_input['kwargs'], self.initialCharacterIndex,
                             self.finalCharacterIndex, copy_ar_index)

    @staticmethod
    def are_from_the_same_parsing(parsing_result_a, parsing_result_b):
        if isinstance(parsing_result_a, ParsingResult) and isinstance(parsing_result_b, ParsingResult):
            return (parsing_result_a.streamClass == parsing_result_b.streamClass and
                    parsing_result_a.arInput['args'] == parsing_result_b.arInput['args'] and
                    parsing_result_a.arInput['kwargs'] == parsing_result_b.arInput['kwargs'] and
                    parsing_result_a.initialCharacterIndex == parsing_result_b.initialCharacterIndex and
                    parsing_result_a.finalCharacterIndex == parsing_result_b.finalCharacterIndex and
                    parsing_result_a.readMethod == parsing_result_b.readMethod and
                    parsing_result_a.writeMethod == parsing_result_b.writeMethod and
                    parsing_result_a.returnMethod == parsing_result_b.returnMethod)
        else:
            TypeError("Operands have to be ParsingResult classes or subclasses")

    def check_indexes(self):
        previous_index_value = -1
        for index in self.arIndex:
            if index[0] > previous_index_value:
                previous_index_value = index[0]
            else:
                raise ValueError('Indexes have to be sorted in ascending order')
            if len(index[1]) != 1 or not isinstance(index[1], str):
                raise TypeError("Indexes's characters have to be 'str' objects with a length of 1")

        return True
<|endoftext|>


<commit_before>#
# Copyright (c) 2011 rPath, Inc.
#
# All Rights Reserved
#

import urlparse

from django.db import models

from mint.django_rest.deco import D
from mint.django_rest.rbuilder import modellib
from mint.django_rest.rbuilder.users import models as usersmodels
from mint.django_rest.rbuilder.inventory import zones as zmodels
from xobj import xobj
import sys

XObjHidden = modellib.XObjHidden

class TargetType(modellib.XObjModel):
    class Meta:
         db_table = 'target_types'

    target_type_id = models.AutoField(primary_key=True)
    name = D(models.TextField(unique=True), "Target Type Name")
    description = D(models.TextField(null=False), "Target Type Description")
    created_date = D(modellib.DateTimeUtcField(auto_now_add=True), "the date the resource was created (UTC)")
    modified_date = D(modellib.DateTimeUtcField(auto_now_add=True), "the date the resource was modified (UTC)")

class Targets(modellib.Collection):
    class Meta:
        abstract = True

    _xobj = xobj.XObjMetadata(tag='targets')
    list_fields = ['target']

class Target(modellib.XObjModel):
    _xobj_hidden_accessors = set(
        ['targetdata_set', 'targetimagesdeployed_set', 'targetusercredentials_set', 'system_set', ])

    class Meta:
        db_table = u'targets'

    target_id = models.AutoField(primary_key=True, db_column='targetid')
    target_type = modellib.DeferredForeignKey(TargetType, null=False,
        related_name='targets', view_name='TargetTypeTargets')
    zone = modellib.DeferredForeignKey(zmodels.Zone, null=False,
        related_name='targets')
    name = models.TextField(null=False)
    description = models.TextField(null=False)
    unique_together = (target_type, name)

class TargetData(modellib.XObjModel):
    class Meta:
        db_table = u'targetdata'

    targetdata_id = models.AutoField(primary_key=True, db_column='targetdataid')
    target_id = models.ForeignKey('Target', db_column="targetid")
    name = models.CharField(max_length=255, null=False)
    value = models.TextField()
    # Uhm. django does not support multi-column PKs.

class TargetCredentials(modellib.XObjModel):
    class Meta:
        db_table = u'targetcredentials'
    target_credentials_id = models.AutoField(primary_key=True,
        db_column="targetcredentialsid")
    credentials = models.TextField(null=False, unique=True)

class TargetUserCredentials(modellib.XObjModel):
    target_id = models.ForeignKey('Target', db_column="targetid")
    user_id = models.ForeignKey(usersmodels.User, db_column="userid",
        related_name='target_user_credentials')
    target_credentials_id = models.ForeignKey('TargetCredentials',
        db_column="targetcredentialsid")
    class Meta:
        db_table = u'targetusercredentials'

class TargetImagesDeployed(modellib.XObjModel):
    target_id = models.ForeignKey('Target', db_column="targetid")
    file_id = models.IntegerField(null=False, db_column='fileid')
    target_image_id = models.CharField(max_length=128, db_column='targetimageid')
    class Meta:
        db_table = u'targetimagesdeployed'

class TargetTypes(modellib.Collection):
    class Meta:
        abstract = True

    _xobj = xobj.XObjMetadata(tag='target_types')
    list_fields = ['target_type']

for mod_obj in sys.modules[__name__].__dict__.values():
    if hasattr(mod_obj, '_xobj'):
        if mod_obj._xobj.tag:
            modellib.type_map[mod_obj._xobj.tag] = mod_obj
    if hasattr(mod_obj, '_meta'):
        modellib.type_map[mod_obj._meta.verbose_name] = mod_obj
<commit_msg>resolved<commit_after>#
# Copyright (c) 2011 rPath, Inc.
#
# All Rights Reserved
#

import urlparse

from django.db import models

from mint.django_rest.deco import D
from mint.django_rest.rbuilder import modellib
from mint.django_rest.rbuilder.users import models as usersmodels
from mint.django_rest.rbuilder.inventory import zones as zmodels
from xobj import xobj
import sys

XObjHidden = modellib.XObjHidden

class TargetType(modellib.XObjModel):
    class Meta:
         db_table = 'target_types'

    target_type_id = models.AutoField(primary_key=True)
    name = D(models.TextField(unique=True), "Target Type Name")
    description = D(models.TextField(null=False), "Target Type Description")
    created_date = D(modellib.DateTimeUtcField(auto_now_add=True), "the date the resource was created (UTC)")
    modified_date = D(modellib.DateTimeUtcField(auto_now_add=True), "the date the resource was modified (UTC)")

class Targets(modellib.Collection):
    class Meta:
        abstract = True

    _xobj = xobj.XObjMetadata(tag='targets')
    list_fields = ['target']

class Target(modellib.XObjModel):
    _xobj_hidden_accessors = set(
        ['targetdata_set', 'targetimagesdeployed_set', 'targetusercredentials_set', 'system_set', ])

    class Meta:
        db_table = u'targets'

    target_id = models.AutoField(primary_key=True, db_column='targetid')
    target_type = modellib.DeferredForeignKey(TargetType, null=False,
        related_name='targets', view_name='TargetTypeTargets')
    zone = modellib.DeferredForeignKey(zmodels.Zone, null=False,
        related_name='targets')
    name = models.TextField(null=False)
    description = models.TextField(null=False)
    unique_together = (target_type, name)

class TargetData(modellib.XObjModel):
    class Meta:
        db_table = u'targetdata'

    targetdata_id = models.AutoField(primary_key=True, db_column='targetdataid')
    target_id = models.ForeignKey('Target', db_column="targetid")
    name = models.CharField(max_length=255, null=False)
    value = models.TextField()
    # Uhm. django does not support multi-column PKs.

class TargetCredentials(modellib.XObjModel):
    class Meta:
        db_table = u'targetcredentials'
    target_credentials_id = models.AutoField(primary_key=True,
        db_column="targetcredentialsid")
    credentials = models.TextField(null=False, unique=True)

class TargetUserCredentials(modellib.XObjModel):
    target_id = models.ForeignKey('Target', db_column="targetid")
    user_id = models.ForeignKey(usersmodels.User, db_column="userid",
        related_name='target_user_credentials')
    target_credentials_id = models.ForeignKey('TargetCredentials',
        db_column="targetcredentialsid")
    class Meta:
        db_table = u'targetusercredentials'

class TargetImagesDeployed(modellib.XObjModel):
    target_id = models.ForeignKey('Target', db_column="targetid")
    file_id = models.IntegerField(null=False, db_column='fileid')
    target_image_id = models.CharField(max_length=128, db_column='targetimageid')
    class Meta:
        db_table = u'targetimagesdeployed'

class TargetTypes(modellib.Collection):
    class Meta:
        abstract = True

    _xobj = xobj.XObjMetadata(tag='target_types')
    list_fields = ['target_type']

class TargetType(modellib.XObjModel):
    class Meta:
         db_table = u'targettypes'

    target_type_id = models.AutoField(primary_key=True, db_column='targettypeid')
    name = models.CharField(max_length=255)
    created_date = modellib.DecimalField(max_digits=14, decimal_places=3, db_column='timecreated')
    modified_date = modellib.DecimalField(max_digits=14, decimal_places=3, db_column='timeaccessed')
    description = models.TextField(null=True, blank=True)

for mod_obj in sys.modules[__name__].__dict__.values():
    if hasattr(mod_obj, '_xobj'):
        if mod_obj._xobj.tag:
            modellib.type_map[mod_obj._xobj.tag] = mod_obj
    if hasattr(mod_obj, '_meta'):
        modellib.type_map[mod_obj._meta.verbose_name] = mod_obj
<|endoftext|>