<commit_before>"""
Wood author: thislight

Copyright 2016 thislight

   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.

Under License Apache v2, more information, see file 'LICENSE' in project root directory.
"""
import tornado.httpserver as _httpserver
import tornado.web as _web
import tornado.ioloop as _ioloop
import logging

BASELOGTEMPLATE = '{method} {httpver} {path} {handler_name} {request_time}s'

def _get_info(handler):
    _r = handler.request
    return dict(
        method=_r.method,
        path=_r.path,
        httpver=_r.version,
        cliip=_r.remote_ip,
        p=_r.protocol,
        issec=True if _r.protocol.endswith('s') else False,
        host=_r.host,
        args=_r.arguments,
        request_time=_r.request_time(),
        handler_name=getattr(handler, '__name__', str(handler)),
    )

def _get_formated_log_string_from_handler(handler):
    return BASELOGTEMPLATE.format(**_get_info(handler))

class BaseTornadoView(_web.RequestHandler):
    __log__ = lambda self: _get_formated_log_string_from_handler(self)

class RegisterAllow(object):
    """
    Override all of methods to use for route handler
    """
    @property
    def uri(self):
        """
        Override to return a uri to register
        :return: str
        """
        return None

    @property
    def handler(self):
        """
        Override to return a handler to register
        :return: tornado.web.RequestHandler
        """
        return None

class PackedHandler(RegisterAllow):
    def __init__(self, view, uri='/'):
        self._view = view
        self.__name__ = self._view.__name__ + '_Packed'
        self._uri = uri

    @property
    def get(self):
        return self.override('get', back=True)

    @property
    def post(self):
        return self.override('post', back=True)

    @property
    def head(self):
        return self.override('head', back=True)

    @property
    def put(self):
        return self.override('put', back=True)

    @property
    def delete(self):
        return self.override('delete', back=True)

    @property
    def patch(self):
        return self.override('patch', back=True)

    @property
    def options(self):
        return self.override('options', back=True)

    def override(self, name, back=False):
        def override(func):
            setattr(self.handler, name, func)
            if back:
                return func

        return override

    @property
    def handler(self):
        return self._view

    @property
    def uri(self):
        return self._uri

def _make_empty_view(uri, name='View', *parents):
    """
    a help function for make a empty view.
    :return: PackedHandler
    """
    view = type(name, (BaseTornadoView, *parents), {})
    view.__name__ = name
    _packed = PackedHandler(view, uri=uri)
    return _packed

def _make_uri_tuple(uri, handler, kargs=None):
    t = [uri, handler]
    if kargs: t.append(kargs)
    return tuple(t)

def _print_and_log(msg, logger=logging.getLogger()):
    """
    Print msg and log msg to logger
    :param msg: msg string
    :param logger: A logger from logging
    :return: None
    """
    print(msg)
    logger.info(msg)

def base_log_function(o):
    if hasattr(o, '__log__'):  #
        _print_and_log(o.__log__())
    elif isinstance(o, _web.ErrorHandler):
        _print_and_log(_get_formated_log_string_from_handler(o))
    else:
        _print_and_log(str(o))

class Wood(object):
    def __init__(self, name=__name__, **config):
        self._app_settings = config
        self._name = name
        self.prepare_funcs = []
        if 'log_function' not in self._app_settings:
            self._app_settings['log_function'] = base_log_function
        self._bind_ports = []
        self._ui_mods = []
        if 'ui_modules' not in self._app_settings:
            self._app_settings['ui_modules'] = {}

    @property
    def server(self):
        if not hasattr(self, '_server'):
            self._server = _httpserver.HTTPServer(self.application, xheaders=True)
        return self._server

    @property
    def application(self):
        if not hasattr(self, '_app'):
            self._app = _web.Application(**self._app_settings)
        return self._app

    def handler(self, uri, handler, **kargs):
        """
        ADD handler to handle uri
        :param uri: URI for handler
        :param handler: handler
        :param kargs: arguments call handler.prepare (tornado feature)
        :return: None
        """
        self.application.add_handlers('.*$', [_make_uri_tuple(uri, handler, kargs)])

    def empty(self, uri, name, *parents):
        """
        :return: PackedHandler
        """
        v = _make_empty_view(uri=uri, name=name, *parents)
        self.register(v)
        return v

    def route(self, uri='/', method='get', *parents, **kargs):
        """
        Route a function to uri.
        :return: function
        """

        def route(f):
            """
            :return: PackedHandler
            """
            view = self.empty(uri, f.__name__, *parents)
            mstr = method.lower()
            view.override(mstr)(f)
            return view

        return route

    def register(self, view):
        if isinstance(view, RegisterAllow):
            self.handler(uri=view.uri, handler=view.handler)

    def register_all(self, g):
        for k in g:
            o = g[k]
            if isinstance(o, RegisterAllow):
                self.register(o)

    def uimod(self, name):
        """
        A dec to add ui_module
        :param name: Name of ui module
        :return: function
        """

        def register_uimod(cls):
            self.application.ui_modules.update({
                name: cls
            })
            return cls

        return register_uimod

    def _bind(self):
        """
        Bind all of ports in list self._bind_ports
        """
        for p in self._bind_ports:
            self.server.bind(p)

    def bind(self, port):
        self._bind_ports.append(port)

    def prepare(self, func):
        self.prepare_funcs.append(func)
        return func

    def call_prepare(self):
        for f in self.prepare_funcs:
            f(self)

    def _start(self):
        self.call_prepare()
        try:
            self.ioloop.start()
        except Exception as e:
            self.server.stop()
            raise SystemExit from e

    def start(self, port=None, wokers=None):
        if port:
            self.bind(port)
        self._bind()  # Bind before start server.
        if not wokers:
            self.server.start()
        else:
            self.server.start(wokers)
        self._start()

    @property
    def ioloop(self):
        return _ioloop.IOLoop.current()

# The end of the file
<commit_msg>ADD method Wood.stop to stop server.<commit_after>"""
Wood author: thislight

Copyright 2016 thislight

   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.

Under License Apache v2, more information, see file 'LICENSE' in project root directory.
"""
import tornado.httpserver as _httpserver
import tornado.web as _web
import tornado.ioloop as _ioloop
import logging

BASELOGTEMPLATE = '{method} {httpver} {path} {handler_name} {request_time}s'

def _get_info(handler):
    _r = handler.request
    return dict(
        method=_r.method,
        path=_r.path,
        httpver=_r.version,
        cliip=_r.remote_ip,
        p=_r.protocol,
        issec=True if _r.protocol.endswith('s') else False,
        host=_r.host,
        args=_r.arguments,
        request_time=_r.request_time(),
        handler_name=getattr(handler, '__name__', str(handler)),
    )

def _get_formated_log_string_from_handler(handler):
    return BASELOGTEMPLATE.format(**_get_info(handler))

class BaseTornadoView(_web.RequestHandler):
    __log__ = lambda self: _get_formated_log_string_from_handler(self)

class RegisterAllow(object):
    """
    Override all of methods to use for route handler
    """
    @property
    def uri(self):
        """
        Override to return a uri to register
        :return: str
        """
        return None

    @property
    def handler(self):
        """
        Override to return a handler to register
        :return: tornado.web.RequestHandler
        """
        return None

class PackedHandler(RegisterAllow):
    def __init__(self, view, uri='/'):
        self._view = view
        self.__name__ = self._view.__name__ + '_Packed'
        self._uri = uri

    @property
    def get(self):
        return self.override('get', back=True)

    @property
    def post(self):
        return self.override('post', back=True)

    @property
    def head(self):
        return self.override('head', back=True)

    @property
    def put(self):
        return self.override('put', back=True)

    @property
    def delete(self):
        return self.override('delete', back=True)

    @property
    def patch(self):
        return self.override('patch', back=True)

    @property
    def options(self):
        return self.override('options', back=True)

    def override(self, name, back=False):
        def override(func):
            setattr(self.handler, name, func)
            if back:
                return func

        return override

    @property
    def handler(self):
        return self._view

    @property
    def uri(self):
        return self._uri

def _make_empty_view(uri, name='View', *parents):
    """
    a help function for make a empty view.
    :return: PackedHandler
    """
    view = type(name, (BaseTornadoView, *parents), {})
    view.__name__ = name
    _packed = PackedHandler(view, uri=uri)
    return _packed

def _make_uri_tuple(uri, handler, kargs=None):
    t = [uri, handler]
    if kargs: t.append(kargs)
    return tuple(t)

def _print_and_log(msg, logger=logging.getLogger()):
    """
    Print msg and log msg to logger
    :param msg: msg string
    :param logger: A logger from logging
    :return: None
    """
    print(msg)
    logger.info(msg)

def base_log_function(o):
    if hasattr(o, '__log__'):  #
        _print_and_log(o.__log__())
    elif isinstance(o, _web.ErrorHandler):
        _print_and_log(_get_formated_log_string_from_handler(o))
    else:
        _print_and_log(str(o))

