"""DocVault - Offline-First Document Storage System""" from flask import Flask, jsonify, send_file, render_template_string from flask_cors import CORS import os try: from .config import SECRET_KEY, DEBUG, MAX_CONTENT_LENGTH from .routes.api import api_bp from .utils.logger import setup_logger except ImportError: from config import SECRET_KEY, DEBUG, MAX_CONTENT_LENGTH from routes.api import api_bp from utils.logger import setup_logger logger = setup_logger(__name__) # Get the root directory (parent of server directory) ROOT_DIR = os.path.dirname(os.path.dirname(__file__)) def create_app(): """Create and configure Flask application""" app = Flask(__name__, static_folder=None) # Configuration app.config['SECRET_KEY'] = SECRET_KEY app.config['MAX_CONTENT_LENGTH'] = MAX_CONTENT_LENGTH app.config['JSON_SORT_KEYS'] = False # Enable CORS for local development CORS(app, resources={r"/api/*": {"origins": "*"}}) # Register blueprints app.register_blueprint(api_bp) # Cache busting headers for all responses @app.after_request def add_cache_headers(response): if response.content_type and ('text/html' in response.content_type or 'text/javascript' in response.content_type or 'application/javascript' in response.content_type or 'text/css' in response.content_type): response.cache_control.max_age = 0 response.cache_control.no_cache = True response.cache_control.no_store = True response.headers['Pragma'] = 'no-cache' response.headers['Expires'] = '0' return response # Global error handlers @app.errorhandler(413) def request_entity_too_large(error): return jsonify({ "success": False, "error": f"File too large. Maximum size: {MAX_CONTENT_LENGTH / (1024 * 1024):.0f}MB" }), 413 # Serve static frontend files with no-cache headers @app.route('/') def serve_static(filename): """Serve static files from root directory""" filepath = os.path.join(ROOT_DIR, filename) if os.path.exists(filepath) and os.path.isfile(filepath): return send_file(filepath) return jsonify({"error": "Not found"}), 404 @app.route('/', methods=['GET']) def index(): """Serve index.html for root path""" index_path = os.path.join(ROOT_DIR, 'index.html') if os.path.exists(index_path): with open(index_path, 'r', encoding='utf-8') as f: return f.read() # Fallback to API documentation if index.html doesn't exist return jsonify({ "name": "DocVault", "version": "1.0.0", "description": "Offline-First Document Storage System", "endpoints": { "GET /api/health": "Health check", "POST /api/create-folder": "Create folder", "POST /api/delete-folder": "Delete folder", "POST /api/delete-file": "Delete file", "POST /api/upload-file": "Upload file", "GET /api/list": "List contents", "POST /api/rename": "Rename file/folder", "GET /api/storage-stats": "Storage statistics", "GET /api/download/": "Download file" }, "documentation": "See README.md for detailed API documentation" }), 200 @app.route('/docs', methods=['GET']) def docs(): """API documentation in detail""" docs_text = """ DocVault API Documentation

DocVault API Documentation

Offline-First Document Storage System

Available Endpoints

POST /api/create-folder

Create a new folder (including nested folders)

{
  "folder_path": "Documents/MyProject"
}
            

POST /api/delete-folder

Delete a folder

{
  "folder_path": "Documents/MyProject",
  "force": true
}
            

POST /api/delete-file

Delete a file

{
  "file_path": "Documents/report.pdf"
}
            

POST /api/upload-file

Upload a file to a folder

Form data: file (binary), folder_path (string)

GET /api/list

List files and folders

Query: folder_path (optional)

POST /api/rename

Rename a file or folder

{
  "item_path": "Documents/OldName",
  "new_name": "NewName"
}
            

GET /api/storage-stats

Get storage statistics

GET /api/download/<file_path>

Download a file

Headers

Optional: X-User-ID (defaults to 'default_user')

Error Responses

{
  "success": false,
  "error": "Error message"
}
            
""" return docs_text, 200, {'Content-Type': 'text/html'} logger.info("DocVault application initialized") return app if __name__ == '__main__': app = create_app() port = int(os.environ.get("PORT", 7860)) logger.info(f"Starting DocVault on http://localhost:{port} (DEBUG: {DEBUG})") app.run(debug=DEBUG, host='0.0.0.0', port=port)