-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement
DarwinClipboard
for Clipboard
class.
- Loading branch information
1 parent
fdfd421
commit 94f69a4
Showing
2 changed files
with
108 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,82 +1,107 @@ | ||
import os | ||
import subprocess | ||
import time | ||
|
||
import bpy | ||
|
||
from .pasteboard import _native as pasteboard | ||
|
||
|
||
# Check if clipboard doesn't contain any file paths | ||
def no_furls(): | ||
script = [ | ||
"osascript", | ||
"-e", | ||
'((clipboard info) as string does not contain "«class furl»") as string', | ||
] | ||
popen = subprocess.Popen(script, stdout=subprocess.PIPE) | ||
return popen.communicate()[0].decode("utf-8").strip() == "true" | ||
|
||
|
||
# Save image data directly from clipboard | ||
def save_clipboard(fullpath): | ||
commands = [ | ||
f'set pastedImage to (open for access POSIX file "{fullpath}" with write permission)', | ||
"try", | ||
" write (the clipboard as «class PNGf») to pastedImage", | ||
"end try", | ||
"close access pastedImage", | ||
] | ||
script = ["osascript"] | ||
for command in commands: | ||
script += ["-e", command] | ||
subprocess.Popen(script).wait() | ||
|
||
|
||
def GrabImage(): | ||
|
||
timestamp = time.strftime("%y%m%d-%H%M%S") | ||
img_name = f"PastedImage{timestamp}.png" | ||
|
||
bpy_addon_prefs = bpy.context.preferences.addons[ | ||
__package__.split(".")[0] | ||
].preferences | ||
|
||
if bpy.data.filepath and bpy_addon_prefs.force_default_dir is False: | ||
Directory = os.path.join(os.path.split(bpy.data.filepath)[0], "ImagePaste") | ||
|
||
if os.path.isdir(Directory) is False: | ||
os.mkdir(Directory) | ||
|
||
else: | ||
Directory = bpy_addon_prefs.default_img_dir | ||
|
||
img_dir = os.path.join(Directory, img_name) | ||
|
||
pb = pasteboard.Pasteboard() | ||
urls = pb.get_file_urls() | ||
contents = pb.get_contents() | ||
|
||
if urls is not None: | ||
urls = list(urls) | ||
img_dir = urls | ||
img_name = [os.path.basename(current) for current in img_dir] | ||
return img_dir, img_name | ||
elif contents == "": | ||
return 0 | ||
else: | ||
if no_furls(): | ||
save_clipboard(img_dir) | ||
return [img_dir], [img_name] | ||
|
||
return 1 | ||
|
||
|
||
# Function to copy image from given path to clipboard | ||
def CopyImage(img_path): | ||
script = [ | ||
"osascript", | ||
"-e", | ||
f'set the clipboard to (read file POSIX file "{img_path}" as «class PNGf»)', | ||
] | ||
subprocess.Popen(script).wait() | ||
from __future__ import annotations | ||
from os.path import join | ||
|
||
from .pasteboard._native import Pasteboard | ||
from ..clipboard import Clipboard | ||
from ...image import Image | ||
from ...report import Report | ||
from ...process import Process | ||
|
||
|
||
class DarwinClipboard(Clipboard): | ||
"""A Clipboard implementation for macOS.""" | ||
|
||
def __init__(self, report: Report, images: list[Image] = None) -> None: | ||
"""Initialize the Darwin Clipboard. | ||
Args: | ||
report (Report): A Report object to hold operation results. | ||
images (list[Image], optional): A list of Image objects. Default: None. | ||
""" | ||
super().__init__(report, images=images) | ||
|
||
@classmethod | ||
def push(cls, save_directory: str) -> DarwinClipboard: | ||
"""Push the current image information from the clipboard. | ||
Args: | ||
save_directory (str): A path to a directory to save the image. | ||
Returns: | ||
DarwinClipboard: A new instance of the DarwinClipboard, with a Report | ||
object containing the operation results and a list of Image objects | ||
holding the images information. | ||
""" | ||
# Use Pasteboard to get file URLs from the clipboard | ||
pasteboard = Pasteboard() | ||
urls = pasteboard.get_file_urls() | ||
if urls is not None: | ||
filepaths = list(urls) | ||
images = [Image(filepath) for filepath in filepaths] | ||
return cls(Report(6, f"Pasted {len(images)} image files: {images}"), images) | ||
|
||
# If no images are found, return a report with no images | ||
contents = pasteboard.get_contents() | ||
if contents == "": | ||
return cls(Report(2)) | ||
|
||
# Check if clipboard doesn't contain any filepaths | ||
# (e.g. if the clipboard contains just a single image) | ||
commands = [ | ||
'((clipboard info) as string does not contain "«class furl»") as string' | ||
] | ||
process = Process(cls.get_osascript_args(commands)) | ||
if process.stdout == "true": | ||
filename = cls.get_timestamp_filename() | ||
filepath = join(save_directory, filename) | ||
image = Image(filepath, filename) | ||
commands = [ | ||
"set pastedImage to " | ||
f'(open for access POSIX file "{filepath}" with write permission)', | ||
"try", | ||
" write (the clipboard as «class PNGf») to pastedImage", | ||
"end try", | ||
"close access pastedImage", | ||
] | ||
process = Process.execute(cls.get_osascript_args(commands)) | ||
if process.stderr: | ||
return cls(Report(3, f"Cannot save image: {image} ({process.stderr})")) | ||
return cls(Report(6, f"Saved and pasted 1 image: {image}"), [image]) | ||
return cls(Report(3)) | ||
|
||
@classmethod | ||
def pull(cls, image_path: str) -> DarwinClipboard: | ||
"""Pull the image to the clipboard from its path. | ||
Args: | ||
image_path (str): A path to an image to be pulled to the clipboard. | ||
Returns: | ||
DarwinClipboard: A new instance of the DarwinClipboard, with a Report | ||
object containing the operation results and a list of one Image object | ||
holding information of the pulled image we put its path to the input. | ||
""" | ||
commands = [ | ||
"set the clipboard to " | ||
f'(read file POSIX file "{image_path}" as «class PNGf»)' | ||
] | ||
process = Process(cls.get_osascript_args(commands)) | ||
if process.stderr: | ||
return cls(Report(4, f"Process failed ({process.stderr})")) | ||
image = Image(image_path) | ||
return cls(Report(5, f"Copied 1 image: {image}"), [image]) | ||
|
||
@staticmethod | ||
def get_osascript_args(commands: list[str]) -> list[str]: | ||
"""Get the arguments for osascript command. | ||
Args: | ||
commands (list[str]): A list of commands to be executed. | ||
Returns: | ||
list[str]: A list of arguments for osascript command ready to be executed. | ||
""" | ||
args = ["osascript"] | ||
for command in commands: | ||
args += ["-e", command] | ||
return args |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters