implement stripe and idenfy webhooks support

This commit is contained in:
Timur Gordon
2025-07-08 22:49:47 +02:00
parent 7dfd54a20a
commit 93977bad7a
129 changed files with 9655 additions and 3640 deletions

2
research/launcher/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/examples/ourworld/ourworld_output.json
test_worker_db*

View File

@@ -0,0 +1,52 @@
# `launcher` Architecture
This document provides a detailed look into the internal architecture of the `launcher` utility, explaining how it orchestrates the creation and management of multiple Circle instances.
## 1. Core Design
The `launcher` is a `tokio`-based asynchronous application. Its primary responsibility is to parse a configuration file and then spawn and manage the lifecycle of two key components for each configured Circle:
1. **A `server` instance**: A WebSocket server running in its own `tokio` task.
2. **A Rhai worker**: A script execution engine running in a separate `tokio` task.
The launcher maintains a central registry of all running circles, allowing it to monitor their status and coordinate a graceful shutdown.
## 2. Startup and Initialization Sequence
The `main` function in `launcher/src/main.rs` executes the following sequence:
1. **Parse Command-Line Arguments**: It checks for verbosity flags (`-v`, `-vv`, `-vvv`) and a debug flag (`-d`) to configure the logging level.
2. **Load Configuration**: It reads and deserializes the `circles.json` file into a `Vec<CircleConfig>`.
3. **Iterate and Spawn**: For each `CircleConfig` in the vector, it performs the following steps:
a. **Database Setup**: It creates a dedicated database directory for the Circle at `~/.hero/circles/{id}/`.
b. **Rhai Engine Initialization**: It creates an instance of the Rhai engine and, if a `script_path` is provided, executes the initial script.
c. **Worker Spawning**: It calls `worker_lib::spawn_rhai_worker`, which starts the Rhai worker in a new `tokio` task. It provides the worker with a shutdown channel receiver.
d. **Server Spawning**: It calls `circle_ws_lib::spawn_circle_ws_server`, which starts the `Actix` WebSocket server in another `tokio` task. It provides the server with a channel to send back its `ServerHandle`.
4. **Store Handles**: It stores all the necessary handles for each running circle—including the worker's shutdown channel sender and the server's `ServerHandle`—in a central `Vec<RunningCircleInfo>`.
5. **Display Status**: It prints a table to the console with details about each running circle.
## 3. Graceful Shutdown
The launcher is designed to shut down all its child processes cleanly when it receives a `Ctrl+C` signal.
```mermaid
sequenceDiagram
participant User
participant Launcher as main()
participant Worker as Rhai Worker Task
participant Server as WS Server Task
User->>Launcher: Presses Ctrl+C
Launcher->>Launcher: Catches signal::ctrl_c()
loop For Each Running Circle
Launcher->>Worker: Sends shutdown signal via mpsc::channel
Launcher->>Server: Calls handle.stop(true)
end
Note over Launcher: Waits for all tasks to complete.
Launcher->>User: Exits cleanly
```
This process ensures that both the WebSocket servers and the Rhai workers have a chance to terminate properly, preventing orphaned processes and potential data corruption.

2654
research/launcher/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
[package]
name = "circles-launcher"
version = "0.1.0"
edition = "2021"
[lib]
name = "circles_launcher"
path = "src/lib.rs"
[[bin]]
name = "launcher"
path = "src/cmd/main.rs"
[dependencies]
tokio = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
log = { workspace = true }
comfy-table = "7.0"
actix-web = { workspace = true }
secp256k1 = { version = "0.28.0", features = ["rand-std"] }
clap = { version = "4.5.4", features = ["derive"] }
once_cell = "1.19.0"
rhai = "1.18.0"
# Path dependencies to other local crates
heromodels = { path = "../../../db/heromodels" }
rhailib_engine = { path = "../../../rhailib/src/engine" }
rhailib_worker = { path = "../../../rhailib/src/worker" }
rhai_client = { path = "../../../rhailib/src/client" }
ourdb = { path = "../../../db/ourdb" } # Added for IdSequence
sal-service-manager = { path = "../../../sal/service_manager" }
tokio-tungstenite = "0.23"
url = "2.5.2"
[dev-dependencies]
secp256k1 = { version = "0.28.0", features = ["rand-std"] }
serde_json = { workspace = true }
tempfile = "3.3"
tokio-tungstenite = { version = "0.23", features = ["native-tls"] }
futures-util = "0.3"
redis = { version = "0.25.4", features = ["tokio-comp"] }
rand = "0.8"
url = "2.5.2"
hex = "0.4"
[[example]]
name = "circle_launcher_example"
path = "examples/circle_launcher_example.rs"
[[example]]
name = "cleanup_example"
path = "examples/cleanup_example.rs"

254
research/launcher/README.md Normal file
View File

@@ -0,0 +1,254 @@
# Circle Launcher
Crate for launching and managing [circle workers](../worker) and the [circles ws server](../server).
## Features
- **Single-server multi-circle architecture**: One WebSocket server handles all circles via path-based routing
- **Dual operation modes**: Direct spawning or service manager integration
- **Initialization scripts**: Send Rhai scripts to workers on startup
- **Service management**: Automatic restart and background operation support
- **Cross-platform**: macOS (launchctl) and Linux (systemd) support
- **Service cleanup**: Automatic cleanup of background services on exit
## Installation
Build the launcher:
```bash
cargo build --release --bin launcher
```
## Usage
### Basic Syntax
```bash
launcher [OPTIONS] -c <CIRCLE>...
```
### Circle Configuration Format
Circles are specified using the `-c/--circle` option with the format:
```
public_key[:init_script.rhai]
```
- `public_key`: secp256k1 public key in hex format (required)
- `init_script.rhai`: Optional initialization script to send to the worker
### Examples
#### Development Mode (Direct Spawning)
```bash
# Single circle without initialization script
launcher -c 02a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4
# Multiple circles with initialization scripts
launcher -c 02a1b2c3d4e5f6a7...d4:setup.rhai -c 03b2c3d4e5f6a7...e5:config.rhai
# Mixed configuration (some with scripts, some without)
launcher -c 02a1b2c3d4e5f6a7...d4:init.rhai -c 03b2c3d4e5f6a7...e5
```
#### Production Mode (Service Manager)
```bash
# Using service manager with worker binary
launcher --use-service-manager --worker-binary ./target/release/worker \
-c 02a1b2c3d4e5f6a7...d4:prod_init.rhai \
-c 03b2c3d4e5f6a7...e5
# Service manager without initialization scripts
launcher --use-service-manager --worker-binary /usr/local/bin/worker \
-c 02a1b2c3d4e5f6a7...d4 \
-c 03b2c3d4e5f6a7...e5
```
## Command Line Options
| Option | Short | Description | Default |
|--------|-------|-------------|---------|
| `--circle` | `-c` | Circle configuration: `public_key[:init_script.rhai]` | Required |
| `--port` | `-p` | WebSocket server port | 8080 |
| `--redis-url` | | Redis connection URL | `redis://127.0.0.1:6379` |
| `--enable-auth` | | Enable WebSocket authentication | false |
| `--use-service-manager` | | Use service manager instead of direct spawning | false |
| `--worker-binary` | | Path to worker binary (required with service manager) | None |
| `--debug` | `-d` | Enable debug logging | false |
| `--verbose` | `-v` | Increase verbosity (can be used multiple times) | 0 |
## Operation Modes
### Direct Spawn Mode (Default)
In direct spawn mode, workers run as Tokio tasks within the launcher process:
- **Pros**: Simple setup, immediate shutdown, ideal for development
- **Cons**: Workers stop when launcher exits, no automatic restart
```bash
launcher -c 02a1b2c3d4e5f6a7...d4:init.rhai
```
### Service Manager Mode
In service manager mode, workers are managed by the system service manager:
- **Pros**: Background operation, automatic restart, production-ready
- **Cons**: Requires worker binary, platform-specific setup
```bash
launcher --use-service-manager --worker-binary ./target/release/worker \
-c 02a1b2c3d4e5f6a7...d4:init.rhai
```
#### Service Manager Support
- **macOS**: Uses `launchctl` with launch agents
- **Linux**: Uses `systemd` (implementation in progress)
Services are named: `tf.ourworld.circles.circle-worker-{public_key}`
## Architecture
### Single-Server Multi-Circle
The launcher creates one WebSocket server that handles multiple circles through path-based routing:
- **Server URL**: `ws://127.0.0.1:8080`
- **Circle URLs**: `ws://127.0.0.1:8080/{circle_public_key}`
- **Worker Queues**: `rhai_tasks:{circle_public_key}`
### Initialization Scripts
When a circle configuration includes an initialization script:
1. Worker starts and connects to Redis
2. Launcher waits 2 seconds for worker startup
3. Launcher sends script content via RhaiClient to worker's queue
4. Worker executes the initialization script
## Configuration
### Environment Variables
- `RUST_LOG`: Controls logging level (auto-configured based on verbosity)
- `PRESERVE_TASKS`: Preserve Redis tasks on worker shutdown
### Data Directory
The launcher creates a `./launch_data` directory for:
- Worker databases: `circle_db_{public_key}.db`
- Service configuration files (service manager mode)
## Error Handling
Common error scenarios and solutions:
| Error | Cause | Solution |
|-------|-------|----------|
| "Invalid public key" | Malformed secp256k1 key | Verify key format (64 hex chars) |
| "Worker binary path required" | Missing `--worker-binary` in service mode | Provide path to worker executable |
| "Failed to read init script" | Script file not found | Check script file path and permissions |
| "Service already exists" | Service name conflict | Stop existing service or use different key |
## Development
### Building
```bash
# Debug build
cargo build --bin launcher
# Release build
cargo build --release --bin launcher
```
### Testing
```bash
# Run with debug logging
RUST_LOG=debug cargo run --bin launcher -- -c 02a1b2c3d4e5f6a7...d4
# Test service manager mode
cargo run --bin launcher -- --use-service-manager \
--worker-binary ./target/debug/worker \
-c 02a1b2c3d4e5f6a7...d4:test.rhai
```
## Troubleshooting
### Worker Connection Issues
1. Verify Redis is running on the specified URL
2. Check worker binary exists and is executable
3. Ensure public keys are valid secp256k1 format
### Service Manager Issues
1. Check service manager logs: `launchctl log show --predicate 'subsystem == "tf.ourworld.circles"'`
2. Verify worker binary permissions and dependencies
3. Ensure working directory is accessible
### Script Execution Issues
1. Verify script file exists and is readable
2. Check Redis connectivity for script transmission
3. Monitor worker logs for script execution errors
## Security Considerations
- **Public Key Validation**: All keys are validated as proper secp256k1 public keys
- **Script Execution**: Initialization scripts run with worker privileges
- **Service Isolation**: Each worker runs as a separate service in service manager mode
- **Redis Security**: Ensure Redis instance is properly secured in production
## Performance
- **Concurrent Workers**: No hard limit on number of circles
- **Resource Usage**: Each worker consumes memory for database and Rhai engine
- **Network**: Single WebSocket server reduces port usage
- **Startup Time**: ~2 second delay for initialization script transmission
## Service Cleanup
The launcher provides automatic cleanup functionality to stop and remove all circle-related services:
### Automatic Cleanup
Examples automatically clean up services on exit:
```bash
# Run example - services are cleaned up automatically on exit or Ctrl+C
cargo run --example circle_launcher_example
```
### Manual Cleanup
Clean up all circle services manually:
```bash
# Using the cleanup example
cargo run --example cleanup_example
# Or using the library function
use circles_launcher::cleanup_launcher;
cleanup_launcher().await?;
```
### What Gets Cleaned Up
The cleanup function removes:
- All worker services (`circle-worker-{public_key}`)
- WebSocket server service (`circle-ws-server`)
- Associated service configuration files (plist files on macOS)
### Signal Handling
Examples include signal handling for graceful cleanup:
- **Ctrl+C**: Triggers cleanup before exit
- **Normal exit**: Always runs cleanup before termination
- **Error exit**: Cleanup still runs to prevent orphaned services

View File

@@ -0,0 +1,3 @@
[
{ "id": 100, "name": "Test Circle", "port": 9000, "script_path": "../circles/src/launcher/examples/test_script.rhai" }
]

View File

@@ -0,0 +1,144 @@
# Launcher Examples
This directory contains examples demonstrating how to use the circles launcher.
## Prerequisites
Before running the examples, make sure you have:
1. Built the worker binary:
```bash
cd ../worker && cargo build --release
```
2. Built the WebSocket server binary:
```bash
cd ../server && cargo build --release
```
3. Redis server running on `redis://127.0.0.1:6379`
## Examples
### 1. Circle Launcher Example (`circle_launcher_example.rs`)
Demonstrates the builder pattern API for launching circles programmatically:
```bash
cd src/launcher
cargo run --example circle_launcher_example
```
This example shows:
- Creating circles with generated public keys
- Using the builder pattern API
- Launching single and multiple circles
- Adding initialization scripts
- Proper cleanup between examples
### 2. Cleanup Example (`cleanup_example.rs`)
Shows how to clean up all launcher services:
```bash
cd src/launcher
cargo run --example cleanup_example
```
### 3. End-to-End Confirmation (`confirm_launch.rs`)
Tests the complete launcher workflow including service communication:
```bash
cd src/launcher
cargo run --example confirm_launch
```
This example:
- Launches the launcher binary with command line arguments
- Tests worker communication via Redis
- Verifies environment variables are set correctly
- Performs end-to-end validation
### 4. OurWorld Example (`ourworld/main.rs`)
Real-world example using actual circle configurations:
```bash
cd src/launcher
cargo run --example ourworld
```
## Command Line Usage
You can also use the launcher binary directly:
```bash
# Single circle
cargo run --bin launcher -- \
--circle 02a1b2c3d4e5f6789abcdef... \
--worker-binary ../target/release/worker \
--port 8080
# Multiple circles with initialization scripts
cargo run --bin launcher -- \
--circle 02a1b2c3d4e5f6789abcdef...:test_script.rhai \
--circle 03b2c3d4e5f6789abcdef012... \
--worker-binary ../target/release/worker \
--port 8080
# With custom Redis URL
cargo run --bin launcher -- \
--circle 02a1b2c3d4e5f6789abcdef... \
--worker-binary ../target/release/worker \
--redis-url redis://localhost:6379 \
--port 8080
```
## Circle Configuration Format
Circles can be specified in two formats:
1. **Public key only**: `02a1b2c3d4e5f6789abcdef...`
2. **Public key with init script**: `02a1b2c3d4e5f6789abcdef...:init_script.rhai`
The public key must be a valid secp256k1 public key in hex format.
## Service Management
The launcher uses the system service manager (launchctl on macOS) to manage:
- **WebSocket server**: `circle-ws-server`
- **Worker processes**: `circle-worker-<PUBLIC_KEY>`
Services are automatically started and can be managed independently after launch.
## Cleanup
To clean up all launcher services:
```bash
cargo run --example cleanup_example
```
Or use the library function:
```rust
use circles_launcher::cleanup_launcher;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
cleanup_launcher().await?;
Ok(())
}
```
## Troubleshooting
1. **Port already in use**: The launcher checks if services are already running and reuses them when possible.
2. **Worker binary not found**: Make sure to build the worker binary first and specify the correct path.
3. **Redis connection failed**: Ensure Redis is running and accessible at the specified URL.
4. **Service manager errors**: Check system logs for service-specific errors. On macOS, use `launchctl list | grep circle` to see service status.

View File

@@ -0,0 +1,146 @@
use circles_launcher::{Circle, Launcher};
use rand::rngs::OsRng;
use sal_service_manager::create_service_manager;
use secp256k1::{PublicKey, Secp256k1, SecretKey};
const WORKER_BINARY: &str = "../target/release/worker";
const SERVER_BINARY: &str = "../target/release/server";
const REDIS_URL: &str = "redis://127.0.0.1/";
const PORT: u16 = 8080;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
run_examples().await
}
async fn run_examples() -> Result<(), Box<dyn std::error::Error>> {
// Generate valid secp256k1 keypairs for testing
let secp = Secp256k1::new();
let mut rng = OsRng;
let secret_key1 = SecretKey::new(&mut rng);
let public_key1 = PublicKey::from_secret_key(&secp, &secret_key1);
let pk1_hex = hex::encode(public_key1.serialize());
let secret_key2 = SecretKey::new(&mut rng);
let public_key2 = PublicKey::from_secret_key(&secp, &secret_key2);
let pk2_hex = hex::encode(public_key2.serialize());
let secret_key3 = SecretKey::new(&mut rng);
let public_key3 = PublicKey::from_secret_key(&secp, &secret_key3);
let pk3_hex = hex::encode(public_key3.serialize());
println!("Generated test public keys:");
println!(" PK1: {}", pk1_hex);
println!(" PK2: {}", pk2_hex);
println!(" PK3: {}", pk3_hex);
// Example 1: Simple launcher with single circle
println!("\n=== Example 1: Simple Launcher ===");
let launcher1 = Launcher {
service_manager: tokio::task::spawn_blocking(|| create_service_manager(None))
.await??,
circles: vec![Circle {
public_key: pk1_hex.clone(),
init_script: None,
}],
worker_binary: WORKER_BINARY.to_string(),
server_binary: SERVER_BINARY.to_string(),
redis_url: REDIS_URL.to_string(),
port: PORT,
};
match launcher1.launch().await {
Ok(_) => println!("Circle launched successfully!"),
Err(e) => println!("Failed to launch: {}", e),
}
launcher1.clean().await?;
// Example 2: Launcher with multiple circles
println!("\n=== Example 2: Multiple Circles ===");
let launcher2 = Launcher {
service_manager: tokio::task::spawn_blocking(|| create_service_manager(None))
.await??,
circles: vec![
Circle {
public_key: pk1_hex.clone(),
init_script: None,
},
Circle {
public_key: pk2_hex.clone(),
init_script: None,
},
],
worker_binary: WORKER_BINARY.to_string(),
server_binary: SERVER_BINARY.to_string(),
redis_url: REDIS_URL.to_string(),
port: PORT,
};
match launcher2.launch().await {
Ok(_) => println!("Multiple circles launched successfully!"),
Err(e) => println!("Failed to launch multiple circles: {}", e),
}
launcher2.clean().await?;
// Example 3: Multiple circles with initialization scripts
println!("\n=== Example 3: Multiple Circles with Init Scripts ===");
let launcher3 = Launcher {
service_manager: tokio::task::spawn_blocking(|| create_service_manager(None))
.await??,
circles: vec![
Circle {
public_key: pk1_hex.clone(),
init_script: Some("test_script.rhai".to_string()),
},
Circle {
public_key: pk2_hex.clone(),
init_script: Some("test_script.rhai".to_string()),
},
Circle {
public_key: pk3_hex.clone(),
init_script: Some("test_script.rhai".to_string()),
},
],
worker_binary: WORKER_BINARY.to_string(),
server_binary: SERVER_BINARY.to_string(),
redis_url: REDIS_URL.to_string(),
port: PORT,
};
match launcher3.launch().await {
Ok(_) => println!("Multiple circles with init scripts launched successfully!"),
Err(e) => println!("Failed to launch multiple circles with init scripts: {}", e),
}
launcher3.clean().await?;
// Example 4: Mixed configuration (some with scripts, some without)
println!("\n=== Example 4: Mixed Configuration ===");
let launcher4 = Launcher {
service_manager: tokio::task::spawn_blocking(|| create_service_manager(None))
.await??,
circles: vec![
Circle {
public_key: pk1_hex.clone(),
init_script: Some("test_script.rhai".to_string()),
},
Circle {
public_key: pk2_hex.clone(),
init_script: None,
},
Circle {
public_key: pk3_hex.clone(),
init_script: Some("test_script.rhai".to_string()),
},
],
worker_binary: WORKER_BINARY.to_string(),
server_binary: SERVER_BINARY.to_string(),
redis_url: REDIS_URL.to_string(),
port: PORT,
};
match launcher4.launch().await {
Ok(_) => println!("Mixed configuration launched successfully!"),
Err(e) => println!("Failed to launch mixed configuration: {}", e),
}
launcher4.clean().await?;
println!("\nAll examples completed.");
Ok(())
}

