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

## This file is part of Invenio.
## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 CERN.
##
## 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.
##
## 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 Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

"""
Global organisation of the application's URLs.

This module binds together Invenio's modules and maps them to
their corresponding URLs (ie, /search to the websearch modules,...)
"""

__revision__ = \
    "$Id$"

from invenio.webinterface_handler import create_handler
from invenio.errorlib import register_exception
from invenio.webinterface_handler import WebInterfaceDirectory
from invenio import webinterface_handler_config as apache
from invenio.config import CFG_DEVEL_SITE

class WebInterfaceDumbPages(WebInterfaceDirectory):
    """This class implements a dumb interface to use as a fallback in case of
    errors importing particular module pages."""
    _exports = ['']
    def __call__(self, req, form):
        try:
            from invenio.webpage import page
        except ImportError:
            page = lambda *args: args[1]
        req.status = apache.HTTP_INTERNAL_SERVER_ERROR
        msg = "
This functionality is facing a temporary failure.
"
        msg += "
The administrator has been informed about the problem.
"
        try:
            from invenio.config import CFG_SITE_ADMIN_EMAIL
            msg += """
You can contact %s
                         in case of questions.
""" % \
                      CFG_SITE_ADMIN_EMAIL
        except ImportError:
            pass
        msg += """
We hope to restore the service soon.

Sorry for the inconvenience.
"""
        try:
            return page('Service failure', msg)
        except:
            return msg

    def _lookup(self, component, path):
        return WebInterfaceDumbPages(), path
    index = __call__

try:
    from invenio.websearch_webinterface import WebInterfaceSearchInterfacePages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceSearchInterfacePages = WebInterfaceDumbPages

try:
    from invenio.websearch_webinterface import WebInterfaceAuthorPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceAuthorPages = WebInterfaceDumbPages

try:
    from invenio.websearch_webinterface import WebInterfaceRSSFeedServicePages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceRSSFeedServicePages = WebInterfaceDumbPages

try:
    from invenio.websearch_webinterface import WebInterfaceUnAPIPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceUnAPIPages = WebInterfaceDumbPages

try:
    from invenio.websubmit_webinterface import websubmit_legacy_getfile
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    websubmit_legacy_getfile = WebInterfaceDumbPages

try:
    from invenio.websubmit_webinterface import WebInterfaceSubmitPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceSubmitPages = WebInterfaceDumbPages

try:
    from invenio.websession_webinterface import WebInterfaceYourAccountPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourAccountPages = WebInterfaceDumbPages

try:
    from invenio.websession_webinterface import WebInterfaceYourTicketsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourTicketsPages = WebInterfaceDumbPages

try:
    from invenio.websession_webinterface import WebInterfaceYourGroupsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourGroupsPages = WebInterfaceDumbPages

try:
    from invenio.webalert_webinterface import WebInterfaceYourAlertsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourAlertsPages = WebInterfaceDumbPages

try:
    from invenio.webbasket_webinterface import WebInterfaceYourBasketsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourBasketsPages = WebInterfaceDumbPages

try:
    from invenio.webcomment_webinterface import WebInterfaceCommentsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceCommentsPages = WebInterfaceDumbPages

try:
    from invenio.webmessage_webinterface import WebInterfaceYourMessagesPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourMessagesPages = WebInterfaceDumbPages

try:
    from invenio.errorlib_webinterface import WebInterfaceErrorPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceErrorPages = WebInterfaceDumbPages

try:
    from invenio.oai_repository_webinterface import WebInterfaceOAIProviderPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceOAIProviderPages = WebInterfaceDumbPages

try:
    from invenio.webstat_webinterface import WebInterfaceStatsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceStatsPages = WebInterfaceDumbPages
try:
    from invenio.bibcirculation_webinterface import WebInterfaceYourLoansPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourLoansPages = WebInterfaceDumbPages

try:
    from invenio.webjournal_webinterface import WebInterfaceJournalPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceJournalPages = WebInterfaceDumbPages

try:
    from invenio.webdoc_webinterface import WebInterfaceDocumentationPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceDocumentationPages = WebInterfaceDumbPages

try:
    from invenio.bibexport_method_fieldexporter_webinterface import \
         WebInterfaceFieldExporterPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceFieldExporterPages = WebInterfaceDumbPages

try:
    from invenio.bibknowledge_webinterface import WebInterfaceBibKnowledgePages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceBibKnowledgePages = WebInterfaceDumbPages

try:
    from invenio.batchuploader_webinterface import \
         WebInterfaceBatchUploaderPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceBatchUploaderPages = WebInterfaceDumbPages

try:
    from invenio.bibsword_webinterface import \
         WebInterfaceSword
except:
    register_exception(alert_admin=True, subject='EMERGENCE')
    WebInterfaceSword = WebInterfaceDumbPages

try:
    from invenio.bibauthorid_webinterface import WebInterfaceBibAuthorIDPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceBibAuthorIDPages = WebInterfaceDumbPages

if CFG_DEVEL_SITE:
    try:
        from invenio.httptest_webinterface import WebInterfaceHTTPTestPages
    except:
        register_exception(alert_admin=True, subject='EMERGENCY')
        WebInterfaceHTTPTestPages = WebInterfaceDumbPages
    test_exports = ['httptest']
else:
    test_exports = []

class WebInterfaceInvenio(WebInterfaceSearchInterfacePages):
    """ The global URL layout is composed of the search API plus all
    the other modules."""

    _exports = WebInterfaceSearchInterfacePages._exports + \
        WebInterfaceAuthorPages._exports + [
        'youraccount',
        'youralerts',
        'yourbaskets',
        'yourmessages',
        'yourloans',
        'yourgroups',
        'yourtickets',
        'comments',
        'error',
        'oai2d', ('oai2d.py', 'oai2d'),
        ('getfile.py', 'getfile'),
        'submit',
        'rss',
        'stats',
        'journal',
        'help',
        'unapi',
        'exporter',
        'kb',
        'batchuploader',
        'bibsword',
        'person'
        ] + test_exports

    def __init__(self):
        self.getfile = websubmit_legacy_getfile
        if CFG_DEVEL_SITE:
            self.httptest = WebInterfaceHTTPTestPages()

    author = WebInterfaceAuthorPages()
    submit = WebInterfaceSubmitPages()
    youraccount = WebInterfaceYourAccountPages()
    youralerts = WebInterfaceYourAlertsPages()
    yourbaskets = WebInterfaceYourBasketsPages()
    yourmessages = WebInterfaceYourMessagesPages()
    yourloans = WebInterfaceYourLoansPages()
    yourgroups = WebInterfaceYourGroupsPages()
    yourtickets = WebInterfaceYourTicketsPages()
    comments = WebInterfaceCommentsPages()
    error = WebInterfaceErrorPages()
    oai2d = WebInterfaceOAIProviderPages()
    rss = WebInterfaceRSSFeedServicePages()
    stats = WebInterfaceStatsPages()
    journal = WebInterfaceJournalPages()
    help = WebInterfaceDocumentationPages()
    unapi = WebInterfaceUnAPIPages()
    exporter = WebInterfaceFieldExporterPages()
    kb = WebInterfaceBibKnowledgePages()
    batchuploader = WebInterfaceBatchUploaderPages()
    bibsword = WebInterfaceSword()
    person = WebInterfaceBibAuthorIDPages()

# This creates the 'handler' function, which will be invoked directly
# by mod_python.
invenio_handler = create_handler(WebInterfaceInvenio())
<commit_msg>WebStyle: fix spelling mistake<commit_after># -*- coding: utf-8 -*-

## This file is part of Invenio.
## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 CERN.
##
## 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.
##
## 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 Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

"""
Global organisation of the application's URLs.

This module binds together Invenio's modules and maps them to
their corresponding URLs (ie, /search to the websearch modules,...)
"""

__revision__ = \
    "$Id$"

from invenio.webinterface_handler import create_handler
from invenio.errorlib import register_exception
from invenio.webinterface_handler import WebInterfaceDirectory
from invenio import webinterface_handler_config as apache
from invenio.config import CFG_DEVEL_SITE

class WebInterfaceDumbPages(WebInterfaceDirectory):
    """This class implements a dumb interface to use as a fallback in case of
    errors importing particular module pages."""
    _exports = ['']
    def __call__(self, req, form):
        try:
            from invenio.webpage import page
        except ImportError:
            page = lambda *args: args[1]
        req.status = apache.HTTP_INTERNAL_SERVER_ERROR
        msg = "
This functionality is facing a temporary failure.
"
        msg += "
The administrator has been informed about the problem.
"
        try:
            from invenio.config import CFG_SITE_ADMIN_EMAIL
            msg += """
You can contact %s
                         in case of questions.
""" % \
                      CFG_SITE_ADMIN_EMAIL
        except ImportError:
            pass
        msg += """
We hope to restore the service soon.

Sorry for the inconvenience.
"""
        try:
            return page('Service failure', msg)
        except:
            return msg

    def _lookup(self, component, path):
        return WebInterfaceDumbPages(), path
    index = __call__

try:
    from invenio.websearch_webinterface import WebInterfaceSearchInterfacePages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceSearchInterfacePages = WebInterfaceDumbPages

try:
    from invenio.websearch_webinterface import WebInterfaceAuthorPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceAuthorPages = WebInterfaceDumbPages

try:
    from invenio.websearch_webinterface import WebInterfaceRSSFeedServicePages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceRSSFeedServicePages = WebInterfaceDumbPages

try:
    from invenio.websearch_webinterface import WebInterfaceUnAPIPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceUnAPIPages = WebInterfaceDumbPages

try:
    from invenio.websubmit_webinterface import websubmit_legacy_getfile
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    websubmit_legacy_getfile = WebInterfaceDumbPages