class Wood(object):
    def __init__(self, name=__name__, **config):
        self._app_settings = config
        self._name = name
        self.prepare_funcs = []
        if 'log_function' not in self._app_settings:
            self._app_settings['log_function'] = base_log_function
        self._bind_ports = []
        self._ui_mods = []
        if 'ui_modules' not in self._app_settings:
            self._app_settings['ui_modules'] = {}

    @property
    def server(self):
        if not hasattr(self, '_server'):
            self._server = _httpserver.HTTPServer(self.application, xheaders=True)
        return self._server

    @property
    def application(self):
        if not hasattr(self, '_app'):
            self._app = _web.Application(**self._app_settings)
        return self._app

    def handler(self, uri, handler, **kargs):
        """
        ADD handler to handle uri
        :param uri: URI for handler
        :param handler: handler
        :param kargs: arguments call handler.prepare (tornado feature)
        :return: None
        """
        self.application.add_handlers('.*$', [_make_uri_tuple(uri, handler, kargs)])

    def empty(self, uri, name, *parents):
        """
        :return: PackedHandler
        """
        v = _make_empty_view(uri=uri, name=name, *parents)
        self.register(v)
        return v

    def route(self, uri='/', method='get', *parents, **kargs):
        """
        Route a function to uri.
        :return: function
        """

        def route(f):
            """
            :return: PackedHandler
            """
            view = self.empty(uri, f.__name__, *parents)
            mstr = method.lower()
            view.override(mstr)(f)
            return view

        return route

    def register(self, view):
        if isinstance(view, RegisterAllow):
            self.handler(uri=view.uri, handler=view.handler)

    def register_all(self, g):
        for k in g:
            o = g[k]
            if isinstance(o, RegisterAllow):
                self.register(o)

    def uimod(self, name):
        """
        A dec to add ui_module
        :param name: Name of ui module
        :return: function
        """

        def register_uimod(cls):
            self.application.ui_modules.update({
                name: cls
            })
            return cls

        return register_uimod

    def _bind(self):
        """
        Bind all of ports in list self._bind_ports
        """
        for p in self._bind_ports:
            self.server.bind(p)

    def bind(self, port):
        self._bind_ports.append(port)

    def prepare(self, func):
        self.prepare_funcs.append(func)
        return func

    def call_prepare(self):
        for f in self.prepare_funcs:
            f(self)

    def _start(self):
        self.call_prepare()
        try:
            self.ioloop.start()
        except Exception as e:
            self.server.stop()
            raise SystemExit from e

    def start(self, port=None, wokers=None):
        if port:
            self.bind(port)
        self._bind()  # Bind before start server.
        if not wokers:
            self.server.start()
        else:
            self.server.start(wokers)
        self._start()

    def stop(self):
        self.ioloop.stop()
        self.server.stop()

    @property
    def ioloop(self):
        return _ioloop.IOLoop.current()

# The end of the file
<|endoftext|>


<commit_before>#! /usr/bin/env python
"""Fetch remote BMI models."""
from __future__ import print_function

import os
import sys
import re
import argparse

import yaml

from ..utils import cd
from ..git import git_repo_name, git_clone_or_update, git_repo_sha
from ..project import empty_bmi_project, add_bmi_component
from .. import api
from ..errors import MissingFileError, ParseError

def _cache_dir_from_repo(repo, branch='master'):
    """Name of cache directory for a git repository.

    Parameters
    ----------
    repo : str
        URL of git repository.
    branch : str, optional
        Branch of the git repository.

    Returns
    -------
    str
        Name of the directory to use for the cache.
    """
    cache_dir = '${repo}-${sha}'.format(repo=git_repo_name(repo),
                                        sha=git_repo_sha(repo, branch=branch))
    return os.path.join('cache', cache_dir)

def _component_name_from_repo(repo, name=None):
    """Get fully-qualified component name from repository name.

    Parameters
    ----------
    repo : str
        Name of a repository.
    name : str, optional
        Name of component.

    Returns
    -------
    str
        Fully-qualified component name.
    """
    name = name or re.sub('-', '', os.path.basename(repo).title())

    return '.'.join(['model', name])

def _parse_repo_line(line):
    """Parse a line containing the location of a BMI repository.

    Parameters
    ----------
    line : str
        Location of repository.

    Returns
    -------
    (repo, branch)
        Tuple of repository url, and a branch name.
    """
    if ',' in line:
        repo, branch = line.split(',')
    else:
        repo, branch = line, 'master'

    return repo.strip(), branch.strip()

def _get_bmi_from_repo(repo, prefix='/usr/local'):
    """Get BMI description from a git repository.

    Parameters
    ----------
    repo : str
        url or path to repository.
    prefix : str
        Path to installation prefix for BMI implementation

    Returns
    -------
    dict
        BMI description.
    """
    if repo.startswith('http'):
        repo, branch = _parse_repo_line(repo)

        cache_dir = _cache_dir_from_repo(repo, branch=branch)

        git_clone_or_update(repo, dir=cache_dir, branch=branch)
    else:
        cache_dir = repo

    with cd(cache_dir) as _:
        api.execute_api_build(prefix=prefix)
        bmi = api.load_all()

    #bmi['name'] = _component_name_from_repo(repo, bmi.get('name', None))

    return bmi

def scan_repos_from_file(fname):
    """Read repositories from a file.

    Parameters
    ----------
    fname : str
        Name of file containing repositories.

    Returns
    -------
    list
        List of repositories.
    """
    with open(fname, 'r') as file_like:
        repos = yaml.load(file_like)

    return repos

def main():
    """Get a remote BMI implementation and build it."""
    parser = argparse.ArgumentParser()

    parser.add_argument('repo', type=str, nargs='*',
                        help='GitHub repository for BMI implementation')
    parser.add_argument('--prefix', type=str, default='/usr/local/csdms',
                        help='Prefix for installation')
    parser.add_argument('--file', type=str, default=None,
                        help='Repos file.')

    args = parser.parse_args()

    repos = args.repo
    if args.file:
        repos += scan_repos_from_file(args.file)

    proj = empty_bmi_project()
    for repo in repos:
        try:
            add_bmi_component(proj, _get_bmi_from_repo(repo,
                                                       prefix=args.prefix))
        except MissingFileError as err:
            print('Skipping %s: missing file (%s)' % (repo, err),
                  file=sys.stderr)
        except ParseError as err:
            print('Skipping %s: parse error (%s)' % (repo, err),
                  file=sys.stderr)

    print('%s' % yaml.dump(proj, default_flow_style=False), file=sys.stdout)

if __name__ == '__main__':
    main()
<commit_msg>Added --no-build option.<commit_after>#! /usr/bin/env python
"""Fetch remote BMI models."""
from __future__ import print_function

import os
import sys
import re
import argparse

import yaml

from ..utils import cd
from ..git import git_repo_name, git_clone_or_update, git_repo_sha
from ..project import empty_bmi_project, add_bmi_component
from .. import api
from ..errors import MissingFileError, ParseError

def _cache_dir_from_repo(repo, branch='master'):
    """Name of cache directory for a git repository.

    Parameters
    ----------
    repo : str
        URL of git repository.
    branch : str, optional
        Branch of the git repository.

    Returns
    -------
    str
        Name of the directory to use for the cache.
    """
    cache_dir = '${repo}-${sha}'.format(repo=git_repo_name(repo),
                                        sha=git_repo_sha(repo, branch=branch))
    return os.path.join('cache', cache_dir)

def _component_name_from_repo(repo, name=None):
    """Get fully-qualified component name from repository name.

    Parameters
    ----------
    repo : str
        Name of a repository.
    name : str, optional
        Name of component.

    Returns
    -------
    str
        Fully-qualified component name.
    """
    name = name or re.sub('-', '', os.path.basename(repo).title())

    return '.'.join(['model', name])

def _parse_repo_line(line):
    """Parse a line containing the location of a BMI repository.

    Parameters
    ----------
    line : str
        Location of repository.

    Returns
    -------
    (repo, branch)
        Tuple of repository url, and a branch name.
    """
    if ',' in line:
        repo, branch = line.split(',')
    else:
        repo, branch = line, 'master'

    return repo.strip(), branch.strip()

def _get_bmi_from_repo(repo, prefix='/usr/local', build_api=False):
    """Get BMI description from a git repository.

    Parameters
    ----------
    repo : str
        url or path to repository.
    prefix : str
        Path to installation prefix for BMI implementation

    Returns
    -------
    dict
        BMI description.
    """
    if repo.startswith('http'):
        repo, branch = _parse_repo_line(repo)

        cache_dir = _cache_dir_from_repo(repo, branch=branch)

        git_clone_or_update(repo, dir=cache_dir, branch=branch)
    else:
        cache_dir = repo

    with cd(cache_dir) as _:
        if build_api:
            api.execute_api_build(prefix=prefix)
        bmi = api.load_all()

    #bmi['name'] = _component_name_from_repo(repo, bmi.get('name', None))

    return bmi

def scan_repos_from_file(fname):
    """Read repositories from a file.

    Parameters
    ----------
    fname : str
        Name of file containing repositories.

    Returns
    -------
    list
        List of repositories.
    """
    with open(fname, 'r') as file_like:
        repos = yaml.load(file_like)

    return repos

def main():
    """Get a remote BMI implementation and build it."""
    parser = argparse.ArgumentParser()

    parser.add_argument('repo', type=str, nargs='*',
                        help='GitHub repository for BMI implementation')
    parser.add_argument('--prefix', type=str, default='/usr/local/csdms',
                        help='Prefix for installation')
    parser.add_argument('--file', type=str, default=None,
                        help='Repos file.')
    parser.add_argument('--no-build', dest='build_api', action='store_false',
                        default=True,
                        help='Get API info but do not build the API.')

    args = parser.parse_args()

    repos = args.repo
    if args.file:
        repos += scan_repos_from_file(args.file)

    proj = empty_bmi_project()
    for repo in repos:
        try:
            add_bmi_component(proj,
                              _get_bmi_from_repo(repo, prefix=args.prefix,
                                                 build_api=args.build_api))
        except MissingFileError as err:
            print('Skipping %s: missing file (%s)' % (repo, err),
                  file=sys.stderr)
        except ParseError as err:
            print('Skipping %s: parse error (%s)' % (repo, err),
                  file=sys.stderr)

    print('%s' % yaml.dump(proj, default_flow_style=False), file=sys.stdout)

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


