Runnable with both Python3 and Python2, with PyQt4 #2249

Open
kashikoibumi wants to merge 60 commits from kashikoibumi/py3 into v0.6
8 changed files with 37 additions and 29 deletions
Showing only changes of commit 46d56c703e - Show all commits

View File

@ -14,6 +14,7 @@ import threading
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta
from sqlite3 import register_adapter from sqlite3 import register_adapter
import six
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from PyQt4.QtNetwork import QLocalSocket, QLocalServer from PyQt4.QtNetwork import QLocalSocket, QLocalServer
@ -468,7 +469,7 @@ class MyForm(settingsmixin.SMainWindow):
# add missing folders # add missing folders
if len(db[toAddress]) > 0: if len(db[toAddress]) > 0:
j = 0 j = 0
for f, c in db[toAddress].iteritems(): for f, c in six.iteritems(db[toAddress]):
try: try:
subwidget = Ui_FolderWidget(widget, j, toAddress, f, c['count']) subwidget = Ui_FolderWidget(widget, j, toAddress, f, c['count'])
except KeyError: except KeyError:
@ -598,7 +599,7 @@ class MyForm(settingsmixin.SMainWindow):
# add missing folders # add missing folders
if len(db[toAddress]) > 0: if len(db[toAddress]) > 0:
j = 0 j = 0
for f, c in db[toAddress].iteritems(): for f, c in six.iteritems(db[toAddress]):
if toAddress is not None and tab == 'messages' and folder == "new": if toAddress is not None and tab == 'messages' and folder == "new":
continue continue
subwidget = Ui_FolderWidget(widget, j, toAddress, f, c) subwidget = Ui_FolderWidget(widget, j, toAddress, f, c)
@ -1075,15 +1076,15 @@ class MyForm(settingsmixin.SMainWindow):
for i in range(root.childCount()): for i in range(root.childCount()):
addressItem = root.child(i) addressItem = root.child(i)
if addressItem.type == AccountMixin.ALL: if addressItem.type == AccountMixin.ALL:
newCount = sum(totalUnread.itervalues()) newCount = sum(six.itervalues(totalUnread))
self.drawTrayIcon(self.currentTrayIconFileName, newCount) self.drawTrayIcon(self.currentTrayIconFileName, newCount)
else: else:
try: try:
newCount = sum(( newCount = sum(six.itervalues((
broadcastsUnread broadcastsUnread
if addressItem.type == AccountMixin.SUBSCRIPTION if addressItem.type == AccountMixin.SUBSCRIPTION
else normalUnread else normalUnread
)[addressItem.address].itervalues()) )[addressItem.address]))
except KeyError: except KeyError:
newCount = 0 newCount = 0
if newCount != addressItem.unreadCount: if newCount != addressItem.unreadCount:
@ -2871,7 +2872,7 @@ class MyForm(settingsmixin.SMainWindow):
QtCore.QEventLoop.AllEvents, 1000 QtCore.QEventLoop.AllEvents, 1000
) )
self.saveSettings() self.saveSettings()
for attr, obj in self.ui.__dict__.iteritems(): for attr, obj in six.iteritems(self.ui.__dict__):
if hasattr(obj, "__class__") \ if hasattr(obj, "__class__") \
and isinstance(obj, settingsmixin.SettingsMixin): and isinstance(obj, settingsmixin.SettingsMixin):
saveMethod = getattr(obj, "saveSettings", None) saveMethod = getattr(obj, "saveSettings", None)
@ -4209,7 +4210,7 @@ class MyForm(settingsmixin.SMainWindow):
def initSettings(self): def initSettings(self):
self.loadSettings() self.loadSettings()
for attr, obj in self.ui.__dict__.iteritems(): for attr, obj in six.iteritems(self.ui.__dict__):
if hasattr(obj, "__class__") and \ if hasattr(obj, "__class__") and \
isinstance(obj, settingsmixin.SettingsMixin): isinstance(obj, settingsmixin.SettingsMixin):
loadMethod = getattr(obj, "loadSettings", None) loadMethod = getattr(obj, "loadSettings", None)

View File

