<commit_before># -*- coding: utf-8 -*-

from .utils import entity
from ..constants import *

__all__ = [
    'abundance',
    'gene',
    'rna',
    'mirna',
    'protein',
    'complex_abundance',
    'bioprocess',
    'pathology',
    'pmod',
    'gmod',
    'hgvs',
    'protein_fusion',
    'rna_fusion',
    'gene_fusion',
]

def _make_abundance(func, namespace, name=None, identifier=None):
    """

    :param str func: The PyBEL function
    :param str namespace: The name of the namespace
    :param Optional[str] name:
    :param Optional[str] identifier:
    :return:
    """
    if name is None and identifier is None:
        raise ValueError('Either name or identifier must be specified')

    rv = {FUNCTION: func}
    rv.update(entity(namespace=namespace, name=name, identifier=identifier))
    return rv

def pmod(name, code=None, position=None, namespace=None, identifier=None):
    """Builds a protein modification dict

    :param str name: The name of the modification
    :param str code: The three letter amino acid code for the affected residue
    :param int position: The position of the affected residue
    :param str namespace: The namespace to which the name of this modification belongs
    :param str identifier: The identifier of the name of the modification
    :rtype: dict
    """
    rv = {
        KIND: PMOD,
        IDENTIFIER: entity(
            namespace=(namespace or BEL_DEFAULT_NAMESPACE),
            name=name,
            identifier=identifier
        )
    }

    if code:
        rv[PMOD_CODE] = code

    if position:
        rv[PMOD_POSITION] = position

    return rv

def gmod(name, namespace=None, identifier=None):
    """Builds a gene modification dict

    :param str name: The name of the gene modification
    :param Optional[str] namespace: The namespace of the gene modification
    :param Optional[str] identifier: The identifier of the name in the database

    Example:
    >>> gene(namespace='HGNC', name='AKT1', variants=[gmod('Me')])
    """
    rv = {
        KIND: GMOD,
        IDENTIFIER: entity(
            namespace=(namespace or BEL_DEFAULT_NAMESPACE),
            name=name,
            identifier=identifier
        )
    }

    return rv

def hgvs(variant):
    """A convenience function for building a variant dictionary

    :param str variant: The HGVS variant string
    :rtype: dict

    Example:
    >>> protein(namespace='HGNC', name='AKT1', variants=[hgvs('p.Ala127Tyr')])
    """
    return {KIND: HGVS, IDENTIFIER: variant}

def _make_central_dogma_abundance(func, name=None, namespace=None, identifier=None, variants=None):
    """Make central dogma abundance (meaning it can have variants)"""
    rv = _make_abundance(func, name=name, namespace=namespace, identifier=identifier)

    if variants:
        rv[VARIANTS] = variants

    return rv

def gene(name=None, namespace=None, identifier=None, variants=None):
    """Returns the node data dictionary for a gene

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :param list variants: A list of variants
    :rtype: dict
    """
    rv = _make_central_dogma_abundance(GENE, name=name, namespace=namespace, identifier=identifier, variants=variants)
    return rv

def rna(name=None, namespace=None, identifier=None, variants=None):
    """Returns the node data dictionary for an RNA

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :param list variants: A list of variants
    :rtype: dict
    """
    rv = _make_central_dogma_abundance(RNA, name=name, namespace=namespace, identifier=identifier, variants=variants)
    return rv

def mirna(name=None, namespace=None, identifier=None, variants=None):
    """Returns the node data dictionary for a miRNA

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :param list variants: A list of variants
    :rtype: dict
    """
    rv = _make_central_dogma_abundance(MIRNA, name=name, namespace=namespace, identifier=identifier, variants=variants)
    return rv

def protein(name=None, namespace=None, identifier=None, variants=None):
    """Returns the node data dictionary for a protein

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :param list variants: A list of variants
    :rtype: dict

    Example: AKT

    >>> protein(namespace='HGNC', name='AKT1')

    Example: AKT with optionally included HGNC database identifier

    >>> protein(namespace='HGNC', name='AKT1', identifier='391')

    Example: AKT with phosphorylation

    >>> protein(namespace='HGNC', name='AKT', variants=[pmod('Ph', code='Thr', position=308)])
    """
    rv = _make_central_dogma_abundance(PROTEIN, name=name, namespace=namespace, identifier=identifier,
                                       variants=variants)
    return rv

def abundance(namespace, name=None, identifier=None):
    """Returns the node data dictionary for an abundance

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :rtype: dict
    """
    return _make_abundance(ABUNDANCE, name=name, namespace=namespace, identifier=identifier)

def bioprocess(namespace, name=None, identifier=None):
    """Returns the node data dictionary for a biological process

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :rtype: dict
    """
    return _make_abundance(BIOPROCESS, name=name, namespace=namespace, identifier=identifier)

def pathology(namespace, name=None, identifier=None):
    """Returns the node data dictionary for a pathology

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :rtype: dict
    """
    return _make_abundance(PATHOLOGY, name=name, namespace=namespace, identifier=identifier)

def complex_abundance(members, namespace=None, name=None, identifier=None):
    """Returns the node data dictionary for a protein complex

    :param list[dict] members: A list of PyBEL node data dictionaries
    :param str namespace: The namespace from which the name originates
    :param str name: The name of the complex
    :param str identifier: The identifier in the namespace in which the name originates
    :rtype: dict
    """
    rv = {
        FUNCTION: COMPLEX,
        MEMBERS: members
    }

    if namespace:
        rv.update(entity(namespace=namespace, name=name, identifier=identifier))

    return rv

def fusion_range(reference, start, stop):
    """Creates a fusion range

    :param reference:
    :param start:
    :param stop:
    :rtype: dict
    """
    return {
        FUSION_REFERENCE: reference,
        FUSION_START: start,
        FUSION_STOP: stop
    }

def fusion(func, partner_5p, range_5p, partner_3p, range_3p):
    """Creates a fusion entry

    :param str func: A PyBEL function
    :param dict partner_5p: A PyBEL node data dictionary for the 5-prime partner
    :param dict range_5p: A fusion range produced by :func:`fusion_range` for the 5-prime partner
    :param dict partner_3p: A PyBEL node data dictionary for the 3-prime partner
    :param dict range_3p: A fusion range produced by :func:`fusion_range` for the 3-prime partner
    :rtype: dict
    """
    return {
        FUNCTION: func,
        FUSION: {
            PARTNER_5P: partner_5p,
            PARTNER_3P: partner_3p,
            RANGE_5P: range_5p,
            RANGE_3P: range_3p
        }
    }

def protein_fusion(partner_5p, range_5p, partner_3p, range_3p):
    """Creates a protein fusion

    :param dict partner_5p: A PyBEL node data dictionary for the 5-prime partner
    :param dict range_5p: A fusion range produced by :func:`fusion_range` for the 5-prime partner
    :param dict partner_3p: A PyBEL node data dictionary for the 3-prime partner
    :param dict range_3p: A fusion range produced by :func:`fusion_range` for the 3-prime partner
    :rtype: dict
    """
    return fusion(PROTEIN, partner_5p=partner_5p, range_5p=range_5p, partner_3p=partner_3p, range_3p=range_3p)

def rna_fusion(partner_5p, range_5p, partner_3p, range_3p):
    """Creates a RNA fusion

    :param dict partner_5p: A PyBEL node data dictionary for the 5-prime partner
    :param dict range_5p: A fusion range produced by :func:`fusion_range` for the 5-prime partner
    :param dict partner_3p: A PyBEL node data dictionary for the 3-prime partner
    :param dict range_3p: A fusion range produced by :func:`fusion_range` for the 3-prime partner
    :rtype: dict
    """
    return fusion(RNA, partner_5p=partner_5p, range_5p=range_5p, partner_3p=partner_3p, range_3p=range_3p)

def gene_fusion(partner_5p, range_5p, partner_3p, range_3p):
    """Creates a gene fusion

    :param dict partner_5p: A PyBEL node data dictionary for the 5-prime partner
    :param dict range_5p: A fusion range produced by :func:`fusion_range` for the 5-prime partner
    :param dict partner_3p: A PyBEL node data dictionary for the 3-prime partner
    :param dict range_3p: A fusion range produced by :func:`fusion_range` for the 3-prime partner
    :rtype: dict
    """
    return fusion(GENE, partner_5p=partner_5p, range_5p=range_5p, partner_3p=partner_3p, range_3p=range_3p)
<commit_msg>Update DSL<commit_after># -*- coding: utf-8 -*-

from .utils import entity
from ..constants import *

__all__ = [
    'abundance',
    'gene',
    'rna',
    'mirna',
    'protein',
    'complex_abundance',
    'bioprocess',
    'pathology',
    'pmod',
    'gmod',
    'hgvs',
    'fusion_range',
    'protein_fusion',
    'rna_fusion',
    'gene_fusion',
]

def _make_abundance(func, namespace, name=None, identifier=None):
    """

    :param str func: The PyBEL function
    :param str namespace: The name of the namespace
    :param Optional[str] name:
    :param Optional[str] identifier:
    :return:
    """
    if name is None and identifier is None:
        raise ValueError('Either name or identifier must be specified')

    rv = {FUNCTION: func}
    rv.update(entity(namespace=namespace, name=name, identifier=identifier))
    return rv

def pmod(name, code=None, position=None, namespace=None, identifier=None):
    """Builds a protein modification dict

    :param str name: The name of the modification
    :param str code: The three letter amino acid code for the affected residue
    :param int position: The position of the affected residue
    :param str namespace: The namespace to which the name of this modification belongs
    :param str identifier: The identifier of the name of the modification
    :rtype: dict
    """
    rv = {
        KIND: PMOD,
        IDENTIFIER: entity(
            namespace=(namespace or BEL_DEFAULT_NAMESPACE),
            name=name,
            identifier=identifier
        )
    }

    if code:
        rv[PMOD_CODE] = code

    if position:
        rv[PMOD_POSITION] = position

    return rv

