def open_app_at_startup(enabled=True): """ This function adds/removes the current app bundle from Login items in macOS """ if sys.platform == 'darwin': from Foundation import NSDictionary from Cocoa import NSBundle, NSURL from CoreFoundation import kCFAllocatorDefault # CF = CDLL(find_library('CoreFoundation')) from LaunchServices import (LSSharedFileListCreate, kLSSharedFileListSessionLoginItems, LSSharedFileListInsertItemURL, kLSSharedFileListItemHidden, kLSSharedFileListItemLast, LSSharedFileListItemRemove) app_path = NSBundle.mainBundle().bundlePath() url = NSURL.alloc().initFileURLWithPath_(app_path) login_items = LSSharedFileListCreate( kCFAllocatorDefault, kLSSharedFileListSessionLoginItems, None) props = NSDictionary.dictionaryWithObject_forKey_( True, kLSSharedFileListItemHidden) new_item = LSSharedFileListInsertItemURL(login_items, kLSSharedFileListItemLast, None, None, url, props, None) if not enabled: LSSharedFileListItemRemove(login_items, new_item)
def register_folder_link(self, folder_path, name=None): try: from LaunchServices import LSSharedFileListInsertItemURL from LaunchServices import kLSSharedFileListItemBeforeFirst from LaunchServices import CFURLCreateWithString except ImportError: log.warning("PyObjC package is not installed:" " skipping favorite link creation") return folder_path = normalized_path(folder_path) if name is None: name = self._manager.get_appname() lst = self._get_favorite_list() if lst is None: log.warning("Could not fetch the Finder favorite list.") return url = CFURLCreateWithString(None, "file://" + urllib2.quote(folder_path), None) if url is None: log.warning("Could not generate valid favorite URL for: %s", folder_path) return # Register the folder as favorite if not already there item = LSSharedFileListInsertItemURL(lst, kLSSharedFileListItemBeforeFirst, name, None, url, {}, []) if item is not None: log.debug("Registered new favorite in Finder for: %s", folder_path)
def register_folder_link(self, folder_path, name=None): from LaunchServices import LSSharedFileListInsertItemURL from LaunchServices import kLSSharedFileListItemBeforeFirst from LaunchServices import CFURLCreateWithString favorites = self._get_favorite_list() or [] if not favorites: log.warning('Could not fetch the Finder favorite list.') return folder_path = normalized_path(folder_path) if name is None: name = self._manager.app_name else: name = os.path.basename(name) if self._find_item_in_list(favorites, name): return url = CFURLCreateWithString(None, 'file://' + urllib2.quote(folder_path), None) if url is None: log.warning('Could not generate valid favorite URL for: %r', folder_path) return # Register the folder as favorite if not already there item = LSSharedFileListInsertItemURL(favorites, kLSSharedFileListItemBeforeFirst, name, None, url, {}, []) if item is not None: log.debug('Registered new favorite in Finder for: %r', folder_path)
def register_folder_link_darwin(self, folder_path): try: from LaunchServices import LSSharedFileListCreate from LaunchServices import kLSSharedFileListFavoriteItems from LaunchServices import LSSharedFileListInsertItemURL from LaunchServices import kLSSharedFileListItemBeforeFirst from LaunchServices import CFURLCreateWithString except ImportError: log.warning("PyObjC package is not installed:" " skipping favorite link creation") return folder_path = normalized_path(folder_path) folder_name = os.path.basename(folder_path) lst = LSSharedFileListCreate(None, kLSSharedFileListFavoriteItems, None) if lst is None: log.warning("Could not fetch the Finder favorite list.") return url = CFURLCreateWithString(None, "file://" + quote(folder_path), None) if url is None: log.warning("Could not generate valid favorite URL for: %s", folder_path) return # Register the folder as favorite if not already there item = LSSharedFileListInsertItemURL(lst, kLSSharedFileListItemBeforeFirst, folder_name, None, url, {}, []) if item is not None: log.debug("Registered new favorite in Finder for: %s", folder_path)
def register_folder_link(self, folder_path: str, name: str = None) -> None: favorites = self._get_favorite_list() or [] if not favorites: log.warning("Could not fetch the Finder favorite list.") return folder_path = normalized_path(folder_path) name = os.path.basename(name) if name else self._manager.app_name if self._find_item_in_list(favorites, name): return url = CFURLCreateWithString(None, "file://{}".format(quote(folder_path)), None) if not url: log.warning("Could not generate valid favorite URL for: %r", folder_path) return # Register the folder as favorite if not already there item = LSSharedFileListInsertItemURL(favorites, kLSSharedFileListItemBeforeFirst, name, None, url, {}, []) if item: log.debug("Registered new favorite in Finder for: %r", folder_path)
def open_app_at_startup(enabled=True): """ This function adds/removes the current app bundle from Login items in macOS or most Linux desktops """ if sys.platform == 'darwin': from Foundation import NSDictionary from Cocoa import NSBundle, NSURL from CoreFoundation import kCFAllocatorDefault # CF = CDLL(find_library('CoreFoundation')) from LaunchServices import (LSSharedFileListCreate, kLSSharedFileListSessionLoginItems, LSSharedFileListInsertItemURL, kLSSharedFileListItemHidden, kLSSharedFileListItemLast, LSSharedFileListItemRemove) app_path = NSBundle.mainBundle().bundlePath() url = NSURL.alloc().initFileURLWithPath_(app_path) login_items = LSSharedFileListCreate( kCFAllocatorDefault, kLSSharedFileListSessionLoginItems, None) props = NSDictionary.dictionaryWithObject_forKey_( True, kLSSharedFileListItemHidden) new_item = LSSharedFileListInsertItemURL(login_items, kLSSharedFileListItemLast, None, None, url, props, None) if not enabled: LSSharedFileListItemRemove(login_items, new_item) elif sys.platform.startswith('linux'): autostart_path = Path.home() / '.config' / 'autostart' if not autostart_path.exists(): autostart_path.mkdir() autostart_file_path = autostart_path / 'vorta.desktop' if enabled: if Path('/.flatpak-info').exists(): # Vorta runs as flatpak autostart_file_path.write_text( LINUX_STARTUP_FILE.format( 'flatpak run com.borgbase.vorta')) else: autostart_file_path.write_text( LINUX_STARTUP_FILE.format('vorta')) else: if autostart_file_path.exists(): autostart_file_path.unlink()
def add(self, to_add: str, uri: str = "file://localhost") -> None: """Append item to sidebar list items. :param str to_add: Path to item to append to sidebar list. :param str uri: URI of server where item resides if not on localhost. """ if uri.startswith("afp") or uri.startswith("smb"): to_add = mount_share(uri + to_add) item = NSURL.alloc().initFileURLWithPath_(to_add) LSSharedFileListInsertItemURL(self.sflRef, kLSSharedFileListItemBeforeFirst, None, None, item, None, None) self.synchronize() self.update()
def process(self): # Veriify if the path provided exists if not os.path.exists(self.path): raise ActionError('the path provided could not be found') # Create the new item's bookmark and properties url = NSURL.fileURLWithPath_(self.path) properties = {'com.apple.loginitem.HideOnLaunch': self.hidden} # Find a specific login item login_items = LSSharedFileListCreate( None, kLSSharedFileListSessionLoginItems, None) if self.state == 'present': # Search for the login item in the existing login items for login_item in login_items.allItems(): login_item_url, error = LSSharedFileListItemCopyResolvedURL( login_item, 0, None) # The item path was found and has the same hidden setting if (not error and login_item_url.path() == url.path() and login_item.properties() ['com.apple.loginitem.HideOnLaunch'] == self.hidden): return self.ok() # Add (or update) the login item to the list LSSharedFileListInsertItemURL(login_items, kLSSharedFileListItemLast, None, None, url, properties, None) return self.changed() else: # 'absent' # Search for the login item in the existing login items found_item = None for login_item in login_items.allItems(): login_item_url, error = LSSharedFileListItemCopyResolvedURL( login_item, 0, None) # The item path was found so we delete it if not error and login_item_url.path() == url.path(): found_item = login_item break if not found_item: return self.ok() LSSharedFileListItemRemove(login_items, found_item) return self.changed()
def add(self, to_add, uri="file://localhost"): """ Append item to sidebar list items. Args: to_add (str): Path to item to append to sidebar list. Keyword Args: uri (str): URI of server where item resides if not on localhost. """ if uri.startswith("afp") or uri.startswith("smb"): path = "%s%s" % (uri, to_add) to_add = mount_share(path) item = NSURL.alloc().initFileURLWithPath_(to_add) LSSharedFileListInsertItemURL(self.sflRef, kLSSharedFileListItemBeforeFirst, None, None, item, None, None) self.synchronize() self.update()
def register_folder_link(self, path: Path) -> None: favorites = self._get_favorite_list() or [] if not favorites: log.warning("Could not fetch the Finder favorite list.") return if self._find_item_in_list(favorites, path.name): return url = CFURLCreateWithString(None, f"file://{quote(str(path))}", None) if not url: log.warning(f"Could not generate valid favorite URL for: {path!r}") return # Register the folder as favorite if not already there item = LSSharedFileListInsertItemURL(favorites, kLSSharedFileListItemBeforeFirst, path.name, None, url, {}, []) if item: log.info(f"Registered new favorite in Finder for: {path!r}")
def open_app_at_startup(enabled=True): """ This function adds/removes the current app bundle from Login items in macOS or most Linux desktops """ if sys.platform == 'darwin': from Foundation import NSDictionary from Cocoa import NSBundle, NSURL from CoreFoundation import kCFAllocatorDefault # CF = CDLL(find_library('CoreFoundation')) from LaunchServices import (LSSharedFileListCreate, kLSSharedFileListSessionLoginItems, LSSharedFileListInsertItemURL, kLSSharedFileListItemHidden, kLSSharedFileListItemLast, LSSharedFileListItemRemove) app_path = NSBundle.mainBundle().bundlePath() url = NSURL.alloc().initFileURLWithPath_(app_path) login_items = LSSharedFileListCreate( kCFAllocatorDefault, kLSSharedFileListSessionLoginItems, None) props = NSDictionary.dictionaryWithObject_forKey_( True, kLSSharedFileListItemHidden) new_item = LSSharedFileListInsertItemURL(login_items, kLSSharedFileListItemLast, None, None, url, props, None) if not enabled: LSSharedFileListItemRemove(login_items, new_item) elif sys.platform.startswith('linux'): config_path = QtCore.QStandardPaths.writableLocation( QtCore.QStandardPaths.ConfigLocation) autostart_file_path = Path(config_path) / 'autostart' / 'vorta.desktop' if enabled: dir_entry_point = get_setuptools_script_dir() autostart_file_path.write_text( LINUX_STARTUP_FILE.format(dir_entry_point)) else: if autostart_file_path.exists(): autostart_file_path.unlink()
def open_app_at_startup(enabled=True): """ On macOS, this function adds/removes the current app bundle from Login items while on Linux it adds a .desktop file at ~/.config/autostart """ if sys.platform == 'darwin': from Foundation import NSDictionary from Cocoa import NSBundle, NSURL from CoreFoundation import kCFAllocatorDefault # CF = CDLL(find_library('CoreFoundation')) from LaunchServices import (LSSharedFileListCreate, kLSSharedFileListSessionLoginItems, LSSharedFileListInsertItemURL, kLSSharedFileListItemHidden, kLSSharedFileListItemLast, LSSharedFileListItemRemove) app_path = NSBundle.mainBundle().bundlePath() url = NSURL.alloc().initFileURLWithPath_(app_path) login_items = LSSharedFileListCreate( kCFAllocatorDefault, kLSSharedFileListSessionLoginItems, None) props = NSDictionary.dictionaryWithObject_forKey_( True, kLSSharedFileListItemHidden) new_item = LSSharedFileListInsertItemURL(login_items, kLSSharedFileListItemLast, None, None, url, props, None) if not enabled: LSSharedFileListItemRemove(login_items, new_item) elif sys.platform.startswith('linux'): from appdirs import user_config_dir from pathlib import Path is_flatpak = Path('/.flatpak-info').exists() with open( Path(__file__).parent / "assets/metadata/com.borgbase.Vorta.desktop") as desktop_file: desktop_file_text = desktop_file.read() # Find XDG_CONFIG_HOME unless when running in flatpak if is_flatpak: autostart_path = Path.home() / '.config' / 'autostart' else: autostart_path = Path(user_config_dir("autostart")) if not autostart_path.exists(): autostart_path.mkdir(parents=True, exist_ok=True) autostart_file_path = autostart_path / 'vorta.desktop' if enabled: # Replace command for flatpak if appropriate and start in background desktop_file_text = desktop_file_text.replace( "Exec=vorta", "Exec=flatpak run com.borgbase.Vorta --daemonize" if is_flatpak else "Exec=vorta --daemonize") # Add autostart delay desktop_file_text += (AUTOSTART_DELAY) autostart_file_path.write_text(desktop_file_text) elif autostart_file_path.exists(): autostart_file_path.unlink()
def add_login_item(path_to_item, position=-1): # position: # 0..N: Attempt to insert at that index position, with 0 being first # -1: Insert as last item # Note: # If the item is already present in the list, it will get moved to the new location automatically. list_ref, current_items = _get_login_items() added_item = NSURL.fileURLWithPath_(path_to_item) if position == 0: # Seems to be buggy, will force it below destination_point = kLSSharedFileListItemBeforeFirst elif position == -1: destination_point = kLSSharedFileListItemLast elif position >= len(current_items): # At or beyond to the end of the current list position = -1 destination_point = kLSSharedFileListItemLast else: # 1 = after item 0, 2 = after item 1, etc. destination_point = current_items[position - 1] # The logic for LSSharedFileListInsertItemURL is generally fine when the item is not in the list # already (with the exception of kLSSharedFileListItemBeforeFirst which appears to be broken, period) # However, if the item is already in the list, the logic gets really really screwy. # Your index calculations are invalidated by OS X because you shift an item, possibly shifting the # indexes of other items in the list. # It's easier to just remove it first, then re-add it. current_paths = list_login_items() if (len(current_items) == 0) or (position == -1): # Either there's nothing there or it wants to be last # Just add the item, it'll be fine result = LSSharedFileListInsertItemURL(list_ref, destination_point, None, None, added_item, {}, []) elif (position == 0): # Special case - kLSSharedFileListItemBeforeFirst appears broken on (at least) 10.9 # Remove if already in the list if path_to_item in current_paths: i = current_paths.index(path_to_item) old_item = current_items[i] result = LSSharedFileListItemRemove(list_ref, old_item) # Regenerate list_ref and items list_ref, current_items = _get_login_items() if (len(current_items) == 0): # Simple case if nothing remains in the list result = LSSharedFileListInsertItemURL(list_ref, destination_point, None, None, added_item, {}, []) else: # At least one item remains. # The fix for the bug is: # - Add our item after the first ('needs_fixing') item # - Move the 'needs_fixing' item to the end # - Move the 'needs_fixing' item after our added item (which is now first) needs_fixing = _get_item_cfurl(current_items[0]) # Move our item result = LSSharedFileListInsertItemURL(list_ref, current_items[0], None, None, added_item, {}, []) if not (result is None): # Only shift if the first insert worked # Regenerate list_ref and items list_ref, current_items = _get_login_items() # Now move the old item last result = LSSharedFileListInsertItemURL(list_ref, kLSSharedFileListItemLast, None, None, needs_fixing, {}, []) # Regenerate list_ref and items list_ref, current_items = _get_login_items() # Now move the old item back under the new one result = LSSharedFileListInsertItemURL(list_ref, current_items[0], None, None, needs_fixing, {}, []) else: # We're aiming for an index based on something else in the list. # Only do something if we're not aiming at ourselves. insert_after_path = _get_item_cfurl(destination_point).path() if (insert_after_path != path_to_item): # Seems to be a different file if path_to_item in current_paths: # Remove our object if it's already present i = current_paths.index(path_to_item) self_item = current_items[i] result = LSSharedFileListItemRemove(list_ref, self_item) # Regenerate list_ref and items list_ref, current_items = _get_login_items() # Re-find our original target current_paths = list_login_items() i = current_paths.index(insert_after_path) destination_point = current_items[i] # Add ourselves after the file result = LSSharedFileListInsertItemURL(list_ref, destination_point, None, None, added_item, {}, [])