mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-17 14:08:03 -06:00
Compare commits
1 Commits
release-2.
...
release-2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19d4709c94 |
16
Changelog
16
Changelog
@@ -1,19 +1,3 @@
|
||||
* Fri Dec 18 2009 - Christophe Dumez <chris@qbittorrent.org> - v2.0.2
|
||||
- BUGFIX: Fix .qbittorrent folder not being created (critical bug introduced in v2.0.1 that makes qBittorrent unusuable for new users)
|
||||
- BUGFIX: Fix RSS Feed downloader for some feeds
|
||||
- BUGFIX: Do not use home folder as a fallback when the save path is not accessible
|
||||
- BUGFIX: Fix Mininova, ThePirateBay search engine plugins
|
||||
- BUGFIX: Read RSS articles are remembered on restart for feeds with no torrents attached
|
||||
|
||||
* Sun Dec 13 2009 - Christophe Dumez <chris@qbittorrent.org> - v2.0.1
|
||||
- BUGFIX: µTorrent user-agent is now spoofed correctly
|
||||
- BUGFIX: Fix column hiding behavior when queueing system is disabled
|
||||
- BUGFIX: Fix link to plugins.qbittorrent.org in plugins dialog
|
||||
- BUGFIX: ~/qBT_dir is created only when it is actually used
|
||||
- BUGFIX: Fix possible missing slot message (toggleSelectedTorrentsSuperSeeding)
|
||||
- BUGFIX: Fix possible crash in torrent properties (files)
|
||||
- BUGFIX: Added Hex Magnet Links support (Thanks Haypo)
|
||||
|
||||
* Thu Dec 10 2009 - Christophe Dumez <chris@qbittorrent.org> - v2.0.0
|
||||
- FEATURE: Added program option to disable splash screen
|
||||
- FEATURE: Dropped dependency on libcurl and libzzip
|
||||
|
||||
BIN
src/Icons/oxygen/application-x-kgetlist-no.png
Normal file
BIN
src/Icons/oxygen/application-x-kgetlist-no.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 743 B |
BIN
src/Icons/oxygen/application-x-kgetlist.png
Normal file
BIN
src/Icons/oxygen/application-x-kgetlist.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 659 B |
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Categories=Qt;Network;P2P;
|
||||
Comment=V2.0.2
|
||||
Comment=V2.0.0
|
||||
Exec=qbittorrent %f
|
||||
GenericName=Bittorrent client
|
||||
GenericName[bg]=Торент клиент
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 78 KiB |
@@ -303,7 +303,7 @@ void Bittorrent::configureSession() {
|
||||
// * Session settings
|
||||
session_settings sessionSettings;
|
||||
if(Preferences::isUtorrentSpoofingEnabled()) {
|
||||
sessionSettings.user_agent = "uTorrent/1850(17414)";
|
||||
sessionSettings.user_agent = "uTorrent/1850";
|
||||
} else {
|
||||
sessionSettings.user_agent = "qBittorrent "VERSION;
|
||||
}
|
||||
@@ -1671,7 +1671,7 @@ QString Bittorrent::getSavePath(QString hash) {
|
||||
if(!saveDir.mkpath(saveDir.path())) {
|
||||
std::cerr << "Couldn't create the save directory: " << saveDir.path().toLocal8Bit().data() << "\n";
|
||||
// XXX: handle this better
|
||||
//return QDir::homePath();
|
||||
return QDir::homePath();
|
||||
}
|
||||
}
|
||||
return savePath;
|
||||
|
||||
@@ -144,6 +144,7 @@
|
||||
<file>Icons/oxygen/encrypted.png</file>
|
||||
<file>Icons/oxygen/edit_clear.png</file>
|
||||
<file>Icons/oxygen/download.png</file>
|
||||
<file>Icons/oxygen/application-x-kgetlist-no.png</file>
|
||||
<file>Icons/oxygen/gear.png</file>
|
||||
<file>Icons/oxygen/remove.png</file>
|
||||
<file>Icons/oxygen/dialog-warning.png</file>
|
||||
@@ -164,6 +165,7 @@
|
||||
<file>Icons/oxygen/help-about.png</file>
|
||||
<file>Icons/oxygen/list-add.png</file>
|
||||
<file>Icons/oxygen/network-server.png</file>
|
||||
<file>Icons/oxygen/application-x-kgetlist.png</file>
|
||||
<file>Icons/oxygen/folder.png</file>
|
||||
<file>Icons/oxygen/urlseed.png</file>
|
||||
<file>Icons/oxygen/edit-cut.png</file>
|
||||
|
||||
28
src/misc.h
28
src/misc.h
@@ -271,30 +271,14 @@ public:
|
||||
|
||||
static QString magnetUriToHash(QString magnet_uri) {
|
||||
QString hash = "";
|
||||
QRegExp regHex("urn:btih:([0-9A-Za-z]+)");
|
||||
// Hex
|
||||
int pos = regHex.indexIn(magnet_uri);
|
||||
QRegExp reg("urn:btih:([A-Z2-7=]+)");
|
||||
int pos = reg.indexIn(magnet_uri);
|
||||
if(pos > -1) {
|
||||
QString found = regHex.cap(1);
|
||||
if(found.length() == 40) {
|
||||
sha1_hash sha1;
|
||||
sha1.assign(QString(QByteArray::fromHex(regHex.cap(1).toLocal8Bit())).toStdString());
|
||||
qDebug("magnetUriToHash (Hex): hash: %s", misc::toString(sha1).c_str());
|
||||
return misc::toQString(sha1);
|
||||
}
|
||||
sha1_hash sha1;
|
||||
sha1.assign(base32decode(reg.cap(1).toStdString()));
|
||||
hash = misc::toQString(sha1);
|
||||
}
|
||||
// Base 32
|
||||
QRegExp regBase32("urn:btih:([A-Za-z2-7=]+)");
|
||||
pos = regBase32.indexIn(magnet_uri);
|
||||
if(pos > -1) {
|
||||
QString found = regBase32.cap(1);
|
||||
if(found.length() > 20 && (found.length()*5)%40 == 0) {
|
||||
sha1_hash sha1;
|
||||
sha1.assign(base32decode(regBase32.cap(1).toStdString()));
|
||||
hash = misc::toQString(sha1);
|
||||
}
|
||||
}
|
||||
qDebug("magnetUriToHash (base32): hash: %s", hash.toLocal8Bit().data());
|
||||
qDebug("magnetUriToHash: hash: %s", hash.toLocal8Bit().data());
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
@@ -362,12 +362,7 @@ void PropertiesWidget::loadDynamicData() {
|
||||
}
|
||||
if(stackedProperties->currentIndex() == FILES_TAB) {
|
||||
// Files progress
|
||||
if(h.is_valid() && h.has_metadata()) {
|
||||
if(PropListModel->rowCount() == 0) {
|
||||
PropListModel->setupModelData(h.get_torrent_info());
|
||||
// Expand first item if possible
|
||||
filesList->expand(PropListModel->index(0, 0));
|
||||
}
|
||||
if(h.has_metadata()) {
|
||||
std::vector<size_type> fp;
|
||||
h.file_progress(fp);
|
||||
PropListModel->updateFilesPriorities(h.file_priorities());
|
||||
|
||||
49
src/rss.cpp
49
src/rss.cpp
@@ -376,6 +376,7 @@ void RssManager::saveStreamList(){
|
||||
/** RssStream **/
|
||||
|
||||
RssStream::RssStream(RssFolder* parent, RssManager *rssmanager, Bittorrent *BTSession, QString _url): parent(parent), rssmanager(rssmanager), BTSession(BTSession), alias(""), iconPath(":/Icons/rss16.png"), refreshed(false), downloadFailure(false), currently_loading(false) {
|
||||
has_attachments = false;
|
||||
qDebug("RSSStream constructed");
|
||||
QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
|
||||
url = QUrl(_url).toString();
|
||||
@@ -387,6 +388,8 @@ RssStream::RssStream(RssFolder* parent, RssManager *rssmanager, Bittorrent *BTSe
|
||||
RssItem *rss_item = RssItem::fromHash(this, item);
|
||||
if(rss_item->isValid()) {
|
||||
(*this)[rss_item->getTitle()] = rss_item;
|
||||
if(rss_item->has_attachment())
|
||||
has_attachments = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -581,31 +584,29 @@ short RssStream::readDoc(const QDomDocument& doc) {
|
||||
delete item;
|
||||
item = this->value(title);
|
||||
}
|
||||
QString torrent_url;
|
||||
if(item->has_attachment())
|
||||
torrent_url = item->getTorrentUrl();
|
||||
else
|
||||
torrent_url = item->getLink();
|
||||
// Check if the item should be automatically downloaded
|
||||
if(!already_exists || !(*this)[item->getTitle()]->isRead()) {
|
||||
FeedFilter * matching_filter = FeedFilters::getFeedFilters(url).matches(item->getTitle());
|
||||
if(matching_filter != 0) {
|
||||
// Download the torrent
|
||||
BTSession->addConsoleMessage(tr("Automatically downloading %1 torrent from %2 RSS feed...").arg(item->getTitle()).arg(getName()));
|
||||
if(matching_filter->isValid()) {
|
||||
QString save_path = matching_filter->getSavePath();
|
||||
if(save_path.isEmpty())
|
||||
BTSession->downloadUrlAndSkipDialog(torrent_url);
|
||||
else
|
||||
BTSession->downloadUrlAndSkipDialog(torrent_url, save_path);
|
||||
} else {
|
||||
// All torrents are downloaded from this feed
|
||||
BTSession->downloadUrlAndSkipDialog(torrent_url);
|
||||
if(item->has_attachment()) {
|
||||
has_attachments = true;
|
||||
// Check if the item should be automatically downloaded
|
||||
if(!already_exists || !(*this)[item->getTitle()]->isRead()) {
|
||||
FeedFilter * matching_filter = FeedFilters::getFeedFilters(url).matches(item->getTitle());
|
||||
if(matching_filter != 0) {
|
||||
// Download the torrent
|
||||
BTSession->addConsoleMessage(tr("Automatically downloading %1 torrent from %2 RSS feed...").arg(item->getTitle()).arg(getName()));
|
||||
if(matching_filter->isValid()) {
|
||||
QString save_path = matching_filter->getSavePath();
|
||||
if(save_path.isEmpty())
|
||||
BTSession->downloadUrlAndSkipDialog(item->getTorrentUrl());
|
||||
else
|
||||
BTSession->downloadUrlAndSkipDialog(item->getTorrentUrl(), save_path);
|
||||
} else {
|
||||
// All torrents are downloaded from this feed
|
||||
BTSession->downloadUrlAndSkipDialog(item->getTorrentUrl());
|
||||
}
|
||||
// Item was downloaded, consider it as Read
|
||||
(*this)[item->getTitle()]->setRead();
|
||||
// Clean up
|
||||
delete matching_filter;
|
||||
}
|
||||
// Item was downloaded, consider it as Read
|
||||
(*this)[item->getTitle()]->setRead();
|
||||
// Clean up
|
||||
delete matching_filter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ public:
|
||||
|
||||
RssItem(RssStream* parent, QString _title, QString _torrent_url, QString _news_link, QString _description, QDateTime _date, QString _author, bool _read):
|
||||
parent(parent), title(_title), torrent_url(_torrent_url), news_link(_news_link), description(_description), date(_date), author(_author), read(_read){
|
||||
if(!title.isEmpty()) {
|
||||
if(!title.isEmpty() && !torrent_url.isEmpty()) {
|
||||
is_valid = true;
|
||||
} else {
|
||||
std::cerr << "ERROR: an invalid RSS item was saved" << std::endl;
|
||||
@@ -394,6 +394,7 @@ private:
|
||||
bool refreshed;
|
||||
bool downloadFailure;
|
||||
bool currently_loading;
|
||||
bool has_attachments;
|
||||
|
||||
public slots:
|
||||
void processDownloadedFile(QString file_path);
|
||||
@@ -429,6 +430,7 @@ public:
|
||||
QList<RssItem*> getNewsList() const;
|
||||
QList<RssItem*> getUnreadNewsList() const;
|
||||
QString getIconUrl();
|
||||
bool hasAttachments() const { return has_attachments; }
|
||||
|
||||
private:
|
||||
short readDoc(const QDomDocument& doc);
|
||||
|
||||
@@ -71,8 +71,10 @@ void RSSImp::displayRSSListMenu(const QPoint& pos){
|
||||
myRSSListMenu.addSeparator();
|
||||
myRSSListMenu.addAction(actionCopy_feed_URL);
|
||||
if(selectedItems.size() == 1) {
|
||||
myRSSListMenu.addSeparator();
|
||||
myRSSListMenu.addAction(actionRSS_feed_downloader);
|
||||
if(((RssStream*)listStreams->getRSSItem(selectedItems.first()))->hasAttachments()) {
|
||||
myRSSListMenu.addSeparator();
|
||||
myRSSListMenu.addAction(actionRSS_feed_downloader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@@ -291,7 +293,9 @@ void RSSImp::downloadTorrent() {
|
||||
if(article->has_attachment()) {
|
||||
BTSession->downloadFromUrl(article->getTorrentUrl());
|
||||
} else {
|
||||
BTSession->downloadFromUrl(article->getLink());
|
||||
QString link = article->getLink();
|
||||
if(!link.isEmpty())
|
||||
QDesktopServices::openUrl(QUrl(link));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -440,6 +444,10 @@ void RSSImp::refreshNewsList(QTreeWidgetItem* item) {
|
||||
foreach(RssItem* article, news){
|
||||
QTreeWidgetItem* it = new QTreeWidgetItem(listNews);
|
||||
it->setText(NEWS_TITLE_COL, article->getTitle());
|
||||
if(article->has_attachment())
|
||||
it->setData(NEWS_TITLE_COL, Qt::DecorationRole, QVariant(QIcon(":/Icons/oxygen/application-x-kgetlist.png")));
|
||||
else
|
||||
it->setData(NEWS_TITLE_COL, Qt::DecorationRole, QVariant(QIcon(":/Icons/oxygen/application-x-kgetlist-no.png")));
|
||||
it->setText(NEWS_URL_COL, article->getParent()->getUrl());
|
||||
if(article->isRead()){
|
||||
it->setData(NEWS_TITLE_COL, Qt::ForegroundRole, QVariant(QColor("grey")));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#VERSION: 1.40
|
||||
#AUTHORS: Christophe Dumez (chris@qbittorrent.org)
|
||||
#VERSION: 1.32
|
||||
#AUTHORS: Fabien Devaux (fab@gnux.info)
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
@@ -27,85 +27,88 @@
|
||||
|
||||
from novaprinter import prettyPrinter
|
||||
from helpers import retrieve_url, download_file
|
||||
import sgmllib
|
||||
from xml.dom import minidom
|
||||
import re
|
||||
|
||||
class mininova(object):
|
||||
# Mandatory properties
|
||||
url = 'http://www.mininova.org'
|
||||
name = 'Mininova'
|
||||
supported_categories = {'all': '0', 'movies': '4', 'tv': '8', 'music': '5', 'games': '3', 'anime': '1', 'software': '7', 'pictures': '6', 'books': '2'}
|
||||
# Mandatory properties
|
||||
url = 'http://www.mininova.org'
|
||||
name = 'Mininova'
|
||||
supported_categories = {'all': '0', 'movies': '4', 'tv': '8', 'music': '5', 'games': '3', 'anime': '1', 'software': '7', 'pictures': '6', 'books': '2'}
|
||||
|
||||
def download_torrent(self, info):
|
||||
print download_file(info)
|
||||
|
||||
def __init__(self):
|
||||
self.results = []
|
||||
self.parser = self.SimpleSGMLParser(self.results, self.url)
|
||||
def search(self, what, cat='all'):
|
||||
|
||||
def download_torrent(self, info):
|
||||
print download_file(info)
|
||||
def get_link(lnk):
|
||||
lnks = lnk.getElementsByTagName('a')
|
||||
i = 0
|
||||
try:
|
||||
while not lnks.item(i).attributes.get('href').value.startswith('/get'):
|
||||
i += 1
|
||||
except:
|
||||
return None
|
||||
return (self.url+lnks.item(i).attributes.get('href').value).strip()
|
||||
|
||||
def get_name(lnk):
|
||||
lnks = lnk.getElementsByTagName('a')
|
||||
i = 0
|
||||
try:
|
||||
while not lnks.item(i).attributes.get('href').value.startswith('/tor'):
|
||||
i += 1
|
||||
except:
|
||||
return None
|
||||
name = ""
|
||||
for node in lnks[i].childNodes:
|
||||
if node.hasChildNodes():
|
||||
name += node.firstChild.toxml()
|
||||
else:
|
||||
name += node.toxml()
|
||||
return re.sub('<[a-zA-Z\/][^>]*>', '', name)
|
||||
|
||||
class SimpleSGMLParser(sgmllib.SGMLParser):
|
||||
def __init__(self, results, url, *args):
|
||||
sgmllib.SGMLParser.__init__(self)
|
||||
self.url = url
|
||||
self.td_counter = None
|
||||
self.current_item = None
|
||||
self.results = results
|
||||
|
||||
def start_a(self, attr):
|
||||
params = dict(attr)
|
||||
#print params
|
||||
if params.has_key('href') and params['href'].startswith("/get/"):
|
||||
self.current_item = {}
|
||||
self.td_counter = 0
|
||||
self.current_item['link']=self.url+params['href'].strip()
|
||||
|
||||
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
|
||||
elif self.td_counter == 1:
|
||||
if not self.current_item.has_key('size'):
|
||||
self.current_item['size'] = ''
|
||||
self.current_item['size']+= data.strip()
|
||||
elif self.td_counter == 2:
|
||||
if not self.current_item.has_key('seeds'):
|
||||
self.current_item['seeds'] = ''
|
||||
self.current_item['seeds']+= data.strip()
|
||||
elif self.td_counter == 3:
|
||||
if not self.current_item.has_key('leech'):
|
||||
self.current_item['leech'] = ''
|
||||
self.current_item['leech']+= data.strip()
|
||||
|
||||
def start_td(self,attr):
|
||||
if isinstance(self.td_counter,int):
|
||||
self.td_counter += 1
|
||||
if self.td_counter > 4:
|
||||
self.td_counter = None
|
||||
# Display item
|
||||
if self.current_item:
|
||||
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)
|
||||
self.results.append('a')
|
||||
|
||||
def search(self, what, cat='all'):
|
||||
ret = []
|
||||
i = 1
|
||||
while True and i<11:
|
||||
results = []
|
||||
parser = self.SimpleSGMLParser(results, self.url)
|
||||
dat = retrieve_url(self.url+'/search/%s/%s/seeds/%d'%(what, self.supported_categories[cat], i))
|
||||
results_re = re.compile('(?s)<h1>Search results for.*')
|
||||
for match in results_re.finditer(dat):
|
||||
res_tab = match.group(0)
|
||||
parser.feed(res_tab)
|
||||
parser.close()
|
||||
break
|
||||
if len(results) <= 0:
|
||||
break
|
||||
i += 1
|
||||
|
||||
def get_text(txt):
|
||||
if txt.nodeType == txt.TEXT_NODE:
|
||||
return txt.toxml()
|
||||
else:
|
||||
return ''.join([ get_text(n) for n in txt.childNodes])
|
||||
|
||||
if cat == 'all':
|
||||
self.table_items = 'added cat name size seeds leech'.split()
|
||||
else:
|
||||
self.table_items = 'added name size seeds leech'.split()
|
||||
page = 1
|
||||
while True and page<11:
|
||||
res = 0
|
||||
dat = retrieve_url(self.url+'/search/%s/%s/seeds/%d'%(what, self.supported_categories[cat], page))
|
||||
dat = re.sub("<a href=\"http://www.boardreader.com/index.php.*\"", "<a href=\"plop\"", dat)
|
||||
dat = re.sub("<=", "<=", dat)
|
||||
dat = re.sub("&\s", "& ", dat)
|
||||
dat = re.sub("&(?!amp)", "&", dat)
|
||||
x = minidom.parseString(dat)
|
||||
table = x.getElementsByTagName('table').item(0)
|
||||
if not table: return
|
||||
for tr in table.getElementsByTagName('tr'):
|
||||
tds = tr.getElementsByTagName('td')
|
||||
if tds:
|
||||
i = 0
|
||||
vals = {}
|
||||
for td in tds:
|
||||
if self.table_items[i] == 'name':
|
||||
vals['link'] = get_link(td)
|
||||
vals['name'] = get_name(td)
|
||||
else:
|
||||
vals[self.table_items[i]] = get_text(td).strip()
|
||||
i += 1
|
||||
vals['engine_url'] = self.url
|
||||
if not vals['seeds'].isdigit():
|
||||
vals['seeds'] = 0
|
||||
if not vals['leech'].isdigit():
|
||||
vals['leech'] = 0
|
||||
if vals['link'] is None:
|
||||
continue
|
||||
prettyPrinter(vals)
|
||||
res = res + 1
|
||||
if res == 0:
|
||||
break
|
||||
page = page +1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#VERSION: 1.30
|
||||
#VERSION: 1.22
|
||||
#AUTHORS: Fabien Devaux (fab@gnux.info)
|
||||
#CONTRIBUTORS: Christophe Dumez (chris@qbittorrent.org)
|
||||
|
||||
@@ -50,35 +50,32 @@ class piratebay(object):
|
||||
self.results = results
|
||||
self.url = url
|
||||
self.code = 0
|
||||
self.in_name = None
|
||||
|
||||
def start_a(self, attr):
|
||||
params = dict(attr)
|
||||
if params['href'].startswith('/torrent/'):
|
||||
if params['href'].startswith('/browse'):
|
||||
self.current_item = {}
|
||||
self.td_counter = 0
|
||||
elif params['href'].startswith('/tor'):
|
||||
self.code = params['href'].split('/')[2]
|
||||
self.in_name = True
|
||||
elif params['href'].startswith('http://torrents.thepiratebay.org/%s'%self.code):
|
||||
self.current_item['link']=params['href'].strip()
|
||||
self.in_name = False
|
||||
self.td_counter = self.td_counter+1
|
||||
|
||||
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 self.td_counter == 1:
|
||||
if not self.current_item.has_key('name'):
|
||||
self.current_item['name'] = ''
|
||||
self.current_item['name']+= data.strip()
|
||||
if self.td_counter == 5:
|
||||
if not self.current_item.has_key('size'):
|
||||
self.current_item['size'] = ''
|
||||
self.current_item['size']+= data.strip()
|
||||
elif self.td_counter == 6:
|
||||
if not self.current_item.has_key('seeds'):
|
||||
self.current_item['seeds'] = ''
|
||||
self.current_item['seeds']+= data.strip()
|
||||
elif self.td_counter == 2:
|
||||
elif self.td_counter == 7:
|
||||
if not self.current_item.has_key('leech'):
|
||||
self.current_item['leech'] = ''
|
||||
self.current_item['leech']+= data.strip()
|
||||
@@ -86,7 +83,7 @@ class piratebay(object):
|
||||
def start_td(self,attr):
|
||||
if isinstance(self.td_counter,int):
|
||||
self.td_counter += 1
|
||||
if self.td_counter > 3:
|
||||
if self.td_counter > 7:
|
||||
self.td_counter = None
|
||||
# Display item
|
||||
if self.current_item:
|
||||
@@ -104,8 +101,7 @@ class piratebay(object):
|
||||
while True and i<11:
|
||||
results = []
|
||||
parser = self.SimpleSGMLParser(results, self.url)
|
||||
dat = retrieve_url(self.url+'/search/%s/%u/7/%s' % (what, i, self.supported_categories[cat]))
|
||||
print self.url+'/search/%s/%u/7/%s' % (what, i, self.supported_categories[cat])
|
||||
dat = retrieve_url(self.url+'/search/%s/%u/99/%s' % (what, i, self.supported_categories[cat]))
|
||||
parser.feed(dat)
|
||||
parser.close()
|
||||
if len(results) <= 0:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
isohunt: 1.30
|
||||
torrentreactor: 1.20
|
||||
btjunkie: 2.21
|
||||
mininova: 1.40
|
||||
piratebay: 1.30
|
||||
mininova: 1.32
|
||||
piratebay: 1.22
|
||||
|
||||
@@ -22,15 +22,16 @@
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#VERSION: 1.2
|
||||
#VERSION: 1.1
|
||||
|
||||
# Author:
|
||||
# Christophe DUMEZ (chris@qbittorrent.org)
|
||||
|
||||
import re, htmlentitydefs
|
||||
import urllib2
|
||||
import tempfile
|
||||
import os
|
||||
import StringIO, gzip, urllib2
|
||||
import StringIO, gzip, httplib
|
||||
|
||||
def htmlentitydecode(s):
|
||||
# First convert alpha entities (such as é)
|
||||
@@ -63,14 +64,12 @@ def retrieve_url(url):
|
||||
dat = htmlentitydecode(dat)
|
||||
return dat.encode('utf-8', 'replace')
|
||||
|
||||
def download_file(url, referer=None):
|
||||
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, "w")
|
||||
# Download url
|
||||
req = urllib2.Request(url)
|
||||
if referer is not None:
|
||||
req.add_header('referer', referer)
|
||||
response = urllib2.urlopen(req)
|
||||
dat = response.read()
|
||||
# Check if data is gzip encoded
|
||||
|
||||
@@ -12,10 +12,10 @@ CONFIG += qt \
|
||||
thread
|
||||
|
||||
# Update this VERSION for each release
|
||||
DEFINES += VERSION=\\\"v2.0.2\\\"
|
||||
DEFINES += VERSION=\\\"v2.0.0\\\"
|
||||
DEFINES += VERSION_MAJOR=2
|
||||
DEFINES += VERSION_MINOR=0
|
||||
DEFINES += VERSION_BUGFIX=2
|
||||
DEFINES += VERSION_BUGFIX=0
|
||||
|
||||
# !mac:QMAKE_LFLAGS += -Wl,--as-needed
|
||||
contains(DEBUG_MODE, 1) {
|
||||
|
||||
@@ -762,10 +762,7 @@ void TransferListWidget::displayDLHoSMenu(const QPoint&){
|
||||
hideshowColumn.setTitle(tr("Column visibility"));
|
||||
QList<QAction*> actions;
|
||||
for(int i=0; i < TR_HASH; ++i) {
|
||||
if(!BTSession->isQueueingEnabled() && i == TR_PRIORITY) {
|
||||
actions.append(0);
|
||||
continue;
|
||||
}
|
||||
if(!BTSession->isQueueingEnabled() && i == TR_PRIORITY) continue;
|
||||
QIcon icon;
|
||||
if(isColumnHidden(i))
|
||||
icon = QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png"));
|
||||
@@ -774,12 +771,9 @@ void TransferListWidget::displayDLHoSMenu(const QPoint&){
|
||||
actions.append(hideshowColumn.addAction(icon, listModel->headerData(i, Qt::Horizontal).toString()));
|
||||
}
|
||||
// Call menu
|
||||
QAction *act = 0;
|
||||
act = hideshowColumn.exec(QCursor::pos());
|
||||
if(act) {
|
||||
int col = actions.indexOf(act);
|
||||
setColumnHidden(col, !isColumnHidden(col));
|
||||
}
|
||||
QAction *act = hideshowColumn.exec(QCursor::pos());
|
||||
int col = actions.indexOf(act);
|
||||
setColumnHidden(col, !isColumnHidden(col));
|
||||
}
|
||||
|
||||
#ifdef LIBTORRENT_0_15
|
||||
@@ -846,10 +840,8 @@ void TransferListWidget::displayListMenu(const QPoint&) {
|
||||
connect(&actionForce_recheck, SIGNAL(triggered()), this, SLOT(recheckSelectedTorrents()));
|
||||
QAction actionCopy_magnet_link(QIcon(QString::fromUtf8(":/Icons/magnet.png")), tr("Copy magnet link"), 0);
|
||||
connect(&actionCopy_magnet_link, SIGNAL(triggered()), this, SLOT(copySelectedMagnetURIs()));
|
||||
#ifdef LIBTORRENT_0_15
|
||||
QAction actionSuper_seeding_mode(tr("Super seeding mode"), 0);
|
||||
connect(&actionSuper_seeding_mode, SIGNAL(triggered()), this, SLOT(toggleSelectedTorrentsSuperSeeding()));
|
||||
#endif
|
||||
QAction actionSequential_download(tr("Download in sequential order"), 0);
|
||||
connect(&actionSequential_download, SIGNAL(triggered()), this, SLOT(toggleSelectedTorrentsSequentialDownload()));
|
||||
QAction actionFirstLastPiece_prio(tr("Download first and last piece first"), 0);
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<ui version="4.0" >
|
||||
<class>engineSelect</class>
|
||||
<widget class="QDialog" name="engineSelect">
|
||||
<property name="geometry">
|
||||
<widget class="QDialog" name="engineSelect" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
@@ -10,100 +9,94 @@
|
||||
<height>254</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<property name="acceptDrops" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<property name="windowTitle" >
|
||||
<string>Search plugins</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<widget class="QLabel" name="lbl_engines">
|
||||
<property name="font">
|
||||
<widget class="QLabel" name="lbl_engines" >
|
||||
<property name="font" >
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
<underline>true</underline>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<property name="text" >
|
||||
<string>Installed search engines:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="pluginsTree">
|
||||
<property name="contextMenuPolicy">
|
||||
<widget class="QTreeWidget" name="pluginsTree" >
|
||||
<property name="contextMenuPolicy" >
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<property name="selectionMode" >
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<property name="uniformRowHeights" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<property name="itemsExpandable" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<property name="text" >
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<property name="text" >
|
||||
<string>Url</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<property name="text" >
|
||||
<string>Enabled</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="getNewEngine_lbl">
|
||||
<property name="font">
|
||||
<widget class="QLabel" name="getNewEngine_lbl" >
|
||||
<property name="font" >
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::AutoText</enum>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
<property name="text" >
|
||||
<string>You can get new search engine plugins here: <a href="http:plugins.qbittorrent.org">http://plugins.qbittorrent.org</a></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QPushButton" name="installButton">
|
||||
<property name="text">
|
||||
<widget class="QPushButton" name="installButton" >
|
||||
<property name="text" >
|
||||
<string>Install a new one</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="updateButton">
|
||||
<property name="text">
|
||||
<widget class="QPushButton" name="updateButton" >
|
||||
<property name="text" >
|
||||
<string>Check for updates</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="text">
|
||||
<widget class="QPushButton" name="closeButton" >
|
||||
<property name="text" >
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
@@ -111,18 +104,18 @@
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionEnable">
|
||||
<property name="text">
|
||||
<action name="actionEnable" >
|
||||
<property name="text" >
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDisable">
|
||||
<property name="text">
|
||||
<action name="actionDisable" >
|
||||
<property name="text" >
|
||||
<string>Disable</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUninstall">
|
||||
<property name="text">
|
||||
<action name="actionUninstall" >
|
||||
<property name="text" >
|
||||
<string>Uninstall</string>
|
||||
</property>
|
||||
</action>
|
||||
|
||||
Reference in New Issue
Block a user