<commit_before>import slumber

from django.core.cache import cache
from django.utils.safestring import mark_safe

from evaluator import suite

from packages.models import ReadTheDocsPackageSlug
from packages.utils import verlib

class PEP386Compatability(object):
    title = "PEP386 Compatibility"
    message = mark_safe("PEP386 defines a specific allowed syntax for Python package versions."
                "

"
                "Previously it was impossible to accurately determine across any Python package what "
                "order the versions should go in, but with PEP386 we can now intelligently sort by version..."
                "

"
                "But only if the version numbers are compatible!")

    def evaluate(self, release):
        normalized = verlib.suggest_normalized_version(release.version)

        if release.version == normalized:
            # Release Is Already Normalized
            return {
                "level": "success",
                "message": mark_safe('Compatible with PEP386.'),
            }
        elif normalized is not None:
            # Release Isn't Normalized, But We Can Figure It Out
            return {
                "level": None,
                "message": mark_safe('Almost Compatible with PEP386.'),
            }
        else:
            # We Can't Normalize the Release Version
            return {
                "level": "error",
                "message": mark_safe('Incompatible with PEP386.'),
            }

class PackageHosting(object):
    title = "Package Hosting"
    message = mark_safe("Did you know that packages listed on PyPI aren't required to host there?"
                "

"
                "When your package manager tries to install a package from PyPI it looks in number "
                "of locations, one such location is an author specified url of where the package can "
                "be downloaded from."
                "

"
                "Packages hosted by the author means that installing this package depends on the "
                "authors server staying up, adding another link in the chain that can cause your "
                "installation to fail")

    def evaluate(self, release):
        if release.files.all().exists():
            return {
                "level": "success",
                "message": "Package is hosted on PyPI",
            }
        elif release.download_uri:
            return {
                "level": "error",
                "message": "Package isn't hosted on PyPI",
            }
        else:
            return {
                "level": "error",
                "message": "No Package Hosting",
            }

class RTDocs(object):
    title = "Documentation hosted on Read The Docs"
    message = mark_safe("Documentation can be one of the most important parts of any library. "
                "Even more important than just having documentation, is making sure that people are "
                "able to find it easily."
                "

"
                "Read The Docs is an open source platform for hosting documentation generated by Sphinx."
                "

"
                "Hosting your documentation on Read The Docs is easy (even if it's just an additional copy), and "
                "it allows people who want to use your package the ability to locate your documentation in "
                "what is quickly becoming a one stop shop for online open source documentation."
                "

"
                "If this says you aren't hosted on Read The Docs and you are please contact "
                "support@crate.io")

    def evaluate(self, release):
        qs = ReadTheDocsPackageSlug.objects.filter(slug=release.package.name)
        slug = qs[0].slug if qs else release.package.name

        key = "evaluate:rtd:%s" % slug

        if cache.get(key, version=3) is not None:
            hosted_on_rtd, url = cache.get(key, version=3)
        else:
            api = slumber.API(base_url="http://readthedocs.org/api/v1/")
            results = api.project.get(slug__iexact=slug)

            if results["objects"]:
                hosted_on_rtd = True
                url = results["objects"][0]["subdomain"]
            else:
                hosted_on_rtd = False
                url = None

            cache.set(key, (hosted_on_rtd, url), 60 * 60 * 24, version=3)  # Cache This for a Day

        if hosted_on_rtd:
            return {
                "level": "success",
                "message": mark_safe('Docs Available on Read The Docs' % url),
            }
        else:
            return {
                "level": "unknown",
                "message": mark_safe('Docs Unavailable on Read The Docs')
            }

suite.register(PEP386Compatability)
suite.register(PackageHosting)
suite.register(RTDocs)
<commit_msg>bring RTD cache down from 1 day to 30 minutes<commit_after>import slumber

from django.core.cache import cache
from django.utils.safestring import mark_safe

from evaluator import suite

from packages.models import ReadTheDocsPackageSlug
from packages.utils import verlib

class PEP386Compatability(object):
    title = "PEP386 Compatibility"
    message = mark_safe("PEP386 defines a specific allowed syntax for Python package versions."
                "

"
                "Previously it was impossible to accurately determine across any Python package what "
                "order the versions should go in, but with PEP386 we can now intelligently sort by version..."
                "

"
                "But only if the version numbers are compatible!")

    def evaluate(self, release):
        normalized = verlib.suggest_normalized_version(release.version)

        if release.version == normalized:
            # Release Is Already Normalized
            return {
                "level": "success",
                "message": mark_safe('Compatible with PEP386.'),
            }
        elif normalized is not None:
            # Release Isn't Normalized, But We Can Figure It Out
            return {
                "level": None,
                "message": mark_safe('Almost Compatible with PEP386.'),
            }
        else:
            # We Can't Normalize the Release Version
            return {
                "level": "error",
                "message": mark_safe('Incompatible with PEP386.'),
            }

class PackageHosting(object):
    title = "Package Hosting"
    message = mark_safe("Did you know that packages listed on PyPI aren't required to host there?"
                "

"
                "When your package manager tries to install a package from PyPI it looks in number "
                "of locations, one such location is an author specified url of where the package can "
                "be downloaded from."
                "

"
                "Packages hosted by the author means that installing this package depends on the "
                "authors server staying up, adding another link in the chain that can cause your "
                "installation to fail")

    def evaluate(self, release):
        if release.files.all().exists():
            return {
                "level": "success",
                "message": "Package is hosted on PyPI",
            }
        elif release.download_uri:
            return {
                "level": "error",
                "message": "Package isn't hosted on PyPI",
            }
        else:
            return {
                "level": "error",
                "message": "No Package Hosting",
            }

class RTDocs(object):
    title = "Documentation hosted on Read The Docs"
    message = mark_safe("Documentation can be one of the most important parts of any library. "
                "Even more important than just having documentation, is making sure that people are "
                "able to find it easily."
                "

"
                "Read The Docs is an open source platform for hosting documentation generated by Sphinx."
                "

"
                "Hosting your documentation on Read The Docs is easy (even if it's just an additional copy), and "
                "it allows people who want to use your package the ability to locate your documentation in "
                "what is quickly becoming a one stop shop for online open source documentation."
                "

"
                "If this says you aren't hosted on Read The Docs and you are please contact "
                "support@crate.io")

    def evaluate(self, release):
        qs = ReadTheDocsPackageSlug.objects.filter(slug=release.package.name)
        slug = qs[0].slug if qs else release.package.name

        key = "evaluate:rtd:%s" % slug

        if cache.get(key, version=4) is not None:
            hosted_on_rtd, url = cache.get(key, version=4)
        else:
            api = slumber.API(base_url="http://readthedocs.org/api/v1/")
            results = api.project.get(slug__iexact=slug)

            if results["objects"]:
                hosted_on_rtd = True
                url = results["objects"][0]["subdomain"]
            else:
                hosted_on_rtd = False
                url = None

            cache.set(key, (hosted_on_rtd, url), 60 * 30, version=4)  # Cache This for 30 Minutes

        if hosted_on_rtd:
            return {
                "level": "success",
                "message": mark_safe('Docs Available on Read The Docs' % url),
            }
        else:
            return {
                "level": "unknown",
                "message": mark_safe('Docs Unavailable on Read The Docs')
            }

suite.register(PEP386Compatability)
suite.register(PackageHosting)
suite.register(RTDocs)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##
## This file is part of CDS Invenio.
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 CERN.
##
## CDS Invenio is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 2 of the
## License, or (at your option) any later version.
##
## CDS Invenio is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with CDS Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

"""
bibformat_xslt_engine - Wrapper for an XSLT engine.

Some functions are registered in order to be used in XSL code:
  - creation_date(recID)
  - modification_date(recID)

Dependencies: Need one of the following XSLT processors:
              - libxml2 & libxslt
              - 4suite

Used by: bibformat_engine.py
"""

__revision__ = "$Id$"

import sys
import os

from invenio.config import \
     CFG_SITE_URL
from invenio.bibformat_config import \
     CFG_BIBFORMAT_TEMPLATES_PATH
from invenio.bibformat_dblayer import \
     get_creation_date, \
     get_modification_date

# The namespace used for BibFormat function
CFG_BIBFORMAT_FUNCTION_NS = "http://cdsweb.cern.ch/bibformat/fn"

# Import one XSLT processor
#
# processor_type:
#       -1 : No processor found
#        0 : libxslt
#        1 : 4suite
processor_type = -1
try:
    # libxml2 & libxslt
    processor_type = 0
    import libxml2
    import libxslt
except ImportError:
    pass

if processor_type == -1:
    try:
        # 4suite
        processor_type = 1
        from Ft.Xml.Xslt import Processor
        from Ft.Xml import InputSource
        from xml.dom import Node
    except ImportError:
        pass

if processor_type == -1:
    # No XSLT processor found
    sys.stderr.write('No XSLT processor could be found.\n' \
                     'No output produced.\n')
    sys.exit(1)

##################################################################
# Support for 'creation_date' and 'modification_date' functions  #

def get_creation_date_libxslt(ctx, recID, fmt="%Y-%m-%dT%H:%M:%SZ"):
    """
    libxslt extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns record creation date.

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:creation_date(445)"/> where 445 is a recID

    if recID is string, value is converted to int
    if recID is Node, first child node (text node) is taken as value
    """
    try:
        if isinstance(recID, str):
            recID_int = int(recID)
        elif isinstance(recID, (int, long)):
            recID_int = recID
        else:
            recID_int = libxml2.xmlNode(_obj=recID[0]).children.content

        if isinstance(fmt, str):
            fmt_str = fmt
        else:
            fmt_str = libxml2.xmlNode(_obj=recID[0]).children.content

        return get_creation_date(recID_int, fmt_str)
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

def get_creation_date_4suite(ctx, recID, fmt="%Y-%m-%dT%H:%M:%SZ"):
    """
    4suite extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns record creation date.

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:creation_date(445)"/>

    if value is int, value is converted to string
    if value is Node, first child node (text node) is taken as value
    """
    try:
        if len(recID) > 0 and isinstance(recID[0], Node):
            recID_int = recID[0].firstChild.nodeValue
            if recID_int is None:
                return ''
        else:
            recID_int = int(recID)

        if len(fmt) > 0 and isinstance(fmt[0], Node):
            fmt_str = fmt[0].firstChild.nodeValue
            if fmt_str is None:
                fmt_str = "%Y-%m-%dT%H:%M:%SZ"
        else:
            fmt_str = str(fmt)

        return get_creation_date(recID_int, fmt_str)
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

def get_modification_date_libxslt(ctx, recID, fmt="%Y-%m-%dT%H:%M:%SZ"):
    """
    libxslt extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns record modification date.

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:creation_date(445)"/> where 445 is a recID

    if recID is string, value is converted to int
    if recID is Node, first child node (text node) is taken as value
    """
    try:
        if isinstance(recID, str):
            recID_int = int(recID)
        elif isinstance(recID, (int, long)):
            recID_int = recID
        else:
            recID_int = libxml2.xmlNode(_obj=recID[0]).children.content

        if isinstance(fmt, str):
            fmt_str = fmt
        else:
            fmt_str = libxml2.xmlNode(_obj=recID[0]).children.content

        return get_modification_date(recID_int, fmt_str)
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

def get_modification_date_4suite(ctx, recID, fmt="%Y-%m-%dT%H:%M:%SZ"):
    """
    4suite extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns record modification date.

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:modification_date(445)"/>

    if value is int, value is converted to string
    if value is Node, first child node (text node) is taken as value
    """
    try:
        if len(recID) > 0 and isinstance(recID[0], Node):
            recID_int = recID[0].firstChild.nodeValue
            if recID_int is None:
                return ''
        else:
            recID_int = int(recID_int)

        if len(fmt) > 0 and isinstance(fmt[0], Node):
            fmt_str = fmt[0].firstChild.nodeValue
            if fmt_str is None:
                fmt_str = "%Y-%m-%dT%H:%M:%SZ"
        else:
            fmt_str = str(fmt)

        return get_modification_date(recID_int, fmt_str)
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

def eval_bibformat_libxslt(ctx, recID, template_code):
    """
    libxslt extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns the evaluation of the given piece of format template

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:eval_bibformat(marc:controlfield[@tag='001'],'<BFE_SERVER_INFO var="recurl">')" />

    if recID is string, value is converted to int
    if recID is Node, first child node (text node) is taken as value
    template_code is evaluated as a format template piece of code. '<'
    and '"' need to be escaped with '<' and '"'
    """
    from invenio.bibformat_engine import \
    format_with_format_template, \
    BibFormatObject
    try:
        if isinstance(recID, str):
            recID_int = int(recID)
        elif isinstance(recID, (int, long)):
            recID_int = recID
        else:
            recID_int = libxml2.xmlNode(_obj=recID[0]).children.content
        bfo = BibFormatObject(recID_int)
        return format_with_format_template(None, bfo,
                                           verbose=0,
                                           format_template_code=template_code)[0]
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

def eval_bibformat_4suite(ctx, recID, template_code):
    """
    4suite extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns the evaluation of the given piece of format template

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:eval_bibformat(marc:controlfield[@tag='001'],'<BFE_SERVER_INFO var="recurl">')" />

    if recID is string, value is converted to int
    if recID is Node, first child node (text node) is taken as value
    template_code is evaluated as a format template piece of code. '<'
    and '"' need to be escaped with '<' and '"'
    """
    from invenio.bibformat_engine import \
    format_with_format_template, \
    BibFormatObject
    try:
        if len(recID) > 0 and isinstance(recID[0], Node):
            recID_int = recID[0].firstChild.nodeValue
            if recID_int is None:
                return ''
        else:
            recID_int = int(recID_int)

        bfo = BibFormatObject(recID_int)
        return format_with_format_template(None, bfo,
                                           verbose=0,
                                           format_template_code=template_code)[0]
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

# End of date-related functions                                  #
##################################################################

def format(xmltext, template_filename=None, template_source=None):
    """
    Processes an XML text according to a template, and returns the result.

    The template can be given either by name (or by path) or by source.
    If source is given, name is ignored.

    bibformat_xslt_engine will look for template_filename in standard directories
    for templates. If not found, template_filename will be assumed to be a path to
    a template. If none can be found, return None.

    @param xmltext The string representation of the XML to process
    @param template_filename The name of the template to use for the processing
    @param template_source The configuration describing the processing.
    @return the transformed XML text.
    """
    if processor_type == -1:
        # No XSLT processor found
        sys.stderr.write('No XSLT processor could be found.')
        sys.exit(1)

    # Retrieve template and read it
    if template_source:
        template = template_source
    elif template_filename:
        try:
            path_to_templates = (CFG_BIBFORMAT_TEMPLATES_PATH + os.sep +
                                 template_filename)
            if os.path.exists(path_to_templates):
                template = file(path_to_templates).read()
            elif os.path.exists(template_filename):
                template = file(template_filename).read()
            else:
                sys.stderr.write(template_filename +' does not exist.')
                return None
        except IOError:
            sys.stderr.write(template_filename +' could not be read.')
            return None
    else:
        sys.stderr.write(template_filename +' was not given.')
        return None

    result = ""
    if processor_type == 0:
        # libxml2 & libxslt

        # Register BibFormat functions for use in XSL
        libxslt.registerExtModuleFunction("creation_date",
                                          CFG_BIBFORMAT_FUNCTION_NS,
                                          get_creation_date_libxslt)
        libxslt.registerExtModuleFunction("modification_date",
                                          CFG_BIBFORMAT_FUNCTION_NS,
                                          get_modification_date_libxslt)
        libxslt.registerExtModuleFunction("eval_bibformat",
                                          CFG_BIBFORMAT_FUNCTION_NS,
                                          eval_bibformat_libxslt)
        # Load template and source
        template_xml = libxml2.parseDoc(template)
        processor = libxslt.parseStylesheetDoc(template_xml)
        source = libxml2.parseDoc(xmltext)

        # Transform
        result_object = processor.applyStylesheet(source, None)
        try:
            result = processor.saveResultToString(result_object)
        except SystemError :
            # Catch an exception thrown when result is empty,
            # due to a bug in libxslt
            result = ''

        # Deallocate
        processor.freeStylesheet()
        source.freeDoc()
        result_object.freeDoc()

    elif processor_type == 1:
        # 4suite

        # Init
        processor = Processor.Processor()

        # Register BibFormat functions for use in XSL
        processor.registerExtensionFunction(CFG_BIBFORMAT_FUNCTION_NS,
                                            "creation_date",
                                            get_creation_date_4suite)
        processor.registerExtensionFunction(CFG_BIBFORMAT_FUNCTION_NS,
                                            "modification_date",
                                            get_modification_date_4suite)
        processor.registerExtensionFunction(CFG_BIBFORMAT_FUNCTION_NS,
                                            "eval_bibformat",
                                            eval_bibformat_4suite)
        # Load template and source
        transform = InputSource.DefaultFactory.fromString(template,
                                                       uri=CFG_SITE_URL)
        source = InputSource.DefaultFactory.fromString(xmltext,
                                                       uri=CFG_SITE_URL)
        processor.appendStylesheet(transform)

        # Transform
        result = processor.run(source)
    else:
        sys.stderr.write("No XSLT processor could be found")

    return result

if __name__ == "__main__":
    pass

<commit_msg>BibFormat: fixed XSL parser detection<commit_after># -*- coding: utf-8 -*-
##
## This file is part of CDS Invenio.
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 CERN.
##
## CDS Invenio is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 2 of the
## License, or (at your option) any later version.
##
## CDS Invenio is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with CDS Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

"""
bibformat_xslt_engine - Wrapper for an XSLT engine.

Some functions are registered in order to be used in XSL code:
  - creation_date(recID)
  - modification_date(recID)

Dependencies: Need one of the following XSLT processors:
              - libxml2 & libxslt
              - 4suite

Used by: bibformat_engine.py
"""

__revision__ = "$Id$"

import sys
import os

from invenio.config import \
     CFG_SITE_URL
from invenio.bibformat_config import \
     CFG_BIBFORMAT_TEMPLATES_PATH
from invenio.bibformat_dblayer import \
     get_creation_date, \
     get_modification_date

# The namespace used for BibFormat function
CFG_BIBFORMAT_FUNCTION_NS = "http://cdsweb.cern.ch/bibformat/fn"

# Import one XSLT processor
#
# processor_type:
#       -1 : No processor found
#        0 : libxslt
#        1 : 4suite
processor_type = -1
try:
    # libxml2 & libxslt
    import libxml2
    import libxslt
    processor_type = 0
except ImportError:
    pass

if processor_type == -1:
    try:
        # 4suite
        from Ft.Xml.Xslt import Processor
        from Ft.Xml import InputSource
        from xml.dom import Node
        processor_type = 1
    except ImportError:
        pass

if processor_type == -1:
    # No XSLT processor found
    sys.stderr.write('No XSLT processor could be found.\n' \
                     'No output produced.\n')
    sys.exit(1)

##################################################################
# Support for 'creation_date' and 'modification_date' functions  #

def get_creation_date_libxslt(ctx, recID, fmt="%Y-%m-%dT%H:%M:%SZ"):
    """
    libxslt extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns record creation date.

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:creation_date(445)"/> where 445 is a recID

    if recID is string, value is converted to int
    if recID is Node, first child node (text node) is taken as value
    """
    try:
        if isinstance(recID, str):
            recID_int = int(recID)
        elif isinstance(recID, (int, long)):
            recID_int = recID
        else:
            recID_int = libxml2.xmlNode(_obj=recID[0]).children.content

        if isinstance(fmt, str):
            fmt_str = fmt
        else:
            fmt_str = libxml2.xmlNode(_obj=recID[0]).children.content

        return get_creation_date(recID_int, fmt_str)
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

