Code cleanup and refactoring
[snf-image-creator] / image_creator / dialog_util.py
1 #!/usr/bin/env python
2
3 # Copyright 2012 GRNET S.A. All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or
6 # without modification, are permitted provided that the following
7 # conditions are met:
8 #
9 #   1. Redistributions of source code must retain the above
10 #      copyright notice, this list of conditions and the following
11 #      disclaimer.
12 #
13 #   2. Redistributions in binary form must reproduce the above
14 #      copyright notice, this list of conditions and the following
15 #      disclaimer in the documentation and/or other materials
16 #      provided with the distribution.
17 #
18 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 # POSSIBILITY OF SUCH DAMAGE.
30 #
31 # The views and conclusions contained in the software and
32 # documentation are those of the authors and should not be
33 # interpreted as representing official policies, either expressed
34 # or implied, of GRNET S.A.
35
36 import os
37
38 SMALL_WIDTH = 60
39 WIDTH = 70
40
41
42 def update_background_title(session):
43     d = session['dialog']
44     dev = session['device']
45
46     MB = 2 ** 20
47
48     size = (dev.size + MB - 1) // MB
49     shrinked = 'shrinked' in session and session['shrinked']
50     postfix = " (shrinked)" if shrinked else ''
51
52     title = "OS: %s, Distro: %s, Size: %dMB%s" % \
53             (dev.ostype, dev.distro, size, postfix)
54
55     d.setBackgroundTitle(title)
56
57
58 def confirm_exit(d, msg=''):
59     return not d.yesno("%s Do you want to exit?" % msg, width=SMALL_WIDTH)
60
61
62 def confirm_reset(d):
63     return not d.yesno("Are you sure you want to reset everything?",
64                        width=SMALL_WIDTH, defaultno=1)
65
66
67 class Reset(Exception):
68     pass
69
70
71 def extract_image(session):
72     d = session['dialog']
73     dir = os.getcwd()
74     while 1:
75         if dir and dir[-1] != os.sep:
76             dir = dir + os.sep
77
78         (code, path) = d.fselect(dir, 10, 50, title="Save image as...")
79         if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
80             return False
81
82         if os.path.isdir(path):
83             dir = path
84             continue
85
86         if os.path.isdir("%s.meta" % path):
87             d.msgbox("Can't overwrite directory `%s.meta'" % path,
88                      width=SMALL_WIDTH)
89             continue
90
91         if os.path.isdir("%s.md5sum" % path):
92             d.msgbox("Can't overwrite directory `%s.md5sum'" % path,
93                      width=SMALL_WIDTH)
94             continue
95
96         basedir = os.path.dirname(path)
97         name = os.path.basename(path)
98         if not os.path.exists(basedir):
99             d.msgbox("Directory `%s' does not exist" % basedir,
100                      width=SMALL_WIDTH)
101             continue
102
103         dir = basedir
104         if len(name) == 0:
105             continue
106
107         files = ["%s%s" % (path, ext) for ext in ('', '.meta', '.md5sum')]
108         overwrite = filter(os.path.exists, files)
109
110         if len(overwrite) > 0:
111             if d.yesno("The following file(s) exist:\n"
112                        "%s\nDo you want to overwrite them?" %
113                        "\n".join(overwrite), width=SMALL_WIDTH):
114                 continue
115
116         gauge = GaugeOutput(d, "Image Extraction", "Extracting image...")
117         try:
118             dev = session['device']
119             out = dev.out
120             out.add(gauge)
121             try:
122                 if "checksum" not in session:
123                     size = dev.size
124                     md5 = MD5(out)
125                     session['checksum'] = md5.compute(session['snapshot'],
126                                                       size)
127
128                 # Extract image file
129                 dev.dump(path)
130
131                 # Extract metadata file
132                 out.output("Extracting metadata file...")
133                 with open('%s.meta' % path, 'w') as f:
134                     f.write(extract_metadata_string(session))
135                 out.success('done')
136
137                 # Extract md5sum file
138                 out.output("Extracting md5sum file...")
139                 md5str = "%s %s\n" % (session['checksum'], name)
140                 with open('%s.md5sum' % path, 'w') as f:
141                     f.write(md5str)
142                 out.success("done")
143             finally:
144                 out.remove(gauge)
145         finally:
146             gauge.cleanup()
147         d.msgbox("Image file `%s' was successfully extracted!" % path,
148                  width=SMALL_WIDTH)
149         break
150
151     return True
152
153 # vim: set sta sts=4 shiftwidth=4 sw=4 et ai :