@ -1,4 +1,5 @@
from os import path from os import path
import six
from PyQt4 import QtGui from PyQt4 import QtGui
from debug import logger from debug import logger
import widgets import widgets
@ -7,7 +8,7 @@ class RetranslateMixin(object):
def retranslateUi(self): def retranslateUi(self):
defaults = QtGui.QWidget() defaults = QtGui.QWidget()
widgets.load(self.__class__.__name__.lower() + '.ui', defaults) widgets.load(self.__class__.__name__.lower() + '.ui', defaults)
for attr, value in defaults.__dict__.iteritems(): for attr, value in six.iteritems(defaults.__dict__):
setTextMethod = getattr(value, "setText", None) setTextMethod = getattr(value, "setText", None)
if callable(setTextMethod): if callable(setTextMethod):
getattr(self, attr).setText(getattr(defaults, attr).text()) getattr(self, attr).setText(getattr(defaults, attr).text())

View File

@ -6,6 +6,7 @@ from collections import namedtuple
from random import choice, expovariate, sample from random import choice, expovariate, sample
from threading import RLock from threading import RLock
from time import time from time import time
import six
import connectionpool import connectionpool
import state import state
@ -99,12 +100,12 @@ class Dandelion: # pylint: disable=old-style-class
with self.lock: with self.lock:
if len(self.stem) < MAX_STEMS: if len(self.stem) < MAX_STEMS:
self.stem.append(connection) self.stem.append(connection)
for k in (k for k, v in self.nodeMap.iteritems() if v is None): for k in (k for k, v in six.iteritems(self.nodeMap) if v is None):
self.nodeMap[k] = connection self.nodeMap[k] = connection
for k, v in { for k, v in six.iteritems({
k: v for k, v in self.hashMap.iteritems() k: v for k, v in six.iteritems(self.hashMap)
if v.child is None if v.child is None
}.iteritems(): }):
self.hashMap[k] = Stem( self.hashMap[k] = Stem(
connection, v.stream, self.poissonTimeout()) connection, v.stream, self.poissonTimeout())
invQueue.put((v.stream, k, v.child)) invQueue.put((v.stream, k, v.child))
@ -120,14 +121,14 @@ class Dandelion: # pylint: disable=old-style-class
self.stem.remove(connection) self.stem.remove(connection)
# active mappings to pointing to the removed node # active mappings to pointing to the removed node
for k in ( for k in (
k for k, v in self.nodeMap.iteritems() k for k, v in six.iteritems(self.nodeMap)
if v == connection if v == connection
): ):
self.nodeMap[k] = None self.nodeMap[k] = None
for k, v in { for k, v in six.iteritems({
k: v for k, v in self.hashMap.iteritems() k: v for k, v in six.iteritems(self.hashMap)
if v.child == connection if v.child == connection
}.iteritems(): }):
self.hashMap[k] = Stem( self.hashMap[k] = Stem(
None, v.stream, self.poissonTimeout()) None, v.stream, self.poissonTimeout())
@ -168,7 +169,7 @@ class Dandelion: # pylint: disable=old-style-class
with self.lock: with self.lock:
deadline = time() deadline = time()
toDelete = [ toDelete = [
[v.stream, k, v.child] for k, v in self.hashMap.iteritems() [v.stream, k, v.child] for k, v in six.iteritems(self.hashMap)
if v.timeout < deadline if v.timeout < deadline
] ]

View File

@ -3,6 +3,7 @@
""" """
import time import time
import state import state
import six
import addresses import addresses
import helper_random import helper_random
import protocol import protocol
@ -28,7 +29,7 @@ class DownloadThread(StoppableThread):
deadline = time.time() - self.requestExpires deadline = time.time() - self.requestExpires
try: try:
toDelete = [ toDelete = [
k for k, v in missingObjects.iteritems() k for k, v in six.iteritems(missingObjects)
if v < deadline] if v < deadline]
except RuntimeError: except RuntimeError:
pass pass

View File

