~cubic-wizard/cubic/experimental

« back to all changes in this revision

Viewing changes to usr/share/cubic/cubic/pages/preseed_copy_page.py

  • Committer: PJ Singh
  • Date: 2021-11-30 01:31:16 UTC
  • Revision ID: psingh.cubic@gmail.com-20211130013116-yspl57zt59xfr1e5
* Fixed Bug #1951662, On the Copy pages, pause to allow the user to view the results before automatically transitioning away from the page. * Fixed Bug #1951693, On the Copy pages, clicking the Cancel button may be unresponsive. * Fixed Bug #1951695, Show error status on the Copy pages. * Fixed Bug #1951715, On the Generate page, clicking the Back during update checksums may be unresponsive. * Experimental fix for issue, Cannot install Cubic in Linux Mint 19.x.

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
########################################################################
39
39
 
40
40
import os
 
41
import time
41
42
import urllib
42
43
 
43
 
from cubic.constants import BOLD_RED, NORMAL
 
44
from cubic.constants import BOLD_RED, MAGENTA, NORMAL
44
45
from cubic.constants import FINAL_PERCENT
 
46
from cubic.constants import SLEEP_1000_MS
 
47
from cubic.navigator import InterruptException
45
48
from cubic.utilities import constructor
46
49
from cubic.utilities import displayer
47
50
from cubic.utilities import iso_utilities
72
75
        count = len(model.selected_uris)
73
76
        count_text = constructor.number_as_text(count)
74
77
        files_text = constructor.get_plural('file', 'files', count)
75
 
        # label = 'Copy %s %s to <span font_family="monospace">%s</span>...' % (count_text, files_text, model.current_directory)
76
 
        label = 'Copy %s %s to %s...' % (count_text, files_text, model.current_directory)
 
78
        message = f'Copy {count_text} {files_text} to {model.current_directory}...'
77
79
 
78
80
        # Create a file details list of files to be copied.
79
81
        file_details_list = create_file_details_list(model.selected_uris)
80
82
 
81
 
        displayer.update_label('preseed_copy_page__progress_label', label)
 
83
        displayer.update_label('preseed_copy_page__progress_message', message)
82
84
        displayer.update_progress_bar_text('preseed_copy_page__copy_files_progress_bar', None)
83
85
        displayer.update_progress_bar_percent('preseed_copy_page__copy_files_progress_bar', 0)
 
86
        displayer.update_status('preseed_copy_page__progress', displayer.BULLET)
84
87
        displayer.update_list_store('preseed_copy_page__file_details__list_store', file_details_list)
85
88
 
86
89
        return
87
90
 
 
91
    elif action == 'error':
 
92
 
 
93
        # Handle the error from the leave() function.
 
94
 
 
95
        return
 
96
 
88
97
    else:
89
98
 
90
 
        logger.log_value('Error', BOLD_RED + 'Unknown action for setup' + NORMAL)
 
99
        logger.log_value('Error', f'{BOLD_RED}Unknown action for setup{NORMAL}')
91
100
 
92
101
        return 'unknown'
93
102
 
110
119
 
111
120
        return
112
121
 
 
122
    elif action == 'error':
 
123
 
 
124
        # Handle the error from the leave() function.
 
125
 
 
126
        return
 
127
 
113
128
    else:
114
129
 
115
 
        logger.log_value('Error', BOLD_RED + 'Unknown action for enter' + NORMAL)
 
130
        logger.log_value('Error', f'{BOLD_RED}Unknown action for enter{NORMAL}')
116
131
 
117
132
        return 'unknown'
118
133
 
129
144
 
130
145
        displayer.reset_buttons(is_back_sensitive=True, is_next_sensitive=False)
131
146
 
132
 
        copy_files(model.current_directory, model.selected_uris)
 
147
        is_error = copy_files(model.current_directory, model.selected_uris)
 
148
        if is_error: return 'error'  # Stay on this page.
133
149
 
134
150
        displayer.reset_buttons(is_back_sensitive=False, is_next_sensitive=False)
135
151
 
 
152
        # Pause to allow the user to see the result.
 
153
        time.sleep(SLEEP_1000_MS)
 
154
 
136
155
        return
137
156
 
138
157
    elif action == 'quit':
143
162
 
144
163
        return
145
164
 
 
165
    elif action == 'error':
 
166
 
 
167
        # Handle the error from the leave() function.
 
168
 
 
169
        return
 
170
 
146
171
    else:
147
172
 
148
173
        displayer.reset_buttons(is_back_sensitive=False, is_next_sensitive=False)
149
174
 
150
175
        iso_utilities.unmount_iso_and_delete_mount_point(model.project.iso_mount_point)
151
176
 
152
 
        logger.log_value('Error', BOLD_RED + 'Unknown action for leave' + NORMAL)
 
177
        logger.log_value('Error', f'{BOLD_RED}Unknown action for leave{NORMAL}')
153
178
 
154
179
        return 'unknown'
155
180
 
164
189
 
165
190
 
166
191
def create_file_details_list(uris):
167
 
    # logger.log_value('List files to copy')
168
192
 
169
193
    file_details_list = []
170
194
 
179
203
# Copy Files Functions
180
204
########################################################################
181
205
 
182
 
# TODO: Move these functions to file_utilities.py
183
 
 
184
206
 
185
207
def copy_files(current_directory, uris):
186
208
 
189
211
    global total_files
190
212
    total_files = len(uris)
191
213
 
192
 
    # It is necessary to strip the leading '/' from the current directory,
193
 
    # otherwise os.path.join() considers the current directory to be an absolute
194
 
    # path and discards the custom disk directory prefix: "If a component
195
 
    # is an absolute path, all previous components are thrown away and
196
 
    # os.path.joining continues from the absolute path component."
 
