Hello community,

here is the log from the commit of package qbittorrent for openSUSE:Factory 
checked in at 2014-10-29 21:09:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/qbittorrent (Old)
 and      /work/SRC/openSUSE:Factory/.qbittorrent.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "qbittorrent"

Changes:
--------
--- /work/SRC/openSUSE:Factory/qbittorrent/qbittorrent.changes  2014-09-28 
19:54:20.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.qbittorrent.new/qbittorrent.changes     
2014-10-29 21:09:53.000000000 +0100
@@ -1,0 +2,21 @@
+Sat Oct 25 21:40:04 UTC 2014 - sor.ale...@meowr.ru
+
+- Update to 3.1.11:
+  + FEATURE: Allow relative torrent paths when qBittorrent is already running.
+  + FEATURE: Make Windows icons suitable for high dpi screens.
+  + FEATURE: Increase maximum size of system icons.
+  + BUGFIX: Fix crash in the "Content" widget when user would right click in 
it without a torrent selected.
+  + BUGFIX: Don't show multiple unlock UI dialogs. Closes #2040.
+  + SEARCH: Fix bug where python would falsely be detected and nothing worked.
+  + SEARCH: Fix TorrentReactor search plugin.
+  + SEARCH: Pirate bay search engine update.
+  + SEARCH: Internal improvements in the python code.
+  + WEBUI: Set correct HTTP Content-Type in case of forbidden access.
+  + COSMETIC: Remove unneeded tooltip.
+  + COSMETIC: Don't stretch the last section in the transfer list.
+  + COSMETIC: Set minimum width of the left panel in the preferences.
+  + OTHER: Optimize sorting of rows. This should have less CPU impact when 
many torrents are present.
+  + OTHER: Use the correct character encoding for exceptions coming from 
libtorrent.
+  + OTHER: Use boost:bind() as the docs show. Allows compilation with older 
gcc versions.
+
+-------------------------------------------------------------------

Old:
----
  qbittorrent-3.1.10.tar.xz

New:
----
  qbittorrent-3.1.11.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ qbittorrent.spec ++++++
--- /var/tmp/diff_new_pack.QLWU0B/_old  2014-10-29 21:09:54.000000000 +0100
+++ /var/tmp/diff_new_pack.QLWU0B/_new  2014-10-29 21:09:54.000000000 +0100
@@ -19,7 +19,7 @@
 
 Name:           qbittorrent
 %define _name   qBittorrent
-Version:        3.1.10
+Version:        3.1.11
 Release:        0
 Summary:        A Bittorrent Client built with C++ / Qt4
 License:        GPL-2.0+

++++++ qbittorrent-3.1.10.tar.xz -> qbittorrent-3.1.11.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/Changelog 
new/qbittorrent-3.1.11/Changelog
--- old/qbittorrent-3.1.10/Changelog    2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/Changelog    2014-10-22 21:45:31.000000000 +0200
@@ -1,3 +1,25 @@
+* Wed Oct 22 2014 - sledgehammer999 <sledgehammer...@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 <sledgehammer...@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)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/addnewtorrentdialog.cpp 
new/qbittorrent-3.1.11/src/addnewtorrentdialog.cpp
--- old/qbittorrent-3.1.10/src/addnewtorrentdialog.cpp  2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/addnewtorrentdialog.cpp  2014-10-22 
21:45:31.000000000 +0200
@@ -197,7 +197,7 @@
     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;
   }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/iconprovider.cpp 
new/qbittorrent-3.1.11/src/iconprovider.cpp
--- old/qbittorrent-3.1.10/src/iconprovider.cpp 2014-09-21 19:58:56.000000000 
+0200
+++ new/qbittorrent-3.1.11/src/iconprovider.cpp 2014-10-22 21:45:31.000000000 
+0200
@@ -81,7 +81,7 @@
 {
   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) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/mac/Info.plist 
new/qbittorrent-3.1.11/src/mac/Info.plist
--- old/qbittorrent-3.1.10/src/mac/Info.plist   2014-09-21 19:58:56.000000000 
+0200
+++ new/qbittorrent-3.1.11/src/mac/Info.plist   2014-10-22 21:45:31.000000000 
+0200
@@ -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>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/main.cpp 
new/qbittorrent-3.1.11/src/main.cpp
--- old/qbittorrent-3.1.10/src/main.cpp 2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/main.cpp 2014-10-22 21:45:31.000000000 +0200
@@ -228,9 +228,14 @@
     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 += "|";
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/mainwindow.cpp 
new/qbittorrent-3.1.11/src/mainwindow.cpp
--- old/qbittorrent-3.1.10/src/mainwindow.cpp   2014-09-21 19:58:56.000000000 
+0200
+++ new/qbittorrent-3.1.11/src/mainwindow.cpp   2014-10-22 21:45:31.000000000 
+0200
@@ -101,7 +101,7 @@
  *****************************************************/
 
 // 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 @@
 }
 
 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 @@
     bool res = false;
 
     // Check if python is already in PATH