def get_creation_date_4suite(ctx, recID, fmt="%Y-%m-%dT%H:%M:%SZ"):
    """
    4suite extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns record creation date.

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:creation_date(445)"/>

    if value is int, value is converted to string
    if value is Node, first child node (text node) is taken as value
    """
    try:
        if len(recID) > 0 and isinstance(recID[0], Node):
            recID_int = recID[0].firstChild.nodeValue
            if recID_int is None:
                return ''
        else:
            recID_int = int(recID)

        if len(fmt) > 0 and isinstance(fmt[0], Node):
            fmt_str = fmt[0].firstChild.nodeValue
            if fmt_str is None:
                fmt_str = "%Y-%m-%dT%H:%M:%SZ"
        else:
            fmt_str = str(fmt)

        return get_creation_date(recID_int, fmt_str)
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

def get_modification_date_libxslt(ctx, recID, fmt="%Y-%m-%dT%H:%M:%SZ"):
    """
    libxslt extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns record modification date.

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:creation_date(445)"/> where 445 is a recID

    if recID is string, value is converted to int
    if recID is Node, first child node (text node) is taken as value
    """
    try:
        if isinstance(recID, str):
            recID_int = int(recID)
        elif isinstance(recID, (int, long)):
            recID_int = recID
        else:
            recID_int = libxml2.xmlNode(_obj=recID[0]).children.content

        if isinstance(fmt, str):
            fmt_str = fmt
        else:
            fmt_str = libxml2.xmlNode(_obj=recID[0]).children.content

        return get_modification_date(recID_int, fmt_str)
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

def get_modification_date_4suite(ctx, recID, fmt="%Y-%m-%dT%H:%M:%SZ"):
    """
    4suite extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns record modification date.

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:modification_date(445)"/>

    if value is int, value is converted to string
    if value is Node, first child node (text node) is taken as value
    """
    try:
        if len(recID) > 0 and isinstance(recID[0], Node):
            recID_int = recID[0].firstChild.nodeValue
            if recID_int is None:
                return ''
        else:
            recID_int = int(recID_int)

        if len(fmt) > 0 and isinstance(fmt[0], Node):
            fmt_str = fmt[0].firstChild.nodeValue
            if fmt_str is None:
                fmt_str = "%Y-%m-%dT%H:%M:%SZ"
        else:
            fmt_str = str(fmt)

        return get_modification_date(recID_int, fmt_str)
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

def eval_bibformat_libxslt(ctx, recID, template_code):
    """
    libxslt extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns the evaluation of the given piece of format template

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:eval_bibformat(marc:controlfield[@tag='001'],'<BFE_SERVER_INFO var="recurl">')" />

    if recID is string, value is converted to int
    if recID is Node, first child node (text node) is taken as value
    template_code is evaluated as a format template piece of code. '<'
    and '"' need to be escaped with '<' and '"'
    """
    from invenio.bibformat_engine import \
    format_with_format_template, \
    BibFormatObject
    try:
        if isinstance(recID, str):
            recID_int = int(recID)
        elif isinstance(recID, (int, long)):
            recID_int = recID
        else:
            recID_int = libxml2.xmlNode(_obj=recID[0]).children.content
        bfo = BibFormatObject(recID_int)
        return format_with_format_template(None, bfo,
                                           verbose=0,
                                           format_template_code=template_code)[0]
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

def eval_bibformat_4suite(ctx, recID, template_code):
    """
    4suite extension function:
    Bridge between BibFormat and XSL stylesheets.
    Returns the evaluation of the given piece of format template

    Can be used in that way in XSL stylesheet
    (provided xmlns:fn="http://cdsweb.cern.ch/bibformat/fn" has been declared):
    <xsl:value-of select="fn:eval_bibformat(marc:controlfield[@tag='001'],'<BFE_SERVER_INFO var="recurl">')" />

    if recID is string, value is converted to int
    if recID is Node, first child node (text node) is taken as value
    template_code is evaluated as a format template piece of code. '<'
    and '"' need to be escaped with '<' and '"'
    """
    from invenio.bibformat_engine import \
    format_with_format_template, \
    BibFormatObject
    try:
        if len(recID) > 0 and isinstance(recID[0], Node):
            recID_int = recID[0].firstChild.nodeValue
            if recID_int is None:
                return ''
        else:
            recID_int = int(recID_int)

        bfo = BibFormatObject(recID_int)
        return format_with_format_template(None, bfo,
                                           verbose=0,
                                           format_template_code=template_code)[0]
    except Exception, err:
        sys.stderr.write("Error during formatting function evaluation: " + \
                         str(err) + \
                         '\n')

        return ''

# End of date-related functions                                  #
##################################################################

def format(xmltext, template_filename=None, template_source=None):
    """
    Processes an XML text according to a template, and returns the result.

    The template can be given either by name (or by path) or by source.
    If source is given, name is ignored.

    bibformat_xslt_engine will look for template_filename in standard directories
    for templates. If not found, template_filename will be assumed to be a path to
    a template. If none can be found, return None.

    @param xmltext The string representation of the XML to process
    @param template_filename The name of the template to use for the processing
    @param template_source The configuration describing the processing.
    @return the transformed XML text.
    """
    if processor_type == -1:
        # No XSLT processor found
        sys.stderr.write('No XSLT processor could be found.')
        sys.exit(1)

    # Retrieve template and read it
    if template_source:
        template = template_source
    elif template_filename:
        try:
            path_to_templates = (CFG_BIBFORMAT_TEMPLATES_PATH + os.sep +
                                 template_filename)
            if os.path.exists(path_to_templates):
                template = file(path_to_templates).read()
            elif os.path.exists(template_filename):
                template = file(template_filename).read()
            else:
                sys.stderr.write(template_filename +' does not exist.')
                return None
        except IOError:
            sys.stderr.write(template_filename +' could not be read.')
            return None
    else:
        sys.stderr.write(template_filename +' was not given.')
        return None

    result = ""
    if processor_type == 0:
        # libxml2 & libxslt

        # Register BibFormat functions for use in XSL
        libxslt.registerExtModuleFunction("creation_date",
                                          CFG_BIBFORMAT_FUNCTION_NS,
                                          get_creation_date_libxslt)
        libxslt.registerExtModuleFunction("modification_date",
                                          CFG_BIBFORMAT_FUNCTION_NS,
                                          get_modification_date_libxslt)
        libxslt.registerExtModuleFunction("eval_bibformat",
                                          CFG_BIBFORMAT_FUNCTION_NS,
                                          eval_bibformat_libxslt)
        # Load template and source
        template_xml = libxml2.parseDoc(template)
        processor = libxslt.parseStylesheetDoc(template_xml)
        source = libxml2.parseDoc(xmltext)

        # Transform
        result_object = processor.applyStylesheet(source, None)
        try:
            result = processor.saveResultToString(result_object)
        except SystemError :
            # Catch an exception thrown when result is empty,
            # due to a bug in libxslt
            result = ''

        # Deallocate
        processor.freeStylesheet()
        source.freeDoc()
        result_object.freeDoc()

    elif processor_type == 1:
        # 4suite

        # Init
        processor = Processor.Processor()

        # Register BibFormat functions for use in XSL
        processor.registerExtensionFunction(CFG_BIBFORMAT_FUNCTION_NS,
                                            "creation_date",
                                            get_creation_date_4suite)
        processor.registerExtensionFunction(CFG_BIBFORMAT_FUNCTION_NS,
                                            "modification_date",
                                            get_modification_date_4suite)
        processor.registerExtensionFunction(CFG_BIBFORMAT_FUNCTION_NS,
                                            "eval_bibformat",
                                            eval_bibformat_4suite)
        # Load template and source
        transform = InputSource.DefaultFactory.fromString(template,
                                                       uri=CFG_SITE_URL)
        source = InputSource.DefaultFactory.fromString(xmltext,
                                                       uri=CFG_SITE_URL)
        processor.appendStylesheet(transform)

        # Transform
        result = processor.run(source)
    else:
        sys.stderr.write("No XSLT processor could be found")

    return result

if __name__ == "__main__":
    pass

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program 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.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import tools

import math
import logging
_logger = logging.getLogger(__name__)

def rounding(f, r):
	# TODO for trunk: log deprecation warning
	# _logger.warning("Deprecated rounding method, please use tools.float_round to round floats.")
	return tools.float_round(f, precision_rounding=r)

# TODO for trunk: add rounding method parameter to tools.float_round and use this method as hook
def ceiling(f, r):
    if not r:
        return f
    return math.ceil(f / r) * r
<commit_msg>[IMP] remove useless imports<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program 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.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import tools

import math

def rounding(f, r):
	# TODO for trunk: log deprecation warning
	# _logger.warning("Deprecated rounding method, please use tools.float_round to round floats.")
	return tools.float_round(f, precision_rounding=r)

# TODO for trunk: add rounding method parameter to tools.float_round and use this method as hook
def ceiling(f, r):
    if not r:
        return f
    return math.ceil(f / r) * r
<|endoftext|>


<commit_before>#!/usr/bin/python

# Copyright (c) 2014, Alexander Belchenko
# All rights reserved.
#
# Redistribution and use in source and binary forms,
# with or without modification, are permitted provided
# that the following conditions are met:
#
# * Redistributions of source code must retain
#   the above copyright notice, this list of conditions
#   and the following disclaimer.
# * Redistributions in binary form must reproduce
#   the above copyright notice, this list of conditions
#   and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
# * Neither the name of the author nor the names
#   of its contributors may be used to endorse
#   or promote products derived from this software
#   without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

""" Ad-hoc test runner against multiple python versions. """

import subprocess
import sys
import time

PYTHONS = (
    # display name, executable [full] path
    #('2.3', 'C:\Python23\python'),     # 2.3 is not supported
    ('2.4', 'C:\Python24\python'),
    ('2.5', 'C:\Python25\python'),
    ('2.6-32bit', 'C:\Python26-32bit\python'),
    ('2.6-64bit', 'C:\Python26-64bit\python'),
    ('2.7-32bit', 'C:\Python27-32bit\python'),
    ('2.7-64bit', 'C:\Python27-64bit\python'),
    ('3.3-32bit', 'C:\Python33-32bit\python'),
    ('3.3-64bit', 'C:\Python33-64bit\python'),
    )