def gmod(name, namespace=None, identifier=None):
    """Builds a gene modification dict

    :param str name: The name of the gene modification
    :param Optional[str] namespace: The namespace of the gene modification
    :param Optional[str] identifier: The identifier of the name in the database

    Example:
    >>> gene(namespace='HGNC', name='AKT1', variants=[gmod('Me')])
    """
    rv = {
        KIND: GMOD,
        IDENTIFIER: entity(
            namespace=(namespace or BEL_DEFAULT_NAMESPACE),
            name=name,
            identifier=identifier
        )
    }

    return rv

def hgvs(variant):
    """A convenience function for building a variant dictionary

    :param str variant: The HGVS variant string
    :rtype: dict

    Example:
    >>> protein(namespace='HGNC', name='AKT1', variants=[hgvs('p.Ala127Tyr')])
    """
    return {KIND: HGVS, IDENTIFIER: variant}

def _make_central_dogma_abundance(func, name=None, namespace=None, identifier=None, variants=None):
    """Make central dogma abundance (meaning it can have variants)"""
    rv = _make_abundance(func, name=name, namespace=namespace, identifier=identifier)

    if variants:
        rv[VARIANTS] = variants

    return rv

def gene(name=None, namespace=None, identifier=None, variants=None):
    """Returns the node data dictionary for a gene

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :param list variants: A list of variants
    :rtype: dict
    """
    rv = _make_central_dogma_abundance(GENE, name=name, namespace=namespace, identifier=identifier, variants=variants)
    return rv

def rna(name=None, namespace=None, identifier=None, variants=None):
    """Returns the node data dictionary for an RNA

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :param list variants: A list of variants
    :rtype: dict
    """
    rv = _make_central_dogma_abundance(RNA, name=name, namespace=namespace, identifier=identifier, variants=variants)
    return rv

def mirna(name=None, namespace=None, identifier=None, variants=None):
    """Returns the node data dictionary for a miRNA

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :param list variants: A list of variants
    :rtype: dict
    """
    rv = _make_central_dogma_abundance(MIRNA, name=name, namespace=namespace, identifier=identifier, variants=variants)
    return rv

def protein(name=None, namespace=None, identifier=None, variants=None):
    """Returns the node data dictionary for a protein

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :param list variants: A list of variants
    :rtype: dict

    Example: AKT

    >>> protein(namespace='HGNC', name='AKT1')

    Example: AKT with optionally included HGNC database identifier

    >>> protein(namespace='HGNC', name='AKT1', identifier='391')

    Example: AKT with phosphorylation

    >>> protein(namespace='HGNC', name='AKT', variants=[pmod('Ph', code='Thr', position=308)])
    """
    rv = _make_central_dogma_abundance(PROTEIN, name=name, namespace=namespace, identifier=identifier,
                                       variants=variants)
    return rv

def abundance(namespace, name=None, identifier=None):
    """Returns the node data dictionary for an abundance

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :rtype: dict
    """
    return _make_abundance(ABUNDANCE, name=name, namespace=namespace, identifier=identifier)

def bioprocess(namespace, name=None, identifier=None):
    """Returns the node data dictionary for a biological process

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :rtype: dict
    """
    return _make_abundance(BIOPROCESS, name=name, namespace=namespace, identifier=identifier)

def pathology(namespace, name=None, identifier=None):
    """Returns the node data dictionary for a pathology

    :param str namespace: The name of the database used to identify this entity
    :param str name: The database's preferred name or label for this entity
    :param str identifier: The database's identifier for this entity
    :rtype: dict
    """
    return _make_abundance(PATHOLOGY, name=name, namespace=namespace, identifier=identifier)

def complex_abundance(members, namespace=None, name=None, identifier=None):
    """Returns the node data dictionary for a complex, with optional ability to specify a name

    :param list[dict] members: A list of PyBEL node data dictionaries
    :param str namespace: The namespace from which the name originates
    :param str name: The name of the complex
    :param str identifier: The identifier in the namespace in which the name originates
    :rtype: dict
    """
    rv = {
        FUNCTION: COMPLEX,
        MEMBERS: members
    }

    if namespace:
        rv.update(entity(namespace=namespace, name=name, identifier=identifier))

    return rv

def composite_abundance(members):
    """Returns the node data dictionary for a composite

    :param list[dict] members: A list of PyBEL node data dictionaries
    :rtype: dict
    """
    rv = {
        FUNCTION: COMPOSITE,
        MEMBERS: members
    }

    return rv

def fusion_range(reference, start, stop):
    """Creates a fusion range

    :param reference:
    :param start:
    :param stop:
    :rtype: dict
    """
    return {
        FUSION_REFERENCE: reference,
        FUSION_START: start,
        FUSION_STOP: stop
    }

def fusion(func, partner_5p, range_5p, partner_3p, range_3p):
    """Creates a fusion entry

    :param str func: A PyBEL function
    :param dict partner_5p: A PyBEL node data dictionary for the 5-prime partner
    :param dict range_5p: A fusion range produced by :func:`fusion_range` for the 5-prime partner
    :param dict partner_3p: A PyBEL node data dictionary for the 3-prime partner
    :param dict range_3p: A fusion range produced by :func:`fusion_range` for the 3-prime partner
    :rtype: dict
    """
    return {
        FUNCTION: func,
        FUSION: {
            PARTNER_5P: partner_5p,
            PARTNER_3P: partner_3p,
            RANGE_5P: range_5p,
            RANGE_3P: range_3p
        }
    }

def protein_fusion(partner_5p, range_5p, partner_3p, range_3p):
    """Creates a protein fusion

    :param dict partner_5p: A PyBEL node data dictionary for the 5-prime partner
    :param dict range_5p: A fusion range produced by :func:`fusion_range` for the 5-prime partner
    :param dict partner_3p: A PyBEL node data dictionary for the 3-prime partner
    :param dict range_3p: A fusion range produced by :func:`fusion_range` for the 3-prime partner
    :rtype: dict
    """
    return fusion(PROTEIN, partner_5p=partner_5p, range_5p=range_5p, partner_3p=partner_3p, range_3p=range_3p)

def rna_fusion(partner_5p, range_5p, partner_3p, range_3p):
    """Creates a RNA fusion

    :param dict partner_5p: A PyBEL node data dictionary for the 5-prime partner
    :param dict range_5p: A fusion range produced by :func:`fusion_range` for the 5-prime partner
    :param dict partner_3p: A PyBEL node data dictionary for the 3-prime partner
    :param dict range_3p: A fusion range produced by :func:`fusion_range` for the 3-prime partner
    :rtype: dict
    """
    return fusion(RNA, partner_5p=partner_5p, range_5p=range_5p, partner_3p=partner_3p, range_3p=range_3p)

def gene_fusion(partner_5p, range_5p, partner_3p, range_3p):
    """Creates a gene fusion

    :param dict partner_5p: A PyBEL node data dictionary for the 5-prime partner
    :param dict range_5p: A fusion range produced by :func:`fusion_range` for the 5-prime partner
    :param dict partner_3p: A PyBEL node data dictionary for the 3-prime partner
    :param dict range_3p: A fusion range produced by :func:`fusion_range` for the 3-prime partner
    :rtype: dict
    """
    return fusion(GENE, partner_5p=partner_5p, range_5p=range_5p, partner_3p=partner_3p, range_3p=range_3p)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

#
# Copyright 2016 edX PDR Lab, National Central University, Taiwan.
#
#     http://edxpdrlab.ncu.cc/
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Created By: yrchen@ATCity.org
# Maintained By: yrchen@ATCity.org
#

from __future__ import absolute_import, unicode_literals

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

from rest_framework import permissions
from rest_framework import renderers
from rest_framework import viewsets
from rest_framework.decorators import detail_route
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.parsers import JSONParser

from rest_framework_tracking.mixins import LoggingMixin

from commonrepo.users.models import User as User

from .permissions import IsOwnerOrReadOnly
from .serializers import UserSerializer, UserSerializerV2, UserLiteSerializer

class UserViewSet(LoggingMixin, viewsets.ModelViewSet):
    """
    This endpoint presents the users in the system.

    As you can see, the collection of snippet instances owned by a user are
    serialized using a hyperlinked representation.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [IsOwnerOrReadOnly]

class UserViewSetV2(LoggingMixin, viewsets.ModelViewSet):
    """
    This endpoint presents the users in the system.

    As you can see, the collection of snippet instances owned by a user are
    serialized using a hyperlinked representation.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializerV2
    permission_classes = [IsOwnerOrReadOnly]

    def list(self, request):
        queryset = User.objects.all()
        serializer = UserLiteSerializer(queryset, many=True)
        return Response(serializer.data)
<commit_msg>更新 modules Users API 中的 views.py, 新增函式功能宣告註解<commit_after># -*- coding: utf-8 -*-

#
# Copyright 2016 edX PDR Lab, National Central University, Taiwan.
#
#     http://edxpdrlab.ncu.cc/
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Created By: yrchen@ATCity.org
# Maintained By: yrchen@ATCity.org
#

"""
View configurations of user information for Users APIs in Common Repo project.
"""

from __future__ import absolute_import, unicode_literals

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

from rest_framework import permissions
from rest_framework import renderers
from rest_framework import viewsets
from rest_framework.decorators import detail_route
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.parsers import JSONParser

from rest_framework_tracking.mixins import LoggingMixin

from commonrepo.users.models import User as User

from .permissions import IsOwnerOrReadOnly
from .serializers import UserSerializer, UserSerializerV2, UserLiteSerializer

class UserViewSet(LoggingMixin, viewsets.ModelViewSet):
    """
    This endpoint presents the users in the system. (API version 1)

    As you can see, the collection of snippet instances owned by a user are
    serialized using a hyperlinked representation.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [IsOwnerOrReadOnly]

class UserViewSetV2(LoggingMixin, viewsets.ModelViewSet):
    """
    This endpoint presents the users in the system. (API version 2)

    As you can see, the collection of ELOs and Groups instances owned by a user
    are serialized using normal model serializer representation.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializerV2
    permission_classes = [IsOwnerOrReadOnly]

    def list(self, request):
        queryset = User.objects.all()
        serializer = UserLiteSerializer(queryset, many=True)
        return Response(serializer.data)
<|endoftext|>


<commit_before>import os
import yaml

import sys
if sys.version[0]=="3": raw_input=input