@ -14,6 +14,7 @@ try:
from collections.abc import Iterable from collections.abc import Iterable
except ImportError: except ImportError:
from collections import Iterable from collections import Iterable
import six
import state import state
from bmconfigparser import config from bmconfigparser import config
@ -54,8 +55,8 @@ def json_serialize_knownnodes(output):
Reorganize knownnodes dict and write it as JSON to output Reorganize knownnodes dict and write it as JSON to output
""" """
_serialized = [] _serialized = []
for stream, peers in knownNodes.iteritems(): for stream, peers in six.iteritems(knownNodes):
for peer, info in peers.iteritems(): for peer, info in six.iteritems(peers):
info.update(rating=round(info.get('rating', 0), 2)) info.update(rating=round(info.get('rating', 0), 2))
_serialized.append({ _serialized.append({
'stream': stream, 'peer': peer._asdict(), 'info': info 'stream': stream, 'peer': peer._asdict(), 'info': info
@ -87,7 +88,7 @@ def pickle_deserialize_old_knownnodes(source):
global knownNodes global knownNodes
knownNodes = pickle.load(source) # nosec B301 knownNodes = pickle.load(source) # nosec B301
for stream in knownNodes.keys(): for stream in knownNodes.keys():
for node, params in knownNodes[stream].iteritems(): for node, params in six.iteritems(knownNodes[stream]):
if isinstance(params, (float, int)): if isinstance(params, (float, int)):
addKnownNode(stream, node, params) addKnownNode(stream, node, params)

View File

@ -3,6 +3,7 @@ Module for tracking objects
""" """
import time import time
from threading import RLock from threading import RLock
import six
import state import state
import connectionpool import connectionpool
@ -75,7 +76,7 @@ class ObjectTracker(object):
with self.objectsNewToThemLock: with self.objectsNewToThemLock:
self.objectsNewToThem = { self.objectsNewToThem = {
k: v k: v
for k, v in self.objectsNewToThem.iteritems() for k, v in six.iteritems(self.objectsNewToThem)
if v >= deadline} if v >= deadline}
self.lastCleaned = time.time() self.lastCleaned = time.time()

View File

@ -8,6 +8,7 @@ import math
import random import random
import socket import socket
import time import time
import six
# magic imports! # magic imports!
import addresses import addresses
@ -191,7 +192,7 @@ class TCPConnection(BMProto, TLSDispatcher):
# only if more recent than 3 hours # only if more recent than 3 hours
# and having positive or neutral rating # and having positive or neutral rating
filtered = [ filtered = [
(k, v) for k, v in nodes.iteritems() (k, v) for k, v in six.iteritems(nodes)
if v["lastseen"] > int(time.time()) if v["lastseen"] > int(time.time())
- maximumAgeOfNodesThatIAdvertiseToOthers - maximumAgeOfNodesThatIAdvertiseToOthers
and v["rating"] >= 0 and not k.host.endswith('.onion') and v["rating"] >= 0 and not k.host.endswith('.onion')

View File

@ -15,6 +15,7 @@ import sys
import threading import threading
import time import time
import unittest import unittest
import six
import protocol import protocol
import state import state
@ -137,8 +138,8 @@ class TestCore(unittest.TestCase):
@staticmethod @staticmethod
def _outdate_knownnodes(): def _outdate_knownnodes():
with knownnodes.knownNodesLock: with knownnodes.knownNodesLock:
for nodes in knownnodes.knownNodes.itervalues(): for nodes in six.itervalues(knownnodes.knownNodes):
for node in nodes.itervalues(): for node in six.itervalues(nodes):
node['lastseen'] -= 2419205 # older than 28 days node['lastseen'] -= 2419205 # older than 28 days
def test_knownnodes_pickle(self): def test_knownnodes_pickle(self):
@ -146,9 +147,9 @@ class TestCore(unittest.TestCase):
pickle_knownnodes() pickle_knownnodes()
self._wipe_knownnodes() self._wipe_knownnodes()
knownnodes.readKnownNodes() knownnodes.readKnownNodes()
for nodes in knownnodes.knownNodes.itervalues(): for nodes in six.itervalues(knownnodes.knownNodes):
self_count = n = 0 self_count = n = 0
for n, node in enumerate(nodes.itervalues()): for n, node in enumerate(six.itervalues(nodes)):
if node.get('self'): if node.get('self'):
self_count += 1 self_count += 1
self.assertEqual(n - self_count, 2) self.assertEqual(n - self_count, 2)
@ -202,7 +203,7 @@ class TestCore(unittest.TestCase):
while c > 0: while c > 0:
time.sleep(1) time.sleep(1)
c -= 2 c -= 2
for peer, con in connectionpool.pool.outboundConnections.iteritems(): for peer, con in six.iteritems(connectionpool.pool.outboundConnections):
if ( if (
peer.host.startswith('bootstrap') peer.host.startswith('bootstrap')
or peer.host == 'quzwelsuziwqgpt2.onion' or peer.host == 'quzwelsuziwqgpt2.onion'
@ -223,7 +224,7 @@ class TestCore(unittest.TestCase):
'Failed to connect during %.2f sec' % (time.time() - _started)) 'Failed to connect during %.2f sec' % (time.time() - _started))
def _check_knownnodes(self): def _check_knownnodes(self):
for stream in knownnodes.knownNodes.itervalues(): for stream in six.itervalues(knownnodes.knownNodes):
for peer in stream: for peer in stream:
if peer.host.startswith('bootstrap'): if peer.host.startswith('bootstrap'):
self.fail( self.fail(