Statistics
| Branch: | Tag: | Revision:

root / image_creator / output / dialog.py @ 12c97404

History | View | Annotate | Download (5.9 kB)

1 121f3bc0 Nikos Skalkotos
# -*- coding: utf-8 -*-
2 121f3bc0 Nikos Skalkotos
#
3 7bf93524 Nikos Skalkotos
# Copyright 2012 GRNET S.A. All rights reserved.
4 7bf93524 Nikos Skalkotos
#
5 7bf93524 Nikos Skalkotos
# Redistribution and use in source and binary forms, with or
6 7bf93524 Nikos Skalkotos
# without modification, are permitted provided that the following
7 7bf93524 Nikos Skalkotos
# conditions are met:
8 7bf93524 Nikos Skalkotos
#
9 7bf93524 Nikos Skalkotos
#   1. Redistributions of source code must retain the above
10 7bf93524 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
11 7bf93524 Nikos Skalkotos
#      disclaimer.
12 7bf93524 Nikos Skalkotos
#
13 7bf93524 Nikos Skalkotos
#   2. Redistributions in binary form must reproduce the above
14 7bf93524 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
15 7bf93524 Nikos Skalkotos
#      disclaimer in the documentation and/or other materials
16 7bf93524 Nikos Skalkotos
#      provided with the distribution.
17 7bf93524 Nikos Skalkotos
#
18 7bf93524 Nikos Skalkotos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 7bf93524 Nikos Skalkotos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 7bf93524 Nikos Skalkotos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 7bf93524 Nikos Skalkotos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 7bf93524 Nikos Skalkotos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 7bf93524 Nikos Skalkotos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 7bf93524 Nikos Skalkotos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 7bf93524 Nikos Skalkotos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 7bf93524 Nikos Skalkotos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 7bf93524 Nikos Skalkotos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 7bf93524 Nikos Skalkotos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 7bf93524 Nikos Skalkotos
# POSSIBILITY OF SUCH DAMAGE.
30 7bf93524 Nikos Skalkotos
#
31 7bf93524 Nikos Skalkotos
# The views and conclusions contained in the software and
32 7bf93524 Nikos Skalkotos
# documentation are those of the authors and should not be
33 7bf93524 Nikos Skalkotos
# interpreted as representing official policies, either expressed
34 7bf93524 Nikos Skalkotos
# or implied, of GRNET S.A.
35 7bf93524 Nikos Skalkotos
36 121f3bc0 Nikos Skalkotos
"""This module provides various dialog-based Output classes"""
37 121f3bc0 Nikos Skalkotos
38 7bf93524 Nikos Skalkotos
from image_creator.output import Output
39 7bf93524 Nikos Skalkotos
import time
40 7bf93524 Nikos Skalkotos
import fcntl
41 7bf93524 Nikos Skalkotos
42 7bf93524 Nikos Skalkotos
43 7bf93524 Nikos Skalkotos
class GaugeOutput(Output):
44 88f83027 Nikos Skalkotos
    """Output class implemented using dialog's gauge widget"""
45 7bf93524 Nikos Skalkotos
    def __init__(self, dialog, title, msg=''):
46 7bf93524 Nikos Skalkotos
        self.d = dialog
47 7bf93524 Nikos Skalkotos
        self.msg = msg
48 7bf93524 Nikos Skalkotos
        self.percent = 0
49 7bf93524 Nikos Skalkotos
        self.d.gauge_start(self.msg, title=title)
50 7bf93524 Nikos Skalkotos
51 7bf93524 Nikos Skalkotos
        # Open pipe workaround. A fork will dublicate the open file descriptor.
52 7bf93524 Nikos Skalkotos
        # The FD_CLOEXEC flag makes sure that the gauge internal fd will be
53 7bf93524 Nikos Skalkotos
        # closed if execve is executed. This is needed because libguestfs will
54 7bf93524 Nikos Skalkotos
        # fork/exec the kvm process. If this fd stays open in the kvm process,
