Client-server through DBus, cmake support
authordeztructor <denis.zalewsky@gmail.com>
Mon, 16 Nov 2009 13:20:04 +0000 (13:20 +0000)
committerdeztructor <denis.zalewsky@gmail.com>
Mon, 16 Nov 2009 13:20:04 +0000 (13:20 +0000)
git-svn-id: file:///svnroot/qtrapids/trunk@22 42ac0dd5-4c8c-4c71-bb3e-ecdfe252ffda

31 files changed:
CMakeLists.txt [new file with mode: 0644]
dbus/CMakeLists.txt [new file with mode: 0644]
dbus/com.ixonos.qtrapids.xml [new file with mode: 0644]
includes.pri
src/client/CMakeLists.txt [new file with mode: 0644]
src/client/DownloadView.cpp [new file with mode: 0644]
src/client/DownloadView.h [new file with mode: 0644]
src/client/MainWindow.cpp [new file with mode: 0644]
src/client/MainWindow.h [new file with mode: 0644]
src/client/PreferencesDialog.cpp [new file with mode: 0644]
src/client/PreferencesDialog.h [new file with mode: 0644]
src/client/SeedView.cpp [new file with mode: 0644]
src/client/SeedView.h [new file with mode: 0644]
src/client/gui.pro [new file with mode: 0644]
src/client/main.cpp [new file with mode: 0644]
src/include/qtrapids/dbus.hpp [new file with mode: 0644]
src/include/qtrapids/error.hpp [new file with mode: 0644]
src/include/qtrapids/format.hpp [new file with mode: 0644]
src/include/qtrapids/info.hpp [new file with mode: 0644]
src/server/AlertWaiterThread.cpp [new file with mode: 0644]
src/server/AlertWaiterThread.hpp [new file with mode: 0644]
src/server/CMakeLists.txt [new file with mode: 0644]
src/server/ServerDb.hpp [new file with mode: 0644]
src/server/TorrentHandle.cpp [new file with mode: 0644]
src/server/TorrentHandle.hpp [new file with mode: 0644]
src/server/TorrentSession.cpp [new file with mode: 0644]
src/server/TorrentSession.hpp [new file with mode: 0644]
src/server/create_db.sql [new file with mode: 0644]
src/server/main.cpp [new file with mode: 0644]
src/server/server.pro [new file with mode: 0644]
src/src.pro

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..adee58e
--- /dev/null
@@ -0,0 +1,12 @@
+project(qtrapids)
+cmake_minimum_required(VERSION 2.6)
+set(CMAKE_VERBOSE_MAKEFILE ON)
+
+add_definitions(-Wall -g)
+
+find_package(Qt4 REQUIRED)
+
+add_subdirectory(./dbus)
+add_subdirectory(./src/client)
+add_subdirectory(./src/server)
+
diff --git a/dbus/CMakeLists.txt b/dbus/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4a4c67c
--- /dev/null
@@ -0,0 +1,24 @@
+SET(SOURCES com.ixonos.qtrapids.xml)
+SET(PROXY_SRC proxy.h proxy.cpp)
+SET(SERVER_SRC server.h server.cpp)
+
+SET(PROXY_TARGET 
+  ${CMAKE_HOME_DIRECTORY}/src/client/proxy.h 
+  ${CMAKE_HOME_DIRECTORY}/src/client/proxy.cpp)
+
+SET(SERVER_TARGET 
+  ${CMAKE_HOME_DIRECTORY}/src/server/server.h 
+  ${CMAKE_HOME_DIRECTORY}/src/server/server.cpp)
+
+SET(GENERATED_FILES ${PROXY_SRC} ${SERVER_SRC})
+
+ADD_CUSTOM_COMMAND(OUTPUT ${GENERATED_FILES} 
+  COMMAND qdbusxml2cpp -a server -c QtRapidsServer -i "qtrapids/dbus.hpp" -p proxy ${SOURCES}
+  COMMAND cp ${PROXY_SRC} ${CMAKE_HOME_DIRECTORY}/src/client
+  COMMAND cp ${SERVER_SRC} ${CMAKE_HOME_DIRECTORY}/src/server
+  DEPENDS ${SOURCES}
+  COMMENT "DBus API sources")
+
+
+ADD_CUSTOM_TARGET(dbusapi ALL DEPENDS ${GENERATED_FILES})
+
diff --git a/dbus/com.ixonos.qtrapids.xml b/dbus/com.ixonos.qtrapids.xml
new file mode 100644 (file)
index 0000000..92f5702
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/com/ixonos/qtrapids">
+
+  <interface name="com.ixonos.qtrapids">
+
+    <method name="getState">
+    </method>
+
+    <method name="addTorrent">
+      <arg type="s" name="path" direction="in"/>
+      <arg type="s" name="save_path" direction="in"/>
+      <arg type="a{ss}" name="other_params" direction="in"/>
+      <annotation name="com.trolltech.QtDBus.QtTypeName.In2" 
+                  value="qtrapids::ParamsMap_t"/>
+    </method>
+
+    <method name="removeTorrent">
+      <arg type="s" name="hash" direction="in"/>
+    </method>
+
+    <signal name="alert">
+      <arg type="(ssuuuuuuut)" name="info" direction="out"/>
+      <annotation name="com.trolltech.QtDBus.QtTypeName.In0" 
+                  value="qtrapids::TorrentState"/>
+      <arg type="a{ss}" name="other_info" direction="out"/>
+      <annotation name="com.trolltech.QtDBus.QtTypeName.In1" 
+                  value="qtrapids::ParamsMap_t"/>
+    </signal>
+
+  </interface>
+
+</node>
index 108a4fb..0c073f1 100644 (file)
@@ -1,4 +1,5 @@
 INCLUDEPATH = /usr/local/include/libtorrent \
-       /usr/local/include/boost-1_38
+       /usr/local/include/boost-1_38 \
+    ../include
 
 CONFIG -= debug
diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d2ae12d
--- /dev/null
@@ -0,0 +1,48 @@
+INCLUDE(${QT_USE_FILE})
+
+INCLUDE_DIRECTORIES(../include)
+
+FIND_LIBRARY(BOOST_SYSTEM boost_system-mt)
+IF(${BOOST_SYSTEM} STREQUAL BOOST_SYSTEM-NOTFOUND)
+  MESSAGE(SEND_ERROR ${BOOST_SYSTEM})
+ENDIF(${BOOST_SYSTEM} STREQUAL BOOST_SYSTEM-NOTFOUND)
+
+INCLUDE_DIRECTORIES(
+   ${QT_INCLUDE_DIR}
+   ${QT_QTTEST_INCLUDE_DIR}
+   ${QT_QTDBUS}
+   ${QT_QTGUI}
+)
+
+SET_SOURCE_FILES_PROPERTIES(./proxy.cpp ./proxy.h PROPERTIES GENERATED 1)
+
+SET(MOC_HEADERS
+  ./DownloadView.h
+  ./MainWindow.h
+  ./PreferencesDialog.h
+  ./proxy.h
+  ./SeedView.h
+)
+
+SET(SRC
+  ./DownloadView.cpp
+  ./main.cpp
+  ./MainWindow.cpp
+  ./PreferencesDialog.cpp
+  ./proxy.cpp
+  ./SeedView.cpp
+)
+
+QT4_WRAP_CPP(SRC ${MOC_HEADERS})
+ADD_EXECUTABLE(qtrapids ${SRC} ${MOC_HEADERS})
+
+ADD_DEFINITIONS(-DQT_SHARED)
+TARGET_LINK_LIBRARIES(qtrapids 
+  ${QT_QTGUI_LIBRARY} 
+  ${QT_QTCORE_LIBRARY} 
+  ${QT_QTDBUS_LIBRARY}
+  ${QT_QTTEST_LIBRARY}
+  -lboost_system-mt
+)
+
+ADD_DEPENDENCIES(qtrapids dbusapi)
diff --git a/src/client/DownloadView.cpp b/src/client/DownloadView.cpp
new file mode 100644 (file)
index 0000000..d2201db
--- /dev/null
@@ -0,0 +1,181 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#include <qtrapids/format.hpp>
+
+#include "DownloadView.h"
+
+#include <QDebug>
+#include <QVariant>
+#include <QColor>
+
+namespace qtrapids
+{
+
+    DownloadView::DownloadView(QWidget* parent) :
+        QTreeWidget(parent),
+        items_()
+    {
+        setRootIsDecorated(false); // Hide branch lines, making one-level treeview (similar to list)
+        setHeaderItem(DownloadViewItem::getHeaderItem());
+
+        connect(this, SIGNAL(itemPressed(QTreeWidgetItem*, int)),
+                this, SLOT(on_itemClicked(QTreeWidgetItem*, int)));
+
+    }
+
+
+    DownloadView::~DownloadView()
+    {
+    }
+
+    void DownloadView::updateItem(TorrentState const& info, ParamsMap_t other_info)
+    {
+        DownloadItems_t::iterator p = items_.find(info.hash);
+        if (p != items_.end()) {
+            updateItem_(p.value(), info, other_info);
+        } else {
+            addItem_(info, other_info);
+        }
+    }
+
+    void DownloadView::addItem_(TorrentState const& info, ParamsMap_t)
+    {
+        DownloadViewItem *item = new DownloadViewItem
+            ( info.hash, 
+              QStringList()
+              << info.name
+              << formatSize(info.total_size)
+              << GetStatusString((TorrentStatus::Id)info.state)
+              << formatProgress(info.progress)
+              << QString::number(info.down_rate, 'f', 2)
+              << QString::number(info.up_rate, 'f', 2)
+              << QString::number(info.seeds) + "/" + QString::number(info.leeches)
+              << QString::number(info.ratio)
+              << "ETA" );
+
+        QBrush brushTmp(GetStatusColor((TorrentStatus::Id)info.state));
+        item->setForeground(2, brushTmp);
+
+        addTopLevelItem(item);
+        items_[info.hash] = item;
+    }
+
+
+    void DownloadView::updateItem_(DownloadViewItem *item
+                                   , TorrentState const& info, ParamsMap_t)
+    {
+        item->setData(2, Qt::DisplayRole,
+                      QVariant(GetStatusString((TorrentStatus::Id)info.state)));
+        item->setData(3, Qt::DisplayRole,
+                      QVariant(formatProgress(info.progress)));
+        item->setData(4, Qt::DisplayRole,
+                      QVariant(QString::number(info.down_rate)));
+        item->setData(5, Qt::DisplayRole,
+                      QVariant(QString::number(info.up_rate)));
+        item->setData(6, Qt::DisplayRole,
+                      QString::number(info.seeds) + "/" + QString::number(info.leeches));
+    
+        QBrush brushTmp(GetStatusColor((TorrentStatus::Id)info.state));
+        item->setForeground(2, brushTmp);
+    }
+
+
+    QString DownloadView::removeSelected()
+    {
+        qDebug() << "DownloadView::removeSelected() " <<  topLevelItemCount() ;
+
+        DownloadViewItem *item = dynamic_cast<DownloadViewItem*> (currentItem());
+        QString hash = item->getHash();
+
+        int removed = items_.remove(hash);
+        if (!removed)
+            qDebug() << "Inconsistent download view state on item removal";
+
+        int index = indexOfTopLevelItem(currentItem());
+        if (index >= 0) {
+            takeTopLevelItem(index);
+        }
+
+        qDebug() << "DownloadView::removeSelected() " <<  topLevelItemCount() ;
+
+        return hash;
+    }
+
+
+    void DownloadView::on_itemClicked(QTreeWidgetItem * , int)
+    {
+        /*
+          qDebug() << "DownloadView::on_itemClicked(()" << item << "," << column;
+          qDebug() << "current item" << currentItem();
+
+          if (item == currentItem() && item->isSelected()) {
+          item->setSelected(false);
+          }
+        */
+    }
+
+
+    QString DownloadView::GetStatusString(TorrentStatus::Id status)
+    {
+        switch (status) {
+            case TorrentStatus::QUEUED_FOR_CHECKING :
+                return tr("Queued");
+            case TorrentStatus::CHECKING_FILES :
+                return tr("Checking");
+            case TorrentStatus::DOWNLOADING_METADATA :
+                return tr("DL meta");
+            case TorrentStatus::DOWNLOADING :
+                return tr("Downloading");
+            case TorrentStatus::FINISHED :
+                return tr("Finished");
+            case TorrentStatus::SEEDING :
+                return tr("Seeding");
+            case TorrentStatus::ALLOCATING :
+                return tr("Allocating");
+            case TorrentStatus::CHECKING_RESUME_DATA :
+                return tr("Checking resume");
+            default:
+                return tr("N/A");
+        }
+    }
+
+
+    QColor DownloadView::GetStatusColor(TorrentStatus::Id status)
+    {
+        QColor green(40,205,40);
+        QColor yellow(255,174,0);
+
+        switch (status) {
+            case TorrentStatus::QUEUED_FOR_CHECKING :
+            case TorrentStatus::CHECKING_FILES :
+            case TorrentStatus::DOWNLOADING_METADATA :
+            case TorrentStatus::ALLOCATING :
+            case TorrentStatus::CHECKING_RESUME_DATA:
+                return yellow;
+            case TorrentStatus::DOWNLOADING :
+            case TorrentStatus::FINISHED :
+            case TorrentStatus::SEEDING :
+                               return green;
+            default:
+                return QColor();
+        }
+    }
+
+} // namespace qtrapids
diff --git a/src/client/DownloadView.h b/src/client/DownloadView.h
new file mode 100644 (file)
index 0000000..abc7ea6
--- /dev/null
@@ -0,0 +1,118 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef DOWNLOADVIEW_H
+#define DOWNLOADVIEW_H
+
+#include <map>
+#include <qtrapids/info.hpp>
+#include <qtrapids/dbus.hpp>
+
+#include <QTreeWidget>
+
+
+namespace qtrapids
+{
+
+    class DownloadViewItem;
+
+    typedef QHash<QString, DownloadViewItem*> DownloadItems_t;
+
+    /**
+       @class DownloadView
+       @brief A view showing all downloaded torrents
+       @author Lassi Väätämöinen <lassi.vaatamoinen@ixonos.com>
+    */
+    class DownloadView : public QTreeWidget
+    {
+        Q_OBJECT
+               
+        public:
+        DownloadView(QWidget* parent);
+
+        ~DownloadView();
+
+               void updateItem(TorrentState const& info, ParamsMap_t other_info);
+               QString removeSelected();
+               
+    private slots:
+               void on_itemClicked(QTreeWidgetItem * item, int column);
+       private:
+
+               void addItem_(TorrentState const& info, ParamsMap_t other_info);
+               void updateItem_(DownloadViewItem *item
+                         , TorrentState const& info, ParamsMap_t other_info);
+
+               // Maps torrent to downloadview item.
+               // Key: SHA1 info hash of torrent. Data: View item corresponding to torrent.
+        DownloadItems_t items_;
+               
+               // Private functions.
+        static QString GetStatusString(TorrentStatus::Id status);
+        static QColor GetStatusColor(TorrentStatus::Id status);
+    };
+
+
+    /**
+       @class DownloadViewItem
+       @brief Represents one item row of DownloadView
+    */
+    class DownloadViewItem : public QTreeWidgetItem {
+       
+       public: 
+        DownloadViewItem(QTreeWidget* parent, int type) : 
+            QTreeWidgetItem(parent, type = QTreeWidgetItem::UserType) {};
+               
+        DownloadViewItem(QString hash, const QStringList& strings, 
+                         int type = QTreeWidgetItem::UserType) : 
+            QTreeWidgetItem (strings, type = Type),
+            hash_(hash)
+        {}
+               
+               
+        /// @return An item comprising of string list, suitable for QTableView
+               /// header.
+               static DownloadViewItem *getHeaderItem()
+               {
+                       DownloadViewItem *item  
+                               = new DownloadViewItem("", QStringList() 
+                                       << "Name" 
+                                       << "Size" << "Status" 
+                                       << "Progress" << "DL speed" 
+                                       << "UL speed" << "Seeds/Leechers"
+                                       << "Ratio" << "ETA");
+                       
+                       return item;
+               }
+
+               /// @todo QTorrentHandle as one hidden column
+
+        QString getHash() const 
+        { 
+            return hash_;
+        }
+
+    private:
+        QString hash_;
+    };
+
+} // namespace qtrapids
+
+#endif // DOWNLOADVIEW_H
+
diff --git a/src/client/MainWindow.cpp b/src/client/MainWindow.cpp
new file mode 100644 (file)
index 0000000..e200865
--- /dev/null
@@ -0,0 +1,234 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+
+#include <qtrapids/dbus.hpp>
+
+#include <QDebug>
+#include <QtGui/QMenuBar>
+#include <QtGui/QToolBar>
+#include <QAction>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QTabWidget>
+
+#include "DownloadView.h"
+#include "SeedView.h"
+#include "PreferencesDialog.h"
+
+#include "MainWindow.h"
+
+namespace qtrapids
+{
+
+    const QString ABOUT_TEXT 
+       = QString(QObject::trUtf8("QtRapids, a simple BitTorrent client based on"
+                              "\nQt and Libtorrent."
+                              "\n\nURL: http://qtrapids.garage.maemo.org/"
+                              "\n\nAuthor(s):\nLassi Väätämöinen, lassi.vaatamoinen@ixonos.com"
+                              "\nDenis Zalevskiy, denis.zalewsky@ixonos.com"
+                              "\n\nIxonos Plc, Finland\n"));
+
+
+    // Consturctor
+    MainWindow::MainWindow() :
+        QMainWindow(), // Superclass
+        tabWidget_(NULL),
+        dlView_(NULL),
+        seedView_(NULL),
+        preferencesDialog_(NULL),
+        settings_(QCoreApplication::organizationName()
+                  , QCoreApplication::applicationName()),
+        server_(QtRapidsServer::staticInterfaceName()
+                , "/qtrapids", QDBusConnection::sessionBus())
+        //     torrentHandles_(),
+    {
+        // MENUBAR 
+        QMenuBar *menuBar = new QMenuBar();
+        QMenu *tempMenu = NULL;
+       
+        tempMenu = menuBar->addMenu(tr("&File"));
+        QAction *openAction = tempMenu->addAction(tr("&Open"));
+        QAction *removeAction = tempMenu->addAction(tr("&Remove"));
+        removeAction->setEnabled(false);
+        QAction *quitAction = tempMenu->addAction(tr("&Quit"));
+       
+        tempMenu = menuBar->addMenu(tr("&Settings"));
+        QAction *preferencesAction = tempMenu->addAction(tr("&Preferences"));
+       
+        tempMenu = menuBar->addMenu(tr("&Help"));
+        QAction *aboutAction = tempMenu->addAction(tr("&About"));
+        QAction *aboutQtAction = tempMenu->addAction(tr("About &Qt"));
+       
+        setMenuBar(menuBar);
+        connect(openAction, SIGNAL(triggered()), this, SLOT(on_openAction_clicked()));
+        connect(removeAction, SIGNAL(triggered()), this, SLOT(on_removeAction_clicked()));
+        connect(this, SIGNAL(itemSelected(bool)), removeAction, SLOT(setEnabled(bool)));
+        connect(quitAction, SIGNAL(triggered()), this, SLOT(on_quitAction_clicked()));
+        connect(preferencesAction, SIGNAL(triggered()), this, SLOT(on_preferencesAction_clicked()));
+        connect(aboutAction, SIGNAL(triggered()), this, SLOT(on_aboutAction_clicked()));
+        connect(aboutQtAction, SIGNAL(triggered()), this, SLOT(on_aboutQtAction_clicked()));
+       
+        // TABWIDGET (central widget)
+        tabWidget_ = new QTabWidget();
+       
+        /// @todo Exception handling
+        dlView_ = new DownloadView(this);
+        seedView_ = new SeedView(this);
+        tabWidget_->addTab(dlView_, tr("Downloads"));
+        tabWidget_->addTab(seedView_, tr("Seeds"));
+        connect(dlView_, SIGNAL(itemSelectionChanged()), this,
+                SLOT(on_downloadItemSelectionChanged()));
+
+        connect(seedView_, SIGNAL(itemSelectionChanged()), this,
+                SLOT(on_seedItemSelectionChanged()));
+       
+        // Tab widget as central widget.
+        setCentralWidget(tabWidget_);
+       
+        // TOOLBAR
+        QToolBar *toolBar = new QToolBar();
+        toolBar->addAction(tr("Open"));
+        removeAction = toolBar->addAction(tr("Remove"));
+        removeAction->setEnabled(false);
+        addToolBar(Qt::TopToolBarArea, toolBar);
+       
+        connect(this, SIGNAL(itemSelected(bool)), removeAction,
+                SLOT(setEnabled(bool)));
+        connect(toolBar, SIGNAL(actionTriggered(QAction*)), this,
+                SLOT(handleToolBarAction(QAction*)));
+
+        QVariant geometry(settings_.value("geometry"));
+        if (!geometry.isNull()) {
+            qDebug() << "restoring geometry";
+            restoreGeometry(geometry.toByteArray());
+        }
+    }
+
+
+    MainWindow::~MainWindow()
+    {
+        settings_.setValue("geometry", saveGeometry());
+    }
+
+    // =========================== SLOTS =================================
+    void MainWindow::on_openAction_clicked()
+    {
+        QFileDialog *dialog = new QFileDialog( this, "Open torrent file", QString(), tr("Torrent files (*.torrent)"));
+        dialog->setFileMode(QFileDialog::ExistingFile);
+        connect(dialog, SIGNAL(fileSelected(const QString&)), this, SLOT(on_torrentFileSelected(const QString&)));
+        dialog->show();
+
+    }
+
+    void MainWindow::on_removeAction_clicked()
+    {
+        QString hash = dlView_->removeSelected();
+        try {
+            server_.removeTorrent(hash);
+        } catch (...) {
+            qDebug() << "Exception removing torrent";
+        }
+    }
+
+    void MainWindow::on_quitAction_clicked()
+    {
+        close();
+    }
+
+    void MainWindow::on_preferencesAction_clicked()
+    {
+        if (!preferencesDialog_) {
+            preferencesDialog_ = new PreferencesDialog(this);
+        }
+        preferencesDialog_->show();
+        preferencesDialog_->raise();
+        preferencesDialog_->activateWindow();
+    }
+
+    void MainWindow::on_aboutAction_clicked()
+    {
+        QMessageBox::about(this, tr("About QtRapids"), ABOUT_TEXT); 
+    }
+               
+               
+    void MainWindow::on_aboutQtAction_clicked()
+    {
+        QMessageBox::aboutQt (this, tr("About Qt"));
+    }
+
+
+    void MainWindow::on_downloadItemSelectionChanged()
+    {
+        qDebug() << "MainWindow::on_seedItemSelectionChanged():" << dlView_->currentItem();
+        if (dlView_->currentItem() != NULL) {
+            emit(itemSelected(true));
+        } else {
+            emit(itemSelected(false));
+        }
+    }
+
+    void MainWindow::on_seedItemSelectionChanged()
+    {
+        qDebug() << "MainWindow::on_seedItemSelectionChanged():" << seedView_->currentItem();
+        if (seedView_->currentItem() != NULL) {
+               emit(itemSelected(true));
+        } else {
+               emit(itemSelected(false));
+        }
+    }
+               
+    void MainWindow::handleToolBarAction(QAction* action)
+    {
+        if (action->text() == "Open") {
+            on_openAction_clicked();
+        } else if (action->text() == "Remove") {
+            on_removeAction_clicked();
+        }
+    }
+
+    void MainWindow::on_torrentFileSelected(const QString& file)
+    {
+        qDebug() << " MainWindow::on_torrentFileSelected(): " << file;
+        // Torrent filename empty, do nothing.
+        if (file == "") {
+            return;
+        }
+       
+        // Otherwise add torrent
+        // For params, see: http://www.rasterbar.com/products/libtorrent/manual.html#add-torrent
+        // save_path is the only mandatory parameter, rest are optional.
+        //addParams.storage_mode = libtorrent::storage_mode_allocate;
+        try {
+            server_.addTorrent(file, settings_.value("download/directory").toString()
+                               , ParamsMap_t());
+        } catch (...) {
+            qDebug() << "Exception adding torrent";
+        }
+    }
+
+
+    void MainWindow::alert(qtrapids::TorrentState info, qtrapids::ParamsMap_t other_info)
+    {
+        std::cerr << "got alert" << std::endl;
+        dlView_->updateItem(info, other_info);
+    }
+
+} // namespace qtrapids
diff --git a/src/client/MainWindow.h b/src/client/MainWindow.h
new file mode 100644 (file)
index 0000000..43e2bc4
--- /dev/null
@@ -0,0 +1,96 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QSettings>
+
+#include "proxy.h"
+
+class QTabWidget;
+class DownloadView;
+class PreferencesDialog;
+
+namespace qtrapids
+{
+
+    class SeedView;
+
+    /**
+       @author Lassi Väätämöinen <lassi.vaatamoinen@ixonos.com>
+    */
+    class MainWindow : public QMainWindow {
+        Q_OBJECT;
+                       
+    public:
+        
+        MainWindow();
+        ~MainWindow();
+        
+        void connectToServer()
+        {
+            qDBusRegisterMetaType<qtrapids::TorrentState>();
+            qDBusRegisterMetaType<qtrapids::ParamsMap_t>();
+
+            connect(&server_
+                    , SIGNAL(alert(qtrapids::TorrentState
+                                   , qtrapids::ParamsMap_t))
+                    , this
+                    , SLOT(alert(qtrapids::TorrentState
+                                 , qtrapids::ParamsMap_t)));
+            server_.getState();
+        }
+               
+       signals:
+               void itemSelected(bool enabled);
+               
+       public slots:
+       private slots:
+               void on_openAction_clicked();
+               void on_removeAction_clicked();
+               void on_quitAction_clicked();
+               void on_preferencesAction_clicked();
+               void on_aboutAction_clicked();
+               void on_aboutQtAction_clicked();
+               void on_downloadItemSelectionChanged();
+               void on_seedItemSelectionChanged();
+               void handleToolBarAction(QAction* action);
+               void on_torrentFileSelected(const QString& file);
+        void alert(qtrapids::TorrentState, qtrapids::ParamsMap_t);
+               
+       private:
+               QTabWidget *tabWidget_;
+               DownloadView *dlView_;
+               SeedView *seedView_;
+               PreferencesDialog *preferencesDialog_;
+               QSettings settings_;
+               
+               //std::vector< std::auto_ptr<QTorrentHandle> const > torrentHandles_;
+
+        QtRapidsServer server_;
+               
+
+               //bool IsNewTorrent(std::auto_ptr<QTorrentHandle> handlePtr);
+    };
+
+} // namespace qtrapids
+
+#endif
diff --git a/src/client/PreferencesDialog.cpp b/src/client/PreferencesDialog.cpp
new file mode 100644 (file)
index 0000000..9ee381b
--- /dev/null
@@ -0,0 +1,143 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#include <QDebug>
+#include <QBoxLayout>
+#include <QLineEdit>
+#include <QLabel>
+#include <QPushButton>
+#include <QDialogButtonBox>
+#include <QAbstractButton>
+#include <QFileDialog>
+
+#include "PreferencesDialog.h"
+
+PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags f) : 
+       QDialog(parent, f), // Superclass
+       dirLineEdit_(NULL),
+       dialogButtons_(NULL),
+       settings_()
+{
+       setWindowTitle("Preferences");
+       
+       QBoxLayout *verticalBox = new QBoxLayout(QBoxLayout::TopToBottom);
+       QBoxLayout *horizontalBox1 = new QBoxLayout(QBoxLayout::LeftToRight);
+       setLayout(verticalBox); 
+       verticalBox->addLayout(horizontalBox1);
+
+       QLabel *dirLabel = new QLabel(tr("Download directory: "));
+       dirLineEdit_ = new QLineEdit(this);
+       QPushButton *browseDirButton = new QPushButton(tr("Browse.."));
+       
+       horizontalBox1->addWidget(dirLabel);
+       horizontalBox1->addWidget(dirLineEdit_);
+       horizontalBox1->addWidget(browseDirButton);
+       
+       connect(browseDirButton, SIGNAL(clicked()),
+                                       this, SLOT(on_browseDirButtonClicked()));
+       
+       
+       dialogButtons_ = new QDialogButtonBox(this);
+       dialogButtons_->setStandardButtons(QDialogButtonBox::Ok
+                                                                                                                                                       | QDialogButtonBox::Apply 
+                                                                                                                                                       | QDialogButtonBox::Cancel);
+       
+       verticalBox->addWidget(dialogButtons_);
+       
+       connect(dialogButtons_, SIGNAL(clicked(QAbstractButton*)),
+                                       this, SLOT(on_buttonClicked(QAbstractButton*)));
+       
+       // Set saved preference values to fields.
+       ReadSettings();
+       
+}
+
+
+PreferencesDialog::~PreferencesDialog()
+{
+}
+
+// ======================== SLOTS ========================
+void PreferencesDialog::on_browseDirButtonClicked()
+{
+       QFileDialog *dialog 
+                       = new QFileDialog(this, "Download directory",   
+                                                                                               QString(), tr("Torrent files (*.torrent)"));
+       
+       dialog->setFileMode(QFileDialog::Directory);
+       dialog->setOption(QFileDialog::ShowDirsOnly, true);
+       
+       connect(dialog, SIGNAL(fileSelected(const QString&)),
+                                       this, SLOT(on_downloadDirectorySelected(const QString&)));
+       
+       dialog->show();
+}
+
+void PreferencesDialog::on_buttonClicked(QAbstractButton* button)
+{
+       switch (dialogButtons_->buttonRole ( button ) )
+       {
+               case QDialogButtonBox::AcceptRole :
+                       qDebug() << "PreferencesDialog: OK";
+                       WriteSettings();
+                       close();
+                       break;
+               case QDialogButtonBox::ApplyRole :
+                       qDebug() << "PreferencesDialog: APPLY";
+                       WriteSettings();
+                       break;
+               case QDialogButtonBox::RejectRole : 
+                       qDebug() << "PreferencesDialog: CANCEL";
+                       close();
+                       break;
+               default: 
+                       return;
+       }
+}
+
+void PreferencesDialog::on_downloadDirectorySelected(const QString& directory)
+{
+       qDebug() << "PreferencesDialog::on_downloadDirectorySelected(): " << directory;
+       // Torrent filename empty, do nothing.
+       if (directory == "") 
+               return;
+       
+       dirLineEdit_->insert(directory);
+       
+       /// @todo check that user has privileges to write to this directory.
+}
+
+
+// ========================= Private functions ==========================
+void PreferencesDialog::WriteSettings()
+{
+       settings_.setValue("download/directory", dirLineEdit_->text());
+       
+       // NOTE: We might need to call QSettigns::sync() here to instantly write settings.
+       // settings are written also by QSettings() destructor and by event loop at regular interval.
+}
+
+void PreferencesDialog::ReadSettings()
+{
+       dirLineEdit_->insert(settings_.value("download/directory").toString());
+       
+       // NOTE: We might need to call QSettigns::sync() here to instantly write settings.
+       // settings are written also by QSettings() destructor and by event loop at regular interval.
+}
+
diff --git a/src/client/PreferencesDialog.h b/src/client/PreferencesDialog.h
new file mode 100644 (file)
index 0000000..c368ea0
--- /dev/null
@@ -0,0 +1,59 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef PREFERENCESDIALOG_H
+#define PREFERENCESDIALOG_H
+
+#include <QDialog>
+#include <QSettings>
+
+
+class QAbstractButton;
+class QLineEdit;
+class QDialogButtonBox;
+
+/**
+       @author Lassi Väätämöinen <lassi.vaatamoinen@ixonos.com>
+*/
+class PreferencesDialog : public QDialog
+{
+       
+       Q_OBJECT
+               
+       public:
+    PreferencesDialog(QWidget* parent = 0, Qt::WindowFlags f = 0);
+
+    ~PreferencesDialog();
+
+       private slots:
+               void on_browseDirButtonClicked();
+               void on_buttonClicked(QAbstractButton* button);
+               void on_downloadDirectorySelected(const QString& directory);
+               
+       private:
+               QLineEdit *dirLineEdit_;
+               QDialogButtonBox *dialogButtons_;
+               QSettings settings_;
+               
+               // Private functions:
+               void WriteSettings();
+               void ReadSettings();
+};
+
+#endif
diff --git a/src/client/SeedView.cpp b/src/client/SeedView.cpp
new file mode 100644 (file)
index 0000000..3d4d320
--- /dev/null
@@ -0,0 +1,47 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#include "SeedView.h"
+
+#include <QDebug>
+
+namespace qtrapids
+{
+
+    SeedView::SeedView(QWidget* parent):
+        QTreeWidget(parent)
+    {
+        setRootIsDecorated(false); // Hide branch lines, making one-level treeview (similar to list)
+        setHeaderItem(SeedViewItem::getHeaderItem());
+       
+        connect(this, SIGNAL(itemPressed(QTreeWidgetItem*, int)),
+                this, SLOT(on_itemPressed(QTreeWidgetItem*, int)));
+    }
+
+
+    SeedView::~SeedView()
+    {
+    }
+
+    void SeedView::on_itemPressed(QTreeWidgetItem * item, int column)
+    {
+        qDebug() << "SeedView::on_itemPressed() " << item << "," << column;
+    }
+
+} // namespace qtrapids
diff --git a/src/client/SeedView.h b/src/client/SeedView.h
new file mode 100644 (file)
index 0000000..2eb8e15
--- /dev/null
@@ -0,0 +1,92 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef SEEDVIEW_H
+#define SEEDVIEW_H
+
+#include <QTreeWidget>
+
+namespace qtrapids
+{
+
+    class TorrentHandle;
+    class SeedViewItem;
+
+    /**
+       @author Lassi Väätämöinen <lassi.vaatamoinen@ixonos.com>
+    */
+    class SeedView : public QTreeWidget
+    {
+        Q_OBJECT
+        public:
+        SeedView(QWidget* parent);
+
+        ~SeedView();
+               
+       private slots:
+               void on_itemPressed(QTreeWidgetItem *item, int column);
+               
+       private:
+
+        // Name
+               // Size
+               // Status
+               // UP speed
+               // Seeds/Leechers
+               // Connected peers
+               // total uploaded
+               // ratio 
+    };
+
+    /**
+       @class DownloadViewItem
+       @brief Represents one item row of DownloadView
+    */
+    class SeedViewItem : public QTreeWidgetItem {
+       
+       public:
+               
+               SeedViewItem(QTreeWidget* parent, int type) : 
+                       QTreeWidgetItem(parent, type = QTreeWidgetItem::UserType) {};
+               
+               SeedViewItem(const QStringList& strings, int type = QTreeWidgetItem::UserType ) : 
+                       QTreeWidgetItem (strings, type = Type) {};
+               
+               
+               /// @return An item comprising of string list, suitable for QTableView
+               /// header.
+               static SeedViewItem *getHeaderItem()
+               {
+                       SeedViewItem *item  
+                               = new SeedViewItem(QStringList()
+                                   << "Name" 
+                                   << "Size" << "Status" 
+                                   << "Progress" << "UL speed" << "Seeds/Leechers"
+                                   << "Conn. peers"
+                                   << "Ratio");
+
+                       return item;
+               }
+
+               /// @todo TorrentHandle as one hidden column
+    };
+
+} // namespace qtrapids
+
+#endif
diff --git a/src/client/gui.pro b/src/client/gui.pro
new file mode 100644 (file)
index 0000000..866e0f5
--- /dev/null
@@ -0,0 +1,40 @@
+include (../../includes.pri)
+
+SOURCES += DownloadView.cpp \
+       SeedView.cpp \
+       MainWindow.cpp \
+       main.cpp \
+       PreferencesDialog.cpp \
+       proxy.cpp
+
+
+HEADERS += DownloadView.h \
+       SeedView.h \
+       MainWindow.h \
+       PreferencesDialog.h \
+       proxy.h \
+       ../include/qtrapids/dbus.hpp \
+    ../include/qtrapids/info.hpp
+
+
+TEMPLATE = app
+
+TARGET = qtrapids
+
+CONFIG -= release
+
+CONFIG += debug \
+ qtestlib
+
+QT += dbus
+
+DESTDIR = ../../bin
+
+INCLUDEPATH += ../include
+
+LIBS += -L../../bin \
+       -L../engine
+
+QMAKE_LFLAGS_DEBUG += -L.
+
+LIBS += -lboost_system-mt
diff --git a/src/client/main.cpp b/src/client/main.cpp
new file mode 100644 (file)
index 0000000..81b7b15
--- /dev/null
@@ -0,0 +1,74 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#include <QApplication>
+#include <QTest>
+#include <QDebug>
+//#include <QDesktopWidget>
+//#include "DownloadView.h"
+
+#include "MainWindow.h"
+
+using qtrapids::MainWindow;
+
+int main(int argc, char *argv[])
+{
+       
+       QCoreApplication::setOrganizationName("Ixonos");
+       QCoreApplication::setOrganizationDomain("ixonos.com");
+       QCoreApplication::setApplicationName("QtRapids");
+       
+  // Q_INIT_RESOURCE(application);
+       QApplication app(argc, argv);
+       MainWindow mainWindow;
+    mainWindow.connectToServer();
+    // mainWindow->setGeometry(QApplication::desktop()->screenGeometry());
+
+       mainWindow.show();
+
+       /*
+       DownloadView* dlw = new DownloadView(NULL);
+      //qtrapids * mw = new qtrapids();
+       dlw->show();
+       DownloadViewItem* dlwItem = new DownloadViewItem(QStringList() << "Name" 
+                       << "Size" << "Status" 
+                       << "Progress" << "DL speed" 
+                       << "UL speed" << "Seeds/Leechers"
+                       << "ratio");
+       DownloadViewItem* dlwItem2 = new DownloadViewItem(QStringList() << "Name" 
+                       << "1000" << "Downloading" 
+                       << "23%" << "11" 
+                       << "0.1" << "0/2"
+                       << "1.10");
+       //dlwItem->insertChild(0, new DownloadViewItem(QStringList() << "Name"));
+       dlw->insertTopLevelItem(0,dlwItem);
+       dlw->insertTopLevelItem(1,dlwItem2);
+       
+       for (unsigned i = 0; i < 10; ++i)
+       {
+               DownloadViewItem *editItem = dynamic_cast<DownloadViewItem*>
+                               (dlw->itemAt(QPoint(0,0)));
+               editItem->setData ( 8, Qt::DisplayRole, QVariant("EDITED" + QString::number(i, 'g', 2)));
+               QTest::qSleep(2000);
+       }
+       */
+       
+       
+       return app.exec();
+}
diff --git a/src/include/qtrapids/dbus.hpp b/src/include/qtrapids/dbus.hpp
new file mode 100644 (file)
index 0000000..52681d4
--- /dev/null
@@ -0,0 +1,120 @@
+#ifndef _QTRAPIDS_DBUS_HPP_
+#define _QTRAPIDS_DBUS_HPP_
+
+#include <QtDBus/QtDBus>
+#include <QtCore/QString>
+#include <QtCore/QHash>
+
+// TMP TODO
+#include <iostream>
+
+namespace qtrapids
+{
+
+    struct TorrentState
+    {
+        TorrentState() 
+            : hash("")
+            , name("")
+            , state(0)
+            , progress(0)
+            , down_rate(0)
+            , up_rate(0)
+            , seeds(0)
+            , leeches(0)
+            , ratio(0)
+            , total_size(0)
+        { }
+
+        QString hash;
+        QString name;
+        uint state;
+        uint progress;
+        uint down_rate;
+        uint up_rate;
+        uint seeds;
+        uint leeches;
+        uint ratio;
+        qulonglong total_size;
+    };
+
+    typedef QHash<QString, QString> ParamsMap_t;
+    typedef QHash<QString, QString> const ParamsMapConst_t;
+    typedef QHash<QString, QString>::iterator ParamsMapIterator_t;
+    typedef QHash<QString, QString>::const_iterator ParamsMapConstIterator_t;
+
+    static inline QDBusArgument& operator << (QDBusArgument& argument
+                                              , TorrentState const& state)
+    {
+        std::cout << "serialize" << std::endl;
+        argument.beginStructure();
+        argument << state.hash << state.name << state.state << state.progress 
+                 << state.down_rate << state.up_rate << state.seeds
+                 << state.leeches << state.ratio << state.total_size;
+        argument.endStructure();
+        return argument;
+    }
+
+    static inline QDBusArgument const& operator >> (QDBusArgument const& argument
+                                                    , TorrentState& state)
+    {
+        std::cout << "deserialize" << std::endl;
+        argument.beginStructure();
+        argument >> state.hash >> state.name >> state.state >> state.progress 
+                 >> state.down_rate >> state.up_rate >> state.seeds
+                 >> state.leeches >> state.ratio >> state.total_size;
+        argument.endStructure();
+        return argument;
+    }
+
+    static inline QDBusArgument& operator << (QDBusArgument& argument
+                                              , ParamsMapConst_t& params)
+    {
+        ParamsMapConstIterator_t p;
+        std::cout << "serialize params" << std::endl;
+        argument.beginMap();
+        for (p = params.constBegin(); p != params.constEnd(); ++p) {
+            argument.beginMapEntry();
+            argument << p.key() << p.value();
+            argument.endMapEntry();
+        }
+        argument.endMap();
+        return argument;
+    }
+
+    static inline QDBusArgument const& operator >> (QDBusArgument const& argument
+                                                    , ParamsMap_t& params)
+    {
+        ParamsMapConstIterator_t p;
+        QString key, value;
+        std::cout << "deserialize params" << std::endl;
+        argument.beginMap();
+        for (p = params.constBegin(); p != params.constEnd(); ++p) {
+            argument.beginMapEntry();
+            argument >> key >> value;
+            params[key] = value; 
+            argument.endMapEntry();
+        }
+        argument.endMap();
+        return argument;
+    }
+
+
+    // class DBusConnector
+    // {
+    // public:
+    //     DBusConnector()
+    //         : connection_()
+    //     {
+    //     }
+    // private:
+    //     QDBusConnection connection_;
+    // };
+
+}
+
+Q_DECLARE_METATYPE(qtrapids::TorrentState);
+Q_DECLARE_METATYPE(qtrapids::ParamsMap_t);
+
+#endif // _QTRAPIDS_DBUS_HPP_
+
diff --git a/src/include/qtrapids/error.hpp b/src/include/qtrapids/error.hpp
new file mode 100644 (file)
index 0000000..0bf83f5
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef _QTRAPIDS_ERROR_HPP_
+#define _QTRAPIDS_ERROR_HPP_
+
+#include <QString>
+
+namespace qtrapids
+{
+
+    class Error
+    {
+    public:
+
+        Error()
+            : msg_("")
+        { }
+
+        Error(char const *msg)
+            : msg_(msg)
+        {}
+
+        template <typename T>
+        void append_to_msg(T val)
+        {
+            msg_ << val;
+        }
+
+    private:
+        QString msg_;
+
+    };
+
+    template <typename T>
+    Error& operator << (Error &self, T val)
+    {
+        self.append_to_msg(val);
+        return self;
+    }
+
+    class InvalidArgument : public Error
+    {
+    };
+
+    template <typename T>
+    InvalidArgument& operator << (InvalidArgument &self, T val)
+    {
+        self.append_to_msg(val);
+        return self;
+    }
+
+}
+
+#endif // _QTRAPIDS_ERROR_HPP_
+
diff --git a/src/include/qtrapids/format.hpp b/src/include/qtrapids/format.hpp
new file mode 100644 (file)
index 0000000..8094101
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef _QTRAPIDS_FORMAT_HPP_
+#define _QTRAPIDS_FORMAT_HPP_
+
+#include <qtrapids/info.hpp>
+#include <QtCore/QString>
+
+
+
+namespace qtrapids
+{
+
+   
+    static inline QString formatProgress(uint progress)
+    {
+        return QString::number(((double)progress) / torrent_progress_max * 100);
+    }
+
+    namespace 
+    {
+
+        static const qulonglong size_KB = 1024;
+        static const qulonglong size_MB = size_KB << 10;
+        static const qulonglong size_GB = size_MB << 10;
+
+        static char const* size_names[] = {
+            "GB",
+            "MB",
+            "KB",
+            "B"
+        };
+    }
+
+    static inline QString formatSize(qulonglong size)
+    {
+        qulonglong unit = size_GB;
+        char const ** unit_name = &size_names[0];
+        QString ret("");
+        for (unit = size_GB; unit > 0; unit >>= 10, ++unit_name) {
+            if (size & (~(unit - 1))) {
+                ret += (QString::number(size / unit) + *unit_name);
+                return ret;
+            }
+        }
+        ret += (QString::number(size / unit) + "B");
+        return ret;
+    }
+
+
+} // namespace qtrapids
+
+#endif // _QTRAPIDS_FORMAT_HPP_
+
diff --git a/src/include/qtrapids/info.hpp b/src/include/qtrapids/info.hpp
new file mode 100644 (file)
index 0000000..6265155
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _QTRAPIDS_INFO_HPP_
+#define _QTRAPIDS_INFO_HPP_
+
+#include <libtorrent/torrent_handle.hpp>
+
+#include <limits>
+#include <stdint.h>
+
+namespace qtrapids
+{
+
+    static const uint32_t torrent_progress_max = std::numeric_limits<uint32_t>::max();
+
+    typedef libtorrent::torrent_status TorrentStatus_t;
+    typedef libtorrent::torrent_status::state_t TorrentStatusIds_t;
+
+    struct TorrentStatus
+    {
+        enum Id {
+            QUEUED_FOR_CHECKING = TorrentStatus_t::queued_for_checking,
+            CHECKING_FILES = TorrentStatus_t::checking_files,
+            DOWNLOADING_METADATA = TorrentStatus_t::downloading_metadata,
+            DOWNLOADING = TorrentStatus_t::downloading,
+            FINISHED = TorrentStatus_t::finished,
+            SEEDING = TorrentStatus_t::seeding,
+            ALLOCATING = TorrentStatus_t::allocating,
+            CHECKING_RESUME_DATA = TorrentStatus_t::checking_resume_data,
+            UNSPECIFIED
+        };
+    };
+
+}
+
+#endif // _QTRAPIDS_INFO_HPP_
+
diff --git a/src/server/AlertWaiterThread.cpp b/src/server/AlertWaiterThread.cpp
new file mode 100644 (file)
index 0000000..f6029be
--- /dev/null
@@ -0,0 +1,71 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "AlertWaiterThread.hpp"
+#include <QDebug>
+
+
+namespace qtrapids
+{
+
+    // Constants:
+    // Timeout for waiting alerts
+    const libtorrent::time_duration ALERT_WAIT_TIMEOUT 
+    = libtorrent::time_duration(libtorrent::seconds(15));
+
+
+    AlertWaiterThread::AlertWaiterThread(session_t *session, QObject* parent) : 
+               QThread(parent),
+               btSession_(session)
+    {
+    }
+
+
+    AlertWaiterThread::~AlertWaiterThread()
+    {
+    }
+
+
+    void AlertWaiterThread::allAlerts(bool enable)
+    {
+        // If all enabled, set all alert cateogries:
+        if (enable) {
+            btSession_->set_alert_mask(libtorrent::alert::all_categories);
+        } else {
+            // Otherwise set to default, which is only error notifications.
+            btSession_->set_alert_mask(libtorrent::alert::error_notification);
+        }
+    }
+
+
+    void AlertWaiterThread::run()
+    {
+        alert_t const *alertTemp = NULL;
+        while (true) {
+            // wait_for_alert() call blocks. Returns libtorrent alert. 
+            // Returns NULL, if no alerts in timeout period.
+            alertTemp = btSession_->wait_for_alert(ALERT_WAIT_TIMEOUT);
+            emit alert();
+            // 2000 us = 2ms. Gives main thread time to handle alert signal.
+            usleep(2000); 
+        }
+    }
+
+}
diff --git a/src/server/AlertWaiterThread.hpp b/src/server/AlertWaiterThread.hpp
new file mode 100644 (file)
index 0000000..9d35226
--- /dev/null
@@ -0,0 +1,55 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef ALERTWAITERTHREAD_H
+#define ALERTWAITERTHREAD_H
+
+#include <QThread>
+#include "TorrentSession.hpp"
+
+namespace qtrapids
+{
+
+    /**
+       @author Lassi Väätämöinen <lassi.vaatamoinen@ixonos.com>
+    */
+    class AlertWaiterThread : public QThread
+    {
+        Q_OBJECT
+       
+        public:
+               AlertWaiterThread(session_t *session, QObject *parent = 0);
+
+        virtual ~AlertWaiterThread();
+
+               void allAlerts(bool enable = true);
+               
+               virtual void run(); // Overridden from QThread
+               
+       signals:
+               void alert();
+               
+       private:
+               session_t *const btSession_;
+
+    };
+
+} // namespace qtrapids
+
+#endif
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2429ac0
--- /dev/null
@@ -0,0 +1,45 @@
+INCLUDE(${QT_USE_FILE})
+
+FIND_LIBRARY(TORRENT_RASTERBAR torrent-rasterbar)
+IF(${TORRENT_RASTERBAR} STREQUAL TORRENT_RASTERBAR-NOTFOUND)
+  MESSAGE(SEND_ERROR ${TORRENT_RASTERBAR})
+ENDIF(${TORRENT_RASTERBAR} STREQUAL TORRENT_RASTERBAR-NOTFOUND)
+
+INCLUDE_DIRECTORIES(../include)
+
+INCLUDE_DIRECTORIES(
+   ${QT_INCLUDE_DIR}
+   ${QT_QTDBUS_INCLUDE_DIR}
+   ${QT_QTSQL_INCLUDE_DIR}
+)
+
+SET_SOURCE_FILES_PROPERTIES(./server.cpp ./server.h PROPERTIES GENERATED 1)
+
+SET(MOC_HEADERS
+  ./AlertWaiterThread.hpp
+  ./TorrentHandle.hpp
+  ./TorrentSession.hpp
+  ./server.h
+)
+
+SET(SRC
+  ./AlertWaiterThread.cpp
+  ./main.cpp
+  ./server.cpp
+  ./TorrentHandle.cpp
+  ./TorrentSession.cpp
+)
+
+QT4_WRAP_CPP(SRC ${MOC_HEADERS} )
+
+ADD_EXECUTABLE(qtrapids-server ${SRC} ${MOC_HEADERS})
+
+ADD_DEFINITIONS(-DQT_SHARED)
+TARGET_LINK_LIBRARIES(qtrapids-server
+  ${QT_QTCORE_LIBRARY}
+  ${QT_QTDBUS_LIBRARY}
+  ${QT_QTSQL_LIBRARY}
+  -ltorrent-rasterbar
+)
+
+ADD_DEPENDENCIES(qtrapids-server dbusapi)
diff --git a/src/server/ServerDb.hpp b/src/server/ServerDb.hpp
new file mode 100644 (file)
index 0000000..060bb96
--- /dev/null
@@ -0,0 +1,128 @@
+#ifndef _SERVERDB_HPP_
+#define _SERVERDB_HPP_
+
+#include <QSettings>
+#include <QtSql>
+#include <QDir>
+
+namespace qtrapids
+{
+
+    class ServerSettings
+    {
+
+    public:
+        ServerSettings(QSettings *settings)
+            : settings_(settings)
+        { }
+
+        ~ServerSettings()
+        {
+            
+        }
+
+        QString getDbEngine() const
+        {
+            return getParamAndStore("db_engine", getDefaultDbEngine()).toString();
+        }
+
+        QString getDbName() const
+        {
+            QString default_db_path(QDir::home().filePath(appName() + ".sqlite"));
+            return getParamAndStore("db", default_db_path).toString();
+        }
+
+        QString getTorrentsDir() const
+        {
+            QString default_dir(QDir::home().filePath(QString(".") + appName()));
+            return getParamAndStore("db", default_dir).toString();
+          
+        }
+
+    private:
+
+        ServerSettings(ServerSettings const&);
+        ServerSettings& operator= (ServerSettings const&);
+
+        static inline QString appName()
+        {
+            return QCoreApplication::applicationName();
+        }
+
+        static QString getDefaultDbEngine()
+        {
+            // for (QStringListIterator p = QSqlDatabase::drivers(); p.hasNext();) {
+            //     return p.next();
+            // }
+            return "QSQLITE";
+        }
+
+        QVariant getParamAndStore(QString const& name, QVariant default_value) const
+        {
+            QVariant v(settings_->value(name));
+            if (!v.isNull()) {
+                return v;
+            }
+
+            settings_->setValue(name, default_value);
+            return default_value;
+        }
+
+        mutable QSettings *settings_;
+    };
+
+    class ServerDb
+    {
+
+    public:
+        ServerDb(ServerSettings *settings)
+        : db_(QSqlDatabase::addDatabase(settings->getDbEngine()))
+        {
+            QString db_name(settings->getDbName());
+            db_.setDatabaseName(db_name);
+
+            if (!db_.open()) {
+                qDebug() << "cant open db";
+                return;
+            }
+            qDebug() << "opened " << db_name;
+
+            QSqlQuery q;
+            if (!q.exec("create table torrents (hash varchar primary key, path varchar, savepath varchar);\n")) {
+                qDebug() << "cant create table: " << q.lastError().text();
+            }
+        }
+
+        ~ServerDb()
+        {
+            db_.close();
+        }
+
+        void addTorrent(const QString &hash, const QString &path, const QString &save_path)
+        {
+            if (!db_.open()) {
+                qDebug() << "cant open db";
+            }
+            QSqlQuery query_add_;
+            query_add_.prepare("INSERT INTO torrents (hash, path, savepath) VALUES (?, ?, ?)");
+            query_add_.bindValue(0, hash);
+            query_add_.bindValue(1, path);
+            query_add_.bindValue(2, save_path);
+            if (!query_add_.exec()) {
+                qDebug() << "cant add torrent info into db: " 
+                         << query_add_.lastError().text();
+            }
+            db_.close();
+        }
+
+    private:
+
+        ServerDb(ServerDb const&);
+        ServerDb& operator= (ServerDb const&);
+
+        QSqlDatabase db_;
+    };
+
+} // namespace qtrapids
+
+#endif // _SERVERDB_HPP_
diff --git a/src/server/TorrentHandle.cpp b/src/server/TorrentHandle.cpp
new file mode 100644 (file)
index 0000000..d4b5533
--- /dev/null
@@ -0,0 +1,143 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "TorrentHandle.hpp"
+#include <QDebug>
+
+
+namespace qtrapids
+{
+
+    TorrentHandle::TorrentHandle(libtorrent::torrent_handle handle) :
+               torrentHandle_(handle)
+    {
+    }
+
+
+    TorrentHandle::~TorrentHandle()
+    {
+    }
+
+
+    TorrentStatus_t TorrentHandle::status() const
+    {
+        return torrentHandle_.status();
+    }
+
+
+    torrent_info_cref TorrentHandle::getTorrentInfo() const
+    {
+        return torrentHandle_.get_torrent_info();
+    }
+
+
+    bool TorrentHandle::isValid() const
+    {
+        return torrentHandle_.is_valid();
+    }
+
+
+    QString TorrentHandle::name() const
+    {
+        return QString::fromStdString(torrentHandle_.name());
+    }
+
+    size_t TorrentHandle::getTotalSize() const
+    {
+        torrent_info_cref info = getTorrentInfo();
+        return static_cast<size_t> (info.total_size());
+    }
+
+
+    TorrentStatus::Id TorrentHandle::state() const
+    {
+        TorrentStatus::Id s = (TorrentStatus::Id)(status().state);
+        return ( (s < TorrentStatus::UNSPECIFIED)
+                 ? s : TorrentStatus::UNSPECIFIED );
+    }
+
+
+    float TorrentHandle::progress() const
+    {
+        TorrentStatus_t statusTmp = status();
+        return statusTmp.progress;
+    }
+
+    float TorrentHandle::uploadRate() const
+    {
+        TorrentStatus_t statusTmp = status();
+        return statusTmp.upload_rate;
+    }
+
+
+    float TorrentHandle::downloadRate() const
+    {
+        TorrentStatus_t statusTmp = status();
+        return statusTmp.download_rate;
+    }
+
+
+    qint32 TorrentHandle::numSeeds() const
+    {
+        TorrentStatus_t statusTmp = status();
+        return statusTmp.list_seeds;
+    }
+
+
+    qint32 TorrentHandle::numLeeches() const
+    {
+        TorrentStatus_t statusTmp = status();
+        return (statusTmp.list_peers - statusTmp.list_seeds);
+    }
+
+
+    qint32 TorrentHandle::ratio() const
+    {
+        TorrentStatus_t statusTmp = status();
+        size_t ratio;
+        if (statusTmp.total_payload_download == 0) {
+            ratio = 0;
+        } else {
+            ratio = static_cast<size_t> (statusTmp.total_payload_upload / statusTmp.total_payload_download);
+        }
+
+        return ratio;
+    }
+
+
+    torrent_handle_t TorrentHandle::getHandle() const
+    {
+        return torrentHandle_;
+    }
+
+
+    bool TorrentHandle::operator==(TorrentHandle const& h) const
+    {
+        return torrentHandle_ == h.torrentHandle_;
+    }
+
+
+    bool TorrentHandle::operator<(TorrentHandle const& h) const
+    {
+        return torrentHandle_ < h.torrentHandle_;
+    }
+
+
+}
diff --git a/src/server/TorrentHandle.hpp b/src/server/TorrentHandle.hpp
new file mode 100644 (file)
index 0000000..c84c174
--- /dev/null
@@ -0,0 +1,87 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Lassi Väätämöinen   *
+ *   lassi.vaatamoinen@ixonos.com   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef QTORRENTHANDLE_H
+#define QTORRENTHANDLE_H
+
+#include <QtGlobal>
+#include <QString>
+
+#include <qtrapids/info.hpp>
+#include <libtorrent/torrent_handle.hpp>
+
+namespace qtrapids
+{
+
+    typedef libtorrent::torrent_info const& torrent_info_cref;
+    typedef libtorrent::torrent_handle torrent_handle_t;
+    typedef libtorrent::sha1_hash Sha1Hash;
+
+
+    inline QString Hash2QStr(Sha1Hash const& hash)
+    {
+        return QString(hash.to_string().c_str());
+    }
+
+    /**
+       @author Lassi Väätämöinen <lassi.vaatamoinen@ixonos.com>
+    */
+    class TorrentHandle 
+    {
+    public:
+               
+        TorrentHandle(libtorrent::torrent_handle handle);
+        ~TorrentHandle();
+               
+
+               
+        torrent_info_cref getTorrentInfo() const;
+               
+        bool isValid() const;
+
+        Sha1Hash hash() const
+        {
+            return torrentHandle_.info_hash();
+        }
+
+        QString name() const;
+        size_t getTotalSize() const;
+        TorrentStatus::Id state() const;
+        float progress() const;
+        float uploadRate() const;
+        float downloadRate() const;
+        qint32 numSeeds() const;
+        qint32 numLeeches() const;
+        qint32 ratio() const;
+               
+        torrent_handle_t getHandle() const;
+        bool operator==(TorrentHandle const& h) const; 
+        bool operator<(TorrentHandle const& h) const;
+               
+    private:
+        TorrentHandle(); // Prevent default construct.
+        torrent_handle_t torrentHandle_;
+       
+        TorrentStatus_t status() const;
+
+    };
+
+}
+
+#endif
diff --git a/src/server/TorrentSession.cpp b/src/server/TorrentSession.cpp
new file mode 100644 (file)
index 0000000..514b2c9
--- /dev/null
@@ -0,0 +1,147 @@
+#include "TorrentSession.hpp"
+#include "TorrentHandle.hpp"
+#include "AlertWaiterThread.hpp"
+
+
+namespace qtrapids
+{
+
+
+
+    TorrentSession::TorrentSession(QObject *parent, QSettings *settings)
+        : QObject(parent)
+        , btSession_()
+               , alertWaiter_(new AlertWaiterThread(&btSession_, this))
+    {
+        qDBusRegisterMetaType<qtrapids::TorrentState>();
+        qDBusRegisterMetaType<qtrapids::ParamsMap_t>();
+        new QtRapidsServer(this);
+
+        QDBusConnection dbus = QDBusConnection::sessionBus();
+        dbus.registerObject("/qtrapids", this);
+        dbus.registerService("com.ixonos.qtrapids");
+
+        alertWaiter_->allAlerts();
+        connect(alertWaiter_, SIGNAL(alert()), this, SLOT(on_alert()));
+        alertWaiter_->start();
+
+
+    }
+
+    void TorrentSession::on_alert()
+    //NOTE: al parameter not necessarily needed here, as we pop_alert() now!
+    {
+
+        //qDebug() << "QBittorrentSession:on_alert(" << al << ")";
+        //     if (al)
+        //             qDebug() << "on_alert():" << QString::fromStdString(al->message());
+
+        std::auto_ptr<alert_t> alertPtr = btSession_.pop_alert();
+
+        if (alertPtr.get() != NULL) {
+
+            torrent_alert_t *ta = dynamic_cast<torrent_alert_t*> (alertPtr.get());
+
+            qDebug()
+                               << "QBittorrentSession::on_alert(): "
+                               << QString::fromStdString(alertPtr->message());
+
+
+            if (ta) {
+                TorrentHandle handle(ta->handle);
+                TorrentState state;
+
+                state.hash = Hash2QStr(handle.hash());
+                state.state = handle.state();
+                state.progress = handle.progress() * torrent_progress_max;
+                state.down_rate = handle.downloadRate();
+                state.up_rate = handle.uploadRate();
+                state.seeds = handle.numSeeds();
+                state.leeches = handle.numLeeches();
+            
+                ParamsMap_t params;
+                emit alert(state, params);
+            }
+
+        }
+    }
+
+    void TorrentSession::getState()
+    {
+        torrents_t::const_iterator p;
+        for (p = torrents_.constBegin(); p != torrents_.constEnd(); ++p) {
+            TorrentHandlePtr handle = *p;
+            TorrentState state;
+            QString hash = Hash2QStr(handle->hash());
+            
+            state.hash = hash;
+            state.name = handle->name();
+            state.state = handle->state();
+            state.progress = handle->progress() * torrent_progress_max;
+            state.down_rate = handle->downloadRate();
+            state.up_rate = handle->uploadRate();
+            state.seeds = handle->numSeeds();
+            state.leeches = handle->numLeeches();
+            state.total_size = handle->getTotalSize();
+
+            emit alert(state, ParamsMap_t());
+        }
+    }
+
+    void TorrentSession::addTorrent(const QString &path, const QString &save_path
+                                    , qtrapids::ParamsMap_t other_params)
+    {
+        add_torrent_params_t addParams;
+        QFile torrent_file(path);
+        if (!torrent_file.exists()) {
+            qWarning() << "Torrent file " << path << "doesn't exist";
+            return;
+        }
+
+        qDebug() << "addTorrent: " << path << " save to " << save_path;
+        boost::intrusive_ptr<libtorrent::torrent_info> tiTmp
+            = new libtorrent::torrent_info(path.toStdString());
+        addParams.ti = tiTmp;
+
+        // save_path is the only mandatory parameter, rest are optional.
+        addParams.save_path = save_path.toStdString();
+        //addParams.storage_mode = libtorrent::storage_mode_allocate;
+
+        TorrentHandlePtr handle(new TorrentHandle(btSession_.add_torrent(addParams)));
+        QString hash = Hash2QStr(handle->hash());
+
+        TorrentState state;
+
+        state.hash = hash;
+        state.name = handle->name();
+        state.state = handle->state();
+        state.progress = handle->progress() * torrent_progress_max;
+        state.down_rate = handle->downloadRate();
+        state.up_rate = handle->uploadRate();
+        state.seeds = handle->numSeeds();
+        state.leeches = handle->numLeeches();
+        state.total_size = handle->getTotalSize();
+
+        torrents_[hash] = handle;
+
+        emit alert(state, ParamsMap_t());
+    }
+
+    void TorrentSession::removeTorrent(const QString &hash)
+    {
+        torrents_t::iterator p = torrents_.find(hash);
+        if (p == torrents_.end()) {
+            qDebug() << "Invalid request to remove torrent with hash " << hash;
+            return;
+        }
+        try {
+            btSession_.remove_torrent(p.value()->getHandle());
+        } catch (torrent_exception_t e) {
+            qDebug() << // e.what()
+                "exception catched"
+                ;
+        }
+    }
+
+
+} // namespace qtrapids
diff --git a/src/server/TorrentSession.hpp b/src/server/TorrentSession.hpp
new file mode 100644 (file)
index 0000000..76b11f2
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef _TEST_HPP_
+#define _TEST_HPP_
+
+#include "TorrentHandle.hpp"
+#include "server.h"
+
+#include <QObject>
+#include <QString>
+#include <QSharedPointer>
+#include <QWeakPointer>
+
+#include <qtrapids/dbus.hpp>
+
+#include <libtorrent/session.hpp>
+#include <libtorrent/torrent_info.hpp>
+#include <libtorrent/alert_types.hpp>
+#include <libtorrent/error_code.hpp>
+
+class QSettings;
+
+namespace qtrapids
+{
+
+    typedef QWeakPointer<QSettings> settings_weak_ptr;
+
+    class AlertWaiterThread;
+    typedef libtorrent::session session_t;
+    typedef libtorrent::session const* session_cptr;
+
+    typedef libtorrent::add_torrent_params add_torrent_params_t;
+    typedef libtorrent::alert alert_t;
+    //    typedef libtorrent::alert const* alert_cptr;
+    typedef    libtorrent::torrent_alert torrent_alert_t;
+    typedef libtorrent::libtorrent_exception torrent_exception_t;
+
+    typedef QSharedPointer<TorrentHandle> TorrentHandlePtr;
+    typedef QHash<QString, TorrentHandlePtr > torrents_t;
+
+    class ServerDb;
+    class ServerSettings;
+
+    class TorrentSession : public QObject
+    {
+
+        Q_OBJECT;
+        Q_CLASSINFO("D-Bus Interface", "com.ixonos.qtrapids");
+
+    public:
+
+        TorrentSession(QObject *parent, QSettings *);
+
+    public slots:
+
+        void getState();
+        void addTorrent(const QString &path, const QString &save_path
+                        , qtrapids::ParamsMap_t other_params);
+        void removeTorrent(const QString &hash);
+
+    signals:
+        void alert(qtrapids::TorrentState info, qtrapids::ParamsMap_t other_info);
+
+    private slots:
+               void on_alert();
+
+    private:
+        session_t btSession_;
+               AlertWaiterThread *alertWaiter_;
+               torrents_t torrents_;
+    };
+
+} // namespace qtrapids
+
+#endif // _TEST_HPP_
diff --git a/src/server/create_db.sql b/src/server/create_db.sql
new file mode 100644 (file)
index 0000000..6d41407
--- /dev/null
@@ -0,0 +1,2 @@
+drop table torrents;
+create table torrents(path varchar, savepath varchar);
diff --git a/src/server/main.cpp b/src/server/main.cpp
new file mode 100644 (file)
index 0000000..ef74cd3
--- /dev/null
@@ -0,0 +1,19 @@
+#include <QtCore/QCoreApplication>
+//#include "server.h"
+#include "TorrentSession.hpp"
+
+using qtrapids::TorrentSession;
+using qtrapids::settings_weak_ptr;
+
+int main(int argc, char *argv[])
+{
+       QCoreApplication::setOrganizationName("Ixonos");
+       QCoreApplication::setOrganizationDomain("ixonos.com");
+       QCoreApplication::setApplicationName("QtRapids");
+    QSettings settings(QCoreApplication::organizationName()
+                       , QCoreApplication::applicationName());
+
+       QCoreApplication app(argc, argv);
+    TorrentSession server(&app, &settings);
+    return app.exec();
+}
diff --git a/src/server/server.pro b/src/server/server.pro
new file mode 100644 (file)
index 0000000..eb10030
--- /dev/null
@@ -0,0 +1,36 @@
+include (../../includes.pri)
+
+TEMPLATE = app
+
+CONFIG += console debug
+CONFIG -= app_bundle
+
+VERSION = 0.2
+
+HEADERS += \
+TorrentSession.hpp \
+AlertWaiterThread.hpp \
+TorrentHandle.hpp \
+server.h \
+../include/qtrapids/dbus.hpp \
+../include/qtrapids/status.hpp
+
+SOURCES += \
+ main.cpp \
+ server.cpp \
+ TorrentSession.cpp \
+ TorrentHandle.cpp \
+ AlertWaiterThread.cpp
+
+QT += dbus sql
+
+QT -= gui
+
+CONFIG -= release
+
+TARGET = qtrapids-server
+
+DESTDIR = ../../bin
+
+LIBS += -ltorrent-rasterbar
+
index 27453b1..71cda24 100644 (file)
@@ -1,7 +1,6 @@
 SUBDIRS += engine \
        gui
 
-
 CONFIG += ordered \ 
        warn_on \
        thread \