def main():
    retcode = 0
    not_found = []
    failed = []
    print('%s started: %s\n' % (__file__, time.asctime()))
    for display_name, executable in PYTHONS:
        if checkPythonExists(display_name, executable):
            if not runTestWithPython(display_name, executable):
                retcode = 1
                failed.append(display_name)
        else:
            not_found.append(display_name)
    if failed or not_found:
        print('\n' + '-'*20)
    if failed:
        print('Tests failed with pythons: %s' % (', '.join(failed)))
    if not_found:
        print('Not found python versions: %s' % (', '.join(not_found)))
    return retcode

def checkPythonExists(display_name, executable):
    """ Run `python -V` and check that it runs OK. """
    sys.stdout.write('Check presence of python %s ... ' % display_name)
    cmd = '%s -V' % executable
    try:
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    except:
        exc = sys.exc_info()[1]     # current exception
        sys.stdout.write('ERROR\n  Exception: %s\n' % str(exc))
        return False
    stdout, stderr = p.communicate()
    retcode = p.poll()
    output = ''
    if stdout:
        output = stdout.decode('ascii', 'replace')
    elif stderr:
        output = stderr.decode('ascii', 'replace')
    output = output.replace('\r', '')
    if not output.endswith('\n'):
        output = output + '\n'
    sys.stdout.write(output)
    return retcode == 0

def runTestWithPython(display_name, executable):
    """ Runs `$(PYTHON) setup.py test -q` """
    cmd = '%s setup.py test -q' % executable
    sys.stdout.write('   Running tests against %s ... ' % display_name)
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = p.communicate()
    retcode = p.poll()
    if retcode == 0:
        sys.stdout.write('OK\n')
        return True
    else:
        sys.stdout.write('FAILED\n')
        return False

if __name__ == '__main__':
    sys.exit(main())
<commit_msg>support unix like<commit_after>#!/usr/bin/python

# Copyright (c) 2014, Alexander Belchenko
# All rights reserved.
#
# Redistribution and use in source and binary forms,
# with or without modification, are permitted provided
# that the following conditions are met:
#
# * Redistributions of source code must retain
#   the above copyright notice, this list of conditions
#   and the following disclaimer.
# * Redistributions in binary form must reproduce
#   the above copyright notice, this list of conditions
#   and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
# * Neither the name of the author nor the names
#   of its contributors may be used to endorse
#   or promote products derived from this software
#   without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

""" Ad-hoc test runner against multiple python versions. """

import subprocess
import sys
import time

if sys.platform == 'win32':
    PYTHONS = (
        # display name, executable [full] path
        #('2.3', 'C:\Python23\python'),     # 2.3 is not supported
        ('2.4', 'C:\Python24\python'),
        ('2.5', 'C:\Python25\python'),
        ('2.6-32bit', 'C:\Python26-32bit\python'),
        ('2.6-64bit', 'C:\Python26-64bit\python'),
        ('2.7-32bit', 'C:\Python27-32bit\python'),
        ('2.7-64bit', 'C:\Python27-64bit\python'),
        ('3.3-32bit', 'C:\Python33-32bit\python'),
        ('3.3-64bit', 'C:\Python33-64bit\python'),
        )
else:
    PYTHONS = (
        # display name, executable [full] path
        ('2.4', 'python2.4'),
        ('2.5', 'python2.5'),
        ('2.6', 'python2.6'),
        ('2.7', 'python2.7'),
        ('3.3-32bit', 'python3.3-32'),
        ('3.3-64bit', 'python3.3-64'),
        )

def main():
    retcode = 0
    not_found = []
    failed = []
    print('%s started: %s\n' % (__file__, time.asctime()))
    for display_name, executable in PYTHONS:
        if checkPythonExists(display_name, executable):
            if not runTestWithPython(display_name, executable):
                retcode = 1
                failed.append(display_name)
        else:
            not_found.append(display_name)
    if failed or not_found:
        print('\n' + '-'*20)
    if failed:
        print('Tests failed with pythons: %s' % (', '.join(failed)))
    if not_found:
        print('Not found python versions: %s' % (', '.join(not_found)))
    return retcode

def checkPythonExists(display_name, executable):
    """ Run `python -V` and check that it runs OK. """
    sys.stdout.write('Check presence of python %s ... ' % display_name)
    cmd = '%s -V' % executable
    try:
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    except:
        exc = sys.exc_info()[1]     # current exception
        sys.stdout.write('ERROR\n  Exception: %s\n' % str(exc))
        return False
    stdout, stderr = p.communicate()
    retcode = p.poll()
    output = ''
    if stdout:
        output = stdout.decode('ascii', 'replace')
    elif stderr:
        output = stderr.decode('ascii', 'replace')
    output = output.replace('\r', '')
    if not output.endswith('\n'):
        output = output + '\n'
    sys.stdout.write(output)
    return retcode == 0

def runTestWithPython(display_name, executable):
    """ Runs `$(PYTHON) setup.py test -q` """
    cmd = '%s setup.py test -q' % executable
    sys.stdout.write('   Running tests against %s ... ' % display_name)
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    stdout, stderr = p.communicate()
    retcode = p.poll()
    if retcode == 0:
        sys.stdout.write('OK\n')
        return True
    else:
        sys.stdout.write('FAILED\n')
        return False

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


<commit_before>from lr.plugins import ITombstonePolicy, DoNotPublishError
from pylons import config
from pprint import pprint
from os import walk
from lr.lib.signing import gpg

import logging, copy

log = logging.getLogger(__name__)

class AdminSignedTombstone(ITombstonePolicy):
    def __init__(self):
        super(ITombstonePolicy, self).__init__()

        self.public_key_fingerprints = []

    def activate(self):
        super(ITombstonePolicy, self).activate()

        public_key_directory = config['app_conf']['lr.tombstone.admin_signed.key_directory']

        for (dirpath, dirnames, filenames) in walk(public_key_directory):
            for f in filenames:
                if f[-4:] == '.txt':
                    with open(dirpath+f, 'r') as key_file:
                        self.public_key_fingerprints.extend(gpg.import_keys(key_file.read()).fingerprints)
                        print "Loading key from %s%s" % (dirpath, f)

    def permit(self, original_rd3=None, original_crypto=None, replacement_rd3=None, replacement_crypto=None):

        # if the public key fingerprint used for signing the replacement
        # request is among our admin list, then permit deletion
        result =  replacement_crypto.pubkey_fingerprint in self.public_key_fingerprints

        log.debug("Checking if signer is amongst admin keys: %s" % result)
        return result

    def permit_burial(self, replacement_rd3=None, replacement_crypto=None, graveyard=[], existing_gravestones=[]):
        # abide the default policy
        permit = False

        return permit

<commit_msg>fix for #285, make whitelist key directory not require trailing slash in configuration.<commit_after>from lr.plugins import ITombstonePolicy, DoNotPublishError
from pylons import config
from pprint import pprint
from os import walk, path
from lr.lib.signing import gpg

import logging, copy

log = logging.getLogger(__name__)

class AdminSignedTombstone(ITombstonePolicy):
    def __init__(self):
        super(ITombstonePolicy, self).__init__()

        self.public_key_fingerprints = []

    def activate(self):
        super(ITombstonePolicy, self).activate()

        public_key_directory = config['app_conf']['lr.tombstone.admin_signed.key_directory']

        for (dirpath, dirnames, filenames) in walk(public_key_directory):
            for f in filenames:
                if f[-4:] == '.txt':
                    with open(os.path.join(dirpath,f), 'r') as key_file:
                        self.public_key_fingerprints.extend(gpg.import_keys(key_file.read()).fingerprints)
                        print "Loading key from %s%s" % (dirpath, f)

    def permit(self, original_rd3=None, original_crypto=None, replacement_rd3=None, replacement_crypto=None):

        # if the public key fingerprint used for signing the replacement
        # request is among our admin list, then permit deletion
        result =  replacement_crypto.pubkey_fingerprint in self.public_key_fingerprints

        log.debug("Checking if signer is amongst admin keys: %s" % result)
        return result

    def permit_burial(self, replacement_rd3=None, replacement_crypto=None, graveyard=[], existing_gravestones=[]):
        # abide the default policy
        permit = False

        return permit

<|endoftext|>


<commit_before>from odoo import models, api, _

class StockMove(models.Model):
    _inherit = 'stock.move'

    @api.multi
    def write(self, vals):
        res = super().write(vals)
        if vals.get('lots_text', False):
            if self.picking_id.picking_type_id.code == 'outgoing':
                products = self.env['sim.type'].search([]).mapped('product_id')
                if self.product_id in products:
                    sims = vals.get('lots_text', '').upper().split(', ')
                    sim_packages = self.env['sim.package'].search([('code', 'in', sims)])
                    if sim_packages and len(sim_packages) == len(sims):
                        for pkg in sim_packages:
                            pkg.write({'partner_id': self.partner_id.commercial_partner_id.id,
                                       'move_id': self.id,
                                       'state': 'sold'})
                            if 'VISIOTECH' not in self.partner_id.commercial_partner_id.name \
                                    and 'VIP' not in pkg.code:  # TODO: manejar con los tipos
                                pkg.with_delay(priority=10).notify_sale_web('sold')
                    else:
                        # Notify warehouse something missing
                        mail_pool = self.env['mail.mail']
                        context = self._context.copy()
                        context.pop('default_state', False)
                        context['message_warn'] = \
                            _('Some of these SIM cards %s of the picking %s have not been found in the system.') % \
                            (vals.get('lots_text', ''), self.picking_id.name)

                        template_id = self.env.ref('sim_manager.email_template_sim_error')

                        if template_id:
                            mail_id = template_id.with_context(context).send_mail(self.id)
                            if mail_id:
                                mail_id_check = mail_pool.browse(mail_id)
                                mail_id_check.with_context(context).send()
        return res

    @api.multi
    def _action_done(self):
        res = super()._action_done()
        for move in self:
            if move.picking_id.picking_type_id.code == 'incoming' and move.lots_text:
                for pkg_code in move.lots_text.upper().split(', '):
                    sim_packages = self.env['sim.package'].search([('code', '=', pkg_code)])
                    if sim_packages:
                        for pkg in sim_packages:
                            pkg.write({'partner_id': None,
                                       'move_id': None,
                                       'state': 'available'})
                            if 'VISIOTECH' not in move.partner_id.commercial_partner_id.name \
                                    and 'VIP' not in pkg.code:  # TODO: manejar con los tipos
                                pkg.with_delay(priority=10).notify_sale_web('return')
        return res

