mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 15:24:05 +00:00
16943ccab1
make selectedText const add a new keyboard shortcut: ctrl+shift+n to make a card if word is empty, warn and exit rename return after ankisearch remove temp vars change the anki action's text depending on selected text reformat article maker the anki button is shown under the heading revert to the previous way of constructing gddictname to reduce size of the diff
125 lines
4 KiB
C++
125 lines
4 KiB
C++
#include "ankiconnector.h"
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QJsonValue>
|
|
#include "utils.hh"
|
|
|
|
QString markTargetWord(QString const& sentence, QString const& word)
|
|
{
|
|
// TODO properly handle inflected words.
|
|
QString result = sentence;
|
|
return result.replace(word, "<b>" + word + "</b>", Qt::CaseInsensitive);
|
|
}
|
|
|
|
AnkiConnector::AnkiConnector( QObject * parent, Config::Class const & _cfg ) : QObject{ parent }, cfg( _cfg )
|
|
{
|
|
mgr = new QNetworkAccessManager( this );
|
|
connect( mgr, &QNetworkAccessManager::finished, this, &AnkiConnector::finishedSlot );
|
|
}
|
|
|
|
void AnkiConnector::sendToAnki( QString const & word, QString text, QString const & sentence )
|
|
{
|
|
if ( word.isEmpty() ) {
|
|
emit this->errorText( tr( "anki: can't create a card without a word" ) );
|
|
return;
|
|
}
|
|
|
|
// Anki doesn't understand the newline character, so it should be escaped.
|
|
text = text.replace( "\n", "<br>" );
|
|
|
|
QString const postTemplate = R"anki({
|
|
"action": "addNote",
|
|
"version": 6,
|
|
"params": {
|
|
"note": {
|
|
"deckName": "%1",
|
|
"modelName": "%2",
|
|
"fields": %3,
|
|
"options": {
|
|
"allowDuplicate": true
|
|
},
|
|
"tags": []
|
|
}
|
|
}
|
|
})anki";
|
|
|
|
QJsonObject fields;
|
|
fields.insert( cfg.preferences.ankiConnectServer.word, word );
|
|
fields.insert( cfg.preferences.ankiConnectServer.text, text );
|
|
if (!cfg.preferences.ankiConnectServer.sentence.isEmpty()) {
|
|
QString sentence_changed = markTargetWord(sentence, word);
|
|
fields.insert( cfg.preferences.ankiConnectServer.sentence, sentence_changed );
|
|
}
|
|
|
|
QString postData = postTemplate.arg( cfg.preferences.ankiConnectServer.deck,
|
|
cfg.preferences.ankiConnectServer.model,
|
|
Utils::json2String( fields ) );
|
|
|
|
// qDebug().noquote() << postData;
|
|
postToAnki( postData );
|
|
}
|
|
|
|
void AnkiConnector::ankiSearch( QString const & word )
|
|
{
|
|
if( !cfg.preferences.ankiConnectServer.enabled ) {
|
|
emit this->errorText( tr( "Anki search: AnkiConnect is not enabled." ) );
|
|
return;
|
|
}
|
|
|
|
QString postTemplate = R"anki({
|
|
"action": "guiBrowse",
|
|
"version": 6,
|
|
"params": {
|
|
"query": "%1"
|
|
}
|
|
})anki";
|
|
postToAnki( postTemplate.arg( word ) );
|
|
}
|
|
|
|
void AnkiConnector::postToAnki( QString const & postData )
|
|
{
|
|
QUrl url;
|
|
url.setScheme( "http" );
|
|
url.setHost( cfg.preferences.ankiConnectServer.host );
|
|
url.setPort( cfg.preferences.ankiConnectServer.port );
|
|
QNetworkRequest request( url );
|
|
request.setTransferTimeout( transfer_timeout );
|
|
// request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy );
|
|
request.setHeader( QNetworkRequest::ContentTypeHeader, "application/json" );
|
|
auto reply = mgr->post( request, postData.toUtf8() );
|
|
connect( reply,
|
|
&QNetworkReply::errorOccurred,
|
|
this,
|
|
[ this ]( QNetworkReply::NetworkError e )
|
|
{
|
|
qWarning() << e;
|
|
emit this->errorText( tr( "anki: post to anki failed" ) );
|
|
} );
|
|
}
|
|
|
|
void AnkiConnector::finishedSlot( QNetworkReply * reply )
|
|
{
|
|
if ( reply->error() == QNetworkReply::NoError ) {
|
|
QByteArray const bytes = reply->readAll();
|
|
QJsonDocument const json = QJsonDocument::fromJson( bytes );
|
|
auto const obj = json.object();
|
|
|
|
// Normally AnkiConnect always returns result and error,
|
|
// unless Anki is not running.
|
|
if ( obj.size() == 2 && obj.contains( "result" ) && obj.contains( "error" ) && obj[ "error" ].isNull() ) {
|
|
emit errorText( tr( "anki: post to anki success" ) );
|
|
}
|
|
else {
|
|
emit errorText( tr( "anki: post to anki failed" ) );
|
|
}
|
|
|
|
qDebug().noquote() << "anki response:" << Utils::json2String( obj );
|
|
}
|
|
else {
|
|
qDebug() << "anki connect error" << reply->errorString();
|
|
emit errorText( "anki:" + reply->errorString() );
|
|
}
|
|
|
|
reply->deleteLater();
|
|
}
|