moved the files around added demo examples and fixed a bunch of stuff!
This commit is contained in:
146
lua/Actions.py
Normal file
146
lua/Actions.py
Normal file
@@ -0,0 +1,146 @@
|
||||
from pathlib import Path
|
||||
from log import Logger
|
||||
import re
|
||||
|
||||
PLUGINS_DIR = Path(__file__).parent / "plugins"
|
||||
HTML_DIR = Path(__file__).parent / "../html"
|
||||
MARKDOWN_DIR = Path(__file__).parent / ".." / "markdown"
|
||||
|
||||
class Actions:
|
||||
def _safe_read_file(self, path):
|
||||
"""Safe file reading with path validation"""
|
||||
try:
|
||||
p = Path(path)
|
||||
# Prevent directory traversal
|
||||
if ".." in str(p.parts):
|
||||
raise ValueError("Path traversal not allowed")
|
||||
return p.read_text(encoding="utf-8")
|
||||
except Exception as e:
|
||||
Logger.log_lua_error(f"Error reading file {path}: {e}")
|
||||
return None
|
||||
@staticmethod
|
||||
def _safe_write_file(self, path, content):
|
||||
"""Safe file writing with path validation"""
|
||||
try:
|
||||
p = Path(path)
|
||||
# Prevent directory traversal
|
||||
if ".." in str(p.parts):
|
||||
raise ValueError("Path traversal not allowed")
|
||||
p.write_text(content, encoding="utf-8")
|
||||
return True
|
||||
except Exception as e:
|
||||
Logger.log_lua_error(f"Error writing file {path}: {e}")
|
||||
return False
|
||||
|
||||
# HTML/Markdown content operations
|
||||
@staticmethod
|
||||
def _read_content(self, base_dir, filename):
|
||||
"""Read content from HTML or Markdown directory"""
|
||||
try:
|
||||
path = base_dir / filename
|
||||
if not path.is_relative_to(base_dir):
|
||||
raise ValueError("Invalid path")
|
||||
if path.exists():
|
||||
return path.read_text(encoding="utf-8")
|
||||
return None
|
||||
except Exception as e:
|
||||
Logger.log_lua_error(f"Error reading {filename}: {e}")
|
||||
return None
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _write_content(self, base_dir, filename, content):
|
||||
"""Write content to HTML or Markdown directory"""
|
||||
try:
|
||||
path = base_dir / filename
|
||||
if not path.is_relative_to(base_dir):
|
||||
raise ValueError("Invalid path")
|
||||
path.write_text(content, encoding="utf-8")
|
||||
return True
|
||||
except Exception as e:
|
||||
Logger.log_lua_error(f"Error writing {filename}: {e}")
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _list_files(self, base_dir, extension):
|
||||
"""List files with given extension"""
|
||||
try:
|
||||
return [f.name for f in base_dir.glob(f"*{extension}")]
|
||||
except Exception as e:
|
||||
Logger.log_lua_error(f"Error listing files: {e}")
|
||||
return []
|
||||
|
||||
# HTML manipulation helpers
|
||||
@staticmethod
|
||||
def _html_find_tag(self, html, tag):
|
||||
"""Find first occurrence of HTML tag"""
|
||||
pattern = f"<{tag}[^>]*>.*?</{tag}>"
|
||||
match = re.search(pattern, html, re.DOTALL | re.IGNORECASE)
|
||||
return match.group(0) if match else None
|
||||
|
||||
@staticmethod
|
||||
def _html_replace_tag(self, html, tag, new_content):
|
||||
"""Replace HTML tag content"""
|
||||
pattern = f"(<{tag}[^>]*>).*?(</{tag}>)"
|
||||
return re.sub(pattern, f"\\1{new_content}\\2", html, flags=re.DOTALL | re.IGNORECASE)
|
||||
|
||||
@staticmethod
|
||||
def _html_insert_before(self, html, marker, content):
|
||||
"""Insert content before a marker"""
|
||||
return html.replace(marker, content + marker)
|
||||
|
||||
@staticmethod
|
||||
def _html_insert_after(self, html, marker, content):
|
||||
"""Insert content after a marker"""
|
||||
return html.replace(marker, marker + content)
|
||||
|
||||
@staticmethod
|
||||
def _html_wrap_content(self, html, tag, wrapper_tag, attrs=""):
|
||||
"""Wrap tag content with another tag"""
|
||||
pattern = f"(<{tag}[^>]*>)(.*?)(</{tag}>)"
|
||||
def replacer(match):
|
||||
open_tag, content, close_tag = match.groups()
|
||||
return f"{open_tag}<{wrapper_tag} {attrs}>{content}</{wrapper_tag}>{close_tag}"
|
||||
return re.sub(pattern, replacer, html, flags=re.DOTALL | re.IGNORECASE)
|
||||
|
||||
# Markdown manipulation helpers
|
||||
@staticmethod
|
||||
def _md_add_header(self, markdown, level, text):
|
||||
"""Add header to markdown"""
|
||||
prefix = "#" * level
|
||||
return f"{prefix} {text}\n\n{markdown}"
|
||||
|
||||
@staticmethod
|
||||
def _md_replace_section(self, markdown, header, new_content):
|
||||
"""Replace markdown section"""
|
||||
# Find section starting with header
|
||||
pattern = f"(#{1,6}\\s+{re.escape(header)}.*?)(?=#{1,6}\\s+|$)"
|
||||
return re.sub(pattern, f"## {header}\n\n{new_content}\n\n", markdown, flags=re.DOTALL)
|
||||
|
||||
@staticmethod
|
||||
def _md_append_content(self, markdown, content):
|
||||
"""Append content to markdown"""
|
||||
return markdown.rstrip() + "\n\n" + content
|
||||
|
||||
# JSON conversion helpers
|
||||
@staticmethod
|
||||
def _table_to_json(self, lua_table):
|
||||
"""Convert Lua table to JSON string"""
|
||||
import json
|
||||
try:
|
||||
# Convert lupa table to Python dict
|
||||
py_dict = dict(lua_table)
|
||||
return json.dumps(py_dict)
|
||||
except Exception as e:
|
||||
Logger.log_lua_error(f"Error converting table to JSON: {e}")
|
||||
return "{}"
|
||||
|
||||
@staticmethod
|
||||
def _json_to_table(self, json_str):
|
||||
"""Convert JSON string to Lua table"""
|
||||
import json
|
||||
try:
|
||||
return json.loads(json_str)
|
||||
except Exception as e:
|
||||
Logger.log_lua_error(f"Error parsing JSON: {e}")
|
||||
return {}
|
||||
Reference in New Issue
Block a user