<commit_before>"""This is the Bokeh charts interface. It gives you a high level API to build
complex plot is a simple way.

This is the Donut class which lets you build your Donut charts just passing
the arguments to the Chart class and calling the proper functions.
It also add a new chained stacked method.
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2012 - 2014, Continuum Analytics, Inc. All rights reserved.
#
# Powered by the Bokeh Development Team.
#
# The full license is in the file LICENCE.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

from math import pi, cos, sin
import pandas as pd

from ._chartobject import ChartObject, DataAdapter
from ..models import ColumnDataSource, Range1d

#-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------

class Donut(ChartObject):
    """This is the Donut class and it is in charge of plotting
    Donut chart in an easy and intuitive way.

    """
    # disable grids
    xgrid=False
    ygrid=False

    def __init__(self, values, cat=None,
                 title=None, xlabel=None, ylabel=None, legend=False,
                 xscale="linear", yscale="linear", width=800, height=600,
                 tools=True, filename=False, server=False, notebook=False):
        """
        Args:
            values (obj): value (iterable obj): Data adapter supported input type
            cat (list or bool, optional): list of string representing the categories.
                Defaults to None.
            title (str, optional): the title of your plot. Defaults to None.
            xlabel (str, optional): the x-axis label of your plot.
                Defaults to None.
            ylabel (str, optional): the y-axis label of your plot.
                Defaults to None.
            legend (str, optional): the legend of your plot. The legend content is
                inferred from incoming input.It can be ``top_left``,
                ``top_right``, ``bottom_left``, ``bottom_right``.
                It is ``top_right`` is you set it as True.
                Defaults to None.
            xscale (str, optional): the x-axis type scale of your plot. It can be
                ``linear``, ``datetime`` or ``categorical``.
                Defaults to ``linear``.
            yscale (str, optional): the y-axis type scale of your plot. It can be
                ``linear``, ``datetime`` or ``categorical``.
                Defaults to ``linear``.
            width (int, optional): the width of your plot in pixels.
                Defaults to 800.
            height (int, optional): the height of you plot in pixels.
                Defaults to 600.
            tools (bool, optional): to enable or disable the tools in your plot.
                Defaults to True
            filename (str or bool, optional): the name of the file where your plot.
                will be written. If you pass True to this argument, it will use
                ``untitled`` as a filename.
                Defaults to False.
            server (str or bool, optional): the name of your plot in the server.
                If you pass True to this argument, it will use ``untitled``
                as the name in the server.
                Defaults to False.
            notebook (bool or optional):if you want to output (or not) your plot into the
                IPython notebook.
                Defaults to False.

        Attributes:
            source (obj): datasource object for your plot,
                initialized as a dummy None.
            xdr (obj): x-associated datarange object for you plot,
                initialized as a dummy None.
            ydr (obj): y-associated datarange object for you plot,
                initialized as a dummy None.
            groups (list): to be filled with the incoming groups of data.
                Useful for legend construction.
            data (dict): to be filled with the incoming data and be passed
                to the ColumnDataSource in each chart inherited class.
                Needed for _set_And_get method.
            attr (list): to be filled with the new attributes created after
                loading the data dict.
                Needed for _set_and_get method.
        """
        self.cat = cat
        self.values = values
        self.source = None
        self.xdr = None
        self.ydr = None
        self.groups = []
        self.data = dict()
        self.attr = []

        super(Donut, self).__init__(
            title, xlabel, ylabel, legend,
            xscale, yscale, width, height,
            tools, filename, server, notebook
        )

    def get_source(self):
        """Push the Donut data into the ColumnDataSource and calculate the proper ranges.

        """
        self.source = ColumnDataSource(self.data)
        self.xdr = Range1d(start=-2, end=2)
        self.ydr = Range1d(start=-2, end=2)

    def draw_central_wedge(self):
        """Draw the central part of the donut wedge from donut.source and its
        calculated start and end angles.

        """
        self.chart.make_wedge(
            self.source, x=0, y=0, radius=1, line_color="white",
            line_width=2, start_angle="start", end_angle="end", fill_color="colors"
        )

    def draw_central_descriptions(self):
        """Draw the descriptions to be placed on the central part of the donut wedge

        """
        text = ["%s" % cat for cat in self.cat]
        x, y = polar_to_cartesian(0.7, self.data["start"], self.data["end"])
        text_source = ColumnDataSource(dict(text=text, x=x, y=y))
        self.chart.make_text(
            text_source,
            x="x", y="y", text="text", text_align="center", text_baseline="middle"
        )

    def draw_external_ring(self, colors=None):
        """Draw the external part of the donut wedge from donut.source and its
        related descriptions

        """
        if colors is None:
            colors = self._set_colors(self.cat)

        first = True
        for i, (cat, start_angle, end_angle) in enumerate(zip(
                self.cat, self.data['start'], self.data['end'])):

            details = self.df[cat]
            radians = lambda x: 2*pi*(x/self.total_units)

            angles = details.map(radians).cumsum() + start_angle
            end = angles.tolist() + [end_angle]
            start = [start_angle] + end[:-1]
            base_color = colors[i]
            #fill = [ base_color.lighten(i*0.05) for i in range(len(details) + 1) ]
            fill = [base_color for i in range(len(details) + 1)]
            text = [rowlabel for rowlabel in details.index]
            x, y = polar_to_cartesian(1.25, start, end)

            source = ColumnDataSource(dict(start=start, end=end, fill=fill))

            self.chart.make_annular(source, x=0, y=0,
                inner_radius=1, outer_radius=1.5, start_angle="start", end_angle="end",
                line_color="white", line_width=2, fill_color="fill")

            text_angle = [(start[i]+end[i])/2 for i in range(len(start))]
            text_angle = [angle + pi if pi/2 < angle < 3*pi/2 else angle for angle in text_angle]

            if first and text:
                text.insert(0, '')
                offset = pi / 48
                text_angle.insert(0, text_angle[0] - offset)
                start.insert(0, start[0] - offset)
                end.insert(0, end[0] - offset)
                x, y = polar_to_cartesian(1.25, start, end)
                first = False

            text_source = ColumnDataSource(dict(text=text, x=x, y=y, angle=text_angle))
            self.chart.make_text(text_source, x="x", y="y", text="text", angle="angle",
                text_align="center", text_baseline="middle")

    def draw(self):
        """Use the AnnularWedge and Wedge glyphs to display the wedges.

        Takes reference points from data loaded at the ColumnDataSurce.
        """
        colors = self._set_colors(self.cat)

        # build the central round area of the donut
        self.draw_central_wedge()

        # write central descriptions
        self.draw_central_descriptions()

        # build external donut ring
        self.draw_external_ring()

        self.reset_legend()

    def _setup_show(self):
        """Prepare data before calling drawing methods.

        It ensures that  x and y scales are forced to linear and that
        donut.values is converted to a DataAdapter.

        """
        self.yscale('linear')
        self.xscale('linear')
        self.check_attr()

        # normalize input to the common DataAdapter Interface
        self.values = DataAdapter(self.values, force_alias=False)

    def get_data(self):
        """Take the chart data from self.values.

        It calculates the chart properties accordingly (start/end angles).
        Then build a dict containing references to all the calculated
        points to be used by the Wedge glyph inside the ``draw`` method.

        """
        self.df = df = pd.DataFrame(self.values.values())
        self.groups = df.columns = self.cat
        df.index = self.values.keys()

        aggregated = df.sum()
        self.total_units = total = aggregated.sum()
        radians = lambda x: 2*pi*(x/total)
        angles = aggregated.map(radians).cumsum()

        end_angles = angles.tolist()
        start_angles = [0] + end_angles[:-1]

        colors = self._set_colors(self.cat)
        self.set_and_get("", "colors", colors)
        self.set_and_get("", "end", end_angles)
        self.set_and_get("", "start", start_angles)

def polar_to_cartesian(r, start_angles, end_angles):
    cartesian = lambda r, alpha: (r*cos(alpha), r*sin(alpha))
    points = []

    for start, end in zip(start_angles, end_angles):
        points.append(cartesian(r, (end + start)/2))

    return zip(*points)
<commit_msg>improve module docstrings and code<commit_after>"""This is the Bokeh charts interface. It gives you a high level API to build
complex plot is a simple way.

This is the Donut class which lets you build your Donut charts just passing
the arguments to the Chart class and calling the proper functions.
It also add a new chained stacked method.
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2012 - 2014, Continuum Analytics, Inc. All rights reserved.
#
# Powered by the Bokeh Development Team.
#
# The full license is in the file LICENCE.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
from math import pi, cos, sin
import pandas as pd

from ._chartobject import ChartObject, DataAdapter
from ..models import ColumnDataSource, Range1d

#-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------