View File

@@ -0,0 +1,13 @@
use circles_launcher::cleanup_launcher;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Cleaning up all launcher services...");
match cleanup_launcher().await {
Ok(_) => println!("Cleanup completed successfully!"),
Err(e) => println!("Cleanup failed: {}", e),
}
Ok(())
}

View File

@@ -0,0 +1,111 @@
use secp256k1::{Secp256k1, SecretKey, PublicKey};
use rand::rngs::OsRng;
use std::process::{Child, Command, Stdio};
use std::time::Duration;
const REDIS_URL: &str = "redis://127.0.0.1:6379";
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("--- Starting End-to-End Circle Launch Confirmation ---");
// Generate a test public key
let secp = Secp256k1::new();
let mut rng = OsRng;
let secret_key = SecretKey::new(&mut rng);
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
let test_public_key = hex::encode(public_key.serialize());
println!("Using test public key: {}", test_public_key);
// Start the launcher with the test public key
let mut launcher_process: Child = Command::new("cargo")
.arg("run")
.arg("--bin")
.arg("launcher")
.arg("--")
.arg("--circle")
.arg(format!("{}:test_script.rhai", test_public_key))
.arg("--worker-binary")
.arg("../target/release/worker")
.arg("--port")
.arg("8080")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
println!(
"Launcher process started with PID: {}",
launcher_process.id()
);
// Wait a moment for the launcher to start services
tokio::time::sleep(Duration::from_secs(5)).await;
let client = rhai_client::RhaiClientBuilder::new()
.redis_url(REDIS_URL)
.caller_id("test_launcher")
.build()?;
// Test 1: Verify that CIRCLE_PUBLIC_KEY is set correctly.
println!("--- Test 1: Verifying CIRCLE_PUBLIC_KEY ---");
let script_circle_pk = r#"CIRCLE_PUBLIC_KEY"#;
println!("Submitting script to verify CIRCLE_PUBLIC_KEY...");
let task_details_circle_pk = client
.new_play_request()
.recipient_id(&format!("rhai_tasks:{}", test_public_key))
.script(script_circle_pk)
.request_id("task_id_circle_pk")
.timeout(Duration::from_secs(10))
.await_response()
.await?;
println!("Received task details: {:?}", task_details_circle_pk);
assert_eq!(task_details_circle_pk.status, "completed");
assert_eq!(task_details_circle_pk.output, Some(test_public_key.to_string()));
println!("✅ SUCCESS: Worker correctly reported its CIRCLE_PUBLIC_KEY.");
// Test 2: Verify that CALLER_PUBLIC_KEY is set correctly when the launcher calls.
println!("\n--- Test 2: Verifying CALLER_PUBLIC_KEY for init scripts ---");
let script_caller_pk = r#"CALLER_PUBLIC_KEY"#;
println!("Submitting script to verify CALLER_PUBLIC_KEY...");
let task_details_caller_pk = client
.new_play_request()
.recipient_id(&format!("rhai_tasks:{}", test_public_key))
.script(script_caller_pk)
.request_id("task_id_caller_pk")
.timeout(Duration::from_secs(10))
.await_response()
.await?;
println!("Received task details: {:?}", task_details_caller_pk);
assert_eq!(task_details_caller_pk.status, "completed");
// The caller should be "launcher" as set in the RhaiClient
println!("✅ SUCCESS: Worker correctly reported CALLER_PUBLIC_KEY for init script.");
// Test 3: Simple script execution
println!("\n--- Test 3: Simple Script Execution ---");
let simple_script = r#"print("Hello from worker!"); "test_result""#;
println!("Submitting simple script...");
let task_details_simple = client
.new_play_request()
.recipient_id(&format!("rhai_tasks:{}", test_public_key))
.script(simple_script)
.request_id("task_id_simple")
.timeout(Duration::from_secs(10))
.await_response()
.await?;
println!("Received task details: {:?}", task_details_simple);
assert_eq!(task_details_simple.status, "completed");
assert_eq!(task_details_simple.output, Some("test_result".to_string()));
println!("✅ SUCCESS: Worker executed simple script correctly.");
// Gracefully shut down the launcher
println!("Shutting down launcher process...");
launcher_process.kill()?;
tokio::task::spawn_blocking(move || {
let _ = launcher_process.wait();
})
.await?;
println!("--- End-to-End Test Finished Successfully ---");
Ok(())
}

View File

@@ -0,0 +1,37 @@
[
{
"name": "OurWorld",
"port": 8090,
"script_path": "scripts/ourworld.rhai"
},
{
"name": "Dunia Cybercity",
"port": 8091,
"script_path": "scripts/dunia_cybercity.rhai"
},
{
"name": "Sikana",
"port": 8092,
"script_path": "scripts/sikana.rhai"
},
{
"name": "Threefold",
"port": 8093,
"script_path": "scripts/threefold.rhai"
},
{
"name": "Mbweni",
"port": 8094,
"script_path": "scripts/mbweni.rhai"
},
{
"name": "Geomind",
"port": 8095,
"script_path": "scripts/geomind.rhai"
},
{
"name": "Freezone",
"port": 8096,
"script_path": "scripts/freezone.rhai"
}
]

View File

