wspr_cdk 0.0.9

This crate provides an abstraction that allows you to do analysis on wspr's real time spot data.
Documentation
# WSPR CDK

`wspr_cdk` provides an abstraction for accessing and analyzing **WSPR** (_Weak Signal Propagation Reporter_) real-time spot data. This crate allows you to perform queries and fetch data from the WSPR database with ease.

## Prerequisites

When running the application, ensure that the `service_account.json` file has been set up correctly. This file contains the authentication _credentials_ needed to access the **Google Drive API**.

- If this file is _missing_ or _incorrectly configured_, you will encounter an authentication error when attempting to upload files to Google Drive.

Here's a step-by-step guide to ensure proper setup:

1.  **Create a Service Account**:
    - Go to the Google Cloud Console.
    - Navigate to the IAM & Admin > Service Accounts page.
    - Click "Create Service Account".
    - Fill out the necessary details and click "Create".
2.  **Generate a JSON Key**:

    - After creating the service account, click on the service account you created.
    - Go to the "Keys" tab.
    - Click "Add Key", then select "Create new key".
    - Choose **JSON** as the key type and click "Create". This will download a JSON file containing your credentials.

3.  **Provide Necessary Permissions**:
    - Ensure that the service account has the required permissions to access Google Drive. You can grant the necessary permissions by assigning the appropriate roles to the service account.
4.  **Configure Environment**:
    - Place the downloaded `service_account.json` file in the appropriate location accessible to your application. Ensure that the file is named exactly `service_account.json`.
    - If running the application in a Docker container, make sure the `service_account.json` file is _mounted_ into the container at runtime.

These steps should ensure that the `service_account.json` file is correctly set up, thus allowing the `server` module to **authenticate** with Google Cloud successfully and avoid encountering the authentication _error mentioned_.

### Usage

- To run the **Python** server, use:

```sh
docker run -it wspr_cdk python ./hyper/hyper/server.py --interval 5
```

- To run the **Rust** server, use:

```sh
docker run -e ROCKET_ADDRESS=0.0.0.0 -e ROCKET_PORT=8000 -it wspr_cdk rust
```

## Features

- Fetch **WSPR** spot data in various formats (**JSON**, **JSONCompact**, **JSONEachRow**)
- Easy integration with **Tokio** for asynchronous operations
- Abstractions to manage session state and dispatch actions to the **ClickHouse** client
- **Server component** for accessing and sharing real-time data via HTTP

### Upcoming Features

- **Mutual TLS** for secure client-server communications
- **SSL (OpenSSL)** support for encrypted data transfer

## Installation

To use this crate, add `wspr_cdk` to your `Cargo.toml`:

```toml
[dependencies]
wspr_cdk = "0.0.9"
```

## Environment Variable

Before using the crate, ensure you set the following environment variable:

```sh
export BASE_URL=http://db1.wspr.live/
```

## Usage

Here are some examples of how to use the `wspr_cdk` crate:

```rust
#![allow(unused)]

use chrono::NaiveDateTime;
use wspr::{services::prelude::*, state::prelude::*};

#[tokio::main]
async fn main() {
    // Initialize the ClickHouse client state
    let mut state = ClickHouseClient::init();
    let session = session_manager::SessionManager::new();

    // Dispatch a GET request to fetch data in JSON format
    ClickHouseClient::dispatch(&mut state, ClickHouseAction::Get, "10", "JSON").await;

    // Print the state after fetching data
    println!("\n{:#?}\n", state);

    // Example of fetching data by ID
    ClickHouseClient::dispatch(&mut state, ClickHouseAction::GetById(1));
    println!("\n[OUTPUT]: {:?}", state);

    // Example of serializing response to JSON
    let json_response = serde_json::to_string_pretty(&response).unwrap();
    println!("{}", json_response);
}
```

### Example Query

```sh
wget -q -O - "http://db1.wspr.live/?query=SELECT * FROM wspr.rx LIMIT 5 FORMAT JSON;"`
```

### Sample Output

```sh
Fetching all records...

ClickHouseState {
    DATA: [
        WsprSpot {
            id: 7766261671,
            time: 2024-05-29T17:30:00,
            band: -1,
            rx_sign: "F6CWA",
            rx_lat: 48.021,
            rx_lon: -4.125,
            rx_loc: "IN78wa",
            tx_sign: "DL7NN",
            tx_lat: 50.771,
            tx_lon: 12.708,
            tx_loc: "JO60is",
            distance: 1253,
            azimuth: 262,
            rx_azimuth: 69,
            frequency: 137433,
            power: 30,
            snr: -18,
            drift: 0,
            version: "2.6.1",
            code: 2,
        },
    ],
    STATUS: "Fetching all records.",
}
```

## Server Component

The server component allows you to access and share real-time WSPR data via HTTP. Below is a snippet of the server component source code:

```rust
#[macro_use]
extern crate rocket;

use anyhow::Error;
use rocket::http::Status;
use rocket::response::{content, status};
use rocket::serde::json::Json;
use serde::{Deserialize, Serialize};
use std::result::Result::{Err, Ok};

// Required [modules].
use wspr_cdk::{services::prelude::*, state::prelude::*};

/// Get all <wspr> spots.
#[get("/api/spots")]
async fn get_wspr_spots() -> Result<Json<Vec<WsprSpot>>, status::Custom<String>> {
    let mut state = ClickHouseClient::init();
    let _session = session_manager::SessionManager::new();

    match ClickHouseClient::dispatch(&mut state, ClickHouseAction::Get, "10", "JSON").await {
        Ok(Some(spots)) => Ok(Json(spots)),
        Ok(None) => Err(status::Custom(Status::NotFound, "No spots found".into())),
        Err(e) => Err(status::Custom(
            Status::InternalServerError,
            format!("Failed to fetch spots: {:?}", e),
        )),
    }
}

#[launch]
#[rocket::main]
async fn rocket() -> _ {
    rocket::build().mount("/", routes![get_wspr_spots])
}
```

### Sample cURL Request

To fetch WSPR spots using the server component, you can use the following cURL command:

```sh
curl -X GET http://localhost:8000/api/spots
```

## Client-Side Usage Example

You can also fetch WSPR data using client-side JavaScript. Here is a sample implementation:

```html
<!doctype html>
<html>
  <head>
    <title>WSPR Spots</title>
  </head>
  <body>
    <div id="demo"></div>

    <script>
      const content = document.getElementById("demo");
      async function getData() {
        let response = await fetch("http://localhost:8000/api/spots");
        let raw = await response.json();

        for (let i of raw) {
          console.log(i);
          content.innerHTML += `
                    <h2>Spot id: ${i.id}</h2>
                    <p>Time: ${i.time}</p>
                    <p>Band: ${i.band}</p>
                `;
        }
      }
      getData();
    </script>
  </body>
</html>
```

## WSPR Guidelines

**Disclaimer**: The dataset contains the raw **spot** data as reported, saved, and published by _wsprnet.org_. Therefore, there might be **duplicates**, **false** spots, and other **errors** in the data. Keep this in mind when you see something strange. You are allowed to use the services provided on **wspr.live** for your own research and projects, as long as the results are accessible **free of charge for everyone**. You are **NOT** allowed to use this service for any _**commercial**_ or _**profit-oriented**_ use cases. The complete WSPR infrastructure is maintained by volunteers in their spare time, so there are no guarantees on the correctness, availability, or stability of these services.

## License

This project is licensed under the BSD License. See the LICENSE file for details.

## Contribution

Contributions are **welcome**! Please submit issues or pull requests as needed. Ensure that your contributions comply with the licensing and guidelines set forth.

## Acknowledgments

Special thanks to the WSPR community for providing access to the data and maintaining the infrastructure.

## Docker Image

The `wspr_cdk` is also available as a Docker image:

```sh
docker pull lexaraprime/wspr_cdk:master
```

You can find it on Docker Hub: [lexaraprime/wspr_cdk](https://hub.docker.com/layers/lexaraprime/wspr_cdk/master/images/sha256-c869961d9a8413bf8ee562c3507632aeaa4b6e720a97792e7eef5ad984437872?context=repo)

---

This documentation is also available as a crate on [crates.io](https://crates.io/)