<commit_before>""" Conways game of life in python """
import curses
import time
import random
import signal
import sys
from itertools import product

# pylint: disable=unused-import
from typing import Dict, Tuple, NewType, Any, Set, Callable, Iterable
# pylint: enable=unused-import

# pylint: disable=invalid-name
Pos = Tuple[int, int]

DEAD_SYMBOL = '-'
ALIVE_SYMBOL = '#'

def signal_handler(_sig, _frame):
    """ Make Ctrl-c exit close curses window """
    curses.endwin()
    sys.exit(0)

class World:
    """ World class """
    def __init__(self, size_x=10, size_y=10, randomize=True):
        # type : (int, int, Bool) -> None
        self.make_neigh_cache()
        self.world = set()  # type: Set[Pos]
        if randomize:
            self.randomize(int(size_x * size_y * 1 / 3), size_x, size_y)

    def randomize(self, num, size_x, size_y):
        # type: (int, int, int) -> None
        """ Create @num number of alive cells between (0, 0) and (size_x, size_y) """
        if num > size_x * size_y:
            raise ValueError("Trying to add more cells than space in world")
        self.world = set()
        all_cells = product(range(size_x), range(size_y))  # type: Iterable[Any]
        for cell in random.sample(list(all_cells), num):
            self.world.add(cell)

    def _find_corner(self, func, empty_pos):
        # type: (Callable[[Iterable[int]], int], Pos) -> Pos
        """ Helper function to find corners of bounding rectangle of alive cells """
        if not self.world:
            # World empty
            return empty_pos
        else:
            x = func(cell[0] for cell in self.world)
            y = func(cell[1] for cell in self.world)
        return (x, y)

    def min_pos(self):
        # type: () -> Pos
        """ Return the top left position of the bounding rectangle of all alive cells """
        return self._find_corner(min, (0, 0))

    def max_pos(self):
        # type: () -> Pos
        """ Return the bottom, right position with alive cell"""
        return self._find_corner(max, (0, 0))

    @staticmethod
    def _new_cell(cell, neighbours):
        # type: (bool, int) -> bool
        """Returns the new cell based on how many alive neighbours there is"""
        if cell:
            return 2 <= neighbours < 4
        else:
            return neighbours == 3

    def make_neigh_cache(self):
        # type: () -> None
        """ Create lists of relative positions of neighbours and
            cells in a 3x3 block """
        self._neigh_cache = [(x, y)
                             for x in range(-1, 2)
                             for y in range(-1, 2)
                             if not (x == 0 and y == 0)]
        self._makro_cell_cache = [(x, y)
                                  for x in range(-1, 2)
                                  for y in range(-1, 2)]

    def calculate_neighbours(self, pos):
        # type: (Pos) -> int
        """ calculate the number of neighbours of cell pos """
        neighbours = 0
        x, y = pos
        for d_x, d_y in self._neigh_cache:
            neighbour_pos = (x + d_x, y + d_y)
            neighbours += 1 if neighbour_pos in self.world else 0
        return neighbours

    def update_cell(self, new_world, pos):
        # type: (Set[Pos], Pos) -> Set[Pos]
        """ Update the cell at position pos """
        neighbours = self.calculate_neighbours(pos)
        new_cell = self._new_cell(pos in self.world, neighbours)
        if new_cell:
            new_world.add(pos)
        return new_world

    def update_neighbours(self, new_world, pos, updated_cells):
        # type: (Set[Pos], Pos, Set[Pos]) -> Tuple[Set[Pos], Set[Pos]]
        """Update the cells in new_world around cell in position pos"""
        for x, y in self._makro_cell_cache:
            if (pos[0] + x, pos[1] + y) in updated_cells:
                # Cell already updated, continue
                continue
            else:
                # Cell not updated yet, updating
                new_world = self.update_cell(new_world, (pos[0] + x, pos[1] + y))
                updated_cells.add((pos[0] + x, pos[1] + y))
        return new_world, updated_cells

    def update(self):
        # type: () -> None
        """ Update the current world one step """
        new_world = set()  # type: Set[Pos]
        updated_cells = set()  # type: Set[Pos]
        for pos in self.world:
            new_world, updated_cells = self.update_neighbours(new_world, pos, updated_cells)
        self.world = new_world

    def set_cell(self, pos):
        # type: (Pos) -> None
        """ Create a live cell at @pos """
        self.world.add(pos)

    def lines(self, top_left=None, bottom_right=None):
        # type: (World, Pos, Pos) -> List[str]
        """Return @world between @top_left and @bottom_right as list of strings """
        if top_left is None:
            top_left = self.min_pos()

        if bottom_right is None:
            bottom_right = self.max_pos()

        world_lines = []
        if not self.world:
            return []

        for y in range(top_left[1], bottom_right[1] + 1):
            string = ""
            for x in range(top_left[0], bottom_right[0] + 1):
                if (x, y) in self.world:
                    string += ALIVE_SYMBOL
                else:
                    string += DEAD_SYMBOL
            world_lines.append(string)
        return world_lines

    def __str__(self):
        # type: () -> str
        return "\n".join(self.lines())

    def __getitem__(self, pos):
        # type: (Pos) -> int
        return 1 if pos in self.world else 0

    def __len__(self):
        return len(self.world)

def print_screen(world, start_pos=None, end_pos=None):
    # type: (World, Pos, Pos) -> None
    """Print @world between @start_pos and @end_pos to stdout"""
    print("\n".join(world.lines(start_pos, end_pos)))

def print_curses(world, screen, start_pos, end_pos):
    # type: (World, Any, Pos, Pos) -> None
    """Print the @world from @start_pos to @end_pos on ncurses @screen"""

    list_of_lines = world.lines(start_pos, end_pos)

    # TODO Add colors?
    for line_no, line in enumerate(list_of_lines):
        screen.addstr(line_no + 1, 1, line)
    screen.refresh()

class Game:
    """ Class handling the user interface """
    def __init__(self, mode="screen", size_x=20, size_y=20,
                 max_size=False):

        self.size_x = size_x
        self.size_y = size_y
        self.mode = mode

        if self.mode == "curses":
            self.init_curses(max_size)

        self.world = World(self.size_x, self.size_y)
        self.top_corner = (0, 0)
        self.bottom_corner = (self.size_x, self.size_y)

    def init_curses(self, max_size):
        """ Initilize the curses screen """
        self.screen = curses.initscr()
        curses.start_color()
        if not curses.has_colors():
            self.exit("Error, no color support", 1)
        else:
            # We have color support
            # Pair 1, green on black background
            curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
        if max_size:
            # Get maximum size of screen
            size_y_max, size_x_max = self.screen.getmaxyx()
            # Need space for border
            self.size_y, self.size_x = size_y_max - 3, size_x_max - 3

        self.screen.border(0)
        curses.noecho()
        curses.cbreak()
        self.screen.keypad(1)
        curses.curs_set(0)

    def ask_user(self, question):
        """ Ask the users a question, return answer as string """
        q_size = len(question)
        self.screen.addstr(self.size_y // 2, self.size_x // 2 - q_size // 2,
                           question + ' ', curses.color_pair(1))
        answer = self.screen.getstr().decode("UTF-8")
        return answer

    def get_command_from_user_screen(self) -> int:
        """ Get a command from user using terminal """
        raise NotImplementedError('Prompt is not supported for \"screen\" mode worlds')

    def get_command_from_user_curses(self) -> int:
        """ Get a command from user using curses """
        return self.screen.getch()

    def get_command_from_user(self):
        """ Get input from user """
        if self.mode == "screen":
            return self.get_command_from_user_screen()
        elif self.mode == "curses":
            return self.get_command_from_user_curses()

    def move_left(self):
        """ Move the viewing window of the world to the left """
        self.top_corner = (self.top_corner[0] - 1, self.top_corner[1])
        self.bottom_corner = (self.bottom_corner[0] - 1, self.bottom_corner[1])

    def move_right(self):
        """ Move the viewing window of the world to the right """
        self.top_corner = (self.top_corner[0] + 1, self.top_corner[1])
        self.bottom_corner = (self.bottom_corner[0] + 1, self.bottom_corner[1])

    def move_up(self):
        """ Move the viewing window of the world to the up """
        self.top_corner = (self.top_corner[0], self.top_corner[1] + 1)
        self.bottom_corner = (self.bottom_corner[0], self.bottom_corner[1] + 1)

    def move_down(self):
        """ Move the viewing window of the world to the down """
        self.top_corner = (self.top_corner[0], self.top_corner[1] - 1)
        self.bottom_corner = (self.bottom_corner[0], self.bottom_corner[1] - 1)

    def handle_command(self, command):
        """ Handle commands
            space: continue one generation
            w or up: move screen up
            a or left: move screen left
            s or down: move screen down
            f or right: move screen right
            r: ask user how many generations to run and then run them
        """

        if command == ord('w') or command == curses.KEY_UP:
            self.move_down()
        elif command == ord('s') or command == curses.KEY_DOWN:
            self.move_up()
        elif command == ord('a') or command == curses.KEY_LEFT:
            self.move_left()
        elif command == ord('d') or command == curses.KEY_RIGHT:
            self.move_right()
        elif command == ord("r"):
            # Ask user how many generations to animate
            try:
                num = int(self.ask_user("How many generations"))
            except ValueError:
                self.ask_user("Enter integer please")
                return
            self.animate(num, 0.001)

        elif command == ord(" "):
            self.world.update()

        elif command == ord("q"):
            self.exit("Quitting", 0)

    def print_world(self):
        """ print the world to curses or as ascii """
        if self.mode == "curses":
            print_curses(self.world, self.screen,
                         self.top_corner,
                         self.bottom_corner)
        elif self.mode == "screen":
            print_screen(self.world)
        else:
            pass

    def kill_screen(self):
        """ Kill the screen and cleanup """
        if self.mode == "curses":
            curses.endwin()

    def exit(self, msg=None, status=0):
        """ Exit game of life """
        self.kill_screen()
        if msg:
            print(msg)
        if not isinstance(status, int):
            status = 0
        sys.exit(status)

    def animate(self, steps, timestep=0.2):
        """ Update and print the screen 'step' times"""
        for _ in range(steps):
            self.world.update()
            self.print_world()
            time.sleep(timestep)