<commit_msg>[FIX]sim_manager: cogemos el partner del picking para evitar que al parcializar queden vacías<commit_after>from odoo import models, api, _

class StockMove(models.Model):
    _inherit = 'stock.move'

    @api.multi
    def write(self, vals):
        res = super().write(vals)
        if vals.get('lots_text', False):
            if self.picking_id.picking_type_id.code == 'outgoing':
                products = self.env['sim.type'].search([]).mapped('product_id')
                if self.product_id in products:
                    sims = vals.get('lots_text', '').upper().split(', ')
                    sim_packages = self.env['sim.package'].search([('code', 'in', sims)])
                    if sim_packages and len(sim_packages) == len(sims):
                        for pkg in sim_packages:
                            pkg.write({'partner_id': self.picking_id.partner_id.commercial_partner_id.id,
                                       'move_id': self.id,
                                       'state': 'sold'})
                            if 'VISIOTECH' not in self.picking_id.partner_id.commercial_partner_id.name \
                                    and 'VIP' not in pkg.code:  # TODO: manejar con los tipos
                                pkg.with_delay(priority=10).notify_sale_web('sold')
                    else:
                        # Notify warehouse something missing
                        mail_pool = self.env['mail.mail']
                        context = self._context.copy()
                        context.pop('default_state', False)
                        context['message_warn'] = \
                            _('Some of these SIM cards %s of the picking %s have not been found in the system.') % \
                            (vals.get('lots_text', ''), self.picking_id.name)

                        template_id = self.env.ref('sim_manager.email_template_sim_error')

                        if template_id:
                            mail_id = template_id.with_context(context).send_mail(self.id)
                            if mail_id:
                                mail_id_check = mail_pool.browse(mail_id)
                                mail_id_check.with_context(context).send()
        return res

    @api.multi
    def _action_done(self):
        res = super()._action_done()
        for move in self:
            if move.picking_id.picking_type_id.code == 'incoming' and move.lots_text:
                for pkg_code in move.lots_text.upper().split(', '):
                    sim_packages = self.env['sim.package'].search([('code', '=', pkg_code)])
                    if sim_packages:
                        for pkg in sim_packages:
                            pkg.write({'partner_id': None,
                                       'move_id': None,
                                       'state': 'available'})
                            if 'VISIOTECH' not in move.partner_id.commercial_partner_id.name \
                                    and 'VIP' not in pkg.code:  # TODO: manejar con los tipos
                                pkg.with_delay(priority=10).notify_sale_web('return')
        return res

<|endoftext|>


<commit_before>from __future__ import print_function
from . import Utils
from . import Survey
from . import Models
import numpy as np
from . import Maps
from .Fields import Fields, TimeFields
from . import Mesh

Solver = Utils.SolverUtils.Solver

class BaseProblem(object):
    """
        Problem is the base class for all geophysical forward problems
        in SimPEG.
    """

    counter = None  #: A SimPEG.Utils.Counter object

    surveyPair = Survey.BaseSurvey  #: A SimPEG.Survey Class
    mapPair = Maps.IdentityMap      #: A SimPEG.Map Class

    Solver = Solver   #: A SimPEG Solver class.
    solverOpts = {}   #: Sovler options as a kwarg dict

    mesh = None       #: A SimPEG.Mesh instance.

    PropMap = None    #: A SimPEG PropertyMap class.

    @property
    def mapping(self):
        "A SimPEG.Map instance or a property map is PropMap is not None"
        return getattr(self, '_mapping', None)

    @mapping.setter
    def mapping(self, val):
        if self.PropMap is None:
            val._assertMatchesPair(self.mapPair)
            self._mapping = val
        else:
            self._mapping = self.PropMap(val)

    def __init__(self, mesh, mapping=None, **kwargs):
        Utils.setKwargs(self, **kwargs)
        assert isinstance(mesh, Mesh.BaseMesh), (
            "mesh must be a SimPEG.Mesh object."
        )
        self.mesh = mesh
        self.mapping = mapping or Maps.IdentityMap(mesh)

    @property
    def survey(self):
        """
        The survey object for this problem.
        """
        return getattr(self, '_survey', None)

    def pair(self, d):
        """Bind a survey to this problem instance using pointers."""
        assert isinstance(d, self.surveyPair), (
            "Data object must be an instance of a {0!s} class.".format(
                self.surveyPair.__name__
            )
        )
        if d.ispaired:
            raise Exception(
                "The survey object is already paired to a problem. "
                "Use survey.unpair()"
            )
        self._survey = d
        d._prob = self

    def unpair(self):
        """Unbind a survey from this problem instance."""
        if not self.ispaired:
            return
        self.survey._prob = None
        self._survey = None

    #: List of strings, e.g. ['_MeSigma', '_MeSigmaI']
    deleteTheseOnModelUpdate = []

    @property
    def curModel(self):
        """
            Sets the current model, and removes dependent mass matrices.
        """
        return getattr(self, '_curModel', None)

    @curModel.setter
    def curModel(self, value):
        if value is self.curModel:
            return  # it is the same!
        if self.PropMap is not None:
            self._curModel = self.mapping(value)
        else:
            self._curModel = Models.Model(value, self.mapping)
        for prop in self.deleteTheseOnModelUpdate:
            if hasattr(self, prop):
                delattr(self, prop)

    @property
    def ispaired(self):
        """True if the problem is paired to a survey."""
        return self.survey is not None

    @Utils.timeIt
    def Jvec(self, m, v, f=None):
        """Jvec(m, v, f=None)

            Effect of J(m) on a vector v.

            :param numpy.array m: model
            :param numpy.array v: vector to multiply
            :param Fields f: fields
            :rtype: numpy.array
            :return: Jv
        """
        raise NotImplementedError('J is not yet implemented.')

    @Utils.timeIt
    def Jtvec(self, m, v, f=None):
        """Jtvec(m, v, f=None)

            Effect of transpose of J(m) on a vector v.

            :param numpy.array m: model
            :param numpy.array v: vector to multiply
            :param Fields f: fields
            :rtype: numpy.array
            :return: JTv
        """
        raise NotImplementedError('Jt is not yet implemented.')

    @Utils.timeIt
    def Jvec_approx(self, m, v, f=None):
        """Jvec_approx(m, v, f=None)

            Approximate effect of J(m) on a vector v

            :param numpy.array m: model
            :param numpy.array v: vector to multiply
            :param Fields f: fields
            :rtype: numpy.array
            :return: approxJv
        """
        return self.Jvec(m, v, f)

    @Utils.timeIt
    def Jtvec_approx(self, m, v, f=None):
        """Jtvec_approx(m, v, f=None)

            Approximate effect of transpose of J(m) on a vector v.

            :param numpy.array m: model
            :param numpy.array v: vector to multiply
            :param Fields f: fields
            :rtype: numpy.array
            :return: JTv
        """
        return self.Jtvec(m, v, f)

    def fields(self, m):
        """
            The field given the model.

            :param numpy.array m: model
            :rtype: numpy.array
            :return: u, the fields

        """
        raise NotImplementedError('fields is not yet implemented.')

class BaseTimeProblem(BaseProblem):
    """Sets up that basic needs of a time domain problem."""

    @property
    def timeSteps(self):
        """Sets/gets the timeSteps for the time domain problem.

        You can set as an array of dt's or as a list of tuples/floats.
        Tuples must be length two with [..., (dt, repeat), ...]

        For example, the following setters are the same::

            prob.timeSteps = [(1e-6, 3), 1e-5, (1e-4, 2)]
            prob.timeSteps = np.r_[1e-6,1e-6,1e-6,1e-5,1e-4,1e-4]

        """
        return getattr(self, '_timeSteps', None)

    @timeSteps.setter
    def timeSteps(self, value):
        if isinstance(value, np.ndarray):
            self._timeSteps = value
            del self.timeMesh
            return

        self._timeSteps = Utils.meshTensor(value)
        del self.timeMesh

    @property
    def nT(self):
        "Number of time steps."
        return self.timeMesh.nC

    @property
    def t0(self):
        return getattr(self, '_t0', 0.0)

    @t0.setter
    def t0(self, value):
        assert Utils.isScalar(value), 't0 must be a scalar'
        del self.timeMesh
        self._t0 = float(value)

    @property
    def times(self):
        "Modeling times"
        return self.timeMesh.vectorNx

    @property
    def timeMesh(self):
        if getattr(self, '_timeMesh', None) is None:
            self._timeMesh = Mesh.TensorMesh([self.timeSteps], x0=[self.t0])
        return self._timeMesh

    @timeMesh.deleter
    def timeMesh(self):
        if hasattr(self, '_timeMesh'):
            del self._timeMesh

class LinearProblem(BaseProblem):

    surveyPair = Survey.LinearSurvey

    def __init__(self, mesh, G, **kwargs):
        BaseProblem.__init__(self, mesh, **kwargs)
        self.G = G

    def fields(self, m):
        return self.G.dot(m)

    def Jvec(self, m, v, f=None):
        return self.G.dot(v)

    def Jtvec(self, m, v, f=None):
        return self.G.T.dot(v)
<commit_msg>Type on solver dict.<commit_after>from __future__ import print_function
from . import Utils
from . import Survey
from . import Models
import numpy as np
from . import Maps
from .Fields import Fields, TimeFields
from . import Mesh

Solver = Utils.SolverUtils.Solver