class Donut(ChartObject):
    """This is the Donut class and it is in charge of plotting
    Donut chart in an easy and intuitive way.

    Essentially, it provides a way to ingest the data, make the proper
    calculations and push the references into a source object.
    We additionally make calculations for the donut slices and angles.
    And finally add the needed glyphs (Wedges and AnnularWedges) taking
    the references from the source.

    Examples:

        xyvalues = OrderedDict()
        # TODO: Fix bug for donut breaking when inputs that are not float
        xyvalues['python'] = [2., 5., 3.]
        xyvalues['pypy'] = [4., 1., 4.]
        xyvalues['jython'] = [6., 4., 3.]
        cat = ['Devs', 'Dev Ops', 'Scientists']
        donut = Donut(xyvalues, cat, filename="donut.html")
        donut.title("Medals Donut").xlabel("Cat").ylabel("Lang")
        donut.legend(True).width(800).height(800).show()
    """
    # disable grids
    xgrid=False
    ygrid=False

    def __init__(self, values, cat=None,
                 title=None, xlabel=None, ylabel=None, legend=False,
                 xscale="linear", yscale="linear", width=800, height=600,
                 tools=True, filename=False, server=False, notebook=False):
        """
        Args:
            values (obj): value (iterable obj): Data adapter supported input type
            cat (list or bool, optional): list of string representing the categories.
                Defaults to None.
            title (str, optional): the title of your chart. Defaults to None.
            xlabel (str, optional): the x-axis label of your chart.
                Defaults to None.
            ylabel (str, optional): the y-axis label of your chart.
                Defaults to None.
            legend (str, optional): the legend of your chart. The legend content is
                inferred from incoming input.It can be ``top_left``,
                ``top_right``, ``bottom_left``, ``bottom_right``.
                It is ``top_right`` is you set it as True.
                Defaults to None.
            xscale (str, optional): the x-axis type scale of your chart. It can be
                ``linear``, ``datetime`` or ``categorical``.
                Defaults to ``datetime``.
            yscale (str, optional): the y-axis type scale of your chart. It can be
                ``linear``, ``datetime`` or ``categorical``.
                Defaults to ``linear``.
            width (int, optional): the width of your chart in pixels.
                Defaults to 800.
            height (int, optional): the height of you chart in pixels.
                Defaults to 600.
            tools (bool, optional): to enable or disable the tools in your chart.
                Defaults to True
            filename (str or bool, optional): the name of the file where your chart.
                will be written. If you pass True to this argument, it will use
                ``untitled`` as a filename.
                Defaults to False.
            server (str or bool, optional): the name of your chart in the server.
                If you pass True to this argument, it will use ``untitled``
                as the name in the server.
                Defaults to False.
            notebook (bool, optional):if you want to output (or not) your chart into the
                IPython notebook.
                Defaults to False.

        Attributes:
            source (obj): datasource object for your plot,
                initialized as a dummy None.
            xdr (obj): x-associated datarange object for you plot,
                initialized as a dummy None.
            ydr (obj): y-associated datarange object for you plot,
                initialized as a dummy None.
            groups (list): to be filled with the incoming groups of data.
                Useful for legend construction.
            data (dict): to be filled with the incoming data and be passed
                to the ColumnDataSource in each chart inherited class.
                Needed for _set_And_get method.
            attr (list): to be filled with the new attributes created after
                loading the data dict.
                Needed for _set_and_get method.
        """
        self.cat = cat
        self.values = values
        self.source = None
        self.xdr = None
        self.ydr = None
        self.groups = []
        self.data = dict()
        self.attr = []

        super(Donut, self).__init__(
            title, xlabel, ylabel, legend,
            xscale, yscale, width, height,
            tools, filename, server, notebook
        )

    def get_source(self):
        """Push the Donut data into the ColumnDataSource and calculate
         the proper ranges.

        """
        self.source = ColumnDataSource(self.data)
        self.xdr = Range1d(start=-2, end=2)
        self.ydr = Range1d(start=-2, end=2)

    def draw_central_wedge(self):
        """Draw the central part of the donut wedge from donut.source and
         its calculated start and end angles.

        """
        self.chart.make_wedge(
            self.source, x=0, y=0, radius=1, line_color="white",
            line_width=2, start_angle="start", end_angle="end",
            fill_color="colors"
        )

    def draw_central_descriptions(self):
        """Draw the descriptions to be placed on the central part of the
        donut wedge
        """
        text = ["%s" % cat for cat in self.cat]
        x, y = polar_to_cartesian(0.7, self.data["start"], self.data["end"])
        text_source = ColumnDataSource(dict(text=text, x=x, y=y))
        self.chart.make_text(
            text_source,
            x="x", y="y", text="text", text_align="center",
            text_baseline="middle"
        )

    def draw_external_ring(self, colors=None):
        """Draw the external part of the donut wedge from donut.source
         and its related descriptions
        """
        if colors is None:
            colors = self._set_colors(self.cat)

        first = True
        for i, (cat, start_angle, end_angle) in enumerate(zip(
                self.cat, self.data['start'], self.data['end'])):

            details = self.df[cat]
            radians = lambda x: 2*pi*(x/self.total_units)

            angles = details.map(radians).cumsum() + start_angle
            end = angles.tolist() + [end_angle]
            start = [start_angle] + end[:-1]
            base_color = colors[i]
            #fill = [ base_color.lighten(i*0.05) for i in range(len(details) + 1) ]
            fill = [base_color for i in range(len(details) + 1)]
            text = [rowlabel for rowlabel in details.index]
            x, y = polar_to_cartesian(1.25, start, end)

            source = ColumnDataSource(dict(start=start, end=end, fill=fill))
            self.chart.make_annular(
                source, x=0, y=0, inner_radius=1, outer_radius=1.5,
                start_angle="start", end_angle="end", line_color="white",
                line_width=2, fill_color="fill"
            )
            text_angle = [(start[i]+end[i])/2 for i in range(len(start))]
            text_angle = [angle + pi if pi/2 < angle < 3*pi/2 else angle
                          for angle in text_angle]

            if first and text:
                text.insert(0, '')
                offset = pi / 48
                text_angle.insert(0, text_angle[0] - offset)
                start.insert(0, start[0] - offset)
                end.insert(0, end[0] - offset)
                x, y = polar_to_cartesian(1.25, start, end)
                first = False
            data = dict(text=text, x=x, y=y, angle=text_angle)
            text_source = ColumnDataSource(data)
            self.chart.make_text(
                text_source, x="x", y="y", text="text", angle="angle",
                text_align="center", text_baseline="middle"
            )

    def draw(self):
        """Use the AnnularWedge and Wedge glyphs to display the wedges.

        Takes reference points from data loaded at the ColumnDataSurce.
        """
        # build the central round area of the donut
        self.draw_central_wedge()
        # write central descriptions
        self.draw_central_descriptions()
        # build external donut ring
        self.draw_external_ring()
        self.reset_legend()

    def _setup_show(self):
        """Prepare data before calling drawing methods.

        It ensures that  x and y scales are forced to linear and that
        donut.values is converted to a DataAdapter.

        """
        self.yscale('linear')
        self.xscale('linear')
        self.check_attr()

        # normalize input to the common DataAdapter Interface
        self.values = DataAdapter(self.values, force_alias=False)

    def get_data(self):
        """Take the chart data from self.values.

        It calculates the chart properties accordingly (start/end angles).
        Then build a dict containing references to all the calculated
        points to be used by the Wedge glyph inside the ``draw`` method.

        """
        self.df = df = pd.DataFrame(self.values.values())
        self.groups = df.columns = self.cat
        df.index = self.values.keys()
        aggregated = df.sum()
        self.total_units = total = aggregated.sum()
        radians = lambda x: 2*pi*(x/total)
        angles = aggregated.map(radians).cumsum()

        end_angles = angles.tolist()
        start_angles = [0] + end_angles[:-1]
        colors = self._set_colors(self.cat)
        self.set_and_get("", "colors", colors)
        self.set_and_get("", "end", end_angles)
        self.set_and_get("", "start", start_angles)

def polar_to_cartesian(r, start_angles, end_angles):
    """Translate polar coordinates to cartesian.

    Args:
    r (float): radial coordinate
    start_angles (list(float)): list of start angles
    end_angles (list(float)): list of end_angles angles

    Returns:
        x, y points
    """
    cartesian = lambda r, alpha: (r*cos(alpha), r*sin(alpha))
    points = []

    for start, end in zip(start_angles, end_angles):
        points.append(cartesian(r, (end + start)/2))

    return zip(*points)
<|endoftext|>


<commit_before>"""
Schedule-related services
"""

import MaKaC.conference as conference

from MaKaC.common.PickleJar import DictPickler
import MaKaC.webinterface.locators as locators
from MaKaC.user import AvatarHolder, GroupHolder

from MaKaC.services.interface.rpc.common import ServiceError, ServiceAccessError

from MaKaC.services.implementation.base import ParameterManager
from MaKaC.services.implementation.base import ProtectedModificationService
from MaKaC.services.implementation.base import ProtectedDisplayService
from MaKaC.errors import ModificationError, MaKaCError
from MaKaC.common.fossilize import fossilize

class UserListChange(object):

    def changeUserList(self, object, newList):
        # clone the list, to avoid problems
        allowedUsers = object.getAllowedToAccessList()[:]

        # user can be a user or group
        for user in allowedUsers:
            if not user.getId() in newList:
                object.revokeAccess(user)
            else:
                del newList[user.getId()]

        for elem in newList:
            if 'isGroup' in elem and elem['isGroup']:
                avatar = GroupHolder().getById(elem['id'])
            else:
                avatar = AvatarHolder().getById(elem['id'])
            object.grantAccess(avatar)

class MaterialBase(object):

    def _checkParams( self ):
        try:
            l = locators.WebLocator()

            self._material = None
            self._conf = None

            l.setMaterial( self._params, 0 )
            self._target = l.getObject()

            #if isinstance(self._target, conference.Material):
            self._material = self._target
            self._conf = self._target.getConference()
            self._categ = self._conf.getOwner()

            ## TODO: remove this, since material/resource creation
            ## doesn't come through this method

            ## if isinstance(self._target, conference.Category):
            ##     self._categ = self._target
            ## else:
            ##     self._conf = self._target.getConference()

            ## if self._conf == None:
            ##     self._categ=self._target.getCategory()

        except Exception, e:
            raise ServiceError("ERR-M0", str(e))

class MaterialDisplayBase(ProtectedDisplayService, MaterialBase):

    def _checkParams(self):
        MaterialBase._checkParams(self)
        ProtectedDisplayService._checkParams(self)

class MaterialModifBase(MaterialBase, ProtectedModificationService):

    def _checkParams(self):
        MaterialBase._checkParams(self)
        ProtectedModificationService._checkParams(self)

    def _checkProtection(self):

        owner = self._material.getOwner()

        # There are two exceptions to the normal permission scheme:
        # (sub-)contribution submitters and session coordinators

        # in case the owner is a (sub-)contribution, we should
        # allow submitters
        if isinstance(owner, conference.Contribution) or \
           isinstance(owner, conference.SubContribution):

            reviewingState = self._material.getReviewingState()

            if (reviewingState < 3 and
                owner.canUserSubmit(self._aw.getUser())):
                # Submitters have access
                return
            elif owner.getSession() and owner.getSession().canCoordinate(self._aw, "modifContribs"):
                # Coordinators of the parent session have access
                return

        # if it's associated with a session, coordinators
        # should be allowed
        elif self._material.getSession() != None and \
            self._material.getSession().canCoordinate(self._aw, "modifContribs"):
            # Session coordinators have access
            return

        try:
            ProtectedModificationService._checkProtection(self)
        except ModificationError:
            raise ServiceAccessError("ERR-P5", _("you are not authorised to manage material for this contribution"))
        except Exception, e:
            raise e

class ResourceBase(object):
    """
    Base class for material resource access
    """

    def _checkParams(self):
        """
        Checks the materialId, and retrieves the material using it
        """

        self._material = None
        self._conf = None

        l = locators.WebLocator()

        try:

            l.setResource( self._params, 0 )
            self._target = l.getObject()

            if isinstance(self._target, conference.Resource):
                self._resource = self._target
                self._material = self._target.getOwner()

            if isinstance(self._target, conference.Material):
                self._material = self._target

            if isinstance(self._target, conference.Category):
                self._categ = self._target
            else:
                self._conf = self._target.getConference()

            if self._conf == None:
                self._categ=self._target.getCategory()

        except Exception, e:
            raise ServiceError("ERR-M0", str(e))

class ResourceDisplayBase(ProtectedDisplayService, ResourceBase):

    def _checkProtection(self):
        ProtectedDisplayService._checkParams(self)

    def _checkParams(self):
        ResourceBase._checkParams(self)
        ProtectedDisplayService._checkParams(self)