try:
    from invenio.websubmit_webinterface import WebInterfaceSubmitPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceSubmitPages = WebInterfaceDumbPages

try:
    from invenio.websession_webinterface import WebInterfaceYourAccountPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourAccountPages = WebInterfaceDumbPages

try:
    from invenio.websession_webinterface import WebInterfaceYourTicketsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourTicketsPages = WebInterfaceDumbPages

try:
    from invenio.websession_webinterface import WebInterfaceYourGroupsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourGroupsPages = WebInterfaceDumbPages

try:
    from invenio.webalert_webinterface import WebInterfaceYourAlertsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourAlertsPages = WebInterfaceDumbPages

try:
    from invenio.webbasket_webinterface import WebInterfaceYourBasketsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourBasketsPages = WebInterfaceDumbPages

try:
    from invenio.webcomment_webinterface import WebInterfaceCommentsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceCommentsPages = WebInterfaceDumbPages

try:
    from invenio.webmessage_webinterface import WebInterfaceYourMessagesPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourMessagesPages = WebInterfaceDumbPages

try:
    from invenio.errorlib_webinterface import WebInterfaceErrorPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceErrorPages = WebInterfaceDumbPages

try:
    from invenio.oai_repository_webinterface import WebInterfaceOAIProviderPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceOAIProviderPages = WebInterfaceDumbPages

try:
    from invenio.webstat_webinterface import WebInterfaceStatsPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceStatsPages = WebInterfaceDumbPages
try:
    from invenio.bibcirculation_webinterface import WebInterfaceYourLoansPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceYourLoansPages = WebInterfaceDumbPages

try:
    from invenio.webjournal_webinterface import WebInterfaceJournalPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceJournalPages = WebInterfaceDumbPages

try:
    from invenio.webdoc_webinterface import WebInterfaceDocumentationPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceDocumentationPages = WebInterfaceDumbPages

try:
    from invenio.bibexport_method_fieldexporter_webinterface import \
         WebInterfaceFieldExporterPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceFieldExporterPages = WebInterfaceDumbPages

try:
    from invenio.bibknowledge_webinterface import WebInterfaceBibKnowledgePages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceBibKnowledgePages = WebInterfaceDumbPages

try:
    from invenio.batchuploader_webinterface import \
         WebInterfaceBatchUploaderPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceBatchUploaderPages = WebInterfaceDumbPages

try:
    from invenio.bibsword_webinterface import \
         WebInterfaceSword
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceSword = WebInterfaceDumbPages

try:
    from invenio.bibauthorid_webinterface import WebInterfaceBibAuthorIDPages
except:
    register_exception(alert_admin=True, subject='EMERGENCY')
    WebInterfaceBibAuthorIDPages = WebInterfaceDumbPages

if CFG_DEVEL_SITE:
    try:
        from invenio.httptest_webinterface import WebInterfaceHTTPTestPages
    except:
        register_exception(alert_admin=True, subject='EMERGENCY')
        WebInterfaceHTTPTestPages = WebInterfaceDumbPages
    test_exports = ['httptest']
else:
    test_exports = []

class WebInterfaceInvenio(WebInterfaceSearchInterfacePages):
    """ The global URL layout is composed of the search API plus all
    the other modules."""

    _exports = WebInterfaceSearchInterfacePages._exports + \
        WebInterfaceAuthorPages._exports + [
        'youraccount',
        'youralerts',
        'yourbaskets',
        'yourmessages',
        'yourloans',
        'yourgroups',
        'yourtickets',
        'comments',
        'error',
        'oai2d', ('oai2d.py', 'oai2d'),
        ('getfile.py', 'getfile'),
        'submit',
        'rss',
        'stats',
        'journal',
        'help',
        'unapi',
        'exporter',
        'kb',
        'batchuploader',
        'bibsword',
        'person'
        ] + test_exports

    def __init__(self):
        self.getfile = websubmit_legacy_getfile
        if CFG_DEVEL_SITE:
            self.httptest = WebInterfaceHTTPTestPages()

    author = WebInterfaceAuthorPages()
    submit = WebInterfaceSubmitPages()
    youraccount = WebInterfaceYourAccountPages()
    youralerts = WebInterfaceYourAlertsPages()
    yourbaskets = WebInterfaceYourBasketsPages()
    yourmessages = WebInterfaceYourMessagesPages()
    yourloans = WebInterfaceYourLoansPages()
    yourgroups = WebInterfaceYourGroupsPages()
    yourtickets = WebInterfaceYourTicketsPages()
    comments = WebInterfaceCommentsPages()
    error = WebInterfaceErrorPages()
    oai2d = WebInterfaceOAIProviderPages()
    rss = WebInterfaceRSSFeedServicePages()
    stats = WebInterfaceStatsPages()
    journal = WebInterfaceJournalPages()
    help = WebInterfaceDocumentationPages()
    unapi = WebInterfaceUnAPIPages()
    exporter = WebInterfaceFieldExporterPages()
    kb = WebInterfaceBibKnowledgePages()
    batchuploader = WebInterfaceBatchUploaderPages()
    bibsword = WebInterfaceSword()
    person = WebInterfaceBibAuthorIDPages()

# This creates the 'handler' function, which will be invoked directly
# by mod_python.
invenio_handler = create_handler(WebInterfaceInvenio())
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import logging
from argparse import ArgumentParser

from .worker import ManagerWorker
from . import __version__

logger = logging.getLogger("pyqs")

def main():
    parser = ArgumentParser(description="""
Run PyQS workers for the given queues
""")
    parser.add_argument(
        "-c",
        "--concurrency",
        type=int,
        dest="concurrency",
        default=1,
        help='Worker concurrency',
        action="store",
    )

    parser.add_argument(
        "queues",
        metavar="QUEUE_NAME",
        nargs="+",
        type=str,
        help='Queues to process',
        action="store",
    )

    parser.add_argument(
        "--loglevel",
        "--log_level",
        "--log-level",
        dest="logging_level",
        type=str,
        default="WARN",
        help='Set logging level. This must be one of the python default logging levels',
        action="store",
    )

    parser.add_argument(
        "--access-key-id",
        dest="access_key_id",
        type=str,
        default=None,
        help='AWS_ACCESS_KEY_ID used by Boto',
        action="store",
    )

    parser.add_argument(
        "--secret-access-key",
        dest="secret_access_key",
        type=str,
        default=None,
        help='AWS_SECRET_ACCESS_KEY used by Boto',
        action="store",
    )

    parser.add_argument(
        "--region",
        dest="region",
        type=str,
        default="us-east-1",
        help='AWS Region to connect to SQS',
        action="store",
    )

    parser.add_argument(
        "--interval",
        dest="interval",
        type=float,
        default=0.0,
        help='Time waited by a worker after processesing a message.',
        action="store",
    )

    parser.add_argument(
        "--batchsize",
        dest="batchsize",
        type=int,
        default=10,
        help='How many messages to download at a time from SQS.',
        action="store",
    )

    parser.add_argument(
        "--prefetch-multiplier",
        dest="prefetch_multiplier",
        type=int,
        default=2,
        help='Multiplier on the size of the internal queue for prefetching SQS messages.',
        action="store",
    )

    args = parser.parse_args()

    _main(
        queue_prefixes=args.queues,
        concurrency=args.concurrency,
        logging_level=args.logging_level,
        region=args.region,
        access_key_id=args.access_key_id,
        secret_access_key=args.secret_access_key,
        interval=args.interval,
        batchsize=args.batchsize,
        prefetch_multiplier=args.prefetch_multiplier
    )

def _main(queue_prefixes, concurrency=5, logging_level="WARN", region='us-east-1', access_key_id=None, secret_access_key=None, interval=1, batchsize=10, prefetch_multiplier=2):
    logging.basicConfig(format="[%(levelname)s]: %(message)s", level=getattr(logging, logging_level))
    logger.info("Starting PyQS version {}".format(__version__))
    manager = ManagerWorker(queue_prefixes, concurrency, interval, batchsize, prefetch_multiplier=prefetch_multiplier, region=region, access_key_id=access_key_id, secret_access_key=secret_access_key)
    manager.start()
    manager.sleep()
<commit_msg>Add current directory to PYTHONPATH<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import logging
import os
import sys
from argparse import ArgumentParser

from .worker import ManagerWorker
from . import __version__

logger = logging.getLogger("pyqs")

def main():
    parser = ArgumentParser(description="""
Run PyQS workers for the given queues
""")
    parser.add_argument(
        "-c",
        "--concurrency",
        type=int,
        dest="concurrency",
        default=1,
        help='Worker concurrency',
        action="store",
    )

    parser.add_argument(
        "queues",
        metavar="QUEUE_NAME",
        nargs="+",
        type=str,
        help='Queues to process',
        action="store",
    )

    parser.add_argument(
        "--loglevel",
        "--log_level",
        "--log-level",
        dest="logging_level",
        type=str,
        default="WARN",
        help='Set logging level. This must be one of the python default logging levels',
        action="store",
    )

    parser.add_argument(
        "--access-key-id",
        dest="access_key_id",
        type=str,
        default=None,
        help='AWS_ACCESS_KEY_ID used by Boto',
        action="store",
    )

    parser.add_argument(
        "--secret-access-key",
        dest="secret_access_key",
        type=str,
        default=None,
        help='AWS_SECRET_ACCESS_KEY used by Boto',
        action="store",
    )

    parser.add_argument(
        "--region",
        dest="region",
        type=str,
        default="us-east-1",
        help='AWS Region to connect to SQS',
        action="store",
    )

    parser.add_argument(
        "--interval",
        dest="interval",
        type=float,
        default=0.0,
        help='Time waited by a worker after processesing a message.',
        action="store",
    )

    parser.add_argument(
        "--batchsize",
        dest="batchsize",
        type=int,
        default=10,
        help='How many messages to download at a time from SQS.',
        action="store",
    )

    parser.add_argument(
        "--prefetch-multiplier",
        dest="prefetch_multiplier",
        type=int,
        default=2,
        help='Multiplier on the size of the internal queue for prefetching SQS messages.',
        action="store",
    )

    args = parser.parse_args()

    _main(
        queue_prefixes=args.queues,
        concurrency=args.concurrency,
        logging_level=args.logging_level,
        region=args.region,
        access_key_id=args.access_key_id,
        secret_access_key=args.secret_access_key,
        interval=args.interval,
        batchsize=args.batchsize,
        prefetch_multiplier=args.prefetch_multiplier
    )

