Skip to content

Commit af28862

Browse files
JeansBoussiersuphamster
authored andcommitted
GUI: Add configurable temporary directory in GUI (#77)
This PR adds the ability to configure a custom temporary directory where unfinished processed videos are stored during the restoration process. Previously, the system temp directory was always used. Reviewed-on: https://codeberg.org/ladaapp/lada/pulls/77 Co-authored-by: suphamster <suphamster@noreply.codeberg.org> Co-committed-by: suphamster <suphamster@noreply.codeberg.org>
1 parent 6655863 commit af28862

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

lada/gui/config/config.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import json
55
import logging
6+
import tempfile
67
import threading
78
from enum import Enum
89
from pathlib import Path
@@ -44,6 +45,7 @@ class Config(GObject.Object):
4445
'post_export_custom_command': '',
4546
'preview_buffer_duration': 0,
4647
'show_mosaic_detections': False,
48+
'temp_directory': tempfile.gettempdir(),
4749
}
4850

4951
def __init__(self, style_manager: Adw.StyleManager):
@@ -64,6 +66,7 @@ def __init__(self, style_manager: Adw.StyleManager):
6466
self._show_mosaic_detections = self._defaults['show_mosaic_detections']
6567
self._post_export_action = PostExportAction.NONE
6668
self._post_export_custom_command = self._defaults['post_export_custom_command']
69+
self._temp_directory = self._defaults['temp_directory']
6770

6871
self.save_lock = threading.Lock()
6972
self._style_manager = style_manager
@@ -245,6 +248,17 @@ def post_export_custom_command(self, value):
245248
self._post_export_custom_command = value
246249
self.save()
247250

251+
@GObject.Property()
252+
def temp_directory(self):
253+
return self._temp_directory
254+
255+
@temp_directory.setter
256+
def temp_directory(self, value):
257+
if value == self._temp_directory:
258+
return
259+
self._temp_directory = value
260+
self.save()
261+
248262
def save(self):
249263
self.save_lock.acquire_lock()
250264
config_file_path = self.get_config_file_path()
@@ -297,6 +311,7 @@ def reset_to_default_values(self):
297311
self.post_export_custom_command = self._defaults['post_export_custom_command']
298312
self.preview_buffer_duration = self._defaults['preview_buffer_duration']
299313
self.show_mosaic_detections = self._defaults['show_mosaic_detections']
314+
self.temp_directory = self._defaults['temp_directory']
300315
self.validate_and_set_device(self._defaults['device'])
301316
self.save()
302317

@@ -325,6 +340,7 @@ def _as_dict(self) -> dict:
325340
'post_export_custom_command': self._post_export_custom_command,
326341
'preview_buffer_duration': self._preview_buffer_duration,
327342
'show_mosaic_detections': self._show_mosaic_detections,
343+
'temp_directory': self._temp_directory,
328344
}
329345

330346
def get_default_value(self, key):
@@ -357,6 +373,8 @@ def _from_dict(self, dict):
357373
self.validate_and_set_export_codec(dict[key])
358374
elif key == 'export_directory':
359375
self.validate_and_set_export_directory(dict[key])
376+
elif key == 'temp_directory':
377+
self.validate_and_set_temp_directory(dict[key])
360378
elif key == 'file_name_pattern':
361379
self.validate_and_set_file_name_pattern(dict[key])
362380
elif key == 'initial_view':
@@ -435,6 +453,14 @@ def validate_and_set_export_directory(self, export_directory: str | None):
435453
self._export_directory = None
436454
logger.warning(f"Configured export directory '{export_directory}' does not exist or is not a directory on the filesystem, falling back to '{self._export_directory}'")
437455

456+
def validate_and_set_temp_directory(self, temp_directory: str):
457+
path = Path(temp_directory)
458+
if path.is_dir():
459+
self._temp_directory = temp_directory
460+
else:
461+
self._temp_directory = self.get_default_value('temp_directory')
462+
logger.warning(f"Configured temp directory '{temp_directory}' does not exist or is not a directory on the filesystem, falling back to '{self._temp_directory}'")
463+
438464
def validate_and_set_file_name_pattern(self, file_name_pattern: str):
439465
if utils.validate_file_name_pattern(file_name_pattern):
440466
self._file_name_pattern = file_name_pattern