DIR = os.path.dirname(os.path.realpath(__file__))
DATA = os.path.join(DIR, '_data')
RULES = os.path.join(DATA, 'rules.yml')
LICENSES = os.path.join(DIR, '_licenses')
YAML_SEP = '---'

# Prettyprint utilities
def print1(s):
    print('')
    print(s)

def print2(s):
    print('')
    print(s)
    print('')

# Utility functions
def load_rules():
    """Load rules - collection of tags, labels and descriptions."""
    s = open(os.path.join(DATA, RULES))
    return yaml.load(s)

def extract_yaml(txt, sep):
    """Extracts YAML and returns it along with leftover."""
    tks = txt.split(sep)
    return tks[1], ''.join(tks[2:])

def process_lic(name):
    """Process a single license file."""
    path = os.path.join(LICENSES, name)
    with open(path) as lic:
        y, md = extract_yaml(lic.read(), YAML_SEP)
        return (name, (yaml.load(y), md))

def load_licenses():
    """Load all the license files and their metadata."""
    lics = [l for l in os.listdir(LICENSES)]
    data = map(process_lic, lics)
    return dict(data)

def get_choice(rule):
    """Ask question, get choice."""
    tag = rule['tag']
    label = rule['label']
    description = rule['description']
    ch = raw_input('%s (%s) [1-5] > ' % (label, description))
    if ch in ['1', '2', '3', '4', '5']:
        return tag, ch

    print1('Please enter a number between 1 and 5!')
    return get_choice(rule)

def get_choice_vector(rules):
    """Ask questions get choices."""
    return dict(map(get_choice, rules))

def get_license_vector(lic):
    """Return pseudo-choice vector given license."""
    data, _ = lic
    vec = {}
    for dim in ['forbidden', 'required', 'permitted']:
        if data[dim] is None:
            continue
        dim_vec = map(lambda x: (x,5), data[dim])
        vec[dim] = dict(dim_vec)
    return vec

def vector_distance(v, _v):
    dist = 0
    for dim in v:
        for x in v[dim]:
            dd = int(v[dim][x]) - int(_v[dim][x])
            dist = dist + dd**2
    return dist

def dget(d, k):
    return d[k] if k in d else ''

def main():
    # load everything
    lics = load_licenses()
    rules = load_rules()
    ch_vectors = {}
    lic_vectors = {}
    dists = []

    # get user choices
    for rule in rules:
        text = 'What should be %s by your license?' % rule
        print2(text)
        ch_vectors[rule] = get_choice_vector(rules[rule])

    # get license stuff
    for lic in lics:
        lic_vectors[lic] = get_license_vector(lics[lic])

    # calculate distance
    for lic in lics:
        d = vector_distance(lic_vectors[lic], ch_vectors)
        dists.append((lic, d))

    # sort distances
    sdists = sorted(dists, key=lambda x: x[1])

    # print results
    print1('According to the given criteria, top 3 FOSS licenses are: ')
    for i, sd in enumerate(sdists[:3]):
        lic, dist = sd
        data, txt = lics[lic]
        print1('%d) %s [dist=%s]' % (i+1, dget(data, 'title'), d))
        print1(dget(data, 'description'))
        print1(dget(data, 'how'))
        print1(dget(data, 'source'))

if __name__ == '__main__':
    main()
<commit_msg>Adding ArgumentParser.<commit_after># -*- coding: utf-8 -*-

"""
    Palal - Pick A License, Any License!
    ------------------------------------

    Picking an open-source license can be confusing for seasoned developers
    let along noobs. There are too many choices to begin with. On top of that,
    there is the vocabulary that reads like English without making any sense.

    The situation is unacceptable and it hurts FOSS.

    Palal aims to resolve that. It is a simple CLI utility that asks the user
    a series of questions In-Plain-English and returns the best possible FOSS
    license for his/her project.

    Palal is inspired by the choosealicense.com and it uses the same license
    meta-data. However, while choosealicense.com displays the meta-data for the
    given license, Palal returns the license for the given meta-data.

    If you use Palal, I would love to have your feedback:

        https://github.com/alixedi/palal

    Now *release* that code!

    :copyright (c) 2015 by Ali Zaidi.
    :license: BSD, see LICENSE for more details.

    ~ * ~
"""

import os
import yaml
import argparse

import sys
if sys.version[0]=="3": raw_input=input

DIR = os.path.dirname(os.path.realpath(__file__))
DATA = os.path.join(DIR, '_data')
RULES = os.path.join(DATA, 'rules.yml')
LICENSES = os.path.join(DIR, '_licenses')
YAML_SEP = '---'

_desc = 'Answer a few questions to get the best FOSS license for your project.'
parser = argparse.ArgumentParser(description=_desc)

# Prettyprint utilities
def print1(s):
    print('')
    print(s)

def print2(s):
    print('')
    print(s)
    print('')

# Utility functions
def load_rules():
    """Load rules - collection of tags, labels and descriptions."""
    s = open(os.path.join(DATA, RULES))
    return yaml.load(s)

def extract_yaml(txt, sep):
    """Extracts YAML and returns it along with leftover."""
    tks = txt.split(sep)
    return tks[1], ''.join(tks[2:])

def process_lic(name):
    """Process a single license file."""
    path = os.path.join(LICENSES, name)
    with open(path) as lic:
        y, md = extract_yaml(lic.read(), YAML_SEP)
        return (name, (yaml.load(y), md))

def load_licenses():
    """Load all the license files and their metadata."""
    lics = [l for l in os.listdir(LICENSES)]
    data = map(process_lic, lics)
    return dict(data)

def get_choice(rule):
    """Ask question, get choice."""
    tag = rule['tag']
    label = rule['label']
    description = rule['description']
    ch = raw_input('%s (%s) [1-5] > ' % (label, description))
    if ch in ['1', '2', '3', '4', '5']:
        return tag, ch

    print1('Please enter a number between 1 and 5!')
    return get_choice(rule)

def get_choice_vector(rules):
    """Ask questions get choices."""
    return dict(map(get_choice, rules))

def get_license_vector(lic):
    """Return pseudo-choice vector given license."""
    data, _ = lic
    vec = {}
    for dim in ['forbidden', 'required', 'permitted']:
        if data[dim] is None:
            continue
        dim_vec = map(lambda x: (x,5), data[dim])
        vec[dim] = dict(dim_vec)
    return vec

def vector_distance(v, _v):
    dist = 0
    for dim in v:
        for x in v[dim]:
            dd = int(v[dim][x]) - int(_v[dim][x])
            dist = dist + dd**2
    return dist

def dget(d, k):
    return d[k] if k in d else ''

def main():
    # parse args
    args = parser.parse_args()
    # load everything
    lics = load_licenses()
    rules = load_rules()
    ch_vectors = {}
    lic_vectors = {}
    dists = []

    # get user choices
    for rule in rules:
        text = 'What should be %s by your license?' % rule
        print2(text)
        ch_vectors[rule] = get_choice_vector(rules[rule])

    # get license stuff
    for lic in lics:
        lic_vectors[lic] = get_license_vector(lics[lic])

    # calculate distance
    for lic in lics:
        d = vector_distance(lic_vectors[lic], ch_vectors)
        dists.append((lic, d))

    # sort distances
    sdists = sorted(dists, key=lambda x: x[1])

    # print results
    print1('According to the given criteria, top 3 FOSS licenses are: ')
    for i, sd in enumerate(sdists[:3]):
        lic, dist = sd
        data, txt = lics[lic]
        print1('%d) %s [dist=%s]' % (i+1, dget(data, 'title'), d))
        print1(dget(data, 'description'))
        print1(dget(data, 'how'))
        print1(dget(data, 'source'))

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before># libavg - Media Playback Engine.
# Copyright (C) 2003-2008 Ulrich von Zadow
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Current versions can be found at www.libavg.de
#
# Original author of this file is Martin Heistermann <mh at sponc dot de>
#

import math
from libavg import Point2D

def getAngle(p1, p2):
    vec = p2 - p1
    res = math.atan2(vec.y, vec.x)
    if res < 0:
        res += math.pi * 2
    return res

def getDistance (p, q):
    return math.sqrt((p.x-q.x)**2 + (p.y-q.y)**2)

def getDistSquared (p, q):
    return (p.x-q.x)**2 + (p.y-q.y)**2

def getScaledDim (size, max = None, min = None):
    width, height = size
    if width == 0 or height == 0:
        return size

    if max:
        assert (max.x > 0 and max.y > 0)
        max = Point2D(max)
        if width > max.x:
            height = height * (max.x / width)
            width = max.x
        if height > max.y:
            width = width * (max.y / height)
            height = max.y

    if min:
        assert (min.x > 0 and min.y > 0)
        min = Point2D(min)
        if width < min.x:
            height = height * (min.x / width)
            width = min.x
        if height < min.y:
            width = width * (min.y / height)
            height = min.y

    return Point2D(width, height)

class EquationNotSolvable (Exception):
    pass
class EquationSingular (Exception):
    pass

def gauss_jordan(m, eps = 1.0/(10**10)):
    """Puts given matrix (2D array) into the Reduced Row Echelon Form.
         Returns True if successful, False if 'm' is singular.
         NOTE: make sure all the matrix items support fractions! Int matrix will NOT work!
         Written by Jarno Elonen in April 2005, released into Public Domain
         http://elonen.iki.fi/code/misc-notes/affine-fit/index.html"""
    (h, w) = (len(m), len(m[0]))
    for y in range(0,h):
        maxrow = y
        for y2 in range(y+1, h):        # Find max pivot
            if abs(m[y2][y]) > abs(m[maxrow][y]):
                maxrow = y2
        (m[y], m[maxrow]) = (m[maxrow], m[y])
        if abs(m[y][y]) <= eps:         # Singular?
            raise EquationSingular
        for y2 in range(y+1, h):        # Eliminate column y
            c = m[y2][y] / m[y][y]
            for x in range(y, w):
                m[y2][x] -= m[y][x] * c
    for y in range(h-1, 0-1, -1): # Backsubstitute
        c    = m[y][y]
        for y2 in range(0,y):
            for x in range(w-1, y-1, -1):
                m[y2][x] -=    m[y][x] * m[y2][y] / c
        m[y][y] /= c
        for x in range(h, w):             # Normalize row y
            m[y][x] /= c
    return m

