1
mirror of https://github.com/qbittorrent/qBittorrent synced 2025-10-09 18:32:15 +02:00

Compare commits

...

1 Commits

Author SHA1 Message Date
Christophe Dumez
429ff34e46 - Tagged beta2 release 2008-06-22 17:41:47 +00:00
104 changed files with 13570 additions and 6933 deletions

View File

@@ -1,4 +1,6 @@
* Tuesday October 06 2007 - Christophe Dumez <chris@qbittorrent.org> - v1.1.0
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.1.0
- FEATURE: Web interface to control qbittorrent (Ishan Arora)
- FEATURE: Can spoof Azureus peer id to avoid ban
- FEATURE: Allow to hide/show some columns in download and seeding lists
- FEATURE: Option to start qBittorrent minimized in systray
- FEATURE: Allow to define double-click actions in torrents lists
@@ -7,11 +9,21 @@
- FEATURE: Allow to buy downloads using ShareMonkey
- FEATURE: Display if UPnP/NAT-PMP was successful or not
- FEATURE: Threadified torrent creation
- FEATURE: Improved eMule DAT ip filter parser
- FEATURE: Added support for PeerGuardian p2p filters (text)
- FEATURE: Added support for PeerGuardian p2b filters (binary)
- FEATURE: Allow to customize folder scan interval
- FEATURE: Allow to add several trackers at once
- BUGFIX: Do not display seeds number in seeding list (always 0)
- BUGFIX: Threadified IP filter file parser to avoid GUI freeze
- COSMETIC: Do not display progress bar in seeding list (always 100%)
- COSMETIC: Added a progress bar for torrent creation
- COSMETIC: Display tracker errors in a cleaner way
- COSMETIC: Display "unpaused/total_torrent" in download/upload tabs
- COSMETIC: Allow to resize RSS column
- COSMETIC: Global UP/DL speeds and ratio are displayed above tabs
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.0.0
* Fri Apr 11 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.0.0
- FEATURE: Based on new libtorrent v0.13
- FEATURE: Added UPnP / NAT-PMP port forwarding support
- FEATURE: Added encryption support (compatible with Azureus)

28
doc/qbittorrent.1 Normal file
View File

@@ -0,0 +1,28 @@
.\" This manpage has been automatically generated by docbook2man
.\" from a DocBook document. This tool can be found at:
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>.
.TH "QBITTORRENT" "1" "September 1st 2007" "Bittorrent client written in C++ / Qt4" ""
.SH NAME
qBittorrent \- a Bittorrent client written in C++ / Qt4
.SH SYNOPSIS
\fBqbittorrent\fR [FILE | URL] [FILE | URL...]
\fBqbittorrent\fR \-\-help
\fBqbittorrent\fR \-\-version
.PP
.SH "DESCRIPTION"
\fBqBittorrent\fR is an advanced Bittorrent client written in C++ / Qt4,
using the \fBrblibtorrent\fR library by Arvid Norberg. qBittorrent aims
to be a good alternative to all other bittorrent clients out there. qBittorrent
is fast, stable, light, it supports unicode and it provides a good integrated search engine.
It also comes with UPnP port forwarding / NAT-PMP, encryption (Azureus compatible), FAST extension (mainline) and PeX support (utorrent compatible).
Please report any problem to http://bugs.qbittorrent.org
.PP
.SH "AUTHOR"
Christophe Dumez <chris@qbittorrent.org>

Binary file not shown.

View File

@@ -280,7 +280,8 @@ int FinishedTorrents::getRowFromHash(QString hash) const{
// Note: does not actually pause the torrent in BT Session
void FinishedTorrents::pauseTorrent(QString hash) {
int row = getRowFromHash(hash);
Q_ASSERT(row != -1);
if(row == -1)
return;
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.0));
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole);
finishedListModel->setData(finishedListModel->index(row, F_LEECH), QVariant(QString::fromUtf8("0")));

File diff suppressed because it is too large Load Diff

View File