-    if (misc::pythonVersion())
+    if (misc::pythonVersion() > 0)
       res = true;
     else
       res = addPythonPathToEnv();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/mainwindow.h 
new/qbittorrent-3.1.11/src/mainwindow.h
--- old/qbittorrent-3.1.10/src/mainwindow.h     2014-09-21 19:58:56.000000000 
+0200
+++ new/qbittorrent-3.1.11/src/mainwindow.h     2014-10-22 21:45:31.000000000 
+0200
@@ -183,6 +183,7 @@
   bool displaySpeedInTitle;
   bool force_exit;
   bool ui_locked;
+  bool unlockDlgShowing;
   LineEdit *search_filter;
   // Keyboard shortcuts
   QShortcut *switchSearchShortcut;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/misc.cpp 
new/qbittorrent-3.1.11/src/misc.cpp
--- old/qbittorrent-3.1.10/src/misc.cpp 2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/misc.cpp 2014-10-22 21:45:31.000000000 +0200
@@ -136,8 +136,8 @@
   }
 #endif
 #ifdef Q_WS_MAC
+  AEEventID EventToSend;
   if (action != SHUTDOWN_COMPUTER)
-  if (sleep)
     EventToSend = kAESleep;
   else
     EventToSend = kAEShutDown;
@@ -556,15 +556,29 @@
 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 @@
 
     // Strings + digits do match and we haven't hit string end
     // Do another round
-    left.remove(0, posL);
-    right.remove(0, posR);
 
   } while (true);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/preferences/options.ui 
new/qbittorrent-3.1.11/src/preferences/options.ui
--- old/qbittorrent-3.1.10/src/preferences/options.ui   2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/preferences/options.ui   2014-10-22 
21:45:31.000000000 +0200
@@ -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>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/preferences/options_imp.cpp 
new/qbittorrent-3.1.11/src/preferences/options_imp.cpp
--- old/qbittorrent-3.1.10/src/preferences/options_imp.cpp      2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/preferences/options_imp.cpp      2014-10-22 
21:45:31.000000000 +0200
@@ -310,8 +310,8 @@
     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);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/preferences/preferences.h 
new/qbittorrent-3.1.11/src/preferences/preferences.h
--- old/qbittorrent-3.1.10/src/preferences/preferences.h        2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/preferences/preferences.h        2014-10-22 
21:45:31.000000000 +0200
@@ -1277,7 +1277,7 @@
         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 @@
 
       // 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");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/programupdater.cpp 
new/qbittorrent-3.1.11/src/programupdater.cpp
--- old/qbittorrent-3.1.10/src/programupdater.cpp       2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/programupdater.cpp       2014-10-22 
21:45:31.000000000 +0200
@@ -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
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qbittorrent-3.1.10/src/properties/propertieswidget.cpp 
new/qbittorrent-3.1.11/src/properties/propertieswidget.cpp
--- old/qbittorrent-3.1.10/src/properties/propertieswidget.cpp  2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/properties/propertieswidget.cpp  2014-10-22 
21:45:31.000000000 +0200
@@ -384,7 +384,7 @@
       }
     }
   } 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::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;
