def save(self, file_path, move_temp_files=True, make_paths_relative=True): """ Save project file to disk """ import openshot # Move all temp files (i.e. Blender animations) to the project folder if move_temp_files: self.move_temp_paths_to_project_folder(file_path) # Convert all file paths to relative based on this new project file's directory if make_paths_relative: self.convert_paths_to_relative(file_path) # Append version info v = openshot.GetVersion() self._data["version"] = { "openshot-qt": info.VERSION, "libopenshot": v.ToString() } # Try to save project settings file, will raise error on failure self.write_to_file(file_path, self._data) # On success, save current filepath self.current_filepath = file_path # Convert all paths back to absolute if make_paths_relative: self.convert_paths_to_absolute() # Add to recent files setting self.add_to_recent_files(file_path) # Track unsaved changes self.has_unsaved_changes = False
def save(self, file_path, move_temp_files=True, make_paths_relative=True): """ Save project file to disk """ import openshot log.info("Saving project file: {}".format(file_path)) # Move all temp files (i.e. Blender animations) to the project folder if move_temp_files: self.move_temp_paths_to_project_folder(file_path) # Append version info v = openshot.GetVersion() self._data["version"] = { "openshot-qt": info.VERSION, "libopenshot": v.ToString() } # Try to save project settings file, will raise error on failure self.write_to_file(file_path, self._data, path_mode="relative", previous_path=self.current_filepath) # On success, save current filepath self.current_filepath = file_path # Add to recent files setting self.add_to_recent_files(file_path) # Track unsaved changes self.has_unsaved_changes = False
import requests import platform import threading import urllib.parse from copy import deepcopy from classes import info from classes import language from classes.logger import log from classes import settings import openshot from PyQt5.QtCore import QT_VERSION_STR from PyQt5.Qt import PYQT_VERSION_STR # Get libopenshot version libopenshot_version = openshot.GetVersion() # Get settings s = settings.get_settings() # Determine OS version os_version = "X11; Linux %s" % platform.machine() linux_distro = "None" try: if platform.system() == "Darwin": v = platform.mac_ver() os_version = "Macintosh; Intel Mac OS X %s" % v[0].replace(".", "_") linux_distro = "OS X %s" % v[0] elif platform.system() == "Windows": v = platform.win32_ver()
def read_legacy_project_file(self, file_path): """Attempt to read a legacy version 1.x openshot project file""" import sys, pickle from classes.query import File, Track, Clip, Transition from classes.app import get_app import openshot try: import json except ImportError: import simplejson as json # Get translation method _ = get_app()._tr # Append version info v = openshot.GetVersion() project_data = {} project_data["version"] = { "openshot-qt": info.VERSION, "libopenshot": v.ToString() } # Get FPS from project from classes.app import get_app fps = get_app().project.get(["fps"]) fps_float = float(fps["num"]) / float(fps["den"]) # Import legacy openshot classes (from version 1.X) from classes.legacy.openshot import classes as legacy_classes from classes.legacy.openshot.classes import project as legacy_project from classes.legacy.openshot.classes import sequences as legacy_sequences from classes.legacy.openshot.classes import track as legacy_track from classes.legacy.openshot.classes import clip as legacy_clip from classes.legacy.openshot.classes import keyframe as legacy_keyframe from classes.legacy.openshot.classes import files as legacy_files from classes.legacy.openshot.classes import transition as legacy_transition from classes.legacy.openshot.classes import effect as legacy_effect from classes.legacy.openshot.classes import marker as legacy_marker sys.modules['openshot.classes'] = legacy_classes sys.modules['classes.project'] = legacy_project sys.modules['classes.sequences'] = legacy_sequences sys.modules['classes.track'] = legacy_track sys.modules['classes.clip'] = legacy_clip sys.modules['classes.keyframe'] = legacy_keyframe sys.modules['classes.files'] = legacy_files sys.modules['classes.transition'] = legacy_transition sys.modules['classes.effect'] = legacy_effect sys.modules['classes.marker'] = legacy_marker # Keep track of files that failed to load failed_files = [] with open(file_path.encode('UTF-8'), 'rb') as f: try: # Unpickle legacy openshot project file v1_data = pickle.load(f, fix_imports=True, encoding="UTF-8") file_lookup = {} # Loop through files for item in v1_data.project_folder.items: # Is this item a File (i.e. ignore folders) if isinstance(item, legacy_files.OpenShotFile): # Create file try: clip = openshot.Clip(item.name) reader = clip.Reader() file_data = json.loads(reader.Json()) # Determine media type if file_data["has_video"] and not self.is_image( file_data): file_data["media_type"] = "video" elif file_data["has_video"] and self.is_image( file_data): file_data["media_type"] = "image" elif file_data["has_audio"] and not file_data[ "has_video"]: file_data["media_type"] = "audio" # Save new file to the project data file = File() file.data = file_data file.save() # Keep track of new ids and old ids file_lookup[item.unique_id] = file except: # Handle exception quietly msg = ( "%s is not a valid video, audio, or image file." % item.name) log.error(msg) failed_files.append(item.name) # Delete all tracks track_list = copy.deepcopy(Track.filter()) for track in track_list: track.delete() # Create new tracks track_counter = 0 for legacy_t in reversed(v1_data.sequences[0].tracks): t = Track() t.data = { "number": track_counter, "y": 0, "label": legacy_t.name } t.save() track_counter += 1 # Loop through clips track_counter = 0 for sequence in v1_data.sequences: for track in reversed(sequence.tracks): for clip in track.clips: # Get associated file for this clip if clip.file_object.unique_id in file_lookup.keys( ): file = file_lookup[clip.file_object.unique_id] else: # Skip missing file log.info( "Skipping importing missing file: %s" % clip.file_object.unique_id) continue # Create clip if (file.data["media_type"] == "video" or file.data["media_type"] == "image"): # Determine thumb path thumb_path = os.path.join( info.THUMBNAIL_PATH, "%s.png" % file.data["id"]) else: # Audio file thumb_path = os.path.join( info.PATH, "images", "AudioThumbnail.png") # Get file name path, filename = os.path.split(file.data["path"]) # Convert path to the correct relative path (based on this folder) file_path = file.absolute_path() # Create clip object for this file c = openshot.Clip(file_path) # Append missing attributes to Clip JSON new_clip = json.loads(c.Json()) new_clip["file_id"] = file.id new_clip["title"] = filename new_clip["image"] = thumb_path # Check for optional start and end attributes new_clip["start"] = clip.start_time new_clip["end"] = clip.end_time new_clip["position"] = clip.position_on_track new_clip["layer"] = track_counter # Clear alpha (if needed) if clip.video_fade_in or clip.video_fade_out: new_clip["alpha"]["Points"] = [] # Video Fade IN if clip.video_fade_in: # Add keyframes start = openshot.Point( round(clip.start_time * fps_float) + 1, 0.0, openshot.BEZIER) start_object = json.loads(start.Json()) end = openshot.Point( round((clip.start_time + clip.video_fade_in_amount) * fps_float) + 1, 1.0, openshot.BEZIER) end_object = json.loads(end.Json()) new_clip["alpha"]["Points"].append( start_object) new_clip["alpha"]["Points"].append(end_object) # Video Fade OUT if clip.video_fade_out: # Add keyframes start = openshot.Point( round((clip.end_time - clip.video_fade_out_amount) * fps_float) + 1, 1.0, openshot.BEZIER) start_object = json.loads(start.Json()) end = openshot.Point( round(clip.end_time * fps_float) + 1, 0.0, openshot.BEZIER) end_object = json.loads(end.Json()) new_clip["alpha"]["Points"].append( start_object) new_clip["alpha"]["Points"].append(end_object) # Clear Audio (if needed) if clip.audio_fade_in or clip.audio_fade_out: new_clip["volume"]["Points"] = [] else: p = openshot.Point(1, clip.volume / 100.0, openshot.BEZIER) p_object = json.loads(p.Json()) new_clip["volume"] = {"Points": [p_object]} # Audio Fade IN if clip.audio_fade_in: # Add keyframes start = openshot.Point( round(clip.start_time * fps_float) + 1, 0.0, openshot.BEZIER) start_object = json.loads(start.Json()) end = openshot.Point( round((clip.start_time + clip.video_fade_in_amount) * fps_float) + 1, clip.volume / 100.0, openshot.BEZIER) end_object = json.loads(end.Json()) new_clip["volume"]["Points"].append( start_object) new_clip["volume"]["Points"].append(end_object) # Audio Fade OUT if clip.audio_fade_out: # Add keyframes start = openshot.Point( round((clip.end_time - clip.video_fade_out_amount) * fps_float) + 1, clip.volume / 100.0, openshot.BEZIER) start_object = json.loads(start.Json()) end = openshot.Point( round(clip.end_time * fps_float) + 1, 0.0, openshot.BEZIER) end_object = json.loads(end.Json()) new_clip["volume"]["Points"].append( start_object) new_clip["volume"]["Points"].append(end_object) # Save clip clip_object = Clip() clip_object.data = new_clip clip_object.save() # Loop through transitions for trans in track.transitions: # Fix default transition if not trans.resource or not os.path.exists( trans.resource): trans.resource = os.path.join( info.PATH, "transitions", "common", "fade.svg") # Open up QtImageReader for transition Image transition_reader = openshot.QtImageReader( trans.resource) trans_begin_value = 1.0 trans_end_value = -1.0 if trans.reverse: trans_begin_value = -1.0 trans_end_value = 1.0 brightness = openshot.Keyframe() brightness.AddPoint(1, trans_begin_value, openshot.BEZIER) brightness.AddPoint( round(trans.length * fps_float) + 1, trans_end_value, openshot.BEZIER) contrast = openshot.Keyframe(trans.softness * 10.0) # Create transition dictionary transitions_data = { "id": get_app().project.generate_id(), "layer": track_counter, "title": "Transition", "type": "Mask", "position": trans.position_on_track, "start": 0, "end": trans.length, "brightness": json.loads(brightness.Json()), "contrast": json.loads(contrast.Json()), "reader": json.loads(transition_reader.Json()), "replace_image": False } # Save transition t = Transition() t.data = transitions_data t.save() # Increment track counter track_counter += 1 except Exception as ex: # Error parsing legacy contents msg = _("Failed to load project file %(path)s: %(error)s" % { "path": file_path, "error": ex }) log.error(msg) raise Exception(msg) # Show warning if some files failed to load if failed_files: # Throw exception raise Exception( _("Failed to load the following files:\n%s" % ", ".join(failed_files))) # Return mostly empty project_data dict (with just the current version #) log.info("Successfully loaded legacy project file: %s" % file_path) return project_data
def __init__(self, *args): QApplication.__init__(self, *args) # Log some basic system info try: v = openshot.GetVersion() log.info("openshot-qt version: %s" % info.VERSION) log.info("libopenshot version: %s" % v.ToString()) log.info("platform: %s" % platform.platform()) log.info("processor: %s" % platform.processor()) log.info("machine: %s" % platform.machine()) log.info("python version: %s" % platform.python_version()) log.info("qt5 version: %s" % QT_VERSION_STR) log.info("pyqt5 version: %s" % PYQT_VERSION_STR) except: pass # Setup appication self.setApplicationName('openshot') self.setApplicationVersion(info.SETUP['version']) # Init settings self.settings = settings.SettingStore() try: self.settings.load() except Exception as ex: log.error("Couldn't load user settings. Exiting.\n{}".format(ex)) exit() # Init translation system language.init_language() # Tests of project data loading/saving self.project = project_data.ProjectDataStore() # Init Update Manager self.updates = updates.UpdateManager() # It is important that the project is the first listener if the key gets update self.updates.add_listener(self.project) # Load ui theme if not set by OS ui_util.load_theme() # Track which dockable window received a context menu self.context_menu_object = None # Set unique install id (if blank) if not self.settings.get("unique_install_id"): self.settings.set("unique_install_id", str(uuid4())) # Track 1st launch metric import classes.metrics classes.metrics.track_metric_screen("initial-launch-screen") # Set Font for any theme if self.settings.get("theme") != "No Theme": # Load embedded font log.info("Setting font to %s" % os.path.join(info.IMAGES_PATH, "fonts", "Ubuntu-R.ttf")) font_id = QFontDatabase.addApplicationFont( os.path.join(info.IMAGES_PATH, "fonts", "Ubuntu-R.ttf")) font_family = QFontDatabase.applicationFontFamilies(font_id)[0] font = QFont(font_family) font.setPointSizeF(10.5) QApplication.setFont(font) # Set Experimental Dark Theme if self.settings.get("theme") == "Humanity: Dark": # Only set if dark theme selected log.info("Setting custom dark theme") self.setStyle(QStyleFactory.create("Fusion")) darkPalette = self.palette() darkPalette.setColor(QPalette.Window, QColor(53, 53, 53)) darkPalette.setColor(QPalette.WindowText, Qt.white) darkPalette.setColor(QPalette.Base, QColor(25, 25, 25)) darkPalette.setColor(QPalette.AlternateBase, QColor(53, 53, 53)) darkPalette.setColor(QPalette.ToolTipBase, Qt.white) darkPalette.setColor(QPalette.ToolTipText, Qt.white) darkPalette.setColor(QPalette.Text, Qt.white) darkPalette.setColor(QPalette.Button, QColor(53, 53, 53)) darkPalette.setColor(QPalette.ButtonText, Qt.white) darkPalette.setColor(QPalette.BrightText, Qt.red) darkPalette.setColor(QPalette.Highlight, QColor(42, 130, 218)) darkPalette.setColor(QPalette.HighlightedText, Qt.black) self.setPalette(darkPalette) self.setStyleSheet( "QToolTip { color: #ffffff; background-color: #2a82da; border: 0px solid white; }" ) # Create main window from windows.main_window import MainWindow self.window = MainWindow() self.window.show() log.info('Process command-line arguments: %s' % args) if len(args[0]) == 2: path = args[0][1] if ".osp" in path: # Auto load project passed as argument self.window.open_project(path) else: # Auto import media file self.window.filesTreeView.add_file(path) # Reset undo/redo history self.updates.reset() self.window.updateStatusChanged(False, False)
def __init__(self, *args, mode=None): QApplication.__init__(self, *args) # Log some basic system info try: v = openshot.GetVersion() log.info("openshot-qt version: %s" % info.VERSION) log.info("libopenshot version: %s" % v.ToString()) log.info("platform: %s" % platform.platform()) log.info("processor: %s" % platform.processor()) log.info("machine: %s" % platform.machine()) log.info("python version: %s" % platform.python_version()) log.info("qt5 version: %s" % QT_VERSION_STR) log.info("pyqt5 version: %s" % PYQT_VERSION_STR) except: pass # Setup application self.setApplicationName('YYSportCoder') self.setApplicationVersion(info.SETUP['version']) # Init settings self.settings = settings.SettingStore() self.settings.load() # Init and attach exception handler from classes import exceptions sys.excepthook = exceptions.ExceptionHandler # Init translation system language.init_language() # Detect minimum libopenshot version _ = self._tr libopenshot_version = openshot.GetVersion().ToString() if mode != "unittest" and libopenshot_version < info.MINIMUM_LIBOPENSHOT_VERSION: QMessageBox.warning( None, _("Wrong Version of YYSportCoder Detected"), _("<b>Version %(minimum_version)s is required</b>, but %(current_version)s was detected. Please update libopenshot or download our latest installer." ) % { "minimum_version": info.MINIMUM_LIBOPENSHOT_VERSION, "current_version": libopenshot_version }) # Stop launching and exit sys.exit() # Tests of project data loading/saving self.project = project_data.ProjectDataStore() # Init Update Manager self.updates = updates.UpdateManager() # It is important that the project is the first listener if the key gets update self.updates.add_listener(self.project) # Load ui theme if not set by OS ui_util.load_theme() # Start libopenshot logging thread self.logger_libopenshot = logger_libopenshot.LoggerLibOpenShot() self.logger_libopenshot.start() # Track which dockable window received a context menu self.context_menu_object = None # Set Font for any theme if self.settings.get("theme") != "No Theme": # Load embedded font try: log.info( "Setting font to %s" % os.path.join(info.IMAGES_PATH, "fonts", "Ubuntu-R.ttf")) font_id = QFontDatabase.addApplicationFont( os.path.join(info.IMAGES_PATH, "fonts", "Ubuntu-R.ttf")) font_family = QFontDatabase.applicationFontFamilies(font_id)[0] font = QFont(font_family) font.setPointSizeF(10.5) QApplication.setFont(font) except Exception as ex: log.error("Error setting Ubuntu-R.ttf QFont: %s" % str(ex)) # Set Experimental Dark Theme if self.settings.get("theme") == "Humanity: Dark": # Only set if dark theme selected log.info("Setting custom dark theme") self.setStyle(QStyleFactory.create("Fusion")) darkPalette = self.palette() darkPalette.setColor(QPalette.Window, QColor(53, 53, 53)) darkPalette.setColor(QPalette.WindowText, Qt.white) darkPalette.setColor(QPalette.Base, QColor(25, 25, 25)) darkPalette.setColor(QPalette.AlternateBase, QColor(53, 53, 53)) darkPalette.setColor(QPalette.ToolTipBase, Qt.white) darkPalette.setColor(QPalette.ToolTipText, Qt.white) darkPalette.setColor(QPalette.Text, Qt.white) darkPalette.setColor(QPalette.Button, QColor(53, 53, 53)) darkPalette.setColor(QPalette.ButtonText, Qt.white) darkPalette.setColor(QPalette.BrightText, Qt.red) darkPalette.setColor(QPalette.Highlight, QColor(42, 130, 218)) darkPalette.setColor(QPalette.HighlightedText, Qt.black) darkPalette.setColor(QPalette.Disabled, QPalette.Text, QColor(104, 104, 104)) self.setPalette(darkPalette) self.setStyleSheet( "QToolTip { color: #ffffff; background-color: #2a82da; border: 0px solid white; }" ) ''' # Create main window from windows.main_window import MainWindow self.window = MainWindow(mode) # Reset undo/redo history self.updates.reset() self.window.updateStatusChanged(False, False) log.info('Process command-line arguments: %s' % args) if len(args[0]) == 2: path = args[0][1] if ".osp" in path: # Auto load project passed as argument self.window.OpenProjectSignal.emit(path) else: # Auto import media file self.window.filesTreeView.add_file(path) else: # Recover backup file (this can't happen until after the Main Window has completely loaded) self.window.RecoverBackup.emit() ''' #from windows.yy_main_window import YYMainWindow #self.window = YYMainWindow(mode) from windows.yymain_window import YYMainWindow self.window = YYMainWindow()