@@ -46,6 +46,7 @@ class options_imp;
class QTabWidget;
class QLabel;
class QModelIndex;
class HttpServer;
class GUI : public QMainWindow, private Ui::MainWindow{
Q_OBJECT
@@ -79,6 +80,8 @@ class GUI : public QMainWindow, private Ui::MainWindow{
SearchEngine *searchEngine;
// RSS
RSSImp *rssWidget;
// Web UI
HttpServer *httpServer;
// Misc
QTcpServer *tcpServer;
QTcpSocket *clientConnection;
@@ -134,10 +137,13 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void processScannedFiles(const QStringList& params);
void processDownloadedFiles(QString path, QString url);
void downloadFromURLList(const QStringList& urls);
void deleteTorrent(QString hash, QString fileName, bool finished);
void deleteTorrent(QString hash);
void deleteRatioTorrent(QString fileName);
void finishedTorrent(QTorrentHandle& h) const;
void torrentChecked(QString hash) const;
void updateLists();
bool initWebUi(QString username, QString password, int port);
void pauseTorrent(QString hash);
// Options slots
void on_actionOptions_triggered();
void OptionsSaved(QString info, bool deleteOptions);
@@ -150,6 +156,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void setTabText(int index, QString text) const;
void openDestinationFolder() const;
void goBuyPage() const;
void updateRatio();
protected:
void closeEvent(QCloseEvent *);

View File

@@ -1,7 +1,6 @@
[Desktop Entry]
Categories=Qt;Application;Network;P2P
Comment=V1.1.0
Encoding=UTF-8
Exec=qbittorrent
GenericName=Bittorrent client
GenericName[bg]=Торент клиент
@@ -9,6 +8,7 @@ GenericName[de]=Bittorren Client
GenericName[el]=Τορεντ πελάτης
GenericName[es]=Cliente Bittorrent
GenericName[fr]=Client Bittorrent
GenericName[it]=Client Bittorrent
GenericName[ja]=Bittorrent クライアント
GenericName[ko]=비토렌트 클라이언트
GenericName[nl]=Bittorrent client

View File

@@ -16,13 +16,194 @@
<string/>
</property>
<widget class="QWidget" name="centralwidget" >
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>9</number>
</property>
<property name="geometry" >
<rect>
<x>0</x>
<y>58</y>
<width>849</width>
<height>505</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<layout class="QHBoxLayout" name="_3" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>0</number>
</property>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lbl_DLSpeed_2" >
<property name="text" >
<string>Total DL Speed:</string>
</property>
<property name="alignment" >
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item>
<widget class="QLCDNumber" name="LCD_DownSpeed" >
<property name="autoFillBackground" >
<bool>true</bool>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
<property name="smallDecimalPoint" >
<bool>false</bool>
</property>
<property name="numDigits" >
<number>6</number>
</property>
<property name="segmentStyle" >
<enum>QLCDNumber::Flat</enum>
</property>
<property name="value" stdset="0" >
<double>0.000000000000000</double>
</property>
<property name="intValue" stdset="0" >
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="unitDL_2" >
<property name="text" >
<string>KiB/s</string>
</property>
<property name="alignment" >
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>Session ratio: </string>
</property>
<property name="alignment" >
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item>
<widget class="QLCDNumber" name="LCD_Ratio" >
<property name="autoFillBackground" >
<bool>true</bool>
</property>
<property name="numDigits" >
<number>4</number>
</property>
<property name="segmentStyle" >
<enum>QLCDNumber::Flat</enum>
</property>
<property name="value" stdset="0" >
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lbl_ratio_icon" >
<property name="text" >
<string/>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lbl_UPSpeed_2" >
<property name="text" >
<string>Total UP Speed:</string>
</property>
<property name="alignment" >
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item>
<widget class="QLCDNumber" name="LCD_UpSpeed" >
<property name="autoFillBackground" >
<bool>true</bool>
</property>
<property name="smallDecimalPoint" >
<bool>false</bool>
</property>
<property name="numDigits" >
<number>6</number>
</property>
<property name="segmentStyle" >
<enum>QLCDNumber::Flat</enum>
</property>
<property name="value" stdset="0" >
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="unitUP_2" >
<property name="text" >
<string>KiB/s</string>
</property>
<property name="alignment" >
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar" >
@@ -31,7 +212,7 @@
<x>0</x>
<y>0</y>
<width>849</width>
<height>29</height>
<height>26</height>
</rect>
</property>
<widget class="QMenu" name="menu_Edit" >
@@ -82,6 +263,14 @@
<property name="enabled" >
<bool>true</bool>
</property>
<property name="geometry" >
<rect>
<x>0</x>
<y>26</y>
<width>849</width>
<height>32</height>
</rect>
</property>
<property name="contextMenuPolicy" >
<enum>Qt::NoContextMenu</enum>
</property>
@@ -98,7 +287,7 @@
</size>
</property>
<attribute name="toolBarArea" >
<number>4</number>
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak" >
<bool>false</bool>

53
src/TrackersAdditionDlg.h Normal file
View File

@@ -0,0 +1,53 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contact : chris@qbittorrent.org
*/
#ifndef TRACKERSADDITION_H
#define TRACKERSADDITION_H
#include <QDialog>
#include <QStringList>
#include "ui_trackersAdd.h"
class TrackersAddDlg : public QDialog, private Ui::TrackersAdditionDlg{
Q_OBJECT
public:
TrackersAddDlg(QWidget *parent): QDialog(parent){
setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
show();
}
~TrackersAddDlg(){}
signals:
void TrackersToAdd(QStringList trackers);
public slots:
void on_buttonBox_accepted() {
QStringList trackers = trackers_list->toPlainText().trimmed().split("\n");
if(trackers.size()) {
emit TrackersToAdd(trackers);
}
}
};
#endif

View File

@@ -23,11 +23,13 @@
#include <QTime>
#include <QString>
#include <QTimer>
#include <QSettings>
#include "bittorrent.h"
#include "misc.h"
#include "downloadThread.h"
#include "deleteThread.h"
#include "filterParserThread.h"
#include <libtorrent/extensions/metadata_transfer.hpp>
#include <libtorrent/extensions/ut_pex.hpp>
@@ -41,11 +43,17 @@
#define MAX_TRACKER_ERRORS 2
// Main constructor
bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), max_ratio(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false) {
bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), max_ratio(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), folderScanInterval(5) {
// To avoid some exceptions
fs::path::default_name_check(fs::no_check);
// Creating bittorrent session
s = new session(fingerprint("qB", VERSION_MAJOR, VERSION_MINOR, VERSION_BUGFIX, 0));
// Check if we should spoof azureus
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
if(settings.value(QString::fromUtf8("AzureusSpoof"), false).toBool()) {
s = new session(fingerprint("AZ", 3, 0, 5, 2));
} else {
s = new session(fingerprint("qB", VERSION_MAJOR, VERSION_MINOR, VERSION_BUGFIX, 0));
}
// Set severity level of libtorrent session
s->set_severity_level(alert::info);
// Enabling metadata plugin
@@ -62,12 +70,14 @@ bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false
connect(downloader, SIGNAL(downloadFailure(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
// File deleter (thread)
deleter = new deleteThread(this);
BigRatioTimer = 0;
BigRatioTimer = 0;
filterParser = 0;
qDebug("* BTSession constructed");
}
// Main destructor
bittorrent::~bittorrent() {
qDebug("BTSession deletion");
// Set Session settings
session_settings ss;
ss.tracker_receive_timeout = 1;
@@ -85,6 +95,8 @@ bittorrent::~bittorrent() {
delete timerAlerts;
if(BigRatioTimer != 0)
delete BigRatioTimer;
if(filterParser != 0)
delete filterParser;
delete downloader;
// Delete BT session
qDebug("Deleting session");
@@ -123,7 +135,7 @@ void bittorrent::deleteBigRatios() {
if(getRealRatio(hash) > max_ratio) {
QString fileName = h.name();
deleteTorrent(hash);
emit torrent_deleted(hash, fileName, true);
emit torrent_ratio_deleted(fileName);
}
}
}
@@ -199,6 +211,26 @@ bool bittorrent::isPaused(QString hash) const{
return h.is_paused();
}
unsigned int bittorrent::getFinishedPausedTorrentsNb() const {
unsigned int nbPaused = 0;
foreach(QString hash, finishedTorrents) {
if(isPaused(hash)) {
++nbPaused;
}
}
return nbPaused;
}
unsigned int bittorrent::getUnfinishedPausedTorrentsNb() const {
unsigned int nbPaused = 0;
foreach(QString hash, unfinishedTorrents) {
if(isPaused(hash)) {
++nbPaused;
}
}
return nbPaused;
}
// Delete a torrent from the session, given its hash
// permanent = true means that the torrent will be removed from the hard-drive too
void bittorrent::deleteTorrent(QString hash, bool permanent) {
@@ -249,6 +281,7 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
// Deleting in a thread to avoid GUI freeze
deleter->deleteTorrent(savePath, files_arb);
}
emit deletedTorrent(hash);
}
// Return a list of hashes for the finished torrents
@@ -312,6 +345,7 @@ bool bittorrent::pauseTorrent(QString hash) {
// Save fast resume data
saveFastResumeAndRatioData(hash);
qDebug("Torrent paused successfully");
emit pausedTorrent(hash);
}else{
if(!h.is_valid()) {
qDebug("Could not pause torrent %s, reason: invalid", hash.toUtf8().data());
@@ -341,6 +375,7 @@ bool bittorrent::resumeTorrent(QString hash) {
TorrentsStartTime[hash] = QDateTime::currentDateTime();
h.resume();
success = true;
emit resumedTorrent(hash);
}
// Delete .paused file
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused"))
@@ -353,6 +388,18 @@ bool bittorrent::resumeTorrent(QString hash) {
return success;
}
void bittorrent::pauseAllTorrents() {
QStringList list = getUnfinishedTorrents() + getFinishedTorrents();
foreach(QString hash, list)
pauseTorrent(hash);
}
void bittorrent::resumeAllTorrents() {
QStringList list = getUnfinishedTorrents() + getFinishedTorrents();
foreach(QString hash, list)
resumeTorrent(hash);
}
void bittorrent::loadWebSeeds(QString hash) {
QFile urlseeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".urlseeds");
if(!urlseeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
@@ -698,12 +745,12 @@ bool bittorrent::enableDHT(bool b) {
dht_state = bdecode(std::istream_iterator<char>(dht_state_file), std::istream_iterator<char>());
}catch (std::exception&) {}
try {
s->start_dht(dht_state);
s->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881));
s->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881));
s->add_dht_router(std::make_pair(std::string("router.bitcomet.com"), 6881));
DHTEnabled = true;
qDebug("DHT enabled");
s->start_dht(dht_state);
s->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881));
s->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881));
s->add_dht_router(std::make_pair(std::string("router.bitcomet.com"), 6881));
DHTEnabled = true;
qDebug("DHT enabled");
}catch(std::exception e) {
qDebug("Could not enable DHT, reason: %s", e.what());
return false;
@@ -958,13 +1005,22 @@ void bittorrent::setDefaultSavePath(QString savepath) {
defaultSavePath = savepath;
}
void bittorrent::setTimerScanInterval(int secs) {
if(folderScanInterval != secs) {
folderScanInterval = secs;
if(!scan_dir.isNull()) {
timerScan->start(folderScanInterval*1000);
}
}
}
// Enable directory scanning
void bittorrent::enableDirectoryScanning(QString _scan_dir) {
if(!_scan_dir.isEmpty()) {
scan_dir = _scan_dir;
timerScan = new QTimer(this);
connect(timerScan, SIGNAL(timeout()), this, SLOT(scanDirectory()));
timerScan->start(5000);
timerScan->start(folderScanInterval*1000);
}
}
@@ -1064,6 +1120,7 @@ bool bittorrent::loadTrackerFile(QString hash) {
if(trackers.size() != 0) {
QTorrentHandle h = getTorrentHandle(hash);
h.replace_trackers(trackers);
h.force_reannounce();
return true;
}else{
return false;
@@ -1103,15 +1160,25 @@ void bittorrent::setDHTPort(int dht_port) {
}
// Enable IP Filtering
void bittorrent::enableIPFilter(ip_filter filter) {
void bittorrent::enableIPFilter(QString filter) {
qDebug("Enabling IPFiler");
s->set_ip_filter(filter);
if(!filterParser) {
filterParser = new FilterParserThread(this, s);
}
if(filterPath.isEmpty() || filterPath != filter) {
filterPath = filter;
filterParser->processFilterFile(filter);
}
}
// Disable IP Filtering
void bittorrent::disableIPFilter() {
qDebug("Disabling IPFilter");
s->set_ip_filter(ip_filter());
if(filterParser) {
delete filterParser;
}
filterPath = "";
}
// Set BT session settings (user_agent)
@@ -1162,18 +1229,30 @@ void bittorrent::readAlerts() {
// Level: fatal
QTorrentHandle h(p->handle);
if(h.is_valid()){
QString hash = h.hash();
QList<QPair<QString, QString> > errors = trackersErrors.value(hash, QList<QPair<QString, QString> >());
if(errors.size() > MAX_TRACKER_ERRORS)
errors.removeAt(0);
errors << QPair<QString,QString>(QTime::currentTime().toString("hh:mm:ss"), QString::fromUtf8(a->msg().c_str()));
trackersErrors[hash] = errors;
// Authentication
if(p->status_code == 401) {
if(p->status_code != 401) {
QString hash = h.hash();
qDebug("Received a tracker error for %s", p->url.c_str());
QHash<QString, QString> errors = trackersErrors.value(hash, QHash<QString, QString>());
// p->url requires at least libtorrent v0.13.1
errors[misc::toQString(p->url)] = QString::fromUtf8(a->msg().c_str());
trackersErrors[hash] = errors;
} else {
emit trackerAuthenticationRequired(h);
}
}
}
else if (tracker_reply_alert* p = dynamic_cast<tracker_reply_alert*>(a.get())) {
QTorrentHandle h(p->handle);
if(h.is_valid()){
qDebug("Received a tracker reply from %s", (const char*)h.current_tracker().toUtf8());
QString hash = h.hash();
QHash<QString, QString> errors = trackersErrors.value(hash, QHash<QString, QString>());
// p->url requires at least libtorrent v0.13.1
errors.remove(h.current_tracker());
trackersErrors[hash] = errors;
}
}
else if (portmap_error_alert* p = dynamic_cast<portmap_error_alert*>(a.get())) {
emit UPnPError(QString(p->msg().c_str()));
}
@@ -1217,8 +1296,8 @@ void bittorrent::readAlerts() {
}
}
QList<QPair<QString, QString> > bittorrent::getTrackersErrors(QString hash) const{
return trackersErrors.value(hash, QList<QPair<QString, QString> >());
QHash<QString, QString> bittorrent::getTrackersErrors(QString hash) const{
return trackersErrors.value(hash, QHash<QString, QString>());
}
QStringList bittorrent::getTorrentsToPauseAfterChecking() const{

View File

@@ -36,6 +36,7 @@ using namespace libtorrent;
class downloadThread;
class deleteThread;
class QTimer;
class FilterParserThread;
class bittorrent : public QObject{
Q_OBJECT
@@ -54,7 +55,7 @@ class bittorrent : public QObject{
QHash<QString, QDateTime> TorrentsStartTime;
QHash<QString, size_type> TorrentsStartData;
QHash<QString, QPair<size_type,size_type> > ratioData;
QHash<QString, QList<QPair<QString, QString> > > trackersErrors;
QHash<QString, QHash<QString, QString> > trackersErrors;
deleteThread *deleter;
QStringList finishedTorrents;
QStringList unfinishedTorrents;
@@ -66,6 +67,9 @@ class bittorrent : public QObject{
bool UPnPEnabled;
bool NATPMPEnabled;
bool LSDEnabled;
FilterParserThread *filterParser;
QString filterPath;
int folderScanInterval; // in seconds
protected:
QString getSavePath(QString hash);
@@ -86,11 +90,13 @@ class bittorrent : public QObject{
qlonglong getETA(QString hash) const;
float getRealRatio(QString hash) const;
session* getSession() const;
QList<QPair<QString, QString> > getTrackersErrors(QString hash) const;
QHash<QString, QString> getTrackersErrors(QString hash) const;
QStringList getFinishedTorrents() const;
QStringList getUnfinishedTorrents() const;
bool isFinished(QString hash) const;
bool has_filtered_files(QString hash) const;
unsigned int getFinishedPausedTorrentsNb() const;
unsigned int getUnfinishedPausedTorrentsNb() const;
public slots:
void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
@@ -99,6 +105,8 @@ class bittorrent : public QObject{
void deleteTorrent(QString hash, bool permanent = false);
bool pauseTorrent(QString hash);
bool resumeTorrent(QString hash);
void pauseAllTorrents();
void resumeAllTorrents();
void saveDHTEntry();
void preAllocateAllFiles(bool b);
void saveFastResumeAndRatioData();
@@ -106,7 +114,7 @@ class bittorrent : public QObject{
void enableDirectoryScanning(QString scan_dir);
void disableDirectoryScanning();
void enablePeerExchange();
void enableIPFilter(ip_filter filter);
void enableIPFilter(QString filter);
void disableIPFilter();
void resumeUnfinishedTorrents();
void saveTorrentSpeedLimits(QString hash);
@@ -140,6 +148,7 @@ class bittorrent : public QObject{
void enableLSD(bool b);
bool enableDHT(bool b);
void reloadTorrent(const QTorrentHandle &h, bool full_alloc);
void setTimerScanInterval(int secs);
protected slots:
void scanDirectory();
@@ -153,6 +162,9 @@ class bittorrent : public QObject{
void invalidTorrent(QString path);
void duplicateTorrent(QString path);
void addedTorrent(QString path, QTorrentHandle& h, bool fastResume);
void deletedTorrent(QString hash);
void pausedTorrent(QString hash);
void resumedTorrent(QString hash);
void finishedTorrent(QTorrentHandle& h);
void fullDiskError(QTorrentHandle& h);
void trackerError(QString hash, QString time, QString msg);
@@ -167,7 +179,7 @@ class bittorrent : public QObject{
void fastResumeDataRejected(QString name);
void urlSeedProblem(QString url, QString msg);
void torrentFinishedChecking(QString hash);
void torrent_deleted(QString hash, QString fileName, bool finished);
void torrent_ratio_deleted(QString fileName);
void UPnPError(QString msg);
void UPnPSuccess(QString msg);
};

File diff suppressed because it is too large Load Diff

View File

@@ -47,8 +47,6 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
// tabBottom->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/log.png")));
// tabBottom->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/filter.png")));
// Set default ratio
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/stare.png")));
// Set Download list model
DLListModel = new QStandardItemModel(0,9);
@@ -113,7 +111,6 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
// Set info Bar infos
setInfoBar(tr("qBittorrent %1 started.", "e.g: qBittorrent v0.x started.").arg(QString::fromUtf8(""VERSION)));
setInfoBar(tr("Be careful, sharing copyrighted material without permission is against the law."), QString::fromUtf8("red"));
qDebug("Download tab built");
}
@@ -148,7 +145,8 @@ unsigned int DownloadingTorrents::getNbTorrentsInList() const {
// Note: do not actually pause the torrent in BT session
void DownloadingTorrents::pauseTorrent(QString hash) {
int row = getRowFromHash(hash);
Q_ASSERT(row != -1);
if(row == -1)
return;
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.0));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.0));
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
@@ -490,32 +488,6 @@ QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
return res;
}
void DownloadingTorrents::updateRatio() {
// Update ratio info
float ratio = 1.;
session_status sessionStatus = BTSession->getSessionStatus();
if(sessionStatus.total_payload_download == 0) {
if(sessionStatus.total_payload_upload == 0)
ratio = 1.;
else
ratio = 10.;
}else{
ratio = (double)sessionStatus.total_payload_upload / (double)sessionStatus.total_payload_download;
if(ratio > 10.)
ratio = 10.;
}
LCD_Ratio->display(QString(QByteArray::number(ratio, 'f', 1)));
if(ratio < 0.5) {
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/unhappy.png")));
}else{
if(ratio > 1.0) {
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/smile.png")));
}else{
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/stare.png")));
}
}
}
void DownloadingTorrents::displayInfoBarMenu(const QPoint& pos) {
// Log Menu
QMenu myLogMenu(this);
@@ -534,9 +506,6 @@ void DownloadingTorrents::sortProgressColumnDelayed() {
// get information from torrent handles and
// update download list accordingly
void DownloadingTorrents::updateDlList() {
// update global informations
LCD_UpSpeed->display(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1))); // UP LCD
LCD_DownSpeed->display(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1))); // DL LCD
// browse handles
QStringList unfinishedTorrents = BTSession->getUnfinishedTorrents();
QString hash;

View File

@@ -100,7 +100,6 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
void setInfoBar(QString info, QColor color=QApplication::palette().color(QPalette::WindowText));
void pauseTorrent(QString hash);
void resumeTorrent(QString hash);
void updateRatio();
void deleteTorrent(QString hash);
void setBottomTabEnabled(unsigned int index, bool b);
void propertiesSelection();

186
src/eventmanager.cpp Normal file
View File

@@ -0,0 +1,186 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 "eventmanager.h"
#include "json.h"
#include <QDebug>
EventManager::EventManager(QObject *parent)
: QObject(parent)
{
revision = 0;
}
void EventManager::update(QVariantMap event)
{
revision++;
events << QPair<ulong, QVariantMap>(revision, event);
emit updated();
qDebug("Added the following event");
qDebug() << event;
/* QLinkedList<QPair<ulong, QVariantMap> >::iterator i;
for (i = events.begin(); i != events.end(); i++)
qDebug() << *i;*/
}
QVariant EventManager::querySince(ulong r) const
{
QVariantList list;
QLinkedListIterator<QPair<ulong, QVariantMap> > i(events);
i.toBack();
while (i.hasPrevious())
{
QPair<ulong, QVariantMap> pair = i.previous();
if (pair.first <= r)
break;
list.prepend(QVariant(pair.second));
}
QVariantMap map;
map["events"] = QVariant(list);
map["revision"] = QVariant((qulonglong) revision);
return QVariant(map);
}
bool EventManager::isUpdated(ulong r) const
{
return (r < revision);
}
void EventManager::addedTorrent(QString, QTorrentHandle& h)
{
QVariantMap event;
event["type"] = QVariant("add");
event["hash"] = QVariant(h.hash());
event["name"] = QVariant(h.name());
update(event);
}
void EventManager::deletedTorrent(QString hash)
{
QVariantMap event;
event["type"] = QVariant("delete");
event["hash"] = QVariant(hash);
QLinkedList<QPair<ulong, QVariantMap> >::iterator i = events.end();
bool loop = true;
while (loop && i != events.begin()) {
--i;
QVariantMap oldevent = i->second;
if(oldevent["hash"] == QVariant(hash))
{
if(oldevent["type"] == QVariant("add"))
loop = false;
i = events.erase(i);
}
}
update(event);
}
void EventManager::modifiedTorrent(QTorrentHandle h)
{
QString hash = h.hash();
QVariantMap event;
QVariant v;
if(h.is_paused())
v = QVariant("paused");
else
{
switch(h.state())
{
case torrent_status::finished:
case torrent_status::seeding:
v = QVariant("seeding");
break;
case torrent_status::checking_files:
case torrent_status::queued_for_checking:
v = QVariant("checking");
break;
case torrent_status::connecting_to_tracker:
if(h.download_payload_rate() > 0)
v = QVariant("downloading");
else
v = QVariant("connecting");
break;
case torrent_status::downloading:
case torrent_status::downloading_metadata:
if(h.download_payload_rate() > 0)
v = QVariant("downloading");
else
v = QVariant("stalled");
break;
default:
v = QVariant();
}
}
if(modify(hash, "state", v))
event["state"] = v;
v = QVariant((qlonglong)h.actual_size());
if(modify(hash, "size", v))
event["size"] = v;
v = QVariant(h.progress());
if(modify(hash, "progress", v))
event["progress"] = v;
v = QVariant(h.download_payload_rate());
if(modify(hash, "dlspeed", v))
event["dlspeed"] = v;
v = QVariant(h.upload_payload_rate());
if(modify(hash, "upspeed", v))
event["upspeed"] = v;
if(event.size() > 0)
{
event["type"] = QVariant("modify");
event["hash"] = QVariant(hash);
update(event);
}
}
bool EventManager::modify(QString hash, QString key, QVariant value)
{
QLinkedList<QPair<ulong, QVariantMap> >::iterator i = events.end();
while (i != events.begin()) {
--i;
QVariantMap event = i->second;
if(event["hash"] == QVariant(hash))
{
if(event["type"] == QVariant("add"))
return true;
if(event.contains(key))
{
if(event[key] == value)
return false;
else
{
if(event.size() <= 3)
i = events.erase(i);
else
i->second.remove(key);
return true;
}
}
}
}
return true;
}

55
src/eventmanager.h Normal file
View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 EVENTMANAGER_H
#define EVENTMANAGER_H
#include "qtorrenthandle.h"
#include <QLinkedList>
#include <QPair>
#include <QVariant>
class EventManager : public QObject
{
Q_OBJECT
private:
ulong revision;
QLinkedList<QPair <ulong, QVariantMap> > events;
bool modify(QString hash, QString key, QVariant value);
protected:
void update(QVariantMap event);
public:
EventManager(QObject *parent = 0);
QVariant querySince(ulong r) const;
bool isUpdated(ulong r) const;
signals:
void updated();
public slots:
void addedTorrent(QString path, QTorrentHandle& h);
void deletedTorrent(QString hash);
void modifiedTorrent(QTorrentHandle h);
};
#endif

383
src/filterParserThread.h Normal file

File diff suppressed because it is too large Load Diff

204
src/httpconnection.cpp Normal file
View File

@@ -0,0 +1,204 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 "httpconnection.h"
#include "httpserver.h"
#include "eventmanager.h"
#include "json.h"
#include <QTcpSocket>
#include <QDateTime>
#include <QStringList>
#include <QHttpRequestHeader>
#include <QHttpResponseHeader>
#include <QFile>
#include <QDebug>
HttpConnection::HttpConnection(QTcpSocket *socket, HttpServer *parent)
: QObject(parent), socket(socket), parent(parent)
{
socket->setParent(this);
connect(socket, SIGNAL(readyRead()), this, SLOT(read()));
connect(socket, SIGNAL(disconnected()), this, SLOT(deleteLater()));
}
HttpConnection::~HttpConnection()
{
}
void HttpConnection::read()
{
QString input = socket->readAll();
qDebug(" -------");
qDebug("|REQUEST|");
qDebug(" -------");
qDebug(input.toAscii().constData());
parser.write(input);
if(parser.isError())
{
generator.setStatusLine(400, "Bad Request");
write();
}
else
if (parser.isParsable())
respond();
}
void HttpConnection::write()
{
QByteArray output = generator.toByteArray();
qDebug(" --------");
qDebug("|RESPONSE|");
qDebug(" --------");
qDebug()<<output;
socket->write(output);
socket->disconnectFromHost();
}
void HttpConnection::respond()
{
QStringList auth = parser.value("Authorization").split(" ", QString::SkipEmptyParts);
if (auth.size() != 2 || QString::compare(auth[0], "Basic", Qt::CaseInsensitive) != 0 || !parent->isAuthorized(auth[1].toUtf8()))
{
generator.setStatusLine(401, "Unauthorized");
generator.setValue("WWW-Authenticate", "Basic realm=\"you know what\"");
write();
return;
}
QString url = parser.url();
QStringList list = url.split('/', QString::SkipEmptyParts);
if (list.contains(".") || list.contains(".."))
{
respondNotFound();
return;
}
if (list.size() == 0)
list.append("index.html");
if (list.size() == 2)
{
if (list[0] == "json")
{
if (list[1] == "events")
{
EventManager* manager = parent->eventManager();
uint r = parser.get("r").toUInt();
if(manager->isUpdated(r))
respondJson();
else
connect(manager, SIGNAL(updated()), this, SLOT(respondJson()));
return;
}
}
if (list[0] == "command")
{
QString command = list[1];
respondCommand(command);
generator.setStatusLine(200, "OK");
write();
return;
}
}
if (list[0] == "images")
list[0] = "Icons";
else
list.prepend("webui");
url = ":/" + list.join("/");
QFile file(url);
if(!file.open(QIODevice::ReadOnly))
{
respondNotFound();
return;
}
QString ext = list.last();
int index = ext.lastIndexOf('.') + 1;
if (index > 0)
ext.remove(0, index);
else
ext.clear();
QByteArray data = file.readAll();
generator.setStatusLine(200, "OK");
generator.setContentTypeByExt(ext);
generator.setMessage(data);
write();
}
void HttpConnection::respondNotFound()
{
generator.setStatusLine(404, "File not found");
write();
}
void HttpConnection::respondJson()
{
EventManager* manager = parent->eventManager();
QString temp = parser.get("r");
uint r = parser.get("r").toUInt();
QVariant data = manager->querySince(r);
QString string = toJson(data);
generator.setStatusLine(200, "OK");
generator.setContentTypeByExt("js");
generator.setMessage(string);
write();
}
void HttpConnection::respondCommand(QString command)
{
if(command == "download")
{
QString urls = parser.post("urls");
QStringList list = urls.split('\n');
QStringList url_list_cleaned;
foreach(QString url, list){
url = url.trimmed();
if(!url.isEmpty()){
if(url_list_cleaned.indexOf(QRegExp(url, Qt::CaseInsensitive, QRegExp::FixedString)) < 0){
url_list_cleaned << url;
}
}
}
emit urlsReadyToBeDownloaded(url_list_cleaned);
return;
}
if(command == "resumeall")
{
emit resumeAllTorrents();
return;
}
if(command == "pauseall")
{
emit pauseAllTorrents();
return;
}
if(command == "resume")
{
emit resumeTorrent(parser.post("hash"));
return;
}
if(command == "pause")
{
emit pauseTorrent(parser.post("hash"));
return;
}
if(command == "delete")
{
emit deleteTorrent(parser.post("hash"));
return;
}
}

67
src/httpconnection.h Normal file
View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 HTTPCONNECTION_H
#define HTTPCONNECTION_H
#include "httprequestparser.h"
#include "httpresponsegenerator.h"
#include <QObject>
class QTcpSocket;
class HttpServer;
class HttpConnection : public QObject
{
Q_OBJECT
private:
QTcpSocket *socket;
HttpServer *parent;
protected:
HttpRequestParser parser;
HttpResponseGenerator generator;
protected slots:
void write();
virtual void respond();
void respondJson();
void respondCommand(QString command);
void respondNotFound();
public:
HttpConnection(QTcpSocket *socket, HttpServer *parent);
~HttpConnection();
private slots:
void read();
signals:
void urlsReadyToBeDownloaded(const QStringList&);
void deleteTorrent(QString hash);
void resumeTorrent(QString hash);
void pauseTorrent(QString hash);
void resumeAllTorrents();
void pauseAllTorrents();
};
#endif

128
src/httprequestparser.cpp Normal file
View File

@@ -0,0 +1,128 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 "httprequestparser.h"
#include <QUrl>
#include <QDebug>
HttpRequestParser::HttpRequestParser()
{
headerDone = false;
messageDone = false;
error = false;
}
HttpRequestParser::~HttpRequestParser()
{
}
bool HttpRequestParser::isParsable() const
{
return !error && headerDone && isValid() && (messageDone || !hasContentLength() || contentLength() == 0);
}
bool HttpRequestParser::isError() const
{
return error;
}
QString HttpRequestParser::url() const
{
return path;
}
QString HttpRequestParser::message() const
{
if(isParsable())
return data;
return QString();
}
QString HttpRequestParser::get(const QString key) const
{
return getMap[key];
}
QString HttpRequestParser::post(const QString key) const
{
return postMap[key];
}
void HttpRequestParser::write(QString str)
{
while (!headerDone && str.size()>0)
{
int index = str.indexOf('\n') + 1;
if(index == 0)
{
data += str;
str.clear();
}
else
{
data += str.left(index);
str.remove(0, index);
if(data.right(4) == "\r\n\r\n")
{
QHttpRequestHeader::operator=(QHttpRequestHeader(data));
headerDone = true;
data.clear();
QUrl url = QUrl::fromEncoded(QHttpRequestHeader::path().toAscii());
path = url.path();
qDebug() << path;
QListIterator<QPair<QString, QString> > i(url.queryItems());
while (i.hasNext())
{
QPair<QString, QString> pair = i.next();
getMap[pair.first] = pair.second;
qDebug() << pair.first << "=" << get(pair.first);
}
}
}
}
if(!messageDone && str.size()>0)
{
if(hasContentLength())
{
data += str;
if(data.size() >= (int) contentLength())
{
data.resize(contentLength());
messageDone = true;
//parse POST data
if(contentType() == "application/x-www-form-urlencoded")
{
QUrl url;
url.setEncodedQuery(data.toAscii());
QListIterator<QPair<QString, QString> > i(url.queryItems());
while (i.hasNext())
{
QPair<QString, QString> pair = i.next();
postMap[pair.first] = pair.second;
qDebug() << pair.first << "=" << post(pair.first);
}
}
}
}
else
error = true;
}
}

50
src/httprequestparser.h Normal file
View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 HTTPREQUESTPARSER_H
#define HTTPREQUESTPARSER_H
#include<QHttpRequestHeader>
class HttpRequestParser : public QHttpRequestHeader
{
private:
bool headerDone;
bool messageDone;
bool error;
QString data;
QString path;
QMap<QString, QString> postMap;
QMap<QString, QString> getMap;
public:
HttpRequestParser();
~HttpRequestParser();
bool isParsable() const;
bool isError() const;
QString url() const;
QString message() const;
QString get(const QString key) const;
QString post(const QString key) const;
void write(QString str);
};
#endif

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 "httpresponsegenerator.h"
#include <QDebug>
void HttpResponseGenerator::setMessage(const QByteArray message)
{
HttpResponseGenerator::message = message;
setContentLength(message.size());
}
void HttpResponseGenerator::setMessage(const QString message)
{
setMessage(message.QString::toUtf8());
}
void HttpResponseGenerator::stripMessage()
{
message.clear();
}
QByteArray HttpResponseGenerator::toByteArray() const
{
return QHttpResponseHeader::toString().toUtf8() + message;
}
void HttpResponseGenerator::setContentTypeByExt(const QString ext)
{
if(ext == "css")
{
setContentType("text/css");
return;
}
if(ext == "gif")
{
setContentType("image/gif");
return;
}
if(ext == "htm" || ext == "html")
{
setContentType("text/html");
return;
}
if(ext == "js")
{
setContentType("text/javascript");
return;
}
if(ext == "png")
{
setContentType("image/x-png");
return;
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 HTTPRESPONSEGENERATOR_H
#define HTTPRESPONSEGENERATOR_H
#include<QHttpResponseHeader>
class HttpResponseGenerator : public QHttpResponseHeader
{
private:
QByteArray message;
public:
void setMessage(const QByteArray message);
void setMessage(const QString message);
void stripMessage();
void setContentTypeByExt(const QString ext);
virtual QByteArray toByteArray() const;
};
#endif

98
src/httpserver.cpp Normal file
View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 "httpserver.h"
#include "httpconnection.h"
#include "eventmanager.h"
#include "bittorrent.h"
#include <QTimer>
HttpServer::HttpServer(bittorrent *BTSession, int msec, QObject* parent) : QTcpServer(parent)
{
base64 = QByteArray(":").toBase64();
connect(this, SIGNAL(newConnection()), this, SLOT(newHttpConnection()));
HttpServer::BTSession = BTSession;
manager = new EventManager(this);
//add torrents
QStringList list = BTSession->getUnfinishedTorrents() + BTSession->getFinishedTorrents();
QString hash;
foreach(hash, list)
{
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid())
manager->addedTorrent(QString(), h);
}
//connect BTSession to manager
connect(BTSession, SIGNAL(addedTorrent(QString, QTorrentHandle&, bool)), manager, SLOT(addedTorrent(QString, QTorrentHandle&)));
connect(BTSession, SIGNAL(deletedTorrent(QString)), manager, SLOT(deletedTorrent(QString)));
//set timer
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));
timer->start(msec);
}
HttpServer::~HttpServer()
{
delete manager;
}
void HttpServer::newHttpConnection()
{
QTcpSocket *socket;
while((socket = nextPendingConnection()))
{
HttpConnection *connection = new HttpConnection(socket, this);
//connect connection to BTSession
connect(connection, SIGNAL(urlsReadyToBeDownloaded(const QStringList&)), BTSession, SLOT(downloadFromURLList(const QStringList&)));
connect(connection, SIGNAL(deleteTorrent(QString)), BTSession, SLOT(deleteTorrent(QString)));
connect(connection, SIGNAL(pauseTorrent(QString)), BTSession, SLOT(pauseTorrent(QString)));
connect(connection, SIGNAL(resumeTorrent(QString)), BTSession, SLOT(resumeTorrent(QString)));
connect(connection, SIGNAL(pauseAllTorrents()), BTSession, SLOT(pauseAllTorrents()));
connect(connection, SIGNAL(resumeAllTorrents()), BTSession, SLOT(resumeAllTorrents()));
}
}
void HttpServer::onTimer()
{
QStringList list = BTSession->getUnfinishedTorrents() + BTSession->getFinishedTorrents();
foreach(QString hash, list)
{
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid())
manager->modifiedTorrent(h);
}
}
void HttpServer::setAuthorization(QString username, QString password)
{
QString cat = username + ":" + password;
base64 = QByteArray(cat.toUtf8()).toBase64();
}
bool HttpServer::isAuthorized(QByteArray auth) const
{
return (auth == base64);
}
EventManager *HttpServer::eventManager() const
{
return manager;
}

53
src/httpserver.h Normal file
View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 HTTPSERVER_H
#define HTTPSERVER_H
#include <QTcpServer>
#include <QByteArray>
class bittorrent;
class EventManager;
class HttpServer : public QTcpServer
{
Q_OBJECT
private:
QByteArray base64;
bittorrent *BTSession;
EventManager *manager;
public:
HttpServer(bittorrent *BTSession, int msec, QObject* parent = 0);
~HttpServer();
void setAuthorization(QString username, QString password);
bool isAuthorized(QByteArray auth) const;
EventManager *eventManager() const;
private slots:
void newHttpConnection();
void onTimer();
};
#endif

103
src/json.cpp Normal file
View File

@@ -0,0 +1,103 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 "json.h"
QString toJson(QVariant v)
{
if (v.isNull())
return "null";
QString result;
switch(v.type())
{
case QVariant::Bool:
case QVariant::Double:
case QVariant::Int:
case QVariant::LongLong:
case QVariant::UInt:
case QVariant::ULongLong:
return v.value<QString>();
case QVariant::String:
{
QString s = v.value<QString>();
result = "\"";
for(int i=0; i<s.size(); i++)
{
QChar ch = s[i];
switch(ch.toAscii())
{
case '\b':
result += "\\b";
break;
case '\f':
result += "\\f";
break;
case '\n':
result += "\\n";
break;
case '\r':
result += "\\r";
break;
case '\t':
result += "\\t";
break;
case '\"':
case '\'':
case '\\':
case '&':
result += '\\';
case '\0':
default:
result += ch;
}
}
result += "\"";
return result;
}
case QVariant::List:
{
result = "[";
QListIterator<QVariant> it(v.value<QVariantList>());
while (it.hasNext())
result += toJson(it.next()) + ",";
if(result.size() > 1)
result.chop(1);
result += "]";
return result;
}
case QVariant::Map:
{
result = "{";
QMapIterator<QString, QVariant> it(v.value<QVariantMap>());
while (it.hasNext()) {
it.next();
if(it.value().isValid())
result += toJson(QVariant(it.key())) + ":" + toJson(it.value()) + ",";
}
if(result.size() > 1)
result.chop(1);
result += "}";
return result;
}
default:
return "undefined";
}
}

29
src/json.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.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 JSON_H
#define JSON_H
#include <QVariant>
QString toJson(QVariant v);
#endif

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More