class BaseProblem(object):
    """
        Problem is the base class for all geophysical forward problems
        in SimPEG.
    """

    counter = None  #: A SimPEG.Utils.Counter object

    surveyPair = Survey.BaseSurvey  #: A SimPEG.Survey Class
    mapPair = Maps.IdentityMap      #: A SimPEG.Map Class

    Solver = Solver   #: A SimPEG Solver class.
    solverOpts = {}   #: Solver options as a kwarg dict

    mesh = None       #: A SimPEG.Mesh instance.

    PropMap = None    #: A SimPEG PropertyMap class.

    @property
    def mapping(self):
        "A SimPEG.Map instance or a property map is PropMap is not None"
        return getattr(self, '_mapping', None)

    @mapping.setter
    def mapping(self, val):
        if self.PropMap is None:
            val._assertMatchesPair(self.mapPair)
            self._mapping = val
        else:
            self._mapping = self.PropMap(val)

    def __init__(self, mesh, mapping=None, **kwargs):
        Utils.setKwargs(self, **kwargs)
        assert isinstance(mesh, Mesh.BaseMesh), (
            "mesh must be a SimPEG.Mesh object."
        )
        self.mesh = mesh
        self.mapping = mapping or Maps.IdentityMap(mesh)

    @property
    def survey(self):
        """
        The survey object for this problem.
        """
        return getattr(self, '_survey', None)

    def pair(self, d):
        """Bind a survey to this problem instance using pointers."""
        assert isinstance(d, self.surveyPair), (
            "Data object must be an instance of a {0!s} class.".format(
                self.surveyPair.__name__
            )
        )
        if d.ispaired:
            raise Exception(
                "The survey object is already paired to a problem. "
                "Use survey.unpair()"
            )
        self._survey = d
        d._prob = self

    def unpair(self):
        """Unbind a survey from this problem instance."""
        if not self.ispaired:
            return
        self.survey._prob = None
        self._survey = None

    #: List of strings, e.g. ['_MeSigma', '_MeSigmaI']
    deleteTheseOnModelUpdate = []

    @property
    def curModel(self):
        """
            Sets the current model, and removes dependent mass matrices.
        """
        return getattr(self, '_curModel', None)

    @curModel.setter
    def curModel(self, value):
        if value is self.curModel:
            return  # it is the same!
        if self.PropMap is not None:
            self._curModel = self.mapping(value)
        else:
            self._curModel = Models.Model(value, self.mapping)
        for prop in self.deleteTheseOnModelUpdate:
            if hasattr(self, prop):
                delattr(self, prop)

    @property
    def ispaired(self):
        """True if the problem is paired to a survey."""
        return self.survey is not None

    @Utils.timeIt
    def Jvec(self, m, v, f=None):
        """Jvec(m, v, f=None)

            Effect of J(m) on a vector v.

            :param numpy.array m: model
            :param numpy.array v: vector to multiply
            :param Fields f: fields
            :rtype: numpy.array
            :return: Jv
        """
        raise NotImplementedError('J is not yet implemented.')

    @Utils.timeIt
    def Jtvec(self, m, v, f=None):
        """Jtvec(m, v, f=None)

            Effect of transpose of J(m) on a vector v.

            :param numpy.array m: model
            :param numpy.array v: vector to multiply
            :param Fields f: fields
            :rtype: numpy.array
            :return: JTv
        """
        raise NotImplementedError('Jt is not yet implemented.')

    @Utils.timeIt
    def Jvec_approx(self, m, v, f=None):
        """Jvec_approx(m, v, f=None)

            Approximate effect of J(m) on a vector v

            :param numpy.array m: model
            :param numpy.array v: vector to multiply
            :param Fields f: fields
            :rtype: numpy.array
            :return: approxJv
        """
        return self.Jvec(m, v, f)

    @Utils.timeIt
    def Jtvec_approx(self, m, v, f=None):
        """Jtvec_approx(m, v, f=None)

            Approximate effect of transpose of J(m) on a vector v.

            :param numpy.array m: model
            :param numpy.array v: vector to multiply
            :param Fields f: fields
            :rtype: numpy.array
            :return: JTv
        """
        return self.Jtvec(m, v, f)

    def fields(self, m):
        """
            The field given the model.

            :param numpy.array m: model
            :rtype: numpy.array
            :return: u, the fields

        """
        raise NotImplementedError('fields is not yet implemented.')

class BaseTimeProblem(BaseProblem):
    """Sets up that basic needs of a time domain problem."""

    @property
    def timeSteps(self):
        """Sets/gets the timeSteps for the time domain problem.

        You can set as an array of dt's or as a list of tuples/floats.
        Tuples must be length two with [..., (dt, repeat), ...]

        For example, the following setters are the same::

            prob.timeSteps = [(1e-6, 3), 1e-5, (1e-4, 2)]
            prob.timeSteps = np.r_[1e-6,1e-6,1e-6,1e-5,1e-4,1e-4]

        """
        return getattr(self, '_timeSteps', None)

    @timeSteps.setter
    def timeSteps(self, value):
        if isinstance(value, np.ndarray):
            self._timeSteps = value
            del self.timeMesh
            return

        self._timeSteps = Utils.meshTensor(value)
        del self.timeMesh

    @property
    def nT(self):
        "Number of time steps."
        return self.timeMesh.nC

    @property
    def t0(self):
        return getattr(self, '_t0', 0.0)

    @t0.setter
    def t0(self, value):
        assert Utils.isScalar(value), 't0 must be a scalar'
        del self.timeMesh
        self._t0 = float(value)

    @property
    def times(self):
        "Modeling times"
        return self.timeMesh.vectorNx

    @property
    def timeMesh(self):
        if getattr(self, '_timeMesh', None) is None:
            self._timeMesh = Mesh.TensorMesh([self.timeSteps], x0=[self.t0])
        return self._timeMesh

    @timeMesh.deleter
    def timeMesh(self):
        if hasattr(self, '_timeMesh'):
            del self._timeMesh

class LinearProblem(BaseProblem):

    surveyPair = Survey.LinearSurvey

    def __init__(self, mesh, G, **kwargs):
        BaseProblem.__init__(self, mesh, **kwargs)
        self.G = G

    def fields(self, m):
        return self.G.dot(m)

    def Jvec(self, m, v, f=None):
        return self.G.dot(v)

    def Jtvec(self, m, v, f=None):
        return self.G.T.dot(v)
<|endoftext|>


<commit_before>from netpyne import sim

# Network parameters
netParams = {}  # dictionary to store sets of network parameters

netParams['sizeX'] = 100 # x-dimension (horizontal length) size in um
netParams['sizeY'] = 1000 # y-dimension (vertical height or cortical depth) size in um
netParams['sizeZ'] = 100 # z-dimension (horizontal length) size in um
netParams['propVelocity'] = 100.0 # propagation velocity (um/ms)
netParams['probLengthConst'] = 150.0 # length constant for conn probability (um)

## Population parameters
netParams['popParams'] = []  # list of populations - each item will contain dict with pop params
netParams['popParams'].append({'popLabel': 'E2', 'cellType': 'E', 'numCells': 50, 'yRange': [100,300], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'I2', 'cellType': 'I', 'numCells': 50, 'yRange': [100,300], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'E4', 'cellType': 'E', 'numCells': 50, 'yRange': [300,600], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'I4', 'cellType': 'I', 'numCells': 50, 'yRange': [300,600], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'E5', 'cellType': 'E', 'numCells': 50, 'ynormRange': [0.6,1.0], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'I5', 'cellType': 'I', 'numCells': 50, 'ynormRange': [0.6,1.0], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'background', 'rate': 20, 'noise': 0.3, 'cellModel': 'NetStim'})

## Cell property rules
netParams['cellParams'] = [] # list of cell property rules - each item will contain dict with cell properties
cellRule = {'label': 'PYRrule', 'conditions': {'cellType': 'E'},  'sections': {}}     # cell rule dict
soma = {'geom': {}, 'mechs': {}}                                            # soma params dict
soma['geom'] = {'diam': 15, 'L': 14, 'Ra': 120.0}                                   # soma geometry
soma['mechs']['hh'] = {'gnabar': 0.13, 'gkbar': 0.036, 'gl': 0.003, 'el': -70}          # soma hh mechanism
cellRule['sections'] = {'soma': soma}                                                   # add soma section to dict
netParams['cellParams'].append(cellRule)                                                # add dict to list of cell par

cellRule = {'label': 'BASrule', 'conditions': {'cellType': 'I'},  'sections': {}}     # cell rule dict
soma = {'geom': {}, 'mechs': {}}                                            # soma params dict
soma['geom'] = {'diam': 10.0, 'L': 9.0, 'Ra': 110.0}                                    # soma geometry
soma['mechs']['hh'] = {'gnabar': 0.12, 'gkbar': 0.036, 'gl': 0.003, 'el': -70}          # soma hh mechanism
cellRule['sections'] = {'soma': soma}                                                   # add soma section to dict
netParams['cellParams'].append(cellRule)                                                # add dict to list of cell par

## Synaptic mechanism parameters
netParams['synMechParams'] = []
netParams['synMechParams'].append({'label': 'exc', 'mod': 'Exp2Syn', 'tau1': 0.8, 'tau2': 5.3, 'e': 0})  # NMDA synaptic mechanism
netParams['synMechParams'].append({'label': 'inh', 'mod': 'Exp2Syn', 'tau1': 0.6, 'tau2': 8.5, 'e': -75})  # GABA synaptic mechanism

## Cell connectivity rules
netParams['connParams'] = []

netParams['connParams'].append({'preTags': {'popLabel': 'background'}, 'postTags': {'cellType': ['E', 'I']}, # background -> all
  'weight': 0.01,                     # synaptic weight
  'delay': 'max(1, gauss(5,2))',      # transmission delay (ms)
  'synMech': 'exc'})                  # synaptic mechanism

netParams['connParams'].append({'preTags': {'cellType': 'E'}, 'postTags': {'y': [100,1000]},  #  E -> all (100-1000 um)
  'probability': 0.1,#'uniform(0.05,0.2)',    # probability of connection
  'weight': '0.005*post_ynorm',         # synaptic weight
  'delay': 'dist_3D/propVelocity',      # transmission delay (ms)
  'synMech': 'exc'})                    # synaptic mechanism

netParams['connParams'].append({'preTags': {'cellType': 'I'}, 'postTags': {'popLabel': ['E2','E4','E5']},       #  I -> E
  'probability': '0.4*exp(-dist_3D/probLengthConst)',   # probability of connection
  'weight': 0.001,                                     # synaptic weight
  'delay': 'dist_3D/propVelocity',                    # transmission delay (ms)
  'synMech': 'inh'})                                  # synaptic mechanism