def solveEquationMatrix(_matrix, eps = 1.0/(10**10)):
    matrix=[]
    for coefficients, res in _matrix:
        newrow = map(float, coefficients + (res,))
        matrix.append(newrow)
    matrix = gauss_jordan (matrix)
    res=[]
    for col in xrange(len(matrix[0])-1):
        rows = filter(lambda row: row[col] >= eps, matrix)
        if len(rows)!=1:
            raise EquationNotSolvable
        res.append (rows[0][-1])

    return res

def getOffsetForMovedPivot(oldPivot, newPivot, angle):
    oldPos = Point2D(0,0).getRotated(angle, oldPivot)
    newPos = Point2D(0,0).getRotated(angle, newPivot)
    return oldPos - newPos

<commit_msg>mathutil: added isNaN()<commit_after># libavg - Media Playback Engine.
# Copyright (C) 2003-2008 Ulrich von Zadow
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Current versions can be found at www.libavg.de
#
# Original author of this file is Martin Heistermann <mh at sponc dot de>
#

import math
from libavg import Point2D

def getAngle(p1, p2):
    vec = p2 - p1
    res = math.atan2(vec.y, vec.x)
    if res < 0:
        res += math.pi * 2
    return res

def getDistance (p, q):
    return math.sqrt((p.x-q.x)**2 + (p.y-q.y)**2)

def getDistSquared (p, q):
    return (p.x-q.x)**2 + (p.y-q.y)**2

def getScaledDim (size, max = None, min = None):
    width, height = size
    if width == 0 or height == 0:
        return size

    if max:
        assert (max.x > 0 and max.y > 0)
        max = Point2D(max)
        if width > max.x:
            height = height * (max.x / width)
            width = max.x
        if height > max.y:
            width = width * (max.y / height)
            height = max.y

    if min:
        assert (min.x > 0 and min.y > 0)
        min = Point2D(min)
        if width < min.x:
            height = height * (min.x / width)
            width = min.x
        if height < min.y:
            width = width * (min.y / height)
            height = min.y

    return Point2D(width, height)

class EquationNotSolvable (Exception):
    pass
class EquationSingular (Exception):
    pass

def gauss_jordan(m, eps = 1.0/(10**10)):
    """Puts given matrix (2D array) into the Reduced Row Echelon Form.
         Returns True if successful, False if 'm' is singular.
         NOTE: make sure all the matrix items support fractions! Int matrix will NOT work!
         Written by Jarno Elonen in April 2005, released into Public Domain
         http://elonen.iki.fi/code/misc-notes/affine-fit/index.html"""
    (h, w) = (len(m), len(m[0]))
    for y in range(0,h):
        maxrow = y
        for y2 in range(y+1, h):        # Find max pivot
            if abs(m[y2][y]) > abs(m[maxrow][y]):
                maxrow = y2
        (m[y], m[maxrow]) = (m[maxrow], m[y])
        if abs(m[y][y]) <= eps:         # Singular?
            raise EquationSingular
        for y2 in range(y+1, h):        # Eliminate column y
            c = m[y2][y] / m[y][y]
            for x in range(y, w):
                m[y2][x] -= m[y][x] * c
    for y in range(h-1, 0-1, -1): # Backsubstitute
        c    = m[y][y]
        for y2 in range(0,y):
            for x in range(w-1, y-1, -1):
                m[y2][x] -=    m[y][x] * m[y2][y] / c
        m[y][y] /= c
        for x in range(h, w):             # Normalize row y
            m[y][x] /= c
    return m

def solveEquationMatrix(_matrix, eps = 1.0/(10**10)):
    matrix=[]
    for coefficients, res in _matrix:
        newrow = map(float, coefficients + (res,))
        matrix.append(newrow)
    matrix = gauss_jordan (matrix)
    res=[]
    for col in xrange(len(matrix[0])-1):
        rows = filter(lambda row: row[col] >= eps, matrix)
        if len(rows)!=1:
            raise EquationNotSolvable
        res.append (rows[0][-1])

    return res

def getOffsetForMovedPivot(oldPivot, newPivot, angle):
    oldPos = Point2D(0,0).getRotated(angle, oldPivot)
    newPos = Point2D(0,0).getRotated(angle, newPivot)
    return oldPos - newPos

def isNaN(x):
    return (not(x<=0) and not(x>=0))

<|endoftext|>


<commit_before>import json
import logging
import os

from requests.exceptions import HTTPError

logger = logging.getLogger("dunya")

import compmusic.dunya.conn
import compmusic.dunya.docserver

COLLECTIONS = None

def set_collections(collections):
    """ Set a list of collections mbid to restrict the queries.
    You must call this before you can make any other calls, otherwise
    they won't be restricted.

    :param collections: list of collections mbids
    """
    global COLLECTIONS
    if not isinstance(collections, list):
        raise ValueError('`collections` must be a list')
    COLLECTIONS = collections

def _get_collections():
    extra_headers = None
    if COLLECTIONS:
        extra_headers = {}
        extra_headers['Dunya-Collection'] = ','.join(COLLECTIONS)
    return extra_headers

def get_recordings(recording_detail=False):
    """ Get a list of andalusian recordings in the database.
    This function will automatically page through API results.

    :param recording_detail: if True, return full details for each recording
    like :func:`get_recording`

    :returns: A list of dictionaries containing recording information::
        {"mbid": MusicBrainz recording ID, "title": Title of the recording,
        "transliterated_title"}

    For additional information about each recording use :func:`get_recording`.
    """
    extra_headers = _get_collections()
    args = {}
    if recording_detail:
        args['detail'] = '1'
    return compmusic.dunya.conn._get_paged_json("api/andalusian/recording",
                                                extra_headers=extra_headers, **args)

def get_recording(rmbid):
    """ Get specific information about a recording.

    :param rmbid: A recording mbid

    :returns: mbid, title, transliterated_name, musescore_url, archive url and sections.

         ``sections`` include information about the start and end time of the section,
         the name and the transliterated name.
    """
    extra_headers = _get_collections()
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/recording/%s" % rmbid,
                                                  extra_headers=extra_headers)

def get_artists():
    """ Get a list of Andalusian artists in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing artist information::

        {"mbid": MusicBrainz artist ID, "name": Name of the artist}
    """
    extra_headers = _get_collections()
    return compmusic.dunya.conn._get_paged_json("api/andalusian/artist",
                                                extra_headers=extra_headers)

def get_artist(ambid):
    """ Get specific information about an artist.

    :param ambid: An artist mbid

    :returns: mbid, name, releases, instruments, recordings.

             ``releases``, ``instruments`` and ``recordings`` include
             information from recording- and release-level
             relationships, as well as release artists
    """
    extra_headers = _get_collections()
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/artist/%s" % ambid,
                                                  extra_headers=extra_headers)

def get_works():
    """ Get a list of Andalusian works in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing work information::

        {"mbid": MusicBrainz work ID, "name": work name}

    For additional information about each work use :func:`get_work`.
    """
    extra_headers = _get_collections()
    return compmusic.dunya.conn._get_paged_json("api/andalusian/work",
                                                extra_headers=extra_headers)

def get_work(wmbid):
    """ Get specific information about a work.

    :param wmbid: A work mbid
    :returns: mbid, title, recordings
    """
    extra_headers = _get_collections()
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/work/%s" % wmbid,
                                                  extra_headers=extra_headers)

def get_mizans():
    """ Get a list of Andalusian mizan in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing mizan information::

        {"uuid": Mizan uuid, "name": Name of the mizan, transliterated_name: Transliterated name of the mizan,
        "display_order"}

    For additional information about each mizan use :func:`get_mizan`.
    """
    return compmusic.dunya.conn._get_paged_json("api/andalusian/mizan")

def get_mizan(mid):
    """ Get specific information about a mizan.

    :param mid: uuid
    :returns: uuid, name, transliterated_name, display_order
    """
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/mizan/%s" % str(mid))

def get_tabs():
    """ Get a list of Andalusian tabs in the database.
    This function will automatically page through API results.

    returns: A list of dictionaries containing tab information::

        {"uuid": Mizan uuid, "name": Name of the tab, transliterated_name: Transliterated name of the tab,
        "display_order"}

    For additional information about each taal use :func:`get_tab`.
    """
    return compmusic.dunya.conn._get_paged_json("api/andalusian/tab")

def get_tab(tid):
    """ Get specific information about a tab.

    :param tid: uuid
    :returns: uuid, name, transliterated_name, display_order.
    """
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/tab/%s" % str(tid))

def get_nawbas():
    """ Get a list of Andalusian nawbas in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing nawba information::

        {"uuid": Nawba uuid, "name": Name of the nawba, transliterated_name: Transliterated name of the nawba,
        "display_order"}

    For additional information about each nawba use :func:`get_nawba.
    """
    return compmusic.dunya.conn._get_paged_json("api/andalusian/nawba")

def get_nawba(nid):
    """ Get specific information about a nawba.

    :param nid: uuid
    :returns: uuid, name, transliterated_name, display_order
    """
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/nawba/%s" % str(nid))

def get_forms():
    """ Get a list of Andalusian forms in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing form information::

        {"uuid": Form uuid, "name": Name of the form, transliterated_name: Transliterated name of the form,
        "display_order: Order number of form perform through the nawba"}

    For additional information about each form use :func:`get_form`
    """
    return compmusic.dunya.conn._get_paged_json("api/andalusian/form")

def get_form(fid):
    """ Get specific information about a form.

    :param fid: uuid
    :returns: uuid, name, transliterated_name, display_order
    """
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/form/%s" % str(fid))

def get_instruments():
    """ Get a list of Andalusian instruments in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing instrument information::

        {"id": instrument id, "name": Name of the instrument, "original_name"}

    For additional information about each instrument use :func:`get_instrument`
    """
    return compmusic.dunya.conn._get_paged_json("api/andalusian/instrument")

def get_instrument(iid):
    """ Get specific information about an instrument.

    :param iid: An instrument id
    :returns: id, name
    """
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/instrument/%s" % str(iid))