def _add_cwd_to_path():
    cwd = os.getcwd()
    if cwd not in sys.path:
        sys.path.insert(0, cwd)

def _main(queue_prefixes, concurrency=5, logging_level="WARN", region='us-east-1', access_key_id=None, secret_access_key=None, interval=1, batchsize=10, prefetch_multiplier=2):
    logging.basicConfig(format="[%(levelname)s]: %(message)s", level=getattr(logging, logging_level))
    logger.info("Starting PyQS version {}".format(__version__))
    _add_cwd_to_path()
    manager = ManagerWorker(queue_prefixes, concurrency, interval, batchsize, prefetch_multiplier=prefetch_multiplier, region=region, access_key_id=access_key_id, secret_access_key=secret_access_key)
    manager.start()
    manager.sleep()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Copyright 2017 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)

{'name': 'Connector Tests',
 'summary': 'Automated tests for Connector, do not install.',
 'description': 'Automated tests for Connector, do not install.',
 'version': '10.0.1.0.0',
 'author': 'Camptocamp,Odoo Community Association (OCA)',
 'license': 'AGPL-3',
 'category': 'Hidden',
 'depends': ['connector',
             ],
 'website': 'https://www.camptocamp.com',
 'data': ['security/ir.model.access.csv',
          ],
 'installable': False,
 }
<commit_msg>Make addons installable<commit_after># -*- coding: utf-8 -*-
# Copyright 2017 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)

{'name': 'Connector Tests',
 'summary': 'Automated tests for Connector, do not install.',
 'description': 'Automated tests for Connector, do not install.',
 'version': '11.0.1.0.0',
 'author': 'Camptocamp,Odoo Community Association (OCA)',
 'license': 'AGPL-3',
 'category': 'Hidden',
 'depends': ['connector',
             ],
 'website': 'https://www.camptocamp.com',
 'data': ['security/ir.model.access.csv',
          ],
 'installable': True,
 }
<|endoftext|>


<commit_before>"""Package is for python packages with only code and data.

*Please do not use this.*
*This is just an experiment so far.*

Often you have only a couple of python files, and you want to share them.

* Gather facts.
* Ask about required details.
    * Tell user to set up things (eg .pypirc, .gitconfig)
* Write out template.
* build build dist
* push

"""

import io
import os
import re
import ast
import imp
import tempfile

from configparser import ConfigParser
from email.utils import getaddresses
import subprocess
from fnmatch import fnmatchcase, fnmatch
from shutil import copyfile

class PyPiRc:
    """
    ~/.pypirc
    [simple_setup]
    author = My Name Is
    author_email = myemail@example.com

    """
    def __init__(self):
        parser = ConfigParser()
        parser.read(os.path.expanduser('~/.pypirc'))
        self.author = parser.get('simple_setup', 'author', fallback=None)
        self.author_email = parser.get('simple_setup', 'author_email', fallback=None)

class GitConfig:
    """
    ~/.gitconfig

    [user]
            name = My Name Is
            email = myemail@example.com

    """
    def __init__(self):
        parser = ConfigParser()
        parser.read(os.path.expanduser('~/.gitconfig'))
        self.author = parser.get('user', 'name', fallback=None)
        self.author_email = parser.get('user', 'email', fallback=None)

class HgRc:
    """
    ~/.hgrc
    [ui]
    username = My Name Is <myemail@example.com>
    """
    def __init__(self):
        parser = ConfigParser()
        parser.read(os.path.expanduser('~/.hgrc'))
        username = parser.get('ui', 'username', fallback=None)
        name_email = getaddresses([username])
        self.author = None
        self.author_email = None
        if name_email:
            self.author = name_email[0][0]
            self.author_email = name_email[0][1]

class DotGitConfig:
    """Grab info out of a .git/config file.

    [remote "origin"]
        url = git@github.com:pygame/solarwolf.git

    """
    def __init__(self):
        """
        """

def read(*parts):
    """Reads in file from *parts.
    """
    try:
        return io.open(os.path.join(*parts), 'r', encoding='utf-8').read()
    except IOError:
        return ''

def version_from_file(fname):
    """
    """
    version_file = read(fname)
    version_match = re.search(r'^__version__ = [\'"]([^\'"]*)[\'"]',
                              version_file, re.MULTILINE)
    if version_match:
        return version_match.group(1)

def version_from_git():
    """Gets the current version from git tags.
    """
    try:
        versions = subprocess.check_output('git tag --sort version:refname'.split())
    except subprocess.CalledProcessError:
        return
    lines = versions.splitlines()
    if lines:
        return lines[-1].decode('utf-8')

# find('*.py', 'some/path/')
# def find(pattern, path):
#     result = []
#     for root, _, files in os.walk(path):
#         for name in files:
#             if fnmatch(name, pattern):
#                 result.append(os.path.join(root, name))
#     return result

def package_py(what_to_package):
    """Is there a .py file for this repo or a __init__.py ?

    package_py('.')
    package_py('mypackage.py')
    package_py('/Users/bla/packagefolder/')

    This detects single file packages, and packages with __init__.py in them.
    """
    if what_to_package.endswith('.py'):
        return what_to_package

    if os.path.isdir(what_to_package) or what_to_package == '.':
        # lets see if there is a __init__.py in there.
        apath = os.path.join(what_to_package, '__init__.py')
        if os.path.exists(apath):
            return apath

        # maybe there is a file with the same name as the folder?
        folder_name = os.path.split(os.path.abspath(what_to_package))[-1]
        apath = os.path.join(what_to_package, folder_name + '.py')
        if os.path.exists(apath):
            return apath

        apath = os.path.join(what_to_package, folder_name, '__init__.py')
        if os.path.exists(apath):
            return apath

def dependencies_ast(apy):
    """Try to find 3rd party dependencies in the past in .py file.

    Returns a list of package names.
    """
    module = ast.parse(open(apy).read())
    deps = []
    for node in module.body:
        if type(node) is ast.Import:
            for name in node.names:
                parts = imp.find_module(name.name.split('.')[0])
                if 'site-package' in parts[1]:
                    deps.append(name.name.split('.')[0])
        if type(node) is ast.ImportFrom:

            parts = imp.find_module(node.module.split('.')[0])
            if 'site-package' in parts[1]:
                deps.append(node.module.split('.')[0])

    return deps

class ModuleDocs:
    """For getting the description and long_description out of the module docstring
    """
    def __init__(self, what_to_package):
        data = read(package_py(what_to_package))
        lines = ast.parse(data).body[0].value.s.splitlines()
        self.description = lines[0]
        self.long_description = '\n'.join(lines)

class GatherInfo:

    def __init__(self, what_to_package):
        """
        :param folder_to_package: this is the folder or file we want to package.
                                  It could be
        """
        self.what_to_package = what_to_package
        self.pypirc = PyPiRc()
        self.gitconfig = GitConfig()
        self.hgrc = HgRc()
        self.module_docs = ModuleDocs(what_to_package)

    @property
    def author(self):
        if self.pypirc.author is not None:
            return self.pypirc.author
        if self.gitconfig.author is not None:
            return self.gitconfig.author

    @property
    def author_email(self):
        if self.pypirc.author_email is not None:
            return self.pypirc.author_email
        if self.gitconfig.author_email is not None:
            return self.gitconfig.author_email

    @property
    def name(self):
        """ We can get this by looking at what is there.

        Is there a single python file? 'leftpad.py' -> 'leftpad'
        Is there a single folder of python files? 'leftpad/' -> 'leftpad'
        If it is '.' then we use the folder name -> 'leftpad'
        """
        if self.what_to_package.endswith('.py'):
            return self.what_to_package.rstrip('.py')

        if os.path.isdir(self.what_to_package):
            return os.path.split(os.path.abspath(self.what_to_package))[-1]

    @property
    def description(self):
        return self.module_docs.description

    @property
    def long_description(self):
        return self.module_docs.long_description

    @property
    def version(self):
        afile = package_py(self.what_to_package)
        print(afile)
        ver = version_from_file(afile)
        if ver is None:
            ver = version_from_git()
        if ver is None:
            ver = '0.0.0'
        return ver

    @property
    def url(self):
        # from .git/config
        if os.path.isdir(self.what_to_package):
            package_name = os.path.split(os.path.abspath(self.what_to_package))[-1]
            return 'https://pypi.python.org/pypi/%s' % package_name

    @property
    def install_requires(self):
        if self.what_to_package.endswith('.py'):
            return dependencies_ast(self.what_to_package)
        else:
            return []

    def is_data_files(self):
        return False

    @property
    def is_script(self):
        """Is the package a script? Does it have a module.main() ?
        """
        return 'def main' in read(package_py(self.what_to_package))

    @property
    def is_single_file(self):
        return package_py(self.what_to_package)

    def __str__(self):
        """
        """
        output = """
name="{name}"
description = {description}
long_description = {long_description}
author_email="{author_email}"
author="{author}"
version="{version}"
url="{url}"
is_script={is_script}
"""
        return output.format(name=self.name,
                             description=repr(self.description),
                             long_description=repr(self.long_description),
                             author_email=self.author_email,
                             author=self.author,
                             version=self.version,
                             url=self.url,
                             is_script=self.is_script)

