<commit_before># -*- coding: utf-8; -*-
#
# Licensed to CRATE Technology GmbH ("Crate") under one or more contributor
# license agreements.  See the NOTICE file distributed with this work for
# additional information regarding copyright ownership.  Crate licenses
# this file to you 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.
#
# However, if you have executed another commercial license agreement
# with Crate these terms will supersede the license and you may use the
# software solely pursuant to the terms of the relevant commercial agreement.
"""
crate cli

can be used to query crate using SQL
"""
import inspect
import logging
import os
import sys
import select

_has_readline = False
try:
    import readline
    _has_readline = True
except ImportError:
    _has_readline = False

import atexit
from appdirs import user_data_dir

from cmd import Cmd
from argparse import ArgumentParser

from crate import client
from crate.client.exceptions import ConnectionError, Error, Warning
from crate.client.compat import raw_input
from .tabulate import TableFormat, Line, DataRow, tabulate

crate_fmt = TableFormat(lineabove=Line("+", "-", "+", "+"),
                        linebelowheader=Line("+", "-", "+", "+"),
                        linebetweenrows=None,
                        linebelow=Line("+", "-", "+", "+"),
                        headerrow=DataRow("|", "|", "|"),
                        datarow=DataRow("|", "|", "|"),
                        padding=1, with_header_hide=None)

class CrateCmd(Cmd):
    prompt = 'cr> '
    line_delimiter = ';'
    multi_line_prompt = '... '
    NULL = "NULL"

    keywords = [
        "table", "index", "from", "into", "where", "values", "and", "or",
        "set", "with", "by", "using", "like",
        "boolean", "integer", "string", "float", "double", "short", "long",
        "byte", "timestamp", "ip", "object", "dynamic", "strict", "ignored",
        "array", "blob", "primary key",
        "analyzer", "extends", "tokenizer", "char_filters", "token_filters",
        "number_of_replicas", "clustered",
        "refresh", "alter",
    ]

    def __init__(self, stdin=None, stdout=None):
        Cmd.__init__(self, "tab", stdin, stdout)
        self.partial_lines = []

    def do_connect(self, server):
        """
        connect to one or more server
        with "connect servername:port[ servername:port [...]]"
        """
        self.conn = client.connect(servers=server)
        self.cursor = self.conn.cursor()
        results = []
        failed = 0
        for server in self.conn.client.active_servers:
            try:
                server_infos = self.conn.client.server_infos(server)
            except ConnectionError as e:
                failed += 1
                results.append([server, None, False, e.message])
            else:
                results.append(
                    server_infos + (True, "OK", )
                )
        self.pprint(
            results,
            ["server_url", "node_name", "connected", "message"])
        if failed == len(results):
            self.print_error("connect")
        else:
            self.print_success("connect")

    def execute_query(self, statement):
        if self.execute(statement):
            self.pprint(self.cursor.fetchall())
            self.print_rows_selected()

    def execute(self, statement):
        try:
            self.cursor.execute(statement)
            return True
        except ConnectionError:
            print(
                'Use "connect <hostname:port>" to connect to a server first')
        except (Error, Warning) as e:
            if hasattr(e, 'message'):
                print(e.message)
            else:
                print(e)
        return False

    def pprint(self, rows, cols=None):
        if cols is None:
            cols = self.cols()
        rows = [list(map(self._transform_field, row)) for row in rows]
        print(tabulate(rows, headers=cols, tablefmt=crate_fmt))

    def _transform_field(self, field):
        """transform field for displaying"""
        if field is None:
            return self.NULL
        elif isinstance(field, bool):
            return "TRUE" if field else "FALSE"
        else:
            return field

    def cols(self):
        return [c[0] for c in self.cursor.description]

    def do_select(self, statement):
        """execute a SQL select statement

        E.g.:
            "select name from locations where name = 'Algol'"
        """
        self.execute_query('select ' + statement)

    def do_insert(self, statement):
        """execute a SQL insert statement

        E.g.:
            "insert into locations (name) values ('Algol')"
        """
        if self.execute('insert ' + statement):
            self.print_rows_affected("insert")

    def do_delete(self, statement):
        """execute a SQL delete statement

        E.g.:
            "delete from locations where name = 'Algol'"
        """
        if self.execute('delete ' + statement):
            self.print_rows_affected("delete")

    def do_update(self, statement):
        """execute a SQL update statement

        E.g.:
            "update from locations set name = 'newName' where name = 'Algol'"
        """
        if self.execute('update ' + statement):
            self.print_rows_affected("update")

    def do_alter(self, statement):
        """execute a SQL ALTER statement

        E.g.:
            "alter table locations set (number_of_replicas=2)"
        """
        if self.execute('alter ' + statement):
            self.print_success("alter")

    def do_create(self, statement):
        """execute a SQL create statement

        E.g.:
            "create table locations (id integer, name string)"
        """
        if self.execute('create ' + statement):
            self.print_success("create")

    def do_crate(self, statement):
        """alias for ``do_create``"""
        self.do_create(statement)

    def do_drop(self, statement):
        """execute a SQL drop statement

        E.g.:
            "drop table locations"
        """
        if self.execute('drop ' + statement):
            self.print_success("drop")

    def do_copy(self, statement):
        """execute a SQL copy statement

        E.g.:
            "copy locations from 'path/to/import/data.json'"
        """
        if self.execute('copy ' + statement):
            self.print_rows_affected("copy")

    def do_refresh(self, statement):
        """execute a SQL refresh stataement

        E.g.:
            "refresh table locations"
        """
        if self.execute('refresh ' + statement):
            self.print_success("refresh")

    def do_exit(self, *args):
        """exit the shell"""
        self.stdout.write("Bye\n")
        sys.exit(0)

    def do_quit(self, *args):
        """exit the shell"""
        self.stdout.write("Bye\n")
        sys.exit(0)

    do_EOF = do_exit

    def print_rows_affected(self, command):
        """print success status with rows affected and query duration"""
        rowcount = self.cursor.rowcount
        if self.cursor.duration > -1:
            print("{0} OK, {1} row{2} affected ({3:.3f} sec)".format(
                command.upper(), rowcount, "s"[rowcount == 1:],
                float(self.cursor.duration) / 1000))
        else:
            print("{0} OK, {1} row{2} affected".format(
                command.upper(), rowcount, "s"[rowcount == 1:]))

    def print_rows_selected(self):
        """print count of rows in result set and query duration"""
        rowcount = self.cursor.rowcount
        if self.cursor.duration > -1:
            print("SELECT {0} row{1} in set ({2:.3f} sec)".format(
                rowcount, "s"[rowcount == 1:],
                float(self.cursor.duration) / 1000))
        else:
            print("SELECT {0} row{1} in set".format(
                rowcount, "s"[rowcount == 1:]))

    def print_success(self, command):
        """print success status only and duration"""
        if self.cursor.duration > -1:
            print("{0} OK ({1:.3f} sec)".format(
                command.upper(), float(self.cursor.duration) / 1000))
        else:
            print("{0} OK".format(command.upper()))

    def print_error(self, command, exception=None):
        if exception is not None:
            print("{0}: {1}".format(
                exception.__class__.__name__, exception.message))
        if self.cursor.duration > -1:
            print("{0} ERROR ({1:.3f} sec)".format(
                command.upper(), float(self.cursor.duration) / 1000))
        else:
            print("{0} ERROR".format(command.upper()))

    def cmdloop(self, intro=None):
        """Repeatedly issue a prompt, accept input, parse an initial prefix
        off the received input, and dispatch to action methods, passing them
        the remainder of the line as argument.

        """

        self.preloop()
        if self.use_rawinput and self.completekey:
            if _has_readline:
                try:
                    self.old_completer = readline.get_completer()
                    readline.set_completer(self.complete)
                    if getattr(readline, "__doc__") is not None \
                            and 'libedit' in readline.__doc__:
                        readline.parse_and_bind("bind ^I rl_complete")
                    else:
                        readline.parse_and_bind("tab: complete")
                except ImportError:
                    pass
        try:
            if intro is not None:
                self.intro = intro
            if self.intro:
                self.stdout.write(str(self.intro) + "\n")
            stop = None
            prompt = self.prompt
            while not stop:
                if self.cmdqueue:
                    line = self.cmdqueue.pop(0)
                else:
                    if self.use_rawinput:
                        try:
                            line = raw_input(prompt)
                        except EOFError:
                            line = 'EOF'
                    else:
                        self.stdout.write(prompt)
                        self.stdout.flush()
                        line = self.stdin.readline()
                        if not len(line):
                            line = 'EOF'
                        else:
                            line = line.rstrip('\r\n')
                    if (line or self.partial_lines) and line != 'EOF':
                        if line[-1:] != self.line_delimiter:
                            self.partial_lines.append(line)
                            prompt = self.multi_line_prompt
                        else:
                            self.partial_lines.append(
                                line.rstrip(self.line_delimiter))
                            line = " ".join(self.partial_lines)
                            self.partial_lines = []
                            prompt = self.prompt
                if not self.partial_lines or line == 'EOF':
                    line = self.precmd(line)
                    stop = self.onecmd(line)
                    stop = self.postcmd(stop, line)
            self.postloop()
        finally:
            if self.use_rawinput and self.completekey and _has_readline:
                readline.set_completer(self.old_completer)

    def default(self, line):
        if line.lstrip().startswith('--'):
            return  # ignore comments
        Cmd.default(self, line)

    def completedefault(self, text, line, begidx, endidx):
        """Method called to complete an input line when no command-specific
        complete_*() method is available.

        """
        mline = line.split(' ')[-1]
        offs = len(mline) - len(text)
        return [s[offs:] for s in self.keywords if s.startswith(mline)]

    def emptyline(self):
        """Called when an empty line is entered in response to the prompt.
        """
        pass

# uppercase commands
for name, attr in inspect.getmembers(
        CrateCmd,
        lambda attr: inspect.ismethod(attr) or inspect.isfunction(attr)):
    if name.startswith("do_"):
        cmd_name = name.split("do_")[-1]
        setattr(CrateCmd, "do_{0}".format(cmd_name.upper()), attr)

USER_DATA_DIR = user_data_dir("Crate", "Crate")
HISTORY_FILE_NAME = 'crash_history'
HISTORY_PATH = os.path.join(USER_DATA_DIR, HISTORY_FILE_NAME)