def download_mp3(recordingid, location):
    """Download the mp3 of a document and save it to the specified directory.

    :param recordingid: The MBID of the recording
    :param location: Where to save the mp3 to
    """
    if not os.path.exists(location):
        raise Exception("Location %s doesn't exist; can't save" % location)

    recording = get_recording(recordingid)
    title = recording["title"]
    contents = compmusic.dunya.docserver.get_mp3(recordingid)
    name = "%s.mp3" % (title)
    name = name.replace("/", "-")
    path = os.path.join(location, name)
    with open(path, "wb") as file:
        file.write(contents)
    return name

def download_score(recordingid, location):
    """Download the score of a document and save it to the specified directory.

    :param recordingid: The MBID of the recording
    :param location: Where to save the score file to

    """
    if not os.path.exists(location):
        raise Exception("Location %s doesn't exist; can't save" % location)

    try:
        contents = compmusic.dunya.docserver.file_for_document(recordingid, 'symbtrxml')
        name = "%s.xml" % (recordingid)
        path = os.path.join(location, name)
        with open(path, "wb") as file:
            file.write(contents)
    except HTTPError:
        print("%s score is not stored in Dunya" % recordingid)

def download_pitch_track(recordingid, location):
    """ Download the pitch track from a specific recording and save it to the specified
    directory.

    :param recordingid: The MBID of the recording
    :param location: Where to save the json to
    """
    if not os.path.exists(location):
        raise Exception("Location %s doesn't exist; can't save" % location)
    try:
        result = compmusic.dunya.docserver.get_document_as_json(recordingid, "andalusianpitch", subtype="pitch_filt")
        name = recordingid + "_pitchtrack.json"
        output = os.path.join(location, name)
        with open(output, 'w') as output:
            json.dump(result, output)
    except HTTPError:
        print("%s pitch track is not stored in Dunya" % recordingid)

def download_pitch_distribution(recordingid, location):
    """ Download the pitch distribution from a specific recording and save it to the specified directory.

    :param recordingid: The MBID of the recording
    :param location: Where to save the json to

    """
    if not os.path.exists(location):
        raise Exception("Location %s doesn't exist; can't save" % location)
    try:
        result = compmusic.dunya.docserver.get_document_as_json(recordingid, "andalusianpitch",
                                                                subtype="pitch_distribution")
        name = recordingid + "_pitchdistribution.json"
        output = os.path.join(location, name)
        with open(output, 'w') as output:
            json.dump(result, output)
    except HTTPError:
        print("%s pitch distribution is not stored in Dunya" % recordingid)

def download_lyrics(recordingid, location):
    """ Download the arabic and transliteration version of the lyrics of a specific recording
    :param recordingid: The MBID of the recording
    :param location: Where to save the json to

    """
    if not os.path.exists(location):
        raise Exception("Location %s doesn't exist; can't save" % location)
    try:
        result = compmusic.dunya.docserver.file_for_document(recordingid, "andalusian-lyrics").decode('utf-8')
        name = recordingid + "_lyrics.json"
        output = os.path.join(location, name)
        with open(output, 'w') as json_file:
            json.dump(result, json_file)
    except HTTPError:
        print("%s lyrics is not stored in Dunya" % recordingid)
<commit_msg>Check comments of the functions<commit_after>import json
import logging
import os

from requests.exceptions import HTTPError

logger = logging.getLogger("dunya")

import compmusic.dunya.conn
import compmusic.dunya.docserver

COLLECTIONS = None

def set_collections(collections):
    """ Set a list of collections mbid to restrict the queries.
    You must call this before you can make any other calls, otherwise
    they won't be restricted.

    :param collections: list of collections mbids
    """
    global COLLECTIONS
    if not isinstance(collections, list):
        raise ValueError('`collections` must be a list')
    COLLECTIONS = collections

def _get_collections():
    extra_headers = None
    if COLLECTIONS:
        extra_headers = {}
        extra_headers['Dunya-Collection'] = ','.join(COLLECTIONS)
    return extra_headers

def get_recordings(recording_detail=False):
    """ Get a list of andalusian recordings in the database.
    This function will automatically page through API results.

    :param recording_detail: if True, return full details for each recording
    like :func:`get_recording`

    :returns: A list of dictionaries containing recording information::

        {"mbid": MusicBrainz recording ID, "title": Title of the recording, "transliterated_title"}

    For additional information about each recording use :func:`get_recording`.
    """
    extra_headers = _get_collections()
    args = {}
    if recording_detail:
        args['detail'] = '1'
    return compmusic.dunya.conn._get_paged_json("api/andalusian/recording",
                                                extra_headers=extra_headers, **args)

def get_recording(rmbid):
    """ Get specific information about a recording.

    :param rmbid: A recording mbid

    :returns: mbid, title, transliterated_name, musescore_url, archive url and sections.

         ``sections`` include information about the start and end time of the section,
         the name and the transliterated name.
    """
    extra_headers = _get_collections()
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/recording/%s" % rmbid,
                                                  extra_headers=extra_headers)

def get_artists():
    """ Get a list of Andalusian artists in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing artist information::

        {"mbid": MusicBrainz artist ID, "name": Name of the artist}
    """
    extra_headers = _get_collections()
    return compmusic.dunya.conn._get_paged_json("api/andalusian/artist",
                                                extra_headers=extra_headers)

def get_artist(ambid):
    """ Get specific information about an artist.

    :param ambid: An artist mbid

    :returns: mbid, name, releases, instruments, recordings.

             ``releases``, ``instruments`` and ``recordings`` include
             information from recording- and release-level
             relationships, as well as release artists
    """
    extra_headers = _get_collections()
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/artist/%s" % ambid,
                                                  extra_headers=extra_headers)

def get_works():
    """ Get a list of Andalusian works in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing work information::

        {"mbid": MusicBrainz work ID, "name": work name}

    For additional information about each work use :func:`get_work`.
    """
    extra_headers = _get_collections()
    return compmusic.dunya.conn._get_paged_json("api/andalusian/work",
                                                extra_headers=extra_headers)

def get_work(wmbid):
    """ Get specific information about a work.

    :param wmbid: A work mbid
    :returns: mbid, title, recordings
    """
    extra_headers = _get_collections()
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/work/%s" % wmbid,
                                                  extra_headers=extra_headers)

def get_mizans():
    """ Get a list of Andalusian mizan in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing mizan information::

        {"uuid": Mizan uuid, "name": Name of the mizan, transliterated_name: Transliterated name of the mizan,
        "display_order"}

    For additional information about each mizan use :func:`get_mizan`.
    """
    return compmusic.dunya.conn._get_paged_json("api/andalusian/mizan")

def get_mizan(mid):
    """ Get specific information about a mizan.

    :param mid: uuid
    :returns: uuid, name, transliterated_name, display_order
    """
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/mizan/%s" % str(mid))

def get_tabs():
    """ Get a list of Andalusian tabs in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing tab information::

        {"uuid": Mizan uuid, "name": Name of the tab, transliterated_name: Transliterated name of the tab,
        "display_order"}

    For additional information about each taal use :func:`get_tab`.
    """
    return compmusic.dunya.conn._get_paged_json("api/andalusian/tab")

def get_tab(tid):
    """ Get specific information about a tab.

    :param tid: uuid
    :returns: uuid, name, transliterated_name, display_order.
    """
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/tab/%s" % str(tid))

def get_nawbas():
    """ Get a list of Andalusian nawbas in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing nawba information::

        {"uuid": Nawba uuid, "name": Name of the nawba, transliterated_name: Transliterated name of the nawba,
        "display_order"}

    For additional information about each nawba use :func:`get_nawba.
    """
    return compmusic.dunya.conn._get_paged_json("api/andalusian/nawba")

def get_nawba(nid):
    """ Get specific information about a nawba.

    :param nid: uuid
    :returns: uuid, name, transliterated_name, display_order
    """
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/nawba/%s" % str(nid))

def get_forms():
    """ Get a list of Andalusian forms in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing form information::

        {"uuid": Form uuid, "name": Name of the form, transliterated_name: Transliterated name of the form,
        "display_order: Order number of form perform through the nawba"}

    For additional information about each form use :func:`get_form`
    """
    return compmusic.dunya.conn._get_paged_json("api/andalusian/form")

def get_form(fid):
    """ Get specific information about a form.

    :param fid: uuid
    :returns: uuid, name, transliterated_name, display_order
    """
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/form/%s" % str(fid))

def get_instruments():
    """ Get a list of Andalusian instruments in the database.
    This function will automatically page through API results.

    :returns: A list of dictionaries containing instrument information::

        {"id": instrument id, "name": Name of the instrument, "original_name"}

    For additional information about each instrument use :func:`get_instrument`
    """
    return compmusic.dunya.conn._get_paged_json("api/andalusian/instrument")

def get_instrument(iid):
    """ Get specific information about an instrument.

    :param iid: An instrument id
    :returns: id, name
    """
    return compmusic.dunya.conn._dunya_query_json("api/andalusian/instrument/%s" % str(iid))

def download_mp3(recordingid, location):
    """Download the mp3 of a document and save it to the specified directory.

    :param recordingid: The MBID of the recording
    :param location: Where to save the mp3 to
    """
    if not os.path.exists(location):
        raise Exception("Location %s doesn't exist; can't save" % location)

    recording = get_recording(recordingid)
    title = recording["title"]
    contents = compmusic.dunya.docserver.get_mp3(recordingid)
    name = "%s.mp3" % (title)
    name = name.replace("/", "-")
    path = os.path.join(location, name)
    with open(path, "wb") as file:
        file.write(contents)
    return name

def download_score(recordingid, location):
    """Download the score of a document and save it to the specified directory.

    :param recordingid: The MBID of the recording
    :param location: Where to save the score file to

    """
    if not os.path.exists(location):
        raise Exception("Location %s doesn't exist; can't save" % location)

    try:
        contents = compmusic.dunya.docserver.file_for_document(recordingid, 'symbtrxml')
        name = "%s.xml" % (recordingid)
        path = os.path.join(location, name)
        with open(path, "wb") as file:
            file.write(contents)
    except HTTPError:
        print("%s score is not stored in Dunya" % recordingid)

