feat: v0.1.0 — client Sailfish per hermes-webui con voce

- ApiClient HTTP/SSE: login, sessioni, chat/start, stream SSE, transcribe, tts
- ChatModel: streaming live + risincronizzazione dallo stato del server
- CookieJar persistente (0600, mai la password); Settings
- Recorder OGG/Opus (fallback WAV/PCM, retry); Player TTS (QMediaPlayer)
- UI Silica: splash, login, sessioni, chat (dettatura + read-aloud), settings, cover
- Sailjail Internet;Audio;Microphone; icone; spec RPM; docs PROTOCOL/BUILD
- tests/core_test: unit parser SSE + integrazione live (probe :8899)
This commit is contained in:
2026-09-12 07:11:20 +02:00
commit 9c6a1242f7
36 changed files with 2954 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
#include "cookiejar.h"
#include <QFile>
#include <QDir>
#include <QFileInfo>
#include <QNetworkCookie>
CookieJar::CookieJar(QObject *parent)
: QNetworkCookieJar(parent)
{
}
void CookieJar::setFilePath(const QString &path)
{
m_path = path;
}
QString CookieJar::filePath() const
{
return m_path;
}
bool CookieJar::load()
{
if (m_path.isEmpty())
return false;
QFile f(m_path);
if (!f.open(QIODevice::ReadOnly))
return false;
const QByteArray data = f.readAll();
f.close();
const QList<QNetworkCookie> cookies = QNetworkCookie::parseCookies(data);
if (cookies.isEmpty())
return false;
setAllCookies(cookies);
return true;
}
bool CookieJar::save() const
{
if (m_path.isEmpty())
return false;
const QFileInfo info(m_path);
QDir().mkpath(info.absolutePath());
QFile f(m_path);
if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate))
return false;
// Permessi solo proprietario PRIMA di scrivere il contenuto.
f.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner);
const QList<QNetworkCookie> cookies = allCookies();
for (int i = 0; i < cookies.size(); ++i) {
f.write(cookies.at(i).toRawForm(QNetworkCookie::Full));
f.write("\n");
}
f.close();
return true;
}
void CookieJar::clear()
{
setAllCookies(QList<QNetworkCookie>());
if (!m_path.isEmpty())
QFile::remove(m_path);
}
bool CookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
{
const bool changed = QNetworkCookieJar::setCookiesFromUrl(cookieList, url);
if (changed)
save();
return changed;
}