@@ -0,0 +1,101 @@
//! Example of launching multiple circles and outputting their details to a file.
//!
//! This example demonstrates how to use the launcher library to start circles
//! programmatically, similar to how the `launcher` binary works.
//!
//! # Usage
//!
//! ```sh
//! cd src/launcher
//! cargo run --example ourworld
//! ```
//!
//! This will:
//! 1. Read the `circles.json` file in the `examples/ourworld` directory.
//! 2. Launch all 7 circles defined in the config.
//! 3. Create a `ourworld_output.json` file in the same directory with the details.
//! 4. The launcher will run until you stop it with Ctrl+C.
use circles_launcher::{run_launcher, Args};
use log::{error, info};
use serde::{Deserialize, Serialize};
use std::error::Error as StdError;
use std::fs;
use std::path::PathBuf;
#[derive(Serialize, Deserialize, Debug)]
struct OurWorldCircleConfig {
pub public_key: String,
pub init_script: Option<String>,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn StdError>> {
println!("--- Launching OurWorld Example Programmatically ---");
let example_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples/ourworld");
let config_path = example_dir.join("circles.json");
let output_path = example_dir.join("ourworld_output.json");
println!("Using config file: {:?}", config_path);
println!("Output will be written to: {:?}", output_path);
if !config_path.exists() {
let msg = format!("Configuration file not found at {:?}", config_path);
error!("{}", msg);
return Err(msg.into());
}
let config_content = fs::read_to_string(&config_path)?;
let ourworld_configs: Vec<OurWorldCircleConfig> = match serde_json::from_str(&config_content) {
Ok(configs) => configs,
Err(e) => {
error!(
"Failed to parse {}: {}. Ensure it's a valid JSON array of circle configs.",
config_path.display(),
e
);
return Err(e.into());
}
};
if ourworld_configs.is_empty() {
info!(
"No circle configurations found in {}. Exiting.",
config_path.display()
);
return Ok(());
}
// Convert OurWorld configs to circle strings for the new API
let mut circle_strings = Vec::new();
for config in &ourworld_configs {
let circle_str = if let Some(script) = &config.init_script {
format!("{}:{}", config.public_key, script)
} else {
config.public_key.clone()
};
circle_strings.push(circle_str);
}
// Manually construct the arguments for the new API
let args = Args {
port: 443, // Default port
circles: circle_strings,
redis_url: "redis://127.0.0.1:6379".to_string(),
enable_auth: false,
worker_binary: Some("../target/release/worker".to_string()),
debug: true, // Enable debug logging for the example
verbose: 2, // Set verbosity to max
};
println!("Starting launcher with {} circles... Press Ctrl+C to exit.", ourworld_configs.len());
// The run_launcher function will setup logging, spawn circles, print the table,
// and wait for a shutdown signal (Ctrl+C).
run_launcher(args).await?;
println!("--- OurWorld Example Finished ---");
Ok(())
}

View File

@@ -0,0 +1,249 @@
// OurWorld Circle and Library Data
new_circle()
.title("Dunia Cybercity")
.description("Creating a better world.")
.ws_url("ws://localhost:8091/ws")
.logo("🌍")
.save_circle();
let circle = get_circle();
print("--- Creating OurWorld Library ---");
// === IMAGES ===
print("Creating images...");
let nature1 = save_image(new_image()
.title("Mountain Sunrise")
.description("Breathtaking sunrise over mountain peaks")
.url("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800")
.width(800).height(600));
let nature2 = save_image(new_image()
.title("Ocean Waves")
.description("Powerful ocean waves crashing on rocks")
.url("https://images.unsplash.com/photo-1505142468610-359e7d316be0?w=800")
.width(800).height(600));
let nature3 = save_image(new_image()
.title("Forest Path")
.description("Peaceful path through ancient forest")
.url("https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800")
.width(800).height(600));
let tech1 = save_image(new_image()
.title("Solar Panels")
.description("Modern solar panel installation")
.url("https://images.unsplash.com/photo-1509391366360-2e959784a276?w=800")
.width(800).height(600));
let tech2 = save_image(new_image()
.title("Wind Turbines")
.description("Wind turbines generating clean energy")
.url("https://images.unsplash.com/photo-1466611653911-95081537e5b7?w=800")
.width(800).height(600));
let space1 = save_image(new_image()
.title("Earth from Space")
.description("Our beautiful planet from orbit")
.url("https://images.unsplash.com/photo-1446776877081-d282a0f896e2?w=800")
.width(800).height(600));
let space2 = save_image(new_image()
.title("Galaxy Spiral")
.description("Stunning spiral galaxy in deep space")
.url("https://images.unsplash.com/photo-1502134249126-9f3755a50d78?w=800")
.width(800).height(600));
let city1 = save_image(new_image()
.title("Smart City")
.description("Futuristic smart city at night")
.url("https://images.unsplash.com/photo-1480714378408-67cf0d13bc1f?w=800")
.width(800).height(600));
// === PDFs ===
print("Creating PDFs...");
let pdf1 = save_pdf(new_pdf()
.title("Climate Action Report 2024")
.description("Comprehensive analysis of global climate initiatives")
.url("https://www.ipcc.ch/site/assets/uploads/2018/02/ipcc_wg3_ar5_summary-for-policymakers.pdf")
.page_count(42));
let pdf2 = save_pdf(new_pdf()
.title("Sustainable Development Goals")
.description("UN SDG implementation guide")
.url("https://sdgs.un.org/sites/default/files/publications/21252030%20Agenda%20for%20Sustainable%20Development%20web.pdf")
.page_count(35));
let pdf3 = save_pdf(new_pdf()
.title("Renewable Energy Handbook")
.description("Technical guide to renewable energy systems")
.url("https://www.irena.org/-/media/Files/IRENA/Agency/Publication/2019/Oct/IRENA_Renewable-Energy-Statistics-2019.pdf")
.page_count(280));
let pdf4 = save_pdf(new_pdf()
.title("Blockchain for Good")
.description("How blockchain technology can solve global challenges")
.url("https://www.weforum.org/whitepapers/blockchain-beyond-the-hype")
.page_count(24));
let pdf5 = save_pdf(new_pdf()
.title("Future of Work Report")
.description("Analysis of changing work patterns and remote collaboration")
.url("https://www.mckinsey.com/featured-insights/future-of-work")
.page_count(156));
// === MARKDOWN DOCUMENTS ===
print("Creating markdown documents...");
let md1 = save_markdown(new_markdown()
.title("OurWorld Mission Statement")
.description("Our vision for a better world")
.content("# OurWorld Mission\n\n## Vision\nTo create a more sustainable, equitable, and connected world through technology and collaboration.\n\n## Values\n- **Sustainability**: Every decision considers environmental impact\n- **Inclusivity**: Technology that serves everyone\n- **Transparency**: Open source and open governance\n- **Innovation**: Pushing boundaries for positive change\n\n## Goals\n1. Reduce global carbon footprint by 50% by 2030\n2. Provide internet access to 1 billion underserved people\n3. Create 10 million green jobs worldwide\n4. Establish 1000 sustainable communities"));
let md2 = save_markdown(new_markdown()
.title("Getting Started Guide")
.description("How to join the OurWorld movement")
.content("# Getting Started with OurWorld\n\n## Welcome!\nThank you for joining our mission to create a better world.\n\n## First Steps\n1. **Explore**: Browse our projects and initiatives\n2. **Connect**: Join our community forums\n3. **Contribute**: Find ways to get involved\n4. **Learn**: Access our educational resources\n\n## Ways to Contribute\n- **Developers**: Contribute to open source projects\n- **Activists**: Organize local initiatives\n- **Educators**: Share knowledge and skills\n- **Investors**: Support sustainable ventures\n\n## Resources\n- [Community Forum](https://forum.ourworld.tf)\n- [Developer Portal](https://dev.ourworld.tf)\n- [Learning Hub](https://learn.ourworld.tf)"));
let md3 = save_markdown(new_markdown()
.title("Technology Roadmap 2024")
.description("Our technical development plans")
.content("# Technology Roadmap 2024\n\n## Q1 Objectives\n- Launch decentralized identity system\n- Deploy carbon tracking blockchain\n- Release mobile app v2.0\n\n## Q2 Objectives\n- Implement AI-powered resource optimization\n- Launch peer-to-peer energy trading platform\n- Deploy IoT sensor network\n\n## Q3 Objectives\n- Release virtual collaboration spaces\n- Launch digital twin cities pilot\n- Implement quantum-safe encryption\n\n## Q4 Objectives\n- Deploy autonomous governance systems\n- Launch global impact measurement platform\n- Release AR/VR sustainability training"));
let md4 = save_markdown(new_markdown()
.title("Community Guidelines")
.description("How we work together")
.content("# Community Guidelines\n\n## Our Principles\n- **Respect**: Treat everyone with dignity\n- **Collaboration**: Work together towards common goals\n- **Constructive**: Focus on solutions, not problems\n- **Inclusive**: Welcome diverse perspectives\n\n## Communication Standards\n- Use clear, respectful language\n- Listen actively to others\n- Provide constructive feedback\n- Share knowledge freely\n\n## Conflict Resolution\n1. Address issues directly and respectfully\n2. Seek to understand different viewpoints\n3. Involve mediators when needed\n4. Focus on solutions that benefit everyone"));
let investor = new_contact()
.name("Example Investor")
.save_contact();
let investors = new_group()
.name("Investors")
.description("A group for example inverstors of ourworld");
investors.add_contact(investor.id)
.save_group();
// === BOOKS ===
print("Creating books...");
let sustainability_book = save_book(new_book()
.title("Sustainability Handbook")
.description("Complete guide to sustainable living and practices")
.add_page("# Introduction to Sustainability\n\nSustainability is about meeting our present needs without compromising the ability of future generations to meet their own needs.\n\n## Key Principles\n- Environmental stewardship\n- Social equity\n- Economic viability\n\n## Why It Matters\nOur planet faces unprecedented challenges from climate change, resource depletion, and environmental degradation.")
.add_page("# Energy Efficiency\n\n## Home Energy Savings\n- LED lighting reduces energy consumption by 75%\n- Smart thermostats can save 10-15% on heating/cooling\n- Energy-efficient appliances make a significant difference\n\n## Renewable Energy\n- Solar panels: Clean electricity from sunlight\n- Wind power: Harnessing natural wind currents\n- Hydroelectric: Using water flow for energy\n\n## Transportation\n- Electric vehicles reduce emissions\n- Public transit decreases individual carbon footprint\n- Cycling and walking for short distances")
.add_page("# Waste Reduction\n\n## The 5 R's\n1. **Refuse**: Say no to unnecessary items\n2. **Reduce**: Use less of what you need\n3. **Reuse**: Find new purposes for items\n4. **Recycle**: Process materials into new products\n5. **Rot**: Compost organic waste\n\n## Practical Tips\n- Use reusable bags and containers\n- Buy products with minimal packaging\n- Repair instead of replacing\n- Donate items you no longer need")
.add_page("# Sustainable Food\n\n## Local and Seasonal\n- Support local farmers and reduce transport emissions\n- Eat seasonal produce for better nutrition and taste\n- Visit farmers markets and join CSAs\n\n## Plant-Based Options\n- Reduce meat consumption for environmental benefits\n- Explore diverse plant proteins\n- Grow your own herbs and vegetables\n\n## Food Waste Prevention\n- Plan meals and make shopping lists\n- Store food properly to extend freshness\n- Use leftovers creatively")
.add_toc_entry(new_toc_entry().title("Introduction to Sustainability").page(0))
.add_toc_entry(new_toc_entry().title("Energy Efficiency").page(1))
.add_toc_entry(new_toc_entry().title("Waste Reduction").page(2))
.add_toc_entry(new_toc_entry().title("Sustainable Food").page(3)));
let tech_guide_book = save_book(new_book()
.title("Green Technology Guide")
.description("Understanding and implementing green technologies")
.add_page("# Green Technology Overview\n\nGreen technology, also known as clean technology, refers to the use of science and technology to create products and services that are environmentally friendly.\n\n## Categories\n- Renewable energy systems\n- Energy efficiency technologies\n- Pollution prevention and cleanup\n- Sustainable materials and manufacturing\n\n## Benefits\n- Reduced environmental impact\n- Lower operating costs\n- Improved public health\n- Economic opportunities")
.add_page("# Solar Technology\n\n## How Solar Works\nSolar panels convert sunlight directly into electricity using photovoltaic cells.\n\n## Types of Solar Systems\n- **Grid-tied**: Connected to the electrical grid\n- **Off-grid**: Standalone systems with battery storage\n- **Hybrid**: Combination of grid-tied and battery backup\n\n## Installation Considerations\n- Roof orientation and shading\n- Local climate and sun exposure\n- Energy consumption patterns\n- Available incentives and rebates")
.add_page("# Smart Home Technology\n\n## Automation Benefits\n- Optimized energy usage\n- Enhanced comfort and convenience\n- Remote monitoring and control\n- Predictive maintenance\n\n## Key Technologies\n- Smart thermostats\n- Automated lighting systems\n- Energy monitoring devices\n- Smart appliances\n- Home energy management systems")
.add_toc_entry(new_toc_entry().title("Green Technology Overview").page(0))
.add_toc_entry(new_toc_entry().title("Solar Technology").page(1))
.add_toc_entry(new_toc_entry().title("Smart Home Technology").page(2)));
let community_book = save_book(new_book()
.title("Building Communities")
.description("Guide to creating sustainable and inclusive communities")
.add_page("# Community Building Fundamentals\n\n## What Makes a Strong Community?\n- Shared values and vision\n- Open communication channels\n- Mutual support and cooperation\n- Inclusive decision-making processes\n\n## Benefits of Strong Communities\n- Enhanced quality of life\n- Economic resilience\n- Social cohesion\n- Environmental stewardship")
.add_page("# Governance and Leadership\n\n## Collaborative Leadership\n- Distributed decision-making\n- Transparent processes\n- Accountability mechanisms\n- Conflict resolution systems\n\n## Community Engagement\n- Regular town halls and meetings\n- Digital participation platforms\n- Volunteer coordination\n- Feedback and improvement cycles")
.add_toc_entry(new_toc_entry().title("Community Building Fundamentals").page(0))
.add_toc_entry(new_toc_entry().title("Governance and Leadership").page(1)));
// === SLIDES ===
print("Creating slides...");
let climate_slides = save_slides(new_slides()
.title("Climate Change Awareness")
.description("Visual presentation on climate change impacts and solutions")
.add_slide("https://images.unsplash.com/photo-1569163139394-de4e4f43e4e3?w=1200", "Global Temperature Rise")
.add_slide("https://images.unsplash.com/photo-1578662996442-48f60103fc96?w=1200", "Melting Ice Caps")
.add_slide("https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200", "Extreme Weather Events")
.add_slide("https://images.unsplash.com/photo-1473341304170-971dccb5ac1e?w=1200", "Renewable Energy Solutions")
.add_slide("https://images.unsplash.com/photo-1497436072909-f5e4be1dffea?w=1200", "Sustainable Transportation"));
let innovation_slides = save_slides(new_slides()
.title("Innovation Showcase")
.description("Cutting-edge technologies for a sustainable future")
.add_slide("https://images.unsplash.com/photo-1518709268805-4e9042af2176?w=1200", "AI and Machine Learning")
.add_slide("https://images.unsplash.com/photo-1639322537228-f710d846310a?w=1200", "Blockchain Technology")
.add_slide("https://images.unsplash.com/photo-1581092160562-40aa08e78837?w=1200", "IoT and Smart Cities")
.add_slide("https://images.unsplash.com/photo-1581092918056-0c4c3acd3789?w=1200", "Quantum Computing")
.add_slide("https://images.unsplash.com/photo-1581092162384-8987c1d64718?w=1200", "Biotechnology Advances"));
let nature_slides = save_slides(new_slides()
.title("Biodiversity Gallery")
.description("Celebrating Earth's incredible biodiversity")
.add_slide("https://images.unsplash.com/photo-1564349683136-77e08dba1ef7?w=1200", "Tropical Rainforest")
.add_slide("https://images.unsplash.com/photo-1559827260-dc66d52bef19?w=1200", "Coral Reef Ecosystem")
.add_slide("https://images.unsplash.com/photo-1551698618-1dfe5d97d256?w=1200", "Arctic Wildlife")
.add_slide("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200", "Mountain Ecosystems"));
// === COLLECTIONS ===
print("Creating collections...");
let nature_collection = save_collection(new_collection()
.title("Nature & Environment")
.description("Beautiful images and resources about our natural world")
.add_image(nature1.id)
.add_image(nature2.id)
.add_image(nature3.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id)
.add_book(sustainability_book.id)
.add_slides(nature_slides.id));
let technology_collection = save_collection(new_collection()
.title("Sustainable Technology")
.description("Innovations driving positive change")
.add_image(tech1.id)
.add_image(tech2.id)
.add_pdf(pdf3.id)
.add_pdf(pdf4.id)
.add_markdown(md3.id)
.add_book(tech_guide_book.id)
.add_slides(innovation_slides.id));
let space_collection = save_collection(new_collection()
.title("Space & Cosmos")
.description("Exploring the universe and our place in it")
.add_image(space1.id)
.add_image(space2.id)
.add_pdf(pdf2.id)
.add_markdown(md2.id));
let community_collection = save_collection(new_collection()
.title("Community & Collaboration")
.description("Building better communities together")
.add_image(city1.id)
.add_pdf(pdf5.id)
.add_markdown(md4.id)
.add_book(community_book.id));
let climate_collection = save_collection(new_collection()
.title("Climate Action")
.description("Understanding and addressing climate change")
.add_slides(climate_slides.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id));
print("✅ OurWorld library created successfully!");
print("📚 Collections: 5");
print("🖼️ Images: 8");
print("📄 PDFs: 5");
print("📝 Markdown docs: 4");
print("📖 Books: 3");
print("🎞️ Slide shows: 3");

View File

@@ -0,0 +1,249 @@
// OurWorld Circle and Library Data
new_circle()
.title("Zanzibar Digital Freezone")
.description("Creating a better world.")
.ws_url("ws://localhost:8096/ws")
.logo("🌍")
.save_circle();
let circle = get_circle();
print("--- Creating OurWorld Library ---");
// === IMAGES ===
print("Creating images...");
let nature1 = save_image(new_image()
.title("Mountain Sunrise")
.description("Breathtaking sunrise over mountain peaks")
.url("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800")
.width(800).height(600));
let nature2 = save_image(new_image()
.title("Ocean Waves")
.description("Powerful ocean waves crashing on rocks")
.url("https://images.unsplash.com/photo-1505142468610-359e7d316be0?w=800")
.width(800).height(600));
let nature3 = save_image(new_image()
.title("Forest Path")
.description("Peaceful path through ancient forest")
.url("https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800")
.width(800).height(600));
let tech1 = save_image(new_image()
.title("Solar Panels")
.description("Modern solar panel installation")
.url("https://images.unsplash.com/photo-1509391366360-2e959784a276?w=800")
.width(800).height(600));
let tech2 = save_image(new_image()
.title("Wind Turbines")
.description("Wind turbines generating clean energy")
.url("https://images.unsplash.com/photo-1466611653911-95081537e5b7?w=800")
.width(800).height(600));
let space1 = save_image(new_image()
.title("Earth from Space")
.description("Our beautiful planet from orbit")
.url("https://images.unsplash.com/photo-1446776877081-d282a0f896e2?w=800")
.width(800).height(600));
let space2 = save_image(new_image()
.title("Galaxy Spiral")
.description("Stunning spiral galaxy in deep space")
.url("https://images.unsplash.com/photo-1502134249126-9f3755a50d78?w=800")
.width(800).height(600));
let city1 = save_image(new_image()
.title("Smart City")
.description("Futuristic smart city at night")
.url("https://images.unsplash.com/photo-1480714378408-67cf0d13bc1f?w=800")
.width(800).height(600));
// === PDFs ===
print("Creating PDFs...");
let pdf1 = save_pdf(new_pdf()
.title("Climate Action Report 2024")
.description("Comprehensive analysis of global climate initiatives")
.url("https://www.ipcc.ch/site/assets/uploads/2018/02/ipcc_wg3_ar5_summary-for-policymakers.pdf")
.page_count(42));
let pdf2 = save_pdf(new_pdf()
.title("Sustainable Development Goals")
.description("UN SDG implementation guide")
.url("https://sdgs.un.org/sites/default/files/publications/21252030%20Agenda%20for%20Sustainable%20Development%20web.pdf")
.page_count(35));
let pdf3 = save_pdf(new_pdf()
.title("Renewable Energy Handbook")
.description("Technical guide to renewable energy systems")
.url("https://www.irena.org/-/media/Files/IRENA/Agency/Publication/2019/Oct/IRENA_Renewable-Energy-Statistics-2019.pdf")
.page_count(280));
let pdf4 = save_pdf(new_pdf()
.title("Blockchain for Good")
.description("How blockchain technology can solve global challenges")
.url("https://www.weforum.org/whitepapers/blockchain-beyond-the-hype")
.page_count(24));
let pdf5 = save_pdf(new_pdf()
.title("Future of Work Report")
.description("Analysis of changing work patterns and remote collaboration")
.url("https://www.mckinsey.com/featured-insights/future-of-work")
.page_count(156));
// === MARKDOWN DOCUMENTS ===
print("Creating markdown documents...");
let md1 = save_markdown(new_markdown()
.title("OurWorld Mission Statement")
.description("Our vision for a better world")
.content("# OurWorld Mission\n\n## Vision\nTo create a more sustainable, equitable, and connected world through technology and collaboration.\n\n## Values\n- **Sustainability**: Every decision considers environmental impact\n- **Inclusivity**: Technology that serves everyone\n- **Transparency**: Open source and open governance\n- **Innovation**: Pushing boundaries for positive change\n\n## Goals\n1. Reduce global carbon footprint by 50% by 2030\n2. Provide internet access to 1 billion underserved people\n3. Create 10 million green jobs worldwide\n4. Establish 1000 sustainable communities"));
let md2 = save_markdown(new_markdown()
.title("Getting Started Guide")
.description("How to join the OurWorld movement")
.content("# Getting Started with OurWorld\n\n## Welcome!\nThank you for joining our mission to create a better world.\n\n## First Steps\n1. **Explore**: Browse our projects and initiatives\n2. **Connect**: Join our community forums\n3. **Contribute**: Find ways to get involved\n4. **Learn**: Access our educational resources\n\n## Ways to Contribute\n- **Developers**: Contribute to open source projects\n- **Activists**: Organize local initiatives\n- **Educators**: Share knowledge and skills\n- **Investors**: Support sustainable ventures\n\n## Resources\n- [Community Forum](https://forum.ourworld.tf)\n- [Developer Portal](https://dev.ourworld.tf)\n- [Learning Hub](https://learn.ourworld.tf)"));
let md3 = save_markdown(new_markdown()
.title("Technology Roadmap 2024")
.description("Our technical development plans")
.content("# Technology Roadmap 2024\n\n## Q1 Objectives\n- Launch decentralized identity system\n- Deploy carbon tracking blockchain\n- Release mobile app v2.0\n\n## Q2 Objectives\n- Implement AI-powered resource optimization\n- Launch peer-to-peer energy trading platform\n- Deploy IoT sensor network\n\n## Q3 Objectives\n- Release virtual collaboration spaces\n- Launch digital twin cities pilot\n- Implement quantum-safe encryption\n\n## Q4 Objectives\n- Deploy autonomous governance systems\n- Launch global impact measurement platform\n- Release AR/VR sustainability training"));
let md4 = save_markdown(new_markdown()
.title("Community Guidelines")
.description("How we work together")
.content("# Community Guidelines\n\n## Our Principles\n- **Respect**: Treat everyone with dignity\n- **Collaboration**: Work together towards common goals\n- **Constructive**: Focus on solutions, not problems\n- **Inclusive**: Welcome diverse perspectives\n\n## Communication Standards\n- Use clear, respectful language\n- Listen actively to others\n- Provide constructive feedback\n- Share knowledge freely\n\n## Conflict Resolution\n1. Address issues directly and respectfully\n2. Seek to understand different viewpoints\n3. Involve mediators when needed\n4. Focus on solutions that benefit everyone"));
let investor = new_contact()
.name("Example Investor")
.save_contact();
let investors = new_group()
.name("Investors")
.description("A group for example inverstors of ourworld");
investors.add_contact(investor.id)
.save_group();
// === BOOKS ===
print("Creating books...");
let sustainability_book = save_book(new_book()
.title("Sustainability Handbook")
.description("Complete guide to sustainable living and practices")
.add_page("# Introduction to Sustainability\n\nSustainability is about meeting our present needs without compromising the ability of future generations to meet their own needs.\n\n## Key Principles\n- Environmental stewardship\n- Social equity\n- Economic viability\n\n## Why It Matters\nOur planet faces unprecedented challenges from climate change, resource depletion, and environmental degradation.")
.add_page("# Energy Efficiency\n\n## Home Energy Savings\n- LED lighting reduces energy consumption by 75%\n- Smart thermostats can save 10-15% on heating/cooling\n- Energy-efficient appliances make a significant difference\n\n## Renewable Energy\n- Solar panels: Clean electricity from sunlight\n- Wind power: Harnessing natural wind currents\n- Hydroelectric: Using water flow for energy\n\n## Transportation\n- Electric vehicles reduce emissions\n- Public transit decreases individual carbon footprint\n- Cycling and walking for short distances")
.add_page("# Waste Reduction\n\n## The 5 R's\n1. **Refuse**: Say no to unnecessary items\n2. **Reduce**: Use less of what you need\n3. **Reuse**: Find new purposes for items\n4. **Recycle**: Process materials into new products\n5. **Rot**: Compost organic waste\n\n## Practical Tips\n- Use reusable bags and containers\n- Buy products with minimal packaging\n- Repair instead of replacing\n- Donate items you no longer need")
.add_page("# Sustainable Food\n\n## Local and Seasonal\n- Support local farmers and reduce transport emissions\n- Eat seasonal produce for better nutrition and taste\n- Visit farmers markets and join CSAs\n\n## Plant-Based Options\n- Reduce meat consumption for environmental benefits\n- Explore diverse plant proteins\n- Grow your own herbs and vegetables\n\n## Food Waste Prevention\n- Plan meals and make shopping lists\n- Store food properly to extend freshness\n- Use leftovers creatively")
.add_toc_entry(new_toc_entry().title("Introduction to Sustainability").page(0))
.add_toc_entry(new_toc_entry().title("Energy Efficiency").page(1))
.add_toc_entry(new_toc_entry().title("Waste Reduction").page(2))
.add_toc_entry(new_toc_entry().title("Sustainable Food").page(3)));
let tech_guide_book = save_book(new_book()
.title("Green Technology Guide")
.description("Understanding and implementing green technologies")
.add_page("# Green Technology Overview\n\nGreen technology, also known as clean technology, refers to the use of science and technology to create products and services that are environmentally friendly.\n\n## Categories\n- Renewable energy systems\n- Energy efficiency technologies\n- Pollution prevention and cleanup\n- Sustainable materials and manufacturing\n\n## Benefits\n- Reduced environmental impact\n- Lower operating costs\n- Improved public health\n- Economic opportunities")
.add_page("# Solar Technology\n\n## How Solar Works\nSolar panels convert sunlight directly into electricity using photovoltaic cells.\n\n## Types of Solar Systems\n- **Grid-tied**: Connected to the electrical grid\n- **Off-grid**: Standalone systems with battery storage\n- **Hybrid**: Combination of grid-tied and battery backup\n\n## Installation Considerations\n- Roof orientation and shading\n- Local climate and sun exposure\n- Energy consumption patterns\n- Available incentives and rebates")
.add_page("# Smart Home Technology\n\n## Automation Benefits\n- Optimized energy usage\n- Enhanced comfort and convenience\n- Remote monitoring and control\n- Predictive maintenance\n\n## Key Technologies\n- Smart thermostats\n- Automated lighting systems\n- Energy monitoring devices\n- Smart appliances\n- Home energy management systems")
.add_toc_entry(new_toc_entry().title("Green Technology Overview").page(0))
.add_toc_entry(new_toc_entry().title("Solar Technology").page(1))
.add_toc_entry(new_toc_entry().title("Smart Home Technology").page(2)));
let community_book = save_book(new_book()
.title("Building Communities")
.description("Guide to creating sustainable and inclusive communities")
.add_page("# Community Building Fundamentals\n\n## What Makes a Strong Community?\n- Shared values and vision\n- Open communication channels\n- Mutual support and cooperation\n- Inclusive decision-making processes\n\n## Benefits of Strong Communities\n- Enhanced quality of life\n- Economic resilience\n- Social cohesion\n- Environmental stewardship")
.add_page("# Governance and Leadership\n\n## Collaborative Leadership\n- Distributed decision-making\n- Transparent processes\n- Accountability mechanisms\n- Conflict resolution systems\n\n## Community Engagement\n- Regular town halls and meetings\n- Digital participation platforms\n- Volunteer coordination\n- Feedback and improvement cycles")
.add_toc_entry(new_toc_entry().title("Community Building Fundamentals").page(0))
.add_toc_entry(new_toc_entry().title("Governance and Leadership").page(1)));
// === SLIDES ===
print("Creating slides...");
let climate_slides = save_slides(new_slides()
.title("Climate Change Awareness")
.description("Visual presentation on climate change impacts and solutions")
.add_slide("https://images.unsplash.com/photo-1569163139394-de4e4f43e4e3?w=1200", "Global Temperature Rise")
.add_slide("https://images.unsplash.com/photo-1578662996442-48f60103fc96?w=1200", "Melting Ice Caps")
.add_slide("https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200", "Extreme Weather Events")
.add_slide("https://images.unsplash.com/photo-1473341304170-971dccb5ac1e?w=1200", "Renewable Energy Solutions")
.add_slide("https://images.unsplash.com/photo-1497436072909-f5e4be1dffea?w=1200", "Sustainable Transportation"));
let innovation_slides = save_slides(new_slides()
.title("Innovation Showcase")
.description("Cutting-edge technologies for a sustainable future")
.add_slide("https://images.unsplash.com/photo-1518709268805-4e9042af2176?w=1200", "AI and Machine Learning")
.add_slide("https://images.unsplash.com/photo-1639322537228-f710d846310a?w=1200", "Blockchain Technology")
.add_slide("https://images.unsplash.com/photo-1581092160562-40aa08e78837?w=1200", "IoT and Smart Cities")
.add_slide("https://images.unsplash.com/photo-1581092918056-0c4c3acd3789?w=1200", "Quantum Computing")
.add_slide("https://images.unsplash.com/photo-1581092162384-8987c1d64718?w=1200", "Biotechnology Advances"));
let nature_slides = save_slides(new_slides()
.title("Biodiversity Gallery")
.description("Celebrating Earth's incredible biodiversity")
.add_slide("https://images.unsplash.com/photo-1564349683136-77e08dba1ef7?w=1200", "Tropical Rainforest")
.add_slide("https://images.unsplash.com/photo-1559827260-dc66d52bef19?w=1200", "Coral Reef Ecosystem")
.add_slide("https://images.unsplash.com/photo-1551698618-1dfe5d97d256?w=1200", "Arctic Wildlife")
.add_slide("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200", "Mountain Ecosystems"));
// === COLLECTIONS ===
print("Creating collections...");
let nature_collection = save_collection(new_collection()
.title("Nature & Environment")
.description("Beautiful images and resources about our natural world")
.add_image(nature1.id)
.add_image(nature2.id)
.add_image(nature3.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id)
.add_book(sustainability_book.id)
.add_slides(nature_slides.id));
let technology_collection = save_collection(new_collection()
.title("Sustainable Technology")
.description("Innovations driving positive change")
.add_image(tech1.id)
.add_image(tech2.id)
.add_pdf(pdf3.id)
.add_pdf(pdf4.id)
.add_markdown(md3.id)
.add_book(tech_guide_book.id)
.add_slides(innovation_slides.id));
let space_collection = save_collection(new_collection()
.title("Space & Cosmos")
.description("Exploring the universe and our place in it")
.add_image(space1.id)
.add_image(space2.id)
.add_pdf(pdf2.id)
.add_markdown(md2.id));
let community_collection = save_collection(new_collection()
.title("Community & Collaboration")
.description("Building better communities together")
.add_image(city1.id)
.add_pdf(pdf5.id)
.add_markdown(md4.id)
.add_book(community_book.id));
let climate_collection = save_collection(new_collection()
.title("Climate Action")
.description("Understanding and addressing climate change")
.add_slides(climate_slides.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id));
print("✅ OurWorld library created successfully!");
print("📚 Collections: 5");
print("🖼️ Images: 8");
print("📄 PDFs: 5");
print("📝 Markdown docs: 4");
print("📖 Books: 3");
print("🎞️ Slide shows: 3");

View File

@@ -0,0 +1,249 @@
// OurWorld Circle and Library Data
new_circle()
.title("Geomind")
.description("Creating a better world.")
.ws_url("ws://localhost:8095/ws")
.logo("🌍")
.save_circle();
let circle = get_circle();
print("--- Creating OurWorld Library ---");
// === IMAGES ===
print("Creating images...");
let nature1 = save_image(new_image()
.title("Mountain Sunrise")
.description("Breathtaking sunrise over mountain peaks")
.url("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800")
.width(800).height(600));
let nature2 = save_image(new_image()
.title("Ocean Waves")
.description("Powerful ocean waves crashing on rocks")
.url("https://images.unsplash.com/photo-1505142468610-359e7d316be0?w=800")
.width(800).height(600));
let nature3 = save_image(new_image()
.title("Forest Path")
.description("Peaceful path through ancient forest")
.url("https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800")
.width(800).height(600));
let tech1 = save_image(new_image()
.title("Solar Panels")
.description("Modern solar panel installation")
.url("https://images.unsplash.com/photo-1509391366360-2e959784a276?w=800")
.width(800).height(600));
let tech2 = save_image(new_image()
.title("Wind Turbines")
.description("Wind turbines generating clean energy")
.url("https://images.unsplash.com/photo-1466611653911-95081537e5b7?w=800")
.width(800).height(600));
let space1 = save_image(new_image()
.title("Earth from Space")
.description("Our beautiful planet from orbit")
.url("https://images.unsplash.com/photo-1446776877081-d282a0f896e2?w=800")
.width(800).height(600));
let space2 = save_image(new_image()
.title("Galaxy Spiral")
.description("Stunning spiral galaxy in deep space")
.url("https://images.unsplash.com/photo-1502134249126-9f3755a50d78?w=800")
.width(800).height(600));
let city1 = save_image(new_image()
.title("Smart City")
.description("Futuristic smart city at night")
.url("https://images.unsplash.com/photo-1480714378408-67cf0d13bc1f?w=800")
.width(800).height(600));
// === PDFs ===
print("Creating PDFs...");
let pdf1 = save_pdf(new_pdf()
.title("Climate Action Report 2024")
.description("Comprehensive analysis of global climate initiatives")
.url("https://www.ipcc.ch/site/assets/uploads/2018/02/ipcc_wg3_ar5_summary-for-policymakers.pdf")
.page_count(42));
let pdf2 = save_pdf(new_pdf()
.title("Sustainable Development Goals")
.description("UN SDG implementation guide")
.url("https://sdgs.un.org/sites/default/files/publications/21252030%20Agenda%20for%20Sustainable%20Development%20web.pdf")
.page_count(35));
let pdf3 = save_pdf(new_pdf()
.title("Renewable Energy Handbook")
.description("Technical guide to renewable energy systems")
.url("https://www.irena.org/-/media/Files/IRENA/Agency/Publication/2019/Oct/IRENA_Renewable-Energy-Statistics-2019.pdf")
.page_count(280));
let pdf4 = save_pdf(new_pdf()
.title("Blockchain for Good")
.description("How blockchain technology can solve global challenges")
.url("https://www.weforum.org/whitepapers/blockchain-beyond-the-hype")
.page_count(24));
let pdf5 = save_pdf(new_pdf()
.title("Future of Work Report")
.description("Analysis of changing work patterns and remote collaboration")
.url("https://www.mckinsey.com/featured-insights/future-of-work")
.page_count(156));
// === MARKDOWN DOCUMENTS ===
print("Creating markdown documents...");
let md1 = save_markdown(new_markdown()
.title("OurWorld Mission Statement")
.description("Our vision for a better world")
.content("# OurWorld Mission\n\n## Vision\nTo create a more sustainable, equitable, and connected world through technology and collaboration.\n\n## Values\n- **Sustainability**: Every decision considers environmental impact\n- **Inclusivity**: Technology that serves everyone\n- **Transparency**: Open source and open governance\n- **Innovation**: Pushing boundaries for positive change\n\n## Goals\n1. Reduce global carbon footprint by 50% by 2030\n2. Provide internet access to 1 billion underserved people\n3. Create 10 million green jobs worldwide\n4. Establish 1000 sustainable communities"));
let md2 = save_markdown(new_markdown()
.title("Getting Started Guide")
.description("How to join the OurWorld movement")
.content("# Getting Started with OurWorld\n\n## Welcome!\nThank you for joining our mission to create a better world.\n\n## First Steps\n1. **Explore**: Browse our projects and initiatives\n2. **Connect**: Join our community forums\n3. **Contribute**: Find ways to get involved\n4. **Learn**: Access our educational resources\n\n## Ways to Contribute\n- **Developers**: Contribute to open source projects\n- **Activists**: Organize local initiatives\n- **Educators**: Share knowledge and skills\n- **Investors**: Support sustainable ventures\n\n## Resources\n- [Community Forum](https://forum.ourworld.tf)\n- [Developer Portal](https://dev.ourworld.tf)\n- [Learning Hub](https://learn.ourworld.tf)"));
let md3 = save_markdown(new_markdown()
.title("Technology Roadmap 2024")
.description("Our technical development plans")
.content("# Technology Roadmap 2024\n\n## Q1 Objectives\n- Launch decentralized identity system\n- Deploy carbon tracking blockchain\n- Release mobile app v2.0\n\n## Q2 Objectives\n- Implement AI-powered resource optimization\n- Launch peer-to-peer energy trading platform\n- Deploy IoT sensor network\n\n## Q3 Objectives\n- Release virtual collaboration spaces\n- Launch digital twin cities pilot\n- Implement quantum-safe encryption\n\n## Q4 Objectives\n- Deploy autonomous governance systems\n- Launch global impact measurement platform\n- Release AR/VR sustainability training"));
let md4 = save_markdown(new_markdown()
.title("Community Guidelines")
.description("How we work together")
.content("# Community Guidelines\n\n## Our Principles\n- **Respect**: Treat everyone with dignity\n- **Collaboration**: Work together towards common goals\n- **Constructive**: Focus on solutions, not problems\n- **Inclusive**: Welcome diverse perspectives\n\n## Communication Standards\n- Use clear, respectful language\n- Listen actively to others\n- Provide constructive feedback\n- Share knowledge freely\n\n## Conflict Resolution\n1. Address issues directly and respectfully\n2. Seek to understand different viewpoints\n3. Involve mediators when needed\n4. Focus on solutions that benefit everyone"));
let investor = new_contact()
.name("Example Investor")
.save_contact();
let investors = new_group()
.name("Investors")
.description("A group for example inverstors of ourworld");
investors.add_contact(investor.id)
.save_group();
// === BOOKS ===
print("Creating books...");
let sustainability_book = save_book(new_book()
.title("Sustainability Handbook")
.description("Complete guide to sustainable living and practices")
.add_page("# Introduction to Sustainability\n\nSustainability is about meeting our present needs without compromising the ability of future generations to meet their own needs.\n\n## Key Principles\n- Environmental stewardship\n- Social equity\n- Economic viability\n\n## Why It Matters\nOur planet faces unprecedented challenges from climate change, resource depletion, and environmental degradation.")
.add_page("# Energy Efficiency\n\n## Home Energy Savings\n- LED lighting reduces energy consumption by 75%\n- Smart thermostats can save 10-15% on heating/cooling\n- Energy-efficient appliances make a significant difference\n\n## Renewable Energy\n- Solar panels: Clean electricity from sunlight\n- Wind power: Harnessing natural wind currents\n- Hydroelectric: Using water flow for energy\n\n## Transportation\n- Electric vehicles reduce emissions\n- Public transit decreases individual carbon footprint\n- Cycling and walking for short distances")
.add_page("# Waste Reduction\n\n## The 5 R's\n1. **Refuse**: Say no to unnecessary items\n2. **Reduce**: Use less of what you need\n3. **Reuse**: Find new purposes for items\n4. **Recycle**: Process materials into new products\n5. **Rot**: Compost organic waste\n\n## Practical Tips\n- Use reusable bags and containers\n- Buy products with minimal packaging\n- Repair instead of replacing\n- Donate items you no longer need")
.add_page("# Sustainable Food\n\n## Local and Seasonal\n- Support local farmers and reduce transport emissions\n- Eat seasonal produce for better nutrition and taste\n- Visit farmers markets and join CSAs\n\n## Plant-Based Options\n- Reduce meat consumption for environmental benefits\n- Explore diverse plant proteins\n- Grow your own herbs and vegetables\n\n## Food Waste Prevention\n- Plan meals and make shopping lists\n- Store food properly to extend freshness\n- Use leftovers creatively")
.add_toc_entry(new_toc_entry().title("Introduction to Sustainability").page(0))
.add_toc_entry(new_toc_entry().title("Energy Efficiency").page(1))
.add_toc_entry(new_toc_entry().title("Waste Reduction").page(2))
.add_toc_entry(new_toc_entry().title("Sustainable Food").page(3)));
let tech_guide_book = save_book(new_book()
.title("Green Technology Guide")
.description("Understanding and implementing green technologies")
.add_page("# Green Technology Overview\n\nGreen technology, also known as clean technology, refers to the use of science and technology to create products and services that are environmentally friendly.\n\n## Categories\n- Renewable energy systems\n- Energy efficiency technologies\n- Pollution prevention and cleanup\n- Sustainable materials and manufacturing\n\n## Benefits\n- Reduced environmental impact\n- Lower operating costs\n- Improved public health\n- Economic opportunities")
.add_page("# Solar Technology\n\n## How Solar Works\nSolar panels convert sunlight directly into electricity using photovoltaic cells.\n\n## Types of Solar Systems\n- **Grid-tied**: Connected to the electrical grid\n- **Off-grid**: Standalone systems with battery storage\n- **Hybrid**: Combination of grid-tied and battery backup\n\n## Installation Considerations\n- Roof orientation and shading\n- Local climate and sun exposure\n- Energy consumption patterns\n- Available incentives and rebates")
.add_page("# Smart Home Technology\n\n## Automation Benefits\n- Optimized energy usage\n- Enhanced comfort and convenience\n- Remote monitoring and control\n- Predictive maintenance\n\n## Key Technologies\n- Smart thermostats\n- Automated lighting systems\n- Energy monitoring devices\n- Smart appliances\n- Home energy management systems")
.add_toc_entry(new_toc_entry().title("Green Technology Overview").page(0))
.add_toc_entry(new_toc_entry().title("Solar Technology").page(1))
.add_toc_entry(new_toc_entry().title("Smart Home Technology").page(2)));
let community_book = save_book(new_book()
.title("Building Communities")
.description("Guide to creating sustainable and inclusive communities")
.add_page("# Community Building Fundamentals\n\n## What Makes a Strong Community?\n- Shared values and vision\n- Open communication channels\n- Mutual support and cooperation\n- Inclusive decision-making processes\n\n## Benefits of Strong Communities\n- Enhanced quality of life\n- Economic resilience\n- Social cohesion\n- Environmental stewardship")
.add_page("# Governance and Leadership\n\n## Collaborative Leadership\n- Distributed decision-making\n- Transparent processes\n- Accountability mechanisms\n- Conflict resolution systems\n\n## Community Engagement\n- Regular town halls and meetings\n- Digital participation platforms\n- Volunteer coordination\n- Feedback and improvement cycles")
.add_toc_entry(new_toc_entry().title("Community Building Fundamentals").page(0))
.add_toc_entry(new_toc_entry().title("Governance and Leadership").page(1)));
// === SLIDES ===
print("Creating slides...");
let climate_slides = save_slides(new_slides()
.title("Climate Change Awareness")
.description("Visual presentation on climate change impacts and solutions")
.add_slide("https://images.unsplash.com/photo-1569163139394-de4e4f43e4e3?w=1200", "Global Temperature Rise")
.add_slide("https://images.unsplash.com/photo-1578662996442-48f60103fc96?w=1200", "Melting Ice Caps")
.add_slide("https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200", "Extreme Weather Events")
.add_slide("https://images.unsplash.com/photo-1473341304170-971dccb5ac1e?w=1200", "Renewable Energy Solutions")
.add_slide("https://images.unsplash.com/photo-1497436072909-f5e4be1dffea?w=1200", "Sustainable Transportation"));
let innovation_slides = save_slides(new_slides()
.title("Innovation Showcase")
.description("Cutting-edge technologies for a sustainable future")
.add_slide("https://images.unsplash.com/photo-1518709268805-4e9042af2176?w=1200", "AI and Machine Learning")
.add_slide("https://images.unsplash.com/photo-1639322537228-f710d846310a?w=1200", "Blockchain Technology")
.add_slide("https://images.unsplash.com/photo-1581092160562-40aa08e78837?w=1200", "IoT and Smart Cities")
.add_slide("https://images.unsplash.com/photo-1581092918056-0c4c3acd3789?w=1200", "Quantum Computing")
.add_slide("https://images.unsplash.com/photo-1581092162384-8987c1d64718?w=1200", "Biotechnology Advances"));
let nature_slides = save_slides(new_slides()
.title("Biodiversity Gallery")
.description("Celebrating Earth's incredible biodiversity")
.add_slide("https://images.unsplash.com/photo-1564349683136-77e08dba1ef7?w=1200", "Tropical Rainforest")
.add_slide("https://images.unsplash.com/photo-1559827260-dc66d52bef19?w=1200", "Coral Reef Ecosystem")
.add_slide("https://images.unsplash.com/photo-1551698618-1dfe5d97d256?w=1200", "Arctic Wildlife")
.add_slide("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200", "Mountain Ecosystems"));
// === COLLECTIONS ===
print("Creating collections...");
let nature_collection = save_collection(new_collection()
.title("Nature & Environment")
.description("Beautiful images and resources about our natural world")
.add_image(nature1.id)
.add_image(nature2.id)
.add_image(nature3.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id)
.add_book(sustainability_book.id)
.add_slides(nature_slides.id));
let technology_collection = save_collection(new_collection()
.title("Sustainable Technology")
.description("Innovations driving positive change")
.add_image(tech1.id)
.add_image(tech2.id)
.add_pdf(pdf3.id)
.add_pdf(pdf4.id)
.add_markdown(md3.id)
.add_book(tech_guide_book.id)
.add_slides(innovation_slides.id));
let space_collection = save_collection(new_collection()
.title("Space & Cosmos")
.description("Exploring the universe and our place in it")
.add_image(space1.id)
.add_image(space2.id)
.add_pdf(pdf2.id)
.add_markdown(md2.id));
let community_collection = save_collection(new_collection()
.title("Community & Collaboration")
.description("Building better communities together")
.add_image(city1.id)
.add_pdf(pdf5.id)
.add_markdown(md4.id)
.add_book(community_book.id));
let climate_collection = save_collection(new_collection()
.title("Climate Action")
.description("Understanding and addressing climate change")
.add_slides(climate_slides.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id));
print("✅ OurWorld library created successfully!");
print("📚 Collections: 5");
print("🖼️ Images: 8");
print("📄 PDFs: 5");
print("📝 Markdown docs: 4");
print("📖 Books: 3");
print("🎞️ Slide shows: 3");

View File

@@ -0,0 +1,249 @@
// OurWorld Circle and Library Data
new_circle()
.title("Mbweni Ruins & Gardens")
.description("Mbweni ruins and Gardens")
.ws_url("ws://localhost:8094/ws")
.logo("🌍")
.save_circle();
let circle = get_circle();
print("--- Creating OurWorld Library ---");
// === IMAGES ===
print("Creating images...");
let nature1 = save_image(new_image()
.title("Mountain Sunrise")
.description("Breathtaking sunrise over mountain peaks")
.url("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800")
.width(800).height(600));
let nature2 = save_image(new_image()
.title("Ocean Waves")
.description("Powerful ocean waves crashing on rocks")
.url("https://images.unsplash.com/photo-1505142468610-359e7d316be0?w=800")
.width(800).height(600));
let nature3 = save_image(new_image()
.title("Forest Path")
.description("Peaceful path through ancient forest")
.url("https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800")
.width(800).height(600));
let tech1 = save_image(new_image()
.title("Solar Panels")
.description("Modern solar panel installation")
.url("https://images.unsplash.com/photo-1509391366360-2e959784a276?w=800")
.width(800).height(600));
let tech2 = save_image(new_image()
.title("Wind Turbines")
.description("Wind turbines generating clean energy")
.url("https://images.unsplash.com/photo-1466611653911-95081537e5b7?w=800")
.width(800).height(600));
let space1 = save_image(new_image()
.title("Earth from Space")
.description("Our beautiful planet from orbit")
.url("https://images.unsplash.com/photo-1446776877081-d282a0f896e2?w=800")
.width(800).height(600));
let space2 = save_image(new_image()
.title("Galaxy Spiral")
.description("Stunning spiral galaxy in deep space")
.url("https://images.unsplash.com/photo-1502134249126-9f3755a50d78?w=800")
.width(800).height(600));
let city1 = save_image(new_image()
.title("Smart City")
.description("Futuristic smart city at night")
.url("https://images.unsplash.com/photo-1480714378408-67cf0d13bc1f?w=800")
.width(800).height(600));
// === PDFs ===
print("Creating PDFs...");
let pdf1 = save_pdf(new_pdf()
.title("Climate Action Report 2024")
.description("Comprehensive analysis of global climate initiatives")
.url("https://www.ipcc.ch/site/assets/uploads/2018/02/ipcc_wg3_ar5_summary-for-policymakers.pdf")
.page_count(42));
let pdf2 = save_pdf(new_pdf()
.title("Sustainable Development Goals")
.description("UN SDG implementation guide")
.url("https://sdgs.un.org/sites/default/files/publications/21252030%20Agenda%20for%20Sustainable%20Development%20web.pdf")
.page_count(35));
let pdf3 = save_pdf(new_pdf()
.title("Renewable Energy Handbook")
.description("Technical guide to renewable energy systems")
.url("https://www.irena.org/-/media/Files/IRENA/Agency/Publication/2019/Oct/IRENA_Renewable-Energy-Statistics-2019.pdf")
.page_count(280));
let pdf4 = save_pdf(new_pdf()
.title("Blockchain for Good")
.description("How blockchain technology can solve global challenges")
.url("https://www.weforum.org/whitepapers/blockchain-beyond-the-hype")
.page_count(24));
let pdf5 = save_pdf(new_pdf()
.title("Future of Work Report")
.description("Analysis of changing work patterns and remote collaboration")
.url("https://www.mckinsey.com/featured-insights/future-of-work")
.page_count(156));
// === MARKDOWN DOCUMENTS ===
print("Creating markdown documents...");
let md1 = save_markdown(new_markdown()
.title("OurWorld Mission Statement")
.description("Our vision for a better world")
.content("# OurWorld Mission\n\n## Vision\nTo create a more sustainable, equitable, and connected world through technology and collaboration.\n\n## Values\n- **Sustainability**: Every decision considers environmental impact\n- **Inclusivity**: Technology that serves everyone\n- **Transparency**: Open source and open governance\n- **Innovation**: Pushing boundaries for positive change\n\n## Goals\n1. Reduce global carbon footprint by 50% by 2030\n2. Provide internet access to 1 billion underserved people\n3. Create 10 million green jobs worldwide\n4. Establish 1000 sustainable communities"));
let md2 = save_markdown(new_markdown()
.title("Getting Started Guide")
.description("How to join the OurWorld movement")
.content("# Getting Started with OurWorld\n\n## Welcome!\nThank you for joining our mission to create a better world.\n\n## First Steps\n1. **Explore**: Browse our projects and initiatives\n2. **Connect**: Join our community forums\n3. **Contribute**: Find ways to get involved\n4. **Learn**: Access our educational resources\n\n## Ways to Contribute\n- **Developers**: Contribute to open source projects\n- **Activists**: Organize local initiatives\n- **Educators**: Share knowledge and skills\n- **Investors**: Support sustainable ventures\n\n## Resources\n- [Community Forum](https://forum.ourworld.tf)\n- [Developer Portal](https://dev.ourworld.tf)\n- [Learning Hub](https://learn.ourworld.tf)"));
let md3 = save_markdown(new_markdown()
.title("Technology Roadmap 2024")
.description("Our technical development plans")
.content("# Technology Roadmap 2024\n\n## Q1 Objectives\n- Launch decentralized identity system\n- Deploy carbon tracking blockchain\n- Release mobile app v2.0\n\n## Q2 Objectives\n- Implement AI-powered resource optimization\n- Launch peer-to-peer energy trading platform\n- Deploy IoT sensor network\n\n## Q3 Objectives\n- Release virtual collaboration spaces\n- Launch digital twin cities pilot\n- Implement quantum-safe encryption\n\n## Q4 Objectives\n- Deploy autonomous governance systems\n- Launch global impact measurement platform\n- Release AR/VR sustainability training"));
let md4 = save_markdown(new_markdown()
.title("Community Guidelines")
.description("How we work together")
.content("# Community Guidelines\n\n## Our Principles\n- **Respect**: Treat everyone with dignity\n- **Collaboration**: Work together towards common goals\n- **Constructive**: Focus on solutions, not problems\n- **Inclusive**: Welcome diverse perspectives\n\n## Communication Standards\n- Use clear, respectful language\n- Listen actively to others\n- Provide constructive feedback\n- Share knowledge freely\n\n## Conflict Resolution\n1. Address issues directly and respectfully\n2. Seek to understand different viewpoints\n3. Involve mediators when needed\n4. Focus on solutions that benefit everyone"));
let investor = new_contact()
.name("Example Investor")
.save_contact();
let investors = new_group()
.name("Investors")
.description("A group for example inverstors of ourworld");
investors.add_contact(investor.id)
.save_group();
// === BOOKS ===
print("Creating books...");
let sustainability_book = save_book(new_book()
.title("Sustainability Handbook")
.description("Complete guide to sustainable living and practices")
.add_page("# Introduction to Sustainability\n\nSustainability is about meeting our present needs without compromising the ability of future generations to meet their own needs.\n\n## Key Principles\n- Environmental stewardship\n- Social equity\n- Economic viability\n\n## Why It Matters\nOur planet faces unprecedented challenges from climate change, resource depletion, and environmental degradation.")
.add_page("# Energy Efficiency\n\n## Home Energy Savings\n- LED lighting reduces energy consumption by 75%\n- Smart thermostats can save 10-15% on heating/cooling\n- Energy-efficient appliances make a significant difference\n\n## Renewable Energy\n- Solar panels: Clean electricity from sunlight\n- Wind power: Harnessing natural wind currents\n- Hydroelectric: Using water flow for energy\n\n## Transportation\n- Electric vehicles reduce emissions\n- Public transit decreases individual carbon footprint\n- Cycling and walking for short distances")
.add_page("# Waste Reduction\n\n## The 5 R's\n1. **Refuse**: Say no to unnecessary items\n2. **Reduce**: Use less of what you need\n3. **Reuse**: Find new purposes for items\n4. **Recycle**: Process materials into new products\n5. **Rot**: Compost organic waste\n\n## Practical Tips\n- Use reusable bags and containers\n- Buy products with minimal packaging\n- Repair instead of replacing\n- Donate items you no longer need")
.add_page("# Sustainable Food\n\n## Local and Seasonal\n- Support local farmers and reduce transport emissions\n- Eat seasonal produce for better nutrition and taste\n- Visit farmers markets and join CSAs\n\n## Plant-Based Options\n- Reduce meat consumption for environmental benefits\n- Explore diverse plant proteins\n- Grow your own herbs and vegetables\n\n## Food Waste Prevention\n- Plan meals and make shopping lists\n- Store food properly to extend freshness\n- Use leftovers creatively")
.add_toc_entry(new_toc_entry().title("Introduction to Sustainability").page(0))
.add_toc_entry(new_toc_entry().title("Energy Efficiency").page(1))
.add_toc_entry(new_toc_entry().title("Waste Reduction").page(2))
.add_toc_entry(new_toc_entry().title("Sustainable Food").page(3)));
let tech_guide_book = save_book(new_book()
.title("Green Technology Guide")
.description("Understanding and implementing green technologies")
.add_page("# Green Technology Overview\n\nGreen technology, also known as clean technology, refers to the use of science and technology to create products and services that are environmentally friendly.\n\n## Categories\n- Renewable energy systems\n- Energy efficiency technologies\n- Pollution prevention and cleanup\n- Sustainable materials and manufacturing\n\n## Benefits\n- Reduced environmental impact\n- Lower operating costs\n- Improved public health\n- Economic opportunities")
.add_page("# Solar Technology\n\n## How Solar Works\nSolar panels convert sunlight directly into electricity using photovoltaic cells.\n\n## Types of Solar Systems\n- **Grid-tied**: Connected to the electrical grid\n- **Off-grid**: Standalone systems with battery storage\n- **Hybrid**: Combination of grid-tied and battery backup\n\n## Installation Considerations\n- Roof orientation and shading\n- Local climate and sun exposure\n- Energy consumption patterns\n- Available incentives and rebates")
.add_page("# Smart Home Technology\n\n## Automation Benefits\n- Optimized energy usage\n- Enhanced comfort and convenience\n- Remote monitoring and control\n- Predictive maintenance\n\n## Key Technologies\n- Smart thermostats\n- Automated lighting systems\n- Energy monitoring devices\n- Smart appliances\n- Home energy management systems")
.add_toc_entry(new_toc_entry().title("Green Technology Overview").page(0))
.add_toc_entry(new_toc_entry().title("Solar Technology").page(1))
.add_toc_entry(new_toc_entry().title("Smart Home Technology").page(2)));
let community_book = save_book(new_book()
.title("Building Communities")
.description("Guide to creating sustainable and inclusive communities")
.add_page("# Community Building Fundamentals\n\n## What Makes a Strong Community?\n- Shared values and vision\n- Open communication channels\n- Mutual support and cooperation\n- Inclusive decision-making processes\n\n## Benefits of Strong Communities\n- Enhanced quality of life\n- Economic resilience\n- Social cohesion\n- Environmental stewardship")
.add_page("# Governance and Leadership\n\n## Collaborative Leadership\n- Distributed decision-making\n- Transparent processes\n- Accountability mechanisms\n- Conflict resolution systems\n\n## Community Engagement\n- Regular town halls and meetings\n- Digital participation platforms\n- Volunteer coordination\n- Feedback and improvement cycles")
.add_toc_entry(new_toc_entry().title("Community Building Fundamentals").page(0))
.add_toc_entry(new_toc_entry().title("Governance and Leadership").page(1)));
// === SLIDES ===
print("Creating slides...");
let climate_slides = save_slides(new_slides()
.title("Climate Change Awareness")
.description("Visual presentation on climate change impacts and solutions")
.add_slide("https://images.unsplash.com/photo-1569163139394-de4e4f43e4e3?w=1200", "Global Temperature Rise")
.add_slide("https://images.unsplash.com/photo-1578662996442-48f60103fc96?w=1200", "Melting Ice Caps")
.add_slide("https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200", "Extreme Weather Events")
.add_slide("https://images.unsplash.com/photo-1473341304170-971dccb5ac1e?w=1200", "Renewable Energy Solutions")
.add_slide("https://images.unsplash.com/photo-1497436072909-f5e4be1dffea?w=1200", "Sustainable Transportation"));
let innovation_slides = save_slides(new_slides()
.title("Innovation Showcase")
.description("Cutting-edge technologies for a sustainable future")
.add_slide("https://images.unsplash.com/photo-1518709268805-4e9042af2176?w=1200", "AI and Machine Learning")
.add_slide("https://images.unsplash.com/photo-1639322537228-f710d846310a?w=1200", "Blockchain Technology")
.add_slide("https://images.unsplash.com/photo-1581092160562-40aa08e78837?w=1200", "IoT and Smart Cities")
.add_slide("https://images.unsplash.com/photo-1581092918056-0c4c3acd3789?w=1200", "Quantum Computing")
.add_slide("https://images.unsplash.com/photo-1581092162384-8987c1d64718?w=1200", "Biotechnology Advances"));
let nature_slides = save_slides(new_slides()
.title("Biodiversity Gallery")
.description("Celebrating Earth's incredible biodiversity")
.add_slide("https://images.unsplash.com/photo-1564349683136-77e08dba1ef7?w=1200", "Tropical Rainforest")
.add_slide("https://images.unsplash.com/photo-1559827260-dc66d52bef19?w=1200", "Coral Reef Ecosystem")
.add_slide("https://images.unsplash.com/photo-1551698618-1dfe5d97d256?w=1200", "Arctic Wildlife")
.add_slide("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200", "Mountain Ecosystems"));
// === COLLECTIONS ===
print("Creating collections...");
let nature_collection = save_collection(new_collection()
.title("Nature & Environment")
.description("Beautiful images and resources about our natural world")
.add_image(nature1.id)
.add_image(nature2.id)
.add_image(nature3.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id)
.add_book(sustainability_book.id)
.add_slides(nature_slides.id));
let technology_collection = save_collection(new_collection()
.title("Sustainable Technology")
.description("Innovations driving positive change")
.add_image(tech1.id)
.add_image(tech2.id)
.add_pdf(pdf3.id)
.add_pdf(pdf4.id)
.add_markdown(md3.id)
.add_book(tech_guide_book.id)
.add_slides(innovation_slides.id));
let space_collection = save_collection(new_collection()
.title("Space & Cosmos")
.description("Exploring the universe and our place in it")
.add_image(space1.id)
.add_image(space2.id)
.add_pdf(pdf2.id)
.add_markdown(md2.id));
let community_collection = save_collection(new_collection()
.title("Community & Collaboration")
.description("Building better communities together")
.add_image(city1.id)
.add_pdf(pdf5.id)
.add_markdown(md4.id)
.add_book(community_book.id));
let climate_collection = save_collection(new_collection()
.title("Climate Action")
.description("Understanding and addressing climate change")
.add_slides(climate_slides.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id));
print("✅ OurWorld library created successfully!");
print("📚 Collections: 5");
print("🖼️ Images: 8");
print("📄 PDFs: 5");
print("📝 Markdown docs: 4");
print("📖 Books: 3");
print("🎞️ Slide shows: 3");

View File

@@ -0,0 +1,255 @@
// OurWorld Circle and Library Data
new_circle()
.title("Ourworld")
.description("Creating a better world.")
.ws_url("ws://localhost:8090/ws")
.add_circle("ws://localhost:8091/ws")
.add_circle("ws://localhost:8092/ws")
.add_circle("ws://localhost:8093/ws")
.add_circle("ws://localhost:8094/ws")
.add_circle("ws://localhost:8095/ws")
.add_circle("ws://localhost:8096/ws")
.logo("🌍")
.save_circle();
let circle = get_circle();
print("--- Creating OurWorld Library ---");
// === IMAGES ===
print("Creating images...");
let nature1 = save_image(new_image()
.title("Mountain Sunrise")
.description("Breathtaking sunrise over mountain peaks")
.url("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800")
.width(800).height(600));
let nature2 = save_image(new_image()
.title("Ocean Waves")
.description("Powerful ocean waves crashing on rocks")
.url("https://images.unsplash.com/photo-1505142468610-359e7d316be0?w=800")
.width(800).height(600));
let nature3 = save_image(new_image()
.title("Forest Path")
.description("Peaceful path through ancient forest")
.url("https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800")
.width(800).height(600));
let tech1 = save_image(new_image()
.title("Solar Panels")
.description("Modern solar panel installation")
.url("https://images.unsplash.com/photo-1509391366360-2e959784a276?w=800")
.width(800).height(600));
let tech2 = save_image(new_image()
.title("Wind Turbines")
.description("Wind turbines generating clean energy")
.url("https://images.unsplash.com/photo-1466611653911-95081537e5b7?w=800")
.width(800).height(600));
let space1 = save_image(new_image()
.title("Earth from Space")
.description("Our beautiful planet from orbit")
.url("https://images.unsplash.com/photo-1446776877081-d282a0f896e2?w=800")
.width(800).height(600));
let space2 = save_image(new_image()
.title("Galaxy Spiral")
.description("Stunning spiral galaxy in deep space")
.url("https://images.unsplash.com/photo-1502134249126-9f3755a50d78?w=800")
.width(800).height(600));
let city1 = save_image(new_image()
.title("Smart City")
.description("Futuristic smart city at night")
.url("https://images.unsplash.com/photo-1480714378408-67cf0d13bc1f?w=800")
.width(800).height(600));
// === PDFs ===
print("Creating PDFs...");
let pdf1 = save_pdf(new_pdf()
.title("Climate Action Report 2024")
.description("Comprehensive analysis of global climate initiatives")
.url("https://www.ipcc.ch/site/assets/uploads/2018/02/ipcc_wg3_ar5_summary-for-policymakers.pdf")
.page_count(42));
let pdf2 = save_pdf(new_pdf()
.title("Sustainable Development Goals")
.description("UN SDG implementation guide")
.url("https://sdgs.un.org/sites/default/files/publications/21252030%20Agenda%20for%20Sustainable%20Development%20web.pdf")
.page_count(35));
let pdf3 = save_pdf(new_pdf()
.title("Renewable Energy Handbook")
.description("Technical guide to renewable energy systems")
.url("https://www.irena.org/-/media/Files/IRENA/Agency/Publication/2019/Oct/IRENA_Renewable-Energy-Statistics-2019.pdf")
.page_count(280));
let pdf4 = save_pdf(new_pdf()
.title("Blockchain for Good")
.description("How blockchain technology can solve global challenges")
.url("https://www.weforum.org/whitepapers/blockchain-beyond-the-hype")
.page_count(24));
let pdf5 = save_pdf(new_pdf()
.title("Future of Work Report")
.description("Analysis of changing work patterns and remote collaboration")
.url("https://www.mckinsey.com/featured-insights/future-of-work")
.page_count(156));
// === MARKDOWN DOCUMENTS ===
print("Creating markdown documents...");
let md1 = save_markdown(new_markdown()
.title("OurWorld Mission Statement")
.description("Our vision for a better world")
.content("# OurWorld Mission\n\n## Vision\nTo create a more sustainable, equitable, and connected world through technology and collaboration.\n\n## Values\n- **Sustainability**: Every decision considers environmental impact\n- **Inclusivity**: Technology that serves everyone\n- **Transparency**: Open source and open governance\n- **Innovation**: Pushing boundaries for positive change\n\n## Goals\n1. Reduce global carbon footprint by 50% by 2030\n2. Provide internet access to 1 billion underserved people\n3. Create 10 million green jobs worldwide\n4. Establish 1000 sustainable communities"));
let md2 = save_markdown(new_markdown()
.title("Getting Started Guide")
.description("How to join the OurWorld movement")
.content("# Getting Started with OurWorld\n\n## Welcome!\nThank you for joining our mission to create a better world.\n\n## First Steps\n1. **Explore**: Browse our projects and initiatives\n2. **Connect**: Join our community forums\n3. **Contribute**: Find ways to get involved\n4. **Learn**: Access our educational resources\n\n## Ways to Contribute\n- **Developers**: Contribute to open source projects\n- **Activists**: Organize local initiatives\n- **Educators**: Share knowledge and skills\n- **Investors**: Support sustainable ventures\n\n## Resources\n- [Community Forum](https://forum.ourworld.tf)\n- [Developer Portal](https://dev.ourworld.tf)\n- [Learning Hub](https://learn.ourworld.tf)"));
let md3 = save_markdown(new_markdown()
.title("Technology Roadmap 2024")
.description("Our technical development plans")
.content("# Technology Roadmap 2024\n\n## Q1 Objectives\n- Launch decentralized identity system\n- Deploy carbon tracking blockchain\n- Release mobile app v2.0\n\n## Q2 Objectives\n- Implement AI-powered resource optimization\n- Launch peer-to-peer energy trading platform\n- Deploy IoT sensor network\n\n## Q3 Objectives\n- Release virtual collaboration spaces\n- Launch digital twin cities pilot\n- Implement quantum-safe encryption\n\n## Q4 Objectives\n- Deploy autonomous governance systems\n- Launch global impact measurement platform\n- Release AR/VR sustainability training"));
let md4 = save_markdown(new_markdown()
.title("Community Guidelines")
.description("How we work together")
.content("# Community Guidelines\n\n## Our Principles\n- **Respect**: Treat everyone with dignity\n- **Collaboration**: Work together towards common goals\n- **Constructive**: Focus on solutions, not problems\n- **Inclusive**: Welcome diverse perspectives\n\n## Communication Standards\n- Use clear, respectful language\n- Listen actively to others\n- Provide constructive feedback\n- Share knowledge freely\n\n## Conflict Resolution\n1. Address issues directly and respectfully\n2. Seek to understand different viewpoints\n3. Involve mediators when needed\n4. Focus on solutions that benefit everyone"));
let investor = new_contact()
.name("Example Investor")
.save_contact();
let investors = new_group()
.name("Investors")
.description("A group for example inverstors of ourworld");
investors.add_contact(investor.id)
.save_group();
// === BOOKS ===
print("Creating books...");
let sustainability_book = save_book(new_book()
.title("Sustainability Handbook")
.description("Complete guide to sustainable living and practices")
.add_page("# Introduction to Sustainability\n\nSustainability is about meeting our present needs without compromising the ability of future generations to meet their own needs.\n\n## Key Principles\n- Environmental stewardship\n- Social equity\n- Economic viability\n\n## Why It Matters\nOur planet faces unprecedented challenges from climate change, resource depletion, and environmental degradation.")
.add_page("# Energy Efficiency\n\n## Home Energy Savings\n- LED lighting reduces energy consumption by 75%\n- Smart thermostats can save 10-15% on heating/cooling\n- Energy-efficient appliances make a significant difference\n\n## Renewable Energy\n- Solar panels: Clean electricity from sunlight\n- Wind power: Harnessing natural wind currents\n- Hydroelectric: Using water flow for energy\n\n## Transportation\n- Electric vehicles reduce emissions\n- Public transit decreases individual carbon footprint\n- Cycling and walking for short distances")
.add_page("# Waste Reduction\n\n## The 5 R's\n1. **Refuse**: Say no to unnecessary items\n2. **Reduce**: Use less of what you need\n3. **Reuse**: Find new purposes for items\n4. **Recycle**: Process materials into new products\n5. **Rot**: Compost organic waste\n\n## Practical Tips\n- Use reusable bags and containers\n- Buy products with minimal packaging\n- Repair instead of replacing\n- Donate items you no longer need")
.add_page("# Sustainable Food\n\n## Local and Seasonal\n- Support local farmers and reduce transport emissions\n- Eat seasonal produce for better nutrition and taste\n- Visit farmers markets and join CSAs\n\n## Plant-Based Options\n- Reduce meat consumption for environmental benefits\n- Explore diverse plant proteins\n- Grow your own herbs and vegetables\n\n## Food Waste Prevention\n- Plan meals and make shopping lists\n- Store food properly to extend freshness\n- Use leftovers creatively")
.add_toc_entry(new_toc_entry().title("Introduction to Sustainability").page(0))
.add_toc_entry(new_toc_entry().title("Energy Efficiency").page(1))
.add_toc_entry(new_toc_entry().title("Waste Reduction").page(2))
.add_toc_entry(new_toc_entry().title("Sustainable Food").page(3)));
let tech_guide_book = save_book(new_book()
.title("Green Technology Guide")
.description("Understanding and implementing green technologies")
.add_page("# Green Technology Overview\n\nGreen technology, also known as clean technology, refers to the use of science and technology to create products and services that are environmentally friendly.\n\n## Categories\n- Renewable energy systems\n- Energy efficiency technologies\n- Pollution prevention and cleanup\n- Sustainable materials and manufacturing\n\n## Benefits\n- Reduced environmental impact\n- Lower operating costs\n- Improved public health\n- Economic opportunities")
.add_page("# Solar Technology\n\n## How Solar Works\nSolar panels convert sunlight directly into electricity using photovoltaic cells.\n\n## Types of Solar Systems\n- **Grid-tied**: Connected to the electrical grid\n- **Off-grid**: Standalone systems with battery storage\n- **Hybrid**: Combination of grid-tied and battery backup\n\n## Installation Considerations\n- Roof orientation and shading\n- Local climate and sun exposure\n- Energy consumption patterns\n- Available incentives and rebates")
.add_page("# Smart Home Technology\n\n## Automation Benefits\n- Optimized energy usage\n- Enhanced comfort and convenience\n- Remote monitoring and control\n- Predictive maintenance\n\n## Key Technologies\n- Smart thermostats\n- Automated lighting systems\n- Energy monitoring devices\n- Smart appliances\n- Home energy management systems")
.add_toc_entry(new_toc_entry().title("Green Technology Overview").page(0))
.add_toc_entry(new_toc_entry().title("Solar Technology").page(1))
.add_toc_entry(new_toc_entry().title("Smart Home Technology").page(2)));
let community_book = save_book(new_book()
.title("Building Communities")
.description("Guide to creating sustainable and inclusive communities")
.add_page("# Community Building Fundamentals\n\n## What Makes a Strong Community?\n- Shared values and vision\n- Open communication channels\n- Mutual support and cooperation\n- Inclusive decision-making processes\n\n## Benefits of Strong Communities\n- Enhanced quality of life\n- Economic resilience\n- Social cohesion\n- Environmental stewardship")
.add_page("# Governance and Leadership\n\n## Collaborative Leadership\n- Distributed decision-making\n- Transparent processes\n- Accountability mechanisms\n- Conflict resolution systems\n\n## Community Engagement\n- Regular town halls and meetings\n- Digital participation platforms\n- Volunteer coordination\n- Feedback and improvement cycles")
.add_toc_entry(new_toc_entry().title("Community Building Fundamentals").page(0))
.add_toc_entry(new_toc_entry().title("Governance and Leadership").page(1)));
// === SLIDES ===
print("Creating slides...");
let climate_slides = save_slides(new_slides()
.title("Climate Change Awareness")
.description("Visual presentation on climate change impacts and solutions")
.add_slide("https://images.unsplash.com/photo-1569163139394-de4e4f43e4e3?w=1200", "Global Temperature Rise")
.add_slide("https://images.unsplash.com/photo-1578662996442-48f60103fc96?w=1200", "Melting Ice Caps")
.add_slide("https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200", "Extreme Weather Events")
.add_slide("https://images.unsplash.com/photo-1473341304170-971dccb5ac1e?w=1200", "Renewable Energy Solutions")
.add_slide("https://images.unsplash.com/photo-1497436072909-f5e4be1dffea?w=1200", "Sustainable Transportation"));
let innovation_slides = save_slides(new_slides()
.title("Innovation Showcase")
.description("Cutting-edge technologies for a sustainable future")
.add_slide("https://images.unsplash.com/photo-1518709268805-4e9042af2176?w=1200", "AI and Machine Learning")
.add_slide("https://images.unsplash.com/photo-1639322537228-f710d846310a?w=1200", "Blockchain Technology")
.add_slide("https://images.unsplash.com/photo-1581092160562-40aa08e78837?w=1200", "IoT and Smart Cities")
.add_slide("https://images.unsplash.com/photo-1581092918056-0c4c3acd3789?w=1200", "Quantum Computing")
.add_slide("https://images.unsplash.com/photo-1581092162384-8987c1d64718?w=1200", "Biotechnology Advances"));
let nature_slides = save_slides(new_slides()
.title("Biodiversity Gallery")
.description("Celebrating Earth's incredible biodiversity")
.add_slide("https://images.unsplash.com/photo-1564349683136-77e08dba1ef7?w=1200", "Tropical Rainforest")
.add_slide("https://images.unsplash.com/photo-1559827260-dc66d52bef19?w=1200", "Coral Reef Ecosystem")
.add_slide("https://images.unsplash.com/photo-1551698618-1dfe5d97d256?w=1200", "Arctic Wildlife")
.add_slide("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200", "Mountain Ecosystems"));
// === COLLECTIONS ===
print("Creating collections...");
let nature_collection = save_collection(new_collection()
.title("Nature & Environment")
.description("Beautiful images and resources about our natural world")
.add_image(nature1.id)
.add_image(nature2.id)
.add_image(nature3.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id)
.add_book(sustainability_book.id)
.add_slides(nature_slides.id));
let technology_collection = save_collection(new_collection()
.title("Sustainable Technology")
.description("Innovations driving positive change")
.add_image(tech1.id)
.add_image(tech2.id)
.add_pdf(pdf3.id)
.add_pdf(pdf4.id)
.add_markdown(md3.id)
.add_book(tech_guide_book.id)
.add_slides(innovation_slides.id));
let space_collection = save_collection(new_collection()
.title("Space & Cosmos")
.description("Exploring the universe and our place in it")
.add_image(space1.id)
.add_image(space2.id)
.add_pdf(pdf2.id)
.add_markdown(md2.id));
let community_collection = save_collection(new_collection()
.title("Community & Collaboration")
.description("Building better communities together")
.add_image(city1.id)
.add_pdf(pdf5.id)
.add_markdown(md4.id)
.add_book(community_book.id));
let climate_collection = save_collection(new_collection()
.title("Climate Action")
.description("Understanding and addressing climate change")
.add_slides(climate_slides.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id));
print("✅ OurWorld library created successfully!");
print("📚 Collections: 5");
print("🖼️ Images: 8");
print("📄 PDFs: 5");
print("📝 Markdown docs: 4");
print("📖 Books: 3");
print("🎞️ Slide shows: 3");

View File

@@ -0,0 +1,249 @@
// OurWorld Circle and Library Data
new_circle()
.title("Sikana")
.description("Creating a better world.")
.ws_url("ws://localhost:8092/ws")
.logo("🌍")
.save_circle();
let circle = get_circle();
print("--- Creating OurWorld Library ---");
// === IMAGES ===
print("Creating images...");
let nature1 = save_image(new_image()
.title("Mountain Sunrise")
.description("Breathtaking sunrise over mountain peaks")
.url("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800")
.width(800).height(600));
let nature2 = save_image(new_image()
.title("Ocean Waves")
.description("Powerful ocean waves crashing on rocks")
.url("https://images.unsplash.com/photo-1505142468610-359e7d316be0?w=800")
.width(800).height(600));
let nature3 = save_image(new_image()
.title("Forest Path")
.description("Peaceful path through ancient forest")
.url("https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800")
.width(800).height(600));
let tech1 = save_image(new_image()
.title("Solar Panels")
.description("Modern solar panel installation")
.url("https://images.unsplash.com/photo-1509391366360-2e959784a276?w=800")
.width(800).height(600));
let tech2 = save_image(new_image()
.title("Wind Turbines")
.description("Wind turbines generating clean energy")
.url("https://images.unsplash.com/photo-1466611653911-95081537e5b7?w=800")
.width(800).height(600));
let space1 = save_image(new_image()
.title("Earth from Space")
.description("Our beautiful planet from orbit")
.url("https://images.unsplash.com/photo-1446776877081-d282a0f896e2?w=800")
.width(800).height(600));
let space2 = save_image(new_image()
.title("Galaxy Spiral")
.description("Stunning spiral galaxy in deep space")
.url("https://images.unsplash.com/photo-1502134249126-9f3755a50d78?w=800")
.width(800).height(600));
let city1 = save_image(new_image()
.title("Smart City")
.description("Futuristic smart city at night")
.url("https://images.unsplash.com/photo-1480714378408-67cf0d13bc1f?w=800")
.width(800).height(600));
// === PDFs ===
print("Creating PDFs...");
let pdf1 = save_pdf(new_pdf()
.title("Climate Action Report 2024")
.description("Comprehensive analysis of global climate initiatives")
.url("https://www.ipcc.ch/site/assets/uploads/2018/02/ipcc_wg3_ar5_summary-for-policymakers.pdf")
.page_count(42));
let pdf2 = save_pdf(new_pdf()
.title("Sustainable Development Goals")
.description("UN SDG implementation guide")
.url("https://sdgs.un.org/sites/default/files/publications/21252030%20Agenda%20for%20Sustainable%20Development%20web.pdf")
.page_count(35));
let pdf3 = save_pdf(new_pdf()
.title("Renewable Energy Handbook")
.description("Technical guide to renewable energy systems")
.url("https://www.irena.org/-/media/Files/IRENA/Agency/Publication/2019/Oct/IRENA_Renewable-Energy-Statistics-2019.pdf")
.page_count(280));
let pdf4 = save_pdf(new_pdf()
.title("Blockchain for Good")
.description("How blockchain technology can solve global challenges")
.url("https://www.weforum.org/whitepapers/blockchain-beyond-the-hype")
.page_count(24));
let pdf5 = save_pdf(new_pdf()
.title("Future of Work Report")
.description("Analysis of changing work patterns and remote collaboration")
.url("https://www.mckinsey.com/featured-insights/future-of-work")
.page_count(156));
// === MARKDOWN DOCUMENTS ===
print("Creating markdown documents...");
let md1 = save_markdown(new_markdown()
.title("OurWorld Mission Statement")
.description("Our vision for a better world")
.content("# OurWorld Mission\n\n## Vision\nTo create a more sustainable, equitable, and connected world through technology and collaboration.\n\n## Values\n- **Sustainability**: Every decision considers environmental impact\n- **Inclusivity**: Technology that serves everyone\n- **Transparency**: Open source and open governance\n- **Innovation**: Pushing boundaries for positive change\n\n## Goals\n1. Reduce global carbon footprint by 50% by 2030\n2. Provide internet access to 1 billion underserved people\n3. Create 10 million green jobs worldwide\n4. Establish 1000 sustainable communities"));
let md2 = save_markdown(new_markdown()
.title("Getting Started Guide")
.description("How to join the OurWorld movement")
.content("# Getting Started with OurWorld\n\n## Welcome!\nThank you for joining our mission to create a better world.\n\n## First Steps\n1. **Explore**: Browse our projects and initiatives\n2. **Connect**: Join our community forums\n3. **Contribute**: Find ways to get involved\n4. **Learn**: Access our educational resources\n\n## Ways to Contribute\n- **Developers**: Contribute to open source projects\n- **Activists**: Organize local initiatives\n- **Educators**: Share knowledge and skills\n- **Investors**: Support sustainable ventures\n\n## Resources\n- [Community Forum](https://forum.ourworld.tf)\n- [Developer Portal](https://dev.ourworld.tf)\n- [Learning Hub](https://learn.ourworld.tf)"));
let md3 = save_markdown(new_markdown()
.title("Technology Roadmap 2024")
.description("Our technical development plans")
.content("# Technology Roadmap 2024\n\n## Q1 Objectives\n- Launch decentralized identity system\n- Deploy carbon tracking blockchain\n- Release mobile app v2.0\n\n## Q2 Objectives\n- Implement AI-powered resource optimization\n- Launch peer-to-peer energy trading platform\n- Deploy IoT sensor network\n\n## Q3 Objectives\n- Release virtual collaboration spaces\n- Launch digital twin cities pilot\n- Implement quantum-safe encryption\n\n## Q4 Objectives\n- Deploy autonomous governance systems\n- Launch global impact measurement platform\n- Release AR/VR sustainability training"));
let md4 = save_markdown(new_markdown()
.title("Community Guidelines")
.description("How we work together")
.content("# Community Guidelines\n\n## Our Principles\n- **Respect**: Treat everyone with dignity\n- **Collaboration**: Work together towards common goals\n- **Constructive**: Focus on solutions, not problems\n- **Inclusive**: Welcome diverse perspectives\n\n## Communication Standards\n- Use clear, respectful language\n- Listen actively to others\n- Provide constructive feedback\n- Share knowledge freely\n\n## Conflict Resolution\n1. Address issues directly and respectfully\n2. Seek to understand different viewpoints\n3. Involve mediators when needed\n4. Focus on solutions that benefit everyone"));
let investor = new_contact()
.name("Example Investor")
.save_contact();
let investors = new_group()
.name("Investors")
.description("A group for example inverstors of ourworld");
investors.add_contact(investor.id)
.save_group();
// === BOOKS ===
print("Creating books...");
let sustainability_book = save_book(new_book()
.title("Sustainability Handbook")
.description("Complete guide to sustainable living and practices")
.add_page("# Introduction to Sustainability\n\nSustainability is about meeting our present needs without compromising the ability of future generations to meet their own needs.\n\n## Key Principles\n- Environmental stewardship\n- Social equity\n- Economic viability\n\n## Why It Matters\nOur planet faces unprecedented challenges from climate change, resource depletion, and environmental degradation.")
.add_page("# Energy Efficiency\n\n## Home Energy Savings\n- LED lighting reduces energy consumption by 75%\n- Smart thermostats can save 10-15% on heating/cooling\n- Energy-efficient appliances make a significant difference\n\n## Renewable Energy\n- Solar panels: Clean electricity from sunlight\n- Wind power: Harnessing natural wind currents\n- Hydroelectric: Using water flow for energy\n\n## Transportation\n- Electric vehicles reduce emissions\n- Public transit decreases individual carbon footprint\n- Cycling and walking for short distances")
.add_page("# Waste Reduction\n\n## The 5 R's\n1. **Refuse**: Say no to unnecessary items\n2. **Reduce**: Use less of what you need\n3. **Reuse**: Find new purposes for items\n4. **Recycle**: Process materials into new products\n5. **Rot**: Compost organic waste\n\n## Practical Tips\n- Use reusable bags and containers\n- Buy products with minimal packaging\n- Repair instead of replacing\n- Donate items you no longer need")
.add_page("# Sustainable Food\n\n## Local and Seasonal\n- Support local farmers and reduce transport emissions\n- Eat seasonal produce for better nutrition and taste\n- Visit farmers markets and join CSAs\n\n## Plant-Based Options\n- Reduce meat consumption for environmental benefits\n- Explore diverse plant proteins\n- Grow your own herbs and vegetables\n\n## Food Waste Prevention\n- Plan meals and make shopping lists\n- Store food properly to extend freshness\n- Use leftovers creatively")
.add_toc_entry(new_toc_entry().title("Introduction to Sustainability").page(0))
.add_toc_entry(new_toc_entry().title("Energy Efficiency").page(1))
.add_toc_entry(new_toc_entry().title("Waste Reduction").page(2))
.add_toc_entry(new_toc_entry().title("Sustainable Food").page(3)));
let tech_guide_book = save_book(new_book()
.title("Green Technology Guide")
.description("Understanding and implementing green technologies")
.add_page("# Green Technology Overview\n\nGreen technology, also known as clean technology, refers to the use of science and technology to create products and services that are environmentally friendly.\n\n## Categories\n- Renewable energy systems\n- Energy efficiency technologies\n- Pollution prevention and cleanup\n- Sustainable materials and manufacturing\n\n## Benefits\n- Reduced environmental impact\n- Lower operating costs\n- Improved public health\n- Economic opportunities")
.add_page("# Solar Technology\n\n## How Solar Works\nSolar panels convert sunlight directly into electricity using photovoltaic cells.\n\n## Types of Solar Systems\n- **Grid-tied**: Connected to the electrical grid\n- **Off-grid**: Standalone systems with battery storage\n- **Hybrid**: Combination of grid-tied and battery backup\n\n## Installation Considerations\n- Roof orientation and shading\n- Local climate and sun exposure\n- Energy consumption patterns\n- Available incentives and rebates")
.add_page("# Smart Home Technology\n\n## Automation Benefits\n- Optimized energy usage\n- Enhanced comfort and convenience\n- Remote monitoring and control\n- Predictive maintenance\n\n## Key Technologies\n- Smart thermostats\n- Automated lighting systems\n- Energy monitoring devices\n- Smart appliances\n- Home energy management systems")
.add_toc_entry(new_toc_entry().title("Green Technology Overview").page(0))
.add_toc_entry(new_toc_entry().title("Solar Technology").page(1))
.add_toc_entry(new_toc_entry().title("Smart Home Technology").page(2)));
let community_book = save_book(new_book()
.title("Building Communities")
.description("Guide to creating sustainable and inclusive communities")
.add_page("# Community Building Fundamentals\n\n## What Makes a Strong Community?\n- Shared values and vision\n- Open communication channels\n- Mutual support and cooperation\n- Inclusive decision-making processes\n\n## Benefits of Strong Communities\n- Enhanced quality of life\n- Economic resilience\n- Social cohesion\n- Environmental stewardship")
.add_page("# Governance and Leadership\n\n## Collaborative Leadership\n- Distributed decision-making\n- Transparent processes\n- Accountability mechanisms\n- Conflict resolution systems\n\n## Community Engagement\n- Regular town halls and meetings\n- Digital participation platforms\n- Volunteer coordination\n- Feedback and improvement cycles")
.add_toc_entry(new_toc_entry().title("Community Building Fundamentals").page(0))
.add_toc_entry(new_toc_entry().title("Governance and Leadership").page(1)));
// === SLIDES ===
print("Creating slides...");
let climate_slides = save_slides(new_slides()
.title("Climate Change Awareness")
.description("Visual presentation on climate change impacts and solutions")
.add_slide("https://images.unsplash.com/photo-1569163139394-de4e4f43e4e3?w=1200", "Global Temperature Rise")
.add_slide("https://images.unsplash.com/photo-1578662996442-48f60103fc96?w=1200", "Melting Ice Caps")
.add_slide("https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200", "Extreme Weather Events")
.add_slide("https://images.unsplash.com/photo-1473341304170-971dccb5ac1e?w=1200", "Renewable Energy Solutions")
.add_slide("https://images.unsplash.com/photo-1497436072909-f5e4be1dffea?w=1200", "Sustainable Transportation"));
let innovation_slides = save_slides(new_slides()
.title("Innovation Showcase")
.description("Cutting-edge technologies for a sustainable future")
.add_slide("https://images.unsplash.com/photo-1518709268805-4e9042af2176?w=1200", "AI and Machine Learning")
.add_slide("https://images.unsplash.com/photo-1639322537228-f710d846310a?w=1200", "Blockchain Technology")
.add_slide("https://images.unsplash.com/photo-1581092160562-40aa08e78837?w=1200", "IoT and Smart Cities")
.add_slide("https://images.unsplash.com/photo-1581092918056-0c4c3acd3789?w=1200", "Quantum Computing")
.add_slide("https://images.unsplash.com/photo-1581092162384-8987c1d64718?w=1200", "Biotechnology Advances"));
let nature_slides = save_slides(new_slides()
.title("Biodiversity Gallery")
.description("Celebrating Earth's incredible biodiversity")
.add_slide("https://images.unsplash.com/photo-1564349683136-77e08dba1ef7?w=1200", "Tropical Rainforest")
.add_slide("https://images.unsplash.com/photo-1559827260-dc66d52bef19?w=1200", "Coral Reef Ecosystem")
.add_slide("https://images.unsplash.com/photo-1551698618-1dfe5d97d256?w=1200", "Arctic Wildlife")
.add_slide("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200", "Mountain Ecosystems"));
// === COLLECTIONS ===
print("Creating collections...");
let nature_collection = save_collection(new_collection()
.title("Nature & Environment")
.description("Beautiful images and resources about our natural world")
.add_image(nature1.id)
.add_image(nature2.id)
.add_image(nature3.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id)
.add_book(sustainability_book.id)
.add_slides(nature_slides.id));
let technology_collection = save_collection(new_collection()
.title("Sustainable Technology")
.description("Innovations driving positive change")
.add_image(tech1.id)
.add_image(tech2.id)
.add_pdf(pdf3.id)
.add_pdf(pdf4.id)
.add_markdown(md3.id)
.add_book(tech_guide_book.id)
.add_slides(innovation_slides.id));
let space_collection = save_collection(new_collection()
.title("Space & Cosmos")
.description("Exploring the universe and our place in it")
.add_image(space1.id)
.add_image(space2.id)
.add_pdf(pdf2.id)
.add_markdown(md2.id));
let community_collection = save_collection(new_collection()
.title("Community & Collaboration")
.description("Building better communities together")
.add_image(city1.id)
.add_pdf(pdf5.id)
.add_markdown(md4.id)
.add_book(community_book.id));
let climate_collection = save_collection(new_collection()
.title("Climate Action")
.description("Understanding and addressing climate change")
.add_slides(climate_slides.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id));
print("✅ OurWorld library created successfully!");
print("📚 Collections: 5");
print("🖼️ Images: 8");
print("📄 PDFs: 5");
print("📝 Markdown docs: 4");
print("📖 Books: 3");
print("🎞️ Slide shows: 3");

View File

@@ -0,0 +1,249 @@
// OurWorld Circle and Library Data
new_circle()
.title("Threefold DMCC")
.description("Creating a better world.")
.ws_url("ws://localhost:8093/ws")
.logo("🌍")
.save_circle();
let circle = get_circle();
print("--- Creating OurWorld Library ---");
// === IMAGES ===
print("Creating images...");
let nature1 = save_image(new_image()
.title("Mountain Sunrise")
.description("Breathtaking sunrise over mountain peaks")
.url("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800")
.width(800).height(600));
let nature2 = save_image(new_image()
.title("Ocean Waves")
.description("Powerful ocean waves crashing on rocks")
.url("https://images.unsplash.com/photo-1505142468610-359e7d316be0?w=800")
.width(800).height(600));
let nature3 = save_image(new_image()
.title("Forest Path")
.description("Peaceful path through ancient forest")
.url("https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800")
.width(800).height(600));
let tech1 = save_image(new_image()
.title("Solar Panels")
.description("Modern solar panel installation")
.url("https://images.unsplash.com/photo-1509391366360-2e959784a276?w=800")
.width(800).height(600));
let tech2 = save_image(new_image()
.title("Wind Turbines")
.description("Wind turbines generating clean energy")
.url("https://images.unsplash.com/photo-1466611653911-95081537e5b7?w=800")
.width(800).height(600));
let space1 = save_image(new_image()
.title("Earth from Space")
.description("Our beautiful planet from orbit")
.url("https://images.unsplash.com/photo-1446776877081-d282a0f896e2?w=800")
.width(800).height(600));
let space2 = save_image(new_image()
.title("Galaxy Spiral")
.description("Stunning spiral galaxy in deep space")
.url("https://images.unsplash.com/photo-1502134249126-9f3755a50d78?w=800")
.width(800).height(600));
let city1 = save_image(new_image()
.title("Smart City")
.description("Futuristic smart city at night")
.url("https://images.unsplash.com/photo-1480714378408-67cf0d13bc1f?w=800")
.width(800).height(600));
// === PDFs ===
print("Creating PDFs...");
let pdf1 = save_pdf(new_pdf()
.title("Climate Action Report 2024")
.description("Comprehensive analysis of global climate initiatives")
.url("https://www.ipcc.ch/site/assets/uploads/2018/02/ipcc_wg3_ar5_summary-for-policymakers.pdf")
.page_count(42));
let pdf2 = save_pdf(new_pdf()
.title("Sustainable Development Goals")
.description("UN SDG implementation guide")
.url("https://sdgs.un.org/sites/default/files/publications/21252030%20Agenda%20for%20Sustainable%20Development%20web.pdf")
.page_count(35));
let pdf3 = save_pdf(new_pdf()
.title("Renewable Energy Handbook")
.description("Technical guide to renewable energy systems")
.url("https://www.irena.org/-/media/Files/IRENA/Agency/Publication/2019/Oct/IRENA_Renewable-Energy-Statistics-2019.pdf")
.page_count(280));
let pdf4 = save_pdf(new_pdf()
.title("Blockchain for Good")
.description("How blockchain technology can solve global challenges")
.url("https://www.weforum.org/whitepapers/blockchain-beyond-the-hype")
.page_count(24));
let pdf5 = save_pdf(new_pdf()
.title("Future of Work Report")
.description("Analysis of changing work patterns and remote collaboration")
.url("https://www.mckinsey.com/featured-insights/future-of-work")
.page_count(156));
// === MARKDOWN DOCUMENTS ===
print("Creating markdown documents...");
let md1 = save_markdown(new_markdown()
.title("OurWorld Mission Statement")
.description("Our vision for a better world")
.content("# OurWorld Mission\n\n## Vision\nTo create a more sustainable, equitable, and connected world through technology and collaboration.\n\n## Values\n- **Sustainability**: Every decision considers environmental impact\n- **Inclusivity**: Technology that serves everyone\n- **Transparency**: Open source and open governance\n- **Innovation**: Pushing boundaries for positive change\n\n## Goals\n1. Reduce global carbon footprint by 50% by 2030\n2. Provide internet access to 1 billion underserved people\n3. Create 10 million green jobs worldwide\n4. Establish 1000 sustainable communities"));
let md2 = save_markdown(new_markdown()
.title("Getting Started Guide")
.description("How to join the OurWorld movement")
.content("# Getting Started with OurWorld\n\n## Welcome!\nThank you for joining our mission to create a better world.\n\n## First Steps\n1. **Explore**: Browse our projects and initiatives\n2. **Connect**: Join our community forums\n3. **Contribute**: Find ways to get involved\n4. **Learn**: Access our educational resources\n\n## Ways to Contribute\n- **Developers**: Contribute to open source projects\n- **Activists**: Organize local initiatives\n- **Educators**: Share knowledge and skills\n- **Investors**: Support sustainable ventures\n\n## Resources\n- [Community Forum](https://forum.ourworld.tf)\n- [Developer Portal](https://dev.ourworld.tf)\n- [Learning Hub](https://learn.ourworld.tf)"));
let md3 = save_markdown(new_markdown()
.title("Technology Roadmap 2024")
.description("Our technical development plans")
.content("# Technology Roadmap 2024\n\n## Q1 Objectives\n- Launch decentralized identity system\n- Deploy carbon tracking blockchain\n- Release mobile app v2.0\n\n## Q2 Objectives\n- Implement AI-powered resource optimization\n- Launch peer-to-peer energy trading platform\n- Deploy IoT sensor network\n\n## Q3 Objectives\n- Release virtual collaboration spaces\n- Launch digital twin cities pilot\n- Implement quantum-safe encryption\n\n## Q4 Objectives\n- Deploy autonomous governance systems\n- Launch global impact measurement platform\n- Release AR/VR sustainability training"));
let md4 = save_markdown(new_markdown()
.title("Community Guidelines")
.description("How we work together")
.content("# Community Guidelines\n\n## Our Principles\n- **Respect**: Treat everyone with dignity\n- **Collaboration**: Work together towards common goals\n- **Constructive**: Focus on solutions, not problems\n- **Inclusive**: Welcome diverse perspectives\n\n## Communication Standards\n- Use clear, respectful language\n- Listen actively to others\n- Provide constructive feedback\n- Share knowledge freely\n\n## Conflict Resolution\n1. Address issues directly and respectfully\n2. Seek to understand different viewpoints\n3. Involve mediators when needed\n4. Focus on solutions that benefit everyone"));
let investor = new_contact()
.name("Example Investor")
.save_contact();
let investors = new_group()
.name("Investors")
.description("A group for example inverstors of ourworld");
investors.add_contact(investor.id)
.save_group();
// === BOOKS ===
print("Creating books...");
let sustainability_book = save_book(new_book()
.title("Sustainability Handbook")
.description("Complete guide to sustainable living and practices")
.add_page("# Introduction to Sustainability\n\nSustainability is about meeting our present needs without compromising the ability of future generations to meet their own needs.\n\n## Key Principles\n- Environmental stewardship\n- Social equity\n- Economic viability\n\n## Why It Matters\nOur planet faces unprecedented challenges from climate change, resource depletion, and environmental degradation.")
.add_page("# Energy Efficiency\n\n## Home Energy Savings\n- LED lighting reduces energy consumption by 75%\n- Smart thermostats can save 10-15% on heating/cooling\n- Energy-efficient appliances make a significant difference\n\n## Renewable Energy\n- Solar panels: Clean electricity from sunlight\n- Wind power: Harnessing natural wind currents\n- Hydroelectric: Using water flow for energy\n\n## Transportation\n- Electric vehicles reduce emissions\n- Public transit decreases individual carbon footprint\n- Cycling and walking for short distances")
.add_page("# Waste Reduction\n\n## The 5 R's\n1. **Refuse**: Say no to unnecessary items\n2. **Reduce**: Use less of what you need\n3. **Reuse**: Find new purposes for items\n4. **Recycle**: Process materials into new products\n5. **Rot**: Compost organic waste\n\n## Practical Tips\n- Use reusable bags and containers\n- Buy products with minimal packaging\n- Repair instead of replacing\n- Donate items you no longer need")
.add_page("# Sustainable Food\n\n## Local and Seasonal\n- Support local farmers and reduce transport emissions\n- Eat seasonal produce for better nutrition and taste\n- Visit farmers markets and join CSAs\n\n## Plant-Based Options\n- Reduce meat consumption for environmental benefits\n- Explore diverse plant proteins\n- Grow your own herbs and vegetables\n\n## Food Waste Prevention\n- Plan meals and make shopping lists\n- Store food properly to extend freshness\n- Use leftovers creatively")
.add_toc_entry(new_toc_entry().title("Introduction to Sustainability").page(0))
.add_toc_entry(new_toc_entry().title("Energy Efficiency").page(1))
.add_toc_entry(new_toc_entry().title("Waste Reduction").page(2))
.add_toc_entry(new_toc_entry().title("Sustainable Food").page(3)));
let tech_guide_book = save_book(new_book()
.title("Green Technology Guide")
.description("Understanding and implementing green technologies")
.add_page("# Green Technology Overview\n\nGreen technology, also known as clean technology, refers to the use of science and technology to create products and services that are environmentally friendly.\n\n## Categories\n- Renewable energy systems\n- Energy efficiency technologies\n- Pollution prevention and cleanup\n- Sustainable materials and manufacturing\n\n## Benefits\n- Reduced environmental impact\n- Lower operating costs\n- Improved public health\n- Economic opportunities")
.add_page("# Solar Technology\n\n## How Solar Works\nSolar panels convert sunlight directly into electricity using photovoltaic cells.\n\n## Types of Solar Systems\n- **Grid-tied**: Connected to the electrical grid\n- **Off-grid**: Standalone systems with battery storage\n- **Hybrid**: Combination of grid-tied and battery backup\n\n## Installation Considerations\n- Roof orientation and shading\n- Local climate and sun exposure\n- Energy consumption patterns\n- Available incentives and rebates")
.add_page("# Smart Home Technology\n\n## Automation Benefits\n- Optimized energy usage\n- Enhanced comfort and convenience\n- Remote monitoring and control\n- Predictive maintenance\n\n## Key Technologies\n- Smart thermostats\n- Automated lighting systems\n- Energy monitoring devices\n- Smart appliances\n- Home energy management systems")
.add_toc_entry(new_toc_entry().title("Green Technology Overview").page(0))
.add_toc_entry(new_toc_entry().title("Solar Technology").page(1))
.add_toc_entry(new_toc_entry().title("Smart Home Technology").page(2)));
let community_book = save_book(new_book()
.title("Building Communities")
.description("Guide to creating sustainable and inclusive communities")
.add_page("# Community Building Fundamentals\n\n## What Makes a Strong Community?\n- Shared values and vision\n- Open communication channels\n- Mutual support and cooperation\n- Inclusive decision-making processes\n\n## Benefits of Strong Communities\n- Enhanced quality of life\n- Economic resilience\n- Social cohesion\n- Environmental stewardship")
.add_page("# Governance and Leadership\n\n## Collaborative Leadership\n- Distributed decision-making\n- Transparent processes\n- Accountability mechanisms\n- Conflict resolution systems\n\n## Community Engagement\n- Regular town halls and meetings\n- Digital participation platforms\n- Volunteer coordination\n- Feedback and improvement cycles")
.add_toc_entry(new_toc_entry().title("Community Building Fundamentals").page(0))
.add_toc_entry(new_toc_entry().title("Governance and Leadership").page(1)));
// === SLIDES ===
print("Creating slides...");
let climate_slides = save_slides(new_slides()
.title("Climate Change Awareness")
.description("Visual presentation on climate change impacts and solutions")
.add_slide("https://images.unsplash.com/photo-1569163139394-de4e4f43e4e3?w=1200", "Global Temperature Rise")
.add_slide("https://images.unsplash.com/photo-1578662996442-48f60103fc96?w=1200", "Melting Ice Caps")
.add_slide("https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200", "Extreme Weather Events")
.add_slide("https://images.unsplash.com/photo-1473341304170-971dccb5ac1e?w=1200", "Renewable Energy Solutions")
.add_slide("https://images.unsplash.com/photo-1497436072909-f5e4be1dffea?w=1200", "Sustainable Transportation"));
let innovation_slides = save_slides(new_slides()
.title("Innovation Showcase")
.description("Cutting-edge technologies for a sustainable future")
.add_slide("https://images.unsplash.com/photo-1518709268805-4e9042af2176?w=1200", "AI and Machine Learning")
.add_slide("https://images.unsplash.com/photo-1639322537228-f710d846310a?w=1200", "Blockchain Technology")
.add_slide("https://images.unsplash.com/photo-1581092160562-40aa08e78837?w=1200", "IoT and Smart Cities")
.add_slide("https://images.unsplash.com/photo-1581092918056-0c4c3acd3789?w=1200", "Quantum Computing")
.add_slide("https://images.unsplash.com/photo-1581092162384-8987c1d64718?w=1200", "Biotechnology Advances"));
let nature_slides = save_slides(new_slides()
.title("Biodiversity Gallery")
.description("Celebrating Earth's incredible biodiversity")
.add_slide("https://images.unsplash.com/photo-1564349683136-77e08dba1ef7?w=1200", "Tropical Rainforest")
.add_slide("https://images.unsplash.com/photo-1559827260-dc66d52bef19?w=1200", "Coral Reef Ecosystem")
.add_slide("https://images.unsplash.com/photo-1551698618-1dfe5d97d256?w=1200", "Arctic Wildlife")
.add_slide("https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200", "Mountain Ecosystems"));
// === COLLECTIONS ===
print("Creating collections...");
let nature_collection = save_collection(new_collection()
.title("Nature & Environment")
.description("Beautiful images and resources about our natural world")
.add_image(nature1.id)
.add_image(nature2.id)
.add_image(nature3.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id)
.add_book(sustainability_book.id)
.add_slides(nature_slides.id));
let technology_collection = save_collection(new_collection()
.title("Sustainable Technology")
.description("Innovations driving positive change")
.add_image(tech1.id)
.add_image(tech2.id)
.add_pdf(pdf3.id)
.add_pdf(pdf4.id)
.add_markdown(md3.id)
.add_book(tech_guide_book.id)
.add_slides(innovation_slides.id));
let space_collection = save_collection(new_collection()
.title("Space & Cosmos")
.description("Exploring the universe and our place in it")
.add_image(space1.id)
.add_image(space2.id)
.add_pdf(pdf2.id)
.add_markdown(md2.id));
let community_collection = save_collection(new_collection()
.title("Community & Collaboration")
.description("Building better communities together")
.add_image(city1.id)
.add_pdf(pdf5.id)
.add_markdown(md4.id)
.add_book(community_book.id));
let climate_collection = save_collection(new_collection()
.title("Climate Action")
.description("Understanding and addressing climate change")
.add_slides(climate_slides.id)
.add_pdf(pdf1.id)
.add_markdown(md1.id));
print("✅ OurWorld library created successfully!");
print("📚 Collections: 5");
print("🖼️ Images: 8");
print("📄 PDFs: 5");
print("📝 Markdown docs: 4");
print("📖 Books: 3");
print("🎞️ Slide shows: 3");

View File

@@ -0,0 +1,5 @@
{
"note": "This file is no longer used by the launcher binary.",
"new_usage": "Use command line arguments instead:",
"example": "cargo run --bin launcher -- --circle 02a1b2c3d4e5f6...:test_script.rhai --worker-binary ../target/release/worker --port 8080"
}

View File

@@ -0,0 +1,13 @@
// Simple test script for circle initialization
print("Initialization script running for circle: " + CIRCLE_PUBLIC_KEY);
print("Called by: " + CALLER_PUBLIC_KEY);
// Set some test variables
let test_value = 42;
let test_message = "Hello from " + CIRCLE_PUBLIC_KEY;
print("Test value: " + test_value);
print("Test message: " + test_message);
// Return a success message
"Initialization completed successfully"

View File

@@ -0,0 +1,153 @@
use sal_service_manager::create_service_manager;
use crate::Circle;
use crate::Launcher;
use std::sync::{Arc, Mutex};
const DEFAULT_REDIS_URL: &str = "redis://127.0.0.1:6379";
const DEFAULT_PORT: u16 = 8443;
pub struct LauncherBuilder {
circles: Vec<CircleBuilder>, // circle pk's and their init scripts
worker_binary: String, // path to worker binary
server_binary: String, // path to server binary
redis_url: String, // redis url
port: u16, // port to bind to
}
/// Creates a new launcher builder
pub fn new_launcher() -> LauncherBuilder {
LauncherBuilder::new()
}
impl LauncherBuilder {
/// Creates a new launcher builder
pub fn new() -> Self {
let server_binary = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent() // Go up one level from lib.rs
.unwrap()
.parent() // Go up one level from src
.unwrap()
.join("target/release/circles_server")
.to_string_lossy()
.to_string();
let worker_binary = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent() // Go up one level from lib.rs
.unwrap()
.parent() // Go up one level from src
.unwrap()
.join("target/release/worker")
.to_string_lossy()
.to_string();
Self {
circles: vec![],
worker_binary: worker_binary,
server_binary: server_binary,
redis_url: DEFAULT_REDIS_URL.to_string(),
port: DEFAULT_PORT,
}
}
/// Adds a circle by public key
pub fn add_circle(mut self, public_key: impl ToString) -> Self {
self.circles.push(CircleBuilder::new().public_key(public_key.to_string()));
self
}
/// Sets initialization script for the last added circle
pub fn add_init_script(mut self, script_path: impl ToString) -> Self {
if let Some(last_circle) = self.circles.last_mut() {
last_circle.init_script = Some(script_path.to_string());
}
self
}
/// Sets the worker binary path
pub fn worker_binary(mut self, path: impl ToString) -> Self {
// TODO: Validate path
self.worker_binary = path.to_string();
self
}
/// Sets the server binary path
pub fn server_binary(mut self, path: impl ToString) -> Self {
// TODO: Validate path
self.server_binary = path.to_string();
self
}
/// Sets the Redis URL
pub fn redis_url(mut self, url: impl ToString) -> Self {
// TODO: Validate URL
self.redis_url = url.to_string();
self
}
/// Sets the port
pub fn port(mut self, port: u16) -> Self {
// TODO: Validate port
self.port = port;
self
}
pub async fn build(self) -> Result<Launcher, Box<dyn std::error::Error>> {
if self.circles.is_empty() {
return Err("No circles configured. Use add_circle() to add circles.".into());
}
let service_manager = tokio::task::spawn_blocking(|| create_service_manager(None))
.await??;
Ok(Launcher {
service_manager: Arc::new(Mutex::new(service_manager)),
circles: self.circles.iter().map(|circle| circle.build()).collect(),
worker_binary: self.worker_binary,
server_binary: self.server_binary,
redis_url: self.redis_url,
port: self.port,
})
}
}
/// Check if a port is in use by any process.
/// Note: This only indicates that *something* is using the port,
/// not necessarily our WebSocket server. Should only be used as a fallback
/// when service manager status is unavailable.
async fn is_port_in_use(port: u16) -> bool {
use std::net::{TcpListener, SocketAddr};
let addr = SocketAddr::from(([127, 0, 0, 1], port));
TcpListener::bind(addr).is_err()
}
pub struct CircleBuilder {
public_key: String,
init_script: Option<String>,
}
impl CircleBuilder {
pub fn new() -> Self {
Self {
public_key: String::new(),
init_script: None,
}
}
pub fn public_key(mut self, public_key: String) -> Self {
self.public_key = public_key;
self
}
pub fn init_script(mut self, init_script: String) -> Self {
self.init_script = Some(init_script);
self
}
pub fn build(&self) -> Circle {
Circle {
public_key: self.public_key.clone(),
init_script: self.init_script.clone(),
}
}
}

View File

@@ -0,0 +1,98 @@
use clap::Parser;
use circles_launcher::{Circle, Launcher};
use sal_service_manager::create_service_manager;
use std::error::Error as StdError;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::{Arc, Mutex};
const DEFAULT_REDIS_URL: &str = "redis://127.0.0.1/";
// Newtype wrapper to satisfy the orphan rule
#[derive(Clone, Debug)]
pub struct CircleArg(Circle);
impl FromStr for CircleArg {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts: Vec<&str> = s.split(':').collect();
let circle = match parts.len() {
1 => {
// Validate public key
secp256k1::PublicKey::from_str(parts[0])
.map_err(|e| format!("Invalid public key '{}': {}", parts[0], e))?;
Circle {
public_key: parts[0].to_string(),
init_script: None,
}
}
2 => {
// Validate public key
secp256k1::PublicKey::from_str(parts[0])
.map_err(|e| format!("Invalid public key '{}': {}", parts[0], e))?;
Circle {
public_key: parts[0].to_string(),
init_script: Some(parts[1].to_string()),
}
}
_ => return Err(format!("Invalid circle format '{}'. Expected 'public_key' or 'public_key:init_script.rhai'", s)),
};
Ok(CircleArg(circle))
}
}
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct Args {
/// Port for the WebSocket server
#[arg(short, long, default_value = "443")]
pub port: u16,
/// Circle configurations: public_key[:init_script.rhai] (can be specified multiple times)
#[arg(short = 'c', long = "circle", required = true)]
pub circles: Vec<CircleArg>,
/// Redis URL
#[arg(long, default_value = DEFAULT_REDIS_URL)]
pub redis_url: String,
/// Worker binary path
#[arg(long, default_value = "./target/release/worker")]
pub worker_binary: PathBuf,
/// Server binary path
#[arg(long, default_value = "./target/release/server")]
pub server_binary: PathBuf,
/// Enable debug mode
#[arg(short, long)]
pub debug: bool,
/// Verbosity level
#[arg(short, long, action = clap::ArgAction::Count)]
pub verbose: u8,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn StdError>> {
let args = Args::parse();
// To build the launcher, its fields must be public, or a public constructor
// must be provided from the `circles_launcher` library.
let service_manager = tokio::task::spawn_blocking(|| create_service_manager(None))
.await??;
let launcher = Launcher {
service_manager: Arc::new(Mutex::new(service_manager)),
circles: args.circles.into_iter().map(|c| c.0).collect(),
worker_binary: args.worker_binary.to_string_lossy().into_owned(),
server_binary: args.server_binary.to_string_lossy().into_owned(),
redis_url: args.redis_url,
port: args.port,
};
launcher.launch().await?;
Ok(())
}

View File

@@ -0,0 +1,236 @@
use log::{info, debug};
use rhai_client::RhaiClientBuilder;
use sal_service_manager::{ServiceConfig as ServiceManagerConfig, ServiceStatus};
use std::sync::{Arc, Mutex};
mod builder;
pub use builder::*;
const SERVER_SERVICE_NAME: &str = "circle-ws-server";
pub struct Launcher {
pub service_manager: Arc<Mutex<Box<dyn sal_service_manager::ServiceManager>>>,
pub circles: Vec<Circle>,
pub worker_binary: String,
pub server_binary: String,
pub redis_url: String,
pub port: u16,
}
#[derive(Debug, Clone)]
pub struct Circle {
pub public_key: String,
pub init_script: Option<String>,
}
impl Circle {
pub fn service_name(&self) -> String {
format!("circle-worker-{}", self.public_key)
}
}
impl Launcher {
/// Launches all configured circles
pub async fn launch(&self) -> Result<(), Box<dyn std::error::Error>> {
self.launch_server().await?;
for circle in &self.circles {
println!("Launching circle {}", circle.public_key);
self.launch_circle(circle).await?;
}
Ok(())
}
// Launches the circles WebSocket server
async fn launch_server(&self) -> Result<(), Box<dyn std::error::Error>> {
// Check if service exists
let exists = tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
move || service_manager.lock().unwrap().exists(SERVER_SERVICE_NAME)
}).await??;
if !exists {
self.create_circle_server_service().await?;
}
// Check if the WebSocket server service is already running via service manager
let status = tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
move || service_manager.lock().unwrap().status(SERVER_SERVICE_NAME)
}).await??;
match status {
ServiceStatus::Running => {
println!("✓ WebSocket server service '{}' is already running", SERVER_SERVICE_NAME);
return Ok(());
}
ServiceStatus::Failed => {
println!("WebSocket server service '{}' exists but failed, removing it", SERVER_SERVICE_NAME);
if let Err(e) = tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
move || service_manager.lock().unwrap().remove(SERVER_SERVICE_NAME)
}).await? {
println!("Warning: Failed to remove failed service '{}': {}", SERVER_SERVICE_NAME, e);
return Err(e.into());
}
}
ServiceStatus::Unknown => {
println!("WebSocket server service '{}' exists but is in an unknown state, removing it", SERVER_SERVICE_NAME);
if let Err(e) = tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
move || service_manager.lock().unwrap().remove(SERVER_SERVICE_NAME)
}).await? {
println!("Warning: Failed to remove failed service '{}': {}", SERVER_SERVICE_NAME, e);
return Err(e.into());
}
}
ServiceStatus::Stopped => {
println!("WebSocket server service '{}' exists but is stopped, starting it", SERVER_SERVICE_NAME);
match tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
move || service_manager.lock().unwrap().start(SERVER_SERVICE_NAME)
}).await? {
Ok(_) => {
println!("✓ WebSocket server service '{}' started", SERVER_SERVICE_NAME);
return Ok(());
}
Err(e) => {
println!("Failed to start existing service, removing and recreating: {}", e);
if let Err(e) = tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
move || service_manager.lock().unwrap().remove(SERVER_SERVICE_NAME)
}).await? {
println!("Warning: Failed to remove problematic service '{}': {}", SERVER_SERVICE_NAME, e);
return Err(e.into());
}
}
}
}
}
// This part is reached if the service was Failed, Unknown or Stopped and then removed/failed to start.
// We need to create and start it.
println!("Creating and starting new WebSocket server service '{}'", SERVER_SERVICE_NAME);
self.create_circle_server_service().await?;
tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
move || service_manager.lock().unwrap().start(SERVER_SERVICE_NAME)
}).await??;
println!("✓ WebSocket server service '{}' started successfully", SERVER_SERVICE_NAME);
Ok(())
}
// Creates circles server service
async fn create_circle_server_service(&self) -> Result<(), Box<dyn std::error::Error>> {
let config = ServiceManagerConfig {
name: SERVER_SERVICE_NAME.to_string(),
binary_path: self.server_binary.clone(),
args: vec![
"--port".to_string(),
self.port.to_string(),
"--redis-url".to_string(),
self.redis_url.clone(),
],
working_directory: Some(std::env::current_dir()?.to_string_lossy().to_string()),
environment: std::env::vars().collect(),
auto_restart: true,
};
// Use spawn_blocking to avoid runtime conflicts
tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
move || service_manager.lock().unwrap().create(&config)
}).await??;
Ok(())
}
pub async fn launch_circle(&self, circle: &Circle) -> Result<(), Box<dyn std::error::Error>> {
info!("Launching circle {}", circle.public_key);
let config = ServiceManagerConfig {
name: circle.service_name(),
binary_path: self.worker_binary.clone(),
args: vec![circle.public_key.clone()],
auto_restart: true,
environment: std::env::vars().collect(),
working_directory: Some(std::env::current_dir()?.to_string_lossy().to_string()),
};
// Use spawn_blocking for service manager operations
let service_name = circle.service_name();
tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
let config = config.clone();
move || service_manager.lock().unwrap().create(&config)
}).await?
.map_err(|e| format!("Failed to create service manager: {}", e))?;
tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
let service_name = service_name.clone();
move || service_manager.lock().unwrap().start(&service_name)
}).await?
.map_err(|e| format!("Failed to start service manager: {}", e))?;
if let Some(init_script) = &circle.init_script {
send_init_script_to_worker(&circle.public_key, &init_script, &self.redis_url)
.await?;
}
Ok(())
}
/// Cleanup all services created by the launcher
pub async fn clean(&self) -> Result<(), Box<dyn std::error::Error>> {
tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
move || service_manager.lock().unwrap().remove(SERVER_SERVICE_NAME)
}).await??;
for circle in &self.circles {
self.clean_circle(&circle.public_key).await?;
}
println!("Cleanup completed.");
Ok(())
}
/// Cleanup all services created by the launcher
pub async fn clean_circle(&self, circle_public_key: &str) -> Result<(), Box<dyn std::error::Error>> {
let circle_key = circle_public_key.to_string();
match tokio::task::spawn_blocking({
let service_manager = Arc::clone(&self.service_manager);
move || service_manager.lock().unwrap().remove(&circle_key)
}).await? {
Ok(_) => Ok(()),
Err(e) => Err(e.into()),
}
}
}
async fn send_init_script_to_worker(
public_key: &str,
init_script: &str,
redis_url: &str,
) -> Result<(), Box<dyn std::error::Error>> {
println!("Sending initialization script '{}' to worker for circle: {}", init_script, public_key);
// Create RhaiClient and send script
let client = RhaiClientBuilder::new()
.redis_url(redis_url)
.caller_id("launcher")
.build()?;
client.new_play_request()
.recipient_id(&format!("rhai_tasks:{}", public_key))
.script(init_script)
.submit()
.await?;
println!("Successfully sent initialization script to worker for circle: {}", public_key);
Ok(())
}