def download_pitch_track(recordingid, location):
    """ Download the pitch track from a specific recording and save it to the specified
    directory.

    :param recordingid: The MBID of the recording
    :param location: Where to save the json to
    """
    if not os.path.exists(location):
        raise Exception("Location %s doesn't exist; can't save" % location)
    try:
        result = compmusic.dunya.docserver.get_document_as_json(recordingid, "andalusianpitch", subtype="pitch_filt")
        name = recordingid + "_pitchtrack.json"
        output = os.path.join(location, name)
        with open(output, 'w') as output:
            json.dump(result, output)
    except HTTPError:
        print("%s pitch track is not stored in Dunya" % recordingid)

def download_pitch_distribution(recordingid, location):
    """ Download the pitch distribution from a specific recording and save it to the specified directory.

    :param recordingid: The MBID of the recording
    :param location: Where to save the json to

    """
    if not os.path.exists(location):
        raise Exception("Location %s doesn't exist; can't save" % location)
    try:
        result = compmusic.dunya.docserver.get_document_as_json(recordingid, "andalusianpitch",
                                                                subtype="pitch_distribution")
        name = recordingid + "_pitchdistribution.json"
        output = os.path.join(location, name)
        with open(output, 'w') as output:
            json.dump(result, output)
    except HTTPError:
        print("%s pitch distribution is not stored in Dunya" % recordingid)

def download_lyrics(recordingid, location):
    """ Download the arabic and transliteration version of the lyrics of a specific recording

    :param recordingid: The MBID of the recording
    :param location: Where to save the json to

    """
    if not os.path.exists(location):
        raise Exception("Location %s doesn't exist; can't save" % location)
    try:
        result = compmusic.dunya.docserver.file_for_document(recordingid, "andalusian-lyrics").decode('utf-8')
        name = recordingid + "_lyrics.json"
        output = os.path.join(location, name)
        with open(output, 'w') as json_file:
            json.dump(result, json_file)
    except HTTPError:
        print("%s lyrics is not stored in Dunya" % recordingid)
<|endoftext|>


<commit_before>#!/usr/bin/env python

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from structdata import g_project
from structdata import Param

from varslistwidget import VarsListWidget

class VarSetListWidget(VarsListWidget):

    """
    classe che deriva da VarsListWidget ed e' specifica per lavorare con
    action di tipo VAR_SET
    """

    def secondColumnItem(self, id_item):
        index = self.searchParamIndex(id_item)
        if index:
            return self.item.params[index + 1].value
        return ""

    def searchParamIndex(self, param_value):
        i = 0
        for param in self.item.params:
            if param.value == param_value:
                return i
            i += 1
        return None

<commit_msg>change research for 2 column, now search in all action of selected event<commit_after>#!/usr/bin/env python

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from structdata import g_project
from structdata import Param

from varslistwidget import VarsListWidget

class VarSetListWidget(VarsListWidget):

    """
    classe che deriva da VarsListWidget ed e' specifica per lavorare con
    action di tipo VAR_SET
    """

    def secondColumnItem(self, id_item):
        for action in self.event.actions:
            if action.id == "VAR_SET":
                if action.params[0].value == id_item:
                    return action.params[1].value
        return ""

<|endoftext|>


<commit_before>""" loading documents into panzer """

import os
import json
import subprocess
from . import error
from . import info
from . import const
from . import meta

def load(options):
    """ return ast from running pandoc on input documents """
    # 1. Build pandoc command
    command = ['pandoc']
    command += options['pandoc']['input'].copy()
    if options['pandoc']['read']:
        command += ['--read', options['pandoc']['read']]
    command += ['--write', 'json', '--output', '-']
    opts =  meta.build_cli_options(options['pandoc']['options']['r'])
    command += opts
    info.log('INFO', 'panzer', info.pretty_title('pandoc read'))
    info.log('DEBUG', 'panzer', 'loading source document(s)')
    info.log('DEBUG', 'panzer', 'run "%s"' % ' '.join(command))
    if opts:
        info.log('INFO', 'panzer', 'pandoc reading with options:')
        info.log('INFO', 'panzer', info.pretty_list(opts, separator=' '))
    else:
        info.log('INFO', 'panzer', 'running')
    out_pipe = str()
    stderr = str()
    ast = None
    try:
        process = subprocess.Popen(command,
                                   stderr=subprocess.PIPE,
                                   stdout=subprocess.PIPE)
        out_pipe_bytes, stderr_bytes = process.communicate()
        out_pipe = out_pipe_bytes.decode(const.ENCODING)
        stderr = stderr_bytes.decode(const.ENCODING)
    except OSError as err:
        info.log('ERROR', 'pandoc', err)
    finally:
        info.log_stderr(stderr)
    try:
        ast = json.loads(out_pipe)
    except ValueError:
        raise error.BadASTError('failed to receive valid '
                                'json object from pandoc')
    return ast

def load_styledef(options):
    """ return metadata branch of styles.yaml as dict """
    info.log('DEBUG', 'panzer', 'loading global style definitions file')
    filename = os.path.join(options['panzer']['panzer_support'], 'styles.yaml')
    if not os.path.exists(filename):
        info.log('ERROR', 'panzer',
                 'default styles file not found: %s' % filename)
        return dict()
    # - slurp styles.yaml
    data = []
    with open(filename, 'r', encoding=const.ENCODING) as styles_file:
        data = styles_file.readlines()
    # - top and tail with metadata markings
    data.insert(0, "---\n")
    data.append("...\n")
    data_string = ''.join(data)
    # - build pandoc command
    command = ['pandoc']
    command += ['-']
    command += ['--write', 'json']
    command += ['--output', '-']
    opts =  meta.build_cli_options(options['pandoc']['options']['r'])
    command += opts
    info.log('DEBUG', 'panzer', 'run "%s"' % ' '.join(command))
    # - send to pandoc to convert to json
    in_pipe = data_string
    out_pipe = ''
    stderr = ''
    try:
        process = subprocess.Popen(command,
                                   stderr=subprocess.PIPE,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE)
        in_pipe_bytes = in_pipe.encode(const.ENCODING)
        out_pipe_bytes, stderr_bytes = process.communicate(input=in_pipe_bytes)
        out_pipe = out_pipe_bytes.decode(const.ENCODING)
        stderr = stderr_bytes.decode(const.ENCODING)
    except OSError as err:
        info.log('ERROR', 'pandoc', err)
    finally:
        info.log_stderr(stderr)
    # - convert json to python dict
    ast = None
    try:
        ast = json.loads(out_pipe)
    except ValueError:
        raise error.BadASTError('failed to receive valid '
                                'json object from pandoc')
    # - return metadata branch of dict
    if not ast:
        return dict()
    else:
        return meta.get_metadata(ast)

<commit_msg>filter command line options when reading styles.yaml<commit_after>""" loading documents into panzer """

import os
import json
import subprocess
from . import error
from . import info
from . import const
from . import meta

def load(options):
    """ return ast from running pandoc on input documents """
    # 1. Build pandoc command
    command = ['pandoc']
    command += options['pandoc']['input'].copy()
    if options['pandoc']['read']:
        command += ['--read', options['pandoc']['read']]
    command += ['--write', 'json', '--output', '-']
    opts =  meta.build_cli_options(options['pandoc']['options']['r'])
    command += opts
    info.log('INFO', 'panzer', info.pretty_title('pandoc read'))
    info.log('DEBUG', 'panzer', 'loading source document(s)')
    info.log('DEBUG', 'panzer', 'run "%s"' % ' '.join(command))
    if opts:
        info.log('INFO', 'panzer', 'pandoc reading with options:')
        info.log('INFO', 'panzer', info.pretty_list(opts, separator=' '))
    else:
        info.log('INFO', 'panzer', 'running')
    out_pipe = str()
    stderr = str()
    ast = None
    try:
        process = subprocess.Popen(command,
                                   stderr=subprocess.PIPE,
                                   stdout=subprocess.PIPE)
        out_pipe_bytes, stderr_bytes = process.communicate()
        out_pipe = out_pipe_bytes.decode(const.ENCODING)
        stderr = stderr_bytes.decode(const.ENCODING)
    except OSError as err:
        info.log('ERROR', 'pandoc', err)
    finally:
        info.log_stderr(stderr)
    try:
        ast = json.loads(out_pipe)
    except ValueError:
        raise error.BadASTError('failed to receive valid '
                                'json object from pandoc')
    return ast

def load_styledef(options):
    """ return metadata branch of styles.yaml as dict """
    info.log('DEBUG', 'panzer', 'loading global style definitions file')
    filename = os.path.join(options['panzer']['panzer_support'], 'styles.yaml')
    if not os.path.exists(filename):
        info.log('ERROR', 'panzer',
                 'default styles file not found: %s' % filename)
        return dict()
    # - slurp styles.yaml
    data = []
    with open(filename, 'r', encoding=const.ENCODING) as styles_file:
        data = styles_file.readlines()
    # - top and tail with metadata markings
    data.insert(0, "---\n")
    data.append("...\n")
    data_string = ''.join(data)
    # - build pandoc command
    command = ['pandoc']
    command += ['-']
    command += ['--write', 'json']
    command += ['--output', '-']
    opts =  meta.build_cli_options(options['pandoc']['options']['r'])
    # - remove inappropriate options for styles.yaml
    bad_opts = ['metadata', 'track-changes', 'extract-media']
    opts = [x for x in opts if x not in bad_opts]
    command += opts
    info.log('DEBUG', 'panzer', 'run "%s"' % ' '.join(command))
    # - send to pandoc to convert to json
    in_pipe = data_string
    out_pipe = ''
    stderr = ''
    try:
        process = subprocess.Popen(command,
                                   stderr=subprocess.PIPE,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE)
        in_pipe_bytes = in_pipe.encode(const.ENCODING)
        out_pipe_bytes, stderr_bytes = process.communicate(input=in_pipe_bytes)
        out_pipe = out_pipe_bytes.decode(const.ENCODING)
        stderr = stderr_bytes.decode(const.ENCODING)
    except OSError as err:
        info.log('ERROR', 'pandoc', err)
    finally:
        info.log_stderr(stderr)
    # - convert json to python dict
    ast = None
    try:
        ast = json.loads(out_pipe)
    except ValueError:
        raise error.BadASTError('failed to receive valid '
                                'json object from pandoc')
    # - return metadata branch of dict
    if not ast:
        return dict()
    else:
        return meta.get_metadata(ast)