Files old/qbittorrent-3.1.10/src/qbittorrent.ico and 
new/qbittorrent-3.1.11/src/qbittorrent.ico differ
Files old/qbittorrent-3.1.10/src/qbittorrent_file.ico and 
new/qbittorrent-3.1.11/src/qbittorrent_file.ico differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/qtlibtorrent/qbtsession.cpp 
new/qbittorrent-3.1.11/src/qtlibtorrent/qbtsession.cpp
--- old/qbittorrent-3.1.10/src/qtlibtorrent/qbtsession.cpp      2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/qtlibtorrent/qbtsession.cpp      2014-10-22 
21:45:31.000000000 +0200
@@ -1110,7 +1110,7 @@
   } 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{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qbittorrent-3.1.10/src/searchengine/nova/engines/btdigg.py 
new/qbittorrent-3.1.11/src/searchengine/nova/engines/btdigg.py
--- old/qbittorrent-3.1.10/src/searchengine/nova/engines/btdigg.py      
2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/searchengine/nova/engines/btdigg.py      
2014-10-22 21:45:31.000000000 +0200
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 #
 
-#VERSION: 1.22
+#VERSION: 1.23
 #AUTHORS: BTDigg team (resea...@btdigg.org)
 #
 #                    GNU GENERAL PUBLIC LICENSE
@@ -66,7 +66,7 @@
         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:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qbittorrent-3.1.10/src/searchengine/nova/engines/piratebay.py 
new/qbittorrent-3.1.11/src/searchengine/nova/engines/piratebay.py
--- old/qbittorrent-3.1.10/src/searchengine/nova/engines/piratebay.py   
2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/searchengine/nova/engines/piratebay.py   
2014-10-22 21:45:31.000000000 +0200
@@ -1,6 +1,7 @@
-#VERSION: 1.53
+#VERSION: 2.00
 #AUTHORS: Fabien Devaux (f...@gnux.info)
 #CONTRIBUTORS: Christophe Dumez (ch...@qbittorrent.org)
+#              Arthur (custparas...@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'}
-
-       def __init__(self):
-               self.results = []
-               self.parser = self.SimpleSGMLParser(self.results, self.url)
-
-       def download_torrent(self, info):
-               print download_file(info)
-
-       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 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_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 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
+    url = 'http://thepiratebay.se'
+    name = 'The Pirate Bay'
+    supported_categories = {'all': '0', 'music': '100', 'movies': '200', 
'games': '400', 'software': '300'}
+
+    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      }
+
+        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 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_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 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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qbittorrent-3.1.10/src/searchengine/nova/engines/torrentreactor.py 
new/qbittorrent-3.1.11/src/searchengine/nova/engines/torrentreactor.py
--- old/qbittorrent-3.1.10/src/searchengine/nova/engines/torrentreactor.py      
2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/searchengine/nova/engines/torrentreactor.py      
2014-10-22 21:45:31.000000000 +0200
@@ -1,6 +1,7 @@
-#VERSION: 1.32
+#VERSION: 1.33
 #AUTHORS: Gekko Dam Beer (gekk...@users.sourceforge.net)
 #CONTRIBUTORS: Christophe Dumez (ch...@qbittorrent.org)
+#              Bruno Barbieri (bruno...@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 @@
 
        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 @@
 
        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:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qbittorrent-3.1.10/src/searchengine/nova/engines/versions.txt 
new/qbittorrent-3.1.11/src/searchengine/nova/engines/versions.txt
--- old/qbittorrent-3.1.10/src/searchengine/nova/engines/versions.txt   
2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/searchengine/nova/engines/versions.txt   
2014-10-22 21:45:31.000000000 +0200
@@ -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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/searchengine/nova/nova2.py 
new/qbittorrent-3.1.11/src/searchengine/nova/nova2.py
--- old/qbittorrent-3.1.10/src/searchengine/nova/nova2.py       2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/searchengine/nova/nova2.py       2014-10-22 
21:45:31.000000000 +0200
@@ -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 threading
 import os
 import glob
+import urllib
 
 import fix_encoding
 
@@ -138,7 +139,7 @@
        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:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qbittorrent-3.1.10/src/searchengine/nova3/engines/btdigg.py 
new/qbittorrent-3.1.11/src/searchengine/nova3/engines/btdigg.py
--- old/qbittorrent-3.1.10/src/searchengine/nova3/engines/btdigg.py     
2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/searchengine/nova3/engines/btdigg.py     
2014-10-22 21:45:31.000000000 +0200
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 #
 
-#VERSION: 1.21
+#VERSION: 1.23
 #AUTHORS: BTDigg team (resea...@btdigg.org)
 #
 #                    GNU GENERAL PUBLIC LICENSE
@@ -36,7 +36,7 @@
         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:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qbittorrent-3.1.10/src/searchengine/nova3/engines/piratebay.py 
new/qbittorrent-3.1.11/src/searchengine/nova3/engines/piratebay.py
--- old/qbittorrent-3.1.10/src/searchengine/nova3/engines/piratebay.py  
2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/searchengine/nova3/engines/piratebay.py  
2014-10-22 21:45:31.000000000 +0200
@@ -1,6 +1,7 @@
-#VERSION: 1.53
+#VERSION: 2.00
 #AUTHORS: Fabien Devaux (f...@gnux.info)
 #CONTRIBUTORS: Christophe Dumez (ch...@qbittorrent.org)
+#              Arthur (custparas...@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'}
-
-       def __init__(self):
-               self.results = []
-               self.parser = self.SimpleSGMLParser(self.results, self.url)
-
-       def download_torrent(self, info):
-               print(download_file(info))
-
-       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 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_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 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
+    url = 'http://thepiratebay.se'
+    name = 'The Pirate Bay'
+    supported_categories = {'all': '0', 'music': '100', 'movies': '200', 
'games': '400', 'software': '300'}
+
+    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      }
+
+        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 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_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 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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qbittorrent-3.1.10/src/searchengine/nova3/engines/torrentreactor.py 
new/qbittorrent-3.1.11/src/searchengine/nova3/engines/torrentreactor.py
--- old/qbittorrent-3.1.10/src/searchengine/nova3/engines/torrentreactor.py     
2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/searchengine/nova3/engines/torrentreactor.py     
2014-10-22 21:45:31.000000000 +0200
@@ -1,6 +1,7 @@
-#VERSION: 1.32
+#VERSION: 1.33
 #AUTHORS: Gekko Dam Beer (gekk...@users.sourceforge.net)
 #CONTRIBUTORS: Christophe Dumez (ch...@qbittorrent.org)