SETUP_PY = """
from setuptools import setup, find_packages
setup(
    name='{name}',
    version='{version}',
    description={description},
    long_description={long_description},
    url='{url}',
    author='{author}',
    author_email='{author_email}',
    license='{license}',
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Intended Audience :: Developers',
        'Topic :: Software Development :: Build Tools',
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
    ],

    {packages}
    {py_modules}
    {install_requires}
    {console_scripts}
)
"""

MANIFEST_IN = """

# Include the license file
# include LICENSE.txt

# Include the data files
{include_data_files}
"""

class FillFiles:
    """ This fills setup files in with what they need.
    """

    def __init__(self, package_info):
        self.package_info = package_info
        self.tmpdir = tempfile.mkdtemp()
        print (self.tmpdir)
        # repo = 'https://github.com/pypa/sampleproject/'
        # subprocess.check_output = 'git clone %s %s' % (repo, self.tmpdir)

        setup_py_data = self.setup_py()
        manifest_in_data = self.manifest_in()

        with open(os.path.join(self.tmpdir, 'setup.py'), 'w') as afile:
            afile.write(setup_py_data)
        with open(os.path.join(self.tmpdir, 'MANIFEST.in'), 'w') as afile:
            afile.write(manifest_in_data)

        self.copy_files()

    def copy_files(self):
        """Copies our package files into the new output folder.
        """
        if self.package_info.is_single_file:
            pyfname = package_py(self.package_info.what_to_package)
            dstpath = os.path.join(self.tmpdir, pyfname)
            copyfile(pyfname, dstpath)
        else:
            raise NotImplementedError('only single files supported')

    def manifest_in(self):
        """Fill in a MANIFEST.in
        """
        include_data_files = 'recursive-include data *' if self.package_info.is_data_files else ''
        return MANIFEST_IN.format(include_data_files=include_data_files)

    def setup_py(self):
        """Fill in a setup.py string.
        """

        if self.package_info.is_script:
            console_scripts = """
            entry_points={
                'console_scripts': [
                    '%s=%s:main',
                ],
            },
            """ % (self.package_info.name, self.package_info.name)
        else:
            console_scripts = ''

        if self.package_info.is_single_file:
            py_modules = "py_modules=['%s']," % self.package_info.name
            packages = ''
        else:
            raise NotImplementedError('only single files supported')
            py_modules = ''
            packages = "packages=find_packages(exclude=['contrib', 'docs', 'tests']),"

        install_requires = "install_requires=%s," % repr(self.package_info.install_requires)

        return SETUP_PY.format(name=self.package_info.name,
                               description=repr(self.package_info.description),
                               long_description=repr(self.package_info.long_description),
                               author_email=self.package_info.author_email,
                               author=self.package_info.author,
                               version=self.package_info.version,
                               url=self.package_info.url,
                               console_scripts=console_scripts,
                               install_requires=install_requires,
                               license='MIT',
                               packages=packages,
                               py_modules=py_modules)

class UploadPyPi:
    """
    """
    # twine upload dist/*.tar.gz
    def build(self):
        # python setup.py build sdist bdist_wheel
        pass
    def upload(self):
        pass
        # python setup.py upload

def main():
    """
    """
    package_info = GatherInfo('.')
    filled_files = FillFiles(package_info)

if __name__ == '__main__':
    main()
    # print(GatherInfo('.'))
<commit_msg>Fix build path issue.<commit_after>"""Package is for python packages with only code and data.

*Please do not use this.*
*This is just an experiment so far.*

Often you have only a couple of python files, and you want to share them.

* Gather facts.
* Ask about required details.
    * Tell user to set up things (eg .pypirc, .gitconfig)
* Write out template.
* build build dist
* push

"""
from __future__ import print_function
import io
import os
import re
import ast
import imp
import tempfile
import yaml

# try:
#     from ConfigParser import ConfigParser
# except ImportError:
#     from configparser import ConfigParser

from configparser import ConfigParser

from email.utils import getaddresses
import subprocess
from fnmatch import fnmatchcase, fnmatch
from shutil import copyfile

SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))

class PyPiRc:
    """
    ~/.pypirc
    [simple_setup]
    author = My Name Is
    author_email = myemail@example.com

    """
    def __init__(self):
        parser = ConfigParser()
        parser.read(os.path.expanduser('~/.pypirc'))
        self.author = parser.get('simple_setup', 'author', fallback=None)
        self.author_email = parser.get('simple_setup', 'author_email', fallback=None)

class GitConfig:
    """
    ~/.gitconfig

    [user]
            name = My Name Is
            email = myemail@example.com

    """
    def __init__(self):
        parser = ConfigParser()
        parser.read(os.path.expanduser('~/.gitconfig'))
        self.author = parser.get('user', 'name', fallback=None)
        self.author_email = parser.get('user', 'email', fallback=None)

class HgRc:
    """
    ~/.hgrc
    [ui]
    username = My Name Is <myemail@example.com>
    """
    def __init__(self):
        parser = ConfigParser()
        parser.read(os.path.expanduser('~/.hgrc'))
        username = parser.get('ui', 'username', fallback=None)
        try:
            name_email = getaddresses([username])
        except TypeError:
            name_email = None
        self.author = None
        self.author_email = None
        if name_email:
            self.author = name_email[0][0]
            self.author_email = name_email[0][1]

class DotGitConfig:
    """Grab info out of a .git/config file.

    [remote "origin"]
        url = git@github.com:pygame/solarwolf.git

    """
    def __init__(self):
        """
        """

def read(*parts):
    """Reads in file from *parts.
    """
    try:
        return io.open(os.path.join(*parts), 'r', encoding='utf-8').read()
    except IOError:
        return ''

def version_from_file(fname):
    """
    """
    version_file = read(fname)
    version_match = re.search(r'^__version__ = [\'"]([^\'"]*)[\'"]',
                              version_file, re.MULTILINE)
    if version_match:
        return version_match.group(1)

def version_from_git():
    """Gets the current version from git tags.
    """
    try:
        versions = subprocess.check_output('git tag --sort version:refname'.split())
    except subprocess.CalledProcessError:
        return
    lines = versions.splitlines()
    if lines:
        return lines[-1].decode('utf-8')

# find('*.py', 'some/path/')
# def find(pattern, path):
#     result = []
#     for root, _, files in os.walk(path):
#         for name in files:
#             if fnmatch(name, pattern):
#                 result.append(os.path.join(root, name))
#     return result

def package_py(what_to_package):
    """Is there a .py file for this repo or a __init__.py ?

    package_py('.')
    package_py('mypackage.py')
    package_py('/Users/bla/packagefolder/')

    This detects single file packages, and packages with __init__.py in them.
    """
    if what_to_package.endswith('.py'):
        return what_to_package

    if os.path.isdir(what_to_package) or what_to_package == '.':
        # lets see if there is a __init__.py in there.
        apath = os.path.join(what_to_package, '__init__.py')
        if os.path.exists(apath):
            return apath

        # maybe there is a file with the same name as the folder?
        folder_name = os.path.split(os.path.abspath(what_to_package))[-1]
        apath = os.path.join(what_to_package, folder_name + '.py')
        if os.path.exists(apath):
            return apath

        apath = os.path.join(what_to_package, folder_name, '__init__.py')
        if os.path.exists(apath):
            return apath

def dependencies_ast(apy):
    """Try to find 3rd party dependencies in the past in .py file.

    Returns a list of package names.
    """
    module = ast.parse(open(apy).read())
    deps = []
    for node in module.body:
        if type(node) is ast.Import:
            for name in node.names:
                parts = imp.find_module(name.name.split('.')[0])
                if 'site-package' in parts[1]:
                    deps.append(name.name.split('.')[0])
        if type(node) is ast.ImportFrom:

            parts = imp.find_module(node.module.split('.')[0])
            if 'site-package' in parts[1]:
                deps.append(node.module.split('.')[0])

    return deps

class ModuleDocs:
    """For getting the description and long_description out of the module docstring
    """
    def __init__(self, what_to_package):
        data = read(package_py(what_to_package))
        lines = ast.parse(data).body[0].value.s.splitlines()
        self.description = lines[0]
        self.long_description = '\n'.join(lines)