def parse_args():
    parser = ArgumentParser(description='crate shell')
    parser.add_argument('-v', '--verbose', action='count',
                        help='use -v to get debug output')
    parser.add_argument('--history',
                        type=str,
                        help='the history file to use', default=HISTORY_PATH)
    parser.add_argument('-c', '--command', type=str,
                        help='execute sql statement')
    parser.add_argument('--hosts', type=str, nargs='*',
                        help='connect to crate hosts', metavar='HOST')
    args = parser.parse_args()
    return args

def get_stdin():
    """Get data from stdin, if any
    """
    # use select.select to check if input is available
    # otherwise sys.stdin would block
    partial_lines = []
    delim = CrateCmd.line_delimiter
    while sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
        line = sys.stdin.readline()
        if line:
            if line.lstrip().startswith('--'):
                continue
            if not line.endswith(delim):
                partial_lines.append(line)
            elif not partial_lines:
                for single_cmd in line.rstrip(delim).split(delim):
                    yield single_cmd
            else:
                partial_lines.append(line)
        else:
            if partial_lines:
                lines = "".join(partial_lines)
                for single_cmd in lines.rstrip(delim).split(delim):
                    yield single_cmd
            break
    return

def main():
    logging.basicConfig(level=logging.ERROR)
    args = parse_args()
    # optionally read and write history file
    if _has_readline:
        history_file_path = args.history
        if not os.path.exists(USER_DATA_DIR):
            os.makedirs(USER_DATA_DIR)
        try:
            readline.read_history_file(history_file_path)
        except IOError:
            pass
        atexit.register(readline.write_history_file, history_file_path)
    cmd = CrateCmd()
    cmd.do_connect(args.hosts)
    # select.select on sys.stdin doesn't work on windows
    # so currently there is no pipe support
    done = False
    if os.name == 'posix':
        stdin_data = get_stdin()
    if args.command:
        for single_cmd in args.command.split(CrateCmd.line_delimiter):
            cmd.onecmd(single_cmd)
        done = True
    elif stdin_data:
        for single_cmd in stdin_data:
            cmd.onecmd(single_cmd)
            done = True
    if not done:
        try:
            cmd.cmdloop()
        except KeyboardInterrupt:
            print("interrupted exiting...")

if __name__ == '__main__':
    main()
<commit_msg>reset partial lines to further save memory<commit_after># -*- coding: utf-8; -*-
#
# Licensed to CRATE Technology GmbH ("Crate") under one or more contributor
# license agreements.  See the NOTICE file distributed with this work for
# additional information regarding copyright ownership.  Crate licenses
# this file to you 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.
#
# However, if you have executed another commercial license agreement
# with Crate these terms will supersede the license and you may use the
# software solely pursuant to the terms of the relevant commercial agreement.
"""
crate cli

can be used to query crate using SQL
"""
import inspect
import logging
import os
import sys
import select

_has_readline = False
try:
    import readline
    _has_readline = True
except ImportError:
    _has_readline = False

import atexit
from appdirs import user_data_dir

from cmd import Cmd
from argparse import ArgumentParser

from crate import client
from crate.client.exceptions import ConnectionError, Error, Warning
from crate.client.compat import raw_input
from .tabulate import TableFormat, Line, DataRow, tabulate

crate_fmt = TableFormat(lineabove=Line("+", "-", "+", "+"),
                        linebelowheader=Line("+", "-", "+", "+"),
                        linebetweenrows=None,
                        linebelow=Line("+", "-", "+", "+"),
                        headerrow=DataRow("|", "|", "|"),
                        datarow=DataRow("|", "|", "|"),
                        padding=1, with_header_hide=None)

class CrateCmd(Cmd):
    prompt = 'cr> '
    line_delimiter = ';'
    multi_line_prompt = '... '
    NULL = "NULL"

    keywords = [
        "table", "index", "from", "into", "where", "values", "and", "or",
        "set", "with", "by", "using", "like",
        "boolean", "integer", "string", "float", "double", "short", "long",
        "byte", "timestamp", "ip", "object", "dynamic", "strict", "ignored",
        "array", "blob", "primary key",
        "analyzer", "extends", "tokenizer", "char_filters", "token_filters",
        "number_of_replicas", "clustered",
        "refresh", "alter",
    ]

    def __init__(self, stdin=None, stdout=None):
        Cmd.__init__(self, "tab", stdin, stdout)
        self.partial_lines = []

    def do_connect(self, server):
        """
        connect to one or more server
        with "connect servername:port[ servername:port [...]]"
        """
        self.conn = client.connect(servers=server)
        self.cursor = self.conn.cursor()
        results = []
        failed = 0
        for server in self.conn.client.active_servers:
            try:
                server_infos = self.conn.client.server_infos(server)
            except ConnectionError as e:
                failed += 1
                results.append([server, None, False, e.message])
            else:
                results.append(
                    server_infos + (True, "OK", )
                )
        self.pprint(
            results,
            ["server_url", "node_name", "connected", "message"])
        if failed == len(results):
            self.print_error("connect")
        else:
            self.print_success("connect")

    def execute_query(self, statement):
        if self.execute(statement):
            self.pprint(self.cursor.fetchall())
            self.print_rows_selected()

    def execute(self, statement):
        try:
            self.cursor.execute(statement)
            return True
        except ConnectionError:
            print(
                'Use "connect <hostname:port>" to connect to a server first')
        except (Error, Warning) as e:
            if hasattr(e, 'message'):
                print(e.message)
            else:
                print(e)
        return False

    def pprint(self, rows, cols=None):
        if cols is None:
            cols = self.cols()
        rows = [list(map(self._transform_field, row)) for row in rows]
        print(tabulate(rows, headers=cols, tablefmt=crate_fmt))

    def _transform_field(self, field):
        """transform field for displaying"""
        if field is None:
            return self.NULL
        elif isinstance(field, bool):
            return "TRUE" if field else "FALSE"
        else:
            return field

    def cols(self):
        return [c[0] for c in self.cursor.description]

    def do_select(self, statement):
        """execute a SQL select statement

        E.g.:
            "select name from locations where name = 'Algol'"
        """
        self.execute_query('select ' + statement)

    def do_insert(self, statement):
        """execute a SQL insert statement

        E.g.:
            "insert into locations (name) values ('Algol')"
        """
        if self.execute('insert ' + statement):
            self.print_rows_affected("insert")

    def do_delete(self, statement):
        """execute a SQL delete statement

        E.g.:
            "delete from locations where name = 'Algol'"
        """
        if self.execute('delete ' + statement):
            self.print_rows_affected("delete")

    def do_update(self, statement):
        """execute a SQL update statement

        E.g.:
            "update from locations set name = 'newName' where name = 'Algol'"
        """
        if self.execute('update ' + statement):
            self.print_rows_affected("update")

    def do_alter(self, statement):
        """execute a SQL ALTER statement

        E.g.:
            "alter table locations set (number_of_replicas=2)"
        """
        if self.execute('alter ' + statement):
            self.print_success("alter")

    def do_create(self, statement):
        """execute a SQL create statement

        E.g.:
            "create table locations (id integer, name string)"
        """
        if self.execute('create ' + statement):
            self.print_success("create")

    def do_crate(self, statement):
        """alias for ``do_create``"""
        self.do_create(statement)

    def do_drop(self, statement):
        """execute a SQL drop statement

        E.g.:
            "drop table locations"
        """
        if self.execute('drop ' + statement):
            self.print_success("drop")

    def do_copy(self, statement):
        """execute a SQL copy statement

        E.g.:
            "copy locations from 'path/to/import/data.json'"
        """
        if self.execute('copy ' + statement):
            self.print_rows_affected("copy")

    def do_refresh(self, statement):
        """execute a SQL refresh stataement

        E.g.:
            "refresh table locations"
        """
        if self.execute('refresh ' + statement):
            self.print_success("refresh")

    def do_exit(self, *args):
        """exit the shell"""
        self.stdout.write("Bye\n")
        sys.exit(0)

    def do_quit(self, *args):
        """exit the shell"""
        self.stdout.write("Bye\n")
        sys.exit(0)

    do_EOF = do_exit

    def print_rows_affected(self, command):
        """print success status with rows affected and query duration"""
        rowcount = self.cursor.rowcount
        if self.cursor.duration > -1:
            print("{0} OK, {1} row{2} affected ({3:.3f} sec)".format(
                command.upper(), rowcount, "s"[rowcount == 1:],
                float(self.cursor.duration) / 1000))
        else:
            print("{0} OK, {1} row{2} affected".format(
                command.upper(), rowcount, "s"[rowcount == 1:]))

    def print_rows_selected(self):
        """print count of rows in result set and query duration"""
        rowcount = self.cursor.rowcount
        if self.cursor.duration > -1:
            print("SELECT {0} row{1} in set ({2:.3f} sec)".format(
                rowcount, "s"[rowcount == 1:],
                float(self.cursor.duration) / 1000))
        else:
            print("SELECT {0} row{1} in set".format(
                rowcount, "s"[rowcount == 1:]))

    def print_success(self, command):
        """print success status only and duration"""
        if self.cursor.duration > -1:
            print("{0} OK ({1:.3f} sec)".format(
                command.upper(), float(self.cursor.duration) / 1000))
        else:
            print("{0} OK".format(command.upper()))

    def print_error(self, command, exception=None):
        if exception is not None:
            print("{0}: {1}".format(
                exception.__class__.__name__, exception.message))
        if self.cursor.duration > -1:
            print("{0} ERROR ({1:.3f} sec)".format(
                command.upper(), float(self.cursor.duration) / 1000))
        else:
            print("{0} ERROR".format(command.upper()))

    def cmdloop(self, intro=None):
        """Repeatedly issue a prompt, accept input, parse an initial prefix
        off the received input, and dispatch to action methods, passing them
        the remainder of the line as argument.

        """

        self.preloop()
        if self.use_rawinput and self.completekey:
            if _has_readline:
                try:
                    self.old_completer = readline.get_completer()
                    readline.set_completer(self.complete)
                    if getattr(readline, "__doc__") is not None \
                            and 'libedit' in readline.__doc__:
                        readline.parse_and_bind("bind ^I rl_complete")
                    else:
                        readline.parse_and_bind("tab: complete")
                except ImportError:
                    pass
        try:
            if intro is not None:
                self.intro = intro
            if self.intro:
                self.stdout.write(str(self.intro) + "\n")
            stop = None
            prompt = self.prompt
            while not stop:
                if self.cmdqueue:
                    line = self.cmdqueue.pop(0)
                else:
                    if self.use_rawinput:
                        try:
                            line = raw_input(prompt)
                        except EOFError:
                            line = 'EOF'
                    else:
                        self.stdout.write(prompt)
                        self.stdout.flush()
                        line = self.stdin.readline()
                        if not len(line):
                            line = 'EOF'
                        else:
                            line = line.rstrip('\r\n')
                    if (line or self.partial_lines) and line != 'EOF':
                        if line[-1:] != self.line_delimiter:
                            self.partial_lines.append(line)
                            prompt = self.multi_line_prompt
                        else:
                            self.partial_lines.append(
                                line.rstrip(self.line_delimiter))
                            line = " ".join(self.partial_lines)
                            self.partial_lines = []
                            prompt = self.prompt
                if not self.partial_lines or line == 'EOF':
                    line = self.precmd(line)
                    stop = self.onecmd(line)
                    stop = self.postcmd(stop, line)
            self.postloop()
        finally:
            if self.use_rawinput and self.completekey and _has_readline:
                readline.set_completer(self.old_completer)

    def default(self, line):
        if line.lstrip().startswith('--'):
            return  # ignore comments
        Cmd.default(self, line)

    def completedefault(self, text, line, begidx, endidx):
        """Method called to complete an input line when no command-specific
        complete_*() method is available.

        """
        mline = line.split(' ')[-1]
        offs = len(mline) - len(text)
        return [s[offs:] for s in self.keywords if s.startswith(mline)]

    def emptyline(self):
        """Called when an empty line is entered in response to the prompt.
        """
        pass

