You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-10-21 13:52:16 +02:00
Compare commits
24 Commits
release-3.
...
release-3.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
99a596ab8d | ||
![]() |
9a74b27a85 | ||
![]() |
b12f250642 | ||
![]() |
2dede108e7 | ||
![]() |
7cf1e7b8ca | ||
![]() |
e1934e8c16 | ||
![]() |
14b958216b | ||
![]() |
1120c14890 | ||
![]() |
88075d9226 | ||
![]() |
36464fcd59 | ||
![]() |
f7f1c81238 | ||
![]() |
b8da4bcf74 | ||
![]() |
bf7a6aceb0 | ||
![]() |
3ef2da898b | ||
![]() |
d0cd939143 | ||
![]() |
e36d76d457 | ||
![]() |
daa4314093 | ||
![]() |
f707d6c9d5 | ||
![]() |
83b6619b16 | ||
![]() |
8b322648c8 | ||
![]() |
d159117965 | ||
![]() |
1fd2dce0bd | ||
![]() |
f97238e1c9 | ||
![]() |
67355810ae |
22
Changelog
22
Changelog
@@ -1,3 +1,25 @@
|
||||
* Wed Oct 22 2014 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v3.1.11
|
||||
- FEATURE: Allow relative torrent paths when qBittorrent is already running (pmzqla)
|
||||
- FEATURE: Make Windows icons suitable for high dpi screens (pmzqla)
|
||||
- FEATURE: Increase maximum size of system icons (pmzqla)
|
||||
- BUGFIX: Fix crash in the "Content" widget when user would right click in it without a torrent selected (Ivan Sorokin)
|
||||
- BUGFIX: Don't show multiple unlock UI dialogs. Closes #2040. (sledgehammer999)
|
||||
- SEARCH: Fix bug where python would falsely be detected and nothing worked (paolo-sz)
|
||||
- SEARCH: Fix TorrentReactor search plugin (Bruno Barbieri)
|
||||
- SEARCH: Fix search engine encoding issues with python3 on Windows (Bruno Barbieri)
|
||||
- SEARCH: Pirate bay search engine update (DoumanAsh)
|
||||
- SEARCH: Internal improvements in the python code (Bruno Barbieri)
|
||||
- WINDOWS: Fix magnet link association. Closes #1952. (sledgehammer999)
|
||||
- WINDOWS and OSX: Fix again the program updater. The url was changed by sourceforge.net. Closes #1954. (sledgehammer999)
|
||||
- OSX: Fix compilation (sledgehammer999)
|
||||
- WEBUI: Set correct HTTP Content-Type in case of forbidden access. (pmzqla)
|
||||
- COSMETIC: Remove unneeded tooltip (pmzqla)
|
||||
- COSMETIC: Don't stretch the last section in the transfer list (pmzqla)
|
||||
- COSMETIC: Set minimum width of the left panel in the preferences (pmzqla)
|
||||
- OTHER: Optimize sorting of rows. This should have less CPU impact when many torrents are present. (Ivan Sorokin)
|
||||
- OTHER: Use the correct character encoding for exceptions coming from libtorrent. (sledgehammer999)
|
||||
- OTHER: Use boost:bind() as the docs show. Allows compilation with older gcc versions. (sledgehammer999)
|
||||
|
||||
* Sun Sep 21 2014 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v3.1.10
|
||||
- FEATURE: Allow disabling of OS cache. This will prevent RAM increases on Windows when seeding many files. Closes #1699. (sledgehammer999)
|
||||
- FEATURE: Add 'Completed' column. Closes #1241. (sledgehammer999)
|
||||
|
@@ -197,7 +197,7 @@ bool AddNewTorrentDialog::loadTorrent(const QString& torrent_path, const QString
|
||||
m_torrentInfo = new torrent_info(m_filePath.toUtf8().data());
|
||||
m_hash = misc::toQString(m_torrentInfo->info_hash());
|
||||
} catch(const std::exception& e) {
|
||||
MessageBoxRaised::critical(0, tr("Invalid torrent"), tr("Failed to load the torrent: %1").arg(e.what()));
|
||||
MessageBoxRaised::critical(0, tr("Invalid torrent"), tr("Failed to load the torrent: %1").arg(misc::toQStringU(e.what())));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -81,7 +81,7 @@ QIcon IconProvider::generateDifferentSizes(const QIcon& icon)
|
||||
{
|
||||
QIcon new_icon;
|
||||
QList<QSize> required_sizes;
|
||||
required_sizes << QSize(16, 16) << QSize(24, 24);
|
||||
required_sizes << QSize(16, 16) << QSize(24, 24) << QSize(32, 32);
|
||||
QList<QIcon::Mode> modes;
|
||||
modes << QIcon::Normal << QIcon::Active << QIcon::Selected << QIcon::Disabled;
|
||||
foreach (const QSize& size, required_sizes) {
|
||||
|
@@ -45,7 +45,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.1.10</string>
|
||||
<string>3.1.11</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>qBit</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
@@ -228,9 +228,14 @@ int main(int argc, char *argv[]) {
|
||||
QStringList torrentCmdLine = app.arguments();
|
||||
//Pass program parameters if any
|
||||
QString message;
|
||||
QFileInfo torrentPath;
|
||||
for (int a = 1; a < torrentCmdLine.size(); ++a) {
|
||||
if (torrentCmdLine[a].startsWith("--")) continue;
|
||||
message += torrentCmdLine[a];
|
||||
torrentPath.setFile(torrentCmdLine[a]);
|
||||
if (torrentPath.exists())
|
||||
message += torrentPath.absoluteFilePath();
|
||||
else
|
||||
message += torrentCmdLine[a];
|
||||
if (a < argc-1)
|
||||
message += "|";
|
||||
}
|
||||
|
10
src/mainwindow.cpp
Normal file → Executable file
10
src/mainwindow.cpp
Normal file → Executable file
@@ -101,7 +101,7 @@ using namespace libtorrent;
|
||||
*****************************************************/
|
||||
|
||||
// Constructor
|
||||
MainWindow::MainWindow(QWidget *parent, const QStringList& torrentCmdLine) : QMainWindow(parent), m_posInitialized(false), force_exit(false)
|
||||
MainWindow::MainWindow(QWidget *parent, const QStringList& torrentCmdLine) : QMainWindow(parent), m_posInitialized(false), force_exit(false), unlockDlgShowing(false)
|
||||
#ifdef Q_OS_WIN
|
||||
, has_python(false)
|
||||
#endif
|
||||
@@ -697,8 +697,14 @@ void MainWindow::setTabText(int index, QString text) const {
|
||||
}
|
||||
|
||||
bool MainWindow::unlockUI() {
|
||||
if (unlockDlgShowing)
|
||||
return false;
|
||||
else
|
||||
unlockDlgShowing = true;
|
||||
|
||||
bool ok = false;
|
||||
QString clear_password = AutoExpandableDialog::getText(this, tr("UI lock password"), tr("Please type the UI lock password:"), QLineEdit::Password, "", &ok);
|
||||
unlockDlgShowing = false;
|
||||
if (!ok) return false;
|
||||
Preferences pref;
|
||||
QString real_pass_md5 = pref.getUILockPasswordMD5();
|
||||
@@ -1343,7 +1349,7 @@ void MainWindow::on_actionSearch_engine_triggered() {
|
||||
bool res = false;
|
||||
|
||||
// Check if python is already in PATH
|
||||
if (misc::pythonVersion())
|
||||
if (misc::pythonVersion() > 0)
|
||||
res = true;
|
||||
else
|
||||
res = addPythonPathToEnv();
|
||||
|
@@ -183,6 +183,7 @@ private:
|
||||
bool displaySpeedInTitle;
|
||||
bool force_exit;
|
||||
bool ui_locked;
|
||||
bool unlockDlgShowing;
|
||||
LineEdit *search_filter;
|
||||
// Keyboard shortcuts
|
||||
QShortcut *switchSearchShortcut;
|
||||
|
34
src/misc.cpp
34
src/misc.cpp
@@ -136,8 +136,8 @@ void misc::shutdownComputer(shutDownAction action) {
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_WS_MAC
|
||||
AEEventID EventToSend;
|
||||
if (action != SHUTDOWN_COMPUTER)
|
||||
if (sleep)
|
||||
EventToSend = kAESleep;
|
||||
else
|
||||
EventToSend = kAEShutDown;
|
||||
@@ -556,15 +556,29 @@ QString misc::toQString(time_t t)
|
||||
bool misc::naturalSort(QString left, QString right, bool &result) { // uses lessThan comparison
|
||||
// Return value indicates if functions was successful
|
||||
// result argument will contain actual comparison result if function was successful
|
||||
int posL = 0;
|
||||
int posR = 0;
|
||||
do {
|
||||
int posL = left.indexOf(QRegExp("[0-9]"));
|
||||
int posR = right.indexOf(QRegExp("[0-9]"));
|
||||
if (posL == -1 || posR == -1)
|
||||
break; // No data
|
||||
else if (posL != posR)
|
||||
break; // Digit positions mismatch
|
||||
else if (left.left(posL) != right.left(posR))
|
||||
break; // Strings' subsets before digit do not match
|
||||
for (;;) {
|
||||
if (posL == left.size() || posR == right.size())
|
||||
return false; // No data
|
||||
|
||||
QChar leftChar = left.at(posL);
|
||||
QChar rightChar = right.at(posR);
|
||||
bool leftCharIsDigit = leftChar.isDigit();
|
||||
bool rightCharIsDigit = rightChar.isDigit();
|
||||
if (leftCharIsDigit != rightCharIsDigit)
|
||||
return false; // Digit positions mismatch
|
||||
|
||||
if (leftCharIsDigit)
|
||||
break; // Both are digit, break this loop and compare numbers
|
||||
|
||||
if (leftChar != rightChar)
|
||||
return false; // Strings' subsets before digit do not match
|
||||
|
||||
++posL;
|
||||
++posR;
|
||||
}
|
||||
|
||||
QString temp;
|
||||
while (posL < left.size()) {
|
||||
@@ -593,8 +607,6 @@ bool misc::naturalSort(QString left, QString right, bool &result) { // uses less
|
||||
|
||||
// Strings + digits do match and we haven't hit string end
|
||||
// Do another round
|
||||
left.remove(0, posL);
|
||||
right.remove(0, posR);
|
||||
|
||||
} while (true);
|
||||
|
||||
|
@@ -32,6 +32,12 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>116</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
@@ -78,9 +84,6 @@
|
||||
<property name="text">
|
||||
<string>Behavior</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Behavior</string>
|
||||
</property>
|
||||
<property name="textAlignment">
|
||||
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
|
||||
</property>
|
||||
|
@@ -310,8 +310,8 @@ void options_imp::loadWindowState() {
|
||||
sizes << sizes_str.first().toInt();
|
||||
sizes << sizes_str.last().toInt();
|
||||
} else {
|
||||
sizes << 130;
|
||||
sizes << hsplitter->width()-130;
|
||||
sizes << 116;
|
||||
sizes << hsplitter->width()-116;
|
||||
}
|
||||
hsplitter->setSizes(sizes);
|
||||
}
|
||||
|
@@ -1277,7 +1277,7 @@ public:
|
||||
return false;
|
||||
QString assoc_exe = exe_reg.cap(1);
|
||||
qDebug("exe: %s", qPrintable(assoc_exe));
|
||||
if (assoc_exe.compare(qApp->applicationFilePath(), Qt::CaseInsensitive) != 0)
|
||||
if (assoc_exe.compare(qApp->applicationFilePath().replace("/", "\\"), Qt::CaseInsensitive) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -1303,8 +1303,8 @@ public:
|
||||
|
||||
// Magnet association
|
||||
if (set) {
|
||||
const QString command_str = "\""+qApp->applicationFilePath()+"\" \"%1\"";
|
||||
const QString icon_str = "\""+qApp->applicationFilePath()+"\",1";
|
||||
const QString command_str = "\""+qApp->applicationFilePath().replace("/", "\\")+"\" \"%1\"";
|
||||
const QString icon_str = "\""+qApp->applicationFilePath().replace("/", "\\")+"\",1";
|
||||
|
||||
settings.setValue("magnet/Default", "URL:Magnet link");
|
||||
settings.setValue("magnet/Content Type", "application/x-magnet");
|
||||
|
@@ -40,10 +40,10 @@
|
||||
#include "preferences.h"
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
const QUrl RSS_URL("http://sourceforge.net/api/file/index/project-id/163414/mtime/desc/rss?path=/qbittorrent-mac");
|
||||
const QUrl RSS_URL("http://sourceforge.net/projects/qbittorrent/rss?path=/qbittorrent-mac");
|
||||
const QString FILE_EXT = "DMG";
|
||||
#else
|
||||
const QUrl RSS_URL("http://sourceforge.net/api/file/index/project-id/163414/mtime/desc/rss?path=/qbittorrent-win32");
|
||||
const QUrl RSS_URL("http://sourceforge.net/projects/qbittorrent/rss?path=/qbittorrent-win32");
|
||||
const QString FILE_EXT = "EXE";
|
||||
#endif
|
||||
|
||||
|
@@ -384,7 +384,7 @@ void PropertiesWidget::loadDynamicData() {
|
||||
}
|
||||
}
|
||||
} catch(const invalid_handle& e) {
|
||||
qWarning() << "Caught exception in PropertiesWidget::loadDynamicData(): " << e.what();
|
||||
qWarning() << "Caught exception in PropertiesWidget::loadDynamicData(): " << misc::toQStringU(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,8 +453,10 @@ void PropertiesWidget::openFolder(const QModelIndex &index, bool containing_fold
|
||||
void PropertiesWidget::displayFilesListMenu(const QPoint&) {
|
||||
if (!h.is_valid())
|
||||
return;
|
||||
QMenu myFilesLlistMenu;
|
||||
QModelIndexList selectedRows = filesList->selectionModel()->selectedRows(0);
|
||||
if (selectedRows.empty())
|
||||
return;
|
||||
QMenu myFilesLlistMenu;
|
||||
QAction *actOpen = 0;
|
||||
QAction *actOpenContainingFolder = 0;
|
||||
QAction *actRename = 0;
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 167 KiB |
Binary file not shown.
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 172 KiB |
@@ -1110,7 +1110,7 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr
|
||||
} catch(std::exception& e) {
|
||||
if (!from_url.isNull()) {
|
||||
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(from_url), QString::fromUtf8("red"));
|
||||
addConsoleMessage(misc::toQString(e.what()), "red");
|
||||
addConsoleMessage(misc::toQStringU(e.what()), "red");
|
||||
//emit invalidTorrent(from_url);
|
||||
fsutils::forceRemove(path);
|
||||
}else{
|
||||
|
@@ -2,7 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
#VERSION: 1.22
|
||||
#VERSION: 1.23
|
||||
#AUTHORS: BTDigg team (research@btdigg.org)
|
||||
#
|
||||
# GNU GENERAL PUBLIC LICENSE
|
||||
@@ -66,7 +66,7 @@ class btdigg(object):
|
||||
pass
|
||||
|
||||
def search(self, what, cat='all'):
|
||||
req = what.replace('+', ' ')
|
||||
req = urllib.unquote(what)
|
||||
u = urllib2.urlopen('https://api.btdigg.org/api/public-8e9a50f8335b964f/s01?%s' % (urllib.urlencode(dict(q = req)),))
|
||||
|
||||
try:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#VERSION: 1.53
|
||||
#VERSION: 2.00
|
||||
#AUTHORS: Fabien Devaux (fab@gnux.info)
|
||||
#CONTRIBUTORS: Christophe Dumez (chris@qbittorrent.org)
|
||||
# Arthur (custparasite@gmx.se)
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
@@ -27,94 +28,112 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from novaprinter import prettyPrinter
|
||||
import sgmllib
|
||||
from helpers import retrieve_url, download_file
|
||||
from HTMLParser import HTMLParser
|
||||
from helpers import download_file
|
||||
import urllib2
|
||||
|
||||
PREVIOUS_IDS = set()
|
||||
|
||||
class piratebay(object):
|
||||
url = 'https://thepiratebay.se'
|
||||
name = 'The Pirate Bay'
|
||||
supported_categories = {'all': '0', 'movies': '200', 'music': '100', 'games': '400', 'software': '300'}
|
||||
url = 'http://thepiratebay.se'
|
||||
name = 'The Pirate Bay'
|
||||
supported_categories = {'all': '0', 'music': '100', 'movies': '200', 'games': '400', 'software': '300'}
|
||||
|
||||
def __init__(self):
|
||||
self.results = []
|
||||
self.parser = self.SimpleSGMLParser(self.results, self.url)
|
||||
def download_torrent(self, info):
|
||||
print(download_file(info))
|
||||
|
||||
def download_torrent(self, info):
|
||||
print download_file(info)
|
||||
class MyHtmlParseWithBlackJack(HTMLParser):
|
||||
def __init__(self, results, url):
|
||||
HTMLParser.__init__(self)
|
||||
self.url = url
|
||||
self.results = results
|
||||
self.current_item = None
|
||||
self.size_found = False
|
||||
self.unit_found = False
|
||||
self.seed_found = False
|
||||
self.skip_td = False
|
||||
self.leech_found = False
|
||||
self.dispatcher = {'a' : self.handle_tag_a_ref,
|
||||
'font' : self.handle_tag_font_size,
|
||||
'td' : self.handle_tag_td_sl }
|
||||
|
||||
class SimpleSGMLParser(sgmllib.SGMLParser):
|
||||
def __init__(self, results, url, *args):
|
||||
sgmllib.SGMLParser.__init__(self)
|
||||
self.td_counter = None
|
||||
self.current_item = None
|
||||
self.results = results
|
||||
self.url = url
|
||||
self.code = 0
|
||||
self.in_name = None
|
||||
def handle_tag_a_ref(self, attrs):
|
||||
params = dict(attrs)
|
||||
#1
|
||||
if params['href'].startswith('/torrent/'):
|
||||
get_id = params['href'].split('/')[2]
|
||||
if not get_id in PREVIOUS_IDS:
|
||||
self.current_item = {}
|
||||
self.current_item['desc_link'] = self.url + params['href'].strip()
|
||||
self.current_item['name'] = params['title'][12:].strip()
|
||||
self.current_item['id'] = get_id
|
||||
#2
|
||||
elif (not self.current_item is None) and (params['href'].startswith('magnet:')):
|
||||
self.current_item['link'] = params['href'].strip()
|
||||
|
||||
def start_a(self, attr):
|
||||
params = dict(attr)
|
||||
if params['href'].startswith('/torrent/'):
|
||||
self.current_item = {}
|
||||
self.td_counter = 0
|
||||
self.current_item['desc_link'] = self.url + params['href'].strip()
|
||||
self.in_name = True
|
||||
self.current_item['id'] = params['href'].split('/')[2]
|
||||
elif params['href'].startswith('magnet:'):
|
||||
self.current_item['link']=params['href'].strip()
|
||||
self.in_name = False
|
||||
def handle_tag_font_size(self, attrs):
|
||||
if not self.current_item is None:
|
||||
params = dict(attrs)
|
||||
#3
|
||||
if params['class'] == "detDesc":
|
||||
self.size_found = True
|
||||
|
||||
def handle_data(self, data):
|
||||
if self.td_counter == 0:
|
||||
if self.in_name:
|
||||
if not self.current_item.has_key('name'):
|
||||
self.current_item['name'] = ''
|
||||
self.current_item['name']+= data.strip()
|
||||
else:
|
||||
#Parse size
|
||||
if 'Size' in data:
|
||||
self.current_item['size'] = data[data.index("Size")+5:]
|
||||
self.current_item['size'] = self.current_item['size'][:self.current_item['size'].index(',')]
|
||||
elif self.td_counter == 1:
|
||||
if not self.current_item.has_key('seeds'):
|
||||
self.current_item['seeds'] = ''
|
||||
self.current_item['seeds']+= data.strip()
|
||||
elif self.td_counter == 2:
|
||||
if not self.current_item.has_key('leech'):
|
||||
self.current_item['leech'] = ''
|
||||
self.current_item['leech']+= data.strip()
|
||||
def handle_tag_td_sl(self, attrs):
|
||||
if not self.current_item is None:
|
||||
params = dict(attrs)
|
||||
if not self.current_item is None:
|
||||
if self.seed_found:
|
||||
#5
|
||||
self.current_item['leech'] = ''
|
||||
self.leech_found = True
|
||||
self.seed_found = False
|
||||
else:
|
||||
#4
|
||||
self.current_item['seeds'] = ''
|
||||
self.seed_found = True
|
||||
|
||||
def start_td(self,attr):
|
||||
if isinstance(self.td_counter,int):
|
||||
self.td_counter += 1
|
||||
if self.td_counter > 3:
|
||||
self.td_counter = None
|
||||
# Display item
|
||||
if self.current_item:
|
||||
if self.current_item['id'] in PREVIOUS_IDS:
|
||||
self.results = []
|
||||
self.reset()
|
||||
return
|
||||
self.current_item['engine_url'] = self.url
|
||||
if not self.current_item['seeds'].isdigit():
|
||||
self.current_item['seeds'] = 0
|
||||
if not self.current_item['leech'].isdigit():
|
||||
self.current_item['leech'] = 0
|
||||
prettyPrinter(self.current_item)
|
||||
PREVIOUS_IDS.add(self.current_item['id'])
|
||||
self.results.append('a')
|
||||
def search(self, what, cat='all'):
|
||||
ret = []
|
||||
i = 0
|
||||
order = 'se'
|
||||
while True and i<11:
|
||||
results = []
|
||||
parser = self.SimpleSGMLParser(results, self.url)
|
||||
dat = retrieve_url(self.url+'/search/%s/%d/7/%s' % (what, i, self.supported_categories[cat]))
|
||||
parser.feed(dat)
|
||||
parser.close()
|
||||
if len(results) <= 0:
|
||||
break
|
||||
i += 1
|
||||
def handle_starttag(self, tag, attrs):
|
||||
if tag in self.dispatcher:
|
||||
self.dispatcher[tag](attrs)
|
||||
|
||||
def handle_data(self, data):
|
||||
if not self.current_item is None:
|
||||
if self.size_found:
|
||||
#with utf-8 you're going to have something like that: ['Uploaded', '10-02'], ['15:31,', 'Size', '240.34'], ['MiB,', 'ULed', 'by']
|
||||
temp = data.split()
|
||||
if 'Size' in temp:
|
||||
sizeIn = temp.index('Size')
|
||||
self.current_item['size'] = temp[sizeIn + 1]
|
||||
self.size_found = False
|
||||
self.unit_found = True
|
||||
elif self.unit_found:
|
||||
temp = data.split()
|
||||
self.current_item['size'] = ' '.join((self.current_item['size'], temp[0]))
|
||||
self.unit_found = False
|
||||
elif self.seed_found:
|
||||
self.current_item['seeds'] += data.rstrip()
|
||||
elif self.leech_found:
|
||||
self.current_item['leech'] += data.rstrip()
|
||||
self.current_item['engine_url'] = self.url
|
||||
prettyPrinter(self.current_item)
|
||||
PREVIOUS_IDS.add(self.current_item['id'])
|
||||
self.results.append('a')
|
||||
self.current_item = None
|
||||
self.size_found = False
|
||||
self.unit_found = False
|
||||
self.seed_found = False
|
||||
self.leech_found = False
|
||||
|
||||
def search(self, what, cat='all'):
|
||||
ret = []
|
||||
i = 0
|
||||
while i < 11:
|
||||
results = []
|
||||
parser = self.MyHtmlParseWithBlackJack(results, self.url)
|
||||
query = '%s/search/%s/%d/99/%s' % (self.url, what, i, self.supported_categories[cat])
|
||||
dat = urllib2.urlopen(query)
|
||||
parser.feed(dat.read().decode('utf-8'))
|
||||
parser.close()
|
||||
if len(results) <= 0:
|
||||
break
|
||||
i += 1
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#VERSION: 1.32
|
||||
#VERSION: 1.33
|
||||
#AUTHORS: Gekko Dam Beer (gekko04@users.sourceforge.net)
|
||||
#CONTRIBUTORS: Christophe Dumez (chris@qbittorrent.org)
|
||||
# Bruno Barbieri (brunorex@gmail.com)
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
@@ -27,8 +28,11 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from novaprinter import prettyPrinter
|
||||
import sgmllib
|
||||
from helpers import retrieve_url, download_file
|
||||
from urllib2 import HTTPError
|
||||
from HTMLParser import HTMLParser
|
||||
import urllib
|
||||
import re
|
||||
|
||||
class torrentreactor(object):
|
||||
url = 'http://www.torrentreactor.net'
|
||||
@@ -37,30 +41,32 @@ class torrentreactor(object):
|
||||
|
||||
def download_torrent(self, info):
|
||||
print download_file(info)
|
||||
|
||||
class SimpleSGMLParser(sgmllib.SGMLParser):
|
||||
|
||||
class SimpleHTMLParser(HTMLParser):
|
||||
def __init__(self, results, url, *args):
|
||||
sgmllib.SGMLParser.__init__(self)
|
||||
HTMLParser.__init__(self)
|
||||
self.td_counter = None
|
||||
self.current_item = None
|
||||
self.results = results
|
||||
self.id = None
|
||||
self.url = url
|
||||
self.dispatcher = { 'a' : self.start_a, 'td' : self.start_td }
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
if tag in self.dispatcher:
|
||||
self.dispatcher[tag](attrs)
|
||||
|
||||
def start_a(self, attr):
|
||||
params = dict(attr)
|
||||
if 'torrentreactor.net/download.php' in params['href']:
|
||||
if re.match("/torrents/\d+.*", params['href']):
|
||||
self.current_item = {}
|
||||
self.current_item['desc_link'] = self.url+params['href'].strip()
|
||||
elif 'torrentreactor.net/download.php' in params['href']:
|
||||
self.td_counter = 0
|
||||
self.current_item['link'] = params['href'].strip()
|
||||
elif params['href'].startswith('/torrents/'):
|
||||
self.current_item['desc_link'] = 'http://www.torrentreactor.net'+params['href'].strip()
|
||||
self.current_item['name'] = urllib.unquote_plus(params['href'].split('&')[1].split('name=')[1])
|
||||
|
||||
def handle_data(self, data):
|
||||
if self.td_counter == 0:
|
||||
if not self.current_item.has_key('name'):
|
||||
self.current_item['name'] = ''
|
||||
self.current_item['name']+= data.strip()
|
||||
if self.td_counter == 1:
|
||||
if not self.current_item.has_key('size'):
|
||||
self.current_item['size'] = ''
|
||||
@@ -92,14 +98,20 @@ class torrentreactor(object):
|
||||
|
||||
def __init__(self):
|
||||
self.results = []
|
||||
self.parser = self.SimpleSGMLParser(self.results, self.url)
|
||||
self.parser = self.SimpleHTMLParser(self.results, self.url)
|
||||
|
||||
def search(self, what, cat='all'):
|
||||
i = 0
|
||||
dat = ''
|
||||
while True and i<11:
|
||||
results = []
|
||||
parser = self.SimpleSGMLParser(results, self.url)
|
||||
dat = retrieve_url(self.url+'/ts.php?search=&words=%s&cid=%s&sid=&type=1&orderby=a.seeds&asc=0&skip=%s'%(what, self.supported_categories[cat], (i*35)))
|
||||
parser = self.SimpleHTMLParser(results, self.url)
|
||||
|
||||
try:
|
||||
dat = retrieve_url(self.url+'/torrent-search/%s/%s?sort=seeders.desc&type=all&period=none&categories=%s'%(what, (i*35), self.supported_categories[cat]))
|
||||
except HTTPError:
|
||||
break
|
||||
|
||||
parser.feed(dat)
|
||||
parser.close()
|
||||
if len(results) <= 0:
|
||||
|
@@ -1,8 +1,8 @@
|
||||
torrentreactor: 1.32
|
||||
torrentreactor: 1.33
|
||||
mininova: 1.50
|
||||
piratebay: 1.53
|
||||
piratebay: 2.00
|
||||
vertor: 1.3
|
||||
extratorrent: 1.2
|
||||
kickasstorrents: 1.24
|
||||
btdigg: 1.22
|
||||
btdigg: 1.23
|
||||
legittorrents: 1.02
|
||||
|
@@ -26,7 +26,7 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
#VERSION: 1.31
|
||||
#VERSION: 1.32
|
||||
|
||||
# Author:
|
||||
# Fabien Devaux <fab AT gnux DOT info>
|
||||
@@ -41,6 +41,7 @@ import sys
|
||||
import threading
|
||||
import os
|
||||
import glob
|
||||
import urllib
|
||||
|
||||
import fix_encoding
|
||||
|
||||
@@ -138,7 +139,7 @@ if __name__ == '__main__':
|
||||
if cat not in CATEGORIES:
|
||||
raise SystemExit('Invalid category!')
|
||||
|
||||
what = '+'.join(sys.argv[3:])
|
||||
what = urllib.quote(' '.join(sys.argv[3:]))
|
||||
|
||||
threads = []
|
||||
for engine in engines_list:
|
||||
|
@@ -2,7 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
#VERSION: 1.21
|
||||
#VERSION: 1.23
|
||||
#AUTHORS: BTDigg team (research@btdigg.org)
|
||||
#
|
||||
# GNU GENERAL PUBLIC LICENSE
|
||||
@@ -36,7 +36,7 @@ class btdigg(object):
|
||||
pass
|
||||
|
||||
def search(self, what, cat='all'):
|
||||
req = urllib.parse.unquote(what).replace('+', ' ')
|
||||
req = urllib.parse.unquote(what)
|
||||
u = urllib.request.urlopen('https://api.btdigg.org/api/public-8e9a50f8335b964f/s01?%s' % (urllib.parse.urlencode(dict(q = req)),))
|
||||
|
||||
try:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#VERSION: 1.53
|
||||
#VERSION: 2.00
|
||||
#AUTHORS: Fabien Devaux (fab@gnux.info)
|
||||
#CONTRIBUTORS: Christophe Dumez (chris@qbittorrent.org)
|
||||
# Arthur (custparasite@gmx.se)
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
@@ -27,94 +28,112 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from novaprinter import prettyPrinter
|
||||
import sgmllib3
|
||||
from helpers import retrieve_url, download_file
|
||||
from html.parser import HTMLParser
|
||||
from helpers import download_file
|
||||
import urllib.request
|
||||
|
||||
PREVIOUS_IDS = set()
|
||||
|
||||
class piratebay(object):
|
||||
url = 'https://thepiratebay.se'
|
||||
name = 'The Pirate Bay'
|
||||
supported_categories = {'all': '0', 'movies': '200', 'music': '100', 'games': '400', 'software': '300'}
|
||||
url = 'http://thepiratebay.se'
|
||||
name = 'The Pirate Bay'
|
||||
supported_categories = {'all': '0', 'music': '100', 'movies': '200', 'games': '400', 'software': '300'}
|
||||
|
||||
def __init__(self):
|
||||
self.results = []
|
||||
self.parser = self.SimpleSGMLParser(self.results, self.url)
|
||||
def download_torrent(self, info):
|
||||
print(download_file(info))
|
||||
|
||||
def download_torrent(self, info):
|
||||
print(download_file(info))
|
||||
class MyHtmlParseWithBlackJack(HTMLParser):
|
||||
def __init__(self, results, url):
|
||||
super().__init__()
|
||||
self.url = url
|
||||
self.results = results
|
||||
self.current_item = None
|
||||
self.size_found = False
|
||||
self.unit_found = False
|
||||
self.seed_found = False
|
||||
self.skip_td = False
|
||||
self.leech_found = False
|
||||
self.dispatcher = {'a' : self.handle_tag_a_ref,
|
||||
'font' : self.handle_tag_font_size,
|
||||
'td' : self.handle_tag_td_sl }
|
||||
|
||||
class SimpleSGMLParser(sgmllib3.SGMLParser):
|
||||
def __init__(self, results, url, *args):
|
||||
sgmllib3.SGMLParser.__init__(self)
|
||||
self.td_counter = None
|
||||
self.current_item = None
|
||||
self.results = results
|
||||
self.url = url
|
||||
self.code = 0
|
||||
self.in_name = None
|
||||
def handle_tag_a_ref(self, attrs):
|
||||
params = dict(attrs)
|
||||
#1
|
||||
if params['href'].startswith('/torrent/'):
|
||||
get_id = params['href'].split('/')[2]
|
||||
if not get_id in PREVIOUS_IDS:
|
||||
self.current_item = {}
|
||||
self.current_item['desc_link'] = self.url + params['href'].strip()
|
||||
self.current_item['name'] = params['title'][12:].strip()
|
||||
self.current_item['id'] = get_id
|
||||
#2
|
||||
elif (not self.current_item is None) and (params['href'].startswith('magnet:')):
|
||||
self.current_item['link'] = params['href'].strip()
|
||||
|
||||
def start_a(self, attr):
|
||||
params = dict(attr)
|
||||
if params['href'].startswith('/torrent/'):
|
||||
self.current_item = {}
|
||||
self.td_counter = 0
|
||||
self.current_item['desc_link'] = self.url + params['href'].strip()
|
||||
self.in_name = True
|
||||
self.current_item['id'] = params['href'].split('/')[2]
|
||||
elif params['href'].startswith('magnet:'):
|
||||
self.current_item['link']=params['href'].strip()
|
||||
self.in_name = False
|
||||
def handle_tag_font_size(self, attrs):
|
||||
if not self.current_item is None:
|
||||
params = dict(attrs)
|
||||
#3
|
||||
if params['class'] == "detDesc":
|
||||
self.size_found = True
|
||||
|
||||
def handle_data(self, data):
|
||||
if self.td_counter == 0:
|
||||
if self.in_name:
|
||||
if 'name' not in self.current_item:
|
||||
self.current_item['name'] = ''
|
||||
self.current_item['name']+= data.strip()
|
||||
else:
|
||||
#Parse size
|
||||
if 'Size' in data:
|
||||
self.current_item['size'] = data[data.index("Size")+5:]
|
||||
self.current_item['size'] = self.current_item['size'][:self.current_item['size'].index(',')]
|
||||
elif self.td_counter == 1:
|
||||
if 'seeds' not in self.current_item:
|
||||
self.current_item['seeds'] = ''
|
||||
self.current_item['seeds']+= data.strip()
|
||||
elif self.td_counter == 2:
|
||||
if 'leech' not in self.current_item:
|
||||
self.current_item['leech'] = ''
|
||||
self.current_item['leech']+= data.strip()
|
||||
def handle_tag_td_sl(self, attrs):
|
||||
if not self.current_item is None:
|
||||
params = dict(attrs)
|
||||
if not self.current_item is None:
|
||||
if self.seed_found:
|
||||
#5
|
||||
self.current_item['leech'] = ''
|
||||
self.leech_found = True
|
||||
self.seed_found = False
|
||||
else:
|
||||
#4
|
||||
self.current_item['seeds'] = ''
|
||||
self.seed_found = True
|
||||
|
||||
def start_td(self,attr):
|
||||
if isinstance(self.td_counter,int):
|
||||
self.td_counter += 1
|
||||
if self.td_counter > 3:
|
||||
self.td_counter = None
|
||||
# Display item
|
||||
if self.current_item:
|
||||
if self.current_item['id'] in PREVIOUS_IDS:
|
||||
self.results = []
|
||||
self.reset()
|
||||
return
|
||||
self.current_item['engine_url'] = self.url
|
||||
if not self.current_item['seeds'].isdigit():
|
||||
self.current_item['seeds'] = 0
|
||||
if not self.current_item['leech'].isdigit():
|
||||
self.current_item['leech'] = 0
|
||||
prettyPrinter(self.current_item)
|
||||
PREVIOUS_IDS.add(self.current_item['id'])
|
||||
self.results.append('a')
|
||||
def search(self, what, cat='all'):
|
||||
ret = []
|
||||
i = 0
|
||||
order = 'se'
|
||||
while True and i<11:
|
||||
results = []
|
||||
parser = self.SimpleSGMLParser(results, self.url)
|
||||
dat = retrieve_url(self.url+'/search/%s/%d/7/%s' % (what, i, self.supported_categories[cat]))
|
||||
parser.feed(dat)
|
||||
parser.close()
|
||||
if len(results) <= 0:
|
||||
break
|
||||
i += 1
|
||||
def handle_starttag(self, tag, attrs):
|
||||
if tag in self.dispatcher:
|
||||
self.dispatcher[tag](attrs)
|
||||
|
||||
def handle_data(self, data):
|
||||
if not self.current_item is None:
|
||||
if self.size_found:
|
||||
#with utf-8 you're going to have something like that: ['Uploaded', '10-02'], ['15:31,', 'Size', '240.34'], ['MiB,', 'ULed', 'by']
|
||||
temp = data.split()
|
||||
if 'Size' in temp:
|
||||
sizeIn = temp.index('Size')
|
||||
self.current_item['size'] = temp[sizeIn + 1]
|
||||
self.size_found = False
|
||||
self.unit_found = True
|
||||
elif self.unit_found:
|
||||
temp = data.split()
|
||||
self.current_item['size'] = ' '.join((self.current_item['size'], temp[0]))
|
||||
self.unit_found = False
|
||||
elif self.seed_found:
|
||||
self.current_item['seeds'] += data.rstrip()
|
||||
elif self.leech_found:
|
||||
self.current_item['leech'] += data.rstrip()
|
||||
self.current_item['engine_url'] = self.url
|
||||
prettyPrinter(self.current_item)
|
||||
PREVIOUS_IDS.add(self.current_item['id'])
|
||||
self.results.append('a')
|
||||
self.current_item = None
|
||||
self.size_found = False
|
||||
self.unit_found = False
|
||||
self.seed_found = False
|
||||
self.leech_found = False
|
||||
|
||||
def search(self, what, cat='all'):
|
||||
ret = []
|
||||
i = 0
|
||||
while i < 11:
|
||||
results = []
|
||||
parser = self.MyHtmlParseWithBlackJack(results, self.url)
|
||||
query = '%s/search/%s/%d/99/%s' % (self.url, what, i, self.supported_categories[cat])
|
||||
dat = urllib.request.urlopen(query)
|
||||
parser.feed(dat.read().decode('utf-8'))
|
||||
parser.close()
|
||||
if len(results) <= 0:
|
||||
break
|
||||
i += 1
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#VERSION: 1.32
|
||||
#VERSION: 1.33
|
||||
#AUTHORS: Gekko Dam Beer (gekko04@users.sourceforge.net)
|
||||
#CONTRIBUTORS: Christophe Dumez (chris@qbittorrent.org)
|
||||
# Bruno Barbieri (brunorex@gmail.com)
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
@@ -27,8 +28,10 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from novaprinter import prettyPrinter
|
||||
import sgmllib3
|
||||
from helpers import retrieve_url, download_file
|
||||
from urllib import error, parse
|
||||
from html.parser import HTMLParser
|
||||
import re
|
||||
|
||||
class torrentreactor(object):
|
||||
url = 'http://www.torrentreactor.net'
|
||||
@@ -37,30 +40,32 @@ class torrentreactor(object):
|
||||
|
||||
def download_torrent(self, info):
|
||||
print(download_file(info))
|
||||
|
||||
class SimpleSGMLParser(sgmllib3.SGMLParser):
|
||||
|
||||
class SimpleHTMLParser(HTMLParser):
|
||||
def __init__(self, results, url, *args):
|
||||
sgmllib3.SGMLParser.__init__(self)
|
||||
HTMLParser.__init__(self)
|
||||
self.td_counter = None
|
||||
self.current_item = None
|
||||
self.results = results
|
||||
self.id = None
|
||||
self.url = url
|
||||
self.dispatcher = { 'a' : self.start_a, 'td' : self.start_td }
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
if tag in self.dispatcher:
|
||||
self.dispatcher[tag](attrs)
|
||||
|
||||
def start_a(self, attr):
|
||||
params = dict(attr)
|
||||
if 'torrentreactor.net/download.php' in params['href']:
|
||||
if re.match("/torrents/\d+.*", params['href']):
|
||||
self.current_item = {}
|
||||
self.current_item['desc_link'] = self.url+params['href'].strip()
|
||||
elif 'torrentreactor.net/download.php' in params['href']:
|
||||
self.td_counter = 0
|
||||
self.current_item['link'] = params['href'].strip()
|
||||
elif params['href'].startswith('/torrents/'):
|
||||
self.current_item['desc_link'] = 'http://www.torrentreactor.net'+params['href'].strip()
|
||||
self.current_item['name'] = parse.unquote_plus(params['href'].split('&')[1].split('name=')[1])
|
||||
|
||||
def handle_data(self, data):
|
||||
if self.td_counter == 0:
|
||||
if 'name' not in self.current_item:
|
||||
self.current_item['name'] = ''
|
||||
self.current_item['name']+= data.strip()
|
||||
if self.td_counter == 1:
|
||||
if 'size' not in self.current_item:
|
||||
self.current_item['size'] = ''
|
||||
@@ -92,14 +97,20 @@ class torrentreactor(object):
|
||||
|
||||
def __init__(self):
|
||||
self.results = []
|
||||
self.parser = self.SimpleSGMLParser(self.results, self.url)
|
||||
self.parser = self.SimpleHTMLParser(self.results, self.url)
|
||||
|
||||
def search(self, what, cat='all'):
|
||||
i = 0
|
||||
dat = ''
|
||||
while True and i<11:
|
||||
results = []
|
||||
parser = self.SimpleSGMLParser(results, self.url)
|
||||
dat = retrieve_url(self.url+'/ts.php?search=&words=%s&cid=%s&sid=&type=1&orderby=a.seeds&asc=0&skip=%s'%(what, self.supported_categories[cat], (i*35)))
|
||||
parser = self.SimpleHTMLParser(results, self.url)
|
||||
|
||||
try:
|
||||
dat = retrieve_url(self.url+'/torrent-search/%s/%s?sort=seeders.desc&type=all&period=none&categories=%s'%(what, (i*35), self.supported_categories[cat]))
|
||||
except error.HTTPError:
|
||||
break
|
||||
|
||||
parser.feed(dat)
|
||||
parser.close()
|
||||
if len(results) <= 0:
|
||||
|
@@ -1,8 +1,8 @@
|
||||
torrentreactor: 1.32
|
||||
torrentreactor: 1.33
|
||||
mininova: 1.50
|
||||
piratebay: 1.53
|
||||
piratebay: 2.00
|
||||
vertor: 1.3
|
||||
extratorrent: 1.2
|
||||
kickasstorrents: 1.24
|
||||
btdigg: 1.21
|
||||
btdigg: 1.23
|
||||
legittorrents: 1.02
|
||||
|
@@ -26,7 +26,7 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
#VERSION: 1.23
|
||||
#VERSION: 1.24
|
||||
|
||||
# Author:
|
||||
# Fabien Devaux <fab AT gnux DOT info>
|
||||
@@ -134,7 +134,7 @@ if __name__ == '__main__':
|
||||
if cat not in CATEGORIES:
|
||||
raise SystemExit('Invalid category!')
|
||||
|
||||
what = urllib.parse.quote('+'.join(sys.argv[3:]))
|
||||
what = urllib.parse.quote(' '.join(sys.argv[3:]))
|
||||
|
||||
threads = []
|
||||
for engine in engines_list:
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#VERSION: 1.43
|
||||
#VERSION: 1.44
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
@@ -24,22 +24,18 @@
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import sys
|
||||
#import codecs
|
||||
|
||||
# Force UTF-8 printing
|
||||
#sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
|
||||
|
||||
def prettyPrinter(dictionary):
|
||||
# Convert everything to unicode for safe printing
|
||||
#for key,value in list(dictionary.items()):
|
||||
#if isinstance(dictionary[key], str):
|
||||
# dictionary[key] = str(dictionary[key], 'utf-8')
|
||||
outtext = ''
|
||||
dictionary['size'] = anySizeToBytes(dictionary['size'])
|
||||
if 'desc_link' in dictionary:
|
||||
print("%s|%s|%s|%s|%s|%s|%s"%(dictionary['link'],dictionary['name'].replace('|',' '),dictionary['size'],dictionary['seeds'],dictionary['leech'],dictionary['engine_url'],dictionary['desc_link']))
|
||||
outtext = '%s|%s|%s|%s|%s|%s|%s'%(dictionary['link'],dictionary['name'].replace('|',' '),dictionary['size'],dictionary['seeds'],dictionary['leech'],dictionary['engine_url'],dictionary['desc_link'])
|
||||
else:
|
||||
print("%s|%s|%s|%s|%s|%s"%(dictionary['link'],dictionary['name'].replace('|',' '),dictionary['size'],dictionary['seeds'],dictionary['leech'],dictionary['engine_url']))
|
||||
outtext = '%s|%s|%s|%s|%s|%s'%(dictionary['link'],dictionary['name'].replace('|',' '),dictionary['size'],dictionary['seeds'],dictionary['leech'],dictionary['engine_url'])
|
||||
|
||||
# fd 1 is stdout
|
||||
with open(1, 'w', encoding='utf-8', closefd=False) as utf8stdout:
|
||||
print(outtext, file=utf8stdout)
|
||||
|
||||
def anySizeToBytes(size_string):
|
||||
"""
|
||||
|
@@ -42,6 +42,7 @@
|
||||
|
||||
#include "torrentcreatorthread.h"
|
||||
#include "fs_utils.h"
|
||||
#include "misc.h"
|
||||
|
||||
#if LIBTORRENT_VERSION_NUM < 1600
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
@@ -130,7 +131,7 @@ void TorrentCreatorThread::run() {
|
||||
if (abort) return;
|
||||
// calculate the hash for all pieces
|
||||
const QString parent_path = fsutils::branchPath(input_path) + QDir::separator();
|
||||
set_piece_hashes(t, parent_path.toUtf8().constData(), boost::bind<void>(&sendProgressUpdateSignal, _1, t.num_pieces(), this));
|
||||
set_piece_hashes(t, parent_path.toUtf8().constData(), boost::bind(sendProgressUpdateSignal, _1, t.num_pieces(), this));
|
||||
// Set qBittorrent as creator and add user comment to
|
||||
// torrent_info structure
|
||||
t.set_creator(creator_str.toUtf8().constData());
|
||||
@@ -156,6 +157,6 @@ void TorrentCreatorThread::run() {
|
||||
emit updateProgress(100);
|
||||
emit creationSuccess(save_path, parent_path);
|
||||
} catch (std::exception& e) {
|
||||
emit creationFailure(QString::fromLocal8Bit(e.what()));
|
||||
emit creationFailure(misc::toQStringU(e.what()));
|
||||
}
|
||||
}
|
||||
|
@@ -112,6 +112,7 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *main_window,
|
||||
#if defined(Q_WS_MAC)
|
||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
#endif
|
||||
header()->setStretchLastSection(false);
|
||||
|
||||
// Default hidden columns
|
||||
if (!column_loaded) {
|
||||
|
@@ -257,7 +257,7 @@ QByteArray btjson::getTrackersForTorrent(const QString& hash)
|
||||
tracker_list.append(tracker_dict);
|
||||
}
|
||||
} catch(const std::exception& e) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << e.what();
|
||||
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what());
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ QByteArray btjson::getPropertiesForTorrent(const QString& hash)
|
||||
const qreal ratio = QBtSession::instance()->getRealRatio(h.hash());
|
||||
data[KEY_PROP_RATIO] = ratio > 100. ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 1, false);
|
||||
} catch(const std::exception& e) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << e.what();
|
||||
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what());
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ QByteArray btjson::getFilesForTorrent(const QString& hash)
|
||||
file_list.append(file_dict);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << e.what();
|
||||
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what());
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
|
@@ -193,6 +193,7 @@ void HttpConnection::respond() {
|
||||
if (nb_fail >= MAX_AUTH_FAILED_ATTEMPTS) {
|
||||
m_generator.setStatusLine(403, "Forbidden");
|
||||
m_generator.setMessage(tr("Your IP address has been banned after too many failed authentication attempts."));
|
||||
m_generator.setContentType("text/plain; charset=utf-8");
|
||||
m_generator.setContentEncoding(m_parser.acceptsEncoding());
|
||||
write();
|
||||
return;
|
||||
|
@@ -19,7 +19,7 @@ XPStyle on
|
||||
!define CSIDL_APPDATA '0x1A' ;Application Data path
|
||||
!define CSIDL_LOCALAPPDATA '0x1C' ;Local Application Data path
|
||||
|
||||
!define PROG_VERSION "3.1.10"
|
||||
!define PROG_VERSION "3.1.11"
|
||||
!define MUI_FINISHPAGE_RUN
|
||||
!define MUI_FINISHPAGE_RUN_FUNCTION PageFinishRun
|
||||
!define MUI_FINISHPAGE_RUN_TEXT $(launch_qbt)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user