feat: Enhance WebDAV file management and UI
- Add functionality to create new collections via API - Implement copy and move operations between collections - Improve image rendering in markdown preview with relative path resolution - Add support for previewing binary files (images, PDFs) - Refactor modal styling to use flat buttons and improve accessibility
This commit is contained in:
@@ -28,8 +28,16 @@ class MarkdownEditorApp:
|
||||
|
||||
def load_config(self, config_path):
|
||||
"""Load configuration from YAML file"""
|
||||
self.config_path = config_path
|
||||
with open(config_path, 'r') as f:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
def save_config(self):
|
||||
"""Save configuration to YAML file"""
|
||||
# Update config with current collections
|
||||
self.config['collections'] = self.collections
|
||||
with open(self.config_path, 'w') as f:
|
||||
yaml.dump(self.config, f, default_flow_style=False, sort_keys=False)
|
||||
|
||||
def setup_collections(self):
|
||||
"""Create collection directories if they don't exist"""
|
||||
@@ -92,6 +100,10 @@ class MarkdownEditorApp:
|
||||
if path == '/fs/' and method == 'GET':
|
||||
return self.handle_collections_list(environ, start_response)
|
||||
|
||||
# API to create new collection
|
||||
if path == '/fs/' and method == 'POST':
|
||||
return self.handle_create_collection(environ, start_response)
|
||||
|
||||
# Check if path starts with a collection name (for SPA routing)
|
||||
# This handles URLs like /notes/ttt or /documents/file.md
|
||||
# MUST be checked BEFORE WebDAV routing to prevent WebDAV from intercepting SPA routes
|
||||
@@ -113,14 +125,86 @@ class MarkdownEditorApp:
|
||||
"""Return list of available collections"""
|
||||
collections = list(self.collections.keys())
|
||||
response_body = json.dumps(collections).encode('utf-8')
|
||||
|
||||
|
||||
start_response('200 OK', [
|
||||
('Content-Type', 'application/json'),
|
||||
('Content-Length', str(len(response_body))),
|
||||
('Access-Control-Allow-Origin', '*')
|
||||
])
|
||||
|
||||
|
||||
return [response_body]
|
||||
|
||||
def handle_create_collection(self, environ, start_response):
|
||||
"""Create a new collection"""
|
||||
try:
|
||||
# Read request body
|
||||
content_length = int(environ.get('CONTENT_LENGTH', 0))
|
||||
request_body = environ['wsgi.input'].read(content_length)
|
||||
data = json.loads(request_body.decode('utf-8'))
|
||||
|
||||
collection_name = data.get('name')
|
||||
if not collection_name:
|
||||
start_response('400 Bad Request', [('Content-Type', 'application/json')])
|
||||
return [json.dumps({'error': 'Collection name is required'}).encode('utf-8')]
|
||||
|
||||
# Check if collection already exists
|
||||
if collection_name in self.collections:
|
||||
start_response('409 Conflict', [('Content-Type', 'application/json')])
|
||||
return [json.dumps({'error': f'Collection "{collection_name}" already exists'}).encode('utf-8')]
|
||||
|
||||
# Create collection directory
|
||||
collection_path = Path(f'./collections/{collection_name}')
|
||||
collection_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create images subdirectory
|
||||
images_path = collection_path / 'images'
|
||||
images_path.mkdir(exist_ok=True)
|
||||
|
||||
# Add to collections dict
|
||||
self.collections[collection_name] = {
|
||||
'path': str(collection_path),
|
||||
'description': f'User-created collection: {collection_name}'
|
||||
}
|
||||
|
||||
# Update config file
|
||||
self.save_config()
|
||||
|
||||
# Add to WebDAV provider mapping
|
||||
from wsgidav.fs_dav_provider import FilesystemProvider
|
||||
provider_path = os.path.abspath(str(collection_path))
|
||||
provider_key = f'/fs/{collection_name}'
|
||||
|
||||
# Use the add_provider method if available, otherwise add directly to provider_map
|
||||
provider = FilesystemProvider(provider_path)
|
||||
if hasattr(self.webdav_app, 'add_provider'):
|
||||
self.webdav_app.add_provider(provider_key, provider)
|
||||
print(f"Added provider using add_provider(): {provider_key}")
|
||||
else:
|
||||
self.webdav_app.provider_map[provider_key] = provider
|
||||
print(f"Added provider to provider_map: {provider_key}")
|
||||
|
||||
# Also update sorted_share_list if it exists
|
||||
if hasattr(self.webdav_app, 'sorted_share_list'):
|
||||
if provider_key not in self.webdav_app.sorted_share_list:
|
||||
self.webdav_app.sorted_share_list.append(provider_key)
|
||||
self.webdav_app.sorted_share_list.sort(reverse=True)
|
||||
print(f"Updated sorted_share_list")
|
||||
|
||||
print(f"Created collection '{collection_name}' at {provider_path}")
|
||||
|
||||
response_body = json.dumps({'success': True, 'name': collection_name}).encode('utf-8')
|
||||
start_response('201 Created', [
|
||||
('Content-Type', 'application/json'),
|
||||
('Content-Length', str(len(response_body))),
|
||||
('Access-Control-Allow-Origin', '*')
|
||||
])
|
||||
|
||||
return [response_body]
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error creating collection: {e}")
|
||||
start_response('500 Internal Server Error', [('Content-Type', 'application/json')])
|
||||
return [json.dumps({'error': str(e)}).encode('utf-8')]
|
||||
|
||||
def handle_static(self, environ, start_response):
|
||||
"""Serve static files"""
|
||||
|
||||
Reference in New Issue
Block a user