<|endoftext|>


<commit_before># Copyright (C) 2015 SINTEF ICT,
# Applied Mathematics, Norway.
#
# Contact information:
# E-mail: eivind.fonn@sintef.no
# SINTEF ICT, Department of Applied Mathematics,
# P.O. Box 4760 Sluppen,
# 7045 Trondheim, Norway.
#
# This file is part of BADGER.
#
# BADGER is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# BADGER 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with BADGER. If not, see
# <http://www.gnu.org/licenses/>.
#
# In accordance with Section 7(b) of the GNU Affero General Public
# License, a covered work must retain the producer line in every data
# file that is created or manipulated using BADGER.
#
# Other Usage
# You can be released from the requirements of the license by purchasing
# a commercial license. Buying such a license is mandatory as soon as you
# develop commercial activities involving BADGER without disclosing the
# source code of your own applications.
#
# This file may be used in accordance with the terms contained in a
# written agreement between you and SINTEF ICT.

import operator
import shlex
import shutil
import subprocess
import tempfile

from functools import reduce
from socket import gethostname
from datetime import datetime
from itertools import chain, product
from os.path import join, dirname
from operator import methodcaller
from jinja2 import Environment, FileSystemLoader

from sett import output, input, log
from sett.utils import *

def interpolate_vars(string, namespace):
    for name, value in namespace.items():
        string = string.replace('$' + name, str(value))
    return string

def build_initial_namespace(setup, parameters):
    namespace = dict(zip(setup.parameters, parameters))
    for name, expr in setup.dependencies.items():
        try:
            namespace[name] = eval(expr, {}, namespace)
        except (TypeError, SyntaxError):
            namespace[name] = expr
    return namespace

def render_files(templates, namespace):
    env = Environment(loader=FileSystemLoader(searchpath='.'))
    ret = {}
    for fn in templates:
        template = env.get_template(fn)
        ret[fn] = template.render(**namespace)
    return ret

def render_templates(templates, namespace):
    return list(map(methodcaller('render', **namespace), templates))

def work(args, setup):
    results = []
    output_root = dirname(args.output)
    num_cases = reduce(operator.mul, [len(vals) for vals in setup.parameters.values()], 1)
    num = 1

    for tp in product(*(l for _, l in setup.parameters.items())):
        namespace = build_initial_namespace(setup, tp)
        namespace['case_number'] = num

        templates = render_templates(setup.templates, namespace)
        template_data = render_files(templates, namespace)
        copy_files = render_templates(setup.files, namespace)

        if num_cases > 1:
            target_dir = join(output_root, setup.target_dir.render(**namespace))
        else:
            target_dir = output_root
        ensure_path_exists(target_dir, file=False)

        with tempfile.TemporaryDirectory() as path:
            for fn in chain(template_data, copy_files):
                ensure_path_exists(join(path, fn))
            for fn, data in template_data.items():
                with open(join(path, fn), 'w') as f:
                    f.write(data)
            for fn in copy_files:
                shutil.copy(fn, join(path, fn))

            log.log('running', 'Running ' + ', '.join('{}={}'.format(var, namespace[var])
                                                      for var in setup.parameters) + ' ...')
            for fn, data in template_data.items():
                log.log('templates', data, 'Template: {}'.format(fn))

            result = {}
            for cmd in setup.commands:
                cmdargs = render_templates(cmd.args, namespace)
                if args.dry:
                    log.log('results', ' '.join(shlex.quote(a) for a in cmdargs))
                else:
                    stdout, stderr, retcode = run_process(cmdargs, path)
                    cmd.capture_files(path, target_dir, namespace)
                    result.update(cmd.capture_stdout(stdout, namespace))
                    log.log('stdout', stdout, 'Captured stdout')
                    log.log('stderr', stderr, 'Captured stderr')
                    if retcode != 0:
                        log.log('retcode', '!! Process exited with code {}'.format(retcode))
            coerce_types(result, setup.types)
            results.append(result)
            log.log('results', ', '.join('{}={}'.format(t, result[t]) for t in sorted(result)))

        num += 1

    if not args.dry:
        all_output = set().union(*results)
        for out in all_output:
            if out not in setup.types:
                setup.types['out'] = 'str'

        return {
            'metadata': {
                'hostname': gethostname(),
                'time': str(datetime.now()),
            },
            'parameters': [{'name': param, 'values': values}
                           for param, values in setup.parameters.items()],
            'results': {output: [result.get(output) for result in results]
                        for output in all_output},
        }
<commit_msg>Catch nameerror in formula evaluation<commit_after># Copyright (C) 2015 SINTEF ICT,
# Applied Mathematics, Norway.
#
# Contact information:
# E-mail: eivind.fonn@sintef.no
# SINTEF ICT, Department of Applied Mathematics,
# P.O. Box 4760 Sluppen,
# 7045 Trondheim, Norway.
#
# This file is part of BADGER.
#
# BADGER is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# BADGER 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with BADGER. If not, see
# <http://www.gnu.org/licenses/>.
#
# In accordance with Section 7(b) of the GNU Affero General Public
# License, a covered work must retain the producer line in every data
# file that is created or manipulated using BADGER.
#
# Other Usage
# You can be released from the requirements of the license by purchasing
# a commercial license. Buying such a license is mandatory as soon as you
# develop commercial activities involving BADGER without disclosing the
# source code of your own applications.
#
# This file may be used in accordance with the terms contained in a
# written agreement between you and SINTEF ICT.

import operator
import shlex
import shutil
import subprocess
import tempfile

from functools import reduce
from socket import gethostname
from datetime import datetime
from itertools import chain, product
from os.path import join, dirname
from operator import methodcaller
from jinja2 import Environment, FileSystemLoader

from sett import output, input, log
from sett.utils import *

def interpolate_vars(string, namespace):
    for name, value in namespace.items():
        string = string.replace('$' + name, str(value))
    return string

def build_initial_namespace(setup, parameters):
    namespace = dict(zip(setup.parameters, parameters))
    for name, expr in setup.dependencies.items():
        try:
            namespace[name] = eval(expr, {}, namespace)
        except (TypeError, SyntaxError, NameError):
            namespace[name] = expr
    return namespace

def render_files(templates, namespace):
    env = Environment(loader=FileSystemLoader(searchpath='.'))
    ret = {}
    for fn in templates:
        template = env.get_template(fn)
        ret[fn] = template.render(**namespace)
    return ret

def render_templates(templates, namespace):
    return list(map(methodcaller('render', **namespace), templates))

def work(args, setup):
    results = []
    output_root = dirname(args.output)
    num_cases = reduce(operator.mul, [len(vals) for vals in setup.parameters.values()], 1)
    num = 1

    for tp in product(*(l for _, l in setup.parameters.items())):
        namespace = build_initial_namespace(setup, tp)
        namespace['case_number'] = num

        templates = render_templates(setup.templates, namespace)
        template_data = render_files(templates, namespace)
        copy_files = render_templates(setup.files, namespace)

        if num_cases > 1:
            target_dir = join(output_root, setup.target_dir.render(**namespace))
        else:
            target_dir = output_root
        ensure_path_exists(target_dir, file=False)

        with tempfile.TemporaryDirectory() as path:
            for fn in chain(template_data, copy_files):
                ensure_path_exists(join(path, fn))
            for fn, data in template_data.items():
                with open(join(path, fn), 'w') as f:
                    f.write(data)
            for fn in copy_files:
                shutil.copy(fn, join(path, fn))

            log.log('running', 'Running ' + ', '.join('{}={}'.format(var, namespace[var])
                                                      for var in setup.parameters) + ' ...')
            for fn, data in template_data.items():
                log.log('templates', data, 'Template: {}'.format(fn))

            result = {}
            for cmd in setup.commands:
                cmdargs = render_templates(cmd.args, namespace)
                if args.dry:
                    log.log('results', ' '.join(shlex.quote(a) for a in cmdargs))
                else:
                    stdout, stderr, retcode = run_process(cmdargs, path)
                    cmd.capture_files(path, target_dir, namespace)
                    result.update(cmd.capture_stdout(stdout, namespace))
                    log.log('stdout', stdout, 'Captured stdout')
                    log.log('stderr', stderr, 'Captured stderr')
                    if retcode != 0:
                        log.log('retcode', '!! Process exited with code {}'.format(retcode))
            coerce_types(result, setup.types)
            results.append(result)
            log.log('results', ', '.join('{}={}'.format(t, result[t]) for t in sorted(result)))

        num += 1

    if not args.dry:
        all_output = set().union(*results)
        for out in all_output:
            if out not in setup.types:
                setup.types['out'] = 'str'

        return {
            'metadata': {
                'hostname': gethostname(),
                'time': str(datetime.now()),
            },
            'parameters': [{'name': param, 'values': values}
                           for param, values in setup.parameters.items()],
            'results': {output: [result.get(output) for result in results]
                        for output in all_output},
        }
<|endoftext|>


<commit_before>#
# linter.py
# Linter for SublimeLinter3, a code checking framework for Sublime Text 3
#
# Written by Aparajita Fishman
# Copyright (c) 2013 Aparajita Fishman
#
# License: MIT
#

"""This module exports the Pyflakes plugin linter class."""

from io import StringIO

try:
    from pyflakes.reporter import Reporter
except ImportError:
    pass

from SublimeLinter.lint import PythonLinter, util

