mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 10:18:41 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			168 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			168 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
#!/usr/bin/python
 | 
						|
# This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
# License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
# file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
"""
 | 
						|
mac_desktop_image.py
 | 
						|
 | 
						|
Mac-specific utility to get/set the desktop background image or check that
 | 
						|
the current background image path matches a provided path.
 | 
						|
 | 
						|
Depends on Objective-C python binding imports which are in the python import
 | 
						|
paths by default when using macOS's /usr/bin/python.
 | 
						|
 | 
						|
Includes generous amount of logging to aid debugging for use in automated tests.
 | 
						|
"""
 | 
						|
 | 
						|
import argparse
 | 
						|
import logging
 | 
						|
import os
 | 
						|
import sys
 | 
						|
 | 
						|
#
 | 
						|
# These Objective-C bindings imports are included in the import path by default
 | 
						|
# for the Mac-bundled python installed in /usr/bin/python. They're needed to
 | 
						|
# call the Objective-C API's to set and retrieve the current desktop background
 | 
						|
# image.
 | 
						|
#
 | 
						|
from AppKit import NSScreen, NSWorkspace
 | 
						|
from Cocoa import NSURL
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    parser = argparse.ArgumentParser(
 | 
						|
        description="Utility to print, set, or "
 | 
						|
        + "check the path to image being used as "
 | 
						|
        + "the desktop background image. By "
 | 
						|
        + "default, prints the path to the "
 | 
						|
        + "current desktop background image."
 | 
						|
    )
 | 
						|
    parser.add_argument(
 | 
						|
        "-v",
 | 
						|
        "--verbose",
 | 
						|
        action="store_true",
 | 
						|
        help="print verbose debugging information",
 | 
						|
        default=False,
 | 
						|
    )
 | 
						|
    group = parser.add_mutually_exclusive_group()
 | 
						|
    group.add_argument(
 | 
						|
        "-s",
 | 
						|
        "--set-background-image",
 | 
						|
        dest="newBackgroundImagePath",
 | 
						|
        required=False,
 | 
						|
        help="path to the new background image to set. A zero "
 | 
						|
        + "exit code indicates no errors occurred.",
 | 
						|
        default=None,
 | 
						|
    )
 | 
						|
    group.add_argument(
 | 
						|
        "-c",
 | 
						|
        "--check-background-image",
 | 
						|
        dest="checkBackgroundImagePath",
 | 
						|
        required=False,
 | 
						|
        help="check if the provided background image path "
 | 
						|
        + "matches the provided path. A zero exit code "
 | 
						|
        + "indicates the paths match.",
 | 
						|
        default=None,
 | 
						|
    )
 | 
						|
    args = parser.parse_args()
 | 
						|
 | 
						|
    # Using logging for verbose output
 | 
						|
    if args.verbose:
 | 
						|
        logging.basicConfig(level=logging.DEBUG)
 | 
						|
    else:
 | 
						|
        logging.basicConfig(level=logging.CRITICAL)
 | 
						|
    logger = logging.getLogger("desktopImage")
 | 
						|
 | 
						|
    # Print what we're going to do
 | 
						|
    if args.checkBackgroundImagePath is not None:
 | 
						|
        logger.debug(
 | 
						|
            "checking provided desktop image %s matches current "
 | 
						|
            "image" % args.checkBackgroundImagePath
 | 
						|
        )
 | 
						|
    elif args.newBackgroundImagePath is not None:
 | 
						|
        logger.debug("setting image to %s " % args.newBackgroundImagePath)
 | 
						|
    else:
 | 
						|
        logger.debug("retrieving desktop image path")
 | 
						|
 | 
						|
    focussedScreen = NSScreen.mainScreen()
 | 
						|
    if not focussedScreen:
 | 
						|
        raise RuntimeError("mainScreen error")
 | 
						|
 | 
						|
    ws = NSWorkspace.sharedWorkspace()
 | 
						|
    if not ws:
 | 
						|
        raise RuntimeError("sharedWorkspace error")
 | 
						|
 | 
						|
    # If we're just checking the image path, check it and then return.
 | 
						|
    # A successful exit code (0) indicates the paths match.
 | 
						|
    if args.checkBackgroundImagePath is not None:
 | 
						|
        # Get existing desktop image path and resolve it
 | 
						|
        existingImageURL = getCurrentDesktopImageURL(focussedScreen, ws, logger)
 | 
						|
        existingImagePath = existingImageURL.path()
 | 
						|
        existingImagePathReal = os.path.realpath(existingImagePath)
 | 
						|
        logger.debug("existing desktop image: %s" % existingImagePath)
 | 
						|
        logger.debug("existing desktop image realpath: %s" % existingImagePath)
 | 
						|
 | 
						|
        # Resolve the path we're going to check
 | 
						|
        checkImagePathReal = os.path.realpath(args.checkBackgroundImagePath)
 | 
						|
        logger.debug("check desktop image: %s" % args.checkBackgroundImagePath)
 | 
						|
        logger.debug("check desktop image realpath: %s" % checkImagePathReal)
 | 
						|
 | 
						|
        if existingImagePathReal == checkImagePathReal:
 | 
						|
            print("desktop image path matches provided path")
 | 
						|
            return True
 | 
						|
 | 
						|
        print("desktop image path does NOT match provided path")
 | 
						|
        return False
 | 
						|
 | 
						|
    # Log the current desktop image
 | 
						|
    if args.verbose:
 | 
						|
        existingImageURL = getCurrentDesktopImageURL(focussedScreen, ws, logger)
 | 
						|
        logger.debug("existing desktop image: %s" % existingImageURL.path())
 | 
						|
 | 
						|
    # Set the desktop image
 | 
						|
    if args.newBackgroundImagePath is not None:
 | 
						|
        newImagePath = args.newBackgroundImagePath
 | 
						|
        if not os.path.exists(newImagePath):
 | 
						|
            logger.critical("%s does not exist" % newImagePath)
 | 
						|
            return False
 | 
						|
        if not os.access(newImagePath, os.R_OK):
 | 
						|
            logger.critical("%s is not readable" % newImagePath)
 | 
						|
            return False
 | 
						|
 | 
						|
        logger.debug("new desktop image to set: %s" % newImagePath)
 | 
						|
        newImageURL = NSURL.fileURLWithPath_(newImagePath)
 | 
						|
        logger.debug("new desktop image URL to set: %s" % newImageURL)
 | 
						|
 | 
						|
        status = False
 | 
						|
        (status, error) = ws.setDesktopImageURL_forScreen_options_error_(
 | 
						|
            newImageURL, focussedScreen, None, None
 | 
						|
        )
 | 
						|
        if not status:
 | 
						|
            raise RuntimeError("setDesktopImageURL error")
 | 
						|
 | 
						|
    # Print the current desktop image
 | 
						|
    imageURL = getCurrentDesktopImageURL(focussedScreen, ws, logger)
 | 
						|
    imagePath = imageURL.path()
 | 
						|
    imagePathReal = os.path.realpath(imagePath)
 | 
						|
    logger.debug("updated desktop image URL: %s" % imageURL)
 | 
						|
    logger.debug("updated desktop image path: %s" % imagePath)
 | 
						|
    logger.debug("updated desktop image path (resolved): %s" % imagePathReal)
 | 
						|
    print(imagePathReal)
 | 
						|
    return True
 | 
						|
 | 
						|
 | 
						|
def getCurrentDesktopImageURL(focussedScreen, workspace, logger):
 | 
						|
    imageURL = workspace.desktopImageURLForScreen_(focussedScreen)
 | 
						|
    if not imageURL:
 | 
						|
        raise RuntimeError("desktopImageURLForScreen returned invalid URL")
 | 
						|
    if not imageURL.isFileURL():
 | 
						|
        logger.warning("desktop image URL is not a file URL")
 | 
						|
    return imageURL
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    if not main():
 | 
						|
        sys.exit(1)
 | 
						|
    else:
 | 
						|
        sys.exit(0)
 |