初始提交,未完全测试
This commit is contained in:
109
template/source/ClassPathSource.py
Normal file
109
template/source/ClassPathSource.py
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env python3.9
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
JFinal ClassPathSource - Class Path Source
|
||||
"""
|
||||
|
||||
import importlib.resources
|
||||
import os
|
||||
|
||||
class ClassPathSource:
|
||||
"""Class path source for template loading"""
|
||||
|
||||
def __init__(self, base_template_path: str, fileName: str, encoding: str):
|
||||
"""
|
||||
Initialize class path source
|
||||
|
||||
Args:
|
||||
base_template_path: Base template path
|
||||
fileName: File name
|
||||
encoding: Encoding
|
||||
"""
|
||||
self._fileName = fileName
|
||||
self._encoding = encoding
|
||||
self._baseTemplatePath = base_template_path
|
||||
|
||||
# Build resource path
|
||||
if base_template_path:
|
||||
self._resourcePath = os.path.join(base_template_path, fileName).replace('\\', '/')
|
||||
else:
|
||||
self._resourcePath = fileName.replace('\\', '/')
|
||||
|
||||
def get_content(self) -> str:
|
||||
"""
|
||||
Get class path resource content
|
||||
|
||||
Returns:
|
||||
Resource content as string
|
||||
"""
|
||||
try:
|
||||
# Try to load from classpath
|
||||
import importlib
|
||||
import sys
|
||||
|
||||
# Try different approaches to load resource
|
||||
try:
|
||||
# Try direct resource loading
|
||||
with open(self._resourcePath, 'r', encoding=self._encoding) as f:
|
||||
return f.read()
|
||||
except:
|
||||
# Try as package resource
|
||||
if '.' in self._resourcePath:
|
||||
parts = self._resourcePath.split('/')
|
||||
if len(parts) > 1:
|
||||
package_name = '.'.join(parts[:-1])
|
||||
resource_name = parts[-1]
|
||||
try:
|
||||
with importlib.resources.open_text(package_name, resource_name, encoding=self._encoding) as f:
|
||||
return f.read()
|
||||
except:
|
||||
pass
|
||||
|
||||
# Fall back to file system
|
||||
return self._try_file_system()
|
||||
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Error reading classpath resource {self._resourcePath}: {e}")
|
||||
|
||||
def _try_file_system(self) -> str:
|
||||
"""
|
||||
Try to load from file system as fallback
|
||||
|
||||
Returns:
|
||||
File content as string
|
||||
"""
|
||||
# Try current directory
|
||||
try:
|
||||
current_dir = os.getcwd()
|
||||
file_path = os.path.join(current_dir, self._resourcePath)
|
||||
if os.path.exists(file_path):
|
||||
with open(file_path, 'r', encoding=self._encoding) as f:
|
||||
return f.read()
|
||||
except:
|
||||
pass
|
||||
|
||||
# Try absolute path
|
||||
if os.path.isabs(self._resourcePath):
|
||||
try:
|
||||
with open(self._resourcePath, 'r', encoding=self._encoding) as f:
|
||||
return f.read()
|
||||
except:
|
||||
pass
|
||||
|
||||
raise RuntimeError(f"Resource not found: {self._resourcePath}")
|
||||
|
||||
def is_modified(self) -> bool:
|
||||
"""
|
||||
Check if resource has been modified
|
||||
|
||||
Returns:
|
||||
False for classpath resources (not supported)
|
||||
"""
|
||||
return False
|
||||
|
||||
def get_file_name(self) -> str:
|
||||
"""Get file name"""
|
||||
return self._fileName
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"ClassPathSource({self._fileName})"
|
||||
28
template/source/ClassPathSourceFactory.py
Normal file
28
template/source/ClassPathSourceFactory.py
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python3.9
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
JFinal ClassPathSourceFactory - Class Path Source Factory
|
||||
"""
|
||||
|
||||
from .ISourceFactory import ISourceFactory
|
||||
|
||||
class ClassPathSourceFactory(ISourceFactory):
|
||||
"""Class path source factory for template loading"""
|
||||
|
||||
def get_source(self, base_template_path: str, fileName: str, encoding: str):
|
||||
"""
|
||||
Get class path source
|
||||
|
||||
Args:
|
||||
base_template_path: Base template path
|
||||
fileName: File name
|
||||
encoding: Encoding
|
||||
|
||||
Returns:
|
||||
Class path source object
|
||||
"""
|
||||
from .ClassPathSource import ClassPathSource
|
||||
return ClassPathSource(base_template_path, fileName, encoding)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "ClassPathSourceFactory()"
|
||||
76
template/source/FileSource.py
Normal file
76
template/source/FileSource.py
Normal file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3.9
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
JFinal FileSource - File Source
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
class FileSource:
|
||||
"""File source for template loading"""
|
||||
|
||||
def __init__(self, base_template_path: str, fileName: str, encoding: str):
|
||||
"""
|
||||
Initialize file source
|
||||
|
||||
Args:
|
||||
base_template_path: Base template path
|
||||
fileName: File name
|
||||
encoding: Encoding
|
||||
"""
|
||||
self._fileName = fileName
|
||||
self._encoding = encoding
|
||||
self._lastModified = 0
|
||||
|
||||
# Build file path
|
||||
if base_template_path:
|
||||
self._filePath = os.path.join(base_template_path, fileName)
|
||||
else:
|
||||
self._filePath = fileName
|
||||
|
||||
# Normalize path
|
||||
self._filePath = os.path.normpath(self._filePath)
|
||||
|
||||
# Get last modified time
|
||||
self._update_last_modified()
|
||||
|
||||
def get_content(self) -> str:
|
||||
"""
|
||||
Get file content
|
||||
|
||||
Returns:
|
||||
File content as string
|
||||
"""
|
||||
try:
|
||||
with open(self._filePath, 'r', encoding=self._encoding) as f:
|
||||
return f.read()
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Error reading file {self._filePath}: {e}")
|
||||
|
||||
def is_modified(self) -> bool:
|
||||
"""
|
||||
Check if file has been modified
|
||||
|
||||
Returns:
|
||||
True if modified, False otherwise
|
||||
"""
|
||||
current_modified = os.path.getmtime(self._filePath)
|
||||
if current_modified > self._lastModified:
|
||||
self._lastModified = current_modified
|
||||
return True
|
||||
return False
|
||||
|
||||
def _update_last_modified(self):
|
||||
"""Update last modified time"""
|
||||
try:
|
||||
self._lastModified = os.path.getmtime(self._filePath)
|
||||
except:
|
||||
self._lastModified = 0
|
||||
|
||||
def get_file_name(self) -> str:
|
||||
"""Get file name"""
|
||||
return self._fileName
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"FileSource({self._fileName})"
|
||||
29
template/source/FileSourceFactory.py
Normal file
29
template/source/FileSourceFactory.py
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python3.9
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
JFinal FileSourceFactory - File Source Factory
|
||||
"""
|
||||
|
||||
import os
|
||||
from .ISourceFactory import ISourceFactory
|
||||
|
||||
class FileSourceFactory(ISourceFactory):
|
||||
"""File source factory for template loading"""
|
||||
|
||||
def get_source(self, base_template_path: str, fileName: str, encoding: str):
|
||||
"""
|
||||
Get file source
|
||||
|
||||
Args:
|
||||
base_template_path: Base template path
|
||||
fileName: File name
|
||||
encoding: Encoding
|
||||
|
||||
Returns:
|
||||
File source object
|
||||
"""
|
||||
from .FileSource import FileSource
|
||||
return FileSource(base_template_path, fileName, encoding)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "FileSourceFactory()"
|
||||
22
template/source/ISourceFactory.py
Normal file
22
template/source/ISourceFactory.py
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3.9
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
JFinal ISourceFactory - Source Factory Interface
|
||||
"""
|
||||
|
||||
class ISourceFactory:
|
||||
"""Source factory interface for template loading"""
|
||||
|
||||
def get_source(self, base_template_path: str, fileName: str, encoding: str):
|
||||
"""
|
||||
Get source by file name
|
||||
|
||||
Args:
|
||||
base_template_path: Base template path
|
||||
fileName: File name
|
||||
encoding: Encoding
|
||||
|
||||
Returns:
|
||||
Source object
|
||||
"""
|
||||
raise NotImplementedError("ISourceFactory.get_source() must be implemented by subclasses")
|
||||
50
template/source/StringSource.py
Normal file
50
template/source/StringSource.py
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python3.9
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
JFinal StringSource - String Source
|
||||
"""
|
||||
|
||||
class StringSource:
|
||||
"""String source for template loading"""
|
||||
|
||||
def __init__(self, content: str, cache_key: str = None):
|
||||
"""
|
||||
Initialize string source
|
||||
|
||||
Args:
|
||||
content: Template content
|
||||
cache_key: Cache key (optional)
|
||||
"""
|
||||
self._content = content
|
||||
self._cache_key = cache_key
|
||||
|
||||
def get_content(self) -> str:
|
||||
"""
|
||||
Get string content
|
||||
|
||||
Returns:
|
||||
Content as string
|
||||
"""
|
||||
return self._content
|
||||
|
||||
def is_modified(self) -> bool:
|
||||
"""
|
||||
Check if content has been modified
|
||||
|
||||
Returns:
|
||||
Always False for string sources
|
||||
"""
|
||||
return False
|
||||
|
||||
def get_cache_key(self) -> str:
|
||||
"""
|
||||
Get cache key
|
||||
|
||||
Returns:
|
||||
Cache key
|
||||
"""
|
||||
return self._cache_key
|
||||
|
||||
def __repr__(self) -> str:
|
||||
content_preview = self._content[:50] + "..." if len(self._content) > 50 else self._content
|
||||
return f"StringSource('{content_preview}')"
|
||||
1
template/source/__init__.py
Normal file
1
template/source/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# Python package initialization
|
||||
Reference in New Issue
Block a user