class ResourceModifBase(ResourceBase, MaterialModifBase):

    def _checkParams(self):
        ResourceBase._checkParams(self)

    #def _checkProtection(self):
    #    MaterialModifBase._checkProtection(self)

class GetMaterialClassesBase(MaterialDisplayBase):
    """
    Base class for obtaining a listing of material classes
    """

    def _checkParams( self ):
        l = locators.WebLocator()

        l.setMaterial( self._params, 0 )
        self._target = l.getObject()

    def _getAnswer(self):
        """
        Provides the list of material classes, based on the target
        resource (conference, session, contribution, etc...)
        """
        matList = {}

        for mat in self._target.getAllMaterialList():
            matList[mat.getId()] = DictPickler.pickle(mat)

        return matList

class GetMaterial(MaterialDisplayBase):
    """
    Service for obtaining a material by id
    """

    def _getAnswer(self):
        """
        Provides the list of material classes, based on the target
        resource (conference, session, contribution, etc...)
        """
        return DictPickler.pickle(self._material)

class GetMaterialAllowedUsers(MaterialModifBase):
    """
    Lists the users that allowed to access the material
    """

    def _checkParams(self):
        MaterialModifBase._checkParams(self)
        self._includeFavList = self._params.get("includeFavList", False)
        self._user = self._getUser() #will be None if user is not authenticated

    def _getAnswer(self):
        #will use IAvatarFossil or IGroupFossil
        allowedAccesList = fossilize(self._material.getAllowedToAccessList())
        if self._includeFavList and self._user:
            favList = fossilize(self._user.getPersonalInfo().getBasket().getUsers().values())
            return [allowedAccesList, favList]
        else:
            return allowedAccesList

class GetMaterialProtection(MaterialModifBase):

    def _getAnswer(self):
        """
        Returns the material's protection
        """
        try:
            materialId = self._target.getMaterialById(self._params['matId'])
        except:
        #it's not in the material list, we return the parent's level of protection
        #WATCH OUT! This is the default value to inherit from parent in Editor.js, if that value is changed
        #for any reason this function may not work properly
            return 0
        else:
            return materialId.getAccessProtectionLevel()

class EditMaterialClassBase(MaterialModifBase, UserListChange):
    """
    Base class for material class edition
    """

    def _checkParams(self):
        """
        Gets a reference to the material, using the
        id as the key, and gets the properties to change
        """
        MaterialModifBase._checkParams(self)

        matId = self._params.get("materialId",None)
        self._newProperties = self._params.get("materialInfo",None)
        self._newUserList = self._newProperties['userList']

        materialPM = ParameterManager(self._newProperties)

        self._title = materialPM.extract('title', pType=str, allowEmpty=True, defaultValue="NO TITLE ASSIGNED")
        self._description = materialPM.extract('description', pType=str, allowEmpty=True)
        self._protection = materialPM.extract('protection', pType=int)
        self._hidden = materialPM.extract('hidden', pType=int)
        self._accessKey = materialPM.extract('accessKey', pType=str, allowEmpty=True)

    def _getAnswer(self):
        """
        Updates the material with the new properties
        """

        self.changeUserList(self._material, self._newUserList)

        self._material.setTitle(self._title);
        self._material.setDescription(self._description);
        self._material.setProtection(self._protection);
        self._material.setHidden(self._hidden);
        self._material.setAccessKey(self._accessKey);

        event = self._material.getOwner()
        materialRegistry = event.getMaterialRegistry()

        return {
            'material': DictPickler.pickle(self._material),
            'newMaterialTypes': materialRegistry.getMaterialList(event)
            }

class DeleteMaterialClassBase(MaterialModifBase):

    def _getAnswer(self):
        materialId = self._material.getId()
        event = self._material.getOwner()

        # actually delete it
        self._target.getOwner().removeMaterial(self._material)

        materialRegistry = event.getMaterialRegistry()

        return {
            'deletedMaterialId': materialId,
            'newMaterialTypes': materialRegistry.getMaterialList(event)
            }

class GetResourcesBase(ResourceDisplayBase):

    def _getAnswer(self):
        resList = {}

        for resource in self._material.getResourceList():
            resList[resource.getId()] = DictPickler.pickle(resource)
        return resList

class EditResourceBase(ResourceModifBase, UserListChange):

    def _checkParams(self):
        ResourceModifBase._checkParams(self)

        resId = self._params.get("resourceId",None)
        self._newProperties = self._params.get("resourceInfo",None)
        self._newUserList = self._newProperties['userList']

    def _getAnswer(self):

        self.changeUserList(self._resource, self._newUserList)

        DictPickler.update(self._resource, self._newProperties)
        return DictPickler.pickle(self._resource)

class GetResourceAllowedUsers(ResourceModifBase):
    """
    Lists the users that allowed to access the resource
    """

    def _checkParams(self):
        ResourceModifBase._checkParams(self)
        self._includeFavList = self._params.get("includeFavList", False)
        self._user = self._getUser() #will be None if user is not authenticated

    def _getAnswer(self):
        #will use IAvatarFossil or IGroupFossil
        allowedAccesList = fossilize(self._resource.getAllowedToAccessList())
        if self._includeFavList and self._user:
            favList = fossilize(self._user.getPersonalInfo().getBasket().getUsers().values())
            return [allowedAccesList, favList]
        else:
            return allowedAccesList

class DeleteResourceBase(ResourceModifBase):

    def _getAnswer(self):
        resourceId = self._resource.getId()

        # remove the resource
        self._material.removeResource(self._resource)
        event = self._material.getOwner()

        # if there are no resources left inside the material,
        # just delete it
        if len(self._material.getResourceList()) == 0:
            event.removeMaterial(self._material)

        newMaterialTypes = event.getMaterialRegistry().getMaterialList(event)

        return {
            'deletedResourceId': resourceId,
            'newMaterialTypes': newMaterialTypes
            }

methodMap = {

    "list": GetMaterialClassesBase,
    "listAllowedUsers": GetMaterialAllowedUsers,
    "get": GetMaterial,
    "edit": EditMaterialClassBase,
    "delete": DeleteMaterialClassBase,
    "getProtection": GetMaterialProtection,

    # Resource add is quite hacky, and uses a normal RH, because of file upload
    # So, you won't find it here...
    "resources.listAllowedUsers": GetResourceAllowedUsers,
    "resources.list": GetResourcesBase,
    "resources.edit": EditResourceBase,
    "resources.delete": DeleteResourceBase
    }

<commit_msg>[FIX] Edition material for categories fails<commit_after>"""
Schedule-related services
"""

import MaKaC.conference as conference

from MaKaC.common.PickleJar import DictPickler
import MaKaC.webinterface.locators as locators
from MaKaC.user import AvatarHolder, GroupHolder

from MaKaC.services.interface.rpc.common import ServiceError, ServiceAccessError

from MaKaC.services.implementation.base import ParameterManager
from MaKaC.services.implementation.base import ProtectedModificationService
from MaKaC.services.implementation.base import ProtectedDisplayService
from MaKaC.errors import ModificationError, MaKaCError
from MaKaC.common.fossilize import fossilize

class UserListChange(object):

    def changeUserList(self, object, newList):
        # clone the list, to avoid problems
        allowedUsers = object.getAllowedToAccessList()[:]

        # user can be a user or group
        for user in allowedUsers:
            if not user.getId() in newList:
                object.revokeAccess(user)
            else:
                del newList[user.getId()]

        for elem in newList:
            if 'isGroup' in elem and elem['isGroup']:
                avatar = GroupHolder().getById(elem['id'])
            else:
                avatar = AvatarHolder().getById(elem['id'])
            object.grantAccess(avatar)

class MaterialBase(object):

    def _checkParams( self ):
        try:
            l = locators.WebLocator()

            self._material = None
            self._conf = None

            l.setMaterial( self._params, 0 )
            self._target = l.getObject()

            #if isinstance(self._target, conference.Material):
            self._material = self._target
            self._conf = self._target.getConference()
            if self._conf == None:
                self._categ = self._target
            else:
                self._categ = self._conf.getOwner()

            ## TODO: remove this, since material/resource creation
            ## doesn't come through this method

            ## if isinstance(self._target, conference.Category):
            ##     self._categ = self._target
            ## else:
            ##     self._conf = self._target.getConference()

            ## if self._conf == None:
            ##     self._categ=self._target.getCategory()

        except Exception, e:
            raise ServiceError("ERR-M0", str(e))

class MaterialDisplayBase(ProtectedDisplayService, MaterialBase):

    def _checkParams(self):
        MaterialBase._checkParams(self)
        ProtectedDisplayService._checkParams(self)

class MaterialModifBase(MaterialBase, ProtectedModificationService):

    def _checkParams(self):
        MaterialBase._checkParams(self)
        ProtectedModificationService._checkParams(self)

    def _checkProtection(self):
        owner = self._material.getOwner()

        # There are two exceptions to the normal permission scheme:
        # (sub-)contribution submitters and session coordinators

        # in case the owner is a (sub-)contribution, we should
        # allow submitters
        if isinstance(owner, conference.Contribution) or \
           isinstance(owner, conference.SubContribution):

            reviewingState = self._material.getReviewingState()

            if (reviewingState < 3 and
                owner.canUserSubmit(self._aw.getUser())):
                # Submitters have access
                return
            elif owner.getSession() and owner.getSession().canCoordinate(self._aw, "modifContribs"):
                # Coordinators of the parent session have access
                return

        # if it's associated with a session, coordinators
        # should be allowed
        elif self._material.getSession() != None and \
            self._material.getSession().canCoordinate(self._aw, "modifContribs"):
            # Session coordinators have access
            return

        try:
            ProtectedModificationService._checkProtection(self)
        except ModificationError:
            raise ServiceAccessError("ERR-P5", _("you are not authorised to manage material for this contribution"))
        except Exception, e:
            raise e

