openapi: 3.0.3 info: title: PyraFiles API version: 1.0.0 description: | API specification for the PyraFiles application. PyraFiles allows users to register, authenticate, upload media files, and manage their media content. servers: - url: http://localhost:{port} description: Local development server variables: port: default: '6544' - url: https://upload.unturf.com description: prod for humans & agents to mingle. paths: /: get: summary: Home Page description: Displays the home page. responses: '200': description: Successful response content: text/html: schema: type: string /auth/login: get: summary: Display Login Page description: Renders the login page where users can enter their email. responses: '200': description: Login page rendered content: text/html: schema: type: string post: summary: Process Login description: Sends a verification code to the user's email. requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object properties: email: type: string format: email required: - email responses: '302': description: Redirects to the verification page '400': description: Bad Request (e.g., email missing) '500': description: Internal Server Error /auth/verify: get: summary: Display Verification Page description: Renders the verification page where users can enter their code. responses: '200': description: Verification page rendered content: text/html: schema: type: string post: summary: Verify User description: Verifies the user's code and logs them in. requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object properties: code: type: string required: - code responses: '302': description: Redirects to the home page upon successful verification '400': description: Bad Request (e.g., invalid code) '500': description: Internal Server Error /auth/logout: get: summary: Logout User description: Logs out the current user. responses: '302': description: Redirects to the home page /auth/profile: get: summary: Display User Profile description: Shows the user's profile, including upload stats. security: - sessionAuth: [] responses: '200': description: Profile page rendered content: text/html: schema: type: string '403': description: Unauthorized (user not logged in) post: summary: Update User Profile description: Updates the user's profile settings. security: - sessionAuth: [] requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object properties: enable_gravatar: type: string enum: ['on'] new_username: type: string responses: '302': description: Redirects to the profile page '400': description: Bad Request (e.g., username already in use) '403': description: Unauthorized (user not logged in or guest mode) /auth/download_db: get: summary: Download User Database description: Allows the user to download their personal database file. security: - sessionAuth: [] responses: '200': description: Database file downloaded content: application/octet-stream: schema: type: string format: binary '403': description: Unauthorized (user not logged in or unverified) '404': description: Database file not found /auth/export_user_record: get: summary: Export User Record description: Exports the user's record as a JSON file. security: - sessionAuth: [] responses: '200': description: User record JSON file downloaded content: application/json: schema: type: object '403': description: Unauthorized (user not logged in or unverified) /admin/import_user_record: get: summary: Display Import User Record Page description: Renders a page to import a user record (Admin only). security: - sessionAuth: [] responses: '200': description: Import user record page rendered content: text/html: schema: type: string '403': description: Forbidden (user not admin) post: summary: Import User Record description: Processes uploaded user record file and imports the user (Admin only). security: - sessionAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object properties: user_record_file: type: string format: binary required: - user_record_file responses: '302': description: Redirects to the home page after successful import '400': description: Bad Request (e.g., invalid file) '403': description: Forbidden (user not admin) /media/upload: get: summary: Display Media Upload Page description: Renders the media upload form. security: - sessionAuth: [] responses: '200': description: Upload media page rendered content: text/html: schema: type: string '403': description: Unauthorized (user not logged in or unverified) post: summary: Upload Media description: Processes the uploaded media file. security: - sessionAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object properties: media_file: type: string format: binary title: type: string is_public: type: string enum: ['on'] required: - media_file responses: '302': description: Redirects to the media details page '400': description: Bad Request (e.g., no file uploaded, unsupported media type) '403': description: Unauthorized (user not logged in or unverified) /media/list: get: summary: List Public Media description: Displays a list of public media from all users. responses: '200': description: Media list page rendered content: text/html: schema: type: string /media/user/{user_short_id}: get: summary: Display User's Media description: Shows all media uploaded by a specific user. parameters: - in: path name: user_short_id required: true schema: type: string description: The short ID of the user responses: '200': description: User's media page rendered content: text/html: schema: type: string '404': description: User not found '500': description: Internal Server Error /media/{user_short_id}/{media_short_id}/details: get: summary: Display Media Details description: Shows details of a specific media item. parameters: - in: path name: user_short_id required: true schema: type: string description: The short ID of the user - in: path name: media_short_id required: true schema: type: string description: The short ID of the media item responses: '200': description: Media details page rendered content: text/html: schema: type: string '404': description: Media or user not found '403': description: Forbidden (media not public and not owner) /media/{user_short_id}/{media_short_id}/edit: get: summary: Display Media Edit Page description: Renders a form to edit media details (owner only). security: - sessionAuth: [] parameters: - in: path name: user_short_id required: true schema: type: string description: The short ID of the user - in: path name: media_short_id required: true schema: type: string description: The short ID of the media item responses: '200': description: Media edit page rendered content: text/html: schema: type: string '403': description: Forbidden (not owner or not logged in) '404': description: Media not found post: summary: Edit Media description: Updates the media item (owner only). security: - sessionAuth: [] parameters: - in: path name: user_short_id required: true schema: type: string description: The short ID of the user - in: path name: media_short_id required: true schema: type: string description: The short ID of the media item requestBody: required: true content: multipart/form-data: schema: type: object properties: title: type: string is_public: type: string enum: ['on'] media_file: type: string format: binary responses: '302': description: Redirects to the media details page '400': description: Bad Request (e.g., file too large) '403': description: Forbidden (not owner) '404': description: Media not found /media/{user_short_id}/{media_short_id}/delete: post: summary: Delete Media description: Deletes the media item (owner only). security: - sessionAuth: [] parameters: - in: path name: user_short_id required: true schema: type: string description: The short ID of the user - in: path name: media_short_id required: true schema: type: string description: The short ID of the media item responses: '302': description: Redirects to the user's media list '403': description: Forbidden (not owner) '404': description: Media not found /media/{user_short_id}/{media_short_id}: get: summary: View Media description: Retrieves the media file for viewing or download. parameters: - in: path name: user_short_id required: true schema: type: string description: The short ID of the user - in: path name: media_short_id required: true schema: type: string description: The short ID of the media item - in: query name: download schema: type: string enum: ['true', 'false'] description: Set to 'true' to trigger download responses: '200': description: Media file retrieved content: '*/*': schema: type: string format: binary '403': description: Forbidden (media not public and not owner) '404': description: Media not found components: securitySchemes: sessionAuth: type: apiKey in: cookie name: session description: Session cookie for authenticated users