Skip to content

Commit

Permalink
More Schema options
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefterv committed Jan 26, 2025
1 parent 89ab3a0 commit 26b3fd9
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 7 deletions.
52 changes: 52 additions & 0 deletions SCHEMA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Processing URI Schema Definition

## Local File Schema
```
pde:///path/to/sketch.pde
```

## Sketch Operations

### Create New Sketch
```
pde://sketch/new
```

### Load Base64 Encoded Sketch
```
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

### Load Sketch from URL
```
pde://sketch/url/domain.com/path/to/sketch.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

Example with query parameters:
```
pde://sketch/url/example.com/sketch.pde?data=image1.png,sound1.mp3&mode=java
```

## Preferences
```
pde://preferences?key1=value1&key2=value2
```
Sets and saves multiple preferences in a single operation.

## Security Considerations
- URL-based operations automatically prepend https:// if no scheme is provided
- All URLs and query parameters are decoded using UTF-8
- File downloads occur asynchronously in a separate thread
- Base64 and remote sketches are saved to temporary folders
86 changes: 79 additions & 7 deletions app/src/processing/app/Schema.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package processing.app

import processing.app.ui.Editor
import java.io.File
import java.io.FileOutputStream
import java.net.URI
import java.net.URL
import java.net.URLDecoder
import java.nio.charset.StandardCharsets

Expand All @@ -18,7 +20,7 @@ class Schema {
null -> handleLocalFile(uri.path)
"sketch" -> handleSketch(uri)
"preferences" -> handlePreferences(uri)
else -> handleRemoteFile(uri)
else -> null
}
}
private fun handleLocalFile(input: String): Editor?{
Expand All @@ -27,20 +29,94 @@ class Schema {
private fun handleSketch(uri: URI): Editor?{
val paths = uri.path.split("/")
return when(paths.getOrNull(1)){
"new" -> handleSketchNew(uri)
"base64" -> handleSketchBase64(uri)
"url" -> handleSketchUrl(uri)
else -> null
}
}
private fun handleSketchNew(uri: URI): Editor?{
base?.handleNew()
return null
}
private fun handleSketchBase64(uri: URI): Editor?{
val tempSketchFolder = SketchName.nextFolder(Base.untitledFolder);
tempSketchFolder.mkdirs()
val tempSketchFile = File(tempSketchFolder, "${tempSketchFolder.name}.pde")
val sketchB64 = uri.path.replace("/base64/", "")
val sketch = java.util.Base64.getDecoder().decode(sketchB64)
tempSketchFile.writeBytes(sketch)
val editor = base?.handleOpenUntitled(tempSketchFile.absolutePath)
return editor
handleSketchOptions(uri, tempSketchFolder)
return base?.handleOpenUntitled(tempSketchFile.absolutePath)
}
private fun handleSketchUrl(uri: URI): Editor?{
val url = File(uri.path.replace("/url/", ""))

val tempSketchFolder = File(Base.untitledFolder, url.nameWithoutExtension)
tempSketchFolder.mkdirs()
val tempSketchFile = File(tempSketchFolder, "${tempSketchFolder.name}.pde")


URL("https://$url").openStream().use { input ->
FileOutputStream(tempSketchFile).use { output ->
input.copyTo(output)
}
}
handleSketchOptions(uri, tempSketchFolder)
return base?.handleOpenUntitled(tempSketchFile.absolutePath)
}
private fun handleSketchOptions(uri: URI, sketchFolder: File){
val options = uri.query?.split("&")
?.map { it.split("=") }
?.associate {
URLDecoder.decode(it[0], StandardCharsets.UTF_8) to
URLDecoder.decode(it[1], StandardCharsets.UTF_8)
}
?: emptyMap()

options["data"]?.let{ data ->
downloadFiles(uri, data, File(sketchFolder, "data"))
}
options["code"]?.let{ code ->
downloadFiles(uri, code, File(sketchFolder, "code"))
}
options["pde"]?.let{ pde ->
downloadFiles(uri, pde, sketchFolder)
}
options["mode"]?.let{ mode ->
val modeFile = File(sketchFolder, "sketch.properties")
modeFile.writeText("mode.id=$mode")
}

}
private fun downloadFiles(uri: URI, urlList: String, sketchFolder: File){
Thread{
val base = uri.path.split("/").drop(2).dropLast(1).joinToString("/")
val files = urlList.split(",")
.map {
val fileUrl = URI.create(it)
if(fileUrl.host == null){
return@map "https://$base/$it"
}
if(fileUrl.scheme == null){
return@map "https://$it"
}
return@map it
}
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)
}
}
}
}.start()
}


private fun handlePreferences(uri: URI): Editor?{
val options = uri.query?.split("&")
Expand All @@ -57,9 +133,5 @@ class Schema {

return null
}

private fun handleRemoteFile(uri: URI): Editor?{
return null
}
}
}

0 comments on commit 26b3fd9

Please sign in to comment.