mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-11 07:18:08 +00:00
- Torrent downloading is now handled by search engine plugins to allow for more flexibility
This commit is contained in:
parent
8214d87ce5
commit
c2244f746e
16
src/GUI.cpp
16
src/GUI.cpp
@ -139,7 +139,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
|
|||||||
downloadingTorrentTab = new DownloadingTorrents(this, BTSession);
|
downloadingTorrentTab = new DownloadingTorrents(this, BTSession);
|
||||||
tabs->addTab(downloadingTorrentTab, tr("Downloads") + QString::fromUtf8(" (0/0)"));
|
tabs->addTab(downloadingTorrentTab, tr("Downloads") + QString::fromUtf8(" (0/0)"));
|
||||||
tabs->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")));
|
tabs->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")));
|
||||||
vboxLayout->addWidget(tabs);
|
propertiesSplitter->insertWidget(0, tabs);
|
||||||
connect(downloadingTorrentTab, SIGNAL(unfinishedTorrentsNumberChanged(unsigned int)), this, SLOT(updateUnfinishedTorrentNumber(unsigned int)));
|
connect(downloadingTorrentTab, SIGNAL(unfinishedTorrentsNumberChanged(unsigned int)), this, SLOT(updateUnfinishedTorrentNumber(unsigned int)));
|
||||||
connect(downloadingTorrentTab, SIGNAL(torrentDoubleClicked(QString, bool)), this, SLOT(torrentDoubleClicked(QString, bool)));
|
connect(downloadingTorrentTab, SIGNAL(torrentDoubleClicked(QString, bool)), this, SLOT(torrentDoubleClicked(QString, bool)));
|
||||||
// Finished torrents tab
|
// Finished torrents tab
|
||||||
@ -237,6 +237,10 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
|
|||||||
QMainWindow::statusBar()->addPermanentWidget(upSpeedLbl);
|
QMainWindow::statusBar()->addPermanentWidget(upSpeedLbl);
|
||||||
QMainWindow::statusBar()->addPermanentWidget(statusSep4);
|
QMainWindow::statusBar()->addPermanentWidget(statusSep4);
|
||||||
QMainWindow::statusBar()->addPermanentWidget(ratioLbl);
|
QMainWindow::statusBar()->addPermanentWidget(ratioLbl);
|
||||||
|
// Properties code
|
||||||
|
propertiesSplitter->handle(1)->setVisible(false);
|
||||||
|
stackedProperties->setVisible(false);
|
||||||
|
// Display window if necessary
|
||||||
if(!settings.value(QString::fromUtf8("Preferences/General/StartMinimized"), false).toBool()) {
|
if(!settings.value(QString::fromUtf8("Preferences/General/StartMinimized"), false).toBool()) {
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
@ -294,6 +298,16 @@ GUI::~GUI() {
|
|||||||
qDebug("5");
|
qDebug("5");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUI::on_prop_infos_button_clicked() {
|
||||||
|
if(stackedProperties->isVisible()) {
|
||||||
|
propertiesSplitter->handle(1)->setVisible(false);
|
||||||
|
stackedProperties->setVisible(false);
|
||||||
|
} else {
|
||||||
|
stackedProperties->setVisible(true);
|
||||||
|
propertiesSplitter->handle(1)->setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GUI::displayRSSTab(bool enable) {
|
void GUI::displayRSSTab(bool enable) {
|
||||||
if(enable) {
|
if(enable) {
|
||||||
// RSS tab
|
// RSS tab
|
||||||
|
@ -173,7 +173,8 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
|||||||
void OptionsSaved(bool deleteOptions);
|
void OptionsSaved(bool deleteOptions);
|
||||||
// HTTP slots
|
// HTTP slots
|
||||||
void on_actionDownload_from_URL_triggered();
|
void on_actionDownload_from_URL_triggered();
|
||||||
|
// Properties
|
||||||
|
void on_prop_infos_button_clicked();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void trackerAuthenticationRequired(QTorrentHandle& h);
|
void trackerAuthenticationRequired(QTorrentHandle& h);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "ui_search.h"
|
#include "ui_search.h"
|
||||||
|
|
||||||
|
#define ENGINE_URL_COLUMN 4
|
||||||
#define URL_COLUMN 5
|
#define URL_COLUMN 5
|
||||||
|
|
||||||
class SearchListDelegate;
|
class SearchListDelegate;
|
||||||
|
@ -910,6 +910,7 @@ void bittorrent::setDefaultTempPath(QString temppath) {
|
|||||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||||
if(!h.is_valid()) continue;
|
if(!h.is_valid()) continue;
|
||||||
|
std::cout << "Moving storage for " << h.hash().toUtf8().data() << ", from " << h.save_path().toUtf8().data() << " to " << getSavePath(h.hash()).toUtf8().data() << std::endl;
|
||||||
h.move_storage(getSavePath(h.hash()));
|
h.move_storage(getSavePath(h.hash()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -154,11 +154,11 @@ class bittorrent : public QObject {
|
|||||||
bool enableDHT(bool b);
|
bool enableDHT(bool b);
|
||||||
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
|
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
|
||||||
void addPeerBanMessage(QString msg, bool from_ipfilter);
|
void addPeerBanMessage(QString msg, bool from_ipfilter);
|
||||||
|
void processDownloadedFile(QString, QString);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void scanDirectory(QString);
|
void scanDirectory(QString);
|
||||||
void readAlerts();
|
void readAlerts();
|
||||||
void processDownloadedFile(QString, QString);
|
|
||||||
bool loadTrackerFile(QString hash);
|
bool loadTrackerFile(QString hash);
|
||||||
void saveTrackerFile(QString hash);
|
void saveTrackerFile(QString hash);
|
||||||
void deleteBigRatios();
|
void deleteBigRatios();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE RCC><RCC version="1.0">
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
<qresource>
|
<qresource>
|
||||||
<file>search_engine/nova2.py</file>
|
<file>search_engine/nova2.py</file>
|
||||||
|
<file>search_engine/nova2dl.py</file>
|
||||||
<file>search_engine/novaprinter.py</file>
|
<file>search_engine/novaprinter.py</file>
|
||||||
<file>search_engine/helpers.py</file>
|
<file>search_engine/helpers.py</file>
|
||||||
<file>search_engine/engines/btjunkie.png</file>
|
<file>search_engine/engines/btjunkie.png</file>
|
||||||
|
@ -78,6 +78,11 @@ SearchEngine::~SearchEngine(){
|
|||||||
saveSearchHistory();
|
saveSearchHistory();
|
||||||
searchProcess->kill();
|
searchProcess->kill();
|
||||||
searchProcess->waitForFinished();
|
searchProcess->waitForFinished();
|
||||||
|
foreach(QProcess *downloader, downloaders) {
|
||||||
|
downloader->kill();
|
||||||
|
downloader->waitForFinished();
|
||||||
|
delete downloader;
|
||||||
|
}
|
||||||
delete searchTimeout;
|
delete searchTimeout;
|
||||||
delete searchProcess;
|
delete searchProcess;
|
||||||
delete searchCompleter;
|
delete searchCompleter;
|
||||||
@ -225,6 +230,18 @@ void SearchEngine::saveResultsColumnsWidth() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchEngine::downloadTorrent(QString engine_url, QString torrent_url) {
|
||||||
|
QProcess *downloadProcess = new QProcess(this);
|
||||||
|
connect(downloadProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(downloadFinished(int,QProcess::ExitStatus)));
|
||||||
|
downloaders << downloadProcess;
|
||||||
|
QStringList params;
|
||||||
|
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2dl.py";
|
||||||
|
params << engine_url;
|
||||||
|
params << torrent_url;
|
||||||
|
// Launch search
|
||||||
|
downloadProcess->start("python", params, QIODevice::ReadOnly);
|
||||||
|
}
|
||||||
|
|
||||||
void SearchEngine::searchStarted(){
|
void SearchEngine::searchStarted(){
|
||||||
// Update SearchEngine widgets
|
// Update SearchEngine widgets
|
||||||
search_status->setText(tr("Searching..."));
|
search_status->setText(tr("Searching..."));
|
||||||
@ -242,9 +259,10 @@ void SearchEngine::downloadSelectedItem(const QModelIndex& index){
|
|||||||
int row = index.row();
|
int row = index.row();
|
||||||
// Get Item url
|
// Get Item url
|
||||||
QStandardItemModel *model = all_tab.at(tabWidget->currentIndex())->getCurrentSearchListModel();
|
QStandardItemModel *model = all_tab.at(tabWidget->currentIndex())->getCurrentSearchListModel();
|
||||||
QString url = model->data(model->index(index.row(), URL_COLUMN)).toString();
|
QString engine_url = model->data(model->index(index.row(), ENGINE_URL_COLUMN)).toString();
|
||||||
|
QString torrent_url = model->data(model->index(index.row(), URL_COLUMN)).toString();
|
||||||
// Download from url
|
// Download from url
|
||||||
BTSession->downloadFromUrl(url);
|
downloadTorrent(engine_url, torrent_url);
|
||||||
// Set item color to RED
|
// Set item color to RED
|
||||||
all_tab.at(tabWidget->currentIndex())->setRowColor(row, "red");
|
all_tab.at(tabWidget->currentIndex())->setRowColor(row, "red");
|
||||||
}
|
}
|
||||||
@ -267,6 +285,22 @@ void SearchEngine::readSearchOutput(){
|
|||||||
currentSearchTab->getCurrentLabel()->setText(tr("Results")+QString::fromUtf8(" <i>(")+misc::toQString(nb_search_results)+QString::fromUtf8(")</i>:"));
|
currentSearchTab->getCurrentLabel()->setText(tr("Results")+QString::fromUtf8(" <i>(")+misc::toQString(nb_search_results)+QString::fromUtf8(")</i>:"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchEngine::downloadFinished(int exitcode, QProcess::ExitStatus) {
|
||||||
|
QProcess *downloadProcess = (QProcess*)sender();
|
||||||
|
if(exitcode == 0) {
|
||||||
|
QString line = QString::fromUtf8(downloadProcess->readAllStandardOutput()).trimmed();
|
||||||
|
QStringList parts = line.split(' ');
|
||||||
|
if(parts.length() == 2) {
|
||||||
|
QString path = parts[0];
|
||||||
|
QString url = parts[1];
|
||||||
|
BTSession->processDownloadedFile(url, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qDebug("Deleting downloadProcess");
|
||||||
|
downloaders.removeOne(downloadProcess);
|
||||||
|
delete downloadProcess;
|
||||||
|
}
|
||||||
|
|
||||||
// Update nova.py search plugin if necessary
|
// Update nova.py search plugin if necessary
|
||||||
void SearchEngine::updateNova() {
|
void SearchEngine::updateNova() {
|
||||||
qDebug("Updating nova");
|
qDebug("Updating nova");
|
||||||
@ -294,6 +328,14 @@ void SearchEngine::updateNova() {
|
|||||||
// Set permissions
|
// Set permissions
|
||||||
QFile::Permissions perm=QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::ReadGroup;
|
QFile::Permissions perm=QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::ReadGroup;
|
||||||
QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py").setPermissions(perm);
|
QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py").setPermissions(perm);
|
||||||
|
filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2dl.py";
|
||||||
|
if(misc::getPluginVersion(":/search_engine/nova2dl.py") > misc::getPluginVersion(filePath)) {
|
||||||
|
if(QFile::exists(filePath)){
|
||||||
|
QFile::remove(filePath);
|
||||||
|
}
|
||||||
|
QFile::copy(":/search_engine/nova2dl.py", filePath);
|
||||||
|
}
|
||||||
|
QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2dl.py").setPermissions(perm);
|
||||||
filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"novaprinter.py";
|
filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"novaprinter.py";
|
||||||
if(misc::getPluginVersion(":/search_engine/novaprinter.py") > misc::getPluginVersion(filePath)) {
|
if(misc::getPluginVersion(":/search_engine/novaprinter.py") > misc::getPluginVersion(filePath)) {
|
||||||
if(QFile::exists(filePath)){
|
if(QFile::exists(filePath)){
|
||||||
@ -301,7 +343,7 @@ void SearchEngine::updateNova() {
|
|||||||
}
|
}
|
||||||
QFile::copy(":/search_engine/novaprinter.py", filePath);
|
QFile::copy(":/search_engine/novaprinter.py", filePath);
|
||||||
}
|
}
|
||||||
QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"helpers.py").setPermissions(perm);
|
QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"novaprinter.py").setPermissions(perm);
|
||||||
filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"helpers.py";
|
filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"helpers.py";
|
||||||
if(misc::getPluginVersion(":/search_engine/helpers.py") > misc::getPluginVersion(filePath)) {
|
if(misc::getPluginVersion(":/search_engine/helpers.py") > misc::getPluginVersion(filePath)) {
|
||||||
if(QFile::exists(filePath)){
|
if(QFile::exists(filePath)){
|
||||||
@ -309,6 +351,7 @@ void SearchEngine::updateNova() {
|
|||||||
}
|
}
|
||||||
QFile::copy(":/search_engine/helpers.py", filePath);
|
QFile::copy(":/search_engine/helpers.py", filePath);
|
||||||
}
|
}
|
||||||
|
QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"helpers.py").setPermissions(perm);
|
||||||
QString destDir = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator();
|
QString destDir = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator();
|
||||||
QDir shipped_subDir(":/search_engine/engines/");
|
QDir shipped_subDir(":/search_engine/engines/");
|
||||||
QStringList files = shipped_subDir.entryList();
|
QStringList files = shipped_subDir.entryList();
|
||||||
@ -436,8 +479,9 @@ void SearchEngine::on_download_button_clicked(){
|
|||||||
if(index.column() == NAME){
|
if(index.column() == NAME){
|
||||||
// Get Item url
|
// Get Item url
|
||||||
QStandardItemModel *model = all_tab.at(tabWidget->currentIndex())->getCurrentSearchListModel();
|
QStandardItemModel *model = all_tab.at(tabWidget->currentIndex())->getCurrentSearchListModel();
|
||||||
QString url = model->data(model->index(index.row(), URL_COLUMN)).toString();
|
QString torrent_url = model->data(model->index(index.row(), URL_COLUMN)).toString();
|
||||||
BTSession->downloadFromUrl(url);
|
QString engine_url = model->data(model->index(index.row(), ENGINE_URL_COLUMN)).toString();
|
||||||
|
downloadTorrent(engine_url, torrent_url);
|
||||||
all_tab.at(tabWidget->currentIndex())->setRowColor(index.row(), "red");
|
all_tab.at(tabWidget->currentIndex())->setRowColor(index.row(), "red");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QPair>
|
||||||
#include "ui_search.h"
|
#include "ui_search.h"
|
||||||
#include "engineSelectDlg.h"
|
#include "engineSelectDlg.h"
|
||||||
#include "SearchTab.h"
|
#include "SearchTab.h"
|
||||||
@ -42,6 +43,7 @@ class SearchEngine : public QWidget, public Ui::search_engine{
|
|||||||
private:
|
private:
|
||||||
// Search related
|
// Search related
|
||||||
QProcess *searchProcess;
|
QProcess *searchProcess;
|
||||||
|
QList<QProcess*> downloaders;
|
||||||
bool search_stopped;
|
bool search_stopped;
|
||||||
bool no_search_results;
|
bool no_search_results;
|
||||||
QByteArray search_result_line_truncated;
|
QByteArray search_result_line_truncated;
|
||||||
@ -81,6 +83,8 @@ class SearchEngine : public QWidget, public Ui::search_engine{
|
|||||||
void on_clearPatternButton_clicked();
|
void on_clearPatternButton_clicked();
|
||||||
void propagateSectionResized(int index, int oldsize , int newsize);
|
void propagateSectionResized(int index, int oldsize , int newsize);
|
||||||
void saveResultsColumnsWidth();
|
void saveResultsColumnsWidth();
|
||||||
|
void downloadFinished(int exitcode, QProcess::ExitStatus);
|
||||||
|
void downloadTorrent(QString engine_url, QString torrent_url);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#VERSION: 2.1
|
#VERSION: 2.11
|
||||||
#AUTHORS: Christophe Dumez (chris@qbittorrent.org)
|
#AUTHORS: Christophe Dumez (chris@qbittorrent.org)
|
||||||
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
|
|
||||||
from novaprinter import prettyPrinter
|
from novaprinter import prettyPrinter
|
||||||
from helpers import retrieve_url
|
from helpers import retrieve_url, download_file
|
||||||
import sgmllib
|
import sgmllib
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@ -38,7 +38,10 @@ class btjunkie(object):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.results = []
|
self.results = []
|
||||||
self.parser = self.SimpleSGMLParser(self.results, self.url)
|
self.parser = self.SimpleSGMLParser(self.results, self.url)
|
||||||
|
|
||||||
|
def download_torrent(self, info):
|
||||||
|
print download_file(info)
|
||||||
|
|
||||||
class SimpleSGMLParser(sgmllib.SGMLParser):
|
class SimpleSGMLParser(sgmllib.SGMLParser):
|
||||||
def __init__(self, results, url, *args):
|
def __init__(self, results, url, *args):
|
||||||
sgmllib.SGMLParser.__init__(self)
|
sgmllib.SGMLParser.__init__(self)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#VERSION: 1.2
|
#VERSION: 1.21
|
||||||
#AUTHORS: Christophe Dumez (chris@qbittorrent.org)
|
#AUTHORS: Christophe Dumez (chris@qbittorrent.org)
|
||||||
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@ -27,12 +27,15 @@
|
|||||||
|
|
||||||
from novaprinter import prettyPrinter
|
from novaprinter import prettyPrinter
|
||||||
import re
|
import re
|
||||||
from helpers import retrieve_url
|
from helpers import retrieve_url, download_file
|
||||||
|
|
||||||
class isohunt(object):
|
class isohunt(object):
|
||||||
url = 'http://isohunt.com'
|
url = 'http://isohunt.com'
|
||||||
name = 'isoHunt'
|
name = 'isoHunt'
|
||||||
|
|
||||||
|
def download_torrent(self, info):
|
||||||
|
print download_file(info)
|
||||||
|
|
||||||
def search(self, what):
|
def search(self, what):
|
||||||
i = 1
|
i = 1
|
||||||
while True and i<11:
|
while True and i<11:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#VERSION: 1.21
|
#VERSION: 1.22
|
||||||
#AUTHORS: Fabien Devaux (fab@gnux.info)
|
#AUTHORS: Fabien Devaux (fab@gnux.info)
|
||||||
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@ -26,7 +26,7 @@
|
|||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
from novaprinter import prettyPrinter
|
from novaprinter import prettyPrinter
|
||||||
from helpers import retrieve_url
|
from helpers import retrieve_url, download_file
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@ -34,6 +34,9 @@ class mininova(object):
|
|||||||
url = 'http://www.mininova.org'
|
url = 'http://www.mininova.org'
|
||||||
name = 'Mininova'
|
name = 'Mininova'
|
||||||
table_items = 'added cat name size seeds leech'.split()
|
table_items = 'added cat name size seeds leech'.split()
|
||||||
|
|
||||||
|
def download_torrent(self, info):
|
||||||
|
print download_file(info)
|
||||||
|
|
||||||
def search(self, what):
|
def search(self, what):
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#VERSION: 1.1
|
#VERSION: 1.11
|
||||||
#AUTHORS: Fabien Devaux (fab@gnux.info)
|
#AUTHORS: Fabien Devaux (fab@gnux.info)
|
||||||
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
from novaprinter import prettyPrinter
|
from novaprinter import prettyPrinter
|
||||||
import sgmllib
|
import sgmllib
|
||||||
from helpers import retrieve_url
|
from helpers import retrieve_url, download_file
|
||||||
|
|
||||||
class piratebay(object):
|
class piratebay(object):
|
||||||
url = 'http://thepiratebay.org'
|
url = 'http://thepiratebay.org'
|
||||||
@ -36,6 +36,9 @@ class piratebay(object):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.results = []
|
self.results = []
|
||||||
self.parser = self.SimpleSGMLParser(self.results, self.url)
|
self.parser = self.SimpleSGMLParser(self.results, self.url)
|
||||||
|
|
||||||
|
def download_torrent(self, info):
|
||||||
|
print download_file(info)
|
||||||
|
|
||||||
class SimpleSGMLParser(sgmllib.SGMLParser):
|
class SimpleSGMLParser(sgmllib.SGMLParser):
|
||||||
def __init__(self, results, url, *args):
|
def __init__(self, results, url, *args):
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#VERSION: 1.1
|
#VERSION: 1.11
|
||||||
#AUTHORS: Gekko Dam Beer (gekko04@users.sourceforge.net)
|
#AUTHORS: Gekko Dam Beer (gekko04@users.sourceforge.net)
|
||||||
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@ -27,12 +27,15 @@
|
|||||||
|
|
||||||
from novaprinter import prettyPrinter
|
from novaprinter import prettyPrinter
|
||||||
import sgmllib
|
import sgmllib
|
||||||
from helpers import retrieve_url
|
from helpers import retrieve_url, download_file
|
||||||
|
|
||||||
class torrentreactor(object):
|
class torrentreactor(object):
|
||||||
url = 'http://www.torrentreactor.net'
|
url = 'http://www.torrentreactor.net'
|
||||||
name = 'TorrentReactor.Net'
|
name = 'TorrentReactor.Net'
|
||||||
|
|
||||||
|
def download_torrent(self, info):
|
||||||
|
print download_file(info)
|
||||||
|
|
||||||
class SimpleSGMLParser(sgmllib.SGMLParser):
|
class SimpleSGMLParser(sgmllib.SGMLParser):
|
||||||
def __init__(self, results, url, *args):
|
def __init__(self, results, url, *args):
|
||||||
sgmllib.SGMLParser.__init__(self)
|
sgmllib.SGMLParser.__init__(self)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
isohunt: 1.2
|
isohunt: 1.21
|
||||||
torrentreactor: 1.1
|
torrentreactor: 1.11
|
||||||
btjunkie: 2.1
|
btjunkie: 2.11
|
||||||
mininova: 1.21
|
mininova: 1.22
|
||||||
piratebay: 1.1
|
piratebay: 1.11
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
import re, htmlentitydefs
|
import re, htmlentitydefs
|
||||||
import urllib2
|
import urllib2
|
||||||
|
import tempfile
|
||||||
|
import os
|
||||||
|
|
||||||
def htmlentitydecode(s):
|
def htmlentitydecode(s):
|
||||||
# First convert alpha entities (such as é)
|
# First convert alpha entities (such as é)
|
||||||
@ -57,3 +59,17 @@ def retrieve_url(url):
|
|||||||
dat = dat.decode(charset, 'replace')
|
dat = dat.decode(charset, 'replace')
|
||||||
dat = htmlentitydecode(dat)
|
dat = htmlentitydecode(dat)
|
||||||
return dat.encode('utf-8', 'replace')
|
return dat.encode('utf-8', 'replace')
|
||||||
|
|
||||||
|
def download_file(url):
|
||||||
|
""" Download file at url and write it to a file, return the path to the file and the url """
|
||||||
|
file, path = tempfile.mkstemp()
|
||||||
|
file = os.fdopen(file, "wb")
|
||||||
|
# Download url
|
||||||
|
req = urllib2.Request(url)
|
||||||
|
response = urllib2.urlopen(url)
|
||||||
|
dat = response.read()
|
||||||
|
# Write it to a file
|
||||||
|
file.write(dat)
|
||||||
|
file.close()
|
||||||
|
# return file path
|
||||||
|
return path+" "+url
|
||||||
|
@ -75,7 +75,7 @@ class EngineLauncher(threading.Thread):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
raise SystemExit('./nova.py [all|engine1[,engine2]*] <keywords>\navailable engines: %s'%
|
raise SystemExit('./nova2.py [all|engine1[,engine2]*] <keywords>\navailable engines: %s'%
|
||||||
(','.join(supported_engines)))
|
(','.join(supported_engines)))
|
||||||
|
|
||||||
if len(sys.argv) == 2:
|
if len(sys.argv) == 2:
|
||||||
|
60
src/search_engine/nova2dl.py
Executable file
60
src/search_engine/nova2dl.py
Executable file
@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of the author nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software without
|
||||||
|
# specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#VERSION: 1.00
|
||||||
|
|
||||||
|
# Author:
|
||||||
|
# Christophe DUMEZ (chris@qbittorrent.org)
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
|
||||||
|
supported_engines = dict()
|
||||||
|
|
||||||
|
engines = glob.glob(os.path.join(os.path.dirname(__file__), 'engines','*.py'))
|
||||||
|
for engine in engines:
|
||||||
|
e = engine.split(os.sep)[-1][:-3]
|
||||||
|
if len(e.strip()) == 0: continue
|
||||||
|
if e.startswith('_'): continue
|
||||||
|
try:
|
||||||
|
exec "from engines.%s import %s"%(e,e)
|
||||||
|
exec "engine_url = %s.url"%e
|
||||||
|
supported_engines[engine_url] = e
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
raise SystemExit('./nova2dl.py engine_url download_parameter')
|
||||||
|
engine_url = sys.argv[1].strip()
|
||||||
|
download_param = sys.argv[2].strip()
|
||||||
|
if engine_url not in supported_engines.keys():
|
||||||
|
raise SystemExit('./nova2dl.py: this engine_url was not recognized')
|
||||||
|
exec "engine = %s()"%supported_engines[engine_url]
|
||||||
|
engine.download_torrent(download_param)
|
||||||
|
sys.exit(0)
|
Loading…
Reference in New Issue
Block a user