# uppercase commands
for name, attr in inspect.getmembers(
        CrateCmd,
        lambda attr: inspect.ismethod(attr) or inspect.isfunction(attr)):
    if name.startswith("do_"):
        cmd_name = name.split("do_")[-1]
        setattr(CrateCmd, "do_{0}".format(cmd_name.upper()), attr)

USER_DATA_DIR = user_data_dir("Crate", "Crate")
HISTORY_FILE_NAME = 'crash_history'
HISTORY_PATH = os.path.join(USER_DATA_DIR, HISTORY_FILE_NAME)

def parse_args():
    parser = ArgumentParser(description='crate shell')
    parser.add_argument('-v', '--verbose', action='count',
                        help='use -v to get debug output')
    parser.add_argument('--history',
                        type=str,
                        help='the history file to use', default=HISTORY_PATH)
    parser.add_argument('-c', '--command', type=str,
                        help='execute sql statement')
    parser.add_argument('--hosts', type=str, nargs='*',
                        help='connect to crate hosts', metavar='HOST')
    args = parser.parse_args()
    return args

def get_stdin():
    """Get data from stdin, if any
    """
    # use select.select to check if input is available
    # otherwise sys.stdin would block
    partial_lines = []
    delim = CrateCmd.line_delimiter
    while sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
        line = sys.stdin.readline()
        if line:
            line = line.strip()
            if line.startswith('--'):
                continue
            if line.endswith(delim):
                line = line.rstrip(delim)
                if partial_lines:
                    yield ''.join(partial_lines) + line
                    partial_lines = []
                else:
                    yield line
            else:
                partial_lines.append(line)
        else:
            if partial_lines:
                yield ''.join(partial_lines) + line
            break
    return

def main():
    logging.basicConfig(level=logging.ERROR)
    args = parse_args()
    # optionally read and write history file
    if _has_readline:
        history_file_path = args.history
        if not os.path.exists(USER_DATA_DIR):
            os.makedirs(USER_DATA_DIR)
        try:
            readline.read_history_file(history_file_path)
        except IOError:
            pass
        atexit.register(readline.write_history_file, history_file_path)
    cmd = CrateCmd()
    cmd.do_connect(args.hosts)
    # select.select on sys.stdin doesn't work on windows
    # so currently there is no pipe support
    done = False
    if os.name == 'posix':
        stdin_data = get_stdin()
    if args.command:
        for single_cmd in args.command.split(CrateCmd.line_delimiter):
            cmd.onecmd(single_cmd)
        done = True
    elif stdin_data:
        for single_cmd in stdin_data:
            cmd.onecmd(single_cmd)
            done = True
    if not done:
        try:
            cmd.cmdloop()
        except KeyboardInterrupt:
            print("interrupted exiting...")

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


<commit_before>########
# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved
#
# 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.

import os
import sys
import unittest
import tempfile
import subprocess

import yaml
import distro
from mock import patch

from cloudify.mocks import MockCloudifyContext
from .. import tasks
sys.path.append(os.path.join(os.path.dirname(__file__), '../'))

distro = distro.id()
PATH = os.path.dirname(__file__)
TEST_SERVICE_NAME = 'filebeat'
TEST_RESOURCE_NAME = 'test_resource'
TEMP_FILEBEAT = os.path.join(tempfile.gettempdir(), 'filebeat')
CONFIG_FILE = os.path.join(TEMP_FILEBEAT, 'filebeat.yml')
os.mkdir(TEMP_FILEBEAT)

class MockNodeProperties(dict):

    def __init__(self, properties):
        self.update(properties)

    def get_all(self):
        return self

def mock_install_ctx():
    install_node_props = {'es_rpm_source_url': 'http://www.mock.com/fb.tar.gz',
                          'test_property': 'test'}
    return _create_mock_context(install_node_props)

def _create_mock_context(install_node_props,
                         node_id='fb_node',
                         service=TEST_SERVICE_NAME):
    mock_node_props = MockNodeProperties(properties=install_node_props)
    return MockCloudifyContext(node_id=node_id,
                               node_name=service,
                               properties=mock_node_props)

class TestFilebeatPlugin(unittest.TestCase):

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_configure_with_inputs_no_file(self):
        '''validate configuration was rendered correctly
        and placed on the right place - with file comprison'''
        dict1 = {
            'inputs': {'string': 'string', 'int': 10, 'list': ['a', 'b', 'c']},
            'outputs': {'string': 'string', 'int': 10,
                        'list': ['a', 'b', 'c']},
            'paths': {'string': 'string', 'int': 10, 'list': ['a', 'b', 'c']}
        }
        tasks.configure('', dict1)
        self.assertTrue(os.isfile(CONFIG_FILE))
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)
        output = subprocess.check_output(['filebeat',
                                          '-c',
                                          CONFIG_FILE,
                                          '-configtest'])
        self.assertNotIn('error', output)

        dict2 = {
            'inputs': None,
            'outputs': {'string': 'string', 'int': None, 'list': ['a',
                                                                  'b',
                                                                  'c']},
            'paths': {'string': 'string', 'int': 10, 'list': None}
        }
        tasks.configure('', dict2)
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)
        output = subprocess.check_output(['filebeat',
                                          '-c',
                                          CONFIG_FILE,
                                          '-configtest'])
        self.assertNotIn('error', output)

        dict3 = {
            'inputs': {'string': None, 'int': 10, 'list': ['a', 'b', 'c']},
            'outputs': None,
            'paths': {'string': 'string', 'int': 10, 'list': None}
        }
        tasks.configure('', dict3)
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)
        self.assertNotIn('error', output)

        dict4 = {
            'inputs': {'string': 'string', 'int': None,
                       'list': ['a', 'b', 'c']},
            'outputs': {'string': None, 'int': 10, 'list': ['a', 'b', 'c']},
            'paths': '',
        }
        tasks.configure('', dict4)
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)
        self.assertNotIn('error', output)

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_configure_with_inputs_and_file(self):
        '''validate configuration was rendered correctly and
         placed on the right place - with file comprison'''
        dict1 = {
            'inputs': {'string': 'string', 'int': 10, 'list': ['a', 'b', 'c']},
            'outputs': {'string': 'string', 'int': 10,
                        'list': ['a', 'b', 'c']},
        }

        tasks.configure('example_with_inputs.yml', dict1)
        self.assertTrue(os.isfile(CONFIG_FILE))
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_configure_with_file_without_inputs(self):
        '''validate configuration was rendered correctly and
         placed on the right place - with file comprison'''
        tasks.configure('example.yml', '')
        self.assertTrue(os.isfile(CONFIG_FILE))
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_download_filebeat(self):
        '''verify file exists after download'''
        filename = tasks.download_filebeat('', PATH)
        if distro in ('ubuntu', 'debian'):
            self.assertEqual(filename, 'filebeat_1.2.3_amd64.deb')
        elif distro in ('centos', 'redhat'):
            self.assertEqual(filename, 'filebeat-1.2.3-x86_64.rpm')
        self.assertTrue(os.isfile(os.path.join(PATH, filename)))

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_download_file(self):
        '''verify file exists after download'''
        filename = tasks._download_file(
            'https://download.elastic.co/beats/filebeat/' +
            'filebeat_1.2.3_amd64.deb',
            PATH)
        self.assertEqual(filename, 'filebeat_1.2.3_amd64.deb')
        self.assertTrue(os.isfile(filename))

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_download_file_failed(self):
        '''verify nothing downloaded'''
        filename = tasks._download_file(None, None)
        self.assertEqual(filename, None)
        self.assertFalse(os.isfile(filename))

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_install_service(self):
        '''verify service is available after installation -
         installation file is provided'''
        if distro in ('ubuntu', 'debian'):
            tasks.install_filebeat('filebeat_1.2.3_amd64.deb', PATH)
            output = subprocess.check_output(['dpkg', '-l', 'filebeat'])
            self.assertIn('filebeat', output)
        elif distro in ('centos', 'redhat'):
            tasks.install_filebeat('filebeat-1.2.3-x86_64.rpm', PATH)
            output = subprocess.check_output(['rpm', '-qa'])
            self.assertIn('filebeat', output)
<commit_msg>poc+tests<commit_after>########
# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved
#
# 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.

import os
import sys
import unittest
import tempfile
import subprocess

import yaml
import distro
from mock import patch

from cloudify.mocks import MockCloudifyContext
from .. import tasks
sys.path.append(os.path.join(os.path.dirname(__file__), '../'))