class GatherInfo:

    def __init__(self, what_to_package):
        """
        :param folder_to_package: this is the folder or file we want to package.
                                  It could be
        """
        self.what_to_package = what_to_package
        self.pypirc = PyPiRc()
        self.gitconfig = GitConfig()
        self.hgrc = HgRc()
        self.module_docs = ModuleDocs(what_to_package)

    @property
    def author(self):
        if self.pypirc.author is not None:
            return self.pypirc.author
        if self.gitconfig.author is not None:
            return self.gitconfig.author

    @property
    def author_email(self):
        if self.pypirc.author_email is not None:
            return self.pypirc.author_email
        if self.gitconfig.author_email is not None:
            return self.gitconfig.author_email

    @property
    def name(self):
        """ We can get this by looking at what is there.

        Is there a single python file? 'leftpad.py' -> 'leftpad'
        Is there a single folder of python files? 'leftpad/' -> 'leftpad'
        If it is '.' then we use the folder name -> 'leftpad'
        """
        if self.what_to_package.endswith('.py'):
            return self.what_to_package.rstrip('.py')

        if os.path.isdir(self.what_to_package):
            return os.path.split(os.path.abspath(self.what_to_package))[-1]

    @property
    def description(self):
        return self.module_docs.description

    @property
    def long_description(self):
        return self.module_docs.long_description

    @property
    def version(self):
        afile = package_py(self.what_to_package)
        print(afile)
        ver = version_from_file(afile)
        if ver is None:
            ver = version_from_git()
        if ver is None:
            ver = '0.0.0'
        return ver

    @property
    def url(self):
        # from .git/config
        if os.path.isdir(self.what_to_package):
            package_name = os.path.split(os.path.abspath(self.what_to_package))[-1]
            return 'https://pypi.python.org/pypi/%s' % package_name

    @property
    def install_requires(self):
        if self.what_to_package.endswith('.py'):
            return dependencies_ast(self.what_to_package)
        else:
            return []

    def is_data_files(self):
        return False

    @property
    def is_script(self):
        """Is the package a script? Does it have a module.main() ?
        """
        return 'def main' in read(package_py(self.what_to_package))

    @property
    def is_single_file(self):
        return package_py(self.what_to_package)

    def __str__(self):
        """
        """
        output = """
name="{name}"
description = {description}
long_description = {long_description}
author_email="{author_email}"
author="{author}"
version="{version}"
url="{url}"
is_script={is_script}
"""
        return output.format(name=self.name,
                             description=repr(self.description),
                             long_description=repr(self.long_description),
                             author_email=self.author_email,
                             author=self.author,
                             version=self.version,
                             url=self.url,
                             is_script=self.is_script)

SETUP_PY = """
from setuptools import setup, find_packages
setup(
    name='{name}',
    version='{version}',
    description={description},
    long_description={long_description},
    url='{url}',
    author='{author}',
    author_email='{author_email}',
    license='{license}',
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Intended Audience :: Developers',
        'Topic :: Software Development :: Build Tools',
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
    ],

    {packages}
    {py_modules}
    {install_requires}
    {console_scripts}
)
"""

MANIFEST_IN = """

# Include the license file
# include LICENSE.txt

# Include the data files
{include_data_files}
"""

class FillFiles:
    """ This fills setup files in with what they need.
    """

    def __init__(self, package_info):
        self.package_info = package_info
        self.tmpdir = tempfile.mkdtemp()
        print(self.tmpdir)
        # repo = 'https://github.com/pypa/sampleproject/'
        # subprocess.check_output = 'git clone %s %s' % (repo, self.tmpdir)

    def fill_files(self):
        setup_py_data = self.setup_py()
        manifest_in_data = self.manifest_in()

        with open(os.path.join(self.tmpdir, 'setup.py'), 'w') as afile:
            afile.write(setup_py_data)
        with open(os.path.join(self.tmpdir, 'MANIFEST.in'), 'w') as afile:
            afile.write(manifest_in_data)
        self.copy_files()

    def copy_files(self):
        """Copies our package files into the new output folder.
        """
        if self.package_info.is_single_file:
            pyfname = package_py(self.package_info.what_to_package)
            dstpath = os.path.join(self.tmpdir, pyfname)
            copyfile(pyfname, dstpath)
        else:
            raise NotImplementedError('only single files supported')

    def manifest_in(self):
        """Fill in a MANIFEST.in
        """
        include_data_files = 'recursive-include data *' if self.package_info.is_data_files else ''
        return MANIFEST_IN.format(include_data_files=include_data_files)

    def setup_py(self):
        """Fill in a setup.py string.
        """

        if self.package_info.is_script:
            console_scripts = """
            entry_points={
                'console_scripts': [
                    '%s=%s:main',
                ],
            },
            """ % (self.package_info.name, self.package_info.name)
        else:
            console_scripts = ''

        if self.package_info.is_single_file:
            py_modules = "py_modules=['%s']," % self.package_info.name
            packages = ''
        else:
            raise NotImplementedError('only single files supported')
            py_modules = ''
            packages = "packages=find_packages(exclude=['contrib', 'docs', 'tests']),"

        install_requires = "install_requires=%s," % repr(self.package_info.install_requires)

        return SETUP_PY.format(name=self.package_info.name,
                               description=repr(self.package_info.description),
                               long_description=repr(self.package_info.long_description),
                               author_email=self.package_info.author_email,
                               author=self.package_info.author,
                               version=self.package_info.version,
                               url=self.package_info.url,
                               console_scripts=console_scripts,
                               install_requires=install_requires,
                               license='MIT',
                               packages=packages,
                               py_modules=py_modules)

def fill_files(package_info):
    filler = FillFiles(package_info)
    filler.fill_files()
    return filler.tmpdir

class UploadPyPi:
    """Builds pypackage project and uploads to PyPi.

    Commands for build are intended to be stored in a config file
    to allow for easy customization. Config format is `yaml`. If
    no config is found the default commands should be used.
    Errors during build will set the self.errors switch to True
    indicating there was an error.
    """

    command_file = os.path.join(SCRIPT_PATH, "pybuilder.yml")
    default_commands = {
        "builds": [
            "python setup.py sdist",
            "python setup.py bdist_wheel --universal"
        ]
    }

    def __init__(self):
        self.errors = None
        self.config = self._read_command_config()

    def build(self):
        """Build out project distros.

        Build commands are pulled from config file to
        allow for easy customization.
        """
        for cmd in self.config["builds"]:
            try:
                subprocess.call(cmd, shell=True)
            except Exception as e:
                print("Error processing", str(cmd))
                print(e)
                self.errors = True
                return
            else:
                self.errors = False

    def upload(self):
        """Uploads package to PyPi using twine.
        The advantage to using Twine is your package is uploaded

        over HTTPS which prevents your private info from appearing
        in the request header.
        """
        response = subprocess.call("twine upload dist/*", shell=True)
        if response == 127:
            print("Twine not installed.. Cancelled.")
            self.errors = True

    def _read_command_config(self):
        """Get yaml config file with build commands.

        If no config file is found the defaults are used
        """
        if not os.path.isfile(self.command_file):
            return self.default_commands
        with open(self.command_file, 'r') as f:
            return yaml.load(f.read())

    @property
    def success(self):
        """Get build and deploy status.

        If self.errors is None, then no builds have been
        attempted yet. Otherwise returns False if an error
        was detected, True if build was a success.
        """
        if self.errors is None:
            return False
        return not self.errors

def build_and_upload_to_pypi(path):
    """Helper function for `UploadPyPi` class.

    Raises BuildError Exception if errors occur during build.
    Raises DeployError Exception if error occurs during upload

    TODO: Need better twine update status.

    """
    class BuildError(Exception):
        pass

    class DeployError(Exception):
        pass

    builder = UploadPyPi()
    os.chdir(path)
    builder.build()
    if not builder.success:
        raise BuildError("Error while building package.")
    builder.upload()
    if not builder.success:
        raise DeployError("Error deploying package to PyPi")

def main():
    """Main entry point for pyrelease.

    Gathers info for package, fills out necessary files, builds,
    then uploads to PyPi
    """
    package_info = GatherInfo('.')
    temp_dir = fill_files(package_info)
    build_and_upload_to_pypi(temp_dir)

if __name__ == '__main__':
    main()
    # print(GatherInfo('.'))
<|endoftext|>


<commit_before>#!/usr/bin/python

import time
import requests
import json
import sys
#import logging
import os
#import traceback
import argparse
import datetime
import weather_conditions as wc

#script_path = os.getcwd()
#log_path = script_path + "/circleci.log"
#print "logging to " + log_path

#logging.basicConfig(filename=log_path, level=logging.INFO, format='%(asctime)s %(message)s')
#logging.info("Circleci7.py started")

global verbose_mode, api_key, zip_code, timezone_offset, min_api_delay
verbose_mode = None
api_key = None
zip_code = None
timezone_offset = None
min_api_delay = 2

def begin(api_key_, zip_code_, timezone_offset_):
    global api_key, zip_code, timezone_offset
    api_key = api_key_
    zip_code = zip_code_
    timezone_offset = timezone_offset_

def get_daily_url():
    return "http://api.openweathermap.org/data/2.5/weather?zip=%s&APPID=%s&units=imperial" % (zip_code, api_key)

def get_forecast_url():
    return "http://api.openweathermap.org/data/2.5/forecast?zip=%s&APPID=%s&units=imperial" % (zip_code, api_key)

def retrieve_data(url):
    request = requests.get(url)
    request = request.text.encode('utf-8')
    json_data = json.loads(request)
    #report_verbose("api delay...")
    time.sleep(min_api_delay)
    return json_data

def daily_main(data):
    return data["main"]

def daily_sys(data):
    return data["sys"]

def daily_wind(data):
    return data["wind"]

def daily_timestamp(data):
    return data["dt"]

def daily_visibility(data):
    try:
        return data["visibility"]
    except:
        return 5280 * 10

def daily_weather(data):
    return data["weather"][0]

def daily_sunrise(data):
    return daily_sys(data)["sunrise"]

def daily_sunset(data):
    return daily_sys(data)["sunset"]

def daily_wind_speed(data):
    return daily_wind(data)["speed"]

def daily_wind_deg(data):
    return daily_wind(data)["deg"]

def daily_pressure(data):
    return daily_main(data)["pressure"]

def daily_humidity(data):
    return daily_main(data)["humidity"]

def daily_temp_min(data):
    return daily_main(data)["temp_min"]

def daily_temp_max(data):
    return daily_main(data)["temp_max"]

def daily_temp(data):
    return daily_main(data)["temp"]

def daily_city(data):
    return data["name"]

def daily_coord(data):
    return data["coord"]

def daily_lat(data):
    return daily_coord(data)["lat"]

def daily_lon(data):
    return daily_coord(data)["lon"]

def daily_description(data):
    return daily_weather(data)["description"]

def daily_conditions(data):
    return daily_weather(data)["main"]

def daily_id(data):
    return daily_weather(data)["id"]

