mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-31 17:04:34 +00:00
FEATURE: qBittorrent can update dynamic DNS services (DynDNS, no-ip)
This commit is contained in:
parent
fd4f46485c
commit
c85cb8799e
@ -2,6 +2,7 @@
|
|||||||
- FEATURE: Added support for secure SMTP connection (SSL)
|
- FEATURE: Added support for secure SMTP connection (SSL)
|
||||||
- FEATURE: Added support for SMTP authentication
|
- FEATURE: Added support for SMTP authentication
|
||||||
- FEATURE: Added UPnP/NAT-PMP port forward for the Web UI port
|
- FEATURE: Added UPnP/NAT-PMP port forward for the Web UI port
|
||||||
|
- FEATURE: qBittorrent can update dynamic DNS services (DynDNS, no-ip)
|
||||||
- BUGFIX: Change systray icon on the fly (no restart needed)
|
- BUGFIX: Change systray icon on the fly (no restart needed)
|
||||||
- COSMETIC: Added monochrome icon for light themes
|
- COSMETIC: Added monochrome icon for light themes
|
||||||
|
|
||||||
|
287
src/dnsupdater.cpp
Normal file
287
src/dnsupdater.cpp
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt4 and libtorrent.
|
||||||
|
* Copyright (C) 2011 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.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*
|
||||||
|
* Contact : chris@qbittorrent.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include "dnsupdater.h"
|
||||||
|
#include "qbtsession.h"
|
||||||
|
|
||||||
|
DNSUpdater::DNSUpdater(QObject *parent) :
|
||||||
|
QObject(parent), m_state(OK)
|
||||||
|
{
|
||||||
|
updateCredentials();
|
||||||
|
|
||||||
|
// Load saved settings from previous session
|
||||||
|
QIniSettings settings("qBittorrent", "qBittorrent");
|
||||||
|
m_lastIPCheckTime = settings.value("DNSUpdater/lastUpdateTime").toDateTime();
|
||||||
|
m_lastIP = QHostAddress(settings.value("DNSUpdater/lastIP").toString());
|
||||||
|
|
||||||
|
// Start IP checking timer
|
||||||
|
m_ipCheckTimer.setInterval(IP_CHECK_INTERVAL_MS);
|
||||||
|
connect(&m_ipCheckTimer, SIGNAL(timeout()), SLOT(checkPublicIP()));
|
||||||
|
m_ipCheckTimer.start();
|
||||||
|
|
||||||
|
// Check lastUpdate to avoid flooding
|
||||||
|
if(!m_lastIPCheckTime.isValid() ||
|
||||||
|
m_lastIPCheckTime.secsTo(QDateTime::currentDateTime())*1000 > IP_CHECK_INTERVAL_MS) {
|
||||||
|
checkPublicIP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DNSUpdater::~DNSUpdater() {
|
||||||
|
// Save lastupdate time and last ip
|
||||||
|
QIniSettings settings("qBittorrent", "qBittorrent");
|
||||||
|
settings.setValue("DNSUpdater/lastUpdateTime", m_lastIPCheckTime);
|
||||||
|
settings.setValue("DNSUpdater/lastIP", m_lastIP.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DNSUpdater::checkPublicIP()
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_state == OK);
|
||||||
|
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
|
||||||
|
connect(manager, SIGNAL(finished(QNetworkReply*)),
|
||||||
|
SLOT(ipRequestFinished(QNetworkReply*)));
|
||||||
|
m_lastIPCheckTime = QDateTime::currentDateTime();
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(QUrl("http://checkip.dyndns.org"));
|
||||||
|
request.setRawHeader("User-Agent", "qBittorrent/"VERSION" chris@qbittorrent.org");
|
||||||
|
manager->get(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DNSUpdater::ipRequestFinished(QNetworkReply *reply)
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
if(reply->error()) {
|
||||||
|
// Error
|
||||||
|
qWarning() << Q_FUNC_INFO << "Error:" << reply->errorString();
|
||||||
|
} else {
|
||||||
|
// Parse response
|
||||||
|
QRegExp ipregex("Current IP Address:\\s+([^<]+)</body>");
|
||||||
|
QString ret = reply->readAll();
|
||||||
|
if(ipregex.indexIn(ret) >= 0) {
|
||||||
|
QString ip_str = ipregex.cap(1);
|
||||||
|
qDebug() << Q_FUNC_INFO << "Regular expression captured the following IP:" << ip_str;
|
||||||
|
QHostAddress new_ip(ip_str);
|
||||||
|
if(!new_ip.isNull()) {
|
||||||
|
if(m_lastIP != new_ip) {
|
||||||
|
qDebug() << Q_FUNC_INFO << "The IP address changed, report the change to DynDNS...";
|
||||||
|
m_lastIP = new_ip;
|
||||||
|
updateDNSService();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << Q_FUNC_INFO << "Failed to construct a QHostAddress from the IP string";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << Q_FUNC_INFO << "Regular expression failed ot capture the IP address";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Clean up
|
||||||
|
reply->deleteLater();
|
||||||
|
sender()->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DNSUpdater::updateDNSService()
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
// Prepare request
|
||||||
|
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
|
||||||
|
connect(manager, SIGNAL(finished(QNetworkReply*)),
|
||||||
|
SLOT(ipUpdateFinished(QNetworkReply*)));
|
||||||
|
m_lastIPCheckTime = QDateTime::currentDateTime();
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(getUpdateUrl());
|
||||||
|
request.setRawHeader("User-Agent", "qBittorrent/"VERSION" chris@qbittorrent.org");
|
||||||
|
manager->get(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl DNSUpdater::getUpdateUrl() const
|
||||||
|
{
|
||||||
|
QUrl url;
|
||||||
|
#ifdef QT_NO_OPENSSL
|
||||||
|
url.setScheme("http");
|
||||||
|
#else
|
||||||
|
url.setScheme("https");
|
||||||
|
#endif
|
||||||
|
url.setUserName(m_username);
|
||||||
|
url.setPassword(m_password);
|
||||||
|
|
||||||
|
Q_ASSERT(!m_lastIP.isNull());
|
||||||
|
// Service specific
|
||||||
|
switch(m_service) {
|
||||||
|
case DNS::DYNDNS:
|
||||||
|
url.setHost("members.dyndns.org");
|
||||||
|
break;
|
||||||
|
case DNS::NOIP:
|
||||||
|
url.setHost("dynupdate.no-ip.com");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qWarning() << "Unrecognized Dynamic DNS service!";
|
||||||
|
Q_ASSERT(0);
|
||||||
|
}
|
||||||
|
url.setPath("/nic/update");
|
||||||
|
url.addQueryItem("hostname", m_domain);
|
||||||
|
url.addQueryItem("myip", m_lastIP.toString());
|
||||||
|
Q_ASSERT(url.isValid());
|
||||||
|
qDebug() << Q_FUNC_INFO << url.toString();
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DNSUpdater::ipUpdateFinished(QNetworkReply *reply)
|
||||||
|
{
|
||||||
|
if(reply->error()) {
|
||||||
|
// Error
|
||||||
|
qWarning() << Q_FUNC_INFO << "Error:" << reply->errorString();
|
||||||
|
} else {
|
||||||
|
// Pase reply
|
||||||
|
processIPUpdateReply(reply->readAll());
|
||||||
|
}
|
||||||
|
// Clean up
|
||||||
|
reply->deleteLater();
|
||||||
|
sender()->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DNSUpdater::processIPUpdateReply(const QString &reply)
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << reply;
|
||||||
|
QString code = reply.split(" ").first();
|
||||||
|
qDebug() << Q_FUNC_INFO << "Code:" << code;
|
||||||
|
if(code == "good" || code == "nochg") {
|
||||||
|
QBtSession::instance()->addConsoleMessage(tr("Your dynamic DNS was successfuly updated."), "green");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(code == "911" || code == "dnserr") {
|
||||||
|
QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes."),
|
||||||
|
"red");
|
||||||
|
m_lastIP.clear();
|
||||||
|
// It will retry in 30 minutes because the timer was not stopped
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Everything bellow is an error, stop updating until the user updates something
|
||||||
|
m_ipCheckTimer.stop();
|
||||||
|
m_lastIP.clear();
|
||||||
|
if(code == "nohost") {
|
||||||
|
QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: hostname supplied does not exist under specified account."),
|
||||||
|
"red");
|
||||||
|
m_state = INVALID_CREDS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(code == "badauth") {
|
||||||
|
QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: Invalid username/password."), "red");
|
||||||
|
m_state = INVALID_CREDS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(code == "badagent") {
|
||||||
|
QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org."),
|
||||||
|
"red");
|
||||||
|
m_state = FATAL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(code == "!donator") {
|
||||||
|
QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org.").arg("!donator"),
|
||||||
|
"red");
|
||||||
|
m_state = FATAL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(code == "abuse") {
|
||||||
|
QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: Your username was blocked due to abuse."),
|
||||||
|
"red");
|
||||||
|
m_state = FATAL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DNSUpdater::updateCredentials()
|
||||||
|
{
|
||||||
|
if(m_state == FATAL) return;
|
||||||
|
Preferences pref;
|
||||||
|
bool change = false;
|
||||||
|
// Get DNS service information
|
||||||
|
if(m_service != pref.getDynDNSService()) {
|
||||||
|
m_service = pref.getDynDNSService();
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
if(m_domain != pref.getDynDomainName()) {
|
||||||
|
m_domain = pref.getDynDomainName();
|
||||||
|
QRegExp domain_regex("^(?:(?!\\d|-)[a-zA-Z0-9\\-]{1,63}\\.)+[a-zA-Z]{2,}$");
|
||||||
|
if(domain_regex.indexIn(m_domain) < 0) {
|
||||||
|
QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: supplied domain name is invalid."),
|
||||||
|
"red");
|
||||||
|
m_lastIP.clear();
|
||||||
|
m_ipCheckTimer.stop();
|
||||||
|
m_state = INVALID_CREDS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
if(m_username != pref.getDynDNSUsername()) {
|
||||||
|
m_username = pref.getDynDNSUsername();
|
||||||
|
if(m_username.length() < 4) {
|
||||||
|
QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: supplied username is too short."),
|
||||||
|
"red");
|
||||||
|
m_lastIP.clear();
|
||||||
|
m_ipCheckTimer.stop();
|
||||||
|
m_state = INVALID_CREDS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
if(m_password != pref.getDynDNSPassword()) {
|
||||||
|
m_password = pref.getDynDNSPassword();
|
||||||
|
if(m_password.length() < 4) {
|
||||||
|
QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: supplied password is too short."),
|
||||||
|
"red");
|
||||||
|
m_lastIP.clear();
|
||||||
|
m_ipCheckTimer.stop();
|
||||||
|
m_state = INVALID_CREDS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_state == INVALID_CREDS && change) {
|
||||||
|
m_state = OK; // Try again
|
||||||
|
m_ipCheckTimer.start();
|
||||||
|
checkPublicIP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl DNSUpdater::getRegistrationUrl(int service)
|
||||||
|
{
|
||||||
|
switch(service) {
|
||||||
|
case DNS::DYNDNS:
|
||||||
|
return QUrl("https://www.dyndns.com/account/services/hosts/add.html");
|
||||||
|
case DNS::NOIP:
|
||||||
|
return QUrl("http://www.no-ip.com/services/managed_dns/free_dynamic_dns.html");
|
||||||
|
default:
|
||||||
|
Q_ASSERT(0);
|
||||||
|
}
|
||||||
|
return QUrl();
|
||||||
|
}
|
81
src/dnsupdater.h
Normal file
81
src/dnsupdater.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt4 and libtorrent.
|
||||||
|
* Copyright (C) 2011 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.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*
|
||||||
|
* Contact : chris@qbittorrent.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DNSUPDATER_H
|
||||||
|
#define DNSUPDATER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QTimer>
|
||||||
|
#include "preferences.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Based on http://www.dyndns.com/developers/specs/
|
||||||
|
*/
|
||||||
|
class DNSUpdater : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DNSUpdater(QObject *parent = 0);
|
||||||
|
~DNSUpdater();
|
||||||
|
static QUrl getRegistrationUrl(int service);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updateCredentials();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void checkPublicIP();
|
||||||
|
void ipRequestFinished(QNetworkReply* reply);
|
||||||
|
void updateDNSService();
|
||||||
|
void ipUpdateFinished(QNetworkReply* reply);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QUrl getUpdateUrl() const;
|
||||||
|
void processIPUpdateReply(const QString &reply);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHostAddress m_lastIP;
|
||||||
|
QDateTime m_lastIPCheckTime;
|
||||||
|
QTimer m_ipCheckTimer;
|
||||||
|
int m_state;
|
||||||
|
// Service creds
|
||||||
|
DNS::Service m_service;
|
||||||
|
QString m_domain;
|
||||||
|
QString m_username;
|
||||||
|
QString m_password;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const int IP_CHECK_INTERVAL_MS = 1800000; // 30 min
|
||||||
|
enum State { OK, INVALID_CREDS, FATAL };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DNSUPDATER_H
|
@ -2281,11 +2281,103 @@ QGroupBox {
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="checkDynDNS">
|
||||||
|
<property name="title">
|
||||||
|
<string>Update my dynamic domain name</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_5">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_19">
|
||||||
|
<property name="text">
|
||||||
|
<string>Service:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboDNSService">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>DynDNS</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>No-IP</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="registerDNSBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Register</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_20">
|
||||||
|
<property name="text">
|
||||||
|
<string>Domain name:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="domainNameTxt">
|
||||||
|
<property name="text">
|
||||||
|
<string>changeme.dyndns.org</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_21">
|
||||||
|
<property name="text">
|
||||||
|
<string>Username:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="DNSUsernameTxt">
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_22">
|
||||||
|
<property name="text">
|
||||||
|
<string>Password:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLineEdit" name="DNSPasswordTxt">
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_9">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -2315,8 +2407,8 @@ QGroupBox {
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>86</width>
|
<width>504</width>
|
||||||
<height>16</height>
|
<height>384</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_36"/>
|
<layout class="QVBoxLayout" name="verticalLayout_36"/>
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
|
||||||
#include <libtorrent/version.hpp>
|
#include <libtorrent/version.hpp>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -50,6 +51,7 @@
|
|||||||
#include "qinisettings.h"
|
#include "qinisettings.h"
|
||||||
#include "qbtsession.h"
|
#include "qbtsession.h"
|
||||||
#include "iconprovider.h"
|
#include "iconprovider.h"
|
||||||
|
#include "dnsupdater.h"
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
|
||||||
@ -203,6 +205,11 @@ options_imp::options_imp(QWidget *parent):
|
|||||||
connect(textWebUiUsername, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
|
connect(textWebUiUsername, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
|
||||||
connect(textWebUiPassword, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
|
connect(textWebUiPassword, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
|
||||||
connect(checkBypassLocalAuth, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton()));
|
connect(checkBypassLocalAuth, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton()));
|
||||||
|
connect(checkDynDNS, SIGNAL(toggled(bool)), SLOT(enableApplyButton()));
|
||||||
|
connect(comboDNSService, SIGNAL(currentIndexChanged(int)), SLOT(enableApplyButton()));
|
||||||
|
connect(domainNameTxt, SIGNAL(textChanged(QString)), SLOT(enableApplyButton()));
|
||||||
|
connect(DNSUsernameTxt, SIGNAL(textChanged(QString)), SLOT(enableApplyButton()));
|
||||||
|
connect(DNSPasswordTxt, SIGNAL(textChanged(QString)), SLOT(enableApplyButton()));
|
||||||
// Disable apply Button
|
// Disable apply Button
|
||||||
applyButton->setEnabled(false);
|
applyButton->setEnabled(false);
|
||||||
// Tab selection mecanism
|
// Tab selection mecanism
|
||||||
@ -428,6 +435,12 @@ void options_imp::saveOptions(){
|
|||||||
// FIXME: Check that the password is valid (not empty at least)
|
// FIXME: Check that the password is valid (not empty at least)
|
||||||
pref.setWebUiPassword(webUiPassword());
|
pref.setWebUiPassword(webUiPassword());
|
||||||
pref.setWebUiLocalAuthEnabled(!checkBypassLocalAuth->isChecked());
|
pref.setWebUiLocalAuthEnabled(!checkBypassLocalAuth->isChecked());
|
||||||
|
// DynDNS
|
||||||
|
pref.setDynDNSEnabled(checkDynDNS->isChecked());
|
||||||
|
pref.setDynDNSService(comboDNSService->currentIndex());
|
||||||
|
pref.setDynDomainName(domainNameTxt->text());
|
||||||
|
pref.setDynDNSUsername(DNSUsernameTxt->text());
|
||||||
|
pref.setDynDNSPassword(DNSPasswordTxt->text());
|
||||||
}
|
}
|
||||||
// End Web UI
|
// End Web UI
|
||||||
// End preferences
|
// End preferences
|
||||||
@ -666,6 +679,12 @@ void options_imp::loadOptions(){
|
|||||||
textWebUiUsername->setText(pref.getWebUiUsername());
|
textWebUiUsername->setText(pref.getWebUiUsername());
|
||||||
textWebUiPassword->setText(pref.getWebUiPassword());
|
textWebUiPassword->setText(pref.getWebUiPassword());
|
||||||
checkBypassLocalAuth->setChecked(!pref.isWebUiLocalAuthEnabled());
|
checkBypassLocalAuth->setChecked(!pref.isWebUiLocalAuthEnabled());
|
||||||
|
// Dynamic DNS
|
||||||
|
checkDynDNS->setChecked(pref.isDynDNSEnabled());
|
||||||
|
comboDNSService->setCurrentIndex((int)pref.getDynDNSService());
|
||||||
|
domainNameTxt->setText(pref.getDynDomainName());
|
||||||
|
DNSUsernameTxt->setText(pref.getDynDNSUsername());
|
||||||
|
DNSPasswordTxt->setText(pref.getDynDNSPassword());
|
||||||
// End Web UI
|
// End Web UI
|
||||||
// Random stuff
|
// Random stuff
|
||||||
srand(time(0));
|
srand(time(0));
|
||||||
@ -1090,6 +1109,10 @@ void options_imp::showConnectionTab()
|
|||||||
tabSelection->setCurrentRow(2);
|
tabSelection->setCurrentRow(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void options_imp::on_registerDNSBtn_clicked() {
|
||||||
|
QDesktopServices::openUrl(DNSUpdater::getRegistrationUrl(comboDNSService->currentIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
void options_imp::on_IpFilterRefreshBtn_clicked() {
|
void options_imp::on_IpFilterRefreshBtn_clicked() {
|
||||||
if(m_refreshingIpFilter) return;
|
if(m_refreshingIpFilter) return;
|
||||||
m_refreshingIpFilter = true;
|
m_refreshingIpFilter = true;
|
||||||
|
@ -80,6 +80,7 @@ private slots:
|
|||||||
void on_randomButton_clicked();
|
void on_randomButton_clicked();
|
||||||
void on_addScanFolderButton_clicked();
|
void on_addScanFolderButton_clicked();
|
||||||
void on_removeScanFolderButton_clicked();
|
void on_removeScanFolderButton_clicked();
|
||||||
|
void on_registerDNSBtn_clicked();
|
||||||
void setLocale(const QString &locale);
|
void setLocale(const QString &locale);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -61,6 +61,9 @@ enum ProxyType {HTTP=1, SOCKS5=2, HTTP_PW=3, SOCKS5_PW=4, SOCKS4=5};
|
|||||||
namespace TrayIcon {
|
namespace TrayIcon {
|
||||||
enum Style { NORMAL = 0, MONO_DARK, MONO_LIGHT };
|
enum Style { NORMAL = 0, MONO_DARK, MONO_LIGHT };
|
||||||
}
|
}
|
||||||
|
namespace DNS {
|
||||||
|
enum Service { DYNDNS, NOIP };
|
||||||
|
}
|
||||||
|
|
||||||
class Preferences : public QIniSettings {
|
class Preferences : public QIniSettings {
|
||||||
Q_DISABLE_COPY(Preferences);
|
Q_DISABLE_COPY(Preferences);
|
||||||
@ -746,6 +749,46 @@ public:
|
|||||||
return pass_ha1;
|
return pass_ha1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isDynDNSEnabled() const {
|
||||||
|
return value("Preferences/DynDNS/Enabled", false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDynDNSEnabled(bool enabled) {
|
||||||
|
setValue("Preferences/DynDNS/Enabled", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
DNS::Service getDynDNSService() const {
|
||||||
|
return DNS::Service(value("Preferences/DynDNS/Service", DNS::DYNDNS).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDynDNSService(int service) {
|
||||||
|
setValue("Preferences/DynDNS/Service", service);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getDynDomainName() const {
|
||||||
|
return value("Preferences/DynDNS/DomainName", "changeme.dyndns.org").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDynDomainName(const QString name) {
|
||||||
|
setValue("Preferences/DynDNS/DomainName", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getDynDNSUsername() const {
|
||||||
|
return value("Preferences/DynDNS/Username").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDynDNSUsername(const QString username) {
|
||||||
|
setValue("Preferences/DynDNS/Username", username);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getDynDNSPassword() const {
|
||||||
|
return value("Preferences/DynDNS/Password").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDynDNSPassword(const QString password) {
|
||||||
|
setValue("Preferences/DynDNS/Password", password);
|
||||||
|
}
|
||||||
|
|
||||||
// Advanced settings
|
// Advanced settings
|
||||||
|
|
||||||
void setUILockPassword(const QString &clear_password) {
|
void setUILockPassword(const QString &clear_password) {
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "dnsupdater.h"
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
|
||||||
@ -98,7 +99,7 @@ QBtSession::QBtSession()
|
|||||||
, geoipDBLoaded(false), resolve_countries(false)
|
, geoipDBLoaded(false), resolve_countries(false)
|
||||||
#endif
|
#endif
|
||||||
, m_tracker(0), m_shutdownAct(NO_SHUTDOWN),
|
, m_tracker(0), m_shutdownAct(NO_SHUTDOWN),
|
||||||
m_upnp(0), m_natpmp(0)
|
m_upnp(0), m_natpmp(0), m_dynDNSUpdater(0)
|
||||||
{
|
{
|
||||||
BigRatioTimer = new QTimer(this);
|
BigRatioTimer = new QTimer(this);
|
||||||
BigRatioTimer->setInterval(10000);
|
BigRatioTimer->setInterval(10000);
|
||||||
@ -612,8 +613,25 @@ void QBtSession::initWebUi() {
|
|||||||
else
|
else
|
||||||
addConsoleMessage(tr("Web User Interface Error - Unable to bind Web UI to port %1").arg(port), "red");
|
addConsoleMessage(tr("Web User Interface Error - Unable to bind Web UI to port %1").arg(port), "red");
|
||||||
}
|
}
|
||||||
} else if(httpServer) {
|
// DynDNS
|
||||||
delete httpServer;
|
if(pref.isDynDNSEnabled()) {
|
||||||
|
if(!m_dynDNSUpdater)
|
||||||
|
m_dynDNSUpdater = new DNSUpdater(this);
|
||||||
|
else
|
||||||
|
m_dynDNSUpdater->updateCredentials();
|
||||||
|
} else {
|
||||||
|
if(m_dynDNSUpdater) {
|
||||||
|
delete m_dynDNSUpdater;
|
||||||
|
m_dynDNSUpdater = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(httpServer)
|
||||||
|
delete httpServer;
|
||||||
|
if(m_dynDNSUpdater) {
|
||||||
|
delete m_dynDNSUpdater;
|
||||||
|
m_dynDNSUpdater = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ class HttpServer;
|
|||||||
class BandwidthScheduler;
|
class BandwidthScheduler;
|
||||||
class ScanFoldersModel;
|
class ScanFoldersModel;
|
||||||
class TorrentSpeedMonitor;
|
class TorrentSpeedMonitor;
|
||||||
|
class DNSUpdater;
|
||||||
|
|
||||||
class QBtSession : public QObject {
|
class QBtSession : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -272,6 +273,8 @@ private:
|
|||||||
// Port forwarding
|
// Port forwarding
|
||||||
libtorrent::upnp *m_upnp;
|
libtorrent::upnp *m_upnp;
|
||||||
libtorrent::natpmp *m_natpmp;
|
libtorrent::natpmp *m_natpmp;
|
||||||
|
// DynDNS
|
||||||
|
DNSUpdater *m_dynDNSUpdater;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -101,13 +101,15 @@ HEADERS += misc.h \
|
|||||||
filesystemwatcher.h \
|
filesystemwatcher.h \
|
||||||
scannedfoldersmodel.h \
|
scannedfoldersmodel.h \
|
||||||
qinisettings.h \
|
qinisettings.h \
|
||||||
smtp.h
|
smtp.h \
|
||||||
|
dnsupdater.h
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
downloadthread.cpp \
|
downloadthread.cpp \
|
||||||
scannedfoldersmodel.cpp \
|
scannedfoldersmodel.cpp \
|
||||||
misc.cpp \
|
misc.cpp \
|
||||||
smtp.cpp
|
smtp.cpp \
|
||||||
|
dnsupdater.cpp
|
||||||
|
|
||||||
nox {
|
nox {
|
||||||
HEADERS += headlessloader.h
|
HEADERS += headlessloader.h
|
||||||
|
Loading…
x
Reference in New Issue
Block a user