distro = distro.id()
PATH = os.path.dirname(__file__)
TEST_SERVICE_NAME = 'filebeat'
TEST_RESOURCE_NAME = 'test_resource'
TEMP_FILEBEAT = os.path.join(tempfile.gettempdir(), 'filebeat')
CONFIG_FILE = os.path.join(TEMP_FILEBEAT, 'filebeat.yml')
os.mkdir(TEMP_FILEBEAT)

class MockNodeProperties(dict):

    def __init__(self, properties):
        self.update(properties)

    def get_all(self):
        return self

def mock_install_ctx():
    install_node_props = {'es_rpm_source_url': 'http://www.mock.com/fb.tar.gz',
                          'test_property': 'test'}
    return _create_mock_context(install_node_props)

def _create_mock_context(install_node_props,
                         node_id='fb_node',
                         service=TEST_SERVICE_NAME):
    return MockCloudifyContext(node_id=node_id,
                               node_name=service,
                               properties=install_node_props)

class TestFilebeatPlugin(unittest.TestCase):

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('../tasks.ctx', mock_install_ctx())
    def test_configure_with_inputs_no_file(self):
        '''validate configuration was rendered correctly
        and placed on the right place - with file comprison'''
        dict1 = {
            'inputs': {'string': 'string', 'int': 10, 'list': ['a', 'b', 'c']},
            'outputs': {'string': 'string', 'int': 10,
                        'list': ['a', 'b', 'c']},
            'paths': {'string': 'string', 'int': 10, 'list': ['a', 'b', 'c']}
        }
        tasks.configure('', dict1)
        self.assertTrue(os.isfile(CONFIG_FILE))
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)
        output = subprocess.check_output(['filebeat',
                                          '-c',
                                          CONFIG_FILE,
                                          '-configtest'])
        self.assertNotIn('error', output)

        dict2 = {
            'inputs': None,
            'outputs': {'string': 'string', 'int': None, 'list': ['a',
                                                                  'b',
                                                                  'c']},
            'paths': {'string': 'string', 'int': 10, 'list': None}
        }
        tasks.configure('', dict2)
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)
        output = subprocess.check_output(['filebeat',
                                          '-c',
                                          CONFIG_FILE,
                                          '-configtest'])
        self.assertNotIn('error', output)

        dict3 = {
            'inputs': {'string': None, 'int': 10, 'list': ['a', 'b', 'c']},
            'outputs': None,
            'paths': {'string': 'string', 'int': 10, 'list': None}
        }
        tasks.configure('', dict3)
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)
        self.assertNotIn('error', output)

        dict4 = {
            'inputs': {'string': 'string', 'int': None,
                       'list': ['a', 'b', 'c']},
            'outputs': {'string': None, 'int': 10, 'list': ['a', 'b', 'c']},
            'paths': '',
        }
        tasks.configure('', dict4)
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)
        self.assertNotIn('error', output)

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_configure_with_inputs_and_file(self):
        '''validate configuration was rendered correctly and
         placed on the right place - with file comprison'''
        dict1 = {
            'inputs': {'string': 'string', 'int': 10, 'list': ['a', 'b', 'c']},
            'outputs': {'string': 'string', 'int': 10,
                        'list': ['a', 'b', 'c']},
        }

        tasks.configure('example_with_inputs.yml', dict1)
        self.assertTrue(os.isfile(CONFIG_FILE))
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_configure_with_file_without_inputs(self):
        '''validate configuration was rendered correctly and
         placed on the right place - with file comprison'''
        tasks.configure('example.yml', '')
        self.assertTrue(os.isfile(CONFIG_FILE))
        with open(CONFIG_FILE, "r") as stream:
            try:
                yaml.load(stream)
            except yaml.YAMLError, exc:
                raise AssertionError(exc)

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_download_filebeat(self):
        '''verify file exists after download'''
        filename = tasks.download_filebeat('', PATH)
        if distro in ('ubuntu', 'debian'):
            self.assertEqual(filename, 'filebeat_1.2.3_amd64.deb')
        elif distro in ('centos', 'redhat'):
            self.assertEqual(filename, 'filebeat-1.2.3-x86_64.rpm')
        self.assertTrue(os.isfile(os.path.join(PATH, filename)))

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_download_file(self):
        '''verify file exists after download'''
        filename = tasks._download_file(
            'https://download.elastic.co/beats/filebeat/' +
            'filebeat_1.2.3_amd64.deb',
            PATH)
        self.assertEqual(filename, 'filebeat_1.2.3_amd64.deb')
        self.assertTrue(os.isfile(filename))

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_download_file_failed(self):
        '''verify nothing downloaded'''
        filename = tasks._download_file(None, None)
        self.assertEqual(filename, None)
        self.assertFalse(os.isfile(filename))

    @patch('tasks.FILEBEAT_CONFIG_FILE_DEFAULT', CONFIG_FILE)
    @patch('tasks.FILEBEAT_INSTALL_PATH_DEFAULT', TEMP_FILEBEAT)
    @patch('tasks.ctx', mock_install_ctx())
    def test_install_service(self):
        '''verify service is available after installation -
         installation file is provided'''
        if distro in ('ubuntu', 'debian'):
            tasks.install_filebeat('filebeat_1.2.3_amd64.deb', PATH)
            output = subprocess.check_output(['dpkg', '-l', 'filebeat'])
            self.assertIn('filebeat', output)
        elif distro in ('centos', 'redhat'):
            tasks.install_filebeat('filebeat-1.2.3-x86_64.rpm', PATH)
            output = subprocess.check_output(['rpm', '-qa'])
            self.assertIn('filebeat', output)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# http://google-styleguide.googlecode.com/svn/trunk/pyguide.html

from copy import deepcopy
from flask import request
from flask.ext.classy import FlaskView, route

from smsgw.models import Outbox
from smsgw.lib.utils import response
from smsgw.resources import decorators
# from smsgw.resources.users.schemas import post, put
from smsgw.resources.error.api import ErrorResource
from smsgw.extensions import db

class OutboxResource(FlaskView):
    """ Outbox endpoints """

    route_base = '/users/<uuid:user_uuid>/outbox/'

    @decorators.auth()
    def index(self, **kwargs):
        """
        Getting list of outbox messages
        """
        user = kwargs.get('user')

        return response([message.to_dict() for message in user.outbox.all()])

    @route('/<int:outbox_id>/', methods=['DELETE'])
    @decorators.auth()
    def delete(self, outbox, **kwargs):
        """
        Delete outbox message
        """
        paylod = deepcopy(outbox.to_dict())
        db.session.delete(outbox)
        db.session.commit()

        return response(paylod)
<commit_msg>OutboxResource: added basic post api functionality<commit_after># -*- coding: utf-8 -*-
# http://google-styleguide.googlecode.com/svn/trunk/pyguide.html

from copy import deepcopy
from flask import request
from flask.ext.classy import FlaskView, route

from smsgw.models import Outbox
from smsgw.lib.utils import response
from smsgw.resources import decorators
from smsgw.resources.outbox.schemas import post
from smsgw.resources.error.api import ErrorResource
from smsgw.extensions import db

class OutboxResource(FlaskView):
    """ Outbox endpoints """

    route_base = '/users/<uuid:user_uuid>/outbox/'

    @decorators.auth()
    def index(self, **kwargs):
        """
        Getting list of outbox messages
        """
        user = kwargs.get('user')

        return response([message.to_dict() for message in user.outbox.all()])

    @decorators.jsonschema_validate(post.schema)
    def post(self):
        """
        Creating new message in outbox
        """
        user = kwargs.get('user')
        message = request.json.get('message')
        phone_number = request.json.get('phoneNumber')
        outbox = Outbox.send(phone_number=phone_number,
                             message=message)

        return response(outbox.to_dict(), status_code=201)

    @route('/<int:outbox_id>/', methods=['DELETE'])
    @decorators.auth()
    def delete(self, outbox, **kwargs):
        """
        Delete outbox message
        """
        payload = deepcopy(outbox.to_dict())
        db.session.delete(outbox)
        db.session.commit()

        return response(payload)
<|endoftext|>


<commit_before>#!/usr/bin/python2.5
#
# Copyright 2009 the Melange authors.
#
# 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.

"""Views for GSoCProgram.
"""

__authors__ = [
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
  ]

from soc.logic import dicts
from soc.views.helper import decorators
from soc.views.helper import access # TODO
from soc.views.models import program

from soc.logic.models.host import logic as host_logic
from soc.modules.gsoc.logic.models.program import logic as program_logic
from soc.modules.gsoc.logic.models.org_admin import logic as org_admin_logic

class View(program.View):
  """View methods for the Program model.
  """

  def __init__(self, params=None):
    """Defines the fields and methods required for the base View class
    to provide the user with list, public, create, edit and delete views.

    Params:
      params: a dict with params for this View
    """

    rights = access.Checker(params)
    rights['any_access'] = ['allow']
    rights['show'] = ['allow']
    rights['create'] = [('checkSeeded', ['checkHasActiveRoleForScope',
        host_logic])]
    rights['edit'] = [('checkIsHostForProgram', [program_logic.logic])]
    rights['delete'] = ['checkIsDeveloper']
    rights['assign_slots'] = [('checkIsHostForProgram', [program_logic.logic])]
    rights['slots'] = [('checkIsHostForProgram', [program_logic.logic])]
    rights['show_duplicates'] = [('checkIsHostForProgram',
        [program_logic.logic])]
    rights['assigned_proposals'] = [('checkIsHostForProgram',
        [program_logic.logic])]
    rights['accepted_orgs'] = [('checkIsAfterEvent',
        ['accepted_organization_announced_deadline',
         '__all__', program_logic])]
    rights['list_projects'] = [('checkIsAfterEvent',
        ['accepted_students_announced_deadline',
         '__all__', program_logic])]

    new_params = {}
    new_params['logic'] = program_logic
    new_params['rights'] = rights

    new_params['name'] = "GSoC Program"
    new_params['module_name'] = "program"
    new_params['sidebar_grouping'] = 'Programs'

    new_params['module_package'] = 'soc.modules.gsoc.views.models'
    new_params['url_name'] = 'gsoc/program'

    params = dicts.merge(params, new_params, sub_merge=True)

    super(View, self).__init__(params)

view = View()