def timezone_timestamp(ts):
    return int(ts) - (timezone_offset * 60 * 60)

def get_datetime(ts):
    ts = timezone_timestamp(ts)
    return datetime.datetime.fromtimestamp(ts)

def format_unix_timestamp(ts):
    return format_datetime(get_datetime(ts))

def format_datetime(dt):
    return dt.strftime('%A %Y-%m-%d %I:%M:%S %p')

def weather_entry(key, value):
    return tc.green(key) + ": " + tc.cyan(str(value))

def current_time():
    dt = datetime.datetime.now()
    return int(time.mktime(dt.timetuple()))

def current_weekday():
    dt = get_datetime(current_time())
    return dt.weekday()

def get_daily_data():
    url = get_daily_url()
    #report_verbose("requesting: %s" % url)
    data = retrieve_data(url)
    #report_verbose("received data:")
    #if verbose_mode:
    #    report_json(data)
    return data

def get_forecast_data():
    url = get_forecast_url()
    #report_verbose("requesting: %s" % url)
    data = retrieve_data(url)
    #report_verbose("received data:")
    #if verbose_mode:
    #    report_json(data)
    return data

def forecast_list(data):
    return data["list"]

def forecast_count(data):
    return len(forecast_list(data))

def forecast_entry(data, entry):
    return forecast_list(data)[int(entry)]

def forecast_timestamp(data, entry):
    return forecast_entry(data, entry)["dt"]

def forecast_main(data, entry):
    return forecast_entry(data, entry)["main"]

def forecast_wind(data, entry):
    return forecast_entry(data, entry)["wind"]

def forecast_clouds(data, entry):
    return forecast_entry(data, entry)["clouds"]

def forecast_weather(data, entry):
    return forecast_entry(data, entry)["weather"][0]

def forecast_pressure(data, entry):
    return forecast_main(data, entry)["pressure"]

def forecast_temp(data, entry):
    return forecast_main(data, entry)["temp"]

def forecast_temp_min(data, entry):
    return forecast_main(data, entry)["temp_min"]

def forecast_temp_max(data, entry):
    return forecast_main(data, entry)["temp_max"]

def forecast_humidity(data, entry):
    return forecast_main(data, entry)["humidity"]

def forecast_wind_speed(data, entry):
    return forecast_wind(data, entry)["speed"]

def forecast_wind_direction(data, entry):
    return forecast_wind(data, entry)["deg"]

def forecast_cloudiness(data, entry):
    return forecast_clouds(data, entry)["all"]

def forecast_description(data, entry):
    return forecast_weather(data, entry)["description"]

def forecast_conditions(data, entry):
    return forecast_weather(data, entry)["main"]

def forecast_cond_id(data, entry):
    return forecast_weather(data, entry)["id"]

<commit_msg>add quite mode, reorganize<commit_after>#!/usr/bin/python

import time
import requests
import json
import sys
#import logging
import os
#import traceback
import argparse
import datetime
import weather_conditions as wc
import app_ui as ui

#script_path = os.getcwd()
#log_path = script_path + "/circleci.log"
#print "logging to " + log_path

#logging.basicConfig(filename=log_path, level=logging.INFO, format='%(asctime)s %(message)s')
#logging.info("Circleci7.py started")

global verbose_mode, api_key, zip_code, timezone_offset, min_api_delay, quiet_mode
verbose_mode = None
quiet_mode = None
api_key = None
zip_code = None
timezone_offset = None
min_api_delay = 2

## --------------------------------------------------------------------------
## Public API
## --------------------------------------------------------------------------

## general

def begin(api_key_, zip_code_, timezone_offset_, verbose_mode_, quiet_mode_):
    global api_key, zip_code, timezone_offset, verbose_mode, quiet_mode
    api_key = api_key_
    zip_code = zip_code_
    timezone_offset = timezone_offset_
    verbose_mode = verbose_mode_
    quiet_mode = quiet_mode_
    ui.begin(verbose_mode, quiet_mode)

def current_time():
    dt = datetime.datetime.now()
    return int(time.mktime(dt.timetuple()))

def get_datetime(ts):
    ts = timezone_timestamp(ts)
    return datetime.datetime.fromtimestamp(ts)

def current_weekday():
    dt = get_datetime(current_time())
    return dt.weekday()

## formatting

def format_unix_timestamp(ts):
    return format_datetime(get_datetime(ts))

def format_datetime(dt):
    return dt.strftime('%A %Y-%m-%d %I:%M:%S %p')

## daily

def get_daily_data():
    url = get_daily_url()
    ui.report_verbose("requesting: %s" % url)
    data = retrieve_data(url)
    ui.report_verbose("received data:")
    ui.report_verbose_alt(str(data))
    return data

def daily_sunrise(data):
    return daily_sys(data)["sunrise"]

def daily_sunset(data):
    return daily_sys(data)["sunset"]

def daily_city(data):
    return data["name"]

def daily_lat(data):
    return daily_coord(data)["lat"]

def daily_lon(data):
    return daily_coord(data)["lon"]

def daily_timestamp(data):
    return data["dt"]

def daily_visibility(data):
    try:
        return data["visibility"]
    except:
        return 5280 * 10

def daily_wind_speed(data):
    return daily_wind(data)["speed"]

def daily_wind_deg(data):
    return daily_wind(data)["deg"]

def daily_pressure(data):
    return daily_main(data)["pressure"]

def daily_humidity(data):
    return daily_main(data)["humidity"]

def daily_temp_min(data):
    return daily_main(data)["temp_min"]

def daily_temp_max(data):
    return daily_main(data)["temp_max"]

def daily_temp(data):
    return daily_main(data)["temp"]

def daily_description(data):
    return daily_weather(data)["description"]

def daily_conditions(data):
    return daily_weather(data)["main"]

def daily_id(data):
    return daily_weather(data)["id"]

## forecast

def get_forecast_data():
    url = get_forecast_url()
    ui.report_verbose("requesting: %s" % url)
    data = retrieve_data(url)
    ui.report_verbose("received data:")
    ui.report_verbose_alt(str(data))
    return data

def forecast_count(data):
    return len(forecast_list(data))

def forecast_timestamp(data, entry):
    return forecast_entry(data, entry)["dt"]

def forecast_pressure(data, entry):
    return forecast_main(data, entry)["pressure"]

def forecast_temp(data, entry):
    return forecast_main(data, entry)["temp"]

def forecast_temp_min(data, entry):
    return forecast_main(data, entry)["temp_min"]

def forecast_temp_max(data, entry):
    return forecast_main(data, entry)["temp_max"]

def forecast_humidity(data, entry):
    return forecast_main(data, entry)["humidity"]

def forecast_wind_speed(data, entry):
    return forecast_wind(data, entry)["speed"]

def forecast_wind_direction(data, entry):
    return forecast_wind(data, entry)["deg"]

def forecast_cloudiness(data, entry):
    return forecast_clouds(data, entry)["all"]

def forecast_cond_id(data, entry):
    return forecast_weather(data, entry)["id"]

def forecast_conditions(data, entry):
    return forecast_weather(data, entry)["main"]

def forecast_description(data, entry):
    return forecast_weather(data, entry)["description"]

def current_weekday():
    dt = get_datetime(current_time())
    return dt.weekday()

## --------------------------------------------------------------------------
## Private
## --------------------------------------------------------------------------

## general

def retrieve_data(url):
    # returns None if there's a json loading error
    request = requests.get(url)
    request = request.text.encode('utf-8')
    json_data = None
    try:
        json_data = json.loads(request)
    except ValueError as e:
        ui.report_error("Exception caught loading JSON data: " + str(e))
    ui.report_verbose("api delay...")
    time.sleep(min_api_delay)
    return json_data

def timezone_timestamp(ts):
    return int(ts) - (timezone_offset * 60 * 60)

def weather_entry(key, value):
    return tc.green(key) + ": " + tc.cyan(str(value))

## daily

def get_daily_url():
    return "http://api.openweathermap.org/data/2.5/weather?zip=%s&APPID=%s&units=imperial" % (zip_code, api_key)

def daily_main(data):
    return data["main"]

def daily_sys(data):
    return data["sys"]

def daily_wind(data):
    return data["wind"]

def daily_weather(data):
    return data["weather"][0]

def daily_coord(data):
    return data["coord"]

def get_forecast_url():
    return "http://api.openweathermap.org/data/2.5/forecast?zip=%s&APPID=%s&units=imperial" % (zip_code, api_key)

## forecast

def forecast_list(data):
    return data["list"]

def forecast_entry(data, entry):
    return forecast_list(data)[int(entry)]

def forecast_main(data, entry):
    return forecast_entry(data, entry)["main"]

def forecast_wind(data, entry):
    return forecast_entry(data, entry)["wind"]

def forecast_clouds(data, entry):
    return forecast_entry(data, entry)["clouds"]

def forecast_weather(data, entry):
    return forecast_entry(data, entry)["weather"][0]

<|endoftext|>


<commit_before># Import the base Widget class and the traitlets Unicode class.
from IPython.html.widgets.widget import Widget, DOMWidget
from IPython.utils.traitlets import (Unicode, Int, Instance, Enum, List, Float,
                                     Any, CFloat, Bool, This, CInt)
import numpy

def vector3(trait_type, default=None, **kwargs):
    if default is None:
        default=[0,0,0]
    return List(trait_type, default_value=default,
                minlen=3, maxlen=3, allow_none=False, **kwargs)

class Object3d(Widget):
    """
    If matrix is not None, it overrides the position, rotation, scale, and up variables.
    """
    position = vector3(CFloat, sync=True)
    rotation = vector3(CFloat, sync=True)
    scale = vector3(CFloat, [1,1,1], sync=True)
    up = vector3(CFloat, [0,1,0], sync=True)
    visible = Bool(True, sync=True)
    castShadow = Bool(False, sync=True)
    receiveShadow = Bool(False, sync=True)
    matrix = List(CFloat, sync=True)
    # TODO: figure out how to get a list of instances of Object3d
    children = List(trait=None, default_value=[], allow_none=False, sync=True)

