Skip to content

Commit

Permalink
info: Don't auto-create dirs on import
Browse files Browse the repository at this point in the history
- The directory-creation code is moved to info.setup_userdirs(),
  called by launch.py before creating the OpenShotApp instance
- app.mode is now set by keyword-only argument, and is no longer
  passed to MainWindow() (as the GUI is never started in unit test
  mode).
- Removed all references to window.mode from the GUI code
  • Loading branch information
ferdnyc committed Dec 9, 2021
1 parent 87f6bc0 commit 0e3b6ef
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 56 deletions.
25 changes: 11 additions & 14 deletions src/classes/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@
import traceback
import json

from PyQt5.QtCore import PYQT_VERSION_STR
from PyQt5.QtCore import QT_VERSION_STR
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import PYQT_VERSION_STR, QT_VERSION_STR, pyqtSlot
from PyQt5.QtWidgets import QApplication, QStyleFactory, QMessageBox


Expand Down Expand Up @@ -72,12 +70,11 @@ def show(self):


class OpenShotApp(QApplication):
""" This class is the primary QApplication for OpenShot.
mode=None (normal), mode=unittest (testing)"""
"""The primary QApplication subclass for OpenShot."""

def __init__(self, *args, mode=None):
QApplication.__init__(self, *args)
self.mode = mode or "normal"
def __init__(self, *args, **kwargs):
self.mode = kwargs.pop("mode", None)
super().__init__(*args, **kwargs)
self.args = super().arguments()
self.errors = []

Expand All @@ -87,20 +84,19 @@ def __init__(self, *args, mode=None):
from classes.logger import log, reroute_output

# Log the session's start
if mode != "unittest":
if self.mode != "unittest":
import time
log.info("-" * 48)
log.info(time.asctime().center(48))
log.info('Starting new session'.center(48))

log.debug("Starting up in {} mode".format(self.mode))
log.debug("Command line: {}".format(self.args))

from classes import settings, project_data, updates
import openshot

# Re-route stdout and stderr to logger
if mode != "unittest":
if self.mode != "unittest":
reroute_output()

except ImportError as ex:
Expand Down Expand Up @@ -137,7 +133,7 @@ def __init__(self, *args, mode=None):
openshot.Settings.Instance().PATH_OPENSHOT_INSTALL = info.PATH

# Check to disable sentry
if not self.settings.get('send_metrics'):
if self.mode == "unittest" or not self.settings.get('send_metrics'):
sentry.disable_tracing()

def show_environment(self, info, openshot):
Expand Down Expand Up @@ -262,7 +258,7 @@ def gui(self):
# Create main window
from windows.main_window import MainWindow
log.debug("Creating main interface window")
self.window = MainWindow(mode=self.mode)
self.window = MainWindow()

# Clear undo/redo history
self.window.updateStatusChanged(False, False)
Expand All @@ -276,7 +272,7 @@ def gui(self):
self.window.RecoverBackup.emit()
return

log.info('Process command-line arguments: %s' % args)
log.info('Process command-line arguments: %s', args[1:])

# Auto load project if passed as argument
if args[1].endswith(".osp"):
Expand Down Expand Up @@ -338,3 +334,4 @@ def onLogTheEnd():
import logging
log = logging.getLogger(".")
log.debug('Failed to write session ended log', exc_info=1)

53 changes: 28 additions & 25 deletions src/classes/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,27 +66,7 @@
# User files
BACKUP_FILE = os.path.join(BACKUP_PATH, "backup.osp")
USER_DEFAULT_PROJECT = os.path.join(USER_PATH, "default.osp")

# Create user paths if they do not exist
# (this is where temp files are stored... such as cached thumbnails)
for folder in [
USER_PATH, BACKUP_PATH, RECOVERY_PATH, THUMBNAIL_PATH, CACHE_PATH,
BLENDER_PATH, TITLE_PATH, TRANSITIONS_PATH, PREVIEW_CACHE_PATH,
USER_PROFILES_PATH, USER_PRESETS_PATH, USER_TITLES_PATH, EMOJIS_PATH,
PROTOBUF_DATA_PATH, YOLO_PATH]:
try:
if not os.path.exists(os.fsencode(folder)):
os.makedirs(folder, exist_ok=True)
except PermissionError:
# Fail gracefully if we have no permission to create these folders
# This happens on build servers, such as Launchpad (imported by Sphinx)
print(f"Failed to create `{folder}` folder due to permissions (ignoring exception)")

# Migrate USER_DEFAULT_PROJECT from former name
LEGACY_DEFAULT_PROJECT = USER_DEFAULT_PROJECT.replace(".osp", ".project")
if all([os.path.exists(LEGACY_DEFAULT_PROJECT), not os.path.exists(USER_DEFAULT_PROJECT)]):
print("Migrating default project file to new name")
os.rename(LEGACY_DEFAULT_PROJECT, USER_DEFAULT_PROJECT)

try:
from PyQt5.QtCore import QSize
Expand Down Expand Up @@ -122,11 +102,6 @@
# Web backend selection, overridable at launch
WEB_BACKEND = 'auto'

# Languages
CMDLINE_LANGUAGE = None
CURRENT_LANGUAGE = 'en_US'
SUPPORTED_LANGUAGES = ['en_US']

# Sentry.io error reporting rate (0.0 TO 1.0)
# 0.0 = no error reporting to Sentry
# 0.5 = 1/2 of errors reported to Sentry
Expand All @@ -138,6 +113,11 @@
ERROR_REPORT_RATE_UNSTABLE = 0.0
ERROR_REPORT_STABLE_VERSION = None

