Skip to content

Commit

Permalink
feat: add disk provider
Browse files Browse the repository at this point in the history
  • Loading branch information
veryard committed Nov 4, 2024
1 parent e58c09c commit f2318a3
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 10 deletions.
6 changes: 6 additions & 0 deletions packages/client-api/src/providers/create-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import type {
WeatherProviderConfig,
WeatherProvider,
} from './weather/weather-provider-types';
import { createDiskProvider } from './disk/create-disk-provider';
import type { DiskProvider, DiskProviderConfig } from './disk/disk-provider-types';

export interface ProviderConfigMap {
battery: BatteryProviderConfig;
Expand All @@ -63,6 +65,7 @@ export interface ProviderConfigMap {
network: NetworkProviderConfig;
weather: WeatherProviderConfig;
keyboard: KeyboardProviderConfig;
disk: DiskProviderConfig;
}

export interface ProviderMap {
Expand All @@ -77,6 +80,7 @@ export interface ProviderMap {
network: NetworkProvider;
weather: WeatherProvider;
keyboard: KeyboardProvider;
disk: DiskProvider;
}

export type ProviderType = keyof ProviderConfigMap;
Expand Down Expand Up @@ -122,6 +126,8 @@ export function createProvider<T extends ProviderConfig>(
return createWeatherProvider(config) as any;
case 'keyboard':
return createKeyboardProvider(config) as any;
case 'disk':
return createDiskProvider(config) as any;
default:
throw new Error('Not a supported provider type.');
}
Expand Down
30 changes: 30 additions & 0 deletions packages/client-api/src/providers/disk/create-disk-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { z } from 'zod';

import { createBaseProvider } from '../create-base-provider';
import { onProviderEmit } from '~/desktop';
import type {
DiskOutput,
DiskProvider,
DiskProviderConfig,
} from './disk-provider-types';

const diskProviderConfigSchema = z.object({
type: z.literal('disk'),
refreshInterval: z.coerce.number().default(60 * 1000),
});

export function createDiskProvider(
config: DiskProviderConfig,
): DiskProvider {
const mergedConfig = diskProviderConfigSchema.parse(config);

return createBaseProvider(mergedConfig, async queue => {
return onProviderEmit<DiskOutput>(mergedConfig, ({ result }) => {
if ('error' in result) {
queue.error(result.error);
} else {
queue.output(result.output);
}
});
});
}
26 changes: 26 additions & 0 deletions packages/client-api/src/providers/disk/disk-provider-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Provider } from '../create-base-provider';

export interface DiskProviderConfig {
type: 'disk';

/**
* How often this provider refreshes in milliseconds.
*/
refreshInterval?: number;
}

export type DiskProvider = Provider<DiskProviderConfig, DiskOutput>;

export interface Disk {
name: string;
fileSystem: string;
mountPoint: string;
totalSpace: number;
availableSpace: number;
isRemovable: boolean;
diskType: string;
}

export interface DiskOutput {
disks: Disk[];
}
1 change: 1 addition & 0 deletions packages/client-api/src/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './glazewm/glazewm-provider-types';
export * from './host/host-provider-types';
export * from './ip/ip-provider-types';
export * from './keyboard/keyboard-provider-types';
export * from './disk/disk-provider-types';
export * from './komorebi/komorebi-provider-types';
export * from './memory/memory-provider-types';
export * from './network/network-provider-types';
Expand Down
103 changes: 103 additions & 0 deletions packages/desktop/src/providers/disk/disk_provider.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use std::{any::Any, sync::Arc};

use serde::{Deserialize, Serialize};
use sysinfo::{Disk, Disks};
use tokio::sync::Mutex;

use crate::{
common::{to_iec_bytes, to_si_bytes},
impl_interval_provider,
providers::ProviderOutput,
};

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct DiskProviderConfig {
pub refresh_interval: u64,
}

#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DiskOutput {
pub disks: Vec<DiskInner>,
}

#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DiskInner {
pub name: String,
pub file_system: String,
pub mount_point: String,
pub total_space: DiskSizeMeasure,
pub available_space: DiskSizeMeasure,
pub is_removable: bool,
pub disk_type: String,
}

pub struct DiskProvider {
config: DiskProviderConfig,
system: Arc<Mutex<Disks>>,
}

#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DiskSizeMeasure {
pub bytes: u64,
pub si_value: f64,
pub si_unit: String,
pub iec_value: f64,
pub iec_unit: String,
}

impl DiskProvider {
pub fn new(
config: DiskProviderConfig,
system: Arc<Mutex<Disks>>,
) -> DiskProvider {
DiskProvider { config, system }
}

fn refresh_interval_ms(&self) -> u64 {
self.config.refresh_interval
}

async fn run_interval(&self) -> anyhow::Result<ProviderOutput> {
let mut disks = self.system.lock().await;
disks.refresh();

let list: Vec<DiskInner> = disks
.iter()
.map(|disk| -> anyhow::Result<DiskInner> {
Ok(DiskInner {
name: disk.name().to_string_lossy().to_string(),
file_system: disk.file_system().to_string_lossy().to_string(),
mount_point: disk.mount_point().to_string_lossy().to_string(),
total_space: Self::to_disk_size_measure(disk.total_space())?,
available_space: Self::to_disk_size_measure(
disk.available_space(),
)?,
is_removable: disk.is_removable(),
disk_type: disk.kind().to_string(),
})
})
.collect::<anyhow::Result<Vec<DiskInner>>>()?;

let output = DiskOutput { disks: list };
Ok(ProviderOutput::Disk(output))
}

fn to_disk_size_measure(bytes: u64) -> anyhow::Result<DiskSizeMeasure> {
let (si_value, si_unit) = to_si_bytes(bytes as f64);
let (iec_value, iec_unit) = to_iec_bytes(bytes as f64);

Ok(DiskSizeMeasure {
bytes,
si_value,
si_unit,
iec_value,
iec_unit,
})
}
}

impl_interval_provider!(DiskProvider, true);
3 changes: 3 additions & 0 deletions packages/desktop/src/providers/disk/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod disk_provider;

pub use disk_provider::*;
1 change: 1 addition & 0 deletions packages/desktop/src/providers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod battery;
mod cpu;
mod disk;
mod host;
mod ip;
#[cfg(windows)]
Expand Down
7 changes: 4 additions & 3 deletions packages/desktop/src/providers/provider_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use serde::Deserialize;

use super::{
battery::BatteryProviderConfig, cpu::CpuProviderConfig,
host::HostProviderConfig, ip::IpProviderConfig,
memory::MemoryProviderConfig, network::NetworkProviderConfig,
weather::WeatherProviderConfig,
disk::DiskProviderConfig, host::HostProviderConfig,
ip::IpProviderConfig, memory::MemoryProviderConfig,
network::NetworkProviderConfig, weather::WeatherProviderConfig,
};
#[cfg(windows)]
use super::{
Expand All @@ -21,6 +21,7 @@ pub enum ProviderConfig {
#[cfg(windows)]
Komorebi(KomorebiProviderConfig),
Memory(MemoryProviderConfig),
Disk(DiskProviderConfig),
Network(NetworkProviderConfig),
Weather(WeatherProviderConfig),
#[cfg(windows)]
Expand Down
4 changes: 3 additions & 1 deletion packages/desktop/src/providers/provider_manager.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{collections::HashMap, sync::Arc};

use sysinfo::{Networks, System};
use sysinfo::{Disks, Networks, System};
use tauri::AppHandle;
use tokio::sync::Mutex;
use tracing::warn;
Expand All @@ -12,6 +12,7 @@ use super::{ProviderConfig, ProviderRef};
pub struct SharedProviderState {
pub sysinfo: Arc<Mutex<System>>,
pub netinfo: Arc<Mutex<Networks>>,
pub diskinfo: Arc<Mutex<Disks>>,
}

/// Manages the creation and cleanup of providers.
Expand All @@ -29,6 +30,7 @@ impl ProviderManager {
shared_state: SharedProviderState {
sysinfo: Arc::new(Mutex::new(System::new_all())),
netinfo: Arc::new(Mutex::new(Networks::new_with_refreshed_list())),
diskinfo: Arc::new(Mutex::new(Disks::new_with_refreshed_list())),
},
}
}
Expand Down
6 changes: 4 additions & 2 deletions packages/desktop/src/providers/provider_output.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use serde::Serialize;

use super::{
battery::BatteryOutput, cpu::CpuOutput, host::HostOutput, ip::IpOutput,
memory::MemoryOutput, network::NetworkOutput, weather::WeatherOutput,
battery::BatteryOutput, cpu::CpuOutput, disk::DiskOutput,
host::HostOutput, ip::IpOutput, memory::MemoryOutput,
network::NetworkOutput, weather::WeatherOutput,
};
#[cfg(windows)]
use super::{keyboard::KeyboardOutput, komorebi::KomorebiOutput};
Expand All @@ -17,6 +18,7 @@ pub enum ProviderOutput {
#[cfg(windows)]
Komorebi(KomorebiOutput),
Memory(MemoryOutput),
Disk(DiskOutput),
Network(NetworkOutput),
Weather(WeatherOutput),
#[cfg(windows)]
Expand Down
11 changes: 7 additions & 4 deletions packages/desktop/src/providers/provider_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ use tokio::{
use tracing::{info, warn};

use super::{
battery::BatteryProvider, cpu::CpuProvider, host::HostProvider,
ip::IpProvider, memory::MemoryProvider, network::NetworkProvider,
weather::WeatherProvider, Provider, ProviderConfig, ProviderOutput,
SharedProviderState,
battery::BatteryProvider, cpu::CpuProvider, disk::DiskProvider,
host::HostProvider, ip::IpProvider, memory::MemoryProvider,
network::NetworkProvider, weather::WeatherProvider, Provider,
ProviderConfig, ProviderOutput, SharedProviderState,
};
#[cfg(windows)]
use super::{keyboard::KeyboardProvider, komorebi::KomorebiProvider};
Expand Down Expand Up @@ -176,6 +176,9 @@ impl ProviderRef {
ProviderConfig::Memory(config) => {
Box::new(MemoryProvider::new(config, shared_state.sysinfo.clone()))
}
ProviderConfig::Disk(config) => {
Box::new(DiskProvider::new(config, shared_state.diskinfo.clone()))
}
ProviderConfig::Network(config) => Box::new(NetworkProvider::new(
config,
shared_state.netinfo.clone(),
Expand Down

0 comments on commit f2318a3

Please sign in to comment.