class Controls(Widget):
    _view_name = Unicode('ControlsView', sync=True)
    controlling = Instance(Object3d, sync=True)

class OrbitControls(Controls):
    _view_name = Unicode('OrbitControlsView', sync=True)

class Geometry(Widget):
    _view_name = Unicode('GeometryView', sync=True)

class SphereGeometry(Geometry):
    _view_name = Unicode('SphereGeometryView', sync=True)
    radius = CFloat(1, sync=True)

class CylinderGeometry(Geometry):
    _view_name = Unicode('CylinderGeometryView', sync=True)
    radiusTop = CFloat(1, sync=True)
    radiusBottom = CFloat(1, sync=True)
    height = CFloat(1, sync=True)
    radiusSegments = CFloat(1, sync=True)
    heightSegments = CFloat(1, sync=True)
    openEnded = Bool(False, sync=True)

class CubeGeometry(Geometry):
    _view_name = Unicode('CubeGeometryView', sync=True)
    width = CFloat(1, sync=True)
    height = CFloat(1, sync=True)
    depth = CFloat(1, sync=True)
    widthSegments = CFloat(1, sync=True)
    heightSegments = CFloat(1, sync=True)
    depthSegments = CFloat(1, sync=True)

class CircleGeometry(Geometry):
    _view_name = Unicode('CircleGeometryView', sync=True)
    radius = CFloat(1, sync=True)
    segments = CFloat(8, sync=True)
    thetaStart = CFloat(0, sync=True)
    thetaLength = CFloat(2*math.pi, sync=True)

class IcosahedronGeometry(radius, detail):
    _view_name = Unicode('IcosahedronGeometryView', sync=True)
    radius = CFloat(1, sync=True)
    detail = CFloat(0, sync=True)

class SurfaceGeometry(Geometry):
    """
    A regular grid with heights
    """
    _view_name = Unicode('SurfaceGeometryView', sync=True)
    z = List(CFloat, [0]*100, sync=True)
    width = CInt(10, sync=True)
    height = CInt(10, sync=True)
    width_segments = CInt(10, sync=True)
    height_segments = CInt(10, sync=True)

class FaceGeometry(Geometry):
    """
    List of vertices and faces
    """
    _view_name = Unicode('FaceGeometryView', sync=True)
    vertices = List(CFloat, sync=True) # [x0, y0, z0, x1, y1, z1, x2, y2, z2, ...]
    face3 = List(CInt, sync=True) # [v0,v1,v2, v0,v1,v2, v0,v1,v2, ...]
    face4 = List(CInt, sync=True) # [v0,v1,v2,v3, v0,v1,v2,v3, v0,v1,v2,v3, ...]

class Material(Widget):
    _view_name = Unicode('MaterialView', sync=True)
    color = Any('yellow', sync=True)
    opacity = CFloat(1.0, sync=True)
    wireframe = Bool(False, sync=True)

class Mesh(Object3d):
    _view_name = Unicode('MeshView', sync=True)
    geometry = Instance(Geometry, sync=True)
    material = Instance(Material, sync=True)

class PlotMesh(Mesh):
    plot = Instance('sage.plot.plot3d.base.Graphics3d')

    def _plot_changed(self, name, old, new):
        self.geometry = self.geometry_from_plot(new)
        self.material = self.material_from_plot(new)

    def material_from_plot(self, p):
        # TODO: do this without scenetree_json()
        t = p.texture.scenetree_json()
        m = Material()
        m.color = t['color']
        m.opacity = t['opacity']
        # TODO: support other attributes
        return m

    def geometry_from_plot(self, p):
        from itertools import groupby, chain
        def flatten(ll):
            return list(chain.from_iterable(ll))
        p.triangulate()

        g = FaceGeometry()
        g.vertices = flatten(p.vertices())
        f = p.index_faces()
        f.sort(key=len)
        faces = {k:flatten(v) for k,v in groupby(f,len)}
        g.face3 = faces.get(3,[])
        g.face4 = faces.get(4,[])
        return g

class Camera(Object3d):
    _view_name = Unicode('CameraView', sync=True)
    fov = CFloat(40, sync=True)
    ratio = CFloat(600.0/400.0, sync=True)

class Scene(Object3d):
    _view_name = Unicode('SceneView', sync=True)

class Renderer(DOMWidget):
    _view_name = Unicode('RendererView', sync=True)
    width = CInt(600, sync=True)
    height = CInt(400, sync=True)
    renderer_type = Enum(['webgl', 'canvas', 'auto'], 'auto', sync=True)
    scene = Instance(Scene, sync=True)
    camera = Instance(Camera, sync=True)
    controls = Instance(Controls, sync=True)

class Light(Object3d):
    color = Any('white', sync=True) # could be string or number or tuple

class AmbientLight(Light):
    _view_name = Unicode('AmbientLight', sync=True)

class IntensityLight(Light):
    _view_name = Unicode('PositionLight', sync=True)
    intensity = CFloat(1, sync=True)

class HemisphereLight(IntensityLight):
    _view_name = Unicode('HemisphereLight', sync=True)
    ground_color = Any('blue', sync=True) # could be string, number, or RGB tuple

class DirectionalLight(IntensityLight):
    _view_name = Unicode('DirectionalLight', sync=True)

class PointLight(IntensityLight):
    _view_name = Unicode('PointLight', sync=True)
    distance = CFloat(10, sync=True)

class SpotLight(PointLight):
    _view_name = Unicode('SpotLight', sync=True)
    angle = CFloat(10, sync=True)
    exponent = CFloat(0.5, sync=True)

lights = {
    'colors': [
        AmbientLight(color=(0.312,0.188,0.4)),
        DirectionalLight(position=[1,0,1], color=[0.8, 0, 0]),
        DirectionalLight(position=[1,1,1], color=[0, 0.8, 0]),
        DirectionalLight(position=[0,1,1], color=[0, 0, 0.8]),
        DirectionalLight(position=[-1,-1,-1], color=[.9,.7,.9]),
        ],
    'shades': [
        AmbientLight(color=[.6, .6, .6]),
        DirectionalLight(position=[0,1,1], color=[.5, .5, .5]),
        DirectionalLight(position=[0,0,1], color=[.5, .5, .5]),
        DirectionalLight(position=[1,1,1], color=[.5, .5, .5]),
        DirectionalLight(position=[-1,-1,-1], color=[.7,.7,.7]),
        ],
    }

import contextlib
class Connect(object):
    """Connect traits from different objects together so they remain in sync.

    Parameters
    ----------
    obj : pairs of objects/attributes

    Examples
    --------

    >>> c = Connect((obj1, 'value'), (obj2, 'value'), (obj3, 'value'))
    >>> obj1.value = 5 # updates other objects as well
    """
    updating = False
    def __init__(self, *args):

        self.objects = args
        for obj,attr in args:
            obj.on_trait_change(self._update, attr)

    @contextlib.contextmanager
    def _busy_updating(self):
        self.updating = True
        yield
        self.updating = False

    def _update(self, name, old, new):
        if self.updating:
            return
        with self._busy_updating():
            for obj,attr in self.objects:
                setattr(obj, attr, new)

    def disconnect(self):
        for obj,attr in self.objects:
            obj.on_trait_change(self._update, attr, remove=True)

<commit_msg>Fix to icosahedron geometry<commit_after># Import the base Widget class and the traitlets Unicode class.
from IPython.html.widgets.widget import Widget, DOMWidget
from IPython.utils.traitlets import (Unicode, Int, Instance, Enum, List, Float,
                                     Any, CFloat, Bool, This, CInt)
import numpy

def vector3(trait_type, default=None, **kwargs):
    if default is None:
        default=[0,0,0]
    return List(trait_type, default_value=default,
                minlen=3, maxlen=3, allow_none=False, **kwargs)

class Object3d(Widget):
    """
    If matrix is not None, it overrides the position, rotation, scale, and up variables.
    """
    position = vector3(CFloat, sync=True)
    rotation = vector3(CFloat, sync=True)
    scale = vector3(CFloat, [1,1,1], sync=True)
    up = vector3(CFloat, [0,1,0], sync=True)
    visible = Bool(True, sync=True)
    castShadow = Bool(False, sync=True)
    receiveShadow = Bool(False, sync=True)
    matrix = List(CFloat, sync=True)
    # TODO: figure out how to get a list of instances of Object3d
    children = List(trait=None, default_value=[], allow_none=False, sync=True)

class Controls(Widget):
    _view_name = Unicode('ControlsView', sync=True)
    controlling = Instance(Object3d, sync=True)

class OrbitControls(Controls):
    _view_name = Unicode('OrbitControlsView', sync=True)

class Geometry(Widget):
    _view_name = Unicode('GeometryView', sync=True)

class SphereGeometry(Geometry):
    _view_name = Unicode('SphereGeometryView', sync=True)
    radius = CFloat(1, sync=True)

class CylinderGeometry(Geometry):
    _view_name = Unicode('CylinderGeometryView', sync=True)
    radiusTop = CFloat(1, sync=True)
    radiusBottom = CFloat(1, sync=True)
    height = CFloat(1, sync=True)
    radiusSegments = CFloat(1, sync=True)
    heightSegments = CFloat(1, sync=True)
    openEnded = Bool(False, sync=True)

class CubeGeometry(Geometry):
    _view_name = Unicode('CubeGeometryView', sync=True)
    width = CFloat(1, sync=True)
    height = CFloat(1, sync=True)
    depth = CFloat(1, sync=True)
    widthSegments = CFloat(1, sync=True)
    heightSegments = CFloat(1, sync=True)
    depthSegments = CFloat(1, sync=True)

