Initial release.
This commit is contained in:
parent
699b3a0760
commit
72bd841f05
8 changed files with 335 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
result
|
||||
*.qcow2
|
55
README.md
Normal file
55
README.md
Normal file
|
@ -0,0 +1,55 @@
|
|||
NixOS-speak
|
||||
===
|
||||
|
||||
## Aims
|
||||
NixOS as of now is [not accessible to blind people](https://github.com/NixOS/nixpkgs/issues/30760), this projects aim is to mend this issue.
|
||||
|
||||
## Getting Started
|
||||
### Getting the installation image
|
||||
As of now an existing installation of Nix is needed (see [Installing a Binary Distribution](https://nixos.org/nix/manual/#ch-installing-binary)).
|
||||
If there are enough people interested I may end up providing pre-built images.
|
||||
|
||||
After installing nix just clone this repo and run
|
||||
```nix
|
||||
nix-build release.nix -A image.<target>
|
||||
```
|
||||
|
||||
The currently available targets are:
|
||||
- minimal
|
||||
- mate
|
||||
|
||||
### Integrate this module into your existing NixOS configuration
|
||||
Installing the speak submodule is as simple as adding:
|
||||
```nix
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(fetchTarball git.ophanim.de/derped/NixOS-Speak/archive/master.tar.gz)
|
||||
];
|
||||
|
||||
config.speak = {
|
||||
enable = true;
|
||||
config.speakup = {
|
||||
synth = "soft";
|
||||
key_echo = "0";
|
||||
punc_level = "0";
|
||||
reading_punc = "0";
|
||||
soft = {
|
||||
rate = "7";
|
||||
vol = "0";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
to your configuration.
|
||||
|
||||
## Status/Progress
|
||||
Current Feature Progress (more will be added later):
|
||||
- TTY
|
||||
- ✓ espeak
|
||||
- ✓ espeakup
|
||||
- Desktop
|
||||
- ❌ orca
|
||||
- ❌ speechd
|
7
default.nix
Normal file
7
default.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./options/espeak.nix
|
||||
];
|
||||
}
|
17
extra/exampleConfig.nix
Normal file
17
extra/exampleConfig.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
imports = [ ./.. ];
|
||||
config.speak = {
|
||||
enable = true;
|
||||
# runAsRoot = false;
|
||||
config.speakup = {
|
||||
soft = {
|
||||
direct = "1";
|
||||
rate = "7";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config.sound.enable = true;
|
||||
}
|
54
extra/mate.nix
Normal file
54
extra/mate.nix
Normal file
|
@ -0,0 +1,54 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
addToXDGDirs = p: ''
|
||||
if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then
|
||||
export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name}
|
||||
fi
|
||||
if [ -d "${p}/lib/girepository-1.0" ]; then
|
||||
export GI_TYPELIB_PATH=$GI_TYPELIB_PATH''${GI_TYPELIB_PATH:+:}${p}/lib/girepository-1.0
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib
|
||||
fi
|
||||
'';
|
||||
in {
|
||||
environment.systemPackages = with pkgs; [
|
||||
orca
|
||||
glib.bin
|
||||
];
|
||||
services.gnome3.at-spi2-core.enable = true;
|
||||
services.xserver = {
|
||||
desktopManager.mate.enable = true;
|
||||
displayManager = {
|
||||
gdm = {
|
||||
enable = true;
|
||||
autoSuspend = false;
|
||||
autoLogin = {
|
||||
enable = true;
|
||||
user = "nixos";
|
||||
};
|
||||
};
|
||||
sessionCommands = ''
|
||||
if test "$XDG_CURRENT_DESKTOP" = "MATE"; then
|
||||
export XDG_MENU_PREFIX=mate-
|
||||
# Let caja find extensions
|
||||
export CAJA_EXTENSION_DIRS=$CAJA_EXTENSION_DIRS''${CAJA_EXTENSION_DIRS:+:}${config.system.path}/lib/caja/extensions-2.0
|
||||
# Let caja extensions find gsettings schemas
|
||||
${concatMapStrings (p: ''
|
||||
if [ -d "${p}/lib/caja/extensions-2.0" ]; then
|
||||
${addToXDGDirs p}
|
||||
fi
|
||||
'') config.environment.systemPackages}
|
||||
# Add mate-control-center paths to some XDG variables because its schemas are needed by mate-settings-daemon, and mate-settings-daemon is a dependency for mate-control-center (that is, they are mutually recursive)
|
||||
${addToXDGDirs pkgs.mate.mate-control-center}
|
||||
# Auto start orca screen-reader
|
||||
GSETTINGS_BACKEND=dconf ${pkgs.glib.bin}/bin/gsettings set org.gnome.desktop.a11y.applications screen-reader-enabled true
|
||||
GSETTINGS_BACKEND=dconf ${pkgs.glib.bin}/bin/gsettings set org.mate.interface accessibility true
|
||||
GSETTINGS_BACKEND=dconf ${pkgs.glib.bin}/bin/gsettings set org.mate.applications-at-visual startup true
|
||||
export GTK_MODULES=gail:atk-bridge
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
116
options/espeak.nix
Normal file
116
options/espeak.nix
Normal file
|
@ -0,0 +1,116 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config;
|
||||
speak = cfg.speak;
|
||||
in rec {
|
||||
options.speak = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable NixOS speak module.
|
||||
'';
|
||||
};
|
||||
installPackages = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Add spech related packages to environment.
|
||||
'';
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "root";
|
||||
description = ''
|
||||
User which runs services like espeakup and speech-dispatcher.
|
||||
User needs to be in audio group.
|
||||
'';
|
||||
};
|
||||
config = {
|
||||
speakup = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
example = ''
|
||||
{
|
||||
synth = "soft";
|
||||
punc_level = "0";
|
||||
reading_punc = "0";
|
||||
soft = {
|
||||
rate = "6";
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf speak.enable rec {
|
||||
boot.kernelModules = [ "speakup_soft" ];
|
||||
nixpkgs.config.packageOverrides = {
|
||||
espeakup = pkgs.callPackage ../pkgs/espeakup.nix {};
|
||||
};
|
||||
|
||||
# needed for orca
|
||||
services.gnome3.at-spi2-core.enable = mkDefault (cfg.services.xserver.enable);
|
||||
|
||||
# allow users in the audio group to use and configure speakup_soft
|
||||
services.udev.extraRules = ''
|
||||
KERNEL=="synth", SUBSYSTEM=="misc", GROUP="audio", MODE="0660"
|
||||
KERNEL=="softsynth", SUBSYSTEM=="misc", GROUP="audio", MODE="0660"
|
||||
KERNEL=="softsynthu", SUBSYSTEM=="misc", GROUP="audio", MODE="0660"
|
||||
'';
|
||||
|
||||
# See https://aur.archlinux.org/cgit/aur.git/tree/espeakup.service?h=espeakup-git
|
||||
systemd.services = {
|
||||
speakup-configure = let
|
||||
# This whole thing still feels a little bit awkward
|
||||
pathList = collect (v: isList v) (mapAttrsRecursive (p: v: p) speak.config.speakup);
|
||||
mkCommand = p: v: "echo ${v} > /sys/accessibility/speakup/${p}";
|
||||
commandList = (map (l: (mkCommand (concatStringsSep "/" l) (attrByPath l "0" speak.config.speakup))) pathList);
|
||||
in {
|
||||
enable = true;
|
||||
description = "configure speakup.";
|
||||
wantedBy = [ "default.target" ];
|
||||
wants = [ "systemd-udev-settle.service" ];
|
||||
after = [ "systemd-udev-settle.service" "sound.target" ];
|
||||
script = (concatStringsSep "\n" commandList);
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
espeakup = {
|
||||
enable = (speak.user == "root");
|
||||
description = "Software speech output system wide settings.";
|
||||
wantedBy = [ "default.target" ];
|
||||
wants = [ "systemd-udev-settle.service" ];
|
||||
after = [ "systemd-udev-settle.service" "sound.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
ExecStart = "${pkgs.espeakup}/bin/espeakup";
|
||||
ExecStop = "${pkgs.utillinux.bin}/bin/kill -HUP $MAINPID";
|
||||
Restart= "always";
|
||||
};
|
||||
};
|
||||
};
|
||||
systemd.user.services.espeakup = {
|
||||
enable = (speak.user != "root");
|
||||
description = "Software speech output system wide settings.";
|
||||
wantedBy = [ "default.target" ];
|
||||
wants = [ "systemd-udev-settle.service" ];
|
||||
after = [ "systemd-udev-settle.service" "sound.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
ExecStart = "${pkgs.espeakup}/bin/espeakup";
|
||||
ExecStop = "${pkgs.utillinux.bin}/bin/kill -HUP $MAINPID";
|
||||
Restart= "always";
|
||||
};
|
||||
};
|
||||
environment.systemPackages = optionals speak.installPackages (with pkgs; [
|
||||
(lowPrio espeak-classic) espeak-ng
|
||||
espeakup
|
||||
]);
|
||||
};
|
||||
}
|
26
pkgs/espeakup.nix
Normal file
26
pkgs/espeakup.nix
Normal file
|
@ -0,0 +1,26 @@
|
|||
{ stdenv, fetchFromGitHub
|
||||
, espeak-classic }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
name = "espeakup";
|
||||
version = "0.80.${rev}";
|
||||
rev = "e69d61b2d88d8dc679558dea03c48130127102ac";
|
||||
|
||||
buildInputs = [ espeak-classic ];
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "williamh";
|
||||
repo = name;
|
||||
inherit rev;
|
||||
sha256 = "0zs5asvxavbibpi98pnhl9y2yc701nxf7h17xm6a1q3liippvix1";
|
||||
};
|
||||
|
||||
patchPhase = ''
|
||||
substituteInPlace Makefile --replace "/usr/local" $out
|
||||
'';
|
||||
meta = with stdenv.lib; {
|
||||
description = "espeakup is a program which makes it possible for speakup to use the espeak software synthesizer.";
|
||||
homepage = "https://github.com/williamh/espeakup";
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
}
|
59
release.nix
Normal file
59
release.nix
Normal file
|
@ -0,0 +1,59 @@
|
|||
# This file is heavily inspired by <nixpkgs/nixos/release.nix>
|
||||
{ nixpkgs ? <nixpkgs> # builtins.fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-20.03.tar.gz
|
||||
, targetSystem ? builtins.currentSystem
|
||||
, speak ? ./. #builtins.fetchGit ./.
|
||||
, configuration ? ./extra/exampleConfig.nix #{ imports = [ (speak + builtins.toPath "/options/espeak.nix") ]; config.speak.enable = true; config.sound.enable = true; }
|
||||
}:
|
||||
|
||||
with builtins;
|
||||
with import (nixpkgs + (toPath "/lib"));
|
||||
|
||||
let
|
||||
pkgs = import nixpkgs { system = targetSystem; };
|
||||
tarball = pkgs.releaseTools.sourceTarball {
|
||||
name = "speak-tarball";
|
||||
src = speak;
|
||||
};
|
||||
modulePath = (nixpkgs + (toPath "/nixos/modules"));
|
||||
makeTarget = target:
|
||||
with import nixpkgs { system = targetSystem; };
|
||||
((import (nixpkgs + (toPath "/nixos/lib/eval-config.nix")) {
|
||||
system = targetSystem;
|
||||
modules = target.modules ++ [ configuration ];
|
||||
}).config.system.build);
|
||||
makeSubTargets = target: {
|
||||
isoImage = hydraJob (makeTarget (mergeAttrsConcatenateValues target {
|
||||
modules = [
|
||||
{ isoImage.isoBaseName = "nixos-${target.name}"; }
|
||||
];
|
||||
})).isoImage;
|
||||
tarball = hydraJob (makeTarget (mergeAttrsConcatenateValues target {
|
||||
modules = [ (modulePath + toPath "/installer/cd-dvd/system-tarball.nix") ];
|
||||
})).tarball;
|
||||
vm = (makeTarget (mergeAttrsConcatenateValues target {
|
||||
modules = [ (modulePath + toPath "/virtualisation/qemu-vm.nix") { config.virtualisation.qemu.options = [ "-soundhw hda" ]; } ];
|
||||
})).vm;
|
||||
};
|
||||
targets = rec {
|
||||
minimal = {
|
||||
name = "minimal";
|
||||
modules = [
|
||||
(modulePath + (toPath "/installer/cd-dvd/installation-cd-minimal.nix"))
|
||||
(modulePath + (toPath "/installer/cd-dvd/channel.nix"))
|
||||
];
|
||||
};
|
||||
mate = {
|
||||
name = "mate";
|
||||
modules = [
|
||||
(modulePath + (toPath "/installer/cd-dvd/installation-cd-graphical-base.nix"))
|
||||
./modules/mate.nix
|
||||
(modulePath + (toPath "/installer/cd-dvd/channel.nix"))
|
||||
];
|
||||
};
|
||||
};
|
||||
allTargets = mapAttrs (name: value: (makeSubTargets value)) targets;
|
||||
in {
|
||||
inherit tarball;
|
||||
image = allTargets;
|
||||
pkgs.espeakup = hydraJob (pkgs.callPackage ./pkgs/espeakup.nix {});
|
||||
}
|
Loading…
Reference in a new issue