Compare commits
2 commits
aead2342ab
...
36814b5a7a
Author | SHA1 | Date | |
---|---|---|---|
36814b5a7a | |||
990de81c42 |
10 changed files with 315 additions and 107 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
/.geany
|
/.geany
|
||||||
/build/
|
/build/
|
||||||
|
/lib/piper/
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
# Notizen
|
||||||
|
|
||||||
|
## Ziele
|
||||||
|
|
||||||
- soll eine kleine Web-Anwendung werden
|
- soll eine kleine Web-Anwendung werden
|
||||||
- einzige Domäne im Modell ist die der Dokumente
|
- einzige Domäne im Modell ist die der Dokumente
|
||||||
- Eigenschaften von Dokumenten:
|
- Eigenschaften von Dokumenten:
|
||||||
|
@ -9,3 +13,7 @@
|
||||||
- für jedes bestehende Dokument soll es Funktionen zum Aufbereiten und Herunderladen geben in den Formaten pdf und ogg
|
- für jedes bestehende Dokument soll es Funktionen zum Aufbereiten und Herunderladen geben in den Formaten pdf und ogg
|
||||||
- für die Erstellung der Audio-Variante soll nach Möglichkeit [Piper](https://github.com/rhasspy/piper) verwendet werden
|
- für die Erstellung der Audio-Variante soll nach Möglichkeit [Piper](https://github.com/rhasspy/piper) verwendet werden
|
||||||
|
|
||||||
|
|
||||||
|
## Zu erledigen
|
||||||
|
|
||||||
|
- asynchrones Erstellen der Audio-Dateien (solange nicht fertig, eine Markierung in der Liste anzeigen)
|
||||||
|
|
17
readme.md
17
readme.md
|
@ -5,6 +5,18 @@
|
||||||
proof-of-concept für Partei-Arbeits-Dokumenten-Verwaltung, welche hörbare Versionen der Dokumente bereitstellt
|
proof-of-concept für Partei-Arbeits-Dokumenten-Verwaltung, welche hörbare Versionen der Dokumente bereitstellt
|
||||||
|
|
||||||
|
|
||||||
|
## Einrichtung
|
||||||
|
|
||||||
|
### Voraussetzungen
|
||||||
|
|
||||||
|
- curl
|
||||||
|
|
||||||
|
|
||||||
|
### Anweisungen
|
||||||
|
|
||||||
|
- `tools/update-piper` ausführen
|
||||||
|
|
||||||
|
|
||||||
## Erstellung
|
## Erstellung
|
||||||
|
|
||||||
### Voraussetzungen
|
### Voraussetzungen
|
||||||
|
@ -14,7 +26,7 @@ proof-of-concept für Partei-Arbeits-Dokumenten-Verwaltung, welche hörbare Vers
|
||||||
|
|
||||||
### Anweisungen
|
### Anweisungen
|
||||||
|
|
||||||
- `tools/build` ausführen
|
- nach Einrichtung `tools/build` ausführen
|
||||||
|
|
||||||
|
|
||||||
## Ausführung
|
## Ausführung
|
||||||
|
@ -22,7 +34,8 @@ proof-of-concept für Partei-Arbeits-Dokumenten-Verwaltung, welche hörbare Vers
|
||||||
### Voraussetzungen
|
### Voraussetzungen
|
||||||
|
|
||||||
- PHP auf Kommandozeile (Debian-Paket-Name: `php-cli`)
|
- PHP auf Kommandozeile (Debian-Paket-Name: `php-cli`)
|
||||||
- Browser
|
- ffmpeg (Debian-Paket-Name: `ffmpeg`)
|
||||||
|
- beliebigen Browser
|
||||||
|
|
||||||
|
|
||||||
### Anweisungen
|
### Anweisungen
|
||||||
|
|
|
@ -28,6 +28,59 @@ function cache_get(string $key, \Closure $retrieve)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function database_map_type(string $type)
|
||||||
|
{
|
||||||
|
switch ($type)
|
||||||
|
{
|
||||||
|
case 'integer': return \SQLITE3_INTEGER;
|
||||||
|
case 'string': return \SQLITE3_TEXT;
|
||||||
|
default: throw (new \Exception(\sprintf('unhandled type: %s', $type)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function database_get(string $query_template, array $arguments) : array
|
||||||
|
{
|
||||||
|
$connection = new \SQLite3('data.sqlite');
|
||||||
|
$rows = $connection->query($query_template);
|
||||||
|
/*
|
||||||
|
$query = "SELECT * FROM books";
|
||||||
|
$result = $db->query($query);
|
||||||
|
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function database_put(string $query_template, array $arguments) : int
|
||||||
|
{
|
||||||
|
$connection = new \SQLite3('data.sqlite');
|
||||||
|
$statement = $connection->prepare($query);
|
||||||
|
foreach ($arguments as $key => $value)
|
||||||
|
{
|
||||||
|
$statement->bindValue(
|
||||||
|
\sprintf(':%s', $key),
|
||||||
|
$value['value'],
|
||||||
|
database_map_type($value['type'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ($statement->execute()) {
|
||||||
|
// SELECT last_insert_rowid()
|
||||||
|
echo "Buch erfolgreich hinzugefügt!";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo "Fehler beim Hinzufügen des Buches: " . $db->lastErrorMsg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function string_coin(string $template, array $arguments) : string
|
function string_coin(string $template, array $arguments) : string
|
||||||
|
@ -41,6 +94,114 @@ function string_coin(string $template, array $arguments) : string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
class class_crud_jsonfile
|
||||||
|
{
|
||||||
|
private string $path;
|
||||||
|
|
||||||
|
private \Closure $id_encode;
|
||||||
|
|
||||||
|
private \Closure $id_decode;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
string $path,
|
||||||
|
\Closure $id_encode,
|
||||||
|
\Closure $id_decode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->path = $path;
|
||||||
|
$this->id_encode = $id_encode;
|
||||||
|
$this->id_decode = $id_decode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function get() : array
|
||||||
|
{
|
||||||
|
$content = (\file_exists($this->path) ? \file_get_contents($this->path) : null);
|
||||||
|
return (
|
||||||
|
($content === null)
|
||||||
|
?
|
||||||
|
['last_id' => 0, 'entries' => []]
|
||||||
|
:
|
||||||
|
\json_decode($content, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function put(array $data) : void
|
||||||
|
{
|
||||||
|
$content = \json_encode($data, \JSON_PRETTY_PRINT);
|
||||||
|
\file_put_contents($this->path, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function list_() : array
|
||||||
|
{
|
||||||
|
$data = $this->get();
|
||||||
|
return \array_map(
|
||||||
|
fn ($id_encoded) => [
|
||||||
|
'id' => ($this->id_decode)($id_encoded),
|
||||||
|
'value' => $data['entries'][$id_encoded],
|
||||||
|
],
|
||||||
|
\array_keys($data['entries'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function read(int $id)
|
||||||
|
{
|
||||||
|
$data = $this->get();
|
||||||
|
$id_encoded = ($this->id_encode)($id);
|
||||||
|
if (! \array_key_exists($id_encoded, $data['entries']))
|
||||||
|
{
|
||||||
|
throw (new \Exception('not found'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $data['entries'][$id_encoded];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create($value) : int
|
||||||
|
{
|
||||||
|
$data = $this->get();
|
||||||
|
$id = ($data['last_id'] + 1);
|
||||||
|
$id_encoded = ($this->id_encode)($id);
|
||||||
|
$data['last_id'] = $id;
|
||||||
|
$data['entries'][$id_encoded] = $value;
|
||||||
|
$this->put($data);
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(int $id, $value) : void
|
||||||
|
{
|
||||||
|
$data = $this->get();
|
||||||
|
$id_encoded = ($this->id_encode)($id);
|
||||||
|
if (! \array_key_exists($id_encoded, $data['entries']))
|
||||||
|
{
|
||||||
|
throw (new \Exception('not found'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$data['entries'][$id_encoded] = $value;
|
||||||
|
$this->put($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(int $id) : void
|
||||||
|
{
|
||||||
|
$data = $this->get();
|
||||||
|
$id_encoded = ($this->id_encode)($id);
|
||||||
|
if (! \array_key_exists($id_encoded, $data['entries']))
|
||||||
|
{
|
||||||
|
throw (new \Exception('not found'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($data['entries'][$id_encoded]);
|
||||||
|
$this->put($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function render(string $template_name, array $arguments) : string
|
function render(string $template_name, array $arguments) : string
|
||||||
|
@ -76,4 +237,32 @@ function navigate(string $target) : void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function generate_audio(string $name, string $input) : string
|
||||||
|
{
|
||||||
|
$path_wav = string_coin(
|
||||||
|
'/tmp/{{name}}.wav',
|
||||||
|
[
|
||||||
|
'name' => $name,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$path_ogg = string_coin(
|
||||||
|
'{{name}}.ogg',
|
||||||
|
[
|
||||||
|
'name' => $name,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$command = string_coin(
|
||||||
|
'echo "{{input}}" | piper/piper --model piper/voice.onnx --output_file {{path_wav}} ; ffmpeg -y -i {{path_wav}} {{path_ogg}}',
|
||||||
|
[
|
||||||
|
'input' => $input,
|
||||||
|
'path_wav' => $path_wav,
|
||||||
|
'path_ogg' => $path_ogg,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
exec($command);
|
||||||
|
return $path_ogg;
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -7,7 +7,7 @@ require_once(__DIR__ . '/logic.php');
|
||||||
|
|
||||||
$mode = ($_GET['mode'] ?? 'list');
|
$mode = ($_GET['mode'] ?? 'list');
|
||||||
$id_encoded = (! empty($_GET['id']) ? $_GET['id'] : null);
|
$id_encoded = (! empty($_GET['id']) ? $_GET['id'] : null);
|
||||||
$id = (($id_encoded === null) ? null : \rosavox\logic\docs_id_decode($id_encoded));
|
$id = (($id_encoded === null) ? null : \intval($id_encoded));
|
||||||
|
|
||||||
|
|
||||||
function nav(string $mode, array $args) : void
|
function nav(string $mode, array $args) : void
|
||||||
|
@ -37,15 +37,10 @@ function nav(string $mode, array $args) : void
|
||||||
<link rel="stylesheet" type="text/css" href="/style.css"/>
|
<link rel="stylesheet" type="text/css" href="/style.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<h1>rosavox</h1>
|
||||||
<?php
|
<?php
|
||||||
switch ($mode)
|
switch ($mode)
|
||||||
{
|
{
|
||||||
case 'example':
|
|
||||||
{
|
|
||||||
\rosavox\logic\docs_add_examples();
|
|
||||||
nav('list', []);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'list':
|
case 'list':
|
||||||
{
|
{
|
||||||
echo(
|
echo(
|
||||||
|
@ -58,13 +53,15 @@ function nav(string $mode, array $args) : void
|
||||||
fn ($entry) => \rosavox\helpers\render(
|
fn ($entry) => \rosavox\helpers\render(
|
||||||
'docs-list-entry',
|
'docs-list-entry',
|
||||||
[
|
[
|
||||||
'link' => \rosavox\helpers\string_coin(
|
'link_open' => \rosavox\helpers\string_coin(
|
||||||
'?mode=edit&id={{id}}',
|
'?mode=edit&id={{id}}',
|
||||||
[
|
[
|
||||||
'id' => $entry['id'],
|
'id' => $entry['id'],
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
'text' => $entry['doc']['title'],
|
'link_read' => '#not_implemented',
|
||||||
|
'link_hear' => \rosavox\logic\docs_audio_path($entry['id']),
|
||||||
|
'text' => $entry['value']['title'],
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
\rosavox\logic\docs_list()
|
\rosavox\logic\docs_list()
|
||||||
|
|
156
source/logic.php
156
source/logic.php
|
@ -9,60 +9,56 @@ require_once(__DIR__ . '/helpers.php');
|
||||||
*/
|
*/
|
||||||
class docs_state
|
class docs_state
|
||||||
{
|
{
|
||||||
public static int $current_id = 0;
|
public static ?\rosavox\helpers\class_crud_jsonfile $crud = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array {record<string,array>}
|
|
||||||
*/
|
|
||||||
public static array $pool = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function docs_push() : void
|
function docs_audio_name(int $id) : string
|
||||||
{
|
{
|
||||||
$path = 'docs.json';
|
return \sprintf('%04u', $id);
|
||||||
$data = [
|
|
||||||
'current_id' => docs_state::$current_id,
|
|
||||||
'pool' => docs_state::$pool,
|
|
||||||
];
|
|
||||||
$content = \json_encode($data, \JSON_PRETTY_PRINT);
|
|
||||||
\file_put_contents($path, $content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function docs_pull() : void
|
function docs_audio_path(int $id) : string
|
||||||
{
|
{
|
||||||
$path = 'docs.json';
|
return \sprintf('%s.ogg', docs_audio_name($id));
|
||||||
$content = (\file_exists($path) ? \file_get_contents($path) : null);
|
}
|
||||||
$data = (
|
|
||||||
($content === null)
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function docs_generate_audio(int $id, $doc) : void
|
||||||
|
{
|
||||||
|
$pause = ' . ';
|
||||||
|
\rosavox\helpers\generate_audio(
|
||||||
|
docs_audio_name($id),
|
||||||
|
\rosavox\helpers\string_coin(
|
||||||
|
"{{title}}{{pause}}Autoren: {{authors}}{{pause}}Formulierung: {{content}}{{macro_reasoning}}",
|
||||||
|
[
|
||||||
|
'pause' => $pause,
|
||||||
|
'title' => $doc['title'],
|
||||||
|
'authors' => implode(', ', $doc['authors']),
|
||||||
|
'content' => $doc['content'],
|
||||||
|
'macro_reasoning' => (
|
||||||
|
($doc['reasoning'] === null)
|
||||||
?
|
?
|
||||||
['current_id' => 0, 'pool' => []]
|
''
|
||||||
:
|
:
|
||||||
\json_decode($content, true)
|
\rosavox\helpers\string_coin(
|
||||||
|
"{{pause}}Begründung: {{reasoning}}",
|
||||||
|
[
|
||||||
|
'pause' => $pause,
|
||||||
|
'reasoning' => $doc['reasoning'],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
);
|
);
|
||||||
docs_state::$current_id = $data['current_id'];
|
|
||||||
docs_state::$pool = $data['pool'];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function docs_id_encode(int $id) : string
|
|
||||||
{
|
|
||||||
return \sprintf('%u', $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function docs_id_decode(string $id_encoded) : int
|
|
||||||
{
|
|
||||||
return intval($id_encoded);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,13 +66,7 @@ function docs_id_decode(string $id_encoded) : int
|
||||||
*/
|
*/
|
||||||
function docs_list() : array
|
function docs_list() : array
|
||||||
{
|
{
|
||||||
return \array_map(
|
return docs_state::$crud->list_();
|
||||||
fn ($id_encoded) => [
|
|
||||||
'id' => docs_id_decode($id_encoded),
|
|
||||||
'doc' => docs_state::$pool[$id_encoded],
|
|
||||||
],
|
|
||||||
\array_keys(docs_state::$pool)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,27 +74,17 @@ function docs_list() : array
|
||||||
*/
|
*/
|
||||||
function docs_read(int $id) : array
|
function docs_read(int $id) : array
|
||||||
{
|
{
|
||||||
$id_encoded = docs_id_encode($id);
|
return docs_state::$crud->read($id);
|
||||||
if (! \array_key_exists($id_encoded, docs_state::$pool))
|
|
||||||
{
|
|
||||||
throw (new \Exception('not found'));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return docs_state::$pool[$id_encoded];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @todo async generating
|
||||||
*/
|
*/
|
||||||
function docs_create(array $doc) : int
|
function docs_create(array $doc) : int
|
||||||
{
|
{
|
||||||
docs_state::$current_id += 1;
|
$id = docs_state::$crud->create($doc);
|
||||||
$id = docs_state::$current_id;
|
docs_generate_audio($id, $doc);
|
||||||
$id_encoded = docs_id_encode($id);
|
|
||||||
docs_state::$pool[$id_encoded] = $doc;
|
|
||||||
docs_push();
|
|
||||||
return $id;
|
return $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,16 +93,8 @@ function docs_create(array $doc) : int
|
||||||
*/
|
*/
|
||||||
function docs_update(int $id, array $doc) : void
|
function docs_update(int $id, array $doc) : void
|
||||||
{
|
{
|
||||||
$id_encoded = docs_id_encode($id);
|
docs_state::$crud->update($id, $doc);
|
||||||
if (! \array_key_exists($id_encoded, docs_state::$pool))
|
docs_generate_audio($id, $doc);
|
||||||
{
|
|
||||||
throw (new \Exception('not found'));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
docs_state::$pool[$id_encoded] = $doc;
|
|
||||||
docs_push();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,25 +102,7 @@ function docs_update(int $id, array $doc) : void
|
||||||
*/
|
*/
|
||||||
function docs_delete(int $id) : void
|
function docs_delete(int $id) : void
|
||||||
{
|
{
|
||||||
$id_encoded = docs_id_encode($id);
|
docs_state::$crud->delete($id);
|
||||||
if (! \array_key_exists($id_encoded, docs_state::$pool))
|
|
||||||
{
|
|
||||||
throw (new \Exception('not found'));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
docs_state::$pool[$id_encoded] = null;
|
|
||||||
unset(docs_state::$pool[$id_encoded]);
|
|
||||||
docs_push();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function docs_init() : void
|
|
||||||
{
|
|
||||||
docs_pull();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,10 +117,30 @@ function docs_add_examples() : void
|
||||||
'Björn Biernot',
|
'Björn Biernot',
|
||||||
'Doreen Dauerdurst',
|
'Doreen Dauerdurst',
|
||||||
],
|
],
|
||||||
'content' => 'Wir haben Durst!',
|
'content' => 'Der Landesverband möge beschließen, dass zu Beginn eines jeden Parteitags für jeden Deligierten mindestens zwei Flaschen Bier auf den zugehörigen Platz zu stellen sind.',
|
||||||
'reasoning' => null,
|
'reasoning' => 'Wir haben Durst!',
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function docs_init() : void
|
||||||
|
{
|
||||||
|
docs_state::$crud = new \rosavox\helpers\class_crud_jsonfile(
|
||||||
|
'docs.json',
|
||||||
|
fn ($id) => \sprintf('%u', $id),
|
||||||
|
fn ($id_encoded) => \intval($id_encoded)
|
||||||
|
);
|
||||||
|
if (empty(docs_state::$crud->list_()))
|
||||||
|
{
|
||||||
|
docs_add_examples();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
<li class="docs-list-entry">
|
<li class="docs-list-entry">
|
||||||
<a href="{{link}}">{{text}}</a>
|
<a href="{{link_open}}">{{text}}</a>
|
||||||
|
| <a href="{{link_read}}">[lesen]</a>
|
||||||
|
| <a href="{{link_hear}}">[hören]</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -9,5 +9,6 @@ dir_source="source"
|
||||||
## exec
|
## exec
|
||||||
|
|
||||||
mkdir -p ${dir_build}
|
mkdir -p ${dir_build}
|
||||||
|
cp -r -u lib/* ${dir_build}/
|
||||||
cp -r -u -v ${dir_source}/* ${dir_build}/
|
cp -r -u -v ${dir_source}/* ${dir_build}/
|
||||||
cd ${dir_build} && ln -f -s index.html.php index.php
|
cd ${dir_build} && ln -f -s index.html.php index.php ; cd -
|
||||||
|
|
3
tools/clear
Executable file
3
tools/clear
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
rm -r -f build/*
|
20
tools/update-piper
Executable file
20
tools/update-piper
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
## const
|
||||||
|
|
||||||
|
dir_lib=lib
|
||||||
|
voice="v1.0.0/de/de_DE/eva_k/x_low/de_DE-eva_k-x_low.onnx"
|
||||||
|
|
||||||
|
|
||||||
|
## exec
|
||||||
|
|
||||||
|
mkdir -p ${dir_lib}
|
||||||
|
cd ${dir_lib}
|
||||||
|
curl -s -L https://github.com/rhasspy/piper/releases/download/v1.2.0/piper_amd64.tar.gz | tar -x -z
|
||||||
|
cd -
|
||||||
|
|
||||||
|
for voice in ${voices}
|
||||||
|
do
|
||||||
|
curl -s -L https://huggingface.co/rhasspy/piper-voices/resolve/${voice}?download=true > ${dir_lib}/piper/voice.onnx
|
||||||
|
curl -s -L https://huggingface.co/rhasspy/piper-voices/resolve/${voice}.json?download=true.json > ${dir_lib}/piper/voice.onnx.json
|
||||||
|
done
|
Loading…
Add table
Reference in a new issue