class ResourceBase(object):
    """
    Base class for material resource access
    """

    def _checkParams(self):
        """
        Checks the materialId, and retrieves the material using it
        """

        self._material = None
        self._conf = None

        l = locators.WebLocator()

        try:

            l.setResource( self._params, 0 )
            self._target = l.getObject()

            if isinstance(self._target, conference.Resource):
                self._resource = self._target
                self._material = self._target.getOwner()

            if isinstance(self._target, conference.Material):
                self._material = self._target

            if isinstance(self._target, conference.Category):
                self._categ = self._target
            else:
                self._conf = self._target.getConference()

            if self._conf == None:
                self._categ=self._target.getCategory()

        except Exception, e:
            raise ServiceError("ERR-M0", str(e))

class ResourceDisplayBase(ProtectedDisplayService, ResourceBase):

    def _checkProtection(self):
        ProtectedDisplayService._checkParams(self)

    def _checkParams(self):
        ResourceBase._checkParams(self)
        ProtectedDisplayService._checkParams(self)

class ResourceModifBase(ResourceBase, MaterialModifBase):

    def _checkParams(self):
        ResourceBase._checkParams(self)

    #def _checkProtection(self):
    #    MaterialModifBase._checkProtection(self)

class GetMaterialClassesBase(MaterialDisplayBase):
    """
    Base class for obtaining a listing of material classes
    """

    def _checkParams( self ):
        l = locators.WebLocator()

        l.setMaterial( self._params, 0 )
        self._target = l.getObject()

    def _getAnswer(self):
        """
        Provides the list of material classes, based on the target
        resource (conference, session, contribution, etc...)
        """
        matList = {}

        for mat in self._target.getAllMaterialList():
            matList[mat.getId()] = DictPickler.pickle(mat)

        return matList

class GetMaterial(MaterialDisplayBase):
    """
    Service for obtaining a material by id
    """

    def _getAnswer(self):
        """
        Provides the list of material classes, based on the target
        resource (conference, session, contribution, etc...)
        """
        return DictPickler.pickle(self._material)

class GetMaterialAllowedUsers(MaterialModifBase):
    """
    Lists the users that allowed to access the material
    """

    def _checkParams(self):
        MaterialModifBase._checkParams(self)
        self._includeFavList = self._params.get("includeFavList", False)
        self._user = self._getUser() #will be None if user is not authenticated

    def _getAnswer(self):
        #will use IAvatarFossil or IGroupFossil
        allowedAccesList = fossilize(self._material.getAllowedToAccessList())
        if self._includeFavList and self._user:
            favList = fossilize(self._user.getPersonalInfo().getBasket().getUsers().values())
            return [allowedAccesList, favList]
        else:
            return allowedAccesList

class GetMaterialProtection(MaterialModifBase):

    def _getAnswer(self):
        """
        Returns the material's protection
        """
        try:
            materialId = self._target.getMaterialById(self._params['matId'])
        except:
        #it's not in the material list, we return the parent's level of protection
        #WATCH OUT! This is the default value to inherit from parent in Editor.js, if that value is changed
        #for any reason this function may not work properly
            return 0
        else:
            return materialId.getAccessProtectionLevel()

class EditMaterialClassBase(MaterialModifBase, UserListChange):
    """
    Base class for material class edition
    """

    def _checkParams(self):
        """
        Gets a reference to the material, using the
        id as the key, and gets the properties to change
        """
        MaterialModifBase._checkParams(self)

        matId = self._params.get("materialId",None)
        self._newProperties = self._params.get("materialInfo",None)
        self._newUserList = self._newProperties['userList']

        materialPM = ParameterManager(self._newProperties)

        self._title = materialPM.extract('title', pType=str, allowEmpty=True, defaultValue="NO TITLE ASSIGNED")
        self._description = materialPM.extract('description', pType=str, allowEmpty=True)
        self._protection = materialPM.extract('protection', pType=int)
        self._hidden = materialPM.extract('hidden', pType=int)
        self._accessKey = materialPM.extract('accessKey', pType=str, allowEmpty=True)

    def _getAnswer(self):
        """
        Updates the material with the new properties
        """

        self.changeUserList(self._material, self._newUserList)

        self._material.setTitle(self._title);
        self._material.setDescription(self._description);
        self._material.setProtection(self._protection);
        self._material.setHidden(self._hidden);
        self._material.setAccessKey(self._accessKey);

        event = self._material.getOwner()
        materialRegistry = event.getMaterialRegistry()

        return {
            'material': DictPickler.pickle(self._material),
            'newMaterialTypes': materialRegistry.getMaterialList(event)
            }

class DeleteMaterialClassBase(MaterialModifBase):

    def _getAnswer(self):
        materialId = self._material.getId()
        event = self._material.getOwner()

        # actually delete it
        self._target.getOwner().removeMaterial(self._material)

        materialRegistry = event.getMaterialRegistry()

        return {
            'deletedMaterialId': materialId,
            'newMaterialTypes': materialRegistry.getMaterialList(event)
            }

class GetResourcesBase(ResourceDisplayBase):

    def _getAnswer(self):
        resList = {}

        for resource in self._material.getResourceList():
            resList[resource.getId()] = DictPickler.pickle(resource)
        return resList

class EditResourceBase(ResourceModifBase, UserListChange):

    def _checkParams(self):
        ResourceModifBase._checkParams(self)

        resId = self._params.get("resourceId",None)
        self._newProperties = self._params.get("resourceInfo",None)
        self._newUserList = self._newProperties['userList']

    def _getAnswer(self):

        self.changeUserList(self._resource, self._newUserList)

        DictPickler.update(self._resource, self._newProperties)
        return DictPickler.pickle(self._resource)

class GetResourceAllowedUsers(ResourceModifBase):
    """
    Lists the users that allowed to access the resource
    """

    def _checkParams(self):
        ResourceModifBase._checkParams(self)
        self._includeFavList = self._params.get("includeFavList", False)
        self._user = self._getUser() #will be None if user is not authenticated

    def _getAnswer(self):
        #will use IAvatarFossil or IGroupFossil
        allowedAccesList = fossilize(self._resource.getAllowedToAccessList())
        if self._includeFavList and self._user:
            favList = fossilize(self._user.getPersonalInfo().getBasket().getUsers().values())
            return [allowedAccesList, favList]
        else:
            return allowedAccesList

class DeleteResourceBase(ResourceModifBase):

    def _getAnswer(self):
        resourceId = self._resource.getId()

        # remove the resource
        self._material.removeResource(self._resource)
        event = self._material.getOwner()

        # if there are no resources left inside the material,
        # just delete it
        if len(self._material.getResourceList()) == 0:
            event.removeMaterial(self._material)

        newMaterialTypes = event.getMaterialRegistry().getMaterialList(event)

        return {
            'deletedResourceId': resourceId,
            'newMaterialTypes': newMaterialTypes
            }

methodMap = {

    "list": GetMaterialClassesBase,
    "listAllowedUsers": GetMaterialAllowedUsers,
    "get": GetMaterial,
    "edit": EditMaterialClassBase,
    "delete": DeleteMaterialClassBase,
    "getProtection": GetMaterialProtection,

    # Resource add is quite hacky, and uses a normal RH, because of file upload
    # So, you won't find it here...
    "resources.listAllowedUsers": GetResourceAllowedUsers,
    "resources.list": GetResourcesBase,
    "resources.edit": EditResourceBase,
    "resources.delete": DeleteResourceBase
    }

<|endoftext|>


<commit_before>from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
from flask import request, current_app
import gevent
import gevent.monkey
gevent.monkey.patch_all()
import uuid
import socket
import redis

#server imports
from app import app
import wsmanager
from .. import protocol
from serverbb import ContinuumModelsStorage
from .. import bbmodel
bbmodel.load_special_types()

import models.user as user
import models.convenience as mconv
import models.docs as docs

import logging
import time
port = 5006
log = logging.getLogger(__name__)

def prepare_app(rhost='127.0.0.1', rport=6379):
    #must import views before running apps
    import views.deps
    app.wsmanager = wsmanager.WebSocketManager()
    def auth(auth, docid):
        doc = docs.Doc.load(current_app.model_redis, docid)
        status = mconv.can_write_doc_api(doc, auth, current_app)
        return status
    app.wsmanager.register_auth("bokehplot", auth)
    app.ph = protocol.ProtocolHelper()
    app.collections = ContinuumModelsStorage(
        redis.Redis(host=rhost, port=rport, db=2)
        )
    #for non-backbone models
    app.model_redis = redis.Redis(host=rhost, port=rport, db=3)
    app.pubsub_redis = redis.Redis(host=rhost, port=rport, db=4)
    app.secret_key = str(uuid.uuid4())

def make_default_user(app):
    docid = "defaultdoc"
    bokehuser = user.new_user(app.model_redis, "defaultuser",
                            str(uuid.uuid4()),
                            docs=[doc.docid])
    return bokehuser

def prepare_local():
    #monkeypatching
    def current_user(request):
        bokehuser = user.User.load(app.model_redis, "defaultuser")
        if bokehuser is None:
            bokehuser = make_default_user(app)
        return bokehuser
    def write_plot_file(username, codedata):
        return
    app.current_user = current_user
    app.write_plot_file = write_plot_file

http_server = None

def start_app(verbose=False):
    global http_server
    if verbose:
        print "Starting server on port 5006..."
    http_server = WSGIServer(('', 5006), app,
                             handler_class=WebSocketHandler,
                             )
    http_server.serve_forever()

#database

#logging
<commit_msg>broke default non-wakari users doing wakari work<commit_after>from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
from flask import request, current_app
import gevent
import gevent.monkey
gevent.monkey.patch_all()
import uuid
import socket
import redis

#server imports
from app import app
import wsmanager
from .. import protocol
from serverbb import ContinuumModelsStorage
from .. import bbmodel
bbmodel.load_special_types()

import models.user as user
import models.convenience as mconv
import models.docs as docs

import logging
import time
port = 5006
log = logging.getLogger(__name__)

def prepare_app(rhost='127.0.0.1', rport=6379):
    #must import views before running apps
    import views.deps
    app.wsmanager = wsmanager.WebSocketManager()
    def auth(auth, docid):
        doc = docs.Doc.load(current_app.model_redis, docid)
        status = mconv.can_write_doc_api(doc, auth, current_app)
        return status
    app.wsmanager.register_auth("bokehplot", auth)
    app.ph = protocol.ProtocolHelper()
    app.collections = ContinuumModelsStorage(
        redis.Redis(host=rhost, port=rport, db=2)
        )
    #for non-backbone models
    app.model_redis = redis.Redis(host=rhost, port=rport, db=3)
    app.pubsub_redis = redis.Redis(host=rhost, port=rport, db=4)
    app.secret_key = str(uuid.uuid4())