View File

@@ -0,0 +1,173 @@
use futures_util::{SinkExt, StreamExt};
use circles_launcher::{new_launcher, setup_multi_circle_server, shutdown_circles, Args, CircleConfig};
use secp256k1::Secp256k1;
use tokio_tungstenite::connect_async;
use url::Url;
use std::str::FromStr;
#[tokio::test]
async fn test_launcher_builder_pattern() {
// Test the new builder pattern API
let secp = Secp256k1::new();
let (secret_key, public_key) = secp.generate_keypair(&mut secp256k1::rand::thread_rng());
let public_key_str = public_key.to_string();
// Use the builder pattern to create a launcher
let launcher = new_launcher()
.add_circle(&public_key_str)
.port(8088)
.redis_url("redis://127.0.0.1:6379")
.worker_binary("../target/debug/worker") // Use debug for tests
.enable_auth(false);
// Note: We can't easily test the full launch in unit tests since it requires
// actual binaries and Redis. This test verifies the builder pattern works.
// Verify the builder created the launcher correctly
// (This is more of a compilation test than a runtime test)
assert!(true, "Builder pattern works correctly");
}
#[tokio::test]
async fn test_circle_config_parsing() {
// Test parsing circle configurations from strings
let public_key_only = "02a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890";
let config = CircleConfig::from_str(public_key_only).expect("Failed to parse public key only");
assert_eq!(config.public_key, public_key_only);
assert!(config.init_script.is_none());
// Test with init script
let with_script = "02a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890:init.rhai";
let config = CircleConfig::from_str(with_script).expect("Failed to parse with script");
assert_eq!(config.public_key, public_key_only);
assert_eq!(config.init_script, Some("init.rhai".to_string()));
// Test invalid format
let invalid = "invalid:too:many:colons";
let result = CircleConfig::from_str(invalid);
assert!(result.is_err(), "Should fail with invalid format");
}
#[tokio::test]
async fn test_args_structure() {
// Test that Args structure works correctly with the new API
let secp = Secp256k1::new();
let (_, public_key) = secp.generate_keypair(&mut secp256k1::rand::thread_rng());
let public_key_str = public_key.to_string();
let args = Args {
port: 8089,
circles: vec![public_key_str.clone()],
redis_url: "redis://127.0.0.1:6379".to_string(),
enable_auth: false,
worker_binary: Some("../target/debug/worker".to_string()),
debug: true,
verbose: 1,
};
// Verify args structure
assert_eq!(args.port, 8089);
assert_eq!(args.circles.len(), 1);
assert_eq!(args.circles[0], public_key_str);
assert!(!args.enable_auth);
assert!(args.worker_binary.is_some());
}
#[tokio::test]
async fn test_setup_multi_circle_server_validation() {
// Test validation in setup_multi_circle_server
let args = Args {
port: 8090,
circles: vec![], // Empty circles should cause error
redis_url: "redis://127.0.0.1:6379".to_string(),
enable_auth: false,
worker_binary: None, // Missing worker binary should cause error
debug: true,
verbose: 0,
};
// This should fail due to missing worker binary
let result = setup_multi_circle_server(&args).await;
assert!(result.is_err(), "Should fail with missing worker binary");
if let Err(e) = result {
let error_msg = e.to_string();
assert!(
error_msg.contains("Worker binary path is required"),
"Error should mention missing worker binary, got: {}",
error_msg
);
}
}
#[tokio::test]
async fn test_circle_config_validation() {
// Test that invalid public keys are rejected
let invalid_key = "not_a_valid_public_key";
let result = CircleConfig::from_str(invalid_key);
assert!(result.is_err(), "Should reject invalid public key");
// Test valid public key format
let valid_key = "02a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890";
let result = CircleConfig::from_str(valid_key);
assert!(result.is_ok(), "Should accept valid public key");
}
#[tokio::test]
async fn test_launcher_cleanup_functionality() {
// Test that cleanup functionality exists and can be called
// Note: This doesn't test actual cleanup since we don't have running services
use circles_launcher::cleanup_launcher;
// This should not panic and should handle the case where no services exist
let result = cleanup_launcher().await;
// It's OK if this fails due to no services - we're just testing the API exists
let _ = result;
assert!(true, "Cleanup function exists and can be called");
}
// Integration test that would require actual binaries and Redis
// Commented out since it requires external dependencies
/*
#[tokio::test]
#[ignore] // Use `cargo test -- --ignored` to run this test
async fn test_full_launcher_integration() {
// This test requires:
// 1. Redis server running on localhost:6379
// 2. Worker binary built at ../target/debug/worker
// 3. WebSocket server binary built at ../target/debug/circles_server
let secp = Secp256k1::new();
let (_, public_key) = secp.generate_keypair(&mut secp256k1::rand::thread_rng());
let public_key_str = public_key.to_string();
let args = Args {
port: 8091,
circles: vec![public_key_str.clone()],
redis_url: "redis://127.0.0.1:6379".to_string(),
enable_auth: false,
worker_binary: Some("../target/debug/worker".to_string()),
debug: true,
verbose: 1,
};
// Setup the multi-circle server
let result = setup_multi_circle_server(&args).await;
assert!(result.is_ok(), "Failed to setup multi-circle server: {:?}", result.err());
let (running_circles, outputs) = result.unwrap();
// Verify outputs
assert_eq!(outputs.len(), 1);
assert_eq!(outputs[0].public_key, public_key_str);
// Test WebSocket connection
let ws_url = &outputs[0].ws_url;
let connection_result = connect_async(ws_url).await;
assert!(connection_result.is_ok(), "Failed to connect to WebSocket");
// Cleanup
shutdown_circles(running_circles).await;
}
*/