accepted_orgs = decorators.view(view.acceptedOrgs)
list_projects = decorators.view(view.acceptedProjects)
admin = decorators.view(view.admin)
assign_slots = decorators.view(view.assignSlots)
assigned_proposals = decorators.view(view.assignedProposals)
create = decorators.view(view.create)
delete = decorators.view(view.delete)
edit = decorators.view(view.edit)
list = decorators.view(view.list)
public = decorators.view(view.public)
export = decorators.view(view.export)
show_duplicates = decorators.view(view.showDuplicates)
slots = decorators.view(view.slots)
home = decorators.view(view.home)
pick = decorators.view(view.pick)
<commit_msg>Added missing Document Prefix to the GSoC Program module.<commit_after>#!/usr/bin/python2.5
#
# Copyright 2009 the Melange authors.
#
# 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.

"""Views for GSoCProgram.
"""

__authors__ = [
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
  ]

from soc.logic import dicts
from soc.views.helper import decorators
from soc.views.helper import access # TODO
from soc.views.models import program

from soc.logic.models.host import logic as host_logic
from soc.modules.gsoc.logic.models.program import logic as program_logic
from soc.modules.gsoc.logic.models.org_admin import logic as org_admin_logic

class View(program.View):
  """View methods for the Program model.
  """

  def __init__(self, params=None):
    """Defines the fields and methods required for the base View class
    to provide the user with list, public, create, edit and delete views.

    Params:
      params: a dict with params for this View
    """

    rights = access.Checker(params)
    rights['any_access'] = ['allow']
    rights['show'] = ['allow']
    rights['create'] = [('checkSeeded', ['checkHasActiveRoleForScope',
        host_logic])]
    rights['edit'] = [('checkIsHostForProgram', [program_logic.logic])]
    rights['delete'] = ['checkIsDeveloper']
    rights['assign_slots'] = [('checkIsHostForProgram', [program_logic.logic])]
    rights['slots'] = [('checkIsHostForProgram', [program_logic.logic])]
    rights['show_duplicates'] = [('checkIsHostForProgram',
        [program_logic.logic])]
    rights['assigned_proposals'] = [('checkIsHostForProgram',
        [program_logic.logic])]
    rights['accepted_orgs'] = [('checkIsAfterEvent',
        ['accepted_organization_announced_deadline',
         '__all__', program_logic])]
    rights['list_projects'] = [('checkIsAfterEvent',
        ['accepted_students_announced_deadline',
         '__all__', program_logic])]

    new_params = {}
    new_params['logic'] = program_logic
    new_params['rights'] = rights

    new_params['name'] = "GSoC Program"
    new_params['module_name'] = "program"
    new_params['sidebar_grouping'] = 'Programs'
    new_params['document_prefix'] = 'gsoc_program'

    new_params['module_package'] = 'soc.modules.gsoc.views.models'
    new_params['url_name'] = 'gsoc/program'

    params = dicts.merge(params, new_params, sub_merge=True)

    super(View, self).__init__(params)

view = View()

accepted_orgs = decorators.view(view.acceptedOrgs)
list_projects = decorators.view(view.acceptedProjects)
admin = decorators.view(view.admin)
assign_slots = decorators.view(view.assignSlots)
assigned_proposals = decorators.view(view.assignedProposals)
create = decorators.view(view.create)
delete = decorators.view(view.delete)
edit = decorators.view(view.edit)
list = decorators.view(view.list)
public = decorators.view(view.public)
export = decorators.view(view.export)
show_duplicates = decorators.view(view.showDuplicates)
slots = decorators.view(view.slots)
home = decorators.view(view.home)
pick = decorators.view(view.pick)
<|endoftext|>


<commit_before># coding: utf-8
# Copyright (c) Pymatgen Development Team.
# Distributed under the terms of the MIT License.

from __future__ import unicode_literals

import numpy as np

from pymatgen.core.structure import Structure
from pymatgen.core.spectrum import Spectrum
from pymatgen.vis.plotters import SpectrumPlotter
from pymatgen.util.plotting import add_fig_kwargs
from monty.json import MSONable

"""
This module provides classes to handle the calculation of the IR spectra
This implementation is adapted from Abipy
https://github.com/abinit/abipy
where it was originally done by Guido Petretto and Matteo Giantomassi
"""

__author__ = "Henrique Miranda, Guido Pettreto, Matteo Giantomassi"
__copyright__ = "Copyright 2018, The Materials Project"
__version__ = "0.1"
__maintainer__ = "Henrique Miranda"
__email__ = "miranda.henrique@gmail.com"
__date__ = "Oct 31, 2018"

class IRDielectricTensor(MSONable):
    """
    Class to handle the Ionic Dielectric Tensor
    The implementation is adapted from Abipy
    See the definitions Eq.(53-54) in :cite:`Gonze1997` PRB55, 10355 (1997).
    """
    def __init__(self, oscillator_strength, ph_freqs_gamma, epsilon_infinity, structure):
        """
        Args:
            oscillatator_strength: IR oscillator strengths as defined
                                   in Eq. 54 in :cite:`Gonze1997` PRB55, 10355 (1997).
            ph_freqs_gamma: Phonon frequencies at the Gamma point
            epsilon_infinity: electronic susceptibility as defined in Eq. 29.
            structure: A Structure object corresponding to the structure used for the calculation.
        """
        self.structure = structure
        self.oscillator_strength = np.array(oscillator_strength).real
        self.ph_freqs_gamma = np.array(ph_freqs_gamma)
        self.epsilon_infinity = np.array(epsilon_infinity)

    @classmethod
    def from_dict(cls, d):
        """
        Returns IRDielectricTensor from dict representation
        """
        structure = Structure.from_dict(d['structure'])
        oscillator_strength = d['oscillator_strength']
        ph_freqs_gamma = d['ph_freqs_gamma']
        epsilon_infinity = d['epsilon_infinity']
        return cls(oscillator_strength, ph_freqs_gamma, epsilon_infinity, structure)

    @property
    def max_phfreq(self):
        """Maximum phonon frequency"""
        return max(self.ph_freqs_gamma)

    @property
    def nph_freqs(self):
        """Number of phonon frequencies"""
        return len(self.ph_freqs_gamma)

    def as_dict(self):
        """
        Json-serializable dict representation of IRDielectricTensor.
        """
        return {"@module": self.__class__.__module__,
                "@class": self.__class__.__name__,
                "oscillator_strength": self.oscillator_strength.tolist(),
                "ph_freqs_gamma": self.ph_freqs_gamma.tolist(),
                "structure": self.structure.as_dict(),
                "epsilon_infinity": self.epsilon_infinity.tolist()}

    def write_json(self, filename):
        """
        Save a json file with this data
        """
        import json
        with open(filename, 'w') as f:
            json.dump(self.as_dict(), f)

    def get_ir_spectra(self, broad=0.00005, emin=0, emax=None, divs=500):
        """
        The IR spectra is obtained for the different directions

        Args:
            broad: a list of broadenings or a single broadening for the phonon peaks
            emin, emax: minimum and maximum energy in which to obtain the spectra
            divs: number of frequency samples between emin and emax

        Returns:
            frequencies: divs array with the frequencies at which the
                         dielectric tensor is calculated
            dielectric_tensor: divsx3x3 numpy array with the dielectric tensor
                         for the range of frequencies
        """
        if isinstance(broad, float):
            broad = [broad]*self.nph_freqs
        if isinstance(broad, list) and len(broad) != self.nph_freqs:
            raise ValueError('The number of elements in the broad_list '
                             'is not the same as the number of frequencies')

        if emax is None:
            emax = self.max_phfreq + max(broad)*20
        frequencies = np.linspace(emin, emax, divs)

        na = np.newaxis
        dielectric_tensor = np.zeros((divs, 3, 3), dtype=complex)
        for i in range(3, len(self.ph_freqs_gamma)):
            g = broad[i] * self.ph_freqs_gamma[i]
            num = self.oscillator_strength[i, :, :]
            den = (self.ph_freqs_gamma[i]**2 - frequencies[:, na, na]**2 - 1j*g)
            dielectric_tensor += num / den
        dielectric_tensor += self.epsilon_infinity[na, :, :]

        return frequencies, dielectric_tensor

    @add_fig_kwargs
    def plot(self, components=('xx',), reim="reim", show_phonon_frequencies=True, xlim=None, ylim=None, **kwargs):
        """
        Helper function to generate the Spectrum plotter and directly plot the results

        Arguments:
            components: A list with the components of the dielectric tensor to plot.
                        Can be either two indexes or a string like 'xx' to plot the (0,0) component
            reim: If 're' (im) is present in the string plots the real (imaginary) part of the dielectric tensor
            show_phonon_frequencies: plot a dot where the phonon frequencies are to help identify IR inactive modes
        """
        plotter = self.get_plotter(components=components, reim=reim, **kwargs)
        plt = plotter.get_plot(xlim=xlim, ylim=ylim)

        if show_phonon_frequencies:
            ph_freqs_gamma = self.ph_freqs_gamma[3:]
            plt.scatter(ph_freqs_gamma*1000, np.zeros_like(ph_freqs_gamma))
        plt.xlabel(r'$\epsilon(\omega)$')
        plt.xlabel(r'Frequency (meV)')
        return plt

    def get_spectrum(self, component, reim, broad=0.00005, emin=0, emax=None, divs=500, label=None):
        """
            component: either two indexes or a string like 'xx' to plot the (0,0) component
            reim: only "re" or "im"
            broad: a list of broadenings or a single broadening for the phonon peaks
        """
        # some check on component and reim value? but not really necessary maybe

        directions_map = {'x': 0, 'y': 1, 'z': 2, 0: 0, 1: 1, 2: 2}
        functions_map = {'re': lambda x: x.real, 'im': lambda x: x.imag}
        reim_label = {'re': 'Re', 'im': 'Im'}
        i, j = [directions_map[direction] for direction in component]
        label = r"%s{$\epsilon_{%s%s}$}" % (reim_label[reim], 'xyz'[i], 'xyz'[j])

        frequencies, dielectric_tensor = self.get_ir_spectra(broad=broad, emin=emin, emax=emax, divs=divs)
        y = functions_map[reim](dielectric_tensor[:, i, j])

        return Spectrum(frequencies*1000, y, label=label)

    def get_plotter(self, components=('xx',), reim="reim", broad=0.00005, emin=0, emax=None, divs=500, **kwargs):
        """
        Return an instance of the Spectrum plotter containing the different requested components

        Arguments:
            components: A list with the components of the dielectric tensor to plot.
                        Can be either two indexes or a string like 'xx' to plot the (0,0) component
            reim: If 're' (im) is present in the string plots the real (imaginary) part of the dielectric tensor
            emin, emax: minimum and maximum energy in which to obtain the spectra
            divs: number of frequency samples between emin and emax
        """

        directions_map = {'x': 0, 'y': 1, 'z': 2, 0: 0, 1: 1, 2: 2}
        functions_map = {'re': lambda x: x.real, 'im': lambda x: x.imag}
        reim_label = {'re': 'Re', 'im': 'Im'}

        plotter = SpectrumPlotter()
        for component in components:
            i, j = [directions_map[direction] for direction in component]
            for fstr in ("re", "im"):
                if fstr in reim:
                    label = r"%s{$\epsilon_{%s%s}$}" % (reim_label[fstr], 'xyz'[i], 'xyz'[j])
                    spectrum = self.get_spectrum(component, fstr, broad=broad, emin=emin, emax=emax, divs=divs)
                    spectrum.XLABEL = r'Frequency (meV)'
                    spectrum.YLABEL = r'$\epsilon(\omega)$'
                    plotter.add_spectrum(label, spectrum)

        return plotter