55 7bf93524 Nikos Skalkotos
        # then doing a gauge_stop will make this process wait forever for
56 7bf93524 Nikos Skalkotos
        # a dialog process that is blocked waiting for input from the kvm
57 7bf93524 Nikos Skalkotos
        # process's open file descriptor.
58 7bf93524 Nikos Skalkotos
        fd = self.d._gauge_process['stdin'].fileno()
59 7bf93524 Nikos Skalkotos
        flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0)
60 7bf93524 Nikos Skalkotos
        fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
61 7bf93524 Nikos Skalkotos
62 7bf93524 Nikos Skalkotos
    def output(self, msg='', new_line=True):
63 88f83027 Nikos Skalkotos
        """Print msg as normal output"""
64 7bf93524 Nikos Skalkotos
        self.msg = msg
65 7bf93524 Nikos Skalkotos
        self.percent = 0
66 7bf93524 Nikos Skalkotos
        self.d.gauge_update(self.percent, self.msg, update_text=True)
67 7bf93524 Nikos Skalkotos
        time.sleep(0.4)
68 7bf93524 Nikos Skalkotos
69 7bf93524 Nikos Skalkotos
    def success(self, result, new_line=True):
70 88f83027 Nikos Skalkotos
        """Print result after a successfull action"""
71 7bf93524 Nikos Skalkotos
        self.percent = 100
72 7bf93524 Nikos Skalkotos
        self.d.gauge_update(self.percent, "%s %s" % (self.msg, result),
73 7bf93524 Nikos Skalkotos
                            update_text=True)
74 7bf93524 Nikos Skalkotos
        time.sleep(0.4)
75 7bf93524 Nikos Skalkotos
76 7bf93524 Nikos Skalkotos
    def warn(self, msg, new_line=True):
77 88f83027 Nikos Skalkotos
        """Print a warning"""
78 0d7d3237 Nikos Skalkotos
        self.d.gauge_update(self.percent, "%s Warning: %s" % (self.msg, msg),
79 7bf93524 Nikos Skalkotos
                            update_text=True)
80 7bf93524 Nikos Skalkotos
        time.sleep(0.4)
81 7bf93524 Nikos Skalkotos
82 7bf93524 Nikos Skalkotos
    def cleanup(self):
83 88f83027 Nikos Skalkotos
        """Cleanup the GaugeOutput instance"""
84 7bf93524 Nikos Skalkotos
        self.d.gauge_stop()
85 7bf93524 Nikos Skalkotos
86 7bf93524 Nikos Skalkotos
    class _Progress(Output._Progress):
87 88f83027 Nikos Skalkotos
        """Progress class for dialog's gauge widget"""
88 7bf93524 Nikos Skalkotos
        template = {
89 7bf93524 Nikos Skalkotos
            'default': '%(index)d/%(size)d',
90 7bf93524 Nikos Skalkotos
            'percent': '',
91 7bf93524 Nikos Skalkotos
            'b': "%(index)d/%(size)d B",
92 7bf93524 Nikos Skalkotos
            'kb': "%(index)d/%(size)d KB",
93 7bf93524 Nikos Skalkotos
            'mb': "%(index)d/%(size)d MB"
94 7bf93524 Nikos Skalkotos
        }
95 7bf93524 Nikos Skalkotos
96 7bf93524 Nikos Skalkotos
        def __init__(self, size, title, bar_type='default'):
97 7bf93524 Nikos Skalkotos
            self.output.size = size
98 7bf93524 Nikos Skalkotos
            self.bar_type = bar_type
99 663f5f80 Nikos Skalkotos
            self.output.msg = "%s ..." % title
100 7bf93524 Nikos Skalkotos
            self.goto(0)
101 7bf93524 Nikos Skalkotos
102 7bf93524 Nikos Skalkotos
        def _postfix(self):
103 7bf93524 Nikos Skalkotos
            return self.template[self.bar_type] % self.output.__dict__
104 7bf93524 Nikos Skalkotos
105 7bf93524 Nikos Skalkotos
        def goto(self, dest):