signal.signal(signal.SIGINT, signal_handler)
<commit_msg>cleanup<commit_after>""" Conways game of life in python """
import curses
import time
import random
import signal
import sys
from itertools import product

# pylint: disable=unused-import
from typing import Dict, Tuple, NewType, Any, Set, Callable, Iterable
# pylint: enable=unused-import

# pylint: disable=invalid-name
Pos = Tuple[int, int]
# pylint: enable=invalid-name

DEAD_SYMBOL = '-'
ALIVE_SYMBOL = '#'

def signal_handler(_sig, _frame):
    """ Make Ctrl-c exit close curses window """
    curses.endwin()
    sys.exit(0)

class World:
    """ World class """
    def __init__(self, size_x=10, size_y=10, randomize=True):
        # type : (int, int, Bool) -> None
        self.make_neigh_cache()
        self.world = set()  # type: Set[Pos]
        if randomize:
            self.randomize(int(size_x * size_y * 1 / 3), size_x, size_y)

    def randomize(self, num, size_x, size_y):
        # type: (int, int, int) -> None
        """ Create @num number of alive cells between (0, 0) and (size_x, size_y) """
        if num > size_x * size_y:
            raise ValueError("Trying to add more cells than space in world")
        self.world = set()
        all_cells = product(range(size_x), range(size_y))  # type: Iterable[Any]
        for cell in random.sample(list(all_cells), num):
            self.world.add(cell)

    def _find_corner(self, func, empty_pos):
        # type: (Callable[[Iterable[int]], int], Pos) -> Pos
        """ Helper function to find corners of bounding rectangle of alive cells """
        if not self.world:
            # World empty
            return empty_pos
        else:
            x = func(cell[0] for cell in self.world)
            y = func(cell[1] for cell in self.world)
        return (x, y)

    def min_pos(self):
        # type: () -> Pos
        """ Return the top left position of the bounding rectangle of all alive cells """
        return self._find_corner(min, (0, 0))

    def max_pos(self):
        # type: () -> Pos
        """ Return the bottom, right position with alive cell"""
        return self._find_corner(max, (0, 0))

    @staticmethod
    def _new_cell(cell, neighbours):
        # type: (bool, int) -> bool
        """Returns the new cell based on how many alive neighbours there is"""
        if cell:
            return 2 <= neighbours < 4
        return neighbours == 3

    def make_neigh_cache(self):
        # type: () -> None
        """ Create lists of relative positions of neighbours and
            cells in a 3x3 block """
        self._neigh_cache = [(x, y)
                             for x in range(-1, 2)
                             for y in range(-1, 2)
                             if not (x == 0 and y == 0)]
        self._makro_cell_cache = [(x, y)
                                  for x in range(-1, 2)
                                  for y in range(-1, 2)]

    def calculate_neighbours(self, pos):
        # type: (Pos) -> int
        """ calculate the number of neighbours of cell pos """
        neighbours = 0
        x, y = pos
        for d_x, d_y in self._neigh_cache:
            neighbour_pos = (x + d_x, y + d_y)
            neighbours += 1 if neighbour_pos in self.world else 0
        return neighbours

    def update_cell(self, new_world, pos):
        # type: (Set[Pos], Pos) -> Set[Pos]
        """ Update the cell at position pos """
        neighbours = self.calculate_neighbours(pos)
        new_cell = self._new_cell(pos in self.world, neighbours)
        if new_cell:
            new_world.add(pos)
        return new_world

    def update_neighbours(self, new_world, pos, updated_cells):
        # type: (Set[Pos], Pos, Set[Pos]) -> Tuple[Set[Pos], Set[Pos]]
        """Update the cells in new_world around cell in position pos"""
        for x, y in self._makro_cell_cache:
            if (pos[0] + x, pos[1] + y) in updated_cells:
                # Cell already updated, continue
                continue
            else:
                # Cell not updated yet, updating
                new_world = self.update_cell(new_world, (pos[0] + x, pos[1] + y))
                updated_cells.add((pos[0] + x, pos[1] + y))
        return new_world, updated_cells

    def update(self):
        # type: () -> None
        """ Update the current world one step """
        new_world = set()  # type: Set[Pos]
        updated_cells = set()  # type: Set[Pos]
        for pos in self.world:
            new_world, updated_cells = self.update_neighbours(new_world, pos, updated_cells)
        self.world = new_world

    def set_cell(self, pos):
        # type: (Pos) -> None
        """ Create a live cell at @pos """
        self.world.add(pos)

    def lines(self, top_left=None, bottom_right=None):
        # type: (World, Pos, Pos) -> List[str]
        """Return @world between @top_left and @bottom_right as list of strings """
        if top_left is None:
            top_left = self.min_pos()

        if bottom_right is None:
            bottom_right = self.max_pos()

        world_lines = []
        if not self.world:
            return []

        for y in range(top_left[1], bottom_right[1] + 1):
            string = ""
            for x in range(top_left[0], bottom_right[0] + 1):
                if (x, y) in self.world:
                    string += ALIVE_SYMBOL
                else:
                    string += DEAD_SYMBOL
            world_lines.append(string)
        return world_lines

    def __str__(self):
        # type: () -> str
        return "\n".join(self.lines())

    def __getitem__(self, pos):
        # type: (Pos) -> int
        return 1 if pos in self.world else 0

    def __len__(self):
        return len(self.world)

def print_screen(world, start_pos=None, end_pos=None):
    # type: (World, Pos, Pos) -> None
    """Print @world between @start_pos and @end_pos to stdout"""
    print("\n".join(world.lines(start_pos, end_pos)))

def print_curses(world, screen, start_pos, end_pos):
    # type: (World, Any, Pos, Pos) -> None
    """Print the @world from @start_pos to @end_pos on ncurses @screen"""

    list_of_lines = world.lines(start_pos, end_pos)

    # TODO Add colors?
    for line_no, line in enumerate(list_of_lines):
        screen.addstr(line_no + 1, 1, line)
    screen.refresh()