<commit_msg>Removed functions_map otherwise flake8 complains<commit_after># coding: utf-8
# Copyright (c) Pymatgen Development Team.
# Distributed under the terms of the MIT License.

from __future__ import unicode_literals

import numpy as np

from pymatgen.core.structure import Structure
from pymatgen.core.spectrum import Spectrum
from pymatgen.vis.plotters import SpectrumPlotter
from pymatgen.util.plotting import add_fig_kwargs
from monty.json import MSONable

"""
This module provides classes to handle the calculation of the IR spectra
This implementation is adapted from Abipy
https://github.com/abinit/abipy
where it was originally done by Guido Petretto and Matteo Giantomassi
"""

__author__ = "Henrique Miranda, Guido Pettreto, Matteo Giantomassi"
__copyright__ = "Copyright 2018, The Materials Project"
__version__ = "0.1"
__maintainer__ = "Henrique Miranda"
__email__ = "miranda.henrique@gmail.com"
__date__ = "Oct 31, 2018"

class IRDielectricTensor(MSONable):
    """
    Class to handle the Ionic Dielectric Tensor
    The implementation is adapted from Abipy
    See the definitions Eq.(53-54) in :cite:`Gonze1997` PRB55, 10355 (1997).
    """
    def __init__(self, oscillator_strength, ph_freqs_gamma, epsilon_infinity, structure):
        """
        Args:
            oscillatator_strength: IR oscillator strengths as defined
                                   in Eq. 54 in :cite:`Gonze1997` PRB55, 10355 (1997).
            ph_freqs_gamma: Phonon frequencies at the Gamma point
            epsilon_infinity: electronic susceptibility as defined in Eq. 29.
            structure: A Structure object corresponding to the structure used for the calculation.
        """
        self.structure = structure
        self.oscillator_strength = np.array(oscillator_strength).real
        self.ph_freqs_gamma = np.array(ph_freqs_gamma)
        self.epsilon_infinity = np.array(epsilon_infinity)

    @classmethod
    def from_dict(cls, d):
        """
        Returns IRDielectricTensor from dict representation
        """
        structure = Structure.from_dict(d['structure'])
        oscillator_strength = d['oscillator_strength']
        ph_freqs_gamma = d['ph_freqs_gamma']
        epsilon_infinity = d['epsilon_infinity']
        return cls(oscillator_strength, ph_freqs_gamma, epsilon_infinity, structure)

    @property
    def max_phfreq(self):
        """Maximum phonon frequency"""
        return max(self.ph_freqs_gamma)

    @property
    def nph_freqs(self):
        """Number of phonon frequencies"""
        return len(self.ph_freqs_gamma)

    def as_dict(self):
        """
        Json-serializable dict representation of IRDielectricTensor.
        """
        return {"@module": self.__class__.__module__,
                "@class": self.__class__.__name__,
                "oscillator_strength": self.oscillator_strength.tolist(),
                "ph_freqs_gamma": self.ph_freqs_gamma.tolist(),
                "structure": self.structure.as_dict(),
                "epsilon_infinity": self.epsilon_infinity.tolist()}

    def write_json(self, filename):
        """
        Save a json file with this data
        """
        import json
        with open(filename, 'w') as f:
            json.dump(self.as_dict(), f)

    def get_ir_spectra(self, broad=0.00005, emin=0, emax=None, divs=500):
        """
        The IR spectra is obtained for the different directions

        Args:
            broad: a list of broadenings or a single broadening for the phonon peaks
            emin, emax: minimum and maximum energy in which to obtain the spectra
            divs: number of frequency samples between emin and emax

        Returns:
            frequencies: divs array with the frequencies at which the
                         dielectric tensor is calculated
            dielectric_tensor: divsx3x3 numpy array with the dielectric tensor
                         for the range of frequencies
        """
        if isinstance(broad, float):
            broad = [broad]*self.nph_freqs
        if isinstance(broad, list) and len(broad) != self.nph_freqs:
            raise ValueError('The number of elements in the broad_list '
                             'is not the same as the number of frequencies')

        if emax is None:
            emax = self.max_phfreq + max(broad)*20
        frequencies = np.linspace(emin, emax, divs)

        na = np.newaxis
        dielectric_tensor = np.zeros((divs, 3, 3), dtype=complex)
        for i in range(3, len(self.ph_freqs_gamma)):
            g = broad[i] * self.ph_freqs_gamma[i]
            num = self.oscillator_strength[i, :, :]
            den = (self.ph_freqs_gamma[i]**2 - frequencies[:, na, na]**2 - 1j*g)
            dielectric_tensor += num / den
        dielectric_tensor += self.epsilon_infinity[na, :, :]

        return frequencies, dielectric_tensor

    @add_fig_kwargs
    def plot(self, components=('xx',), reim="reim", show_phonon_frequencies=True, xlim=None, ylim=None, **kwargs):
        """
        Helper function to generate the Spectrum plotter and directly plot the results

        Arguments:
            components: A list with the components of the dielectric tensor to plot.
                        Can be either two indexes or a string like 'xx' to plot the (0,0) component
            reim: If 're' (im) is present in the string plots the real (imaginary) part of the dielectric tensor
            show_phonon_frequencies: plot a dot where the phonon frequencies are to help identify IR inactive modes
        """
        plotter = self.get_plotter(components=components, reim=reim, **kwargs)
        plt = plotter.get_plot(xlim=xlim, ylim=ylim)

        if show_phonon_frequencies:
            ph_freqs_gamma = self.ph_freqs_gamma[3:]
            plt.scatter(ph_freqs_gamma*1000, np.zeros_like(ph_freqs_gamma))
        plt.xlabel(r'$\epsilon(\omega)$')
        plt.xlabel(r'Frequency (meV)')
        return plt

    def get_spectrum(self, component, reim, broad=0.00005, emin=0, emax=None, divs=500, label=None):
        """
            component: either two indexes or a string like 'xx' to plot the (0,0) component
            reim: only "re" or "im"
            broad: a list of broadenings or a single broadening for the phonon peaks
        """
        # some check on component and reim value? but not really necessary maybe

        directions_map = {'x': 0, 'y': 1, 'z': 2, 0: 0, 1: 1, 2: 2}
        functions_map = {'re': lambda x: x.real, 'im': lambda x: x.imag}
        reim_label = {'re': 'Re', 'im': 'Im'}
        i, j = [directions_map[direction] for direction in component]
        label = r"%s{$\epsilon_{%s%s}$}" % (reim_label[reim], 'xyz'[i], 'xyz'[j])

        frequencies, dielectric_tensor = self.get_ir_spectra(broad=broad, emin=emin, emax=emax, divs=divs)
        y = functions_map[reim](dielectric_tensor[:, i, j])

        return Spectrum(frequencies*1000, y, label=label)

    def get_plotter(self, components=('xx',), reim="reim", broad=0.00005, emin=0, emax=None, divs=500, **kwargs):
        """
        Return an instance of the Spectrum plotter containing the different requested components

        Arguments:
            components: A list with the components of the dielectric tensor to plot.
                        Can be either two indexes or a string like 'xx' to plot the (0,0) component
            reim: If 're' (im) is present in the string plots the real (imaginary) part of the dielectric tensor
            emin, emax: minimum and maximum energy in which to obtain the spectra
            divs: number of frequency samples between emin and emax
        """

        directions_map = {'x': 0, 'y': 1, 'z': 2, 0: 0, 1: 1, 2: 2}
        reim_label = {'re': 'Re', 'im': 'Im'}

        plotter = SpectrumPlotter()
        for component in components:
            i, j = [directions_map[direction] for direction in component]
            for fstr in ("re", "im"):
                if fstr in reim:
                    label = r"%s{$\epsilon_{%s%s}$}" % (reim_label[fstr], 'xyz'[i], 'xyz'[j])
                    spectrum = self.get_spectrum(component, fstr, broad=broad, emin=emin, emax=emax, divs=divs)
                    spectrum.XLABEL = r'Frequency (meV)'
                    spectrum.YLABEL = r'$\epsilon(\omega)$'
                    plotter.add_spectrum(label, spectrum)

        return plotter
<|endoftext|>


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

import os, sys, argparse, os.path, json, time, signal, atexit
#NOTE: This script uses pygments for RGB->X256 conversion since pygments is
#readily available. If you do not like pygments (e.g. because it is large),
#you could patch in something like https://github.com/magarcia/python-x256
#(but don't forget to send me a pull request ;)
from pygments.formatters import terminal256
from PIL import Image, GifImagePlugin, ImageSequence

formatter = terminal256.Terminal256Formatter()
reset_sequence = terminal256.EscapeSequence(fg=formatter._closest_color(0,0,0), bg=formatter._closest_color(0,0,0)).reset_string()
clear_screen = '\033[H\033[2J'
cursor_invisible = '\033[?25l'
cursor_visible = '\033[?25h'