# Simulation options
simConfig = {}
simConfig['duration'] = 1*1e3           # Duration of the simulation, in ms
simConfig['dt'] = 0.1                 # Internal integration timestep to use
simConfig['verbose'] = False            # Show detailed messages
simConfig['recordTraces'] = {'V_soma':{'sec':'soma','loc':0.5,'var':'v'}}  # Dict with traces to record
simConfig['recordStep'] = 1             # Step size in ms to save data (eg. V traces, LFP, etc)
simConfig['filename'] = 'model_output'  # Set file output name
simConfig['savePickle'] = False         # Save params, network and sim output to pickle file
simConfig['plotRaster'] = True          # Plot a raster
simConfig['orderRasterYnorm'] = 1       # Order cells in raster by yfrac (default is by pop and cell id)
simConfig['plotCells'] = ['E2','E4','E5']    # Plot recorded traces for this list of cells
simConfig['plot2Dnet'] = True           # plot 2D visualization of cell positions and connections

# Create network and run simulation
sim.createAndSimulate(netParams = netParams, simConfig = simConfig)

# import pylab; pylab.show()  # this line is only necessary in certain systems where figures appear empty
<commit_msg>where am i?<commit_after>from netpyne import sim

# Network parameters
netParams = {}  # dictionary to store sets of network parameters

netParams['sizeX'] = 100 # x-dimension (horizontal length) size in um
netParams['sizeY'] = 1000 # y-dimension (vertical height or cortical depth) size in um
netParams['sizeZ'] = 100 # z-dimension (horizontal length) size in um
netParams['propVelocity'] = 100.0 # propagation velocity (um/ms)
netParams['probLengthConst'] = 150.0 # length constant for conn probability (um)

## Population parameters
netParams['popParams'] = []  # list of populations - each item will contain dict with pop params
netParams['popParams'].append({'popLabel': 'E2', 'cellType': 'E', 'numCells': 50, 'yRange': [100,300], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'I2', 'cellType': 'I', 'numCells': 50, 'yRange': [100,300], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'E4', 'cellType': 'E', 'numCells': 50, 'yRange': [300,600], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'I4', 'cellType': 'I', 'numCells': 50, 'yRange': [300,600], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'E5', 'cellType': 'E', 'numCells': 50, 'ynormRange': [0.6,1.0], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'I5', 'cellType': 'I', 'numCells': 50, 'ynormRange': [0.6,1.0], 'cellModel': 'HH'})
netParams['popParams'].append({'popLabel': 'background', 'rate': 20, 'noise': 0.3, 'cellModel': 'NetStim'})

## Cell property rules
netParams['cellParams'] = [] # list of cell property rules - each item will contain dict with cell properties
cellRule = {'label': 'PYRrule', 'conditions': {'cellType': 'E'},  'sections': {}}     # cell rule dict
soma = {'geom': {}, 'mechs': {}}                                            # soma params dict
soma['geom'] = {'diam': 15, 'L': 14, 'Ra': 120.0}                                   # soma geometry
soma['mechs']['hh'] = {'gnabar': 0.13, 'gkbar': 0.036, 'gl': 0.003, 'el': -70}          # soma hh mechanism
cellRule['sections'] = {'soma': soma}                                                   # add soma section to dict
netParams['cellParams'].append(cellRule)                                                # add dict to list of cell par

cellRule = {'label': 'BASrule', 'conditions': {'cellType': 'I'},  'sections': {}}     # cell rule dict
soma = {'geom': {}, 'mechs': {}}                                            # soma params dict
soma['geom'] = {'diam': 10.0, 'L': 9.0, 'Ra': 110.0}                                    # soma geometry
soma['mechs']['hh'] = {'gnabar': 0.12, 'gkbar': 0.036, 'gl': 0.003, 'el': -70}          # soma hh mechanism
cellRule['sections'] = {'soma': soma}                                                   # add soma section to dict
netParams['cellParams'].append(cellRule)                                                # add dict to list of cell par

## Synaptic mechanism parameters
netParams['synMechParams'] = []
netParams['synMechParams'].append({'label': 'exc', 'mod': 'Exp2Syn', 'tau1': 0.8, 'tau2': 5.3, 'e': 0})  # NMDA synaptic mechanism
netParams['synMechParams'].append({'label': 'inh', 'mod': 'Exp2Syn', 'tau1': 0.6, 'tau2': 8.5, 'e': -75})  # GABA synaptic mechanism

## Cell connectivity rules
netParams['connParams'] = []

netParams['connParams'].append({'preTags': {'popLabel': 'background'}, 'postTags': {'cellType': ['E', 'I']}, # background -> all
  'weight': 0.01,                     # synaptic weight
  'delay': 'max(1, gauss(5,2))',      # transmission delay (ms)
  'synMech': 'exc'})                  # synaptic mechanism

netParams['connParams'].append({'preTags': {'cellType': 'E'}, 'postTags': {'y': [100,1000]},  #  E -> all (100-1000 um)
  'probability': 0.1,#'uniform(0.05,0.2)',    # probability of connection
  'weight': '0.005*post_ynorm',         # synaptic weight
  'delay': 'dist_3D/propVelocity',      # transmission delay (ms)
  'synMech': 'exc'})                    # synaptic mechanism

netParams['connParams'].append({'preTags': {'cellType': 'I'}, 'postTags': {'popLabel': ['E2','E4','E5']},       #  I -> E
  'probability': '0.4*exp(-dist_3D/probLengthConst)',   # probability of connection
  'weight': 0.001,                                     # synaptic weight
  'delay': 'dist_3D/propVelocity',                    # transmission delay (ms)
  'synMech': 'inh'})                                  # synaptic mechanism

# Simulation options
simConfig = {}
simConfig['duration'] = 1*1e3           # Duration of the simulation, in ms
simConfig['dt'] = 0.1                 # Internal integration timestep to use
simConfig['verbose'] = False            # Show detailed messages
simConfig['recordTraces'] = {'V_soma':{'sec':'soma','loc':0.5,'var':'v'}}  # Dict with traces to record
simConfig['recordStep'] = 1             # Step size in ms to save data (eg. V traces, LFP, etc)
simConfig['filename'] = 'model_output'  # Set file output name
simConfig['savePickle'] = False         # Save params, network and sim output to pickle file
simConfig['plotRaster'] = True          # Plot a raster
simConfig['orderRasterYnorm'] = 1       # Order cells in raster by yfrac (default is by pop and cell id)
simConfig['plotCells'] = ['E2','E4','E5']    # Plot recorded traces for this list of cells
simConfig['plot2Dnet'] = False           # plot 2D visualization of cell positions and connections

# Create network and run simulation
sim.createAndSimulate(netParams = netParams, simConfig = simConfig)

# import pylab; pylab.show()  # this line is only necessary in certain systems where figures appear empty
<|endoftext|>


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

# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 OpenStack LLC.
#
#    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.

"""
Utility for diff'ing two versions of the DB schema.

Each release cycle the plan is to compact all of the migrations from that
release into a single file. This is a manual and, unfortunately, error-prone
process. To ensure that the schema doesn't change, this tool can be used to
diff the compacted DB schema to the original, uncompacted form.

The schema versions are specified by providing a git ref (a branch name or
commit hash) and a SQLAlchemy-Migrate version number:
Run like:

    ./tools/db/schema_diff.py mysql master:latest my_branch:82
"""
import datetime
import glob
import os
import subprocess
import sys

### Dump

def dump_db(db_driver, db_name, migration_version, dump_filename):
    db_driver.create(db_name)
    try:
        migrate(db_driver, db_name, migration_version)
        db_driver.dump(db_name, dump_filename)
    finally:
        db_driver.drop(db_name)

### Diff

def diff_files(filename1, filename2):
    pipeline = ['diff -U 3 %(filename1)s %(filename2)s' % locals()]

    # Use colordiff if available
    if subprocess.call(['which', 'colordiff']) == 0:
        pipeline.append('colordiff')

    pipeline.append('less -R')

    cmd = ' | '.join(pipeline)
    subprocess.check_call(cmd, shell=True)

### Database

class MySQL(object):
    def create(self, name):
        subprocess.check_call(['mysqladmin', '-u', 'root', 'create', name])

    def drop(self, name):
        subprocess.check_call(['mysqladmin', '-f', '-u', 'root', 'drop', name])

    def dump(self, name, dump_filename):
        subprocess.check_call(
                'mysqldump -u root %(name)s > %(dump_filename)s' % locals(),
                shell=True)

    def url(self, name):
        return 'mysql://root@localhost/%s' % name

class Postgres(object):
    def create(self, name):
        subprocess.check_call(['createdb', name])

    def drop(self, name):
        subprocess.check_call(['dropdb', name])

    def dump(self, name, dump_filename):
        subprocess.check_call(
                'pg_dump %(name)s > %(dump_filename)s' % locals(),
                shell=True)

    def url(self, name):
        return 'postgres://localhost/%s' % name

def _get_db_driver_class(db_type):
    if db_type == "mysql":
        return MySQL
    elif db_type == "postgres":
        return Postgres
    else:
        raise Exception("database %s not supported" % db_type)

### Migrate

MIGRATE_REPO = os.path.join(os.getcwd(), "nova/db/sqlalchemy/migrate_repo")

def migrate(db_driver, db_name, migration_version):
    earliest_version = _migrate_get_earliest_version()

    # NOTE(sirp): sqlalchemy-migrate currently cannot handle the skipping of
    # migration numbers.
    _migrate_cmd(
            db_driver, db_name, 'version_control', str(earliest_version - 1))

    upgrade_cmd = ['upgrade']
    if migration_version != 'latest':
        upgrade_cmd.append(str(migration_version))

    _migrate_cmd(db_driver, db_name, *upgrade_cmd)