class Game:
    """ Class handling the user interface """
    def __init__(self, mode="screen", size_x=20, size_y=20,
                 max_size=False):

        self.size_x = size_x
        self.size_y = size_y
        self.mode = mode

        if self.mode == "curses":
            self.init_curses(max_size)

        self.world = World(self.size_x, self.size_y)
        self.top_corner = (0, 0)
        self.bottom_corner = (self.size_x, self.size_y)

    def init_curses(self, max_size):
        """ Initilize the curses screen """
        self.screen = curses.initscr()
        curses.start_color()
        if not curses.has_colors():
            self.exit("Error, no color support", 1)
        else:
            # We have color support
            # Pair 1, green on black background
            curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
        if max_size:
            # Get maximum size of screen
            size_y_max, size_x_max = self.screen.getmaxyx()
            # Need space for border
            self.size_y, self.size_x = size_y_max - 3, size_x_max - 3

        self.screen.border(0)
        curses.noecho()
        curses.cbreak()
        self.screen.keypad(1)
        curses.curs_set(0)

    def ask_user(self, question):
        """ Ask the users a question, return answer as string """
        q_size = len(question)
        self.screen.addstr(self.size_y // 2, self.size_x // 2 - q_size // 2,
                           question + ' ', curses.color_pair(1))
        answer = self.screen.getstr().decode("UTF-8")
        return answer

    def get_command_from_user_screen(self) -> int:
        """ Get a command from user using terminal """
        raise NotImplementedError('Prompt is not supported for \"screen\" mode worlds')

    def get_command_from_user_curses(self) -> int:
        """ Get a command from user using curses """
        return self.screen.getch()

    def get_command_from_user(self):
        """ Get input from user """
        if self.mode == "screen":
            return self.get_command_from_user_screen()
        elif self.mode == "curses":
            return self.get_command_from_user_curses()

    def move_left(self):
        """ Move the viewing window of the world to the left """
        self.top_corner = (self.top_corner[0] - 1, self.top_corner[1])
        self.bottom_corner = (self.bottom_corner[0] - 1, self.bottom_corner[1])

    def move_right(self):
        """ Move the viewing window of the world to the right """
        self.top_corner = (self.top_corner[0] + 1, self.top_corner[1])
        self.bottom_corner = (self.bottom_corner[0] + 1, self.bottom_corner[1])

    def move_up(self):
        """ Move the viewing window of the world to the up """
        self.top_corner = (self.top_corner[0], self.top_corner[1] + 1)
        self.bottom_corner = (self.bottom_corner[0], self.bottom_corner[1] + 1)

    def move_down(self):
        """ Move the viewing window of the world to the down """
        self.top_corner = (self.top_corner[0], self.top_corner[1] - 1)
        self.bottom_corner = (self.bottom_corner[0], self.bottom_corner[1] - 1)

    def handle_command(self, command):
        """ Handle commands
            space: continue one generation
            w or up: move screen up
            a or left: move screen left
            s or down: move screen down
            f or right: move screen right
            r: ask user how many generations to run and then run them
        """

        if command == ord('w') or command == curses.KEY_UP:
            self.move_down()
        elif command == ord('s') or command == curses.KEY_DOWN:
            self.move_up()
        elif command == ord('a') or command == curses.KEY_LEFT:
            self.move_left()
        elif command == ord('d') or command == curses.KEY_RIGHT:
            self.move_right()
        elif command == ord("r"):
            # Ask user how many generations to animate
            try:
                num = int(self.ask_user("How many generations"))
            except ValueError:
                self.ask_user("Enter integer please")
                return
            self.animate(num, 0.001)

        elif command == ord(" "):
            self.world.update()

        elif command == ord("q"):
            self.exit("Quitting", 0)

    def print_world(self):
        """ print the world to curses or as ascii """
        if self.mode == "curses":
            print_curses(self.world, self.screen,
                         self.top_corner,
                         self.bottom_corner)
        elif self.mode == "screen":
            print_screen(self.world)
        else:
            pass

    def kill_screen(self):
        """ Kill the screen and cleanup """
        if self.mode == "curses":
            curses.endwin()

    def exit(self, msg=None, status=0):
        """ Exit game of life """
        self.kill_screen()
        if msg:
            print(msg)
        if not isinstance(status, int):
            status = 0
        sys.exit(status)

    def animate(self, steps, timestep=0.2):
        """ Update and print the screen 'step' times"""
        for _ in range(steps):
            self.world.update()
            self.print_world()
            time.sleep(timestep)

signal.signal(signal.SIGINT, signal_handler)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Copyright (c) 2014 Docker.
#
# 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 logging
import math
import random
import string

from nose import tools

from ..core import compat
from ..core import driver
from ..core import exceptions

logger = logging.getLogger(__name__)

class Driver(object):

    def __init__(self, scheme=None, path=None, config=None):
        self.scheme = scheme
        self.path = path
        self.config = config

    # Load the requested driver
    def setUp(self):
        storage = driver.fetch(self.scheme)
        self._storage = storage(self.path, self.config)

    def tearDown(self):
        pass

    def gen_random_string(self, length=16):
        return ''.join([random.choice(string.ascii_uppercase + string.digits)
                        for x in range(length)]).lower()

    def simplehelp(self, path, content, expected, size=0):
        self._storage.put_content(path, content)
        assert self._storage.get_content(path) == expected
        assert self._storage.get_content(path) == expected
        if size:
            assert self._storage.get_size(path) == size

    def unicodehelp(self, path, content, expected):
        self._storage.put_unicode(path, content)
        assert self._storage.get_unicode(path) == expected
        assert self._storage.get_unicode(path) == expected

    def jsonhelp(self, path, content, expected):
        self._storage.put_json(path, content)
        assert self._storage.get_json(path) == expected
        assert self._storage.get_json(path) == expected

    def test_exists_non_existent(self):
        filename = self.gen_random_string()
        assert not self._storage.exists(filename)

    def test_exists_existent(self):
        filename = self.gen_random_string()
        self._storage.put_content(filename, '')
        assert self._storage.exists(filename)

    # get / put
    def test_write_read_1(self):
        filename = self.gen_random_string()
        content = b'a'
        expected = b'a'
        self.simplehelp(filename, content, expected, len(expected))

    def test_write_read_2(self):
        filename = self.gen_random_string()
        content = b'\xc3\x9f'
        expected = b'\xc3\x9f'
        self.simplehelp(filename, content, expected, len(expected))

    def test_write_read_3(self):
        filename = self.gen_random_string()
        content = u'ß'.encode('utf8')
        expected = b'\xc3\x9f'
        self.simplehelp(filename, content, expected, len(expected))

    def test_write_read_4(self):
        filename = self.gen_random_string()
        content = 'ß'
        if compat.is_py2:
            content = content.decode('utf8')
        content = content.encode('utf8')
        expected = b'\xc3\x9f'
        self.simplehelp(filename, content, expected, len(expected))

    def test_write_read_5(self):
        filename = self.gen_random_string()
        content = self.gen_random_string().encode('utf8')
        expected = content
        self.simplehelp(filename, content, expected, len(expected))

    def test_write_read_6(self):
        filename = self.gen_random_string()
        content = self.gen_random_string(1024 * 1024).encode('utf8')
        expected = content
        self.simplehelp(filename, content, expected, len(expected))

    # get / put unicode
    def test_unicode_1(self):
        filename = self.gen_random_string()
        content = 'a'
        expected = u'a'
        self.unicodehelp(filename, content, expected)

    def test_unicode_2(self):
        filename = self.gen_random_string()
        content = b'\xc3\x9f'.decode('utf8')
        expected = u'ß'
        self.unicodehelp(filename, content, expected)

    def test_unicode_3(self):
        filename = self.gen_random_string()
        content = u'ß'
        expected = u'ß'
        self.unicodehelp(filename, content, expected)

    def test_unicode_4(self):
        filename = self.gen_random_string()
        content = 'ß'
        if compat.is_py2:
            content = content.decode('utf8')
        expected = u'ß'
        self.unicodehelp(filename, content, expected)

    def test_unicode_5(self):
        filename = self.gen_random_string()
        content = self.gen_random_string()
        expected = content
        self.unicodehelp(filename, content, expected)

    def test_unicode_6(self):
        filename = self.gen_random_string()
        content = self.gen_random_string(1024 * 1024)
        expected = content
        self.unicodehelp(filename, content, expected)

    # JSON
    def test_json(self):
        filename = self.gen_random_string()
        content = {u"ß": u"ß"}
        expected = {u"ß": u"ß"}
        self.jsonhelp(filename, content, expected)

    # Removes
    def test_remove_existent(self):
        filename = self.gen_random_string()
        content = self.gen_random_string()
        self._storage.put_content(filename, content)
        self._storage.remove(filename)
        assert not self._storage.exists(filename)

    @tools.raises(exceptions.FileNotFoundError)
    def test_remove_inexistent(self):
        filename = self.gen_random_string()
        self._storage.remove(filename)

    @tools.raises(exceptions.FileNotFoundError)
    def test_read_inexistent(self):
        filename = self.gen_random_string()
        self._storage.get_content(filename)

    @tools.raises(exceptions.FileNotFoundError)
    def test_get_size_inexistent(self):
        filename = self.gen_random_string()
        self._storage.get_size(filename)

    def test_stream(self):
        filename = self.gen_random_string()
        # test 7MB
        content = self.gen_random_string(7).encode('utf8')  # * 1024 * 1024
        # test exists
        io = compat.StringIO(content)
        logger.debug("%s should NOT exists still" % filename)
        assert not self._storage.exists(filename)

        self._storage.stream_write(filename, io)
        io.close()

        logger.debug("%s should exist now" % filename)
        assert self._storage.exists(filename)

        # test read / write
        data = compat.bytes()
        for buf in self._storage.stream_read(filename):
            data += buf

        assert content == data

        # test bytes_range only if the storage backend suppports it
        if self._storage.supports_bytes_range:
            b = random.randint(0, math.floor(len(content) / 2))
            bytes_range = (b, random.randint(b + 1, len(content) - 1))
            data = compat.bytes()
            for buf in self._storage.stream_read(filename, bytes_range):
                data += buf
            expected_content = content[bytes_range[0]:bytes_range[1] + 1]
            assert data == expected_content

        # logger.debug("Content length is %s" % len(content))
        # logger.debug("And retrieved content length should equal it: %s" %
        #              len(data))
        # logger.debug("got content %s" % content)
        # logger.debug("got data %s" % data)

        # test remove
        self._storage.remove(filename)
        assert not self._storage.exists(filename)

    @tools.raises(exceptions.FileNotFoundError)
    def test_stream_read_inexistent(self):
        filename = self.gen_random_string()
        data = compat.bytes()
        for buf in self._storage.stream_read(filename):
            data += buf

    @tools.raises(exceptions.FileNotFoundError)
    def test_inexistent_list_directory(self):
        notexist = self.gen_random_string()
        iterator = self._storage.list_directory(notexist)
        iterator.next()

    # XXX only elliptics return StopIteration for now - though we should
    # return probably that for all
    @tools.raises(exceptions.FileNotFoundError, StopIteration)
    def test_empty_list_directory(self):
        path = self.gen_random_string()
        content = self.gen_random_string().encode('utf8')
        self._storage.put_content(path, content)

        iterator = self._storage.list_directory(path)
        iterator.next()

    def test_list_directory(self):
        base = self.gen_random_string()
        filename1 = self.gen_random_string()
        filename2 = self.gen_random_string()
        fb1 = '%s/%s' % (base, filename1)
        fb2 = '%s/%s' % (base, filename2)
        content = self.gen_random_string()
        self._storage.put_content(fb1, content)
        self._storage.put_content(fb2, content)
        assert sorted([fb1, fb2]
                      ) == sorted(list(self._storage.list_directory(base)))

    # def test_root_list_directory(self):
    #     fb1 = self.gen_random_string()
    #     fb2 = self.gen_random_string()
    #     content = self.gen_random_string()
    #     self._storage.put_content(fb1, content)
    #     self._storage.put_content(fb2, content)
    #     print(list(self._storage.list_directory()))
    #     assert sorted([fb1, fb2]
    #                   ) == sorted(list(self._storage.list_directory()))

    @tools.raises(exceptions.FileNotFoundError, StopIteration)
    def test_empty_after_remove_list_directory(self):
        base = self.gen_random_string()
        filename1 = self.gen_random_string()
        filename2 = self.gen_random_string()
        fb1 = '%s/%s' % (base, filename1)
        fb2 = '%s/%s' % (base, filename2)
        content = self.gen_random_string()
        self._storage.put_content(fb1, content)
        self._storage.put_content(fb2, content)

        self._storage.remove(fb1)
        self._storage.remove(fb2)

        iterator = self._storage.list_directory(base)
        iterator.next()

    def test_paths(self):
        namespace = 'namespace'
        repository = 'repository'
        tag = 'sometag'
        image_id = 'imageid'
        p = self._storage.images_list_path(namespace, repository)
        assert not self._storage.exists(p)
        p = self._storage.image_json_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_mark_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_checksum_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_layer_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_ancestry_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_files_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_diff_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.repository_path(namespace, repository)
        assert not self._storage.exists(p)
        p = self._storage.tag_path(namespace, repository)
        assert not self._storage.exists(p)
        p = self._storage.tag_path(namespace, repository, tag)
        assert not self._storage.exists(p)
        p = self._storage.repository_json_path(namespace, repository)
        assert not self._storage.exists(p)
        p = self._storage.repository_tag_json_path(namespace, repository, tag)
        assert not self._storage.exists(p)
        p = self._storage.index_images_path(namespace, repository)
        assert not self._storage.exists(p)
        p = self._storage.private_flag_path(namespace, repository)
        assert not self._storage.exists(p)