def termify_pixels(img):
	sx, sy = img.size
	out = ''

	fg,bg = None,None
	fgd,bgd = {},{}
	def bgescape(color):
		nonlocal bg, bgd
		if bg == color:
			return ''
		bg=color
		if color == (0,0,0,0):
			return '\033[49m'
		if color in bgd:
			return bgd[color]
		r,g,b,_ = color
		bgd[color] = '\033[48;5;'+str(formatter._closest_color(r,g,b))+'m'
		return bgd[color]

	def fgescape(color):
		nonlocal fg, fgd
		if fg == color:
			return ''
		fg=color
		r,g,b,_ = color
		fgd[color] = '\033[38;5;'+str(formatter._closest_color(r,g,b))+'m'
		return fgd[color]

	def balloon(x,y):
		if x+1 == img.size[0] or img.im.getpixel((x+1, y)) != (0,255,0,127):
			w = 1
			while x-w >= 0 and img.im.getpixel((x-w, y)) == (0,255,0,127):
				w += 1
			return '$balloon{}$'.format(w)
		return ''

	for y in range(0, sy, 2):
		for x in range(sx):
			coltop = img.im.getpixel((x, y))
			colbot = img.im.getpixel((x, y+1)) if y+1 < img.size[1] else (0,0,0,0)

			if coltop[3] == 127: #Control colors
				out += reset_sequence
				out += {(255, 0, 0, 127): lambda x,y:'$\\$',
						(0, 0, 255, 127): lambda x,y:'$/$',
						(0, 255, 0, 127): balloon
					   }.get(coltop, lambda x,y:' ')(x,y)
				continue

			if coltop[3] != 255:
				coltop = (0,0,0,0)
			if colbot[3] != 255:
				colbot = (0,0,0,0)

			#Da magicks: ▀█▄
			c,cf = '▀','█'
			te,be = fgescape,bgescape
			if coltop == (0,0,0,0) or ((coltop == bg or colbot == fg) and not colbot == (0,0,0,0)):
				c,cf,te,be = '▄',' ',be,te
			if colbot == coltop:
				c,te,be = cf,te,te
			out += te(coltop) + be(colbot) + c
		out = out.rstrip() + '\n'
	return out[:-1] + reset_sequence + '\n'

if __name__ == '__main__':
	parser = argparse.ArgumentParser(description='Render pixel images on 256-color ANSI terminals')
	parser.add_argument('image', type=str)
	args = parser.parse_args()
	img = Image.open(args.image)
	frames = []
	palette = img.getpalette()
	for frame in ImageSequence.Iterator(img):
		f = frame.copy()
		#This works around a known bug in Pillow
		#See also: http://stackoverflow.com/questions/4904940/python-converting-gif-frames-to-png
		f.putpalette(palette)
		f = f.convert("RGBA")
		frames.append(termify_pixels(f))

	print(cursor_invisible)
	atexit.register(lambda:print(cursor_visible))
	signal.signal(signal.SIGTERM, lambda signum, stack_frame: exit(1))

	while True:
		for frame in frames:
			print(clear_screen, reset_sequence)
			print(frame)
			time.sleep(img.info['duration']/1000.0)

<commit_msg>Updated gifterm to just import pixelterm<commit_after>#!/usr/bin/env python

import os, sys, argparse, os.path, json, time, signal, atexit
#NOTE: This script uses pygments for RGB->X256 conversion since pygments is
#readily available. If you do not like pygments (e.g. because it is large),
#you could patch in something like https://github.com/magarcia/python-x256
#(but don't forget to send me a pull request ;)
from pygments.formatters import terminal256
from PIL import Image, GifImagePlugin, ImageSequence
import pixelterm

clear_screen = '\033[H\033[2J'
cursor_invisible = '\033[?25l'
cursor_visible = '\033[?25h'

if __name__ == '__main__':
	parser = argparse.ArgumentParser(description='Render pixel images on 256-color ANSI terminals')
	parser.add_argument('image', type=str)
	args = parser.parse_args()
	img = Image.open(args.image)
	frames = []
	palette = img.getpalette()
	tw, th = os.get_terminal_size()
	th = th*2
	for frame in ImageSequence.Iterator(img):
		f = frame.copy()
		#This works around a known bug in Pillow
		#See also: http://stackoverflow.com/questions/4904940/python-converting-gif-frames-to-png
		f.putpalette(palette)
		f = f.convert("RGBA")
		f.thumbnail((tw, th), Image.ANTIALIAS)
		frames.append(pixelterm.termify_pixels(f))

	print(cursor_invisible)
	atexit.register(lambda:print(cursor_visible))
	signal.signal(signal.SIGTERM, lambda signum, stack_frame: exit(1))

	while True:
		for frame in frames:
			print(clear_screen, pixelterm.reset_sequence)
			print(frame)
			time.sleep(img.info['duration']/1000.0)

<|endoftext|>


<commit_before># Copyright 2020 The TensorFlow Probability Authors.
#
# 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.
# ============================================================================
"""TensorFlow Probability experimental bijectors package."""

from tensorflow_probability.python.bijectors.ldj_ratio import inverse_log_det_jacobian_ratio
from tensorflow_probability.python.experimental.bijectors.distribution_bijectors import make_distribution_bijector
from tensorflow_probability.python.experimental.bijectors.scalar_function_with_inferred_inverse import ScalarFunctionWithInferredInverse
from tensorflow_probability.python.experimental.bijectors.highway_flow import build_highway_flow_layer, HighwayFlow

__all__ = [
    'build_highway_flow_layer',
    'HighwayFlow',
    'inverse_log_det_jacobian_ratio',
    'make_distribution_bijector',
    'ScalarFunctionWithInferredInverse',

]
<commit_msg>imports divided in different lines<commit_after># Copyright 2020 The TensorFlow Probability Authors.
#
# 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.
# ============================================================================
"""TensorFlow Probability experimental bijectors package."""

from tensorflow_probability.python.bijectors.ldj_ratio import inverse_log_det_jacobian_ratio
from tensorflow_probability.python.experimental.bijectors.distribution_bijectors import make_distribution_bijector
from tensorflow_probability.python.experimental.bijectors.scalar_function_with_inferred_inverse import ScalarFunctionWithInferredInverse
from tensorflow_probability.python.experimental.bijectors.highway_flow import build_highway_flow_layer
from tensorflow_probability.python.experimental.bijectors.highway_flow import HighwayFlow
__all__ = [
    'build_highway_flow_layer',
    'HighwayFlow',
    'inverse_log_det_jacobian_ratio',
    'make_distribution_bijector',
    'ScalarFunctionWithInferredInverse',
]
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) 2014, Vispy Development Team. All Rights Reserved.
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
# -----------------------------------------------------------------------------

import numpy as np

from .visual import CompoundVisual
from .line import LineVisual
from .text import TextVisual

# XXX TODO list (see code, plus):
# 1. Automated tick direction?
# 2. Expand to 3D (only 2D supported currently)
# 3. Input validation
# 4. Property support
# 5. Reactivity to resizing (current tick lengths grow/shrink w/zoom)
# 6. Improve tick label naming (str(x) is not good) and tick selection

class AxisVisual(CompoundVisual):
    """Axis visual

    Parameters
    ----------
    pos : array
        Co-ordinates of start and end of the axis.
    domain : tuple
        The data values at the beginning and end of the axis, used for tick
        labels. i.e. (5, 10) means the axis starts at 5 and ends at 10. Default
        is (0, 1).
    tick_direction : array
        The tick direction to use (in document coordinates).
    scale_type : str
        The type of scale. For now only 'linear' is supported.
    axis_color : tuple
        RGBA values for the axis colour. Default is black.
    tick_color : tuple
        RGBA values for the tick colours. The colour for the major and minor
        ticks is currently fixed to be the same. Default is a dark grey.
    **kwargs : dict
        Keyword arguments to pass to `Visual`.
    """
    def __init__(self, pos=None, domain=(0., 1.), tick_direction=(-1., 0.),
                 scale_type="linear", axis_color=(1, 1, 1),
                 tick_color=(0.7, 0.7, 0.7)):
        if scale_type != 'linear':
            raise NotImplementedError('only linear scaling is currently '
                                      'supported')
        self._pos = None
        self._domain = None
        self.tick_direction = np.array(tick_direction, float)
        self.tick_direction = self.tick_direction
        self.scale_type = scale_type
        self.axis_color = axis_color
        self.tick_color = tick_color

        self.minor_tick_length = 5  # px
        self.major_tick_length = 10  # px
        self.label_margin = 5  # px

        self._need_update = True

        CompoundVisual.__init__(self, [])

        self._line = LineVisual(method='gl', width=3.0)
        self._ticks = LineVisual(method='gl', width=2.0, connect='segments')
        self._text = TextVisual(font_size=8, color='w')
        self.add_subvisual(self._line)
        self.add_subvisual(self._ticks)
        self.add_subvisual(self._text)

        if pos is not None:
            self.pos = pos
        self.domain = domain

    @property
    def pos(self):
        return self._pos

    @pos.setter
    def pos(self, pos):
        self._pos = np.array(pos, float)
        self._need_update = True
        self.update()

    @property
    def domain(self):
        return self._domain

    @domain.setter
    def domain(self, d):
        if d != self._domain:
            self._domain = d
            self._need_update = True
            self.update()

    @property
    def _vec(self):
        """Vector in the direction of the axis line"""
        return self.pos[1] - self.pos[0]

    def _update_subvisuals(self):
        major_tick_fractions, minor_tick_fractions, tick_labels = \
            self._get_tick_frac_labels()

        tick_pos, tick_label_pos, anchors = self._get_tick_positions(
            major_tick_fractions, minor_tick_fractions)

        self._line.set_data(pos=self.pos, color=self.axis_color)
        self._ticks.set_data(pos=tick_pos, color=self.tick_color)
        self._text.text = list(tick_labels)
        self._text.pos = tick_label_pos
        self._text.anchors = anchors

        self._need_update = False

    def _prepare_draw(self, view):
        if self._pos is None:
            return False
        if self._need_update:
            self._update_subvisuals()

    def _compute_bounds(self, axis, view):
        if axis == 2:
            return (0., 0.)
        # now axis in (0, 1)
        return self.pos[:, axis].min(), self.pos[:, axis].max()

    def _get_tick_positions(self, major_tick_fractions, minor_tick_fractions):
        # transform our tick direction to document coords
        trs = self.transforms
        visual_to_document = trs.get_transform('visual', 'document')
        direction = visual_to_document.map(np.array([[0., 0.],
                                                     self.tick_direction],
                                                    float))
        direction = (direction[1] - direction[0])[:2]
        direction /= np.linalg.norm(direction)
        # use the document (pixel) coord system to set text anchors
        anchors = []
        if direction[0] < 0:
            anchors.append('right')
        elif direction[0] > 0:
            anchors.append('left')
        else:
            anchors.append('center')
        if direction[1] < 0:
            anchors.append('bottom')
        elif direction[1] > 0:
            anchors.append('top')
        else:
            anchors.append('middle')

        # now figure out the tick positions in visual (data) coords
        vectors = np.array([[0., 0.],
                            direction * self.minor_tick_length,
                            direction * self.major_tick_length,
                            direction * (self.major_tick_length +
                                         self.label_margin)], float)
        vectors = visual_to_document.imap(vectors)[:, :2]
        minor_vector = vectors[1] - vectors[0]
        major_vector = vectors[2] - vectors[0]
        label_vector = vectors[3] - vectors[0]

        major_origins, major_endpoints = self._tile_ticks(
            major_tick_fractions, major_vector)

        minor_origins, minor_endpoints = self._tile_ticks(
            minor_tick_fractions, minor_vector)

        tick_label_pos = major_origins + label_vector

        num_major = len(major_tick_fractions)
        num_minor = len(minor_tick_fractions)

        c = np.empty([(num_major + num_minor) * 2, 2])

        c[0:(num_major-1)*2+1:2] = major_origins
        c[1:(num_major-1)*2+2:2] = major_endpoints
        c[(num_major-1)*2+2::2] = minor_origins
        c[(num_major-1)*2+3::2] = minor_endpoints

        return c, tick_label_pos, anchors

    def _tile_ticks(self, frac, tickvec):
        """Tiles tick marks along the axis."""
        origins = np.tile(self._vec, (len(frac), 1))
        origins = self.pos[0].T + (origins.T*frac).T
        endpoints = tickvec + origins
        return origins, endpoints

    def _get_tick_frac_labels(self):
        # This conditional is currently unnecessary since we only support
        # linear, but eventually we will support others so we leave it in
        if (self.scale_type == 'linear'):

            major_num = 11  # maximum number of major ticks
            minor_num = 4   # maximum number of minor ticks per major division

            major, majstep = np.linspace(0, 1, num=major_num, retstep=True)

            # XXX TODO: this should be better than just str(x)
            labels = [str(x) for x in np.interp(major, [0, 1], self.domain)]

            # XXX TODO: make these nice numbers only
            # - and faster! Potentially could draw in linspace across the whole
            # axis and render them before the major ticks, so the overlap
            # gets hidden. Might be messy. Benchmark trade-off of extra GL
            # versus extra NumPy.
            minor = []
            for i in np.nditer(major[:-1]):
                minor.extend(np.linspace(i, (i + majstep),
                             (minor_num + 2))[1:-1])
        # elif (self.scale_type == 'logarithmic'):
        #     return NotImplementedError
        # elif (self.scale_type == 'power'):
        #     return NotImplementedError
        return major, minor, labels
