diff --git a/res/include/md/about.md b/res/include/md/about.md
new file mode 100644
index 0000000..99c9a76
--- /dev/null
+++ b/res/include/md/about.md
@@ -0,0 +1,79 @@
+# Questions and Answers
+
+## For how long will my files be stored?
+
+Files will be removed if they have not been viewed for 30 days. A view is
+counted when someone visits the file's download page (pixeldrain.com/u/somefile)
+or views the file through a list the file is included in
+(pixeldrain.com/l/somelist).
+
+If you upload a file while logged into your pixeldrain account you will be able
+to delete the file yourself from the download page of the file. If you are not
+logged in and you accidentally upload something you shouldn't have, just don't
+share the link. The file will expire eventually. File links are not indexed or
+published anywhere. As long as you don't share it nobody will see it.
+
+## Does pixeldrain cost any money?
+
+No, pixeldrain is completely free at the moment. While there is an advertisement
+on the file downloading page, it doesn't generate nearly enough revenue to pay
+for maintaining this service. That's why I'd really appreciate it if you could
+spare some coins. Possible methods for donating are:
+
+ *
+ {{template `patreon.svg` .}} Support me on Patreon and get some perks too!
+
+ * Bitcoin:
+ [1Ne7hGuvnfz9EFTRD3PLWVeaJTX9oA1QUr](bitcoin:1Ne7hGuvnfz9EFTRD3PLWVeaJTX9oA1QUr?label=Pixeldrain%20Donation)
+ * BasicAttentionToken: Donate BAT by clicking the BAT icon in your address bar.
+ If you don't have Brave browser yet you can download it here: Install Brave. Installing and using Brave with this
+ referral link also counts as a 5$ donation.
+ * Siacoin:
+ 26117c19ca3975b315d663dcbbc19cf9c07274f441689d4392ed380b2337589ef1aacfbdc93f
+ (this address points directly at the storage backend. Donations will be used
+ for paying storage contracts with Sia hosts)
+ * PayPal:
+ Donate with PayPal
+
+## Do I need to register an account?
+
+Not if you don't want to. You're free to use pixeldrain completely anonymously.
+Without a pixeldrain account you can upload files, download files and create
+lists of files. And view your uploaded files on the [history page](/history).
+This page only shows files which were uploaded anonymously in this web browser.
+
+By registering an account on pixeldrain you will be able to access your files
+from any device with a web browser. Files you upload and lists you create will
+be linked to your pixeldrain account and will show up on your [personal home
+page](/user).
+
+## What cookies does pixeldrain use?
+
+When logging in to a pixeldrain account a cookie named 'pd_auth_key' will be
+installed. This cookie keeps your login session active. When you delete it you
+will be logged out of your account.
+
+When you use the style selector on the [Appearance](/appearance) page a cookie
+called 'style' will be set. This cookie controls the appearance of the website
+for you.
+
+When uploading a file pixeldrain will save a list of file links on your
+browser's local storage. This data is **only** used for viewing your upload
+history on the [history page](/history).
+
+## Legality
+
+I cannot be held liable for any illegal and / or copyrighted material that's
+uploaded by the users of this application. Files uploaded to this website are
+subjected to local laws. If laws are being broken, and I've been notified of the
+fact I'll have to delete the offending content. If you find any files on this
+domain that break the law, please contact me at
+[abuse@pixeldrain.com](mailto:abuse@pixeldrain.com), and I'll take care of it.
+
+Please share responsibly.
+
+For other questions you can reach me at
+[support@pixeldrain.com](mailto:support@pixeldrain.com)
diff --git a/res/include/md/apidoc.md b/res/include/md/apidoc.md
new file mode 100644
index 0000000..fdc78d7
--- /dev/null
+++ b/res/include/md/apidoc.md
@@ -0,0 +1,644 @@
+# Pixeldrain API documentation
+
+The methods for uploading and retrieving files don't require an API key. The
+methods for creating and retrieving lists also don't require an API key. All
+methods which delete or modify a resource **do** require an API key.
+
+API keys can be obtained from the login API.
+
+Some JSON responses include fields which end in "_href" (some people don't know
+this, but "href" stands for "Hypertext Reference", the more you know). These
+point to different places in the API, which you can retrieve with a GET request.
+The path is to be appended to the API URL, so "/file/someid/thumbnail" becomes
+"{{apiUrl}}/file/someid/thumbnail".
+
+The base URL for the API is "{{apiUrl}}", all paths below are relative to that
+URL.
+
+## Form value order
+
+I recommend you put files at the end of every file upload form. By doing this
+the pixeldrain server can respond to malformed requests before the file upload
+finishes and this may save you a lot of time and bandwidth when uploading large
+files. Make sure your HTTP client has support for premature responses,
+pixeldrain uses them a lot. If the server responds before your request is
+finished it will always indicate an error and you may abort the connection.
+
+## File Methods
+
+POST/file
+GET/file/{id}
+GET/file/{id}/info
+POST/list
+GET/list/{id}
+
- Files will be removed if they have not been viewed for 30 days. - A view is counted when someone visits the file's download page - (pixeldrain.com/u/somefile) or views the file through a list the - file is included in (pixeldrain.com/l/somelist). -
-- If you upload a file while logged into your pixeldrain account - you will be able to delete the file yourself from the download - page of the file. If you are not logged in and you accidentally - upload something you shouldn't have, just don't share the link. - The file will expire eventually. File links are not indexed or - published anywhere. As long as you don't share it nobody will - see it. -
- -- No, pixeldrain is completely free at the moment. While there is - an advertisement on the file downloading page, it doesn't - generate nearly enough revenue to pay for maintaining this - service. That's why I'd really appreciate it if you could spare - some coins. Possible methods for donating are: -
-- Not if you don't want to. You're free to use pixeldrain - completely anonymously. Without a pixeldrain account you can - upload files, download files and create lists of files. And view - your uploaded files on the history page. - This page only shows files which were uploaded anonymously in - this web browser. -
-- By registering an account on pixeldrain you will be able to - access your files from any device with a web browser. Files you - upload and lists you create will be linked to your pixeldrain - account and will show up on your personal home - page. -
- -- When logging in to a pixeldrain account a cookie named - 'pd_auth_key' will be installed. This cookie keeps your login - session active. When you delete it you will be logged out of - your account. -
-- When you use the style selector on the Appearance page a cookie called 'style' - will be set. This cookie controls the appearance of the website - for you. -
-- When uploading a file pixeldrain will save a list of file links - on your browser's local storage. This data is - only used for viewing your upload history on the history page. -
- -
- I cannot be held liable for any illegal and / or copyrighted
- material that's uploaded by the users of this application. Files
- uploaded to this website are subjected to local laws. If laws
- are being broken, and I've been notified of the fact I'll have
- to delete the offending content. If you find any files on this
- domain that break the law, please contact me at
- abuse@pixeldrain.com,
- and I'll take care of it.
-
Please share responsibly.
-
- For other questions you can reach me at - support@pixeldrain.com -
-
- Welcome to the pixeldrain API documentation.
-
- The methods for uploading and retrieving files don't require an
- API key. The methods for creating and retrieving lists also
- don't require an API key. All methods which delete or modify a
- resource do require an API key.
-
- API keys can be obtained from the login API.
-
- Some JSON responses include fields which end in "_href" (some - people don't know this, but "href" stands for "Hypertext - Reference", the more you know). These point to different places - in the API, which you can retrieve with a GET request. The path - is to be appended to the API URL, so "/file/someid/thumbnail" - becomes "{{apiUrl}}/file/someid/thumbnail". -
-- The base URL for the API is "{{apiUrl}}", all paths below are - relative to that URL. -
- -- I recommend you put files at the end of every file upload form. - By doing this the pixeldrain server can respond to malformed - requests before the file upload finishes and this may save you a - lot of time and bandwidth when uploading large files. Make sure - your HTTP client has support for premature responses, pixeldrain - uses them a lot. If the server responds before your request is - finished it will always indicate an error and you may abort the - connection. -
- -- Upload a file. -
- -Param | -Type | -Required | -Maximum Size | -Default | -Description | -
name | -string | -false | -255 Characters | -Multipart file name | -Name of the file to upload | -
anonymous | -boolean | -false | -N/A | -false | -If the file should be uploaded anonymously | -
file | -multipart file | -true | -10 000 000 000 Bytes | -none | -Multipart file to upload | -
HTTP 200: OK -{ - "success": true, - "id": "abc123" // ID of the newly uploaded file -}-
HTTP 422: Unprocessable Entity -{ - "success": false, - "value": "no_file", - "message": "The file does not exist or is empty." -}-
HTTP 500: Internal Server Error -{ - "success": false, - "value": "internal", - "message": "An internal server error occurred." -}-
HTTP 413: Payload Too Large -{ - "success": false, - "value": "file_too_large", - "message": "The file you tried to upload is too large" -}-
HTTP 500: Internal Server Error -{ - "success": false, - "value": "writing", - "message": "Something went wrong while writing the file to disk, the server may be out of storage space." -}-
HTTP 413: Payload Too Large -{ - "success": false, - "value": "name_too_long", - "message": "File Name is too long, Max 255 characters allowed." -}-
- Returns the full file associated with the ID. Supports - byte range requests. -
-- When '?download' is added to the URL the server will send an - attachment header instead of inline rendering, which causes the - browser to show a 'Save File' dialog. -
-- Warning: If a file is using too much bandwidth it can be rate - limited. The rate limit will be enabled if a file has ten times more - downloads than views. The owner of a file can always download it. - When a file is rate limited the user will need to fill out a captcha - in order to continue downloading the file. The captcha will only - appear on the file viewer page (pixeldrain.com/u/{id}). Rate - limiting has been added to prevent the spread of viruses and to stop - direct linking. -
-- Pixeldrain also includes a virus scanner. If a virus has been - detected in a file the user will also have to fill in a captcha to - download it. -
-Param | -Required | -Location | -Description | -
id | -true | -URL | -ID of the file to request | -
download | -false | -URL | -Sends file attachment instead of inline | -
HTTP 200: OK -The requested file. -- -
HTTP 404: Not Found -{ - "success": false, - "value": "not_found", - "message": "The entity you requested could not be found" -} --
HTTP 403: Forbidden -{ - "success": false, - "value": "file_rate_limited_captcha_required", - "message": "This file is using too much bandwidth. For anonymous downloads a captcha is required now. The captcha entry is available on the download page" -} --
HTTP 403: Forbidden -{ - "success": false, - "value": "virus_detected_captcha_required", - "message": "This file has been marked as malware by our scanning systems. To avoid infecting other systems through automated downloads we require you to enter a captcha. The captcha entry is available on the download page" -} --
- Returns information about one or more files. - You can also put a comma separated list of file IDs in - the URL and it will return an array of file info, - instead of a single object. -
-Param | -Required | -Location | -Description | -
id | -true | -URL | -ID(s) of the file | -
HTTP 200: OK -{ - "success": true, - "id": "1234abcd", - "name": "screenshot.png", - "date_upload": 2020-02-04T18:34:05.706801Z, - "date_last_view": 2020-02-04T18:34:05.706801Z, - "size": 5694837, // Bytes - "views" 1234, // Amount of unique file views - "bandwidth_used": 1234567890, // Bytes - "mime_type" "image/png", - "thumbnail_href": "/file/1234abcd/thumbnail" // Link to a thumbnail of this file -}-
HTTP 404: Not Found -{ - "success": false, - "value": "file_not_found" -}-
- Returns a PNG thumbnail image representing the file. The thumbnail - image will be 128x128 px by default. You can specify the width and - height with parameters in the URL. The width and height parameters - need to be a multiple of 16. So the allowed values are 16, 32, 48, - 64, 80, 96, 112 and 128. If a thumbnail cannot be generated for the - file you will be redirected to a mime type image of 128x128 px. -
-Param | -Required | -Location | -Description | -
id | -true | -URL | -ID of the file to get a thumbnail for | -
width | -false | -URL | -Width of the thumbnail image | -
height | -false | -URL | -Height of the thumbnail image | -
- A PNG image if a thumbnail can be generated. If a thumbnail cannot - be generated you will get a 301 redirect to an image representing - the type of the file. -
-- Deletes a file. Only works when the users owns the file. -
-Param | -Required | -Location | -Description | -
id | -true | -URL | -ID of the file to delete | -
HTTP 200: OK -{ - "success": true, - "value": "file_deleted", - "message": "The file has been deleted." -}-
HTTP 404: Not Found -{ - "success": false, - "value": "file_not_found", - "message": "File ID was not found in the database." -}-
HTTP 401: Unauthorized -{ - "success": false, - "value": "unauthorized", - "message": "You are not logged in." -}-
HTTP 403: Forbidden -{ - "success": false, - "value": "forbidden", - "message": "This is not your file." -}-
- Creates a new directory or uploads a file to an existing directory. -
- -- The form parameters must be sent in the order displayed below - for the realtime error checking to work. If 'name' comes after - 'file' it will be ignored. -
-Param | -Location | -Description | -
type | -Form Values | -The type of node to create, can either be 'directory', or 'file' | -
name | -Form Values | -- Name of the directory to create, or of file to create. Not - required if 'type' is 'file' - | -
file | -Form Values | -- Multipart file to upload to the directory. Will be ignored - if 'type' is 'directory' - | -
HTTP 200: OK -{ - "success": true, - "id": "abc123" // ID of the newly uploaded file -}- todo -
- Returns information about the requested path. -
-Param | -Required | -Location | -Description | -
path | -true | -URL | -Path to the directory or file to request | -
download | -false | -URL | -- If the URL paramater '?download' is passed the requested - file will be downloaded (if it is a file) - | -
HTTP 200: OK -{ - "success": true, - "name": "some dir", - "path": "/some dir", - "type": "directory", - "child_directories": [ - { - "name": "some other directory", - "type": "directory", - "path": "/some dir/some other directory" - } - ], - "child_files": [ - { - "name": "11. Lenny Kravitz - Fly away.ogg", - "type": "file", - "path": "/some dir/11. Lenny Kravitz - Fly away.ogg" - } - ] -}-
HTTP 200: OK -{ - "success": true, - "name": "11. Lenny Kravitz - Fly away.ogg", - "path": "/some dir/11. Lenny Kravitz - Fly away.ogg", - "type": "file", - "file_info": { - "success": true, - "id": "Jf_u5TI9", - "name": "11. Lenny Kravitz - Fly away.ogg", - "date_upload": "2018-07-04T22:24:48Z", - "date_last_view": "2018-07-04T22:24:48Z", - "size": 9757269, - "views": 0, - "mime_type": "application/ogg", - "thumbnail_href": "/file/Jf_u5TI9/thumbnail" - } -}-
- Deletes a filesystem node. -
-Param | -Required | -Location | -Description | -
path | -true | -URL | -Path of the entity to delete | -
HTTP 200: OK -{ - "success": true -}-
- Creates a list of files that can be viewed together on the file - viewer page. -
-- POST body should be a JSON object, example below. A list can contain - maximally 10000 files. If you try to add more the request will fail. -
--{ - "title": "My beautiful photos", // Defaults to "Pixeldrain List" - "anonymous": false / true, // If true this list will not be linked to your user account. Defaults to "false" - "files": [ // Ordered array of files to add to the list - { - "id": "abc123", - "description": "First photo of the week, such a beautiful valley" - }, - { - "id": "123abc", - "description": "The week went by so quickly, here's a photo from the plane back" - } - ] -} --
HTTP 200: OK -{ - "success": true, - "id": "yay137" // ID of the newly created list -} --
HTTP 422: Unprocessable Entity -{ - "success": false, - "value": "list_file_not_found", - "message": "File Oh42No was not found in the database.", - "extra": { - "file_not_found": "0h42No" // The file you tried to add with this ID does not exist - } -} --
HTTP 413: Payload too large -{ - "success": false, - "value": "too_many_files", - "message": "This list contains too many files, max 10000 allowed." -} --
HTTP 422: Unprocessable Entity -{ - "success": false, - "value": "json_parse_failed", - "message": "The JSON object in the request body could not be read." -} --
HTTP 413: Payload too large -{ - "success": false, - "value": "title_too_long", - "message": "The title of this list is too long, max 300 characters allowed." -} --
HTTP 413: Payload too large -{ - "success": false, - "value": "description_too_long", - "message": "The description of one of the files in the list is too long, max 3000 characters allowed." -} --
HTTP 422: Unprocessable Entity -{ - "success": false, - "value": "cannot_create_empty_list", - "message": "You cannot make a list with no files." -} --
- Returns information about a file list and the files in it. -
-Param | -Required | -Location | -Description | -
id | -true | -URL | -ID of the list | -
- The API will return some basic information about every file. - Every file also has a "detail_href" field which contains a URL - to the info API of the file. Follow that link to get more - information about the file like size, checksum, mime type, etc. - The address is relative to the API URL and should be appended to - the end. -
-HTTP 200: OK -{ - "success": true, - "id": "L8bhwx", - "title": "Rust in Peace", - "date_created": 2020-02-04T18:34:13.466276Z, - "files": [ - // These structures are the same as the file info response, except for the detail_href and description fields - { - "detail_href": "/file/_SqVWi/info", - "description": "", - "success": true, - "id": "_SqVWi", - "name": "01 Holy Wars... The Punishment Due.mp3", - "size": 123456, - "date_created": 2020-02-04T18:34:13.466276Z, - "date_last_view": 2020-02-04T18:34:13.466276Z, - "mime_type": "audio/mp3", - "views": 1, - "bandwidth_used": 1234567890, - "thumbnail_href": "/file/_SqVWi/thumbnail" - }, - { - "detail_href": "/file/RKwgZb/info", - "description": "", - "success": true, - "id": "RKwgZb", - "name": "02 Hangar 18.mp3", - "size": 123456, - "date_created": 2020-02-04T18:34:13.466276Z, - "date_last_view": 2020-02-04T18:34:13.466276Z, - "mime_type": "audio/mp3", - "views": 2, - "bandwidth_used": 1234567890, - "thumbnail_href": "/file/RKwgZb/thumbnail" - }, - { - "detail_href": "/file/DRaL_e/info", - "description": "", - "success": true, - "id": "DRaL_e", - "name": "03 Take No Prisoners.mp3", - "size": 123456, - "date_created": 2020-02-04T18:34:13.466276Z, - "date_last_view": 2020-02-04T18:34:13.466276Z, - "mime_type": "audio/mp3", - "views": 3, - "bandwidth_used": 1234567890, - "thumbnail_href": "/file/DRaL_e/thumbnail" - } - ] -} --
HTTP 404: Not Found -{ - "success": false, - "value": "list_not_found", -} --