<commit_msg>Fix py3 compat and tests (core)<commit_after># -*- coding: utf-8 -*-
# Copyright (c) 2014 Docker.
#
# 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 logging
import math
import random
import string

from nose import tools

from ..core import compat
from ..core import driver
from ..core import exceptions

logger = logging.getLogger(__name__)

class Driver(object):

    def __init__(self, scheme=None, path=None, config=None):
        self.scheme = scheme
        self.path = path
        self.config = config

    # Load the requested driver
    def setUp(self):
        storage = driver.fetch(self.scheme)
        self._storage = storage(self.path, self.config)

    def tearDown(self):
        pass

    def gen_random_string(self, length=16):
        return ''.join([random.choice(string.ascii_uppercase + string.digits)
                        for x in range(length)]).lower()

    def simplehelp(self, path, content, expected, size=0):
        self._storage.put_content(path, content)
        assert self._storage.get_content(path) == expected
        assert self._storage.get_content(path) == expected
        if size:
            assert self._storage.get_size(path) == size

    def unicodehelp(self, path, content, expected):
        self._storage.put_unicode(path, content)
        assert self._storage.get_unicode(path) == expected
        assert self._storage.get_unicode(path) == expected

    def jsonhelp(self, path, content, expected):
        self._storage.put_json(path, content)
        assert self._storage.get_json(path) == expected
        assert self._storage.get_json(path) == expected

    def test_exists_non_existent(self):
        filename = self.gen_random_string()
        assert not self._storage.exists(filename)

    def test_exists_existent(self):
        filename = self.gen_random_string()
        self._storage.put_content(filename, b'')
        assert self._storage.exists(filename)

    # get / put
    def test_write_read_1(self):
        filename = self.gen_random_string()
        content = b'a'
        expected = b'a'
        self.simplehelp(filename, content, expected, len(expected))

    def test_write_read_2(self):
        filename = self.gen_random_string()
        content = b'\xc3\x9f'
        expected = b'\xc3\x9f'
        self.simplehelp(filename, content, expected, len(expected))

    def test_write_read_3(self):
        filename = self.gen_random_string()
        content = u'ß'.encode('utf8')
        expected = b'\xc3\x9f'
        self.simplehelp(filename, content, expected, len(expected))

    def test_write_read_4(self):
        filename = self.gen_random_string()
        content = 'ß'
        if compat.is_py2:
            content = content.decode('utf8')
        content = content.encode('utf8')
        expected = b'\xc3\x9f'
        self.simplehelp(filename, content, expected, len(expected))

    def test_write_read_5(self):
        filename = self.gen_random_string()
        content = self.gen_random_string().encode('utf8')
        expected = content
        self.simplehelp(filename, content, expected, len(expected))

    def test_write_read_6(self):
        filename = self.gen_random_string()
        content = self.gen_random_string(1024 * 1024).encode('utf8')
        expected = content
        self.simplehelp(filename, content, expected, len(expected))

    # get / put unicode
    def test_unicode_1(self):
        filename = self.gen_random_string()
        content = 'a'
        expected = u'a'
        self.unicodehelp(filename, content, expected)

    def test_unicode_2(self):
        filename = self.gen_random_string()
        content = b'\xc3\x9f'.decode('utf8')
        expected = u'ß'
        self.unicodehelp(filename, content, expected)

    def test_unicode_3(self):
        filename = self.gen_random_string()
        content = u'ß'
        expected = u'ß'
        self.unicodehelp(filename, content, expected)

    def test_unicode_4(self):
        filename = self.gen_random_string()
        content = 'ß'
        if compat.is_py2:
            content = content.decode('utf8')
        expected = u'ß'
        self.unicodehelp(filename, content, expected)

    def test_unicode_5(self):
        filename = self.gen_random_string()
        content = self.gen_random_string()
        expected = content
        self.unicodehelp(filename, content, expected)

    def test_unicode_6(self):
        filename = self.gen_random_string()
        content = self.gen_random_string(1024 * 1024)
        expected = content
        self.unicodehelp(filename, content, expected)

    # JSON
    def test_json(self):
        filename = self.gen_random_string()
        content = {u"ß": u"ß"}
        expected = {u"ß": u"ß"}
        self.jsonhelp(filename, content, expected)

    # Removes
    def test_remove_existent(self):
        filename = self.gen_random_string()
        content = self.gen_random_string().encode('utf8')
        self._storage.put_content(filename, content)
        self._storage.remove(filename)
        assert not self._storage.exists(filename)

    @tools.raises(exceptions.FileNotFoundError)
    def test_remove_inexistent(self):
        filename = self.gen_random_string()
        self._storage.remove(filename)

    @tools.raises(exceptions.FileNotFoundError)
    def test_read_inexistent(self):
        filename = self.gen_random_string()
        self._storage.get_content(filename)

    @tools.raises(exceptions.FileNotFoundError)
    def test_get_size_inexistent(self):
        filename = self.gen_random_string()
        self._storage.get_size(filename)

    def test_stream(self):
        filename = self.gen_random_string()
        # test 7MB
        content = self.gen_random_string(7).encode('utf8')  # * 1024 * 1024
        # test exists
        io = compat.StringIO(content)
        logger.debug("%s should NOT exists still" % filename)
        assert not self._storage.exists(filename)

        self._storage.stream_write(filename, io)
        io.close()

        logger.debug("%s should exist now" % filename)
        assert self._storage.exists(filename)

        # test read / write
        data = compat.bytes()
        for buf in self._storage.stream_read(filename):
            data += buf

        assert content == data

        # test bytes_range only if the storage backend suppports it
        if self._storage.supports_bytes_range:
            b = random.randint(0, math.floor(len(content) / 2))
            bytes_range = (b, random.randint(b + 1, len(content) - 1))
            data = compat.bytes()
            for buf in self._storage.stream_read(filename, bytes_range):
                data += buf
            expected_content = content[bytes_range[0]:bytes_range[1] + 1]
            assert data == expected_content

        # logger.debug("Content length is %s" % len(content))
        # logger.debug("And retrieved content length should equal it: %s" %
        #              len(data))
        # logger.debug("got content %s" % content)
        # logger.debug("got data %s" % data)

        # test remove
        self._storage.remove(filename)
        assert not self._storage.exists(filename)

    @tools.raises(exceptions.FileNotFoundError)
    def test_stream_read_inexistent(self):
        filename = self.gen_random_string()
        data = compat.bytes()
        for buf in self._storage.stream_read(filename):
            data += buf

    @tools.raises(exceptions.FileNotFoundError)
    def test_inexistent_list_directory(self):
        notexist = self.gen_random_string()
        iterator = self._storage.list_directory(notexist)
        next(iterator)

    # XXX only elliptics return StopIteration for now - though we should
    # return probably that for all
    @tools.raises(exceptions.FileNotFoundError, StopIteration)
    def test_empty_list_directory(self):
        path = self.gen_random_string()
        content = self.gen_random_string().encode('utf8')
        self._storage.put_content(path, content)

        iterator = self._storage.list_directory(path)
        next(iterator)

    def test_list_directory(self):
        base = self.gen_random_string()
        filename1 = self.gen_random_string()
        filename2 = self.gen_random_string()
        fb1 = '%s/%s' % (base, filename1)
        fb2 = '%s/%s' % (base, filename2)
        content = self.gen_random_string().encode('utf8')
        self._storage.put_content(fb1, content)
        self._storage.put_content(fb2, content)
        assert sorted([fb1, fb2]
                      ) == sorted(list(self._storage.list_directory(base)))

    # def test_root_list_directory(self):
    #     fb1 = self.gen_random_string()
    #     fb2 = self.gen_random_string()
    #     content = self.gen_random_string()
    #     self._storage.put_content(fb1, content)
    #     self._storage.put_content(fb2, content)
    #     print(list(self._storage.list_directory()))
    #     assert sorted([fb1, fb2]
    #                   ) == sorted(list(self._storage.list_directory()))

    @tools.raises(exceptions.FileNotFoundError, StopIteration)
    def test_empty_after_remove_list_directory(self):
        base = self.gen_random_string()
        filename1 = self.gen_random_string()
        filename2 = self.gen_random_string()
        fb1 = '%s/%s' % (base, filename1)
        fb2 = '%s/%s' % (base, filename2)
        content = self.gen_random_string().encode('utf8')
        self._storage.put_content(fb1, content)
        self._storage.put_content(fb2, content)

        self._storage.remove(fb1)
        self._storage.remove(fb2)

        iterator = self._storage.list_directory(base)
        next(iterator)

    def test_paths(self):
        namespace = 'namespace'
        repository = 'repository'
        tag = 'sometag'
        image_id = 'imageid'
        p = self._storage.images_list_path(namespace, repository)
        assert not self._storage.exists(p)
        p = self._storage.image_json_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_mark_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_checksum_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_layer_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_ancestry_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_files_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.image_diff_path(image_id)
        assert not self._storage.exists(p)
        p = self._storage.repository_path(namespace, repository)
        assert not self._storage.exists(p)
        p = self._storage.tag_path(namespace, repository)
        assert not self._storage.exists(p)
        p = self._storage.tag_path(namespace, repository, tag)
        assert not self._storage.exists(p)
        p = self._storage.repository_json_path(namespace, repository)
        assert not self._storage.exists(p)
        p = self._storage.repository_tag_json_path(namespace, repository, tag)
        assert not self._storage.exists(p)
        p = self._storage.index_images_path(namespace, repository)
        assert not self._storage.exists(p)
        p = self._storage.private_flag_path(namespace, repository)
        assert not self._storage.exists(p)