<commit_msg>Split axis ticking into separate class<commit_after># -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) 2014, Vispy Development Team. All Rights Reserved.
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
# -----------------------------------------------------------------------------

import numpy as np

from .visual import CompoundVisual
from .line import LineVisual
from .text import TextVisual

# XXX TODO list (see code, plus):
# 1. Automated tick direction?
# 2. Expand to 3D (only 2D supported currently)
# 3. Input validation
# 4. Property support
# 5. Reactivity to resizing (current tick lengths grow/shrink w/zoom)
# 6. Improve tick label naming (str(x) is not good) and tick selection

class AxisVisual(CompoundVisual):
    """Axis visual

    Parameters
    ----------
    pos : array
        Co-ordinates of start and end of the axis.
    domain : tuple
        The data values at the beginning and end of the axis, used for tick
        labels. i.e. (5, 10) means the axis starts at 5 and ends at 10. Default
        is (0, 1).
    tick_direction : array
        The tick direction to use (in document coordinates).
    scale_type : str
        The type of scale. For now only 'linear' is supported.
    axis_color : tuple
        RGBA values for the axis colour. Default is black.
    tick_color : tuple
        RGBA values for the tick colours. The colour for the major and minor
        ticks is currently fixed to be the same. Default is a dark grey.
    **kwargs : dict
        Keyword arguments to pass to `Visual`.
    """
    def __init__(self, pos=None, domain=(0., 1.), tick_direction=(-1., 0.),
                 scale_type="linear", axis_color=(1, 1, 1),
                 tick_color=(0.7, 0.7, 0.7)):
        if scale_type != 'linear':
            raise NotImplementedError('only linear scaling is currently '
                                      'supported')
        self._pos = None
        self._domain = None
        self.ticker = Ticker(self)
        self.tick_direction = np.array(tick_direction, float)
        self.tick_direction = self.tick_direction
        self.scale_type = scale_type
        self.axis_color = axis_color
        self.tick_color = tick_color

        self.minor_tick_length = 5  # px
        self.major_tick_length = 10  # px
        self.label_margin = 5  # px

        self._need_update = True

        CompoundVisual.__init__(self, [])

        self._line = LineVisual(method='gl', width=3.0)
        self._ticks = LineVisual(method='gl', width=2.0, connect='segments')
        self._text = TextVisual(font_size=8, color='w')
        self.add_subvisual(self._line)
        self.add_subvisual(self._ticks)
        self.add_subvisual(self._text)

        if pos is not None:
            self.pos = pos
        self.domain = domain

    @property
    def pos(self):
        return self._pos

    @pos.setter
    def pos(self, pos):
        self._pos = np.array(pos, float)
        self._need_update = True
        self.update()

    @property
    def domain(self):
        return self._domain

    @domain.setter
    def domain(self, d):
        if d != self._domain:
            self._domain = d
            self._need_update = True
            self.update()

    @property
    def _vec(self):
        """Vector in the direction of the axis line"""
        return self.pos[1] - self.pos[0]

    def _update_subvisuals(self):
        tick_pos, labels, label_pos, anchors = self.ticker.get_update()

        self._line.set_data(pos=self.pos, color=self.axis_color)
        self._ticks.set_data(pos=tick_pos, color=self.tick_color)
        self._text.text = list(labels)
        self._text.pos = label_pos
        self._text.anchors = anchors

        self._need_update = False

    def _prepare_draw(self, view):
        if self._pos is None:
            return False
        if self._need_update:
            self._update_subvisuals()

    def _compute_bounds(self, axis, view):
        if axis == 2:
            return (0., 0.)
        # now axis in (0, 1)
        return self.pos[:, axis].min(), self.pos[:, axis].max()

class Ticker(object):
    def __init__(self, axis):
        self.axis = axis

    def get_update(self):
        major_tick_fractions, minor_tick_fractions, tick_labels = \
            self._get_tick_frac_labels()
        tick_pos, label_pos, anchors = self._get_tick_positions(
            major_tick_fractions, minor_tick_fractions)
        return tick_pos, tick_labels, label_pos, anchors

    def _get_tick_positions(self, major_tick_fractions, minor_tick_fractions):
        # transform our tick direction to document coords
        trs = self.axis.transforms
        visual_to_document = trs.get_transform('visual', 'document')
        direction = visual_to_document.map(np.array([[0., 0.],
                                                     self.axis.tick_direction],
                                                    float))
        direction = (direction[1] - direction[0])[:2]
        direction /= np.linalg.norm(direction)
        # use the document (pixel) coord system to set text anchors
        anchors = []
        if direction[0] < 0:
            anchors.append('right')
        elif direction[0] > 0:
            anchors.append('left')
        else:
            anchors.append('center')
        if direction[1] < 0:
            anchors.append('bottom')
        elif direction[1] > 0:
            anchors.append('top')
        else:
            anchors.append('middle')

        # now figure out the tick positions in visual (data) coords
        vectors = np.array([[0., 0.],
                            direction * self.axis.minor_tick_length,
                            direction * self.axis.major_tick_length,
                            direction * (self.axis.major_tick_length +
                                         self.axis.label_margin)], float)
        vectors = visual_to_document.imap(vectors)[:, :2]
        minor_vector = vectors[1] - vectors[0]
        major_vector = vectors[2] - vectors[0]
        label_vector = vectors[3] - vectors[0]

        major_origins, major_endpoints = self._tile_ticks(
            major_tick_fractions, major_vector)

        minor_origins, minor_endpoints = self._tile_ticks(
            minor_tick_fractions, minor_vector)

        tick_label_pos = major_origins + label_vector

        num_major = len(major_tick_fractions)
        num_minor = len(minor_tick_fractions)

        c = np.empty([(num_major + num_minor) * 2, 2])

        c[0:(num_major-1)*2+1:2] = major_origins
        c[1:(num_major-1)*2+2:2] = major_endpoints
        c[(num_major-1)*2+2::2] = minor_origins
        c[(num_major-1)*2+3::2] = minor_endpoints

        return c, tick_label_pos, anchors

    def _tile_ticks(self, frac, tickvec):
        """Tiles tick marks along the axis."""
        origins = np.tile(self.axis._vec, (len(frac), 1))
        origins = self.axis.pos[0].T + (origins.T*frac).T
        endpoints = tickvec + origins
        return origins, endpoints

    def _get_tick_frac_labels(self):
        # This conditional is currently unnecessary since we only support
        # linear, but eventually we will support others so we leave it in
        if (self.axis.scale_type == 'linear'):

            major_num = 11  # maximum number of major ticks
            minor_num = 4   # maximum number of minor ticks per major division

            major, majstep = np.linspace(0, 1, num=major_num, retstep=True)

            # XXX TODO: this should be better than just str(x)
            labels = [str(x) for x in np.interp(major, [0, 1], self.axis.domain)]

            # XXX TODO: make these nice numbers only
            # - and faster! Potentially could draw in linspace across the whole
            # axis and render them before the major ticks, so the overlap
            # gets hidden. Might be messy. Benchmark trade-off of extra GL
            # versus extra NumPy.
            minor = []
            for i in np.nditer(major[:-1]):
                minor.extend(np.linspace(i, (i + majstep),
                             (minor_num + 2))[1:-1])
        # elif (self.scale_type == 'logarithmic'):
        #     return NotImplementedError
        # elif (self.scale_type == 'power'):
        #     return NotImplementedError
        return major, minor, labels
<|endoftext|>