class CircleGeometry(Geometry):
    _view_name = Unicode('CircleGeometryView', sync=True)
    radius = CFloat(1, sync=True)
    segments = CFloat(8, sync=True)
    thetaStart = CFloat(0, sync=True)
    thetaLength = CFloat(2*math.pi, sync=True)

class IcosahedronGeometry(Geometry):
    _view_name = Unicode('IcosahedronGeometryView', sync=True)
    radius = CFloat(1, sync=True)
    detail = CFloat(0, sync=True)

class SurfaceGeometry(Geometry):
    """
    A regular grid with heights
    """
    _view_name = Unicode('SurfaceGeometryView', sync=True)
    z = List(CFloat, [0]*100, sync=True)
    width = CInt(10, sync=True)
    height = CInt(10, sync=True)
    width_segments = CInt(10, sync=True)
    height_segments = CInt(10, sync=True)

class FaceGeometry(Geometry):
    """
    List of vertices and faces
    """
    _view_name = Unicode('FaceGeometryView', sync=True)
    vertices = List(CFloat, sync=True) # [x0, y0, z0, x1, y1, z1, x2, y2, z2, ...]
    face3 = List(CInt, sync=True) # [v0,v1,v2, v0,v1,v2, v0,v1,v2, ...]
    face4 = List(CInt, sync=True) # [v0,v1,v2,v3, v0,v1,v2,v3, v0,v1,v2,v3, ...]

class Material(Widget):
    _view_name = Unicode('MaterialView', sync=True)
    color = Any('yellow', sync=True)
    opacity = CFloat(1.0, sync=True)
    wireframe = Bool(False, sync=True)

class Mesh(Object3d):
    _view_name = Unicode('MeshView', sync=True)
    geometry = Instance(Geometry, sync=True)
    material = Instance(Material, sync=True)

class PlotMesh(Mesh):
    plot = Instance('sage.plot.plot3d.base.Graphics3d')

    def _plot_changed(self, name, old, new):
        self.geometry = self.geometry_from_plot(new)
        self.material = self.material_from_plot(new)

    def material_from_plot(self, p):
        # TODO: do this without scenetree_json()
        t = p.texture.scenetree_json()
        m = Material()
        m.color = t['color']
        m.opacity = t['opacity']
        # TODO: support other attributes
        return m

    def geometry_from_plot(self, p):
        from itertools import groupby, chain
        def flatten(ll):
            return list(chain.from_iterable(ll))
        p.triangulate()

        g = FaceGeometry()
        g.vertices = flatten(p.vertices())
        f = p.index_faces()
        f.sort(key=len)
        faces = {k:flatten(v) for k,v in groupby(f,len)}
        g.face3 = faces.get(3,[])
        g.face4 = faces.get(4,[])
        return g

class Camera(Object3d):
    _view_name = Unicode('CameraView', sync=True)
    fov = CFloat(40, sync=True)
    ratio = CFloat(600.0/400.0, sync=True)

class Scene(Object3d):
    _view_name = Unicode('SceneView', sync=True)

class Renderer(DOMWidget):
    _view_name = Unicode('RendererView', sync=True)
    width = CInt(600, sync=True)
    height = CInt(400, sync=True)
    renderer_type = Enum(['webgl', 'canvas', 'auto'], 'auto', sync=True)
    scene = Instance(Scene, sync=True)
    camera = Instance(Camera, sync=True)
    controls = Instance(Controls, sync=True)

class Light(Object3d):
    color = Any('white', sync=True) # could be string or number or tuple

class AmbientLight(Light):
    _view_name = Unicode('AmbientLight', sync=True)

class IntensityLight(Light):
    _view_name = Unicode('PositionLight', sync=True)
    intensity = CFloat(1, sync=True)

class HemisphereLight(IntensityLight):
    _view_name = Unicode('HemisphereLight', sync=True)
    ground_color = Any('blue', sync=True) # could be string, number, or RGB tuple

class DirectionalLight(IntensityLight):
    _view_name = Unicode('DirectionalLight', sync=True)

class PointLight(IntensityLight):
    _view_name = Unicode('PointLight', sync=True)
    distance = CFloat(10, sync=True)

class SpotLight(PointLight):
    _view_name = Unicode('SpotLight', sync=True)
    angle = CFloat(10, sync=True)
    exponent = CFloat(0.5, sync=True)

lights = {
    'colors': [
        AmbientLight(color=(0.312,0.188,0.4)),
        DirectionalLight(position=[1,0,1], color=[0.8, 0, 0]),
        DirectionalLight(position=[1,1,1], color=[0, 0.8, 0]),
        DirectionalLight(position=[0,1,1], color=[0, 0, 0.8]),
        DirectionalLight(position=[-1,-1,-1], color=[.9,.7,.9]),
        ],
    'shades': [
        AmbientLight(color=[.6, .6, .6]),
        DirectionalLight(position=[0,1,1], color=[.5, .5, .5]),
        DirectionalLight(position=[0,0,1], color=[.5, .5, .5]),
        DirectionalLight(position=[1,1,1], color=[.5, .5, .5]),
        DirectionalLight(position=[-1,-1,-1], color=[.7,.7,.7]),
        ],
    }

import contextlib
class Connect(object):
    """Connect traits from different objects together so they remain in sync.

    Parameters
    ----------
    obj : pairs of objects/attributes

    Examples
    --------

    >>> c = Connect((obj1, 'value'), (obj2, 'value'), (obj3, 'value'))
    >>> obj1.value = 5 # updates other objects as well
    """
    updating = False
    def __init__(self, *args):

        self.objects = args
        for obj,attr in args:
            obj.on_trait_change(self._update, attr)

    @contextlib.contextmanager
    def _busy_updating(self):
        self.updating = True
        yield
        self.updating = False

    def _update(self, name, old, new):
        if self.updating:
            return
        with self._busy_updating():
            for obj,attr in self.objects:
                setattr(obj, attr, new)

    def disconnect(self):
        for obj,attr in self.objects:
            obj.on_trait_change(self._update, attr, remove=True)

<|endoftext|>


<commit_before>from django.http import Http404
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
from django.views.generic import View
from corehq.apps.domain.decorators import login_and_domain_required

class DomainAPI(View):
    """
    DomainAPI allows for additional separate RESTful assets to be accessible within or outside
    the context of the reports UI.

    URL addition is added via inspecting subclasses of this parent class and appending
    the name and version of the domain of this API instance in question.
    """

    #If enabling CSRF, here's how to access it over APIs
    #note - for security purposes, csrf protection is ENABLED
    #query={query_json}
    #csrfmiddlewaretoken=token

    #in curl, this is:
    #curl -b "csrftoken=<csrftoken>;sessionid=<session_id>" -H "Content-Type: application/json" -XPOST http://server/a/domain/api/v0.1/xform_es/
    #     -d"query=@myquery.json&csrfmiddlewaretoken=<csrftoken>"

    @classmethod
    def allowed_domain(self, domain):
        return False

    @classmethod
    def api_version(cls):
        raise NotImplementedError("This API's version is not implemented")

    @classmethod
    def api_name(cls):
        raise NotImplementedError("This API's name is not implemented")

    http_method_names = ['get', 'post', 'head', ]
    def get(self, *args, **kwargs):
        raise NotImplementedError("Not implemented")
    def post(self,  *args, **kwargs):
        raise NotImplementedError("Not implemented")
    def head(self, *args, **kwargs):
        raise NotImplementedError("Not implemented")

    @method_decorator(login_and_domain_required)
    def dispatch(self, *args, **kwargs):
        req = args[0]
        if not self.allowed_domain(req.domain):
            raise Http404
        ret =  super(DomainAPI, self).dispatch(*args, **kwargs)
        return ret
<commit_msg>updating domain api, deferring login/constraint stuff to implementer's prerogative<commit_after>from django.http import Http404
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
from django.views.generic import View
from corehq.apps.domain.decorators import login_and_domain_required

class DomainAPI(View):
    """
    DomainAPI allows for additional separate RESTful assets to be accessible within or outside
    the context of the reports UI.

    URL addition is added via inspecting subclasses of this parent class and appending
    the name and version of the domain of this API instance in question.
    """

    #If enabling CSRF, here's how to access it over APIs
    #note - for security purposes, csrf protection is ENABLED
    #query={query_json}
    #csrfmiddlewaretoken=token

    #in curl, this is:
    #curl -b "csrftoken=<csrftoken>;sessionid=<session_id>" -H "Content-Type: application/json" -XPOST http://server/a/domain/api/v0.1/xform_es/
    #     -d"query=@myquery.json&csrfmiddlewaretoken=<csrftoken>"

    @classmethod
    def allowed_domain(self, domain):
        return False

    @classmethod
    def api_version(cls):
        raise NotImplementedError("This API's version is not implemented")

    @classmethod
    def api_name(cls):
        raise NotImplementedError("This API's name is not implemented")

    http_method_names = ['get', 'post', 'head', ]
    def get(self, *args, **kwargs):
        raise NotImplementedError("Not implemented")
    def post(self,  *args, **kwargs):
        raise NotImplementedError("Not implemented")
    def head(self, *args, **kwargs):
        raise NotImplementedError("Not implemented")

    #security/login constraint methods are the implementors' decision - the @method_doctorator trumps subclasses in this case
    #@method_decorator(login_and_domain_required)
    def dispatch(self, *args, **kwargs):
        req = args[0]
        if not self.allowed_domain(req.domain):
            raise Http404
        ret =  super(DomainAPI, self).dispatch(*args, **kwargs)
        return ret
<|endoftext|>