mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
Added support for Base64 encoded extra files
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
```
|
||||
pde:///path/to/sketch.pde
|
||||
```
|
||||
Attention: The 3rd slash is import to trigger local files.
|
||||
|
||||
## Sketch Operations
|
||||
|
||||
@@ -17,27 +18,37 @@ pde://sketch/new
|
||||
pde://sketch/base64/<base64_encoded_content>
|
||||
```
|
||||
Optional query parameters:
|
||||
- `data`: Comma-separated URLs of data files to download
|
||||
- `code`: Comma-separated URLs of code files to download
|
||||
- `pde`: Comma-separated URLs of Processing sketch files to download
|
||||
- `mode`: Processing mode identifier
|
||||
- `data`: Comma-separated {File} that should be placed in the data folder
|
||||
- `code`: Comma-separated {File} that should be placed in the code folder
|
||||
- `pde`: Comma-separated {File} that should be placed in the sketch folder
|
||||
- `mode`: Processing mode identifier, e.g. `processing.mode.android.AndroidMode` You can find this in the sketch.properties file when switching modes on a sketch
|
||||
|
||||
### Load Sketch from URL
|
||||
|
||||
```
|
||||
pde://sketch/url/domain.com/path/to/sketch.pde
|
||||
pde://sketch/url/github.com/processing/processing-examples/raw/refs/heads/main/Basics/Arrays/Array/Array.pde
|
||||
```
|
||||
[Click to here to test](pde://sketch/url/github.com/processing/processing-examples/raw/refs/heads/main/Basics/Arrays/Array/Array.pde)
|
||||
|
||||
Supports the same query parameters as base64 endpoint.
|
||||
Optional query parameters:
|
||||
|
||||
- `data`: Comma-separated URLs of data files to download
|
||||
- `code`: Comma-separated URLs of code files to download
|
||||
- `pde`: Comma-separated URLs of Processing sketch files to download
|
||||
- `mode`: Processing mode identifier
|
||||
- `data`: Comma-separated {File} that should be placed in the data folder
|
||||
- `code`: Comma-separated {File} that should be placed in the code folder
|
||||
- `pde`: Comma-separated {File} that should be placed in the sketch folder
|
||||
- `mode`: Processing mode identifier, e.g. `processing.mode.android.AndroidMode` You can find this in the sketch.properties file when switching modes on a sketch
|
||||
|
||||
Example with query parameters:
|
||||
|
||||
```
|
||||
pde://sketch/url/example.com/sketch.pde?data=image1.png,sound1.mp3&mode=java
|
||||
pde://sketch/url/github.com/processing/processing-examples/raw/refs/heads/main/Basics/Image/Alphamask/Alphamask.pde?data=data/moonwalk.jpg,data/mask.jpg,processing.org/img/processing-web.png
|
||||
```
|
||||
[Click to here to test](pde://sketch/url/github.com/processing/processing-examples/raw/refs/heads/main/Basics/Image/Alphamask/Alphamask.pde?data=data/moonwalk.jpg,data/mask.jpg,processing.org/img/processing-web.png)
|
||||
|
||||
#### A {File}
|
||||
A {File} is a string that represents a file in the sketch and has a couple of options, it always starts with the filename followed by a colon, e.g. `file.pde:example.com/path/to/file.pde`. The following options are available:
|
||||
- `example.com/path/to/file.pde`: A remote file that should be downloaded
|
||||
- `file.pde`: A remote file that should be downloaded with a path relative to the sketch (only available in loading the sketch from url)
|
||||
- a base64 encoded file: A base64 encoded file
|
||||
|
||||
## Preferences
|
||||
```
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.net.URI
|
||||
import java.net.URL
|
||||
import java.net.URLDecoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.*
|
||||
|
||||
|
||||
class Schema {
|
||||
@@ -44,7 +45,7 @@ class Schema {
|
||||
tempSketchFolder.mkdirs()
|
||||
val tempSketchFile = File(tempSketchFolder, "${tempSketchFolder.name}.pde")
|
||||
val sketchB64 = uri.path.replace("/base64/", "")
|
||||
val sketch = java.util.Base64.getDecoder().decode(sketchB64)
|
||||
val sketch = Base64.getDecoder().decode(sketchB64)
|
||||
tempSketchFile.writeBytes(sketch)
|
||||
handleSketchOptions(uri, tempSketchFolder)
|
||||
return base?.handleOpenUntitled(tempSketchFile.absolutePath)
|
||||
@@ -73,7 +74,6 @@ class Schema {
|
||||
URLDecoder.decode(it[1], StandardCharsets.UTF_8)
|
||||
}
|
||||
?: emptyMap()
|
||||
|
||||
options["data"]?.let{ data ->
|
||||
downloadFiles(uri, data, File(sketchFolder, "data"))
|
||||
}
|
||||
@@ -89,31 +89,56 @@ class Schema {
|
||||
}
|
||||
|
||||
}
|
||||
private fun downloadFiles(uri: URI, urlList: String, sketchFolder: File){
|
||||
private fun downloadFiles(uri: URI, urlList: String, targetFolder: File){
|
||||
Thread{
|
||||
val base = uri.path.split("/").drop(2).dropLast(1).joinToString("/")
|
||||
targetFolder.mkdirs()
|
||||
|
||||
val base = uri.path.split("/")
|
||||
.drop(2) // drop the /sketch/base64/ or /sketch/url/ etc...
|
||||
.dropLast(1) // drop the file name
|
||||
.joinToString("/")
|
||||
|
||||
val files = urlList.split(",")
|
||||
.map {
|
||||
val fileUrl = URI.create(it)
|
||||
if(fileUrl.host == null){
|
||||
return@map "https://$base/$it"
|
||||
|
||||
files.filter { it.isNotBlank() }
|
||||
.map{ it.split(":", limit = 2) }
|
||||
.map{ segments ->
|
||||
if(segments.size == 2){
|
||||
if(segments[0].isBlank()){
|
||||
return@map listOf(null, segments[1])
|
||||
}
|
||||
return@map segments
|
||||
}
|
||||
if(fileUrl.scheme == null){
|
||||
return@map "https://$it"
|
||||
}
|
||||
return@map it
|
||||
return@map listOf(null, segments[0])
|
||||
}
|
||||
sketchFolder.mkdirs()
|
||||
for(file in files){
|
||||
val url = URL(file)
|
||||
val name = url.path.split("/").last()
|
||||
val dataFile = File(sketchFolder, name)
|
||||
URL(file).openStream().use { input ->
|
||||
FileOutputStream(dataFile).use { output ->
|
||||
input.copyTo(output)
|
||||
.forEach { (name, content) ->
|
||||
try{
|
||||
// Try to decode the content as base64
|
||||
val file = Base64.getDecoder().decode(content)
|
||||
if(name == null){
|
||||
Messages.err("Base64 files needs to start with a file name followed by a colon")
|
||||
return@forEach
|
||||
}
|
||||
File(targetFolder, name).writeBytes(file)
|
||||
}catch(_: IllegalArgumentException){
|
||||
// Assume it's a URL and download it
|
||||
var url = URI.create(content)
|
||||
if(url.host == null){
|
||||
url = URI.create("https://$base/$content")
|
||||
}
|
||||
if(url.scheme == null){
|
||||
url = URI.create("https://$content")
|
||||
}
|
||||
|
||||
val target = File(targetFolder, name ?: url.path.split("/").last())
|
||||
url.toURL().openStream().use { input ->
|
||||
target.outputStream().use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user