class Pyflakes(PythonLinter):

    """Provides an interface to the pyflakes python module/script."""

    syntax = 'python'
    cmd = 'pyflakes@python'
    regex = r'''(?x)
        .+?:\s*               # filename
        (?P<line>\d+):\s*     # line number

        # The rest of the line is the error message.
        # Within that, capture anything within single quotes as 'near'.
        (?P<message>[^\'\n\r]+(?P<near>\'.+?\')?.*)

        # The error message may be followed by the offending line of code...
        (?:\r?\n.*

        # and then another line with a caret (preceded by spaces)
        # pointing to the position where the error occurred.
        \r?\n(?P<col>[ ]+)\^)?
    '''
    multiline = True
    error_stream = util.STREAM_BOTH
    module = 'pyflakes.api'
    check_version = True

    def check(self, code, filename):
        """Run pyflakes.check on code and return the output."""

        output = StringIO()
        reporter = Reporter(output, output)

        self.module.check(code, filename, reporter=reporter)
        return output.getvalue()
<commit_msg>Can't import module until runtime when python paths are available.<commit_after>#
# linter.py
# Linter for SublimeLinter3, a code checking framework for Sublime Text 3
#
# Written by Aparajita Fishman
# Copyright (c) 2013 Aparajita Fishman
#
# License: MIT
#

"""This module exports the Pyflakes plugin linter class."""

from io import StringIO
from SublimeLinter.lint import PythonLinter, util

class Pyflakes(PythonLinter):

    """Provides an interface to the pyflakes python module/script."""

    syntax = 'python'
    cmd = 'pyflakes@python'
    regex = r'''(?x)
        .+?:\s*               # filename
        (?P<line>\d+):\s*     # line number

        # The rest of the line is the error message.
        # Within that, capture anything within single quotes as 'near'.
        (?P<message>[^\'\n\r]+(?P<near>\'.+?\')?.*)

        # The error message may be followed by the offending line of code...
        (?:\r?\n.*

        # and then another line with a caret (preceded by spaces)
        # pointing to the position where the error occurred.
        \r?\n(?P<col>[ ]+)\^)?
    '''
    multiline = True
    error_stream = util.STREAM_BOTH
    module = 'pyflakes.api'
    check_version = True

    # Internal
    reporter = None

    def check(self, code, filename):
        """Run pyflakes.check on code and return the output."""

        output = StringIO()
        reporter = self.get_reporter()
        reporter = reporter(output, output)

        self.module.check(code, filename, reporter=reporter)
        return output.getvalue()

    def get_reporter(self):
        """Return pyflakes.Reporter. Must be deferred to runtime."""
        if self.reporter is None:
            from pyflakes.reporter import Reporter
            self.__class__.reporter = Reporter

        return self.reporter
<|endoftext|>


<commit_before>#!/usr/bin/python2
"""
   Copyright 2016 Iakov Kirilenko

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

   Simple generator for colorful AR tags
"""
import argparse
import errno
import numpy as np
import os

import cv2 as cv

def palette2((row,col)):
    maxDarkLuma = 100 if row % 5 == 0 or col % 5 == 0  else 180
    colors = [(maxDarkLuma * 7 / 10, 0, 0), (0, maxDarkLuma * 6 / 10, 0), (0, 0, maxDarkLuma)]
    return colors[(row + col) % len(colors)]

def generate_palette(s):
    n = int(s)
    if n == 0:
        return lambda _: (0, 0, 0)
    elif n == 1:
        maxDarkLuma = 150
        colors = [(maxDarkLuma * 7 / 10, 0, 0), (0, maxDarkLuma * 6 / 10, 0), (0, 0, maxDarkLuma)]
        return lambda(row,col): colors[(row + col) % len(colors)]
    elif n == 2:
        return palette2
    else:
        raise argparse.ArgumentTypeError("palette %r not implemented" % s)

def parse_args():
    parser = argparse.ArgumentParser(description='AR marker tag generator')
    parser.add_argument('codes', metavar='N[..M]', nargs='+', help='integer code N or range N..M')
    parser.add_argument('--force', dest='force', action='store_true',
                        help='ignore checks & errors (depends on context)')
    parser.add_argument('--out-dir', dest='dir', default='.', help='output directory name')
    parser.add_argument('--palette', dest='palette', metavar='P', type=generate_palette, default=generate_palette("0"),
                        help='use palette #P ( 0 -- b/w) ')
    parser.add_argument('--box-size', dest='boxSize', type=int, default=50, help='bit box size per side in pixels')
    return parser.parse_args()

class Generator:
    def draw_box(self, pos, color=None):
        if color is None:
            color = self.args.palette(pos)
        row, col = pos
        top_left = ((col + 1) * self.args.boxSize, (row + 1) * self.args.boxSize)
        down_right = ((col + 2) * self.args.boxSize - 1, (row + 2) * self.args.boxSize - 1)
        points = np.array([top_left, (down_right[0], top_left[1]), down_right, (top_left[0], down_right[1])])
        cv.fillConvexPoly(self.img, points, color)

    def generate(self, code):
        freeBits = (6 - 2) * (6 - 2) - 3
        if code < 0 or code >= 1 << freeBits:
            return None

        binCode = bin(code)[2:].zfill(freeBits)
        binCode = '1' + binCode[0:11] + '1' + binCode[11:] + '0'

        """Check message (for parity, etc.)"""
        if binCode[3] == '1' or binCode[8] == '1' or binCode.count('1') % 2 != 0:
            if not self.args.force:
                return None

        """Draw border"""
        for i in range(0, 6):
            for pos in [(0, i), (5, i), (i, 0), (i, 5)]:
                self.draw_box(pos)

        """Draw message"""
        for i in range(0, len(binCode)):
            pos = (i / 4 + 1, i % 4 + 1)
            self.draw_box(pos, None if binCode[i] == '1' else (255, 255, 255))

        return self.img

    def __init__(self, args):
        self.img = cv.bitwise_not(np.zeros(((6 + 2) * args.boxSize, (6 + 2) * args.boxSize, 3), np.uint8))
        self.args = args

def main():
    args = parse_args()
    try:
        os.makedirs(args.dir)
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise
    g = Generator(args)
    for code in [z for y in [x.split("..") for x in args.codes]
                 for z in range(int(y[0]), 1 + int(y[0] if len(y) == 1 else y[1]))]:

        marker = g.generate(code)
        if marker is None: continue
        filename = args.dir + '/{0:04}.png'.format(code)
        cv.cvtColor(marker, cv.COLOR_RGB2BGR, marker)
        cv.imwrite(filename, marker, [cv.IMWRITE_PNG_COMPRESSION, 9])

if __name__ == "__main__":
    main()
<commit_msg>Fixed bug in marker code check<commit_after>#!/usr/bin/python2
"""
   Copyright 2016 Iakov Kirilenko

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

   Simple generator for colorful AR tags
"""
import argparse
import errno
import numpy as np
import os

import cv2 as cv

def palette2((row,col)):
    maxDarkLuma = 100 if row % 5 == 0 or col % 5 == 0  else 180
    colors = [(maxDarkLuma * 7 / 10, 0, 0), (0, maxDarkLuma * 6 / 10, 0), (0, 0, maxDarkLuma)]
    return colors[(row + col) % len(colors)]

def generate_palette(s):
    n = int(s)
    if n == 0:
        return lambda _: (0, 0, 0)
    elif n == 1:
        maxDarkLuma = 150
        colors = [(maxDarkLuma * 7 / 10, 0, 0), (0, maxDarkLuma * 6 / 10, 0), (0, 0, maxDarkLuma)]
        return lambda(row,col): colors[(row + col) % len(colors)]
    elif n == 2:
        return palette2
    else:
        raise argparse.ArgumentTypeError("palette %r not implemented" % s)

def parse_args():
    parser = argparse.ArgumentParser(description='AR marker tag generator')
    parser.add_argument('codes', metavar='N[..M]', nargs='+', help='integer code N or range N..M')
    parser.add_argument('--force', dest='force', action='store_true',
                        help='ignore checks & errors (depends on context)')
    parser.add_argument('--out-dir', dest='dir', default='.', help='output directory name')
    parser.add_argument('--palette', dest='palette', metavar='P', type=generate_palette, default=generate_palette("0"),
                        help='use palette #P ( 0 -- b/w) ')
    parser.add_argument('--box-size', dest='boxSize', type=int, default=50, help='bit box size per side in pixels')
    return parser.parse_args()

class Generator:
    def draw_box(self, pos, color=None):
        if color is None:
            color = self.args.palette(pos)
        row, col = pos
        top_left = ((col + 1) * self.args.boxSize, (row + 1) * self.args.boxSize)
        down_right = ((col + 2) * self.args.boxSize - 1, (row + 2) * self.args.boxSize - 1)
        points = np.array([top_left, (down_right[0], top_left[1]), down_right, (top_left[0], down_right[1])])
        cv.fillConvexPoly(self.img, points, color)

    def generate(self, code):
        freeBits = (6 - 2) * (6 - 2) - 3
        if code < 0 or code >= 1 << freeBits:
            return None

        binCode = bin(code)[2:].zfill(freeBits)
        binCode = '1' + binCode[0:11] + '1' + binCode[11:] + '0'

        """Check message (for parity, etc.)"""
        if binCode[3] == '1' or binCode[4] == '1' or binCode.count('1') % 2 != 0:
            if not self.args.force:
                return None

        """Draw border"""
        for i in range(0, 6):
            for pos in [(0, i), (5, i), (i, 0), (i, 5)]:
                self.draw_box(pos)

        """Draw message"""
        for i in range(0, len(binCode)):
            pos = (i / 4 + 1, i % 4 + 1)
            self.draw_box(pos, None if binCode[i] == '1' else (255, 255, 255))

        return self.img

    def __init__(self, args):
        self.img = cv.bitwise_not(np.zeros(((6 + 2) * args.boxSize, (6 + 2) * args.boxSize, 3), np.uint8))
        self.args = args

def main():
    args = parse_args()
    try:
        os.makedirs(args.dir)
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise
    g = Generator(args)
    for code in [z for y in [x.split("..") for x in args.codes]
                 for z in range(int(y[0]), 1 + int(y[0] if len(y) == 1 else y[1]))]:

        marker = g.generate(code)
        if marker is None: continue
        filename = args.dir + '/{0:04}.png'.format(code)
        cv.cvtColor(marker, cv.COLOR_RGB2BGR, marker)
        cv.imwrite(filename, marker, [cv.IMWRITE_PNG_COMPRESSION, 9])

if __name__ == "__main__":
    main()
<|endoftext|>