Skip to content

Commit

Permalink
feat(api): Add rotate method to ArtLayer and improve layer management…
Browse files Browse the repository at this point in the history
… classes

Signed-off-by: longhao <[email protected]>
  • Loading branch information
loonghao committed Dec 29, 2024
1 parent 3dd89ae commit 4212e45
Show file tree
Hide file tree
Showing 73 changed files with 10,359 additions and 1,896 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ docs_src/_build/
/examples/files/blue/
/examples/files/green/
/examples/files/red/
/site/
1 change: 1 addition & 0 deletions docs/gen_api_nav.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@


def main() -> None:
"""Generate API navigation for mkdocs."""
nav = mkdocs_gen_files.Nav()
root = Path(__file__).parent.parent
api_root = root.joinpath("photoshop")
Expand Down
95 changes: 83 additions & 12 deletions docs/gen_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
from __future__ import annotations

from pathlib import Path

import mkdocs_gen_files
import stringcase
import re
import shutil

# Import third-party modules
import mkdocs_gen_files
from jinja2 import Template

template = Template(
Expand All @@ -28,37 +28,108 @@


class Examples:
"""Class for handling example files generation."""

def __init__(self, root: Path) -> None:
"""Initialize Examples class.
Args:
root: Root directory path.
"""
self._root = root

def get_examples(self) -> list[Path]:
return [file_ for file_ in self._root.glob("*.py") if "_psd_files.py" not in file_.as_posix()]
"""Get list of example files.
Returns:
List of example file paths.
"""
return sorted([file_ for file_ in self._root.glob("*.py") if "_psd_files.py" not in file_.as_posix()])

@staticmethod
def convert_relative_path(file: str) -> str:
path = file.split("examples")[1]
return "../examples{}".format(path.replace("\\", "/"))
"""Convert file path to relative path.
Args:
file: File path to convert.
Returns:
Relative path string.
"""
# Use raw string for regex pattern
return re.sub(r"\W+", "", str(file))

@staticmethod
def get_name(file: str) -> str:
name = Path(file).name.split(".py")[0]
return stringcase.titlecase(name)
"""Get example name from file path.
Args:
file: File path.
Returns:
Example name in title case.
"""
name = Path(file).stem
return name.replace("_", " ").title()

@staticmethod
def get_line(name: str) -> str:
"""Generate underline for example name.
Args:
name: Example name.
Returns:
String of dashes matching name length.
"""
return "-" * len(name)

@staticmethod
def get_content(file_: str) -> str:
with Path(file_).open() as f:
"""Get content of example file.
Args:
file_: File path.
Returns:
File content as string.
"""
with Path(file_).open(encoding='utf-8') as f:
return "".join(f.readlines())


def main() -> None:
"""Generate examples documentation."""
root = Path(__file__).parent.parent
with mkdocs_gen_files.open("examples.md", "w") as nav_file:
examples_data = Examples(root.joinpath("examples"))
nav_file.write(template.render(Examples=examples_data))
examples_dir = root / "examples"

# 生成 examples.md 文件
examples_data = Examples(examples_dir)
content = template.render(Examples=examples_data)

# 使用 mkdocs_gen_files 生成文件到正确的位置
with mkdocs_gen_files.open("examples.md", "w", encoding='utf-8') as f:
f.write(content)
print("Generated examples.md")

# 确保文件被写入到正确的位置
mkdocs_gen_files.set_edit_path("examples.md", "docs/gen_examples.py")

# 同时写入到 docs 目录
docs_dir = root / "docs"
docs_dir.mkdir(exist_ok=True)
examples_file = docs_dir / "examples.md"

# 如果文件已存在,先删除它
if examples_file.exists():
try:
examples_file.unlink()
except PermissionError:
pass

# 写入新文件
examples_file.write_text(content, encoding='utf-8')
print(f"Generated {examples_file}")


if __name__ == "__main__":
Expand Down
50 changes: 26 additions & 24 deletions examples/active_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
Example:
```python
with Session() as ps:
docRef = ps.app.documents.add() # Create new document
new_layer = docRef.artLayers.add() # Add new layer
doc_ref = ps.app.documents.add() # Create new document
new_layer = doc_ref.artLayers.add() # Add new layer
new_layer.name = "test" # Rename layer
```
Note:
The script will create a new document if none exists,
and will add a new layer if the document has less than 2 layers.
and will add a new layer if the document has less than MIN_LAYERS layers.
"""

# Import built-in modules
Expand All @@ -25,24 +25,26 @@
# Import local modules
from photoshop import Session

# Create a new Photoshop session
with Session() as ps:
# Create a new document if none exists
if len(ps.app.documents) < 1:
docRef = ps.app.documents.add()
else:
docRef = ps.app.activeDocument

# Add a new layer if document has less than 2 layers
if len(docRef.layers) < 2:
docRef.artLayers.add()

# Print the name of the current active layer
ps.echo(docRef.activeLayer.name)

# Create a new art layer and make it active
new_layer = docRef.artLayers.add()
ps.echo(new_layer.name)

# Rename the new layer
new_layer.name = "test"
def main():
"""Demonstrate active layer operations in Photoshop."""
with Session() as ps:
# Create a new document if none exists
doc_ref = ps.app.documents.add() if len(ps.app.documents) < 1 else ps.app.activeDocument

# Add a new layer if document has less than MIN_LAYERS layers
MIN_LAYERS = 2
if len(doc_ref.layers) < MIN_LAYERS:
doc_ref.artLayers.add()

# Print the name of the current active layer
ps.echo(doc_ref.activeLayer.name)

# Create a new art layer and make it active
new_layer = doc_ref.artLayers.add()
ps.echo(new_layer.name)

# Rename the new layer
new_layer.name = "test"

if __name__ == "__main__":
main()
4 changes: 2 additions & 2 deletions examples/add_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@
with Session(action="new_document") as ps:
# Get reference to active document
doc = ps.active_document

# Set metadata properties
doc.info.author = os.getenv("USERNAME") # Set author to system username
doc.info.provinceState = "Beijing" # Set location information
doc.info.title = "My Demo" # Set document title

# Print the metadata information
ps.echo("Metadata of current active document:")
ps.echo(doc.info)
8 changes: 4 additions & 4 deletions examples/add_slate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
Example:
```python
with Session(template_file, action="open") as ps:
layer_set = ps.active_document.layerSets.getByName("template")
layer_set = ps.active_document.layerSets["template"]
for layer in layer_set.layers:
if layer.kind == ps.LayerKind.TextLayer:
layer.textItem.contents = dynamic_data[layer.textItem.contents]
Expand Down Expand Up @@ -46,14 +46,14 @@
# Open template file in Photoshop
with Session(slate_template, action="open", auto_close=True) as ps:
# Get the layer set named "template"
layer_set = ps.active_document.layerSets.getByName("template")
layer_set = ps.active_document.layerSets["template"]

# Prepare dynamic data for text layers
data = {
"project name": "test_project",
"datetime": datetime.now(tz=timezone.utc).strftime("%Y-%m-%d"),
}

# Update text layers with dynamic content
for layer in layer_set.layers:
if layer.kind == ps.LayerKind.TextLayer:
Expand All @@ -63,7 +63,7 @@
jpg_file = Path(mkdtemp("photoshop-python-api")) / "slate.jpg"
ps.active_document.saveAs(str(jpg_file), ps.JPEGSaveOptions())
ps.echo(f"Save jpg to {jpg_file}")

# Open the saved JPG file (Windows-specific)
# Note: os.startfile is Windows-specific, consider using a cross-platform solution
os.startfile(str(jpg_file))
6 changes: 3 additions & 3 deletions examples/add_start_application_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@
# Create a temporary directory to store the JSX script
root = Path(mkdtemp())
jsx_file = root / "event.jsx"

# Write the JavaScript code that will be executed when Photoshop starts
jsx_file.write_text('alert("Start Application event.")')

# Add the event notifier to Photoshop
# EventID.Notify is triggered when Photoshop starts
ps.app.notifiers.add(ps.EventID.Notify, str(jsx_file))

# Confirm the event was added successfully
ps.echo("Add event done.")
Loading

0 comments on commit 4212e45

Please sign in to comment.