def make_default_user(app):
    docid = "defaultdoc"
    bokehuser = user.new_user(app.model_redis, "defaultuser",
                              str(uuid.uuid4()), apikey='nokey', docs=[])

    return bokehuser

def prepare_local():
    #monkeypatching
    def current_user(request):
        bokehuser = user.User.load(app.model_redis, "defaultuser")
        if bokehuser is None:
            bokehuser = make_default_user(app)
        return bokehuser
    def write_plot_file(username, codedata):
        return
    app.current_user = current_user
    app.write_plot_file = write_plot_file

http_server = None

def start_app(verbose=False):
    global http_server
    if verbose:
        print "Starting server on port 5006..."
    http_server = WSGIServer(('', 5006), app,
                             handler_class=WebSocketHandler,
                             )
    http_server.serve_forever()

#database

#logging
<|endoftext|>


<commit_before>import unicodecsv
from cStringIO import StringIO
from intelmq.lib.bot import Bot, sys
from intelmq.lib.message import Event
from intelmq.lib.utils import encode
from intelmq.bots import utils

class MalwareDomainListParserBot(Bot):

    def process(self):
        report = self.receive_message()

        if report:
            report = encode(report)

            columns = ["source_time", "source_url", "source_ip", "source_reverse_dns", "malware", "__IGNORE__", "source_asn"]

            for row in unicodecsv.reader(StringIO(report), encoding='utf-8'):
                event = Event()

                with open('/tmp/test.txt','a') as fp:
                    fp.write(str(row))

                for key, value in zip(columns, row):

                    if key is "__IGNORE__":
                        continue

                    if key is "source_time":
                        value = value.replace('_',' ')
                        value += " UTC"

                    if key is "malware":
                        value = value.lower()

                    event.add(key, value)

                event.add('feed', 'malwaredomainslist')
                event.add('feed_url', 'http://www.malwaredomainlist.com/updatescsv.php')
                event.add('type', 'malware')    # FIXME

                event = utils.parse_source_time(event, "source_time")
                event = utils.generate_observation_time(event, "observation_time")
                event = utils.generate_reported_fields(event)

                self.send_message(event)
        self.acknowledge_message()

if __name__ == "__main__":
    bot = MalwareDomainListParserBot(sys.argv[1])
    bot.start()
<commit_msg>Update parser.py<commit_after>import unicodecsv
from cStringIO import StringIO
from intelmq.lib.bot import Bot, sys
from intelmq.lib.message import Event
from intelmq.lib.utils import encode
from intelmq.bots import utils

class MalwareDomainListParserBot(Bot):

    def process(self):
        report = self.receive_message()

        if report:
            report = encode(report)

            columns = ["source_time", "source_url", "source_ip", "source_reverse_dns", "malware", "__IGNORE__", "source_asn"]

            for row in unicodecsv.reader(StringIO(report), encoding='utf-8'):
                event = Event()

                for key, value in zip(columns, row):

                    if key is "__IGNORE__":
                        continue

                    if key is "source_time":
                        value = value.replace('_',' ')
                        value += " UTC"

                    if key is "malware":
                        value = value.lower()

                    event.add(key, value)

                event.add('feed', 'malwaredomainslist')
                event.add('feed_url', 'http://www.malwaredomainlist.com/updatescsv.php')
                event.add('type', 'malware')    # FIXME

                event = utils.parse_source_time(event, "source_time")
                event = utils.generate_observation_time(event, "observation_time")
                event = utils.generate_reported_fields(event)

                self.send_message(event)
        self.acknowledge_message()

if __name__ == "__main__":
    bot = MalwareDomainListParserBot(sys.argv[1])
    bot.start()
<|endoftext|>


<commit_before>import unicodecsv
from intelmq.lib.utils import encode
from cStringIO import StringIO
from intelmq.lib.bot import Bot, sys
from intelmq.lib.message import Event
from intelmq.bots import utils

class MalwareDomainListParserBot(Bot):

    def process(self):
        report = self.receive_message()

        if report:
            report = encode(report)
            report = report.strip()

            columns = ["source_time", "source_url", "source_ip", "source_reverse_dns", "malware", "__IGNORE__", "source_asn"]
            #rows = csv.DictReader(StringIO.StringIO(report), fieldnames = columns)

            for row in unicodecsv.reader(StringIO(report), encoding='utf-8'):
                event = Event()

                for key, value in zip(columns, row):

                #for key, value in row.items():

                    if key is "__IGNORE__":
                        continue

                    if key is "source_time":
                        value = value.replace('_',' ')
                        value += " UTC"

                    if key is "malware":
                        value = value.lower()

                    event.add(key, value)

                event.add('feed', 'malwaredomainslist')
                event.add('feed_url', 'http://www.malwaredomainlist.com/updatescsv.php')
                event.add('type', 'malware')    # FIXME

                event = utils.parse_source_time(event, "source_time")
                event = utils.generate_observation_time(event, "observation_time")
                event = utils.generate_reported_fields(event)

                self.send_message(event)
        self.acknowledge_message()

if __name__ == "__main__":
    bot = MalwareDomainListParserBot(sys.argv[1])
    bot.start()
<commit_msg>Update parser.py<commit_after>import unicodecsv
from cStringIO import StringIO
from intelmq.lib.bot import Bot, sys
from intelmq.lib.message import Event
from intelmq.lib.utils import encode
from intelmq.bots import utils

class MalwareDomainListParserBot(Bot):

    def process(self):
        report = self.receive_message()

        if report:
            report = encode(report)

            columns = ["source_time", "source_url", "source_ip", "source_reverse_dns", "malware", "__IGNORE__", "source_asn"]

            for row in unicodecsv.reader(StringIO(report), encoding='utf-8'):
                event = Event()

                for key, value in zip(columns, row):

                    if key is "__IGNORE__":
                        continue

                    if key is "source_time":
                        value = value.replace('_',' ')
                        value += " UTC"

                    if key is "malware":
                        value = value.lower()

                    event.add(key, value)

                event.add('feed', 'malwaredomainslist')
                event.add('feed_url', 'http://www.malwaredomainlist.com/updatescsv.php')
                event.add('type', 'malware')    # FIXME

                event = utils.parse_source_time(event, "source_time")
                event = utils.generate_observation_time(event, "observation_time")
                event = utils.generate_reported_fields(event)

                self.send_message(event)
        self.acknowledge_message()

if __name__ == "__main__":
    bot = MalwareDomainListParserBot(sys.argv[1])
    bot.start()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import json
import logging
import asyncio
import aiohttp

class Exchanges():
    def __init__(self):
        header = {
            'content-type': 'application/json',
            'User-Agent': 'Mozilla/5.0 Gecko/20100101 Firefox/22.0'}
        self.session = aiohttp.ClientSession(headers=header)
        self.log = logging.getLogger('bts')
        self.order_types = ["bids", "asks"]

    @asyncio.coroutine
    def orderbook_btc38(self, quote="cny", base="bts"):
        try:
            url = "http://api.btc38.com/v1/depth.php"
            params = {'c': base, 'mk_type': quote}
            response = yield from asyncio.wait_for(self.session.get(
                url, params=params), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            for order_type in self.order_types:
                for order in result[order_type]:
                    order[0] = float(order[0])
                    order[1] = float(order[1])
            order_book_ask = sorted(result["asks"])
            order_book_bid = sorted(result["bids"], reverse=True)
            return {"bids": order_book_bid, "asks": order_book_ask}
        except:
            self.log.error("Error fetching book from btc38!")

    @asyncio.coroutine
    def orderbook_bter(self, quote="cny", base="bts"):
        try:
            url = "http://data.bter.com/api/1/depth/%s_%s" % (base, quote)
            response = yield from asyncio.wait_for(self.session.get(
                url), 120)
            result = yield from response.json()
            for order_type in self.order_types:
                for order in result[order_type]:
                    order[0] = float(order[0])
                    order[1] = float(order[1])
            order_book_ask = sorted(result["asks"])
            order_book_bid = sorted(result["bids"], reverse=True)
            return {"bids": order_book_bid, "asks": order_book_ask}
        except:
            self.log.error("Error fetching book from bter!")

    @asyncio.coroutine
    def orderbook_yunbi(self, quote="cny", base="bts"):
        try:
            url = "https://yunbi.com/api/v2/depth.json"
            params = {'market': base+quote, 'limit': 20}
            response = yield from asyncio.wait_for(self.session.get(
                url, params=params), 120)
            result = yield from response.json()
            for order_type in self.order_types:
                for order in result[order_type]:
                    order[0] = float(order[0])
                    order[1] = float(order[1])
            order_book_ask = sorted(result["asks"])
            order_book_bid = sorted(result["bids"], reverse=True)
            time = int(result["timestamp"])
            return {
                "bids": order_book_bid, "asks": order_book_ask, "time": time}
        except:
            self.log.error("Error fetching book from yunbi!")

    @asyncio.coroutine
    def orderbook_poloniex(self, quote="btc", base="bts"):
        try:
            quote = quote.upper()
            base = base.upper()
            url = "http://poloniex.com/public"
            params = {
                "command": "returnOrderBook",
                "currencyPair": "%s_%s" % (quote, base),
                "depth": 50
                }

            response = yield from asyncio.wait_for(self.session.get(
                url, params=params), 120)
            result = yield from response.json()
            for order_type in self.order_types:
                for order in result[order_type]:
                    order[0] = float(order[0])
                    order[1] = float(order[1])
            order_book_ask = sorted(result["asks"])
            order_book_bid = sorted(result["bids"], reverse=True)
            return {"bids": order_book_bid, "asks": order_book_ask}
        except:
            self.log.error("Error fetching book from poloniex!")

    @asyncio.coroutine
    def ticker_btc38(self, quote="cny", base="bts"):
        try:
            url = "http://api.btc38.com/v1/ticker.php?c=%s&mk_type=%s" % (
                base, quote)
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            _ticker = result["ticker"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            return _ticker
        except:
            self.log.error("Error fetching ticker from btc38!")

    @asyncio.coroutine
    def ticker_poloniex(self, quote="USDT", base="BTC"):
        try:

            url = "https://poloniex.com/public?command=returnTicker"
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(
                response.decode("utf-8-sig"))["%s_%s" % (quote, base)]
            _ticker = {}
            _ticker["last"] = result["last"]
            _ticker["vol"] = result["baseVolume"]
            _ticker["buy"] = result["highestBid"]
            _ticker["sell"] = result["lowestAsk"]
            _ticker["low"] = result["low24hr"]
            _ticker["high"] = result["high24hr"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            return _ticker
        except:
            self.log.error("Error fetching ticker from btc38!")

    @asyncio.coroutine
    def ticker_btcchina(self, quote="cny", base="btc"):
        try:
            url = "https://data.btcchina.com/data/ticker?market=%s%s" % (
                base, quote)
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            _ticker = result["ticker"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            _ticker["time"] = int(_ticker["date"])
            return _ticker
        except:
            self.log.error("Error fetching ticker from btcchina!")

    @asyncio.coroutine
    def ticker_huobi(self, base="btc"):
        try:
            url = "http://api.huobi.com/staticmarket/ticker_%s_json.js" % base
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            _ticker = result["ticker"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            _ticker["time"] = int(result['time'])
            return _ticker
        except:
            self.log.error("Error fetching ticker from huobi!")

    @asyncio.coroutine
    def ticker_okcoin_cn(self, quote="cny", base="btc"):
        try:
            url = "https://www.okcoin.cn/api/ticker.do?symbol=%s_%s" % (
                base, quote)
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            _ticker = result["ticker"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            _ticker["time"] = int(result['date'])
            return _ticker
        except:
            self.log.error("Error fetching ticker from okcoin cn!")

    @asyncio.coroutine
    def ticker_okcoin_com(self, quote="usd", base="btc"):
        try:
            url = "https://www.okcoin.com/api/v1/ticker.do?symbol=%s_%s" % (
                base, quote)
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            _ticker = result["ticker"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            _ticker["time"] = int(result['date'])
            return _ticker
        except:
            self.log.error("Error fetching ticker from okcoin com!")

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    exchanges = Exchanges()

    @asyncio.coroutine
    def run_task(coro, *args):
        while True:
            result = yield from coro(*args)
            print(result)
            yield from asyncio.sleep(120)

    tasks = [
        loop.create_task(run_task(exchanges.orderbook_btc38)),
        loop.create_task(run_task(exchanges.orderbook_btc38, "cny", "btc")),
        loop.create_task(run_task(exchanges.orderbook_bter)),
        loop.create_task(run_task(exchanges.orderbook_yunbi)),
        loop.create_task(run_task(exchanges.orderbook_poloniex)),
        loop.create_task(run_task(exchanges.ticker_btc38)),
        loop.create_task(run_task(exchanges.ticker_poloniex)),
        loop.create_task(run_task(exchanges.ticker_btcchina)),
        loop.create_task(run_task(exchanges.ticker_huobi)),
        loop.create_task(run_task(exchanges.ticker_okcoin_cn)),
        loop.create_task(run_task(exchanges.ticker_okcoin_com))
        ]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.run_forever()
<commit_msg>remove log of exchanges<commit_after># -*- coding: utf-8 -*-
import json
import asyncio
import aiohttp

class Exchanges():
    def __init__(self):
        header = {
            'content-type': 'application/json',
            'User-Agent': 'Mozilla/5.0 Gecko/20100101 Firefox/22.0'}
        self.session = aiohttp.ClientSession(headers=header)
        self.order_types = ["bids", "asks"]

    @asyncio.coroutine
    def orderbook_btc38(self, quote="cny", base="bts"):
        try:
            url = "http://api.btc38.com/v1/depth.php"
            params = {'c': base, 'mk_type': quote}
            response = yield from asyncio.wait_for(self.session.get(
                url, params=params), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            for order_type in self.order_types:
                for order in result[order_type]:
                    order[0] = float(order[0])
                    order[1] = float(order[1])
            order_book_ask = sorted(result["asks"])
            order_book_bid = sorted(result["bids"], reverse=True)
            return {"bids": order_book_bid, "asks": order_book_ask}
        except:
            print("Error fetching book from btc38!")

    @asyncio.coroutine
    def orderbook_bter(self, quote="cny", base="bts"):
        try:
            url = "http://data.bter.com/api/1/depth/%s_%s" % (base, quote)
            response = yield from asyncio.wait_for(self.session.get(
                url), 120)
            result = yield from response.json()
            for order_type in self.order_types:
                for order in result[order_type]:
                    order[0] = float(order[0])
                    order[1] = float(order[1])
            order_book_ask = sorted(result["asks"])
            order_book_bid = sorted(result["bids"], reverse=True)
            return {"bids": order_book_bid, "asks": order_book_ask}
        except:
            print("Error fetching book from bter!")

    @asyncio.coroutine
    def orderbook_yunbi(self, quote="cny", base="bts"):
        try:
            url = "https://yunbi.com/api/v2/depth.json"
            params = {'market': base+quote, 'limit': 20}
            response = yield from asyncio.wait_for(self.session.get(
                url, params=params), 120)
            result = yield from response.json()
            for order_type in self.order_types:
                for order in result[order_type]:
                    order[0] = float(order[0])
                    order[1] = float(order[1])
            order_book_ask = sorted(result["asks"])
            order_book_bid = sorted(result["bids"], reverse=True)
            time = int(result["timestamp"])
            return {
                "bids": order_book_bid, "asks": order_book_ask, "time": time}
        except:
            print("Error fetching book from yunbi!")

    @asyncio.coroutine
    def orderbook_poloniex(self, quote="btc", base="bts"):
        try:
            quote = quote.upper()
            base = base.upper()
            url = "http://poloniex.com/public"
            params = {
                "command": "returnOrderBook",
                "currencyPair": "%s_%s" % (quote, base),
                "depth": 50
                }

            response = yield from asyncio.wait_for(self.session.get(
                url, params=params), 120)
            result = yield from response.json()
            for order_type in self.order_types:
                for order in result[order_type]:
                    order[0] = float(order[0])
                    order[1] = float(order[1])
            order_book_ask = sorted(result["asks"])
            order_book_bid = sorted(result["bids"], reverse=True)
            return {"bids": order_book_bid, "asks": order_book_ask}
        except:
            print("Error fetching book from poloniex!")

    @asyncio.coroutine
    def ticker_btc38(self, quote="cny", base="bts"):
        try:
            url = "http://api.btc38.com/v1/ticker.php?c=%s&mk_type=%s" % (
                base, quote)
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            _ticker = result["ticker"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            return _ticker
        except:
            print("Error fetching ticker from btc38!")

    @asyncio.coroutine
    def ticker_poloniex(self, quote="USDT", base="BTC"):
        try:

            url = "https://poloniex.com/public?command=returnTicker"
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(
                response.decode("utf-8-sig"))["%s_%s" % (quote, base)]
            _ticker = {}
            _ticker["last"] = result["last"]
            _ticker["vol"] = result["baseVolume"]
            _ticker["buy"] = result["highestBid"]
            _ticker["sell"] = result["lowestAsk"]
            _ticker["low"] = result["low24hr"]
            _ticker["high"] = result["high24hr"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            return _ticker
        except:
            print("Error fetching ticker from btc38!")

    @asyncio.coroutine
    def ticker_btcchina(self, quote="cny", base="btc"):
        try:
            url = "https://data.btcchina.com/data/ticker?market=%s%s" % (
                base, quote)
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            _ticker = result["ticker"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            _ticker["time"] = int(_ticker["date"])
            return _ticker
        except:
            print("Error fetching ticker from btcchina!")

    @asyncio.coroutine
    def ticker_huobi(self, base="btc"):
        try:
            url = "http://api.huobi.com/staticmarket/ticker_%s_json.js" % base
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            _ticker = result["ticker"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            _ticker["time"] = int(result['time'])
            return _ticker
        except:
            print("Error fetching ticker from huobi!")

    @asyncio.coroutine
    def ticker_okcoin_cn(self, quote="cny", base="btc"):
        try:
            url = "https://www.okcoin.cn/api/ticker.do?symbol=%s_%s" % (
                base, quote)
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            _ticker = result["ticker"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            _ticker["time"] = int(result['date'])
            return _ticker
        except:
            print("Error fetching ticker from okcoin cn!")

    @asyncio.coroutine
    def ticker_okcoin_com(self, quote="usd", base="btc"):
        try:
            url = "https://www.okcoin.com/api/v1/ticker.do?symbol=%s_%s" % (
                base, quote)
            response = yield from asyncio.wait_for(self.session.get(url), 120)
            response = yield from response.read()
            result = json.loads(response.decode("utf-8-sig"))
            _ticker = result["ticker"]
            for key in _ticker:
                _ticker[key] = float(_ticker[key])
            _ticker["time"] = int(result['date'])
            return _ticker
        except:
            print("Error fetching ticker from okcoin com!")

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    exchanges = Exchanges()

    @asyncio.coroutine
    def run_task(coro, *args):
        while True:
            result = yield from coro(*args)
            print(result)
            yield from asyncio.sleep(120)

    tasks = [
        loop.create_task(run_task(exchanges.orderbook_btc38)),
        loop.create_task(run_task(exchanges.orderbook_btc38, "cny", "btc")),
        loop.create_task(run_task(exchanges.orderbook_bter)),
        loop.create_task(run_task(exchanges.orderbook_yunbi)),
        loop.create_task(run_task(exchanges.orderbook_poloniex)),
        loop.create_task(run_task(exchanges.ticker_btc38)),
        loop.create_task(run_task(exchanges.ticker_poloniex)),
        loop.create_task(run_task(exchanges.ticker_btcchina)),
        loop.create_task(run_task(exchanges.ticker_huobi)),
        loop.create_task(run_task(exchanges.ticker_okcoin_cn)),
        loop.create_task(run_task(exchanges.ticker_okcoin_com))
        ]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.run_forever()
<|endoftext|>