<|endoftext|>


<commit_before>import markdown
from datetime import datetime

from django.utils.text import slugify
from django.db import models

class Tag(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

class Category(models.Model):
    name = models.CharField(max_length=100, db_index=True)
    slug = models.CharField(max_length=100, db_index=True, blank=True)
    parent = models.ForeignKey('self', null=True, blank=True)

    def __unicode__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Category, self).save(*args, **kwargs)

    class Meta:
        verbose_name_plural = 'Categories'

class Post(models.Model):
    STATUS_CHOICES = (
        ('p', 'Published'),
        ('d', 'Draft'),
        ('u', 'Unpublished')
    )
    title = models.CharField(max_length=100)
    slug  = models.CharField(max_length=100, blank=True)
    body  = models.TextField()
    status  = models.CharField(max_length=2, choices=STATUS_CHOICES,  default='d')
    created = models.DateTimeField(db_index=True, blank=True)
    modified= models.DateTimeField(blank=True)
    tags    = models.ManyToManyField(Tag, null=True, blank=True)
    category= models.ForeignKey(Category, null=True, blank=True)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        if not self.id:
            self.created = datetime.now()
        self.modified = datetime.now()
        super(Post, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.title

    def preview(self):
        return markdown.markdown(self.body)
    preview.allow_tags = True
<commit_msg>Render category tree<commit_after>import markdown
from datetime import datetime

from django.utils.text import slugify
from django.db import models

class Tag(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

class Category(models.Model):
    name = models.CharField(max_length=100, db_index=True)
    slug = models.CharField(max_length=100, db_index=True, blank=True)
    parent = models.ForeignKey('self', null=True, blank=True)

    def __unicode__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Category, self).save(*args, **kwargs)

    def children(self):
        return Category.objects.filter(parent=self)

    def descendants(self):
        children = self.children().values('id', 'name', 'slug')
        if children:
            for c in children:
                childs_descendants = Category.objects.get(id=c['id']).descendants()
                if childs_descendants:
                    c['children'] = childs_descendants
                else:
                    c['children'] = None
            return c
        else:
            return None

    @classmethod
    def tree(cls):
        roots = cls.objects.filter(parent=None)
        res = []
        for r in roots:
            res.append({
                'id': r.id,
                'name': r.name,
                'slug': r.slug,
                'children': r.descendants()
            })
        return res

    class Meta:
        verbose_name_plural = 'Categories'

class Post(models.Model):
    STATUS_CHOICES = (
        ('p', 'Published'),
        ('d', 'Draft'),
        ('u', 'Unpublished')
    )
    title = models.CharField(max_length=100)
    slug  = models.CharField(max_length=100, blank=True)
    body  = models.TextField()
    status  = models.CharField(max_length=2, choices=STATUS_CHOICES,  default='d')
    created = models.DateTimeField(db_index=True, blank=True)
    modified= models.DateTimeField(blank=True)
    tags    = models.ManyToManyField(Tag, null=True, blank=True)
    category= models.ForeignKey(Category, null=True, blank=True)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        if not self.id:
            self.created = datetime.now()
        self.modified = datetime.now()
        super(Post, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.title

    def preview(self):
        return markdown.markdown(self.body)
    preview.allow_tags = True
<|endoftext|>


<commit_before>from xml.etree import ElementTree
from random import shuffle

from basicserver import BasicVirtualServer
from clusto.exceptions import DriverException

from IPy import IP
import libvirt

class XenVirtualServer(BasicVirtualServer):
    _driver_name = "xenvirtualserver"

    def __init__(self, name, **kwargs):
        BasicVirtualServer.__init__(self, name, **kwargs)

    def _libvirt_create_disk(self, conn, name, capacity, vgname):
        volume = ElementTree.XML('''
        <volume>
            <name></name>
            <capacity></capacity>
            <target>
                <path></path>
            </target>
        </volume>''')
        volume.find('name').text = '%s-%s' % (self.name, name)
        volume.find('capacity').text = str(capacity)
        volume.find('target/path').text = '/dev/%s/%s-%s' % (vgname, self.name, name)

        vg = conn.storagePoolLookupByName(vgname)
        return vg.createXML(ElementTree.tostring(volume), 0)

    def _libvirt_delete_disk(self, conn, name, vgname):
        vol = conn.storageVolLookupByPath('/dev/%s/%s-%s' % (vgname, self.name, name))
        if vol.delete(0) != 0:
            raise DriverException('Unable to delete disk %s-%s' % (self.name, name))

    def _libvirt_create_domain(self, conn, memory, cpucount, vgname):
        domain = ElementTree.XML('''
        <domain type="xen">
            <name></name>
            <memory></memory>
            <vcpu></vcpu>
            <os>
                <type>hvm</type>
                <loader>/usr/lib/xen-default/boot/hvmloader</loader>
                <boot dev="hd" />
                <boot dev="network" />
            </os>
            <features>
                <pae />
            </features>
            <devices>
                <disk type="block">
                    <source />
                    <target />
                </disk>
                <disk type="block">
                    <source />
                    <target />
                </disk>
                <interface type="bridge">
                    <mac />
                    <source bridge="eth0" />
                </interface>
                <console type="pty">
                    <target port="0" />
                </console>
            </devices>
        </domain>''')

        domain.find('name').text = self.name
        domain.find('memory').text = str(memory)
        domain.find('vcpu').text = str(cpucount)

        disks = list(domain.findall('devices/disk'))
        disks[0].find('source').set('dev', '/dev/%s/%s-root' % (vgname, self.name))
        disks[0].find('target').set('dev', 'sda')
        disks[1].find('source').set('dev', '/dev/%s/%s-swap' % (vgname, self.name))
        disks[1].find('target').set('dev', 'sdb')

        domain.find('devices/interface/mac').set('address', self.get_port_attr('nic-eth', 1, 'mac'))

        xml = ElementTree.tostring(domain)
        print xml
        return conn.defineXML(xml)

    def _libvirt_delete_domain(self, conn):
        domain = conn.lookupByName(self.name)
        if domain.undefine() != 0:
            raise DriverException('Unable to delete (undefine) domain %s' % name)

    def _libvirt_connect(self):
        # Connect to the hypervisor
        from clusto.drivers import VMManager
        host = VMManager.resources(self)
        if not host:
            raise DriverException('Cannot start a VM without first allocating a hypervisor with VMManager.allocate')
        host = host[0].value

        ip = host.get_ips()
        if not ip:
            raise DriverException('Hypervisor does not have an IP!')
        ip = ip[0]

        conn = libvirt.open('xen+tcp://%s' % ip)
        if not conn:
            raise DriverException('Unable to connect to hypervisor! xen+tcp://%s' % ip)
        return conn

    def vm_create(self, conn=None):
        print 'Connecting to libvirt'
        if not conn:
            conn = self._libvirt_connect()

        print 'Getting system attributes'
        # Get and validate attributes
        disk_size = self.attr_values(key='system', subkey='disk')
        memory_size = self.attr_values(key='system', subkey='memory')
        swap_size = self.attr_values(key='system', subkey='swap')
        cpu_count = self.attr_values(key='system', subkey='cpucount')

        print 'Checking specs'
        if not disk_size:
            raise DriverException('Cannot create a VM without a key=system,subkey=disk parameter (disk size in GB)')
        if not memory_size:
            raise DriverException('Cannot create a VM without a key=system,subkey=memory parameter (memory size in MB)')
        if not swap_size:
            swap_size = [512]
        if not cpu_count:
            cpu_count = [1]

        disk_size = disk_size[0]
        swap_size = swap_size[0]
        memory_size = memory_size[0]
        cpu_count = cpu_count[0]

        disk_size *= 1073741824
        swap_size *= 1048576
        memory_size *= 1024

        print 'disk', disk_size
        print 'swap', swap_size
        print 'cpu', cpu_count
        print 'memory', memory_size

        # Create disks and domain
        print 'create_root'
        if not self._libvirt_create_disk(conn, 'root', disk_size, 'vol0'):
            raise DriverException('Unable to create logical volume %s-root' % self.name)
        print 'create_swap'
        if not self._libvirt_create_disk(conn, 'swap', swap_size, 'vol0'):
            raise DriverException('Unable to create logical volume %s-swap' % self.name)
        print 'create_domain'
        if not self._libvirt_create_domain(conn, memory_size, cpu_count, 'vol0'):
            raise DriverException('Unable to define domain %s' % self.name)

    def vm_start(self, conn=None):
        if not conn:
            conn = self._libvirt_connect()
        domain = conn.lookupByName(self.name)
        if domain.create() != 0:
            raise DriverException('Unable to start domain %s' % self.name)

    def vm_stop(self, force=False, conn=None):
        if not conn:
            conn = self._libvirt_connect()
        domain = conn.lookupByName(self.name)

        if force:
            ret = domain.destroy()
        else:
            ret = domain.shutdown()

        if ret != 0:
            raise DriverException('Unable to stop (destroy) domain %s' % self.name)

    def vm_reboot(self, conn=None):
        if not conn:
            conn = self._libvirt_connect()
        domain = conn.lookupByName(self.name)
        if domain.reboot() != 0:
            raise DriverException('Unable to reboot domain %s' % self.name)

    def vm_delete(self, conn=None):
        if not conn:
            conn = self._libvirt_connect()

        self._libvirt_delete_domain(conn)
        self._libvirt_delete_disk(conn, 'root', 'vol0')
        self._libvirt_delete_disk(conn, 'swap', 'vol0')
<commit_msg>Remove debug statements from XenVirtualServer<commit_after>from xml.etree import ElementTree
from random import shuffle

from basicserver import BasicVirtualServer
from clusto.exceptions import DriverException

from IPy import IP
import libvirt

class XenVirtualServer(BasicVirtualServer):
    _driver_name = "xenvirtualserver"

    def __init__(self, name, **kwargs):
        BasicVirtualServer.__init__(self, name, **kwargs)

    def _libvirt_create_disk(self, conn, name, capacity, vgname):
        volume = ElementTree.XML('''
        <volume>
            <name></name>
            <capacity></capacity>
            <target>
                <path></path>
            </target>
        </volume>''')
        volume.find('name').text = '%s-%s' % (self.name, name)
        volume.find('capacity').text = str(capacity)
        volume.find('target/path').text = '/dev/%s/%s-%s' % (vgname, self.name, name)

        vg = conn.storagePoolLookupByName(vgname)
        return vg.createXML(ElementTree.tostring(volume), 0)

    def _libvirt_delete_disk(self, conn, name, vgname):
        vol = conn.storageVolLookupByPath('/dev/%s/%s-%s' % (vgname, self.name, name))
        if vol.delete(0) != 0:
            raise DriverException('Unable to delete disk %s-%s' % (self.name, name))

    def _libvirt_create_domain(self, conn, memory, cpucount, vgname):
        domain = ElementTree.XML('''
        <domain type="xen">
            <name></name>
            <memory></memory>
            <vcpu></vcpu>
            <os>
                <type>hvm</type>
                <loader>/usr/lib/xen-default/boot/hvmloader</loader>
                <boot dev="hd" />
                <boot dev="network" />
            </os>
            <features>
                <pae />
            </features>
            <devices>
                <disk type="block">
                    <source />
                    <target />
                </disk>
                <disk type="block">
                    <source />
                    <target />
                </disk>
                <interface type="bridge">
                    <mac />
                    <source bridge="eth0" />
                </interface>
                <console type="pty">
                    <target port="0" />
                </console>
            </devices>
        </domain>''')

        domain.find('name').text = self.name
        domain.find('memory').text = str(memory)
        domain.find('vcpu').text = str(cpucount)

        disks = list(domain.findall('devices/disk'))
        disks[0].find('source').set('dev', '/dev/%s/%s-root' % (vgname, self.name))
        disks[0].find('target').set('dev', 'sda')
        disks[1].find('source').set('dev', '/dev/%s/%s-swap' % (vgname, self.name))
        disks[1].find('target').set('dev', 'sdb')

        domain.find('devices/interface/mac').set('address', self.get_port_attr('nic-eth', 1, 'mac'))

        xml = ElementTree.tostring(domain)
        return conn.defineXML(xml)

    def _libvirt_delete_domain(self, conn):
        domain = conn.lookupByName(self.name)
        if domain.undefine() != 0:
            raise DriverException('Unable to delete (undefine) domain %s' % name)

    def _libvirt_connect(self):
        # Connect to the hypervisor
        from clusto.drivers import VMManager
        host = VMManager.resources(self)
        if not host:
            raise DriverException('Cannot start a VM without first allocating a hypervisor with VMManager.allocate')
        host = host[0].value

        ip = host.get_ips()
        if not ip:
            raise DriverException('Hypervisor does not have an IP!')
        ip = ip[0]

        conn = libvirt.open('xen+tcp://%s' % ip)
        if not conn:
            raise DriverException('Unable to connect to hypervisor! xen+tcp://%s' % ip)
        return conn

    def vm_create(self, conn=None):
        if not conn:
            conn = self._libvirt_connect()

        # Get and validate attributes
        disk_size = self.attr_values(key='system', subkey='disk')
        memory_size = self.attr_values(key='system', subkey='memory')
        swap_size = self.attr_values(key='system', subkey='swap')
        cpu_count = self.attr_values(key='system', subkey='cpucount')

        if not disk_size:
            raise DriverException('Cannot create a VM without a key=system,subkey=disk parameter (disk size in GB)')
        if not memory_size:
            raise DriverException('Cannot create a VM without a key=system,subkey=memory parameter (memory size in MB)')
        if not swap_size:
            swap_size = [512]
        if not cpu_count:
            cpu_count = [1]

        disk_size = disk_size[0]
        swap_size = swap_size[0]
        memory_size = memory_size[0]
        cpu_count = cpu_count[0]

        disk_size *= 1073741824
        swap_size *= 1048576
        memory_size *= 1024

        # Create disks and domain
        if not self._libvirt_create_disk(conn, 'root', disk_size, 'vol0'):
            raise DriverException('Unable to create logical volume %s-root' % self.name)
        if not self._libvirt_create_disk(conn, 'swap', swap_size, 'vol0'):
            raise DriverException('Unable to create logical volume %s-swap' % self.name)
        if not self._libvirt_create_domain(conn, memory_size, cpu_count, 'vol0'):
            raise DriverException('Unable to define domain %s' % self.name)

    def vm_start(self, conn=None):
        if not conn:
            conn = self._libvirt_connect()
        domain = conn.lookupByName(self.name)
        if domain.create() != 0:
            raise DriverException('Unable to start domain %s' % self.name)

    def vm_stop(self, force=False, conn=None):
        if not conn:
            conn = self._libvirt_connect()
        domain = conn.lookupByName(self.name)

        if force:
            ret = domain.destroy()
        else:
            ret = domain.shutdown()

        if ret != 0:
            raise DriverException('Unable to stop (destroy) domain %s' % self.name)

    def vm_reboot(self, conn=None):
        if not conn:
            conn = self._libvirt_connect()
        domain = conn.lookupByName(self.name)
        if domain.reboot() != 0:
            raise DriverException('Unable to reboot domain %s' % self.name)

    def vm_delete(self, conn=None):
        if not conn:
            conn = self._libvirt_connect()

        self._libvirt_delete_domain(conn)
        self._libvirt_delete_disk(conn, 'root', 'vol0')
        self._libvirt_delete_disk(conn, 'swap', 'vol0')
<|endoftext|>


<commit_before>import paddle.v2.framework.core as core
from paddle.v2.framework.op import Operator
import numpy
import paddle.v2 as paddle

BATCH_SIZE = 100

scope = core.Scope()
place = core.CPUPlace()
# if you want to test GPU training, you can use gpu place
# place = core.GPUPlace(0)
dev_ctx = core.DeviceContext.create(place)

init_net = core.Net.create()
forward_net = core.Net.create()
backward_net = None
optimize_net = core.Net.create()

def atomic_id():
    id = 0
    while True:
        yield id
        id += 1

uniq_id = atomic_id().next

def data_layer(name, dims):
    var = scope.new_var(name)
    tensor = var.get_tensor()
    tensor.set_dims(dims)  # 1 is batch size holder.
    return name

def feed_data(name, data):
    assert isinstance(data, numpy.ndarray)
    tensor = scope.find_var(name).get_tensor()
    tensor.set_dims(data.shape)
    if data.dtype == numpy.dtype('int32'):
        tensor.alloc_int(place)
    elif data.dtype == numpy.dtype('float32'):
        tensor.alloc_float(place)
    else:
        raise ValueError("data type not supported")
    tensor.set(data, place)

def grad_var_name(var_name):
    return var_name + "@GRAD"

def sgd_optimizer(net, param_name, learning_rate=0.005):
    grad_name = grad_var_name(param_name)
    optimize_op = Operator(
        "sgd",
        param=param_name,
        grad=grad_name,
        param_out=param_name,
        learning_rate=learning_rate)
    net.append_op(optimize_op)

# should use operator and add these to the init_network
def init_param(net, param_name, dims):
    scope.new_var(param_name)
    op = Operator(
        "uniform_random", Out=param_name, dims=dims, min=-0.5, max=0.5, seed=10)
    op.infer_shape(scope)
    net.append_op(op)

# fc_layer
def fc_layer(net, input, size, act="softmax", bias=True, param=None, name=None):
    """
    Add a fc layer to net

    :param input: input variable name.
    :type input: str
    :param size: fully connected layer size.
    :param act: activation name
    :param param: parameter attribute, used for initialize parameters.
    :param bias: bias attribute. False will not have a bias.
    :param name: the name of fc layer. If not set, model will generate a
    readable name
    :return: output variable name.
    """
    if name is None:
        name = 'fc_%d' % uniq_id()
    if not isinstance(name, str):
        raise ValueError("name should be string")

    input_dims = scope.find_var(input).get_tensor().get_dims()

    w_name = param or name + ".w"
    init_param(net=init_net, param_name=w_name, dims=[input_dims[1], size])
    sgd_optimizer(net=optimize_net, param_name=w_name, learning_rate=0.01)

    pre_activation = name + ".mul.out"
    scope.new_var(pre_activation)
    mul_op = Operator("mul", X=input, Y=w_name, Out=pre_activation)
    net.append_op(mul_op)

    # create bias variable if needed
    if bias:
        bias_name = name + ".b"
        init_param(net=init_net, param_name=bias_name, dims=[size])
        sgd_optimizer(
            net=optimize_net, param_name=bias_name, learning_rate=0.001)
        bias_out = name + ".rowwise_add.out"
        scope.new_var(bias_out)
        rowwise_append_op = Operator(
            "rowwise_add", X=pre_activation, b=bias_name, Out=bias_out)
        net.append_op(rowwise_append_op)
        pre_activation = bias_out

    activation_op = Operator(act, X=pre_activation, Y=name)
    net.append_op(activation_op)
    scope.new_var(name)
    net.infer_shape(scope)
    return name

def cross_entropy_layer(net, input, label):
    cost_name = 'cross_entropy_%d' % uniq_id()
    cross_entropy_op = Operator(
        "onehot_cross_entropy", X=input, label=label, Y=cost_name)
    net.append_op(cross_entropy_op)
    scope.new_var(cost_name)
    net.infer_shape(scope)
    return cost_name

def create_backward_net(forward_net):
    net = core.Operator.backward(forward_net, set())
    for input in net.inputs()["all"]:
        var = scope.new_var(input)
        var.get_tensor()
    for output in net.outputs()["all"]:
        var = scope.new_var(output)
        var.get_tensor()
    return net

def debug_print_op(op):
    print("===============" + op.type() + "==============")
    print("***inputs:***")
    for input in op.inputs()["all"]:
        print input, scope.find_var(input).get_tensor().get_dims()
    print("\n***outputs:***")
    for output in op.outputs()["all"]:
        print output, scope.find_var(output).get_tensor().get_dims()
    print("")
    print("")

def set_cost(cost):
    cost_shape = numpy.array(scope.find_var(cost).get_tensor()).shape
    cost_grad = \
        scope.find_var(grad_var_name(cost)).get_tensor()
    cost_grad.set_dims(cost_shape)
    cost_grad.alloc_float(place)
    cost_grad.set(numpy.ones(cost_shape).astype("float32"), place)

def get_cost_mean(cost):
    cost_data = numpy.array(scope.find_var(cost).get_tensor())
    return cost_data.sum() / len(cost_data)

def error_rate(predict, label):
    predict_var = numpy.array(scope.find_var(predict).get_tensor()).argmax(
        axis=1)
    label = numpy.array(scope.find_var(label).get_tensor())
    error_num = numpy.sum(predict_var != label)
    return error_num / float(len(label))

images = data_layer(name='pixel', dims=[BATCH_SIZE, 784])
labels = data_layer(name='label', dims=[BATCH_SIZE])
fc1 = fc_layer(net=forward_net, input=images, size=100, act="sigmoid")
fc2 = fc_layer(net=forward_net, input=fc1, size=100, act="sigmoid")
predict = fc_layer(net=forward_net, input=fc2, size=100, act="softmax")
cost = cross_entropy_layer(net=forward_net, input=predict, label=labels)

init_net.complete_add_op(True)
forward_net.complete_add_op(True)
backward_net = create_backward_net(forward_net)
optimize_net.complete_add_op(True)

print(init_net)
print(forward_net)
print(backward_net)
print(optimize_net)

debug_print_op(forward_net)
debug_print_op(backward_net)
debug_print_op(optimize_net)

train_reader = paddle.batch(
    paddle.reader.shuffle(
        paddle.dataset.mnist.train(), buf_size=8192),
    batch_size=BATCH_SIZE)

def test(cost_name):
    test_reader = paddle.batch(
        paddle.dataset.mnist.test(), batch_size=BATCH_SIZE)
    cost = []
    error = []
    for data in test_reader():
        image_data = numpy.array(map(lambda x: x[0], data)).astype("float32")
        label_data = numpy.array(map(lambda x: x[1], data)).astype("int32")
        feed_data(images, image_data)
        feed_data(labels, label_data)

        forward_net.infer_shape(scope)
        forward_net.run(scope, dev_ctx)
        cost.append(get_cost_mean(cost_name))
        error.append(error_rate(predict, "label"))
    print("cost=" + str(sum(cost) / float(len(cost))) + " error_rate=" + str(
        sum(error) / float(len(error))))

PASS_NUM = 1

init_net.run(scope, dev_ctx)
for pass_id in range(PASS_NUM):
    batch_id = 0

    for data in train_reader():
        image_data = numpy.array(map(lambda x: x[0], data)).astype("float32")
        label_data = numpy.array(map(lambda x: x[1], data)).astype("int32")
        feed_data(images, image_data)
        feed_data(labels, label_data)

        forward_net.infer_shape(scope)
        forward_net.run(scope, dev_ctx)
        set_cost(cost)
        backward_net.infer_shape(scope)
        backward_net.run(scope, dev_ctx)

        optimize_net.run(scope, dev_ctx)
        if batch_id % 100 == 0:
            print("pass[" + str(pass_id) + "] batch_id[" + str(batch_id) + "]")
            test(cost)

        batch_id = batch_id + 1
<commit_msg>change predict size to label class_num<commit_after>import paddle.v2.framework.core as core
from paddle.v2.framework.op import Operator
import numpy
import paddle.v2 as paddle

BATCH_SIZE = 100

scope = core.Scope()
place = core.CPUPlace()
# if you want to test GPU training, you can use gpu place
# place = core.GPUPlace(0)
dev_ctx = core.DeviceContext.create(place)

init_net = core.Net.create()
forward_net = core.Net.create()
backward_net = None
optimize_net = core.Net.create()

def atomic_id():
    id = 0
    while True:
        yield id
        id += 1

uniq_id = atomic_id().next

def data_layer(name, dims):
    var = scope.new_var(name)
    tensor = var.get_tensor()
    tensor.set_dims(dims)  # 1 is batch size holder.
    return name

def feed_data(name, data):
    assert isinstance(data, numpy.ndarray)
    tensor = scope.find_var(name).get_tensor()
    tensor.set_dims(data.shape)
    if data.dtype == numpy.dtype('int32'):
        tensor.alloc_int(place)
    elif data.dtype == numpy.dtype('float32'):
        tensor.alloc_float(place)
    else:
        raise ValueError("data type not supported")
    tensor.set(data, place)

def grad_var_name(var_name):
    return var_name + "@GRAD"

def sgd_optimizer(net, param_name, learning_rate=0.005):
    grad_name = grad_var_name(param_name)
    optimize_op = Operator(
        "sgd",
        param=param_name,
        grad=grad_name,
        param_out=param_name,
        learning_rate=learning_rate)
    net.append_op(optimize_op)

# should use operator and add these to the init_network
def init_param(net, param_name, dims):
    scope.new_var(param_name)
    op = Operator(
        "uniform_random", Out=param_name, dims=dims, min=-0.5, max=0.5, seed=10)
    op.infer_shape(scope)
    net.append_op(op)

# fc_layer
def fc_layer(net, input, size, act="softmax", bias=True, param=None, name=None):
    """
    Add a fc layer to net

    :param input: input variable name.
    :type input: str
    :param size: fully connected layer size.
    :param act: activation name
    :param param: parameter attribute, used for initialize parameters.
    :param bias: bias attribute. False will not have a bias.
    :param name: the name of fc layer. If not set, model will generate a
    readable name
    :return: output variable name.
    """
    if name is None:
        name = 'fc_%d' % uniq_id()
    if not isinstance(name, str):
        raise ValueError("name should be string")

    input_dims = scope.find_var(input).get_tensor().get_dims()

    w_name = param or name + ".w"
    init_param(net=init_net, param_name=w_name, dims=[input_dims[1], size])
    sgd_optimizer(net=optimize_net, param_name=w_name, learning_rate=0.01)

    pre_activation = name + ".mul.out"
    scope.new_var(pre_activation)
    mul_op = Operator("mul", X=input, Y=w_name, Out=pre_activation)
    net.append_op(mul_op)

    # create bias variable if needed
    if bias:
        bias_name = name + ".b"
        init_param(net=init_net, param_name=bias_name, dims=[size])
        sgd_optimizer(
            net=optimize_net, param_name=bias_name, learning_rate=0.001)
        bias_out = name + ".rowwise_add.out"
        scope.new_var(bias_out)
        rowwise_append_op = Operator(
            "rowwise_add", X=pre_activation, b=bias_name, Out=bias_out)
        net.append_op(rowwise_append_op)
        pre_activation = bias_out

    activation_op = Operator(act, X=pre_activation, Y=name)
    net.append_op(activation_op)
    scope.new_var(name)
    net.infer_shape(scope)
    return name

def cross_entropy_layer(net, input, label):
    cost_name = 'cross_entropy_%d' % uniq_id()
    cross_entropy_op = Operator(
        "onehot_cross_entropy", X=input, label=label, Y=cost_name)
    net.append_op(cross_entropy_op)
    scope.new_var(cost_name)
    net.infer_shape(scope)
    return cost_name

def create_backward_net(forward_net):
    net = core.Operator.backward(forward_net, set())
    for input in net.inputs()["all"]:
        var = scope.new_var(input)
        var.get_tensor()
    for output in net.outputs()["all"]:
        var = scope.new_var(output)
        var.get_tensor()
    return net

def debug_print_op(op):
    print("===============" + op.type() + "==============")
    print("***inputs:***")
    for input in op.inputs()["all"]:
        print input, scope.find_var(input).get_tensor().get_dims()
    print("\n***outputs:***")
    for output in op.outputs()["all"]:
        print output, scope.find_var(output).get_tensor().get_dims()
    print("")
    print("")

def set_cost(cost):
    cost_shape = numpy.array(scope.find_var(cost).get_tensor()).shape
    cost_grad = \
        scope.find_var(grad_var_name(cost)).get_tensor()
    cost_grad.set_dims(cost_shape)
    cost_grad.alloc_float(place)
    cost_grad.set(numpy.ones(cost_shape).astype("float32"), place)

def get_cost_mean(cost):
    cost_data = numpy.array(scope.find_var(cost).get_tensor())
    return cost_data.sum() / len(cost_data)

def error_rate(predict, label):
    predict_var = numpy.array(scope.find_var(predict).get_tensor()).argmax(
        axis=1)
    label = numpy.array(scope.find_var(label).get_tensor())
    error_num = numpy.sum(predict_var != label)
    return error_num / float(len(label))

images = data_layer(name='pixel', dims=[BATCH_SIZE, 784])
labels = data_layer(name='label', dims=[BATCH_SIZE])
fc1 = fc_layer(net=forward_net, input=images, size=100, act="sigmoid")
fc2 = fc_layer(net=forward_net, input=fc1, size=100, act="sigmoid")
predict = fc_layer(net=forward_net, input=fc2, size=10, act="softmax")
cost = cross_entropy_layer(net=forward_net, input=predict, label=labels)

init_net.complete_add_op(True)
forward_net.complete_add_op(True)
backward_net = create_backward_net(forward_net)
optimize_net.complete_add_op(True)

print(init_net)
print(forward_net)
print(backward_net)
print(optimize_net)

debug_print_op(forward_net)
debug_print_op(backward_net)
debug_print_op(optimize_net)

train_reader = paddle.batch(
    paddle.reader.shuffle(
        paddle.dataset.mnist.train(), buf_size=8192),
    batch_size=BATCH_SIZE)

def test(cost_name):
    test_reader = paddle.batch(
        paddle.dataset.mnist.test(), batch_size=BATCH_SIZE)
    cost = []
    error = []
    for data in test_reader():
        image_data = numpy.array(map(lambda x: x[0], data)).astype("float32")
        label_data = numpy.array(map(lambda x: x[1], data)).astype("int32")
        feed_data(images, image_data)
        feed_data(labels, label_data)

        forward_net.infer_shape(scope)
        forward_net.run(scope, dev_ctx)
        cost.append(get_cost_mean(cost_name))
        error.append(error_rate(predict, "label"))
    print("cost=" + str(sum(cost) / float(len(cost))) + " error_rate=" + str(
        sum(error) / float(len(error))))

PASS_NUM = 10

init_net.run(scope, dev_ctx)
for pass_id in range(PASS_NUM):
    batch_id = 0

    for data in train_reader():
        image_data = numpy.array(map(lambda x: x[0], data)).astype("float32")
        label_data = numpy.array(map(lambda x: x[1], data)).astype("int32")
        feed_data(images, image_data)
        feed_data(labels, label_data)

        forward_net.infer_shape(scope)
        forward_net.run(scope, dev_ctx)
        set_cost(cost)
        backward_net.infer_shape(scope)
        backward_net.run(scope, dev_ctx)

        optimize_net.run(scope, dev_ctx)
        if batch_id % 100 == 0:
            print("pass[" + str(pass_id) + "] batch_id[" + str(batch_id) + "]")
            test(cost)

        batch_id = batch_id + 1
<|endoftext|>


<commit_before># License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields, api
from datetime import datetime
from dateutil.relativedelta import relativedelta

class SaleStockReserve(models.TransientModel):
    _inherit = 'sale.stock.reserve'

    @api.multi
    def button_reserve(self):
        order_id = self.env.context.get('params').get('id')
        order_obj = self.env['sale.order'].browse(order_id)
        days_release_reserve = self.env['ir.config_parameter'].sudo().get_param('days_to_release_reserve_stock')
        now = datetime.now()

        if order_obj.infinite_reservation:
            date_validity = (now + relativedelta(days=365)).strftime("%Y-%m-%d")
        else:
            date_validity = (now + relativedelta(days=int(days_release_reserve))).strftime("%Y-%m-%d")

        self.ensure_one()
        lines = self._get_so_lines()
        if lines and not self.date_validity \
                or self.date_validity > date_validity:
            lines.acquire_stock_reservation(date_validity=date_validity,
                                            note=self.note)
        else:
            super().button_reserve()
        return {'type': 'ir.actions.act_window_close'}
<commit_msg>[FIX] reserve_without_save_sale: corregido funcionamiento del check "reservas infinitas" en la reserva mediante candado<commit_after># License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields, api
from datetime import datetime
from dateutil.relativedelta import relativedelta

class SaleStockReserve(models.TransientModel):
    _inherit = 'sale.stock.reserve'

    @api.multi
    def button_reserve(self):
        sale_line_id = self.env.context.get('active_id')
        sale_line_obj = self.env['sale.order.line'].browse(sale_line_id)
        order_obj = sale_line_obj.order_id
        days_release_reserve = self.env['ir.config_parameter'].sudo().get_param('days_to_release_reserve_stock')
        now = datetime.now()

        if order_obj.infinite_reservation:
            date_validity = (now + relativedelta(days=365)).strftime("%Y-%m-%d")
        else:
            date_validity = (now + relativedelta(days=int(days_release_reserve))).strftime("%Y-%m-%d")

        self.ensure_one()
        lines = self._get_so_lines()
        if lines and not self.date_validity \
                or self.date_validity > date_validity:
            lines.acquire_stock_reservation(date_validity=date_validity,
                                            note=self.note)
        else:
            super().button_reserve()
        return {'type': 'ir.actions.act_window_close'}
<|endoftext|>