+#              Bruno Barbieri (bruno...@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 @@
 
        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 @@
 
        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:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qbittorrent-3.1.10/src/searchengine/nova3/engines/versions.txt 
new/qbittorrent-3.1.11/src/searchengine/nova3/engines/versions.txt
--- old/qbittorrent-3.1.10/src/searchengine/nova3/engines/versions.txt  
2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/searchengine/nova3/engines/versions.txt  
2014-10-22 21:45:31.000000000 +0200
@@ -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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/searchengine/nova3/nova2.py 
new/qbittorrent-3.1.11/src/searchengine/nova3/nova2.py
--- old/qbittorrent-3.1.10/src/searchengine/nova3/nova2.py      2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/searchengine/nova3/nova2.py      2014-10-22 
21:45:31.000000000 +0200
@@ -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 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:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qbittorrent-3.1.10/src/searchengine/nova3/novaprinter.py 
new/qbittorrent-3.1.11/src/searchengine/nova3/novaprinter.py
--- old/qbittorrent-3.1.10/src/searchengine/nova3/novaprinter.py        
2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/searchengine/nova3/novaprinter.py        
2014-10-22 21:45:31.000000000 +0200
@@ -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):
        """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qbittorrent-3.1.10/src/torrentcreator/torrentcreatorthread.cpp 
new/qbittorrent-3.1.11/src/torrentcreator/torrentcreatorthread.cpp
--- old/qbittorrent-3.1.10/src/torrentcreator/torrentcreatorthread.cpp  
2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/torrentcreator/torrentcreatorthread.cpp  
2014-10-22 21:45:31.000000000 +0200
@@ -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 @@
     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 @@
     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()));
   }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/transferlistwidget.cpp 
new/qbittorrent-3.1.11/src/transferlistwidget.cpp
--- old/qbittorrent-3.1.10/src/transferlistwidget.cpp   2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/transferlistwidget.cpp   2014-10-22 
21:45:31.000000000 +0200
@@ -112,6 +112,7 @@
 #if defined(Q_WS_MAC)
   setAttribute(Qt::WA_MacShowFocusRect, false);
 #endif
+  header()->setStretchLastSection(false);
 
   // Default hidden columns
   if (!column_loaded) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/webui/btjson.cpp 
new/qbittorrent-3.1.11/src/webui/btjson.cpp
--- old/qbittorrent-3.1.10/src/webui/btjson.cpp 2014-09-21 19:58:56.000000000 
+0200
+++ new/qbittorrent-3.1.11/src/webui/btjson.cpp 2014-10-22 21:45:31.000000000 
+0200
@@ -257,7 +257,7 @@
       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 @@
     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 @@
       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();
   }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/webui/httpconnection.cpp 
new/qbittorrent-3.1.11/src/webui/httpconnection.cpp
--- old/qbittorrent-3.1.10/src/webui/httpconnection.cpp 2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/webui/httpconnection.cpp 2014-10-22 
21:45:31.000000000 +0200
@@ -193,6 +193,7 @@
     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;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/src/windows/options.nsi 
new/qbittorrent-3.1.11/src/windows/options.nsi
--- old/qbittorrent-3.1.10/src/windows/options.nsi      2014-09-21 
19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/src/windows/options.nsi      2014-10-22 
21:45:31.000000000 +0200
@@ -19,7 +19,7 @@
 !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)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qbittorrent-3.1.10/version.pri 
new/qbittorrent-3.1.11/version.pri
--- old/qbittorrent-3.1.10/version.pri  2014-09-21 19:58:56.000000000 +0200
+++ new/qbittorrent-3.1.11/version.pri  2014-10-22 21:45:31.000000000 +0200
@@ -1,5 +1,5 @@
 PROJECT_NAME = qbittorrent
-PROJECT_VERSION = 3.1.10
+PROJECT_VERSION = 3.1.11
 
 os2 {
     DEFINES += VERSION=\'\"v$${PROJECT_VERSION}\"\'
@@ -9,4 +9,4 @@
 
 DEFINES += VERSION_MAJOR=3
 DEFINES += VERSION_MINOR=1
-DEFINES += VERSION_BUGFIX=10
+DEFINES += VERSION_BUGFIX=11

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to