OSDN Git Service

kget: implement torrent transfer plugin settings
authorIvailo Monev <xakepa10@gmail.com>
Thu, 24 Mar 2022 11:20:28 +0000 (13:20 +0200)
committerIvailo Monev <xakepa10@gmail.com>
Thu, 24 Mar 2022 11:20:28 +0000 (13:20 +0200)
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
kget/transfer-plugins/torrent/CMakeLists.txt
kget/transfer-plugins/torrent/dlgtorrent.cpp [new file with mode: 0644]
kget/transfer-plugins/torrent/dlgtorrent.h [new file with mode: 0644]
kget/transfer-plugins/torrent/dlgtorrent.ui [new file with mode: 0644]
kget/transfer-plugins/torrent/kget_torrentfactory_config.desktop [new file with mode: 0644]
kget/transfer-plugins/torrent/transferTorrent.cpp
kget/transfer-plugins/torrent/transferTorrent.h

index 9fd18a2..b0b15f0 100644 (file)
@@ -1,4 +1,4 @@
-#Set supported mime type
+# Set supported mime type
 SET(SUPPORTED_KGET_MIMETYPES "${SUPPORTED_KGET_MIMETYPES}application/x-bittorrent;" PARENT_SCOPE)
 
 include_directories(
@@ -32,3 +32,25 @@ install(
     FILES kget_torrentfactory.desktop
     DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
 )
+
+# KCM module
+set(kcm_kget_torrentfactory_PART_SRCS
+    dlgtorrent.cpp
+    dlgtorrent.ui 
+)
+
+kde4_add_plugin(kcm_kget_torrentfactory ${kcm_kget_torrentfactory_PART_SRCS})
+target_link_libraries(kcm_kget_torrentfactory
+    ${KDE4_KDEUI_LIBS} 
+    ${LIBTORRENT_LIBRARIES}
+)
+
+install(
+    TARGETS kcm_kget_torrentfactory
+    DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
+)
+
+install(
+    FILES kget_torrentfactory_config.desktop
+    DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
+)
diff --git a/kget/transfer-plugins/torrent/dlgtorrent.cpp b/kget/transfer-plugins/torrent/dlgtorrent.cpp
new file mode 100644 (file)
index 0000000..fefa0c6
--- /dev/null
@@ -0,0 +1,222 @@
+/*  This file is part of the KDE project
+
+    Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License version 2, as published by the Free Software Foundation.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "dlgtorrent.h"
+
+#include "kget_export.h"
+
+#include <QFile>
+#include <QJsonDocument>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+
+#include <libtorrent/settings_pack.hpp>
+
+KGET_EXPORT_PLUGIN_CONFIG(DlgTorrentSettings)
+
+static const int tableindexrole = 1234;
+static const int tabletyperole = 4321;
+
+DlgTorrentSettings::DlgTorrentSettings(QWidget *parent, const QVariantList &args)
+    : KCModule(KGetFactory::componentData(), parent, args)
+{
+    ui.setupUi(this);
+
+    load();
+
+    connect(
+        ui.settingsTableWidget, SIGNAL(itemChanged(QTableWidgetItem*)),
+        this, SLOT(slotItemChanged(QTableWidgetItem*))
+    );
+}
+
+DlgTorrentSettings::~DlgTorrentSettings()
+{
+}
+
+void DlgTorrentSettings::load()
+{
+    QFile settingsfile(KStandardDirs::locateLocal("appdata", "torrentsettings.json"));
+    QJsonDocument settingsjson;
+    if (settingsfile.open(QFile::ReadOnly)) {
+        settingsjson = QJsonDocument::fromJson(settingsfile.readAll());
+    }
+
+    const QVariantMap settingsmap = settingsjson.toVariant().toMap();
+    lt::settings_pack ltsettings = lt::default_settings();
+    foreach (const QString &key, settingsmap.keys()) {
+        const int settingskey = key.toInt();
+        const QVariant settingsvalue = settingsmap.value(key);
+        switch (settingsvalue.type()) {
+            case QVariant::ByteArray:
+            case QVariant::String: {
+                const QString settingsstring = settingsvalue.toString();
+                ltsettings.set_str(settingskey, settingsstring.toStdString());
+                break;
+            }
+            case QVariant::Int:
+            case QVariant::UInt:
+            case QVariant::LongLong:
+            case QVariant::ULongLong: {
+                const int settingsint = settingsvalue.toInt();
+                ltsettings.set_int(settingskey, settingsint);
+                break;
+            }
+            case QVariant::Bool: {
+                const bool settingsbool = settingsvalue.toBool();
+                ltsettings.set_int(settingskey, settingsbool);
+                break;
+            }
+            default: {
+                kWarning(5001) << "invalid setting type";
+                break;
+            }
+        }
+    }
+
+    int tablerowcount = 0;
+    // qDebug() << Q_FUNC_INFO << "string settings";
+    for (int i = 0; i < lt::settings_pack::settings_counts_t::num_string_settings; i++) {
+        ui.settingsTableWidget->setRowCount(tablerowcount + 1);
+
+        const int settingindex = (lt::settings_pack::string_type_base + i);
+        // qDebug() << Q_FUNC_INFO << lt::name_for_setting(settingindex) << ltsettings.get_str(settingindex).c_str();
+
+        QTableWidgetItem* tablewidget = new QTableWidgetItem();
+        tablewidget->setFlags(Qt::ItemIsEnabled);
+        tablewidget->setText(QString::fromStdString(lt::name_for_setting(settingindex)));
+        ui.settingsTableWidget->setItem(tablerowcount, 0, tablewidget);
+
+        tablewidget = new QTableWidgetItem();
+        tablewidget->setData(tableindexrole, QVariant(settingindex));
+        tablewidget->setData(tabletyperole, QVariant(int(QVariant::String)));
+        tablewidget->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable);
+        tablewidget->setText(QString::fromStdString(ltsettings.get_str(settingindex)));
+        ui.settingsTableWidget->setItem(tablerowcount, 1, tablewidget);
+
+        tablerowcount++;
+    }
+
+    // qDebug() << Q_FUNC_INFO << "int settings";
+    for (int i = 0; i < lt::settings_pack::settings_counts_t::num_int_settings; i++) {
+        ui.settingsTableWidget->setRowCount(tablerowcount + 1);
+
+        const int settingindex = (lt::settings_pack::int_type_base + i);
+        // qDebug() << Q_FUNC_INFO << lt::name_for_setting(settingindex) << ltsettings.get_int(settingindex);
+
+        QTableWidgetItem* tablewidget = new QTableWidgetItem();
+        tablewidget->setFlags(Qt::ItemIsEnabled);
+        tablewidget->setText(QString::fromStdString(lt::name_for_setting(settingindex)));
+        ui.settingsTableWidget->setItem(tablerowcount, 0, tablewidget);
+
+        tablewidget = new QTableWidgetItem();
+        tablewidget->setData(tableindexrole, QVariant(settingindex));
+        tablewidget->setData(tabletyperole, QVariant(int(QVariant::Int)));
+        tablewidget->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable);
+        tablewidget->setText(QString::number(ltsettings.get_int(settingindex)));
+        ui.settingsTableWidget->setItem(tablerowcount, 1, tablewidget);
+
+        tablerowcount++;
+    }
+
+    // qDebug() << Q_FUNC_INFO << "bool settings";
+    for (int i = 0; i < lt::settings_pack::settings_counts_t::num_bool_settings; i++) {
+        ui.settingsTableWidget->setRowCount(tablerowcount + 1);
+
+        const int settingindex = (lt::settings_pack::bool_type_base + i);
+        // qDebug() << Q_FUNC_INFO << lt::name_for_setting(settingindex) << ltsettings.get_bool(settingindex);
+
+        QTableWidgetItem* tablewidget = new QTableWidgetItem();;
+        tablewidget->setFlags(Qt::ItemIsEnabled);
+        tablewidget->setText(QString::fromStdString(lt::name_for_setting(settingindex)));
+        ui.settingsTableWidget->setItem(tablerowcount, 0, tablewidget);
+
+        tablewidget = new QTableWidgetItem();
+        tablewidget->setData(tableindexrole, QVariant(settingindex));
+        tablewidget->setData(tabletyperole, QVariant(int(QVariant::Bool)));
+        tablewidget->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
+        tablewidget->setCheckState(ltsettings.get_bool(settingindex) ? Qt::Checked : Qt::Unchecked);
+        ui.settingsTableWidget->setItem(tablerowcount, 1, tablewidget);
+
+        tablerowcount++;
+    }
+
+    emit changed(false);
+}
+
+void DlgTorrentSettings::save()
+{
+    QVariantMap settingsmap;
+    for (int i = 0; i < ui.settingsTableWidget->rowCount(); i++) {
+        QTableWidgetItem* tablewidget = ui.settingsTableWidget->item(i, 1);
+        const int settingsindex = tablewidget->data(tableindexrole).toInt();
+        const int settingstype = tablewidget->data(tabletyperole).toInt();
+        const QString settingskey = QString::number(settingsindex);
+        
+        // qDebug() << Q_FUNC_INFO << settingsindex << settingstype;
+
+        switch (settingstype) {
+            case QVariant::String: {
+                settingsmap.insert(settingskey, tablewidget->text());
+                break;
+            }
+            case QVariant::Int: {
+                settingsmap.insert(settingskey, tablewidget->text().toInt());
+                break;
+            }
+            case QVariant::Bool: {
+                settingsmap.insert(settingskey, tablewidget->checkState() == Qt::Checked ? true : false);
+                break;
+            }
+            default: {
+                kWarning() << "invalid setting type" << settingstype;
+                break;
+            }
+        }
+    }
+
+    QJsonDocument settingsjson = QJsonDocument::fromVariant(settingsmap);
+    if (settingsjson.isNull()) {
+        kWarning() << "could not parse settings map";
+        return;
+    }
+
+    QFile settingsfile(KStandardDirs::locateLocal("appdata", "torrentsettings.json"));
+    if (!settingsfile.open(QFile::WriteOnly)) {
+        kWarning() << "could not open settings file";
+        return;
+    }
+
+    const QByteArray settingsdata = settingsjson.toJson();
+    if (settingsfile.write(settingsdata) != settingsdata.size()) {
+        kWarning() << "could not write settings file";
+        return;
+    }
+
+    emit changed(false);
+}
+
+void DlgTorrentSettings::slotItemChanged(QTableWidgetItem* tablewidget)
+{
+    Q_UNUSED(tablewidget);
+    emit changed(true);
+}
+
+#include "moc_dlgtorrent.cpp"
diff --git a/kget/transfer-plugins/torrent/dlgtorrent.h b/kget/transfer-plugins/torrent/dlgtorrent.h
new file mode 100644 (file)
index 0000000..da4840c
--- /dev/null
@@ -0,0 +1,47 @@
+/*  This file is part of the KDE project
+
+    Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License version 2, as published by the Free Software Foundation.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef DLGTORRENT_H
+#define DLGTORRENT_H
+        
+#include "ui_dlgtorrent.h"
+
+#include <KCModule>
+#include <KDialog>
+
+class DlgTorrentSettings : public KCModule
+{
+    Q_OBJECT
+
+public:
+    explicit DlgTorrentSettings(QWidget *parent = 0, const QVariantList &args = QVariantList());
+    ~DlgTorrentSettings();
+
+public Q_SLOTS:
+    void save();
+    void load();
+
+private Q_SLOTS:
+    void slotItemChanged(QTableWidgetItem* tablewidget);
+
+private:
+    Ui::DlgTorrent ui;
+};
+
+#endif // DLGTORRENT_H
diff --git a/kget/transfer-plugins/torrent/dlgtorrent.ui b/kget/transfer-plugins/torrent/dlgtorrent.ui
new file mode 100644 (file)
index 0000000..959f193
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="System"?>
+<ui version="4.0">
+ <class>DlgTorrent</class>
+ <widget class="QWidget" name="DlgTorrent">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>403</width>
+    <height>439</height>
+   </rect>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="KTitleWidget" name="ktitlewidget">
+     <property name="text">
+      <string>Torrent Settings</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QTableWidget" name="settingsTableWidget">
+     <property name="sortingEnabled">
+      <bool>true</bool>
+     </property>
+     <attribute name="horizontalHeaderStretchLastSection">
+      <bool>true</bool>
+     </attribute>
+     <attribute name="verticalHeaderVisible">
+      <bool>false</bool>
+     </attribute>
+     <column>
+      <property name="text">
+       <string>Setting</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Value</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout"/>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KTitleWidget</class>
+   <extends></extends>
+   <header>ktitlewidget.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/kget/transfer-plugins/torrent/kget_torrentfactory_config.desktop b/kget/transfer-plugins/torrent/kget_torrentfactory_config.desktop
new file mode 100644 (file)
index 0000000..bf05b67
--- /dev/null
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Type=Service
+X-KDE-ServiceTypes=KCModule
+
+X-KDE-Library=kcm_kget_torrentfactory
+X-KDE-ParentComponents=kget_torrent_plugin
+
+Name=Torrent
index 5e06881..ea0baa3 100644 (file)
 #include "transferTorrent.h"
 
 #include <QTimer>
+#include <QFile>
+#include <QJsonDocument>
 #include <klocale.h>
+#include <kstandarddirs.h>
 #include <kdebug.h>
 
 #include <boost/make_shared.hpp>
@@ -380,11 +383,11 @@ TransferTorrent::TransferTorrent(TransferGroup* parent, TransferFactory* factory
                                  Scheduler* scheduler, const KUrl &source, const KUrl &dest,
                                  const QDomElement* e)
     : Transfer(parent, factory, scheduler, source, dest, e),
-    m_timerid(0), m_ltsession(nullptr), m_filemodel(nullptr)
+    m_timerid(0), m_ltsession(nullptr), m_filemodel(nullptr), m_dirwatch(nullptr)
 {
     setCapabilities(Transfer::Cap_SpeedLimit | Transfer::Cap_Resuming | Transfer::Cap_MultipleMirrors);
 
-    lt::settings_pack ltsettings;
+    lt::settings_pack ltsettings = lt::default_settings();
     ltsettings.set_int(lt::settings_pack::alert_mask,
         lt::alert::status_notification
         | lt::alert::error_notification
@@ -392,6 +395,12 @@ TransferTorrent::TransferTorrent(TransferGroup* parent, TransferFactory* factory
         | lt::alert::stats_notification);
 
     m_ltsession = new lt::session(ltsettings);
+
+    m_dirwatch = new KDirWatch(this);
+    m_dirwatch->addFile(KStandardDirs::locateLocal("appdata", "torrentsettings.json"));
+    connect(m_dirwatch, SIGNAL(dirty(QString)), this, SLOT(slotSettingsDirty(QString)));
+
+    applySettings();
 }
 
 TransferTorrent::~TransferTorrent()
@@ -690,6 +699,71 @@ void TransferTorrent::slotCheckStateChanged()
     }
 }
 
+void TransferTorrent::slotSettingsDirty(const QString &settings)
+{
+    kDebug(5001) << "torrent settings are dirty";
+    Q_UNUSED(settings);
+    applySettings();
+}
+
+void TransferTorrent::applySettings()
+{
+    if (!m_ltsession) {
+        kDebug(5001) << "null torrent session pointer";
+        return;
+    }
+
+    QFile settingsfile(KStandardDirs::locateLocal("appdata", "torrentsettings.json"));
+    if (!settingsfile.exists()) {
+        kDebug(5001) << "settings file does not exist";
+        return;
+    }
+
+    if (!settingsfile.open(QFile::ReadOnly)) {
+        kWarning(5001) << "could not open settings file";
+        return;
+    }
+
+    const QJsonDocument settingsjson = QJsonDocument::fromJson(settingsfile.readAll());
+    if (settingsjson.isNull()) {
+        kWarning(5001) << "could not parse settings file";
+        return;
+    }
+
+    const QVariantMap settingsmap = settingsjson.toVariant().toMap();
+    lt::settings_pack ltsettings = lt::default_settings();
+    foreach (const QString &key, settingsmap.keys()) {
+        const int settingskey = key.toInt();
+        const QVariant settingsvalue = settingsmap.value(key);
+        switch (settingsvalue.type()) {
+            case QVariant::ByteArray:
+            case QVariant::String: {
+                const QString settingsstring = settingsvalue.toString();
+                ltsettings.set_str(settingskey, settingsstring.toStdString());
+                break;
+            }
+            case QVariant::Int:
+            case QVariant::UInt:
+            case QVariant::LongLong:
+            case QVariant::ULongLong: {
+                const int settingsint = settingsvalue.toInt();
+                ltsettings.set_int(settingskey, settingsint);
+                break;
+            }
+            case QVariant::Bool: {
+                const bool settingsbool = settingsvalue.toBool();
+                ltsettings.set_int(settingskey, settingsbool);
+                break;
+            }
+            default: {
+                kWarning(5001) << "invalid setting type";
+                break;
+            }
+        }
+    }
+    m_ltsession->apply_settings(ltsettings);
+}
+
 void TransferTorrent::save(const QDomElement &element)
 {
     QDomElement elementcopy = element;
index 11e5bb9..a85d003 100644 (file)
@@ -24,6 +24,7 @@
 #include "core/filemodel.h"
 
 #include <QTimerEvent>
+#include <kdirwatch.h>
 
 #include <vector>
 #include <libtorrent/session.hpp>
@@ -66,13 +67,17 @@ protected:
 private Q_SLOTS:
     void slotDelayedStart();
     void slotCheckStateChanged();
+    void slotSettingsDirty(const QString &settings);
 
 private:
+    void applySettings();
+
     int m_timerid;
     lt::session* m_ltsession;
     lt::torrent_handle m_lthandle;
     TorrentFileModel* m_filemodel;
     std::vector<boost::uint8_t> m_priorities;
+    KDirWatch* m_dirwatch;
 };
 
 #endif // TRANSFER_TORRENT_H