# Languages
CMDLINE_LANGUAGE = None
CURRENT_LANGUAGE = 'en_US'
SUPPORTED_LANGUAGES = ['en_US']

try:
from language import openshot_lang
language_path = ":/locale/"
Expand Down Expand Up @@ -209,10 +189,33 @@
}
}

def setup_userdirs():
"""Create user paths if they do not exist (this is where
temp files are stored... such as cached thumbnails)"""
for folder in [
USER_PATH, BACKUP_PATH, RECOVERY_PATH, THUMBNAIL_PATH,
CACHE_PATH, BLENDER_PATH, TITLE_PATH, TRANSITIONS_PATH,
PREVIEW_CACHE_PATH, USER_PROFILES_PATH, USER_PRESETS_PATH,
USER_TITLES_PATH, EMOJIS_PATH, PROTOBUF_DATA_PATH,
YOLO_PATH,
]:
if not os.path.exists(os.fsencode(folder)):
os.makedirs(folder, exist_ok=True)

# Migrate USER_DEFAULT_PROJECT from former name
if all([
os.path.exists(LEGACY_DEFAULT_PROJECT),
not os.path.exists(USER_DEFAULT_PROJECT),
]):
print("Migrating default project file to new name")
os.rename(LEGACY_DEFAULT_PROJECT, USER_DEFAULT_PROJECT)


def website_language():
"""Get the current website language code for URLs"""
return {
"zh_CN": "zh-hans/",
"zh_TW": "zh-hant/",
"en_US": ""}.get(CURRENT_LANGUAGE,
"%s/" % CURRENT_LANGUAGE.split("_")[0].lower())

20 changes: 12 additions & 8 deletions src/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,15 @@ def main():

if args.py_path:
for p in args.py_path:
newpath = os.path.realpath(p)
try:
if os.path.exists(os.path.realpath(p)):
sys.path.insert(0, os.path.realpath(p))
print("Added {} to PYTHONPATH".format(os.path.realpath(p)))
if os.path.exists(newpath):
sys.path.insert(0, newpath)
print(f"Added {newpath} to PYTHONPATH")
else:
print("{} does not exist".format(os.path.realpath(p)))
print(f"{newpath} does not exist")
except TypeError as ex:
print("Bad path {}: {}".format(p, ex))
print(f"Bad path {newpath}: {ex}")
continue

if args.modeltest:
Expand All @@ -165,16 +166,19 @@ def main():
if args.lang in info.SUPPORTED_LANGUAGES:
info.CMDLINE_LANGUAGE = args.lang
else:
print("Unsupported language '{}'! (See --list-languages)".format(args.lang))
print(f"Unsupported language '{args.lang}'! (See --list-languages)")
sys.exit(-1)

# Normal startup, print module path and lauch application
print("Loaded modules from: %s" % info.PATH)
print(f"Loaded modules from: {info.PATH}")

# Initialize sentry exception tracing
from classes import sentry
sentry.init_tracing()

# Create any missing paths in the user's settings dir
info.setup_userdirs()

# Create Qt application, pass any unprocessed arguments
from classes.app import OpenShotApp

Expand All @@ -188,7 +192,7 @@ def main():

# Setup Qt application details
app.setApplicationName('openshot')
app.setApplicationVersion(info.SETUP['version'])
app.setApplicationVersion(info.VERSION)
try:
# Qt 5.7+ only
app.setDesktopFile("org.openshot.OpenShot")
Expand Down
8 changes: 3 additions & 5 deletions src/windows/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def closeEvent(self, event):
self.tutorial_manager.hide_dialog()

# Prompt user to save (if needed)
if app.project.needs_save() and self.mode != "unittest":
if app.project.needs_save():
log.info('Prompt user to save project')
# Translate object
_ = app._tr
Expand Down Expand Up @@ -2828,11 +2828,10 @@ def initModels(self):
self.emojiListView = EmojisListView(self.emojis_model)
self.tabEmojis.layout().addWidget(self.emojiListView)

def __init__(self, *args, mode=None):
def __init__(self, *args):

# Create main window base class
super().__init__(*args)
self.mode = mode # None or unittest (None is normal usage)
self.initialized = False

# set window on app for reference during initialization of children
Expand Down Expand Up @@ -2891,8 +2890,7 @@ def __init__(self, *args, mode=None):
get_current_Version()

# Connect signals
if self.mode != "unittest":
self.RecoverBackup.connect(self.recover_backup)
self.RecoverBackup.connect(self.recover_backup)

# Initialize and start the thumbnail HTTP server
self.http_server_thread = httpThumbnailServerThread()
Expand Down
3 changes: 1 addition & 2 deletions src/windows/preview_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ def onError(self, error):
_ = get_app()._tr

# Only JUCE audio errors bubble up here now
if get_app().window.mode != "unittest":
QMessageBox.warning(self.parent, _("Audio Error"), _("Please fix the following error and restart OpenShot\n%s") % error)
QMessageBox.warning(self.parent, _("Audio Error"), _("Please fix the following error and restart OpenShot\n%s") % error)

@pyqtSlot(object, object)
def Init(self, parent, timeline, video_widget):
Expand Down
3 changes: 1 addition & 2 deletions src/windows/views/emojis_listview.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,5 @@ def __init__(self, model):
# Off by one, due to 'show all' choice above
dropdown_index = index + 1

if self.win.mode != "unittest":
self.win.emojiFilterGroup.currentIndexChanged.connect(self.group_changed)
self.win.emojiFilterGroup.currentIndexChanged.connect(self.group_changed)
self.win.emojiFilterGroup.setCurrentIndex(dropdown_index)

0 comments on commit 0e3b6ef

Please sign in to comment.