214
    # It is necessary to strip the leading '/' from the current
 
215
    # directory, otherwise os.path.join() considers the current
 
216
    # directory to be an absolute path and discards the custom root
 
217
    # directory prefix: "If a component is an absolute path, all
 
218
    # previous components are thrown away and os.path.joining continues
 
219
    # from the absolute path component."
197
220
    # (See https://docs.python.org/3/library/os.path.html).
198
221
    target_directory = os.path.abspath(os.path.join(model.project.custom_disk_directory, current_directory.strip(os.path.sep)))
199
222
 
201
224
    logger.log_value('The custom disk directory is', model.project.custom_disk_directory)
202
225
    logger.log_value('The target directory is', target_directory)
203
226
 
 
227
    displayer.update_status('preseed_copy_page__progress', displayer.PROCESSING)
 
228
 
204
229
    global file_number
205
 
    for file_number, uri in enumerate(uris):
206
 
 
207
 
        file_path = urllib.parse.unquote(urllib.parse.urlparse(uri).path)
208
 
 
209
 
        if total_files == 1:
210
 
            # label = 'Copying one file to <span font_family="monospace">%s</span>' % current_directory
211
 
            label = 'Copying one file to %s...' % current_directory
212
 
        else:
213
 
            # label = 'Copying file %s of %s to <span font_family="monospace">%s</span>' % (file_number + 1, total_files, current_directory)
214
 
            label = 'Copying file %s of %s to %s...' % (file_number + 1, total_files, current_directory)
215
 
 
216
 
        displayer.update_label('preseed_copy_page__progress_label', label)
217
 
        displayer.scroll_to_tree_view_row('preseed_copy_page__tree_view', file_number)
218
 
        displayer.select_tree_view_row('preseed_copy_page__tree_view', file_number)
219
 
 
220
 
        copy_file(file_path, file_number, target_directory, total_files)
 
230
    file_name = None
 
231
    try:
 
232
        for file_number, uri in enumerate(uris):
 
233
            file_path = urllib.parse.unquote(urllib.parse.urlparse(uri).path)
 
234
            if total_files == 1:
 
235
                message = f'Copying one file to {current_directory}...'
 
236
            else:
 
237
                message = f'Copying file {(file_number+1):n} of {total_files:n} to {current_directory}...'
 
238
            displayer.update_label('preseed_copy_page__progress_message', message)
 
239
            displayer.scroll_to_tree_view_row('preseed_copy_page__tree_view', file_number)
 
240
            displayer.select_tree_view_row('preseed_copy_page__tree_view', file_number)
 
241
            copy_file(file_path, file_number, target_directory, total_files)
 
242
    except InterruptException as exception:
 
243
        displayer.update_status('preseed_copy_page__progress', displayer.ERROR)
 
244
        file_name = os.path.basename(file_path)
 
245
        if 'No space left on device' in str(exception):
 
246
            message = f'<span foreground="red">Error. Unable to copy files to {current_directory}. Not enough space on the disk.</span>'
 
247
        else:
 
248
            message = f'<span foreground="red">Error. Unable to copy files to {current_directory}.</span>'
 
249
        displayer.update_label('preseed_copy_page__progress_message', message)
 
250
        logger.log_value('Propagate exception', exception)
 
251
        raise exception
 
252
    except Exception as exception:
 
253
        displayer.update_status('preseed_copy_page__progress', displayer.ERROR)
 
254
        file_name = os.path.basename(file_path)
 
255
        if 'No space left on device' in str(exception):
 
256
            message = f'<span foreground="red">Error. Unable to copy files to {current_directory}. Not enough space on the disk.</span>'
 
257
        else:
 
258
            message = f'<span foreground="red">Error. Unable to copy files to {current_directory}.</span>'
 
259
        displayer.update_label('preseed_copy_page__progress_message', message)
 
260
        logger.log_value('Do not propagate exception', exception)
 
261
        return True  # (Error)
 
262
 
 
263
    displayer.update_status('preseed_copy_page__progress', displayer.OK)
 
264
    number_text = constructor.number_as_text(total_files)
 
265
    plural_text = constructor.get_plural('file', 'files', total_files)
 
266
    message = f'Copied {number_text} {plural_text} to {current_directory}.'
 
267
    displayer.update_label('preseed_copy_page__progress_message', message)
 
268
    return False  # (No error)
221
269
 
222
270
 
223
271
def copy_file(file_path, file_number, directory, total_files):
224
272
 
225
 
    logger.log_label('Copy file number %s of %s' % (file_number + 1, total_files))
 
273
    logger.log_label(f'Copy file number {file_number+1} of {total_files}')
226
274
 
227
275
    logger.log_value('The file is', file_path)
228
276
    logger.log_value('The target directory is', directory)
229
277
 
230
278
    program = os.path.join(model.application.directory, 'commands', 'copy-path')
231
 
    command = 'pkexec "%s" "%s" "%s"' % (program, file_path, directory)
 
279
    command = f'pkexec "{program}" "{file_path}" "{directory}"'
232
280
 
233
281
    # The progress callback function.
234
282
    def progress_callback(percent):
238
286
        displayer.update_progress_bar_percent('preseed_copy_page__copy_files_progress_bar', total_percent)
239
287
        displayer.update_list_store_progress_bar_percent('preseed_copy_page__file_details__list_store', file_number, percent)
240
288
        if total_percent % 10 == 0:
241
 
            logger.log_value('Completed', '%i%%' % total_percent)
242
 
 
243
 
    exception, message = show_progress(command, progress_callback)
244
 
 
245
 
 
246
 
########################################################################
247
 
# Validation Functions
248
 
########################################################################
 
289
            logger.log_value('Completed', f'{total_percent:n}%')
 
290
 
 
291
    message = show_progress(command, progress_callback)