You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-10-09 18:32:15 +02:00
Compare commits
20 Commits
release-3.
...
release-2.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
42574242ef | ||
![]() |
d5c174a6f8 | ||
![]() |
173999e504 | ||
![]() |
1ed928bc39 | ||
![]() |
b85d51ba79 | ||
![]() |
779b53722b | ||
![]() |
76780c4c46 | ||
![]() |
da74f24a71 | ||
![]() |
01c56865db | ||
![]() |
b541c9fa4c | ||
![]() |
aac0fbcbe4 | ||
![]() |
b315551edd | ||
![]() |
58a885cb87 | ||
![]() |
d19282285c | ||
![]() |
e0d8ca39a5 | ||
![]() |
ec3169c9b0 | ||
![]() |
7bfd7e9cda | ||
![]() |
459bb8c51d | ||
![]() |
9159a9f25d | ||
![]() |
8ea8f8a9f7 |
16
Changelog
16
Changelog
@@ -1,3 +1,19 @@
|
||||
* 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
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 743 B |
Binary file not shown.
Before Width: | Height: | Size: 659 B |
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Categories=Qt;Network;P2P;
|
||||
Comment=V2.0.0
|
||||
Comment=V2.0.2
|
||||
Exec=qbittorrent %f
|
||||
GenericName=Bittorrent client
|
||||
GenericName[bg]=Торент клиент
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 79 KiB |
@@ -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,7 +144,6 @@
|
||||
<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>
|
||||
@@ -165,7 +164,6 @@
|
||||
<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>
|
||||
|
33
src/misc.h
33
src/misc.h
@@ -215,6 +215,11 @@ public:
|
||||
// return qBittorrent config path
|
||||
static QString qBittorrentPath() {
|
||||
QString qBtPath = QDir::homePath()+QDir::separator()+QString::fromUtf8(".qbittorrent") + QDir::separator();
|
||||
// Create dir if it does not exist
|
||||
if(!QFile::exists(qBtPath)){
|
||||
QDir dir(qBtPath);
|
||||
dir.mkpath(qBtPath);
|
||||
}
|
||||
return qBtPath;
|
||||
}
|
||||
|
||||
@@ -266,14 +271,30 @@ public:
|
||||
|
||||
static QString magnetUriToHash(QString magnet_uri) {
|
||||
QString hash = "";
|
||||
QRegExp reg("urn:btih:([A-Z2-7=]+)");
|
||||
int pos = reg.indexIn(magnet_uri);
|
||||
QRegExp regHex("urn:btih:([0-9A-Za-z]+)");
|
||||
// Hex
|
||||
int pos = regHex.indexIn(magnet_uri);
|
||||
if(pos > -1) {
|
||||
sha1_hash sha1;
|
||||
sha1.assign(base32decode(reg.cap(1).toStdString()));
|
||||
hash = misc::toQString(sha1);
|
||||
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);
|
||||
}
|
||||
}
|
||||
qDebug("magnetUriToHash: hash: %s", hash.toLocal8Bit().data());
|
||||
// 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());
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
@@ -362,7 +362,12 @@ void PropertiesWidget::loadDynamicData() {
|
||||
}
|
||||
if(stackedProperties->currentIndex() == FILES_TAB) {
|
||||
// Files progress
|
||||
if(h.has_metadata()) {
|
||||
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));
|
||||
}
|
||||
std::vector<size_type> fp;
|
||||
h.file_progress(fp);
|
||||
PropListModel->updateFilesPriorities(h.file_priorities());
|
||||
|
49
src/rss.cpp
49
src/rss.cpp
@@ -376,7 +376,6 @@ 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();
|
||||
@@ -388,8 +387,6 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -584,29 +581,31 @@ short RssStream::readDoc(const QDomDocument& doc) {
|
||||
delete item;
|
||||
item = this->value(title);
|
||||
}
|
||||
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;
|
||||
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);
|
||||
}
|
||||
// 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() && !torrent_url.isEmpty()) {
|
||||
if(!title.isEmpty()) {
|
||||
is_valid = true;
|
||||
} else {
|
||||
std::cerr << "ERROR: an invalid RSS item was saved" << std::endl;
|
||||
@@ -394,7 +394,6 @@ private:
|
||||
bool refreshed;
|
||||
bool downloadFailure;
|
||||
bool currently_loading;
|
||||
bool has_attachments;
|
||||
|
||||
public slots:
|
||||
void processDownloadedFile(QString file_path);
|
||||
@@ -430,7 +429,6 @@ public:
|
||||
QList<RssItem*> getNewsList() const;
|
||||
QList<RssItem*> getUnreadNewsList() const;
|
||||
QString getIconUrl();
|
||||
bool hasAttachments() const { return has_attachments; }
|
||||
|
||||
private:
|
||||
short readDoc(const QDomDocument& doc);
|
||||
|
@@ -71,10 +71,8 @@ void RSSImp::displayRSSListMenu(const QPoint& pos){
|
||||
myRSSListMenu.addSeparator();
|
||||
myRSSListMenu.addAction(actionCopy_feed_URL);
|
||||
if(selectedItems.size() == 1) {
|
||||
if(((RssStream*)listStreams->getRSSItem(selectedItems.first()))->hasAttachments()) {
|
||||
myRSSListMenu.addSeparator();
|
||||
myRSSListMenu.addAction(actionRSS_feed_downloader);
|
||||
}
|
||||
myRSSListMenu.addSeparator();
|
||||
myRSSListMenu.addAction(actionRSS_feed_downloader);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@@ -293,9 +291,7 @@ void RSSImp::downloadTorrent() {
|
||||
if(article->has_attachment()) {
|
||||
BTSession->downloadFromUrl(article->getTorrentUrl());
|
||||
} else {
|
||||
QString link = article->getLink();
|
||||
if(!link.isEmpty())
|
||||
QDesktopServices::openUrl(QUrl(link));
|
||||
BTSession->downloadFromUrl(article->getLink());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -444,10 +440,6 @@ 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.32
|
||||
#AUTHORS: Fabien Devaux (fab@gnux.info)
|
||||
#VERSION: 1.40
|
||||
#AUTHORS: Christophe Dumez (chris@qbittorrent.org)
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
@@ -27,88 +27,85 @@
|
||||
|
||||
from novaprinter import prettyPrinter
|
||||
from helpers import retrieve_url, download_file
|
||||
from xml.dom import minidom
|
||||
import sgmllib
|
||||
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'}
|
||||
|
||||
def download_torrent(self, info):
|
||||
print download_file(info)
|
||||
# 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 search(self, what, cat='all'):
|
||||
def __init__(self):
|
||||
self.results = []
|
||||
self.parser = self.SimpleSGMLParser(self.results, self.url)
|
||||
|
||||
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)
|
||||
def download_torrent(self, info):
|
||||
print download_file(info)
|
||||
|
||||
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
|
||||
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
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#VERSION: 1.22
|
||||
#VERSION: 1.30
|
||||
#AUTHORS: Fabien Devaux (fab@gnux.info)
|
||||
#CONTRIBUTORS: Christophe Dumez (chris@qbittorrent.org)
|
||||
|
||||
@@ -50,32 +50,35 @@ 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('/browse'):
|
||||
if params['href'].startswith('/torrent/'):
|
||||
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.td_counter = self.td_counter+1
|
||||
self.in_name = False
|
||||
|
||||
def handle_data(self, data):
|
||||
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 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 == 7:
|
||||
elif self.td_counter == 2:
|
||||
if not self.current_item.has_key('leech'):
|
||||
self.current_item['leech'] = ''
|
||||
self.current_item['leech']+= data.strip()
|
||||
@@ -83,7 +86,7 @@ class piratebay(object):
|
||||
def start_td(self,attr):
|
||||
if isinstance(self.td_counter,int):
|
||||
self.td_counter += 1
|
||||
if self.td_counter > 7:
|
||||
if self.td_counter > 3:
|
||||
self.td_counter = None
|
||||
# Display item
|
||||
if self.current_item:
|
||||
@@ -101,7 +104,8 @@ class piratebay(object):
|
||||
while True and i<11:
|
||||
results = []
|
||||
parser = self.SimpleSGMLParser(results, self.url)
|
||||
dat = retrieve_url(self.url+'/search/%s/%u/99/%s' % (what, i, self.supported_categories[cat]))
|
||||
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])
|
||||
parser.feed(dat)
|
||||
parser.close()
|
||||
if len(results) <= 0:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
isohunt: 1.30
|
||||
torrentreactor: 1.20
|
||||
btjunkie: 2.21
|
||||
mininova: 1.32
|
||||
piratebay: 1.22
|
||||
mininova: 1.40
|
||||
piratebay: 1.30
|
||||
|
@@ -22,16 +22,15 @@
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#VERSION: 1.1
|
||||
#VERSION: 1.2
|
||||
|
||||
# Author:
|
||||
# Christophe DUMEZ (chris@qbittorrent.org)
|
||||
|
||||
import re, htmlentitydefs
|
||||
import urllib2
|
||||
import tempfile
|
||||
import os
|
||||
import StringIO, gzip, httplib
|
||||
import StringIO, gzip, urllib2
|
||||
|
||||
def htmlentitydecode(s):
|
||||
# First convert alpha entities (such as é)
|
||||
@@ -64,12 +63,14 @@ def retrieve_url(url):
|
||||
dat = htmlentitydecode(dat)
|
||||
return dat.encode('utf-8', 'replace')
|
||||
|
||||
def download_file(url):
|
||||
def download_file(url, referer=None):
|
||||
""" 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
|
||||
|
@@ -3,7 +3,7 @@ LANG_PATH = lang
|
||||
ICONS_PATH = Icons
|
||||
|
||||
# Set the following variable to 1 to enable debug
|
||||
DEBUG_MODE = 1
|
||||
DEBUG_MODE = 0
|
||||
|
||||
# Global
|
||||
TEMPLATE = app
|
||||
@@ -12,10 +12,10 @@ CONFIG += qt \
|
||||
thread
|
||||
|
||||
# Update this VERSION for each release
|
||||
DEFINES += VERSION=\\\"v2.0.0\\\"
|
||||
DEFINES += VERSION=\\\"v2.0.2\\\"
|
||||
DEFINES += VERSION_MAJOR=2
|
||||
DEFINES += VERSION_MINOR=0
|
||||
DEFINES += VERSION_BUGFIX=0
|
||||
DEFINES += VERSION_BUGFIX=2
|
||||
|
||||
# !mac:QMAKE_LFLAGS += -Wl,--as-needed
|
||||
contains(DEBUG_MODE, 1) {
|
||||
|
@@ -846,8 +846,10 @@ 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);
|
||||
|
Reference in New Issue
Block a user