lada/gui/config/config_sidebar.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class ConfigSidebar(Gtk.Box):
3535
action_row_export_directory: Adw.ActionRow = Gtk.Template.Child()
3636
check_button_export_directory_alwaysask: Gtk.CheckButton = Gtk.Template.Child()
3737
check_button_export_directory_defaultdir: Gtk.CheckButton = Gtk.Template.Child()
38+
action_row_temp_directory: Adw.ActionRow = Gtk.Template.Child()
3839
entry_row_file_name_pattern: Adw.EntryRow = Gtk.Template.Child()
3940
toggle_button_initial_view_preview: Gtk.ToggleButton = Gtk.Template.Child()
4041
toggle_button_initial_view_export: Gtk.ToggleButton = Gtk.Template.Child()
@@ -117,6 +118,9 @@ def init_sidebar_from_config(self, config: Config):
117118

118119
self.entry_row_file_name_pattern.set_text(config.file_name_pattern)
119120

121+
# init temp directory
122+
self.action_row_temp_directory.set_subtitle(config.temp_directory)
123+
120124
self.toggle_button_initial_view_preview.set_active(config.initial_view == "preview")
121125
self.toggle_button_initial_view_export.set_active(config.initial_view == "export")
122126

@@ -250,6 +254,11 @@ def check_button_export_directory_defaultdir_callback(self, button_clicked):
250254
def toggle_button_export_directory_filepicker_callback(self, button_clicked):
251255
self.show_select_folder()
252256

257+
@Gtk.Template.Callback()
258+
@skip_if_uninitialized
259+
def toggle_button_temp_directory_filepicker_callback(self, button_clicked):
260+
self.show_select_temp_folder()
261+
253262
@Gtk.Template.Callback()
254263
@skip_if_uninitialized
255264
def entry_row_file_name_pattern_changed_callback(self, entry_row):
@@ -322,6 +331,25 @@ def on_select_folder(_file_dialog, result):
322331
if self.check_button_export_directory_defaultdir and not self._config.export_directory:
323332
self.check_button_export_directory_alwaysask.set_active(True)
324333
file_dialog.select_folder(callback=on_select_folder)
334+
335+
def show_select_temp_folder(self):
336+
file_dialog = Gtk.FileDialog()
337+
file_dialog.set_title(_("Select a folder for temporary files"))
338+
file_dialog.set_initial_folder(Gio.File.new_for_path(self._config.temp_directory))
339+
def on_select_temp_folder(_file_dialog, result):
340+
try:
341+
selected_folder: Gio.File = _file_dialog.select_folder_finish(result)
342+
selected_folder_path = selected_folder.get_path()
343+
self._config.temp_directory = selected_folder_path
344+
self.action_row_temp_directory.set_subtitle(selected_folder_path)
345+
except GLib.Error as error:
346+
if error.message == "Dismissed by user":
347+
logger.debug("FileDialog cancelled: Dismissed by user")
348+
else:
349+
logger.error(f"Error selecting folder: {error.message}")
350+
raise error
351+
file_dialog.select_folder(callback=on_select_temp_folder)
352+
325353
def update_custom_command_visibility(self, action):
326354
self.entry_row_post_export_custom_command.set_visible(action == "custom_command")
327355

lada/gui/config/config_sidebar.ui

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,19 @@ SPDX-License-Identifier: AGPL-3.0
180180
</child>
181181
</object>
182182
</child>
183+
<child>
184+
<object class="AdwActionRow" id="action_row_temp_directory">
185+
<property name="title" translatable="true">Temporary directory</property>
186+
<property name="subtitle" translatable="true">Directory for temporary video files during restoration process</property>
187+
<child type="suffix">
188+
<object class="GtkButton">
189+
<property name="icon-name">folder-open-symbolic</property>
190+
<property name="valign">3</property>
191+
<signal name="clicked" handler="toggle_button_temp_directory_filepicker_callback"/>
192+
</object>
193+
</child>
194+
</object>
195+
</child>
183196
<child>
184197
<object class="AdwEntryRow" id="entry_row_file_name_pattern">
185198
<property name="title" translatable="true">File name pattern for restored files.&#xA;Must include placeholder &lt;span background=&quot;#D3D3D350&quot;&gt;&lt;tt&gt;{orig_file_name}&lt;/tt&gt;&lt;/span&gt;.</property>

lada/gui/export/export_view.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ def run_export():
408408

409409
progress_update_step_size = 100
410410
success = True
411-
video_tmp_file_output_path = os.path.join(tempfile.gettempdir(),f"{os.path.basename(os.path.splitext(restore_file_path)[0])}.tmp{os.path.splitext(restore_file_path)[1]}")
411+
temp_dir = self._config.temp_directory
412+
video_tmp_file_output_path = os.path.join(temp_dir, f"{os.path.basename(os.path.splitext(restore_file_path)[0])}.tmp{os.path.splitext(restore_file_path)[1]}")
412413
try:
413414
if self.resume_info:
414415
start_ns = self.resume_info.get_resume_timestamp_ns()

0 commit comments

Comments
 (0)