support markdown pages
This commit is contained in:
79
res/include/md/about.md
Normal file
79
res/include/md/about.md
Normal file
@@ -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:
|
||||
|
||||
* <a href="https://www.patreon.com/join/pixeldrain" target="_blank">
|
||||
{{template `patreon.svg` .}} Support me on Patreon and get some perks too!
|
||||
</a>
|
||||
* 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: <a
|
||||
class="button button_highlight" href="https://brave.com/pix009"
|
||||
target="_blank">Install Brave</a>. 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: <a class="button button_highlight"
|
||||
href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WU49A5NHPAZ9G&source=url">
|
||||
Donate with PayPal</a>
|
||||
|
||||
## 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)
|
644
res/include/md/apidoc.md
Normal file
644
res/include/md/apidoc.md
Normal file
@@ -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
|
||||
|
||||
<details class="request_post">
|
||||
<summary><span class="method">POST</span>/file</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Upload a file.
|
||||
|
||||
### Parameters
|
||||
|
||||
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 | File is not linked to user if true
|
||||
file | multipart file | true | 1000^3 bytes | none | File to upload
|
||||
|
||||
### Returns
|
||||
|
||||
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."
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
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.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Required | Location | Description
|
||||
---------|----------|----------|------------------------------------------
|
||||
id | true | URL | ID of the file to request
|
||||
download | false | URL | Sends attachment header instead of inline
|
||||
|
||||
### Returns
|
||||
|
||||
```
|
||||
HTTP 200: OK
|
||||
|
||||
Requested file data
|
||||
```
|
||||
|
||||
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"
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}/info</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
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.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Required | Location | Description
|
||||
------|----------|----------|---------------
|
||||
id | true | URL | ID of the file
|
||||
|
||||
### Returns
|
||||
|
||||
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"
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<!--
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}/thumbnail?width=x&height=x</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
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.
|
||||
|
||||
### Parameters
|
||||
|
||||
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
|
||||
|
||||
### Returns
|
||||
|
||||
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.
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_delete">
|
||||
<summary><span class="method">DELETE</span>/file/{id}</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Deletes a file. Only works when the users owns the file.
|
||||
|
||||
### Parameters
|
||||
|
||||
Param | Required | Location | Description
|
||||
------|----------|----------|-------------------------
|
||||
id | true | URL | ID of the file to delete
|
||||
|
||||
### Returns
|
||||
|
||||
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."
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
-->
|
||||
|
||||
## List Methods
|
||||
|
||||
<details class="api_doc_details request_post">
|
||||
<summary><span class="method">POST</span>/list</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Creates a list of files that can be viewed together on the file viewer page.
|
||||
|
||||
### Parameters
|
||||
|
||||
POST body should be a JSON object, example below. A list can contain at most
|
||||
10000 files. If you try to add more the request will fail.
|
||||
|
||||
#### Example
|
||||
```
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Returns
|
||||
|
||||
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."
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/list/{id}</summary>
|
||||
<div>
|
||||
|
||||
### Description
|
||||
|
||||
Returns information about a file list and the files in it.
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Param | Required | Location | Description
|
||||
------|----------|----------|---------------
|
||||
id | true | URL | ID of the list
|
||||
|
||||
### Returns
|
||||
|
||||
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",
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<!-- ## Filesystem Methods
|
||||
<details class="api_doc_details request_post">
|
||||
<summary><span class="method">POST</span>/filesystem/{path}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Creates a new directory or uploads a file to an existing directory.
|
||||
</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<p>
|
||||
The form parameters <b>must</b> be sent in the order displayed below
|
||||
for the realtime error checking to work. If 'name' comes after
|
||||
'file' it will be ignored.
|
||||
</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>type</td>
|
||||
<td>Form Values</td>
|
||||
<td>The type of node to create, can either be 'directory', or 'file'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>name</td>
|
||||
<td>Form Values</td>
|
||||
<td>
|
||||
Name of the directory to create, or of file to create. Not
|
||||
required if 'type' is 'file'
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>file</td>
|
||||
<td>Form Values</td>
|
||||
<td>
|
||||
Multipart file to upload to the directory. Will be ignored
|
||||
if 'type' is 'directory'
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Returns</h3>
|
||||
<pre>HTTP 200: OK
|
||||
{
|
||||
"success": true,
|
||||
"id": "abc123" // ID of the newly uploaded file
|
||||
}</pre>
|
||||
todo
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/filesystem/{path}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Returns information about the requested path.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Required</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>path</td>
|
||||
<td>true</td>
|
||||
<td>URL</td>
|
||||
<td>Path to the directory or file to request</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>download</td>
|
||||
<td>false</td>
|
||||
<td>URL</td>
|
||||
<td>
|
||||
If the URL paramater '?download' is passed the requested
|
||||
file will be downloaded (if it is a file)
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>Returns</h3>
|
||||
<h4>When the requested entity is a directory:</h4>
|
||||
<pre>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"
|
||||
}
|
||||
]
|
||||
}</pre>
|
||||
<h4>When the requested entity is a file:</h4>
|
||||
<pre>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"
|
||||
}
|
||||
}</pre>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="api_doc_details request_delete">
|
||||
<summary><span class="method">DELETE</span>/filesystem/{path}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Deletes a filesystem node.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Required</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>path</td>
|
||||
<td>true</td>
|
||||
<td>URL</td>
|
||||
<td>Path of the entity to delete</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>Returns</h3>
|
||||
<pre>HTTP 200: OK
|
||||
{
|
||||
"success": true
|
||||
}</pre>
|
||||
</div>
|
||||
</details> -->
|
25
res/include/md/donation.md
Normal file
25
res/include/md/donation.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Thank you for supporting pixeldrain!
|
||||
|
||||
{{$success := .URLQuery.Get "success"}}
|
||||
{{if eq $success "true"}}
|
||||
{{if .Authenticated}}
|
||||
Dear {{.User.Username}},
|
||||
|
||||
Thank you for your donation. I really appreciate it!
|
||||
|
||||
Sincerely, Fornax.
|
||||
{{else}}
|
||||
Thank you for your donation! You are amazing.
|
||||
|
||||
Sincerely, Fornax.
|
||||
{{end}}
|
||||
{{else}}
|
||||
It seems you have canceled your donation. I don't blame you, money is expensive :)
|
||||
|
||||
If this was not your intention, you're welcome to try again by clicking this button:
|
||||
<a class="button" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WU49A5NHPAZ9G&source=url">
|
||||
Donate with PayPal
|
||||
</a>
|
||||
|
||||
Sincerely, Fornax.
|
||||
{{end}}
|
@@ -305,7 +305,7 @@ a:hover {text-decoration: underline;}
|
||||
}
|
||||
table:not(.form) {border-collapse: collapse; width: 100%;}
|
||||
tr:not(.form) {border-bottom: 1px var(--layer_2_color_border) solid;}
|
||||
tr > td {padding: 0.3em;}
|
||||
tr > td, tr > th {padding: 0.3em;}
|
||||
@media(max-width: 30em) {
|
||||
/* Forms will be stacked on small screens */
|
||||
tr.form > td {
|
||||
@@ -319,7 +319,7 @@ tr > td {padding: 0.3em;}
|
||||
pre{
|
||||
padding: 2px;
|
||||
border-bottom: 1px var(--layer_2_color_border) solid;
|
||||
overflow-x: scroll;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.big_button{
|
||||
@@ -371,6 +371,31 @@ pre{
|
||||
color: var(--highlight_color);
|
||||
}
|
||||
|
||||
/* API documentation markup */
|
||||
|
||||
details {
|
||||
border-top: 1px solid;
|
||||
border-bottom: 1px solid;
|
||||
margin: 15px 0 15px 0;
|
||||
}
|
||||
details > summary {
|
||||
padding: 2px;
|
||||
font-family: monospace;
|
||||
}
|
||||
details > summary > .method {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
}
|
||||
details > div {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
details.request_get { border-color: #3636ff; background-color: rgba(32, 32, 255, 0.2); }
|
||||
details.request_post { border-color: #00d000; background-color: rgba(0, 255, 0, 0.05); }
|
||||
details.request_delete { border-color: #B00000; background-color: rgba(255, 0, 0, 0.05); }
|
||||
details.request_put { border-color: #B06000; background-color: rgba(255, 128, 0, 0.05); }
|
||||
details.request_patch { border-color: #6000B0; background-color: rgba(128, 0, 255, 0.1); }
|
||||
|
||||
/* Form fields */
|
||||
|
||||
.form_input {width: 100%;}
|
||||
|
@@ -1,128 +0,0 @@
|
||||
{{define "about"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "About"}}
|
||||
{{template "user_style" .}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<h1>About pixeldrain</h1>
|
||||
<div class="page_content"><div class="limit_width">
|
||||
<h2>Questions and Answers</h2>
|
||||
|
||||
<h3>For how long will my files be stored?</h3>
|
||||
<p>
|
||||
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).
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<h3>Does pixeldrain cost any money?</h3>
|
||||
<p>
|
||||
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:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://www.patreon.com/join/pixeldrain" target="_blank">
|
||||
{{template `patreon.svg` .}} Support me on Patreon and get some perks too!
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
Bitcoin:
|
||||
<a href="bitcoin:1Ne7hGuvnfz9EFTRD3PLWVeaJTX9oA1QUr?label=Pixeldrain%20Donation">1Ne7hGuvnfz9EFTRD3PLWVeaJTX9oA1QUr</a>
|
||||
</li>
|
||||
<li>
|
||||
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:
|
||||
<a class="button button_highlight" href="https://brave.com/pix009" target="_blank">Install Brave</a>.
|
||||
Installing and using Brave with this referral link also
|
||||
counts as a 5$ donation.
|
||||
</li>
|
||||
<li>
|
||||
Siacoin:
|
||||
26117c19ca3975b315d663dcbbc19cf9c07274f441689d4392ed380b2337589ef1aacfbdc93f
|
||||
(this address points directly at the storage backend.
|
||||
Donations will be used for paying storage contracts with Sia
|
||||
hosts)
|
||||
</li>
|
||||
<li>
|
||||
PayPal:
|
||||
<a class="button button_highlight" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WU49A5NHPAZ9G&source=url">Donate with PayPal</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Do I need to register an account?</h3>
|
||||
<p>
|
||||
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 <a href="/history">history page</a>.
|
||||
This page only shows files which were uploaded anonymously in
|
||||
this web browser.
|
||||
</p>
|
||||
<p>
|
||||
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 <a href="/user">personal home
|
||||
page</a>.
|
||||
</p>
|
||||
|
||||
<h3>What cookies does pixeldrain use?</h3>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
When you use the style selector on the <a
|
||||
href="/appearance">Appearance</a> page a cookie called 'style'
|
||||
will be set. This cookie controls the appearance of the website
|
||||
for you.
|
||||
</p>
|
||||
<p>
|
||||
When uploading a file pixeldrain will save a list of file links
|
||||
on your browser's local storage. This data is
|
||||
<b>only</b> used for viewing your upload history on the <a
|
||||
href="/history">history page</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="legality">Legality</h3>
|
||||
<p>
|
||||
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
|
||||
<a href="mailto:abuse@pixeldrain.com">abuse@pixeldrain.com</a>,
|
||||
and I'll take care of it.
|
||||
<br/>Please share responsibly.
|
||||
</p>
|
||||
<p>
|
||||
For other questions you can reach me at
|
||||
<a href="mailto:support@pixeldrain.com">support@pixeldrain.com</a>
|
||||
</p>
|
||||
</div></div>
|
||||
{{template "page_bottom" .}}
|
||||
{{template "analytics"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
@@ -1,92 +0,0 @@
|
||||
{{define "apidoc"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "API Documentation"}}
|
||||
{{template "user_style" .}}
|
||||
<style>
|
||||
.api_doc_details{
|
||||
border-top: 1px solid;
|
||||
border-bottom: 1px solid;
|
||||
margin: 15px 0 15px 0;
|
||||
}
|
||||
.api_doc_details > summary {
|
||||
padding: 2px;
|
||||
font-family: monospace;
|
||||
}
|
||||
.api_doc_details > summary > .method {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
}
|
||||
.api_doc_details > div {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.api_doc_details.request_get{ border-color: #3636ff; background-color: rgba(32, 32, 255, 0.2);} /* GET requests */
|
||||
.api_doc_details.request_post{ border-color: #00d000; background-color: rgba(0, 255, 0, 0.05);} /* POST requests */
|
||||
.api_doc_details.request_delete{border-color: #B00000; background-color: rgba(255, 0, 0, 0.05);} /* DELETE requests */
|
||||
.api_doc_details.request_put{ border-color: #B06000; background-color: rgba(255, 128, 0, 0.05);} /* PUT requests */
|
||||
.api_doc_details.request_patch{ border-color: #6000B0; background-color: rgba(128, 0, 255, 0.1);} /* PATCH requests */
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<h1>Pixeldrain API documentation</h1>
|
||||
|
||||
<div class="page_content"><div class="limit_width">
|
||||
<p>
|
||||
Welcome to the pixeldrain API documentation.
|
||||
<br/>
|
||||
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 <strong>do</strong> require an API key.
|
||||
<br/>
|
||||
API keys can be obtained from the login API.
|
||||
</p>
|
||||
<p>
|
||||
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".
|
||||
</p>
|
||||
<p>
|
||||
The base URL for the API is "{{apiUrl}}", all paths below are
|
||||
relative to that URL.
|
||||
</p>
|
||||
|
||||
<h2>Form value order</h2>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<h2>File Methods</h2>
|
||||
{{template "api-file-post"}}
|
||||
{{template "api-file-id-get"}}
|
||||
{{template "api-file-id-info-get"}}
|
||||
{{template "api-file-id-thumbnail-get"}}
|
||||
{{/*template "api-file-id-delete"*/}}
|
||||
|
||||
<h2>List Methods</h2>
|
||||
{{template "api-list-post"}}
|
||||
{{template "api-list-get"}}
|
||||
|
||||
<!--<h2>Filesystem Methods</h2>-->
|
||||
{{/*template "api-filesystem-path-post"*/}}
|
||||
{{/*template "api-filesystem-path-get"*/}}
|
||||
{{/*template "api-filesystem-path-delete"*/}}
|
||||
</div></div>
|
||||
{{template "page_bottom" .}}
|
||||
{{template "analytics"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
@@ -1,41 +0,0 @@
|
||||
{{define "donation"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" "Thank you for supporting pixeldrain!"}}
|
||||
{{template "user_style" .}}
|
||||
</head>
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<div class="page_content"><div class="limit_width">
|
||||
<br/>
|
||||
{{$success := .URLQuery.Get "success"}}
|
||||
{{if eq $success "true"}}
|
||||
{{if .Authenticated}}
|
||||
Dear {{.User.Username}},
|
||||
<br/><br/>
|
||||
Thank you for your donation. I really appreciate it!
|
||||
<br/><br/>
|
||||
Sincerely,<br/>
|
||||
Fornax
|
||||
{{else}}
|
||||
Thank you for your donation! You are amazing.
|
||||
<br/><br/>
|
||||
Sincerely,<br/>
|
||||
Fornax
|
||||
{{end}}
|
||||
{{else}}
|
||||
It seems you have canceled your donation. I don't blame you, money is expensive :)
|
||||
<br/><br/>
|
||||
If this was not your intention, you're welcome to try again by clicking this button:
|
||||
<a class="button" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WU49A5NHPAZ9G&source=url">Donate with PayPal</a>
|
||||
<br/><br/>
|
||||
Sincerely,<br/>
|
||||
Fornax
|
||||
{{end}}
|
||||
</div></div>
|
||||
{{template "page_bottom" .}}
|
||||
{{template "analytics"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
@@ -1,311 +0,0 @@
|
||||
{{define "api-file-post"}}
|
||||
<details class="api_doc_details request_post">
|
||||
<summary><span class="method">POST</span>/file</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Upload a file.
|
||||
</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Type</td>
|
||||
<td>Required</td>
|
||||
<td>Maximum Size</td>
|
||||
<td>Default</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>name</td>
|
||||
<td>string</td>
|
||||
<td>false</td>
|
||||
<td>255 Characters</td>
|
||||
<td>Multipart file name</td>
|
||||
<td>Name of the file to upload</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>anonymous</td>
|
||||
<td>boolean</td>
|
||||
<td>false</td>
|
||||
<td>N/A</td>
|
||||
<td>false</td>
|
||||
<td>If the file should be uploaded anonymously</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>file</td>
|
||||
<td>multipart file</td>
|
||||
<td>true</td>
|
||||
<td>10 000 000 000 Bytes</td>
|
||||
<td>none</td>
|
||||
<td>Multipart file to upload</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Returns</h3>
|
||||
<pre>HTTP 200: OK
|
||||
{
|
||||
"success": true,
|
||||
"id": "abc123" // ID of the newly uploaded file
|
||||
}</pre>
|
||||
<pre>HTTP 422: Unprocessable Entity
|
||||
{
|
||||
"success": false,
|
||||
"value": "no_file",
|
||||
"message": "The file does not exist or is empty."
|
||||
}</pre>
|
||||
<pre>HTTP 500: Internal Server Error
|
||||
{
|
||||
"success": false,
|
||||
"value": "internal",
|
||||
"message": "An internal server error occurred."
|
||||
}</pre>
|
||||
<pre>HTTP 413: Payload Too Large
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_too_large",
|
||||
"message": "The file you tried to upload is too large"
|
||||
}</pre>
|
||||
<pre>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."
|
||||
}</pre>
|
||||
<pre>HTTP 413: Payload Too Large
|
||||
{
|
||||
"success": false,
|
||||
"value": "name_too_long",
|
||||
"message": "File Name is too long, Max 255 characters allowed."
|
||||
}</pre>
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
||||
{{define "api-file-id-get"}}
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Returns the full file associated with the ID. Supports
|
||||
byte range requests.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Required</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>id</td>
|
||||
<td>true</td>
|
||||
<td>URL</td>
|
||||
<td>ID of the file to request</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>download</td>
|
||||
<td>false</td>
|
||||
<td>URL</td>
|
||||
<td>Sends file attachment instead of inline</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>Returns</h3>
|
||||
<pre>HTTP 200: OK
|
||||
The requested file.
|
||||
</pre>
|
||||
|
||||
<pre>HTTP 404: Not Found
|
||||
{
|
||||
"success": false,
|
||||
"value": "not_found",
|
||||
"message": "The entity you requested could not be found"
|
||||
}
|
||||
</pre>
|
||||
<pre>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"
|
||||
}
|
||||
</pre>
|
||||
<pre>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"
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
||||
{{define "api-file-id-info-get"}}
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}/info</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Required</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>id</td>
|
||||
<td>true</td>
|
||||
<td>URL</td>
|
||||
<td>ID(s) of the file</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>Returns</h3>
|
||||
<pre>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
|
||||
}</pre>
|
||||
<pre>HTTP 404: Not Found
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_not_found"
|
||||
}</pre>
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
||||
{{define "api-file-id-thumbnail-get"}}
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/file/{id}/thumbnail?width=x&height=x</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Required</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>id</td>
|
||||
<td>true</td>
|
||||
<td>URL</td>
|
||||
<td>ID of the file to get a thumbnail for</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>width</td>
|
||||
<td>false</td>
|
||||
<td>URL</td>
|
||||
<td>Width of the thumbnail image</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>height</td>
|
||||
<td>false</td>
|
||||
<td>URL</td>
|
||||
<td>Height of the thumbnail image</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>Returns</h3>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
||||
{{define "api-file-id-delete"}}
|
||||
<details class="api_doc_details request_delete">
|
||||
<summary><span class="method">DELETE</span>/file/{id}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Deletes a file. Only works when the users owns the file.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Required</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>id</td>
|
||||
<td>true</td>
|
||||
<td>URL</td>
|
||||
<td>ID of the file to delete</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>Returns</h3>
|
||||
<pre>HTTP 200: OK
|
||||
{
|
||||
"success": true,
|
||||
"value": "file_deleted",
|
||||
"message": "The file has been deleted."
|
||||
}</pre>
|
||||
<pre>HTTP 404: Not Found
|
||||
{
|
||||
"success": false,
|
||||
"value": "file_not_found",
|
||||
"message": "File ID was not found in the database."
|
||||
}</pre>
|
||||
<pre>HTTP 401: Unauthorized
|
||||
{
|
||||
"success": false,
|
||||
"value": "unauthorized",
|
||||
"message": "You are not logged in."
|
||||
}</pre>
|
||||
<pre>HTTP 403: Forbidden
|
||||
{
|
||||
"success": false,
|
||||
"value": "forbidden",
|
||||
"message": "This is not your file."
|
||||
}</pre>
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
@@ -1,162 +0,0 @@
|
||||
{{define "api-filesystem-path-post"}}
|
||||
<details class="api_doc_details request_post">
|
||||
<summary><span class="method">POST</span>/filesystem/{path}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Creates a new directory or uploads a file to an existing directory.
|
||||
</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<p>
|
||||
The form parameters <b>must</b> be sent in the order displayed below
|
||||
for the realtime error checking to work. If 'name' comes after
|
||||
'file' it will be ignored.
|
||||
</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>type</td>
|
||||
<td>Form Values</td>
|
||||
<td>The type of node to create, can either be 'directory', or 'file'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>name</td>
|
||||
<td>Form Values</td>
|
||||
<td>
|
||||
Name of the directory to create, or of file to create. Not
|
||||
required if 'type' is 'file'
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>file</td>
|
||||
<td>Form Values</td>
|
||||
<td>
|
||||
Multipart file to upload to the directory. Will be ignored
|
||||
if 'type' is 'directory'
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Returns</h3>
|
||||
<pre>HTTP 200: OK
|
||||
{
|
||||
"success": true,
|
||||
"id": "abc123" // ID of the newly uploaded file
|
||||
}</pre>
|
||||
todo
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
||||
{{define "api-filesystem-path-get"}}
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/filesystem/{path}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Returns information about the requested path.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Required</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>path</td>
|
||||
<td>true</td>
|
||||
<td>URL</td>
|
||||
<td>Path to the directory or file to request</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>download</td>
|
||||
<td>false</td>
|
||||
<td>URL</td>
|
||||
<td>
|
||||
If the URL paramater '?download' is passed the requested
|
||||
file will be downloaded (if it is a file)
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>Returns</h3>
|
||||
<h4>When the requested entity is a directory:</h4>
|
||||
<pre>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"
|
||||
}
|
||||
]
|
||||
}</pre>
|
||||
<h4>When the requested entity is a file:</h4>
|
||||
<pre>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"
|
||||
}
|
||||
}</pre>
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
||||
{{define "api-filesystem-path-delete"}}
|
||||
<details class="api_doc_details request_delete">
|
||||
<summary><span class="method">DELETE</span>/filesystem/{path}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Deletes a filesystem node.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Required</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>path</td>
|
||||
<td>true</td>
|
||||
<td>URL</td>
|
||||
<td>Path of the entity to delete</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>Returns</h3>
|
||||
<pre>HTTP 200: OK
|
||||
{
|
||||
"success": true
|
||||
}</pre>
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
@@ -1,180 +0,0 @@
|
||||
{{define "api-list-post"}}
|
||||
<details class="api_doc_details request_post">
|
||||
<summary><span class="method">POST</span>/list</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Creates a list of files that can be viewed together on the file
|
||||
viewer page.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<h4>Example</h4>
|
||||
<pre>
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
</pre>
|
||||
<h3>Returns</h3>
|
||||
<pre>HTTP 200: OK
|
||||
{
|
||||
"success": true,
|
||||
"id": "yay137" // ID of the newly created list
|
||||
}
|
||||
</pre>
|
||||
<pre>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
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
<pre>HTTP 413: Payload too large
|
||||
{
|
||||
"success": false,
|
||||
"value": "too_many_files",
|
||||
"message": "This list contains too many files, max 10000 allowed."
|
||||
}
|
||||
</pre>
|
||||
<pre>HTTP 422: Unprocessable Entity
|
||||
{
|
||||
"success": false,
|
||||
"value": "json_parse_failed",
|
||||
"message": "The JSON object in the request body could not be read."
|
||||
}
|
||||
</pre>
|
||||
<pre>HTTP 413: Payload too large
|
||||
{
|
||||
"success": false,
|
||||
"value": "title_too_long",
|
||||
"message": "The title of this list is too long, max 300 characters allowed."
|
||||
}
|
||||
</pre>
|
||||
<pre>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."
|
||||
}
|
||||
</pre>
|
||||
<pre>HTTP 422: Unprocessable Entity
|
||||
{
|
||||
"success": false,
|
||||
"value": "cannot_create_empty_list",
|
||||
"message": "You cannot make a list with no files."
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
||||
{{define "api-list-get"}}
|
||||
<details class="api_doc_details request_get">
|
||||
<summary><span class="method">GET</span>/list/{id}</summary>
|
||||
<div>
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
Returns information about a file list and the files in it.
|
||||
</p>
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Param</td>
|
||||
<td>Required</td>
|
||||
<td>Location</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>id</td>
|
||||
<td>true</td>
|
||||
<td>URL</td>
|
||||
<td>ID of the list</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>Returns</h3>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<pre>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"
|
||||
}
|
||||
]
|
||||
}
|
||||
</pre>
|
||||
<pre>HTTP 404: Not Found
|
||||
{
|
||||
"success": false,
|
||||
"value": "list_not_found",
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
18
res/template/fragments/markdown_wrapper.html
Normal file
18
res/template/fragments/markdown_wrapper.html
Normal file
@@ -0,0 +1,18 @@
|
||||
{{define "markdown_wrapper"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{template "meta_tags" .Title}}
|
||||
{{template "user_style" .}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "page_top" .}}
|
||||
<h1>{{.Title}}</h1>
|
||||
<div class="page_content"><div class="limit_width">
|
||||
{{.Other}}
|
||||
</div></div>
|
||||
{{template "page_bottom" .}}
|
||||
{{template "analytics"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
@@ -1,8 +1,10 @@
|
||||
package webcontroller
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -12,6 +14,7 @@ import (
|
||||
"github.com/Fornaxian/log"
|
||||
"github.com/google/uuid"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
blackfriday "github.com/russross/blackfriday/v2"
|
||||
)
|
||||
|
||||
// WebController controls how requests are handled and makes sure they have
|
||||
@@ -100,16 +103,16 @@ func New(
|
||||
}{
|
||||
// General navigation
|
||||
{GET, "" /* */, wc.serveTemplate("home", false)},
|
||||
{GET, "api" /* */, wc.serveTemplate("apidoc", false)},
|
||||
{GET, "api" /* */, wc.serveMarkdown("apidoc.md", false)},
|
||||
{GET, "history" /* */, wc.serveTemplate("history_cookies", false)},
|
||||
{GET, "u/:id" /* */, wc.serveFileViewer},
|
||||
{GET, "u/:id/preview" /**/, wc.serveFilePreview},
|
||||
{GET, "l/:id" /* */, wc.serveListViewer},
|
||||
{GET, "s/:id" /* */, wc.serveSkynetViewer},
|
||||
{GET, "t" /* */, wc.serveTemplate("paste", false)},
|
||||
{GET, "donation" /* */, wc.serveTemplate("donation", false)},
|
||||
{GET, "donation" /* */, wc.serveMarkdown("donation.md", false)},
|
||||
{GET, "widgets" /* */, wc.serveTemplate("widgets", false)},
|
||||
{GET, "about" /* */, wc.serveTemplate("about", false)},
|
||||
{GET, "about" /* */, wc.serveMarkdown("about.md", false)},
|
||||
{GET, "appearance" /* */, wc.serveTemplate("appearance", false)},
|
||||
|
||||
// User account pages
|
||||
@@ -171,6 +174,65 @@ func (wc *WebController) serveTemplate(
|
||||
}
|
||||
}
|
||||
|
||||
func (wc *WebController) serveMarkdown(tpl string, requireAuth bool) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
var err error
|
||||
var tpld = wc.newTemplateData(w, r)
|
||||
if requireAuth && !tpld.Authenticated {
|
||||
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
// Execute the raw markdown template and save the result in a buffer
|
||||
var tplBuf bytes.Buffer
|
||||
if err = wc.templates.Get().ExecuteTemplate(&tplBuf, tpl, tpld); err != nil {
|
||||
log.Error("Error executing template '%s': %s", tpl, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Parse the markdown document and save the resulting HTML in a buffer
|
||||
renderer := blackfriday.NewHTMLRenderer(blackfriday.HTMLRendererParameters{
|
||||
Flags: blackfriday.CommonHTMLFlags,
|
||||
})
|
||||
|
||||
// We parse the markdown document, walk through the nodes. Extract the
|
||||
// title of the document, and the rest of the nodes are rendered like
|
||||
// normal
|
||||
var mdBuf bytes.Buffer
|
||||
var inHeader = false
|
||||
blackfriday.New(
|
||||
blackfriday.WithRenderer(renderer),
|
||||
blackfriday.WithExtensions(blackfriday.CommonExtensions),
|
||||
).Parse(
|
||||
tplBuf.Bytes(),
|
||||
).Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
|
||||
// Capture the title of the document so we can put it at the top of
|
||||
// the template and in the metadata. When entering a h1 node the
|
||||
// next node will be the title of the document. Save that value
|
||||
if node.Type == blackfriday.Heading && node.HeadingData.Level == 1 {
|
||||
inHeader = entering
|
||||
return blackfriday.GoToNext
|
||||
}
|
||||
if inHeader {
|
||||
tpld.Title = string(node.Literal)
|
||||
log.Info(string(node.Literal))
|
||||
return blackfriday.GoToNext
|
||||
}
|
||||
|
||||
return renderer.RenderNode(&mdBuf, node, entering)
|
||||
})
|
||||
|
||||
// Pass the buffer's parsed contents to the wrapper template
|
||||
tpld.Other = template.HTML(mdBuf.Bytes())
|
||||
|
||||
// Execute the wrapper template
|
||||
err = wc.templates.Get().ExecuteTemplate(w, "markdown_wrapper", tpld)
|
||||
if err != nil && !strings.Contains(err.Error(), "broken pipe") {
|
||||
log.Error("Error executing template '%s': %s", tpl, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wc *WebController) serveFile(path string) httprouter.Handle {
|
||||
return func(
|
||||
w http.ResponseWriter,
|
||||
|
Reference in New Issue
Block a user