106 88f83027 Nikos Skalkotos
            """Move progress bar to a specific position"""
107 7bf93524 Nikos Skalkotos
            self.output.index = dest
108 7bf93524 Nikos Skalkotos
            self.output.percent = self.output.index * 100 // self.output.size
109 7bf93524 Nikos Skalkotos
            msg = "%s %s" % (self.output.msg, self._postfix())
110 7bf93524 Nikos Skalkotos
            self.output.d.gauge_update(self.output.percent, msg,
111 7bf93524 Nikos Skalkotos
                                       update_text=True)
112 7bf93524 Nikos Skalkotos
113 7bf93524 Nikos Skalkotos
        def next(self):
114 88f83027 Nikos Skalkotos
            """Move progress bar one step forward"""
115 7bf93524 Nikos Skalkotos
            self.goto(self.output.index + 1)
116 7bf93524 Nikos Skalkotos
117 7bf93524 Nikos Skalkotos
118 9afc4b89 Nikos Skalkotos
class InfoBoxOutput(Output):
119 88f83027 Nikos Skalkotos
    """Output class implemented using dialog's infobox widget"""
120 9afc4b89 Nikos Skalkotos
    def __init__(self, dialog, title, msg='', height=20, width=70):
121 9afc4b89 Nikos Skalkotos
        self.d = dialog
122 9afc4b89 Nikos Skalkotos
        self.title = title
123 9afc4b89 Nikos Skalkotos
        self.msg = msg
124 9afc4b89 Nikos Skalkotos
        self.width = width
125 9afc4b89 Nikos Skalkotos
        self.height = height
126 9afc4b89 Nikos Skalkotos
        self.d.infobox(self.msg, title=self.title)
127 9afc4b89 Nikos Skalkotos
128 9afc4b89 Nikos Skalkotos
    def output(self, msg='', new_line=True):
129 88f83027 Nikos Skalkotos
        """Print msg as normal output"""
130 9afc4b89 Nikos Skalkotos
        nl = '\n' if new_line else ''
131 9afc4b89 Nikos Skalkotos
        self.msg += "%s%s" % (msg, nl)
132 9afc4b89 Nikos Skalkotos
        # If output is long, only output the last lines that fit in the box
133 9afc4b89 Nikos Skalkotos
        lines = self.msg.splitlines()
134 9afc4b89 Nikos Skalkotos
        h = self.height
135 9afc4b89 Nikos Skalkotos
        display = self.msg if len(lines) <= h else "\n".join(lines[-h:])
136 9afc4b89 Nikos Skalkotos
        self.d.infobox(display, title=self.title, height=self.height,
137 9afc4b89 Nikos Skalkotos
                       width=self.width)
138 9afc4b89 Nikos Skalkotos
139 9afc4b89 Nikos Skalkotos
    def success(self, result, new_line=True):
140 88f83027 Nikos Skalkotos
        """Print result after an action is completed successfully"""
141 9afc4b89 Nikos Skalkotos
        self.output(result, new_line)
142 9afc4b89 Nikos Skalkotos
143 9afc4b89 Nikos Skalkotos
    def warn(self, msg, new_line=True):
144 88f83027 Nikos Skalkotos
        """Print a warning message"""
145 9afc4b89 Nikos Skalkotos
        self.output("Warning: %s" % msg, new_line)
146 9afc4b89 Nikos Skalkotos
147 9afc4b89 Nikos Skalkotos
    def finalize(self):
148 88f83027 Nikos Skalkotos
        """Finalize the output. After this is called, the InfoboxOutput
149 88f83027 Nikos Skalkotos
        instance should be destroyed
150 88f83027 Nikos Skalkotos
        """
151 a42a42b3 Nikos Skalkotos
        self.d.msgbox(self.msg, title=self.title, height=(self.height + 2),
152 a42a42b3 Nikos Skalkotos
                      width=self.width)
153 7bf93524 Nikos Skalkotos
154 7bf93524 Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :