Skip to content

Commit

Permalink
Text to speech
Browse files Browse the repository at this point in the history
Systtray Balloon
Beep
WinBeep
Refactore clipboard
  • Loading branch information
fakoua committed Dec 30, 2023
1 parent 56e15d4 commit 5e0b17a
Show file tree
Hide file tree
Showing 9 changed files with 243 additions and 72 deletions.
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@ DenoPilot is a Windows Desktop automation module for Deno, written in TypeScript
* [Key Features](#key-features)
* [Getting Started](#getting-started)
* [Window Actions](#window-actions)
* [byTitleExact](#bytitleexact-finds-a-window-with-an-exact-title-to-execute-actions)
* [byTitleContains](#bytitlecontains-finds-a-window-with-an-exact-title-to-execute-actions)
* [byTitleStartsWith](#bytitlestartswith-finds-a-window-with-a-title-starting-with-specified-text-to-execute-actions)
* [byTitleEndsWith](#bytitleendswith-finds-a-window-with-a-title-ending-with-specified-text-to-execute-actions)
* [byProcessName](#byprocessname-finds-a-window-associated-with-a-specified-process-name-to-execute-actions)
* [byProcessId](#byprocessid-finds-a-window-associated-with-a-specified-process-id-to-execute-actions)
* [byActiveWindow](#byactivewindow-finds-the-active-window-to-execute-an-action)
* [Keyboard Actions](#keyboard-actions)
* [Mouse Actions](#mouse-actions)
* [Clipboard Actions](#clipboard-actions)
* [System](#system-actions)
* [License](#license)

## Key Features:
Expand All @@ -26,9 +33,9 @@ Simulate keyboard strokes, enabling automated data input or interaction with app

Control the mouse, including movement, left and right clicks, and scrolling.

### Clipboard Management:
### System Actions:

Manipulate the clipboard content, facilitating seamless data transfer between applications.
System actions including beeps, speak, clipboard, tray ballon and notifications.

### Use Cases:

Expand Down Expand Up @@ -136,16 +143,16 @@ await win.byProcessId(1234).max();

-------------

#### activeWindow: Finds the active window to execute an action.
#### byActiveWindow: Finds the active window to execute an action.
#### Signature:
```ts
activeWindow(): WindowFinder
byActiveWindow(): WindowFinder
```
#### Examples:
```ts
import * as win from "https://deno.land/x/denopilot/mod_window.ts";
// Maximize the active window
await win.activeWindow().max();
await win.byActiveWindow().max();
```

## Keyboard Actions
Expand Down Expand Up @@ -273,11 +280,11 @@ await await mouse.left().click()

-------------

## Clipboard Actions
## System Actions

### Overview

This `mod` Allows you to set a value into the clipboard and clear the clipboard.
This `mod` Allows you access and control various system actions.

## License:
This project is licensed under the MIT License
Expand Down
1 change: 0 additions & 1 deletion mod_clipboard.ts

This file was deleted.

2 changes: 1 addition & 1 deletion mod_system.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { screenshot } from "./src/system-actions.ts"
export { beep, screenshot, winbeep, speak, setClipboard, clearClipboard, trayBalloon } from "./src/system-actions.ts"
2 changes: 1 addition & 1 deletion mod_window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ export {
byTitleEndsWith,
byTitleExact,
byTitleStartsWith,
activeWindow,
btActiveWindow,
} from "./src/window-actions.ts";
34 changes: 0 additions & 34 deletions src/clipboard-actions.ts

This file was deleted.

25 changes: 19 additions & 6 deletions src/models/system.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
export type ScreenshotMode = "PrimaryMonitor" | "AllMonitors" | "ActiveWindow"
export type ScreenshotMode = "PrimaryMonitor" | "AllMonitors" | "ActiveWindow";
export interface IScreenRegion {
x: number
y: number
width: number
height: number
}
x: number;
y: number;
width: number;
height: number;
}

export type Speech = {
text: string;
rate?: number;
volume?: number;
};

export type Balloon = {
title: string;
text: string;
icon: number;
timeout: number;
}
9 changes: 9 additions & 0 deletions src/mouse-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ export async function setCursor(x: number, y: number): Promise<number> {
return await nirCmd.runNirCmd(args);
}


/**
* Mouse buttons class
* @date 12/29/2023 - 10:42:12 AM
*
* @export
* @class MouseButton
* @typedef {MouseButton}
*/
export class MouseButton {
constructor(private readonly button: MouseButtons) {}

Expand Down
204 changes: 186 additions & 18 deletions src/system-actions.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,190 @@
import { IScreenRegion, ScreenshotMode } from "./models/system.ts";
import {
Balloon,
IScreenRegion,
ScreenshotMode,
Speech,
} from "./models/system.ts";
import * as nirCmd from "./nirCmd.ts";

/**
* Take a screenshot of monitor, region or window
* @date 12/29/2023 - 10:30:52 AM
*
* @export
* @async
* @param {(ScreenshotMode | IScreenRegion)} mode
* @param {string} imagePath Image path, supported: .bmp, .gif, .png, .jpg, .tiff. if *clipboard* is used the image will be copied to clipboard.
* @example
* ```ts
* import * as system from "https://deno.land/x/denopilot/mod_system.ts"
* //Take a screenshot of active window and save the image.
* await system.screenshot("ActiveWindow", "c:\\temp\\deno.png")
* ```
*
* @example
* ```ts
* import * as system from "https://deno.land/x/denopilot/mod_system.ts"
* //Take a screenshot of all monitors
* await system.screenshot("AllMonitors", "c:\\temp\\deno.png")
* ```
*
* @example
* ```ts
* import * as system from "https://deno.land/x/denopilot/mod_system.ts"
* //Take a screenshot of primary monitor
* await system.screenshot("PrimaryMonitor", "c:\\temp\\deno.png")
* ```
*
* @example
* ```ts
* import * as system from "https://deno.land/x/denopilot/mod_system.ts"
* //Take a screenshot of a region
* await system.screenshot({x:10, y:20, width:300, height:500}, "c:\\temp\\deno.png")
* ```
* @returns {Promise<number>}
*/
export async function screenshot(
mode: ScreenshotMode | IScreenRegion,
imagePath: string,
): Promise<number> {
const args: string[] = [];

if (typeof mode === "string") {
const modeMap: Record<string, string> = {
ActiveWindow: "savescreenshotwin",
AllMonitors: "savescreenshotfull",
PrimaryMonitor: "savescreenshot",
};
args.push(modeMap[mode], imagePath);
} else {
args.push("savescreenshot", imagePath, ...Object.values(mode).map(String));
}

return await nirCmd.runNirCmd(args);
mode: ScreenshotMode | IScreenRegion,
imagePath: string,
): Promise<number> {
const args: string[] = [];

if (typeof mode === "string") {
const modeMap: Record<string, string> = {
ActiveWindow: "savescreenshotwin",
AllMonitors: "savescreenshotfull",
PrimaryMonitor: "savescreenshot",
};
args.push(modeMap[mode], imagePath);
} else {
args.push("savescreenshot", imagePath, ...Object.values(mode).map(String));
}

return await nirCmd.runNirCmd(args);
}

/**
* Plays a beep
* @date 12/29/2023 - 10:48:23 AM
*
* @export
* @async
* @param {number} frequency - Frequency in hertz
* @param {number} duration - Duration in milliseconds
* @example
* ```ts
* import * as system from "https://deno.land/x/denopilot/mod_system.ts"
* //Play 500 Hz beep for 1 sec (1000 milliseconds)
* await system.beep(500, 1000)
* ```
* @returns {Promise<number>}
*/
export async function beep(
frequency: number,
duration: number,
): Promise<number> {
const args: string[] = ["beep", frequency.toString(), duration.toString()];
return await nirCmd.runNirCmd(args);
}

/**
* Plays the standard beep of Windows.
* @date 12/29/2023 - 10:52:04 AM
*
* @export
* @async
* @example
* ```ts
* import * as system from "https://deno.land/x/denopilot/mod_system.ts"
* await system.winbeep()
* ```
* @returns {Promise<number>}
*/
export async function winbeep(): Promise<number> {
const args: string[] = ["stdbeep"];
return await nirCmd.runNirCmd(args);
}

/**
* Speaks the contents of the text
* @date 12/29/2023 - 9:06:45 PM
*
* @export
* @async
* @param {Speech} speech - Speech parameter
* @param {string} speech.text - Text to speak
* @param {number=} speech.rate - Optional: Speech rate between -10 (very slow) and 10 (very fast)
* @param {number=} speech.volume - Optional: Volume of the Speech between 0 and 100
* @returns {Promise<number>}
*/
export async function speak(speech: Speech): Promise<number> {
const args: string[] = ["speak", "text", speech.text];
const rate = speech.rate ?? 0;
args.push(rate.toString());
if (speech.volume) {
args.push(speech.volume.toString());
}
return await nirCmd.runNirCmd(args);
}

/**
* Set the specified text into the clipboard.
* @date 12/27/2023 - 9:40:51 PM
*
* @export
* @async
* @param {string} text cliboard text
* @example
* ```ts
* await system.setClipboard("Hello Deno.")
* ```
* @returns {Promise<number>} process exit code.
*/
export async function setClipboard(text: string): Promise<number> {
return await nirCmd.runNirCmd(["clipboard", "set", text]);
}

/**
* Clear the clipboard.
* @date 12/27/2023 - 9:43:06 PM
*
* @export
* @async
* @example
* ```ts
* await system.clearClipboard()
* ```
* @returns {Promise<number>}
*/
export async function clearClipboard(): Promise<number> {
return await nirCmd.runNirCmd(["clipboard", "clear"]);
}


/**
* Description placeholder
* @date 12/29/2023 - 11:24:46 PM
*
* @export
* @async
* @param {Balloon} balloon - Balloon parameter
* @param {string} balloon.title - Tray Balloon title
* @param {string} balloon.text - Tray Balloon text
* @param {number} balloon.icon - Tray Balloon icon, icon number in shell32.dll
* @param {number} balloon.timeout - Tray Ballon timeout in milliseconds.
* @example
* ```ts
* await system.trayBalloon({title:"Deno", text:"Hello from deno", icon: 300, timeout:2000})
* ```
* @returns {Promise<number>}
*/
export async function trayBalloon(balloon: Balloon): Promise<number> {
const args: string[] = [
"trayballoon",
balloon.title,
balloon.text,
`shell32.dll,${balloon.icon}`,
balloon.timeout.toString(),
];
return await nirCmd.runNirCmd(args);
}
15 changes: 12 additions & 3 deletions src/window-actions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { IWindowAction, WindowFind } from "./models/window.ts";
import { IWindowAction, WindowFind, WindowActions } from "./models/window.ts";
import { runNirCmd, validateNotBlank } from "./nirCmd.ts";
import { WindowActions } from "./models/window.ts";

/**
* Find window by exact title to execute an action
Expand Down Expand Up @@ -147,13 +146,23 @@ export function byProcessId(processId: number): WindowFinder {
* @export
* @returns {WindowFinder} WindowFinder which contains all the actions
*/
export function activeWindow(): WindowFinder {
export function btActiveWindow(): WindowFinder {
const wf: WindowFind = {
active: true
}
return new WindowFinder(wf)
}


/**
* Window Finder class
* This class is the main window finder which contains all the actions.
* @date 12/29/2023 - 10:42:52 AM
*
* @export
* @class WindowFinder
* @typedef {WindowFinder}
*/
export class WindowFinder {
constructor(private readonly wf: WindowFind) {}

Expand Down

0 comments on commit 5e0b17a

Please sign in to comment.