def _migrate_cmd(db_driver, db_name, *cmd):
    manage_py = os.path.join(MIGRATE_REPO, 'manage.py')

    args = ['python', manage_py]
    args += cmd
    args += ['--repository=%s' % MIGRATE_REPO,
             '--url=%s' % db_driver.url(db_name)]

    subprocess.check_call(args)

def _migrate_get_earliest_version():
    versions_glob = os.path.join(MIGRATE_REPO, 'versions', '???_*.py')

    versions = []
    for path in glob.iglob(versions_glob):
        filename = os.path.basename(path)
        prefix = filename.split('_', 1)[0]
        try:
            version = int(prefix)
        except ValueError:
            pass
        versions.append(version)

    versions.sort()
    return versions[0]

### Git

def git_current_branch_name():
    ref_name = git_symbolic_ref('HEAD', quiet=True)
    current_branch_name = ref_name.replace('refs/heads/', '')
    return current_branch_name

def git_symbolic_ref(ref, quiet=False):
    args = ['git', 'symbolic-ref', ref]
    if quiet:
        args.append('-q')
    proc = subprocess.Popen(args, stdout=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    return stdout.strip()

def git_checkout(branch_name):
    subprocess.check_call(['git', 'checkout', branch_name])

def git_has_uncommited_changes():
    return subprocess.call(['git', 'diff', '--quiet', '--exit-code']) == 1

### Command

def die(msg):
    print >> sys.stderr, "ERROR: %s" % msg
    sys.exit(1)

def usage(msg=None):
    if msg:
        print >> sys.stderr, "ERROR: %s" % msg

    prog = "schema_diff.py"
    args = ["<mysql|postgres>", "<orig-branch:orig-version>",
            "<new-branch:new-version>"]

    print >> sys.stderr, "usage: %s %s" % (prog, ' '.join(args))
    sys.exit(1)

def parse_options():
    try:
        db_type = sys.argv[1]
    except IndexError:
        usage("must specify DB type")

    try:
        orig_branch, orig_version = sys.argv[2].split(':')
    except IndexError:
        usage('original branch and version required (e.g. master:82)')

    try:
        new_branch, new_version = sys.argv[3].split(':')
    except IndexError:
        usage('new branch and version required (e.g. master:82)')

    return db_type, orig_branch, orig_version, new_branch, new_version

def main():
    timestamp = datetime.datetime.utcnow().strftime("%Y%m%d_%H%M%S")

    ORIG_DB = 'orig_db_%s' % timestamp
    NEW_DB = 'new_db_%s' % timestamp

    ORIG_DUMP = ORIG_DB + ".dump"
    NEW_DUMP = NEW_DB + ".dump"

    options = parse_options()
    db_type, orig_branch, orig_version, new_branch, new_version = options

    # Since we're going to be switching branches, ensure user doesn't have any
    # uncommited changes
    if git_has_uncommited_changes():
        die("You have uncommited changes. Please commit them before running "
            "this command.")

    db_driver = _get_db_driver_class(db_type)()

    users_branch = git_current_branch_name()
    git_checkout(orig_branch)

    try:
        # Dump Original Schema
        dump_db(db_driver, ORIG_DB, orig_version, ORIG_DUMP)

        # Dump New Schema
        git_checkout(new_branch)
        dump_db(db_driver, NEW_DB, new_version, NEW_DUMP)

        diff_files(ORIG_DUMP, NEW_DUMP)
    finally:
        git_checkout(users_branch)

        if os.path.exists(ORIG_DUMP):
            os.unlink(ORIG_DUMP)

        if os.path.exists(NEW_DUMP):
            os.unlink(NEW_DUMP)

if __name__ == "__main__":
    main()
<commit_msg>i18n raise Exception messages<commit_after>#!/usr/bin/env python

# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 OpenStack LLC.
#
#    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.

"""
Utility for diff'ing two versions of the DB schema.

Each release cycle the plan is to compact all of the migrations from that
release into a single file. This is a manual and, unfortunately, error-prone
process. To ensure that the schema doesn't change, this tool can be used to
diff the compacted DB schema to the original, uncompacted form.

The schema versions are specified by providing a git ref (a branch name or
commit hash) and a SQLAlchemy-Migrate version number:
Run like:

    ./tools/db/schema_diff.py mysql master:latest my_branch:82
"""
import datetime
import glob
import os
import subprocess
import sys

### Dump

def dump_db(db_driver, db_name, migration_version, dump_filename):
    db_driver.create(db_name)
    try:
        migrate(db_driver, db_name, migration_version)
        db_driver.dump(db_name, dump_filename)
    finally:
        db_driver.drop(db_name)

### Diff

def diff_files(filename1, filename2):
    pipeline = ['diff -U 3 %(filename1)s %(filename2)s' % locals()]

    # Use colordiff if available
    if subprocess.call(['which', 'colordiff']) == 0:
        pipeline.append('colordiff')

    pipeline.append('less -R')

    cmd = ' | '.join(pipeline)
    subprocess.check_call(cmd, shell=True)

### Database

class MySQL(object):
    def create(self, name):
        subprocess.check_call(['mysqladmin', '-u', 'root', 'create', name])

    def drop(self, name):
        subprocess.check_call(['mysqladmin', '-f', '-u', 'root', 'drop', name])

    def dump(self, name, dump_filename):
        subprocess.check_call(
                'mysqldump -u root %(name)s > %(dump_filename)s' % locals(),
                shell=True)

    def url(self, name):
        return 'mysql://root@localhost/%s' % name

class Postgres(object):
    def create(self, name):
        subprocess.check_call(['createdb', name])

    def drop(self, name):
        subprocess.check_call(['dropdb', name])

    def dump(self, name, dump_filename):
        subprocess.check_call(
                'pg_dump %(name)s > %(dump_filename)s' % locals(),
                shell=True)

    def url(self, name):
        return 'postgres://localhost/%s' % name

def _get_db_driver_class(db_type):
    if db_type == "mysql":
        return MySQL
    elif db_type == "postgres":
        return Postgres
    else:
        raise Exception(_("database %s not supported") % db_type)

### Migrate

MIGRATE_REPO = os.path.join(os.getcwd(), "nova/db/sqlalchemy/migrate_repo")

def migrate(db_driver, db_name, migration_version):
    earliest_version = _migrate_get_earliest_version()

    # NOTE(sirp): sqlalchemy-migrate currently cannot handle the skipping of
    # migration numbers.
    _migrate_cmd(
            db_driver, db_name, 'version_control', str(earliest_version - 1))

    upgrade_cmd = ['upgrade']
    if migration_version != 'latest':
        upgrade_cmd.append(str(migration_version))

    _migrate_cmd(db_driver, db_name, *upgrade_cmd)

def _migrate_cmd(db_driver, db_name, *cmd):
    manage_py = os.path.join(MIGRATE_REPO, 'manage.py')

    args = ['python', manage_py]
    args += cmd
    args += ['--repository=%s' % MIGRATE_REPO,
             '--url=%s' % db_driver.url(db_name)]

    subprocess.check_call(args)

def _migrate_get_earliest_version():
    versions_glob = os.path.join(MIGRATE_REPO, 'versions', '???_*.py')

    versions = []
    for path in glob.iglob(versions_glob):
        filename = os.path.basename(path)
        prefix = filename.split('_', 1)[0]
        try:
            version = int(prefix)
        except ValueError:
            pass
        versions.append(version)

    versions.sort()
    return versions[0]

### Git

def git_current_branch_name():
    ref_name = git_symbolic_ref('HEAD', quiet=True)
    current_branch_name = ref_name.replace('refs/heads/', '')
    return current_branch_name

def git_symbolic_ref(ref, quiet=False):
    args = ['git', 'symbolic-ref', ref]
    if quiet:
        args.append('-q')
    proc = subprocess.Popen(args, stdout=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    return stdout.strip()

def git_checkout(branch_name):
    subprocess.check_call(['git', 'checkout', branch_name])

def git_has_uncommited_changes():
    return subprocess.call(['git', 'diff', '--quiet', '--exit-code']) == 1

### Command

def die(msg):
    print >> sys.stderr, "ERROR: %s" % msg
    sys.exit(1)

def usage(msg=None):
    if msg:
        print >> sys.stderr, "ERROR: %s" % msg

    prog = "schema_diff.py"
    args = ["<mysql|postgres>", "<orig-branch:orig-version>",
            "<new-branch:new-version>"]

    print >> sys.stderr, "usage: %s %s" % (prog, ' '.join(args))
    sys.exit(1)

def parse_options():
    try:
        db_type = sys.argv[1]
    except IndexError:
        usage("must specify DB type")

    try:
        orig_branch, orig_version = sys.argv[2].split(':')
    except IndexError:
        usage('original branch and version required (e.g. master:82)')

    try:
        new_branch, new_version = sys.argv[3].split(':')
    except IndexError:
        usage('new branch and version required (e.g. master:82)')

    return db_type, orig_branch, orig_version, new_branch, new_version

def main():
    timestamp = datetime.datetime.utcnow().strftime("%Y%m%d_%H%M%S")

    ORIG_DB = 'orig_db_%s' % timestamp
    NEW_DB = 'new_db_%s' % timestamp

    ORIG_DUMP = ORIG_DB + ".dump"
    NEW_DUMP = NEW_DB + ".dump"

    options = parse_options()
    db_type, orig_branch, orig_version, new_branch, new_version = options

    # Since we're going to be switching branches, ensure user doesn't have any
    # uncommited changes
    if git_has_uncommited_changes():
        die("You have uncommited changes. Please commit them before running "
            "this command.")

    db_driver = _get_db_driver_class(db_type)()

    users_branch = git_current_branch_name()
    git_checkout(orig_branch)

    try:
        # Dump Original Schema
        dump_db(db_driver, ORIG_DB, orig_version, ORIG_DUMP)

        # Dump New Schema
        git_checkout(new_branch)
        dump_db(db_driver, NEW_DB, new_version, NEW_DUMP)

        diff_files(ORIG_DUMP, NEW_DUMP)
    finally:
        git_checkout(users_branch)

        if os.path.exists(ORIG_DUMP):
            os.unlink(ORIG_DUMP)

        if os.path.exists(NEW_DUMP):
            os.unlink(NEW_DUMP)

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